summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Universal/HiiDatabaseDxe/Font.c')
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/Font.c6036
1 files changed, 3018 insertions, 3018 deletions
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
index 8a0b12f72f..fc1fee17db 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
@@ -1,3018 +1,3018 @@
-/** @file
-Implementation for EFI_HII_FONT_PROTOCOL.
-
-
-Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "HiiDatabase.h"
-
-EFI_GRAPHICS_OUTPUT_BLT_PIXEL mHiiEfiColors[16] = {
- //
- // B G R
- //
- { 0x00, 0x00, 0x00, 0x00 }, // BLACK
- { 0x98, 0x00, 0x00, 0x00 }, // BLUE
- { 0x00, 0x98, 0x00, 0x00 }, // GREEN
- { 0x98, 0x98, 0x00, 0x00 }, // CYAN
- { 0x00, 0x00, 0x98, 0x00 }, // RED
- { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
- { 0x00, 0x98, 0x98, 0x00 }, // BROWN
- { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
- { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
- { 0xff, 0x00, 0x00, 0x00 }, // LIGHTBLUE
- { 0x00, 0xff, 0x00, 0x00 }, // LIGHTGREEN
- { 0xff, 0xff, 0x00, 0x00 }, // LIGHTCYAN
- { 0x00, 0x00, 0xff, 0x00 }, // LIGHTRED
- { 0xff, 0x00, 0xff, 0x00 }, // LIGHTMAGENTA
- { 0x00, 0xff, 0xff, 0x00 }, // YELLOW
- { 0xff, 0xff, 0xff, 0x00 }, // WHITE
-};
-
-/**
- Insert a character cell information to the list specified by GlyphInfoList.
-
- This is a internal function.
-
- @param CharValue Unicode character value, which identifies a glyph
- block.
- @param GlyphInfoList HII_GLYPH_INFO list head.
- @param Cell Incoming character cell information.
-
- @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
- @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
- task.
-
-**/
-EFI_STATUS
-NewCell (
- IN CHAR16 CharValue,
- IN LIST_ENTRY *GlyphInfoList,
- IN EFI_HII_GLYPH_INFO *Cell
- )
-{
- HII_GLYPH_INFO *GlyphInfo;
-
- ASSERT (Cell != NULL && GlyphInfoList != NULL);
-
- GlyphInfo = (HII_GLYPH_INFO *)AllocateZeroPool (sizeof (HII_GLYPH_INFO));
- if (GlyphInfo == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // GlyphInfoList stores a list of default character cell information, each is
- // identified by "CharId".
- //
- GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;
- GlyphInfo->CharId = CharValue;
- if (Cell->AdvanceX == 0) {
- Cell->AdvanceX = Cell->Width;
- }
-
- CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));
- InsertTailList (GlyphInfoList, &GlyphInfo->Entry);
-
- return EFI_SUCCESS;
-}
-
-/**
- Get a character cell information from the list specified by GlyphInfoList.
-
- This is a internal function.
-
- @param CharValue Unicode character value, which identifies a glyph
- block.
- @param GlyphInfoList HII_GLYPH_INFO list head.
- @param Cell Buffer which stores output character cell
- information.
-
- @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
- @retval EFI_NOT_FOUND The character info specified by CharValue does
- not exist.
-
-**/
-EFI_STATUS
-GetCell (
- IN CHAR16 CharValue,
- IN LIST_ENTRY *GlyphInfoList,
- OUT EFI_HII_GLYPH_INFO *Cell
- )
-{
- HII_GLYPH_INFO *GlyphInfo;
- LIST_ENTRY *Link;
-
- ASSERT (Cell != NULL && GlyphInfoList != NULL);
-
- //
- // Since the EFI_HII_GIBT_DEFAULTS block won't increment CharValueCurrent,
- // the value of "CharId" of a default character cell which is used for a
- // EFI_HII_GIBT_GLYPH_DEFAULT or EFI_HII_GIBT_GLYPHS_DEFAULT should be
- // less or equal to the value of "CharValueCurrent" of this default block.
- //
- // For instance, if the CharId of a GlyphInfoList is {1, 3, 7}, a default glyph
- // with CharValue equals "7" uses the GlyphInfo with CharId = 7;
- // a default glyph with CharValue equals "6" uses the GlyphInfo with CharId = 3.
- //
- for (Link = GlyphInfoList->BackLink; Link != GlyphInfoList; Link = Link->BackLink) {
- GlyphInfo = CR (Link, HII_GLYPH_INFO, Entry, HII_GLYPH_INFO_SIGNATURE);
- if (GlyphInfo->CharId <= CharValue) {
- CopyMem (Cell, &GlyphInfo->Cell, sizeof (EFI_HII_GLYPH_INFO));
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Convert the glyph for a single character into a bitmap.
-
- This is a internal function.
-
- @param Private HII database driver private data.
- @param Char Character to retrieve.
- @param StringInfo Points to the string font and color information
- or NULL if the string should use the default
- system font and color.
- @param GlyphBuffer Buffer to store the retrieved bitmap data.
- @param Cell Points to EFI_HII_GLYPH_INFO structure.
- @param Attributes If not NULL, output the glyph attributes if any.
-
- @retval EFI_SUCCESS Glyph bitmap outputted.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer GlyphBuffer.
- @retval EFI_NOT_FOUND The glyph was unknown can not be found.
- @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
-
-**/
-EFI_STATUS
-GetGlyphBuffer (
- IN HII_DATABASE_PRIVATE_DATA *Private,
- IN CHAR16 Char,
- IN EFI_FONT_INFO *StringInfo,
- OUT UINT8 **GlyphBuffer,
- OUT EFI_HII_GLYPH_INFO *Cell,
- OUT UINT8 *Attributes OPTIONAL
- )
-{
- HII_DATABASE_RECORD *Node;
- LIST_ENTRY *Link;
- HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFont;
- LIST_ENTRY *Link1;
- UINT16 Index;
- EFI_NARROW_GLYPH Narrow;
- EFI_WIDE_GLYPH Wide;
- HII_GLOBAL_FONT_INFO *GlobalFont;
- UINTN HeaderSize;
- EFI_NARROW_GLYPH *NarrowPtr;
- EFI_WIDE_GLYPH *WidePtr;
-
- if ((GlyphBuffer == NULL) || (Cell == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ZeroMem (Cell, sizeof (EFI_HII_GLYPH_INFO));
-
- //
- // If StringInfo is not NULL, it must point to an existing EFI_FONT_INFO rather
- // than system default font and color.
- // If NULL, try to find the character in simplified font packages since
- // default system font is the fixed font (narrow or wide glyph).
- //
- if (StringInfo != NULL) {
- if (!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Attributes != NULL) {
- *Attributes = PROPORTIONAL_GLYPH;
- }
-
- return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);
- } else {
- HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);
-
- for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
- Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
- for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;
- Link1 != &Node->PackageList->SimpleFontPkgHdr;
- Link1 = Link1->ForwardLink
- )
- {
- SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
- //
- // Search the narrow glyph array
- //
- NarrowPtr = (EFI_NARROW_GLYPH *)((UINT8 *)(SimpleFont->SimpleFontPkgHdr) + HeaderSize);
- for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {
- CopyMem (&Narrow, NarrowPtr + Index, sizeof (EFI_NARROW_GLYPH));
- if (Narrow.UnicodeWeight == Char) {
- *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT);
- if (*GlyphBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Cell->Width = EFI_GLYPH_WIDTH;
- Cell->Height = EFI_GLYPH_HEIGHT;
- Cell->AdvanceX = Cell->Width;
- CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);
- if (Attributes != NULL) {
- *Attributes = (UINT8)(Narrow.Attributes | NARROW_GLYPH);
- }
-
- return EFI_SUCCESS;
- }
- }
-
- //
- // Search the wide glyph array
- //
- WidePtr = (EFI_WIDE_GLYPH *)(NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);
- for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {
- CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));
- if (Wide.UnicodeWeight == Char) {
- *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);
- if (*GlyphBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Cell->Width = EFI_GLYPH_WIDTH * 2;
- Cell->Height = EFI_GLYPH_HEIGHT;
- Cell->AdvanceX = Cell->Width;
- CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);
- CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);
- if (Attributes != NULL) {
- *Attributes = (UINT8)(Wide.Attributes | EFI_GLYPH_WIDE);
- }
-
- return EFI_SUCCESS;
- }
- }
- }
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Convert bitmap data of the glyph to blt structure.
-
- This is a internal function.
-
- @param GlyphBuffer Buffer points to bitmap data of glyph.
- @param Foreground The color of the "on" pixels in the glyph in the
- bitmap.
- @param Background The color of the "off" pixels in the glyph in the
- bitmap.
- @param ImageWidth Width of the whole image in pixels.
- @param RowWidth The width of the text on the line, in pixels.
- @param RowHeight The height of the line, in pixels.
- @param Transparent If TRUE, the Background color is ignored and all
- "off" pixels in the character's drawn will use the
- pixel value from BltBuffer.
- @param Origin On input, points to the origin of the to be
- displayed character, on output, points to the
- next glyph's origin.
-
-**/
-VOID
-NarrowGlyphToBlt (
- IN UINT8 *GlyphBuffer,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
- IN UINT16 ImageWidth,
- IN UINTN RowWidth,
- IN UINTN RowHeight,
- IN BOOLEAN Transparent,
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
- )
-{
- UINT8 Xpos;
- UINT8 Ypos;
- UINT8 Height;
- UINT8 Width;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
-
- ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);
-
- Height = EFI_GLYPH_HEIGHT;
- Width = EFI_GLYPH_WIDTH;
-
- //
- // Move position to the left-top corner of char.
- //
- Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;
-
- //
- // Char may be partially displayed when CLIP_X or CLIP_Y is not set.
- //
- if (RowHeight < Height) {
- Height = (UINT8)RowHeight;
- }
-
- if (RowWidth < Width) {
- Width = (UINT8)RowWidth;
- }
-
- for (Ypos = 0; Ypos < Height; Ypos++) {
- for (Xpos = 0; Xpos < Width; Xpos++) {
- if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {
- Buffer[Ypos * ImageWidth + Xpos] = Foreground;
- } else {
- if (!Transparent) {
- Buffer[Ypos * ImageWidth + Xpos] = Background;
- }
- }
- }
- }
-
- *Origin = *Origin + EFI_GLYPH_WIDTH;
-}
-
-/**
- Convert bitmap data of the glyph to blt structure.
-
- This is a internal function.
-
- @param GlyphBuffer Buffer points to bitmap data of glyph.
- @param Foreground The color of the "on" pixels in the glyph in the
- bitmap.
- @param Background The color of the "off" pixels in the glyph in the
- bitmap.
- @param ImageWidth Width of the whole image in pixels.
- @param BaseLine BaseLine in the line.
- @param RowWidth The width of the text on the line, in pixels.
- @param RowHeight The height of the line, in pixels.
- @param Transparent If TRUE, the Background color is ignored and all
- "off" pixels in the character's drawn will use the
- pixel value from BltBuffer.
- @param Cell Points to EFI_HII_GLYPH_INFO structure.
- @param Attributes The attribute of incoming glyph in GlyphBuffer.
- @param Origin On input, points to the origin of the to be
- displayed character, on output, points to the
- next glyph's origin.
-
-
-**/
-VOID
-GlyphToBlt (
- IN UINT8 *GlyphBuffer,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
- IN UINT16 ImageWidth,
- IN UINT16 BaseLine,
- IN UINTN RowWidth,
- IN UINTN RowHeight,
- IN BOOLEAN Transparent,
- IN CONST EFI_HII_GLYPH_INFO *Cell,
- IN UINT8 Attributes,
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
- )
-{
- UINT16 Xpos;
- UINT16 Ypos;
- UINT8 Data;
- UINT16 Index;
- UINT16 YposOffset;
- UINTN OffsetY;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
-
- ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
-
- //
- // Only adjust origin position if char has no bitmap.
- //
- if (GlyphBuffer == NULL) {
- *Origin = *Origin + Cell->AdvanceX;
- return;
- }
-
- //
- // Move position to the left-top corner of char.
- //
- BltBuffer = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;
- YposOffset = (UINT16)(BaseLine - (Cell->OffsetY + Cell->Height));
-
- //
- // Since non-spacing key will be printed OR'd with the previous glyph, don't
- // write 0.
- //
- if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
- Transparent = TRUE;
- }
-
- //
- // The glyph's upper left hand corner pixel is the most significant bit of the
- // first bitmap byte.
- //
- for (Ypos = 0; Ypos < Cell->Height && (((UINT32)Ypos + YposOffset) < RowHeight); Ypos++) {
- OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);
-
- //
- // All bits in these bytes are meaningful.
- //
- for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {
- Data = *(GlyphBuffer + OffsetY + Xpos);
- for (Index = 0; Index < 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
- if ((Data & (1 << (8 - Index - 1))) != 0) {
- BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
- } else {
- if (!Transparent) {
- BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
- }
- }
- }
- }
-
- if (Cell->Width % 8 != 0) {
- //
- // There are some padding bits in this byte. Ignore them.
- //
- Data = *(GlyphBuffer + OffsetY + Xpos);
- for (Index = 0; Index < Cell->Width % 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
- if ((Data & (1 << (8 - Index - 1))) != 0) {
- BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
- } else {
- if (!Transparent) {
- BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
- }
- }
- }
- } // end of if (Width % 8...)
- } // end of for (Ypos=0...)
-
- *Origin = *Origin + Cell->AdvanceX;
-}
-
-/**
- Convert bitmap data of the glyph to blt structure.
-
- This is a internal function.
-
- @param GlyphBuffer Buffer points to bitmap data of glyph.
- @param Foreground The color of the "on" pixels in the glyph in the
- bitmap.
- @param Background The color of the "off" pixels in the glyph in the
- bitmap.
- @param ImageWidth Width of the whole image in pixels.
- @param BaseLine BaseLine in the line.
- @param RowWidth The width of the text on the line, in pixels.
- @param RowHeight The height of the line, in pixels.
- @param Transparent If TRUE, the Background color is ignored and all
- "off" pixels in the character's drawn will use the
- pixel value from BltBuffer.
- @param Cell Points to EFI_HII_GLYPH_INFO structure.
- @param Attributes The attribute of incoming glyph in GlyphBuffer.
- @param Origin On input, points to the origin of the to be
- displayed character, on output, points to the
- next glyph's origin.
-
- @return Points to the address of next origin node in BltBuffer.
-
-**/
-VOID
-GlyphToImage (
- IN UINT8 *GlyphBuffer,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
- IN UINT16 ImageWidth,
- IN UINT16 BaseLine,
- IN UINTN RowWidth,
- IN UINTN RowHeight,
- IN BOOLEAN Transparent,
- IN CONST EFI_HII_GLYPH_INFO *Cell,
- IN UINT8 Attributes,
- IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
- )
-{
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
-
- ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
-
- Buffer = *Origin;
-
- if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
- //
- // This character is a non-spacing key, print it OR'd with the previous glyph.
- // without advancing cursor.
- //
- Buffer -= Cell->AdvanceX;
- GlyphToBlt (
- GlyphBuffer,
- Foreground,
- Background,
- ImageWidth,
- BaseLine,
- RowWidth,
- RowHeight,
- Transparent,
- Cell,
- Attributes,
- &Buffer
- );
- } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {
- //
- // This character is wide glyph, i.e. 16 pixels * 19 pixels.
- // Draw it as two narrow glyphs.
- //
- NarrowGlyphToBlt (
- GlyphBuffer,
- Foreground,
- Background,
- ImageWidth,
- RowWidth,
- RowHeight,
- Transparent,
- Origin
- );
-
- NarrowGlyphToBlt (
- GlyphBuffer + EFI_GLYPH_HEIGHT,
- Foreground,
- Background,
- ImageWidth,
- RowWidth,
- RowHeight,
- Transparent,
- Origin
- );
- } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {
- //
- // This character is narrow glyph, i.e. 8 pixels * 19 pixels.
- //
- NarrowGlyphToBlt (
- GlyphBuffer,
- Foreground,
- Background,
- ImageWidth,
- RowWidth,
- RowHeight,
- Transparent,
- Origin
- );
- } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {
- //
- // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.
- //
- GlyphToBlt (
- GlyphBuffer,
- Foreground,
- Background,
- ImageWidth,
- BaseLine,
- RowWidth,
- RowHeight,
- Transparent,
- Cell,
- Attributes,
- Origin
- );
- }
-}
-
-/**
- Write the output parameters of FindGlyphBlock().
-
- This is a internal function.
-
- @param BufferIn Buffer which stores the bitmap data of the found
- block.
- @param BufferLen Length of BufferIn.
- @param InputCell Buffer which stores cell information of the
- encoded bitmap.
- @param GlyphBuffer Output the corresponding bitmap data of the found
- block. It is the caller's responsibility to free
- this buffer.
- @param Cell Output cell information of the encoded bitmap.
- @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.
-
- @retval EFI_SUCCESS The operation is performed successfully.
- @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
- @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
- task.
-
-**/
-EFI_STATUS
-WriteOutputParam (
- IN UINT8 *BufferIn,
- IN UINTN BufferLen,
- IN EFI_HII_GLYPH_INFO *InputCell,
- OUT UINT8 **GlyphBuffer OPTIONAL,
- OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,
- OUT UINTN *GlyphBufferLen OPTIONAL
- )
-{
- if ((BufferIn == NULL) || (InputCell == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Cell != NULL) {
- CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));
- }
-
- if ((GlyphBuffer != NULL) && (BufferLen > 0)) {
- *GlyphBuffer = (UINT8 *)AllocateZeroPool (BufferLen);
- if (*GlyphBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- CopyMem (*GlyphBuffer, BufferIn, BufferLen);
- }
-
- if (GlyphBufferLen != NULL) {
- *GlyphBufferLen = BufferLen;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Parse all glyph blocks to find a glyph block specified by CharValue.
- If CharValue = (CHAR16) (-1), collect all default character cell information
- within this font package and backup its information.
-
- @param FontPackage Hii string package instance.
- @param CharValue Unicode character value, which identifies a glyph
- block.
- @param GlyphBuffer Output the corresponding bitmap data of the found
- block. It is the caller's responsibility to free
- this buffer.
- @param Cell Output cell information of the encoded bitmap.
- @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.
-
- @retval EFI_SUCCESS The bitmap data is retrieved successfully.
- @retval EFI_NOT_FOUND The specified CharValue does not exist in current
- database.
- @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
- task.
-
-**/
-EFI_STATUS
-FindGlyphBlock (
- IN HII_FONT_PACKAGE_INSTANCE *FontPackage,
- IN CHAR16 CharValue,
- OUT UINT8 **GlyphBuffer OPTIONAL,
- OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,
- OUT UINTN *GlyphBufferLen OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINT8 *BlockPtr;
- UINT16 CharCurrent;
- UINT16 Length16;
- UINT32 Length32;
- EFI_HII_GIBT_GLYPHS_BLOCK Glyphs;
- UINTN BufferLen;
- UINT16 Index;
- EFI_HII_GLYPH_INFO DefaultCell;
- EFI_HII_GLYPH_INFO LocalCell;
- INT16 MinOffsetY;
- UINT16 BaseLine;
-
- ASSERT (FontPackage != NULL);
- ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);
- BaseLine = 0;
- MinOffsetY = 0;
-
- if (CharValue == (CHAR16)(-1)) {
- //
- // Collect the cell information specified in font package fixed header.
- // Use CharValue =0 to represent this particular cell.
- //
- Status = NewCell (
- 0,
- &FontPackage->GlyphInfoList,
- (EFI_HII_GLYPH_INFO *)((UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32))
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- CopyMem (
- &LocalCell,
- (UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32),
- sizeof (EFI_HII_GLYPH_INFO)
- );
- }
-
- BlockPtr = FontPackage->GlyphBlock;
- CharCurrent = 1;
- BufferLen = 0;
-
- while (*BlockPtr != EFI_HII_GIBT_END) {
- switch (*BlockPtr) {
- case EFI_HII_GIBT_DEFAULTS:
- //
- // Collect all default character cell information specified by
- // EFI_HII_GIBT_DEFAULTS.
- //
- if (CharValue == (CHAR16)(-1)) {
- Status = NewCell (
- CharCurrent,
- &FontPackage->GlyphInfoList,
- (EFI_HII_GLYPH_INFO *)(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- CopyMem (
- &LocalCell,
- BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
- sizeof (EFI_HII_GLYPH_INFO)
- );
- if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
- BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
- }
-
- if (MinOffsetY > LocalCell.OffsetY) {
- MinOffsetY = LocalCell.OffsetY;
- }
- }
-
- BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);
- break;
-
- case EFI_HII_GIBT_DUPLICATE:
- if (CharCurrent == CharValue) {
- CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));
- CharCurrent = 1;
- BlockPtr = FontPackage->GlyphBlock;
- continue;
- }
-
- CharCurrent++;
- BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);
- break;
-
- case EFI_HII_GIBT_EXT1:
- BlockPtr += *(UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));
- break;
- case EFI_HII_GIBT_EXT2:
- CopyMem (
- &Length16,
- (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
- sizeof (UINT16)
- );
- BlockPtr += Length16;
- break;
- case EFI_HII_GIBT_EXT4:
- CopyMem (
- &Length32,
- (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
- sizeof (UINT32)
- );
- BlockPtr += Length32;
- break;
-
- case EFI_HII_GIBT_GLYPH:
- CopyMem (
- &LocalCell,
- BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
- sizeof (EFI_HII_GLYPH_INFO)
- );
- if (CharValue == (CHAR16)(-1)) {
- if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
- BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
- }
-
- if (MinOffsetY > LocalCell.OffsetY) {
- MinOffsetY = LocalCell.OffsetY;
- }
- }
-
- BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);
- if (CharCurrent == CharValue) {
- return WriteOutputParam (
- (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),
- BufferLen,
- &LocalCell,
- GlyphBuffer,
- Cell,
- GlyphBufferLen
- );
- }
-
- CharCurrent++;
- BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;
- break;
-
- case EFI_HII_GIBT_GLYPHS:
- BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);
- CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));
- BlockPtr += sizeof (EFI_HII_GLYPH_INFO);
- CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));
- BlockPtr += sizeof (UINT16);
-
- if (CharValue == (CHAR16)(-1)) {
- if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {
- BaseLine = (UINT16)(Glyphs.Cell.Height + Glyphs.Cell.OffsetY);
- }
-
- if (MinOffsetY > Glyphs.Cell.OffsetY) {
- MinOffsetY = Glyphs.Cell.OffsetY;
- }
- }
-
- BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);
- for (Index = 0; Index < Glyphs.Count; Index++) {
- if (CharCurrent + Index == CharValue) {
- return WriteOutputParam (
- BlockPtr,
- BufferLen,
- &Glyphs.Cell,
- GlyphBuffer,
- Cell,
- GlyphBufferLen
- );
- }
-
- BlockPtr += BufferLen;
- }
-
- CharCurrent = (UINT16)(CharCurrent + Glyphs.Count);
- break;
-
- case EFI_HII_GIBT_GLYPH_DEFAULT:
- Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (CharValue == (CHAR16)(-1)) {
- if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
- BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
- }
-
- if (MinOffsetY > DefaultCell.OffsetY) {
- MinOffsetY = DefaultCell.OffsetY;
- }
- }
-
- BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
-
- if (CharCurrent == CharValue) {
- return WriteOutputParam (
- BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
- BufferLen,
- &DefaultCell,
- GlyphBuffer,
- Cell,
- GlyphBufferLen
- );
- }
-
- CharCurrent++;
- BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;
- break;
-
- case EFI_HII_GIBT_GLYPHS_DEFAULT:
- CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
- Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (CharValue == (CHAR16)(-1)) {
- if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
- BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
- }
-
- if (MinOffsetY > DefaultCell.OffsetY) {
- MinOffsetY = DefaultCell.OffsetY;
- }
- }
-
- BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
- BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);
- for (Index = 0; Index < Length16; Index++) {
- if (CharCurrent + Index == CharValue) {
- return WriteOutputParam (
- BlockPtr,
- BufferLen,
- &DefaultCell,
- GlyphBuffer,
- Cell,
- GlyphBufferLen
- );
- }
-
- BlockPtr += BufferLen;
- }
-
- CharCurrent = (UINT16)(CharCurrent + Length16);
- break;
-
- case EFI_HII_GIBT_SKIP1:
- CharCurrent = (UINT16)(CharCurrent + (UINT16)(*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));
- BlockPtr += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);
- break;
- case EFI_HII_GIBT_SKIP2:
- CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
- CharCurrent = (UINT16)(CharCurrent + Length16);
- BlockPtr += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- if (CharValue < CharCurrent) {
- return EFI_NOT_FOUND;
- }
- }
-
- if (CharValue == (CHAR16)(-1)) {
- FontPackage->BaseLine = BaseLine;
- FontPackage->Height = (UINT16)(BaseLine - MinOffsetY);
- return EFI_SUCCESS;
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Copy a Font Name to a new created EFI_FONT_INFO structure.
-
- This is a internal function.
-
- @param FontName NULL-terminated string.
- @param FontInfo a new EFI_FONT_INFO which stores the FontName.
- It's caller's responsibility to free this buffer.
-
- @retval EFI_SUCCESS FontInfo is allocated and copied with FontName.
- @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
- task.
-
-**/
-EFI_STATUS
-SaveFontName (
- IN EFI_STRING FontName,
- OUT EFI_FONT_INFO **FontInfo
- )
-{
- UINTN FontInfoLen;
- UINTN NameSize;
-
- ASSERT (FontName != NULL && FontInfo != NULL);
-
- NameSize = StrSize (FontName);
- FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;
- *FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoLen);
- if (*FontInfo == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);
- return EFI_SUCCESS;
-}
-
-/**
- Retrieve system default font and color.
-
- @param Private HII database driver private data.
- @param FontInfo Points to system default font output-related
- information. It's caller's responsibility to free
- this buffer.
- @param FontInfoSize If not NULL, output the size of buffer FontInfo.
-
- @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
- @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
- task.
- @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
-
-**/
-EFI_STATUS
-GetSystemFont (
- IN HII_DATABASE_PRIVATE_DATA *Private,
- OUT EFI_FONT_DISPLAY_INFO **FontInfo,
- OUT UINTN *FontInfoSize OPTIONAL
- )
-{
- EFI_FONT_DISPLAY_INFO *Info;
- UINTN InfoSize;
- UINTN NameSize;
-
- if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (FontInfo == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // The standard font always has the name "sysdefault".
- //
- NameSize = StrSize (L"sysdefault");
- InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
- Info = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (InfoSize);
- if (Info == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Info->ForegroundColor = mHiiEfiColors[Private->Attribute & 0x0f];
- ASSERT ((Private->Attribute >> 4) < 8);
- Info->BackgroundColor = mHiiEfiColors[Private->Attribute >> 4];
- Info->FontInfoMask = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;
- Info->FontInfo.FontStyle = 0;
- Info->FontInfo.FontSize = EFI_GLYPH_HEIGHT;
- StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");
-
- *FontInfo = Info;
- if (FontInfoSize != NULL) {
- *FontInfoSize = InfoSize;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or
- returns the system default according to the optional inputs.
-
- This is a internal function.
-
- @param Private HII database driver private data.
- @param StringInfo Points to the string output information,
- including the color and font.
- @param SystemInfo If not NULL, points to system default font and color.
-
- @param SystemInfoLen If not NULL, output the length of default system
- info.
-
- @retval TRUE Yes, it points to system default.
- @retval FALSE No.
-
-**/
-BOOLEAN
-IsSystemFontInfo (
- IN HII_DATABASE_PRIVATE_DATA *Private,
- IN EFI_FONT_DISPLAY_INFO *StringInfo,
- OUT EFI_FONT_DISPLAY_INFO **SystemInfo OPTIONAL,
- OUT UINTN *SystemInfoLen OPTIONAL
- )
-{
- EFI_STATUS Status;
- EFI_FONT_DISPLAY_INFO *SystemDefault;
- UINTN DefaultLen;
- BOOLEAN Flag;
-
- ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
-
- if ((StringInfo == NULL) && (SystemInfo == NULL)) {
- return TRUE;
- }
-
- SystemDefault = NULL;
- DefaultLen = 0;
-
- Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);
- ASSERT_EFI_ERROR (Status);
- ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));
-
- //
- // Record the system default info.
- //
- if (SystemInfo != NULL) {
- *SystemInfo = SystemDefault;
- }
-
- if (SystemInfoLen != NULL) {
- *SystemInfoLen = DefaultLen;
- }
-
- if (StringInfo == NULL) {
- return TRUE;
- }
-
- Flag = FALSE;
- //
- // Check the FontInfoMask to see whether it is retrieving system info.
- //
- if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {
- if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {
- goto Exit;
- }
- }
-
- if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {
- if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {
- goto Exit;
- }
- }
-
- if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {
- if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {
- goto Exit;
- }
- }
-
- if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {
- if (CompareMem (
- &StringInfo->ForegroundColor,
- &SystemDefault->ForegroundColor,
- sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
- ) != 0)
- {
- goto Exit;
- }
- }
-
- if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {
- if (CompareMem (
- &StringInfo->BackgroundColor,
- &SystemDefault->BackgroundColor,
- sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
- ) != 0)
- {
- goto Exit;
- }
- }
-
- Flag = TRUE;
-
-Exit:
- if (SystemInfo == NULL) {
- if (SystemDefault != NULL) {
- FreePool (SystemDefault);
- }
- }
-
- return Flag;
-}
-
-/**
- This function checks whether EFI_FONT_INFO exists in current database. If
- FontInfoMask is specified, check what options can be used to make a match.
- Note that the masks relate to where the system default should be supplied
- are ignored by this function.
-
- @param Private Hii database private structure.
- @param FontInfo Points to EFI_FONT_INFO structure.
- @param FontInfoMask If not NULL, describes what options can be used
- to make a match between the font requested and
- the font available. The caller must guarantee
- this mask is valid.
- @param FontHandle On entry, Points to the font handle returned by a
- previous call to GetFontInfo() or NULL to start
- with the first font.
- @param GlobalFontInfo If not NULL, output the corresponding global font
- info.
-
- @retval TRUE Existed
- @retval FALSE Not existed
-
-**/
-BOOLEAN
-IsFontInfoExisted (
- IN HII_DATABASE_PRIVATE_DATA *Private,
- IN EFI_FONT_INFO *FontInfo,
- IN EFI_FONT_INFO_MASK *FontInfoMask OPTIONAL,
- IN EFI_FONT_HANDLE FontHandle OPTIONAL,
- OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL
- )
-{
- HII_GLOBAL_FONT_INFO *GlobalFont;
- HII_GLOBAL_FONT_INFO *GlobalFontBackup1;
- HII_GLOBAL_FONT_INFO *GlobalFontBackup2;
- LIST_ENTRY *Link;
- EFI_FONT_INFO_MASK Mask;
- BOOLEAN Matched;
- BOOLEAN VagueMatched1;
- BOOLEAN VagueMatched2;
-
- ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
- ASSERT (FontInfo != NULL);
-
- //
- // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE
- // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.
- //
- Matched = FALSE;
- VagueMatched1 = FALSE;
- VagueMatched2 = FALSE;
-
- Mask = 0;
- GlobalFontBackup1 = NULL;
- GlobalFontBackup2 = NULL;
-
- // The process of where the system default should be supplied instead of
- // the specified font info beyonds this function's scope.
- //
- if (FontInfoMask != NULL) {
- Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);
- }
-
- //
- // If not NULL, FontHandle points to the next node of the last searched font
- // node by previous call.
- //
- if (FontHandle == NULL) {
- Link = Private->FontInfoList.ForwardLink;
- } else {
- Link = (LIST_ENTRY *)FontHandle;
- }
-
- for ( ; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
- GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
- if (FontInfoMask == NULL) {
- if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {
- if (GlobalFontInfo != NULL) {
- *GlobalFontInfo = GlobalFont;
- }
-
- return TRUE;
- }
- } else {
- //
- // Check which options could be used to make a match.
- //
- switch (Mask) {
- case EFI_FONT_INFO_ANY_FONT:
- if ((GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) &&
- (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
- {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:
- Matched = TRUE;
- break;
- //
- // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to
- // remove some of the specified styles to meet the style requested.
- //
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- Matched = TRUE;
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- //
- // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to
- // stretch or shrink a font to meet the size requested.
- //
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- } else {
- VagueMatched2 = TRUE;
- GlobalFontBackup2 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
-
- break;
- case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- Matched = TRUE;
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
-
- break;
- case EFI_FONT_INFO_ANY_STYLE:
- if ((CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0) &&
- (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
- {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:
- if (CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0)
- {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
- if (CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0)
- {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_ANY_SIZE:
- if ((CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0) &&
- (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
- {
- Matched = TRUE;
- }
-
- break;
- case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
- if (CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0)
- {
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- Matched = TRUE;
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_RESTYLE:
- if ((CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0) &&
- (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
- {
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- Matched = TRUE;
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_RESIZE:
- if ((CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0) &&
- (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
- {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- }
-
- break;
- case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:
- if (CompareMem (
- GlobalFont->FontInfo->FontName,
- FontInfo->FontName,
- StrSize (FontInfo->FontName)
- ) == 0)
- {
- if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- Matched = TRUE;
- } else {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- }
- } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
- if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
- VagueMatched1 = TRUE;
- GlobalFontBackup1 = GlobalFont;
- } else {
- VagueMatched2 = TRUE;
- GlobalFontBackup2 = GlobalFont;
- }
- }
- }
-
- break;
- default:
- break;
- }
-
- if (Matched) {
- if (GlobalFontInfo != NULL) {
- *GlobalFontInfo = GlobalFont;
- }
-
- return TRUE;
- }
- }
- }
-
- if (VagueMatched1) {
- if (GlobalFontInfo != NULL) {
- *GlobalFontInfo = GlobalFontBackup1;
- }
-
- return TRUE;
- } else if (VagueMatched2) {
- if (GlobalFontInfo != NULL) {
- *GlobalFontInfo = GlobalFontBackup2;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- Check whether the unicode represents a line break or not.
-
- This is a internal function. Please see Section 27.2.6 of the UEFI Specification
- for a description of the supported string format.
-
- @param Char Unicode character
-
- @retval 0 Yes, it forces a line break.
- @retval 1 Yes, it presents a line break opportunity
- @retval 2 Yes, it requires a line break happen before and after it.
- @retval -1 No, it is not a link break.
-
-**/
-INT8
-IsLineBreak (
- IN CHAR16 Char
- )
-{
- switch (Char) {
- //
- // Mandatory line break characters, which force a line-break
- //
- case 0x000A:
- case 0x000C:
- case 0x000D:
- case 0x2028:
- case 0x2029:
- return 0;
- //
- // Space characters, which is taken as a line-break opportunity
- //
- case 0x0020:
- case 0x1680:
- case 0x2000:
- case 0x2001:
- case 0x2002:
- case 0x2003:
- case 0x2004:
- case 0x2005:
- case 0x2006:
- case 0x2008:
- case 0x2009:
- case 0x200A:
- case 0x205F:
- //
- // In-Word Break Opportunities
- //
- case 0x200B:
- return 1;
- //
- // A space which is not a line-break opportunity
- //
- case 0x00A0:
- case 0x202F:
- //
- // A hyphen which is not a line-break opportunity
- //
- case 0x2011:
- return -1;
- //
- // Hyphen characters which describe line break opportunities after the character
- //
- case 0x058A:
- case 0x2010:
- case 0x2012:
- case 0x2013:
- case 0x0F0B:
- case 0x1361:
- case 0x17D5:
- return 1;
- //
- // A hyphen which describes line break opportunities before and after them, but not between a pair of them
- //
- case 0x2014:
- return 2;
- }
-
- return -1;
-}
-
-/**
- Renders a string to a bitmap or to the display.
-
- @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
- @param Flags Describes how the string is to be drawn.
- @param String Points to the null-terminated string to be
- displayed.
- @param StringInfo Points to the string output information,
- including the color and font. If NULL, then the
- string will be output in the default system font
- and color.
- @param Blt If this points to a non-NULL on entry, this
- points to the image, which is Width pixels wide
- and Height pixels high. The string will be drawn
- onto this image and
- EFI_HII_OUT_FLAG_CLIP is implied. If this points
- to a NULL on entry, then a buffer
- will be allocated to hold the generated image and
- the pointer updated on exit. It is the caller's
- responsibility to free this buffer.
- @param BltX Specifies the offset from the left and top edge
- of the image of the first character cell in the
- image.
- @param BltY Specifies the offset from the left and top edge
- of the image of the first character cell in the
- image.
- @param RowInfoArray If this is non-NULL on entry, then on exit, this
- will point to an allocated buffer containing
- row information and RowInfoArraySize will be
- updated to contain the number of elements.
- This array describes the characters which were at
- least partially drawn and the heights of the
- rows. It is the caller's responsibility to free
- this buffer.
- @param RowInfoArraySize If this is non-NULL on entry, then on exit it
- contains the number of elements in RowInfoArray.
- @param ColumnInfoArray If this is non-NULL, then on return it will be
- filled with the horizontal offset for each
- character in the string on the row where it is
- displayed. Non-printing characters will have
- the offset ~0. The caller is responsible to
- allocate a buffer large enough so that there
- is one entry for each character in the string,
- not including the null-terminator. It is possible
- when character display is normalized that some
- character cells overlap.
-
- @retval EFI_SUCCESS The string was successfully rendered.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for
- RowInfoArray or Blt.
- @retval EFI_INVALID_PARAMETER The String or Blt was NULL.
- @retval EFI_INVALID_PARAMETER Flags were invalid combination..
-
-**/
-EFI_STATUS
-EFIAPI
-HiiStringToImage (
- IN CONST EFI_HII_FONT_PROTOCOL *This,
- IN EFI_HII_OUT_FLAGS Flags,
- IN CONST EFI_STRING String,
- IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
- IN OUT EFI_IMAGE_OUTPUT **Blt,
- IN UINTN BltX,
- IN UINTN BltY,
- OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
- OUT UINTN *RowInfoArraySize OPTIONAL,
- OUT UINTN *ColumnInfoArray OPTIONAL
- )
-{
- EFI_STATUS Status;
- HII_DATABASE_PRIVATE_DATA *Private;
- UINT8 **GlyphBuf;
- EFI_HII_GLYPH_INFO *Cell;
- UINT8 *Attributes;
- EFI_IMAGE_OUTPUT *Image;
- EFI_STRING StringPtr;
- EFI_STRING StringTmp;
- EFI_HII_ROW_INFO *RowInfo;
- UINTN LineWidth;
- UINTN LineHeight;
- UINTN LineOffset;
- UINTN LastLineHeight;
- UINTN BaseLineOffset;
- UINT16 MaxRowNum;
- UINT16 RowIndex;
- UINTN Index;
- UINTN NextIndex;
- UINTN Index1;
- EFI_FONT_DISPLAY_INFO *StringInfoOut;
- EFI_FONT_DISPLAY_INFO *SystemDefault;
- EFI_FONT_HANDLE FontHandle;
- EFI_STRING StringIn;
- EFI_STRING StringIn2;
- UINT16 Height;
- UINT16 BaseLine;
- EFI_FONT_INFO *FontInfo;
- BOOLEAN SysFontFlag;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
- BOOLEAN Transparent;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
- UINTN RowInfoSize;
- BOOLEAN LineBreak;
- UINTN StrLength;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *RowBufferPtr;
- HII_GLOBAL_FONT_INFO *GlobalFont;
- UINT32 PreInitBkgnd;
-
- //
- // Check incoming parameters.
- //
-
- if ((This == NULL) || (String == NULL) || (Blt == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (*Blt == NULL) {
- //
- // These two flag cannot be used if Blt is NULL upon entry.
- //
- if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- //
- // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
- //
- if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.
- //
- 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)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (*Blt == NULL) {
- //
- // Create a new bitmap and draw the string onto this image.
- //
- Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
- if (Image == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Image->Width = 800;
- Image->Height = 600;
- Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- if (Image->Image.Bitmap == NULL) {
- FreePool (Image);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Other flags are not permitted when Blt is NULL.
- //
- Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
- *Blt = Image;
- }
-
- StrLength = StrLen (String);
- GlyphBuf = (UINT8 **)AllocateZeroPool (StrLength * sizeof (UINT8 *));
- ASSERT (GlyphBuf != NULL);
- Cell = (EFI_HII_GLYPH_INFO *)AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
- ASSERT (Cell != NULL);
- Attributes = (UINT8 *)AllocateZeroPool (StrLength * sizeof (UINT8));
- ASSERT (Attributes != NULL);
-
- FontInfo = NULL;
- RowInfo = NULL;
- Status = EFI_SUCCESS;
- StringIn2 = NULL;
- SystemDefault = NULL;
- StringIn = NULL;
-
- //
- // Calculate the string output information, including specified color and font .
- // If StringInfo does not points to system font info, it must indicate an existing
- // EFI_FONT_INFO.
- //
- StringInfoOut = NULL;
- FontHandle = NULL;
- Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
- SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
-
- if (SysFontFlag) {
- ASSERT (SystemDefault != NULL);
- FontInfo = NULL;
- Height = SystemDefault->FontInfo.FontSize;
- BaseLine = SystemDefault->FontInfo.FontSize;
- Foreground = SystemDefault->ForegroundColor;
- Background = SystemDefault->BackgroundColor;
- } else {
- //
- // StringInfo must not be NULL if it is not system info.
- //
- ASSERT (StringInfo != NULL);
- Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);
- if (Status == EFI_NOT_FOUND) {
- //
- // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
- // Use the system font instead. Still use the color specified by StringInfo.
- //
- SysFontFlag = TRUE;
- FontInfo = NULL;
- Height = SystemDefault->FontInfo.FontSize;
- BaseLine = SystemDefault->FontInfo.FontSize;
- Foreground = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;
- Background = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;
- } else if (Status == EFI_SUCCESS) {
- FontInfo = &StringInfoOut->FontInfo;
- if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
- Height = GlobalFont->FontPackage->Height;
- BaseLine = GlobalFont->FontPackage->BaseLine;
- Foreground = StringInfoOut->ForegroundColor;
- Background = StringInfoOut->BackgroundColor;
- } else {
- goto Exit;
- }
- } else {
- goto Exit;
- }
- }
-
- //
- // Use the maximum height of font as the base line.
- // And, use the maximum height as line height.
- //
- LineHeight = Height;
- LastLineHeight = Height;
- BaseLineOffset = Height - BaseLine;
-
- //
- // Parse the string to be displayed to drop some ignored characters.
- //
-
- StringPtr = String;
-
- //
- // Ignore line-break characters only. Hyphens or dash character will be displayed
- // without line-break opportunity.
- //
- if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
- StringIn = AllocateZeroPool (StrSize (StringPtr));
- if (StringIn == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- StringTmp = StringIn;
- while (*StringPtr != 0) {
- if (IsLineBreak (*StringPtr) == 0) {
- StringPtr++;
- } else {
- *StringTmp++ = *StringPtr++;
- }
- }
-
- *StringTmp = 0;
- StringPtr = StringIn;
- }
-
- //
- // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
- // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.
- //
- StringIn2 = AllocateZeroPool (StrSize (StringPtr));
- if (StringIn2 == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Index = 0;
- StringTmp = StringIn2;
- StrLength = StrLen (StringPtr);
- while (*StringPtr != 0 && Index < StrLength) {
- if (IsLineBreak (*StringPtr) == 0) {
- *StringTmp++ = *StringPtr++;
- Index++;
- continue;
- }
-
- Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
- if (Status == EFI_NOT_FOUND) {
- if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
- GlyphBuf[Index] = NULL;
- ZeroMem (&Cell[Index], sizeof (Cell[Index]));
- Status = EFI_SUCCESS;
- } else {
- //
- // Unicode 0xFFFD must exist in current hii database if this flag is not set.
- //
- Status = GetGlyphBuffer (
- Private,
- REPLACE_UNKNOWN_GLYPH,
- FontInfo,
- &GlyphBuf[Index],
- &Cell[Index],
- &Attributes[Index]
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_INVALID_PARAMETER;
- }
- }
- }
-
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- *StringTmp++ = *StringPtr++;
- Index++;
- }
-
- *StringTmp = 0;
- StringPtr = StringIn2;
-
- //
- // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
- // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
- // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
- // Otherwise render this string to a new allocated image and output it.
- //
- Image = *Blt;
- BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
- if (Image->Height < BltY) {
- //
- // the top edge of the image should be in Image resolution scope.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- MaxRowNum = (UINT16)((Image->Height - BltY) / Height);
- if ((Image->Height - BltY) % Height != 0) {
- LastLineHeight = (Image->Height - BltY) % Height;
- MaxRowNum++;
- }
-
- RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
- if (RowInfo == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Format the glyph buffer according to flags.
- //
- Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
-
- for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
- LineWidth = 0;
- LineBreak = FALSE;
-
- //
- // Clip the final row if the row's bottom-most on pixel cannot fit when
- // EFI_HII_OUT_FLAG_CLEAN_Y is set.
- //
- if (RowIndex == MaxRowNum - 1) {
- if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {
- //
- // Don't draw at all if the row's bottom-most on pixel cannot fit.
- //
- break;
- }
-
- LineHeight = LastLineHeight;
- }
-
- //
- // Calculate how many characters there are in a row.
- //
- RowInfo[RowIndex].StartIndex = Index;
-
- while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
- if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&
- (IsLineBreak (StringPtr[Index]) == 0))
- {
- //
- // It forces a line break that ends this row.
- //
- Index++;
- LineBreak = TRUE;
- break;
- }
-
- //
- // If the glyph of the character is existing, then accumulate the actual printed width
- //
- LineWidth += (UINTN)Cell[Index].AdvanceX;
-
- Index++;
- }
-
- //
- // Record index of next char.
- //
- NextIndex = Index;
- //
- // Return to the previous char.
- //
- Index--;
- if (LineBreak && (Index > 0)) {
- //
- // Return the previous non line break char.
- //
- Index--;
- }
-
- //
- // If this character is the last character of a row, we need not
- // draw its (AdvanceX - Width - OffsetX) for next character.
- //
- LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
-
- //
- // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
- //
- if ((LineWidth + BltX <= Image->Width) ||
- ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))
- {
- //
- // Record right-most character in RowInfo even if it is partially displayed.
- //
- RowInfo[RowIndex].EndIndex = Index;
- RowInfo[RowIndex].LineWidth = LineWidth;
- RowInfo[RowIndex].LineHeight = LineHeight;
- RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
- } else {
- //
- // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
- // if its right-most on pixel cannot fit.
- //
- if (Index > RowInfo[RowIndex].StartIndex) {
- //
- // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
- //
- LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);
- LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
- RowInfo[RowIndex].EndIndex = Index - 1;
- RowInfo[RowIndex].LineWidth = LineWidth;
- RowInfo[RowIndex].LineHeight = LineHeight;
- RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
- } else {
- //
- // There is no enough column to draw any character, so set current line width to zero.
- // And go to draw Next line if LineBreak is set.
- //
- RowInfo[RowIndex].LineWidth = 0;
- goto NextLine;
- }
- }
-
- //
- // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
- // opportunity prior to a character whose right-most extent would exceed Width.
- // Search the right-most line-break opportunity here.
- //
- if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&
- ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&
- !LineBreak)
- {
- if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
- LineWidth = RowInfo[RowIndex].LineWidth;
- for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
- if (Index1 == RowInfo[RowIndex].EndIndex) {
- LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
- } else {
- LineWidth -= Cell[Index1].AdvanceX;
- }
-
- if (IsLineBreak (StringPtr[Index1]) > 0) {
- LineBreak = TRUE;
- if (Index1 > RowInfo[RowIndex].StartIndex) {
- RowInfo[RowIndex].EndIndex = Index1 - 1;
- }
-
- //
- // relocate to the character after the right-most line break opportunity of this line
- //
- NextIndex = Index1 + 1;
- break;
- }
-
- //
- // If don't find a line break opportunity from EndIndex to StartIndex,
- // then jump out.
- //
- if (Index1 == RowInfo[RowIndex].StartIndex) {
- break;
- }
- }
-
- //
- // Update LineWidth to the real width
- //
- if (IsLineBreak (StringPtr[Index1]) > 0) {
- if (Index1 == RowInfo[RowIndex].StartIndex) {
- LineWidth = 0;
- } else {
- LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
- }
-
- RowInfo[RowIndex].LineWidth = LineWidth;
- }
- }
-
- //
- // If no line-break opportunity can be found, then the text will
- // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
- //
- if (!LineBreak) {
- LineWidth = RowInfo[RowIndex].LineWidth;
- Index1 = RowInfo[RowIndex].EndIndex;
- if (LineWidth + BltX > Image->Width) {
- if (Index1 > RowInfo[RowIndex].StartIndex) {
- //
- // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
- //
- LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
- LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
- RowInfo[RowIndex].EndIndex = Index1 - 1;
- RowInfo[RowIndex].LineWidth = LineWidth;
- } else {
- //
- // There is no enough column to draw any character, so set current line width to zero.
- // And go to draw Next line if LineBreak is set.
- //
- RowInfo[RowIndex].LineWidth = 0;
- goto NextLine;
- }
- }
- }
- }
-
- //
- // LineWidth can't exceed Image width.
- //
- if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
- RowInfo[RowIndex].LineWidth = Image->Width - BltX;
- }
-
- //
- // Draw it to screen or existing bitmap depending on whether
- // EFI_HII_DIRECT_TO_SCREEN is set.
- //
- LineOffset = 0;
- if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
- BltBuffer = NULL;
- if (RowInfo[RowIndex].LineWidth != 0) {
- BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- if (BltBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Initialize the background color.
- //
- PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;
- SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);
- //
- // Set BufferPtr to Origin by adding baseline to the starting position.
- //
- BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
- }
-
- for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
- if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
- //
- // Only BLT these character which have corresponding glyph in font database.
- //
- GlyphToImage (
- GlyphBuf[Index1],
- Foreground,
- Background,
- (UINT16)RowInfo[RowIndex].LineWidth,
- BaseLine,
- RowInfo[RowIndex].LineWidth - LineOffset,
- RowInfo[RowIndex].LineHeight,
- Transparent,
- &Cell[Index1],
- Attributes[Index1],
- &BufferPtr
- );
- }
-
- if (ColumnInfoArray != NULL) {
- if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
- || (RowInfo[RowIndex].LineWidth == 0))
- {
- *ColumnInfoArray = (UINTN) ~0;
- } else {
- *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
- }
-
- ColumnInfoArray++;
- }
-
- LineOffset += Cell[Index1].AdvanceX;
- }
-
- if (BltBuffer != NULL) {
- Status = Image->Image.Screen->Blt (
- Image->Image.Screen,
- BltBuffer,
- EfiBltBufferToVideo,
- 0,
- 0,
- BltX,
- BltY,
- RowInfo[RowIndex].LineWidth,
- RowInfo[RowIndex].LineHeight,
- 0
- );
- if (EFI_ERROR (Status)) {
- FreePool (BltBuffer);
- goto Exit;
- }
-
- FreePool (BltBuffer);
- }
- } else {
- //
- // Save the starting position for calculate the starting position of next row.
- //
- RowBufferPtr = BufferPtr;
- //
- // Set BufferPtr to Origin by adding baseline to the starting position.
- //
- BufferPtr = BufferPtr + BaseLine * Image->Width;
- for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
- if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
- //
- // Only BLT these character which have corresponding glyph in font database.
- //
- GlyphToImage (
- GlyphBuf[Index1],
- Foreground,
- Background,
- Image->Width,
- BaseLine,
- RowInfo[RowIndex].LineWidth - LineOffset,
- RowInfo[RowIndex].LineHeight,
- Transparent,
- &Cell[Index1],
- Attributes[Index1],
- &BufferPtr
- );
- }
-
- if (ColumnInfoArray != NULL) {
- if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
- || (RowInfo[RowIndex].LineWidth == 0))
- {
- *ColumnInfoArray = (UINTN) ~0;
- } else {
- *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
- }
-
- ColumnInfoArray++;
- }
-
- LineOffset += Cell[Index1].AdvanceX;
- }
-
- //
- // Jump to starting position of next row.
- //
- if (RowIndex == 0) {
- BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
- } else {
- BufferPtr = RowBufferPtr + LineHeight * Image->Width;
- }
- }
-
-NextLine:
- //
- // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down
- //
- BltY += RowInfo[RowIndex].LineHeight;
-
- RowIndex++;
- Index = NextIndex;
-
- if (!LineBreak) {
- //
- // If there is not a mandatory line break or line break opportunity, only render one line to image
- //
- break;
- }
- }
-
- //
- // Write output parameters.
- //
- RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
- if (RowInfoArray != NULL) {
- if (RowInfoSize > 0) {
- *RowInfoArray = AllocateZeroPool (RowInfoSize);
- if (*RowInfoArray == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
- } else {
- *RowInfoArray = NULL;
- }
- }
-
- if (RowInfoArraySize != NULL) {
- *RowInfoArraySize = RowIndex;
- }
-
- Status = EFI_SUCCESS;
-
-Exit:
-
- for (Index = 0; Index < StrLength; Index++) {
- if (GlyphBuf[Index] != NULL) {
- FreePool (GlyphBuf[Index]);
- }
- }
-
- if (StringIn != NULL) {
- FreePool (StringIn);
- }
-
- if (StringIn2 != NULL) {
- FreePool (StringIn2);
- }
-
- if (StringInfoOut != NULL) {
- FreePool (StringInfoOut);
- }
-
- if (RowInfo != NULL) {
- FreePool (RowInfo);
- }
-
- if (SystemDefault != NULL) {
- FreePool (SystemDefault);
- }
-
- if (GlyphBuf != NULL) {
- FreePool (GlyphBuf);
- }
-
- if (Cell != NULL) {
- FreePool (Cell);
- }
-
- if (Attributes != NULL) {
- FreePool (Attributes);
- }
-
- return Status;
-}
-
-/**
- Render a string to a bitmap or the screen containing the contents of the specified string.
-
- @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
- @param Flags Describes how the string is to be drawn.
- @param PackageList The package list in the HII database to search
- for the specified string.
- @param StringId The string's id, which is unique within
- PackageList.
- @param Language Points to the language for the retrieved string.
- If NULL, then the current system language is
- used.
- @param StringInfo Points to the string output information,
- including the color and font. If NULL, then the
- string will be output in the default system font
- and color.
- @param Blt If this points to a non-NULL on entry, this
- points to the image, which is Width pixels wide
- and Height pixels high. The string will be drawn
- onto this image and
- EFI_HII_OUT_FLAG_CLIP is implied. If this points
- to a NULL on entry, then a buffer
- will be allocated to hold the generated image and
- the pointer updated on exit. It is the caller's
- responsibility to free this buffer.
- @param BltX Specifies the offset from the left and top edge
- of the image of the first character cell in the
- image.
- @param BltY Specifies the offset from the left and top edge
- of the image of the first character cell in the
- image.
- @param RowInfoArray If this is non-NULL on entry, then on exit, this
- will point to an allocated buffer containing
- row information and RowInfoArraySize will be
- updated to contain the number of elements.
- This array describes the characters which were at
- least partially drawn and the heights of the
- rows. It is the caller's responsibility to free
- this buffer.
- @param RowInfoArraySize If this is non-NULL on entry, then on exit it
- contains the number of elements in RowInfoArray.
- @param ColumnInfoArray If this is non-NULL, then on return it will be
- filled with the horizontal offset for each
- character in the string on the row where it is
- displayed. Non-printing characters will have
- the offset ~0. The caller is responsible to
- allocate a buffer large enough so that there
- is one entry for each character in the string,
- not including the null-terminator. It is possible
- when character display is normalized that some
- character cells overlap.
-
- @retval EFI_SUCCESS The string was successfully rendered.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for
- RowInfoArray or Blt.
- @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.
- @retval EFI_INVALID_PARAMETER Flags were invalid combination.
- @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the string id is not
- in the specified PackageList.
-
-**/
-EFI_STATUS
-EFIAPI
-HiiStringIdToImage (
- IN CONST EFI_HII_FONT_PROTOCOL *This,
- IN EFI_HII_OUT_FLAGS Flags,
- IN EFI_HII_HANDLE PackageList,
- IN EFI_STRING_ID StringId,
- IN CONST CHAR8 *Language,
- IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
- IN OUT EFI_IMAGE_OUTPUT **Blt,
- IN UINTN BltX,
- IN UINTN BltY,
- OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
- OUT UINTN *RowInfoArraySize OPTIONAL,
- OUT UINTN *ColumnInfoArray OPTIONAL
- )
-{
- EFI_STATUS Status;
- HII_DATABASE_PRIVATE_DATA *Private;
- EFI_HII_STRING_PROTOCOL *HiiString;
- EFI_STRING String;
- UINTN StringSize;
- UINTN FontLen;
- UINTN NameSize;
- EFI_FONT_INFO *StringFontInfo;
- EFI_FONT_DISPLAY_INFO *NewStringInfo;
- CHAR8 TempSupportedLanguages;
- CHAR8 *SupportedLanguages;
- UINTN SupportedLanguagesSize;
- CHAR8 *CurrentLanguage;
- CHAR8 *BestLanguage;
-
- if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (!IsHiiHandleValid (PackageList)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Initialize string pointers to be NULL
- //
- SupportedLanguages = NULL;
- CurrentLanguage = NULL;
- BestLanguage = NULL;
- String = NULL;
- StringFontInfo = NULL;
- NewStringInfo = NULL;
-
- //
- // Get the string to be displayed.
- //
- Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
- HiiString = &Private->HiiString;
-
- //
- // Get the size of supported language.
- //
- SupportedLanguagesSize = 0;
- Status = HiiString->GetLanguages (
- HiiString,
- PackageList,
- &TempSupportedLanguages,
- &SupportedLanguagesSize
- );
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return Status;
- }
-
- SupportedLanguages = AllocatePool (SupportedLanguagesSize);
- if (SupportedLanguages == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = HiiString->GetLanguages (
- HiiString,
- PackageList,
- SupportedLanguages,
- &SupportedLanguagesSize
- );
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- if (Language == NULL) {
- Language = "";
- }
-
- GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);
- BestLanguage = GetBestLanguage (
- SupportedLanguages,
- FALSE,
- Language,
- (CurrentLanguage == NULL) ? CurrentLanguage : "",
- (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
- NULL
- );
- if (BestLanguage == NULL) {
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
-
- StringSize = MAX_STRING_LENGTH;
- String = (EFI_STRING)AllocateZeroPool (StringSize);
- if (String == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Status = HiiString->GetString (
- HiiString,
- BestLanguage,
- PackageList,
- StringId,
- String,
- &StringSize,
- &StringFontInfo
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (String);
- String = (EFI_STRING)AllocateZeroPool (StringSize);
- if (String == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Status = HiiString->GetString (
- HiiString,
- BestLanguage,
- PackageList,
- StringId,
- String,
- &StringSize,
- NULL
- );
- }
-
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- //
- // When StringInfo specifies that string will be output in the system default font and color,
- // use particular stringfontinfo described in string package instead if exists.
- // StringFontInfo equals NULL means system default font attaches with the string block.
- //
- if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {
- NameSize = StrSize (StringFontInfo->FontName);
- FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
- NewStringInfo = AllocateZeroPool (FontLen);
- if (NewStringInfo == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
- NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
- NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;
- StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
-
- Status = HiiStringToImage (
- This,
- Flags,
- String,
- NewStringInfo,
- Blt,
- BltX,
- BltY,
- RowInfoArray,
- RowInfoArraySize,
- ColumnInfoArray
- );
- goto Exit;
- }
-
- Status = HiiStringToImage (
- This,
- Flags,
- String,
- StringInfo,
- Blt,
- BltX,
- BltY,
- RowInfoArray,
- RowInfoArraySize,
- ColumnInfoArray
- );
-
-Exit:
- if (SupportedLanguages != NULL) {
- FreePool (SupportedLanguages);
- }
-
- if (CurrentLanguage != NULL) {
- FreePool (CurrentLanguage);
- }
-
- if (BestLanguage != NULL) {
- FreePool (BestLanguage);
- }
-
- if (String != NULL) {
- FreePool (String);
- }
-
- if (StringFontInfo != NULL) {
- FreePool (StringFontInfo);
- }
-
- if (NewStringInfo != NULL) {
- FreePool (NewStringInfo);
- }
-
- return Status;
-}
-
-/**
- Convert the glyph for a single character into a bitmap.
-
- @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
- @param Char Character to retrieve.
- @param StringInfo Points to the string font and color information
- or NULL if the string should use the default
- system font and color.
- @param Blt Thus must point to a NULL on entry. A buffer will
- be allocated to hold the output and the pointer
- updated on exit. It is the caller's
- responsibility to free this buffer.
- @param Baseline Number of pixels from the bottom of the bitmap to
- the baseline.
-
- @retval EFI_SUCCESS Glyph bitmap created.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.
- @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the
- glyph for Unicode character 0xFFFD.
- @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-HiiGetGlyph (
- IN CONST EFI_HII_FONT_PROTOCOL *This,
- IN CHAR16 Char,
- IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
- OUT EFI_IMAGE_OUTPUT **Blt,
- OUT UINTN *Baseline OPTIONAL
- )
-{
- EFI_STATUS Status;
- HII_DATABASE_PRIVATE_DATA *Private;
- EFI_IMAGE_OUTPUT *Image;
- UINT8 *GlyphBuffer;
- EFI_FONT_DISPLAY_INFO *SystemDefault;
- EFI_FONT_DISPLAY_INFO *StringInfoOut;
- BOOLEAN Default;
- EFI_FONT_HANDLE FontHandle;
- EFI_STRING String;
- EFI_HII_GLYPH_INFO Cell;
- EFI_FONT_INFO *FontInfo;
- UINT8 Attributes;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
- UINT16 BaseLine;
-
- if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
-
- Default = FALSE;
- Image = NULL;
- SystemDefault = NULL;
- FontHandle = NULL;
- String = NULL;
- GlyphBuffer = NULL;
- StringInfoOut = NULL;
- FontInfo = NULL;
-
- ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
-
- Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
-
- if (!Default) {
- //
- // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
- // the specified color and font.
- //
- String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);
- if (String == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- *String = Char;
- *(String + 1) = 0;
-
- Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- ASSERT (StringInfoOut != NULL);
- FontInfo = &StringInfoOut->FontInfo;
- Foreground = StringInfoOut->ForegroundColor;
- Background = StringInfoOut->BackgroundColor;
- } else {
- ASSERT (SystemDefault != NULL);
- Foreground = SystemDefault->ForegroundColor;
- Background = SystemDefault->BackgroundColor;
- }
-
- Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
- if (Image == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Image->Width = Cell.Width;
- Image->Height = Cell.Height;
-
- if (Image->Width * Image->Height > 0) {
- Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
- if (Image->Image.Bitmap == NULL) {
- FreePool (Image);
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Set BaseLine to the char height.
- //
- BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);
- //
- // Set BltBuffer to the position of Origin.
- //
- BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
- GlyphToImage (
- GlyphBuffer,
- Foreground,
- Background,
- Image->Width,
- BaseLine,
- Cell.Width + Cell.OffsetX,
- BaseLine - Cell.OffsetY,
- FALSE,
- &Cell,
- Attributes,
- &BltBuffer
- );
- }
-
- *Blt = Image;
- if (Baseline != NULL) {
- *Baseline = Cell.OffsetY;
- }
-
- Status = EFI_SUCCESS;
-
-Exit:
-
- if (Status == EFI_NOT_FOUND) {
- //
- // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
- //
- if (Char != REPLACE_UNKNOWN_GLYPH) {
- Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
- if (!EFI_ERROR (Status)) {
- Status = EFI_WARN_UNKNOWN_GLYPH;
- }
- } else {
- Status = EFI_WARN_UNKNOWN_GLYPH;
- }
- }
-
- if (SystemDefault != NULL) {
- FreePool (SystemDefault);
- }
-
- if (StringInfoOut != NULL) {
- FreePool (StringInfoOut);
- }
-
- if (String != NULL) {
- FreePool (String);
- }
-
- if (GlyphBuffer != NULL) {
- FreePool (GlyphBuffer);
- }
-
- return Status;
-}
-
-/**
- This function iterates through fonts which match the specified font, using
- the specified criteria. If String is non-NULL, then all of the characters in
- the string must exist in order for a candidate font to be returned.
-
- @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
- @param FontHandle On entry, points to the font handle returned by a
- previous call to GetFontInfo() or NULL to start
- with the first font. On return, points to the
- returned font handle or points to NULL if there
- are no more matching fonts.
- @param StringInfoIn Upon entry, points to the font to return information
- about. If NULL, then the information about the system
- default font will be returned.
- @param StringInfoOut Upon return, contains the matching font's information.
- If NULL, then no information is returned. This buffer
- is allocated with a call to the Boot Service AllocatePool().
- It is the caller's responsibility to call the Boot
- Service FreePool() when the caller no longer requires
- the contents of StringInfoOut.
- @param String Points to the string which will be tested to
- determine if all characters are available. If
- NULL, then any font is acceptable.
-
- @retval EFI_SUCCESS Matching font returned successfully.
- @retval EFI_NOT_FOUND No matching font was found.
- @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.
- @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
- request.
-
-**/
-EFI_STATUS
-EFIAPI
-HiiGetFontInfo (
- IN CONST EFI_HII_FONT_PROTOCOL *This,
- IN OUT EFI_FONT_HANDLE *FontHandle,
- IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL,
- OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
- IN CONST EFI_STRING String OPTIONAL
- )
-{
- HII_DATABASE_PRIVATE_DATA *Private;
- EFI_STATUS Status;
- EFI_FONT_DISPLAY_INFO *SystemDefault;
- EFI_FONT_DISPLAY_INFO InfoOut;
- UINTN StringInfoOutLen;
- EFI_FONT_INFO *FontInfo;
- HII_GLOBAL_FONT_INFO *GlobalFont;
- EFI_STRING StringIn;
- EFI_FONT_HANDLE LocalFontHandle;
-
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- StringInfoOutLen = 0;
- FontInfo = NULL;
- SystemDefault = NULL;
- LocalFontHandle = NULL;
- if (FontHandle != NULL) {
- LocalFontHandle = *FontHandle;
- }
-
- Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
-
- //
- // Already searched to the end of the whole list, return directly.
- //
- if (LocalFontHandle == &Private->FontInfoList) {
- LocalFontHandle = NULL;
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
-
- //
- // Get default system display info, if StringInfoIn points to
- // system display info, return it directly.
- //
- if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
- //
- // System font is the first node. When handle is not NULL, system font can not
- // be found any more.
- //
- if (LocalFontHandle == NULL) {
- if (StringInfoOut != NULL) {
- *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
- if (*StringInfoOut == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- LocalFontHandle = NULL;
- goto Exit;
- }
- }
-
- LocalFontHandle = Private->FontInfoList.ForwardLink;
- Status = EFI_SUCCESS;
- goto Exit;
- } else {
- LocalFontHandle = NULL;
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
- }
-
- //
- // StringInfoIn must not be NULL if it is not system default font info.
- //
- ASSERT (StringInfoIn != NULL);
- //
- // Check the font information mask to make sure it is valid.
- //
- if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
- (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
- ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
- (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
- ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
- (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
- ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
- (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
- ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
- (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Parse the font information mask to find a matching font.
- //
-
- CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
-
- if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
- Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
- } else {
- Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);
- }
-
- if (EFI_ERROR (Status)) {
- goto Exit;
- }
-
- if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
- InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
- }
-
- if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
- InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
- }
-
- if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
- InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
- }
-
- if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
- InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
- }
-
- ASSERT (FontInfo != NULL);
- FontInfo->FontSize = InfoOut.FontInfo.FontSize;
- FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
-
- if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
- //
- // Test to guarantee all characters are available in the found font.
- //
- if (String != NULL) {
- StringIn = String;
- while (*StringIn != 0) {
- Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
- if (EFI_ERROR (Status)) {
- LocalFontHandle = NULL;
- goto Exit;
- }
-
- StringIn++;
- }
- }
-
- //
- // Write to output parameter
- //
- if (StringInfoOut != NULL) {
- StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
- *StringInfoOut = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);
- if (*StringInfoOut == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- LocalFontHandle = NULL;
- goto Exit;
- }
-
- CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
- CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
- }
-
- LocalFontHandle = GlobalFont->Entry.ForwardLink;
- Status = EFI_SUCCESS;
- goto Exit;
- }
-
- Status = EFI_NOT_FOUND;
-
-Exit:
-
- if (FontHandle != NULL) {
- *FontHandle = LocalFontHandle;
- }
-
- if (SystemDefault != NULL) {
- FreePool (SystemDefault);
- }
-
- if (FontInfo != NULL) {
- FreePool (FontInfo);
- }
-
- return Status;
-}
+/** @file
+Implementation for EFI_HII_FONT_PROTOCOL.
+
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "HiiDatabase.h"
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL mHiiEfiColors[16] = {
+ //
+ // B G R
+ //
+ { 0x00, 0x00, 0x00, 0x00 }, // BLACK
+ { 0x98, 0x00, 0x00, 0x00 }, // BLUE
+ { 0x00, 0x98, 0x00, 0x00 }, // GREEN
+ { 0x98, 0x98, 0x00, 0x00 }, // CYAN
+ { 0x00, 0x00, 0x98, 0x00 }, // RED
+ { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA
+ { 0x00, 0x98, 0x98, 0x00 }, // BROWN
+ { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY
+ { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK
+ { 0xff, 0x00, 0x00, 0x00 }, // LIGHTBLUE
+ { 0x00, 0xff, 0x00, 0x00 }, // LIGHTGREEN
+ { 0xff, 0xff, 0x00, 0x00 }, // LIGHTCYAN
+ { 0x00, 0x00, 0xff, 0x00 }, // LIGHTRED
+ { 0xff, 0x00, 0xff, 0x00 }, // LIGHTMAGENTA
+ { 0x00, 0xff, 0xff, 0x00 }, // YELLOW
+ { 0xff, 0xff, 0xff, 0x00 }, // WHITE
+};
+
+/**
+ Insert a character cell information to the list specified by GlyphInfoList.
+
+ This is a internal function.
+
+ @param CharValue Unicode character value, which identifies a glyph
+ block.
+ @param GlyphInfoList HII_GLYPH_INFO list head.
+ @param Cell Incoming character cell information.
+
+ @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
+ @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
+ task.
+
+**/
+EFI_STATUS
+NewCell (
+ IN CHAR16 CharValue,
+ IN LIST_ENTRY *GlyphInfoList,
+ IN EFI_HII_GLYPH_INFO *Cell
+ )
+{
+ HII_GLYPH_INFO *GlyphInfo;
+
+ ASSERT (Cell != NULL && GlyphInfoList != NULL);
+
+ GlyphInfo = (HII_GLYPH_INFO *)AllocateZeroPool (sizeof (HII_GLYPH_INFO));
+ if (GlyphInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // GlyphInfoList stores a list of default character cell information, each is
+ // identified by "CharId".
+ //
+ GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;
+ GlyphInfo->CharId = CharValue;
+ if (Cell->AdvanceX == 0) {
+ Cell->AdvanceX = Cell->Width;
+ }
+
+ CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));
+ InsertTailList (GlyphInfoList, &GlyphInfo->Entry);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get a character cell information from the list specified by GlyphInfoList.
+
+ This is a internal function.
+
+ @param CharValue Unicode character value, which identifies a glyph
+ block.
+ @param GlyphInfoList HII_GLYPH_INFO list head.
+ @param Cell Buffer which stores output character cell
+ information.
+
+ @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
+ @retval EFI_NOT_FOUND The character info specified by CharValue does
+ not exist.
+
+**/
+EFI_STATUS
+GetCell (
+ IN CHAR16 CharValue,
+ IN LIST_ENTRY *GlyphInfoList,
+ OUT EFI_HII_GLYPH_INFO *Cell
+ )
+{
+ HII_GLYPH_INFO *GlyphInfo;
+ LIST_ENTRY *Link;
+
+ ASSERT (Cell != NULL && GlyphInfoList != NULL);
+
+ //
+ // Since the EFI_HII_GIBT_DEFAULTS block won't increment CharValueCurrent,
+ // the value of "CharId" of a default character cell which is used for a
+ // EFI_HII_GIBT_GLYPH_DEFAULT or EFI_HII_GIBT_GLYPHS_DEFAULT should be
+ // less or equal to the value of "CharValueCurrent" of this default block.
+ //
+ // For instance, if the CharId of a GlyphInfoList is {1, 3, 7}, a default glyph
+ // with CharValue equals "7" uses the GlyphInfo with CharId = 7;
+ // a default glyph with CharValue equals "6" uses the GlyphInfo with CharId = 3.
+ //
+ for (Link = GlyphInfoList->BackLink; Link != GlyphInfoList; Link = Link->BackLink) {
+ GlyphInfo = CR (Link, HII_GLYPH_INFO, Entry, HII_GLYPH_INFO_SIGNATURE);
+ if (GlyphInfo->CharId <= CharValue) {
+ CopyMem (Cell, &GlyphInfo->Cell, sizeof (EFI_HII_GLYPH_INFO));
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert the glyph for a single character into a bitmap.
+
+ This is a internal function.
+
+ @param Private HII database driver private data.
+ @param Char Character to retrieve.
+ @param StringInfo Points to the string font and color information
+ or NULL if the string should use the default
+ system font and color.
+ @param GlyphBuffer Buffer to store the retrieved bitmap data.
+ @param Cell Points to EFI_HII_GLYPH_INFO structure.
+ @param Attributes If not NULL, output the glyph attributes if any.
+
+ @retval EFI_SUCCESS Glyph bitmap outputted.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer GlyphBuffer.
+ @retval EFI_NOT_FOUND The glyph was unknown can not be found.
+ @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
+
+**/
+EFI_STATUS
+GetGlyphBuffer (
+ IN HII_DATABASE_PRIVATE_DATA *Private,
+ IN CHAR16 Char,
+ IN EFI_FONT_INFO *StringInfo,
+ OUT UINT8 **GlyphBuffer,
+ OUT EFI_HII_GLYPH_INFO *Cell,
+ OUT UINT8 *Attributes OPTIONAL
+ )
+{
+ HII_DATABASE_RECORD *Node;
+ LIST_ENTRY *Link;
+ HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFont;
+ LIST_ENTRY *Link1;
+ UINT16 Index;
+ EFI_NARROW_GLYPH Narrow;
+ EFI_WIDE_GLYPH Wide;
+ HII_GLOBAL_FONT_INFO *GlobalFont;
+ UINTN HeaderSize;
+ EFI_NARROW_GLYPH *NarrowPtr;
+ EFI_WIDE_GLYPH *WidePtr;
+
+ if ((GlyphBuffer == NULL) || (Cell == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem (Cell, sizeof (EFI_HII_GLYPH_INFO));
+
+ //
+ // If StringInfo is not NULL, it must point to an existing EFI_FONT_INFO rather
+ // than system default font and color.
+ // If NULL, try to find the character in simplified font packages since
+ // default system font is the fixed font (narrow or wide glyph).
+ //
+ if (StringInfo != NULL) {
+ if (!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attributes != NULL) {
+ *Attributes = PROPORTIONAL_GLYPH;
+ }
+
+ return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);
+ } else {
+ HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);
+
+ for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
+ Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
+ for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;
+ Link1 != &Node->PackageList->SimpleFontPkgHdr;
+ Link1 = Link1->ForwardLink
+ )
+ {
+ SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);
+ //
+ // Search the narrow glyph array
+ //
+ NarrowPtr = (EFI_NARROW_GLYPH *)((UINT8 *)(SimpleFont->SimpleFontPkgHdr) + HeaderSize);
+ for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {
+ CopyMem (&Narrow, NarrowPtr + Index, sizeof (EFI_NARROW_GLYPH));
+ if (Narrow.UnicodeWeight == Char) {
+ *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT);
+ if (*GlyphBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Cell->Width = EFI_GLYPH_WIDTH;
+ Cell->Height = EFI_GLYPH_HEIGHT;
+ Cell->AdvanceX = Cell->Width;
+ CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);
+ if (Attributes != NULL) {
+ *Attributes = (UINT8)(Narrow.Attributes | NARROW_GLYPH);
+ }
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Search the wide glyph array
+ //
+ WidePtr = (EFI_WIDE_GLYPH *)(NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);
+ for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {
+ CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));
+ if (Wide.UnicodeWeight == Char) {
+ *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);
+ if (*GlyphBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Cell->Width = EFI_GLYPH_WIDTH * 2;
+ Cell->Height = EFI_GLYPH_HEIGHT;
+ Cell->AdvanceX = Cell->Width;
+ CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);
+ CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);
+ if (Attributes != NULL) {
+ *Attributes = (UINT8)(Wide.Attributes | EFI_GLYPH_WIDE);
+ }
+
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert bitmap data of the glyph to blt structure.
+
+ This is a internal function.
+
+ @param GlyphBuffer Buffer points to bitmap data of glyph.
+ @param Foreground The color of the "on" pixels in the glyph in the
+ bitmap.
+ @param Background The color of the "off" pixels in the glyph in the
+ bitmap.
+ @param ImageWidth Width of the whole image in pixels.
+ @param RowWidth The width of the text on the line, in pixels.
+ @param RowHeight The height of the line, in pixels.
+ @param Transparent If TRUE, the Background color is ignored and all
+ "off" pixels in the character's drawn will use the
+ pixel value from BltBuffer.
+ @param Origin On input, points to the origin of the to be
+ displayed character, on output, points to the
+ next glyph's origin.
+
+**/
+VOID
+NarrowGlyphToBlt (
+ IN UINT8 *GlyphBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
+ IN UINT16 ImageWidth,
+ IN UINTN RowWidth,
+ IN UINTN RowHeight,
+ IN BOOLEAN Transparent,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
+ )
+{
+ UINT8 Xpos;
+ UINT8 Ypos;
+ UINT8 Height;
+ UINT8 Width;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
+
+ ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);
+
+ Height = EFI_GLYPH_HEIGHT;
+ Width = EFI_GLYPH_WIDTH;
+
+ //
+ // Move position to the left-top corner of char.
+ //
+ Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;
+
+ //
+ // Char may be partially displayed when CLIP_X or CLIP_Y is not set.
+ //
+ if (RowHeight < Height) {
+ Height = (UINT8)RowHeight;
+ }
+
+ if (RowWidth < Width) {
+ Width = (UINT8)RowWidth;
+ }
+
+ for (Ypos = 0; Ypos < Height; Ypos++) {
+ for (Xpos = 0; Xpos < Width; Xpos++) {
+ if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {
+ Buffer[Ypos * ImageWidth + Xpos] = Foreground;
+ } else {
+ if (!Transparent) {
+ Buffer[Ypos * ImageWidth + Xpos] = Background;
+ }
+ }
+ }
+ }
+
+ *Origin = *Origin + EFI_GLYPH_WIDTH;
+}
+
+/**
+ Convert bitmap data of the glyph to blt structure.
+
+ This is a internal function.
+
+ @param GlyphBuffer Buffer points to bitmap data of glyph.
+ @param Foreground The color of the "on" pixels in the glyph in the
+ bitmap.
+ @param Background The color of the "off" pixels in the glyph in the
+ bitmap.
+ @param ImageWidth Width of the whole image in pixels.
+ @param BaseLine BaseLine in the line.
+ @param RowWidth The width of the text on the line, in pixels.
+ @param RowHeight The height of the line, in pixels.
+ @param Transparent If TRUE, the Background color is ignored and all
+ "off" pixels in the character's drawn will use the
+ pixel value from BltBuffer.
+ @param Cell Points to EFI_HII_GLYPH_INFO structure.
+ @param Attributes The attribute of incoming glyph in GlyphBuffer.
+ @param Origin On input, points to the origin of the to be
+ displayed character, on output, points to the
+ next glyph's origin.
+
+
+**/
+VOID
+GlyphToBlt (
+ IN UINT8 *GlyphBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
+ IN UINT16 ImageWidth,
+ IN UINT16 BaseLine,
+ IN UINTN RowWidth,
+ IN UINTN RowHeight,
+ IN BOOLEAN Transparent,
+ IN CONST EFI_HII_GLYPH_INFO *Cell,
+ IN UINT8 Attributes,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
+ )
+{
+ UINT16 Xpos;
+ UINT16 Ypos;
+ UINT8 Data;
+ UINT16 Index;
+ UINT16 YposOffset;
+ UINTN OffsetY;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+
+ ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
+
+ //
+ // Only adjust origin position if char has no bitmap.
+ //
+ if (GlyphBuffer == NULL) {
+ *Origin = *Origin + Cell->AdvanceX;
+ return;
+ }
+
+ //
+ // Move position to the left-top corner of char.
+ //
+ BltBuffer = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;
+ YposOffset = (UINT16)(BaseLine - (Cell->OffsetY + Cell->Height));
+
+ //
+ // Since non-spacing key will be printed OR'd with the previous glyph, don't
+ // write 0.
+ //
+ if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
+ Transparent = TRUE;
+ }
+
+ //
+ // The glyph's upper left hand corner pixel is the most significant bit of the
+ // first bitmap byte.
+ //
+ for (Ypos = 0; Ypos < Cell->Height && (((UINT32)Ypos + YposOffset) < RowHeight); Ypos++) {
+ OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);
+
+ //
+ // All bits in these bytes are meaningful.
+ //
+ for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {
+ Data = *(GlyphBuffer + OffsetY + Xpos);
+ for (Index = 0; Index < 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
+ if ((Data & (1 << (8 - Index - 1))) != 0) {
+ BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
+ } else {
+ if (!Transparent) {
+ BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
+ }
+ }
+ }
+ }
+
+ if (Cell->Width % 8 != 0) {
+ //
+ // There are some padding bits in this byte. Ignore them.
+ //
+ Data = *(GlyphBuffer + OffsetY + Xpos);
+ for (Index = 0; Index < Cell->Width % 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {
+ if ((Data & (1 << (8 - Index - 1))) != 0) {
+ BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;
+ } else {
+ if (!Transparent) {
+ BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;
+ }
+ }
+ }
+ } // end of if (Width % 8...)
+ } // end of for (Ypos=0...)
+
+ *Origin = *Origin + Cell->AdvanceX;
+}
+
+/**
+ Convert bitmap data of the glyph to blt structure.
+
+ This is a internal function.
+
+ @param GlyphBuffer Buffer points to bitmap data of glyph.
+ @param Foreground The color of the "on" pixels in the glyph in the
+ bitmap.
+ @param Background The color of the "off" pixels in the glyph in the
+ bitmap.
+ @param ImageWidth Width of the whole image in pixels.
+ @param BaseLine BaseLine in the line.
+ @param RowWidth The width of the text on the line, in pixels.
+ @param RowHeight The height of the line, in pixels.
+ @param Transparent If TRUE, the Background color is ignored and all
+ "off" pixels in the character's drawn will use the
+ pixel value from BltBuffer.
+ @param Cell Points to EFI_HII_GLYPH_INFO structure.
+ @param Attributes The attribute of incoming glyph in GlyphBuffer.
+ @param Origin On input, points to the origin of the to be
+ displayed character, on output, points to the
+ next glyph's origin.
+
+ @return Points to the address of next origin node in BltBuffer.
+
+**/
+VOID
+GlyphToImage (
+ IN UINT8 *GlyphBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
+ IN UINT16 ImageWidth,
+ IN UINT16 BaseLine,
+ IN UINTN RowWidth,
+ IN UINTN RowHeight,
+ IN BOOLEAN Transparent,
+ IN CONST EFI_HII_GLYPH_INFO *Cell,
+ IN UINT8 Attributes,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin
+ )
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;
+
+ ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);
+
+ Buffer = *Origin;
+
+ if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {
+ //
+ // This character is a non-spacing key, print it OR'd with the previous glyph.
+ // without advancing cursor.
+ //
+ Buffer -= Cell->AdvanceX;
+ GlyphToBlt (
+ GlyphBuffer,
+ Foreground,
+ Background,
+ ImageWidth,
+ BaseLine,
+ RowWidth,
+ RowHeight,
+ Transparent,
+ Cell,
+ Attributes,
+ &Buffer
+ );
+ } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {
+ //
+ // This character is wide glyph, i.e. 16 pixels * 19 pixels.
+ // Draw it as two narrow glyphs.
+ //
+ NarrowGlyphToBlt (
+ GlyphBuffer,
+ Foreground,
+ Background,
+ ImageWidth,
+ RowWidth,
+ RowHeight,
+ Transparent,
+ Origin
+ );
+
+ NarrowGlyphToBlt (
+ GlyphBuffer + EFI_GLYPH_HEIGHT,
+ Foreground,
+ Background,
+ ImageWidth,
+ RowWidth,
+ RowHeight,
+ Transparent,
+ Origin
+ );
+ } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {
+ //
+ // This character is narrow glyph, i.e. 8 pixels * 19 pixels.
+ //
+ NarrowGlyphToBlt (
+ GlyphBuffer,
+ Foreground,
+ Background,
+ ImageWidth,
+ RowWidth,
+ RowHeight,
+ Transparent,
+ Origin
+ );
+ } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {
+ //
+ // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.
+ //
+ GlyphToBlt (
+ GlyphBuffer,
+ Foreground,
+ Background,
+ ImageWidth,
+ BaseLine,
+ RowWidth,
+ RowHeight,
+ Transparent,
+ Cell,
+ Attributes,
+ Origin
+ );
+ }
+}
+
+/**
+ Write the output parameters of FindGlyphBlock().
+
+ This is a internal function.
+
+ @param BufferIn Buffer which stores the bitmap data of the found
+ block.
+ @param BufferLen Length of BufferIn.
+ @param InputCell Buffer which stores cell information of the
+ encoded bitmap.
+ @param GlyphBuffer Output the corresponding bitmap data of the found
+ block. It is the caller's responsibility to free
+ this buffer.
+ @param Cell Output cell information of the encoded bitmap.
+ @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.
+
+ @retval EFI_SUCCESS The operation is performed successfully.
+ @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
+ task.
+
+**/
+EFI_STATUS
+WriteOutputParam (
+ IN UINT8 *BufferIn,
+ IN UINTN BufferLen,
+ IN EFI_HII_GLYPH_INFO *InputCell,
+ OUT UINT8 **GlyphBuffer OPTIONAL,
+ OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,
+ OUT UINTN *GlyphBufferLen OPTIONAL
+ )
+{
+ if ((BufferIn == NULL) || (InputCell == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Cell != NULL) {
+ CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));
+ }
+
+ if ((GlyphBuffer != NULL) && (BufferLen > 0)) {
+ *GlyphBuffer = (UINT8 *)AllocateZeroPool (BufferLen);
+ if (*GlyphBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (*GlyphBuffer, BufferIn, BufferLen);
+ }
+
+ if (GlyphBufferLen != NULL) {
+ *GlyphBufferLen = BufferLen;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Parse all glyph blocks to find a glyph block specified by CharValue.
+ If CharValue = (CHAR16) (-1), collect all default character cell information
+ within this font package and backup its information.
+
+ @param FontPackage Hii string package instance.
+ @param CharValue Unicode character value, which identifies a glyph
+ block.
+ @param GlyphBuffer Output the corresponding bitmap data of the found
+ block. It is the caller's responsibility to free
+ this buffer.
+ @param Cell Output cell information of the encoded bitmap.
+ @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.
+
+ @retval EFI_SUCCESS The bitmap data is retrieved successfully.
+ @retval EFI_NOT_FOUND The specified CharValue does not exist in current
+ database.
+ @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
+ task.
+
+**/
+EFI_STATUS
+FindGlyphBlock (
+ IN HII_FONT_PACKAGE_INSTANCE *FontPackage,
+ IN CHAR16 CharValue,
+ OUT UINT8 **GlyphBuffer OPTIONAL,
+ OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,
+ OUT UINTN *GlyphBufferLen OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *BlockPtr;
+ UINT16 CharCurrent;
+ UINT16 Length16;
+ UINT32 Length32;
+ EFI_HII_GIBT_GLYPHS_BLOCK Glyphs;
+ UINTN BufferLen;
+ UINT16 Index;
+ EFI_HII_GLYPH_INFO DefaultCell;
+ EFI_HII_GLYPH_INFO LocalCell;
+ INT16 MinOffsetY;
+ UINT16 BaseLine;
+
+ ASSERT (FontPackage != NULL);
+ ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);
+ BaseLine = 0;
+ MinOffsetY = 0;
+
+ if (CharValue == (CHAR16)(-1)) {
+ //
+ // Collect the cell information specified in font package fixed header.
+ // Use CharValue =0 to represent this particular cell.
+ //
+ Status = NewCell (
+ 0,
+ &FontPackage->GlyphInfoList,
+ (EFI_HII_GLYPH_INFO *)((UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32))
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (
+ &LocalCell,
+ (UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32),
+ sizeof (EFI_HII_GLYPH_INFO)
+ );
+ }
+
+ BlockPtr = FontPackage->GlyphBlock;
+ CharCurrent = 1;
+ BufferLen = 0;
+
+ while (*BlockPtr != EFI_HII_GIBT_END) {
+ switch (*BlockPtr) {
+ case EFI_HII_GIBT_DEFAULTS:
+ //
+ // Collect all default character cell information specified by
+ // EFI_HII_GIBT_DEFAULTS.
+ //
+ if (CharValue == (CHAR16)(-1)) {
+ Status = NewCell (
+ CharCurrent,
+ &FontPackage->GlyphInfoList,
+ (EFI_HII_GLYPH_INFO *)(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (
+ &LocalCell,
+ BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
+ sizeof (EFI_HII_GLYPH_INFO)
+ );
+ if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
+ BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
+ }
+
+ if (MinOffsetY > LocalCell.OffsetY) {
+ MinOffsetY = LocalCell.OffsetY;
+ }
+ }
+
+ BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);
+ break;
+
+ case EFI_HII_GIBT_DUPLICATE:
+ if (CharCurrent == CharValue) {
+ CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));
+ CharCurrent = 1;
+ BlockPtr = FontPackage->GlyphBlock;
+ continue;
+ }
+
+ CharCurrent++;
+ BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);
+ break;
+
+ case EFI_HII_GIBT_EXT1:
+ BlockPtr += *(UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));
+ break;
+ case EFI_HII_GIBT_EXT2:
+ CopyMem (
+ &Length16,
+ (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT16)
+ );
+ BlockPtr += Length16;
+ break;
+ case EFI_HII_GIBT_EXT4:
+ CopyMem (
+ &Length32,
+ (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT32)
+ );
+ BlockPtr += Length32;
+ break;
+
+ case EFI_HII_GIBT_GLYPH:
+ CopyMem (
+ &LocalCell,
+ BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
+ sizeof (EFI_HII_GLYPH_INFO)
+ );
+ if (CharValue == (CHAR16)(-1)) {
+ if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {
+ BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);
+ }
+
+ if (MinOffsetY > LocalCell.OffsetY) {
+ MinOffsetY = LocalCell.OffsetY;
+ }
+ }
+
+ BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);
+ if (CharCurrent == CharValue) {
+ return WriteOutputParam (
+ (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),
+ BufferLen,
+ &LocalCell,
+ GlyphBuffer,
+ Cell,
+ GlyphBufferLen
+ );
+ }
+
+ CharCurrent++;
+ BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;
+ break;
+
+ case EFI_HII_GIBT_GLYPHS:
+ BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);
+ CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));
+ BlockPtr += sizeof (EFI_HII_GLYPH_INFO);
+ CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));
+ BlockPtr += sizeof (UINT16);
+
+ if (CharValue == (CHAR16)(-1)) {
+ if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {
+ BaseLine = (UINT16)(Glyphs.Cell.Height + Glyphs.Cell.OffsetY);
+ }
+
+ if (MinOffsetY > Glyphs.Cell.OffsetY) {
+ MinOffsetY = Glyphs.Cell.OffsetY;
+ }
+ }
+
+ BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);
+ for (Index = 0; Index < Glyphs.Count; Index++) {
+ if (CharCurrent + Index == CharValue) {
+ return WriteOutputParam (
+ BlockPtr,
+ BufferLen,
+ &Glyphs.Cell,
+ GlyphBuffer,
+ Cell,
+ GlyphBufferLen
+ );
+ }
+
+ BlockPtr += BufferLen;
+ }
+
+ CharCurrent = (UINT16)(CharCurrent + Glyphs.Count);
+ break;
+
+ case EFI_HII_GIBT_GLYPH_DEFAULT:
+ Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (CharValue == (CHAR16)(-1)) {
+ if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
+ BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
+ }
+
+ if (MinOffsetY > DefaultCell.OffsetY) {
+ MinOffsetY = DefaultCell.OffsetY;
+ }
+ }
+
+ BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
+
+ if (CharCurrent == CharValue) {
+ return WriteOutputParam (
+ BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),
+ BufferLen,
+ &DefaultCell,
+ GlyphBuffer,
+ Cell,
+ GlyphBufferLen
+ );
+ }
+
+ CharCurrent++;
+ BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;
+ break;
+
+ case EFI_HII_GIBT_GLYPHS_DEFAULT:
+ CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
+ Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (CharValue == (CHAR16)(-1)) {
+ if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {
+ BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);
+ }
+
+ if (MinOffsetY > DefaultCell.OffsetY) {
+ MinOffsetY = DefaultCell.OffsetY;
+ }
+ }
+
+ BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);
+ BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);
+ for (Index = 0; Index < Length16; Index++) {
+ if (CharCurrent + Index == CharValue) {
+ return WriteOutputParam (
+ BlockPtr,
+ BufferLen,
+ &DefaultCell,
+ GlyphBuffer,
+ Cell,
+ GlyphBufferLen
+ );
+ }
+
+ BlockPtr += BufferLen;
+ }
+
+ CharCurrent = (UINT16)(CharCurrent + Length16);
+ break;
+
+ case EFI_HII_GIBT_SKIP1:
+ CharCurrent = (UINT16)(CharCurrent + (UINT16)(*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));
+ BlockPtr += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);
+ break;
+ case EFI_HII_GIBT_SKIP2:
+ CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));
+ CharCurrent = (UINT16)(CharCurrent + Length16);
+ BlockPtr += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ if (CharValue < CharCurrent) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (CharValue == (CHAR16)(-1)) {
+ FontPackage->BaseLine = BaseLine;
+ FontPackage->Height = (UINT16)(BaseLine - MinOffsetY);
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Copy a Font Name to a new created EFI_FONT_INFO structure.
+
+ This is a internal function.
+
+ @param FontName NULL-terminated string.
+ @param FontInfo a new EFI_FONT_INFO which stores the FontName.
+ It's caller's responsibility to free this buffer.
+
+ @retval EFI_SUCCESS FontInfo is allocated and copied with FontName.
+ @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
+ task.
+
+**/
+EFI_STATUS
+SaveFontName (
+ IN EFI_STRING FontName,
+ OUT EFI_FONT_INFO **FontInfo
+ )
+{
+ UINTN FontInfoLen;
+ UINTN NameSize;
+
+ ASSERT (FontName != NULL && FontInfo != NULL);
+
+ NameSize = StrSize (FontName);
+ FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;
+ *FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoLen);
+ if (*FontInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve system default font and color.
+
+ @param Private HII database driver private data.
+ @param FontInfo Points to system default font output-related
+ information. It's caller's responsibility to free
+ this buffer.
+ @param FontInfoSize If not NULL, output the size of buffer FontInfo.
+
+ @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.
+ @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the
+ task.
+ @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
+
+**/
+EFI_STATUS
+GetSystemFont (
+ IN HII_DATABASE_PRIVATE_DATA *Private,
+ OUT EFI_FONT_DISPLAY_INFO **FontInfo,
+ OUT UINTN *FontInfoSize OPTIONAL
+ )
+{
+ EFI_FONT_DISPLAY_INFO *Info;
+ UINTN InfoSize;
+ UINTN NameSize;
+
+ if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FontInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The standard font always has the name "sysdefault".
+ //
+ NameSize = StrSize (L"sysdefault");
+ InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
+ Info = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (InfoSize);
+ if (Info == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Info->ForegroundColor = mHiiEfiColors[Private->Attribute & 0x0f];
+ ASSERT ((Private->Attribute >> 4) < 8);
+ Info->BackgroundColor = mHiiEfiColors[Private->Attribute >> 4];
+ Info->FontInfoMask = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;
+ Info->FontInfo.FontStyle = 0;
+ Info->FontInfo.FontSize = EFI_GLYPH_HEIGHT;
+ StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");
+
+ *FontInfo = Info;
+ if (FontInfoSize != NULL) {
+ *FontInfoSize = InfoSize;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or
+ returns the system default according to the optional inputs.
+
+ This is a internal function.
+
+ @param Private HII database driver private data.
+ @param StringInfo Points to the string output information,
+ including the color and font.
+ @param SystemInfo If not NULL, points to system default font and color.
+
+ @param SystemInfoLen If not NULL, output the length of default system
+ info.
+
+ @retval TRUE Yes, it points to system default.
+ @retval FALSE No.
+
+**/
+BOOLEAN
+IsSystemFontInfo (
+ IN HII_DATABASE_PRIVATE_DATA *Private,
+ IN EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_FONT_DISPLAY_INFO **SystemInfo OPTIONAL,
+ OUT UINTN *SystemInfoLen OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_FONT_DISPLAY_INFO *SystemDefault;
+ UINTN DefaultLen;
+ BOOLEAN Flag;
+
+ ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
+
+ if ((StringInfo == NULL) && (SystemInfo == NULL)) {
+ return TRUE;
+ }
+
+ SystemDefault = NULL;
+ DefaultLen = 0;
+
+ Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));
+
+ //
+ // Record the system default info.
+ //
+ if (SystemInfo != NULL) {
+ *SystemInfo = SystemDefault;
+ }
+
+ if (SystemInfoLen != NULL) {
+ *SystemInfoLen = DefaultLen;
+ }
+
+ if (StringInfo == NULL) {
+ return TRUE;
+ }
+
+ Flag = FALSE;
+ //
+ // Check the FontInfoMask to see whether it is retrieving system info.
+ //
+ if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {
+ if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {
+ goto Exit;
+ }
+ }
+
+ if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {
+ if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {
+ goto Exit;
+ }
+ }
+
+ if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {
+ if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {
+ goto Exit;
+ }
+ }
+
+ if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {
+ if (CompareMem (
+ &StringInfo->ForegroundColor,
+ &SystemDefault->ForegroundColor,
+ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ ) != 0)
+ {
+ goto Exit;
+ }
+ }
+
+ if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {
+ if (CompareMem (
+ &StringInfo->BackgroundColor,
+ &SystemDefault->BackgroundColor,
+ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ ) != 0)
+ {
+ goto Exit;
+ }
+ }
+
+ Flag = TRUE;
+
+Exit:
+ if (SystemInfo == NULL) {
+ if (SystemDefault != NULL) {
+ FreePool (SystemDefault);
+ }
+ }
+
+ return Flag;
+}
+
+/**
+ This function checks whether EFI_FONT_INFO exists in current database. If
+ FontInfoMask is specified, check what options can be used to make a match.
+ Note that the masks relate to where the system default should be supplied
+ are ignored by this function.
+
+ @param Private Hii database private structure.
+ @param FontInfo Points to EFI_FONT_INFO structure.
+ @param FontInfoMask If not NULL, describes what options can be used
+ to make a match between the font requested and
+ the font available. The caller must guarantee
+ this mask is valid.
+ @param FontHandle On entry, Points to the font handle returned by a
+ previous call to GetFontInfo() or NULL to start
+ with the first font.
+ @param GlobalFontInfo If not NULL, output the corresponding global font
+ info.
+
+ @retval TRUE Existed
+ @retval FALSE Not existed
+
+**/
+BOOLEAN
+IsFontInfoExisted (
+ IN HII_DATABASE_PRIVATE_DATA *Private,
+ IN EFI_FONT_INFO *FontInfo,
+ IN EFI_FONT_INFO_MASK *FontInfoMask OPTIONAL,
+ IN EFI_FONT_HANDLE FontHandle OPTIONAL,
+ OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL
+ )
+{
+ HII_GLOBAL_FONT_INFO *GlobalFont;
+ HII_GLOBAL_FONT_INFO *GlobalFontBackup1;
+ HII_GLOBAL_FONT_INFO *GlobalFontBackup2;
+ LIST_ENTRY *Link;
+ EFI_FONT_INFO_MASK Mask;
+ BOOLEAN Matched;
+ BOOLEAN VagueMatched1;
+ BOOLEAN VagueMatched2;
+
+ ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);
+ ASSERT (FontInfo != NULL);
+
+ //
+ // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE
+ // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.
+ //
+ Matched = FALSE;
+ VagueMatched1 = FALSE;
+ VagueMatched2 = FALSE;
+
+ Mask = 0;
+ GlobalFontBackup1 = NULL;
+ GlobalFontBackup2 = NULL;
+
+ // The process of where the system default should be supplied instead of
+ // the specified font info beyonds this function's scope.
+ //
+ if (FontInfoMask != NULL) {
+ Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);
+ }
+
+ //
+ // If not NULL, FontHandle points to the next node of the last searched font
+ // node by previous call.
+ //
+ if (FontHandle == NULL) {
+ Link = Private->FontInfoList.ForwardLink;
+ } else {
+ Link = (LIST_ENTRY *)FontHandle;
+ }
+
+ for ( ; Link != &Private->FontInfoList; Link = Link->ForwardLink) {
+ GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);
+ if (FontInfoMask == NULL) {
+ if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {
+ if (GlobalFontInfo != NULL) {
+ *GlobalFontInfo = GlobalFont;
+ }
+
+ return TRUE;
+ }
+ } else {
+ //
+ // Check which options could be used to make a match.
+ //
+ switch (Mask) {
+ case EFI_FONT_INFO_ANY_FONT:
+ if ((GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) &&
+ (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
+ {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:
+ Matched = TRUE;
+ break;
+ //
+ // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to
+ // remove some of the specified styles to meet the style requested.
+ //
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ Matched = TRUE;
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ //
+ // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to
+ // stretch or shrink a font to meet the size requested.
+ //
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ } else {
+ VagueMatched2 = TRUE;
+ GlobalFontBackup2 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ Matched = TRUE;
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_STYLE:
+ if ((CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0) &&
+ (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
+ {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:
+ if (CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0)
+ {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:
+ if (CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0)
+ {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_SIZE:
+ if ((CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0) &&
+ (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
+ {
+ Matched = TRUE;
+ }
+
+ break;
+ case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:
+ if (CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0)
+ {
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ Matched = TRUE;
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_RESTYLE:
+ if ((CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0) &&
+ (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))
+ {
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ Matched = TRUE;
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_RESIZE:
+ if ((CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0) &&
+ (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))
+ {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ }
+
+ break;
+ case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:
+ if (CompareMem (
+ GlobalFont->FontInfo->FontName,
+ FontInfo->FontName,
+ StrSize (FontInfo->FontName)
+ ) == 0)
+ {
+ if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ Matched = TRUE;
+ } else {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ }
+ } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {
+ if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {
+ VagueMatched1 = TRUE;
+ GlobalFontBackup1 = GlobalFont;
+ } else {
+ VagueMatched2 = TRUE;
+ GlobalFontBackup2 = GlobalFont;
+ }
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ if (Matched) {
+ if (GlobalFontInfo != NULL) {
+ *GlobalFontInfo = GlobalFont;
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ if (VagueMatched1) {
+ if (GlobalFontInfo != NULL) {
+ *GlobalFontInfo = GlobalFontBackup1;
+ }
+
+ return TRUE;
+ } else if (VagueMatched2) {
+ if (GlobalFontInfo != NULL) {
+ *GlobalFontInfo = GlobalFontBackup2;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Check whether the unicode represents a line break or not.
+
+ This is a internal function. Please see Section 27.2.6 of the UEFI Specification
+ for a description of the supported string format.
+
+ @param Char Unicode character
+
+ @retval 0 Yes, it forces a line break.
+ @retval 1 Yes, it presents a line break opportunity
+ @retval 2 Yes, it requires a line break happen before and after it.
+ @retval -1 No, it is not a link break.
+
+**/
+INT8
+IsLineBreak (
+ IN CHAR16 Char
+ )
+{
+ switch (Char) {
+ //
+ // Mandatory line break characters, which force a line-break
+ //
+ case 0x000A:
+ case 0x000C:
+ case 0x000D:
+ case 0x2028:
+ case 0x2029:
+ return 0;
+ //
+ // Space characters, which is taken as a line-break opportunity
+ //
+ case 0x0020:
+ case 0x1680:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x205F:
+ //
+ // In-Word Break Opportunities
+ //
+ case 0x200B:
+ return 1;
+ //
+ // A space which is not a line-break opportunity
+ //
+ case 0x00A0:
+ case 0x202F:
+ //
+ // A hyphen which is not a line-break opportunity
+ //
+ case 0x2011:
+ return -1;
+ //
+ // Hyphen characters which describe line break opportunities after the character
+ //
+ case 0x058A:
+ case 0x2010:
+ case 0x2012:
+ case 0x2013:
+ case 0x0F0B:
+ case 0x1361:
+ case 0x17D5:
+ return 1;
+ //
+ // A hyphen which describes line break opportunities before and after them, but not between a pair of them
+ //
+ case 0x2014:
+ return 2;
+ }
+
+ return -1;
+}
+
+/**
+ Renders a string to a bitmap or to the display.
+
+ @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
+ @param Flags Describes how the string is to be drawn.
+ @param String Points to the null-terminated string to be
+ displayed.
+ @param StringInfo Points to the string output information,
+ including the color and font. If NULL, then the
+ string will be output in the default system font
+ and color.
+ @param Blt If this points to a non-NULL on entry, this
+ points to the image, which is Width pixels wide
+ and Height pixels high. The string will be drawn
+ onto this image and
+ EFI_HII_OUT_FLAG_CLIP is implied. If this points
+ to a NULL on entry, then a buffer
+ will be allocated to hold the generated image and
+ the pointer updated on exit. It is the caller's
+ responsibility to free this buffer.
+ @param BltX Specifies the offset from the left and top edge
+ of the image of the first character cell in the
+ image.
+ @param BltY Specifies the offset from the left and top edge
+ of the image of the first character cell in the
+ image.
+ @param RowInfoArray If this is non-NULL on entry, then on exit, this
+ will point to an allocated buffer containing
+ row information and RowInfoArraySize will be
+ updated to contain the number of elements.
+ This array describes the characters which were at
+ least partially drawn and the heights of the
+ rows. It is the caller's responsibility to free
+ this buffer.
+ @param RowInfoArraySize If this is non-NULL on entry, then on exit it
+ contains the number of elements in RowInfoArray.
+ @param ColumnInfoArray If this is non-NULL, then on return it will be
+ filled with the horizontal offset for each
+ character in the string on the row where it is
+ displayed. Non-printing characters will have
+ the offset ~0. The caller is responsible to
+ allocate a buffer large enough so that there
+ is one entry for each character in the string,
+ not including the null-terminator. It is possible
+ when character display is normalized that some
+ character cells overlap.
+
+ @retval EFI_SUCCESS The string was successfully rendered.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for
+ RowInfoArray or Blt.
+ @retval EFI_INVALID_PARAMETER The String or Blt was NULL.
+ @retval EFI_INVALID_PARAMETER Flags were invalid combination..
+
+**/
+EFI_STATUS
+EFIAPI
+HiiStringToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ HII_DATABASE_PRIVATE_DATA *Private;
+ UINT8 **GlyphBuf;
+ EFI_HII_GLYPH_INFO *Cell;
+ UINT8 *Attributes;
+ EFI_IMAGE_OUTPUT *Image;
+ EFI_STRING StringPtr;
+ EFI_STRING StringTmp;
+ EFI_HII_ROW_INFO *RowInfo;
+ UINTN LineWidth;
+ UINTN LineHeight;
+ UINTN LineOffset;
+ UINTN LastLineHeight;
+ UINTN BaseLineOffset;
+ UINT16 MaxRowNum;
+ UINT16 RowIndex;
+ UINTN Index;
+ UINTN NextIndex;
+ UINTN Index1;
+ EFI_FONT_DISPLAY_INFO *StringInfoOut;
+ EFI_FONT_DISPLAY_INFO *SystemDefault;
+ EFI_FONT_HANDLE FontHandle;
+ EFI_STRING StringIn;
+ EFI_STRING StringIn2;
+ UINT16 Height;
+ UINT16 BaseLine;
+ EFI_FONT_INFO *FontInfo;
+ BOOLEAN SysFontFlag;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+ BOOLEAN Transparent;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
+ UINTN RowInfoSize;
+ BOOLEAN LineBreak;
+ UINTN StrLength;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *RowBufferPtr;
+ HII_GLOBAL_FONT_INFO *GlobalFont;
+ UINT32 PreInitBkgnd;
+
+ //
+ // Check incoming parameters.
+ //
+
+ if ((This == NULL) || (String == NULL) || (Blt == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*Blt == NULL) {
+ //
+ // These two flag cannot be used if Blt is NULL upon entry.
+ //
+ if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
+ //
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.
+ //
+ 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)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*Blt == NULL) {
+ //
+ // Create a new bitmap and draw the string onto this image.
+ //
+ Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
+ if (Image == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Image->Width = 800;
+ Image->Height = 600;
+ Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (Image->Image.Bitmap == NULL) {
+ FreePool (Image);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Other flags are not permitted when Blt is NULL.
+ //
+ Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
+ *Blt = Image;
+ }
+
+ StrLength = StrLen (String);
+ GlyphBuf = (UINT8 **)AllocateZeroPool (StrLength * sizeof (UINT8 *));
+ ASSERT (GlyphBuf != NULL);
+ Cell = (EFI_HII_GLYPH_INFO *)AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
+ ASSERT (Cell != NULL);
+ Attributes = (UINT8 *)AllocateZeroPool (StrLength * sizeof (UINT8));
+ ASSERT (Attributes != NULL);
+
+ FontInfo = NULL;
+ RowInfo = NULL;
+ Status = EFI_SUCCESS;
+ StringIn2 = NULL;
+ SystemDefault = NULL;
+ StringIn = NULL;
+
+ //
+ // Calculate the string output information, including specified color and font .
+ // If StringInfo does not points to system font info, it must indicate an existing
+ // EFI_FONT_INFO.
+ //
+ StringInfoOut = NULL;
+ FontHandle = NULL;
+ Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
+ SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
+
+ if (SysFontFlag) {
+ ASSERT (SystemDefault != NULL);
+ FontInfo = NULL;
+ Height = SystemDefault->FontInfo.FontSize;
+ BaseLine = SystemDefault->FontInfo.FontSize;
+ Foreground = SystemDefault->ForegroundColor;
+ Background = SystemDefault->BackgroundColor;
+ } else {
+ //
+ // StringInfo must not be NULL if it is not system info.
+ //
+ ASSERT (StringInfo != NULL);
+ Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
+ // Use the system font instead. Still use the color specified by StringInfo.
+ //
+ SysFontFlag = TRUE;
+ FontInfo = NULL;
+ Height = SystemDefault->FontInfo.FontSize;
+ BaseLine = SystemDefault->FontInfo.FontSize;
+ Foreground = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;
+ Background = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;
+ } else if (Status == EFI_SUCCESS) {
+ FontInfo = &StringInfoOut->FontInfo;
+ if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
+ Height = GlobalFont->FontPackage->Height;
+ BaseLine = GlobalFont->FontPackage->BaseLine;
+ Foreground = StringInfoOut->ForegroundColor;
+ Background = StringInfoOut->BackgroundColor;
+ } else {
+ goto Exit;
+ }
+ } else {
+ goto Exit;
+ }
+ }
+
+ //
+ // Use the maximum height of font as the base line.
+ // And, use the maximum height as line height.
+ //
+ LineHeight = Height;
+ LastLineHeight = Height;
+ BaseLineOffset = Height - BaseLine;
+
+ //
+ // Parse the string to be displayed to drop some ignored characters.
+ //
+
+ StringPtr = String;
+
+ //
+ // Ignore line-break characters only. Hyphens or dash character will be displayed
+ // without line-break opportunity.
+ //
+ if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
+ StringIn = AllocateZeroPool (StrSize (StringPtr));
+ if (StringIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ StringTmp = StringIn;
+ while (*StringPtr != 0) {
+ if (IsLineBreak (*StringPtr) == 0) {
+ StringPtr++;
+ } else {
+ *StringTmp++ = *StringPtr++;
+ }
+ }
+
+ *StringTmp = 0;
+ StringPtr = StringIn;
+ }
+
+ //
+ // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
+ // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.
+ //
+ StringIn2 = AllocateZeroPool (StrSize (StringPtr));
+ if (StringIn2 == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Index = 0;
+ StringTmp = StringIn2;
+ StrLength = StrLen (StringPtr);
+ while (*StringPtr != 0 && Index < StrLength) {
+ if (IsLineBreak (*StringPtr) == 0) {
+ *StringTmp++ = *StringPtr++;
+ Index++;
+ continue;
+ }
+
+ Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
+ if (Status == EFI_NOT_FOUND) {
+ if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
+ GlyphBuf[Index] = NULL;
+ ZeroMem (&Cell[Index], sizeof (Cell[Index]));
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Unicode 0xFFFD must exist in current hii database if this flag is not set.
+ //
+ Status = GetGlyphBuffer (
+ Private,
+ REPLACE_UNKNOWN_GLYPH,
+ FontInfo,
+ &GlyphBuf[Index],
+ &Cell[Index],
+ &Attributes[Index]
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ *StringTmp++ = *StringPtr++;
+ Index++;
+ }
+
+ *StringTmp = 0;
+ StringPtr = StringIn2;
+
+ //
+ // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
+ // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
+ // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
+ // Otherwise render this string to a new allocated image and output it.
+ //
+ Image = *Blt;
+ BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
+ if (Image->Height < BltY) {
+ //
+ // the top edge of the image should be in Image resolution scope.
+ //
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ MaxRowNum = (UINT16)((Image->Height - BltY) / Height);
+ if ((Image->Height - BltY) % Height != 0) {
+ LastLineHeight = (Image->Height - BltY) % Height;
+ MaxRowNum++;
+ }
+
+ RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
+ if (RowInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Format the glyph buffer according to flags.
+ //
+ Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
+
+ for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
+ LineWidth = 0;
+ LineBreak = FALSE;
+
+ //
+ // Clip the final row if the row's bottom-most on pixel cannot fit when
+ // EFI_HII_OUT_FLAG_CLEAN_Y is set.
+ //
+ if (RowIndex == MaxRowNum - 1) {
+ if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {
+ //
+ // Don't draw at all if the row's bottom-most on pixel cannot fit.
+ //
+ break;
+ }
+
+ LineHeight = LastLineHeight;
+ }
+
+ //
+ // Calculate how many characters there are in a row.
+ //
+ RowInfo[RowIndex].StartIndex = Index;
+
+ while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
+ if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&
+ (IsLineBreak (StringPtr[Index]) == 0))
+ {
+ //
+ // It forces a line break that ends this row.
+ //
+ Index++;
+ LineBreak = TRUE;
+ break;
+ }
+
+ //
+ // If the glyph of the character is existing, then accumulate the actual printed width
+ //
+ LineWidth += (UINTN)Cell[Index].AdvanceX;
+
+ Index++;
+ }
+
+ //
+ // Record index of next char.
+ //
+ NextIndex = Index;
+ //
+ // Return to the previous char.
+ //
+ Index--;
+ if (LineBreak && (Index > 0)) {
+ //
+ // Return the previous non line break char.
+ //
+ Index--;
+ }
+
+ //
+ // If this character is the last character of a row, we need not
+ // draw its (AdvanceX - Width - OffsetX) for next character.
+ //
+ LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
+
+ //
+ // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
+ //
+ if ((LineWidth + BltX <= Image->Width) ||
+ ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))
+ {
+ //
+ // Record right-most character in RowInfo even if it is partially displayed.
+ //
+ RowInfo[RowIndex].EndIndex = Index;
+ RowInfo[RowIndex].LineWidth = LineWidth;
+ RowInfo[RowIndex].LineHeight = LineHeight;
+ RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
+ } else {
+ //
+ // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
+ // if its right-most on pixel cannot fit.
+ //
+ if (Index > RowInfo[RowIndex].StartIndex) {
+ //
+ // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
+ //
+ LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);
+ LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
+ RowInfo[RowIndex].EndIndex = Index - 1;
+ RowInfo[RowIndex].LineWidth = LineWidth;
+ RowInfo[RowIndex].LineHeight = LineHeight;
+ RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
+ } else {
+ //
+ // There is no enough column to draw any character, so set current line width to zero.
+ // And go to draw Next line if LineBreak is set.
+ //
+ RowInfo[RowIndex].LineWidth = 0;
+ goto NextLine;
+ }
+ }
+
+ //
+ // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
+ // opportunity prior to a character whose right-most extent would exceed Width.
+ // Search the right-most line-break opportunity here.
+ //
+ if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&
+ ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&
+ !LineBreak)
+ {
+ if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
+ LineWidth = RowInfo[RowIndex].LineWidth;
+ for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
+ if (Index1 == RowInfo[RowIndex].EndIndex) {
+ LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
+ } else {
+ LineWidth -= Cell[Index1].AdvanceX;
+ }
+
+ if (IsLineBreak (StringPtr[Index1]) > 0) {
+ LineBreak = TRUE;
+ if (Index1 > RowInfo[RowIndex].StartIndex) {
+ RowInfo[RowIndex].EndIndex = Index1 - 1;
+ }
+
+ //
+ // relocate to the character after the right-most line break opportunity of this line
+ //
+ NextIndex = Index1 + 1;
+ break;
+ }
+
+ //
+ // If don't find a line break opportunity from EndIndex to StartIndex,
+ // then jump out.
+ //
+ if (Index1 == RowInfo[RowIndex].StartIndex) {
+ break;
+ }
+ }
+
+ //
+ // Update LineWidth to the real width
+ //
+ if (IsLineBreak (StringPtr[Index1]) > 0) {
+ if (Index1 == RowInfo[RowIndex].StartIndex) {
+ LineWidth = 0;
+ } else {
+ LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
+ }
+
+ RowInfo[RowIndex].LineWidth = LineWidth;
+ }
+ }
+
+ //
+ // If no line-break opportunity can be found, then the text will
+ // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
+ //
+ if (!LineBreak) {
+ LineWidth = RowInfo[RowIndex].LineWidth;
+ Index1 = RowInfo[RowIndex].EndIndex;
+ if (LineWidth + BltX > Image->Width) {
+ if (Index1 > RowInfo[RowIndex].StartIndex) {
+ //
+ // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
+ //
+ LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
+ LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
+ RowInfo[RowIndex].EndIndex = Index1 - 1;
+ RowInfo[RowIndex].LineWidth = LineWidth;
+ } else {
+ //
+ // There is no enough column to draw any character, so set current line width to zero.
+ // And go to draw Next line if LineBreak is set.
+ //
+ RowInfo[RowIndex].LineWidth = 0;
+ goto NextLine;
+ }
+ }
+ }
+ }
+
+ //
+ // LineWidth can't exceed Image width.
+ //
+ if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
+ RowInfo[RowIndex].LineWidth = Image->Width - BltX;
+ }
+
+ //
+ // Draw it to screen or existing bitmap depending on whether
+ // EFI_HII_DIRECT_TO_SCREEN is set.
+ //
+ LineOffset = 0;
+ if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
+ BltBuffer = NULL;
+ if (RowInfo[RowIndex].LineWidth != 0) {
+ BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (BltBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Initialize the background color.
+ //
+ PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;
+ SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);
+ //
+ // Set BufferPtr to Origin by adding baseline to the starting position.
+ //
+ BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
+ }
+
+ for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
+ if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
+ //
+ // Only BLT these character which have corresponding glyph in font database.
+ //
+ GlyphToImage (
+ GlyphBuf[Index1],
+ Foreground,
+ Background,
+ (UINT16)RowInfo[RowIndex].LineWidth,
+ BaseLine,
+ RowInfo[RowIndex].LineWidth - LineOffset,
+ RowInfo[RowIndex].LineHeight,
+ Transparent,
+ &Cell[Index1],
+ Attributes[Index1],
+ &BufferPtr
+ );
+ }
+
+ if (ColumnInfoArray != NULL) {
+ if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
+ || (RowInfo[RowIndex].LineWidth == 0))
+ {
+ *ColumnInfoArray = (UINTN) ~0;
+ } else {
+ *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
+ }
+
+ ColumnInfoArray++;
+ }
+
+ LineOffset += Cell[Index1].AdvanceX;
+ }
+
+ if (BltBuffer != NULL) {
+ Status = Image->Image.Screen->Blt (
+ Image->Image.Screen,
+ BltBuffer,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ BltX,
+ BltY,
+ RowInfo[RowIndex].LineWidth,
+ RowInfo[RowIndex].LineHeight,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (BltBuffer);
+ goto Exit;
+ }
+
+ FreePool (BltBuffer);
+ }
+ } else {
+ //
+ // Save the starting position for calculate the starting position of next row.
+ //
+ RowBufferPtr = BufferPtr;
+ //
+ // Set BufferPtr to Origin by adding baseline to the starting position.
+ //
+ BufferPtr = BufferPtr + BaseLine * Image->Width;
+ for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
+ if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
+ //
+ // Only BLT these character which have corresponding glyph in font database.
+ //
+ GlyphToImage (
+ GlyphBuf[Index1],
+ Foreground,
+ Background,
+ Image->Width,
+ BaseLine,
+ RowInfo[RowIndex].LineWidth - LineOffset,
+ RowInfo[RowIndex].LineHeight,
+ Transparent,
+ &Cell[Index1],
+ Attributes[Index1],
+ &BufferPtr
+ );
+ }
+
+ if (ColumnInfoArray != NULL) {
+ if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
+ || (RowInfo[RowIndex].LineWidth == 0))
+ {
+ *ColumnInfoArray = (UINTN) ~0;
+ } else {
+ *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
+ }
+
+ ColumnInfoArray++;
+ }
+
+ LineOffset += Cell[Index1].AdvanceX;
+ }
+
+ //
+ // Jump to starting position of next row.
+ //
+ if (RowIndex == 0) {
+ BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
+ } else {
+ BufferPtr = RowBufferPtr + LineHeight * Image->Width;
+ }
+ }
+
+NextLine:
+ //
+ // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down
+ //
+ BltY += RowInfo[RowIndex].LineHeight;
+
+ RowIndex++;
+ Index = NextIndex;
+
+ if (!LineBreak) {
+ //
+ // If there is not a mandatory line break or line break opportunity, only render one line to image
+ //
+ break;
+ }
+ }
+
+ //
+ // Write output parameters.
+ //
+ RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
+ if (RowInfoArray != NULL) {
+ if (RowInfoSize > 0) {
+ *RowInfoArray = AllocateZeroPool (RowInfoSize);
+ if (*RowInfoArray == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
+ } else {
+ *RowInfoArray = NULL;
+ }
+ }
+
+ if (RowInfoArraySize != NULL) {
+ *RowInfoArraySize = RowIndex;
+ }
+
+ Status = EFI_SUCCESS;
+
+Exit:
+
+ for (Index = 0; Index < StrLength; Index++) {
+ if (GlyphBuf[Index] != NULL) {
+ FreePool (GlyphBuf[Index]);
+ }
+ }
+
+ if (StringIn != NULL) {
+ FreePool (StringIn);
+ }
+
+ if (StringIn2 != NULL) {
+ FreePool (StringIn2);
+ }
+
+ if (StringInfoOut != NULL) {
+ FreePool (StringInfoOut);
+ }
+
+ if (RowInfo != NULL) {
+ FreePool (RowInfo);
+ }
+
+ if (SystemDefault != NULL) {
+ FreePool (SystemDefault);
+ }
+
+ if (GlyphBuf != NULL) {
+ FreePool (GlyphBuf);
+ }
+
+ if (Cell != NULL) {
+ FreePool (Cell);
+ }
+
+ if (Attributes != NULL) {
+ FreePool (Attributes);
+ }
+
+ return Status;
+}
+
+/**
+ Render a string to a bitmap or the screen containing the contents of the specified string.
+
+ @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
+ @param Flags Describes how the string is to be drawn.
+ @param PackageList The package list in the HII database to search
+ for the specified string.
+ @param StringId The string's id, which is unique within
+ PackageList.
+ @param Language Points to the language for the retrieved string.
+ If NULL, then the current system language is
+ used.
+ @param StringInfo Points to the string output information,
+ including the color and font. If NULL, then the
+ string will be output in the default system font
+ and color.
+ @param Blt If this points to a non-NULL on entry, this
+ points to the image, which is Width pixels wide
+ and Height pixels high. The string will be drawn
+ onto this image and
+ EFI_HII_OUT_FLAG_CLIP is implied. If this points
+ to a NULL on entry, then a buffer
+ will be allocated to hold the generated image and
+ the pointer updated on exit. It is the caller's
+ responsibility to free this buffer.
+ @param BltX Specifies the offset from the left and top edge
+ of the image of the first character cell in the
+ image.
+ @param BltY Specifies the offset from the left and top edge
+ of the image of the first character cell in the
+ image.
+ @param RowInfoArray If this is non-NULL on entry, then on exit, this
+ will point to an allocated buffer containing
+ row information and RowInfoArraySize will be
+ updated to contain the number of elements.
+ This array describes the characters which were at
+ least partially drawn and the heights of the
+ rows. It is the caller's responsibility to free
+ this buffer.
+ @param RowInfoArraySize If this is non-NULL on entry, then on exit it
+ contains the number of elements in RowInfoArray.
+ @param ColumnInfoArray If this is non-NULL, then on return it will be
+ filled with the horizontal offset for each
+ character in the string on the row where it is
+ displayed. Non-printing characters will have
+ the offset ~0. The caller is responsible to
+ allocate a buffer large enough so that there
+ is one entry for each character in the string,
+ not including the null-terminator. It is possible
+ when character display is normalized that some
+ character cells overlap.
+
+ @retval EFI_SUCCESS The string was successfully rendered.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for
+ RowInfoArray or Blt.
+ @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.
+ @retval EFI_INVALID_PARAMETER Flags were invalid combination.
+ @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the string id is not
+ in the specified PackageList.
+
+**/
+EFI_STATUS
+EFIAPI
+HiiStringIdToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ HII_DATABASE_PRIVATE_DATA *Private;
+ EFI_HII_STRING_PROTOCOL *HiiString;
+ EFI_STRING String;
+ UINTN StringSize;
+ UINTN FontLen;
+ UINTN NameSize;
+ EFI_FONT_INFO *StringFontInfo;
+ EFI_FONT_DISPLAY_INFO *NewStringInfo;
+ CHAR8 TempSupportedLanguages;
+ CHAR8 *SupportedLanguages;
+ UINTN SupportedLanguagesSize;
+ CHAR8 *CurrentLanguage;
+ CHAR8 *BestLanguage;
+
+ if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsHiiHandleValid (PackageList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Initialize string pointers to be NULL
+ //
+ SupportedLanguages = NULL;
+ CurrentLanguage = NULL;
+ BestLanguage = NULL;
+ String = NULL;
+ StringFontInfo = NULL;
+ NewStringInfo = NULL;
+
+ //
+ // Get the string to be displayed.
+ //
+ Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
+ HiiString = &Private->HiiString;
+
+ //
+ // Get the size of supported language.
+ //
+ SupportedLanguagesSize = 0;
+ Status = HiiString->GetLanguages (
+ HiiString,
+ PackageList,
+ &TempSupportedLanguages,
+ &SupportedLanguagesSize
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ SupportedLanguages = AllocatePool (SupportedLanguagesSize);
+ if (SupportedLanguages == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = HiiString->GetLanguages (
+ HiiString,
+ PackageList,
+ SupportedLanguages,
+ &SupportedLanguagesSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ if (Language == NULL) {
+ Language = "";
+ }
+
+ GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);
+ BestLanguage = GetBestLanguage (
+ SupportedLanguages,
+ FALSE,
+ Language,
+ (CurrentLanguage == NULL) ? CurrentLanguage : "",
+ (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
+ NULL
+ );
+ if (BestLanguage == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ StringSize = MAX_STRING_LENGTH;
+ String = (EFI_STRING)AllocateZeroPool (StringSize);
+ if (String == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Status = HiiString->GetString (
+ HiiString,
+ BestLanguage,
+ PackageList,
+ StringId,
+ String,
+ &StringSize,
+ &StringFontInfo
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (String);
+ String = (EFI_STRING)AllocateZeroPool (StringSize);
+ if (String == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Status = HiiString->GetString (
+ HiiString,
+ BestLanguage,
+ PackageList,
+ StringId,
+ String,
+ &StringSize,
+ NULL
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // When StringInfo specifies that string will be output in the system default font and color,
+ // use particular stringfontinfo described in string package instead if exists.
+ // StringFontInfo equals NULL means system default font attaches with the string block.
+ //
+ if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {
+ NameSize = StrSize (StringFontInfo->FontName);
+ FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
+ NewStringInfo = AllocateZeroPool (FontLen);
+ if (NewStringInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
+ NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
+ NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;
+ StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
+
+ Status = HiiStringToImage (
+ This,
+ Flags,
+ String,
+ NewStringInfo,
+ Blt,
+ BltX,
+ BltY,
+ RowInfoArray,
+ RowInfoArraySize,
+ ColumnInfoArray
+ );
+ goto Exit;
+ }
+
+ Status = HiiStringToImage (
+ This,
+ Flags,
+ String,
+ StringInfo,
+ Blt,
+ BltX,
+ BltY,
+ RowInfoArray,
+ RowInfoArraySize,
+ ColumnInfoArray
+ );
+
+Exit:
+ if (SupportedLanguages != NULL) {
+ FreePool (SupportedLanguages);
+ }
+
+ if (CurrentLanguage != NULL) {
+ FreePool (CurrentLanguage);
+ }
+
+ if (BestLanguage != NULL) {
+ FreePool (BestLanguage);
+ }
+
+ if (String != NULL) {
+ FreePool (String);
+ }
+
+ if (StringFontInfo != NULL) {
+ FreePool (StringFontInfo);
+ }
+
+ if (NewStringInfo != NULL) {
+ FreePool (NewStringInfo);
+ }
+
+ return Status;
+}
+
+/**
+ Convert the glyph for a single character into a bitmap.
+
+ @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
+ @param Char Character to retrieve.
+ @param StringInfo Points to the string font and color information
+ or NULL if the string should use the default
+ system font and color.
+ @param Blt Thus must point to a NULL on entry. A buffer will
+ be allocated to hold the output and the pointer
+ updated on exit. It is the caller's
+ responsibility to free this buffer.
+ @param Baseline Number of pixels from the bottom of the bitmap to
+ the baseline.
+
+ @retval EFI_SUCCESS Glyph bitmap created.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.
+ @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the
+ glyph for Unicode character 0xFFFD.
+ @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+HiiGetGlyph (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN CHAR16 Char,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_IMAGE_OUTPUT **Blt,
+ OUT UINTN *Baseline OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ HII_DATABASE_PRIVATE_DATA *Private;
+ EFI_IMAGE_OUTPUT *Image;
+ UINT8 *GlyphBuffer;
+ EFI_FONT_DISPLAY_INFO *SystemDefault;
+ EFI_FONT_DISPLAY_INFO *StringInfoOut;
+ BOOLEAN Default;
+ EFI_FONT_HANDLE FontHandle;
+ EFI_STRING String;
+ EFI_HII_GLYPH_INFO Cell;
+ EFI_FONT_INFO *FontInfo;
+ UINT8 Attributes;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+ UINT16 BaseLine;
+
+ if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
+
+ Default = FALSE;
+ Image = NULL;
+ SystemDefault = NULL;
+ FontHandle = NULL;
+ String = NULL;
+ GlyphBuffer = NULL;
+ StringInfoOut = NULL;
+ FontInfo = NULL;
+
+ ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
+
+ if (!Default) {
+ //
+ // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
+ // the specified color and font.
+ //
+ String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);
+ if (String == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ *String = Char;
+ *(String + 1) = 0;
+
+ Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ ASSERT (StringInfoOut != NULL);
+ FontInfo = &StringInfoOut->FontInfo;
+ Foreground = StringInfoOut->ForegroundColor;
+ Background = StringInfoOut->BackgroundColor;
+ } else {
+ ASSERT (SystemDefault != NULL);
+ Foreground = SystemDefault->ForegroundColor;
+ Background = SystemDefault->BackgroundColor;
+ }
+
+ Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
+ if (Image == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Image->Width = Cell.Width;
+ Image->Height = Cell.Height;
+
+ if (Image->Width * Image->Height > 0) {
+ Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ if (Image->Image.Bitmap == NULL) {
+ FreePool (Image);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Set BaseLine to the char height.
+ //
+ BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);
+ //
+ // Set BltBuffer to the position of Origin.
+ //
+ BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
+ GlyphToImage (
+ GlyphBuffer,
+ Foreground,
+ Background,
+ Image->Width,
+ BaseLine,
+ Cell.Width + Cell.OffsetX,
+ BaseLine - Cell.OffsetY,
+ FALSE,
+ &Cell,
+ Attributes,
+ &BltBuffer
+ );
+ }
+
+ *Blt = Image;
+ if (Baseline != NULL) {
+ *Baseline = Cell.OffsetY;
+ }
+
+ Status = EFI_SUCCESS;
+
+Exit:
+
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
+ //
+ if (Char != REPLACE_UNKNOWN_GLYPH) {
+ Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
+ if (!EFI_ERROR (Status)) {
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ } else {
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ }
+
+ if (SystemDefault != NULL) {
+ FreePool (SystemDefault);
+ }
+
+ if (StringInfoOut != NULL) {
+ FreePool (StringInfoOut);
+ }
+
+ if (String != NULL) {
+ FreePool (String);
+ }
+
+ if (GlyphBuffer != NULL) {
+ FreePool (GlyphBuffer);
+ }
+
+ return Status;
+}
+
+/**
+ This function iterates through fonts which match the specified font, using
+ the specified criteria. If String is non-NULL, then all of the characters in
+ the string must exist in order for a candidate font to be returned.
+
+ @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
+ @param FontHandle On entry, points to the font handle returned by a
+ previous call to GetFontInfo() or NULL to start
+ with the first font. On return, points to the
+ returned font handle or points to NULL if there
+ are no more matching fonts.
+ @param StringInfoIn Upon entry, points to the font to return information
+ about. If NULL, then the information about the system
+ default font will be returned.
+ @param StringInfoOut Upon return, contains the matching font's information.
+ If NULL, then no information is returned. This buffer
+ is allocated with a call to the Boot Service AllocatePool().
+ It is the caller's responsibility to call the Boot
+ Service FreePool() when the caller no longer requires
+ the contents of StringInfoOut.
+ @param String Points to the string which will be tested to
+ determine if all characters are available. If
+ NULL, then any font is acceptable.
+
+ @retval EFI_SUCCESS Matching font returned successfully.
+ @retval EFI_NOT_FOUND No matching font was found.
+ @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.
+ @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
+ request.
+
+**/
+EFI_STATUS
+EFIAPI
+HiiGetFontInfo (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
+ IN CONST EFI_STRING String OPTIONAL
+ )
+{
+ HII_DATABASE_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_FONT_DISPLAY_INFO *SystemDefault;
+ EFI_FONT_DISPLAY_INFO InfoOut;
+ UINTN StringInfoOutLen;
+ EFI_FONT_INFO *FontInfo;
+ HII_GLOBAL_FONT_INFO *GlobalFont;
+ EFI_STRING StringIn;
+ EFI_FONT_HANDLE LocalFontHandle;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ StringInfoOutLen = 0;
+ FontInfo = NULL;
+ SystemDefault = NULL;
+ LocalFontHandle = NULL;
+ if (FontHandle != NULL) {
+ LocalFontHandle = *FontHandle;
+ }
+
+ Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
+
+ //
+ // Already searched to the end of the whole list, return directly.
+ //
+ if (LocalFontHandle == &Private->FontInfoList) {
+ LocalFontHandle = NULL;
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ //
+ // Get default system display info, if StringInfoIn points to
+ // system display info, return it directly.
+ //
+ if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
+ //
+ // System font is the first node. When handle is not NULL, system font can not
+ // be found any more.
+ //
+ if (LocalFontHandle == NULL) {
+ if (StringInfoOut != NULL) {
+ *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
+ if (*StringInfoOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ LocalFontHandle = NULL;
+ goto Exit;
+ }
+ }
+
+ LocalFontHandle = Private->FontInfoList.ForwardLink;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ } else {
+ LocalFontHandle = NULL;
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+ }
+
+ //
+ // StringInfoIn must not be NULL if it is not system default font info.
+ //
+ ASSERT (StringInfoIn != NULL);
+ //
+ // Check the font information mask to make sure it is valid.
+ //
+ if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
+ (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
+ ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
+ ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse the font information mask to find a matching font.
+ //
+
+ CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
+
+ if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
+ Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
+ } else {
+ Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
+ InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
+ }
+
+ if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
+ InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
+ }
+
+ if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
+ InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
+ }
+
+ if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
+ InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
+ }
+
+ ASSERT (FontInfo != NULL);
+ FontInfo->FontSize = InfoOut.FontInfo.FontSize;
+ FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
+
+ if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
+ //
+ // Test to guarantee all characters are available in the found font.
+ //
+ if (String != NULL) {
+ StringIn = String;
+ while (*StringIn != 0) {
+ Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ LocalFontHandle = NULL;
+ goto Exit;
+ }
+
+ StringIn++;
+ }
+ }
+
+ //
+ // Write to output parameter
+ //
+ if (StringInfoOut != NULL) {
+ StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
+ *StringInfoOut = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);
+ if (*StringInfoOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ LocalFontHandle = NULL;
+ goto Exit;
+ }
+
+ CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
+ CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
+ }
+
+ LocalFontHandle = GlobalFont->Entry.ForwardLink;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+Exit:
+
+ if (FontHandle != NULL) {
+ *FontHandle = LocalFontHandle;
+ }
+
+ if (SystemDefault != NULL) {
+ FreePool (SystemDefault);
+ }
+
+ if (FontInfo != NULL) {
+ FreePool (FontInfo);
+ }
+
+ return Status;
+}