]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
Roll back changes to apply GetBestLanguage() in HiiDataBase. Exact language match...
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Font.c
index a9070c425ad036d3ff3825aac2b7dacf118b8944..4bb72c81d417cc2cf094b2100d32965049a03e02 100644 (file)
@@ -1,6 +1,8 @@
 /** @file\r
+Implementation for EFI_HII_FONT_PROTOCOL.\r
 \r
-Copyright (c) 2007, Intel Corporation\r
+\r
+Copyright (c) 2007 - 2009, 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
@@ -9,23 +11,12 @@ http://opensource.org/licenses/bsd-license.php
 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
 **/\r
 \r
 \r
 #include "HiiDatabase.h"\r
 \r
-static EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mHiiEfiColors[16] = {\r
   //\r
   // B     G     R\r
   //\r
@@ -51,6 +42,8 @@ static EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {
 /**\r
   Insert a character cell information to the list specified by GlyphInfoList.\r
 \r
+  This is a internal function.\r
+\r
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphInfoList           HII_GLYPH_INFO list head.\r
@@ -61,7 +54,6 @@ static EFI_GRAPHICS_OUTPUT_BLT_PIXEL        mEfiColors[16] = {
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 NewCell (\r
   IN  CHAR16                         CharValue,\r
@@ -94,6 +86,8 @@ NewCell (
 /**\r
   Get a character cell information from the list specified by GlyphInfoList.\r
 \r
+  This is a internal function.\r
+\r
   @param  CharValue               Unicode character value, which identifies a glyph\r
                                   block.\r
   @param  GlyphInfoList           HII_GLYPH_INFO list head.\r
@@ -105,7 +99,6 @@ NewCell (
                                   not exist.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetCell (\r
   IN  CHAR16                         CharValue,\r
@@ -143,6 +136,8 @@ GetCell (
 /**\r
   Convert the glyph for a single character into a bitmap.\r
 \r
+  This is a internal function.\r
+\r
   @param  Private                 HII database driver private data.\r
   @param  Char                    Character to retrieve.\r
   @param  StringInfo              Points to the string font and color information\r
@@ -158,7 +153,6 @@ GetCell (
   @retval EFI_INVALID_PARAMETER   Any input parameter is invalid.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 GetGlyphBuffer (\r
   IN  HII_DATABASE_PRIVATE_DATA      *Private,\r
@@ -266,7 +260,28 @@ GetGlyphBuffer (
   return EFI_NOT_FOUND;\r
 }\r
 \r
-STATIC\r
+/**\r
+  Convert bitmap data of the glyph to blt structure.\r
+\r
+  This is a internal function.\r
+\r
+  @param GlyphBuffer     Buffer points to bitmap data of glyph.\r
+  @param  Foreground     The color of the "on" pixels in the glyph in the\r
+                         bitmap.\r
+  @param  Background     The color of the "off" pixels in the glyph in the\r
+                         bitmap.\r
+  @param  ImageWidth     Width of the 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
+\r
+**/\r
 VOID\r
 NarrowGlyphToBlt (\r
   IN     UINT8                         *GlyphBuffer,\r
@@ -278,8 +293,8 @@ NarrowGlyphToBlt (
   IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
   )\r
 {\r
-  UINT8                                X;\r
-  UINT8                                Y;\r
+  UINT8                                Xpos;\r
+  UINT8                                Ypos;\r
   UINT8                                Height;\r
   UINT8                                Width;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL        *Buffer;\r
@@ -293,13 +308,13 @@ NarrowGlyphToBlt (
 \r
   Buffer = *Origin;\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 << Xpos)) != 0) {\r
+        Buffer[Ypos * ImageWidth + (Width - Xpos - 1)] = Foreground;\r
       } else {\r
         if (!Transparent) {\r
-          Buffer[Y * ImageWidth + (Width - X - 1)] = Background;\r
+          Buffer[Ypos * ImageWidth + (Width - Xpos - 1)] = Background;\r
         }\r
       }\r
     }\r
@@ -312,23 +327,28 @@ NarrowGlyphToBlt (
 /**\r
   Convert bitmap data of the glyph to blt structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  GlyphBuffer             Buffer points to bitmap data of glyph.\r
   @param  Foreground              The color of the "on" pixels in the glyph in the\r
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  Width                   Width of the character or character cell, in\r
+  @param  ImageWidth              Width of the character or character cell, in\r
                                   pixels.\r
-  @param  Height                  Height of the character or character cell, in\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  BltBuffer               Points to the blt buffer.\r
+  @param  Cell                    Points to EFI_HII_GLYPH_INFO structure.\r
+  @param  Attributes              The attribute of incoming glyph in GlyphBuffer.\r
+  @param  Origin                  On input, points to the origin of the to be\r
+                                  displayed character, on output, points to the\r
+                                  next glyph's origin.\r
 \r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToBlt (\r
   IN     UINT8                         *GlyphBuffer,\r
@@ -342,8 +362,8 @@ GlyphToBlt (
   IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
   )\r
 {\r
-  UINT8                                X;\r
-  UINT8                                Y;\r
+  UINT8                                Xpos;\r
+  UINT8                                Ypos;\r
   UINT8                                Data;\r
   UINT8                                Index;\r
   UINTN                                OffsetY;\r
@@ -366,20 +386,20 @@ GlyphToBlt (
   // The glyph's upper left hand corner pixel is the most significant bit of the\r
   // first bitmap byte.\r
   //\r
-  for (Y = 0; Y < Cell->Height; Y++) {\r
-    OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Y);\r
+  for (Ypos = 0; Ypos < Cell->Height; Ypos++) {\r
+    OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);\r
 \r
     //\r
     // All bits in these bytes are meaningful.\r
     //\r
-    for (X = 0; X < Cell->Width / 8; X++) {\r
-      Data  = *(GlyphBuffer + OffsetY + X);\r
+    for (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[Y * ImageWidth + X * 8 + (8 - Index - 1)] = Foreground;\r
+          BltBuffer[Ypos * ImageWidth + Xpos * 8 + (8 - Index - 1)] = Foreground;\r
         } else {\r
           if (!Transparent) {\r
-            BltBuffer[Y * ImageWidth + X * 8 + (8 - Index - 1)] = Background;\r
+            BltBuffer[Ypos * ImageWidth + Xpos * 8 + (8 - Index - 1)] = Background;\r
           }\r
         }\r
       }\r
@@ -389,19 +409,19 @@ GlyphToBlt (
       //\r
       // There are some padding bits in this byte. Ignore them.\r
       //\r
-      Data  = *(GlyphBuffer + OffsetY + X);\r
+      Data  = *(GlyphBuffer + OffsetY + Xpos);\r
       for (Index = 0; Index < Cell->Width % 8; Index++) {\r
         if ((Data & (1 << (8 - Index - 1))) != 0) {\r
-          BltBuffer[Y * ImageWidth + X * 8 + Index] = Foreground;\r
+          BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
         } else {\r
           if (!Transparent) {\r
-            BltBuffer[Y * ImageWidth + X * 8 + Index] = Background;\r
+            BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
           }\r
         }\r
       }\r
     } // end of if (Width % 8...)\r
 \r
-  } // end of for (Y=0...)\r
+  } // end of for (Ypos=0...)\r
 \r
   *Origin = BltBuffer + Cell->Width;\r
 }\r
@@ -410,14 +430,16 @@ GlyphToBlt (
 /**\r
   Convert bitmap data of the glyph to blt structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  GlyphBuffer             Buffer points to bitmap data of glyph.\r
   @param  Foreground              The color of the "on" pixels in the glyph in the\r
                                   bitmap.\r
   @param  Background              The color of the "off" pixels in the glyph in the\r
                                   bitmap.\r
-  @param  Width                   Width of the character or character cell, in\r
+  @param  ImageWidth              Width of the character or character cell, in\r
                                   pixels.\r
-  @param  Height                  Height of the character or character cell, in\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
@@ -431,7 +453,6 @@ GlyphToBlt (
   @return Points to the address of next origin node in BltBuffer.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 GlyphToImage (\r
   IN     UINT8                         *GlyphBuffer,\r
@@ -531,6 +552,8 @@ GlyphToImage (
 /**\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
@@ -548,7 +571,6 @@ GlyphToImage (
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 WriteOutputParam (\r
   IN  UINT8                          *BufferIn,\r
@@ -817,6 +839,8 @@ FindGlyphBlock (
 /**\r
   Copy a Font Name to a new created EFI_FONT_INFO structure.\r
 \r
+  This is a internal function.\r
+\r
   @param  FontName                NULL-terminated string.\r
   @param  FontInfo                a new EFI_FONT_INFO which stores the FontName.\r
                                   It's caller's responsibility to free this buffer.\r
@@ -826,7 +850,6 @@ FindGlyphBlock (
                                   task.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 SaveFontName (\r
   IN  EFI_STRING                       FontName,\r
@@ -889,8 +912,8 @@ GetSystemFont (
     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
@@ -905,15 +928,16 @@ GetSystemFont (
 \r
 \r
 /**\r
-  Check whether EFI_FONT_DISPLAY_INFO points to system default font and color.\r
+  Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or\r
+  returns the system default according to the optional inputs.\r
+\r
+  This is a internal function.\r
 \r
   @param  Private                 HII database driver private data.\r
   @param  StringInfo              Points to the string output information,\r
                                   including the color and font.\r
-  @param  SystemInfo              If not NULL, points to system default font and\r
-                                  color when incoming StringInfo does not match the\r
-                                  default.  Points to NULL if matches. It's\r
-                                  caller's reponsibility to free this buffer.\r
+  @param  SystemInfo              If not NULL, points to system default font and color.\r
+\r
   @param  SystemInfoLen           If not NULL, output the length of default system\r
                                   info.\r
 \r
@@ -921,7 +945,6 @@ GetSystemFont (
   @retval FALSE                   No.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 IsSystemFontInfo (\r
   IN  HII_DATABASE_PRIVATE_DATA      *Private,\r
@@ -933,6 +956,7 @@ IsSystemFontInfo (
   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
@@ -940,28 +964,71 @@ IsSystemFontInfo (
     return TRUE;\r
   }\r
 \r
-  //\r
-  // Check whether incoming string font and color matches system default.\r
-  //\r
   Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Record the system default info.\r
+  //\r
   if (SystemInfo != NULL) {\r
     *SystemInfo = SystemDefault;\r
-  } else {\r
-    SafeFreePool (SystemDefault);\r
   }\r
 \r
   if (SystemInfoLen != NULL) {\r
     *SystemInfoLen = DefaultLen;\r
   }\r
 \r
-  if (StringInfo == NULL ||\r
-      (StringInfo != NULL && CompareMem (SystemDefault, StringInfo, DefaultLen) == 0)) {\r
+  if (StringInfo == NULL) {\r
     return TRUE;\r
   }\r
 \r
-  return FALSE;\r
+  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
+  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
+  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
+  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
+      goto Exit;\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
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  Flag = TRUE;\r
+\r
+Exit:\r
+  if (SystemInfo == NULL) {\r
+    if (SystemDefault != NULL) {\r
+      FreePool (SystemDefault);\r
+    }\r
+  }\r
+  return Flag;\r
 }\r
 \r
 \r
@@ -1277,77 +1344,79 @@ IsFontInfoExisted (
 /**\r
   Check whether the unicode represents a line break or not.\r
 \r
+  This is a internal function. Please see Section 27.2.6 of the UEFI Specification\r
+  for a description of the supported string format.\r
+\r
   @param  Char                    Unicode character\r
 \r
-  @retval 0                       Yes, it is a line break.\r
-  @retval 1                       Yes, it is a hyphen that desires a line break\r
-                                  after this character.\r
-  @retval 2                       Yes, it is a dash that desires a line break\r
-                                  before and after it.\r
+  @retval 0                       Yes, it forces a line break.\r
+  @retval 1                       Yes, it presents a line break opportunity\r
+  @retval 2                       Yes, it requires a line break happen before and after it.\r
   @retval -1                      No, it is not a link break.\r
 \r
 **/\r
-STATIC\r
 INT8\r
 IsLineBreak (\r
   IN  CHAR16    Char\r
   )\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 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
@@ -1372,7 +1441,10 @@ IsLineBreak (
                                   will be allocated to hold the generated image and\r
                                   the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\r
-  @param  BltX,BLTY               Specifies the offset from the left and top edge\r
+  @param  BltX                    Specifies the offset from the left and top edge\r
+                                  of the image of the first character cell in the\r
+                                  image.\r
+  @param  BltY                    Specifies the offset from the left and top edge\r
                                   of the image of the first character cell in the\r
                                   image.\r
   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this\r
@@ -1400,6 +1472,7 @@ IsLineBreak (
   @retval EFI_OUT_OF_RESOURCES    Unable to allocate an output buffer for\r
                                   RowInfoArray or Blt.\r
   @retval EFI_INVALID_PARAMETER   The String or Blt was NULL.\r
+  @retval EFI_INVALID_PARAMETER Flags were invalid combination..\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1448,6 +1521,7 @@ HiiStringToImage (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL       *BufferPtr;\r
   UINTN                               RowInfoSize;\r
   BOOLEAN                             LineBreak;\r
+  UINTN                               StrLength;\r
 \r
   //\r
   // Check incoming parameters.\r
@@ -1470,30 +1544,55 @@ HiiStringToImage (
   //\r
   // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.\r
   //\r
-  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLEAN_X) {\r
+  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLEAN_Y) {\r
+  if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) ==  EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   //\r
   // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\r
   //\r
-  if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLEAN_X)) ==  (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLEAN_X)) {\r
+  if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) ==  (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  GlyphBuf = (UINT8 **) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8 *));\r
+  if (*Blt == NULL) {\r
+    //\r
+    // Create a new bitmap and draw the string onto this image.\r
+    //\r
+    Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
+    if (Image == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    Image->Width  = 800;\r
+    Image->Height = 600;\r
+    Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+    if (Image->Image.Bitmap == NULL) {\r
+      FreePool (Image);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    //\r
+    // Other flags are not permitted when Blt is NULL.\r
+    //\r
+    Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
+    *Blt = Image;\r
+  }\r
+\r
+  StrLength = StrLen(String);\r
+  GlyphBuf = (UINT8 **) AllocateZeroPool (StrLength * sizeof (UINT8 *));\r
   ASSERT (GlyphBuf != NULL);\r
-  Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (EFI_HII_GLYPH_INFO));\r
+  Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));\r
   ASSERT (Cell != NULL);\r
