]> 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 a5363d43bd13f009597877d125e9ca28a321ef9e..399f90feb783bb578921941faeee3441c4de87d3 100644 (file)
@@ -1,56 +1,41 @@
 /** @file\r
 /** @file\r
+Implementation for EFI_HII_FONT_PROTOCOL.\r
 \r
 \r
-Copyright (c) 2007, 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
 \r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 **/\r
 \r
-\r
 #include "HiiDatabase.h"\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
   //\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
-\r
 /**\r
   Insert a character cell information to the list specified by GlyphInfoList.\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
   @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
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 NewCell (\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
   )\r
 {\r
-  HII_GLYPH_INFO           *GlyphInfo;\r
+  HII_GLYPH_INFO  *GlyphInfo;\r
 \r
   ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
 \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
   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
   //\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
   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
 /**\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
   @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
                                   not exist.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetCell (\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
   )\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
 \r
   ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
 \r
@@ -139,10 +127,11 @@ GetCell (
   return EFI_NOT_FOUND;\r
 }\r
 \r
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 /**\r
   Convert the glyph for a single character into a bitmap.\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
   @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
   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetGlyphBuffer (\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
   )\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
     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
     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
   // 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
       return EFI_INVALID_PARAMETER;\r
     }\r
+\r
     if (Attributes != NULL) {\r
       *Attributes = PROPORTIONAL_GLYPH;\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
     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
       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
         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
         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
           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
             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->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
             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
+\r
             return EFI_SUCCESS;\r
           }\r
         }\r
             return EFI_SUCCESS;\r
           }\r
         }\r
+\r
         //\r
         // Search the wide glyph array\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
         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
             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->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
             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
+\r
             return EFI_SUCCESS;\r
           }\r
         }\r
             return EFI_SUCCESS;\r
           }\r
         }\r
@@ -266,93 +261,144 @@ GetGlyphBuffer (
   return EFI_NOT_FOUND;\r
 }\r
 \r
   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
 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
   )\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
 \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
 \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
 \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
       } else {\r
         if (!Transparent) {\r
-          Buffer[Y * ImageWidth + (Width - X - 1)] = Background;\r
+          Buffer[Ypos * ImageWidth + Xpos] = Background;\r
         }\r
       }\r
     }\r
   }\r
 \r
         }\r
       }\r
     }\r
   }\r
 \r
-  *Origin = Buffer + Width;\r
+  *Origin = *Origin + EFI_GLYPH_WIDTH;\r
 }\r
 \r
 }\r
 \r
-\r
 /**\r
   Convert bitmap data of the glyph to blt structure.\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  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
   @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
                                   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
 \r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToBlt (\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     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
   )\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
 \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
 \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
 \r
   //\r
   // Since non-spacing key will be printed OR'd with the previous glyph, don't\r
@@ -366,61 +412,61 @@ GlyphToBlt (
   // The glyph's upper left hand corner pixel is the most significant bit of the\r
   // first bitmap byte.\r
   //\r
   // 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
 \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
         } 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
     }\r
 \r
           }\r
         }\r
       }\r
     }\r
 \r
-    if (Cell.Width % 8 != 0) {\r
+    if (Cell->Width % 8 != 0) {\r
       //\r
       // There are some padding bits in this byte. Ignore them.\r
       //\r
       //\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
         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
         } 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
           }\r
         }\r
       }\r
     } // end of if (Width % 8...)\r
+  } // end of for (Ypos=0...)\r
 \r
 \r
-  } // end of for (Y=0...)\r
-\r
-  *Origin = BltBuffer + Cell.Width;\r
+  *Origin = *Origin + Cell->AdvanceX;\r
 }\r
 \r
 }\r
 \r
-\r
 /**\r
   Convert bitmap data of the glyph to blt structure.\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  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
   @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
                                   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
   @return Points to the address of next origin node in BltBuffer.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToImage (\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     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
   )\r
 {\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *Buffer;\r
 \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
 \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
     // 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
     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
       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
   } 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
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
       Transparent,\r
       Origin\r
       );\r
@@ -490,11 +538,11 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\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
   } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {\r
     //\r
     // This character is narrow glyph, i.e. 8 pixels * 19 pixels.\r
@@ -504,21 +552,23 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
       Transparent,\r
       Origin\r
       );\r
-\r
   } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {\r
     //\r
   } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {\r
     //\r
-    // This character is proportional glyph, i.e. Cell.Width * Cell.Height pixels.\r
+    // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.\r
     //\r
     GlyphToBlt (\r
       GlyphBuffer,\r
       Foreground,\r
       Background,\r
       ImageWidth,\r
     //\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
       Transparent,\r
       Cell,\r
       Attributes,\r
@@ -527,17 +577,18 @@ GlyphToImage (
   }\r
 }\r
 \r
   }\r
 }\r
 \r
-\r
 /**\r
   Write the output parameters of FindGlyphBlock().\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
   @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
                                   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
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 WriteOutputParam (\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
   )\r
 {\r
-  if (BufferIn == NULL || BufferLen < 1 || InputCell == NULL) {\r
+  if ((BufferIn == NULL) || (InputCell == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -567,11 +617,12 @@ WriteOutputParam (
     CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));\r
   }\r
 \r
     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
     if (*GlyphBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
     CopyMem (*GlyphBuffer, BufferIn, BufferLen);\r
   }\r
 \r
     CopyMem (*GlyphBuffer, BufferIn, BufferLen);\r
   }\r
 \r
@@ -582,7 +633,6 @@ WriteOutputParam (
   return EFI_SUCCESS;\r
 }\r
 \r
   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
 /**\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
   @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
                                   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
 **/\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
   )\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
 \r
   ASSERT (FontPackage != NULL);\r
   ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);\r
