10#include <Library/BaseMemoryLib.h>
11#include <Library/BaseOverflowLib.h>
12#include <Library/DebugLib.h>
13#include <Library/MemoryAllocationLib.h>
33 Chars = Context->Chars;
35 for (Index = 0; Index < 2; ++Index) {
43 Right =
MIN (Context->NumChars, Char) - 1;
44 while (Left <= Right) {
48 Median = (Left + Right) / 2;
49 if (Chars[Median].
id == Char) {
50 return &Chars[Median];
51 }
else if (Chars[Median].
id < Char) {
87 Pairs = Context->KerningPairs;
97 Right = Context->NumKerningPairs - 1;
98 while (Left <= Right) {
102 Median = (Left + Right) / 2;
103 if (Pairs[Median].
first == Char1) {
108 if (Pairs[Median].
second == Char2) {
109 return &Pairs[Median];
110 }
else if (Pairs[Median].
second < Char2) {
113 Index < Context->NumKerningPairs && Pairs[Index].first == Char1;
117 if (Pairs[Index].
second == Char2) {
118 return &Pairs[Index];
125 if (Pairs[Index].
first != Char1) {
129 if (Pairs[Index].
second == Char2) {
130 return &Pairs[Index];
136 }
else if (Pairs[Median].
first < Char1) {
149 IN CONST VOID *FileBuffer,
169 ASSERT (FileBuffer != NULL);
177 if ((FileSize <
sizeof (*
Header)) || (FileSize > BASE_2MB)) {
178 DEBUG ((DEBUG_WARN,
"BMF: FileSize insane\n"));
182 if ( (
Header->signature[0] !=
'B')
183 || (
Header->signature[1] !=
'M')
184 || (
Header->signature[2] !=
'F')
185 || (
Header->version != 3))
187 DEBUG ((DEBUG_WARN,
"BMF: Header insane\n"));
191 ZeroMem (Context,
sizeof (*Context));
193 FileSize -=
sizeof (*Header);
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));
203 FileSize -= Block->size;
205 switch (Block->identifier) {
209 DEBUG ((DEBUG_WARN,
"BMF: BlockInfo insane\n"));
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,
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
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
252 DEBUG ((DEBUG_WARN,
"BMF: Block Common insane\n"));
257 if (Context->Common->pages != 1) {
258 DEBUG ((DEBUG_WARN,
"BMF: Only one page is supported\n"));
273 if (Block->size % sizeof (
BMF_CHAR) != 0) {
274 DEBUG ((DEBUG_WARN,
"BMF: Block chars size unaligned\n"));
279 Context->NumChars = Block->size /
sizeof (
BMF_CHAR);
286 DEBUG ((DEBUG_WARN,
"BMF: Block Pairs unaligned\n"));
308 if (Context->Info == NULL) {
309 DEBUG ((DEBUG_WARN,
"BMF: Missing Info block\n"));
313 if (Context->Common == NULL) {
314 DEBUG ((DEBUG_WARN,
"BMF: Missing Common block\n"));
318 if (Context->Pages == NULL) {
319 DEBUG ((DEBUG_WARN,
"BMF: Missing Pages block\n"));
323 if (Context->Chars == NULL) {
324 DEBUG ((DEBUG_WARN,
"BMF: Missing Chars block\n"));
328 Chars = Context->Chars;
331 for (Index = 0; Index < Context->NumChars; ++Index) {
332 Result = BaseOverflowAddS32 (
337 Result |= BaseOverflowAddS32 (
342 Result |= BaseOverflowAddS32 (
348 || (0 > Height) || (Height > MAX_UINT16)
349 || (0 > Width) || (Width > MAX_UINT16)
350 || (0 > Advance) || (Advance > MAX_UINT16)
380 MaxHeight =
MAX (MaxHeight, (UINT16)Height);
387 if (Chars[Index - 1].
id > Chars[Index].
id) {
388 DEBUG ((DEBUG_WARN,
"BMF: Character IDs are not sorted\n"));
390 }
else if (Chars[Index - 1].
id == Chars[Index].
id) {
391 DEBUG ((DEBUG_WARN,
"BMF: Character ID duplicate\n"));
399 Context->Height = (UINT16)MaxHeight;
401 Pairs = Context->KerningPairs;
404 for (Index = 0; Index < Context->NumKerningPairs; ++Index) {
409 "BMF: Pair char %u not found\n",
415 Result = BaseOverflowAddS32 (
416 Char->xoffset + Char->width,
420 Result |= BaseOverflowAddS32 (
421 Char->xoffset + Char->xadvance,
426 || (0 > Width) || (Width > MAX_UINT16)
427 || (0 > Advance) || (Advance > MAX_UINT16))
431 "BMF: Pair at index %d insane: first %u, second %u, amount %d\n",
446 if (Pairs[Index - 1].
first > Pairs[Index].
first) {
447 DEBUG ((DEBUG_WARN,
"BMF: First Character IDs are not sorted\n"));
451 if (Pairs[Index - 1].
first == Pairs[Index].
first) {
453 DEBUG ((DEBUG_WARN,
"BMF: Second Character IDs are not sorted\n"));
458 DEBUG ((DEBUG_WARN,
"BMF: Second Character ID duplicate\n"));
482 IN CONST CHAR16 *String,
503 if (StringLen == 0) {
511 DEBUG ((DEBUG_WARN,
"BMF: Text Char not found\n"));
515 TextInfo = AllocatePool (
520 if (TextInfo == NULL) {
521 DEBUG ((DEBUG_WARN,
"BMF: Out of res\n"));
527 TextInfo->
Chars[0] = Char;
528 Width = (INT32)PosX + Char->xadvance;
530 for (Index = 1; Index < StringLen; ++Index) {
531 ASSERT (String[Index] != 0);
535 DEBUG ((DEBUG_WARN,
"BMF: Text Char not found\n"));
540 CurWidth = Char->xadvance;
544 CurWidth += Pair->amount;
547 Result = BaseOverflowAddS32 (Width, CurWidth, &Width);
549 DEBUG ((DEBUG_WARN,
"BMF: width overflows\n"));
554 TextInfo->
Chars[Index] = Char;
555 InfoPairs[Index - 1] = Pair;
558 Width += ((INT32)TextInfo->
Chars[Index - 1]->xoffset + (INT32)TextInfo->
Chars[Index - 1]->width - (INT32)TextInfo->
Chars[Index - 1]->xadvance);
560 InfoPairs[Index - 1] = NULL;
562 if (Width > MAX_UINT16) {
563 DEBUG ((DEBUG_WARN,
"BMF: Width exceeds bounds\n"));
568 TextInfo->
Width = (UINT16)Width;
569 ASSERT (PosY + Context->Height >= PosY);
570 TextInfo->
Height = PosY + Context->Height;
576EFI_GRAPHICS_OUTPUT_BLT_PIXEL
580EFI_GRAPHICS_OUTPUT_BLT_PIXEL
586 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Dst,
587 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *AlphaSrc,
588 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
594 for (Index = 0; Index < PixelCount; ++Index) {
595 if (AlphaSrc->Red != 0) {
612 IN CONST CHAR16 *String,
617 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *
Buffer;
623 UINT32 SourceRowOffset;
624 UINT32 TargetRowOffset;
627 INT32 InitialWidthOffset;
630 ASSERT (LabelImage != NULL);
635 &Context->BmfContext,
641 if (TextInfo == NULL) {
642 DEBUG ((DEBUG_WARN,
"BMF: GetTextInfo failed\n"));
648 DEBUG ((DEBUG_WARN,
"BMF: out of res\n"));
654 TargetCharX = 2 * Context->Scale;
656 InitialCharX = -TextInfo->
Chars[0]->xoffset;
657 InitialWidthOffset = TextInfo->
Chars[0]->xoffset;
659 for (Index = 0; Index < StringLen; ++Index) {
660 OffsetY = TextInfo->
Chars[Index]->yoffset + TextInfo->
OffsetY;
665 "BMF: Char %d y-offset off-screen by %d pixels\n",
666 TextInfo->
Chars[Index]->id,
675 SourceRowOffset = TextInfo->
Chars[Index]->y * Context->FontImage.Width,
676 TargetRowOffset = OffsetY * TextInfo->
Width;
677 RowIndex < TextInfo->Chars[Index]->height;
679 SourceRowOffset += Context->FontImage.Width,
680 TargetRowOffset += TextInfo->
Width
685 &
Buffer[TargetRowOffset + TargetCharX + TextInfo->
Chars[Index]->xoffset + InitialCharX],
686 &Context->FontImage.Buffer[SourceRowOffset + TextInfo->
Chars[Index]->x + InitialCharX],
688 (TextInfo->
Chars[Index]->width + InitialWidthOffset)
692 &
Buffer[TargetRowOffset + TargetCharX + TextInfo->
Chars[Index]->xoffset + InitialCharX],
693 &Context->FontImage.Buffer[SourceRowOffset + TextInfo->
Chars[Index]->x + InitialCharX],
695 (TextInfo->
Chars[Index]->width + InitialWidthOffset)
700 TargetCharX += TextInfo->
Chars[Index]->xadvance;
702 if (InfoPairs[Index] != NULL) {
703 TargetCharX += InfoPairs[Index]->amount;
707 InitialWidthOffset = 0;
710 LabelImage->Width = TextInfo->
Width;
711 LabelImage->Height = TextInfo->
Height;
712 LabelImage->Buffer =
Buffer;
721 IN UINTN FontImageSize,
731 ASSERT (FontImage != NULL);
732 ASSERT (FontImageSize > 0);
733 ASSERT (FileBuffer != NULL);
736 ZeroMem (Context,
sizeof (*Context));
738 Context->KerningData = FileBuffer;
745 FreePool (FontImage);
747 if (EFI_ERROR (Status)) {
758 Context->Scale = Scale;
770 if (Context->FontImage.Buffer != NULL) {
771 FreePool (Context->FontImage.Buffer);
772 Context->FontImage.Buffer = NULL;
775 if (Context->KerningData != NULL) {
776 FreePool (Context->KerningData);
777 Context->KerningData = NULL;
VENDOR_DEVICE_PATH Header
VOID GuiFontDestruct(IN GUI_FONT_CONTEXT *Context)
BMF_TEXT_INFO * BmfGetTextInfo(IN CONST BMF_CONTEXT *Context, IN CONST CHAR16 *String, IN UINTN StringLen, IN UINT8 PosX, IN UINT8 PosY)
BOOLEAN GuiFontConstruct(OUT GUI_FONT_CONTEXT *Context, IN VOID *FontImage, IN UINTN FontImageSize, IN VOID *FileBuffer, IN UINT32 FileSize, IN UINT8 Scale)
BOOLEAN GuiGetLabel(OUT GUI_IMAGE *LabelImage, IN CONST GUI_FONT_CONTEXT *Context, IN CONST CHAR16 *String, IN UINTN StringLen, IN BOOLEAN Inverted)
CONST BMF_CHAR * BmfGetChar(IN CONST BMF_CONTEXT *Context, IN UINT32 Char)
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mWhite
STATIC VOID BlendMem(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Dst, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *AlphaSrc, EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, UINTN PixelCount)
STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mBlack
BOOLEAN BmfContextInitialize(OUT BMF_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize)
CONST BMF_KERNING_PAIR * BmfGetKerningPair(IN CONST BMF_CONTEXT *Context, IN CHAR16 Char1, IN CHAR16 Char2)
VOID GuiBlendPixel(IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackPixel, IN CONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL *FrontPixel, IN UINT8 Opacity)
#define BMF_BLOCK_INFO_ID
#define BMF_BLOCK_PAGES_ID
#define BMF_BLOCK_CHARS_ID
#define BMF_BLOCK_COMMON_ID
PACKED struct @103 BMF_BLOCK_INFO
#define BMF_BLOCK_KERNING_PAIRS_ID
PACKED struct @107 BMF_HEADER
PACKED struct @106 BMF_KERNING_PAIR
BMF_KERNING_PAIR BMF_BLOCK_KERNING_PAIRS
PACKED struct @105 BMF_CHAR
PACKED struct @104 BMF_BLOCK_COMMON
#define BOOT_ENTRY_LABEL_TEXT_OFFSET
EFI_STATUS GuiPngToImage(OUT GUI_IMAGE *Image, IN VOID *ImageData, IN UINTN ImageDataSize, IN BOOLEAN PremultiplyAlpha)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)