]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Font.c
index f60506198125d0dbb53d4692e988aac265c0deeb..399f90feb783bb578921941faeee3441c4de87d3 100644 (file)
@@ -1,56 +1,41 @@
 /** @file\r
+Implementation for EFI_HII_FONT_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-    Font.c\r
-\r
-Abstract:\r
-\r
-    Implementation for EFI_HII_FONT_PROTOCOL.\r
-\r
-Revision History\r
 \r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "HiiDatabase.h"\r
 \r
-static EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL  mHiiEfiColors[16] = {\r
   //\r
   // B     G     R\r
   //\r
-  {0x00, 0x00, 0x00, 0x00},  // BLACK\r
-  {0x98, 0x00, 0x00, 0x00},  // BLUE\r
-  {0x00, 0x98, 0x00, 0x00},  // GREEN\r
-  {0x98, 0x98, 0x00, 0x00},  // CYAN\r
-  {0x00, 0x00, 0x98, 0x00},  // RED\r
-  {0x98, 0x00, 0x98, 0x00},  // MAGENTA\r
-  {0x00, 0x98, 0x98, 0x00},  // BROWN\r
-  {0x98, 0x98, 0x98, 0x00},  // LIGHTGRAY\r
-  {0x30, 0x30, 0x30, 0x00},  // DARKGRAY - BRIGHT BLACK\r
-  {0xff, 0x00, 0x00, 0x00},  // LIGHTBLUE\r
-  {0x00, 0xff, 0x00, 0x00},  // LIGHTGREEN\r
-  {0xff, 0xff, 0x00, 0x00},  // LIGHTCYAN\r
-  {0x00, 0x00, 0xff, 0x00},  // LIGHTRED\r
-  {0xff, 0x00, 0xff, 0x00},  // LIGHTMAGENTA\r
-  {0x00, 0xff, 0xff, 0x00},  // YELLOW\r
-  {0xff, 0xff, 0xff, 0x00},  // WHITE\r
+  { 0x00, 0x00, 0x00, 0x00 },  // BLACK\r
+  { 0x98, 0x00, 0x00, 0x00 },  // BLUE\r
+  { 0x00, 0x98, 0x00, 0x00 },  // GREEN\r
+  { 0x98, 0x98, 0x00, 0x00 },  // CYAN\r
+  { 0x00, 0x00, 0x98, 0x00 },  // RED\r
+  { 0x98, 0x00, 0x98, 0x00 },  // MAGENTA\r
+  { 0x00, 0x98, 0x98, 0x00 },  // BROWN\r
+  { 0x98, 0x98, 0x98, 0x00 },  // LIGHTGRAY\r
+  { 0x30, 0x30, 0x30, 0x00 },  // DARKGRAY - BRIGHT BLACK\r
+  { 0xff, 0x00, 0x00, 0x00 },  // LIGHTBLUE\r
+  { 0x00, 0xff, 0x00, 0x00 },  // LIGHTGREEN\r
+  { 0xff, 0xff, 0x00, 0x00 },  // LIGHTCYAN\r
+  { 0x00, 0x00, 0xff, 0x00 },  // LIGHTRED\r
+  { 0xff, 0x00, 0xff, 0x00 },  // LIGHTMAGENTA\r
+  { 0x00, 0xff, 0xff, 0x00 },  // YELLOW\r
+  { 0xff, 0xff, 0xff, 0x00 },  // WHITE\r
 };\r
 \r
-\r
 /**\r
   Insert a character cell information to the list specified by GlyphInfoList.\r
 \r
+  This is a internal function.\r
+\r
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphInfoList           HII_GLYPH_INFO list head.\r
@@ -61,19 +46,18 @@ static EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 NewCell (\r
-  IN  CHAR16                         CharValue,\r
-  IN  LIST_ENTRY                     *GlyphInfoList,\r
-  IN  EFI_HII_GLYPH_INFO             *Cell\r
+  IN  CHAR16              CharValue,\r
+  IN  LIST_ENTRY          *GlyphInfoList,\r
+  IN  EFI_HII_GLYPH_INFO  *Cell\r
   )\r
 {\r
-  HII_GLYPH_INFO           *GlyphInfo;\r
+  HII_GLYPH_INFO  *GlyphInfo;\r
 \r
   ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
 \r
-  GlyphInfo = (HII_GLYPH_INFO *) AllocateZeroPool (sizeof (HII_GLYPH_INFO));\r
+  GlyphInfo = (HII_GLYPH_INFO *)AllocateZeroPool (sizeof (HII_GLYPH_INFO));\r
   if (GlyphInfo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -84,16 +68,21 @@ NewCell (
   //\r
   GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;\r
   GlyphInfo->CharId    = CharValue;\r
+  if (Cell->AdvanceX == 0) {\r
+    Cell->AdvanceX = Cell->Width;\r
+  }\r
+\r
   CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));\r
   InsertTailList (GlyphInfoList, &GlyphInfo->Entry);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Get a character cell information from the list specified by GlyphInfoList.\r
 \r
+  This is a internal function.\r
+\r
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphInfoList           HII_GLYPH_INFO list head.\r
@@ -105,16 +94,15 @@ NewCell (
                                   not exist.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetCell (\r
-  IN  CHAR16                         CharValue,\r
-  IN  LIST_ENTRY                     *GlyphInfoList,\r
-  OUT EFI_HII_GLYPH_INFO             *Cell\r
+  IN  CHAR16              CharValue,\r
+  IN  LIST_ENTRY          *GlyphInfoList,\r
+  OUT EFI_HII_GLYPH_INFO  *Cell\r
   )\r
 {\r
-  HII_GLYPH_INFO           *GlyphInfo;\r
-  LIST_ENTRY               *Link;\r
+  HII_GLYPH_INFO  *GlyphInfo;\r
+  LIST_ENTRY      *Link;\r
 \r
   ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
 \r
@@ -139,10 +127,11 @@ GetCell (
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 /**\r
   Convert the glyph for a single character into a bitmap.\r
 \r
+  This is a internal function.\r
+\r
   @param  Private                 HII database driver private data.\r
   @param  Char                    Character to retrieve.\r
   @param  StringInfo              Points to the string font and color information\r
@@ -158,33 +147,33 @@ GetCell (
   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetGlyphBuffer (\r
-  IN  HII_DATABASE_PRIVATE_DATA      *Private,\r
-  IN  CHAR16                         Char,\r
-  IN  EFI_FONT_INFO                  *StringInfo,\r
-  OUT UINT8                          **GlyphBuffer,\r
-  OUT EFI_HII_GLYPH_INFO             *Cell,\r
-  OUT UINT8                          *Attributes OPTIONAL\r
+  IN  HII_DATABASE_PRIVATE_DATA  *Private,\r
+  IN  CHAR16                     Char,\r
+  IN  EFI_FONT_INFO              *StringInfo,\r
+  OUT UINT8                      **GlyphBuffer,\r
+  OUT EFI_HII_GLYPH_INFO         *Cell,\r
+  OUT UINT8                      *Attributes OPTIONAL\r
   )\r
 {\r
-  HII_DATABASE_RECORD                *Node;\r
-  LIST_ENTRY                         *Link;\r
-  HII_SIMPLE_FONT_PACKAGE_INSTANCE   *SimpleFont;\r
-  LIST_ENTRY                         *Link1;\r
-  UINT16                             Index;\r
-  EFI_NARROW_GLYPH                   Narrow;\r
-  EFI_WIDE_GLYPH                     Wide;\r
-  HII_GLOBAL_FONT_INFO               *GlobalFont;\r
-  UINTN                              HeaderSize;\r
-  EFI_NARROW_GLYPH                   *NarrowPtr;\r
-  EFI_WIDE_GLYPH                     *WidePtr;\r
-\r
-  if (GlyphBuffer == NULL || Cell == NULL) {\r
+  HII_DATABASE_RECORD               *Node;\r
+  LIST_ENTRY                        *Link;\r
+  HII_SIMPLE_FONT_PACKAGE_INSTANCE  *SimpleFont;\r
+  LIST_ENTRY                        *Link1;\r
+  UINT16                            Index;\r
+  EFI_NARROW_GLYPH                  Narrow;\r
+  EFI_WIDE_GLYPH                    Wide;\r
+  HII_GLOBAL_FONT_INFO              *GlobalFont;\r
+  UINTN                             HeaderSize;\r
+  EFI_NARROW_GLYPH                  *NarrowPtr;\r
+  EFI_WIDE_GLYPH                    *WidePtr;\r
+\r
+  if ((GlyphBuffer == NULL) || (Cell == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
+\r
+  if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -197,12 +186,14 @@ GetGlyphBuffer (
   // default system font is the fixed font (narrow or wide glyph).\r
   //\r
   if (StringInfo != NULL) {\r
-    if(!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {\r
+    if (!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     if (Attributes != NULL) {\r
       *Attributes = PROPORTIONAL_GLYPH;\r
     }\r
+\r
     return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);\r
   } else {\r
     HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);\r
@@ -212,50 +203,54 @@ GetGlyphBuffer (
       for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;\r
            Link1 != &Node->PackageList->SimpleFontPkgHdr;\r
            Link1 = Link1->ForwardLink\r
-          ) {\r
+           )\r
+      {\r
         SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);\r
         //\r
         // Search the narrow glyph array\r
         //\r
-        NarrowPtr = (EFI_NARROW_GLYPH *) ((UINT8 *) (SimpleFont->SimpleFontPkgHdr) + HeaderSize);\r
+        NarrowPtr = (EFI_NARROW_GLYPH *)((UINT8 *)(SimpleFont->SimpleFontPkgHdr) + HeaderSize);\r
         for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {\r
-          CopyMem (&Narrow, NarrowPtr + Index,sizeof (EFI_NARROW_GLYPH));\r
+          CopyMem (&Narrow, NarrowPtr + Index, sizeof (EFI_NARROW_GLYPH));\r
           if (Narrow.UnicodeWeight == Char) {\r
-            *GlyphBuffer = (UINT8 *) AllocateZeroPool (EFI_GLYPH_HEIGHT);\r
+            *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT);\r
             if (*GlyphBuffer == NULL) {\r
               return EFI_OUT_OF_RESOURCES;\r
             }\r
+\r
             Cell->Width    = EFI_GLYPH_WIDTH;\r
             Cell->Height   = EFI_GLYPH_HEIGHT;\r
-            Cell->OffsetY  = NARROW_BASELINE;\r
             Cell->AdvanceX = Cell->Width;\r
             CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);\r
             if (Attributes != NULL) {\r
-              *Attributes = (UINT8) (Narrow.Attributes | NARROW_GLYPH);\r
+              *Attributes = (UINT8)(Narrow.Attributes | NARROW_GLYPH);\r
             }\r
+\r
             return EFI_SUCCESS;\r
           }\r
         }\r
+\r
         //\r
         // Search the wide glyph array\r
         //\r
-        WidePtr = (EFI_WIDE_GLYPH *) (NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);\r
+        WidePtr = (EFI_WIDE_GLYPH *)(NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);\r
         for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {\r
           CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));\r
           if (Wide.UnicodeWeight == Char) {\r
-            *GlyphBuffer    = (UINT8 *) AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);\r
+            *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);\r
             if (*GlyphBuffer == NULL) {\r
               return EFI_OUT_OF_RESOURCES;\r
             }\r
+\r
             Cell->Width    = EFI_GLYPH_WIDTH * 2;\r
             Cell->Height   = EFI_GLYPH_HEIGHT;\r
-            Cell->OffsetY  = WIDE_BASELINE;\r
             Cell->AdvanceX = Cell->Width;\r
             CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);\r
             CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);\r
             if (Attributes != NULL) {\r
-              *Attributes = (UINT8) (Wide.Attributes | EFI_GLYPH_WIDE);\r
+              *Attributes = (UINT8)(Wide.Attributes | EFI_GLYPH_WIDE);\r
             }\r
+\r
             return EFI_SUCCESS;\r
           }\r
         }\r
@@ -266,93 +261,144 @@ GetGlyphBuffer (
   return EFI_NOT_FOUND;\r
 }\r
 \r
-STATIC\r
+/**\r
+  Convert bitmap data of the glyph to blt structure.\r
+\r
+  This is a internal function.\r
+\r
+  @param GlyphBuffer     Buffer points to bitmap data of glyph.\r
+  @param  Foreground     The color of the "on" pixels in the glyph in the\r
+                         bitmap.\r
+  @param  Background     The color of the "off" pixels in the glyph in the\r
+                         bitmap.\r
+  @param  ImageWidth     Width of the whole image in pixels.\r
+  @param  RowWidth       The width of the text on the line, in pixels.\r
+  @param  RowHeight      The height of the line, in pixels.\r
+  @param  Transparent    If TRUE, the Background color is ignored and all\r
+                         "off" pixels in the character's drawn will use the\r
+                         pixel value from BltBuffer.\r
+  @param  Origin         On input, points to the origin of the to be\r
+                         displayed character, on output, points to the\r
+                         next glyph's origin.\r
+\r
+**/\r
 VOID\r
 NarrowGlyphToBlt (\r
-  IN     UINT8                         *GlyphBuffer,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
-  IN     UINTN                         ImageWidth,\r
-  IN     UINTN                         ImageHeight,\r
-  IN     BOOLEAN                       Transparent,\r
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
+  IN     UINT8                          *GlyphBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background,\r
+  IN     UINT16                         ImageWidth,\r
+  IN     UINTN                          RowWidth,\r
+  IN     UINTN                          RowHeight,\r
+  IN     BOOLEAN                        Transparent,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **Origin\r
   )\r
 {\r
-  UINT8                                X;\r
-  UINT8                                Y;\r
-  UINT8                                Height;\r
-  UINT8                                Width;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;\r
+  UINT8                          Xpos;\r
+  UINT8                          Ypos;\r
+  UINT8                          Height;\r
+  UINT8                          Width;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Buffer;\r
 \r
   ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
 \r
   Height = EFI_GLYPH_HEIGHT;\r
   Width  = EFI_GLYPH_WIDTH;\r
 \r
-  ASSERT (Width <= ImageWidth && Height <= ImageHeight);\r
+  //\r
+  // Move position to the left-top corner of char.\r
+  //\r
+  Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;\r
 \r
-  Buffer = *Origin;\r
+  //\r
+  // Char may be partially displayed when CLIP_X or CLIP_Y is not set.\r
+  //\r
+  if (RowHeight < Height) {\r
+    Height = (UINT8)RowHeight;\r
+  }\r
+\r
+  if (RowWidth < Width) {\r
+    Width = (UINT8)RowWidth;\r
+  }\r
 \r
-  for (Y = 0; Y < Height; Y++) {\r
-    for (X = 0; X < Width; X++) {\r
-      if ((GlyphBuffer[Y] & (1 << X)) != 0) {\r
-        Buffer[Y * ImageWidth + (Width - X - 1)] = Foreground;\r
+  for (Ypos = 0; Ypos < Height; Ypos++) {\r
+    for (Xpos = 0; Xpos < Width; Xpos++) {\r
+      if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {\r
+        Buffer[Ypos * ImageWidth + Xpos] = Foreground;\r
       } else {\r
         if (!Transparent) {\r
-          Buffer[Y * ImageWidth + (Width - X - 1)] = Background;\r
+          Buffer[Ypos * ImageWidth + Xpos] = Background;\r
         }\r
       }\r
     }\r
   }\r
 \r
-  *Origin = Buffer + Width;\r
+  *Origin = *Origin + EFI_GLYPH_WIDTH;\r
 }\r
 \r
-\r
 /**\r
   Convert bitmap data of the glyph to blt structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  GlyphBuffer             Buffer points to bitmap data of glyph.\r
   @param  Foreground              The color of the "on" pixels in the glyph in the\r
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  Width                   Width of the character or character cell, in\r
-                                  pixels.\r
-  @param  Height                  Height of the character or character cell, in\r
-                                  pixels.\r
+  @param  ImageWidth              Width of the whole image in pixels.\r
+  @param  BaseLine                BaseLine in the line.\r
+  @param  RowWidth                The width of the text on the line, in pixels.\r
+  @param  RowHeight               The height of the line, in pixels.\r
   @param  Transparent             If TRUE, the Background color is ignored and all\r
-                                  "off" pixels in the character's drawn wil use the\r
+                                  "off" pixels in the character's drawn will use the\r
                                   pixel value from BltBuffer.\r
-  @param  BltBuffer               Points to the blt buffer.\r
+  @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.\r
+  @param  Attributes              The attribute of incoming glyph in GlyphBuffer.\r
+  @param  Origin                  On input, points to the origin of the to be\r
+                                  displayed character, on output, points to the\r
+                                  next glyph's origin.\r
 \r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToBlt (\r
-  IN     UINT8                         *GlyphBuffer,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
-  IN     UINTN                         ImageWidth,\r
-  IN     UINTN                         ImageHeight,\r
-  IN     BOOLEAN                       Transparent,\r
-  IN     CONST EFI_HII_GLYPH_INFO      *Cell,\r
-  IN     UINT8                         Attributes,\r
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
+  IN     UINT8                          *GlyphBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background,\r
+  IN     UINT16                         ImageWidth,\r
+  IN     UINT16                         BaseLine,\r
+  IN     UINTN                          RowWidth,\r
+  IN     UINTN                          RowHeight,\r
+  IN     BOOLEAN                        Transparent,\r
+  IN     CONST EFI_HII_GLYPH_INFO       *Cell,\r
+  IN     UINT8                          Attributes,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **Origin\r
   )\r
 {\r
-  UINT8                                X;\r
-  UINT8                                Y;\r
-  UINT8                                Data;\r
-  UINT8                                Index;\r
-  UINTN                                OffsetY;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *BltBuffer;\r
+  UINT16                         Xpos;\r
+  UINT16                         Ypos;\r
+  UINT8                          Data;\r
+  UINT16                         Index;\r
+  UINT16                         YposOffset;\r
+  UINTN                          OffsetY;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer;\r
 \r
-  ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
-  ASSERT (Cell->Width <= ImageWidth && Cell->Height <= ImageHeight);\r
+  ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
+\r
+  //\r
+  // Only adjust origin position if char has no bitmap.\r
+  //\r
+  if (GlyphBuffer == NULL) {\r
+    *Origin = *Origin + Cell->AdvanceX;\r
+    return;\r
+  }\r
 \r
-  BltBuffer = *Origin;\r
+  //\r
+  // Move position to the left-top corner of char.\r
+  //\r
+  BltBuffer  = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;\r
+  YposOffset = (UINT16)(BaseLine - (Cell->OffsetY + Cell->Height));\r
 \r
   //\r
   // Since non-spacing key will be printed OR'd with the previous glyph, don't\r
@@ -366,20 +412,20 @@ GlyphToBlt (
   // The glyph's upper left hand corner pixel is the most significant bit of the\r
   // first bitmap byte.\r
   //\r
-  for (Y = 0; Y < Cell->Height; Y++) {\r
-    OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Y);\r
+  for (Ypos = 0; Ypos < Cell->Height && (((UINT32)Ypos + YposOffset) < RowHeight); Ypos++) {\r
+    OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);\r
 \r
     //\r
     // All bits in these bytes are meaningful.\r
     //\r
-    for (X = 0; X < Cell->Width / 8; X++) {\r
-      Data  = *(GlyphBuffer + OffsetY + X);\r
-      for (Index = 0; Index < 8; Index++) {\r
-        if ((Data & (1 << Index)) != 0) {\r
-          BltBuffer[Y * ImageWidth + X * 8 + (8 - Index - 1)] = Foreground;\r
+    for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {\r
+      Data = *(GlyphBuffer + OffsetY + Xpos);\r
+      for (Index = 0; Index < 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
+        if ((Data & (1 << (8 - Index - 1))) != 0) {\r
+          BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
         } else {\r
           if (!Transparent) {\r
-            BltBuffer[Y * ImageWidth + X * 8 + (8 - Index - 1)] = Background;\r
+            BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
           }\r
         }\r
       }\r
@@ -389,38 +435,38 @@ GlyphToBlt (
       //\r
       // There are some padding bits in this byte. Ignore them.\r
       //\r
-      Data  = *(GlyphBuffer + OffsetY + X);\r
-      for (Index = 0; Index < Cell->Width % 8; Index++) {\r
+      Data = *(GlyphBuffer + OffsetY + Xpos);\r
+      for (Index = 0; Index < Cell->Width % 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
         if ((Data & (1 << (8 - Index - 1))) != 0) {\r
-          BltBuffer[Y * ImageWidth + X * 8 + Index] = Foreground;\r
+          BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
         } else {\r
           if (!Transparent) {\r
-            BltBuffer[Y * ImageWidth + X * 8 + Index] = Background;\r
+            BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
           }\r
         }\r
       }\r
     } // end of if (Width % 8...)\r
+  } // end of for (Ypos=0...)\r
 \r
-  } // end of for (Y=0...)\r
-\r
-  *Origin = BltBuffer + Cell->Width;\r
+  *Origin = *Origin + Cell->AdvanceX;\r
 }\r
 \r
-\r
 /**\r
   Convert bitmap data of the glyph to blt structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  GlyphBuffer             Buffer points to bitmap data of glyph.\r
   @param  Foreground              The color of the "on" pixels in the glyph in the\r
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  Width                   Width of the character or character cell, in\r
-                                  pixels.\r
-  @param  Height                  Height of the character or character cell, in\r
-                                  pixels.\r
+  @param  ImageWidth              Width of the whole image in pixels.\r
+  @param  BaseLine                BaseLine in the line.\r
+  @param  RowWidth                The width of the text on the line, in pixels.\r
+  @param  RowHeight               The height of the line, in pixels.\r
   @param  Transparent             If TRUE, the Background color is ignored and all\r
-                                  "off" pixels in the character's drawn wil use the\r
+                                  "off" pixels in the character's drawn will use the\r
                                   pixel value from BltBuffer.\r
   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.\r
   @param  Attributes              The attribute of incoming glyph in GlyphBuffer.\r
@@ -431,24 +477,24 @@ GlyphToBlt (
   @return Points to the address of next origin node in BltBuffer.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToImage (\r
-  IN     UINT8                         *GlyphBuffer,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
-  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
-  IN     UINTN                         ImageWidth,\r
-  IN     UINTN                         ImageHeight,\r
-  IN     BOOLEAN                       Transparent,\r
-  IN     CONST EFI_HII_GLYPH_INFO      *Cell,\r
-  IN     UINT8                         Attributes,\r
-  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
+  IN     UINT8                          *GlyphBuffer,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground,\r
+  IN     EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background,\r
+  IN     UINT16                         ImageWidth,\r
+  IN     UINT16                         BaseLine,\r
+  IN     UINTN                          RowWidth,\r
+  IN     UINTN                          RowHeight,\r
+  IN     BOOLEAN                        Transparent,\r
+  IN     CONST EFI_HII_GLYPH_INFO       *Cell,\r
+  IN     UINT8                          Attributes,\r
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **Origin\r
   )\r
 {\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Buffer;\r
 \r
-  ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
-  ASSERT (Cell->Width <= ImageWidth && Cell->Height <= ImageHeight);\r
+  ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
 \r
   Buffer = *Origin;\r
 \r
@@ -457,19 +503,20 @@ GlyphToImage (
     // This character is a non-spacing key, print it OR'd with the previous glyph.\r
     // without advancing cursor.\r
     //\r
-    Buffer -= Cell->Width;\r
+    Buffer -= Cell->AdvanceX;\r
     GlyphToBlt (\r
       GlyphBuffer,\r
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      BaseLine,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Cell,\r
       Attributes,\r
       &Buffer\r
       );\r
-\r
   } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {\r
     //\r
     // This character is wide glyph, i.e. 16 pixels * 19 pixels.\r
@@ -480,7 +527,8 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
@@ -490,11 +538,11 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
-\r
   } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {\r
     //\r
     // This character is narrow glyph, i.e. 8 pixels * 19 pixels.\r
@@ -504,11 +552,11 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
-\r
   } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {\r
     //\r
     // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.\r
@@ -518,7 +566,9 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      BaseLine,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Cell,\r
       Attributes,\r
@@ -527,17 +577,18 @@ GlyphToImage (
   }\r
 }\r
 \r
-\r
 /**\r
   Write the output parameters of FindGlyphBlock().\r
 \r
+  This is a internal function.\r
+\r
   @param  BufferIn                Buffer which stores the bitmap data of the found\r
                                   block.\r
   @param  BufferLen               Length of BufferIn.\r
   @param  InputCell               Buffer which stores cell information of the\r
                                   encoded bitmap.\r
   @param  GlyphBuffer             Output the corresponding bitmap data of the found\r
-                                  block. It is the caller's responsiblity to free\r
+                                  block. It is the caller's responsibility to free\r
                                   this buffer.\r
   @param  Cell                    Output cell information of the encoded bitmap.\r
   @param  GlyphBufferLen          If not NULL, output the length of GlyphBuffer.\r
@@ -548,18 +599,17 @@ GlyphToImage (
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 WriteOutputParam (\r
-  IN  UINT8                          *BufferIn,\r
-  IN  UINTN                          BufferLen,\r
-  IN  EFI_HII_GLYPH_INFO             *InputCell,\r
-  OUT UINT8                          **GlyphBuffer, OPTIONAL\r
-  OUT EFI_HII_GLYPH_INFO             *Cell, OPTIONAL\r
-  OUT UINTN                          *GlyphBufferLen OPTIONAL\r
+  IN  UINT8               *BufferIn,\r
+  IN  UINTN               BufferLen,\r
+  IN  EFI_HII_GLYPH_INFO  *InputCell,\r
+  OUT UINT8               **GlyphBuffer  OPTIONAL,\r
+  OUT EFI_HII_GLYPH_INFO  *Cell  OPTIONAL,\r
+  OUT UINTN               *GlyphBufferLen OPTIONAL\r
   )\r
 {\r
-  if (BufferIn == NULL || BufferLen < 1 || InputCell == NULL) {\r
+  if ((BufferIn == NULL) || (InputCell == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -567,11 +617,12 @@ WriteOutputParam (
     CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));\r
   }\r
 \r
-  if (GlyphBuffer != NULL) {\r
-    *GlyphBuffer = (UINT8 *) AllocateZeroPool (BufferLen);\r
+  if ((GlyphBuffer != NULL) && (BufferLen > 0)) {\r
+    *GlyphBuffer = (UINT8 *)AllocateZeroPool (BufferLen);\r
     if (*GlyphBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
     CopyMem (*GlyphBuffer, BufferIn, BufferLen);\r
   }\r
 \r
@@ -582,7 +633,6 @@ WriteOutputParam (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Parse all glyph blocks to find a glyph block specified by CharValue.\r
   If CharValue = (CHAR16) (-1), collect all default character cell information\r
@@ -592,7 +642,7 @@ WriteOutputParam (
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphBuffer             Output the corresponding bitmap data of the found\r
-                                  block. It is the caller's responsiblity to free\r
+                                  block. It is the caller's responsibility to free\r
                                   this buffer.\r
   @param  Cell                    Output cell information of the encoded bitmap.\r
   @param  GlyphBufferLen          If not NULL, output the length of GlyphBuffer.\r
@@ -606,28 +656,32 @@ WriteOutputParam (
 **/\r
 EFI_STATUS\r
 FindGlyphBlock (\r
-  IN  HII_FONT_PACKAGE_INSTANCE      *FontPackage,\r
-  IN  CHAR16                         CharValue,\r
-  OUT UINT8                          **GlyphBuffer, OPTIONAL\r
-  OUT EFI_HII_GLYPH_INFO             *Cell, OPTIONAL\r
-  OUT UINTN                          *GlyphBufferLen OPTIONAL\r
+  IN  HII_FONT_PACKAGE_INSTANCE  *FontPackage,\r
+  IN  CHAR16                     CharValue,\r
+  OUT UINT8                      **GlyphBuffer  OPTIONAL,\r
+  OUT EFI_HII_GLYPH_INFO         *Cell  OPTIONAL,\r
+  OUT UINTN                      *GlyphBufferLen OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
-  UINT8                               *BlockPtr;\r
-  UINT16                              CharCurrent;\r
-  UINT16                              Length16;\r
-  UINT32                              Length32;\r
-  EFI_HII_GIBT_GLYPHS_BLOCK           Glyphs;\r
-  UINTN                               BufferLen;\r
-  UINT16                              Index;\r
-  EFI_HII_GLYPH_INFO                  DefaultCell;\r
-  EFI_HII_GLYPH_INFO                  LocalCell;\r
+  EFI_STATUS                 Status;\r
+  UINT8                      *BlockPtr;\r
+  UINT16                     CharCurrent;\r
+  UINT16                     Length16;\r
+  UINT32                     Length32;\r
+  EFI_HII_GIBT_GLYPHS_BLOCK  Glyphs;\r
+  UINTN                      BufferLen;\r
+  UINT16                     Index;\r
+  EFI_HII_GLYPH_INFO         DefaultCell;\r
+  EFI_HII_GLYPH_INFO         LocalCell;\r
+  INT16                      MinOffsetY;\r
+  UINT16                     BaseLine;\r
 \r
   ASSERT (FontPackage != NULL);\r
   ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);\r
+  BaseLine   = 0;\r
+  MinOffsetY = 0;\r
 \r
-  if (CharValue == (CHAR16) (-1)) {\r
+  if (CharValue == (CHAR16)(-1)) {\r
     //\r
     // Collect the cell information specified in font package fixed header.\r
     // Use CharValue =0 to represent this particular cell.\r
@@ -635,11 +689,17 @@ FindGlyphBlock (
     Status = NewCell (\r
                0,\r
                &FontPackage->GlyphInfoList,\r
-               (EFI_HII_GLYPH_INFO *) ((UINT8 *) FontPackage->FontPkgHdr + 3 * sizeof (UINT32))\r
+               (EFI_HII_GLYPH_INFO *)((UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32))\r
                );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
+    CopyMem (\r
+      &LocalCell,\r
+      (UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32),\r
+      sizeof (EFI_HII_GLYPH_INFO)\r
+      );\r
   }\r
 \r
   BlockPtr    = FontPackage->GlyphBlock;\r
@@ -648,133 +708,159 @@ FindGlyphBlock (
 \r
   while (*BlockPtr != EFI_HII_GIBT_END) {\r
     switch (*BlockPtr) {\r
-    case EFI_HII_GIBT_DEFAULTS:\r
-      //\r
-      // Collect all default character cell information specified by\r
-      // EFI_HII_GIBT_DEFAULTS.\r
-      //\r
-      if (CharValue == (CHAR16) (-1)) {\r
-        Status = NewCell (\r
-                   CharCurrent,\r
-                   &FontPackage->GlyphInfoList,\r
-                   (EFI_HII_GLYPH_INFO *) (BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))\r
-                   );\r
-        if (EFI_ERROR (Status)) {\r
-          return Status;\r
+      case EFI_HII_GIBT_DEFAULTS:\r
+        //\r
+        // Collect all default character cell information specified by\r
+        // EFI_HII_GIBT_DEFAULTS.\r
+        //\r
+        if (CharValue == (CHAR16)(-1)) {\r
+          Status = NewCell (\r
+                     CharCurrent,\r
+                     &FontPackage->GlyphInfoList,\r
+                     (EFI_HII_GLYPH_INFO *)(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))\r
+                     );\r
+          if (EFI_ERROR (Status)) {\r
+            return Status;\r
+          }\r
+\r
+          CopyMem (\r
+            &LocalCell,\r
+            BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
+            sizeof (EFI_HII_GLYPH_INFO)\r
+            );\r
+          if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {\r
+            BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);\r
+          }\r
+\r
+          if (MinOffsetY > LocalCell.OffsetY) {\r
+            MinOffsetY = LocalCell.OffsetY;\r
+          }\r
         }\r
-      }\r
-      BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);\r
-      break;\r
 \r
-    case EFI_HII_GIBT_DUPLICATE:\r
-      if (CharCurrent == CharValue) {\r
-        CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));\r
-        CharCurrent = 1;\r
-        BlockPtr    = FontPackage->GlyphBlock;\r
-        continue;\r
-      }\r
-      CharCurrent++;\r
-      BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);\r
-      break;\r
+        BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);\r
+        break;\r
 \r
-    case EFI_HII_GIBT_EXT1:\r
-      BlockPtr += *(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));\r
-      break;\r
-    case EFI_HII_GIBT_EXT2:\r
-      CopyMem (\r
-        &Length16,\r
-        BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8),\r
-        sizeof (UINT16)\r
-        );\r
-      BlockPtr += Length16;\r
-      break;\r
-    case EFI_HII_GIBT_EXT4:\r
-      CopyMem (\r
-        &Length32,\r
-        BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8),\r
-        sizeof (UINT32)\r
-        );\r
-      BlockPtr += Length32;\r
-      break;\r
+      case EFI_HII_GIBT_DUPLICATE:\r
+        if (CharCurrent == CharValue) {\r
+          CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));\r
+          CharCurrent = 1;\r
+          BlockPtr    = FontPackage->GlyphBlock;\r
+          continue;\r
+        }\r
 \r
