OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Font.c
Go to the documentation of this file.
1
10#include "HiiDatabase.h"
11
12EFI_GRAPHICS_OUTPUT_BLT_PIXEL mHiiEfiColors[16] = {
13 //
14 // B G R
15 //
16 { 0x00, 0x00, 0x00, 0x00 }, // BLACK
17 { 0x98, 0x00, 0x00, 0x00 }, // BLUE
18 { 0x00, 0x98, 0x00, 0x00 }, // GREEN
19 { 0x98, 0x98, 0x00, 0x00 }, // CYAN
20 { 0x00, 0x00, 0x98, 0x00 }, // RED
21 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
22 { 0x00, 0x98, 0x98, 0x00 }, // BROWN
23 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
24 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
25 { 0xff, 0x00, 0x00, 0x00 }, // LIGHTBLUE
26 { 0x00, 0xff, 0x00, 0x00 }, // LIGHTGREEN
27 { 0xff, 0xff, 0x00, 0x00 }, // LIGHTCYAN
28 { 0x00, 0x00, 0xff, 0x00 }, // LIGHTRED
29 { 0xff, 0x00, 0xff, 0x00 }, // LIGHTMAGENTA
30 { 0x00, 0xff, 0xff, 0x00 }, // YELLOW
31 { 0xff, 0xff, 0xff, 0x00 }, // WHITE
32};
33
49EFI_STATUS
51 IN CHAR16 CharValue,
52 IN LIST_ENTRY *GlyphInfoList,
53 IN EFI_HII_GLYPH_INFO *Cell
54 )
55{
56 HII_GLYPH_INFO *GlyphInfo;
57
58 ASSERT (Cell != NULL && GlyphInfoList != NULL);
59
60 GlyphInfo = (HII_GLYPH_INFO *)AllocateZeroPool (sizeof (HII_GLYPH_INFO));
61 if (GlyphInfo == NULL) {
62 return EFI_OUT_OF_RESOURCES;
63 }
64
65 //
66 // GlyphInfoList stores a list of default character cell information, each is
67 // identified by "CharId".
68 //
70 GlyphInfo->CharId = CharValue;
71 if (Cell->AdvanceX == 0) {
72 Cell->AdvanceX = Cell->Width;
73 }
74
75 CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));
76 InsertTailList (GlyphInfoList, &GlyphInfo->Entry);
77
78 return EFI_SUCCESS;
79}
80
97EFI_STATUS
99 IN CHAR16 CharValue,
100 IN LIST_ENTRY *GlyphInfoList,
101 OUT EFI_HII_GLYPH_INFO *Cell
102 )
103{
104 HII_GLYPH_INFO *GlyphInfo;
105 LIST_ENTRY *Link;
106
107 ASSERT (Cell != NULL && GlyphInfoList != NULL);
108
109 //
110 // Since the EFI_HII_GIBT_DEFAULTS block won't increment CharValueCurrent,
111 // the value of "CharId" of a default character cell which is used for a
112 // EFI_HII_GIBT_GLYPH_DEFAULT or EFI_HII_GIBT_GLYPHS_DEFAULT should be
113 // less or equal to the value of "CharValueCurrent" of this default block.
114 //
115 // For instance, if the CharId of a GlyphInfoList is {1, 3, 7}, a default glyph
116 // with CharValue equals "7" uses the GlyphInfo with CharId = 7;
117 // a default glyph with CharValue equals "6" uses the GlyphInfo with CharId = 3.
118 //
119 for (Link = GlyphInfoList->BackLink; Link != GlyphInfoList; Link = Link->BackLink) {
120 GlyphInfo = CR (Link, HII_GLYPH_INFO, Entry, HII_GLYPH_INFO_SIGNATURE);
121 if (GlyphInfo->CharId <= CharValue) {
122 CopyMem (Cell, &GlyphInfo->Cell, sizeof (EFI_HII_GLYPH_INFO));
123 return EFI_SUCCESS;
124 }
125 }
126
127 return EFI_NOT_FOUND;
128}
129
150EFI_STATUS
152 IN HII_DATABASE_PRIVATE_DATA *Private,
153 IN CHAR16 Char,
154 IN EFI_FONT_INFO *StringInfo,
155 OUT UINT8 **GlyphBuffer,
156 OUT EFI_HII_GLYPH_INFO *Cell,
157 OUT UINT8 *Attributes OPTIONAL
158 )
159{
161 LIST_ENTRY *Link;
163 LIST_ENTRY *Link1;
164 UINT16 Index;
165 EFI_NARROW_GLYPH Narrow;
166 EFI_WIDE_GLYPH Wide;
167 HII_GLOBAL_FONT_INFO *GlobalFont;
168 UINTN HeaderSize;
169 EFI_NARROW_GLYPH *NarrowPtr;
170 EFI_WIDE_GLYPH *WidePtr;
171
172 if ((GlyphBuffer == NULL) || (Cell == NULL)) {
173 return EFI_INVALID_PARAMETER;
174 }
175
176 if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
177 return EFI_INVALID_PARAMETER;
178 }
179
180 ZeroMem (Cell, sizeof (EFI_HII_GLYPH_INFO));
181
182 //
183 // If StringInfo is not NULL, it must point to an existing EFI_FONT_INFO rather
184 // than system default font and color.
185 // If NULL, try to find the character in simplified font packages since
186 // default system font is the fixed font (narrow or wide glyph).
187 //
188 if (StringInfo != NULL) {
189 if (!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {
190 return EFI_INVALID_PARAMETER;
191 }
192
193 if (Attributes != NULL) {
194 *Attributes = PROPORTIONAL_GLYPH;
195 }
196
197 return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);
198 } else {
199 HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);
200
201 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
202 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
203 for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;
204 Link1 != &Node->PackageList->SimpleFontPkgHdr;
205 Link1 = Link1->ForwardLink
206 )
207 {
208 SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
209 //
210 // Search the narrow glyph array
211 //
212 NarrowPtr = (EFI_NARROW_GLYPH *)((UINT8 *)(SimpleFont->SimpleFontPkgHdr) + HeaderSize);
213 for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {
214 CopyMem (&Narrow, NarrowPtr + Index, sizeof (EFI_NARROW_GLYPH));
215 if (Narrow.UnicodeWeight == Char) {
216 *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT);
217 if (*GlyphBuffer == NULL) {
218 return EFI_OUT_OF_RESOURCES;
219 }
220
221 Cell->Width = EFI_GLYPH_WIDTH;
222 Cell->Height = EFI_GLYPH_HEIGHT;
223 Cell->AdvanceX = Cell->Width;
224 CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);
225 if (Attributes != NULL) {
226 *Attributes = (UINT8)(Narrow.Attributes | NARROW_GLYPH);
227 }
228
229 return EFI_SUCCESS;
230 }
231 }
232
233 //
234 // Search the wide glyph array
235 //
236 WidePtr = (EFI_WIDE_GLYPH *)(NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);
237 for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {
238 CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));
239 if (Wide.UnicodeWeight == Char) {
240 *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);
241 if (*GlyphBuffer == NULL) {
242 return EFI_OUT_OF_RESOURCES;
243 }
244
245 Cell->Width = EFI_GLYPH_WIDTH * 2;
246 Cell->Height = EFI_GLYPH_HEIGHT;
247 Cell->AdvanceX = Cell->Width;
248 CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);
249 CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);
250 if (Attributes != NULL) {
251 *Attributes = (UINT8)(Wide.Attributes | EFI_GLYPH_WIDE);
252 }
253
254 return EFI_SUCCESS;
255 }
256 }
257 }
258 }
259 }
260
261 return EFI_NOT_FOUND;
262}
263
285VOID
287 IN UINT8 *GlyphBuffer,
288 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
289 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
290 IN UINT16 ImageWidth,
291 IN UINTN RowWidth,
292 IN UINTN RowHeight,
293 IN BOOLEAN Transparent,
294 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
295 )
296{
297 UINT8 Xpos;
298 UINT8 Ypos;
299 UINT8 Height;
300 UINT8 Width;
301 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
302
303 ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);
304
305 Height = EFI_GLYPH_HEIGHT;
306 Width = EFI_GLYPH_WIDTH;
307
308 //
309 // Move position to the left-top corner of char.
310 //
311 Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;
312
313 //
314 // Char may be partially displayed when CLIP_X or CLIP_Y is not set.
315 //
316 if (RowHeight < Height) {
317 Height = (UINT8)RowHeight;
318 }
319
320 if (RowWidth < Width) {
321 Width = (UINT8)RowWidth;
322 }
323
324 for (Ypos = 0; Ypos < Height; Ypos++) {
325 for (Xpos = 0; Xpos < Width; Xpos++) {
326 if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {
327 Buffer[Ypos * ImageWidth + Xpos] = Foreground;
328 } else {
329 if (!Transparent) {
330 Buffer[Ypos * ImageWidth + Xpos] = Background;
331 }
332 }
333 }
334 }
335
336 *Origin = *Origin + EFI_GLYPH_WIDTH;
337}
338
364VOID
366 IN UINT8 *GlyphBuffer,
367 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
368 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
369 IN UINT16 ImageWidth,
370 IN UINT16 BaseLine,
371 IN UINTN RowWidth,
372 IN UINTN RowHeight,
373 IN BOOLEAN Transparent,
374 IN CONST EFI_HII_GLYPH_INFO *Cell,
375 IN UINT8 Attributes,
376 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
377 )
378{
379 UINT16 Xpos;
380 UINT16 Ypos;
381 UINT8 Data;
382 UINT16 Index;
383 UINT16 YposOffset;
384 UINTN OffsetY;
385 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
386
387 ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
388
389 //
390 // Only adjust origin position if char has no bitmap.
391 //
392 if (GlyphBuffer == NULL) {
393 *Origin = *Origin + Cell->AdvanceX;
394 return;
395 }
396
397 //
398 // Move position to the left-top corner of char.
399 //
400 BltBuffer = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;
401 YposOffset = (UINT16)(BaseLine - (Cell->OffsetY + Cell->Height));
402
403 //
404 // Since non-spacing key will be printed OR'd with the previous glyph, don't
405 // write 0.
406 //
407 if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
408 Transparent = TRUE;
409 }
410
411 //
412 // The glyph's upper left hand corner pixel is the most significant bit of the
413 // first bitmap byte.
414 //
415 for (Ypos = 0; Ypos < Cell->Height && (((UINT32)Ypos + YposOffset) < RowHeight); Ypos++) {
416 OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);
417
418 //
419 // All bits in these bytes are meaningful.
420 //
421 for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {
422 Data = *(GlyphBuffer + OffsetY + Xpos);
423 for (Index = 0; Index < 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
424 if ((Data & (1 << (8 - Index - 1))) != 0) {
425 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
426 } else {
427 if (!Transparent) {
428 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
429 }
430 }
431 }
432 }
433
434 if (Cell->Width % 8 != 0) {
435 //
436 // There are some padding bits in this byte. Ignore them.
437 //
438 Data = *(GlyphBuffer + OffsetY + Xpos);
439 for (Index = 0; Index < Cell->Width % 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
440 if ((Data & (1 << (8 - Index - 1))) != 0) {
441 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
442 } else {
443 if (!Transparent) {
444 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
445 }
446 }
447 }
448 } // end of if (Width % 8...)
449 } // end of for (Ypos=0...)
450
451 *Origin = *Origin + Cell->AdvanceX;
452}
453
480VOID
482 IN UINT8 *GlyphBuffer,
483 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
484 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
485 IN UINT16 ImageWidth,
486 IN UINT16 BaseLine,
487 IN UINTN RowWidth,
488 IN UINTN RowHeight,
489 IN BOOLEAN Transparent,
490 IN CONST EFI_HII_GLYPH_INFO *Cell,
491 IN UINT8 Attributes,
492 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
493 )
494{
495 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
496
497 ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
498
499 Buffer = *Origin;
500
501 if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
502 //
503 // This character is a non-spacing key, print it OR'd with the previous glyph.
504 // without advancing cursor.
505 //
506 Buffer -= Cell->AdvanceX;
507 GlyphToBlt (
508 GlyphBuffer,
509 Foreground,
510 Background,
511 ImageWidth,
512 BaseLine,
513 RowWidth,
514 RowHeight,
515 Transparent,
516 Cell,
517 Attributes,
518 &Buffer
519 );
520 } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {
521 //
522 // This character is wide glyph, i.e. 16 pixels * 19 pixels.
523 // Draw it as two narrow glyphs.
524 //
526 GlyphBuffer,
527 Foreground,
528 Background,
529 ImageWidth,
530 RowWidth,
531 RowHeight,
532 Transparent,
533 Origin
534 );
535
537 GlyphBuffer + EFI_GLYPH_HEIGHT,
538 Foreground,
539 Background,
540 ImageWidth,
541 RowWidth,
542 RowHeight,
543 Transparent,
544 Origin
545 );
546 } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {
547 //
548 // This character is narrow glyph, i.e. 8 pixels * 19 pixels.
549 //
551 GlyphBuffer,
552 Foreground,
553 Background,
554 ImageWidth,
555 RowWidth,
556 RowHeight,
557 Transparent,
558 Origin
559 );
560 } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {
561 //
562 // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.
563 //
564 GlyphToBlt (
565 GlyphBuffer,
566 Foreground,
567 Background,
568 ImageWidth,
569 BaseLine,
570 RowWidth,
571 RowHeight,
572 Transparent,
573 Cell,
574 Attributes,
575 Origin
576 );
577 }
578}
579
602EFI_STATUS
604 IN UINT8 *BufferIn,
605 IN UINTN BufferLen,
606 IN EFI_HII_GLYPH_INFO *InputCell,
607 OUT UINT8 **GlyphBuffer, OPTIONAL
608 OUT EFI_HII_GLYPH_INFO *Cell, OPTIONAL
609 OUT UINTN *GlyphBufferLen OPTIONAL
610 )
611{
612 if ((BufferIn == NULL) || (InputCell == NULL)) {
613 return EFI_INVALID_PARAMETER;
614 }
615
616 if (Cell != NULL) {
617 CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));
618 }
619
620 if ((GlyphBuffer != NULL) && (BufferLen > 0)) {
621 *GlyphBuffer = (UINT8 *)AllocateZeroPool (BufferLen);
622 if (*GlyphBuffer == NULL) {
623 return EFI_OUT_OF_RESOURCES;
624 }
625
626 CopyMem (*GlyphBuffer, BufferIn, BufferLen);
627 }
628
629 if (GlyphBufferLen != NULL) {
630 *GlyphBufferLen = BufferLen;
631 }
632
633 return EFI_SUCCESS;
634}
635
657EFI_STATUS
659 IN HII_FONT_PACKAGE_INSTANCE *FontPackage,
660 IN CHAR16 CharValue,
661 OUT UINT8 **GlyphBuffer, OPTIONAL
662 OUT EFI_HII_GLYPH_INFO *Cell, OPTIONAL
663 OUT UINTN *GlyphBufferLen OPTIONAL
664 )
665{
666 EFI_STATUS Status;
667 UINT8 *BlockPtr;
668 UINT16 CharCurrent;
669 UINT16 Length16;
670 UINT32 Length32;
671 EFI_HII_GIBT_GLYPHS_BLOCK Glyphs;
672 UINTN BufferLen;
673 UINT16 Index;
674 EFI_HII_GLYPH_INFO DefaultCell;
675 EFI_HII_GLYPH_INFO LocalCell;
676 INT16 MinOffsetY;
677 UINT16 BaseLine;
678
679 ASSERT (FontPackage != NULL);
680 ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);
681 BaseLine = 0;
682 MinOffsetY = 0;
683
684 if (CharValue == (CHAR16)(-1)) {
685 //
686 // Collect the cell information specified in font package fixed header.
687 // Use CharValue =0 to represent this particular cell.
688 //
689 Status = NewCell (
690 0,
691 &FontPackage->GlyphInfoList,
692 (EFI_HII_GLYPH_INFO *)((UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32))
693 );
694 if (EFI_ERROR (Status)) {
695 return Status;
696 }
697
698 CopyMem (
699 &LocalCell,
700 (UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32),
701 sizeof (EFI_HII_GLYPH_INFO)
702 );
703 }
704
705 BlockPtr = FontPackage->GlyphBlock;
706 CharCurrent = 1;
707 BufferLen = 0;
708
709 while (*BlockPtr != EFI_HII_GIBT_END) {
710 switch (*BlockPtr) {
711 case EFI_HII_GIBT_DEFAULTS:
712 //
713 // Collect all default character cell information specified by
714 // EFI_HII_GIBT_DEFAULTS.
715 //
716 if (CharValue == (CHAR16)(-1)) {
717 Status = NewCell (
718 CharCurrent,
719 &FontPackage->GlyphInfoList,
720 (EFI_HII_GLYPH_INFO *)(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))
721 );
722 if (EFI_ERROR (Status)) {
723 return Status;
724 }
725
726 CopyMem (
727 &LocalCell,
728 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
729 sizeof (EFI_HII_GLYPH_INFO)
730 );
731 if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
732 BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
733 }
734
735 if (MinOffsetY > LocalCell.OffsetY) {
736 MinOffsetY = LocalCell.OffsetY;
737 }
738 }
739
740 BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);
741 break;
742
743 case EFI_HII_GIBT_DUPLICATE:
744 if (CharCurrent == CharValue) {
745 CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));
746 CharCurrent = 1;
747 BlockPtr = FontPackage->GlyphBlock;
748 continue;
749 }
750
751 CharCurrent++;
752 BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);
753 break;
754
755 case EFI_HII_GIBT_EXT1:
756 BlockPtr += *(UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));
757 break;
758 case EFI_HII_GIBT_EXT2:
759 CopyMem (
760 &Length16,
761 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
762 sizeof (UINT16)
763 );
764 BlockPtr += Length16;
765 break;
766 case EFI_HII_GIBT_EXT4:
767 CopyMem (
768 &Length32,
769 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
770 sizeof (UINT32)
771 );
772 BlockPtr += Length32;
773 break;
774
775 case EFI_HII_GIBT_GLYPH:
776 CopyMem (
777 &LocalCell,
778 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
779 sizeof (EFI_HII_GLYPH_INFO)
780 );
781 if (CharValue == (CHAR16)(-1)) {
782 if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
783 BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
784 }
785
786 if (MinOffsetY > LocalCell.OffsetY) {
787 MinOffsetY = LocalCell.OffsetY;
788 }
789 }
790
791 BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);
792 if (CharCurrent == CharValue) {
793 return WriteOutputParam (
794 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),
795 BufferLen,
796 &LocalCell,
797 GlyphBuffer,
798 Cell,
799 GlyphBufferLen
800 );
801 }
802
803 CharCurrent++;
804 BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;
805 break;
806
807 case EFI_HII_GIBT_GLYPHS:
808 BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);
809 CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));
810 BlockPtr += sizeof (EFI_HII_GLYPH_INFO);
811 CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));
812 BlockPtr += sizeof (UINT16);
813
814 if (CharValue == (CHAR16)(-1)) {
815 if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {
816 BaseLine = (UINT16)(Glyphs.Cell.Height + Glyphs.Cell.OffsetY);
817 }
818
819 if (MinOffsetY > Glyphs.Cell.OffsetY) {
820 MinOffsetY = Glyphs.Cell.OffsetY;
821 }
822 }
823
824 BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);
825 for (Index = 0; Index < Glyphs.Count; Index++) {
826 if (CharCurrent + Index == CharValue) {
827 return WriteOutputParam (
828 BlockPtr,
829 BufferLen,
830 &Glyphs.Cell,
831 GlyphBuffer,
832 Cell,
833 GlyphBufferLen
834 );
835 }
836
837 BlockPtr += BufferLen;
838 }
839
840 CharCurrent = (UINT16)(CharCurrent + Glyphs.Count);
841 break;
842
843 case EFI_HII_GIBT_GLYPH_DEFAULT:
844 Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
845 if (EFI_ERROR (Status)) {
846 return Status;
847 }
848
849 if (CharValue == (CHAR16)(-1)) {
850 if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
851 BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
852 }
853
854 if (MinOffsetY > DefaultCell.OffsetY) {
855 MinOffsetY = DefaultCell.OffsetY;
856 }
857 }
858
859 BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
860
861 if (CharCurrent == CharValue) {
862 return WriteOutputParam (
863 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
864 BufferLen,
865 &DefaultCell,
866 GlyphBuffer,
867 Cell,
868 GlyphBufferLen
869 );
870 }
871
872 CharCurrent++;
873 BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;
874 break;
875
876 case EFI_HII_GIBT_GLYPHS_DEFAULT:
877 CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
878 Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
879 if (EFI_ERROR (Status)) {
880 return Status;
881 }
882
883 if (CharValue == (CHAR16)(-1)) {
884 if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
885 BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
886 }
887
888 if (MinOffsetY > DefaultCell.OffsetY) {
889 MinOffsetY = DefaultCell.OffsetY;
890 }
891 }
892
893 BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
894 BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);
895 for (Index = 0; Index < Length16; Index++) {
896 if (CharCurrent + Index == CharValue) {
897 return WriteOutputParam (
898 BlockPtr,
899 BufferLen,
900 &DefaultCell,
901 GlyphBuffer,
902 Cell,
903 GlyphBufferLen
904 );
905 }
906
907 BlockPtr += BufferLen;
908 }
909
910 CharCurrent = (UINT16)(CharCurrent + Length16);
911 break;
912
913 case EFI_HII_GIBT_SKIP1:
914 CharCurrent = (UINT16)(CharCurrent + (UINT16)(*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));
915 BlockPtr += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);
916 break;
917 case EFI_HII_GIBT_SKIP2:
918 CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
919 CharCurrent = (UINT16)(CharCurrent + Length16);
920 BlockPtr += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);
921 break;
922 default:
923 ASSERT (FALSE);
924 break;
925 }
926
927 if (CharValue < CharCurrent) {
928 return EFI_NOT_FOUND;
929 }
930 }
931
932 if (CharValue == (CHAR16)(-1)) {
933 FontPackage->BaseLine = BaseLine;
934 FontPackage->Height = (UINT16)(BaseLine - MinOffsetY);
935 return EFI_SUCCESS;
936 }
937
938 return EFI_NOT_FOUND;
939}
940
955EFI_STATUS
957 IN EFI_STRING FontName,
958 OUT EFI_FONT_INFO **FontInfo
959 )
960{
961 UINTN FontInfoLen;
962 UINTN NameSize;
963
964 ASSERT (FontName != NULL && FontInfo != NULL);
965
966 NameSize = StrSize (FontName);
967 FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;
968 *FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoLen);
969 if (*FontInfo == NULL) {
970 return EFI_OUT_OF_RESOURCES;
971 }
972
973 StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);
974 return EFI_SUCCESS;
975}
976
992EFI_STATUS
994 IN HII_DATABASE_PRIVATE_DATA *Private,
995 OUT EFI_FONT_DISPLAY_INFO **FontInfo,
996 OUT UINTN *FontInfoSize OPTIONAL
997 )
998{
999 EFI_FONT_DISPLAY_INFO *Info;
1000 UINTN InfoSize;
1001 UINTN NameSize;
1002
1003 if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
1004 return EFI_INVALID_PARAMETER;
1005 }
1006
1007 if (FontInfo == NULL) {
1008 return EFI_INVALID_PARAMETER;
1009 }
1010
1011 //
1012 // The standard font always has the name "sysdefault".
1013 //
1014 NameSize = L_STR_SIZE (L"sysdefault");
1015 InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
1016 Info = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (InfoSize);
1017 if (Info == NULL) {
1018 return EFI_OUT_OF_RESOURCES;
1019 }
1020
1021 Info->ForegroundColor = mHiiEfiColors[Private->Attribute & 0x0f];
1022 ASSERT ((Private->Attribute >> 4) < 8);
1023 Info->BackgroundColor = mHiiEfiColors[Private->Attribute >> 4];
1024 Info->FontInfoMask = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;
1025 Info->FontInfo.FontStyle = 0;
1026 Info->FontInfo.FontSize = EFI_GLYPH_HEIGHT;
1027 StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");
1028
1029 *FontInfo = Info;
1030 if (FontInfoSize != NULL) {
1031 *FontInfoSize = InfoSize;
1032 }
1033
1034 return EFI_SUCCESS;
1035}
1036
1055BOOLEAN
1057 IN HII_DATABASE_PRIVATE_DATA *Private,
1058 IN EFI_FONT_DISPLAY_INFO *StringInfo,
1059 OUT EFI_FONT_DISPLAY_INFO **SystemInfo, OPTIONAL
1060 OUT UINTN *SystemInfoLen OPTIONAL
1061 )
1062{
1063 EFI_STATUS Status;
1064 EFI_FONT_DISPLAY_INFO *SystemDefault;
1065 UINTN DefaultLen;
1066 BOOLEAN Flag;
1067
1068 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
1069
1070 if ((StringInfo == NULL) && (SystemInfo == NULL)) {
1071 return TRUE;
1072 }
1073
1074 SystemDefault = NULL;
1075 DefaultLen = 0;
1076
1077 Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);
1078 ASSERT_EFI_ERROR (Status);
1079 ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));
1080
1081 //
1082 // Record the system default info.
1083 //
1084 if (SystemInfo != NULL) {
1085 *SystemInfo = SystemDefault;
1086 }
1087
1088 if (SystemInfoLen != NULL) {
1089 *SystemInfoLen = DefaultLen;
1090 }
1091
1092 if (StringInfo == NULL) {
1093 return TRUE;
1094 }
1095
1096 Flag = FALSE;
1097 //
1098 // Check the FontInfoMask to see whether it is retrieving system info.
1099 //
1100 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {
1101 if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {
1102 goto Exit;
1103 }
1104 }
1105
1106 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {
1107 if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {
1108 goto Exit;
1109 }
1110 }
1111
1112 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {
1113 if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {
1114 goto Exit;
1115 }
1116 }
1117
1118 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {
1119 if (CompareMem (
1120 &StringInfo->ForegroundColor,
1121 &SystemDefault->ForegroundColor,
1122 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1123 ) != 0)
1124 {
1125 goto Exit;
1126 }
1127 }
1128
1129 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {
1130 if (CompareMem (
1131 &StringInfo->BackgroundColor,
1132 &SystemDefault->BackgroundColor,
1133 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1134 ) != 0)
1135 {
1136 goto Exit;
1137 }
1138 }
1139
1140 Flag = TRUE;
1141
1142Exit:
1143 if (SystemInfo == NULL) {
1144 if (SystemDefault != NULL) {
1145 FreePool (SystemDefault);
1146 }
1147 }
1148
1149 return Flag;
1150}
1151
1174BOOLEAN
1176 IN HII_DATABASE_PRIVATE_DATA *Private,
1177 IN EFI_FONT_INFO *FontInfo,
1178 IN EFI_FONT_INFO_MASK *FontInfoMask, OPTIONAL
1179 IN EFI_FONT_HANDLE FontHandle, OPTIONAL
1180 OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL
1181 )
1182{
1183 HII_GLOBAL_FONT_INFO *GlobalFont;
1184 HII_GLOBAL_FONT_INFO *GlobalFontBackup1;
1185 HII_GLOBAL_FONT_INFO *GlobalFontBackup2;
1186 LIST_ENTRY *Link;
1187 EFI_FONT_INFO_MASK Mask;
1188 BOOLEAN Matched;
1189 BOOLEAN VagueMatched1;
1190 BOOLEAN VagueMatched2;
1191
1192 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
1193 ASSERT (FontInfo != NULL);
1194
1195 //
1196 // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE
1197 // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.
1198 //
1199 Matched = FALSE;
1200 VagueMatched1 = FALSE;
1201 VagueMatched2 = FALSE;
1202
1203 Mask = 0;
1204 GlobalFontBackup1 = NULL;
1205 GlobalFontBackup2 = NULL;
1206
1207 // The process of where the system default should be supplied instead of
1208 // the specified font info beyonds this function's scope.
1209 //
1210 if (FontInfoMask != NULL) {
1211 Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);
1212 }
1213
1214 //
1215 // If not NULL, FontHandle points to the next node of the last searched font
1216 // node by previous call.
1217 //
1218 if (FontHandle == NULL) {
1219 Link = Private->FontInfoList.ForwardLink;
1220 } else {
1221 Link = (LIST_ENTRY *)FontHandle;
1222 }
1223
1224 for ( ; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
1225 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
1226 if (FontInfoMask == NULL) {
1227 if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {
1228 if (GlobalFontInfo != NULL) {
1229 *GlobalFontInfo = GlobalFont;
1230 }
1231
1232 return TRUE;
1233 }
1234 } else {
1235 //
1236 // Check which options could be used to make a match.
1237 //
1238 switch (Mask) {
1239 case EFI_FONT_INFO_ANY_FONT:
1240 if ((GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) &&
1241 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
1242 {
1243 Matched = TRUE;
1244 }
1245
1246 break;
1247 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:
1248 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1249 Matched = TRUE;
1250 }
1251
1252 break;
1253 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:
1254 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1255 Matched = TRUE;
1256 }
1257
1258 break;
1259 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:
1260 Matched = TRUE;
1261 break;
1262 //
1263 // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to
1264 // remove some of the specified styles to meet the style requested.
1265 //
1266 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:
1267 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1268 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1269 Matched = TRUE;
1270 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1271 VagueMatched1 = TRUE;
1272 GlobalFontBackup1 = GlobalFont;
1273 }
1274 }
1275
1276 break;
1277 //
1278 // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to
1279 // stretch or shrink a font to meet the size requested.
1280 //
1281 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:
1282 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1283 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1284 Matched = TRUE;
1285 } else {
1286 VagueMatched1 = TRUE;
1287 GlobalFontBackup1 = GlobalFont;
1288 }
1289 }
1290
1291 break;
1292 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:
1293 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1294 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1295 Matched = TRUE;
1296 } else {
1297 VagueMatched1 = TRUE;
1298 GlobalFontBackup1 = GlobalFont;
1299 }
1300 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1301 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1302 VagueMatched1 = TRUE;
1303 GlobalFontBackup1 = GlobalFont;
1304 } else {
1305 VagueMatched2 = TRUE;
1306 GlobalFontBackup2 = GlobalFont;
1307 }
1308 }
1309
1310 break;
1311 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
1312 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1313 Matched = TRUE;
1314 } else {
1315 VagueMatched1 = TRUE;
1316 GlobalFontBackup1 = GlobalFont;
1317 }
1318
1319 break;
1320 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
1321 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1322 Matched = TRUE;
1323 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1324 VagueMatched1 = TRUE;
1325 GlobalFontBackup1 = GlobalFont;
1326 }
1327
1328 break;
1329 case EFI_FONT_INFO_ANY_STYLE:
1330 if ((CompareMem (
1331 GlobalFont->FontInfo->FontName,
1332 FontInfo->FontName,
1333 StrSize (FontInfo->FontName)
1334 ) == 0) &&
1335 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
1336 {
1337 Matched = TRUE;
1338 }
1339
1340 break;
1341 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:
1342 if (CompareMem (
1343 GlobalFont->FontInfo->FontName,
1344 FontInfo->FontName,
1345 StrSize (FontInfo->FontName)
1346 ) == 0)
1347 {
1348 Matched = TRUE;
1349 }
1350
1351 break;
1352 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
1353 if (CompareMem (
1354 GlobalFont->FontInfo->FontName,
1355 FontInfo->FontName,
1356 StrSize (FontInfo->FontName)
1357 ) == 0)
1358 {
1359 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1360 Matched = TRUE;
1361 } else {
1362 VagueMatched1 = TRUE;
1363 GlobalFontBackup1 = GlobalFont;
1364 }
1365 }
1366
1367 break;
1368 case EFI_FONT_INFO_ANY_SIZE:
1369 if ((CompareMem (
1370 GlobalFont->FontInfo->FontName,
1371 FontInfo->FontName,
1372 StrSize (FontInfo->FontName)
1373 ) == 0) &&
1374 (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
1375 {
1376 Matched = TRUE;
1377 }
1378
1379 break;
1380 case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
1381 if (CompareMem (
1382 GlobalFont->FontInfo->FontName,
1383 FontInfo->FontName,
1384 StrSize (FontInfo->FontName)
1385 ) == 0)
1386 {
1387 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1388 Matched = TRUE;
1389 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1390 VagueMatched1 = TRUE;
1391 GlobalFontBackup1 = GlobalFont;
1392 }
1393 }
1394
1395 break;
1396 case EFI_FONT_INFO_RESTYLE:
1397 if ((CompareMem (
1398 GlobalFont->FontInfo->FontName,
1399 FontInfo->FontName,
1400 StrSize (FontInfo->FontName)
1401 ) == 0) &&
1402 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
1403 {
1404 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1405 Matched = TRUE;
1406 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1407 VagueMatched1 = TRUE;
1408 GlobalFontBackup1 = GlobalFont;
1409 }
1410 }
1411
1412 break;
1413 case EFI_FONT_INFO_RESIZE:
1414 if ((CompareMem (
1415 GlobalFont->FontInfo->FontName,
1416 FontInfo->FontName,
1417 StrSize (FontInfo->FontName)
1418 ) == 0) &&
1419 (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
1420 {
1421 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1422 Matched = TRUE;
1423 } else {
1424 VagueMatched1 = TRUE;
1425 GlobalFontBackup1 = GlobalFont;
1426 }
1427 }
1428
1429 break;
1430 case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:
1431 if (CompareMem (
1432 GlobalFont->FontInfo->FontName,
1433 FontInfo->FontName,
1434 StrSize (FontInfo->FontName)
1435 ) == 0)
1436 {
1437 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1438 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1439 Matched = TRUE;
1440 } else {
1441 VagueMatched1 = TRUE;
1442 GlobalFontBackup1 = GlobalFont;
1443 }
1444 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1445 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1446 VagueMatched1 = TRUE;
1447 GlobalFontBackup1 = GlobalFont;
1448 } else {
1449 VagueMatched2 = TRUE;
1450 GlobalFontBackup2 = GlobalFont;
1451 }
1452 }
1453 }
1454
1455 break;
1456 default:
1457 break;
1458 }
1459
1460 if (Matched) {
1461 if (GlobalFontInfo != NULL) {
1462 *GlobalFontInfo = GlobalFont;
1463 }
1464
1465 return TRUE;
1466 }
1467 }
1468 }
1469
1470 if (VagueMatched1) {
1471 if (GlobalFontInfo != NULL) {
1472 *GlobalFontInfo = GlobalFontBackup1;
1473 }
1474
1475 return TRUE;
1476 } else if (VagueMatched2) {
1477 if (GlobalFontInfo != NULL) {
1478 *GlobalFontInfo = GlobalFontBackup2;
1479 }
1480
1481 return TRUE;
1482 }
1483
1484 return FALSE;
1485}
1486
1501INT8
1503 IN CHAR16 Char
1504 )
1505{
1506 switch (Char) {
1507 //
1508 // Mandatory line break characters, which force a line-break
1509 //
1510 case 0x000A:
1511 case 0x000C:
1512 case 0x000D:
1513 case 0x2028:
1514 case 0x2029:
1515 return 0;
1516 //
1517 // Space characters, which is taken as a line-break opportunity
1518 //
1519 case 0x0020:
1520 case 0x1680:
1521 case 0x2000:
1522 case 0x2001:
1523 case 0x2002:
1524 case 0x2003:
1525 case 0x2004:
1526 case 0x2005:
1527 case 0x2006:
1528 case 0x2008:
1529 case 0x2009:
1530 case 0x200A:
1531 case 0x205F:
1532 //
1533 // In-Word Break Opportunities
1534 //
1535 case 0x200B:
1536 return 1;
1537 //
1538 // A space which is not a line-break opportunity
1539 //
1540 case 0x00A0:
1541 case 0x202F:
1542 //
1543 // A hyphen which is not a line-break opportunity
1544 //
1545 case 0x2011:
1546 return -1;
1547 //
1548 // Hyphen characters which describe line break opportunities after the character
1549 //
1550 case 0x058A:
1551 case 0x2010:
1552 case 0x2012:
1553 case 0x2013:
1554 case 0x0F0B:
1555 case 0x1361:
1556 case 0x17D5:
1557 return 1;
1558 //
1559 // A hyphen which describes line break opportunities before and after them, but not between a pair of them
1560 //
1561 case 0x2014:
1562 return 2;
1563 }
1564
1565 return -1;
1566}
1567
1622EFI_STATUS
1623EFIAPI
1625 IN CONST EFI_HII_FONT_PROTOCOL *This,
1626 IN EFI_HII_OUT_FLAGS Flags,
1627 IN CONST EFI_STRING String,
1628 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
1629 IN OUT EFI_IMAGE_OUTPUT **Blt,
1630 IN UINTN BltX,
1631 IN UINTN BltY,
1632 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
1633 OUT UINTN *RowInfoArraySize OPTIONAL,
1634 OUT UINTN *ColumnInfoArray OPTIONAL
1635 )
1636{
1637 EFI_STATUS Status;
1639 UINT8 **GlyphBuf;
1640 EFI_HII_GLYPH_INFO *Cell;
1641 UINT8 *Attributes;
1642 EFI_IMAGE_OUTPUT *Image;
1643 EFI_STRING StringPtr;
1644 EFI_STRING StringTmp;
1645 EFI_HII_ROW_INFO *RowInfo;
1646 UINTN LineWidth;
1647 UINTN LineHeight;
1648 UINTN LineOffset;
1649 UINTN LastLineHeight;
1650 UINTN BaseLineOffset;
1651 UINT16 MaxRowNum;
1652 UINT16 RowIndex;
1653 UINTN Index;
1654 UINTN NextIndex;
1655 UINTN Index1;
1656 EFI_FONT_DISPLAY_INFO *StringInfoOut;
1657 EFI_FONT_DISPLAY_INFO *SystemDefault;
1658 EFI_FONT_HANDLE FontHandle;
1659 EFI_STRING StringIn;
1660 EFI_STRING StringIn2;
1661 UINT16 Height;
1662 UINT16 BaseLine;
1663 EFI_FONT_INFO *FontInfo;
1664 BOOLEAN SysFontFlag;
1665 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
1666 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
1667 BOOLEAN Transparent;
1668 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
1669 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
1670 UINTN RowInfoSize;
1671 BOOLEAN LineBreak;
1672 UINTN StrLength;
1673 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *RowBufferPtr;
1674 HII_GLOBAL_FONT_INFO *GlobalFont;
1675 UINT32 PreInitBkgnd;
1676
1677 //
1678 // Check incoming parameters.
1679 //
1680
1681 if ((This == NULL) || (String == NULL) || (Blt == NULL)) {
1682 return EFI_INVALID_PARAMETER;
1683 }
1684
1685 if (*Blt == NULL) {
1686 //
1687 // These two flag cannot be used if Blt is NULL upon entry.
1688 //
1689 if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {
1690 return EFI_INVALID_PARAMETER;
1691 }
1692
1693 if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {
1694 return EFI_INVALID_PARAMETER;
1695 }
1696 }
1697
1698 //
1699 // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
1700 //
1701 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {
1702 return EFI_INVALID_PARAMETER;
1703 }
1704
1705 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
1706 return EFI_INVALID_PARAMETER;
1707 }
1708
1709 //
1710 // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.
1711 //
1712 if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) {
1713 return EFI_INVALID_PARAMETER;
1714 }
1715
1716 if (*Blt == NULL) {
1717 //
1718 // Create a new bitmap and draw the string onto this image.
1719 //
1720 Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1721 if (Image == NULL) {
1722 return EFI_OUT_OF_RESOURCES;
1723 }
1724
1725 Image->Width = 800;
1726 Image->Height = 600;
1727 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
1728 if (Image->Image.Bitmap == NULL) {
1729 FreePool (Image);
1730 return EFI_OUT_OF_RESOURCES;
1731 }
1732
1733 //
1734 // Other flags are not permitted when Blt is NULL.
1735 //
1736 Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
1737 *Blt = Image;
1738 }
1739
1740 StrLength = StrLen (String);
1741 GlyphBuf = (UINT8 **)AllocateZeroPool (StrLength * sizeof (UINT8 *));
1742 ASSERT (GlyphBuf != NULL);
1743 Cell = (EFI_HII_GLYPH_INFO *)AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
1744 ASSERT (Cell != NULL);
1745 Attributes = (UINT8 *)AllocateZeroPool (StrLength * sizeof (UINT8));
1746 ASSERT (Attributes != NULL);
1747
1748 RowInfo = NULL;
1749 Status = EFI_SUCCESS;
1750 StringIn2 = NULL;
1751 SystemDefault = NULL;
1752 StringIn = NULL;
1753
1754 //
1755 // Calculate the string output information, including specified color and font .
1756 // If StringInfo does not points to system font info, it must indicate an existing
1757 // EFI_FONT_INFO.
1758 //
1759 StringInfoOut = NULL;
1760 FontHandle = NULL;
1762 SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
1763
1764 if (SysFontFlag) {
1765 ASSERT (SystemDefault != NULL);
1766 FontInfo = NULL;
1767 Height = SystemDefault->FontInfo.FontSize;
1768 BaseLine = SystemDefault->FontInfo.FontSize;
1769 Foreground = SystemDefault->ForegroundColor;
1770 Background = SystemDefault->BackgroundColor;
1771 } else {
1772 //
1773 // StringInfo must not be NULL if it is not system info.
1774 //
1775 ASSERT (StringInfo != NULL);
1776 Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);
1777 if (Status == EFI_NOT_FOUND) {
1778 //
1779 // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
1780 // Use the system font instead. Still use the color specified by StringInfo.
1781 //
1782 SysFontFlag = TRUE;
1783 FontInfo = NULL;
1784 Height = SystemDefault->FontInfo.FontSize;
1785 BaseLine = SystemDefault->FontInfo.FontSize;
1786 Foreground = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;
1787 Background = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;
1788 } else if (Status == EFI_SUCCESS) {
1789 FontInfo = &StringInfoOut->FontInfo;
1790 IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);
1791 Height = GlobalFont->FontPackage->Height;
1792 BaseLine = GlobalFont->FontPackage->BaseLine;
1793 Foreground = StringInfoOut->ForegroundColor;
1794 Background = StringInfoOut->BackgroundColor;
1795 } else {
1796 goto Exit;
1797 }
1798 }
1799
1800 //
1801 // Use the maximum height of font as the base line.
1802 // And, use the maximum height as line height.
1803 //
1804 LineHeight = Height;
1805 LastLineHeight = Height;
1806 BaseLineOffset = Height - BaseLine;
1807
1808 //
1809 // Parse the string to be displayed to drop some ignored characters.
1810 //
1811
1812 StringPtr = String;
1813
1814 //
1815 // Ignore line-break characters only. Hyphens or dash character will be displayed
1816 // without line-break opportunity.
1817 //
1818 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
1819 StringIn = AllocateZeroPool (StrSize (StringPtr));
1820 if (StringIn == NULL) {
1821 Status = EFI_OUT_OF_RESOURCES;
1822 goto Exit;
1823 }
1824
1825 StringTmp = StringIn;
1826 while (*StringPtr != 0) {
1827 if (IsLineBreak (*StringPtr) == 0) {
1828 StringPtr++;
1829 } else {
1830 *StringTmp++ = *StringPtr++;
1831 }
1832 }
1833
1834 *StringTmp = 0;
1835 StringPtr = StringIn;
1836 }
1837
1838 //
1839 // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
1840 // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.
1841 //
1842 StringIn2 = AllocateZeroPool (StrSize (StringPtr));
1843 if (StringIn2 == NULL) {
1844 Status = EFI_OUT_OF_RESOURCES;
1845 goto Exit;
1846 }
1847
1848 Index = 0;
1849 StringTmp = StringIn2;
1850 StrLength = StrLen (StringPtr);
1851 while (*StringPtr != 0 && Index < StrLength) {
1852 if (IsLineBreak (*StringPtr) == 0) {
1853 *StringTmp++ = *StringPtr++;
1854 Index++;
1855 continue;
1856 }
1857
1858 Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
1859 if (Status == EFI_NOT_FOUND) {
1860 if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
1861 GlyphBuf[Index] = NULL;
1862 ZeroMem (&Cell[Index], sizeof (Cell[Index]));
1863 Status = EFI_SUCCESS;
1864 } else {
1865 //
1866 // Unicode 0xFFFD must exist in current hii database if this flag is not set.
1867 //
1868 Status = GetGlyphBuffer (
1869 Private,
1871 FontInfo,
1872 &GlyphBuf[Index],
1873 &Cell[Index],
1874 &Attributes[Index]
1875 );
1876 if (EFI_ERROR (Status)) {
1877 Status = EFI_INVALID_PARAMETER;
1878 }
1879 }
1880 }
1881
1882 if (EFI_ERROR (Status)) {
1883 goto Exit;
1884 }
1885
1886 *StringTmp++ = *StringPtr++;
1887 Index++;
1888 }
1889
1890 *StringTmp = 0;
1891 StringPtr = StringIn2;
1892
1893 //
1894 // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
1895 // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
1896 // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
1897 // Otherwise render this string to a new allocated image and output it.
1898 //
1899 Image = *Blt;
1900 BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
1901 if (Image->Height < BltY) {
1902 //
1903 // the top edge of the image should be in Image resolution scope.
1904 //
1905 Status = EFI_INVALID_PARAMETER;
1906 goto Exit;
1907 }
1908
1909 MaxRowNum = (UINT16)((Image->Height - BltY) / Height);
1910 if ((Image->Height - BltY) % Height != 0) {
1911 LastLineHeight = (Image->Height - BltY) % Height;
1912 MaxRowNum++;
1913 }
1914
1915 RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
1916 if (RowInfo == NULL) {
1917 Status = EFI_OUT_OF_RESOURCES;
1918 goto Exit;
1919 }
1920
1921 //
1922 // Format the glyph buffer according to flags.
1923 //
1924 Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
1925
1926 for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
1927 LineWidth = 0;
1928 LineBreak = FALSE;
1929
1930 //
1931 // Clip the final row if the row's bottom-most on pixel cannot fit when
1932 // EFI_HII_OUT_FLAG_CLEAN_Y is set.
1933 //
1934 if (RowIndex == MaxRowNum - 1) {
1935 if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {
1936 //
1937 // Don't draw at all if the row's bottom-most on pixel cannot fit.
1938 //
1939 break;
1940 }
1941
1942 LineHeight = LastLineHeight;
1943 }
1944
1945 //
1946 // Calculate how many characters there are in a row.
1947 //
1948 RowInfo[RowIndex].StartIndex = Index;
1949
1950 while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
1951 if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&
1952 (IsLineBreak (StringPtr[Index]) == 0))
1953 {
1954 //
1955 // It forces a line break that ends this row.
1956 //
1957 Index++;
1958 LineBreak = TRUE;
1959 break;
1960 }
1961
1962 //
1963 // If the glyph of the character is existing, then accumulate the actual printed width
1964 //
1965 LineWidth += (UINTN)Cell[Index].AdvanceX;
1966
1967 Index++;
1968 }
1969
1970 //
1971 // Record index of next char.
1972 //
1973 NextIndex = Index;
1974 //
1975 // Return to the previous char.
1976 //
1977 Index--;
1978 if (LineBreak && (Index > 0)) {
1979 //
1980 // Return the previous non line break char.
1981 //
1982 Index--;
1983 }
1984
1985 //
1986 // If this character is the last character of a row, we need not
1987 // draw its (AdvanceX - Width - OffsetX) for next character.
1988 //
1989 LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
1990
1991 //
1992 // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
1993 //
1994 if ((LineWidth + BltX <= Image->Width) ||
1995 ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))
1996 {
1997 //
1998 // Record right-most character in RowInfo even if it is partially displayed.
1999 //
2000 RowInfo[RowIndex].EndIndex = Index;
2001 RowInfo[RowIndex].LineWidth = LineWidth;
2002 RowInfo[RowIndex].LineHeight = LineHeight;
2003 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
2004 } else {
2005 //
2006 // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
2007 // if its right-most on pixel cannot fit.
2008 //
2009 if (Index > RowInfo[RowIndex].StartIndex) {
2010 //
2011 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
2012 //
2013 LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);
2014 LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
2015 RowInfo[RowIndex].EndIndex = Index - 1;
2016 RowInfo[RowIndex].LineWidth = LineWidth;
2017 RowInfo[RowIndex].LineHeight = LineHeight;
2018 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
2019 } else {
2020 //
2021 // There is no enough column to draw any character, so set current line width to zero.
2022 // And go to draw Next line if LineBreak is set.
2023 //
2024 RowInfo[RowIndex].LineWidth = 0;
2025 goto NextLine;
2026 }
2027 }
2028
2029 //
2030 // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
2031 // opportunity prior to a character whose right-most extent would exceed Width.
2032 // Search the right-most line-break opportunity here.
2033 //
2034 if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&
2035 ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&
2036 !LineBreak)
2037 {
2038 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
2039 LineWidth = RowInfo[RowIndex].LineWidth;
2040 for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
2041 if (Index1 == RowInfo[RowIndex].EndIndex) {
2042 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
2043 } else {
2044 LineWidth -= Cell[Index1].AdvanceX;
2045 }
2046
2047 if (IsLineBreak (StringPtr[Index1]) > 0) {
2048 LineBreak = TRUE;
2049 if (Index1 > RowInfo[RowIndex].StartIndex) {
2050 RowInfo[RowIndex].EndIndex = Index1 - 1;
2051 }
2052
2053 //
2054 // relocate to the character after the right-most line break opportunity of this line
2055 //
2056 NextIndex = Index1 + 1;
2057 break;
2058 }
2059
2060 //
2061 // If don't find a line break opportunity from EndIndex to StartIndex,
2062 // then jump out.
2063 //
2064 if (Index1 == RowInfo[RowIndex].StartIndex) {
2065 break;
2066 }
2067 }
2068
2069 //
2070 // Update LineWidth to the real width
2071 //
2072 if (IsLineBreak (StringPtr[Index1]) > 0) {
2073 if (Index1 == RowInfo[RowIndex].StartIndex) {
2074 LineWidth = 0;
2075 } else {
2076 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
2077 }
2078
2079 RowInfo[RowIndex].LineWidth = LineWidth;
2080 }
2081 }
2082
2083 //
2084 // If no line-break opportunity can be found, then the text will
2085 // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
2086 //
2087 if (!LineBreak) {
2088 LineWidth = RowInfo[RowIndex].LineWidth;
2089 Index1 = RowInfo[RowIndex].EndIndex;
2090 if (LineWidth + BltX > Image->Width) {
2091 if (Index1 > RowInfo[RowIndex].StartIndex) {
2092 //
2093 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
2094 //
2095 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
2096 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
2097 RowInfo[RowIndex].EndIndex = Index1 - 1;
2098 RowInfo[RowIndex].LineWidth = LineWidth;
2099 } else {
2100 //
2101 // There is no enough column to draw any character, so set current line width to zero.
2102 // And go to draw Next line if LineBreak is set.
2103 //
2104 RowInfo[RowIndex].LineWidth = 0;
2105 goto NextLine;
2106 }
2107 }
2108 }
2109 }
2110
2111 //
2112 // LineWidth can't exceed Image width.
2113 //
2114 if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
2115 RowInfo[RowIndex].LineWidth = Image->Width - BltX;
2116 }
2117
2118 //
2119 // Draw it to screen or existing bitmap depending on whether
2120 // EFI_HII_DIRECT_TO_SCREEN is set.
2121 //
2122 LineOffset = 0;
2123 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
2124 BltBuffer = NULL;
2125 if (RowInfo[RowIndex].LineWidth != 0) {
2126 BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2127 if (BltBuffer == NULL) {
2128 Status = EFI_OUT_OF_RESOURCES;
2129 goto Exit;
2130 }
2131
2132 //
2133 // Initialize the background color.
2134 //
2135 PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;
2136 SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);
2137 //
2138 // Set BufferPtr to Origin by adding baseline to the starting position.
2139 //
2140 BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
2141 }
2142
2143 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2144 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
2145 //
2146 // Only BLT these character which have corresponding glyph in font database.
2147 //
2148 GlyphToImage (
2149 GlyphBuf[Index1],
2150 Foreground,
2151 Background,
2152 (UINT16)RowInfo[RowIndex].LineWidth,
2153 BaseLine,
2154 RowInfo[RowIndex].LineWidth - LineOffset,
2155 RowInfo[RowIndex].LineHeight,
2156 Transparent,
2157 &Cell[Index1],
2158 Attributes[Index1],
2159 &BufferPtr
2160 );
2161 }
2162
2163 if (ColumnInfoArray != NULL) {
2164 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
2165 || (RowInfo[RowIndex].LineWidth == 0))
2166 {
2167 *ColumnInfoArray = (UINTN) ~0;
2168 } else {
2169 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2170 }
2171
2172 ColumnInfoArray++;
2173 }
2174
2175 LineOffset += Cell[Index1].AdvanceX;
2176 }
2177
2178 if (BltBuffer != NULL) {
2179 Status = Image->Image.Screen->Blt (
2180 Image->Image.Screen,
2181 BltBuffer,
2182 EfiBltBufferToVideo,
2183 0,
2184 0,
2185 BltX,
2186 BltY,
2187 RowInfo[RowIndex].LineWidth,
2188 RowInfo[RowIndex].LineHeight,
2189 0
2190 );
2191 if (EFI_ERROR (Status)) {
2192 FreePool (BltBuffer);
2193 goto Exit;
2194 }
2195
2196 FreePool (BltBuffer);
2197 }
2198 } else {
2199 //
2200 // Save the starting position for calculate the starting position of next row.
2201 //
2202 RowBufferPtr = BufferPtr;
2203 //
2204 // Set BufferPtr to Origin by adding baseline to the starting position.
2205 //
2206 BufferPtr = BufferPtr + BaseLine * Image->Width;
2207 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2208 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
2209 //
2210 // Only BLT these character which have corresponding glyph in font database.
2211 //
2212 GlyphToImage (
2213 GlyphBuf[Index1],
2214 Foreground,
2215 Background,
2216 Image->Width,
2217 BaseLine,
2218 RowInfo[RowIndex].LineWidth - LineOffset,
2219 RowInfo[RowIndex].LineHeight,
2220 Transparent,
2221 &Cell[Index1],
2222 Attributes[Index1],
2223 &BufferPtr
2224 );
2225 }
2226
2227 if (ColumnInfoArray != NULL) {
2228 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
2229 || (RowInfo[RowIndex].LineWidth == 0))
2230 {
2231 *ColumnInfoArray = (UINTN) ~0;
2232 } else {
2233 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2234 }
2235
2236 ColumnInfoArray++;
2237 }
2238
2239 LineOffset += Cell[Index1].AdvanceX;
2240 }
2241
2242 //
2243 // Jump to starting position of next row.
2244 //
2245 if (RowIndex == 0) {
2246 BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
2247 } else {
2248 BufferPtr = RowBufferPtr + LineHeight * Image->Width;
2249 }
2250 }
2251
2252NextLine:
2253 //
2254 // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down
2255 //
2256 BltY += RowInfo[RowIndex].LineHeight;
2257
2258 RowIndex++;
2259 Index = NextIndex;
2260
2261 if (!LineBreak) {
2262 //
2263 // If there is not a mandatory line break or line break opportunity, only render one line to image
2264 //
2265 break;
2266 }
2267 }
2268
2269 //
2270 // Write output parameters.
2271 //
2272 RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
2273 if (RowInfoArray != NULL) {
2274 if (RowInfoSize > 0) {
2275 *RowInfoArray = AllocateZeroPool (RowInfoSize);
2276 if (*RowInfoArray == NULL) {
2277 Status = EFI_OUT_OF_RESOURCES;
2278 goto Exit;
2279 }
2280
2281 CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
2282 } else {
2283 *RowInfoArray = NULL;
2284 }
2285 }
2286
2287 if (RowInfoArraySize != NULL) {
2288 *RowInfoArraySize = RowIndex;
2289 }
2290
2291 Status = EFI_SUCCESS;
2292
2293Exit:
2294
2295 for (Index = 0; Index < StrLength; Index++) {
2296 if (GlyphBuf[Index] != NULL) {
2297 FreePool (GlyphBuf[Index]);
2298 }
2299 }
2300
2301 if (StringIn != NULL) {
2302 FreePool (StringIn);
2303 }
2304
2305 if (StringIn2 != NULL) {
2306 FreePool (StringIn2);
2307 }
2308
2309 if (StringInfoOut != NULL) {
2310 FreePool (StringInfoOut);
2311 }
2312
2313 if (RowInfo != NULL) {
2314 FreePool (RowInfo);
2315 }
2316
2317 if (SystemDefault != NULL) {
2318 FreePool (SystemDefault);
2319 }
2320
2321 if (GlyphBuf != NULL) {
2322 FreePool (GlyphBuf);
2323 }
2324
2325 if (Cell != NULL) {
2326 FreePool (Cell);
2327 }
2328
2329 if (Attributes != NULL) {
2330 FreePool (Attributes);
2331 }
2332
2333 return Status;
2334}
2335
2397EFI_STATUS
2398EFIAPI
2400 IN CONST EFI_HII_FONT_PROTOCOL *This,
2401 IN EFI_HII_OUT_FLAGS Flags,
2402 IN EFI_HII_HANDLE PackageList,
2403 IN EFI_STRING_ID StringId,
2404 IN CONST CHAR8 *Language,
2405 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
2406 IN OUT EFI_IMAGE_OUTPUT **Blt,
2407 IN UINTN BltX,
2408 IN UINTN BltY,
2409 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
2410 OUT UINTN *RowInfoArraySize OPTIONAL,
2411 OUT UINTN *ColumnInfoArray OPTIONAL
2412 )
2413{
2414 EFI_STATUS Status;
2416 EFI_HII_STRING_PROTOCOL *HiiString;
2417 EFI_STRING String;
2418 UINTN StringSize;
2419 UINTN FontLen;
2420 UINTN NameSize;
2421 EFI_FONT_INFO *StringFontInfo;
2422 EFI_FONT_DISPLAY_INFO *NewStringInfo;
2423 CHAR8 TempSupportedLanguages;
2424 CHAR8 *SupportedLanguages;
2425 UINTN SupportedLanguagesSize;
2426 CHAR8 *CurrentLanguage;
2427 CHAR8 *BestLanguage;
2428
2429 if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {
2430 return EFI_INVALID_PARAMETER;
2431 }
2432
2433 if (!IsHiiHandleValid (PackageList)) {
2434 return EFI_NOT_FOUND;
2435 }
2436
2437 //
2438 // Initialize string pointers to be NULL
2439 //
2440 SupportedLanguages = NULL;
2441 CurrentLanguage = NULL;
2442 BestLanguage = NULL;
2443 String = NULL;
2444 StringFontInfo = NULL;
2445 NewStringInfo = NULL;
2446
2447 //
2448 // Get the string to be displayed.
2449 //
2451 HiiString = &Private->HiiString;
2452
2453 //
2454 // Get the size of supported language.
2455 //
2456 SupportedLanguagesSize = 0;
2457 Status = HiiString->GetLanguages (
2458 HiiString,
2459 PackageList,
2460 &TempSupportedLanguages,
2461 &SupportedLanguagesSize
2462 );
2463 if (Status != EFI_BUFFER_TOO_SMALL) {
2464 return Status;
2465 }
2466
2467 SupportedLanguages = AllocatePool (SupportedLanguagesSize);
2468 if (SupportedLanguages == NULL) {
2469 return EFI_OUT_OF_RESOURCES;
2470 }
2471
2472 Status = HiiString->GetLanguages (
2473 HiiString,
2474 PackageList,
2475 SupportedLanguages,
2476 &SupportedLanguagesSize
2477 );
2478 if (EFI_ERROR (Status)) {
2479 goto Exit;
2480 }
2481
2482 if (Language == NULL) {
2483 Language = "";
2484 }
2485
2486 GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);
2487 BestLanguage = GetBestLanguage (
2488 SupportedLanguages,
2489 FALSE,
2490 Language,
2491 (CurrentLanguage == NULL) ? CurrentLanguage : "",
2492 (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
2493 NULL
2494 );
2495 if (BestLanguage == NULL) {
2496 Status = EFI_NOT_FOUND;
2497 goto Exit;
2498 }
2499
2500 StringSize = MAX_STRING_LENGTH;
2501 String = (EFI_STRING)AllocateZeroPool (StringSize);
2502 if (String == NULL) {
2503 Status = EFI_OUT_OF_RESOURCES;
2504 goto Exit;
2505 }
2506
2507 Status = HiiString->GetString (
2508 HiiString,
2509 BestLanguage,
2510 PackageList,
2511 StringId,
2512 String,
2513 &StringSize,
2514 &StringFontInfo
2515 );
2516 if (Status == EFI_BUFFER_TOO_SMALL) {
2517 FreePool (String);
2518 String = (EFI_STRING)AllocateZeroPool (StringSize);
2519 if (String == NULL) {
2520 Status = EFI_OUT_OF_RESOURCES;
2521 goto Exit;
2522 }
2523
2524 Status = HiiString->GetString (
2525 HiiString,
2526 BestLanguage,
2527 PackageList,
2528 StringId,
2529 String,
2530 &StringSize,
2531 NULL
2532 );
2533 }
2534
2535 if (EFI_ERROR (Status)) {
2536 goto Exit;
2537 }
2538
2539 //
2540 // When StringInfo specifies that string will be output in the system default font and color,
2541 // use particular stringfontinfo described in string package instead if exists.
2542 // StringFontInfo equals NULL means system default font attaches with the string block.
2543 //
2544 if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {
2545 NameSize = StrSize (StringFontInfo->FontName);
2546 FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
2547 NewStringInfo = AllocateZeroPool (FontLen);
2548 if (NewStringInfo == NULL) {
2549 Status = EFI_OUT_OF_RESOURCES;
2550 goto Exit;
2551 }
2552
2553 NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
2554 NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
2555 NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;
2556 StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
2557
2558 Status = HiiStringToImage (
2559 This,
2560 Flags,
2561 String,
2562 NewStringInfo,
2563 Blt,
2564 BltX,
2565 BltY,
2566 RowInfoArray,
2567 RowInfoArraySize,
2568 ColumnInfoArray
2569 );
2570 goto Exit;
2571 }
2572
2573 Status = HiiStringToImage (
2574 This,
2575 Flags,
2576 String,
2577 StringInfo,
2578 Blt,
2579 BltX,
2580 BltY,
2581 RowInfoArray,
2582 RowInfoArraySize,
2583 ColumnInfoArray
2584 );
2585
2586Exit:
2587 if (SupportedLanguages != NULL) {
2588 FreePool (SupportedLanguages);
2589 }
2590
2591 if (CurrentLanguage != NULL) {
2592 FreePool (CurrentLanguage);
2593 }
2594
2595 if (BestLanguage != NULL) {
2596 FreePool (BestLanguage);
2597 }
2598
2599 if (String != NULL) {
2600 FreePool (String);
2601 }
2602
2603 if (StringFontInfo != NULL) {
2604 FreePool (StringFontInfo);
2605 }
2606
2607 if (NewStringInfo != NULL) {
2608 FreePool (NewStringInfo);
2609 }
2610
2611 return Status;
2612}
2613
2636EFI_STATUS
2637EFIAPI
2639 IN CONST EFI_HII_FONT_PROTOCOL *This,
2640 IN CHAR16 Char,
2641 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
2642 OUT EFI_IMAGE_OUTPUT **Blt,
2643 OUT UINTN *Baseline OPTIONAL
2644 )
2645{
2646 EFI_STATUS Status;
2648 EFI_IMAGE_OUTPUT *Image;
2649 UINT8 *GlyphBuffer;
2650 EFI_FONT_DISPLAY_INFO *SystemDefault;
2651 EFI_FONT_DISPLAY_INFO *StringInfoOut;
2652 BOOLEAN Default;
2653 EFI_FONT_HANDLE FontHandle;
2654 EFI_STRING String;
2655 EFI_HII_GLYPH_INFO Cell;
2656 EFI_FONT_INFO *FontInfo;
2657 UINT8 Attributes;
2658 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
2659 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
2660 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
2661 UINT16 BaseLine;
2662
2663 if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {
2664 return EFI_INVALID_PARAMETER;
2665 }
2666
2668
2669 Default = FALSE;
2670 Image = NULL;
2671 SystemDefault = NULL;
2672 FontHandle = NULL;
2673 String = NULL;
2674 GlyphBuffer = NULL;
2675 StringInfoOut = NULL;
2676 FontInfo = NULL;
2677
2678 ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2679 ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2680
2681 Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
2682
2683 if (!Default) {
2684 //
2685 // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
2686 // the specified color and font.
2687 //
2688 String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);
2689 if (String == NULL) {
2690 Status = EFI_OUT_OF_RESOURCES;
2691 goto Exit;
2692 }
2693
2694 *String = Char;
2695 *(String + 1) = 0;
2696
2697 Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
2698 if (EFI_ERROR (Status)) {
2699 goto Exit;
2700 }
2701
2702 ASSERT (StringInfoOut != NULL);
2703 FontInfo = &StringInfoOut->FontInfo;
2704 Foreground = StringInfoOut->ForegroundColor;
2705 Background = StringInfoOut->BackgroundColor;
2706 } else {
2707 ASSERT (SystemDefault != NULL);
2708 Foreground = SystemDefault->ForegroundColor;
2709 Background = SystemDefault->BackgroundColor;
2710 }
2711
2712 Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
2713 if (EFI_ERROR (Status)) {
2714 goto Exit;
2715 }
2716
2717 Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
2718 if (Image == NULL) {
2719 Status = EFI_OUT_OF_RESOURCES;
2720 goto Exit;
2721 }
2722
2723 Image->Width = Cell.Width;
2724 Image->Height = Cell.Height;
2725
2726 if (Image->Width * Image->Height > 0) {
2727 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2728 if (Image->Image.Bitmap == NULL) {
2729 FreePool (Image);
2730 Status = EFI_OUT_OF_RESOURCES;
2731 goto Exit;
2732 }
2733
2734 //
2735 // Set BaseLine to the char height.
2736 //
2737 BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);
2738 //
2739 // Set BltBuffer to the position of Origin.
2740 //
2741 BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
2742 GlyphToImage (
2743 GlyphBuffer,
2744 Foreground,
2745 Background,
2746 Image->Width,
2747 BaseLine,
2748 Cell.Width + Cell.OffsetX,
2749 BaseLine - Cell.OffsetY,
2750 FALSE,
2751 &Cell,
2752 Attributes,
2753 &BltBuffer
2754 );
2755 }
2756
2757 *Blt = Image;
2758 if (Baseline != NULL) {
2759 *Baseline = Cell.OffsetY;
2760 }
2761
2762 Status = EFI_SUCCESS;
2763
2764Exit:
2765
2766 if (Status == EFI_NOT_FOUND) {
2767 //
2768 // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
2769 //
2770 if (Char != REPLACE_UNKNOWN_GLYPH) {
2771 Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
2772 if (!EFI_ERROR (Status)) {
2773 Status = EFI_WARN_UNKNOWN_GLYPH;
2774 }
2775 } else {
2776 Status = EFI_WARN_UNKNOWN_GLYPH;
2777 }
2778 }
2779
2780 if (SystemDefault != NULL) {
2781 FreePool (SystemDefault);
2782 }
2783
2784 if (StringInfoOut != NULL) {
2785 FreePool (StringInfoOut);
2786 }
2787
2788 if (String != NULL) {
2789 FreePool (String);
2790 }
2791
2792 if (GlyphBuffer != NULL) {
2793 FreePool (GlyphBuffer);
2794 }
2795
2796 return Status;
2797}
2798
2830EFI_STATUS
2831EFIAPI
2833 IN CONST EFI_HII_FONT_PROTOCOL *This,
2834 IN OUT EFI_FONT_HANDLE *FontHandle,
2835 IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn, OPTIONAL
2836 OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
2837 IN CONST EFI_STRING String OPTIONAL
2838 )
2839{
2841 EFI_STATUS Status;
2842 EFI_FONT_DISPLAY_INFO *SystemDefault;
2843 EFI_FONT_DISPLAY_INFO InfoOut;
2844 UINTN StringInfoOutLen;
2845 EFI_FONT_INFO *FontInfo;
2846 HII_GLOBAL_FONT_INFO *GlobalFont;
2847 EFI_STRING StringIn;
2848 EFI_FONT_HANDLE LocalFontHandle;
2849
2850 if (This == NULL) {
2851 return EFI_INVALID_PARAMETER;
2852 }
2853
2854 StringInfoOutLen = 0;
2855 FontInfo = NULL;
2856 SystemDefault = NULL;
2857 LocalFontHandle = NULL;
2858 if (FontHandle != NULL) {
2859 LocalFontHandle = *FontHandle;
2860 }
2861
2863
2864 //
2865 // Already searched to the end of the whole list, return directly.
2866 //
2867 if (LocalFontHandle == &Private->FontInfoList) {
2868 LocalFontHandle = NULL;
2869 Status = EFI_NOT_FOUND;
2870 goto Exit;
2871 }
2872
2873 //
2874 // Get default system display info, if StringInfoIn points to
2875 // system display info, return it directly.
2876 //
2877 if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
2878 //
2879 // System font is the first node. When handle is not NULL, system font can not
2880 // be found any more.
2881 //
2882 if (LocalFontHandle == NULL) {
2883 if (StringInfoOut != NULL) {
2884 *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
2885 if (*StringInfoOut == NULL) {
2886 Status = EFI_OUT_OF_RESOURCES;
2887 LocalFontHandle = NULL;
2888 goto Exit;
2889 }
2890 }
2891
2892 LocalFontHandle = Private->FontInfoList.ForwardLink;
2893 Status = EFI_SUCCESS;
2894 goto Exit;
2895 } else {
2896 LocalFontHandle = NULL;
2897 Status = EFI_NOT_FOUND;
2898 goto Exit;
2899 }
2900 }
2901
2902 //
2903 // StringInfoIn must not be NULL if it is not system default font info.
2904 //
2905 ASSERT (StringInfoIn != NULL);
2906 //
2907 // Check the font information mask to make sure it is valid.
2908 //
2909 if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
2910 (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
2911 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
2912 (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
2913 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
2914 (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
2915 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
2916 (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
2917 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
2918 (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
2919 {
2920 return EFI_INVALID_PARAMETER;
2921 }
2922
2923 //
2924 // Parse the font information mask to find a matching font.
2925 //
2926
2927 CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
2928
2929 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
2930 Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
2931 } else {
2932 Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);
2933 }
2934
2935 if (EFI_ERROR (Status)) {
2936 goto Exit;
2937 }
2938
2939 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
2940 InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
2941 }
2942
2943 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
2944 InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
2945 }
2946
2947 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
2948 InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
2949 }
2950
2951 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
2952 InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
2953 }
2954
2955 ASSERT (FontInfo != NULL);
2956 FontInfo->FontSize = InfoOut.FontInfo.FontSize;
2957 FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
2958
2959 if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
2960 //
2961 // Test to guarantee all characters are available in the found font.
2962 //
2963 if (String != NULL) {
2964 StringIn = String;
2965 while (*StringIn != 0) {
2966 Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
2967 if (EFI_ERROR (Status)) {
2968 LocalFontHandle = NULL;
2969 goto Exit;
2970 }
2971
2972 StringIn++;
2973 }
2974 }
2975
2976 //
2977 // Write to output parameter
2978 //
2979 if (StringInfoOut != NULL) {
2980 StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
2981 *StringInfoOut = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);
2982 if (*StringInfoOut == NULL) {
2983 Status = EFI_OUT_OF_RESOURCES;
2984 LocalFontHandle = NULL;
2985 goto Exit;
2986 }
2987
2988 CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
2989 CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
2990 }
2991
2992 LocalFontHandle = GlobalFont->Entry.ForwardLink;
2993 Status = EFI_SUCCESS;
2994 goto Exit;
2995 }
2996
2997 Status = EFI_NOT_FOUND;
2998
2999Exit:
3000
3001 if (FontHandle != NULL) {
3002 *FontHandle = LocalFontHandle;
3003 }
3004
3005 if (SystemDefault != NULL) {
3006 FreePool (SystemDefault);
3007 }
3008
3009 if (FontInfo != NULL) {
3010 FreePool (FontInfo);
3011 }
3012
3013 return Status;
3014}
VOID EFIAPI Exit(IN EFI_STATUS Status)
BOOLEAN IsHiiHandleValid(EFI_HII_HANDLE Handle)
Definition Database.c:123
EFI_STATUS EFIAPI HiiGetGlyph(IN CONST EFI_HII_FONT_PROTOCOL *This, IN CHAR16 Char, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo, OUT EFI_IMAGE_OUTPUT **Blt, OUT UINTN *Baseline OPTIONAL)
Definition Font.c:2638
INT8 IsLineBreak(IN CHAR16 Char)
Definition Font.c:1502
BOOLEAN IsSystemFontInfo(IN HII_DATABASE_PRIVATE_DATA *Private, IN EFI_FONT_DISPLAY_INFO *StringInfo, OUT EFI_FONT_DISPLAY_INFO **SystemInfo, OPTIONAL OUT UINTN *SystemInfoLen OPTIONAL)
Definition Font.c:1056
VOID GlyphToBlt(IN UINT8 *GlyphBuffer, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background, IN UINT16 ImageWidth, IN UINT16 BaseLine, IN UINTN RowWidth, IN UINTN RowHeight, IN BOOLEAN Transparent, IN CONST EFI_HII_GLYPH_INFO *Cell, IN UINT8 Attributes, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin)
Definition Font.c:365
EFI_STATUS GetSystemFont(IN HII_DATABASE_PRIVATE_DATA *Private, OUT EFI_FONT_DISPLAY_INFO **FontInfo, OUT UINTN *FontInfoSize OPTIONAL)
Definition Font.c:993
EFI_STATUS GetCell(IN CHAR16 CharValue, IN LIST_ENTRY *GlyphInfoList, OUT EFI_HII_GLYPH_INFO *Cell)
Definition Font.c:98
VOID NarrowGlyphToBlt(IN UINT8 *GlyphBuffer, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background, IN UINT16 ImageWidth, IN UINTN RowWidth, IN UINTN RowHeight, IN BOOLEAN Transparent, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin)
Definition Font.c:286
VOID GlyphToImage(IN UINT8 *GlyphBuffer, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background, IN UINT16 ImageWidth, IN UINT16 BaseLine, IN UINTN RowWidth, IN UINTN RowHeight, IN BOOLEAN Transparent, IN CONST EFI_HII_GLYPH_INFO *Cell, IN UINT8 Attributes, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin)
Definition Font.c:481
EFI_STATUS EFIAPI HiiStringToImage(IN CONST EFI_HII_FONT_PROTOCOL *This, IN EFI_HII_OUT_FLAGS Flags, IN CONST EFI_STRING String, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY, OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, OUT UINTN *RowInfoArraySize OPTIONAL, OUT UINTN *ColumnInfoArray OPTIONAL)
Definition Font.c:1624
EFI_STATUS GetGlyphBuffer(IN HII_DATABASE_PRIVATE_DATA *Private, IN CHAR16 Char, IN EFI_FONT_INFO *StringInfo, OUT UINT8 **GlyphBuffer, OUT EFI_HII_GLYPH_INFO *Cell, OUT UINT8 *Attributes OPTIONAL)
Definition Font.c:151
EFI_STATUS NewCell(IN CHAR16 CharValue, IN LIST_ENTRY *GlyphInfoList, IN EFI_HII_GLYPH_INFO *Cell)
Definition Font.c:50
BOOLEAN IsFontInfoExisted(IN HII_DATABASE_PRIVATE_DATA *Private, IN EFI_FONT_INFO *FontInfo, IN EFI_FONT_INFO_MASK *FontInfoMask, OPTIONAL IN EFI_FONT_HANDLE FontHandle, OPTIONAL OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL)
Definition Font.c:1175
EFI_STATUS FindGlyphBlock(IN HII_FONT_PACKAGE_INSTANCE *FontPackage, IN CHAR16 CharValue, OUT UINT8 **GlyphBuffer, OPTIONAL OUT EFI_HII_GLYPH_INFO *Cell, OPTIONAL OUT UINTN *GlyphBufferLen OPTIONAL)
Definition Font.c:658
EFI_STATUS WriteOutputParam(IN UINT8 *BufferIn, IN UINTN BufferLen, IN EFI_HII_GLYPH_INFO *InputCell, OUT UINT8 **GlyphBuffer, OPTIONAL OUT EFI_HII_GLYPH_INFO *Cell, OPTIONAL OUT UINTN *GlyphBufferLen OPTIONAL)
Definition Font.c:603
EFI_STATUS SaveFontName(IN EFI_STRING FontName, OUT EFI_FONT_INFO **FontInfo)
Definition Font.c:956
EFI_STATUS EFIAPI HiiStringIdToImage(IN CONST EFI_HII_FONT_PROTOCOL *This, IN EFI_HII_OUT_FLAGS Flags, IN EFI_HII_HANDLE PackageList, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language, IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL, IN OUT EFI_IMAGE_OUTPUT **Blt, IN UINTN BltX, IN UINTN BltY, OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL, OUT UINTN *RowInfoArraySize OPTIONAL, OUT UINTN *ColumnInfoArray OPTIONAL)
Definition Font.c:2399
EFI_GRAPHICS_OUTPUT_BLT_PIXEL mHiiEfiColors[16]
Definition Font.c:12
EFI_STATUS EFIAPI HiiGetFontInfo(IN CONST EFI_HII_FONT_PROTOCOL *This, IN OUT EFI_FONT_HANDLE *FontHandle, IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn, OPTIONAL OUT EFI_FONT_DISPLAY_INFO **StringInfoOut, IN CONST EFI_STRING String OPTIONAL)
Definition Font.c:2832
#define REPLACE_UNKNOWN_GLYPH
Definition HiiDatabase.h:50
#define HII_DATABASE_RECORD_SIGNATURE
#define HII_GLOBAL_FONT_INFO_SIGNATURE
#define HII_FONT_PACKAGE_SIGNATURE
#define NARROW_GLYPH
Definition HiiDatabase.h:52
#define HII_GLYPH_INFO_SIGNATURE
#define MAX_STRING_LENGTH
Definition HiiDatabase.h:45
#define HII_S_FONT_PACKAGE_SIGNATURE
#define BITMAP_LEN_1_BIT(Width, Height)
Definition HiiDatabase.h:54
#define HII_DATABASE_PRIVATE_DATA_SIGNATURE
#define PROPORTIONAL_GLYPH
Definition HiiDatabase.h:51
#define HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS(a)
#define L_STR_SIZE(String)
Definition OcStringLib.h:35
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55
EFI_HII_STRING_PROTOCOL HiiString
HII_DATABASE_PACKAGE_LIST_INSTANCE * PackageList
EFI_FONT_INFO * FontInfo
HII_FONT_PACKAGE_INSTANCE * FontPackage
LIST_ENTRY Entry
EFI_HII_GLYPH_INFO Cell
EFI_HII_SIMPLE_FONT_PACKAGE_HDR * SimpleFontPkgHdr