bmpfont.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <uefi.h>
  2. /* Scalable Screen Font (https://gitlab.com/bztsrc/scalable-font2) */
  3. typedef struct {
  4. unsigned char magic[4];
  5. unsigned int size;
  6. unsigned char type;
  7. unsigned char features;
  8. unsigned char width;
  9. unsigned char height;
  10. unsigned char baseline;
  11. unsigned char underline;
  12. unsigned short fragments_offs;
  13. unsigned int characters_offs;
  14. unsigned int ligature_offs;
  15. unsigned int kerning_offs;
  16. unsigned int cmap_offs;
  17. } __attribute__((packed)) ssfn_font_t;
  18. /* framebuffer properties */
  19. unsigned int width, height, pitch;
  20. unsigned char *lfb;
  21. /* font to be used */
  22. ssfn_font_t *font;
  23. /**
  24. * Display string using a bitmap font without the SSFN library
  25. */
  26. void printString(int x, int y, char *s)
  27. {
  28. unsigned char *ptr, *chr, *frg;
  29. unsigned int c;
  30. uintptr_t o, p;
  31. int i, j, k, l, m, n;
  32. while(*s) {
  33. c = 0; s += mbtowc((wchar_t*)&c, (const char*)s, 4);
  34. if(c == '\r') { x = 0; continue; } else
  35. if(c == '\n') { x = 0; y += font->height; continue; }
  36. for(ptr = (unsigned char*)font + font->characters_offs, chr = 0, i = 0; i < 0x110000; i++) {
  37. if(ptr[0] == 0xFF) { i += 65535; ptr++; }
  38. else if((ptr[0] & 0xC0) == 0xC0) { j = (((ptr[0] & 0x3F) << 8) | ptr[1]); i += j; ptr += 2; }
  39. else if((ptr[0] & 0xC0) == 0x80) { j = (ptr[0] & 0x3F); i += j; ptr++; }
  40. else { if((unsigned int)i == c) { chr = ptr; break; } ptr += 6 + ptr[1] * (ptr[0] & 0x40 ? 6 : 5); }
  41. }
  42. if(!chr) continue;
  43. ptr = chr + 6; o = (uintptr_t)lfb + y * pitch + x * 4;
  44. for(i = n = 0; i < chr[1]; i++, ptr += chr[0] & 0x40 ? 6 : 5) {
  45. if(ptr[0] == 255 && ptr[1] == 255) continue;
  46. frg = (unsigned char*)font + (chr[0] & 0x40 ? ((ptr[5] << 24) | (ptr[4] << 16) | (ptr[3] << 8) | ptr[2]) :
  47. ((ptr[4] << 16) | (ptr[3] << 8) | ptr[2]));
  48. if((frg[0] & 0xE0) != 0x80) continue;
  49. o += (int)(ptr[1] - n) * pitch; n = ptr[1];
  50. k = ((frg[0] & 0x1F) + 1) << 3; j = frg[1] + 1; frg += 2;
  51. for(m = 1; j; j--, n++, o += pitch)
  52. for(p = o, l = 0; l < k; l++, p += 4, m <<= 1) {
  53. if(m > 0x80) { frg++; m = 1; }
  54. if(*frg & m) *((unsigned int*)p) = 0xFFFFFF;
  55. }
  56. }
  57. x += chr[4]+1; y += chr[5];
  58. }
  59. }
  60. /**
  61. * Display bitmap fonts
  62. */
  63. int main(int argc, char **argv)
  64. {
  65. efi_status_t status;
  66. efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  67. efi_gop_t *gop = NULL;
  68. FILE *f;
  69. long int size;
  70. /* load font */
  71. if((f = fopen("\\0A_bmpfont\\font.sfn", "r"))) {
  72. fseek(f, 0, SEEK_END);
  73. size = ftell(f);
  74. fseek(f, 0, SEEK_SET);
  75. font = (ssfn_font_t*)malloc(size + 1);
  76. if(!font) {
  77. fprintf(stderr, "unable to allocate memory\n");
  78. return 1;
  79. }
  80. fread(font, size, 1, f);
  81. fclose(f);
  82. } else {
  83. fprintf(stderr, "Unable to load font\n");
  84. return 0;
  85. }
  86. /* set video mode */
  87. status = BS->LocateProtocol(&gopGuid, NULL, (void**)&gop);
  88. if(!EFI_ERROR(status) && gop) {
  89. status = gop->SetMode(gop, 0);
  90. ST->ConOut->Reset(ST->ConOut, 0);
  91. ST->StdErr->Reset(ST->StdErr, 0);
  92. if(EFI_ERROR(status)) {
  93. fprintf(stderr, "unable to set video mode\n");
  94. return 0;
  95. }
  96. /* set up destination buffer */
  97. lfb = (unsigned char*)gop->Mode->FrameBufferBase;
  98. width = gop->Mode->Information->HorizontalResolution;
  99. height = gop->Mode->Information->VerticalResolution;
  100. pitch = sizeof(unsigned int) * gop->Mode->Information->PixelsPerScanLine;
  101. } else {
  102. fprintf(stderr, "unable to get graphics output protocol\n");
  103. return 0;
  104. }
  105. /* display multilingual text */
  106. printString(10, 10, "Hello 多种语言 Многоязычный többnyelvű World!");
  107. /* free resources exit */
  108. free(font);
  109. return 0;
  110. }