Enable wide string for title and help string

Sign-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com> 

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13371 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ydong10
2012-05-29 11:07:05 +00:00
parent 2721fabc53
commit 6c310dfb78
4 changed files with 232 additions and 92 deletions

View File

@ -1308,102 +1308,174 @@ GetWidth (
/**
Will copy LineWidth amount of a string in the OutputString buffer and return the
number of CHAR16 characters that were copied into the OutputString buffer.
The output string format is:
Glyph Info + String info + '\0'.
In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
@param InputString String description for this option.
@param LineWidth Width of the desired string to extract in CHAR16
characters
@param GlyphWidth The glyph width of the begin of the char in the string.
@param Index Where in InputString to start the copy process
@param OutputString Buffer to copy the string into
@return Returns the number of CHAR16 characters that were copied into the OutputString buffer.
@return Returns the number of CHAR16 characters that were copied into the OutputString
buffer, include extra glyph info and '\0' info.
**/
UINT16
GetLineByWidth (
IN CHAR16 *InputString,
IN UINT16 LineWidth,
IN OUT UINT16 *GlyphWidth,
IN OUT UINTN *Index,
OUT CHAR16 **OutputString
)
{
UINT16 Count;
UINT16 Count2;
UINT16 StrOffset;
UINT16 GlyphOffset;
UINT16 OriginalGlyphWidth;
BOOLEAN ReturnFlag;
UINT16 LastSpaceOffset;
UINT16 LastGlyphWidth;
if (GetLineByWidthFinished) {
GetLineByWidthFinished = FALSE;
return (UINT16) 0;
if (InputString == NULL || Index == NULL || OutputString == NULL) {
return 0;
}
Count = LineWidth;
Count2 = 0;
*OutputString = AllocateZeroPool (((UINTN) (LineWidth + 1) * 2));
if (LineWidth == 0 || *GlyphWidth == 0) {
return 0;
}
//
// Ensure we have got a valid buffer
// Save original glyph width.
//
if (*OutputString != NULL) {
OriginalGlyphWidth = *GlyphWidth;
LastGlyphWidth = OriginalGlyphWidth;
ReturnFlag = FALSE;
LastSpaceOffset = 0;
//
//NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
//To avoid displaying this empty line in screen, just skip the two CHARs here.
//
if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
*Index = *Index + 2;
}
//
// NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
// To avoid displaying this empty line in screen, just skip the two CHARs here.
//
if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
*Index = *Index + 2;
}
//
// Fast-forward the string and see if there is a carriage-return or linefeed in the string
//
for (; (InputString[*Index + Count2] != CHAR_LINEFEED) && (InputString[*Index + Count2] != CHAR_CARRIAGE_RETURN) && (Count2 != LineWidth); Count2++)
;
//
// Fast-forward the string and see if there is a carriage-return in the string
//
for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
switch (InputString[*Index + StrOffset]) {
case NARROW_CHAR:
*GlyphWidth = 1;
break;
case WIDE_CHAR:
*GlyphWidth = 2;
break;
case CHAR_CARRIAGE_RETURN:
case CHAR_LINEFEED:
case CHAR_NULL:
ReturnFlag = TRUE;
break;
default:
GlyphOffset = GlyphOffset + *GlyphWidth;
//
// Copy the desired LineWidth of data to the output buffer.
// Also make sure that we don't copy more than the string.
// Also make sure that if there are linefeeds, we account for them.
//
if ((StrSize (&InputString[*Index]) <= ((UINTN) (LineWidth + 1) * 2)) &&
(StrSize (&InputString[*Index]) <= ((UINTN) (Count2 + 1) * 2))
) {
//
// Convert to CHAR16 value and show that we are done with this operation
//
LineWidth = (UINT16) ((StrSize (&InputString[*Index]) - 2) / 2);
if (LineWidth != 0) {
GetLineByWidthFinished = TRUE;
}
} else {
if (Count2 == LineWidth) {
//
// Rewind the string from the maximum size until we see a space to break the line
// Record the last space info in this line. Will be used in rewind.
//
for (; (InputString[*Index + LineWidth] != CHAR_SPACE) && (LineWidth != 0); LineWidth--)
;
if (LineWidth == 0) {
LineWidth = Count;
if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
LastSpaceOffset = StrOffset;
LastGlyphWidth = *GlyphWidth;
}
} else {
LineWidth = Count2;
}
break;
}
CopyMem (*OutputString, &InputString[*Index], LineWidth * 2);
if (ReturnFlag) {
break;
}
}
//
// Rewind the string from the maximum size until we see a space to break the line
//
if (GlyphOffset > LineWidth) {
//
// If currently pointing to a space or carriage-return or linefeed, increment the index to the first non-space character
// Rewind the string to last space char in this line.
//
for (;
(InputString[*Index + LineWidth] == CHAR_SPACE) || (InputString[*Index + LineWidth] == CHAR_CARRIAGE_RETURN)|| (InputString[*Index + LineWidth] == CHAR_LINEFEED);
(*Index)++
)
;
*Index = (UINT16) (*Index + LineWidth);
return LineWidth;
} else {
return (UINT16) 0;
if (LastSpaceOffset != 0) {
StrOffset = LastSpaceOffset;
*GlyphWidth = LastGlyphWidth;
} else {
//
// Roll back to last char in the line width.
//
StrOffset--;
}
}
//
// The CHAR_NULL has process last time, this time just return 0 to stand for the end.
//
if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
return 0;
}
//
// Need extra glyph info and '\0' info, so +2.
//
*OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
if (*OutputString == NULL) {
return 0;
}
//
// Save the glyph info at the begin of the string, will used by Print function.
//
if (OriginalGlyphWidth == 1) {
*(*OutputString) = NARROW_CHAR;
} else {
*(*OutputString) = WIDE_CHAR;
}
CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
if (InputString[*Index + StrOffset] == CHAR_SPACE) {
//
// Skip the space info at the begin of next line.
//
*Index = (UINT16) (*Index + StrOffset + 1);
} else if ((InputString[*Index + StrOffset] == CHAR_LINEFEED)) {
//
// Skip the /n or /n/r info.
//
if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
*Index = (UINT16) (*Index + StrOffset + 2);
} else {
*Index = (UINT16) (*Index + StrOffset + 1);
}
} else if ((InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN)) {
//
// Skip the /r or /r/n info.
//
if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
*Index = (UINT16) (*Index + StrOffset + 2);
} else {
*Index = (UINT16) (*Index + StrOffset + 1);
}
} else {
*Index = (UINT16) (*Index + StrOffset);
}
//
// Include extra glyph info and '\0' info, so +2.
//
return StrOffset + 2;
}
@ -1426,6 +1498,7 @@ UpdateOptionSkipLines (
UINTN OriginalRow;
CHAR16 *OutputString;
CHAR16 *OptionString;
UINT16 GlyphWidth;
Row = 0;
OptionString = NULL;
@ -1435,8 +1508,9 @@ UpdateOptionSkipLines (
Width = (UINT16) gOptionBlockWidth;
OriginalRow = Row;
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
//
// If there is more string to process print on the next row and increment the Skip value
//
@ -2128,6 +2202,10 @@ UiDisplayMenu (
UINTN HelpHeaderLine;
UINTN HelpBottomLine;
BOOLEAN MultiHelpPage;
UINT16 GlyphWidth;
UINT16 EachLineWidth;
UINT16 HeaderLineWidth;
UINT16 BottomLineWidth;
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
@ -2147,7 +2225,9 @@ UiDisplayMenu (
HelpHeaderLine = 0;
HelpPageIndex = 0;
MultiHelpPage = FALSE;
EachLineWidth = 0;
HeaderLineWidth = 0;
BottomLineWidth = 0;
OutputString = NULL;
UpArrow = FALSE;
DownArrow = FALSE;
@ -2298,6 +2378,7 @@ UiDisplayMenu (
Width = GetWidth (Statement, MenuOption->Handle);
OriginalRow = Row;
GlyphWidth = 1;
if (Statement->Operand == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
//
@ -2311,7 +2392,7 @@ UiDisplayMenu (
);
}
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if ((Temp == 0) && (Row <= BottomRow)) {
PrintStringAt (MenuOption->Col, Row, OutputString);
}
@ -2351,8 +2432,9 @@ UiDisplayMenu (
Width = (UINT16) gOptionBlockWidth;
OriginalRow = Row;
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if ((Temp2 == 0) && (Row <= BottomRow)) {
PrintStringAt (MenuOption->OptCol, Row, OutputString);
}
@ -2459,8 +2541,9 @@ UiDisplayMenu (
Width = (UINT16) gOptionBlockWidth;
OriginalRow = Row;
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (StringPtr, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if ((Temp == 0) && (Row <= BottomRow)) {
PrintStringAt (MenuOption->OptCol, Row, OutputString);
}
@ -2688,8 +2771,9 @@ UiDisplayMenu (
Width = (UINT16) gOptionBlockWidth;
OriginalRow = MenuOption->Row;
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
}
@ -2716,8 +2800,9 @@ UiDisplayMenu (
OriginalRow = MenuOption->Row;
Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
}
@ -2787,8 +2872,9 @@ UiDisplayMenu (
Width = (UINT16) gOptionBlockWidth;
OriginalRow = MenuOption->Row;
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
}
@ -2810,8 +2896,9 @@ UiDisplayMenu (
OriginalRow = MenuOption->Row;
Width = GetWidth (Statement, MenuOption->Handle);
GlyphWidth = 1;
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
}
@ -2866,13 +2953,22 @@ UiDisplayMenu (
//
// 1.Calculate how many line the help string need to print.
//
HelpLine = ProcessHelpString (StringPtr, &HelpString, RowCount);
if (HelpString != NULL) {
FreePool (HelpString);
}
HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
if (HelpLine > RowCount) {
MultiHelpPage = TRUE;
StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, RowCount);
if (HelpHeaderString != NULL) {
FreePool (HelpHeaderString);
}
HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, RowCount);
StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, RowCount);
if (HelpBottomString != NULL) {
FreePool (HelpBottomString);
}
HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, RowCount);
//
// Calculate the help page count.
//
@ -2900,7 +2996,6 @@ UiDisplayMenu (
PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
);
gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
//
// Check whether need to show the 'More(U/u)' at the begin.
// Base on current direct info, here shows aligned to the right side of the column.
@ -2908,13 +3003,14 @@ UiDisplayMenu (
// add ASSERT code here.
//
if (HelpPageIndex > 0) {
gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
for (Index = 0; Index < HelpHeaderLine; Index++) {
ASSERT (HelpHeaderLine == 1);
ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
PrintStringAt (
LocalScreen.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
Index + TopRow,
&HelpHeaderString[Index * gHelpBlockWidth * 2]
&HelpHeaderString[Index * HeaderLineWidth]
);
}
}
@ -2928,16 +3024,17 @@ UiDisplayMenu (
PrintStringAt (
LocalScreen.RightColumn - gHelpBlockWidth,
Index + TopRow,
&HelpString[Index * gHelpBlockWidth * 2]
&HelpString[Index * EachLineWidth]
);
}
gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
} else {
if (HelpPageIndex == 0) {
for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
PrintStringAt (
LocalScreen.RightColumn - gHelpBlockWidth,
Index + TopRow,
&HelpString[Index * gHelpBlockWidth * 2]
&HelpString[Index * EachLineWidth]
);
}
} else {
@ -2946,13 +3043,15 @@ UiDisplayMenu (
PrintStringAt (
LocalScreen.RightColumn - gHelpBlockWidth,
Index + TopRow + HelpHeaderLine,
&HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* gHelpBlockWidth * 2]
&HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth]
);
}
if (HelpPageIndex == HelpPageCount - 1) {
gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
}
}
}
gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
//
// Check whether need to print the 'More(D/d)' at the bottom.
// Base on current direct info, here shows aligned to the right side of the column.
@ -2960,13 +3059,14 @@ UiDisplayMenu (
// add ASSERT code here.
//
if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
for (Index = 0; Index < HelpBottomLine; Index++) {
ASSERT (HelpBottomLine == 1);
ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
PrintStringAt (
LocalScreen.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
Index + BottomRow - HelpBottomLine,
&HelpBottomString[Index * gHelpBlockWidth * 2]
&HelpBottomString[Index * BottomLineWidth]
);
}
}
@ -3785,6 +3885,15 @@ UiDisplayMenu (
gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);
gST->ConOut->EnableCursor (gST->ConOut, TRUE);
gST->ConOut->OutputString (gST->ConOut, L"\n");
if (HelpString != NULL) {
FreePool (HelpString);
}
if (HelpHeaderString != NULL) {
FreePool (HelpHeaderString);
}
if (HelpBottomString != NULL) {
FreePool (HelpBottomString);
}
return EFI_SUCCESS;