mirror of https://github.com/acidanthera/audk.git
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.
|
||||
|
||||
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
|
||||
|
||||
@retval 0 Yes, it is a line break.
|
||||
@retval 1 Yes, it is a hyphen that desires a line break
|
||||
after this character.
|
||||
@retval 2 Yes, it is a dash that desires a line break
|
||||
before and after it.
|
||||
@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.
|
||||
|
||||
**/
|
||||
|
@ -1361,61 +1360,63 @@ IsLineBreak (
|
|||
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) {
|
||||
case 0x1680:
|
||||
//
|
||||
// Mandatory line break characters, which force a line-break
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1520,6 +1521,7 @@ HiiStringToImage (
|
|||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;
|
||||
UINTN RowInfoSize;
|
||||
BOOLEAN LineBreak;
|
||||
UINTN StrLength;
|
||||
|
||||
//
|
||||
// Check incoming parameters.
|
||||
|
@ -1555,11 +1557,35 @@ HiiStringToImage (
|
|||
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);
|
||||
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);
|
||||
Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));
|
||||
Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));
|
||||
ASSERT (Attributes != NULL);
|
||||
|
||||
RowInfo = NULL;
|
||||
|
@ -1649,16 +1675,14 @@ HiiStringToImage (
|
|||
}
|
||||
Index = 0;
|
||||
StringTmp = StringIn2;
|
||||
|
||||
while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {
|
||||
StrLength = StrLen(StringPtr);
|
||||
while (*StringPtr != 0 && Index < StrLength) {
|
||||
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) {
|
||||
if (GlyphBuf[Index] != NULL) {
|
||||
FreePool (GlyphBuf[Index]);
|
||||
}
|
||||
GlyphBuf[Index] = NULL;
|
||||
StringPtr++;
|
||||
*StringTmp++ = *StringPtr++;
|
||||
Index++;
|
||||
} else {
|
||||
//
|
||||
// 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".
|
||||
// Otherwise render this string to a new allocated image and output it.
|
||||
//
|
||||
if (*Blt != NULL) {
|
||||
Image = *Blt;
|
||||
BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
|
||||
MaxRowNum = (UINT16) (Image->Height / Height);
|
||||
if (Image->Height % Height != 0) {
|
||||
MaxRowNum++;
|
||||
}
|
||||
Image = *Blt;
|
||||
BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
|
||||
MaxRowNum = (UINT16) (Image->Height / Height);
|
||||
if (Image->Height % Height != 0) {
|
||||
MaxRowNum++;
|
||||
}
|
||||
|
||||
RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
|
||||
if (RowInfo == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// the row's bottom-most on pixel cannot fit.
|
||||
// If the glyph of the character is existing, then accumulate the actual printed width
|
||||
//
|
||||
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;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
|
||||
LineWidth = 0;
|
||||
LineHeight = 0;
|
||||
BaseLineOffset = 0;
|
||||
LineBreak = FALSE;
|
||||
|
||||
//
|
||||
// Calculate how many characters there are in a row.
|
||||
//
|
||||
RowInfo[RowIndex].StartIndex = Index;
|
||||
|
||||
while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
|
||||
LineWidth += (UINTN) Cell[Index].AdvanceX;
|
||||
if (LineHeight < Cell[Index].Height) {
|
||||
LineHeight = (UINTN) Cell[Index].Height;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
//
|
||||
// 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;
|
||||
//
|
||||
// relocate to the character after the right-most line break opportunity of this line
|
||||
//
|
||||
Index = 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 ||
|
||||
(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;
|
||||
goto Exit;
|
||||
}
|
||||
if (!LineBreak) {
|
||||
Flags &= (~ (EFI_HII_OUT_FLAGS) EFI_HII_OUT_FLAG_WRAP);
|
||||
Flags |= EFI_HII_OUT_FLAG_CLIP_CLEAN_X;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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 && Image->Height < LineHeight) {
|
||||
LineHeight = Image->Height;
|
||||
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.
|
||||
//
|
||||
break;
|
||||
}
|
||||
//
|
||||
// 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 && Image->Height < LineHeight) {
|
||||
LineHeight = Image->Height;
|
||||
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.
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw it to screen or existing bitmap depending on whether
|
||||
// EFI_HII_DIRECT_TO_SCREEN is set.
|
||||
//
|
||||
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));
|
||||
if (BltBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
BufferPtr = BltBuffer;
|
||||
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
||||
//
|
||||
// Draw it to screen or existing bitmap depending on whether
|
||||
// EFI_HII_DIRECT_TO_SCREEN is set.
|
||||
//
|
||||
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));
|
||||
if (BltBuffer == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
BufferPtr = BltBuffer;
|
||||
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 (
|
||||
GlyphBuf[Index1],
|
||||
Foreground,
|
||||
|
@ -1858,37 +1894,50 @@ HiiStringToImage (
|
|||
&Cell[Index1],
|
||||
Attributes[Index1],
|
||||
&BufferPtr
|
||||
);
|
||||
if (ColumnInfoArray != NULL) {
|
||||
if (Index1 == RowInfo[RowIndex].StartIndex) {
|
||||
*ColumnInfoArray = 0;
|
||||
} else {
|
||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||
}
|
||||
ColumnInfoArray++;
|
||||
);
|
||||
}
|
||||
if (ColumnInfoArray != NULL) {
|
||||
if (GlyphBuf[Index1] == NULL) {
|
||||
*ColumnInfoArray = 0;
|
||||
} else {
|
||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||
}
|
||||
ColumnInfoArray++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Recalculate the start point of X/Y axis to draw multi-lines with the order of top-to-down
|
||||
//
|
||||
if (RowIndex != 0) {
|
||||
BltX = 0;
|
||||
BltY += RowInfo[RowIndex].LineHeight;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
|
||||
FreePool (BltBuffer);
|
||||
|
||||
} 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 (
|
||||
GlyphBuf[Index1],
|
||||
Foreground,
|
||||
|
@ -1899,87 +1948,55 @@ HiiStringToImage (
|
|||
&Cell[Index1],
|
||||
Attributes[Index1],
|
||||
&BufferPtr
|
||||
);
|
||||
if (ColumnInfoArray != NULL) {
|
||||
if (Index1 == RowInfo[RowIndex].StartIndex) {
|
||||
*ColumnInfoArray = 0;
|
||||
} else {
|
||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||
}
|
||||
ColumnInfoArray++;
|
||||
}
|
||||
);
|
||||
}
|
||||
if (ColumnInfoArray != NULL) {
|
||||
if (GlyphBuf[Index1] == NULL) {
|
||||
*ColumnInfoArray = 0;
|
||||
} else {
|
||||
*ColumnInfoArray = Cell[Index1 -1].AdvanceX;
|
||||
}
|
||||
ColumnInfoArray++;
|
||||
}
|
||||
//
|
||||
// Jump to next row
|
||||
//
|
||||
BufferPtr += BltX + Image->Width * (LineHeight - 1);
|
||||
}
|
||||
|
||||
Index++;
|
||||
RowIndex++;
|
||||
|
||||
//
|
||||
// Jump to next row
|
||||
//
|
||||
BufferPtr += BltX + Image->Width * (LineHeight - 1);
|
||||
}
|
||||
|
||||
//
|
||||
// Write output parameters.
|
||||
//
|
||||
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;
|
||||
}
|
||||
Index++;
|
||||
RowIndex++;
|
||||
|
||||
} else {
|
||||
//
|
||||
// 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;
|
||||
if (Flags & EFI_HII_IGNORE_LINE_BREAK) {
|
||||
//
|
||||
// If setting IGNORE_LINE_BREAK attribute, only render one line to image
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
Status = HiiStringToImage (
|
||||
This,
|
||||
Flags,
|
||||
String,
|
||||
StringInfo,
|
||||
&Image,
|
||||
BltX,
|
||||
BltY,
|
||||
RowInfoArray,
|
||||
RowInfoArraySize,
|
||||
ColumnInfoArray
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
//
|
||||
// Write output parameters.
|
||||
//
|
||||
RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
|
||||
if (RowInfoArray != NULL) {
|
||||
*RowInfoArray = AllocateZeroPool (RowInfoSize);
|
||||
if (*RowInfoArray == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
*Blt = Image;
|
||||
CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
|
||||
}
|
||||
if (RowInfoArraySize != NULL) {
|
||||
*RowInfoArraySize = RowIndex;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
Exit:
|
||||
|
||||
for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {
|
||||
for (Index = 0; Index < StrLength; Index++) {
|
||||
if (GlyphBuf[Index] != NULL) {
|
||||
FreePool (GlyphBuf[Index]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue