diff options
Diffstat (limited to 'MdeModulePkg/Universal/SetupBrowserDxe/Ui.c')
-rw-r--r-- | MdeModulePkg/Universal/SetupBrowserDxe/Ui.c | 261 |
1 files changed, 185 insertions, 76 deletions
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c index 6999f625db..d59109317d 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c @@ -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 (InputString == NULL || Index == NULL || OutputString == NULL) {
+ return 0;
+ }
- if (GetLineByWidthFinished) {
- GetLineByWidthFinished = FALSE;
- return (UINT16) 0;
+ if (LineWidth == 0 || *GlyphWidth == 0) {
+ return 0;
}
- Count = LineWidth;
- Count2 = 0;
+ //
+ // Save original glyph width.
+ //
+ OriginalGlyphWidth = *GlyphWidth;
+ LastGlyphWidth = OriginalGlyphWidth;
+ ReturnFlag = FALSE;
+ LastSpaceOffset = 0;
- *OutputString = AllocateZeroPool (((UINTN) (LineWidth + 1) * 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;
+ }
//
- // Ensure we have got a valid buffer
+ // Fast-forward the string and see if there is a carriage-return in the string
//
- if (*OutputString != NULL) {
+ for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
+ switch (InputString[*Index + StrOffset]) {
+ case NARROW_CHAR:
+ *GlyphWidth = 1;
+ break;
- //
- //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;
- }
+ case WIDE_CHAR:
+ *GlyphWidth = 2;
+ break;
- //
- // 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++)
- ;
+ case CHAR_CARRIAGE_RETURN:
+ case CHAR_LINEFEED:
+ case CHAR_NULL:
+ ReturnFlag = TRUE;
+ break;
+
+ default:
+ GlyphOffset = GlyphOffset + *GlyphWidth;
+ //
+ // Record the last space info in this line. Will be used in rewind.
+ //
+ if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
+ LastSpaceOffset = StrOffset;
+ LastGlyphWidth = *GlyphWidth;
+ }
+ break;
+ }
+
+ if (ReturnFlag) {
+ break;
+ }
+ }
+
+ //
+ // Rewind the string from the maximum size until we see a space to break the line
+ //
+ if (GlyphOffset > LineWidth) {
//
- // 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.
+ // Rewind the string to last space char in this line.
//
- if ((StrSize (&InputString[*Index]) <= ((UINTN) (LineWidth + 1) * 2)) &&
- (StrSize (&InputString[*Index]) <= ((UINTN) (Count2 + 1) * 2))
- ) {
+ if (LastSpaceOffset != 0) {
+ StrOffset = LastSpaceOffset;
+ *GlyphWidth = LastGlyphWidth;
+ } else {
//
- // Convert to CHAR16 value and show that we are done with this operation
+ // Roll back to last char in the line width.
//
- 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
- //
- for (; (InputString[*Index + LineWidth] != CHAR_SPACE) && (LineWidth != 0); LineWidth--)
- ;
- if (LineWidth == 0) {
- LineWidth = Count;
- }
- } else {
- LineWidth = Count2;
- }
+ 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, &InputString[*Index], LineWidth * 2);
+ CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
+ if (InputString[*Index + StrOffset] == CHAR_SPACE) {
//
- // If currently pointing to a space or carriage-return or linefeed, increment the index to the first non-space character
+ // Skip the space info at the begin of next line.
+ //
+ *Index = (UINT16) (*Index + StrOffset + 1);
+ } else if ((InputString[*Index + StrOffset] == CHAR_LINEFEED)) {
//
- for (;
- (InputString[*Index + LineWidth] == CHAR_SPACE) || (InputString[*Index + LineWidth] == CHAR_CARRIAGE_RETURN)|| (InputString[*Index + LineWidth] == CHAR_LINEFEED);
- (*Index)++
- )
- ;
- *Index = (UINT16) (*Index + LineWidth);
- return LineWidth;
+ // 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 {
- return (UINT16) 0;
+ *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;
|