-  Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));\r
+  Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));\r
   ASSERT (Attributes != NULL);\r
 \r
   RowInfo       = NULL;\r
   Status        = EFI_SUCCESS;\r
   StringIn2     = NULL;\r
   SystemDefault = NULL;\r
+  StringIn      = NULL;\r
 \r
   //\r
   // Calculate the string output information, including specified color and font .\r
@@ -1512,6 +1611,10 @@ HiiStringToImage (
     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
@@ -1524,11 +1627,13 @@ HiiStringToImage (
       Foreground  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;\r
       Background  = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;\r
 \r
-    } else {\r
+    } else if (Status == EFI_SUCCESS) {\r
       FontInfo   = &StringInfoOut->FontInfo;\r
       Height     = StringInfoOut->FontInfo.FontSize;\r
       Foreground = StringInfoOut->ForegroundColor;\r
       Background = StringInfoOut->BackgroundColor;\r
+    } else {\r
+      goto Exit;\r
     }\r
   }\r
 \r
@@ -1537,7 +1642,6 @@ HiiStringToImage (
   //\r
 \r
   StringPtr = String;\r
-  StringIn  = NULL;\r
 \r
   //\r
   // Ignore line-break characters only. Hyphens or dash character will be displayed\r
@@ -1571,14 +1675,14 @@ HiiStringToImage (
   }\r
   Index     = 0;\r
   StringTmp = StringIn2;\r
-\r
-  while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {\r
+  StrLength = StrLen(StringPtr);\r
+  while (*StringPtr != 0 && Index < StrLength) {\r
     Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
     if (Status == EFI_NOT_FOUND) {\r
       if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
-        SafeFreePool (GlyphBuf[Index]);\r
         GlyphBuf[Index] = NULL;\r
-        StringPtr++;\r
+        *StringTmp++ = *StringPtr++;\r
+        Index++;\r
       } else {\r
         //\r
         // Unicode 0xFFFD must exist in current hii database if this flag is not set.\r
@@ -1614,161 +1718,172 @@ HiiStringToImage (
   // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
   // Otherwise render this string to a new allocated image and output it.\r
   //\r
-  if (*Blt != NULL) {\r
-    Image     = *Blt;\r
-    BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
-    MaxRowNum = (UINT16) (Image->Height / Height);\r
-    if (Image->Height % Height != 0) {\r
-      MaxRowNum++;\r
-    }\r
+  Image     = *Blt;\r
+  BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
+  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
+  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
+\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
+\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
     //\r
-    // Format the glyph buffer according to flags.\r
+    // Calculate how many characters there are in a row.\r
     //\r
+    RowInfo[RowIndex].StartIndex = Index;\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
+    while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\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 forces a line break that ends this row.\r
+        //\r
+        Index++;\r
+        break;\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
       //\r
-      // Calculate how many characters there are in a row.\r
+      // If the glyph of the character is existing, then accumulate the actual printed width\r
       //\r
-      RowInfo[RowIndex].StartIndex = Index;\r
-\r
-      while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
+      if (GlyphBuf[Index] != NULL) {\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
 \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
+      Index++;\r
+    }\r
 \r
-        Index++;\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
+    //\r
+    Index--;\r
+    if (!SysFontFlag) {\r
+      LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\r
+    }\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
-      // If this character is the last character of a row, we need not\r
-      // draw its (AdvanceX - Width) for next character.\r
+      // Record right-most character in RowInfo even if it is partially displayed.\r
       //\r
-      Index--;\r
-      if (!SysFontFlag) {\r
-        LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\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
-      // 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
+      // 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 ((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
+      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
         }\r
+        RowInfo[RowIndex].LineHeight     = LineHeight;\r
+      } else {\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
+        // There is only one column and it can not be drawn so that return directly.\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
+        Status = EFI_SUCCESS;\r
+        goto Exit;\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
+      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
+            //\r
+            // relocate to the character after the right-most line break opportunity of this line\r
+            //\r
+            Index = Index1 + 1;\r
+            break;\r
+          }\r
+        }\r
+      }\r
       //\r
-      // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X 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 (LineWidth + BltX <= Image->Width ||\r
-          (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLEAN_X) == 0)) {\r
-        //\r
-        // Record right-most character in RowInfo even if it is partially displayed.\r
-        //\r
-        RowInfo[RowIndex].EndIndex       = Index;\r
-        RowInfo[RowIndex].LineWidth      = LineWidth;\r
-        RowInfo[RowIndex].LineHeight     = LineHeight;\r
-        RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
-      } else {\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
+\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 && 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
-        // 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
+        // Don't draw at all if the row's bottom-most on pixel cannot fit.\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
-          }\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
-          //\r
-          Status = EFI_SUCCESS;\r
-          goto Exit;\r
-        }\r
+        break;\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
-      //\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
+    // 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
+      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
+        if (GlyphBuf[Index1] != NULL) {\r
           //\r
-          // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
+          // Only BLT these character which have corrsponding glyph in font basebase.\r
           //\r
-          break;\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
-        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
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
@@ -1779,37 +1894,50 @@ HiiStringToImage (
             &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
         }\r
-        Status = Image->Image.Screen->Blt (\r
-                                        Image->Image.Screen,\r
-                                        BltBuffer,\r
-                                        EfiBltBufferToVideo,\r
-                                        0,\r
-                                        0,\r
-                                        BltX,\r
-                                        BltY,\r
-                                        RowInfo[RowIndex].LineWidth,\r
-                                        RowInfo[RowIndex].LineHeight,\r
-                                        0\r
-                                        );\r
-        if (EFI_ERROR (Status)) {\r
-          SafeFreePool (BltBuffer);\r
-          goto Exit;\r
+        if (ColumnInfoArray != NULL) {\r
+          if (GlyphBuf[Index1] == NULL) {\r
+            *ColumnInfoArray = 0;\r
+          } else {\r
+            *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
+          }\r
+          ColumnInfoArray++;\r
         }\r
+      }\r
+      //\r
+      // Recalculate the start point of X/Y axis to draw multi-lines with the order of top-to-down\r
+      //\r
+      if (RowIndex != 0) {\r
+        BltX = 0;\r
+        BltY += RowInfo[RowIndex].LineHeight;\r
+      }\r
 \r
-        SafeFreePool (BltBuffer);\r
+      Status = Image->Image.Screen->Blt (\r
+                                      Image->Image.Screen,\r
+                                      BltBuffer,\r
+                                      EfiBltBufferToVideo,\r
+                                      0,\r
+                                      0,\r
+                                      BltX,\r
+                                      BltY,\r
+                                      RowInfo[RowIndex].LineWidth,\r
+                                      RowInfo[RowIndex].LineHeight,\r
+                                      0\r
+                                      );\r
+      if (EFI_ERROR (Status)) {\r
+        FreePool (BltBuffer);\r
+        goto Exit;\r
+      }\r
 \r
-      } else {\r
-        for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+      FreePool (BltBuffer);\r
+\r
+    } else {\r
+      for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
+        if (GlyphBuf[Index1] != NULL) {\r
+          //\r
+          // Only BLT these character which have corrsponding glyph in font basebase.\r
+          //\r
           GlyphToImage (\r
             GlyphBuf[Index1],\r
             Foreground,\r
@@ -1820,97 +1948,83 @@ HiiStringToImage (
             &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) {\r
+            *ColumnInfoArray = 0;\r
+          } else {\r
+            *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
           }\r
+          ColumnInfoArray++;\r
         }\r
-        //\r
-        // Jump to next row\r
-        //\r
-        BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
       }\r
-\r
-      Index++;\r
-      RowIndex++;\r
-\r
+      //\r
+      // Jump to next row\r
+      //\r
+      BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
     }\r
 \r