+  BaseLine   = 0;\r
+  MinOffsetY = 0;\r
 \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
     //\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
     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
     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
   }\r
 \r
   BlockPtr    = FontPackage->GlyphBlock;\r
@@ -648,133 +708,159 @@ FindGlyphBlock (
 \r
   while (*BlockPtr != EFI_HII_GIBT_END) {\r
     switch (*BlockPtr) {\r
 \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
-      }\r
-      BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);\r
-      break;\r
 \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
 \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
 \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
 \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
 \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
           return WriteOutputParam (\r
-                   BlockPtr,\r
+                   (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),\r
                    BufferLen,\r
                    BufferLen,\r
-                   &Glyphs.Cell,\r
+                   &LocalCell,\r
                    GlyphBuffer,\r
                    Cell,\r
                    GlyphBufferLen\r
                    );\r
         }\r
                    GlyphBuffer,\r
                    Cell,\r
                    GlyphBufferLen\r
                    );\r
         }\r
-        BlockPtr += BufferLen;\r
-      }\r
-      CharCurrent = (UINT16) (CharCurrent + Glyphs.Count);\r
-      break;\r
 \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
 \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
           return WriteOutputParam (\r
-                   BlockPtr,\r
+                   BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
                    BufferLen,\r
                    &DefaultCell,\r
                    GlyphBuffer,\r
                    BufferLen,\r
                    &DefaultCell,\r
                    GlyphBuffer,\r
@@ -782,23 +868,60 @@ FindGlyphBlock (
                    GlyphBufferLen\r
                    );\r
         }\r
                    GlyphBufferLen\r
                    );\r
         }\r
