1 /** @file
2 Implementation for EFI_HII_FONT_PROTOCOL.
3 
4 
5 Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution.  The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10 
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 
17 #include "HiiDatabase.h"
18 
19 EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mHiiEfiColors[16] = {
20   //
21   // B     G     R
22   //
23   {0x00, 0x00, 0x00, 0x00},  // BLACK
24   {0x98, 0x00, 0x00, 0x00},  // BLUE
25   {0x00, 0x98, 0x00, 0x00},  // GREEN
26   {0x98, 0x98, 0x00, 0x00},  // CYAN
27   {0x00, 0x00, 0x98, 0x00},  // RED
28   {0x98, 0x00, 0x98, 0x00},  // MAGENTA
29   {0x00, 0x98, 0x98, 0x00},  // BROWN
30   {0x98, 0x98, 0x98, 0x00},  // LIGHTGRAY
31   {0x30, 0x30, 0x30, 0x00},  // DARKGRAY - BRIGHT BLACK
32   {0xff, 0x00, 0x00, 0x00},  // LIGHTBLUE
33   {0x00, 0xff, 0x00, 0x00},  // LIGHTGREEN
34   {0xff, 0xff, 0x00, 0x00},  // LIGHTCYAN
35   {0x00, 0x00, 0xff, 0x00},  // LIGHTRED
36   {0xff, 0x00, 0xff, 0x00},  // LIGHTMAGENTA
37   {0x00, 0xff, 0xff, 0x00},  // YELLOW
38   {0xff, 0xff, 0xff, 0x00},  // WHITE
39 };
40 
41 
42 /**
43   Insert a character cell information to the list specified by GlyphInfoList.
44 
45   This is a internal function.
46 
47   @param  CharValue               Unicode character value, which identifies a glyph
48                                   block.
49   @param  GlyphInfoList           HII_GLYPH_INFO list head.
50   @param  Cell                    Incoming character cell information.
51 
52   @retval EFI_SUCCESS             Cell information is added to the GlyphInfoList.
53   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
54                                   task.
55 
56 **/
57 EFI_STATUS
NewCell(IN CHAR16 CharValue,IN LIST_ENTRY * GlyphInfoList,IN EFI_HII_GLYPH_INFO * Cell)58 NewCell (
59   IN  CHAR16                         CharValue,
60   IN  LIST_ENTRY                     *GlyphInfoList,
61   IN  EFI_HII_GLYPH_INFO             *Cell
62   )
63 {
64   HII_GLYPH_INFO           *GlyphInfo;
65 
66   ASSERT (Cell != NULL && GlyphInfoList != NULL);
67 
68   GlyphInfo = (HII_GLYPH_INFO *) AllocateZeroPool (sizeof (HII_GLYPH_INFO));
69   if (GlyphInfo == NULL) {
70     return EFI_OUT_OF_RESOURCES;
71   }
72 
73   //
74   // GlyphInfoList stores a list of default character cell information, each is
75   // identified by "CharId".
76   //
77   GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;
78   GlyphInfo->CharId    = CharValue;
79   if (Cell->AdvanceX == 0) {
80     Cell->AdvanceX = Cell->Width;
81   }
82   CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));
83   InsertTailList (GlyphInfoList, &GlyphInfo->Entry);
84 
85   return EFI_SUCCESS;
86 }
87 
88 
89 /**
90   Get a character cell information from the list specified by GlyphInfoList.
91 
92   This is a internal function.
93 
94   @param  CharValue               Unicode character value, which identifies a glyph
95                                   block.
96   @param  GlyphInfoList           HII_GLYPH_INFO list head.
97   @param  Cell                    Buffer which stores output character cell
98                                   information.
99 
100   @retval EFI_SUCCESS             Cell information is added to the GlyphInfoList.
101   @retval EFI_NOT_FOUND           The character info specified by CharValue does
102                                   not exist.
103 
104 **/
105 EFI_STATUS
GetCell(IN CHAR16 CharValue,IN LIST_ENTRY * GlyphInfoList,OUT EFI_HII_GLYPH_INFO * Cell)106 GetCell (
107   IN  CHAR16                         CharValue,
108   IN  LIST_ENTRY                     *GlyphInfoList,
109   OUT EFI_HII_GLYPH_INFO             *Cell
110   )
111 {
112   HII_GLYPH_INFO           *GlyphInfo;
113   LIST_ENTRY               *Link;
114 
115   ASSERT (Cell != NULL && GlyphInfoList != NULL);
116 
117   //
118   // Since the EFI_HII_GIBT_DEFAULTS block won't increment CharValueCurrent,
119   // the value of "CharId" of a default character cell which is used for a
120   // EFI_HII_GIBT_GLYPH_DEFAULT or EFI_HII_GIBT_GLYPHS_DEFAULT should be
121   // less or equal to the value of "CharValueCurrent" of this default block.
122   //
123   // For instance, if the CharId of a GlyphInfoList is {1, 3, 7}, a default glyph
124   // with CharValue equals "7" uses the GlyphInfo with CharId = 7;
125   // a default glyph with CharValue equals "6" uses the GlyphInfo with CharId = 3.
126   //
127   for (Link = GlyphInfoList->BackLink; Link != GlyphInfoList; Link = Link->BackLink) {
128     GlyphInfo = CR (Link, HII_GLYPH_INFO, Entry, HII_GLYPH_INFO_SIGNATURE);
129     if (GlyphInfo->CharId <= CharValue) {
130       CopyMem (Cell, &GlyphInfo->Cell, sizeof (EFI_HII_GLYPH_INFO));
131       return EFI_SUCCESS;
132     }
133   }
134 
135   return EFI_NOT_FOUND;
136 }
137 
138 
139 /**
140   Convert the glyph for a single character into a bitmap.
141 
142   This is a internal function.
143 
144   @param  Private                 HII database driver private data.
145   @param  Char                    Character to retrieve.
146   @param  StringInfo              Points to the string font and color information
147                                   or NULL  if the string should use the default
148                                   system font and color.
149   @param  GlyphBuffer             Buffer to store the retrieved bitmap data.
150   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.
151   @param  Attributes              If not NULL, output the glyph attributes if any.
152 
153   @retval EFI_SUCCESS             Glyph bitmap outputted.
154   @retval EFI_OUT_OF_RESOURCES    Unable to allocate the output buffer GlyphBuffer.
155   @retval EFI_NOT_FOUND           The glyph was unknown can not be found.
156   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
157 
158 **/
159 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)160 GetGlyphBuffer (
161   IN  HII_DATABASE_PRIVATE_DATA      *Private,
162   IN  CHAR16                         Char,
163   IN  EFI_FONT_INFO                  *StringInfo,
164   OUT UINT8                          **GlyphBuffer,
165   OUT EFI_HII_GLYPH_INFO             *Cell,
166   OUT UINT8                          *Attributes OPTIONAL
167   )
168 {
169   HII_DATABASE_RECORD                *Node;
170   LIST_ENTRY                         *Link;
171   HII_SIMPLE_FONT_PACKAGE_INSTANCE   *SimpleFont;
172   LIST_ENTRY                         *Link1;
173   UINT16                             Index;
174   EFI_NARROW_GLYPH                   Narrow;
175   EFI_WIDE_GLYPH                     Wide;
176   HII_GLOBAL_FONT_INFO               *GlobalFont;
177   UINTN                              HeaderSize;
178   EFI_NARROW_GLYPH                   *NarrowPtr;
179   EFI_WIDE_GLYPH                     *WidePtr;
180 
181   if (GlyphBuffer == NULL || Cell == NULL) {
182     return EFI_INVALID_PARAMETER;
183   }
184   if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
185     return EFI_INVALID_PARAMETER;
186   }
187 
188   ZeroMem (Cell, sizeof (EFI_HII_GLYPH_INFO));
189 
190   //
191   // If StringInfo is not NULL, it must point to an existing EFI_FONT_INFO rather
192   // than system default font and color.
193   // If NULL, try to find the character in simplified font packages since
194   // default system font is the fixed font (narrow or wide glyph).
195   //
196   if (StringInfo != NULL) {
197     if(!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {
198       return EFI_INVALID_PARAMETER;
199     }
200     if (Attributes != NULL) {
201       *Attributes = PROPORTIONAL_GLYPH;
202     }
203     return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);
204   } else {
205     HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);
206 
207     for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
208       Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
209       for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;
210            Link1 != &Node->PackageList->SimpleFontPkgHdr;
211            Link1 = Link1->ForwardLink
212           ) {
213         SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
214         //
215         // Search the narrow glyph array
216         //
217         NarrowPtr = (EFI_NARROW_GLYPH *) ((UINT8 *) (SimpleFont->SimpleFontPkgHdr) + HeaderSize);
218         for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {
219           CopyMem (&Narrow, NarrowPtr + Index,sizeof (EFI_NARROW_GLYPH));
220           if (Narrow.UnicodeWeight == Char) {
221             *GlyphBuffer = (UINT8 *) AllocateZeroPool (EFI_GLYPH_HEIGHT);
222             if (*GlyphBuffer == NULL) {
223               return EFI_OUT_OF_RESOURCES;
224             }
225             Cell->Width    = EFI_GLYPH_WIDTH;
226             Cell->Height   = EFI_GLYPH_HEIGHT;
227             Cell->AdvanceX = Cell->Width;
228             CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);
229             if (Attributes != NULL) {
230               *Attributes = (UINT8) (Narrow.Attributes | NARROW_GLYPH);
231             }
232             return EFI_SUCCESS;
233           }
234         }
235         //
236         // Search the wide glyph array
237         //
238         WidePtr = (EFI_WIDE_GLYPH *) (NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);
239         for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {
240           CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));
241           if (Wide.UnicodeWeight == Char) {
242             *GlyphBuffer    = (UINT8 *) AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);
243             if (*GlyphBuffer == NULL) {
244               return EFI_OUT_OF_RESOURCES;
245             }
246             Cell->Width    = EFI_GLYPH_WIDTH * 2;
247             Cell->Height   = EFI_GLYPH_HEIGHT;
248             Cell->AdvanceX = Cell->Width;
249             CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);
250             CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);
251             if (Attributes != NULL) {
252               *Attributes = (UINT8) (Wide.Attributes | EFI_GLYPH_WIDE);
253             }
254             return EFI_SUCCESS;
255           }
256         }
257       }
258     }
259   }
260 
261   return EFI_NOT_FOUND;
262 }
263 
264 /**
265   Convert bitmap data of the glyph to blt structure.
266 
267   This is a internal function.
268 
269   @param GlyphBuffer     Buffer points to bitmap data of glyph.
270   @param  Foreground     The color of the "on" pixels in the glyph in the
271                          bitmap.
272   @param  Background     The color of the "off" pixels in the glyph in the
273                          bitmap.
274   @param  ImageWidth     Width of the whole image in pixels.
275   @param  RowWidth       The width of the text on the line, in pixels.
276   @param  RowHeight      The height of the line, in pixels.
277   @param  Transparent    If TRUE, the Background color is ignored and all
278                          "off" pixels in the character's drawn wil use the
279                          pixel value from BltBuffer.
280   @param  Origin         On input, points to the origin of the to be
281                          displayed character, on output, points to the
282                          next glyph's origin.
283 
284 **/
285 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)286 NarrowGlyphToBlt (
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   if (RowWidth < Width) {
320     Width = (UINT8) RowWidth;
321   }
322 
323   for (Ypos = 0; Ypos < Height; Ypos++) {
324     for (Xpos = 0; Xpos < Width; Xpos++) {
325       if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {
326         Buffer[Ypos * ImageWidth + Xpos] = Foreground;
327       } else {
328         if (!Transparent) {
329           Buffer[Ypos * ImageWidth + Xpos] = Background;
330         }
331       }
332     }
333   }
334 
335   *Origin = *Origin + EFI_GLYPH_WIDTH;
336 }
337 
338 
339 /**
340   Convert bitmap data of the glyph to blt structure.
341 
342   This is a internal function.
343 
344   @param  GlyphBuffer             Buffer points to bitmap data of glyph.
345   @param  Foreground              The color of the "on" pixels in the glyph in the
346                                   bitmap.
347   @param  Background              The color of the "off" pixels in the glyph in the
348                                   bitmap.
349   @param  ImageWidth              Width of the whole image in pixels.
350   @param  BaseLine                BaseLine in the line.
351   @param  RowWidth                The width of the text on the line, in pixels.
352   @param  RowHeight               The height of the line, in pixels.
353   @param  Transparent             If TRUE, the Background color is ignored and all
354                                   "off" pixels in the character's drawn wil use the
355                                   pixel value from BltBuffer.
356   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.
357   @param  Attributes              The attribute of incoming glyph in GlyphBuffer.
358   @param  Origin                  On input, points to the origin of the to be
359                                   displayed character, on output, points to the
360                                   next glyph's origin.
361 
362 
363 **/
364 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)365 GlyphToBlt (
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   // Move position to the left-top corner of char.
398   //
399   BltBuffer  = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;
400   YposOffset = (UINT16) (BaseLine - (Cell->OffsetY + Cell->Height));
401 
402   //
403   // Since non-spacing key will be printed OR'd with the previous glyph, don't
404   // write 0.
405   //
406   if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
407     Transparent = TRUE;
408   }
409 
410   //
411   // The glyph's upper left hand corner pixel is the most significant bit of the
412   // first bitmap byte.
413   //
414   for (Ypos = 0; Ypos < Cell->Height && ((UINTN) (Ypos + YposOffset) < RowHeight); Ypos++) {
415     OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);
416 
417     //
418     // All bits in these bytes are meaningful.
419     //
420     for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {
421       Data  = *(GlyphBuffer + OffsetY + Xpos);
422       for (Index = 0; Index < 8 && ((UINTN) (Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
423         if ((Data & (1 << (8 - Index - 1))) != 0) {
424           BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
425         } else {
426           if (!Transparent) {
427             BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
428           }
429         }
430       }
431     }
432 
433     if (Cell->Width % 8 != 0) {
434       //
435       // There are some padding bits in this byte. Ignore them.
436       //
437       Data  = *(GlyphBuffer + OffsetY + Xpos);
438       for (Index = 0; Index < Cell->Width % 8 && ((UINTN) (Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
439         if ((Data & (1 << (8 - Index - 1))) != 0) {
440           BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
441         } else {
442           if (!Transparent) {
443             BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
444           }
445         }
446       }
447     } // end of if (Width % 8...)
448 
449   } // end of for (Ypos=0...)
450 
451   *Origin = *Origin + Cell->AdvanceX;
452 }
453 
454 
455 /**
456   Convert bitmap data of the glyph to blt structure.
457 
458   This is a internal function.
459 
460   @param  GlyphBuffer             Buffer points to bitmap data of glyph.
461   @param  Foreground              The color of the "on" pixels in the glyph in the
462                                   bitmap.
463   @param  Background              The color of the "off" pixels in the glyph in the
464                                   bitmap.
465   @param  ImageWidth              Width of the whole image in pixels.
466   @param  BaseLine                BaseLine in the line.
467   @param  RowWidth                The width of the text on the line, in pixels.
468   @param  RowHeight               The height of the line, in pixels.
469   @param  Transparent             If TRUE, the Background color is ignored and all
470                                   "off" pixels in the character's drawn wil use the
471                                   pixel value from BltBuffer.
472   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.
473   @param  Attributes              The attribute of incoming glyph in GlyphBuffer.
474   @param  Origin                  On input, points to the origin of the to be
475                                   displayed character, on output, points to the
476                                   next glyph's origin.
477 
478   @return Points to the address of next origin node in BltBuffer.
479 
480 **/
481 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)482 GlyphToImage (
483   IN     UINT8                         *GlyphBuffer,
484   IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
485   IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
486   IN     UINT16                        ImageWidth,
487   IN     UINT16                        BaseLine,
488   IN     UINTN                         RowWidth,
489   IN     UINTN                         RowHeight,
490   IN     BOOLEAN                       Transparent,
491   IN     CONST EFI_HII_GLYPH_INFO      *Cell,
492   IN     UINT8                         Attributes,
493   IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
494   )
495 {
496   EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;
497 
498   ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
499 
500   Buffer = *Origin;
501 
502   if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
503     //
504     // This character is a non-spacing key, print it OR'd with the previous glyph.
505     // without advancing cursor.
506     //
507     Buffer -= Cell->AdvanceX;
508     GlyphToBlt (
509       GlyphBuffer,
510       Foreground,
511       Background,
512       ImageWidth,
513       BaseLine,
514       RowWidth,
515       RowHeight,
516       Transparent,
517       Cell,
518       Attributes,
519       &Buffer
520       );
521 
522   } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {
523     //
524     // This character is wide glyph, i.e. 16 pixels * 19 pixels.
525     // Draw it as two narrow glyphs.
526     //
527     NarrowGlyphToBlt (
528       GlyphBuffer,
529       Foreground,
530       Background,
531       ImageWidth,
532       RowWidth,
533       RowHeight,
534       Transparent,
535       Origin
536       );
537 
538     NarrowGlyphToBlt (
539       GlyphBuffer + EFI_GLYPH_HEIGHT,
540       Foreground,
541       Background,
542       ImageWidth,
543       RowWidth,
544       RowHeight,
545       Transparent,
546       Origin
547       );
548 
549   } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {
550     //
551     // This character is narrow glyph, i.e. 8 pixels * 19 pixels.
552     //
553     NarrowGlyphToBlt (
554       GlyphBuffer,
555       Foreground,
556       Background,
557       ImageWidth,
558       RowWidth,
559       RowHeight,
560       Transparent,
561       Origin
562       );
563 
564   } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {
565     //
566     // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.
567     //
568     GlyphToBlt (
569       GlyphBuffer,
570       Foreground,
571       Background,
572       ImageWidth,
573       BaseLine,
574       RowWidth,
575       RowHeight,
576       Transparent,
577       Cell,
578       Attributes,
579       Origin
580       );
581   }
582 }
583 
584 
585 /**
586   Write the output parameters of FindGlyphBlock().
587 
588   This is a internal function.
589 
590   @param  BufferIn                Buffer which stores the bitmap data of the found
591                                   block.
592   @param  BufferLen               Length of BufferIn.
593   @param  InputCell               Buffer which stores cell information of the
594                                   encoded bitmap.
595   @param  GlyphBuffer             Output the corresponding bitmap data of the found
596                                   block. It is the caller's responsiblity to free
597                                   this buffer.
598   @param  Cell                    Output cell information of the encoded bitmap.
599   @param  GlyphBufferLen          If not NULL, output the length of GlyphBuffer.
600 
601   @retval EFI_SUCCESS             The operation is performed successfully.
602   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
603   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
604                                   task.
605 
606 **/
607 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)608 WriteOutputParam (
609   IN  UINT8                          *BufferIn,
610   IN  UINTN                          BufferLen,
611   IN  EFI_HII_GLYPH_INFO             *InputCell,
612   OUT UINT8                          **GlyphBuffer, OPTIONAL
613   OUT EFI_HII_GLYPH_INFO             *Cell, OPTIONAL
614   OUT UINTN                          *GlyphBufferLen OPTIONAL
615   )
616 {
617   if (BufferIn == NULL || InputCell == NULL) {
618     return EFI_INVALID_PARAMETER;
619   }
620 
621   if (Cell != NULL) {
622     CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));
623   }
624 
625   if (GlyphBuffer != NULL && BufferLen > 0) {
626     *GlyphBuffer = (UINT8 *) AllocateZeroPool (BufferLen);
627     if (*GlyphBuffer == NULL) {
628       return EFI_OUT_OF_RESOURCES;
629     }
630     CopyMem (*GlyphBuffer, BufferIn, BufferLen);
631   }
632 
633   if (GlyphBufferLen != NULL) {
634     *GlyphBufferLen = BufferLen;
635   }
636 
637   return EFI_SUCCESS;
638 }
639 
640 
641 /**
642   Parse all glyph blocks to find a glyph block specified by CharValue.
643   If CharValue = (CHAR16) (-1), collect all default character cell information
644   within this font package and backup its information.
645 
646   @param  FontPackage             Hii string package instance.
647   @param  CharValue               Unicode character value, which identifies a glyph
648                                   block.
649   @param  GlyphBuffer             Output the corresponding bitmap data of the found
650                                   block. It is the caller's responsiblity to free
651                                   this buffer.
652   @param  Cell                    Output cell information of the encoded bitmap.
653   @param  GlyphBufferLen          If not NULL, output the length of GlyphBuffer.
654 
655   @retval EFI_SUCCESS             The bitmap data is retrieved successfully.
656   @retval EFI_NOT_FOUND           The specified CharValue does not exist in current
657                                   database.
658   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
659                                   task.
660 
661 **/
662 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)663 FindGlyphBlock (
664   IN  HII_FONT_PACKAGE_INSTANCE      *FontPackage,
665   IN  CHAR16                         CharValue,
666   OUT UINT8                          **GlyphBuffer, OPTIONAL
667   OUT EFI_HII_GLYPH_INFO             *Cell, OPTIONAL
668   OUT UINTN                          *GlyphBufferLen OPTIONAL
669   )
670 {
671   EFI_STATUS                          Status;
672   UINT8                               *BlockPtr;
673   UINT16                              CharCurrent;
674   UINT16                              Length16;
675   UINT32                              Length32;
676   EFI_HII_GIBT_GLYPHS_BLOCK           Glyphs;
677   UINTN                               BufferLen;
678   UINT16                              Index;
679   EFI_HII_GLYPH_INFO                  DefaultCell;
680   EFI_HII_GLYPH_INFO                  LocalCell;
681   INT16                               MinOffsetY;
682   UINT16                              BaseLine;
683 
684   ASSERT (FontPackage != NULL);
685   ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);
686   BaseLine  = 0;
687   MinOffsetY = 0;
688 
689   if (CharValue == (CHAR16) (-1)) {
690     //
691     // Collect the cell information specified in font package fixed header.
692     // Use CharValue =0 to represent this particular cell.
693     //
694     Status = NewCell (
695                0,
696                &FontPackage->GlyphInfoList,
697                (EFI_HII_GLYPH_INFO *) ((UINT8 *) FontPackage->FontPkgHdr + 3 * sizeof (UINT32))
698                );
699     if (EFI_ERROR (Status)) {
700       return Status;
701     }
702     CopyMem (
703       &LocalCell,
704       (UINT8 *) FontPackage->FontPkgHdr + 3 * sizeof (UINT32),
705       sizeof (EFI_HII_GLYPH_INFO)
706       );
707     BaseLine = (UINT16) (LocalCell.Height + LocalCell.OffsetY);
708     if (MinOffsetY > LocalCell.OffsetY) {
709       MinOffsetY = LocalCell.OffsetY;
710     }
711   }
712 
713   BlockPtr    = FontPackage->GlyphBlock;
714   CharCurrent = 1;
715   BufferLen   = 0;
716 
717   while (*BlockPtr != EFI_HII_GIBT_END) {
718     switch (*BlockPtr) {
719     case EFI_HII_GIBT_DEFAULTS:
720       //
721       // Collect all default character cell information specified by
722       // EFI_HII_GIBT_DEFAULTS.
723       //
724       if (CharValue == (CHAR16) (-1)) {
725         Status = NewCell (
726                    CharCurrent,
727                    &FontPackage->GlyphInfoList,
728                    (EFI_HII_GLYPH_INFO *) (BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))
729                    );
730         if (EFI_ERROR (Status)) {
731           return Status;
732         }
733         CopyMem (
734           &LocalCell,
735           BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
736           sizeof (EFI_HII_GLYPH_INFO)
737           );
738         if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
739           BaseLine = (UINT16) (LocalCell.Height + LocalCell.OffsetY);
740         }
741         if (MinOffsetY > LocalCell.OffsetY) {
742           MinOffsetY = LocalCell.OffsetY;
743         }
744       }
745       BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);
746       break;
747 
748     case EFI_HII_GIBT_DUPLICATE:
749       if (CharCurrent == CharValue) {
750         CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));
751         CharCurrent = 1;
752         BlockPtr    = FontPackage->GlyphBlock;
753         continue;
754       }
755       CharCurrent++;
756       BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);
757       break;
758 
759     case EFI_HII_GIBT_EXT1:
760       BlockPtr += *(UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));
761       break;
762     case EFI_HII_GIBT_EXT2:
763       CopyMem (
764         &Length16,
765         (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
766         sizeof (UINT16)
767         );
768       BlockPtr += Length16;
769       break;
770     case EFI_HII_GIBT_EXT4:
771       CopyMem (
772         &Length32,
773         (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
774         sizeof (UINT32)
775         );
776       BlockPtr += Length32;
777       break;
778 
779     case EFI_HII_GIBT_GLYPH:
780       CopyMem (
781         &LocalCell,
782         BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
783         sizeof (EFI_HII_GLYPH_INFO)
784         );
785       if (CharValue == (CHAR16) (-1)) {
786         if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
787           BaseLine = (UINT16) (LocalCell.Height + LocalCell.OffsetY);
788         }
789         if (MinOffsetY > LocalCell.OffsetY) {
790           MinOffsetY = LocalCell.OffsetY;
791         }
792       }
793       BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);
794       if (CharCurrent == CharValue) {
795         return WriteOutputParam (
796                  (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),
797                  BufferLen,
798                  &LocalCell,
799                  GlyphBuffer,
800                  Cell,
801                  GlyphBufferLen
802                  );
803       }
804       CharCurrent++;
805       BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;
806       break;
807 
808     case EFI_HII_GIBT_GLYPHS:
809       BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);
810       CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));
811       BlockPtr += sizeof (EFI_HII_GLYPH_INFO);
812       CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));
813       BlockPtr += sizeof (UINT16);
814 
815       if (CharValue == (CHAR16) (-1)) {
816         if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {
817           BaseLine = (UINT16) (Glyphs.Cell.Height + Glyphs.Cell.OffsetY);
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         BlockPtr += BufferLen;
837       }
838       CharCurrent = (UINT16) (CharCurrent + Glyphs.Count);
839       break;
840 
841     case EFI_HII_GIBT_GLYPH_DEFAULT:
842       Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
843       if (EFI_ERROR (Status)) {
844         return Status;
845       }
846       BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
847 
848       if (CharCurrent == CharValue) {
849         return WriteOutputParam (
850                  BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
851                  BufferLen,
852                  &DefaultCell,
853                  GlyphBuffer,
854                  Cell,
855                  GlyphBufferLen
856                  );
857       }
858       CharCurrent++;
859       BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;
860       break;
861 
862     case EFI_HII_GIBT_GLYPHS_DEFAULT:
863       CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
864       Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
865       if (EFI_ERROR (Status)) {
866         return Status;
867       }
868       BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
869       BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);
870       for (Index = 0; Index < Length16; Index++) {
871         if (CharCurrent + Index == CharValue) {
872           return WriteOutputParam (
873                    BlockPtr,
874                    BufferLen,
875                    &DefaultCell,
876                    GlyphBuffer,
877                    Cell,
878                    GlyphBufferLen
879                    );
880         }
881         BlockPtr += BufferLen;
882       }
883       CharCurrent = (UINT16) (CharCurrent + Length16);
884       break;
885 
886     case EFI_HII_GIBT_SKIP1:
887       CharCurrent = (UINT16) (CharCurrent + (UINT16) (*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));
888       BlockPtr    += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);
889       break;
890     case EFI_HII_GIBT_SKIP2:
891       CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
892       CharCurrent = (UINT16) (CharCurrent + Length16);
893       BlockPtr    += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);
894       break;
895     default:
896       ASSERT (FALSE);
897       break;
898     }
899 
900     if (CharValue < CharCurrent) {
901       return EFI_NOT_FOUND;
902     }
903   }
904 
905   if (CharValue == (CHAR16) (-1)) {
906     FontPackage->BaseLine = BaseLine;
907     FontPackage->Height   = (UINT16) (BaseLine - MinOffsetY);
908     return EFI_SUCCESS;
909   }
910 
911   return EFI_NOT_FOUND;
912 }
913 
914 
915 /**
916   Copy a Font Name to a new created EFI_FONT_INFO structure.
917 
918   This is a internal function.
919 
920   @param  FontName                NULL-terminated string.
921   @param  FontInfo                a new EFI_FONT_INFO which stores the FontName.
922                                   It's caller's responsibility to free this buffer.
923 
924   @retval EFI_SUCCESS             FontInfo is allocated and copied with FontName.
925   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
926                                   task.
927 
928 **/
929 EFI_STATUS
SaveFontName(IN EFI_STRING FontName,OUT EFI_FONT_INFO ** FontInfo)930 SaveFontName (
931   IN  EFI_STRING                       FontName,
932   OUT EFI_FONT_INFO                    **FontInfo
933   )
934 {
935   UINTN         FontInfoLen;
936   UINTN         NameSize;
937 
938   ASSERT (FontName != NULL && FontInfo != NULL);
939 
940   NameSize = StrSize (FontName);
941   FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;
942   *FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoLen);
943   if (*FontInfo == NULL) {
944     return EFI_OUT_OF_RESOURCES;
945   }
946 
947   StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);
948   return EFI_SUCCESS;
949 }
950 
951 
952 /**
953   Retrieve system default font and color.
954 
955   @param  Private                 HII database driver private data.
956   @param  FontInfo                Points to system default font output-related
957                                   information. It's caller's responsibility to free
958                                   this buffer.
959   @param  FontInfoSize            If not NULL, output the size of buffer FontInfo.
960 
961   @retval EFI_SUCCESS             Cell information is added to the GlyphInfoList.
962   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
963                                   task.
964   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
965 
966 **/
967 EFI_STATUS
GetSystemFont(IN HII_DATABASE_PRIVATE_DATA * Private,OUT EFI_FONT_DISPLAY_INFO ** FontInfo,OUT UINTN * FontInfoSize OPTIONAL)968 GetSystemFont (
969   IN  HII_DATABASE_PRIVATE_DATA      *Private,
970   OUT EFI_FONT_DISPLAY_INFO          **FontInfo,
971   OUT UINTN                          *FontInfoSize OPTIONAL
972   )
973 {
974   EFI_FONT_DISPLAY_INFO              *Info;
975   UINTN                              InfoSize;
976   UINTN                              NameSize;
977 
978   if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
979     return EFI_INVALID_PARAMETER;
980   }
981   if (FontInfo == NULL) {
982     return EFI_INVALID_PARAMETER;
983   }
984 
985   //
986   // The standard font always has the name "sysdefault".
987   //
988   NameSize = StrSize (L"sysdefault");
989   InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
990   Info = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (InfoSize);
991   if (Info == NULL) {
992     return EFI_OUT_OF_RESOURCES;
993   }
994 
995   Info->ForegroundColor    = mHiiEfiColors[Private->Attribute & 0x0f];
996   Info->BackgroundColor    = mHiiEfiColors[Private->Attribute >> 4];
997   Info->FontInfoMask       = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;
998   Info->FontInfo.FontStyle = 0;
999   Info->FontInfo.FontSize  = EFI_GLYPH_HEIGHT;
1000   StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");
1001 
1002   *FontInfo = Info;
1003   if (FontInfoSize != NULL) {
1004     *FontInfoSize = InfoSize;
1005   }
1006   return EFI_SUCCESS;
1007 }
1008 
1009 
1010 /**
1011   Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or
1012   returns the system default according to the optional inputs.
1013 
1014   This is a internal function.
1015 
1016   @param  Private                 HII database driver private data.
1017   @param  StringInfo              Points to the string output information,
1018                                   including the color and font.
1019   @param  SystemInfo              If not NULL, points to system default font and color.
1020 
1021   @param  SystemInfoLen           If not NULL, output the length of default system
1022                                   info.
1023 
1024   @retval TRUE                    Yes, it points to system default.
1025   @retval FALSE                   No.
1026 
1027 **/
1028 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)1029 IsSystemFontInfo (
1030   IN  HII_DATABASE_PRIVATE_DATA      *Private,
1031   IN  EFI_FONT_DISPLAY_INFO          *StringInfo,
1032   OUT EFI_FONT_DISPLAY_INFO          **SystemInfo, OPTIONAL
1033   OUT UINTN                          *SystemInfoLen OPTIONAL
1034   )
1035 {
1036   EFI_STATUS                          Status;
1037   EFI_FONT_DISPLAY_INFO               *SystemDefault;
1038   UINTN                               DefaultLen;
1039   BOOLEAN                             Flag;
1040 
1041   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
1042 
1043   if (StringInfo == NULL && SystemInfo == NULL) {
1044     return TRUE;
1045   }
1046 
1047   SystemDefault = NULL;
1048   DefaultLen    = 0;
1049 
1050   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);
1051   ASSERT_EFI_ERROR (Status);
1052   ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));
1053 
1054   //
1055   // Record the system default info.
1056   //
1057   if (SystemInfo != NULL) {
1058     *SystemInfo = SystemDefault;
1059   }
1060 
1061   if (SystemInfoLen != NULL) {
1062     *SystemInfoLen = DefaultLen;
1063   }
1064 
1065   if (StringInfo == NULL) {
1066     return TRUE;
1067   }
1068 
1069   Flag = FALSE;
1070   //
1071   // Check the FontInfoMask to see whether it is retrieving system info.
1072   //
1073   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {
1074     if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {
1075       goto Exit;
1076     }
1077   }
1078   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {
1079     if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {
1080       goto Exit;
1081     }
1082   }
1083   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {
1084     if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {
1085       goto Exit;
1086     }
1087   }
1088   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {
1089     if (CompareMem (
1090           &StringInfo->ForegroundColor,
1091           &SystemDefault->ForegroundColor,
1092           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1093           ) != 0) {
1094       goto Exit;
1095     }
1096   }
1097   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {
1098     if (CompareMem (
1099           &StringInfo->BackgroundColor,
1100           &SystemDefault->BackgroundColor,
1101           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
1102           ) != 0) {
1103       goto Exit;
1104     }
1105   }
1106 
1107   Flag = TRUE;
1108 
1109 Exit:
1110   if (SystemInfo == NULL) {
1111     if (SystemDefault != NULL) {
1112       FreePool (SystemDefault);
1113     }
1114   }
1115   return Flag;
1116 }
1117 
1118 
1119 /**
1120   This function checks whether EFI_FONT_INFO exists in current database. If
1121   FontInfoMask is specified, check what options can be used to make a match.
1122   Note that the masks relate to where the system default should be supplied
1123   are ignored by this function.
1124 
1125   @param  Private                 Hii database private structure.
1126   @param  FontInfo                Points to EFI_FONT_INFO structure.
1127   @param  FontInfoMask            If not NULL, describes what options can be used
1128                                   to make a match between the font requested and
1129                                   the font available. The caller must guarantee
1130                                   this mask is valid.
1131   @param  FontHandle              On entry, Points to the font handle returned by a
1132                                   previous  call to GetFontInfo() or NULL to start
1133                                   with the first font.
1134   @param  GlobalFontInfo          If not NULL, output the corresponding globa font
1135                                   info.
1136 
1137   @retval TRUE                    Existed
1138   @retval FALSE                   Not existed
1139 
1140 **/
1141 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)1142 IsFontInfoExisted (
1143   IN  HII_DATABASE_PRIVATE_DATA *Private,
1144   IN  EFI_FONT_INFO             *FontInfo,
1145   IN  EFI_FONT_INFO_MASK        *FontInfoMask,   OPTIONAL
1146   IN  EFI_FONT_HANDLE           FontHandle,      OPTIONAL
1147   OUT HII_GLOBAL_FONT_INFO      **GlobalFontInfo OPTIONAL
1148   )
1149 {
1150   HII_GLOBAL_FONT_INFO          *GlobalFont;
1151   HII_GLOBAL_FONT_INFO          *GlobalFontBackup1;
1152   HII_GLOBAL_FONT_INFO          *GlobalFontBackup2;
1153   LIST_ENTRY                    *Link;
1154   EFI_FONT_INFO_MASK            Mask;
1155   BOOLEAN                       Matched;
1156   BOOLEAN                       VagueMatched1;
1157   BOOLEAN                       VagueMatched2;
1158 
1159   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
1160   ASSERT (FontInfo != NULL);
1161 
1162   //
1163   // Matched flag represents an exactly match; VagueMatched1 repensents a RESIZE
1164   // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.
1165   //
1166   Matched           = FALSE;
1167   VagueMatched1     = FALSE;
1168   VagueMatched2     = FALSE;
1169 
1170   Mask              = 0;
1171   GlobalFontBackup1 = NULL;
1172   GlobalFontBackup2 = NULL;
1173 
1174   // The process of where the system default should be supplied instead of
1175   // the specified font info beyonds this function's scope.
1176   //
1177   if (FontInfoMask != NULL) {
1178     Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);
1179   }
1180 
1181   //
1182   // If not NULL, FontHandle points to the next node of the last searched font
1183   // node by previous call.
1184   //
1185   if (FontHandle == NULL) {
1186     Link = Private->FontInfoList.ForwardLink;
1187   } else {
1188     Link = (LIST_ENTRY     *) FontHandle;
1189   }
1190 
1191   for (; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
1192     GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
1193     if (FontInfoMask == NULL) {
1194       if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {
1195         if (GlobalFontInfo != NULL) {
1196           *GlobalFontInfo = GlobalFont;
1197         }
1198         return TRUE;
1199       }
1200     } else {
1201       //
1202       // Check which options could be used to make a match.
1203       //
1204       switch (Mask) {
1205       case EFI_FONT_INFO_ANY_FONT:
1206         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle &&
1207             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1208           Matched = TRUE;
1209         }
1210         break;
1211       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:
1212         if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1213           Matched = TRUE;
1214         }
1215         break;
1216       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:
1217         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1218           Matched = TRUE;
1219         }
1220         break;
1221       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:
1222         Matched   = TRUE;
1223         break;
1224       //
1225       // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to
1226       // remove some of the specified styles to meet the style requested.
1227       //
1228       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:
1229         if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
1230           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1231             Matched           = TRUE;
1232           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1233             VagueMatched1     = TRUE;
1234             GlobalFontBackup1 = GlobalFont;
1235           }
1236         }
1237         break;
1238       //
1239       // If EFI_FONT_INFO_RESIZE is specified, then the sytem may attempt to
1240       // stretch or shrink a font to meet the size requested.
1241       //
1242       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:
1243         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1244           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1245             Matched           = TRUE;
1246           } else {
1247             VagueMatched1     = TRUE;
1248             GlobalFontBackup1 = GlobalFont;
1249           }
1250         }
1251         break;
1252       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:
1253         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1254           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1255             Matched           = TRUE;
1256           } else {
1257             VagueMatched1     = TRUE;
1258             GlobalFontBackup1 = GlobalFont;
1259           }
1260         } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1261           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1262             VagueMatched1     = TRUE;
1263             GlobalFontBackup1 = GlobalFont;
1264           } else {
1265             VagueMatched2     = TRUE;
1266             GlobalFontBackup2 = GlobalFont;
1267           }
1268         }
1269         break;
1270       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
1271         if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1272           Matched           = TRUE;
1273         } else {
1274           VagueMatched1     = TRUE;
1275           GlobalFontBackup1 = GlobalFont;
1276         }
1277         break;
1278       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
1279         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1280           Matched           = TRUE;
1281         } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1282           VagueMatched1     = TRUE;
1283           GlobalFontBackup1 = GlobalFont;
1284         }
1285         break;
1286       case EFI_FONT_INFO_ANY_STYLE:
1287         if ((CompareMem (
1288                GlobalFont->FontInfo->FontName,
1289                FontInfo->FontName,
1290                StrSize (FontInfo->FontName)
1291                ) == 0) &&
1292             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1293           Matched = TRUE;
1294         }
1295         break;
1296       case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:
1297         if (CompareMem (
1298               GlobalFont->FontInfo->FontName,
1299               FontInfo->FontName,
1300               StrSize (FontInfo->FontName)
1301               ) == 0) {
1302           Matched = TRUE;
1303         }
1304         break;
1305       case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
1306         if (CompareMem (
1307               GlobalFont->FontInfo->FontName,
1308               FontInfo->FontName,
1309               StrSize (FontInfo->FontName)
1310               ) == 0) {
1311           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1312             Matched           = TRUE;
1313           } else {
1314             VagueMatched1     = TRUE;
1315             GlobalFontBackup1 = GlobalFont;
1316           }
1317         }
1318         break;
1319       case EFI_FONT_INFO_ANY_SIZE:
1320         if ((CompareMem (
1321                GlobalFont->FontInfo->FontName,
1322                FontInfo->FontName,
1323                StrSize (FontInfo->FontName)
1324                ) == 0) &&
1325             GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {
1326           Matched = TRUE;
1327         }
1328         break;
1329       case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
1330         if (CompareMem (
1331               GlobalFont->FontInfo->FontName,
1332               FontInfo->FontName,
1333               StrSize (FontInfo->FontName)
1334               ) == 0) {
1335           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1336             Matched           = TRUE;
1337           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1338             VagueMatched1     = TRUE;
1339             GlobalFontBackup1 = GlobalFont;
1340           }
1341         }
1342         break;
1343       case EFI_FONT_INFO_RESTYLE:
1344         if ((CompareMem (
1345                GlobalFont->FontInfo->FontName,
1346                FontInfo->FontName,
1347                StrSize (FontInfo->FontName)
1348                ) == 0) &&
1349             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1350 
1351           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1352             Matched           = TRUE;
1353           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1354             VagueMatched1     = TRUE;
1355             GlobalFontBackup1 = GlobalFont;
1356           }
1357         }
1358         break;
1359       case EFI_FONT_INFO_RESIZE:
1360         if ((CompareMem (
1361                GlobalFont->FontInfo->FontName,
1362                FontInfo->FontName,
1363                StrSize (FontInfo->FontName)
1364                ) == 0) &&
1365             GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {
1366 
1367           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1368             Matched           = TRUE;
1369           } else {
1370             VagueMatched1     = TRUE;
1371             GlobalFontBackup1 = GlobalFont;
1372           }
1373         }
1374         break;
1375       case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:
1376         if (CompareMem (
1377               GlobalFont->FontInfo->FontName,
1378               FontInfo->FontName,
1379               StrSize (FontInfo->FontName)
1380               ) == 0) {
1381           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
1382             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1383               Matched           = TRUE;
1384             } else {
1385               VagueMatched1     = TRUE;
1386               GlobalFontBackup1 = GlobalFont;
1387             }
1388           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
1389             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
1390               VagueMatched1     = TRUE;
1391               GlobalFontBackup1 = GlobalFont;
1392             } else {
1393               VagueMatched2     = TRUE;
1394               GlobalFontBackup2 = GlobalFont;
1395             }
1396           }
1397         }
1398         break;
1399       default:
1400         break;
1401       }
1402 
1403       if (Matched) {
1404         if (GlobalFontInfo != NULL) {
1405           *GlobalFontInfo = GlobalFont;
1406         }
1407         return TRUE;
1408       }
1409     }
1410   }
1411 
1412   if (VagueMatched1) {
1413     if (GlobalFontInfo != NULL) {
1414       *GlobalFontInfo = GlobalFontBackup1;
1415     }
1416     return TRUE;
1417   } else if (VagueMatched2) {
1418     if (GlobalFontInfo != NULL) {
1419       *GlobalFontInfo = GlobalFontBackup2;
1420     }
1421     return TRUE;
1422   }
1423 
1424   return FALSE;
1425 }
1426 
1427 
1428 /**
1429   Check whether the unicode represents a line break or not.
1430 
1431   This is a internal function. Please see Section 27.2.6 of the UEFI Specification
1432   for a description of the supported string format.
1433 
1434   @param  Char                    Unicode character
1435 
1436   @retval 0                       Yes, it forces a line break.
1437   @retval 1                       Yes, it presents a line break opportunity
1438   @retval 2                       Yes, it requires a line break happen before and after it.
1439   @retval -1                      No, it is not a link break.
1440 
1441 **/
1442 INT8
IsLineBreak(IN CHAR16 Char)1443 IsLineBreak (
1444   IN  CHAR16    Char
1445   )
1446 {
1447   switch (Char) {
1448     //
1449     // Mandatory line break characters, which force a line-break
1450     //
1451     case 0x000A:
1452     case 0x000C:
1453     case 0x000D:
1454     case 0x2028:
1455     case 0x2029:
1456       return 0;
1457     //
1458     // Space characters, which is taken as a line-break opportunity
1459     //
1460     case 0x0020:
1461     case 0x1680:
1462     case 0x2000:
1463     case 0x2001:
1464     case 0x2002:
1465     case 0x2003:
1466     case 0x2004:
1467     case 0x2005:
1468     case 0x2006:
1469     case 0x2008:
1470     case 0x2009:
1471     case 0x200A:
1472     case 0x205F:
1473     //
1474     // In-Word Break Opportunities
1475     //
1476     case 0x200B:
1477       return 1;
1478     //
1479     // A space which is not a line-break opportunity
1480     //
1481     case 0x00A0:
1482     case 0x202F:
1483     //
1484     // A hyphen which is not a line-break opportunity
1485     //
1486     case 0x2011:
1487       return -1;
1488     //
1489     // Hyphen characters which describe line break opportunities after the character
1490     //
1491     case 0x058A:
1492     case 0x2010:
1493     case 0x2012:
1494     case 0x2013:
1495     case 0x0F0B:
1496     case 0x1361:
1497     case 0x17D5:
1498       return 1;
1499     //
1500     // A hyphen which describes line break opportunities before and after them, but not between a pair of them
1501     //
1502     case 0x2014:
1503       return 2;
1504   }
1505   return -1;
1506 }
1507 
1508 
1509 /**
1510   Renders a string to a bitmap or to the display.
1511 
1512   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
1513   @param  Flags                   Describes how the string is to be drawn.
1514   @param  String                  Points to the null-terminated string to be
1515                                   displayed.
1516   @param  StringInfo              Points to the string output information,
1517                                   including the color and font.  If NULL, then the
1518                                   string will be output in the default system font
1519                                   and color.
1520   @param  Blt                     If this points to a non-NULL on entry, this
1521                                   points to the image, which is Width pixels   wide
1522                                   and Height pixels high. The string will be drawn
1523                                   onto this image and
1524                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points
1525                                   to a NULL on entry, then a              buffer
1526                                   will be allocated to hold the generated image and
1527                                   the pointer updated on exit. It is the caller's
1528                                   responsibility to free this buffer.
1529   @param  BltX                    Specifies the offset from the left and top edge
1530                                   of the image of the first character cell in the
1531                                   image.
1532   @param  BltY                    Specifies the offset from the left and top edge
1533                                   of the image of the first character cell in the
1534                                   image.
1535   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this
1536                                   will point to an allocated buffer    containing
1537                                   row information and RowInfoArraySize will be
1538                                   updated to contain the        number of elements.
1539                                   This array describes the characters which were at
1540                                   least partially drawn and the heights of the
1541                                   rows. It is the caller's responsibility to free
1542                                   this buffer.
1543   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it
1544                                   contains the number of elements in RowInfoArray.
1545   @param  ColumnInfoArray         If this is non-NULL, then on return it will be
1546                                   filled with the horizontal offset for each
1547                                   character in the string on the row where it is
1548                                   displayed. Non-printing characters will     have
1549                                   the offset ~0. The caller is responsible to
1550                                   allocate a buffer large enough so that    there
1551                                   is one entry for each character in the string,
1552                                   not including the null-terminator. It is possible
1553                                   when character display is normalized that some
1554                                   character cells overlap.
1555 
1556   @retval EFI_SUCCESS             The string was successfully rendered.
1557   @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for
1558                                   RowInfoArray or Blt.
1559   @retval EFI_INVALID_PARAMETER   The String or Blt was NULL.
1560   @retval EFI_INVALID_PARAMETER Flags were invalid combination..
1561 
1562 **/
1563 EFI_STATUS
1564 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)1565 HiiStringToImage (
1566   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
1567   IN  EFI_HII_OUT_FLAGS              Flags,
1568   IN  CONST EFI_STRING               String,
1569   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,
1570   IN  OUT EFI_IMAGE_OUTPUT           **Blt,
1571   IN  UINTN                          BltX,
1572   IN  UINTN                          BltY,
1573   OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,
1574   OUT UINTN                          *RowInfoArraySize OPTIONAL,
1575   OUT UINTN                          *ColumnInfoArray  OPTIONAL
1576   )
1577 {
1578   EFI_STATUS                          Status;
1579   HII_DATABASE_PRIVATE_DATA           *Private;
1580   UINT8                               **GlyphBuf;
1581   EFI_HII_GLYPH_INFO                  *Cell;
1582   UINT8                               *Attributes;
1583   EFI_IMAGE_OUTPUT                    *Image;
1584   EFI_STRING                          StringPtr;
1585   EFI_STRING                          StringTmp;
1586   EFI_HII_ROW_INFO                    *RowInfo;
1587   UINTN                               LineWidth;
1588   UINTN                               LineHeight;
1589   UINTN                               LineOffset;
1590   UINTN                               LastLineHeight;
1591   UINTN                               BaseLineOffset;
1592   UINT16                              MaxRowNum;
1593   UINT16                              RowIndex;
1594   UINTN                               Index;
1595   UINTN                               NextIndex;
1596   UINTN                               Index1;
1597   EFI_FONT_DISPLAY_INFO               *StringInfoOut;
1598   EFI_FONT_DISPLAY_INFO               *SystemDefault;
1599   EFI_FONT_HANDLE                     FontHandle;
1600   EFI_STRING                          StringIn;
1601   EFI_STRING                          StringIn2;
1602   UINT16                              Height;
1603   UINT16                              BaseLine;
1604   EFI_FONT_INFO                       *FontInfo;
1605   BOOLEAN                             SysFontFlag;
1606   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Foreground;
1607   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Background;
1608   BOOLEAN                             Transparent;
1609   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BltBuffer;
1610   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BufferPtr;
1611   UINTN                               RowInfoSize;
1612   BOOLEAN                             LineBreak;
1613   UINTN                               StrLength;
1614   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *RowBufferPtr;
1615   HII_GLOBAL_FONT_INFO                *GlobalFont;
1616 
1617   //
1618   // Check incoming parameters.
1619   //
1620 
1621   if (This == NULL || String == NULL || Blt == NULL) {
1622     return EFI_INVALID_PARAMETER;
1623   }
1624   if (*Blt == NULL) {
1625     //
1626     // These two flag cannot be used if Blt is NULL upon entry.
1627     //
1628     if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {
1629       return EFI_INVALID_PARAMETER;
1630     }
1631     if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {
1632       return EFI_INVALID_PARAMETER;
1633     }
1634   }
1635   //
1636   // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
1637   //
1638   if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {
1639     return EFI_INVALID_PARAMETER;
1640   }
1641   if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
1642     return EFI_INVALID_PARAMETER;
1643   }
1644   //
1645   // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.
1646   //
1647   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)) {
1648     return EFI_INVALID_PARAMETER;
1649   }
1650 
1651   if (*Blt == NULL) {
1652     //
1653     // Create a new bitmap and draw the string onto this image.
1654     //
1655     Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
1656     if (Image == NULL) {
1657       return EFI_OUT_OF_RESOURCES;
1658     }
1659     Image->Width  = 800;
1660     Image->Height = 600;
1661     Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
1662     if (Image->Image.Bitmap == NULL) {
1663       FreePool (Image);
1664       return EFI_OUT_OF_RESOURCES;
1665     }
1666 
1667     //
1668     // Other flags are not permitted when Blt is NULL.
1669     //
1670     Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
1671     *Blt = Image;
1672   }
1673 
1674   StrLength = StrLen(String);
1675   GlyphBuf = (UINT8 **) AllocateZeroPool (StrLength * sizeof (UINT8 *));
1676   ASSERT (GlyphBuf != NULL);
1677   Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
1678   ASSERT (Cell != NULL);
1679   Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));
1680   ASSERT (Attributes != NULL);
1681 
1682   RowInfo       = NULL;
1683   Status        = EFI_SUCCESS;
1684   StringIn2     = NULL;
1685   SystemDefault = NULL;
1686   StringIn      = NULL;
1687 
1688   //
1689   // Calculate the string output information, including specified color and font .
1690   // If StringInfo does not points to system font info, it must indicate an existing
1691   // EFI_FONT_INFO.
1692   //
1693   StringInfoOut = NULL;
1694   FontHandle    = NULL;
1695   Private       = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1696   SysFontFlag   = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);
1697 
1698   if (SysFontFlag) {
1699     ASSERT (SystemDefault != NULL);
1700     FontInfo   = NULL;
1701     Height     = SystemDefault->FontInfo.FontSize;
1702     BaseLine   = SystemDefault->FontInfo.FontSize;
1703     Foreground = SystemDefault->ForegroundColor;
1704     Background = SystemDefault->BackgroundColor;
1705 
1706   } else {
1707     //
1708     //  StringInfo must not be NULL if it is not system info.
1709     //
1710     ASSERT (StringInfo != NULL);
1711     Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *) StringInfo, &StringInfoOut, NULL);
1712     if (Status == EFI_NOT_FOUND) {
1713       //
1714       // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
1715       // Use the system font instead. Still use the color specified by StringInfo.
1716       //
1717       SysFontFlag = TRUE;
1718       FontInfo    = NULL;
1719       Height      = SystemDefault->FontInfo.FontSize;
1720       BaseLine    = SystemDefault->FontInfo.FontSize;
1721       Foreground  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;
1722       Background  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;
1723 
1724     } else if (Status == EFI_SUCCESS) {
1725       FontInfo   = &StringInfoOut->FontInfo;
1726       IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);
1727       Height     = GlobalFont->FontPackage->Height;
1728       BaseLine   = GlobalFont->FontPackage->BaseLine;
1729       Foreground = StringInfoOut->ForegroundColor;
1730       Background = StringInfoOut->BackgroundColor;
1731     } else {
1732       goto Exit;
1733     }
1734   }
1735 
1736   //
1737   // Use the maxinum height of font as the base line.
1738   // And, use the maxinum height as line height.
1739   //
1740   LineHeight     = Height;
1741   LastLineHeight = Height;
1742   BaseLineOffset = Height - BaseLine;
1743 
1744   //
1745   // Parse the string to be displayed to drop some ignored characters.
1746   //
1747 
1748   StringPtr = String;
1749 
1750   //
1751   // Ignore line-break characters only. Hyphens or dash character will be displayed
1752   // without line-break opportunity.
1753   //
1754   if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
1755     StringIn = AllocateZeroPool (StrSize (StringPtr));
1756     if (StringIn == NULL) {
1757       Status = EFI_OUT_OF_RESOURCES;
1758       goto Exit;
1759     }
1760     StringTmp = StringIn;
1761     while (*StringPtr != 0) {
1762       if (IsLineBreak (*StringPtr) == 0) {
1763         StringPtr++;
1764       } else {
1765         *StringTmp++ = *StringPtr++;
1766       }
1767     }
1768     *StringTmp = 0;
1769     StringPtr  = StringIn;
1770   }
1771   //
1772   // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
1773   // are not drawn. Otherwise they are replaced wth Unicode character 0xFFFD.
1774   //
1775   StringIn2  = AllocateZeroPool (StrSize (StringPtr));
1776   if (StringIn2 == NULL) {
1777     Status = EFI_OUT_OF_RESOURCES;
1778     goto Exit;
1779   }
1780   Index     = 0;
1781   StringTmp = StringIn2;
1782   StrLength = StrLen(StringPtr);
1783   while (*StringPtr != 0 && Index < StrLength) {
1784     if (IsLineBreak (*StringPtr) == 0) {
1785       *StringTmp++ = *StringPtr++;
1786       Index++;
1787       continue;
1788     }
1789 
1790     Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
1791     if (Status == EFI_NOT_FOUND) {
1792       if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
1793         GlyphBuf[Index] = NULL;
1794         ZeroMem (&Cell[Index], sizeof (Cell[Index]));
1795         Status = EFI_SUCCESS;
1796       } else {
1797         //
1798         // Unicode 0xFFFD must exist in current hii database if this flag is not set.
1799         //
1800         Status = GetGlyphBuffer (
1801                    Private,
1802                    REPLACE_UNKNOWN_GLYPH,
1803                    FontInfo,
1804                    &GlyphBuf[Index],
1805                    &Cell[Index],
1806                    &Attributes[Index]
1807                    );
1808         if (EFI_ERROR (Status)) {
1809           Status = EFI_INVALID_PARAMETER;
1810         }
1811       }
1812     }
1813 
1814     if (EFI_ERROR (Status)) {
1815       goto Exit;
1816     }
1817 
1818     *StringTmp++ = *StringPtr++;
1819     Index++;
1820   }
1821   *StringTmp = 0;
1822   StringPtr  = StringIn2;
1823 
1824   //
1825   // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
1826   // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
1827   // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
1828   // Otherwise render this string to a new allocated image and output it.
1829   //
1830   Image     = *Blt;
1831   BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
1832   if (Image->Height < BltY) {
1833     //
1834     // the top edge of the image should be in Image resolution scope.
1835     //
1836     Status = EFI_INVALID_PARAMETER;
1837     goto Exit;
1838   }
1839   MaxRowNum = (UINT16) ((Image->Height - BltY) / Height);
1840   if ((Image->Height - BltY) % Height != 0) {
1841     LastLineHeight = (Image->Height - BltY) % Height;
1842     MaxRowNum++;
1843   }
1844 
1845   RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
1846   if (RowInfo == NULL) {
1847     Status = EFI_OUT_OF_RESOURCES;
1848     goto Exit;
1849   }
1850 
1851   //
1852   // Format the glyph buffer according to flags.
1853   //
1854   Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
1855 
1856   for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
1857     LineWidth      = 0;
1858     LineBreak      = FALSE;
1859 
1860     //
1861     // Clip the final row if the row's bottom-most on pixel cannot fit when
1862     // EFI_HII_OUT_FLAG_CLEAN_Y is set.
1863     //
1864     if (RowIndex == MaxRowNum - 1) {
1865       if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y && LastLineHeight < LineHeight ) {
1866         //
1867         // Don't draw at all if the row's bottom-most on pixel cannot fit.
1868         //
1869         break;
1870       }
1871       LineHeight = LastLineHeight;
1872     }
1873 
1874     //
1875     // Calculate how many characters there are in a row.
1876     //
1877     RowInfo[RowIndex].StartIndex = Index;
1878 
1879     while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
1880       if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&
1881            IsLineBreak (StringPtr[Index]) == 0) {
1882         //
1883         // It forces a line break that ends this row.
1884         //
1885         Index++;
1886         LineBreak = TRUE;
1887         break;
1888       }
1889 
1890       //
1891       // If the glyph of the character is existing, then accumulate the actual printed width
1892       //
1893       LineWidth += (UINTN) Cell[Index].AdvanceX;
1894 
1895       Index++;
1896     }
1897 
1898     //
1899     // Record index of next char.
1900     //
1901     NextIndex = Index;
1902     //
1903     // Return to the previous char.
1904     //
1905     Index--;
1906     if (LineBreak && Index > 0 ) {
1907       //
1908       // Return the previous non line break char.
1909       //
1910       Index --;
1911     }
1912 
1913     //
1914     // If this character is the last character of a row, we need not
1915     // draw its (AdvanceX - Width - OffsetX) for next character.
1916     //
1917     LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
1918 
1919     //
1920     // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
1921     //
1922     if (LineWidth + BltX <= Image->Width ||
1923       (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {
1924       //
1925       // Record right-most character in RowInfo even if it is partially displayed.
1926       //
1927       RowInfo[RowIndex].EndIndex       = Index;
1928       RowInfo[RowIndex].LineWidth      = LineWidth;
1929       RowInfo[RowIndex].LineHeight     = LineHeight;
1930       RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
1931     } else {
1932       //
1933       // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
1934       // if its right-most on pixel cannot fit.
1935       //
1936       if (Index > RowInfo[RowIndex].StartIndex) {
1937         //
1938         // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
1939         //
1940         LineWidth -= (UINTN) (Cell[Index].Width + Cell[Index].OffsetX);
1941         LineWidth -= (UINTN) (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
1942         RowInfo[RowIndex].EndIndex       = Index - 1;
1943         RowInfo[RowIndex].LineWidth      = LineWidth;
1944         RowInfo[RowIndex].LineHeight     = LineHeight;
1945         RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
1946       } else {
1947         //
1948         // There is no enough column to draw any character, so set current line width to zero.
1949         // And go to draw Next line if LineBreak is set.
1950         //
1951         RowInfo[RowIndex].LineWidth      = 0;
1952         goto NextLine;
1953       }
1954     }
1955 
1956     //
1957     // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
1958     // opportunity prior to a character whose right-most extent would exceed Width.
1959     // Search the right-most line-break opportunity here.
1960     //
1961     if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP &&
1962         (RowInfo[RowIndex].LineWidth + BltX > Image->Width || StringPtr[NextIndex] != 0) &&
1963         !LineBreak) {
1964       if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
1965         LineWidth = RowInfo[RowIndex].LineWidth;
1966         for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
1967           if (Index1 == RowInfo[RowIndex].EndIndex) {
1968             LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
1969           } else {
1970             LineWidth -= Cell[Index1].AdvanceX;
1971           }
1972           if (IsLineBreak (StringPtr[Index1]) > 0) {
1973             LineBreak = TRUE;
1974             if (Index1 > RowInfo[RowIndex].StartIndex) {
1975               RowInfo[RowIndex].EndIndex = Index1 - 1;
1976             }
1977             //
1978             // relocate to the character after the right-most line break opportunity of this line
1979             //
1980             NextIndex = Index1 + 1;
1981             break;
1982           }
1983           //
1984           // If don't find a line break opportunity from EndIndex to StartIndex,
1985           // then jump out.
1986           //
1987           if (Index1 == RowInfo[RowIndex].StartIndex)
1988             break;
1989         }
1990 
1991         //
1992         // Update LineWidth to the real width
1993         //
1994         if (IsLineBreak (StringPtr[Index1]) > 0) {
1995           if (Index1 == RowInfo[RowIndex].StartIndex) {
1996             LineWidth = 0;
1997           } else {
1998             LineWidth -= (UINTN) (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
1999           }
2000           RowInfo[RowIndex].LineWidth = LineWidth;
2001         }
2002       }
2003       //
2004       // If no line-break opportunity can be found, then the text will
2005       // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
2006       //
2007       if (!LineBreak) {
2008         LineWidth = RowInfo[RowIndex].LineWidth;
2009         Index1    = RowInfo[RowIndex].EndIndex;
2010         if (LineWidth + BltX > Image->Width) {
2011           if (Index1 > RowInfo[RowIndex].StartIndex) {
2012             //
2013             // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
2014             //
2015             LineWidth -= (UINTN) (Cell[Index1].Width + Cell[Index1].OffsetX);
2016             LineWidth -= (UINTN) (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
2017             RowInfo[RowIndex].EndIndex       = Index1 - 1;
2018             RowInfo[RowIndex].LineWidth      = LineWidth;
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 
2031     //
2032     // LineWidth can't exceed Image width.
2033     //
2034     if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
2035       RowInfo[RowIndex].LineWidth = Image->Width - BltX;
2036     }
2037 
2038     //
2039     // Draw it to screen or existing bitmap depending on whether
2040     // EFI_HII_DIRECT_TO_SCREEN is set.
2041     //
2042     LineOffset = 0;
2043     if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
2044       BltBuffer = NULL;
2045       if (RowInfo[RowIndex].LineWidth != 0) {
2046         BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2047         if (BltBuffer == NULL) {
2048           Status = EFI_OUT_OF_RESOURCES;
2049           goto Exit;
2050         }
2051         //
2052         // Set BufferPtr to Origin by adding baseline to the starting position.
2053         //
2054         BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
2055       }
2056       for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2057         if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {
2058           //
2059           // Only BLT these character which have corrsponding glyph in font basebase.
2060           //
2061           GlyphToImage (
2062             GlyphBuf[Index1],
2063             Foreground,
2064             Background,
2065             (UINT16) RowInfo[RowIndex].LineWidth,
2066             BaseLine,
2067             RowInfo[RowIndex].LineWidth - LineOffset,
2068             RowInfo[RowIndex].LineHeight,
2069             Transparent,
2070             &Cell[Index1],
2071             Attributes[Index1],
2072             &BufferPtr
2073           );
2074         }
2075         if (ColumnInfoArray != NULL) {
2076           if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)
2077               || RowInfo[RowIndex].LineWidth == 0) {
2078             *ColumnInfoArray = (UINTN) ~0;
2079           } else {
2080             *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2081           }
2082           ColumnInfoArray++;
2083         }
2084         LineOffset += Cell[Index1].AdvanceX;
2085       }
2086 
2087       if (BltBuffer != NULL) {
2088         Status = Image->Image.Screen->Blt (
2089                                         Image->Image.Screen,
2090                                         BltBuffer,
2091                                         EfiBltBufferToVideo,
2092                                         0,
2093                                         0,
2094                                         BltX,
2095                                         BltY,
2096                                         RowInfo[RowIndex].LineWidth,
2097                                         RowInfo[RowIndex].LineHeight,
2098                                         0
2099                                         );
2100         if (EFI_ERROR (Status)) {
2101           FreePool (BltBuffer);
2102           goto Exit;
2103         }
2104 
2105         FreePool (BltBuffer);
2106       }
2107     } else {
2108       //
2109       // Save the starting position for calculate the starting postition of next row.
2110       //
2111       RowBufferPtr = BufferPtr;
2112       //
2113       // Set BufferPtr to Origin by adding baseline to the starting position.
2114       //
2115       BufferPtr = BufferPtr + BaseLine * Image->Width;
2116       for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2117         if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {
2118           //
2119           // Only BLT these character which have corrsponding glyph in font basebase.
2120           //
2121           GlyphToImage (
2122             GlyphBuf[Index1],
2123             Foreground,
2124             Background,
2125             Image->Width,
2126             BaseLine,
2127             RowInfo[RowIndex].LineWidth - LineOffset,
2128             RowInfo[RowIndex].LineHeight,
2129             Transparent,
2130             &Cell[Index1],
2131             Attributes[Index1],
2132             &BufferPtr
2133           );
2134         }
2135         if (ColumnInfoArray != NULL) {
2136           if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)
2137               || RowInfo[RowIndex].LineWidth == 0) {
2138             *ColumnInfoArray = (UINTN) ~0;
2139           } else {
2140             *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2141           }
2142           ColumnInfoArray++;
2143         }
2144         LineOffset += Cell[Index1].AdvanceX;
2145       }
2146 
2147       //
2148       // Jump to starting position of next row.
2149       //
2150       if (RowIndex == 0) {
2151         BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
2152       } else {
2153         BufferPtr = RowBufferPtr + LineHeight * Image->Width;
2154       }
2155     }
2156 
2157 NextLine:
2158     //
2159     // Recalculate the start point of X/Y axis to draw multi-lines with the order of top-to-down
2160     //
2161     BltX = 0;
2162     BltY += RowInfo[RowIndex].LineHeight;
2163 
2164     RowIndex++;
2165     Index = NextIndex;
2166 
2167     if (!LineBreak) {
2168       //
2169       // If there is not a mandatory line break or line break opportunity, only render one line to image
2170       //
2171       break;
2172     }
2173   }
2174 
2175   //
2176   // Write output parameters.
2177   //
2178   RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
2179   if (RowInfoArray != NULL) {
2180     if (RowInfoSize > 0) {
2181       *RowInfoArray = AllocateZeroPool (RowInfoSize);
2182       if (*RowInfoArray == NULL) {
2183         Status = EFI_OUT_OF_RESOURCES;
2184         goto Exit;
2185       }
2186       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
2187     } else {
2188       *RowInfoArray = NULL;
2189     }
2190   }
2191   if (RowInfoArraySize != NULL) {
2192     *RowInfoArraySize = RowIndex;
2193   }
2194 
2195   Status = EFI_SUCCESS;
2196 
2197 Exit:
2198 
2199   for (Index = 0; Index < StrLength; Index++) {
2200     if (GlyphBuf[Index] != NULL) {
2201       FreePool (GlyphBuf[Index]);
2202     }
2203   }
2204   if (StringIn != NULL) {
2205     FreePool (StringIn);
2206   }
2207   if (StringIn2 != NULL) {
2208     FreePool (StringIn2);
2209   }
2210   if (StringInfoOut != NULL) {
2211     FreePool (StringInfoOut);
2212   }
2213   if (RowInfo != NULL) {
2214     FreePool (RowInfo);
2215   }
2216   if (SystemDefault != NULL) {
2217     FreePool (SystemDefault);
2218   }
2219   if (GlyphBuf != NULL) {
2220     FreePool (GlyphBuf);
2221   }
2222   if (Cell != NULL) {
2223     FreePool (Cell);
2224   }
2225   if (Attributes != NULL) {
2226     FreePool (Attributes);
2227   }
2228 
2229   return Status;
2230 }
2231 
2232 
2233 /**
2234   Render a string to a bitmap or the screen containing the contents of the specified string.
2235 
2236   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
2237   @param  Flags                   Describes how the string is to be drawn.
2238   @param  PackageList             The package list in the HII database to search
2239                                   for the specified string.
2240   @param  StringId                The string's id, which is unique within
2241                                   PackageList.
2242   @param  Language                Points to the language for the retrieved string.
2243                                   If NULL, then the current system language is
2244                                   used.
2245   @param  StringInfo              Points to the string output information,
2246                                   including the color and font.  If NULL, then the
2247                                   string will be output in the default system font
2248                                   and color.
2249   @param  Blt                     If this points to a non-NULL on entry, this
2250                                   points to the image, which is Width pixels   wide
2251                                   and Height pixels high. The string will be drawn
2252                                   onto this image and
2253                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points
2254                                   to a NULL on entry, then a              buffer
2255                                   will be allocated to hold the generated image and
2256                                   the pointer updated on exit. It is the caller's
2257                                   responsibility to free this buffer.
2258   @param  BltX                    Specifies the offset from the left and top edge
2259                                   of the image of the first character cell in the
2260                                   image.
2261   @param  BltY                    Specifies the offset from the left and top edge
2262                                   of the image of the first character cell in the
2263                                   image.
2264   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this
2265                                   will point to an allocated buffer    containing
2266                                   row information and RowInfoArraySize will be
2267                                   updated to contain the        number of elements.
2268                                   This array describes the characters which were at
2269                                   least partially drawn and the heights of the
2270                                   rows. It is the caller's responsibility to free
2271                                   this buffer.
2272   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it
2273                                   contains the number of elements in RowInfoArray.
2274   @param  ColumnInfoArray         If this is non-NULL, then on return it will be
2275                                   filled with the horizontal offset for each
2276                                   character in the string on the row where it is
2277                                   displayed. Non-printing characters will     have
2278                                   the offset ~0. The caller is responsible to
2279                                   allocate a buffer large enough so that    there
2280                                   is one entry for each character in the string,
2281                                   not including the null-terminator. It is possible
2282                                   when character display is normalized that some
2283                                   character cells overlap.
2284 
2285   @retval EFI_SUCCESS             The string was successfully rendered.
2286   @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for
2287                                   RowInfoArray or Blt.
2288   @retval EFI_INVALID_PARAMETER  The Blt or PackageList was NULL.
2289   @retval EFI_INVALID_PARAMETER  Flags were invalid combination.
2290   @retval EFI_NOT_FOUND         The specified PackageList is not in the Database or the stringid is not
2291                           in the specified PackageList.
2292 
2293 **/
2294 EFI_STATUS
2295 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)2296 HiiStringIdToImage (
2297   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
2298   IN  EFI_HII_OUT_FLAGS              Flags,
2299   IN  EFI_HII_HANDLE                 PackageList,
2300   IN  EFI_STRING_ID                  StringId,
2301   IN  CONST CHAR8*                   Language,
2302   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,
2303   IN  OUT EFI_IMAGE_OUTPUT           **Blt,
2304   IN  UINTN                          BltX,
2305   IN  UINTN                          BltY,
2306   OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,
2307   OUT UINTN                          *RowInfoArraySize OPTIONAL,
2308   OUT UINTN                          *ColumnInfoArray  OPTIONAL
2309   )
2310 {
2311   EFI_STATUS                          Status;
2312   HII_DATABASE_PRIVATE_DATA           *Private;
2313   EFI_HII_STRING_PROTOCOL             *HiiString;
2314   EFI_STRING                          String;
2315   UINTN                               StringSize;
2316   UINTN                               FontLen;
2317   UINTN                               NameSize;
2318   EFI_FONT_INFO                       *StringFontInfo;
2319   EFI_FONT_DISPLAY_INFO               *NewStringInfo;
2320   CHAR8                               TempSupportedLanguages;
2321   CHAR8                               *SupportedLanguages;
2322   UINTN                               SupportedLanguagesSize;
2323   CHAR8                               *CurrentLanguage;
2324   CHAR8                               *BestLanguage;
2325 
2326   if (This == NULL || PackageList == NULL || Blt == NULL || PackageList == NULL) {
2327     return EFI_INVALID_PARAMETER;
2328   }
2329 
2330   if (!IsHiiHandleValid (PackageList)) {
2331     return EFI_NOT_FOUND;
2332   }
2333 
2334   //
2335   // Initialize string pointers to be NULL
2336   //
2337   SupportedLanguages = NULL;
2338   CurrentLanguage    = NULL;
2339   BestLanguage       = NULL;
2340   String             = NULL;
2341   StringFontInfo     = NULL;
2342   NewStringInfo      = NULL;
2343 
2344   //
2345   // Get the string to be displayed.
2346   //
2347   Private   = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2348   HiiString = &Private->HiiString;
2349 
2350   //
2351   // Get the size of supported language.
2352   //
2353   SupportedLanguagesSize = 0;
2354   Status = HiiString->GetLanguages (
2355                         HiiString,
2356                         PackageList,
2357                         &TempSupportedLanguages,
2358                         &SupportedLanguagesSize
2359                         );
2360   if (Status != EFI_BUFFER_TOO_SMALL) {
2361     return Status;
2362   }
2363 
2364   SupportedLanguages = AllocatePool (SupportedLanguagesSize);
2365   if (SupportedLanguages == NULL) {
2366     return EFI_OUT_OF_RESOURCES;
2367   }
2368 
2369   Status = HiiString->GetLanguages (
2370                         HiiString,
2371                         PackageList,
2372                         SupportedLanguages,
2373                         &SupportedLanguagesSize
2374                         );
2375   if (EFI_ERROR (Status)) {
2376     goto Exit;
2377   }
2378 
2379   if (Language == NULL) {
2380     Language = "";
2381   }
2382   GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLanguage, NULL);
2383   BestLanguage = GetBestLanguage (
2384                    SupportedLanguages,
2385                    FALSE,
2386                    Language,
2387                    (CurrentLanguage == NULL) ? CurrentLanguage : "",
2388                    (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
2389                    NULL
2390                    );
2391   if (BestLanguage == NULL) {
2392     Status = EFI_NOT_FOUND;
2393     goto Exit;
2394   }
2395 
2396   StringSize = MAX_STRING_LENGTH;
2397   String = (EFI_STRING) AllocateZeroPool (StringSize);
2398   if (String == NULL) {
2399     Status = EFI_OUT_OF_RESOURCES;
2400     goto Exit;
2401   }
2402 
2403   Status = HiiString->GetString (
2404                         HiiString,
2405                         BestLanguage,
2406                         PackageList,
2407                         StringId,
2408                         String,
2409                         &StringSize,
2410                         &StringFontInfo
2411                         );
2412   if (Status == EFI_BUFFER_TOO_SMALL) {
2413     FreePool (String);
2414     String = (EFI_STRING) AllocateZeroPool (StringSize);
2415     if (String == NULL) {
2416       Status = EFI_OUT_OF_RESOURCES;
2417       goto Exit;
2418     }
2419     Status = HiiString->GetString (
2420                           HiiString,
2421                           BestLanguage,
2422                           PackageList,
2423                           StringId,
2424                           String,
2425                           &StringSize,
2426                           NULL
2427                           );
2428   }
2429 
2430   if (EFI_ERROR (Status)) {
2431     goto Exit;
2432   }
2433 
2434   //
2435   // When StringInfo specifies that string will be output in the system default font and color,
2436   // use particular stringfontinfo described in string package instead if exists.
2437   // StringFontInfo equals NULL means system default font attaches with the string block.
2438   //
2439   if (StringFontInfo != NULL && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, NULL, NULL)) {
2440     NameSize = StrSize (StringFontInfo->FontName);
2441     FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
2442     NewStringInfo = AllocateZeroPool (FontLen);
2443     if (NewStringInfo == NULL) {
2444       Status = EFI_OUT_OF_RESOURCES;
2445       goto Exit;
2446     }
2447     NewStringInfo->FontInfoMask       = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
2448     NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
2449     NewStringInfo->FontInfo.FontSize  = StringFontInfo->FontSize;
2450     StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
2451 
2452     Status = HiiStringToImage (
2453                This,
2454                Flags,
2455                String,
2456                NewStringInfo,
2457                Blt,
2458                BltX,
2459                BltY,
2460                RowInfoArray,
2461                RowInfoArraySize,
2462                ColumnInfoArray
2463                );
2464     goto Exit;
2465   }
2466 
2467   Status = HiiStringToImage (
2468            This,
2469            Flags,
2470            String,
2471            StringInfo,
2472            Blt,
2473            BltX,
2474            BltY,
2475            RowInfoArray,
2476            RowInfoArraySize,
2477            ColumnInfoArray
2478            );
2479 
2480 Exit:
2481   if (SupportedLanguages != NULL) {
2482     FreePool (SupportedLanguages);
2483   }
2484   if (CurrentLanguage != NULL) {
2485     FreePool (CurrentLanguage);
2486   }
2487   if (BestLanguage != NULL) {
2488     FreePool (BestLanguage);
2489   }
2490   if (String != NULL) {
2491     FreePool (String);
2492   }
2493   if (StringFontInfo != NULL) {
2494     FreePool (StringFontInfo);
2495   }
2496   if (NewStringInfo != NULL) {
2497     FreePool (NewStringInfo);
2498   }
2499 
2500   return Status;
2501 }
2502 
2503 
2504 /**
2505   Convert the glyph for a single character into a bitmap.
2506 
2507   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
2508   @param  Char                    Character to retrieve.
2509   @param  StringInfo              Points to the string font and color information
2510                                   or NULL if the string should use the default
2511                                   system font and color.
2512   @param  Blt                     Thus must point to a NULL on entry. A buffer will
2513                                   be allocated to hold the output and the pointer
2514                                   updated on exit. It is the caller's
2515                                   responsibility to free this buffer.
2516   @param  Baseline                Number of pixels from the bottom of the bitmap to
2517                                   the baseline.
2518 
2519   @retval EFI_SUCCESS             Glyph bitmap created.
2520   @retval EFI_OUT_OF_RESOURCES    Unable to allocate the output buffer Blt.
2521   @retval EFI_WARN_UNKNOWN_GLYPH  The glyph was unknown and was replaced with the
2522                                   glyph for Unicode character 0xFFFD.
2523   @retval EFI_INVALID_PARAMETER   Blt is NULL or *Blt is not NULL.
2524 
2525 **/
2526 EFI_STATUS
2527 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)2528 HiiGetGlyph (
2529   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
2530   IN  CHAR16                         Char,
2531   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo,
2532   OUT EFI_IMAGE_OUTPUT               **Blt,
2533   OUT UINTN                          *Baseline OPTIONAL
2534   )
2535 {
2536   EFI_STATUS                         Status;
2537   HII_DATABASE_PRIVATE_DATA          *Private;
2538   EFI_IMAGE_OUTPUT                   *Image;
2539   UINT8                              *GlyphBuffer;
2540   EFI_FONT_DISPLAY_INFO              *SystemDefault;
2541   EFI_FONT_DISPLAY_INFO              *StringInfoOut;
2542   BOOLEAN                            Default;
2543   EFI_FONT_HANDLE                    FontHandle;
2544   EFI_STRING                         String;
2545   EFI_HII_GLYPH_INFO                 Cell;
2546   EFI_FONT_INFO                      *FontInfo;
2547   UINT8                              Attributes;
2548   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Foreground;
2549   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Background;
2550   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer;
2551   UINT16                             BaseLine;
2552 
2553   if (This == NULL || Blt == NULL || *Blt != NULL) {
2554     return EFI_INVALID_PARAMETER;
2555   }
2556 
2557   Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2558 
2559   Default       = FALSE;
2560   Image         = NULL;
2561   SystemDefault = NULL;
2562   FontHandle    = NULL;
2563   String        = NULL;
2564   GlyphBuffer   = NULL;
2565   StringInfoOut = NULL;
2566   FontInfo      = NULL;
2567 
2568   ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2569   ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2570 
2571   Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);
2572 
2573   if (!Default) {
2574     //
2575     // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
2576     // the specified color and font.
2577     //
2578     String = (EFI_STRING) AllocateZeroPool (sizeof (CHAR16) * 2);
2579     if (String == NULL) {
2580       Status = EFI_OUT_OF_RESOURCES;
2581       goto Exit;
2582     }
2583     *String = Char;
2584     *(String + 1) = 0;
2585 
2586     Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
2587     if (EFI_ERROR (Status)) {
2588       goto Exit;
2589     }
2590     ASSERT (StringInfoOut != NULL);
2591     FontInfo   = &StringInfoOut->FontInfo;
2592     Foreground = StringInfoOut->ForegroundColor;
2593     Background = StringInfoOut->BackgroundColor;
2594   } else {
2595     ASSERT (SystemDefault != NULL);
2596     Foreground = SystemDefault->ForegroundColor;
2597     Background = SystemDefault->BackgroundColor;
2598   }
2599 
2600   Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
2601   if (EFI_ERROR (Status)) {
2602     goto Exit;
2603   }
2604 
2605   Image = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
2606   if (Image == NULL) {
2607     Status = EFI_OUT_OF_RESOURCES;
2608     goto Exit;
2609   }
2610   Image->Width   = Cell.Width;
2611   Image->Height  = Cell.Height;
2612 
2613   if (Image->Width * Image->Height > 0) {
2614     Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2615     if (Image->Image.Bitmap == NULL) {
2616       FreePool (Image);
2617       Status = EFI_OUT_OF_RESOURCES;
2618       goto Exit;
2619     }
2620 
2621     //
2622     // Set BaseLine to the char height.
2623     //
2624     BaseLine  = (UINT16) (Cell.Height + Cell.OffsetY);
2625     //
2626     // Set BltBuffer to the position of Origin.
2627     //
2628     BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
2629     GlyphToImage (
2630       GlyphBuffer,
2631       Foreground,
2632       Background,
2633       Image->Width,
2634       BaseLine,
2635       Cell.Width + Cell.OffsetX,
2636       BaseLine - Cell.OffsetY,
2637       FALSE,
2638       &Cell,
2639       Attributes,
2640       &BltBuffer
2641       );
2642   }
2643 
2644   *Blt = Image;
2645   if (Baseline != NULL) {
2646     *Baseline = Cell.OffsetY;
2647   }
2648 
2649   Status = EFI_SUCCESS;
2650 
2651 Exit:
2652 
2653   if (Status == EFI_NOT_FOUND) {
2654     //
2655     // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
2656     //
2657     if (Char != REPLACE_UNKNOWN_GLYPH) {
2658       Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
2659       if (!EFI_ERROR (Status)) {
2660         Status = EFI_WARN_UNKNOWN_GLYPH;
2661       }
2662     } else {
2663       Status = EFI_WARN_UNKNOWN_GLYPH;
2664     }
2665   }
2666 
2667   if (SystemDefault != NULL) {
2668    FreePool (SystemDefault);
2669   }
2670   if (StringInfoOut != NULL) {
2671     FreePool (StringInfoOut);
2672   }
2673   if (String != NULL) {
2674     FreePool (String);
2675   }
2676   if (GlyphBuffer != NULL) {
2677     FreePool (GlyphBuffer);
2678   }
2679 
2680   return Status;
2681 }
2682 
2683 
2684 /**
2685   This function iterates through fonts which match the specified font, using
2686   the specified criteria. If String is non-NULL, then all of the characters in
2687   the string must exist in order for a candidate font to be returned.
2688 
2689   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
2690   @param  FontHandle              On entry, points to the font handle returned by a
2691                                    previous call to GetFontInfo() or NULL to start
2692                                   with the  first font. On return, points to the
2693                                   returned font handle or points to NULL if there
2694                                   are no more matching fonts.
2695   @param  StringInfoIn            Upon entry, points to the font to return information
2696                                   about. If NULL, then the information about the system
2697                                   default font will be returned.
2698   @param  StringInfoOut           Upon return, contains the matching font's information.
2699                                   If NULL, then no information is returned. This buffer
2700                                   is allocated with a call to the Boot Service AllocatePool().
2701                                   It is the caller's responsibility to call the Boot
2702                                   Service FreePool() when the caller no longer requires
2703                                   the contents of StringInfoOut.
2704   @param  String                  Points to the string which will be tested to
2705                                   determine  if all characters are available. If
2706                                   NULL, then any font  is acceptable.
2707 
2708   @retval EFI_SUCCESS             Matching font returned successfully.
2709   @retval EFI_NOT_FOUND           No matching font was found.
2710   @retval EFI_INVALID_PARAMETER  StringInfoIn->FontInfoMask is an invalid combination.
2711   @retval EFI_OUT_OF_RESOURCES    There were insufficient resources to complete the
2712                                   request.
2713 
2714 **/
2715 EFI_STATUS
2716 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)2717 HiiGetFontInfo (
2718   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
2719   IN  OUT   EFI_FONT_HANDLE          *FontHandle,
2720   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfoIn, OPTIONAL
2721   OUT       EFI_FONT_DISPLAY_INFO    **StringInfoOut,
2722   IN  CONST EFI_STRING               String OPTIONAL
2723   )
2724 {
2725   HII_DATABASE_PRIVATE_DATA          *Private;
2726   EFI_STATUS                         Status;
2727   EFI_FONT_DISPLAY_INFO              *SystemDefault;
2728   EFI_FONT_DISPLAY_INFO              InfoOut;
2729   UINTN                              StringInfoOutLen;
2730   EFI_FONT_INFO                      *FontInfo;
2731   HII_GLOBAL_FONT_INFO               *GlobalFont;
2732   EFI_STRING                         StringIn;
2733   EFI_FONT_HANDLE                    LocalFontHandle;
2734 
2735   if (This == NULL) {
2736     return EFI_INVALID_PARAMETER;
2737   }
2738 
2739   StringInfoOutLen = 0;
2740   FontInfo        = NULL;
2741   SystemDefault   = NULL;
2742   LocalFontHandle = NULL;
2743   if (FontHandle != NULL) {
2744     LocalFontHandle = *FontHandle;
2745   }
2746 
2747   Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2748 
2749   //
2750   // Already searched to the end of the whole list, return directly.
2751   //
2752   if (LocalFontHandle == &Private->FontInfoList) {
2753     LocalFontHandle = NULL;
2754     Status = EFI_NOT_FOUND;
2755     goto Exit;
2756   }
2757 
2758   //
2759   // Get default system display info, if StringInfoIn points to
2760   // system display info, return it directly.
2761   //
2762   if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
2763     //
2764     // System font is the first node. When handle is not NULL, system font can not
2765     // be found any more.
2766     //
2767     if (LocalFontHandle == NULL) {
2768       if (StringInfoOut != NULL) {
2769         *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
2770         if (*StringInfoOut == NULL) {
2771           Status = EFI_OUT_OF_RESOURCES;
2772           LocalFontHandle = NULL;
2773           goto Exit;
2774         }
2775       }
2776 
2777       LocalFontHandle = Private->FontInfoList.ForwardLink;
2778       Status = EFI_SUCCESS;
2779       goto Exit;
2780     } else {
2781       LocalFontHandle = NULL;
2782       Status = EFI_NOT_FOUND;
2783       goto Exit;
2784     }
2785   }
2786 
2787   //
2788   // StringInfoIn must not be NULL if it is not system default font info.
2789   //
2790   ASSERT (StringInfoIn != NULL);
2791   //
2792   // Check the font information mask to make sure it is valid.
2793   //
2794   if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT  | EFI_FONT_INFO_ANY_FONT))  ==
2795        (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT))   ||
2796       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE  | EFI_FONT_INFO_ANY_SIZE))  ==
2797        (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE))   ||
2798       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
2799        (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
2800       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE    | EFI_FONT_INFO_ANY_SIZE))  ==
2801        (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE))     ||
2802       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE   | EFI_FONT_INFO_ANY_STYLE)) ==
2803        (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {
2804     return EFI_INVALID_PARAMETER;
2805   }
2806 
2807   //
2808   // Parse the font information mask to find a matching font.
2809   //
2810 
2811   CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
2812 
2813   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
2814     Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
2815   } else {
2816     Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *) StringInfoIn)->FontInfo.FontName, &FontInfo);
2817   }
2818   if (EFI_ERROR (Status)) {
2819     goto Exit;
2820   }
2821 
2822   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
2823     InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
2824   }
2825   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
2826     InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
2827   }
2828   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
2829     InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
2830   }
2831   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
2832     InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
2833   }
2834 
2835   ASSERT (FontInfo != NULL);
2836   FontInfo->FontSize  = InfoOut.FontInfo.FontSize;
2837   FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
2838 
2839   if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
2840     //
2841     // Test to guarantee all characters are available in the found font.
2842     //
2843     if (String != NULL) {
2844       StringIn = String;
2845       while (*StringIn != 0) {
2846         Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
2847         if (EFI_ERROR (Status)) {
2848           LocalFontHandle = NULL;
2849           goto Exit;
2850         }
2851         StringIn++;
2852       }
2853     }
2854     //
2855     // Write to output parameter
2856     //
2857     if (StringInfoOut != NULL) {
2858       StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
2859       *StringInfoOut   = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);
2860       if (*StringInfoOut == NULL) {
2861         Status = EFI_OUT_OF_RESOURCES;
2862         LocalFontHandle = NULL;
2863         goto Exit;
2864       }
2865 
2866       CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
2867       CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
2868     }
2869 
2870     LocalFontHandle = GlobalFont->Entry.ForwardLink;
2871     Status = EFI_SUCCESS;
2872     goto Exit;
2873   }
2874 
2875   Status = EFI_NOT_FOUND;
2876 
2877 Exit:
2878 
2879   if (FontHandle != NULL) {
2880     *FontHandle = LocalFontHandle;
2881   }
2882 
2883   if (SystemDefault != NULL) {
2884    FreePool (SystemDefault);
2885   }
2886   if (FontInfo != NULL) {
2887    FreePool (FontInfo);
2888   }
2889   return Status;
2890 }
2891 
2892 
2893