]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Font.c
index 82f47163b7dd468d707ab9452edc127735ffcbd6..ca63df168c9477e2a7e3cfa784981be0cbf98131 100644 (file)
@@ -2,21 +2,15 @@
 Implementation for EFI_HII_FONT_PROTOCOL.\r
 \r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 #include "HiiDatabase.h"\r
 \r
-EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mHiiEfiColors[16] = {\r
   //\r
   // B     G     R\r
   //\r
@@ -76,6 +70,9 @@ NewCell (
   //\r
   GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;\r
   GlyphInfo->CharId    = CharValue;\r
+  if (Cell->AdvanceX == 0) {\r
+    Cell->AdvanceX = Cell->Width;\r
+  }\r
   CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));\r
   InsertTailList (GlyphInfoList, &GlyphInfo->Entry);\r
 \r
@@ -221,7 +218,6 @@ GetGlyphBuffer (
             }\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
@@ -243,7 +239,6 @@ GetGlyphBuffer (
             }\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
@@ -270,16 +265,15 @@ GetGlyphBuffer (
                          bitmap.\r
   @param  Background     The color of the "off" pixels in the glyph in the\r
                          bitmap.\r
-  @param  ImageWidth     Width of the character or character cell, in\r
-                         pixels.\r
-  @param  ImageHeight    Height of the character or character cell, in\r
-                         pixels.\r
-  @param  Transparent             If TRUE, the Background color is ignored and all\r
-                                  "off" pixels in the character's drawn wil use the\r
-                                  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
+  @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
@@ -287,8 +281,9 @@ NarrowGlyphToBlt (
   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     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
@@ -304,23 +299,34 @@ NarrowGlyphToBlt (
   Height = EFI_GLYPH_HEIGHT;\r
   Width  = EFI_GLYPH_WIDTH;\r
 \r
-  ASSERT (Width <= ImageWidth && Height <= ImageHeight);\r
+  //\r
+  // Move position to the left-top corner of char.\r
+  //\r
+  Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;\r
 \r
-  Buffer = *Origin;\r
+  //\r
+  // Char may be partially displayed when CLIP_X or CLIP_Y is not set.\r
+  //\r
+  if (RowHeight < Height) {\r
+    Height = (UINT8) RowHeight;\r
+  }\r
+  if (RowWidth < Width) {\r
+    Width = (UINT8) RowWidth;\r
+  }\r
 \r
   for (Ypos = 0; Ypos < Height; Ypos++) {\r
     for (Xpos = 0; Xpos < Width; Xpos++) {\r
-      if ((GlyphBuffer[Ypos] & (1 << Xpos)) != 0) {\r
-        Buffer[Ypos * ImageWidth + (Width - Xpos - 1)] = Foreground;\r
+      if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {\r
+        Buffer[Ypos * ImageWidth + Xpos] = Foreground;\r
       } else {\r
         if (!Transparent) {\r
-          Buffer[Ypos * ImageWidth + (Width - Xpos - 1)] = Background;\r
+          Buffer[Ypos * ImageWidth + Xpos] = Background;\r
         }\r
       }\r
     }\r
   }\r
 \r
-  *Origin = Buffer + Width;\r
+  *Origin = *Origin + EFI_GLYPH_WIDTH;\r
 }\r
 \r
 \r
@@ -334,12 +340,12 @@ NarrowGlyphToBlt (
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  ImageWidth              Width of the character or character cell, in\r
-                                  pixels.\r
-  @param  ImageHeight             Height of the character or character cell, in\r
-                                  pixels.\r
+  @param  ImageWidth              Width of the whole image in pixels.\r
+  @param  BaseLine                BaseLine in the line.\r
+  @param  RowWidth                The width of the text on the line, in pixels.\r
+  @param  RowHeight               The height of the line, in pixels.\r
   @param  Transparent             If TRUE, the Background color is ignored and all\r
-                                  "off" pixels in the character's drawn wil use the\r
+                                  "off" pixels in the character's drawn will use the\r
                                   pixel value from BltBuffer.\r
   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.\r
   @param  Attributes              The attribute of incoming glyph in GlyphBuffer.\r
@@ -354,25 +360,38 @@ GlyphToBlt (
   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     UINT16                        ImageWidth,\r
+  IN     UINT16                        BaseLine,\r
+  IN     UINTN                         RowWidth,\r
+  IN     UINTN                         RowHeight,\r
   IN     BOOLEAN                       Transparent,\r
   IN     CONST EFI_HII_GLYPH_INFO      *Cell,\r
   IN     UINT8                         Attributes,\r
   IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
   )\r
 {\r
-  UINT8                                Xpos;\r
-  UINT8                                Ypos;\r
-  UINT8                                Data;\r
-  UINT8                                Index;\r
-  UINTN                                OffsetY;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *BltBuffer;\r
+  UINT16                                Xpos;\r
+  UINT16                                Ypos;\r
+  UINT8                                 Data;\r
+  UINT16                                Index;\r
+  UINT16                                YposOffset;\r
+  UINTN                                 OffsetY;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer;\r
 \r
-  ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
-  ASSERT (Cell->Width <= ImageWidth && Cell->Height <= ImageHeight);\r
+  ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
 \r
-  BltBuffer = *Origin;\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
+  // 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
@@ -386,7 +405,7 @@ GlyphToBlt (
   // The glyph's upper left hand corner pixel is the most significant bit of the\r
   // first bitmap byte.\r
   //\r
-  for (Ypos = 0; Ypos < Cell->Height; Ypos++) {\r
+  for (Ypos = 0; Ypos < Cell->Height && (((UINT32) Ypos + YposOffset) < RowHeight); Ypos++) {\r
     OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);\r
 \r
     //\r
@@ -394,12 +413,12 @@ GlyphToBlt (
     //\r
     for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {\r
       Data  = *(GlyphBuffer + OffsetY + Xpos);\r
-      for (Index = 0; Index < 8; Index++) {\r
-        if ((Data & (1 << Index)) != 0) {\r
-          BltBuffer[Ypos * ImageWidth + Xpos * 8 + (8 - Index - 1)] = Foreground;\r
+      for (Index = 0; Index < 8 && (((UINT32) Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
+        if ((Data & (1 << (8 - Index - 1))) != 0) {\r
+          BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
         } else {\r
           if (!Transparent) {\r
-            BltBuffer[Ypos * ImageWidth + Xpos * 8 + (8 - Index - 1)] = Background;\r
+            BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
           }\r
         }\r
       }\r
@@ -410,7 +429,7 @@ GlyphToBlt (
       // There are some padding bits in this byte. Ignore them.\r
       //\r
       Data  = *(GlyphBuffer + OffsetY + Xpos);\r
-      for (Index = 0; Index < Cell->Width % 8; Index++) {\r
+      for (Index = 0; Index < Cell->Width % 8 && (((UINT32) Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
         if ((Data & (1 << (8 - Index - 1))) != 0) {\r
           BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
         } else {\r
@@ -423,7 +442,7 @@ GlyphToBlt (
 \r
   } // end of for (Ypos=0...)\r
 \r
-  *Origin = BltBuffer + Cell->Width;\r
+  *Origin = *Origin + Cell->AdvanceX;\r
 }\r
 \r
 \r
@@ -437,12 +456,12 @@ GlyphToBlt (
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  ImageWidth              Width of the character or character cell, in\r
-                                  pixels.\r
-  @param  ImageHeight             Height of the character or character cell, in\r
-                                  pixels.\r
+  @param  ImageWidth              Width of the whole image in pixels.\r
+  @param  BaseLine                BaseLine in the line.\r
+  @param  RowWidth                The width of the text on the line, in pixels.\r
+  @param  RowHeight               The height of the line, in pixels.\r
   @param  Transparent             If TRUE, the Background color is ignored and all\r
-                                  "off" pixels in the character's drawn wil use the\r
+                                  "off" pixels in the character's drawn will use the\r
                                   pixel value from BltBuffer.\r
   @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.\r
   @param  Attributes              The attribute of incoming glyph in GlyphBuffer.\r
@@ -458,8 +477,10 @@ GlyphToImage (
   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     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
@@ -468,8 +489,7 @@ GlyphToImage (
 {\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;\r
 \r
-  ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
-  ASSERT (Cell->Width <= ImageWidth && Cell->Height <= ImageHeight);\r
+  ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
 \r
   Buffer = *Origin;\r
 \r
@@ -478,13 +498,15 @@ GlyphToImage (
     // This character is a non-spacing key, print it OR'd with the previous glyph.\r
     // without advancing cursor.\r
     //\r
-    Buffer -= Cell->Width;\r
+    Buffer -= Cell->AdvanceX;\r
     GlyphToBlt (\r
       GlyphBuffer,\r
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      BaseLine,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Cell,\r
       Attributes,\r
@@ -501,7 +523,8 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
@@ -511,7 +534,8 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
@@ -525,7 +549,8 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Origin\r
       );\r
@@ -539,7 +564,9 @@ GlyphToImage (
       Foreground,\r
       Background,\r
       ImageWidth,\r
-      ImageHeight,\r
+      BaseLine,\r
+      RowWidth,\r
+      RowHeight,\r
       Transparent,\r
       Cell,\r
       Attributes,\r
@@ -560,7 +587,7 @@ GlyphToImage (
   @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
@@ -581,7 +608,7 @@ WriteOutputParam (
   OUT UINTN                          *GlyphBufferLen OPTIONAL\r
   )\r
 {\r
-  if (BufferIn == NULL || BufferLen < 1 || InputCell == NULL) {\r
+  if (BufferIn == NULL || InputCell == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -589,7 +616,7 @@ WriteOutputParam (
     CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));\r
   }\r
 \r
-  if (GlyphBuffer != NULL) {\r
+  if (GlyphBuffer != NULL && BufferLen > 0) {\r
     *GlyphBuffer = (UINT8 *) AllocateZeroPool (BufferLen);\r
     if (*GlyphBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -614,7 +641,7 @@ WriteOutputParam (
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphBuffer             Output the corresponding bitmap data of the found\r
-                                  block. It is the caller's responsiblity to free\r
+                                  block. It is the caller's responsibility to free\r
                                   this buffer.\r
   @param  Cell                    Output cell information of the encoded bitmap.\r
   @param  GlyphBufferLen          If not NULL, output the length of GlyphBuffer.\r
@@ -645,9 +672,13 @@ FindGlyphBlock (
   UINT16                              Index;\r
   EFI_HII_GLYPH_INFO                  DefaultCell;\r
   EFI_HII_GLYPH_INFO                  LocalCell;\r
+  INT16                               MinOffsetY;\r
+  UINT16                              BaseLine;\r
 \r
   ASSERT (FontPackage != NULL);\r
   ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);\r
+  BaseLine  = 0;\r
+  MinOffsetY = 0;\r
 \r
   if (CharValue == (CHAR16) (-1)) {\r
     //\r
@@ -662,6 +693,11 @@ FindGlyphBlock (
     if (EFI_ERROR (Status)) {\r
       return Status;\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
@@ -684,6 +720,17 @@ FindGlyphBlock (
         if (EFI_ERROR (Status)) {\r
           return Status;\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
+        if (MinOffsetY > LocalCell.OffsetY) {\r
+          MinOffsetY = LocalCell.OffsetY;\r
+        }\r
       }\r
       BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);\r
       break;\r
@@ -700,12 +747,12 @@ FindGlyphBlock (
       break;\r
 \r
     case EFI_HII_GIBT_EXT1:\r
-      BlockPtr += *(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));\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
-        BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8),\r
+        (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
         sizeof (UINT16)\r
         );\r
       BlockPtr += Length16;\r
@@ -713,7 +760,7 @@ FindGlyphBlock (
     case EFI_HII_GIBT_EXT4:\r
       CopyMem (\r
         &Length32,\r
-        BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8),\r
+        (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
         sizeof (UINT32)\r
         );\r
       BlockPtr += Length32;\r
@@ -725,10 +772,18 @@ FindGlyphBlock (
         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
+        if (MinOffsetY > LocalCell.OffsetY) {\r
+          MinOffsetY = LocalCell.OffsetY;\r
+        }\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
+                 (UINT8*)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),\r
                  BufferLen,\r
                  &LocalCell,\r
                  GlyphBuffer,\r
@@ -747,6 +802,15 @@ FindGlyphBlock (
       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
+        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
@@ -769,6 +833,14 @@ FindGlyphBlock (
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
+      if (CharValue == (CHAR16) (-1)) {\r
+        if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
+          BaseLine = (UINT16) (DefaultCell.Height + DefaultCell.OffsetY);\r
+        }\r
+        if (MinOffsetY > DefaultCell.OffsetY) {\r
+          MinOffsetY = DefaultCell.OffsetY;\r
+        }\r
+      }\r
       BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
 \r
       if (CharCurrent == CharValue) {\r
@@ -791,6 +863,14 @@ FindGlyphBlock (
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
+      if (CharValue == (CHAR16) (-1)) {\r
+        if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
+          BaseLine = (UINT16) (DefaultCell.Height + DefaultCell.OffsetY);\r
+        }\r
+        if (MinOffsetY > DefaultCell.OffsetY) {\r
+          MinOffsetY = DefaultCell.OffsetY;\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
@@ -829,6 +909,8 @@ FindGlyphBlock (
   }\r
 \r
   if (CharValue == (CHAR16) (-1)) {\r
+    FontPackage->BaseLine = BaseLine;\r
+    FontPackage->Height   = (UINT16) (BaseLine - MinOffsetY);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -857,16 +939,18 @@ SaveFontName (
   )\r
 {\r
   UINTN         FontInfoLen;\r
+  UINTN         NameSize;\r
 \r
   ASSERT (FontName != NULL && FontInfo != NULL);\r
 \r
-  FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + StrSize (FontName);\r
+  NameSize = StrSize (FontName);\r
+  FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;\r
   *FontInfo = (EFI_FONT_INFO *) AllocateZeroPool (FontInfoLen);\r
   if (*FontInfo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  StrCpy ((*FontInfo)->FontName, FontName);\r
+  StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -895,6 +979,7 @@ GetSystemFont (
 {\r
   EFI_FONT_DISPLAY_INFO              *Info;\r
   UINTN                              InfoSize;\r
+  UINTN                              NameSize;\r
 \r
   if (Private == NULL || Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -906,18 +991,19 @@ GetSystemFont (
   //\r
   // The standard font always has the name "sysdefault".\r
   //\r
-  InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + StrSize (L"sysdefault");\r
+  NameSize = StrSize (L"sysdefault");\r
+  InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
   Info = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (InfoSize);\r
   if (Info == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Info->ForegroundColor    = mEfiColors[Private->Attribute & 0x0f];\r
-  Info->BackgroundColor    = mEfiColors[Private->Attribute >> 4];\r
+  Info->ForegroundColor    = mHiiEfiColors[Private->Attribute & 0x0f];\r
+  Info->BackgroundColor    = mHiiEfiColors[Private->Attribute >> 4];\r
   Info->FontInfoMask       = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;\r
   Info->FontInfo.FontStyle = 0;\r
   Info->FontInfo.FontSize  = EFI_GLYPH_HEIGHT;\r
-  StrCpy (Info->FontInfo.FontName, L"sysdefault");\r
+  StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");\r
 \r
   *FontInfo = Info;\r
   if (FontInfoSize != NULL) {\r
@@ -964,8 +1050,12 @@ IsSystemFontInfo (
     return TRUE;\r
   }\r
 \r
+  SystemDefault = NULL;\r
+  DefaultLen    = 0;\r
+\r
   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
   ASSERT_EFI_ERROR (Status);\r
+  ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));\r
 \r
   //\r
   // Record the system default info.\r
@@ -1003,8 +1093,8 @@ IsSystemFontInfo (
   }\r
   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {\r
     if (CompareMem (\r
-          &StringInfo->ForegroundColor, \r
-          &SystemDefault->ForegroundColor, \r
+          &StringInfo->ForegroundColor,\r
+          &SystemDefault->ForegroundColor,\r
           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
           ) != 0) {\r
       goto Exit;\r
@@ -1012,8 +1102,8 @@ IsSystemFontInfo (
   }\r
   if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {\r
     if (CompareMem (\r
-          &StringInfo->BackgroundColor, \r
-          &SystemDefault->BackgroundColor, \r
+          &StringInfo->BackgroundColor,\r
+          &SystemDefault->BackgroundColor,\r
           sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
           ) != 0) {\r
       goto Exit;\r
@@ -1047,7 +1137,7 @@ Exit:
   @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
@@ -1076,7 +1166,7 @@ IsFontInfoExisted (
   ASSERT (FontInfo != NULL);\r
 \r
   //\r
-  // Matched flag represents an exactly match; VagueMatched1 repensents a RESIZE\r
+  // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE\r
   // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.\r
   //\r
   Matched           = FALSE;\r
@@ -1152,7 +1242,7 @@ IsFontInfoExisted (
         }\r
         break;\r
       //\r
-      // If EFI_FONT_INFO_RESIZE is specified, then the sytem may attempt to\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
@@ -1344,15 +1434,14 @@ IsFontInfoExisted (
 /**\r
   Check whether the unicode represents a line break or not.\r
 \r
-  This is a internal function.\r
+  This is a internal function. Please see Section 27.2.6 of the UEFI Specification\r
+  for a description of the supported string format.\r
 \r
   @param  Char                    Unicode character\r
 \r
-  @retval 0                       Yes, it is a line break.\r
-  @retval 1                       Yes, it is a hyphen that desires a line break\r
-                                  after this character.\r
-  @retval 2                       Yes, it is a dash that desires a line break\r
-                                  before and after it.\r
+  @retval 0                       Yes, it forces a line break.\r
+  @retval 1                       Yes, it presents a line break opportunity\r
+  @retval 2                       Yes, it requires a line break happen before and after it.\r
   @retval -1                      No, it is not a link break.\r
 \r
 **/\r
@@ -1361,61 +1450,64 @@ IsLineBreak (
   IN  CHAR16    Char\r
   )\r
 {\r
-  UINT8         Byte1;\r
-  UINT8         Byte2;\r
-\r
-  //\r
-  // In little endian, Byte1 is the low byte of Char, Byte2 is the high byte of Char.\r
-  //\r
-  Byte1 = *((UINT8 *) (&Char));\r
-  Byte2 = *(((UINT8 *) (&Char) + 1));\r
-\r
-  if (Byte2 == 0x20) {\r
-    switch (Byte1) {\r
-    case 0x00:\r
-    case 0x01:\r
-    case 0x02:\r
-    case 0x03:\r
-    case 0x04:\r
-    case 0x05:\r
-    case 0x06:\r
-    case 0x08:\r
-    case 0x09:\r
-    case 0x0A:\r
-    case 0x0B:\r
-    case 0x28:\r
-    case 0x29:\r
-    case 0x5F:\r
-      return 0;\r
-    case 0x10:\r
-    case 0x12:\r
-    case 0x13:\r
-      return 1;\r
-    case 0x14:\r
-      //\r
-      // BUGBUG: Does it really require line break before it and after it?\r
-      //\r
-      return 2;\r
-    }\r
-  } else if (Byte2 == 0x00) {\r
-    switch (Byte1) {\r
-    case 0x20:\r
-    case 0x0C:\r
-    case 0x0D:\r
-      return 0;\r
-    }\r
-  }\r
-\r
   switch (Char) {\r
-    case 0x1680:\r
+    //\r
+    // Mandatory line break characters, which force a line-break\r
+    //\r
+    case 0x000A:\r
+    case 0x000C:\r
+    case 0x000D:\r
+    case 0x2028:\r
+    case 0x2029:\r
       return 0;\r
+    //\r
+    // Space characters, which is taken as a line-break opportunity\r
+    //\r
+    case 0x0020:\r
+    case 0x1680:\r
+    case 0x2000:\r
+    case 0x2001:\r
+    case 0x2002:\r
+    case 0x2003:\r
+    case 0x2004:\r
+    case 0x2005:\r
+    case 0x2006:\r
+    case 0x2008:\r
+    case 0x2009:\r
+    case 0x200A:\r
+    case 0x205F:\r
+    //\r
+    // In-Word Break Opportunities\r
+    //\r
+    case 0x200B:\r
+      return 1;\r
+    //\r
+    // A space which is not a line-break opportunity\r
+    //\r
+    case 0x00A0:\r
+    case 0x202F:\r
+    //\r
+    // A hyphen which is not a line-break opportunity\r
+    //\r
+    case 0x2011:\r
+      return -1;\r
+    //\r
+    // Hyphen characters which describe line break opportunities after the character\r
+    //\r
     case 0x058A:\r
+    case 0x2010:\r
+    case 0x2012:\r
+    case 0x2013:\r
     case 0x0F0B:\r
     case 0x1361:\r
     case 0x17D5:\r
       return 1;\r
+    //\r
+    // A hyphen which describes line break opportunities before and after them, but not between a pair of them\r
+    //\r
+    case 0x2014:\r
+      return 2;\r
   }\r
-\r
   return -1;\r
 }\r
 \r
@@ -1500,10 +1592,13 @@ HiiStringToImage (
   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
@@ -1511,6 +1606,7 @@ HiiStringToImage (
   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
@@ -1520,6 +1616,10 @@ HiiStringToImage (
   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
@@ -1555,11 +1655,35 @@ HiiStringToImage (
     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
+    Image->Width  = 800;\r
+    Image->Height = 600;\r
+    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    if (Image->Image.Bitmap == NULL) {\r
+      FreePool (Image);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Other flags are not permitted when Blt is NULL.\r
+    //\r
+    Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
+    *Blt = Image;\r
+  }\r
+\r
+  StrLength = StrLen(String);\r
+  GlyphBuf = (UINT8 **) AllocateZeroPool (StrLength * sizeof (UINT8 *));\r
   ASSERT (GlyphBuf != NULL);\r
-  Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (EFI_HII_GLYPH_INFO));\r
+  Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));\r
   ASSERT (Cell != NULL);\r
-  Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));\r
+  Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));\r
   ASSERT (Attributes != NULL);\r
 \r
   RowInfo       = NULL;\r
@@ -1579,12 +1703,18 @@ HiiStringToImage (
   SysFontFlag   = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
 \r
   if (SysFontFlag) {\r
+    ASSERT (SystemDefault != NULL);\r
     FontInfo   = NULL;\r
     Height     = SystemDefault->FontInfo.FontSize;\r
+    BaseLine   = SystemDefault->FontInfo.FontSize;\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
 \r
   } else {\r
+    //\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
@@ -1594,12 +1724,15 @@ HiiStringToImage (
       SysFontFlag = TRUE;\r
       FontInfo    = NULL;\r
       Height      = SystemDefault->FontInfo.FontSize;\r
+      BaseLine    = SystemDefault->FontInfo.FontSize;\r
       Foreground  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;\r
       Background  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;\r
 \r
     } else if (Status == EFI_SUCCESS) {\r
       FontInfo   = &StringInfoOut->FontInfo;\r
-      Height     = StringInfoOut->FontInfo.FontSize;\r
+      IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);\r
+      Height     = GlobalFont->FontPackage->Height;\r
+      BaseLine   = GlobalFont->FontPackage->BaseLine;\r
       Foreground = StringInfoOut->ForegroundColor;\r
       Background = StringInfoOut->BackgroundColor;\r
     } else {\r
@@ -1607,6 +1740,14 @@ HiiStringToImage (
     }\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
@@ -1636,7 +1777,7 @@ HiiStringToImage (
   }\r
   //\r
   // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs\r
-  // are not drawn. Otherwise they are replaced wth Unicode character 0xFFFD.\r
+  // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.\r
   //\r
   StringIn2  = AllocateZeroPool (StrSize (StringPtr));\r
   if (StringIn2 == NULL) {\r
@@ -1645,16 +1786,20 @@ HiiStringToImage (
   }\r
   Index     = 0;\r
   StringTmp = StringIn2;\r
+  StrLength = StrLen(StringPtr);\r
+  while (*StringPtr != 0 && Index < StrLength) {\r
+    if (IsLineBreak (*StringPtr) == 0) {\r
+      *StringTmp++ = *StringPtr++;\r
+      Index++;\r
+      continue;\r
+    }\r
 \r
-  while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {\r
     Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
     if (Status == EFI_NOT_FOUND) {\r
       if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
-        if (GlyphBuf[Index] != NULL) {\r
-          FreePool (GlyphBuf[Index]);\r
-        }\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
@@ -1669,17 +1814,16 @@ HiiStringToImage (
                    );\r
         if (EFI_ERROR (Status)) {\r
           Status = EFI_INVALID_PARAMETER;\r
-          goto Exit;\r
         }\r
-        *StringTmp++ = *StringPtr++;\r
-        Index++;\r
       }\r
-    } else if (EFI_ERROR (Status)) {\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
       goto Exit;\r
-    } else {\r
-      *StringTmp++ = *StringPtr++;\r
-      Index++;\r
     }\r
+\r
+    *StringTmp++ = *StringPtr++;\r
+    Index++;\r
   }\r
   *StringTmp = 0;\r
   StringPtr  = StringIn2;\r
@@ -1690,180 +1834,269 @@ HiiStringToImage (
   // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
   // Otherwise render this string to a new allocated image and output it.\r
   //\r
-  if (*Blt != NULL) {\r
-    Image     = *Blt;\r
-    BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
-    MaxRowNum = (UINT16) (Image->Height / Height);\r
-    if (Image->Height % Height != 0) {\r
-      MaxRowNum++;\r
-    }\r
-\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
+  Image     = *Blt;\r
+  BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
+  if (Image->Height < BltY) {\r
     //\r
-    // Format the glyph buffer according to flags.\r
+    // the top edge of the image should be in Image resolution scope.\r
     //\r
+    Status = EFI_INVALID_PARAMETER;\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
-    Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
-    if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_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
-      }\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
-    for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
-      LineWidth      = 0;\r
-      LineHeight     = 0;\r
-      BaseLineOffset = 0;\r
-      LineBreak      = FALSE;\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
-      //\r
-      // Calculate how many characters there are in a row.\r
-      //\r
-      RowInfo[RowIndex].StartIndex = Index;\r
+  for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
+    LineWidth      = 0;\r
+    LineBreak      = FALSE;\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
+    //\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
+    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
+      LineHeight = LastLineHeight;\r
+    }\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
+    //\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
+        // It forces a line break that ends this row.\r
+        //\r
         Index++;\r
+        LineBreak = TRUE;\r
+        break;\r
       }\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
+      // If the glyph of the character is existing, then accumulate the actual printed width\r
       //\r
-      Index--;\r
-      if (!SysFontFlag) {\r
-        LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\r
-      }\r
+      LineWidth += (UINTN) Cell[Index].AdvanceX;\r
+\r
+      Index++;\r
+    }\r
 \r
+    //\r
+    // Record index of next char.\r
+    //\r
+    NextIndex = Index;\r
+    //\r
+    // Return to the previous char.\r
+    //\r
+    Index--;\r
+    if (LineBreak && Index > 0 ) {\r
       //\r
-      // 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
+      // Return the previous non line break char.\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_CLIP_CLEAN_X;\r
-        }\r
-      }\r
+      Index --;\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
+      // Record right-most character in RowInfo even if it is partially displayed.\r
       //\r
-      // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
+      RowInfo[RowIndex].EndIndex       = Index;\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
       //\r
-      if (LineWidth + BltX <= Image->Width ||\r
-        (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {\r
+      if (Index > RowInfo[RowIndex].StartIndex) {\r
         //\r
-        // Record right-most character in RowInfo even if it is partially displayed.\r
+        // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
         //\r
-        RowInfo[RowIndex].EndIndex       = Index;\r
+        LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);\r
+        LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);\r
+        RowInfo[RowIndex].EndIndex       = Index - 1;\r
         RowInfo[RowIndex].LineWidth      = LineWidth;\r
         RowInfo[RowIndex].LineHeight     = LineHeight;\r
         RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
       } else {\r
         //\r
-        // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
-        // if its right-most on pixel cannot fit.\r
+        // There is no enough column to draw any character, so set current line width to zero.\r
+        // And go to draw Next line if LineBreak is set.\r
         //\r
-        if (Index > 0) {\r
-          RowInfo[RowIndex].EndIndex       = Index - 1;\r
-          RowInfo[RowIndex].LineWidth      = LineWidth - Cell[Index].AdvanceX;\r
-          RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\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
+      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
+          if (IsLineBreak (StringPtr[Index1]) > 0) {\r
+            LineBreak = TRUE;\r
+            if (Index1 > RowInfo[RowIndex].StartIndex) {\r
+              RowInfo[RowIndex].EndIndex = Index1 - 1;\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
-          RowInfo[RowIndex].LineHeight     = LineHeight;\r
-        } else {\r
           //\r
-          // There is only one column and it can not be drawn so that return directly.\r
+          // If don't find a line break opportunity from EndIndex to StartIndex,\r
+          // then jump out.\r
           //\r
-          Status = EFI_SUCCESS;\r
-          goto Exit;\r
+          if (Index1 == RowInfo[RowIndex].StartIndex)\r
+            break;\r
         }\r
-      }\r
 \r
+        //\r
+        // Update LineWidth to the real width\r
+        //\r
+        if (IsLineBreak (StringPtr[Index1]) > 0) {\r
+          if (Index1 == RowInfo[RowIndex].StartIndex) {\r
+            LineWidth = 0;\r
+          } else {\r
+            LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
+          }\r
+          RowInfo[RowIndex].LineWidth = LineWidth;\r
+        }\r
+      }\r
       //\r
-      // Clip the final row if the row's bottom-most on pixel cannot fit when\r
-      // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
+      // If no line-break opportunity can be found, then the text will\r
+      // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
       //\r
-      if (RowIndex == MaxRowNum - 1 && Image->Height < LineHeight) {\r
-        LineHeight = Image->Height;\r
-        if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
-          //\r
-          // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
-          //\r
-          break;\r
+      if (!LineBreak) {\r
+        LineWidth = RowInfo[RowIndex].LineWidth;\r
+        Index1    = RowInfo[RowIndex].EndIndex;\r
+        if (LineWidth + BltX > Image->Width) {\r
+          if (Index1 > RowInfo[RowIndex].StartIndex) {\r
+            //\r
+            // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
+            //\r
+            LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
+            LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
+            RowInfo[RowIndex].EndIndex       = Index1 - 1;\r
+            RowInfo[RowIndex].LineWidth      = LineWidth;\r
+          } else {\r
+            //\r
+            // There is no enough column to draw any character, so set current line width to zero.\r
+            // And go to draw Next line if LineBreak is set.\r
+            //\r
+            RowInfo[RowIndex].LineWidth = 0;\r
+            goto NextLine;\r
+          }\r
         }\r
       }\r
+    }\r
 \r
-      //\r
-      // Draw it to screen or existing bitmap depending on whether\r
-      // EFI_HII_DIRECT_TO_SCREEN is set.\r
-      //\r
-      if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
-        BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    //\r
+    // LineWidth can't exceed Image width.\r
+    //\r
+    if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {\r
+      RowInfo[RowIndex].LineWidth = Image->Width - BltX;\r
+    }\r
+\r
+    //\r
+    // Draw it to screen or existing bitmap depending on whether\r
+    // EFI_HII_DIRECT_TO_SCREEN is set.\r
+    //\r
+    LineOffset = 0;\r
+    if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
+      BltBuffer = NULL;\r
+      if (RowInfo[RowIndex].LineWidth != 0) {\r
+        BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
         if (BltBuffer == NULL) {\r
           Status = EFI_OUT_OF_RESOURCES;\r
           goto Exit;\r
         }\r
-        BufferPtr = BltBuffer;\r
-        for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        //\r
+        // 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
+      for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {\r
+          //\r
+          // Only BLT these character which have corresponding glyph in font database.\r
+          //\r
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
             Background,\r
-            RowInfo[RowIndex].LineWidth,\r
+            (UINT16) RowInfo[RowIndex].LineWidth,\r
+            BaseLine,\r
+            RowInfo[RowIndex].LineWidth - LineOffset,\r
             RowInfo[RowIndex].LineHeight,\r
             Transparent,\r
             &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
-            );\r
-          if (ColumnInfoArray != NULL) {\r
-            if (Index1 == RowInfo[RowIndex].StartIndex) {\r
-              *ColumnInfoArray = 0;\r
-            } else {\r
-              *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
-            }\r
-            ColumnInfoArray++;\r
+          );\r
+        }\r
+        if (ColumnInfoArray != NULL) {\r
+          if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)\r
+              || RowInfo[RowIndex].LineWidth == 0) {\r
+            *ColumnInfoArray = (UINTN) ~0;\r
+          } else {\r
+            *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
           }\r
+          ColumnInfoArray++;\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
@@ -1882,100 +2115,99 @@ HiiStringToImage (
         }\r
 \r
         FreePool (BltBuffer);\r
-\r
-      } else {\r
-        for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+      }\r
+    } else {\r
+      //\r
+      // Save the starting position for calculate the starting position of next row.\r
+      //\r
+      RowBufferPtr = BufferPtr;\r
+      //\r
+      // Set BufferPtr to Origin by adding baseline to the starting position.\r
+      //\r
+      BufferPtr = BufferPtr + BaseLine * Image->Width;\r
+      for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {\r
+          //\r
+          // Only BLT these character which have corresponding glyph in font database.\r
+          //\r
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
             Background,\r
             Image->Width,\r
-            Image->Height,\r
+            BaseLine,\r
+            RowInfo[RowIndex].LineWidth - LineOffset,\r
+            RowInfo[RowIndex].LineHeight,\r
             Transparent,\r
             &Cell[Index1],\r
             Attributes[Index1],\r
             &BufferPtr\r
-            );\r
-          if (ColumnInfoArray != NULL) {\r
-            if (Index1 == RowInfo[RowIndex].StartIndex) {\r
-              *ColumnInfoArray = 0;\r
-            } else {\r
-              *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
-            }\r
-            ColumnInfoArray++;\r
+          );\r
+        }\r
+        if (ColumnInfoArray != NULL) {\r
+          if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)\r
+              || RowInfo[RowIndex].LineWidth == 0) {\r
+            *ColumnInfoArray = (UINTN) ~0;\r
+          } else {\r
+            *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
           }\r
+          ColumnInfoArray++;\r
         }\r
-        //\r
-        // Jump to next row\r
-        //\r
-        BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
+        LineOffset += Cell[Index1].AdvanceX;\r
       }\r
 \r
-      Index++;\r
-      RowIndex++;\r
-\r
+      //\r
+      // Jump to starting position of next row.\r
+      //\r
+      if (RowIndex == 0) {\r
+        BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;\r
+      } else {\r
+        BufferPtr = RowBufferPtr + LineHeight * Image->Width;\r
+      }\r
     }\r
 \r
+NextLine:\r
     //\r
-    // Write output parameters.\r
+    // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down\r
     //\r
-    RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
-    if (RowInfoArray != NULL) {\r
+    BltY += RowInfo[RowIndex].LineHeight;\r
+\r
+    RowIndex++;\r
+    Index = NextIndex;\r
+\r
+    if (!LineBreak) {\r
+      //\r
+      // If there is not a mandatory line break or line break opportunity, only render one line to image\r
+      //\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Write output parameters.\r
+  //\r
+  RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
+  if (RowInfoArray != NULL) {\r
+    if (RowInfoSize > 0) {\r
       *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
       if (*RowInfoArray == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Exit;\r
       }\r
       CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
+    } else {\r
+      *RowInfoArray = NULL;\r
     }\r
-    if (RowInfoArraySize != NULL) {\r
-      *RowInfoArraySize = RowIndex;\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
-      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
-    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
-    }\r
-\r
-    *Blt = Image;\r
+  }\r
+  if (RowInfoArraySize != NULL) {\r
+    *RowInfoArraySize = RowIndex;\r
   }\r
 \r
   Status = EFI_SUCCESS;\r
 \r
 Exit:\r
 \r
-  for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {\r
+  for (Index = 0; Index < StrLength; Index++) {\r
     if (GlyphBuf[Index] != NULL) {\r
       FreePool (GlyphBuf[Index]);\r
     }\r
@@ -2061,13 +2293,13 @@ Exit:
                                   when character display is normalized that some\r
                                   character cells overlap.\r
 \r
-  @retval EFI_SUCCESS             The string was successfully rendered.\r
-  @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for\r
-                                  RowInfoArray or Blt.\r
+  @retval EFI_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 stringid is not \r
-                          in the specified PackageList. \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
@@ -2089,12 +2321,18 @@ HiiStringIdToImage (
 {\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                               CurrentLang[RFC_3066_ENTRY_SIZE];\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
@@ -2105,84 +2343,131 @@ HiiStringIdToImage (
   }\r
 \r
   //\r
-  // When Language points to NULL, current system language is used.\r
+  // Initialize string pointers to be NULL\r
   //\r
-  if (Language != NULL) {\r
-    AsciiStrCpy (CurrentLang, (CHAR8 *) Language);\r
-  } else {\r
-    GetCurrentLanguage (CurrentLang);\r
-  }\r
+  SupportedLanguages = NULL;\r
+  CurrentLanguage    = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
+  StringFontInfo     = NULL;\r
+  NewStringInfo      = NULL;\r
 \r
   //\r
   // Get the string to be displayed.\r
   //\r
+  Private   = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  HiiString = &Private->HiiString;\r
+\r
+  //\r
+  // Get the size of supported language.\r
+  //\r
+  SupportedLanguagesSize = 0;\r
+  Status = HiiString->GetLanguages (\r
+                        HiiString,\r
+                        PackageList,\r
+                        &TempSupportedLanguages,\r
+                        &SupportedLanguagesSize\r
+                        );\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return Status;\r
+  }\r
+\r
+  SupportedLanguages = AllocatePool (SupportedLanguagesSize);\r
+  if (SupportedLanguages == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = HiiString->GetLanguages (\r
+                        HiiString,\r
+                        PackageList,\r
+                        SupportedLanguages,\r
+                        &SupportedLanguagesSize\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  if (Language == NULL) {\r
+    Language = "";\r
+  }\r
+  GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLanguage, NULL);\r
+  BestLanguage = GetBestLanguage (\r
+                   SupportedLanguages,\r
+                   FALSE,\r
+                   Language,\r
+                   (CurrentLanguage == NULL) ? CurrentLanguage : "",\r
+                   (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
+                   NULL\r
+                   );\r
+  if (BestLanguage == NULL) {\r
+    Status = EFI_NOT_FOUND;\r
+    goto Exit;\r
+  }\r
 \r
   StringSize = MAX_STRING_LENGTH;\r
   String = (EFI_STRING) AllocateZeroPool (StringSize);\r
   if (String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
   }\r
 \r
-  Private        = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
-  StringFontInfo = NULL;\r
-  NewStringInfo  = NULL;\r
-  \r
-  Status = Private->HiiString.GetString (\r
-                                &Private->HiiString,\r
-                                CurrentLang,\r
-                                PackageList,\r
-                                StringId,\r
-                                String,\r
-                                &StringSize,\r
-                                &StringFontInfo\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
     FreePool (String);\r
     String = (EFI_STRING) AllocateZeroPool (StringSize);\r
     if (String == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
     }\r
-    Status = Private->HiiString.GetString (\r
-                                  &Private->HiiString,\r
-                                  Language,\r
-                                  PackageList,\r
-                                  StringId,\r
-                                  String,\r
-                                  &StringSize,\r
-                                  NULL\r
-                                  );\r
-\r
+    Status = HiiString->GetString (\r
+                          HiiString,\r
+                          BestLanguage,\r
+                          PackageList,\r
+                          StringId,\r
+                          String,\r
+                          &StringSize,\r
+                          NULL\r
+                          );\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-      goto Exit;\r
+    goto Exit;\r
   }\r
-    \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
+  // 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
-    FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + StrSize (StringFontInfo->FontName);\r
+    NameSize = StrSize (StringFontInfo->FontName);\r
+    FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
     NewStringInfo = AllocateZeroPool (FontLen);\r
-    if (NewStringInfo == NULL) {      \r
+    if (NewStringInfo == NULL) {\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto Exit;\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
-    StrCpy (NewStringInfo->FontInfo.FontName, StringFontInfo->FontName);\r
-  \r
+    NewStringInfo->FontInfo.FontSize  = StringFontInfo->FontSize;\r
+    StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);\r
+\r
     Status = HiiStringToImage (\r
-               This, \r
-               Flags, \r
-               String, \r
-               NewStringInfo, \r
-               Blt, \r
-               BltX, \r
-               BltY, \r
+               This,\r
+               Flags,\r
+               String,\r
+               NewStringInfo,\r
+               Blt,\r
+               BltX,\r
+               BltY,\r
                RowInfoArray,\r
                RowInfoArraySize,\r
                ColumnInfoArray\r
@@ -2204,6 +2489,15 @@ HiiStringIdToImage (
            );\r
 \r
 Exit:\r
+  if (SupportedLanguages != NULL) {\r
+    FreePool (SupportedLanguages);\r
+  }\r
+  if (CurrentLanguage != NULL) {\r
+    FreePool (CurrentLanguage);\r
+  }\r
+  if (BestLanguage != NULL) {\r
+    FreePool (BestLanguage);\r
+  }\r
   if (String != NULL) {\r
     FreePool (String);\r
   }\r
@@ -2265,6 +2559,7 @@ HiiGetGlyph (
   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
@@ -2303,10 +2598,12 @@ HiiGetGlyph (
     if (EFI_ERROR (Status)) {\r
       goto Exit;\r
     }\r
+    ASSERT (StringInfoOut != NULL);\r
     FontInfo   = &StringInfoOut->FontInfo;\r
     Foreground = StringInfoOut->ForegroundColor;\r
     Background = StringInfoOut->BackgroundColor;\r
   } else {\r
+    ASSERT (SystemDefault != NULL);\r
     Foreground = SystemDefault->ForegroundColor;\r
     Background = SystemDefault->BackgroundColor;\r
   }\r
@@ -2324,25 +2621,36 @@ HiiGetGlyph (
   Image->Width   = Cell.Width;\r
   Image->Height  = Cell.Height;\r
 \r
-  Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
-  if (Image->Image.Bitmap == NULL) {\r
-    FreePool (Image);\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
+  if (Image->Width * Image->Height > 0) {\r
+    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    if (Image->Image.Bitmap == NULL) {\r
+      FreePool (Image);\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
+    }\r
 \r
-  BltBuffer = Image->Image.Bitmap;\r
-  GlyphToImage (\r
-    GlyphBuffer,\r
-    Foreground,\r
-    Background,\r
-    Image->Width,\r
-    Image->Height,\r
-    FALSE,\r
-    &Cell,\r
-    Attributes,\r
-    &BltBuffer\r
-    );\r
+    //\r
+    // Set BaseLine to the char height.\r
+    //\r
+    BaseLine  = (UINT16) (Cell.Height + Cell.OffsetY);\r
+    //\r
+    // Set BltBuffer to the position of Origin.\r
+    //\r
+    BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;\r
+    GlyphToImage (\r
+      GlyphBuffer,\r
+      Foreground,\r
+      Background,\r
+      Image->Width,\r
+      BaseLine,\r
+      Cell.Width + Cell.OffsetX,\r
+      BaseLine - Cell.OffsetY,\r
+      FALSE,\r
+      &Cell,\r
+      Attributes,\r
+      &BltBuffer\r
+      );\r
+  }\r
 \r
   *Blt = Image;\r
   if (Baseline != NULL) {\r
@@ -2395,14 +2703,15 @@ Exit:
                                   with the  first font. On return, points to the\r
                                   returned font handle or points to NULL if there\r
                                   are no more matching fonts.\r
-  @param  StringInfoIn            Upon entry, points to the font to return\r
-                                  information about. \r
-                                  If NULL, then the information about the system default \r
-                                  font will be returned.\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
@@ -2438,6 +2747,7 @@ HiiGetFontInfo (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  StringInfoOutLen = 0;\r
   FontInfo        = NULL;\r
   SystemDefault   = NULL;\r
   LocalFontHandle = NULL;\r
@@ -2485,18 +2795,22 @@ HiiGetFontInfo (
     }\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
-  if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT  | EFI_FONT_INFO_ANY_FONT))  == \r
+  if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT  | EFI_FONT_INFO_ANY_FONT))  ==\r
        (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT))   ||\r
-      ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE  | EFI_FONT_INFO_ANY_SIZE))  == \r
+      ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE  | EFI_FONT_INFO_ANY_SIZE))  ==\r
        (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE))   ||\r
-      ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == \r
+      ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==\r
        (EFI_FONT_INFO_SYS_STYLE | 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
+      ((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
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -2518,7 +2832,7 @@ HiiGetFontInfo (
 \r
   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {\r
     InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;\r
-  } \r
+  }\r
   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
     InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
   }\r
@@ -2528,15 +2842,15 @@ HiiGetFontInfo (
   if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
     InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
   }\r
-  \r
 \r
+  ASSERT (FontInfo != NULL);\r
   FontInfo->FontSize  = InfoOut.FontInfo.FontSize;\r
   FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
 \r
   if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
     //\r
     // Test to guarantee all characters are available in the found font.\r
-    //    \r
+    //\r
     if (String != NULL) {\r
       StringIn = String;\r
       while (*StringIn != 0) {\r
@@ -2553,21 +2867,21 @@ HiiGetFontInfo (
     //\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
+      *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
+\r
       CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
       CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
     }\r
-    \r
-    LocalFontHandle = GlobalFont->Entry.ForwardLink;    \r
+\r
+    LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
     Status = EFI_SUCCESS;\r
     goto Exit;\r
-  }  \r
+  }\r
 \r
   Status = EFI_NOT_FOUND;\r
 \r