-        BlockPtr += BufferLen;\r
-      }\r
-      CharCurrent = (UINT16) (CharCurrent + Length16);\r
-      break;\r
 \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
     }\r
 \r
     if (CharValue < CharCurrent) {\r
@@ -806,17 +929,20 @@ FindGlyphBlock (
     }\r
   }\r
 \r
     }\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
     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
 /**\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
   @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
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 SaveFontName (\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
   )\r
 {\r
-  UINTN         FontInfoLen;\r
+  UINTN  FontInfoLen;\r
+  UINTN  NameSize;\r
 \r
   ASSERT (FontName != NULL && FontInfo != NULL);\r
 \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
   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
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Retrieve system default font and color.\r
 \r
 /**\r
   Retrieve system default font and color.\r
 \r
@@ -865,17 +991,19 @@ SaveFontName (
 **/\r
 EFI_STATUS\r
 GetSystemFont (\r
 **/\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
   )\r
 {\r
-  EFI_FONT_DISPLAY_INFO              *Info;\r
-  UINTN                              InfoSize;\r
+  EFI_FONT_DISPLAY_INFO  *Info;\r
+  UINTN                  InfoSize;\r
+  UINTN                  NameSize;\r
 \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
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if (FontInfo == NULL) {\r
     return EFI_INVALID_PARAMETER;\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
   //\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
   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
   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
   *FontInfo = Info;\r
   if (FontInfoSize != NULL) {\r
     *FontInfoSize = InfoSize;\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\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
 \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
   @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
   @retval FALSE                   No.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 IsSystemFontInfo (\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
   )\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
 \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
     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
   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
   ASSERT_EFI_ERROR (Status);\r
+  ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));\r
 \r
 \r
+  //\r
+  // Record the system default info.\r
+  //\r
   if (SystemInfo != NULL) {\r
     *SystemInfo = SystemDefault;\r
   if (SystemInfo != NULL) {\r
     *SystemInfo = SystemDefault;\r
-  } else {\r
-    SafeFreePool (SystemDefault);\r
   }\r
 \r
   if (SystemInfoLen != NULL) {\r
     *SystemInfoLen = DefaultLen;\r
   }\r
 \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 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
 \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
 \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  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
                                   info.\r
 \r
   @retval TRUE                    Existed\r
@@ -989,32 +1173,32 @@ IsSystemFontInfo (
 **/\r
 BOOLEAN\r
 IsFontInfoExisted (\r
 **/\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
   )\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
 \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
   // 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
 \r
   Mask              = 0;\r
   GlobalFontBackup1 = NULL;\r
@@ -1034,16 +1218,17 @@ IsFontInfoExisted (
   if (FontHandle == NULL) {\r
     Link = Private->FontInfoList.ForwardLink;\r
   } else {\r
   if (FontHandle == NULL) {\r
     Link = Private->FontInfoList.ForwardLink;\r
   } else {\r
-    Link = (LIST_ENTRY     *) FontHandle;\r
+    Link = (LIST_ENTRY     *)FontHandle;\r
   }\r
 \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
     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
         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
       // 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
           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
           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
           } 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
             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
           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
           } 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
 \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
-        }\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
 \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
-        }\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
             if (GlobalFont->FontInfo->FontSize  == FontInfo->FontSize) {\r
-              Matched           = TRUE;\r
+              Matched = TRUE;\r
             } else {\r
               VagueMatched1     = TRUE;\r
               GlobalFontBackup1 = GlobalFont;\r
             }\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
               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
             } else {\r
-              VagueMatched2     = TRUE;\r
-              GlobalFontBackup2 = GlobalFont;\r
+              VagueMatched1     = TRUE;\r
+              GlobalFontBackup1 = GlobalFont;\r
             }\r
           }\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
 \r
       if (Matched) {\r
         if (GlobalFontInfo != NULL) {\r
           *GlobalFontInfo = GlobalFont;\r
         }\r
+\r
         return TRUE;\r
       }\r
     }\r
         return TRUE;\r
       }\r
     }\r