-    case EFI_HII_GIBT_GLYPH:\r
-      CopyMem (\r
-        &LocalCell,\r
-        BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
-        sizeof (EFI_HII_GLYPH_INFO)\r
-        );\r
-      BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);\r
-      if (CharCurrent == CharValue) {\r
-        return WriteOutputParam (\r
-                 BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8),\r
-                 BufferLen,\r
-                 &LocalCell,\r
-                 GlyphBuffer,\r
-                 Cell,\r
-                 GlyphBufferLen\r
-                 );\r
-      }\r
-      CharCurrent++;\r
-      BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;\r
-      break;\r
+        CharCurrent++;\r
+        BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);\r
+        break;\r
+\r
+      case EFI_HII_GIBT_EXT1:\r
+        BlockPtr += *(UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));\r
+        break;\r
+      case EFI_HII_GIBT_EXT2:\r
+        CopyMem (\r
+          &Length16,\r
+          (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
+          sizeof (UINT16)\r
+          );\r
+        BlockPtr += Length16;\r
+        break;\r
+      case EFI_HII_GIBT_EXT4:\r
+        CopyMem (\r
+          &Length32,\r
+          (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
+          sizeof (UINT32)\r
+          );\r
+        BlockPtr += Length32;\r
+        break;\r
+\r
+      case EFI_HII_GIBT_GLYPH:\r
+        CopyMem (\r
+          &LocalCell,\r
+          BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
+          sizeof (EFI_HII_GLYPH_INFO)\r
+          );\r
+        if (CharValue == (CHAR16)(-1)) {\r
+          if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {\r
+            BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);\r
+          }\r
 \r
-    case EFI_HII_GIBT_GLYPHS:\r
-      BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);\r
-      CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));\r
-      BlockPtr += sizeof (EFI_HII_GLYPH_INFO);\r
-      CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));\r
-      BlockPtr += sizeof (UINT16);\r
+          if (MinOffsetY > LocalCell.OffsetY) {\r
+            MinOffsetY = LocalCell.OffsetY;\r
+          }\r
+        }\r
 \r
