Home | History | Annotate | Download | only in HiiDatabaseDxe
      1 /** @file
      2 Implementation for EFI_HII_FONT_PROTOCOL.
      3 
      4 
      5 Copyright (c) 2007 - 2016, 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 will 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 will 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 will 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 responsibility 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 responsibility 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   }
    708 
    709   BlockPtr    = FontPackage->GlyphBlock;
    710   CharCurrent = 1;
    711   BufferLen   = 0;
    712 
    713   while (*BlockPtr != EFI_HII_GIBT_END) {
    714     switch (*BlockPtr) {
    715     case EFI_HII_GIBT_DEFAULTS:
    716       //
    717       // Collect all default character cell information specified by
    718       // EFI_HII_GIBT_DEFAULTS.
    719       //
    720       if (CharValue == (CHAR16) (-1)) {
    721         Status = NewCell (
    722                    CharCurrent,
    723                    &FontPackage->GlyphInfoList,
    724                    (EFI_HII_GLYPH_INFO *) (BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))
    725                    );
    726         if (EFI_ERROR (Status)) {
    727           return Status;
    728         }
    729         CopyMem (
    730           &LocalCell,
    731           BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
    732           sizeof (EFI_HII_GLYPH_INFO)
    733           );
    734         if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
    735           BaseLine = (UINT16) (LocalCell.Height + LocalCell.OffsetY);
    736         }
    737         if (MinOffsetY > LocalCell.OffsetY) {
    738           MinOffsetY = LocalCell.OffsetY;
    739         }
    740       }
    741       BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);
    742       break;
    743 
    744     case EFI_HII_GIBT_DUPLICATE:
    745       if (CharCurrent == CharValue) {
    746         CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));
    747         CharCurrent = 1;
    748         BlockPtr    = FontPackage->GlyphBlock;
    749         continue;
    750       }
    751       CharCurrent++;
    752       BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);
    753       break;
    754 
    755     case EFI_HII_GIBT_EXT1:
    756       BlockPtr += *(UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));
    757       break;
    758     case EFI_HII_GIBT_EXT2:
    759       CopyMem (
    760         &Length16,
    761         (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
    762         sizeof (UINT16)
    763         );
    764       BlockPtr += Length16;
    765       break;
    766     case EFI_HII_GIBT_EXT4:
    767       CopyMem (
    768         &Length32,
    769         (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
    770         sizeof (UINT32)
    771         );
    772       BlockPtr += Length32;
    773       break;
    774 
    775     case EFI_HII_GIBT_GLYPH:
    776       CopyMem (
    777         &LocalCell,
    778         BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
    779         sizeof (EFI_HII_GLYPH_INFO)
    780         );
    781       if (CharValue == (CHAR16) (-1)) {
    782         if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
    783           BaseLine = (UINT16) (LocalCell.Height + LocalCell.OffsetY);
    784         }
    785         if (MinOffsetY > LocalCell.OffsetY) {
    786           MinOffsetY = LocalCell.OffsetY;
    787         }
    788       }
    789       BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);
    790       if (CharCurrent == CharValue) {
    791         return WriteOutputParam (
    792                  (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),
    793                  BufferLen,
    794                  &LocalCell,
    795                  GlyphBuffer,
    796                  Cell,
    797                  GlyphBufferLen
    798                  );
    799       }
    800       CharCurrent++;
    801       BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;
    802       break;
    803 
    804     case EFI_HII_GIBT_GLYPHS:
    805       BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);
    806       CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));
    807       BlockPtr += sizeof (EFI_HII_GLYPH_INFO);
    808       CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));
    809       BlockPtr += sizeof (UINT16);
    810 
    811       if (CharValue == (CHAR16) (-1)) {
    812         if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {
    813           BaseLine = (UINT16) (Glyphs.Cell.Height + Glyphs.Cell.OffsetY);
    814         }
    815         if (MinOffsetY > Glyphs.Cell.OffsetY) {
    816           MinOffsetY = Glyphs.Cell.OffsetY;
    817         }
    818       }
    819 
    820       BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);
    821       for (Index = 0; Index < Glyphs.Count; Index++) {
    822         if (CharCurrent + Index == CharValue) {
    823           return WriteOutputParam (
    824                    BlockPtr,
    825                    BufferLen,
    826                    &Glyphs.Cell,
    827                    GlyphBuffer,
    828                    Cell,
    829                    GlyphBufferLen
    830                    );
    831         }
    832         BlockPtr += BufferLen;
    833       }
    834       CharCurrent = (UINT16) (CharCurrent + Glyphs.Count);
    835       break;
    836 
    837     case EFI_HII_GIBT_GLYPH_DEFAULT:
    838       Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
    839       if (EFI_ERROR (Status)) {
    840         return Status;
    841       }
    842       if (CharValue == (CHAR16) (-1)) {
    843         if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
    844           BaseLine = (UINT16) (DefaultCell.Height + DefaultCell.OffsetY);
    845         }
    846         if (MinOffsetY > DefaultCell.OffsetY) {
    847           MinOffsetY = DefaultCell.OffsetY;
    848         }
    849       }
    850       BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
    851 
    852       if (CharCurrent == CharValue) {
    853         return WriteOutputParam (
    854                  BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
    855                  BufferLen,
    856                  &DefaultCell,
    857                  GlyphBuffer,
    858                  Cell,
    859                  GlyphBufferLen
    860                  );
    861       }
    862       CharCurrent++;
    863       BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;
    864       break;
    865 
    866     case EFI_HII_GIBT_GLYPHS_DEFAULT:
    867       CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
    868       Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
    869       if (EFI_ERROR (Status)) {
    870         return Status;
    871       }
    872       if (CharValue == (CHAR16) (-1)) {
    873         if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
    874           BaseLine = (UINT16) (DefaultCell.Height + DefaultCell.OffsetY);
    875         }
    876         if (MinOffsetY > DefaultCell.OffsetY) {
    877           MinOffsetY = DefaultCell.OffsetY;
    878         }
    879       }
    880       BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
    881       BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);
    882       for (Index = 0; Index < Length16; Index++) {
    883         if (CharCurrent + Index == CharValue) {
    884           return WriteOutputParam (
    885                    BlockPtr,
    886                    BufferLen,
    887                    &DefaultCell,
    888                    GlyphBuffer,
    889                    Cell,
    890                    GlyphBufferLen
    891                    );
    892         }
    893         BlockPtr += BufferLen;
    894       }
    895       CharCurrent = (UINT16) (CharCurrent + Length16);
    896       break;
    897 
    898     case EFI_HII_GIBT_SKIP1:
    899       CharCurrent = (UINT16) (CharCurrent + (UINT16) (*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));
    900       BlockPtr    += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);
    901       break;
    902     case EFI_HII_GIBT_SKIP2:
    903       CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
    904       CharCurrent = (UINT16) (CharCurrent + Length16);
    905       BlockPtr    += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);
    906       break;
    907     default:
    908       ASSERT (FALSE);
    909       break;
    910     }
    911 
    912     if (CharValue < CharCurrent) {
    913       return EFI_NOT_FOUND;
    914     }
    915   }
    916 
    917   if (CharValue == (CHAR16) (-1)) {
    918     FontPackage->BaseLine = BaseLine;
    919     FontPackage->Height   = (UINT16) (BaseLine - MinOffsetY);
    920     return EFI_SUCCESS;
    921   }
    922 
    923   return EFI_NOT_FOUND;
    924 }
    925 
    926 
    927 /**
    928   Copy a Font Name to a new created EFI_FONT_INFO structure.
    929 
    930   This is a internal function.
    931 
    932   @param  FontName                NULL-terminated string.
    933   @param  FontInfo                a new EFI_FONT_INFO which stores the FontName.
    934                                   It's caller's responsibility to free this buffer.
    935 
    936   @retval EFI_SUCCESS             FontInfo is allocated and copied with FontName.
    937   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
    938                                   task.
    939 
    940 **/
    941 EFI_STATUS
    942 SaveFontName (
    943   IN  EFI_STRING                       FontName,
    944   OUT EFI_FONT_INFO                    **FontInfo
    945   )
    946 {
    947   UINTN         FontInfoLen;
    948   UINTN         NameSize;
    949 
    950   ASSERT (FontName != NULL && FontInfo != NULL);
    951 
    952   NameSize = StrSize (FontName);
    953   FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;
    954   *FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoLen);
    955   if (*FontInfo == NULL) {
    956     return EFI_OUT_OF_RESOURCES;
    957   }
    958 
    959   StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);
    960   return EFI_SUCCESS;
    961 }
    962 
    963 
    964 /**
    965   Retrieve system default font and color.
    966 
    967   @param  Private                 HII database driver private data.
    968   @param  FontInfo                Points to system default font output-related
    969                                   information. It's caller's responsibility to free
    970                                   this buffer.
    971   @param  FontInfoSize            If not NULL, output the size of buffer FontInfo.
    972 
    973   @retval EFI_SUCCESS             Cell information is added to the GlyphInfoList.
    974   @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
    975                                   task.
    976   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.
    977 
    978 **/
    979 EFI_STATUS
    980 GetSystemFont (
    981   IN  HII_DATABASE_PRIVATE_DATA      *Private,
    982   OUT EFI_FONT_DISPLAY_INFO          **FontInfo,
    983   OUT UINTN                          *FontInfoSize OPTIONAL
    984   )
    985 {
    986   EFI_FONT_DISPLAY_INFO              *Info;
    987   UINTN                              InfoSize;
    988   UINTN                              NameSize;
    989 
    990   if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {
    991     return EFI_INVALID_PARAMETER;
    992   }
    993   if (FontInfo == NULL) {
    994     return EFI_INVALID_PARAMETER;
    995   }
    996 
    997   //
    998   // The standard font always has the name "sysdefault".
    999   //
   1000   NameSize = StrSize (L"sysdefault");
   1001   InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
   1002   Info = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (InfoSize);
   1003   if (Info == NULL) {
   1004     return EFI_OUT_OF_RESOURCES;
   1005   }
   1006 
   1007   Info->ForegroundColor    = mHiiEfiColors[Private->Attribute & 0x0f];
   1008   Info->BackgroundColor    = mHiiEfiColors[Private->Attribute >> 4];
   1009   Info->FontInfoMask       = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;
   1010   Info->FontInfo.FontStyle = 0;
   1011   Info->FontInfo.FontSize  = EFI_GLYPH_HEIGHT;
   1012   StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");
   1013 
   1014   *FontInfo = Info;
   1015   if (FontInfoSize != NULL) {
   1016     *FontInfoSize = InfoSize;
   1017   }
   1018   return EFI_SUCCESS;
   1019 }
   1020 
   1021 
   1022 /**
   1023   Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or
   1024   returns the system default according to the optional inputs.
   1025 
   1026   This is a internal function.
   1027 
   1028   @param  Private                 HII database driver private data.
   1029   @param  StringInfo              Points to the string output information,
   1030                                   including the color and font.
   1031   @param  SystemInfo              If not NULL, points to system default font and color.
   1032 
   1033   @param  SystemInfoLen           If not NULL, output the length of default system
   1034                                   info.
   1035 
   1036   @retval TRUE                    Yes, it points to system default.
   1037   @retval FALSE                   No.
   1038 
   1039 **/
   1040 BOOLEAN
   1041 IsSystemFontInfo (
   1042   IN  HII_DATABASE_PRIVATE_DATA      *Private,
   1043   IN  EFI_FONT_DISPLAY_INFO          *StringInfo,
   1044   OUT EFI_FONT_DISPLAY_INFO          **SystemInfo, OPTIONAL
   1045   OUT UINTN                          *SystemInfoLen OPTIONAL
   1046   )
   1047 {
   1048   EFI_STATUS                          Status;
   1049   EFI_FONT_DISPLAY_INFO               *SystemDefault;
   1050   UINTN                               DefaultLen;
   1051   BOOLEAN                             Flag;
   1052 
   1053   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
   1054 
   1055   if (StringInfo == NULL && SystemInfo == NULL) {
   1056     return TRUE;
   1057   }
   1058 
   1059   SystemDefault = NULL;
   1060   DefaultLen    = 0;
   1061 
   1062   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);
   1063   ASSERT_EFI_ERROR (Status);
   1064   ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));
   1065 
   1066   //
   1067   // Record the system default info.
   1068   //
   1069   if (SystemInfo != NULL) {
   1070     *SystemInfo = SystemDefault;
   1071   }
   1072 
   1073   if (SystemInfoLen != NULL) {
   1074     *SystemInfoLen = DefaultLen;
   1075   }
   1076 
   1077   if (StringInfo == NULL) {
   1078     return TRUE;
   1079   }
   1080 
   1081   Flag = FALSE;
   1082   //
   1083   // Check the FontInfoMask to see whether it is retrieving system info.
   1084   //
   1085   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {
   1086     if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {
   1087       goto Exit;
   1088     }
   1089   }
   1090   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {
   1091     if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {
   1092       goto Exit;
   1093     }
   1094   }
   1095   if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {
   1096     if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {
   1097       goto Exit;
   1098     }
   1099   }
   1100   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {
   1101     if (CompareMem (
   1102           &StringInfo->ForegroundColor,
   1103           &SystemDefault->ForegroundColor,
   1104           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
   1105           ) != 0) {
   1106       goto Exit;
   1107     }
   1108   }
   1109   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {
   1110     if (CompareMem (
   1111           &StringInfo->BackgroundColor,
   1112           &SystemDefault->BackgroundColor,
   1113           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
   1114           ) != 0) {
   1115       goto Exit;
   1116     }
   1117   }
   1118 
   1119   Flag = TRUE;
   1120 
   1121 Exit:
   1122   if (SystemInfo == NULL) {
   1123     if (SystemDefault != NULL) {
   1124       FreePool (SystemDefault);
   1125     }
   1126   }
   1127   return Flag;
   1128 }
   1129 
   1130 
   1131 /**
   1132   This function checks whether EFI_FONT_INFO exists in current database. If
   1133   FontInfoMask is specified, check what options can be used to make a match.
   1134   Note that the masks relate to where the system default should be supplied
   1135   are ignored by this function.
   1136 
   1137   @param  Private                 Hii database private structure.
   1138   @param  FontInfo                Points to EFI_FONT_INFO structure.
   1139   @param  FontInfoMask            If not NULL, describes what options can be used
   1140                                   to make a match between the font requested and
   1141                                   the font available. The caller must guarantee
   1142                                   this mask is valid.
   1143   @param  FontHandle              On entry, Points to the font handle returned by a
   1144                                   previous  call to GetFontInfo() or NULL to start
   1145                                   with the first font.
   1146   @param  GlobalFontInfo          If not NULL, output the corresponding global font
   1147                                   info.
   1148 
   1149   @retval TRUE                    Existed
   1150   @retval FALSE                   Not existed
   1151 
   1152 **/
   1153 BOOLEAN
   1154 IsFontInfoExisted (
   1155   IN  HII_DATABASE_PRIVATE_DATA *Private,
   1156   IN  EFI_FONT_INFO             *FontInfo,
   1157   IN  EFI_FONT_INFO_MASK        *FontInfoMask,   OPTIONAL
   1158   IN  EFI_FONT_HANDLE           FontHandle,      OPTIONAL
   1159   OUT HII_GLOBAL_FONT_INFO      **GlobalFontInfo OPTIONAL
   1160   )
   1161 {
   1162   HII_GLOBAL_FONT_INFO          *GlobalFont;
   1163   HII_GLOBAL_FONT_INFO          *GlobalFontBackup1;
   1164   HII_GLOBAL_FONT_INFO          *GlobalFontBackup2;
   1165   LIST_ENTRY                    *Link;
   1166   EFI_FONT_INFO_MASK            Mask;
   1167   BOOLEAN                       Matched;
   1168   BOOLEAN                       VagueMatched1;
   1169   BOOLEAN                       VagueMatched2;
   1170 
   1171   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
   1172   ASSERT (FontInfo != NULL);
   1173 
   1174   //
   1175   // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE
   1176   // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.
   1177   //
   1178   Matched           = FALSE;
   1179   VagueMatched1     = FALSE;
   1180   VagueMatched2     = FALSE;
   1181 
   1182   Mask              = 0;
   1183   GlobalFontBackup1 = NULL;
   1184   GlobalFontBackup2 = NULL;
   1185 
   1186   // The process of where the system default should be supplied instead of
   1187   // the specified font info beyonds this function's scope.
   1188   //
   1189   if (FontInfoMask != NULL) {
   1190     Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);
   1191   }
   1192 
   1193   //
   1194   // If not NULL, FontHandle points to the next node of the last searched font
   1195   // node by previous call.
   1196   //
   1197   if (FontHandle == NULL) {
   1198     Link = Private->FontInfoList.ForwardLink;
   1199   } else {
   1200     Link = (LIST_ENTRY     *) FontHandle;
   1201   }
   1202 
   1203   for (; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
   1204     GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
   1205     if (FontInfoMask == NULL) {
   1206       if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {
   1207         if (GlobalFontInfo != NULL) {
   1208           *GlobalFontInfo = GlobalFont;
   1209         }
   1210         return TRUE;
   1211       }
   1212     } else {
   1213       //
   1214       // Check which options could be used to make a match.
   1215       //
   1216       switch (Mask) {
   1217       case EFI_FONT_INFO_ANY_FONT:
   1218         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle &&
   1219             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1220           Matched = TRUE;
   1221         }
   1222         break;
   1223       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:
   1224         if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
   1225           Matched = TRUE;
   1226         }
   1227         break;
   1228       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:
   1229         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1230           Matched = TRUE;
   1231         }
   1232         break;
   1233       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:
   1234         Matched   = TRUE;
   1235         break;
   1236       //
   1237       // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to
   1238       // remove some of the specified styles to meet the style requested.
   1239       //
   1240       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:
   1241         if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
   1242           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1243             Matched           = TRUE;
   1244           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1245             VagueMatched1     = TRUE;
   1246             GlobalFontBackup1 = GlobalFont;
   1247           }
   1248         }
   1249         break;
   1250       //
   1251       // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to
   1252       // stretch or shrink a font to meet the size requested.
   1253       //
   1254       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:
   1255         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1256           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1257             Matched           = TRUE;
   1258           } else {
   1259             VagueMatched1     = TRUE;
   1260             GlobalFontBackup1 = GlobalFont;
   1261           }
   1262         }
   1263         break;
   1264       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:
   1265         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1266           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1267             Matched           = TRUE;
   1268           } else {
   1269             VagueMatched1     = TRUE;
   1270             GlobalFontBackup1 = GlobalFont;
   1271           }
   1272         } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1273           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1274             VagueMatched1     = TRUE;
   1275             GlobalFontBackup1 = GlobalFont;
   1276           } else {
   1277             VagueMatched2     = TRUE;
   1278             GlobalFontBackup2 = GlobalFont;
   1279           }
   1280         }
   1281         break;
   1282       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
   1283         if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1284           Matched           = TRUE;
   1285         } else {
   1286           VagueMatched1     = TRUE;
   1287           GlobalFontBackup1 = GlobalFont;
   1288         }
   1289         break;
   1290       case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
   1291         if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1292           Matched           = TRUE;
   1293         } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1294           VagueMatched1     = TRUE;
   1295           GlobalFontBackup1 = GlobalFont;
   1296         }
   1297         break;
   1298       case EFI_FONT_INFO_ANY_STYLE:
   1299         if ((CompareMem (
   1300                GlobalFont->FontInfo->FontName,
   1301                FontInfo->FontName,
   1302                StrSize (FontInfo->FontName)
   1303                ) == 0) &&
   1304             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1305           Matched = TRUE;
   1306         }
   1307         break;
   1308       case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:
   1309         if (CompareMem (
   1310               GlobalFont->FontInfo->FontName,
   1311               FontInfo->FontName,
   1312               StrSize (FontInfo->FontName)
   1313               ) == 0) {
   1314           Matched = TRUE;
   1315         }
   1316         break;
   1317       case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
   1318         if (CompareMem (
   1319               GlobalFont->FontInfo->FontName,
   1320               FontInfo->FontName,
   1321               StrSize (FontInfo->FontName)
   1322               ) == 0) {
   1323           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1324             Matched           = TRUE;
   1325           } else {
   1326             VagueMatched1     = TRUE;
   1327             GlobalFontBackup1 = GlobalFont;
   1328           }
   1329         }
   1330         break;
   1331       case EFI_FONT_INFO_ANY_SIZE:
   1332         if ((CompareMem (
   1333                GlobalFont->FontInfo->FontName,
   1334                FontInfo->FontName,
   1335                StrSize (FontInfo->FontName)
   1336                ) == 0) &&
   1337             GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {
   1338           Matched = TRUE;
   1339         }
   1340         break;
   1341       case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
   1342         if (CompareMem (
   1343               GlobalFont->FontInfo->FontName,
   1344               FontInfo->FontName,
   1345               StrSize (FontInfo->FontName)
   1346               ) == 0) {
   1347           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1348             Matched           = TRUE;
   1349           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1350             VagueMatched1     = TRUE;
   1351             GlobalFontBackup1 = GlobalFont;
   1352           }
   1353         }
   1354         break;
   1355       case EFI_FONT_INFO_RESTYLE:
   1356         if ((CompareMem (
   1357                GlobalFont->FontInfo->FontName,
   1358                FontInfo->FontName,
   1359                StrSize (FontInfo->FontName)
   1360                ) == 0) &&
   1361             GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1362 
   1363           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1364             Matched           = TRUE;
   1365           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1366             VagueMatched1     = TRUE;
   1367             GlobalFontBackup1 = GlobalFont;
   1368           }
   1369         }
   1370         break;
   1371       case EFI_FONT_INFO_RESIZE:
   1372         if ((CompareMem (
   1373                GlobalFont->FontInfo->FontName,
   1374                FontInfo->FontName,
   1375                StrSize (FontInfo->FontName)
   1376                ) == 0) &&
   1377             GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {
   1378 
   1379           if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1380             Matched           = TRUE;
   1381           } else {
   1382             VagueMatched1     = TRUE;
   1383             GlobalFontBackup1 = GlobalFont;
   1384           }
   1385         }
   1386         break;
   1387       case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:
   1388         if (CompareMem (
   1389               GlobalFont->FontInfo->FontName,
   1390               FontInfo->FontName,
   1391               StrSize (FontInfo->FontName)
   1392               ) == 0) {
   1393           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
   1394             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1395               Matched           = TRUE;
   1396             } else {
   1397               VagueMatched1     = TRUE;
   1398               GlobalFontBackup1 = GlobalFont;
   1399             }
   1400           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
   1401             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {
   1402               VagueMatched1     = TRUE;
   1403               GlobalFontBackup1 = GlobalFont;
   1404             } else {
   1405               VagueMatched2     = TRUE;
   1406               GlobalFontBackup2 = GlobalFont;
   1407             }
   1408           }
   1409         }
   1410         break;
   1411       default:
   1412         break;
   1413       }
   1414 
   1415       if (Matched) {
   1416         if (GlobalFontInfo != NULL) {
   1417           *GlobalFontInfo = GlobalFont;
   1418         }
   1419         return TRUE;
   1420       }
   1421     }
   1422   }
   1423 
   1424   if (VagueMatched1) {
   1425     if (GlobalFontInfo != NULL) {
   1426       *GlobalFontInfo = GlobalFontBackup1;
   1427     }
   1428     return TRUE;
   1429   } else if (VagueMatched2) {
   1430     if (GlobalFontInfo != NULL) {
   1431       *GlobalFontInfo = GlobalFontBackup2;
   1432     }
   1433     return TRUE;
   1434   }
   1435 
   1436   return FALSE;
   1437 }
   1438 
   1439 
   1440 /**
   1441   Check whether the unicode represents a line break or not.
   1442 
   1443   This is a internal function. Please see Section 27.2.6 of the UEFI Specification
   1444   for a description of the supported string format.
   1445 
   1446   @param  Char                    Unicode character
   1447 
   1448   @retval 0                       Yes, it forces a line break.
   1449   @retval 1                       Yes, it presents a line break opportunity
   1450   @retval 2                       Yes, it requires a line break happen before and after it.
   1451   @retval -1                      No, it is not a link break.
   1452 
   1453 **/
   1454 INT8
   1455 IsLineBreak (
   1456   IN  CHAR16    Char
   1457   )
   1458 {
   1459   switch (Char) {
   1460     //
   1461     // Mandatory line break characters, which force a line-break
   1462     //
   1463     case 0x000A:
   1464     case 0x000C:
   1465     case 0x000D:
   1466     case 0x2028:
   1467     case 0x2029:
   1468       return 0;
   1469     //
   1470     // Space characters, which is taken as a line-break opportunity
   1471     //
   1472     case 0x0020:
   1473     case 0x1680:
   1474     case 0x2000:
   1475     case 0x2001:
   1476     case 0x2002:
   1477     case 0x2003:
   1478     case 0x2004:
   1479     case 0x2005:
   1480     case 0x2006:
   1481     case 0x2008:
   1482     case 0x2009:
   1483     case 0x200A:
   1484     case 0x205F:
   1485     //
   1486     // In-Word Break Opportunities
   1487     //
   1488     case 0x200B:
   1489       return 1;
   1490     //
   1491     // A space which is not a line-break opportunity
   1492     //
   1493     case 0x00A0:
   1494     case 0x202F:
   1495     //
   1496     // A hyphen which is not a line-break opportunity
   1497     //
   1498     case 0x2011:
   1499       return -1;
   1500     //
   1501     // Hyphen characters which describe line break opportunities after the character
   1502     //
   1503     case 0x058A:
   1504     case 0x2010:
   1505     case 0x2012:
   1506     case 0x2013:
   1507     case 0x0F0B:
   1508     case 0x1361:
   1509     case 0x17D5:
   1510       return 1;
   1511     //
   1512     // A hyphen which describes line break opportunities before and after them, but not between a pair of them
   1513     //
   1514     case 0x2014:
   1515       return 2;
   1516   }
   1517   return -1;
   1518 }
   1519 
   1520 
   1521 /**
   1522   Renders a string to a bitmap or to the display.
   1523 
   1524   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
   1525   @param  Flags                   Describes how the string is to be drawn.
   1526   @param  String                  Points to the null-terminated string to be
   1527                                   displayed.
   1528   @param  StringInfo              Points to the string output information,
   1529                                   including the color and font.  If NULL, then the
   1530                                   string will be output in the default system font
   1531                                   and color.
   1532   @param  Blt                     If this points to a non-NULL on entry, this
   1533                                   points to the image, which is Width pixels   wide
   1534                                   and Height pixels high. The string will be drawn
   1535                                   onto this image and
   1536                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points
   1537                                   to a NULL on entry, then a              buffer
   1538                                   will be allocated to hold the generated image and
   1539                                   the pointer updated on exit. It is the caller's
   1540                                   responsibility to free this buffer.
   1541   @param  BltX                    Specifies the offset from the left and top edge
   1542                                   of the image of the first character cell in the
   1543                                   image.
   1544   @param  BltY                    Specifies the offset from the left and top edge
   1545                                   of the image of the first character cell in the
   1546                                   image.
   1547   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this
   1548                                   will point to an allocated buffer    containing
   1549                                   row information and RowInfoArraySize will be
   1550                                   updated to contain the        number of elements.
   1551                                   This array describes the characters which were at
   1552                                   least partially drawn and the heights of the
   1553                                   rows. It is the caller's responsibility to free
   1554                                   this buffer.
   1555   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it
   1556                                   contains the number of elements in RowInfoArray.
   1557   @param  ColumnInfoArray         If this is non-NULL, then on return it will be
   1558                                   filled with the horizontal offset for each
   1559                                   character in the string on the row where it is
   1560                                   displayed. Non-printing characters will     have
   1561                                   the offset ~0. The caller is responsible to
   1562                                   allocate a buffer large enough so that    there
   1563                                   is one entry for each character in the string,
   1564                                   not including the null-terminator. It is possible
   1565                                   when character display is normalized that some
   1566                                   character cells overlap.
   1567 
   1568   @retval EFI_SUCCESS             The string was successfully rendered.
   1569   @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for
   1570                                   RowInfoArray or Blt.
   1571   @retval EFI_INVALID_PARAMETER   The String or Blt was NULL.
   1572   @retval EFI_INVALID_PARAMETER Flags were invalid combination..
   1573 
   1574 **/
   1575 EFI_STATUS
   1576 EFIAPI
   1577 HiiStringToImage (
   1578   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
   1579   IN  EFI_HII_OUT_FLAGS              Flags,
   1580   IN  CONST EFI_STRING               String,
   1581   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,
   1582   IN  OUT EFI_IMAGE_OUTPUT           **Blt,
   1583   IN  UINTN                          BltX,
   1584   IN  UINTN                          BltY,
   1585   OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,
   1586   OUT UINTN                          *RowInfoArraySize OPTIONAL,
   1587   OUT UINTN                          *ColumnInfoArray  OPTIONAL
   1588   )
   1589 {
   1590   EFI_STATUS                          Status;
   1591   HII_DATABASE_PRIVATE_DATA           *Private;
   1592   UINT8                               **GlyphBuf;
   1593   EFI_HII_GLYPH_INFO                  *Cell;
   1594   UINT8                               *Attributes;
   1595   EFI_IMAGE_OUTPUT                    *Image;
   1596   EFI_STRING                          StringPtr;
   1597   EFI_STRING                          StringTmp;
   1598   EFI_HII_ROW_INFO                    *RowInfo;
   1599   UINTN                               LineWidth;
   1600   UINTN                               LineHeight;
   1601   UINTN                               LineOffset;
   1602   UINTN                               LastLineHeight;
   1603   UINTN                               BaseLineOffset;
   1604   UINT16                              MaxRowNum;
   1605   UINT16                              RowIndex;
   1606   UINTN                               Index;
   1607   UINTN                               NextIndex;
   1608   UINTN                               Index1;
   1609   EFI_FONT_DISPLAY_INFO               *StringInfoOut;
   1610   EFI_FONT_DISPLAY_INFO               *SystemDefault;
   1611   EFI_FONT_HANDLE                     FontHandle;
   1612   EFI_STRING                          StringIn;
   1613   EFI_STRING                          StringIn2;
   1614   UINT16                              Height;
   1615   UINT16                              BaseLine;
   1616   EFI_FONT_INFO                       *FontInfo;
   1617   BOOLEAN                             SysFontFlag;
   1618   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Foreground;
   1619   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Background;
   1620   BOOLEAN                             Transparent;
   1621   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BltBuffer;
   1622   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BufferPtr;
   1623   UINTN                               RowInfoSize;
   1624   BOOLEAN                             LineBreak;
   1625   UINTN                               StrLength;
   1626   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *RowBufferPtr;
   1627   HII_GLOBAL_FONT_INFO                *GlobalFont;
   1628   UINT32                              PreInitBkgnd;
   1629 
   1630   //
   1631   // Check incoming parameters.
   1632   //
   1633 
   1634   if (This == NULL || String == NULL || Blt == NULL) {
   1635     return EFI_INVALID_PARAMETER;
   1636   }
   1637   if (*Blt == NULL) {
   1638     //
   1639     // These two flag cannot be used if Blt is NULL upon entry.
   1640     //
   1641     if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {
   1642       return EFI_INVALID_PARAMETER;
   1643     }
   1644     if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {
   1645       return EFI_INVALID_PARAMETER;
   1646     }
   1647   }
   1648   //
   1649   // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
   1650   //
   1651   if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {
   1652     return EFI_INVALID_PARAMETER;
   1653   }
   1654   if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
   1655     return EFI_INVALID_PARAMETER;
   1656   }
   1657   //
   1658   // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.
   1659   //
   1660   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)) {
   1661     return EFI_INVALID_PARAMETER;
   1662   }
   1663 
   1664   if (*Blt == NULL) {
   1665     //
   1666     // Create a new bitmap and draw the string onto this image.
   1667     //
   1668     Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
   1669     if (Image == NULL) {
   1670       return EFI_OUT_OF_RESOURCES;
   1671     }
   1672     Image->Width  = 800;
   1673     Image->Height = 600;
   1674     Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
   1675     if (Image->Image.Bitmap == NULL) {
   1676       FreePool (Image);
   1677       return EFI_OUT_OF_RESOURCES;
   1678     }
   1679 
   1680     //
   1681     // Other flags are not permitted when Blt is NULL.
   1682     //
   1683     Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
   1684     *Blt = Image;
   1685   }
   1686 
   1687   StrLength = StrLen(String);
   1688   GlyphBuf = (UINT8 **) AllocateZeroPool (StrLength * sizeof (UINT8 *));
   1689   ASSERT (GlyphBuf != NULL);
   1690   Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
   1691   ASSERT (Cell != NULL);
   1692   Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));
   1693   ASSERT (Attributes != NULL);
   1694 
   1695   RowInfo       = NULL;
   1696   Status        = EFI_SUCCESS;
   1697   StringIn2     = NULL;
   1698   SystemDefault = NULL;
   1699   StringIn      = NULL;
   1700 
   1701   //
   1702   // Calculate the string output information, including specified color and font .
   1703   // If StringInfo does not points to system font info, it must indicate an existing
   1704   // EFI_FONT_INFO.
   1705   //
   1706   StringInfoOut = NULL;
   1707   FontHandle    = NULL;
   1708   Private       = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
   1709   SysFontFlag   = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);
   1710 
   1711   if (SysFontFlag) {
   1712     ASSERT (SystemDefault != NULL);
   1713     FontInfo   = NULL;
   1714     Height     = SystemDefault->FontInfo.FontSize;
   1715     BaseLine   = SystemDefault->FontInfo.FontSize;
   1716     Foreground = SystemDefault->ForegroundColor;
   1717     Background = SystemDefault->BackgroundColor;
   1718 
   1719   } else {
   1720     //
   1721     //  StringInfo must not be NULL if it is not system info.
   1722     //
   1723     ASSERT (StringInfo != NULL);
   1724     Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *) StringInfo, &StringInfoOut, NULL);
   1725     if (Status == EFI_NOT_FOUND) {
   1726       //
   1727       // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
   1728       // Use the system font instead. Still use the color specified by StringInfo.
   1729       //
   1730       SysFontFlag = TRUE;
   1731       FontInfo    = NULL;
   1732       Height      = SystemDefault->FontInfo.FontSize;
   1733       BaseLine    = SystemDefault->FontInfo.FontSize;
   1734       Foreground  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;
   1735       Background  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;
   1736 
   1737     } else if (Status == EFI_SUCCESS) {
   1738       FontInfo   = &StringInfoOut->FontInfo;
   1739       IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);
   1740       Height     = GlobalFont->FontPackage->Height;
   1741       BaseLine   = GlobalFont->FontPackage->BaseLine;
   1742       Foreground = StringInfoOut->ForegroundColor;
   1743       Background = StringInfoOut->BackgroundColor;
   1744     } else {
   1745       goto Exit;
   1746     }
   1747   }
   1748 
   1749   //
   1750   // Use the maximum height of font as the base line.
   1751   // And, use the maximum height as line height.
   1752   //
   1753   LineHeight     = Height;
   1754   LastLineHeight = Height;
   1755   BaseLineOffset = Height - BaseLine;
   1756 
   1757   //
   1758   // Parse the string to be displayed to drop some ignored characters.
   1759   //
   1760 
   1761   StringPtr = String;
   1762 
   1763   //
   1764   // Ignore line-break characters only. Hyphens or dash character will be displayed
   1765   // without line-break opportunity.
   1766   //
   1767   if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
   1768     StringIn = AllocateZeroPool (StrSize (StringPtr));
   1769     if (StringIn == NULL) {
   1770       Status = EFI_OUT_OF_RESOURCES;
   1771       goto Exit;
   1772     }
   1773     StringTmp = StringIn;
   1774     while (*StringPtr != 0) {
   1775       if (IsLineBreak (*StringPtr) == 0) {
   1776         StringPtr++;
   1777       } else {
   1778         *StringTmp++ = *StringPtr++;
   1779       }
   1780     }
   1781     *StringTmp = 0;
   1782     StringPtr  = StringIn;
   1783   }
   1784   //
   1785   // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
   1786   // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.
   1787   //
   1788   StringIn2  = AllocateZeroPool (StrSize (StringPtr));
   1789   if (StringIn2 == NULL) {
   1790     Status = EFI_OUT_OF_RESOURCES;
   1791     goto Exit;
   1792   }
   1793   Index     = 0;
   1794   StringTmp = StringIn2;
   1795   StrLength = StrLen(StringPtr);
   1796   while (*StringPtr != 0 && Index < StrLength) {
   1797     if (IsLineBreak (*StringPtr) == 0) {
   1798       *StringTmp++ = *StringPtr++;
   1799       Index++;
   1800       continue;
   1801     }
   1802 
   1803     Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
   1804     if (Status == EFI_NOT_FOUND) {
   1805       if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
   1806         GlyphBuf[Index] = NULL;
   1807         ZeroMem (&Cell[Index], sizeof (Cell[Index]));
   1808         Status = EFI_SUCCESS;
   1809       } else {
   1810         //
   1811         // Unicode 0xFFFD must exist in current hii database if this flag is not set.
   1812         //
   1813         Status = GetGlyphBuffer (
   1814                    Private,
   1815                    REPLACE_UNKNOWN_GLYPH,
   1816                    FontInfo,
   1817                    &GlyphBuf[Index],
   1818                    &Cell[Index],
   1819                    &Attributes[Index]
   1820                    );
   1821         if (EFI_ERROR (Status)) {
   1822           Status = EFI_INVALID_PARAMETER;
   1823         }
   1824       }
   1825     }
   1826 
   1827     if (EFI_ERROR (Status)) {
   1828       goto Exit;
   1829     }
   1830 
   1831     *StringTmp++ = *StringPtr++;
   1832     Index++;
   1833   }
   1834   *StringTmp = 0;
   1835   StringPtr  = StringIn2;
   1836 
   1837   //
   1838   // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
   1839   // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
   1840   // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
   1841   // Otherwise render this string to a new allocated image and output it.
   1842   //
   1843   Image     = *Blt;
   1844   BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
   1845   if (Image->Height < BltY) {
   1846     //
   1847     // the top edge of the image should be in Image resolution scope.
   1848     //
   1849     Status = EFI_INVALID_PARAMETER;
   1850     goto Exit;
   1851   }
   1852   MaxRowNum = (UINT16) ((Image->Height - BltY) / Height);
   1853   if ((Image->Height - BltY) % Height != 0) {
   1854     LastLineHeight = (Image->Height - BltY) % Height;
   1855     MaxRowNum++;
   1856   }
   1857 
   1858   RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
   1859   if (RowInfo == NULL) {
   1860     Status = EFI_OUT_OF_RESOURCES;
   1861     goto Exit;
   1862   }
   1863 
   1864   //
   1865   // Format the glyph buffer according to flags.
   1866   //
   1867   Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
   1868 
   1869   for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
   1870     LineWidth      = 0;
   1871     LineBreak      = FALSE;
   1872 
   1873     //
   1874     // Clip the final row if the row's bottom-most on pixel cannot fit when
   1875     // EFI_HII_OUT_FLAG_CLEAN_Y is set.
   1876     //
   1877     if (RowIndex == MaxRowNum - 1) {
   1878       if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y && LastLineHeight < LineHeight ) {
   1879         //
   1880         // Don't draw at all if the row's bottom-most on pixel cannot fit.
   1881         //
   1882         break;
   1883       }
   1884       LineHeight = LastLineHeight;
   1885     }
   1886 
   1887     //
   1888     // Calculate how many characters there are in a row.
   1889     //
   1890     RowInfo[RowIndex].StartIndex = Index;
   1891 
   1892     while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
   1893       if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&
   1894            IsLineBreak (StringPtr[Index]) == 0) {
   1895         //
   1896         // It forces a line break that ends this row.
   1897         //
   1898         Index++;
   1899         LineBreak = TRUE;
   1900         break;
   1901       }
   1902 
   1903       //
   1904       // If the glyph of the character is existing, then accumulate the actual printed width
   1905       //
   1906       LineWidth += (UINTN) Cell[Index].AdvanceX;
   1907 
   1908       Index++;
   1909     }
   1910 
   1911     //
   1912     // Record index of next char.
   1913     //
   1914     NextIndex = Index;
   1915     //
   1916     // Return to the previous char.
   1917     //
   1918     Index--;
   1919     if (LineBreak && Index > 0 ) {
   1920       //
   1921       // Return the previous non line break char.
   1922       //
   1923       Index --;
   1924     }
   1925 
   1926     //
   1927     // If this character is the last character of a row, we need not
   1928     // draw its (AdvanceX - Width - OffsetX) for next character.
   1929     //
   1930     LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
   1931 
   1932     //
   1933     // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
   1934     //
   1935     if (LineWidth + BltX <= Image->Width ||
   1936       (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {
   1937       //
   1938       // Record right-most character in RowInfo even if it is partially displayed.
   1939       //
   1940       RowInfo[RowIndex].EndIndex       = Index;
   1941       RowInfo[RowIndex].LineWidth      = LineWidth;
   1942       RowInfo[RowIndex].LineHeight     = LineHeight;
   1943       RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
   1944     } else {
   1945       //
   1946       // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
   1947       // if its right-most on pixel cannot fit.
   1948       //
   1949       if (Index > RowInfo[RowIndex].StartIndex) {
   1950         //
   1951         // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
   1952         //
   1953         LineWidth -= (UINTN) (Cell[Index].Width + Cell[Index].OffsetX);
   1954         LineWidth -= (UINTN) (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
   1955         RowInfo[RowIndex].EndIndex       = Index - 1;
   1956         RowInfo[RowIndex].LineWidth      = LineWidth;
   1957         RowInfo[RowIndex].LineHeight     = LineHeight;
   1958         RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
   1959       } else {
   1960         //
   1961         // There is no enough column to draw any character, so set current line width to zero.
   1962         // And go to draw Next line if LineBreak is set.
   1963         //
   1964         RowInfo[RowIndex].LineWidth      = 0;
   1965         goto NextLine;
   1966       }
   1967     }
   1968 
   1969     //
   1970     // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
   1971     // opportunity prior to a character whose right-most extent would exceed Width.
   1972     // Search the right-most line-break opportunity here.
   1973     //
   1974     if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP &&
   1975         (RowInfo[RowIndex].LineWidth + BltX > Image->Width || StringPtr[NextIndex] != 0) &&
   1976         !LineBreak) {
   1977       if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
   1978         LineWidth = RowInfo[RowIndex].LineWidth;
   1979         for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
   1980           if (Index1 == RowInfo[RowIndex].EndIndex) {
   1981             LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
   1982           } else {
   1983             LineWidth -= Cell[Index1].AdvanceX;
   1984           }
   1985           if (IsLineBreak (StringPtr[Index1]) > 0) {
   1986             LineBreak = TRUE;
   1987             if (Index1 > RowInfo[RowIndex].StartIndex) {
   1988               RowInfo[RowIndex].EndIndex = Index1 - 1;
   1989             }
   1990             //
   1991             // relocate to the character after the right-most line break opportunity of this line
   1992             //
   1993             NextIndex = Index1 + 1;
   1994             break;
   1995           }
   1996           //
   1997           // If don't find a line break opportunity from EndIndex to StartIndex,
   1998           // then jump out.
   1999           //
   2000           if (Index1 == RowInfo[RowIndex].StartIndex)
   2001             break;
   2002         }
   2003 
   2004         //
   2005         // Update LineWidth to the real width
   2006         //
   2007         if (IsLineBreak (StringPtr[Index1]) > 0) {
   2008           if (Index1 == RowInfo[RowIndex].StartIndex) {
   2009             LineWidth = 0;
   2010           } else {
   2011             LineWidth -= (UINTN) (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
   2012           }
   2013           RowInfo[RowIndex].LineWidth = LineWidth;
   2014         }
   2015       }
   2016       //
   2017       // If no line-break opportunity can be found, then the text will
   2018       // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
   2019       //
   2020       if (!LineBreak) {
   2021         LineWidth = RowInfo[RowIndex].LineWidth;
   2022         Index1    = RowInfo[RowIndex].EndIndex;
   2023         if (LineWidth + BltX > Image->Width) {
   2024           if (Index1 > RowInfo[RowIndex].StartIndex) {
   2025             //
   2026             // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
   2027             //
   2028             LineWidth -= (UINTN) (Cell[Index1].Width + Cell[Index1].OffsetX);
   2029             LineWidth -= (UINTN) (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
   2030             RowInfo[RowIndex].EndIndex       = Index1 - 1;
   2031             RowInfo[RowIndex].LineWidth      = LineWidth;
   2032           } else {
   2033             //
   2034             // There is no enough column to draw any character, so set current line width to zero.
   2035             // And go to draw Next line if LineBreak is set.
   2036             //
   2037             RowInfo[RowIndex].LineWidth = 0;
   2038             goto NextLine;
   2039           }
   2040         }
   2041       }
   2042     }
   2043 
   2044     //
   2045     // LineWidth can't exceed Image width.
   2046     //
   2047     if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
   2048       RowInfo[RowIndex].LineWidth = Image->Width - BltX;
   2049     }
   2050 
   2051     //
   2052     // Draw it to screen or existing bitmap depending on whether
   2053     // EFI_HII_DIRECT_TO_SCREEN is set.
   2054     //
   2055     LineOffset = 0;
   2056     if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
   2057       BltBuffer = NULL;
   2058       if (RowInfo[RowIndex].LineWidth != 0) {
   2059         BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
   2060         if (BltBuffer == NULL) {
   2061           Status = EFI_OUT_OF_RESOURCES;
   2062           goto Exit;
   2063         }
   2064         //
   2065         // Initialize the background color.
   2066         //
   2067         PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;
   2068         SetMem32 (BltBuffer,RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),PreInitBkgnd);
   2069         //
   2070         // Set BufferPtr to Origin by adding baseline to the starting position.
   2071         //
   2072         BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
   2073       }
   2074       for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
   2075         if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {
   2076           //
   2077           // Only BLT these character which have corresponding glyph in font database.
   2078           //
   2079           GlyphToImage (
   2080             GlyphBuf[Index1],
   2081             Foreground,
   2082             Background,
   2083             (UINT16) RowInfo[RowIndex].LineWidth,
   2084             BaseLine,
   2085             RowInfo[RowIndex].LineWidth - LineOffset,
   2086             RowInfo[RowIndex].LineHeight,
   2087             Transparent,
   2088             &Cell[Index1],
   2089             Attributes[Index1],
   2090             &BufferPtr
   2091           );
   2092         }
   2093         if (ColumnInfoArray != NULL) {
   2094           if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)
   2095               || RowInfo[RowIndex].LineWidth == 0) {
   2096             *ColumnInfoArray = (UINTN) ~0;
   2097           } else {
   2098             *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
   2099           }
   2100           ColumnInfoArray++;
   2101         }
   2102         LineOffset += Cell[Index1].AdvanceX;
   2103       }
   2104 
   2105       if (BltBuffer != NULL) {
   2106         Status = Image->Image.Screen->Blt (
   2107                                         Image->Image.Screen,
   2108                                         BltBuffer,
   2109                                         EfiBltBufferToVideo,
   2110                                         0,
   2111                                         0,
   2112                                         BltX,
   2113                                         BltY,
   2114                                         RowInfo[RowIndex].LineWidth,
   2115                                         RowInfo[RowIndex].LineHeight,
   2116                                         0
   2117                                         );
   2118         if (EFI_ERROR (Status)) {
   2119           FreePool (BltBuffer);
   2120           goto Exit;
   2121         }
   2122 
   2123         FreePool (BltBuffer);
   2124       }
   2125     } else {
   2126       //
   2127       // Save the starting position for calculate the starting position of next row.
   2128       //
   2129       RowBufferPtr = BufferPtr;
   2130       //
   2131       // Set BufferPtr to Origin by adding baseline to the starting position.
   2132       //
   2133       BufferPtr = BufferPtr + BaseLine * Image->Width;
   2134       for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
   2135         if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {
   2136           //
   2137           // Only BLT these character which have corresponding glyph in font database.
   2138           //
   2139           GlyphToImage (
   2140             GlyphBuf[Index1],
   2141             Foreground,
   2142             Background,
   2143             Image->Width,
   2144             BaseLine,
   2145             RowInfo[RowIndex].LineWidth - LineOffset,
   2146             RowInfo[RowIndex].LineHeight,
   2147             Transparent,
   2148             &Cell[Index1],
   2149             Attributes[Index1],
   2150             &BufferPtr
   2151           );
   2152         }
   2153         if (ColumnInfoArray != NULL) {
   2154           if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)
   2155               || RowInfo[RowIndex].LineWidth == 0) {
   2156             *ColumnInfoArray = (UINTN) ~0;
   2157           } else {
   2158             *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
   2159           }
   2160           ColumnInfoArray++;
   2161         }
   2162         LineOffset += Cell[Index1].AdvanceX;
   2163       }
   2164 
   2165       //
   2166       // Jump to starting position of next row.
   2167       //
   2168       if (RowIndex == 0) {
   2169         BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
   2170       } else {
   2171         BufferPtr = RowBufferPtr + LineHeight * Image->Width;
   2172       }
   2173     }
   2174 
   2175 NextLine:
   2176     //
   2177     // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down
   2178     //
   2179     BltY += RowInfo[RowIndex].LineHeight;
   2180 
   2181     RowIndex++;
   2182     Index = NextIndex;
   2183 
   2184     if (!LineBreak) {
   2185       //
   2186       // If there is not a mandatory line break or line break opportunity, only render one line to image
   2187       //
   2188       break;
   2189     }
   2190   }
   2191 
   2192   //
   2193   // Write output parameters.
   2194   //
   2195   RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
   2196   if (RowInfoArray != NULL) {
   2197     if (RowInfoSize > 0) {
   2198       *RowInfoArray = AllocateZeroPool (RowInfoSize);
   2199       if (*RowInfoArray == NULL) {
   2200         Status = EFI_OUT_OF_RESOURCES;
   2201         goto Exit;
   2202       }
   2203       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
   2204     } else {
   2205       *RowInfoArray = NULL;
   2206     }
   2207   }
   2208   if (RowInfoArraySize != NULL) {
   2209     *RowInfoArraySize = RowIndex;
   2210   }
   2211 
   2212   Status = EFI_SUCCESS;
   2213 
   2214 Exit:
   2215 
   2216   for (Index = 0; Index < StrLength; Index++) {
   2217     if (GlyphBuf[Index] != NULL) {
   2218       FreePool (GlyphBuf[Index]);
   2219     }
   2220   }
   2221   if (StringIn != NULL) {
   2222     FreePool (StringIn);
   2223   }
   2224   if (StringIn2 != NULL) {
   2225     FreePool (StringIn2);
   2226   }
   2227   if (StringInfoOut != NULL) {
   2228     FreePool (StringInfoOut);
   2229   }
   2230   if (RowInfo != NULL) {
   2231     FreePool (RowInfo);
   2232   }
   2233   if (SystemDefault != NULL) {
   2234     FreePool (SystemDefault);
   2235   }
   2236   if (GlyphBuf != NULL) {
   2237     FreePool (GlyphBuf);
   2238   }
   2239   if (Cell != NULL) {
   2240     FreePool (Cell);
   2241   }
   2242   if (Attributes != NULL) {
   2243     FreePool (Attributes);
   2244   }
   2245 
   2246   return Status;
   2247 }
   2248 
   2249 
   2250 /**
   2251   Render a string to a bitmap or the screen containing the contents of the specified string.
   2252 
   2253   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
   2254   @param  Flags                   Describes how the string is to be drawn.
   2255   @param  PackageList             The package list in the HII database to search
   2256                                   for the specified string.
   2257   @param  StringId                The string's id, which is unique within
   2258                                   PackageList.
   2259   @param  Language                Points to the language for the retrieved string.
   2260                                   If NULL, then the current system language is
   2261                                   used.
   2262   @param  StringInfo              Points to the string output information,
   2263                                   including the color and font.  If NULL, then the
   2264                                   string will be output in the default system font
   2265                                   and color.
   2266   @param  Blt                     If this points to a non-NULL on entry, this
   2267                                   points to the image, which is Width pixels   wide
   2268                                   and Height pixels high. The string will be drawn
   2269                                   onto this image and
   2270                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points
   2271                                   to a NULL on entry, then a              buffer
   2272                                   will be allocated to hold the generated image and
   2273                                   the pointer updated on exit. It is the caller's
   2274                                   responsibility to free this buffer.
   2275   @param  BltX                    Specifies the offset from the left and top edge
   2276                                   of the image of the first character cell in the
   2277                                   image.
   2278   @param  BltY                    Specifies the offset from the left and top edge
   2279                                   of the image of the first character cell in the
   2280                                   image.
   2281   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this
   2282                                   will point to an allocated buffer    containing
   2283                                   row information and RowInfoArraySize will be
   2284                                   updated to contain the        number of elements.
   2285                                   This array describes the characters which were at
   2286                                   least partially drawn and the heights of the
   2287                                   rows. It is the caller's responsibility to free
   2288                                   this buffer.
   2289   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it
   2290                                   contains the number of elements in RowInfoArray.
   2291   @param  ColumnInfoArray         If this is non-NULL, then on return it will be
   2292                                   filled with the horizontal offset for each
   2293                                   character in the string on the row where it is
   2294                                   displayed. Non-printing characters will     have
   2295                                   the offset ~0. The caller is responsible to
   2296                                   allocate a buffer large enough so that    there
   2297                                   is one entry for each character in the string,
   2298                                   not including the null-terminator. It is possible
   2299                                   when character display is normalized that some
   2300                                   character cells overlap.
   2301 
   2302   @retval EFI_SUCCESS            The string was successfully rendered.
   2303   @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for
   2304                                  RowInfoArray or Blt.
   2305   @retval EFI_INVALID_PARAMETER  The Blt or PackageList was NULL.
   2306   @retval EFI_INVALID_PARAMETER  Flags were invalid combination.
   2307   @retval EFI_NOT_FOUND          The specified PackageList is not in the Database or the string id is not
   2308                                  in the specified PackageList.
   2309 
   2310 **/
   2311 EFI_STATUS
   2312 EFIAPI
   2313 HiiStringIdToImage (
   2314   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
   2315   IN  EFI_HII_OUT_FLAGS              Flags,
   2316   IN  EFI_HII_HANDLE                 PackageList,
   2317   IN  EFI_STRING_ID                  StringId,
   2318   IN  CONST CHAR8*                   Language,
   2319   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,
   2320   IN  OUT EFI_IMAGE_OUTPUT           **Blt,
   2321   IN  UINTN                          BltX,
   2322   IN  UINTN                          BltY,
   2323   OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,
   2324   OUT UINTN                          *RowInfoArraySize OPTIONAL,
   2325   OUT UINTN                          *ColumnInfoArray  OPTIONAL
   2326   )
   2327 {
   2328   EFI_STATUS                          Status;
   2329   HII_DATABASE_PRIVATE_DATA           *Private;
   2330   EFI_HII_STRING_PROTOCOL             *HiiString;
   2331   EFI_STRING                          String;
   2332   UINTN                               StringSize;
   2333   UINTN                               FontLen;
   2334   UINTN                               NameSize;
   2335   EFI_FONT_INFO                       *StringFontInfo;
   2336   EFI_FONT_DISPLAY_INFO               *NewStringInfo;
   2337   CHAR8                               TempSupportedLanguages;
   2338   CHAR8                               *SupportedLanguages;
   2339   UINTN                               SupportedLanguagesSize;
   2340   CHAR8                               *CurrentLanguage;
   2341   CHAR8                               *BestLanguage;
   2342 
   2343   if (This == NULL || PackageList == NULL || Blt == NULL || PackageList == NULL) {
   2344     return EFI_INVALID_PARAMETER;
   2345   }
   2346 
   2347   if (!IsHiiHandleValid (PackageList)) {
   2348     return EFI_NOT_FOUND;
   2349   }
   2350 
   2351   //
   2352   // Initialize string pointers to be NULL
   2353   //
   2354   SupportedLanguages = NULL;
   2355   CurrentLanguage    = NULL;
   2356   BestLanguage       = NULL;
   2357   String             = NULL;
   2358   StringFontInfo     = NULL;
   2359   NewStringInfo      = NULL;
   2360 
   2361   //
   2362   // Get the string to be displayed.
   2363   //
   2364   Private   = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
   2365   HiiString = &Private->HiiString;
   2366 
   2367   //
   2368   // Get the size of supported language.
   2369   //
   2370   SupportedLanguagesSize = 0;
   2371   Status = HiiString->GetLanguages (
   2372                         HiiString,
   2373                         PackageList,
   2374                         &TempSupportedLanguages,
   2375                         &SupportedLanguagesSize
   2376                         );
   2377   if (Status != EFI_BUFFER_TOO_SMALL) {
   2378     return Status;
   2379   }
   2380 
   2381   SupportedLanguages = AllocatePool (SupportedLanguagesSize);
   2382   if (SupportedLanguages == NULL) {
   2383     return EFI_OUT_OF_RESOURCES;
   2384   }
   2385 
   2386   Status = HiiString->GetLanguages (
   2387                         HiiString,
   2388                         PackageList,
   2389                         SupportedLanguages,
   2390                         &SupportedLanguagesSize
   2391                         );
   2392   if (EFI_ERROR (Status)) {
   2393     goto Exit;
   2394   }
   2395 
   2396   if (Language == NULL) {
   2397     Language = "";
   2398   }
   2399   GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLanguage, NULL);
   2400   BestLanguage = GetBestLanguage (
   2401                    SupportedLanguages,
   2402                    FALSE,
   2403                    Language,
   2404                    (CurrentLanguage == NULL) ? CurrentLanguage : "",
   2405                    (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
   2406                    NULL
   2407                    );
   2408   if (BestLanguage == NULL) {
   2409     Status = EFI_NOT_FOUND;
   2410     goto Exit;
   2411   }
   2412 
   2413   StringSize = MAX_STRING_LENGTH;
   2414   String = (EFI_STRING) AllocateZeroPool (StringSize);
   2415   if (String == NULL) {
   2416     Status = EFI_OUT_OF_RESOURCES;
   2417     goto Exit;
   2418   }
   2419 
   2420   Status = HiiString->GetString (
   2421                         HiiString,
   2422                         BestLanguage,
   2423                         PackageList,
   2424                         StringId,
   2425                         String,
   2426                         &StringSize,
   2427                         &StringFontInfo
   2428                         );
   2429   if (Status == EFI_BUFFER_TOO_SMALL) {
   2430     FreePool (String);
   2431     String = (EFI_STRING) AllocateZeroPool (StringSize);
   2432     if (String == NULL) {
   2433       Status = EFI_OUT_OF_RESOURCES;
   2434       goto Exit;
   2435     }
   2436     Status = HiiString->GetString (
   2437                           HiiString,
   2438                           BestLanguage,
   2439                           PackageList,
   2440                           StringId,
   2441                           String,
   2442                           &StringSize,
   2443                           NULL
   2444                           );
   2445   }
   2446 
   2447   if (EFI_ERROR (Status)) {
   2448     goto Exit;
   2449   }
   2450 
   2451   //
   2452   // When StringInfo specifies that string will be output in the system default font and color,
   2453   // use particular stringfontinfo described in string package instead if exists.
   2454   // StringFontInfo equals NULL means system default font attaches with the string block.
   2455   //
   2456   if (StringFontInfo != NULL && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, NULL, NULL)) {
   2457     NameSize = StrSize (StringFontInfo->FontName);
   2458     FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
   2459     NewStringInfo = AllocateZeroPool (FontLen);
   2460     if (NewStringInfo == NULL) {
   2461       Status = EFI_OUT_OF_RESOURCES;
   2462       goto Exit;
   2463     }
   2464     NewStringInfo->FontInfoMask       = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
   2465     NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
   2466     NewStringInfo->FontInfo.FontSize  = StringFontInfo->FontSize;
   2467     StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
   2468 
   2469     Status = HiiStringToImage (
   2470                This,
   2471                Flags,
   2472                String,
   2473                NewStringInfo,
   2474                Blt,
   2475                BltX,
   2476                BltY,
   2477                RowInfoArray,
   2478                RowInfoArraySize,
   2479                ColumnInfoArray
   2480                );
   2481     goto Exit;
   2482   }
   2483 
   2484   Status = HiiStringToImage (
   2485            This,
   2486            Flags,
   2487            String,
   2488            StringInfo,
   2489            Blt,
   2490            BltX,
   2491            BltY,
   2492            RowInfoArray,
   2493            RowInfoArraySize,
   2494            ColumnInfoArray
   2495            );
   2496 
   2497 Exit:
   2498   if (SupportedLanguages != NULL) {
   2499     FreePool (SupportedLanguages);
   2500   }
   2501   if (CurrentLanguage != NULL) {
   2502     FreePool (CurrentLanguage);
   2503   }
   2504   if (BestLanguage != NULL) {
   2505     FreePool (BestLanguage);
   2506   }
   2507   if (String != NULL) {
   2508     FreePool (String);
   2509   }
   2510   if (StringFontInfo != NULL) {
   2511     FreePool (StringFontInfo);
   2512   }
   2513   if (NewStringInfo != NULL) {
   2514     FreePool (NewStringInfo);
   2515   }
   2516 
   2517   return Status;
   2518 }
   2519 
   2520 
   2521 /**
   2522   Convert the glyph for a single character into a bitmap.
   2523 
   2524   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
   2525   @param  Char                    Character to retrieve.
   2526   @param  StringInfo              Points to the string font and color information
   2527                                   or NULL if the string should use the default
   2528                                   system font and color.
   2529   @param  Blt                     Thus must point to a NULL on entry. A buffer will
   2530                                   be allocated to hold the output and the pointer
   2531                                   updated on exit. It is the caller's
   2532                                   responsibility to free this buffer.
   2533   @param  Baseline                Number of pixels from the bottom of the bitmap to
   2534                                   the baseline.
   2535 
   2536   @retval EFI_SUCCESS             Glyph bitmap created.
   2537   @retval EFI_OUT_OF_RESOURCES    Unable to allocate the output buffer Blt.
   2538   @retval EFI_WARN_UNKNOWN_GLYPH  The glyph was unknown and was replaced with the
   2539                                   glyph for Unicode character 0xFFFD.
   2540   @retval EFI_INVALID_PARAMETER   Blt is NULL or *Blt is not NULL.
   2541 
   2542 **/
   2543 EFI_STATUS
   2544 EFIAPI
   2545 HiiGetGlyph (
   2546   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
   2547   IN  CHAR16                         Char,
   2548   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo,
   2549   OUT EFI_IMAGE_OUTPUT               **Blt,
   2550   OUT UINTN                          *Baseline OPTIONAL
   2551   )
   2552 {
   2553   EFI_STATUS                         Status;
   2554   HII_DATABASE_PRIVATE_DATA          *Private;
   2555   EFI_IMAGE_OUTPUT                   *Image;
   2556   UINT8                              *GlyphBuffer;
   2557   EFI_FONT_DISPLAY_INFO              *SystemDefault;
   2558   EFI_FONT_DISPLAY_INFO              *StringInfoOut;
   2559   BOOLEAN                            Default;
   2560   EFI_FONT_HANDLE                    FontHandle;
   2561   EFI_STRING                         String;
   2562   EFI_HII_GLYPH_INFO                 Cell;
   2563   EFI_FONT_INFO                      *FontInfo;
   2564   UINT8                              Attributes;
   2565   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Foreground;
   2566   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Background;
   2567   EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer;
   2568   UINT16                             BaseLine;
   2569 
   2570   if (This == NULL || Blt == NULL || *Blt != NULL) {
   2571     return EFI_INVALID_PARAMETER;
   2572   }
   2573 
   2574   Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
   2575 
   2576   Default       = FALSE;
   2577   Image         = NULL;
   2578   SystemDefault = NULL;
   2579   FontHandle    = NULL;
   2580   String        = NULL;
   2581   GlyphBuffer   = NULL;
   2582   StringInfoOut = NULL;
   2583   FontInfo      = NULL;
   2584 
   2585   ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
   2586   ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
   2587 
   2588   Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);
   2589 
   2590   if (!Default) {
   2591     //
   2592     // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
   2593     // the specified color and font.
   2594     //
   2595     String = (EFI_STRING) AllocateZeroPool (sizeof (CHAR16) * 2);
   2596     if (String == NULL) {
   2597       Status = EFI_OUT_OF_RESOURCES;
   2598       goto Exit;
   2599     }
   2600     *String = Char;
   2601     *(String + 1) = 0;
   2602 
   2603     Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
   2604     if (EFI_ERROR (Status)) {
   2605       goto Exit;
   2606     }
   2607     ASSERT (StringInfoOut != NULL);
   2608     FontInfo   = &StringInfoOut->FontInfo;
   2609     Foreground = StringInfoOut->ForegroundColor;
   2610     Background = StringInfoOut->BackgroundColor;
   2611   } else {
   2612     ASSERT (SystemDefault != NULL);
   2613     Foreground = SystemDefault->ForegroundColor;
   2614     Background = SystemDefault->BackgroundColor;
   2615   }
   2616 
   2617   Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
   2618   if (EFI_ERROR (Status)) {
   2619     goto Exit;
   2620   }
   2621 
   2622   Image = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
   2623   if (Image == NULL) {
   2624     Status = EFI_OUT_OF_RESOURCES;
   2625     goto Exit;
   2626   }
   2627   Image->Width   = Cell.Width;
   2628   Image->Height  = Cell.Height;
   2629 
   2630   if (Image->Width * Image->Height > 0) {
   2631     Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
   2632     if (Image->Image.Bitmap == NULL) {
   2633       FreePool (Image);
   2634       Status = EFI_OUT_OF_RESOURCES;
   2635       goto Exit;
   2636     }
   2637 
   2638     //
   2639     // Set BaseLine to the char height.
   2640     //
   2641     BaseLine  = (UINT16) (Cell.Height + Cell.OffsetY);
   2642     //
   2643     // Set BltBuffer to the position of Origin.
   2644     //
   2645     BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
   2646     GlyphToImage (
   2647       GlyphBuffer,
   2648       Foreground,
   2649       Background,
   2650       Image->Width,
   2651       BaseLine,
   2652       Cell.Width + Cell.OffsetX,
   2653       BaseLine - Cell.OffsetY,
   2654       FALSE,
   2655       &Cell,
   2656       Attributes,
   2657       &BltBuffer
   2658       );
   2659   }
   2660 
   2661   *Blt = Image;
   2662   if (Baseline != NULL) {
   2663     *Baseline = Cell.OffsetY;
   2664   }
   2665 
   2666   Status = EFI_SUCCESS;
   2667 
   2668 Exit:
   2669 
   2670   if (Status == EFI_NOT_FOUND) {
   2671     //
   2672     // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
   2673     //
   2674     if (Char != REPLACE_UNKNOWN_GLYPH) {
   2675       Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
   2676       if (!EFI_ERROR (Status)) {
   2677         Status = EFI_WARN_UNKNOWN_GLYPH;
   2678       }
   2679     } else {
   2680       Status = EFI_WARN_UNKNOWN_GLYPH;
   2681     }
   2682   }
   2683 
   2684   if (SystemDefault != NULL) {
   2685    FreePool (SystemDefault);
   2686   }
   2687   if (StringInfoOut != NULL) {
   2688     FreePool (StringInfoOut);
   2689   }
   2690   if (String != NULL) {
   2691     FreePool (String);
   2692   }
   2693   if (GlyphBuffer != NULL) {
   2694     FreePool (GlyphBuffer);
   2695   }
   2696 
   2697   return Status;
   2698 }
   2699 
   2700 
   2701 /**
   2702   This function iterates through fonts which match the specified font, using
   2703   the specified criteria. If String is non-NULL, then all of the characters in
   2704   the string must exist in order for a candidate font to be returned.
   2705 
   2706   @param  This                    A pointer to the EFI_HII_FONT_PROTOCOL instance.
   2707   @param  FontHandle              On entry, points to the font handle returned by a
   2708                                    previous call to GetFontInfo() or NULL to start
   2709                                   with the  first font. On return, points to the
   2710                                   returned font handle or points to NULL if there
   2711                                   are no more matching fonts.
   2712   @param  StringInfoIn            Upon entry, points to the font to return information
   2713                                   about. If NULL, then the information about the system
   2714                                   default font will be returned.
   2715   @param  StringInfoOut           Upon return, contains the matching font's information.
   2716                                   If NULL, then no information is returned. This buffer
   2717                                   is allocated with a call to the Boot Service AllocatePool().
   2718                                   It is the caller's responsibility to call the Boot
   2719                                   Service FreePool() when the caller no longer requires
   2720                                   the contents of StringInfoOut.
   2721   @param  String                  Points to the string which will be tested to
   2722                                   determine  if all characters are available. If
   2723                                   NULL, then any font  is acceptable.
   2724 
   2725   @retval EFI_SUCCESS             Matching font returned successfully.
   2726   @retval EFI_NOT_FOUND           No matching font was found.
   2727   @retval EFI_INVALID_PARAMETER  StringInfoIn->FontInfoMask is an invalid combination.
   2728   @retval EFI_OUT_OF_RESOURCES    There were insufficient resources to complete the
   2729                                   request.
   2730 
   2731 **/
   2732 EFI_STATUS
   2733 EFIAPI
   2734 HiiGetFontInfo (
   2735   IN  CONST EFI_HII_FONT_PROTOCOL    *This,
   2736   IN  OUT   EFI_FONT_HANDLE          *FontHandle,
   2737   IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfoIn, OPTIONAL
   2738   OUT       EFI_FONT_DISPLAY_INFO    **StringInfoOut,
   2739   IN  CONST EFI_STRING               String OPTIONAL
   2740   )
   2741 {
   2742   HII_DATABASE_PRIVATE_DATA          *Private;
   2743   EFI_STATUS                         Status;
   2744   EFI_FONT_DISPLAY_INFO              *SystemDefault;
   2745   EFI_FONT_DISPLAY_INFO              InfoOut;
   2746   UINTN                              StringInfoOutLen;
   2747   EFI_FONT_INFO                      *FontInfo;
   2748   HII_GLOBAL_FONT_INFO               *GlobalFont;
   2749   EFI_STRING                         StringIn;
   2750   EFI_FONT_HANDLE                    LocalFontHandle;
   2751 
   2752   if (This == NULL) {
   2753     return EFI_INVALID_PARAMETER;
   2754   }
   2755 
   2756   StringInfoOutLen = 0;
   2757   FontInfo        = NULL;
   2758   SystemDefault   = NULL;
   2759   LocalFontHandle = NULL;
   2760   if (FontHandle != NULL) {
   2761     LocalFontHandle = *FontHandle;
   2762   }
   2763 
   2764   Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
   2765 
   2766   //
   2767   // Already searched to the end of the whole list, return directly.
   2768   //
   2769   if (LocalFontHandle == &Private->FontInfoList) {
   2770     LocalFontHandle = NULL;
   2771     Status = EFI_NOT_FOUND;
   2772     goto Exit;
   2773   }
   2774 
   2775   //
   2776   // Get default system display info, if StringInfoIn points to
   2777   // system display info, return it directly.
   2778   //
   2779   if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
   2780     //
   2781     // System font is the first node. When handle is not NULL, system font can not
   2782     // be found any more.
   2783     //
   2784     if (LocalFontHandle == NULL) {
   2785       if (StringInfoOut != NULL) {
   2786         *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
   2787         if (*StringInfoOut == NULL) {
   2788           Status = EFI_OUT_OF_RESOURCES;
   2789           LocalFontHandle = NULL;
   2790           goto Exit;
   2791         }
   2792       }
   2793 
   2794       LocalFontHandle = Private->FontInfoList.ForwardLink;
   2795       Status = EFI_SUCCESS;
   2796       goto Exit;
   2797     } else {
   2798       LocalFontHandle = NULL;
   2799       Status = EFI_NOT_FOUND;
   2800       goto Exit;
   2801     }
   2802   }
   2803 
   2804   //
   2805   // StringInfoIn must not be NULL if it is not system default font info.
   2806   //
   2807   ASSERT (StringInfoIn != NULL);
   2808   //
   2809   // Check the font information mask to make sure it is valid.
   2810   //
   2811   if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT  | EFI_FONT_INFO_ANY_FONT))  ==
   2812        (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT))   ||
   2813       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE  | EFI_FONT_INFO_ANY_SIZE))  ==
   2814        (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE))   ||
   2815       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
   2816        (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
   2817       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE    | EFI_FONT_INFO_ANY_SIZE))  ==
   2818        (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE))     ||
   2819       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE   | EFI_FONT_INFO_ANY_STYLE)) ==
   2820        (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {
   2821     return EFI_INVALID_PARAMETER;
   2822   }
   2823 
   2824   //
   2825   // Parse the font information mask to find a matching font.
   2826   //
   2827 
   2828   CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
   2829 
   2830   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
   2831     Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
   2832   } else {
   2833     Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *) StringInfoIn)->FontInfo.FontName, &FontInfo);
   2834   }
   2835   if (EFI_ERROR (Status)) {
   2836     goto Exit;
   2837   }
   2838 
   2839   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
   2840     InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
   2841   }
   2842   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
   2843     InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
   2844   }
   2845   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
   2846     InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
   2847   }
   2848   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
   2849     InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
   2850   }
   2851 
   2852   ASSERT (FontInfo != NULL);
   2853   FontInfo->FontSize  = InfoOut.FontInfo.FontSize;
   2854   FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
   2855 
   2856   if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
   2857     //
   2858     // Test to guarantee all characters are available in the found font.
   2859     //
   2860     if (String != NULL) {
   2861       StringIn = String;
   2862       while (*StringIn != 0) {
   2863         Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
   2864         if (EFI_ERROR (Status)) {
   2865           LocalFontHandle = NULL;
   2866           goto Exit;
   2867         }
   2868         StringIn++;
   2869       }
   2870     }
   2871     //
   2872     // Write to output parameter
   2873     //
   2874     if (StringInfoOut != NULL) {
   2875       StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
   2876       *StringInfoOut   = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);
   2877       if (*StringInfoOut == NULL) {
   2878         Status = EFI_OUT_OF_RESOURCES;
   2879         LocalFontHandle = NULL;
   2880         goto Exit;
   2881       }
   2882 
   2883       CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
   2884       CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
   2885     }
   2886 
   2887     LocalFontHandle = GlobalFont->Entry.ForwardLink;
   2888     Status = EFI_SUCCESS;
   2889     goto Exit;
   2890   }
   2891 
   2892   Status = EFI_NOT_FOUND;
   2893 
   2894 Exit:
   2895 
   2896   if (FontHandle != NULL) {
   2897     *FontHandle = LocalFontHandle;
   2898   }
   2899 
   2900   if (SystemDefault != NULL) {
   2901    FreePool (SystemDefault);
   2902   }
   2903   if (FontInfo != NULL) {
   2904    FreePool (FontInfo);
   2905   }
   2906   return Status;
   2907 }
   2908 
   2909 
   2910