OpenCore  1.0.4
OpenCore Bootloader
1.0.4
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BitmapFont.c
Go to the documentation of this file.
1
8#include <Base.h>
9
10#include <Library/BaseMemoryLib.h>
11#include <Library/BaseOverflowLib.h>
12#include <Library/DebugLib.h>
13#include <Library/MemoryAllocationLib.h>
14
15#include "OpenCanopy.h"
16#include "BmfLib.h"
17#include "GuiApp.h"
18
19CONST BMF_CHAR *
21 IN CONST BMF_CONTEXT *Context,
22 IN UINT32 Char
23 )
24{
25 CONST BMF_CHAR *Chars;
26 UINTN Left;
27 UINTN Right;
28 UINTN Median;
29 UINTN Index;
30
31 ASSERT (Context != NULL);
32
33 Chars = Context->Chars;
34
35 for (Index = 0; Index < 2; ++Index) {
36 //
37 // Binary Search for the character as the list is sorted.
38 //
39 Left = 0;
40 //
41 // As duplicates are not allowed, Right can be ceiled with Char.
42 //
43 Right = MIN (Context->NumChars, Char) - 1;
44 while (Left <= Right) {
45 //
46 // This cannot wrap around due to the file size limitation.
47 //
48 Median = (Left + Right) / 2;
49 if (Chars[Median].id == Char) {
50 return &Chars[Median];
51 } else if (Chars[Median].id < Char) {
52 Left = Median + 1;
53 } else {
54 Right = Median - 1;
55 }
56 }
57
58 //
59 // Fallback to underscore on not found symbols.
60 //
61 Char = '_';
62 }
63
64 //
65 // Supplied font does not support even underscores.
66 //
67 return NULL;
68}
69
70CONST BMF_KERNING_PAIR *
72 IN CONST BMF_CONTEXT *Context,
73 IN CHAR16 Char1,
74 IN CHAR16 Char2
75 )
76{
77 CONST BMF_KERNING_PAIR *Pairs;
78
79 UINTN Left;
80 UINTN Right;
81 UINTN Median;
82
83 UINTN Index;
84
85 ASSERT (Context != NULL);
86
87 Pairs = Context->KerningPairs;
88
89 if (Pairs == NULL) {
90 return NULL;
91 }
92
93 //
94 // Binary Search for the first character as the list is sorted.
95 //
96 Left = 0;
97 Right = Context->NumKerningPairs - 1;
98 while (Left <= Right) {
99 //
100 // This cannot wrap around due to the file size limitation.
101 //
102 Median = (Left + Right) / 2;
103 if (Pairs[Median].first == Char1) {
104 //
105 // Flat search for the second character as these are usually a lot less,
106 // the list is sorted (relative to the first character).
107 //
108 if (Pairs[Median].second == Char2) {
109 return &Pairs[Median];
110 } else if (Pairs[Median].second < Char2) {
111 for (
112 Index = Median + 1;
113 Index < Context->NumKerningPairs && Pairs[Index].first == Char1;
114 ++Index
115 )
116 {
117 if (Pairs[Index].second == Char2) {
118 return &Pairs[Index];
119 }
120 }
121 } else {
122 Index = Median;
123 while (Index > 0) {
124 --Index;
125 if (Pairs[Index].first != Char1) {
126 break;
127 }
128
129 if (Pairs[Index].second == Char2) {
130 return &Pairs[Index];
131 }
132 }
133 }
134
135 break;
136 } else if (Pairs[Median].first < Char1) {
137 Left = Median + 1;
138 } else {
139 Right = Median - 1;
140 }
141 }
142
143 return NULL;
144}
145
146BOOLEAN
148 OUT BMF_CONTEXT *Context,
149 IN CONST VOID *FileBuffer,
150 IN UINT32 FileSize
151 )
152{
153 BOOLEAN Result;
154
155 CONST BMF_HEADER *Header;
156 CONST BMF_BLOCK_HEADER *Block;
157 UINTN Index;
158
159 UINT16 MaxHeight;
160 INT32 Height;
161 INT32 Width;
162 INT32 Advance;
163 CONST BMF_CHAR *Chars;
164 CONST BMF_KERNING_PAIR *Pairs;
165
166 CONST BMF_CHAR *Char;
167
168 ASSERT (Context != NULL);
169 ASSERT (FileBuffer != NULL);
170 ASSERT (FileSize > 0);
171
172 Header = FileBuffer;
173 //
174 // Limit file size for sanity reason and to guarantee wrapping around in BS
175 // is not going to happen.
176 //
177 if ((FileSize < sizeof (*Header)) || (FileSize > BASE_2MB)) {
178 DEBUG ((DEBUG_WARN, "BMF: FileSize insane\n"));
179 return FALSE;
180 }
181
182 if ( (Header->signature[0] != 'B')
183 || (Header->signature[1] != 'M')
184 || (Header->signature[2] != 'F')
185 || (Header->version != 3))
186 {
187 DEBUG ((DEBUG_WARN, "BMF: Header insane\n"));
188 return FALSE;
189 }
190
191 ZeroMem (Context, sizeof (*Context));
192
193 FileSize -= sizeof (*Header);
194 Block = (CONST BMF_BLOCK_HEADER *)(Header + 1);
195
196 while (FileSize >= sizeof (*Block)) {
197 FileSize -= sizeof (*Block);
198 if (FileSize < Block->size) {
199 DEBUG ((DEBUG_WARN, "BMF: Block insane %u vs %u\n", FileSize, Block->size));
200 return FALSE;
201 }
202
203 FileSize -= Block->size;
204
205 switch (Block->identifier) {
207 {
208 if (Block->size < sizeof (BMF_BLOCK_INFO)) {
209 DEBUG ((DEBUG_WARN, "BMF: BlockInfo insane\n"));
210 return FALSE;
211 }
212
213 Context->Info = (CONST BMF_BLOCK_INFO *)(Block + 1);
214
215 DEBUG ((
216 DEBUG_INFO,
217 "OCUI: Info->fontSize %u Info->bitField %u Info->charSet %u Info->stretchH %u Info->aa %u\n",
218 Context->Info->fontSize,
219 Context->Info->bitField,
220 Context->Info->charSet,
221 Context->Info->stretchH,
222 Context->Info->aa
223 ));
224 DEBUG ((
225 DEBUG_INFO,
226 "OCUI: Info->paddingUp %u Info->paddingRight %u Info->paddingDown %u Info->paddingLeft %u\n",
227 Context->Info->paddingUp,
228 Context->Info->paddingRight,
229 Context->Info->paddingDown,
230 Context->Info->paddingLeft
231 ));
232 DEBUG ((
233 DEBUG_INFO,
234 "OCUI: Info->spacingHoriz %u Info->spacingVert %u Info->outline %u Info->fontName %a\n",
235 Context->Info->spacingHoriz,
236 Context->Info->spacingVert,
237 Context->Info->outline,
238 Context->Info->fontName
239 ));
240
241 /*if ((Context->Info->bitField & BMF_BLOCK_INFO_BF_UNICODE) == 0) {
242 DEBUG ((DEBUG_WARN, "BMF: Only Unicode is supported\n"));
243 return FALSE;
244 }*/
245
246 break;
247 }
248
250 {
251 if (Block->size != sizeof (BMF_BLOCK_COMMON)) {
252 DEBUG ((DEBUG_WARN, "BMF: Block Common insane\n"));
253 return FALSE;
254 }
255
256 Context->Common = (CONST BMF_BLOCK_COMMON *)(Block + 1);
257 if (Context->Common->pages != 1) {
258 DEBUG ((DEBUG_WARN, "BMF: Only one page is supported\n"));
259 return FALSE;
260 }
261
262 break;
263 }
264
266 {
267 Context->Pages = (CONST BMF_BLOCK_PAGES *)(Block + 1);
268 break;
269 }
270
272 {
273 if (Block->size % sizeof (BMF_CHAR) != 0) {
274 DEBUG ((DEBUG_WARN, "BMF: Block chars size unaligned\n"));
275 return FALSE;
276 }
277
278 Context->Chars = (CONST BMF_BLOCK_CHARS *)(Block + 1);
279 Context->NumChars = Block->size / sizeof (BMF_CHAR);
280 break;
281 }
282
284 {
285 if (Block->size % sizeof (BMF_KERNING_PAIR) != 0) {
286 DEBUG ((DEBUG_WARN, "BMF: Block Pairs unaligned\n"));
287 return FALSE;
288 }
289
290 Context->KerningPairs = (CONST BMF_BLOCK_KERNING_PAIRS *)(Block + 1);
291 Context->NumKerningPairs = Block->size / sizeof (BMF_KERNING_PAIR);
292 break;
293 }
294
295 default:
296 {
297 //
298 // Ignore potential trailer.
299 //
300 FileSize = 0;
301 break;
302 }
303 }
304
305 Block = (CONST BMF_BLOCK_HEADER *)((UINTN)(Block + 1) + Block->size);
306 }
307
308 if (Context->Info == NULL) {
309 DEBUG ((DEBUG_WARN, "BMF: Missing Info block\n"));
310 return FALSE;
311 }
312
313 if (Context->Common == NULL) {
314 DEBUG ((DEBUG_WARN, "BMF: Missing Common block\n"));
315 return FALSE;
316 }
317
318 if (Context->Pages == NULL) {
319 DEBUG ((DEBUG_WARN, "BMF: Missing Pages block\n"));
320 return FALSE;
321 }
322
323 if (Context->Chars == NULL) {
324 DEBUG ((DEBUG_WARN, "BMF: Missing Chars block\n"));
325 return FALSE;
326 }
327
328 Chars = Context->Chars;
329 MaxHeight = 0;
330
331 for (Index = 0; Index < Context->NumChars; ++Index) {
332 Result = BaseOverflowAddS32 (
333 Chars[Index].yoffset,
334 Chars[Index].height,
335 &Height
336 );
337 Result |= BaseOverflowAddS32 (
338 Chars[Index].xoffset,
339 Chars[Index].width,
340 &Width
341 );
342 Result |= BaseOverflowAddS32 (
343 Chars[Index].xoffset,
344 Chars[Index].xadvance,
345 &Advance
346 );
347 if ( Result
348 || (0 > Height) || (Height > MAX_UINT16)
349 || (0 > Width) || (Width > MAX_UINT16)
350 || (0 > Advance) || (Advance > MAX_UINT16)
351 || (Chars[Index].xadvance < 0))
352 {
353 DEBUG ((
354 DEBUG_WARN,
355 "BMF: Char insane\n"
356 " id %u\n"
357 " x %u\n"
358 " y %u\n"
359 " width %u\n"
360 " height %u\n"
361 " xoffset %d\n"
362 " yoffset %d\n"
363 " xadvance %d\n"
364 " page %u\n"
365 " chnl %u\n",
366 Chars[Index].id,
367 Chars[Index].x,
368 Chars[Index].y,
369 Chars[Index].width,
370 Chars[Index].height,
371 Chars[Index].xoffset,
372 Chars[Index].yoffset,
373 Chars[Index].xadvance,
374 Chars[Index].page,
375 Chars[Index].chnl
376 ));
377 return FALSE;
378 }
379
380 MaxHeight = MAX (MaxHeight, (UINT16)Height);
381 //
382 // This only yields unexpected but not undefined behaviour when not met,
383 // hence it is fine verifying it only DEBUG mode.
384 //
385 DEBUG_CODE_BEGIN ();
386 if (Index > 0) {
387 if (Chars[Index - 1].id > Chars[Index].id) {
388 DEBUG ((DEBUG_WARN, "BMF: Character IDs are not sorted\n"));
389 return FALSE;
390 } else if (Chars[Index - 1].id == Chars[Index].id) {
391 DEBUG ((DEBUG_WARN, "BMF: Character ID duplicate\n"));
392 return FALSE;
393 }
394 }
395
396 DEBUG_CODE_END ();
397 }
398
399 Context->Height = (UINT16)MaxHeight;
400
401 Pairs = Context->KerningPairs;
402 if (Pairs != NULL) {
403 // According to the docs, kerning pairs are optional
404 for (Index = 0; Index < Context->NumKerningPairs; ++Index) {
405 Char = BmfGetChar (Context, Pairs[Index].first);
406 if (Char == NULL) {
407 DEBUG ((
408 DEBUG_WARN,
409 "BMF: Pair char %u not found\n",
410 Pairs[Index].first
411 ));
412 return FALSE;
413 }
414
415 Result = BaseOverflowAddS32 (
416 Char->xoffset + Char->width,
417 Pairs[Index].amount,
418 &Width
419 );
420 Result |= BaseOverflowAddS32 (
421 Char->xoffset + Char->xadvance,
422 Pairs[Index].amount,
423 &Advance
424 );
425 if ( Result
426 || (0 > Width) || (Width > MAX_UINT16)
427 || (0 > Advance) || (Advance > MAX_UINT16))
428 {
429 DEBUG ((
430 DEBUG_WARN,
431 "BMF: Pair at index %d insane: first %u, second %u, amount %d\n",
432 Index,
433 Pairs[Index].first,
434 Pairs[Index].second,
435 Pairs[Index].amount
436 ));
437 return FALSE;
438 }
439
440 //
441 // This only yields unexpected but not undefined behaviour when not met,
442 // hence it is fine verifying it only DEBUG mode.
443 //
444 DEBUG_CODE_BEGIN ();
445 if (Index > 0) {
446 if (Pairs[Index - 1].first > Pairs[Index].first) {
447 DEBUG ((DEBUG_WARN, "BMF: First Character IDs are not sorted\n"));
448 return FALSE;
449 }
450
451 if (Pairs[Index - 1].first == Pairs[Index].first) {
452 if (Pairs[Index - 1].second > Pairs[Index].second) {
453 DEBUG ((DEBUG_WARN, "BMF: Second Character IDs are not sorted\n"));
454 return FALSE;
455 }
456
457 if (Pairs[Index - 1].second == Pairs[Index].second) {
458 DEBUG ((DEBUG_WARN, "BMF: Second Character ID duplicate\n"));
459 return FALSE;
460 }
461 }
462 }
463
464 DEBUG_CODE_END ();
465 }
466 }
467
468 return TRUE;
469}
470
471typedef struct {
472 UINT16 Width;
473 UINT16 Height;
474 INT16 OffsetY;
475 CONST BMF_CHAR *Chars[];
476 // CONST BMF_KERNING_PAIR *KerningPairs[];
478
481 IN CONST BMF_CONTEXT *Context,
482 IN CONST CHAR16 *String,
483 IN UINTN StringLen,
484 IN UINT8 PosX,
485 IN UINT8 PosY
486 )
487{
488 BOOLEAN Result;
489
490 BMF_TEXT_INFO *TextInfo;
491 CONST BMF_KERNING_PAIR **InfoPairs;
492
493 INT32 Width;
494 INT32 CurWidth;
495
496 CONST BMF_CHAR *Char;
497 CONST BMF_KERNING_PAIR *Pair;
498 UINTN Index;
499
500 ASSERT (Context != NULL);
501 ASSERT (String != NULL);
502
503 if (StringLen == 0) {
504 return NULL;
505 }
506
507 ASSERT (String[0] != 0);
508
509 Char = BmfGetChar (Context, String[0]);
510 if (Char == NULL) {
511 DEBUG ((DEBUG_WARN, "BMF: Text Char not found\n"));
512 return NULL;
513 }
514
515 TextInfo = AllocatePool (
516 sizeof (*TextInfo)
517 + StringLen * sizeof (BMF_CHAR *)
518 + StringLen * sizeof (BMF_BLOCK_KERNING_PAIRS *)
519 );
520 if (TextInfo == NULL) {
521 DEBUG ((DEBUG_WARN, "BMF: Out of res\n"));
522 return NULL;
523 }
524
525 InfoPairs = (CONST BMF_KERNING_PAIR **)&TextInfo->Chars[StringLen];
526
527 TextInfo->Chars[0] = Char;
528 Width = (INT32)PosX + Char->xadvance;
529
530 for (Index = 1; Index < StringLen; ++Index) {
531 ASSERT (String[Index] != 0);
532
533 Char = BmfGetChar (Context, String[Index]);
534 if (Char == NULL) {
535 DEBUG ((DEBUG_WARN, "BMF: Text Char not found\n"));
536 FreePool (TextInfo);
537 return NULL;
538 }
539
540 CurWidth = Char->xadvance;
541
542 Pair = BmfGetKerningPair (Context, String[Index - 1], String[Index]);
543 if (Pair != NULL) {
544 CurWidth += Pair->amount;
545 }
546
547 Result = BaseOverflowAddS32 (Width, CurWidth, &Width);
548 if (Result) {
549 DEBUG ((DEBUG_WARN, "BMF: width overflows\n"));
550 FreePool (TextInfo);
551 return NULL;
552 }
553
554 TextInfo->Chars[Index] = Char;
555 InfoPairs[Index - 1] = Pair;
556 }
557
558 Width += ((INT32)TextInfo->Chars[Index - 1]->xoffset + (INT32)TextInfo->Chars[Index - 1]->width - (INT32)TextInfo->Chars[Index - 1]->xadvance);
559
560 InfoPairs[Index - 1] = NULL;
561
562 if (Width > MAX_UINT16) {
563 DEBUG ((DEBUG_WARN, "BMF: Width exceeds bounds\n"));
564 FreePool (TextInfo);
565 return NULL;
566 }
567
568 TextInfo->Width = (UINT16)Width;
569 ASSERT (PosY + Context->Height >= PosY);
570 TextInfo->Height = PosY + Context->Height;
571 TextInfo->OffsetY = PosY;
572 return TextInfo;
573}
574
575STATIC
576EFI_GRAPHICS_OUTPUT_BLT_PIXEL
577 mBlack = { 0, 0, 0, 255 };
578
579STATIC
580EFI_GRAPHICS_OUTPUT_BLT_PIXEL
581 mWhite = { 255, 255, 255, 255 };
582
583STATIC
584VOID
586 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Dst,
587 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *AlphaSrc,
588 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
589 UINTN PixelCount
590 )
591{
592 UINTN Index;
593
594 for (Index = 0; Index < PixelCount; ++Index) {
595 if (AlphaSrc->Red != 0) {
596 //
597 // We assume that the font is generated by dpFontBaker
598 // and has only gray channel, which should be interpreted as alpha.
599 //
600 GuiBlendPixel (Dst, Color, AlphaSrc->Red);
601 }
602
603 ++Dst;
604 ++AlphaSrc;
605 }
606}
607
608BOOLEAN
610 OUT GUI_IMAGE *LabelImage,
611 IN CONST GUI_FONT_CONTEXT *Context,
612 IN CONST CHAR16 *String,
613 IN UINTN StringLen,
614 IN BOOLEAN Inverted
615 )
616{
617 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
618 BMF_TEXT_INFO *TextInfo;
619 CONST BMF_KERNING_PAIR **InfoPairs;
620 UINTN Index;
621
622 UINT16 RowIndex;
623 UINT32 SourceRowOffset;
624 UINT32 TargetRowOffset;
625 INT32 TargetCharX;
626 INT32 InitialCharX;
627 INT32 InitialWidthOffset;
628 INT32 OffsetY;
629
630 ASSERT (LabelImage != NULL);
631 ASSERT (Context != NULL);
632 ASSERT (String != NULL);
633
634 TextInfo = BmfGetTextInfo (
635 &Context->BmfContext,
636 String,
637 StringLen,
638 BOOT_ENTRY_LABEL_TEXT_OFFSET * Context->Scale,
639 BOOT_ENTRY_LABEL_TEXT_OFFSET * Context->Scale
640 );
641 if (TextInfo == NULL) {
642 DEBUG ((DEBUG_WARN, "BMF: GetTextInfo failed\n"));
643 return FALSE;
644 }
645
646 Buffer = AllocateZeroPool ((UINT32)TextInfo->Width * (UINT32)TextInfo->Height * sizeof (*Buffer));
647 if (Buffer == NULL) {
648 DEBUG ((DEBUG_WARN, "BMF: out of res\n"));
649 FreePool (TextInfo);
650 return FALSE;
651 }
652
653 InfoPairs = (CONST BMF_KERNING_PAIR **)&TextInfo->Chars[StringLen];
654 TargetCharX = 2 * Context->Scale;
655
656 InitialCharX = -TextInfo->Chars[0]->xoffset;
657 InitialWidthOffset = TextInfo->Chars[0]->xoffset;
658
659 for (Index = 0; Index < StringLen; ++Index) {
660 OffsetY = TextInfo->Chars[Index]->yoffset + TextInfo->OffsetY;
661 if (OffsetY < 0) {
662 OffsetY = 0;
663 DEBUG ((
664 DEBUG_INFO,
665 "BMF: Char %d y-offset off-screen by %d pixels\n",
666 TextInfo->Chars[Index]->id,
667 -OffsetY
668 ));
669 }
670
671 ASSERT (TextInfo->Chars[Index]->yoffset + TextInfo->OffsetY >= 0);
672
673 for (
674 RowIndex = 0,
675 SourceRowOffset = TextInfo->Chars[Index]->y * Context->FontImage.Width,
676 TargetRowOffset = OffsetY * TextInfo->Width;
677 RowIndex < TextInfo->Chars[Index]->height;
678 ++RowIndex,
679 SourceRowOffset += Context->FontImage.Width,
680 TargetRowOffset += TextInfo->Width
681 )
682 {
683 if (Inverted) {
684 BlendMem (
685 &Buffer[TargetRowOffset + TargetCharX + TextInfo->Chars[Index]->xoffset + InitialCharX],
686 &Context->FontImage.Buffer[SourceRowOffset + TextInfo->Chars[Index]->x + InitialCharX],
687 &mBlack,
688 (TextInfo->Chars[Index]->width + InitialWidthOffset)
689 );
690 } else {
691 BlendMem (
692 &Buffer[TargetRowOffset + TargetCharX + TextInfo->Chars[Index]->xoffset + InitialCharX],
693 &Context->FontImage.Buffer[SourceRowOffset + TextInfo->Chars[Index]->x + InitialCharX],
694 &mWhite,
695 (TextInfo->Chars[Index]->width + InitialWidthOffset)
696 );
697 }
698 }
699
700 TargetCharX += TextInfo->Chars[Index]->xadvance;
701
702 if (InfoPairs[Index] != NULL) {
703 TargetCharX += InfoPairs[Index]->amount;
704 }
705
706 InitialCharX = 0;
707 InitialWidthOffset = 0;
708 }
709
710 LabelImage->Width = TextInfo->Width;
711 LabelImage->Height = TextInfo->Height;
712 LabelImage->Buffer = Buffer;
713 FreePool (TextInfo);
714 return TRUE;
715}
716
717BOOLEAN
719 OUT GUI_FONT_CONTEXT *Context,
720 IN VOID *FontImage,
721 IN UINTN FontImageSize,
722 IN VOID *FileBuffer,
723 IN UINT32 FileSize,
724 IN UINT8 Scale
725 )
726{
727 EFI_STATUS Status;
728 BOOLEAN Result;
729
730 ASSERT (Context != NULL);
731 ASSERT (FontImage != NULL);
732 ASSERT (FontImageSize > 0);
733 ASSERT (FileBuffer != NULL);
734 ASSERT (FileSize > 0);
735
736 ZeroMem (Context, sizeof (*Context));
737
738 Context->KerningData = FileBuffer;
739 Status = GuiPngToImage (
740 &Context->FontImage,
741 FontImage,
742 FontImageSize,
743 FALSE
744 );
745 FreePool (FontImage);
746
747 if (EFI_ERROR (Status)) {
748 GuiFontDestruct (Context);
749 return FALSE;
750 }
751
752 Result = BmfContextInitialize (&Context->BmfContext, FileBuffer, FileSize);
753 if (!Result) {
754 GuiFontDestruct (Context);
755 return FALSE;
756 }
757
758 Context->Scale = Scale;
759
760 // TODO: check file size
761 return TRUE;
762}
763
764VOID
766 IN GUI_FONT_CONTEXT *Context
767 )
768{
769 ASSERT (Context != NULL);
770 if (Context->FontImage.Buffer != NULL) {
771 FreePool (Context->FontImage.Buffer);
772 Context->FontImage.Buffer = NULL;
773 }
774
775 if (Context->KerningData != NULL) {
776 FreePool (Context->KerningData);
777 Context->KerningData = NULL;
778 }
779}
VENDOR_DEVICE_PATH Header
VOID GuiFontDestruct(IN GUI_FONT_CONTEXT *Context)
Definition BitmapFont.c:765
BMF_TEXT_INFO * BmfGetTextInfo(IN CONST BMF_CONTEXT *Context, IN CONST CHAR16 *String, IN UINTN StringLen, IN UINT8 PosX, IN UINT8 PosY)
Definition BitmapFont.c:480
BOOLEAN GuiFontConstruct(OUT GUI_FONT_CONTEXT *Context, IN VOID *FontImage, IN UINTN FontImageSize, IN VOID *FileBuffer, IN UINT32 FileSize, IN UINT8 Scale)
Definition BitmapFont.c:718
BOOLEAN GuiGetLabel(OUT GUI_IMAGE *LabelImage, IN CONST GUI_FONT_CONTEXT *Context, IN CONST CHAR16 *String, IN UINTN StringLen, IN BOOLEAN Inverted)
Definition BitmapFont.c:609
CONST BMF_CHAR * BmfGetChar(IN CONST BMF_CONTEXT *Context, IN UINT32 Char)
Definition BitmapFont.c:20
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mWhite
Definition BitmapFont.c:581
STATIC VOID BlendMem(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Dst, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *AlphaSrc, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, UINTN PixelCount)
Definition BitmapFont.c:585
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mBlack
Definition BitmapFont.c:577
BOOLEAN BmfContextInitialize(OUT BMF_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize)
Definition BitmapFont.c:147
CONST BMF_KERNING_PAIR * BmfGetKerningPair(IN CONST BMF_CONTEXT *Context, IN CHAR16 Char1, IN CHAR16 Char2)
Definition BitmapFont.c:71
VOID GuiBlendPixel(IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackPixel, IN CONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FrontPixel, IN UINT8 Opacity)
Definition Blending.c:126
#define BMF_BLOCK_INFO_ID
Definition BmfFile.h:23
UINT16 width
Definition BmfFile.h:85
UINT16 y
Definition BmfFile.h:84
#define BMF_BLOCK_PAGES_ID
Definition BmfFile.h:74
UINT32 second
Definition BmfFile.h:108
UINT16 x
Definition BmfFile.h:83
BMF_CHAR BMF_BLOCK_CHARS
Definition BmfFile.h:104
INT16 yoffset
Definition BmfFile.h:88
#define BMF_BLOCK_CHARS_ID
Definition BmfFile.h:99
INT16 xadvance
Definition BmfFile.h:89
#define BMF_BLOCK_COMMON_ID
Definition BmfFile.h:51
UINT8 page
Definition BmfFile.h:90
PACKED struct @103 BMF_BLOCK_INFO
#define BMF_BLOCK_KERNING_PAIRS_ID
Definition BmfFile.h:117
PACKED struct @107 BMF_HEADER
PACKED struct @106 BMF_KERNING_PAIR
BMF_KERNING_PAIR BMF_BLOCK_KERNING_PAIRS
Definition BmfFile.h:122
PACKED struct @105 BMF_CHAR
UINT32 first
Definition BmfFile.h:107
CHAR8 BMF_BLOCK_PAGES
Definition BmfFile.h:79
PACKED struct @104 BMF_BLOCK_COMMON
INT16 xoffset
Definition BmfFile.h:87
UINT8 chnl
Definition BmfFile.h:91
UINT16 height
Definition BmfFile.h:86
INT16 amount
Definition BmfFile.h:109
UINT32 size
#define BOOT_ENTRY_LABEL_TEXT_OFFSET
Definition GuiApp.h:26
EFI_STATUS GuiPngToImage(OUT GUI_IMAGE *Image, IN VOID *ImageData, IN UINTN ImageDataSize, IN BOOLEAN PremultiplyAlpha)
Definition Images.c:238
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55
#define MAX(a, b)
Definition coder.h:59
#define MIN(a, b)
Definition deflate.c:1673
CONST BMF_CHAR * Chars[]
Definition BitmapFont.c:475