-      BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);\r
-      for (Index = 0; Index < Glyphs.Count; Index++) {\r
-        if (CharCurrent + Index == CharValue) {\r
+        BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);\r
+        if (CharCurrent == CharValue) {\r
           return WriteOutputParam (\r
-                   BlockPtr,\r
+                   (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),\r
                    BufferLen,\r
-                   &Glyphs.Cell,\r
+                   &LocalCell,\r
                    GlyphBuffer,\r
                    Cell,\r
                    GlyphBufferLen\r
                    );\r
         }\r
-        BlockPtr += BufferLen;\r
-      }\r
-      CharCurrent = (UINT16) (CharCurrent + Glyphs.Count);\r
-      break;\r
 \r
-    case EFI_HII_GIBT_GLYPH_DEFAULT:\r
-      Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
-\r
-      if (CharCurrent == CharValue) {\r
-        return WriteOutputParam (\r
-                 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
-                 BufferLen,\r
-                 &DefaultCell,\r
-                 GlyphBuffer,\r
-                 Cell,\r
-                 GlyphBufferLen\r
-                 );\r
-      }\r
-      CharCurrent++;\r
-      BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;\r
-      break;\r
+        CharCurrent++;\r
+        BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;\r
+        break;\r
 \r
-    case EFI_HII_GIBT_GLYPHS_DEFAULT:\r
-      CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
-      Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
-      BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);\r
-      for (Index = 0; Index < Length16; Index++) {\r
-        if (CharCurrent + Index == CharValue) {\r
+      case EFI_HII_GIBT_GLYPHS:\r
+        BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);\r
+        CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));\r
+        BlockPtr += sizeof (EFI_HII_GLYPH_INFO);\r
+        CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));\r
+        BlockPtr += sizeof (UINT16);\r
+\r
+        if (CharValue == (CHAR16)(-1)) {\r
+          if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {\r
+            BaseLine = (UINT16)(Glyphs.Cell.Height + Glyphs.Cell.OffsetY);\r
+          }\r
+\r
+          if (MinOffsetY > Glyphs.Cell.OffsetY) {\r
+            MinOffsetY = Glyphs.Cell.OffsetY;\r
+          }\r
+        }\r
+\r
+        BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);\r
+        for (Index = 0; Index < Glyphs.Count; Index++) {\r
+          if (CharCurrent + Index == CharValue) {\r
+            return WriteOutputParam (\r
+                     BlockPtr,\r
+                     BufferLen,\r
+                     &Glyphs.Cell,\r
+                     GlyphBuffer,\r
+                     Cell,\r
+                     GlyphBufferLen\r
+                     );\r
+          }\r
+\r
+          BlockPtr += BufferLen;\r
+        }\r
+\r
+        CharCurrent = (UINT16)(CharCurrent + Glyphs.Count);\r
+        break;\r
+\r
+      case EFI_HII_GIBT_GLYPH_DEFAULT:\r
+        Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        if (CharValue == (CHAR16)(-1)) {\r
+          if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
+            BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);\r
+          }\r
+\r
+          if (MinOffsetY > DefaultCell.OffsetY) {\r
+            MinOffsetY = DefaultCell.OffsetY;\r
+          }\r
+        }\r
+\r
+        BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
+\r
+        if (CharCurrent == CharValue) {\r
           return WriteOutputParam (\r
-                   BlockPtr,\r
+                   BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
                    BufferLen,\r
                    &DefaultCell,\r
                    GlyphBuffer,\r
@@ -782,23 +868,60 @@ FindGlyphBlock (
                    GlyphBufferLen\r
                    );\r
         }\r
-        BlockPtr += BufferLen;\r
-      }\r
-      CharCurrent = (UINT16) (CharCurrent + Length16);\r
-      break;\r
 \r
-    case EFI_HII_GIBT_SKIP1:\r
-      CharCurrent = (UINT16) (CharCurrent + (UINT16) (*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));\r
-      BlockPtr    += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);\r
-      break;\r
-    case EFI_HII_GIBT_SKIP2:\r
-      CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
-      CharCurrent = (UINT16) (CharCurrent + Length16);\r
-      BlockPtr    += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);\r
-      break;\r
-    default:\r
-      ASSERT (FALSE);\r
-      break;\r
+        CharCurrent++;\r
+        BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;\r
+        break;\r
+\r
+      case EFI_HII_GIBT_GLYPHS_DEFAULT:\r
+        CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
+        Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+\r
+        if (CharValue == (CHAR16)(-1)) {\r
+          if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
+            BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);\r
+          }\r
+\r
+          if (MinOffsetY > DefaultCell.OffsetY) {\r
+            MinOffsetY = DefaultCell.OffsetY;\r
+          }\r
+        }\r
+\r
+        BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
+        BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);\r
+        for (Index = 0; Index < Length16; Index++) {\r
+          if (CharCurrent + Index == CharValue) {\r
+            return WriteOutputParam (\r
+                     BlockPtr,\r
+                     BufferLen,\r
+                     &DefaultCell,\r
+                     GlyphBuffer,\r
+                     Cell,\r
+                     GlyphBufferLen\r
+                     );\r
+          }\r
+\r
+          BlockPtr += BufferLen;\r
+        }\r
+\r
+        CharCurrent = (UINT16)(CharCurrent + Length16);\r
+        break;\r
+\r
+      case EFI_HII_GIBT_SKIP1:\r
+        CharCurrent = (UINT16)(CharCurrent + (UINT16)(*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));\r
+        BlockPtr   += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);\r
+        break;\r
+      case EFI_HII_GIBT_SKIP2:\r
+        CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
+        CharCurrent = (UINT16)(CharCurrent + Length16);\r
+        BlockPtr   += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);\r
+        break;\r
+      default:\r
+        ASSERT (FALSE);\r
+        break;\r
     }\r
 \r
     if (CharValue < CharCurrent) {\r
@@ -806,17 +929,20 @@ FindGlyphBlock (
     }\r
   }\r
 \r