-    //\r
-    // Write output parameters.\r
-    //\r
-    RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
-    if (RowInfoArray != NULL) {\r
-      *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
-      if (*RowInfoArray == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Exit;\r
-      }\r
-      CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
-    }\r
-    if (RowInfoArraySize != NULL) {\r
-      *RowInfoArraySize = RowIndex;\r
-    }\r
+    Index++;\r
+    RowIndex++;\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
+    if (Flags & EFI_HII_IGNORE_LINE_BREAK) {\r
+      //\r
+      // If setting IGNORE_LINE_BREAK attribute, only render one line to image\r
+      //\r
+      break;\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
+  //\r
+  // Write output parameters.\r
+  //\r
+  RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
+  if (RowInfoArray != NULL) {\r
+    *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
+    if (*RowInfoArray == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
     }\r
-\r
-    *Blt = Image;\r
+    CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\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
-    SafeFreePool (GlyphBuf[Index]);\r
+  for (Index = 0; Index < StrLength; Index++) {\r
+    if (GlyphBuf[Index] != NULL) {\r
+      FreePool (GlyphBuf[Index]);\r
+    }\r
+  }\r
+  if (StringIn != NULL) {\r
+    FreePool (StringIn);\r
+  }\r
+  if (StringIn2 != NULL) {\r
+    FreePool (StringIn2);\r
+  }\r
+  if (StringInfoOut != NULL) {\r
+    FreePool (StringInfoOut);\r
+  }\r
+  if (RowInfo != NULL) {\r
+    FreePool (RowInfo);\r
+  }\r
+  if (SystemDefault != NULL) {\r
+    FreePool (SystemDefault);\r
+  }\r
+  if (GlyphBuf != NULL) {\r
+    FreePool (GlyphBuf);\r
+  }\r
+  if (Cell != NULL) {\r
+    FreePool (Cell);\r
+  }\r
+  if (Attributes != NULL) {\r
+    FreePool (Attributes);\r
   }\r
-  SafeFreePool (StringIn);\r
-  SafeFreePool (StringIn2);\r
-  SafeFreePool (StringInfoOut);\r
-  SafeFreePool (RowInfo);\r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (GlyphBuf);\r
-  SafeFreePool (Cell);\r
-  SafeFreePool (Attributes);\r
 \r
   return Status;\r
 }\r
@@ -1941,7 +2055,10 @@ Exit:
                                   will be allocated to hold the generated image and\r
                                   the pointer updated on exit. It is the caller's\r
                                   responsibility to free this buffer.\r
-  @param  BltX,BLTY               Specifies the offset from the left and top edge\r
+  @param  BltX                    Specifies the offset from the left and top edge\r
+                                  of the image of the first character cell in the\r
+                                  image.\r
+  @param  BltY                    Specifies the offset from the left and top edge\r
                                   of the image of the first character cell in the\r
                                   image.\r
   @param  RowInfoArray            If this is non-NULL on entry, then on exit, this\r
@@ -1968,7 +2085,10 @@ Exit:
   @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_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
 \r
 **/\r
 EFI_STATUS\r
@@ -1990,8 +2110,17 @@ 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
+  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
@@ -2001,51 +2130,140 @@ HiiStringIdToImage (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
+  //\r
+  // Initialize string pointers to be NULL\r
+  //\r
+  SupportedLanguages = NULL;\r
+  CurrentLanguage    = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
+  StringInfo         = 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
+  CurrentLanguage = GetEfiGlobalVariable (L"PlatformLang");\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
-  Status = Private->HiiString.GetString (\r
-                                &Private->HiiString,\r
-                                Language,\r
-                                PackageList,\r
-                                StringId,\r
-                                String,\r
-                                &StringSize,\r
-                                NULL\r
-                                );\r
+  Status = HiiString->GetString (\r
+                        HiiString,\r
+                        BestLanguage,\r
+                        PackageList,\r
+                        StringId,\r
+                        String,\r
+                        &StringSize,\r
+                        &StringFontInfo\r
+                        );\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    SafeFreePool (String);\r
+    FreePool (String);\r
     String = (EFI_STRING) AllocateZeroPool (StringSize);\r
     if (String == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Exit;\r
     }\r
-    Status = Private->HiiString.GetString (\r
-                                  &Private->HiiString,\r
-                                  Language,\r
-                                  PackageList,\r
-                                  StringId,\r
-                                  String,\r
-                                  &StringSize,\r
-                                  NULL\r
-                                  );\r
-\r
+    Status = HiiString->GetString (\r
+                          HiiString,\r
+                          BestLanguage,\r
+                          PackageList,\r
+                          StringId,\r
+                          String,\r
+                          &StringSize,\r
+                          NULL\r
+                          );\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    SafeFreePool (String);\r
-    return Status;\r
+    goto Exit;\r
+  }\r
+    \r
+  //\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
+    FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + StrSize (StringFontInfo->FontName);\r
+    NewStringInfo = AllocateZeroPool (FontLen);\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
+    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
-  return HiiStringToImage (\r
+  Status = HiiStringToImage (\r
            This,\r
            Flags,\r
            String,\r
@@ -2058,6 +2276,27 @@ HiiStringIdToImage (
            ColumnInfoArray\r
            );\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
+  if (StringFontInfo != NULL) {\r
+    FreePool (StringFontInfo);\r
+  }\r
+  if (NewStringInfo != NULL) {\r
+    FreePool (NewStringInfo);\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 \r
@@ -2169,7 +2408,7 @@ HiiGetGlyph (
 \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
+    FreePool (Image);\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
   }\r
@@ -2210,10 +2449,18 @@ Exit:
     }\r
   }\r
 \r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (StringInfoOut);\r
-  SafeFreePool (String);\r
-  SafeFreePool (GlyphBuffer);\r
+  if (SystemDefault != NULL) {\r
+   FreePool (SystemDefault);\r
+  }\r
+  if (StringInfoOut != NULL) {\r
+    FreePool (StringInfoOut);\r
+  }\r
+  if (String != NULL) {\r
+    FreePool (String);\r
+  }\r
+  if (GlyphBuffer != NULL) {\r
+    FreePool (GlyphBuffer);\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -2231,7 +2478,9 @@ Exit:
                                   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
+                                  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
@@ -2242,7 +2491,7 @@ Exit:
 \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
@@ -2252,7 +2501,7 @@ EFIAPI
 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
+  IN  CONST EFI_FONT_DISPLAY_INFO    *StringInfoIn, OPTIONAL\r
   OUT       EFI_FONT_DISPLAY_INFO    **StringInfoOut,\r
   IN  CONST EFI_STRING               String OPTIONAL\r
   )\r
@@ -2267,51 +2516,75 @@ HiiGetFontInfo (
   EFI_STRING                         StringIn;\r
   EFI_FONT_HANDLE                    LocalFontHandle;\r
 \r
-  if (This == NULL || StringInfoIn == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\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
-       (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT))   ||\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
-       (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
-       (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {\r
+  if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \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
-  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
+    // 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
 \r
-    LocalFontHandle = Private->FontInfoList.ForwardLink;\r
-    Status = EFI_SUCCESS;\r
-    goto Exit;\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
+  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
+       (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE))   ||\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
+       (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
@@ -2331,22 +2604,26 @@ HiiGetFontInfo (
 \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
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
     InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
-  } else if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
+  }\r
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
     InfoOut.ForegroundColor = SystemDefault->ForegroundColor;\r
-  } else if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
+  }\r
+  if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
     InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
   }\r
+  \r
 \r
   FontInfo->FontSize  = InfoOut.FontInfo.FontSize;\r
   FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
 \r
   if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
+    //\r
+    // Test to guarantee all characters are available in the found font.\r
+    //    \r
     if (String != NULL) {\r
-      //\r
-      // Test to guarantee all characters are available in the found font.\r
-      //\r
       StringIn = String;\r
       while (*StringIn != 0) {\r
         Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);\r
@@ -2356,29 +2633,27 @@ HiiGetFontInfo (
         }\r
         StringIn++;\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
+    //\r
+    // Write to output parameter\r
+    //\r
+    if (StringInfoOut != NULL) {\r
+      StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
+      *StringInfoOut   = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);      \r
+      if (*StringInfoOut == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        LocalFontHandle = NULL;\r
+        goto Exit;\r
       }\r
-      LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
-\r
-      Status = EFI_SUCCESS;\r
-      goto Exit;\r
+      \r
+      CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
+      CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
     }\r
-  } else {\r
-    LocalFontHandle = NULL;\r
-  }\r
+    \r
+    LocalFontHandle = GlobalFont->Entry.ForwardLink;    \r
+    Status = EFI_SUCCESS;\r
+    goto Exit;\r
+  }  \r
 \r
   Status = EFI_NOT_FOUND;\r
 \r
@@ -2388,8 +2663,13 @@ Exit:
     *FontHandle = LocalFontHandle;\r
   }\r
 \r
-  SafeFreePool (SystemDefault);\r
-  SafeFreePool (FontInfo);\r
+  if (SystemDefault != NULL) {\r
+   FreePool (SystemDefault);\r
+  }\r
+  if (FontInfo != NULL) {\r
+   FreePool (FontInfo);\r
+  }\r
   return Status;\r
 }\r
 \r
+\r