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
//\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
}\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
}\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
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
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
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
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
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
// 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
//\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
// 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
\r
} // end of for (Ypos=0...)\r
\r
- *Origin = BltBuffer + Cell->Width;\r
+ *Origin = *Origin + Cell->AdvanceX;\r
}\r
\r
\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 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
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
{\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
// 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
Foreground,\r
Background,\r
ImageWidth,\r
- ImageHeight,\r
+ RowWidth,\r
+ RowHeight,\r
Transparent,\r
Origin\r
);\r
Foreground,\r
Background,\r
ImageWidth,\r
- ImageHeight,\r
+ RowWidth,\r
+ RowHeight,\r
Transparent,\r
Origin\r
);\r
Foreground,\r
Background,\r
ImageWidth,\r
- ImageHeight,\r
+ RowWidth,\r
+ RowHeight,\r
Transparent,\r
Origin\r
);\r
Foreground,\r
Background,\r
ImageWidth,\r
- ImageHeight,\r
+ BaseLine,\r
+ RowWidth,\r
+ RowHeight,\r
Transparent,\r
Cell,\r
Attributes,\r
@param InputCell Buffer which stores cell information of the\r
encoded bitmap.\r
@param GlyphBuffer Output the corresponding bitmap data of the found\r
- block. It is the caller's responsiblity to free\r
+ block. It is the caller's responsibility to free\r
this buffer.\r
@param Cell Output cell information of the encoded bitmap.\r
@param GlyphBufferLen If not NULL, output the length of GlyphBuffer.\r
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
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
@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
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
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
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
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
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
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
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
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
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
}\r
\r
if (CharValue == (CHAR16) (-1)) {\r
+ FontPackage->BaseLine = BaseLine;\r
+ FontPackage->Height = (UINT16) (BaseLine - MinOffsetY);\r
return EFI_SUCCESS;\r
}\r
\r
)\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
{\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
//\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
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
}\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
}\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
@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
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
}\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
/**\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
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
EFI_HII_ROW_INFO *RowInfo;\r
UINTN LineWidth;\r
UINTN LineHeight;\r
+ UINTN LineOffset;\r
+ UINTN LastLineHeight;\r
UINTN BaseLineOffset;\r
UINT16 MaxRowNum;\r
UINT16 RowIndex;\r
UINTN Index;\r
+ UINTN NextIndex;\r
UINTN Index1;\r
EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
EFI_FONT_DISPLAY_INFO *SystemDefault;\r
EFI_STRING StringIn;\r
EFI_STRING StringIn2;\r
UINT16 Height;\r
+ UINT16 BaseLine;\r
EFI_FONT_INFO *FontInfo;\r
BOOLEAN SysFontFlag;\r
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *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
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
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
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
}\r
}\r
\r
+ //\r
+ // Use the maximum height of font as the base line.\r
+ // And, use the maximum height as line height.\r
+ //\r
+ LineHeight = Height;\r
+ LastLineHeight = Height;\r
+ BaseLineOffset = Height - BaseLine;\r
+\r
//\r
// Parse the string to be displayed to drop some ignored characters.\r
//\r
}\r
//\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
}\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
);\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
// 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
}\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
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
{\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
}\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
);\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
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
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
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
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
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ StringInfoOutLen = 0;\r
FontInfo = NULL;\r
SystemDefault = NULL;\r
LocalFontHandle = NULL;\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
+ 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
\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
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
//\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