-  if (CharValue == (CHAR16) (-1)) {\r
+  if (CharValue == (CHAR16)(-1)) {\r
+    FontPackage->BaseLine = BaseLine;\r
+    FontPackage->Height   = (UINT16)(BaseLine - MinOffsetY);\r
     return EFI_SUCCESS;\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 /**\r
   Copy a Font Name to a new created EFI_FONT_INFO structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  FontName                NULL-terminated string.\r
   @param  FontInfo                a new EFI_FONT_INFO which stores the FontName.\r
                                   It's caller's responsibility to free this buffer.\r
@@ -826,28 +952,28 @@ FindGlyphBlock (
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 SaveFontName (\r
-  IN  EFI_STRING                       FontName,\r
-  OUT EFI_FONT_INFO                    **FontInfo\r
+  IN  EFI_STRING     FontName,\r
+  OUT EFI_FONT_INFO  **FontInfo\r
   )\r
 {\r
-  UINTN         FontInfoLen;\r
+  UINTN  FontInfoLen;\r
+  UINTN  NameSize;\r
 \r
   ASSERT (FontName != NULL && FontInfo != NULL);\r
 \r
-  FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StrSize (FontName);\r
-  *FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoLen);\r
+  NameSize    = StrSize (FontName);\r
+  FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;\r
+  *FontInfo   = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoLen);\r
   if (*FontInfo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  StrCpy ((*FontInfo)->FontName, FontName);\r
+  StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Retrieve system default font and color.\r
 \r
@@ -865,17 +991,19 @@ SaveFontName (
 **/\r
 EFI_STATUS\r
 GetSystemFont (\r
-  IN  HII_DATABASE_PRIVATE_DATA      *Private,\r
-  OUT EFI_FONT_DISPLAY_INFO          **FontInfo,\r
-  OUT UINTN                          *FontInfoSize OPTIONAL\r
+  IN  HII_DATABASE_PRIVATE_DATA  *Private,\r
+  OUT EFI_FONT_DISPLAY_INFO      **FontInfo,\r
+  OUT UINTN                      *FontInfoSize OPTIONAL\r
   )\r
 {\r
-  EFI_FONT_DISPLAY_INFO              *Info;\r
-  UINTN                              InfoSize;\r
+  EFI_FONT_DISPLAY_INFO  *Info;\r
+  UINTN                  InfoSize;\r
+  UINTN                  NameSize;\r
 \r
-  if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
+  if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if (FontInfo == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -883,37 +1011,40 @@ GetSystemFont (
   //\r
   // The standard font always has the name "sysdefault".\r
   //\r
-  InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + StrSize (L"sysdefault");\r
-  Info = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (InfoSize);\r
+  NameSize = StrSize (L"sysdefault");\r
+  InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
+  Info     = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (InfoSize);\r
   if (Info == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Info->ForegroundColor    = mEfiColors[Private->Attribute & 0x0f];\r
-  Info->BackgroundColor    = mEfiColors[Private->Attribute >> 4];\r
+  Info->ForegroundColor = mHiiEfiColors[Private->Attribute & 0x0f];\r
+  ASSERT ((Private->Attribute >> 4) < 8);\r
+  Info->BackgroundColor    = mHiiEfiColors[Private->Attribute >> 4];\r
   Info->FontInfoMask       = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;\r
   Info->FontInfo.FontStyle = 0;\r
   Info->FontInfo.FontSize  = EFI_GLYPH_HEIGHT;\r
-  StrCpy (Info->FontInfo.FontName, L"sysdefault");\r
+  StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");\r
 \r
   *FontInfo = Info;\r
   if (FontInfoSize != NULL) {\r
     *FontInfoSize = InfoSize;\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
-  Check whether EFI_FONT_DISPLAY_INFO points to system default font and color.\r
+  Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or\r
+  returns the system default according to the optional inputs.\r
+\r
+  This is a internal function.\r
 \r
   @param  Private                 HII database driver private data.\r
   @param  StringInfo              Points to the string output information,\r
                                   including the color and font.\r
-  @param  SystemInfo              If not NULL, points to system default font and\r
-                                  color when incoming StringInfo does not match the\r
-                                  default.  Points to NULL if matches. It's\r
-                                  caller's reponsibility to free this buffer.\r
+  @param  SystemInfo              If not NULL, points to system default font and color.\r
+\r
   @param  SystemInfoLen           If not NULL, output the length of default system\r
                                   info.\r
 \r
@@ -921,49 +1052,102 @@ GetSystemFont (
   @retval FALSE                   No.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 IsSystemFontInfo (\r
-  IN  HII_DATABASE_PRIVATE_DATA      *Private,\r
-  IN  EFI_FONT_DISPLAY_INFO          *StringInfo,\r
-  OUT EFI_FONT_DISPLAY_INFO          **SystemInfo, OPTIONAL\r
-  OUT UINTN                          *SystemInfoLen OPTIONAL\r
+  IN  HII_DATABASE_PRIVATE_DATA  *Private,\r
+  IN  EFI_FONT_DISPLAY_INFO      *StringInfo,\r
+  OUT EFI_FONT_DISPLAY_INFO      **SystemInfo  OPTIONAL,\r
+  OUT UINTN                      *SystemInfoLen OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
-  EFI_FONT_DISPLAY_INFO               *SystemDefault;\r
-  UINTN                               DefaultLen;\r
+  EFI_STATUS             Status;\r
+  EFI_FONT_DISPLAY_INFO  *SystemDefault;\r
+  UINTN                  DefaultLen;\r
+  BOOLEAN                Flag;\r
 \r
   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
 \r
-  if (StringInfo == NULL && SystemInfo == NULL) {\r
+  if ((StringInfo == NULL) && (SystemInfo == NULL)) {\r
     return TRUE;\r
   }\r
 \r
-  //\r
-  // Check whether incoming string font and color matches system default.\r
-  //\r
+  SystemDefault = NULL;\r
+  DefaultLen    = 0;\r
+\r
   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
   ASSERT_EFI_ERROR (Status);\r
+  ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));\r
 \r
+  //\r
+  // Record the system default info.\r
+  //\r
   if (SystemInfo != NULL) {\r
     *SystemInfo = SystemDefault;\r
-  } else {\r
-    SafeFreePool (SystemDefault);\r
   }\r
 \r
   if (SystemInfoLen != NULL) {\r
     *SystemInfoLen = DefaultLen;\r
   }\r
 \r
-  if (StringInfo == NULL ||\r
-      (StringInfo != NULL && CompareMem (SystemDefault, StringInfo, DefaultLen) == 0)) {\r
+  if (StringInfo == NULL) {\r
     return TRUE;\r
   }\r
 \r
-  return FALSE;\r
-}\r
+  Flag = FALSE;\r
+  //\r
+  // Check the FontInfoMask to see whether it is retrieving system info.\r
+  //\r
+  if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {\r
+    if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {\r
+    if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {\r
+    if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {\r
+    if (CompareMem (\r
+          &StringInfo->ForegroundColor,\r
+          &SystemDefault->ForegroundColor,\r
+          sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+          ) != 0)\r
+    {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {\r
+    if (CompareMem (\r
+          &StringInfo->BackgroundColor,\r
+          &SystemDefault->BackgroundColor,\r
+          sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+          ) != 0)\r
+    {\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  Flag = TRUE;\r
 \r
+Exit:\r
+  if (SystemInfo == NULL) {\r
+    if (SystemDefault != NULL) {\r
+      FreePool (SystemDefault);\r
+    }\r
+  }\r
+\r
+  return Flag;\r
+}\r
 \r
 /**\r
   This function checks whether EFI_FONT_INFO exists in current database. If\r
@@ -980,7 +1164,7 @@ IsSystemFontInfo (
   @param  FontHandle              On entry, Points to the font handle returned by a\r
                                   previous  call to GetFontInfo() or NULL to start\r
                                   with the first font.\r
-  @param  GlobalFontInfo          If not NULL, output the corresponding globa font\r
+  @param  GlobalFontInfo          If not NULL, output the corresponding global font\r
                                   info.\r
 \r
   @retval TRUE                    Existed\r
@@ -989,32 +1173,32 @@ IsSystemFontInfo (
 **/\r
 BOOLEAN\r
 IsFontInfoExisted (\r
-  IN  HII_DATABASE_PRIVATE_DATA *Private,\r
-  IN  EFI_FONT_INFO             *FontInfo,\r
-  IN  EFI_FONT_INFO_MASK        *FontInfoMask,   OPTIONAL\r
-  IN  EFI_FONT_HANDLE           FontHandle,      OPTIONAL\r
-  OUT HII_GLOBAL_FONT_INFO      **GlobalFontInfo OPTIONAL\r
+  IN  HII_DATABASE_PRIVATE_DATA  *Private,\r
+  IN  EFI_FONT_INFO              *FontInfo,\r
+  IN  EFI_FONT_INFO_MASK         *FontInfoMask    OPTIONAL,\r
+  IN  EFI_FONT_HANDLE            FontHandle       OPTIONAL,\r
+  OUT HII_GLOBAL_FONT_INFO       **GlobalFontInfo OPTIONAL\r
   )\r
 {\r
-  HII_GLOBAL_FONT_INFO          *GlobalFont;\r
-  HII_GLOBAL_FONT_INFO          *GlobalFontBackup1;\r
-  HII_GLOBAL_FONT_INFO          *GlobalFontBackup2;\r
-  LIST_ENTRY                    *Link;\r
-  EFI_FONT_INFO_MASK            Mask;\r
-  BOOLEAN                       Matched;\r
-  BOOLEAN                       VagueMatched1;\r
-  BOOLEAN                       VagueMatched2;\r
+  HII_GLOBAL_FONT_INFO  *GlobalFont;\r
+  HII_GLOBAL_FONT_INFO  *GlobalFontBackup1;\r
+  HII_GLOBAL_FONT_INFO  *GlobalFontBackup2;\r
+  LIST_ENTRY            *Link;\r
+  EFI_FONT_INFO_MASK    Mask;\r
+  BOOLEAN               Matched;\r
+  BOOLEAN               VagueMatched1;\r
+  BOOLEAN               VagueMatched2;\r
 \r
   ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
   ASSERT (FontInfo != NULL);\r
 \r
   //\r
-  // Matched flag represents an exactly match; VagueMatched1 repensents a RESIZE\r
+  // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE\r
   // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.\r
   //\r
-  Matched           = FALSE;\r
-  VagueMatched1     = FALSE;\r
-  VagueMatched2     = FALSE;\r
+  Matched       = FALSE;\r
+  VagueMatched1 = FALSE;\r
+  VagueMatched2 = FALSE;\r
 \r
   Mask              = 0;\r
   GlobalFontBackup1 = NULL;\r
@@ -1034,16 +1218,17 @@ IsFontInfoExisted (
   if (FontHandle == NULL) {\r
     Link = Private->FontInfoList.ForwardLink;\r
   } else {\r
-    Link = (LIST_ENTRY     *) FontHandle;\r
+    Link = (LIST_ENTRY     *)FontHandle;\r
   }\r
 \r
-  for (; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
+  for ( ; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
     GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
     if (FontInfoMask == NULL) {\r
       if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {\r
         if (GlobalFontInfo != NULL) {\r
           *GlobalFontInfo = GlobalFont;\r
         }\r
+\r
         return TRUE;\r
       }\r
     } else {\r
@@ -1051,208 +1236,232 @@ IsFontInfoExisted (
       // Check which options could be used to make a match.\r
       //\r
       switch (Mask) {\r
-      case EFI_FONT_INFO_ANY_FONT:\r
-        if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle &&\r
-            GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-          Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:\r
-        if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
-          Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:\r
-        if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+        case EFI_FONT_INFO_ANY_FONT:\r
+          if ((GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) &&\r
+              (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize))\r
+          {\r
+            Matched = TRUE;\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:\r
+          if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
+            Matched = TRUE;\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:\r
+          if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+            Matched = TRUE;\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:\r
           Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:\r
-        Matched   = TRUE;\r
-        break;\r
-      //\r
-      // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to\r
-      // remove some of the specified styles to meet the style requested.\r
-      //\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:\r
-        if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
+          break;\r
+        //\r
+        // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to\r
+        // remove some of the specified styles to meet the style requested.\r
+        //\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:\r
+          if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
+            if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+              Matched = TRUE;\r
+            } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
+            }\r
+          }\r
+\r
+          break;\r
+        //\r
+        // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to\r
+        // stretch or shrink a font to meet the size requested.\r
+        //\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:\r
+          if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+            if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+              Matched = TRUE;\r
+            } else {\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
+            }\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:\r
           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-            Matched           = TRUE;\r
+            if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+              Matched = TRUE;\r
+            } else {\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
+            }\r
           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
+            if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
+            } else {\r
+              VagueMatched2     = TRUE;\r
+              GlobalFontBackup2 = GlobalFont;\r
+            }\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
+          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+            Matched = TRUE;\r
+          } else {\r
             VagueMatched1     = TRUE;\r
             GlobalFontBackup1 = GlobalFont;\r
           }\r
-        }\r
-        break;\r
-      //\r
-      // If EFI_FONT_INFO_RESIZE is specified, then the sytem may attempt to\r
-      // stretch or shrink a font to meet the size requested.\r
-      //\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:\r
-        if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-            Matched           = TRUE;\r
-          } else {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
-          }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:\r
-        if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-            Matched           = TRUE;\r
-          } else {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
-          }\r
-        } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
-          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
-          } else {\r
-            VagueMatched2     = TRUE;\r
-            GlobalFontBackup2 = GlobalFont;\r
-          }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
-        if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-          Matched           = TRUE;\r
-        } else {\r
-          VagueMatched1     = TRUE;\r
-          GlobalFontBackup1 = GlobalFont;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
-        if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-          Matched           = TRUE;\r
-        } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
-          VagueMatched1     = TRUE;\r
-          GlobalFontBackup1 = GlobalFont;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_STYLE:\r
-        if ((CompareMem (\r
-               GlobalFont->FontInfo->FontName,\r
-               FontInfo->FontName,\r
-               StrSize (FontInfo->FontName)\r
-               ) == 0) &&\r
-            GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-          Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:\r
-        if (CompareMem (\r
-              GlobalFont->FontInfo->FontName,\r
-              FontInfo->FontName,\r
-              StrSize (FontInfo->FontName)\r
-              ) == 0) {\r
-          Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
-        if (CompareMem (\r
-              GlobalFont->FontInfo->FontName,\r
-              FontInfo->FontName,\r
-              StrSize (FontInfo->FontName)\r
-              ) == 0) {\r
-          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-            Matched           = TRUE;\r
-          } else {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
-          }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_SIZE:\r
-        if ((CompareMem (\r
-               GlobalFont->FontInfo->FontName,\r
-               FontInfo->FontName,\r
-               StrSize (FontInfo->FontName)\r
-               ) == 0) &&\r
-            GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {\r
-          Matched = TRUE;\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
-        if (CompareMem (\r
-              GlobalFont->FontInfo->FontName,\r
-              FontInfo->FontName,\r
-              StrSize (FontInfo->FontName)\r
-              ) == 0) {\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
           if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-            Matched           = TRUE;\r
+            Matched = TRUE;\r
           } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
             VagueMatched1     = TRUE;\r
             GlobalFontBackup1 = GlobalFont;\r
           }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_RESTYLE:\r
-        if ((CompareMem (\r
-               GlobalFont->FontInfo->FontName,\r
-               FontInfo->FontName,\r
-               StrSize (FontInfo->FontName)\r
-               ) == 0) &&\r
-            GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
 \r
-          if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
-            Matched           = TRUE;\r
-          } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
+          break;\r
+        case EFI_FONT_INFO_ANY_STYLE:\r
+          if ((CompareMem (\r
+                 GlobalFont->FontInfo->FontName,\r
+                 FontInfo->FontName,\r
+                 StrSize (FontInfo->FontName)\r
+                 ) == 0) &&\r
+              (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize))\r
+          {\r
+            Matched = TRUE;\r
           }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_RESIZE:\r
-        if ((CompareMem (\r
-               GlobalFont->FontInfo->FontName,\r
-               FontInfo->FontName,\r
-               StrSize (FontInfo->FontName)\r
-               ) == 0) &&\r
-            GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle) {\r
 \r
-          if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-            Matched           = TRUE;\r
-          } else {\r
-            VagueMatched1     = TRUE;\r
-            GlobalFontBackup1 = GlobalFont;\r
+          break;\r
+        case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:\r
+          if (CompareMem (\r
+                GlobalFont->FontInfo->FontName,\r
+                FontInfo->FontName,\r
+                StrSize (FontInfo->FontName)\r
+                ) == 0)\r
+          {\r
+            Matched = TRUE;\r
           }\r
-        }\r
-        break;\r
-      case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:\r
-        if (CompareMem (\r
-              GlobalFont->FontInfo->FontName,\r
-              FontInfo->FontName,\r
-              StrSize (FontInfo->FontName)\r
-              ) == 0) {\r
-          if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
+          if (CompareMem (\r
+                GlobalFont->FontInfo->FontName,\r
+                FontInfo->FontName,\r
+                StrSize (FontInfo->FontName)\r
+                ) == 0)\r
+          {\r
             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-              Matched           = TRUE;\r
+              Matched = TRUE;\r
             } else {\r
               VagueMatched1     = TRUE;\r
               GlobalFontBackup1 = GlobalFont;\r
             }\r
-          } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
-            if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_SIZE:\r
+          if ((CompareMem (\r
+                 GlobalFont->FontInfo->FontName,\r
+                 FontInfo->FontName,\r
+                 StrSize (FontInfo->FontName)\r
+                 ) == 0) &&\r
+              (GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle))\r
+          {\r
+            Matched = TRUE;\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
+          if (CompareMem (\r
+                GlobalFont->FontInfo->FontName,\r
+                FontInfo->FontName,\r
+                StrSize (FontInfo->FontName)\r
+                ) == 0)\r
+          {\r
+            if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+              Matched = TRUE;\r
+            } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
               VagueMatched1     = TRUE;\r
               GlobalFontBackup1 = GlobalFont;\r
+            }\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_RESTYLE:\r
+          if ((CompareMem (\r
+                 GlobalFont->FontInfo->FontName,\r
+                 FontInfo->FontName,\r
+                 StrSize (FontInfo->FontName)\r
+                 ) == 0) &&\r
+              (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize))\r
+          {\r
+            if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+              Matched = TRUE;\r
+            } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
+            }\r
+          }\r
+\r
+          break;\r
+        case EFI_FONT_INFO_RESIZE:\r
+          if ((CompareMem (\r
+                 GlobalFont->FontInfo->FontName,\r
+                 FontInfo->FontName,\r
+                 StrSize (FontInfo->FontName)\r
+                 ) == 0) &&\r
+              (GlobalFont->FontInfo->FontStyle  == FontInfo->FontStyle))\r
+          {\r
+            if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+              Matched = TRUE;\r
             } else {\r
-              VagueMatched2     = TRUE;\r
-              GlobalFontBackup2 = GlobalFont;\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
             }\r
           }\r
-        }\r
-        break;\r
-      default:\r
-        break;\r
+\r
+          break;\r
+        case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:\r
+          if (CompareMem (\r
+                GlobalFont->FontInfo->FontName,\r
+                FontInfo->FontName,\r
+                StrSize (FontInfo->FontName)\r
+                ) == 0)\r
+          {\r
+            if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
+              if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+                Matched = TRUE;\r
+              } else {\r
+                VagueMatched1     = TRUE;\r
+                GlobalFontBackup1 = GlobalFont;\r
+              }\r
+            } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
+              if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
+                VagueMatched1     = TRUE;\r
+                GlobalFontBackup1 = GlobalFont;\r
+              } else {\r
+                VagueMatched2     = TRUE;\r
+                GlobalFontBackup2 = GlobalFont;\r
+              }\r
+            }\r
+          }\r
+\r
+          break;\r
+        default:\r
+          break;\r
       }\r
 \r
       if (Matched) {\r
         if (GlobalFontInfo != NULL) {\r
           *GlobalFontInfo = GlobalFont;\r
         }\r
+\r
         return TRUE;\r
       }\r
     }\r
@@ -1262,96 +1471,100 @@ IsFontInfoExisted (
     if (GlobalFontInfo != NULL) {\r
       *GlobalFontInfo = GlobalFontBackup1;\r
     }\r
+\r
     return TRUE;\r
   } else if (VagueMatched2) {\r
     if (GlobalFontInfo != NULL) {\r
       *GlobalFontInfo = GlobalFontBackup2;\r
     }\r
+\r
     return TRUE;\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
-\r
 /**\r
   Check whether the unicode represents a line break or not.\r
 \r
+  This is a internal function. Please see Section 27.2.6 of the UEFI Specification\r
+  for a description of the supported string format.\r
+\r
   @param  Char                    Unicode character\r
 \r
-  @retval 0                       Yes, it is a line break.\r
-  @retval 1                       Yes, it is a hyphen that desires a line break\r
-                                  after this character.\r
-  @retval 2                       Yes, it is a dash that desires a line break\r
-                                  before and after it.\r
+  @retval 0                       Yes, it forces a line break.\r
+  @retval 1                       Yes, it presents a line break opportunity\r
+  @retval 2                       Yes, it requires a line break happen before and after it.\r
   @retval -1                      No, it is not a link break.\r
 \r
 **/\r
-STATIC\r
 INT8\r
 IsLineBreak (\r
-  IN  CHAR16    Char\r
+  IN  CHAR16  Char\r
   )\r
 {\r
-  UINT8         Byte1;\r
-  UINT8         Byte2;\r
-\r
-  //\r
-  // In little endian, Byte1 is the low byte of Char, Byte2 is the high byte of Char.\r
-  //\r
-  Byte1 = *((UINT8 *) (&Char));\r
-  Byte2 = *(((UINT8 *) (&Char) + 1));\r
-\r
-  if (Byte2 == 0x20) {\r
-    switch (Byte1) {\r
-    case 0x00:\r
-    case 0x01:\r
-    case 0x02:\r
-    case 0x03:\r
-    case 0x04:\r
-    case 0x05:\r
-    case 0x06:\r
-    case 0x08:\r
-    case 0x09:\r
-    case 0x0A:\r
-    case 0x0B:\r
-    case 0x28:\r
-    case 0x29:\r
-    case 0x5F:\r
-      return 0;\r
-    case 0x10:\r
-    case 0x12:\r
-    case 0x13:\r
-      return 1;\r
-    case 0x14:\r
-      //\r
-      // BUGBUG: Does it really require line break before it and after it?\r
-      //\r
-      return 2;\r
-    }\r
-  } else if (Byte2 == 0x00) {\r
-    switch (Byte1) {\r
-    case 0x20:\r
-    case 0x0C:\r
-    case 0x0D:\r
-      return 0;\r
-    }\r
-  }\r
-\r
   switch (Char) {\r
-    case 0x1680:\r
+    //\r
+    // Mandatory line break characters, which force a line-break\r
+    //\r
+    case 0x000A:\r
+    case 0x000C:\r
+    case 0x000D:\r
+    case 0x2028:\r
+    case 0x2029:\r
       return 0;\r
+    //\r
+    // Space characters, which is taken as a line-break opportunity\r
+    //\r
+    case 0x0020:\r
+    case 0x1680:\r
+    case 0x2000:\r
+    case 0x2001:\r
+    case 0x2002:\r
+    case 0x2003:\r
+    case 0x2004:\r
+    case 0x2005:\r
+    case 0x2006:\r
+    case 0x2008:\r
+    case 0x2009:\r
+    case 0x200A:\r
+    case 0x205F:\r
+    //\r
+    // In-Word Break Opportunities\r
+    //\r
+    case 0x200B:\r
+      return 1;\r
+    //\r
+    // A space which is not a line-break opportunity\r
+    //\r
+    case 0x00A0:\r
+    case 0x202F:\r
+    //\r
+    // A hyphen which is not a line-break opportunity\r
+    //\r
+    case 0x2011:\r
+      return -1;\r
+    //\r
+    // Hyphen characters which describe line break opportunities after the character\r
+    //\r
     case 0x058A:\r
+    case 0x2010:\r
+    case 0x2012:\r
+    case 0x2013:\r
     case 0x0F0B:\r
     case 0x1361:\r
     case 0x17D5:\r
       return 1;\r
+    //\r
+    // A hyphen which describes line break opportunities before and after them, but not between a pair of them\r
+    //\r
+    case 0x2014:\r
+      return 2;\r
   }\r
 \r
   return -1;\r
 }\r
 \r
-\r
 /**\r
   Renders a string to a bitmap or to the display.\r
 \r
@@ -1372,7 +1585,10 @@ IsLineBreak (
                                   will be allocated to hold the generated image and\r
                                   the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\r
-  @param  BltX,BLTY               Specifies the offset from the left and top edge\r
+  @param  BltX                    Specifies the offset from the left and top edge\r
+                                  of the image of the first character cell in the\r
+                                  image.\r
+  @param  BltY                    Specifies the offset from the left and top edge\r
                                   of the image of the first character cell in the\r
                                   image.\r
   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this\r
@@ -1400,62 +1616,72 @@ IsLineBreak (
   @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for\r
                                   RowInfoArray or Blt.\r
   @retval EFI_INVALID_PARAMETER   The String or Blt was NULL.\r
+  @retval EFI_INVALID_PARAMETER Flags were invalid combination..\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiStringToImage (\r
-  IN  CONST EFI_HII_FONT_PROTOCOL    *This,\r
-  IN  EFI_HII_OUT_FLAGS              Flags,\r
-  IN  CONST EFI_STRING               String,\r
-  IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,\r
-  IN  OUT EFI_IMAGE_OUTPUT           **Blt,\r
-  IN  UINTN                          BltX,\r
-  IN  UINTN                          BltY,\r
-  OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,\r
-  OUT UINTN                          *RowInfoArraySize OPTIONAL,\r
-  OUT UINTN                          *ColumnInfoArray  OPTIONAL\r
+  IN  CONST EFI_HII_FONT_PROTOCOL  *This,\r
+  IN  EFI_HII_OUT_FLAGS            Flags,\r
+  IN  CONST EFI_STRING             String,\r
+  IN  CONST EFI_FONT_DISPLAY_INFO  *StringInfo       OPTIONAL,\r
+  IN  OUT EFI_IMAGE_OUTPUT         **Blt,\r
+  IN  UINTN                        BltX,\r
+  IN  UINTN                        BltY,\r
+  OUT EFI_HII_ROW_INFO             **RowInfoArray    OPTIONAL,\r
+  OUT UINTN                        *RowInfoArraySize OPTIONAL,\r
+  OUT UINTN                        *ColumnInfoArray  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  UINT8                               **GlyphBuf;\r
-  EFI_HII_GLYPH_INFO                  *Cell;\r
-  UINT8                               *Attributes;\r
-  EFI_IMAGE_OUTPUT                    *Image;\r
-  EFI_STRING                          StringPtr;\r
-  EFI_STRING                          StringTmp;\r
-  EFI_HII_ROW_INFO                    *RowInfo;\r
-  UINTN                               LineWidth;\r
-  UINTN                               LineHeight;\r
-  UINTN                               BaseLineOffset;\r
-  UINT16                              MaxRowNum;\r
-  UINT16                              RowIndex;\r
-  UINTN                               Index;\r
-  UINTN                               Index1;\r
-  EFI_FONT_DISPLAY_INFO               *StringInfoOut;\r
-  EFI_FONT_DISPLAY_INFO               *SystemDefault;\r
-  EFI_FONT_HANDLE                     FontHandle;\r
-  EFI_STRING                          StringIn;\r
-  EFI_STRING                          StringIn2;\r
-  UINT16                              Height;\r
-  EFI_FONT_INFO                       *FontInfo;\r
-  BOOLEAN                             SysFontFlag;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Foreground;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL       Background;\r
-  BOOLEAN                             Transparent;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BltBuffer;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BufferPtr;\r
-  UINTN                               RowInfoSize;\r
-  BOOLEAN                             LineBreak;\r
+  EFI_STATUS                     Status;\r
+  HII_DATABASE_PRIVATE_DATA      *Private;\r
+  UINT8                          **GlyphBuf;\r
+  EFI_HII_GLYPH_INFO             *Cell;\r
+  UINT8                          *Attributes;\r
+  EFI_IMAGE_OUTPUT               *Image;\r
+  EFI_STRING                     StringPtr;\r
+  EFI_STRING                     StringTmp;\r
+  EFI_HII_ROW_INFO               *RowInfo;\r
+  UINTN                          LineWidth;\r
+  UINTN                          LineHeight;\r
+  UINTN                          LineOffset;\r
+  UINTN                          LastLineHeight;\r
+  UINTN                          BaseLineOffset;\r
+  UINT16                         MaxRowNum;\r
+  UINT16                         RowIndex;\r
+  UINTN                          Index;\r
+  UINTN                          NextIndex;\r
+  UINTN                          Index1;\r
+  EFI_FONT_DISPLAY_INFO          *StringInfoOut;\r
+  EFI_FONT_DISPLAY_INFO          *SystemDefault;\r
+  EFI_FONT_HANDLE                FontHandle;\r
+  EFI_STRING                     StringIn;\r
+  EFI_STRING                     StringIn2;\r
+  UINT16                         Height;\r
+  UINT16                         BaseLine;\r
+  EFI_FONT_INFO                  *FontInfo;\r
+  BOOLEAN                        SysFontFlag;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background;\r
+  BOOLEAN                        Transparent;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BufferPtr;\r
+  UINTN                          RowInfoSize;\r
+  BOOLEAN                        LineBreak;\r
+  UINTN                          StrLength;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *RowBufferPtr;\r
+  HII_GLOBAL_FONT_INFO           *GlobalFont;\r
+  UINT32                         PreInitBkgnd;\r
 \r
   //\r
   // Check incoming parameters.\r
   //\r
 \r
-  if (This == NULL || String == NULL || Blt == NULL) {\r
+  if ((This == NULL) || (String == NULL) || (Blt == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if (*Blt == NULL) {\r
     //\r
     // These two flag cannot be used if Blt is NULL upon entry.\r
@@ -1463,37 +1689,67 @@ HiiStringToImage (
     if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
+\r
   //\r
   // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.\r
   //\r
-  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLEAN_X) {\r
+  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLEAN_Y) {\r
+\r
+  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
   // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\r
   //\r
-  if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLEAN_X)) ==  (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLEAN_X)) {\r
+  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)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  GlyphBuf = (UINT8 **) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8 *));\r
+  if (*Blt == NULL) {\r
+    //\r
+    // Create a new bitmap and draw the string onto this image.\r
+    //\r
+    Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
+    if (Image == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    Image->Width        = 800;\r
+    Image->Height       = 600;\r
+    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    if (Image->Image.Bitmap == NULL) {\r
+      FreePool (Image);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Other flags are not permitted when Blt is NULL.\r
+    //\r
+    Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
+    *Blt   = Image;\r
+  }\r
+\r
+  StrLength = StrLen (String);\r
+  GlyphBuf  = (UINT8 **)AllocateZeroPool (StrLength * sizeof (UINT8 *));\r
   ASSERT (GlyphBuf != NULL);\r
-  Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (EFI_HII_GLYPH_INFO));\r
+  Cell = (EFI_HII_GLYPH_INFO *)AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));\r
   ASSERT (Cell != NULL);\r
-  Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));\r
+  Attributes = (UINT8 *)AllocateZeroPool (StrLength * sizeof (UINT8));\r
   ASSERT (Attributes != NULL);\r
 \r
   RowInfo       = NULL;\r
   Status        = EFI_SUCCESS;\r
   StringIn2     = NULL;\r
   SystemDefault = NULL;\r
+  StringIn      = NULL;\r
 \r
   //\r
   // Calculate the string output information, including specified color and font .\r
@@ -1503,16 +1759,21 @@ HiiStringToImage (
   StringInfoOut = NULL;\r
   FontHandle    = NULL;\r
   Private       = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-  SysFontFlag   = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
+  SysFontFlag   = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);\r
 \r
   if (SysFontFlag) {\r
+    ASSERT (SystemDefault != NULL);\r
     FontInfo   = NULL;\r
     Height     = SystemDefault->FontInfo.FontSize;\r
+    BaseLine   = SystemDefault->FontInfo.FontSize;\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
-\r
   } else {\r
-    Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *) StringInfo, &StringInfoOut, NULL);\r
+    //\r
+    //  StringInfo must not be NULL if it is not system info.\r
+    //\r
+    ASSERT (StringInfo != NULL);\r
+    Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);\r
     if (Status == EFI_NOT_FOUND) {\r
       //\r
       // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.\r
@@ -1521,23 +1782,34 @@ HiiStringToImage (
       SysFontFlag = TRUE;\r
       FontInfo    = NULL;\r
       Height      = SystemDefault->FontInfo.FontSize;\r
-      Foreground  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;\r
-      Background  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;\r
-\r
-    } else {\r
-      FontInfo   = &StringInfoOut->FontInfo;\r
-      Height     = StringInfoOut->FontInfo.FontSize;\r
+      BaseLine    = SystemDefault->FontInfo.FontSize;\r
+      Foreground  = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;\r
+      Background  = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;\r
+    } else if (Status == EFI_SUCCESS) {\r
+      FontInfo = &StringInfoOut->FontInfo;\r
+      IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);\r
+      Height     = GlobalFont->FontPackage->Height;\r
+      BaseLine   = GlobalFont->FontPackage->BaseLine;\r
       Foreground = StringInfoOut->ForegroundColor;\r
       Background = StringInfoOut->BackgroundColor;\r
+    } else {\r
+      goto Exit;\r
     }\r
   }\r
 \r
+  //\r
+  // Use the maximum height of font as the base line.\r
+  // And, use the maximum height as line height.\r
+  //\r
+  LineHeight     = Height;\r
+  LastLineHeight = Height;\r
+  BaseLineOffset = Height - BaseLine;\r
+\r
   //\r
   // Parse the string to be displayed to drop some ignored characters.\r
   //\r
 \r
   StringPtr = String;\r
-  StringIn  = NULL;\r
 \r
   //\r
   // Ignore line-break characters only. Hyphens or dash character will be displayed\r
@@ -1549,6 +1821,7 @@ HiiStringToImage (
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
+\r
     StringTmp = StringIn;\r
     while (*StringPtr != 0) {\r
       if (IsLineBreak (*StringPtr) == 0) {\r
@@ -1557,28 +1830,37 @@ HiiStringToImage (
         *StringTmp++ = *StringPtr++;\r
       }\r
     }\r
+\r
     *StringTmp = 0;\r
     StringPtr  = StringIn;\r
   }\r
+\r
   //\r
   // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs\r
-  // are not drawn. Otherwise they are replaced wth Unicode character 0xFFFD.\r
+  // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.\r
   //\r
-  StringIn2  = AllocateZeroPool (StrSize (StringPtr));\r
+  StringIn2 = AllocateZeroPool (StrSize (StringPtr));\r
   if (StringIn2 == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
+\r
   Index     = 0;\r
   StringTmp = StringIn2;\r
+  StrLength = StrLen (StringPtr);\r
+  while (*StringPtr != 0 && Index < StrLength) {\r
+    if (IsLineBreak (*StringPtr) == 0) {\r
+      *StringTmp++ = *StringPtr++;\r
+      Index++;\r
+      continue;\r
+    }\r
 \r
-  while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {\r
     Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
     if (Status == EFI_NOT_FOUND) {\r
       if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
-        SafeFreePool (GlyphBuf[Index]);\r
         GlyphBuf[Index] = NULL;\r
-        StringPtr++;\r
+        ZeroMem (&Cell[Index], sizeof (Cell[Index]));\r
+        Status = EFI_SUCCESS;\r
       } else {\r
         //\r
         // Unicode 0xFFFD must exist in current hii database if this flag is not set.\r
@@ -1593,18 +1875,18 @@ HiiStringToImage (
                    );\r
         if (EFI_ERROR (Status)) {\r
           Status = EFI_INVALID_PARAMETER;\r
-          goto Exit;\r
         }\r
-        *StringTmp++ = *StringPtr++;\r
-        Index++;\r
       }\r
-    } else if (EFI_ERROR (Status)) {\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
       goto Exit;\r
-    } else {\r
-      *StringTmp++ = *StringPtr++;\r
-      Index++;\r
     }\r
+\r
+    *StringTmp++ = *StringPtr++;\r
+    Index++;\r
   }\r
+\r
   *StringTmp = 0;\r
   StringPtr  = StringIn2;\r
 \r
@@ -1614,181 +1896,286 @@ HiiStringToImage (
   // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
   // Otherwise render this string to a new allocated image and output it.\r
   //\r
-  if (*Blt != NULL) {\r
-    Image     = *Blt;\r
-    BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
-    MaxRowNum = (UINT16) (Image->Height / Height);\r
-    if (Image->Height % Height != 0) {\r
-      MaxRowNum++;\r
-    }\r
+  Image     = *Blt;\r
+  BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
+  if (Image->Height < BltY) {\r
+    //\r
+    // the top edge of the image should be in Image resolution scope.\r
+    //\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Exit;\r
+  }\r
 \r
-    RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));\r
-    if (RowInfo == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Exit;\r
-    }\r
+  MaxRowNum = (UINT16)((Image->Height - BltY) / Height);\r
+  if ((Image->Height - BltY) % Height != 0) {\r
+    LastLineHeight = (Image->Height - BltY) % Height;\r
+    MaxRowNum++;\r
+  }\r
+\r
+  RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));\r
+  if (RowInfo == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Format the glyph buffer according to flags.\r
+  //\r
+  Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
+\r
+  for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
+    LineWidth = 0;\r
+    LineBreak = FALSE;\r
 \r
     //\r
-    // Format the glyph buffer according to flags.\r
+    // Clip the final row if the row's bottom-most on pixel cannot fit when\r
+    // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
     //\r
-\r
-    Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
-    if ((Flags & EFI_HII_OUT_FLAG_CLEAN_Y) == EFI_HII_OUT_FLAG_CLEAN_Y) {\r
-      //\r
-      // Don't draw at all if there is only one row and\r
-      // the row's bottom-most on pixel cannot fit.\r
-      //\r
-      if (MaxRowNum == 1 && SysFontFlag) {\r
-        Status = EFI_SUCCESS;\r
-        goto Exit;\r
+    if (RowIndex == MaxRowNum - 1) {\r
+      if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {\r
+        //\r
+        // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
+        //\r
+        break;\r
       }\r
+\r
+      LineHeight = LastLineHeight;\r
     }\r
 \r
-    for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
-      LineWidth      = 0;\r
-      LineHeight     = 0;\r
-      BaseLineOffset = 0;\r
-      LineBreak      = FALSE;\r
+    //\r
+    // Calculate how many characters there are in a row.\r
+    //\r
+    RowInfo[RowIndex].StartIndex = Index;\r
+\r
+    while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
+      if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&\r
+          (IsLineBreak (StringPtr[Index]) == 0))\r
+      {\r
+        //\r
+        // It forces a line break that ends this row.\r
+        //\r
+        Index++;\r
+        LineBreak = TRUE;\r
+        break;\r
+      }\r
 \r
       //\r
-      // Calculate how many characters there are in a row.\r
+      // If the glyph of the character is existing, then accumulate the actual printed width\r
       //\r
-      RowInfo[RowIndex].StartIndex = Index;\r
-\r
-      while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
-        LineWidth += (UINTN) Cell[Index].AdvanceX;\r
-        if (LineHeight < Cell[Index].Height) {\r
-          LineHeight = (UINTN) Cell[Index].Height;\r
-        }\r
-        BaseLineOffset += (UINTN) Cell[Index].OffsetY;\r
-\r
-        if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&\r
-            (Flags & EFI_HII_OUT_FLAG_WRAP) == 0 &&\r
-             IsLineBreak (StringPtr[Index]) > 0) {\r
-          //\r
-          // It is a line break that ends this row.\r
-          //\r
-          Index++;\r
-          break;\r
-        }\r
+      LineWidth += (UINTN)Cell[Index].AdvanceX;\r
 \r
-        Index++;\r
-      }\r
+      Index++;\r
+    }\r
 \r
+    //\r
+    // Record index of next char.\r
+    //\r
+    NextIndex = Index;\r
+    //\r
+    // Return to the previous char.\r
+    //\r
+    Index--;\r
+    if (LineBreak && (Index > 0)) {\r
       //\r
-      // If this character is the last character of a row, we need not\r
-      // draw its (AdvanceX - Width) for next character.\r
+      // Return the previous non line break char.\r
       //\r
       Index--;\r
-      if (!SysFontFlag) {\r
-        LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\r
-      }\r
+    }\r
 \r
+    //\r
+    // If this character is the last character of a row, we need not\r
+    // draw its (AdvanceX - Width - OffsetX) for next character.\r
+    //\r
+    LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);\r
+\r
+    //\r
+    // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
+    //\r
+    if ((LineWidth + BltX <= Image->Width) ||\r
+        ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))\r
+    {\r
       //\r
-      // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break\r
-      // opportunity prior to a character whose right-most extent would exceed Width.\r
-      // Search the right-most line-break opportunity here.\r
+      // Record right-most character in RowInfo even if it is partially displayed.\r
       //\r
-      if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) {\r
-        if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {\r
-          for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {\r
-            if (IsLineBreak (StringPtr[Index1]) > 0) {\r
-              LineBreak = TRUE;\r
-              RowInfo[RowIndex].EndIndex = Index1 - 1;\r
-              break;\r
-            }\r
-          }\r
-        }\r
-        //\r
-        // If no line-break opportunity can be found, then the text will\r
-        // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
-        //\r
-        if (!LineBreak) {\r
-          Flags &= (~ (EFI_HII_OUT_FLAGS) EFI_HII_OUT_FLAG_WRAP);\r
-          Flags |= EFI_HII_OUT_FLAG_CLEAN_X;\r
-        }\r
-      }\r
-\r
+      RowInfo[RowIndex].EndIndex       = Index;\r
+      RowInfo[RowIndex].LineWidth      = LineWidth;\r
+      RowInfo[RowIndex].LineHeight     = LineHeight;\r
+      RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
+    } else {\r
       //\r
-      // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
+      // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
+      // if its right-most on pixel cannot fit.\r
       //\r
-      if (LineWidth + BltX <= Image->Width ||\r
-          (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLEAN_X) == 0)) {\r
+      if (Index > RowInfo[RowIndex].StartIndex) {\r
         //\r
-        // Record right-most character in RowInfo even if it is partially displayed.\r
+        // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
         //\r
-        RowInfo[RowIndex].EndIndex       = Index;\r
+        LineWidth                       -= (Cell[Index].Width + Cell[Index].OffsetX);\r
+        LineWidth                       -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);\r
+        RowInfo[RowIndex].EndIndex       = Index - 1;\r
         RowInfo[RowIndex].LineWidth      = LineWidth;\r
         RowInfo[RowIndex].LineHeight     = LineHeight;\r
         RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
       } else {\r
         //\r
-        // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
-        // if its right-most on pixel cannot fit.\r
+        // There is no enough column to draw any character, so set current line width to zero.\r
+        // And go to draw Next line if LineBreak is set.\r
         //\r
-        if (Index > 0) {\r
-          RowInfo[RowIndex].EndIndex       = Index - 1;\r
-          RowInfo[RowIndex].LineWidth      = LineWidth - Cell[Index].AdvanceX;\r
-          RowInfo[RowIndex].BaselineOffset = BaseLineOffset - Cell[Index].OffsetY;\r
-          if (LineHeight > Cell[Index - 1].Height) {\r
-            LineHeight = Cell[Index - 1].Height;\r
+        RowInfo[RowIndex].LineWidth = 0;\r
+        goto NextLine;\r
+      }\r
+    }\r
+\r
+    //\r
+    // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break\r
+    // opportunity prior to a character whose right-most extent would exceed Width.\r
+    // Search the right-most line-break opportunity here.\r
+    //\r
+    if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&\r
+        ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&\r
+        !LineBreak)\r
+    {\r
+      if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {\r
+        LineWidth = RowInfo[RowIndex].LineWidth;\r
+        for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {\r
+          if (Index1 == RowInfo[RowIndex].EndIndex) {\r
+            LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
+          } else {\r
+            LineWidth -= Cell[Index1].AdvanceX;\r
           }\r
-          RowInfo[RowIndex].LineHeight     = LineHeight;\r
-        } else {\r
+\r
+          if (IsLineBreak (StringPtr[Index1]) > 0) {\r
+            LineBreak = TRUE;\r
+            if (Index1 > RowInfo[RowIndex].StartIndex) {\r
+              RowInfo[RowIndex].EndIndex = Index1 - 1;\r
+            }\r
+\r
+            //\r
+            // relocate to the character after the right-most line break opportunity of this line\r
+            //\r
+            NextIndex = Index1 + 1;\r
+            break;\r
+          }\r
+\r
           //\r
-          // There is only one column and it can not be drawn so that return directly.\r
+          // If don't find a line break opportunity from EndIndex to StartIndex,\r
+          // then jump out.\r
           //\r
-          Status = EFI_SUCCESS;\r
-          goto Exit;\r
+          if (Index1 == RowInfo[RowIndex].StartIndex) {\r
+            break;\r
+          }\r
+        }\r
+\r
+        //\r
+        // Update LineWidth to the real width\r
+        //\r
+        if (IsLineBreak (StringPtr[Index1]) > 0) {\r
+          if (Index1 == RowInfo[RowIndex].StartIndex) {\r
+            LineWidth = 0;\r
+          } else {\r
+            LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
+          }\r
+\r
+          RowInfo[RowIndex].LineWidth = LineWidth;\r
         }\r
       }\r
 \r
       //\r
-      // Clip the final row if the row's bottom-most on pixel cannot fit when\r
-      // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
+      // If no line-break opportunity can be found, then the text will\r
+      // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
       //\r
-      if (RowIndex == MaxRowNum - 1 && Image->Height < LineHeight) {\r
-        LineHeight = Image->Height;\r
-        if ((Flags & EFI_HII_OUT_FLAG_CLEAN_Y) == EFI_HII_OUT_FLAG_CLEAN_Y) {\r
-          //\r
-          // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
-          //\r
-          break;\r
+      if (!LineBreak) {\r
+        LineWidth = RowInfo[RowIndex].LineWidth;\r
+        Index1    = RowInfo[RowIndex].EndIndex;\r
+        if (LineWidth + BltX > Image->Width) {\r
+          if (Index1 > RowInfo[RowIndex].StartIndex) {\r
+            //\r
+            // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
+            //\r
+            LineWidth                  -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
+            LineWidth                  -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
+            RowInfo[RowIndex].EndIndex  = Index1 - 1;\r
+            RowInfo[RowIndex].LineWidth = LineWidth;\r
+          } else {\r
+            //\r
+            // There is no enough column to draw any character, so set current line width to zero.\r
+            // And go to draw Next line if LineBreak is set.\r
+            //\r
+            RowInfo[RowIndex].LineWidth = 0;\r
+            goto NextLine;\r
+          }\r
         }\r
       }\r
+    }\r
 \r
-      //\r
-      // Draw it to screen or existing bitmap depending on whether\r
-      // EFI_HII_DIRECT_TO_SCREEN is set.\r
-      //\r
-      if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
-        BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    //\r
+    // LineWidth can't exceed Image width.\r
+    //\r
+    if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {\r
+      RowInfo[RowIndex].LineWidth = Image->Width - BltX;\r
+    }\r
+\r
+    //\r
+    // Draw it to screen or existing bitmap depending on whether\r
+    // EFI_HII_DIRECT_TO_SCREEN is set.\r
+    //\r
+    LineOffset = 0;\r
+    if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
+      BltBuffer = NULL;\r
+      if (RowInfo[RowIndex].LineWidth != 0) {\r
+        BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
         if (BltBuffer == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Exit;\r
         }\r
-        BufferPtr = BltBuffer;\r
-        for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+\r
+        //\r
+        // Initialize the background color.\r
+        //\r
+        PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;\r
+        SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);\r
+        //\r
+        // Set BufferPtr to Origin by adding baseline to the starting position.\r
+        //\r
+        BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;\r
+      }\r
+\r
+      for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {\r
+          //\r
+          // Only BLT these character which have corresponding glyph in font database.\r
+          //\r
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
             Background,\r
-            RowInfo[RowIndex].LineWidth,\r
+            (UINT16)RowInfo[RowIndex].LineWidth,\r
+            BaseLine,\r
+            RowInfo[RowIndex].LineWidth - LineOffset,\r
             RowInfo[RowIndex].LineHeight,\r
             Transparent,\r
             &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
             );\r
-          if (ColumnInfoArray != NULL) {\r
-            if (Index1 == RowInfo[RowIndex].StartIndex) {\r
-              *ColumnInfoArray = 0;\r
-            } else {\r
-              *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
-            }\r
-            ColumnInfoArray++;\r
+        }\r
+\r
+        if (ColumnInfoArray != NULL) {\r
+          if (  ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))\r
+             || (RowInfo[RowIndex].LineWidth == 0))\r
+          {\r
+            *ColumnInfoArray = (UINTN) ~0;\r
+          } else {\r
+            *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
           }\r
+\r
+          ColumnInfoArray++;\r
         }\r
+\r
+        LineOffset += Cell[Index1].AdvanceX;\r
+      }\r
+\r
+      if (BltBuffer != NULL) {\r
         Status = Image->Image.Screen->Blt (\r
                                         Image->Image.Screen,\r
                                         BltBuffer,\r
@@ -1802,120 +2189,150 @@ HiiStringToImage (
                                         0\r
                                         );\r
         if (EFI_ERROR (Status)) {\r
-          SafeFreePool (BltBuffer);\r
+          FreePool (BltBuffer);\r
           goto Exit;\r
         }\r
 \r
-        SafeFreePool (BltBuffer);\r
-\r
-      } else {\r
-        for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        FreePool (BltBuffer);\r
+      }\r
+    } else {\r
+      //\r
+      // Save the starting position for calculate the starting position of next row.\r
+      //\r
+      RowBufferPtr = BufferPtr;\r
+      //\r
+      // Set BufferPtr to Origin by adding baseline to the starting position.\r
+      //\r
+      BufferPtr = BufferPtr + BaseLine * Image->Width;\r
+      for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {\r
+          //\r
+          // Only BLT these character which have corresponding glyph in font database.\r
+          //\r
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
             Background,\r
             Image->Width,\r
-            Image->Height,\r
+            BaseLine,\r
+            RowInfo[RowIndex].LineWidth - LineOffset,\r
+            RowInfo[RowIndex].LineHeight,\r
             Transparent,\r
             &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
             );\r
-          if (ColumnInfoArray != NULL) {\r
-            if (Index1 == RowInfo[RowIndex].StartIndex) {\r
-              *ColumnInfoArray = 0;\r
-            } else {\r
-              *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
-            }\r
-            ColumnInfoArray++;\r
+        }\r
+\r
+        if (ColumnInfoArray != NULL) {\r
+          if (  ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))\r
+             || (RowInfo[RowIndex].LineWidth == 0))\r
+          {\r
+            *ColumnInfoArray = (UINTN) ~0;\r
+          } else {\r
+            *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
           }\r
+\r
+          ColumnInfoArray++;\r
         }\r
-        //\r
-        // Jump to next row\r
-        //\r
-        BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
-      }\r
 \r
-      Index++;\r
-      RowIndex++;\r
+        LineOffset += Cell[Index1].AdvanceX;\r
+      }\r
 \r
+      //\r
+      // Jump to starting position of next row.\r
+      //\r
+      if (RowIndex == 0) {\r
+        BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;\r
+      } else {\r
+        BufferPtr = RowBufferPtr + LineHeight * Image->Width;\r
+      }\r
     }\r
 \r
+NextLine:\r
     //\r
-    // Write output parameters.\r
+    // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down\r
     //\r
-    RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
-    if (RowInfoArray != NULL) {\r
+    BltY += RowInfo[RowIndex].LineHeight;\r
+\r
+    RowIndex++;\r
+    Index = NextIndex;\r
+\r
+    if (!LineBreak) {\r
+      //\r
+      // If there is not a mandatory line break or line break opportunity, only render one line to image\r
+      //\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Write output parameters.\r
+  //\r
+  RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
+  if (RowInfoArray != NULL) {\r
+    if (RowInfoSize > 0) {\r
       *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
       if (*RowInfoArray == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Exit;\r
       }\r
+\r
       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
+    } else {\r
+      *RowInfoArray = NULL;\r
     }\r
-    if (RowInfoArraySize != NULL) {\r
-      *RowInfoArraySize = RowIndex;\r
-    }\r
+  }\r
 \r
-  } else {\r
-    //\r
-    // Create a new bitmap and draw the string onto this image.\r
-    //\r
-    Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
-    if (Image == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    Image->Width  = 800;\r
-    Image->Height = 600;\r
-    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-    if (Image->Image.Bitmap == NULL) {\r
-      SafeFreePool (Image);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
+  if (RowInfoArraySize != NULL) {\r
+    *RowInfoArraySize = RowIndex;\r
+  }\r
 \r
-    //\r
-    // Other flags are not permitted when Blt is NULL.\r
-    //\r
-    Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
-    Status = HiiStringToImage (\r
-               This,\r
-               Flags,\r
-               String,\r
-               StringInfo,\r
-               &Image,\r
-               BltX,\r
-               BltY,\r
-               RowInfoArray,\r
-               RowInfoArraySize,\r
-               ColumnInfoArray\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+\r
+  for (Index = 0; Index < StrLength; Index++) {\r
+    if (GlyphBuf[Index] != NULL) {\r
+      FreePool (GlyphBuf[Index]);\r
     }\r
+  }\r
 \r
-    *Blt = Image;\r
+  if (StringIn != NULL) {\r
+    FreePool (StringIn);\r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
+  if (StringIn2 != NULL) {\r
+    FreePool (StringIn2);\r
+  }\r
 \r
-Exit:\r
+  if (StringInfoOut != NULL) {\r
+    FreePool (StringInfoOut);\r
+  }\r
+\r
+  if (RowInfo != NULL) {\r
+    FreePool (RowInfo);\r
+  }\r
+\r
+  if (SystemDefault != NULL) {\r
+    FreePool (SystemDefault);\r
+  }\r
+\r
+  if (GlyphBuf != NULL) {\r
+    FreePool (GlyphBuf);\r
+  }\r
+\r
+  if (Cell != NULL) {\r
+    FreePool (Cell);\r
+  }\r
 \r
-  for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {\r
-    SafeFreePool (GlyphBuf[Index]);\r
+  if (Attributes != NULL) {\r
+    FreePool (Attributes);\r
   }\r
-  SafeFreePool (StringIn);\r
-  SafeFreePool (StringIn2);\r
-  SafeFreePool (StringInfoOut);\r
-  SafeFreePool (RowInfo);\r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (GlyphBuf);\r
-  SafeFreePool (Cell);\r
-  SafeFreePool (Attributes);\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Render a string to a bitmap or the screen containing the contents of the specified string.\r
 \r
@@ -1941,7 +2358,10 @@ Exit:
                                   will be allocated to hold the generated image and\r
                                   the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\r
-  @param  BltX,BLTY               Specifies the offset from the left and top edge\r
+  @param  BltX                    Specifies the offset from the left and top edge\r
+                                  of the image of the first character cell in the\r
+                                  image.\r
+  @param  BltY                    Specifies the offset from the left and top edge\r
                                   of the image of the first character cell in the\r
                                   image.\r
   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this\r
@@ -1965,35 +2385,48 @@ Exit:
                                   when character display is normalized that some\r
                                   character cells overlap.\r
 \r
-  @retval EFI_SUCCESS             The string was successfully rendered.\r
-  @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for\r
-                                  RowInfoArray or Blt.\r
-  @retval EFI_INVALID_PARAMETER   The PackageList was NULL.\r
+  @retval EFI_SUCCESS            The string was successfully rendered.\r
+  @retval EFI_OUT_OF_RESOURCES   Unable to allocate an output buffer for\r
+                                 RowInfoArray or Blt.\r
+  @retval EFI_INVALID_PARAMETER  The Blt or PackageList was NULL.\r
+  @retval EFI_INVALID_PARAMETER  Flags were invalid combination.\r
+  @retval EFI_NOT_FOUND          The specified PackageList is not in the Database or the string id is not\r
+                                 in the specified PackageList.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 HiiStringIdToImage (\r
-  IN  CONST EFI_HII_FONT_PROTOCOL    *This,\r
-  IN  EFI_HII_OUT_FLAGS              Flags,\r
-  IN  EFI_HII_HANDLE                 PackageList,\r
-  IN  EFI_STRING_ID                  StringId,\r
-  IN  CONST CHAR8*                   Language,\r
-  IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo       OPTIONAL,\r
-  IN  OUT EFI_IMAGE_OUTPUT           **Blt,\r
-  IN  UINTN                          BltX,\r
-  IN  UINTN                          BltY,\r
-  OUT EFI_HII_ROW_INFO               **RowInfoArray    OPTIONAL,\r
-  OUT UINTN                          *RowInfoArraySize OPTIONAL,\r
-  OUT UINTN                          *ColumnInfoArray  OPTIONAL\r
+  IN  CONST EFI_HII_FONT_PROTOCOL  *This,\r
+  IN  EFI_HII_OUT_FLAGS            Flags,\r
+  IN  EFI_HII_HANDLE               PackageList,\r
+  IN  EFI_STRING_ID                StringId,\r
+  IN  CONST CHAR8                  *Language,\r
+  IN  CONST EFI_FONT_DISPLAY_INFO  *StringInfo       OPTIONAL,\r
+  IN  OUT EFI_IMAGE_OUTPUT         **Blt,\r
+  IN  UINTN                        BltX,\r
+  IN  UINTN                        BltY,\r
+  OUT EFI_HII_ROW_INFO             **RowInfoArray    OPTIONAL,\r
+  OUT UINTN                        *RowInfoArraySize OPTIONAL,\r
+  OUT UINTN                        *ColumnInfoArray  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
-  HII_DATABASE_PRIVATE_DATA           *Private;\r
-  EFI_STRING                          String;\r
-  UINTN                               StringSize;\r
-\r
-  if (This == NULL || PackageList == NULL || Blt == NULL || PackageList == NULL) {\r
+  EFI_STATUS                 Status;\r
+  HII_DATABASE_PRIVATE_DATA  *Private;\r
+  EFI_HII_STRING_PROTOCOL    *HiiString;\r
+  EFI_STRING                 String;\r
+  UINTN                      StringSize;\r
+  UINTN                      FontLen;\r
+  UINTN                      NameSize;\r
+  EFI_FONT_INFO              *StringFontInfo;\r
+  EFI_FONT_DISPLAY_INFO      *NewStringInfo;\r
+  CHAR8                      TempSupportedLanguages;\r
+  CHAR8                      *SupportedLanguages;\r
+  UINTN                      SupportedLanguagesSize;\r
+  CHAR8                      *CurrentLanguage;\r
+  CHAR8                      *BestLanguage;\r
+\r
+  if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -2001,65 +2434,182 @@ HiiStringIdToImage (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  //\r
+  // Initialize string pointers to be NULL\r
+  //\r
+  SupportedLanguages = NULL;\r
+  CurrentLanguage    = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
+  StringFontInfo     = NULL;\r
+  NewStringInfo      = NULL;\r
 \r
   //\r
   // Get the string to be displayed.\r
   //\r
+  Private   = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  HiiString = &Private->HiiString;\r
+\r
+  //\r
+  // Get the size of supported language.\r
+  //\r
+  SupportedLanguagesSize = 0;\r
+  Status                 = HiiString->GetLanguages (\r
+                                        HiiString,\r
+                                        PackageList,\r
+                                        &TempSupportedLanguages,\r
+                                        &SupportedLanguagesSize\r
+                                        );\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return Status;\r
+  }\r
+\r
+  SupportedLanguages = AllocatePool (SupportedLanguagesSize);\r
+  if (SupportedLanguages == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = HiiString->GetLanguages (\r
+                        HiiString,\r
+                        PackageList,\r
+                        SupportedLanguages,\r
+                        &SupportedLanguagesSize\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  if (Language == NULL) {\r
+    Language = "";\r
+  }\r
+\r
+  GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);\r
+  BestLanguage = GetBestLanguage (\r
+                   SupportedLanguages,\r
+                   FALSE,\r
+                   Language,\r
+                   (CurrentLanguage == NULL) ? CurrentLanguage : "",\r
+                   (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
+                   NULL\r
+                   );\r
+  if (BestLanguage == NULL) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Exit;\r
+  }\r
 \r
   StringSize = MAX_STRING_LENGTH;\r
-  String = (EFI_STRING) AllocateZeroPool (StringSize);\r
+  String     = (EFI_STRING)AllocateZeroPool (StringSize);\r
   if (String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
   }\r
 \r
-  Status = Private->HiiString.GetString (\r
-                                &Private->HiiString,\r
-                                Language,\r
-                                PackageList,\r
-                                StringId,\r
-                                String,\r
-                                &StringSize,\r
-                                NULL\r
-                                );\r
+  Status = HiiString->GetString (\r
+                        HiiString,\r
+                        BestLanguage,\r
+                        PackageList,\r
+                        StringId,\r
+                        String,\r
+                        &StringSize,\r
+                        &StringFontInfo\r
+                        );\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    SafeFreePool (String);\r
-    String = (EFI_STRING) AllocateZeroPool (StringSize);\r
+    FreePool (String);\r
+    String = (EFI_STRING)AllocateZeroPool (StringSize);\r
     if (String == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
     }\r
-    Status = Private->HiiString.GetString (\r
-                                  &Private->HiiString,\r
-                                  Language,\r
-                                  PackageList,\r
-                                  StringId,\r
-                                  String,\r
-                                  &StringSize,\r
-                                  NULL\r
-                                  );\r
 \r
+    Status = HiiString->GetString (\r
+                          HiiString,\r
+                          BestLanguage,\r
+                          PackageList,\r
+                          StringId,\r
+                          String,\r
+                          &StringSize,\r
+                          NULL\r
+                          );\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    SafeFreePool (String);\r
-    return Status;\r
+    goto Exit;\r
   }\r
 \r
-  return HiiStringToImage (\r
-           This,\r
-           Flags,\r
-           String,\r
-           StringInfo,\r
-           Blt,\r
-           BltX,\r
-           BltY,\r
-           RowInfoArray,\r
-           RowInfoArraySize,\r
-           ColumnInfoArray\r
-           );\r
+  //\r
+  // When StringInfo specifies that string will be output in the system default font and color,\r
+  // use particular stringfontinfo described in string package instead if exists.\r
+  // StringFontInfo equals NULL means system default font attaches with the string block.\r
+  //\r
+  if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {\r
+    NameSize      = StrSize (StringFontInfo->FontName);\r
+    FontLen       = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
+    NewStringInfo = AllocateZeroPool (FontLen);\r
+    if (NewStringInfo == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
+\r
+    NewStringInfo->FontInfoMask       = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;\r
+    NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;\r
+    NewStringInfo->FontInfo.FontSize  = StringFontInfo->FontSize;\r
+    StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);\r
 \r
-}\r
+    Status = HiiStringToImage (\r
+               This,\r
+               Flags,\r
+               String,\r
+               NewStringInfo,\r
+               Blt,\r
+               BltX,\r
+               BltY,\r
+               RowInfoArray,\r
+               RowInfoArraySize,\r
+               ColumnInfoArray\r
+               );\r
+    goto Exit;\r
+  }\r
+\r
+  Status = HiiStringToImage (\r
+             This,\r
+             Flags,\r
+             String,\r
+             StringInfo,\r
+             Blt,\r
+             BltX,\r
+             BltY,\r
+             RowInfoArray,\r
+             RowInfoArraySize,\r
+             ColumnInfoArray\r
+             );\r
+\r
+Exit:\r
+  if (SupportedLanguages != NULL) {\r
+    FreePool (SupportedLanguages);\r
+  }\r
+\r
+  if (CurrentLanguage != NULL) {\r
+    FreePool (CurrentLanguage);\r
+  }\r
+\r
+  if (BestLanguage != NULL) {\r
+    FreePool (BestLanguage);\r
+  }\r
+\r
+  if (String != NULL) {\r
+    FreePool (String);\r
+  }\r
 \r
+  if (StringFontInfo != NULL) {\r
+    FreePool (StringFontInfo);\r
+  }\r
+\r
+  if (NewStringInfo != NULL) {\r
+    FreePool (NewStringInfo);\r
+  }\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Convert the glyph for a single character into a bitmap.\r
@@ -2086,30 +2636,31 @@ HiiStringIdToImage (
 EFI_STATUS\r
 EFIAPI\r
 HiiGetGlyph (\r
-  IN  CONST EFI_HII_FONT_PROTOCOL    *This,\r
-  IN  CHAR16                         Char,\r
-  IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfo,\r
-  OUT EFI_IMAGE_OUTPUT               **Blt,\r
-  OUT UINTN                          *Baseline OPTIONAL\r
+  IN  CONST EFI_HII_FONT_PROTOCOL  *This,\r
+  IN  CHAR16                       Char,\r
+  IN  CONST EFI_FONT_DISPLAY_INFO  *StringInfo,\r
+  OUT EFI_IMAGE_OUTPUT             **Blt,\r
+  OUT UINTN                        *Baseline OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS                         Status;\r
-  HII_DATABASE_PRIVATE_DATA          *Private;\r
-  EFI_IMAGE_OUTPUT                   *Image;\r
-  UINT8                              *GlyphBuffer;\r
-  EFI_FONT_DISPLAY_INFO              *SystemDefault;\r
-  EFI_FONT_DISPLAY_INFO              *StringInfoOut;\r
-  BOOLEAN                            Default;\r
-  EFI_FONT_HANDLE                    FontHandle;\r
-  EFI_STRING                         String;\r
-  EFI_HII_GLYPH_INFO                 Cell;\r
-  EFI_FONT_INFO                      *FontInfo;\r
-  UINT8                              Attributes;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Foreground;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      Background;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL      *BltBuffer;\r
-\r
-  if (This == NULL || Blt == NULL || *Blt != NULL) {\r
+  EFI_STATUS                     Status;\r
+  HII_DATABASE_PRIVATE_DATA      *Private;\r
+  EFI_IMAGE_OUTPUT               *Image;\r
+  UINT8                          *GlyphBuffer;\r
+  EFI_FONT_DISPLAY_INFO          *SystemDefault;\r
+  EFI_FONT_DISPLAY_INFO          *StringInfoOut;\r
+  BOOLEAN                        Default;\r
+  EFI_FONT_HANDLE                FontHandle;\r
+  EFI_STRING                     String;\r
+  EFI_HII_GLYPH_INFO             Cell;\r
+  EFI_FONT_INFO                  *FontInfo;\r
+  UINT8                          Attributes;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Foreground;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Background;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer;\r
+  UINT16                         BaseLine;\r
+\r
+  if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -2127,29 +2678,33 @@ HiiGetGlyph (
   ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
   ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
 \r
-  Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
+  Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);\r
 \r
   if (!Default) {\r
     //\r
     // Find out a EFI_FONT_DISPLAY_INFO which could display the character in\r
     // the specified color and font.\r
     //\r
-    String = (EFI_STRING) AllocateZeroPool (sizeof (CHAR16) * 2);\r
+    String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);\r
     if (String == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
-    *String = Char;\r
+\r
+    *String       = Char;\r
     *(String + 1) = 0;\r
 \r
     Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);\r
     if (EFI_ERROR (Status)) {\r
       goto Exit;\r
     }\r
+\r
+    ASSERT (StringInfoOut != NULL);\r
     FontInfo   = &StringInfoOut->FontInfo;\r
     Foreground = StringInfoOut->ForegroundColor;\r
     Background = StringInfoOut->BackgroundColor;\r
   } else {\r
+    ASSERT (SystemDefault != NULL);\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
   }\r
@@ -2159,33 +2714,45 @@ HiiGetGlyph (
     goto Exit;\r
   }\r
 \r
-  Image = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
+  Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
   if (Image == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
-  Image->Width   = Cell.Width;\r
-  Image->Height  = Cell.Height;\r
 \r
-  Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-  if (Image->Image.Bitmap == NULL) {\r
-    SafeFreePool (Image);\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
+  Image->Width  = Cell.Width;\r
+  Image->Height = Cell.Height;\r
+\r
+  if (Image->Width * Image->Height > 0) {\r
+    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    if (Image->Image.Bitmap == NULL) {\r
+      FreePool (Image);\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
 \r
-  BltBuffer = Image->Image.Bitmap;\r
-  GlyphToImage (\r
-    GlyphBuffer,\r
-    Foreground,\r
-    Background,\r
-    Image->Width,\r
-    Image->Height,\r
-    FALSE,\r
-    &Cell,\r
-    Attributes,\r
-    &BltBuffer\r
-    );\r
+    //\r
+    // Set BaseLine to the char height.\r
+    //\r
+    BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);\r
+    //\r
+    // Set BltBuffer to the position of Origin.\r
+    //\r
+    BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;\r
+    GlyphToImage (\r
+      GlyphBuffer,\r
+      Foreground,\r
+      Background,\r
+      Image->Width,\r
+      BaseLine,\r
+      Cell.Width + Cell.OffsetX,\r
+      BaseLine - Cell.OffsetY,\r
+      FALSE,\r
+      &Cell,\r
+      Attributes,\r
+      &BltBuffer\r
+      );\r
+  }\r
 \r
   *Blt = Image;\r
   if (Baseline != NULL) {\r
@@ -2210,15 +2777,25 @@ Exit:
     }\r
   }\r
 \r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (StringInfoOut);\r
-  SafeFreePool (String);\r
-  SafeFreePool (GlyphBuffer);\r
+  if (SystemDefault != NULL) {\r
+    FreePool (SystemDefault);\r
+  }\r
+\r
+  if (StringInfoOut != NULL) {\r
+    FreePool (StringInfoOut);\r
+  }\r
+\r
+  if (String != NULL) {\r
+    FreePool (String);\r
+  }\r
+\r
+  if (GlyphBuffer != NULL) {\r
+    FreePool (GlyphBuffer);\r
+  }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function iterates through fonts which match the specified font, using\r
   the specified criteria. If String is non-NULL, then all of the characters in\r
@@ -2230,19 +2807,22 @@ Exit:
                                   with the  first font. On return, points to the\r
                                   returned font handle or points to NULL if there\r
                                   are no more matching fonts.\r
-  @param  StringInfoIn            Upon entry, points to the font to return\r
-                                  information about.\r
-  @param  StringInfoOut           Upon return, contains the matching font's\r
-                                  information.  If NULL, then no information is\r
-                                  returned. It's caller's responsibility to free\r
-                                  this buffer.\r
+  @param  StringInfoIn            Upon entry, points to the font to return information\r
+                                  about. If NULL, then the information about the system\r
+                                  default font will be returned.\r
+  @param  StringInfoOut           Upon return, contains the matching font's information.\r
+                                  If NULL, then no information is returned. This buffer\r
+                                  is allocated with a call to the Boot Service AllocatePool().\r
+                                  It is the caller's responsibility to call the Boot\r
+                                  Service FreePool() when the caller no longer requires\r
+                                  the contents of StringInfoOut.\r
   @param  String                  Points to the string which will be tested to\r
                                   determine  if all characters are available. If\r
                                   NULL, then any font  is acceptable.\r
 \r
   @retval EFI_SUCCESS             Matching font returned successfully.\r
   @retval EFI_NOT_FOUND           No matching font was found.\r
-  @retval EFI_INVALID_PARAMETER   StringInfoIn is NULL.\r
+  @retval EFI_INVALID_PARAMETER  StringInfoIn->FontInfoMask is an invalid combination.\r
   @retval EFI_OUT_OF_RESOURCES    There were insufficient resources to complete the\r
                                   request.\r
 \r
@@ -2250,27 +2830,79 @@ Exit:
 EFI_STATUS\r
 EFIAPI\r
 HiiGetFontInfo (\r
-  IN  CONST EFI_HII_FONT_PROTOCOL    *This,\r
-  IN  OUT   EFI_FONT_HANDLE          *FontHandle,\r
-  IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfoIn,\r
-  OUT       EFI_FONT_DISPLAY_INFO    **StringInfoOut,\r
-  IN  CONST EFI_STRING               String OPTIONAL\r
+  IN  CONST EFI_HII_FONT_PROTOCOL  *This,\r
+  IN  OUT   EFI_FONT_HANDLE        *FontHandle,\r
+  IN  CONST EFI_FONT_DISPLAY_INFO  *StringInfoIn  OPTIONAL,\r
+  OUT       EFI_FONT_DISPLAY_INFO  **StringInfoOut,\r
+  IN  CONST EFI_STRING             String OPTIONAL\r
   )\r
 {\r
-  HII_DATABASE_PRIVATE_DATA          *Private;\r
-  EFI_STATUS                         Status;\r
-  EFI_FONT_DISPLAY_INFO              *SystemDefault;\r
-  EFI_FONT_DISPLAY_INFO              InfoOut;\r
-  UINTN                              StringInfoOutLen;\r
-  EFI_FONT_INFO                      *FontInfo;\r
-  HII_GLOBAL_FONT_INFO               *GlobalFont;\r
-  EFI_STRING                         StringIn;\r
-  EFI_FONT_HANDLE                    LocalFontHandle;\r
-\r
-  if (This == NULL || StringInfoIn == NULL) {\r
+  HII_DATABASE_PRIVATE_DATA  *Private;\r
+  EFI_STATUS                 Status;\r
+  EFI_FONT_DISPLAY_INFO      *SystemDefault;\r
+  EFI_FONT_DISPLAY_INFO      InfoOut;\r
+  UINTN                      StringInfoOutLen;\r
+  EFI_FONT_INFO              *FontInfo;\r
+  HII_GLOBAL_FONT_INFO       *GlobalFont;\r
+  EFI_STRING                 StringIn;\r
+  EFI_FONT_HANDLE            LocalFontHandle;\r
+\r
+  if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  StringInfoOutLen = 0;\r
+  FontInfo         = NULL;\r
+  SystemDefault    = NULL;\r
+  LocalFontHandle  = NULL;\r
+  if (FontHandle != NULL) {\r
+    LocalFontHandle = *FontHandle;\r
+  }\r
+\r
+  Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  //\r
+  // Already searched to the end of the whole list, return directly.\r
+  //\r
+  if (LocalFontHandle == &Private->FontInfoList) {\r
+    LocalFontHandle = NULL;\r
+    Status          = EFI_NOT_FOUND;\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Get default system display info, if StringInfoIn points to\r
+  // system display info, return it directly.\r
+  //\r
+  if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {\r
+    //\r
+    // System font is the first node. When handle is not NULL, system font can not\r
+    // be found any more.\r
+    //\r
+    if (LocalFontHandle == NULL) {\r
+      if (StringInfoOut != NULL) {\r
+        *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);\r
+        if (*StringInfoOut == NULL) {\r
+          Status          = EFI_OUT_OF_RESOURCES;\r
+          LocalFontHandle = NULL;\r
+          goto Exit;\r
+        }\r
+      }\r
+\r
+      LocalFontHandle = Private->FontInfoList.ForwardLink;\r
+      Status          = EFI_SUCCESS;\r
+      goto Exit;\r
+    } else {\r
+      LocalFontHandle = NULL;\r
+      Status          = EFI_NOT_FOUND;\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  //\r
+  // StringInfoIn must not be NULL if it is not system default font info.\r
+  //\r
+  ASSERT (StringInfoIn != NULL);\r
   //\r
   // Check the font information mask to make sure it is valid.\r
   //\r
@@ -2283,70 +2915,52 @@ HiiGetFontInfo (
       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE    | EFI_FONT_INFO_ANY_SIZE))  ==\r
        (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE))     ||\r
       ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE   | EFI_FONT_INFO_ANY_STYLE)) ==\r
-       (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {\r
+       (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  FontInfo        = NULL;\r
-  LocalFontHandle = NULL;\r
-  if (FontHandle != NULL) {\r
-    LocalFontHandle = *FontHandle;\r
-  }\r
-\r
-  //\r
-  // Get default system display info, if StringInfoIn points to\r
-  // system display info, return it directly.\r
-  //\r
-  Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, &SystemDefault, &StringInfoOutLen)) {\r
-    if (StringInfoOut != NULL) {\r
-      *StringInfoOut = AllocateCopyPool (StringInfoOutLen, (EFI_FONT_DISPLAY_INFO *) StringInfoIn);\r
-      if (*StringInfoOut == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        LocalFontHandle = NULL;\r
-        goto Exit;\r
-      }\r
-    }\r
-\r
-    LocalFontHandle = Private->FontInfoList.ForwardLink;\r
-    Status = EFI_SUCCESS;\r
-    goto Exit;\r
-  }\r
-\r
   //\r
   // Parse the font information mask to find a matching font.\r
   //\r
 \r
-  CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));\r
+  CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));\r
 \r
   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {\r
     Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);\r
   } else {\r
-    Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *) StringInfoIn)->FontInfo.FontName, &FontInfo);\r
+    Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);\r
   }\r
+\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {\r
     InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;\r
-  } else if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
+  }\r
+\r
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
     InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
-  } else if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
+  }\r
+\r
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
     InfoOut.ForegroundColor = SystemDefault->ForegroundColor;\r
-  } else if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
+  }\r
+\r
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
     InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
   }\r
 \r
+  ASSERT (FontInfo != NULL);\r
   FontInfo->FontSize  = InfoOut.FontInfo.FontSize;\r
   FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
 \r
   if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
+    //\r
+    // Test to guarantee all characters are available in the found font.\r
+    //\r
     if (String != NULL) {\r
-      //\r
-      // Test to guarantee all characters are available in the found font.\r
-      //\r
       StringIn = String;\r
       while (*StringIn != 0) {\r
         Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);\r
@@ -2354,30 +2968,30 @@ HiiGetFontInfo (
           LocalFontHandle = NULL;\r
           goto Exit;\r
         }\r
+\r
         StringIn++;\r
       }\r
+    }\r
 \r
-      //\r
-      // Write to output parameter\r
-      //\r
-      if (StringInfoOut != NULL) {\r
-        StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
-        *StringInfoOut   = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);\r
-        if (*StringInfoOut == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          LocalFontHandle = NULL;\r
-          goto Exit;\r
-        }\r
-        CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
-        CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
+    //\r
+    // Write to output parameter\r
+    //\r
+    if (StringInfoOut != NULL) {\r
+      StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
+      *StringInfoOut   = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);\r
+      if (*StringInfoOut == NULL) {\r
+        Status          = EFI_OUT_OF_RESOURCES;\r
+        LocalFontHandle = NULL;\r
+        goto Exit;\r
       }\r
-      LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
 \r
-      Status = EFI_SUCCESS;\r
-      goto Exit;\r
+      CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
+      CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
     }\r
-  } else {\r
-    LocalFontHandle = NULL;\r
+\r
+    LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
+    Status          = EFI_SUCCESS;\r
+    goto Exit;\r
   }\r
 \r
   Status = EFI_NOT_FOUND;\r
@@ -2388,8 +3002,13 @@ Exit:
     *FontHandle = LocalFontHandle;\r
   }\r
 \r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (FontInfo);\r
+  if (SystemDefault != NULL) {\r
+    FreePool (SystemDefault);\r
+  }\r
+\r
+  if (FontInfo != NULL) {\r
+    FreePool (FontInfo);\r
+  }\r
+\r
   return Status;\r
 }\r
-\r