Home | History | Annotate | Download | only in HiiDatabaseDxe
      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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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