@@ -1262,96 +1471,100 @@ IsFontInfoExisted (
     if (GlobalFontInfo != NULL) {\r
       *GlobalFontInfo = GlobalFontBackup1;\r
     }\r
     if (GlobalFontInfo != NULL) {\r
       *GlobalFontInfo = GlobalFontBackup1;\r
     }\r
+\r
     return TRUE;\r
   } else if (VagueMatched2) {\r
     if (GlobalFontInfo != NULL) {\r
       *GlobalFontInfo = GlobalFontBackup2;\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
     return TRUE;\r
   }\r
 \r
   return FALSE;\r
 }\r
 \r
-\r
 /**\r
   Check whether the unicode represents a line break or not.\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
   @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
   @retval -1                      No, it is not a link break.\r
 \r
 **/\r
-STATIC\r
 INT8\r
 IsLineBreak (\r
 INT8\r
 IsLineBreak (\r
-  IN  CHAR16    Char\r
+  IN  CHAR16  Char\r
   )\r
 {\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
   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
       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 0x058A:\r
+    case 0x2010:\r
+    case 0x2012:\r
+    case 0x2013:\r
     case 0x0F0B:\r
     case 0x1361:\r
     case 0x17D5:\r
       return 1;\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
   return -1;\r
 }\r
 \r
-\r
 /**\r
   Renders a string to a bitmap or to the display.\r
 \r
 /**\r
   Renders a string to a bitmap or to the display.\r
 \r
@@ -1370,9 +1583,12 @@ IsLineBreak (
                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
                                   to a NULL on entry, then a              buffer\r
                                   will be allocated to hold the generated image and\r
                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
                                   to a NULL on entry, then a              buffer\r
                                   will be allocated to hold the generated image and\r
-                                  the pointer updated on exit. It is the caller¡¯s\r
+                                  the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\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
                                   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
@@ -1381,7 +1597,7 @@ IsLineBreak (
                                   updated to contain the        number of elements.\r
                                   This array describes the characters which were at\r
                                   least partially drawn and the heights of the\r
                                   updated to contain the        number of elements.\r
                                   This array describes the characters which were at\r
                                   least partially drawn and the heights of the\r
-                                  rows. It is the caller¡¯s responsibility to free\r
+                                  rows. It is the caller's responsibility to free\r
                                   this buffer.\r
   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it\r
                                   contains the number of elements in RowInfoArray.\r
                                   this buffer.\r
   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it\r
                                   contains the number of elements in RowInfoArray.\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_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
 \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
   )\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
 \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
     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
   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
     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
     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
   //\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
     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
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
   // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\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
     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
   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
   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
   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
 \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
   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
 \r
   if (SysFontFlag) {\r
+    ASSERT (SystemDefault != NULL);\r
     FontInfo   = NULL;\r
     Height     = SystemDefault->FontInfo.FontSize;\r
     FontInfo   = NULL;\r
     Height     = SystemDefault->FontInfo.FontSize;\r
+    BaseLine   = SystemDefault->FontInfo.FontSize;\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
-\r
   } else {\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
     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
       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
       Foreground = StringInfoOut->ForegroundColor;\r
       Background = StringInfoOut->BackgroundColor;\r
+    } else {\r
+      goto Exit;\r
     }\r
   }\r
 \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
   //\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
 \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
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\r
     }\r
+\r
     StringTmp = StringIn;\r
     while (*StringPtr != 0) {\r
       if (IsLineBreak (*StringPtr) == 0) {\r
     StringTmp = StringIn;\r
     while (*StringPtr != 0) {\r
       if (IsLineBreak (*StringPtr) == 0) {\r
@@ -1557,28 +1830,37 @@ HiiStringToImage (
         *StringTmp++ = *StringPtr++;\r
       }\r
     }\r
         *StringTmp++ = *StringPtr++;\r
       }\r
     }\r
+\r
     *StringTmp = 0;\r
     StringPtr  = StringIn;\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
   //\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
   //\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
   if (StringIn2 == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
+\r
   Index     = 0;\r
   StringTmp = StringIn2;\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
 \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
     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
         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
       } 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
                    );\r
         if (EFI_ERROR (Status)) {\r
           Status = EFI_INVALID_PARAMETER;\r
-          goto Exit;\r
         }\r
         }\r
-        *StringTmp++ = *StringPtr++;\r
-        Index++;\r
       }\r
       }\r
-    } else if (EFI_ERROR (Status)) {\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
       goto Exit;\r
       goto Exit;\r
-    } else {\r
-      *StringTmp++ = *StringPtr++;\r
-      Index++;\r
     }\r
     }\r
+\r
+    *StringTmp++ = *StringPtr++;\r
+    Index++;\r
   }\r
   }\r
+\r
   *StringTmp = 0;\r
   StringPtr  = StringIn2;\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
   // 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
 \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
 \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
-\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
+\r
+      LineHeight = LastLineHeight;\r
     }\r
 \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
 \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
       //\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
 \r
-        Index++;\r
-      }\r
+      Index++;\r
+    }\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
       //\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
       //\r
       Index--;\r
-      if (!SysFontFlag) {\r
-        LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\r
-      }\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
       //\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
       //\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
       //\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
       //\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
         //\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
         //\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
         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
         //\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
           }\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
           //\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
           //\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
         }\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
       //\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
 \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
         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
           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
             RowInfo[RowIndex].LineHeight,\r
             Transparent,\r
-            Cell[Index1],\r
+            &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
             );\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
+\r
+          ColumnInfoArray++;\r
         }\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
         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
                                         0\r
                                         );\r
         if (EFI_ERROR (Status)) {\r
-          SafeFreePool (BltBuffer);\r
+          FreePool (BltBuffer);\r
           goto Exit;\r
         }\r
 \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
           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
             Transparent,\r
-            Cell[Index1],\r
+            &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
             );\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
+\r
+          ColumnInfoArray++;\r
         }\r
         }\r
-        //\r
-        // Jump to next row\r
-        //\r
-        BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
-      }\r
 \r
 \r
-      Index++;\r
-      RowIndex++;\r
+        LineOffset += Cell[Index1].AdvanceX;\r
+      }\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
     }\r
 \r
+NextLine:\r
     //\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
     //\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
       *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
       if (*RowInfoArray == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Exit;\r
       }\r
+\r
       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
+    } else {\r
+      *RowInfoArray = NULL;\r
     }\r
     }\r
-    if (RowInfoArraySize != NULL) {\r
-      *RowInfoArraySize = RowIndex;\r
-    }\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
-    //\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
 \r
 \r
-    *Blt = Image;\r
+  if (StringIn != NULL) {\r
+    FreePool (StringIn);\r
   }\r
 \r
   }\r
 \r
-  Status = EFI_SUCCESS;\r
+  if (StringIn2 != NULL) {\r
+    FreePool (StringIn2);\r
+  }\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
 \r
-  for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {\r
-    SafeFreePool (GlyphBuf[Index]);\r
+  if (Attributes != NULL) {\r
+    FreePool (Attributes);\r
   }\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
   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
 /**\r
   Render a string to a bitmap or the screen containing the contents of the specified string.\r
 \r
@@ -1923,7 +2340,7 @@ Exit:
   @param  Flags                   Describes how the string is to be drawn.\r
   @param  PackageList             The package list in the HII database to search\r
                                   for the specified string.\r
   @param  Flags                   Describes how the string is to be drawn.\r
   @param  PackageList             The package list in the HII database to search\r
                                   for the specified string.\r
-  @param  StringId                The string¡¯s id, which is unique within\r
+  @param  StringId                The string's id, which is unique within\r
                                   PackageList.\r
   @param  Language                Points to the language for the retrieved string.\r
                                   If NULL, then the current system language is\r
                                   PackageList.\r
   @param  Language                Points to the language for the retrieved string.\r
                                   If NULL, then the current system language is\r
@@ -1939,9 +2356,12 @@ Exit:
                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
                                   to a NULL on entry, then a              buffer\r
                                   will be allocated to hold the generated image and\r
                                   EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
                                   to a NULL on entry, then a              buffer\r
                                   will be allocated to hold the generated image and\r
-                                  the pointer updated on exit. It is the caller¡¯s\r
+                                  the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\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
                                   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
@@ -1950,7 +2370,7 @@ Exit:
                                   updated to contain the        number of elements.\r
                                   This array describes the characters which were at\r
                                   least partially drawn and the heights of the\r
                                   updated to contain the        number of elements.\r
                                   This array describes the characters which were at\r
                                   least partially drawn and the heights of the\r
-                                  rows. It is the caller¡¯s responsibility to free\r
+                                  rows. It is the caller's responsibility to free\r
                                   this buffer.\r
   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it\r
                                   contains the number of elements in RowInfoArray.\r
                                   this buffer.\r
   @param  RowInfoArraySize        If this is non-NULL on entry, then on exit it\r
                                   contains the number of elements in RowInfoArray.\r
@@ -1965,35 +2385,48 @@ Exit:
                                   when character display is normalized that some\r
                                   character cells overlap.\r
 \r
                                   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
 \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
   )\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
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -2001,65 +2434,182 @@ HiiStringIdToImage (
     return EFI_NOT_FOUND;\r
   }\r
 \r
     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
 \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
 \r
   StringSize = MAX_STRING_LENGTH;\r
-  String = (EFI_STRING) AllocateZeroPool (StringSize);\r
+  String     = (EFI_STRING)AllocateZeroPool (StringSize);\r
   if (String == NULL) {\r
   if (String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
   }\r
 \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
   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
     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
 \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
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    SafeFreePool (String);\r
-    return Status;\r
+    goto Exit;\r
   }\r
 \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
-}\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
 \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
 \r
 /**\r
   Convert the glyph for a single character into a bitmap.\r
@@ -2071,7 +2621,7 @@ HiiStringIdToImage (
                                   system font and color.\r
   @param  Blt                     Thus must point to a NULL on entry. A buffer will\r
                                   be allocated to hold the output and the pointer\r
                                   system font and color.\r
   @param  Blt                     Thus must point to a NULL on entry. A buffer will\r
                                   be allocated to hold the output and the pointer\r
-                                  updated on exit. It is the caller¡¯s\r
+                                  updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\r
   @param  Baseline                Number of pixels from the bottom of the bitmap to\r
                                   the baseline.\r
                                   responsibility to free this buffer.\r
   @param  Baseline                Number of pixels from the bottom of the bitmap to\r
                                   the baseline.\r
@@ -2086,30 +2636,31 @@ HiiStringIdToImage (
 EFI_STATUS\r
 EFIAPI\r
 HiiGetGlyph (\r
 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
   )\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
     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
   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
 \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
     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
     *(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
     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
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
   }\r
@@ -2159,33 +2714,45 @@ HiiGetGlyph (
     goto Exit;\r
   }\r
 \r
     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
   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
 \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
 \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
 \r
   *Blt = Image;\r
   if (Baseline != NULL) {\r
@@ -2210,15 +2777,25 @@ Exit:
     }\r
   }\r
 \r
     }\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
   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
 /**\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
                                   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
   @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
   @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
 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
   )\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
     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
   //\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
       ((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
     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
   //\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
 \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
+\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
   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
     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
     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
     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
   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
     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
       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
           LocalFontHandle = NULL;\r
           goto Exit;\r
         }\r
+\r
         StringIn++;\r
       }\r
         StringIn++;\r
       }\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
       }\r
-      LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
 \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
     }\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
   }\r
 \r
   Status = EFI_NOT_FOUND;\r
@@ -2388,8 +3002,13 @@ Exit:
     *FontHandle = LocalFontHandle;\r
   }\r
 \r
     *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
   return Status;\r
 }\r
-\r