refine the implementation of HiiStringToImage:
1. Remove the limitation of MAX_STRING_LENGTH and according to actual string length to store glyph info 2. fix a issue when print multi-lines, the next line will overlaps the above line. The original implementation doesn't recalculate the start point of X/Y axis. 3. refine the flow to avoid the meaningless recursive call. 4. modify the usage of "Index" to force them 1/1 mapping between glyphbuf and string. So the RowInfoArray and ColumnInfoArray can reflect the actual situation. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8371 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
619e4c06c3
commit
4772ce75e8
@ -1344,15 +1344,14 @@ IsFontInfoExisted (
|
|||||||
/**
|
/**
|
||||||
Check whether the unicode represents a line break or not.
|
Check whether the unicode represents a line break or not.
|
||||||
|
|
||||||
This is a internal function.
|
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
|
@param Char Unicode character
|
||||||
|
|
||||||
@retval 0 Yes, it is a line break.
|
@retval 0 Yes, it forces a line break.
|
||||||
@retval 1 Yes, it is a hyphen that desires a line break
|
@retval 1 Yes, it presents a line break opportunity
|
||||||
after this character.
|
@retval 2 Yes, it requires a line break happen before and after it.
|
||||||
@retval 2 Yes, it is a dash that desires a line break
|
|
||||||
before and after it.
|
|
||||||
@retval -1 No, it is not a link break.
|
@retval -1 No, it is not a link break.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
@ -1361,61 +1360,63 @@ IsLineBreak (
|
|||||||
IN CHAR16 Char
|
IN CHAR16 Char
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT8 Byte1;
|
|
||||||
UINT8 Byte2;
|
|
||||||
|
|
||||||
//
|
|
||||||
// In little endian, Byte1 is the low byte of Char, Byte2 is the high byte of Char.
|
|
||||||
//
|
|
||||||
Byte1 = *((UINT8 *) (&Char));
|
|
||||||
Byte2 = *(((UINT8 *) (&Char) + 1));
|
|
||||||
|
|
||||||
if (Byte2 == 0x20) {
|
|
||||||
switch (Byte1) {
|
|
||||||
case 0x00:
|
|
||||||
case 0x01:
|
|
||||||
case 0x02:
|
|
||||||
case 0x03:
|
|
||||||
case 0x04:
|
|
||||||
case 0x05:
|
|
||||||
case 0x06:
|
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0A:
|
|
||||||
case 0x0B:
|
|
||||||
case 0x28:
|
|
||||||
case 0x29:
|
|
||||||
case 0x5F:
|
|
||||||
return 0;
|
|
||||||
case 0x10:
|
|
||||||
case 0x12:
|
|
||||||
case 0x13:
|
|
||||||
return 1;
|
|
||||||
case 0x14:
|
|
||||||
//
|
|
||||||
// BUGBUG: Does it really require line break before it and after it?
|
|
||||||
//
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
} else if (Byte2 == 0x00) {
|
|
||||||
switch (Byte1) {
|
|
||||||
case 0x20:
|
|
||||||
case 0x0C:
|
|
||||||
case 0x0D:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Char) {
|
switch (Char) {
|
||||||
case 0x1680:
|
//
|
||||||
|
// Mandatory line break characters, which force a line-break
|
||||||
|
//
|
||||||
|
case 0x000C:
|
||||||
|
case 0x000D:
|
||||||
|
case 0x2028:
|
||||||
|
case 0x2029:
|
||||||
return 0;
|
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 0x058A:
|
||||||
|
case 0x2010:
|
||||||
|
case 0x2012:
|
||||||
|
case 0x2013:
|
||||||
case 0x0F0B:
|
case 0x0F0B:
|
||||||
case 0x1361:
|
case 0x1361:
|
||||||
case 0x17D5:
|
case 0x17D5:
|
||||||
return 1;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1520,6 +1521,7 @@ HiiStringToImage (
|
|||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
|
||||||
UINTN RowInfoSize;
|
UINTN RowInfoSize;
|
||||||
BOOLEAN LineBreak;
|
BOOLEAN LineBreak;
|
||||||
|
UINTN StrLength;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check incoming parameters.
|
// Check incoming parameters.
|
||||||
@ -1555,11 +1557,35 @@ HiiStringToImage (
|
|||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphBuf = (UINT8 **) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8 *));
|
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);
|
ASSERT (GlyphBuf != NULL);
|
||||||
Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (EFI_HII_GLYPH_INFO));
|
Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));
|
||||||
ASSERT (Cell != NULL);
|
ASSERT (Cell != NULL);
|
||||||
Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));
|
Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));
|
||||||
ASSERT (Attributes != NULL);
|
ASSERT (Attributes != NULL);
|
||||||
|
|
||||||
RowInfo = NULL;
|
RowInfo = NULL;
|
||||||
@ -1649,16 +1675,14 @@ HiiStringToImage (
|
|||||||
}
|
}
|
||||||
Index = 0;
|
Index = 0;
|
||||||
StringTmp = StringIn2;
|
StringTmp = StringIn2;
|
||||||
|
StrLength = StrLen(StringPtr);
|
||||||
while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {
|
while (*StringPtr != 0 && Index < StrLength) {
|
||||||
Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
|
Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
|
||||||
if (Status == EFI_NOT_FOUND) {
|
if (Status == EFI_NOT_FOUND) {
|
||||||
if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
|
if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
|
||||||
if (GlyphBuf[Index] != NULL) {
|
|
||||||
FreePool (GlyphBuf[Index]);
|
|
||||||
}
|
|
||||||
GlyphBuf[Index] = NULL;
|
GlyphBuf[Index] = NULL;
|
||||||
StringPtr++;
|
*StringTmp++ = *StringPtr++;
|
||||||
|
Index++;
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// Unicode 0xFFFD must exist in current hii database if this flag is not set.
|
// Unicode 0xFFFD must exist in current hii database if this flag is not set.
|
||||||
@ -1694,160 +1718,172 @@ HiiStringToImage (
|
|||||||
// to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
|
// 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.
|
// Otherwise render this string to a new allocated image and output it.
|
||||||
//
|
//
|
||||||
if (*Blt != NULL) {
|
Image = *Blt;
|
||||||
Image = *Blt;
|
BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
|
||||||
BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
|
MaxRowNum = (UINT16) (Image->Height / Height);
|
||||||
MaxRowNum = (UINT16) (Image->Height / Height);
|
if (Image->Height % Height != 0) {
|
||||||
if (Image->Height % Height != 0) {
|
MaxRowNum++;
|
||||||
MaxRowNum++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
|
RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
|
||||||
if (RowInfo == NULL) {
|
if (RowInfo == NULL) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
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);
|
||||||
|
if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
|
||||||
|
//
|
||||||
|
// Don't draw at all if there is only one row and
|
||||||
|
// the row's bottom-most on pixel cannot fit.
|
||||||
|
//
|
||||||
|
if (MaxRowNum == 1 && SysFontFlag) {
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
|
||||||
|
LineWidth = 0;
|
||||||
|
LineHeight = 0;
|
||||||
|
BaseLineOffset = 0;
|
||||||
|
LineBreak = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Format the glyph buffer according to flags.
|
// 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 &&
|
||||||
|
(Flags & EFI_HII_OUT_FLAG_WRAP) == 0 &&
|
||||||
|
IsLineBreak (StringPtr[Index]) == 0) {
|
||||||
|
//
|
||||||
|
// It forces a line break that ends this row.
|
||||||
|
//
|
||||||
|
Index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
|
|
||||||
if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
|
|
||||||
//
|
//
|
||||||
// Don't draw at all if there is only one row and
|
// If the glyph of the character is existing, then accumulate the actual printed width
|
||||||
// the row's bottom-most on pixel cannot fit.
|
|
||||||
//
|
//
|
||||||
if (MaxRowNum == 1 && SysFontFlag) {
|
if (GlyphBuf[Index] != NULL) {
|
||||||
|
LineWidth += (UINTN) Cell[Index].AdvanceX;
|
||||||
|
if (LineHeight < Cell[Index].Height) {
|
||||||
|
LineHeight = (UINTN) Cell[Index].Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If this character is the last character of a row, we need not
|
||||||
|
// draw its (AdvanceX - Width) for next character.
|
||||||
|
//
|
||||||
|
Index--;
|
||||||
|
if (!SysFontFlag) {
|
||||||
|
LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 > 0) {
|
||||||
|
RowInfo[RowIndex].EndIndex = Index - 1;
|
||||||
|
RowInfo[RowIndex].LineWidth = LineWidth - Cell[Index].AdvanceX;
|
||||||
|
RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
|
||||||
|
if (LineHeight > Cell[Index - 1].Height) {
|
||||||
|
LineHeight = Cell[Index - 1].Height;
|
||||||
|
}
|
||||||
|
RowInfo[RowIndex].LineHeight = LineHeight;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// There is only one column and it can not be drawn so that return directly.
|
||||||
|
//
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
|
//
|
||||||
LineWidth = 0;
|
// EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
|
||||||
LineHeight = 0;
|
// opportunity prior to a character whose right-most extent would exceed Width.
|
||||||
BaseLineOffset = 0;
|
// Search the right-most line-break opportunity here.
|
||||||
LineBreak = FALSE;
|
//
|
||||||
|
if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) {
|
||||||
//
|
if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
|
||||||
// Calculate how many characters there are in a row.
|
for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
|
||||||
//
|
if (IsLineBreak (StringPtr[Index1]) > 0) {
|
||||||
RowInfo[RowIndex].StartIndex = Index;
|
LineBreak = TRUE;
|
||||||
|
RowInfo[RowIndex].EndIndex = Index1 - 1;
|
||||||
while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
|
//
|
||||||
LineWidth += (UINTN) Cell[Index].AdvanceX;
|
// relocate to the character after the right-most line break opportunity of this line
|
||||||
if (LineHeight < Cell[Index].Height) {
|
//
|
||||||
LineHeight = (UINTN) Cell[Index].Height;
|
Index = Index1 + 1;
|
||||||
}
|
break;
|
||||||
|
|
||||||
if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&
|
|
||||||
(Flags & EFI_HII_OUT_FLAG_WRAP) == 0 &&
|
|
||||||
IsLineBreak (StringPtr[Index]) > 0) {
|
|
||||||
//
|
|
||||||
// It is a line break that ends this row.
|
|
||||||
//
|
|
||||||
Index++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If this character is the last character of a row, we need not
|
|
||||||
// draw its (AdvanceX - Width) for next character.
|
|
||||||
//
|
|
||||||
Index--;
|
|
||||||
if (!SysFontFlag) {
|
|
||||||
LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
|
|
||||||
for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
|
|
||||||
if (IsLineBreak (StringPtr[Index1]) > 0) {
|
|
||||||
LineBreak = TRUE;
|
|
||||||
RowInfo[RowIndex].EndIndex = Index1 - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
Flags &= (~ (EFI_HII_OUT_FLAGS) EFI_HII_OUT_FLAG_WRAP);
|
|
||||||
Flags |= EFI_HII_OUT_FLAG_CLIP_CLEAN_X;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
|
// If no line-break opportunity can be found, then the text will
|
||||||
|
// behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
|
||||||
//
|
//
|
||||||
if (LineWidth + BltX <= Image->Width ||
|
if (!LineBreak) {
|
||||||
(LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {
|
Flags &= (~ (EFI_HII_OUT_FLAGS) EFI_HII_OUT_FLAG_WRAP);
|
||||||
//
|
Flags |= EFI_HII_OUT_FLAG_CLIP_CLEAN_X;
|
||||||
// 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 > 0) {
|
|
||||||
RowInfo[RowIndex].EndIndex = Index - 1;
|
|
||||||
RowInfo[RowIndex].LineWidth = LineWidth - Cell[Index].AdvanceX;
|
|
||||||
RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
|
|
||||||
if (LineHeight > Cell[Index - 1].Height) {
|
|
||||||
LineHeight = Cell[Index - 1].Height;
|
|
||||||
}
|
|
||||||
RowInfo[RowIndex].LineHeight = LineHeight;
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// There is only one column and it can not be drawn so that return directly.
|
|
||||||
//
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clip the final row if the row's bottom-most on pixel cannot fit when
|
// Clip the final row if the row's bottom-most on pixel cannot fit when
|
||||||
// EFI_HII_OUT_FLAG_CLEAN_Y is set.
|
// EFI_HII_OUT_FLAG_CLEAN_Y is set.
|
||||||
//
|
//
|
||||||
if (RowIndex == MaxRowNum - 1 && Image->Height < LineHeight) {
|
if (RowIndex == MaxRowNum - 1 && Image->Height < LineHeight) {
|
||||||
LineHeight = Image->Height;
|
LineHeight = Image->Height;
|
||||||
if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
|
if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {
|
||||||
//
|
//
|
||||||
// Don't draw at all if the row's bottom-most on pixel cannot fit.
|
// Don't draw at all if the row's bottom-most on pixel cannot fit.
|
||||||
//
|
//
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Draw it to screen or existing bitmap depending on whether
|
// Draw it to screen or existing bitmap depending on whether
|
||||||
// EFI_HII_DIRECT_TO_SCREEN is set.
|
// EFI_HII_DIRECT_TO_SCREEN is set.
|
||||||
//
|
//
|
||||||
if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
|
if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
|
||||||
BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
|
||||||
if (BltBuffer == NULL) {
|
if (BltBuffer == NULL) {
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
BufferPtr = BltBuffer;
|
BufferPtr = BltBuffer;
|
||||||
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
||||||
|
if (GlyphBuf[Index1] != NULL) {
|
||||||
|
//
|
||||||
|
// Only BLT these character which have corrsponding glyph in font basebase.
|
||||||
|
//
|
||||||
GlyphToImage (
|
GlyphToImage (
|
||||||
GlyphBuf[Index1],
|
GlyphBuf[Index1],
|
||||||
Foreground,
|
Foreground,
|
||||||
@ -1858,37 +1894,50 @@ HiiStringToImage (
|
|||||||
&Cell[Index1],
|
&Cell[Index1],
|
||||||
Attributes[Index1],
|
Attributes[Index1],
|
||||||
&BufferPtr
|
&BufferPtr
|
||||||
);
|
);
|
||||||
if (ColumnInfoArray != NULL) {
|
}
|
||||||
if (Index1 == RowInfo[RowIndex].StartIndex) {
|
if (ColumnInfoArray != NULL) {
|
||||||
*ColumnInfoArray = 0;
|
if (GlyphBuf[Index1] == NULL) {
|
||||||
} else {
|
*ColumnInfoArray = 0;
|
||||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
} else {
|
||||||
}
|
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||||
ColumnInfoArray++;
|
|
||||||
}
|
}
|
||||||
|
ColumnInfoArray++;
|
||||||
}
|
}
|
||||||
Status = Image->Image.Screen->Blt (
|
}
|
||||||
Image->Image.Screen,
|
//
|
||||||
BltBuffer,
|
// Recalculate the start point of X/Y axis to draw multi-lines with the order of top-to-down
|
||||||
EfiBltBufferToVideo,
|
//
|
||||||
0,
|
if (RowIndex != 0) {
|
||||||
0,
|
BltX = 0;
|
||||||
BltX,
|
BltY += RowInfo[RowIndex].LineHeight;
|
||||||
BltY,
|
}
|
||||||
RowInfo[RowIndex].LineWidth,
|
|
||||||
RowInfo[RowIndex].LineHeight,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
FreePool (BltBuffer);
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
FreePool (BltBuffer);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
FreePool (BltBuffer);
|
||||||
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
|
||||||
|
} else {
|
||||||
|
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
||||||
|
if (GlyphBuf[Index1] != NULL) {
|
||||||
|
//
|
||||||
|
// Only BLT these character which have corrsponding glyph in font basebase.
|
||||||
|
//
|
||||||
GlyphToImage (
|
GlyphToImage (
|
||||||
GlyphBuf[Index1],
|
GlyphBuf[Index1],
|
||||||
Foreground,
|
Foreground,
|
||||||
@ -1899,87 +1948,55 @@ HiiStringToImage (
|
|||||||
&Cell[Index1],
|
&Cell[Index1],
|
||||||
Attributes[Index1],
|
Attributes[Index1],
|
||||||
&BufferPtr
|
&BufferPtr
|
||||||
);
|
);
|
||||||
if (ColumnInfoArray != NULL) {
|
}
|
||||||
if (Index1 == RowInfo[RowIndex].StartIndex) {
|
if (ColumnInfoArray != NULL) {
|
||||||
*ColumnInfoArray = 0;
|
if (GlyphBuf[Index1] == NULL) {
|
||||||
} else {
|
*ColumnInfoArray = 0;
|
||||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
} else {
|
||||||
}
|
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||||
ColumnInfoArray++;
|
}
|
||||||
}
|
ColumnInfoArray++;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Jump to next row
|
|
||||||
//
|
|
||||||
BufferPtr += BltX + Image->Width * (LineHeight - 1);
|
|
||||||
}
|
}
|
||||||
|
//
|
||||||
Index++;
|
// Jump to next row
|
||||||
RowIndex++;
|
//
|
||||||
|
BufferPtr += BltX + Image->Width * (LineHeight - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
Index++;
|
||||||
// Write output parameters.
|
RowIndex++;
|
||||||
//
|
|
||||||
RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
|
|
||||||
if (RowInfoArray != NULL) {
|
|
||||||
*RowInfoArray = AllocateZeroPool (RowInfoSize);
|
|
||||||
if (*RowInfoArray == NULL) {
|
|
||||||
Status = EFI_OUT_OF_RESOURCES;
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
|
|
||||||
}
|
|
||||||
if (RowInfoArraySize != NULL) {
|
|
||||||
*RowInfoArraySize = RowIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
if (Flags & EFI_HII_IGNORE_LINE_BREAK) {
|
||||||
//
|
//
|
||||||
// Create a new bitmap and draw the string onto this image.
|
// If setting IGNORE_LINE_BREAK attribute, only render one line to image
|
||||||
//
|
//
|
||||||
Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
|
break;
|
||||||
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.
|
// Write output parameters.
|
||||||
//
|
//
|
||||||
Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;
|
RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
|
||||||
Status = HiiStringToImage (
|
if (RowInfoArray != NULL) {
|
||||||
This,
|
*RowInfoArray = AllocateZeroPool (RowInfoSize);
|
||||||
Flags,
|
if (*RowInfoArray == NULL) {
|
||||||
String,
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
StringInfo,
|
goto Exit;
|
||||||
&Image,
|
|
||||||
BltX,
|
|
||||||
BltY,
|
|
||||||
RowInfoArray,
|
|
||||||
RowInfoArraySize,
|
|
||||||
ColumnInfoArray
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
|
||||||
*Blt = Image;
|
}
|
||||||
|
if (RowInfoArraySize != NULL) {
|
||||||
|
*RowInfoArraySize = RowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
|
||||||
for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {
|
for (Index = 0; Index < StrLength; Index++) {
|
||||||
if (GlyphBuf[Index] != NULL) {
|
if (GlyphBuf[Index] != NULL) {
|
||||||
FreePool (GlyphBuf[Index]);
|
FreePool (GlyphBuf[Index]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user