summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MdePkg/Library/UefiLib/Console.c117
1 files changed, 107 insertions, 10 deletions
diff --git a/MdePkg/Library/UefiLib/Console.c b/MdePkg/Library/UefiLib/Console.c
index 5a7684ecff..41a9f3db97 100644
--- a/MdePkg/Library/UefiLib/Console.c
+++ b/MdePkg/Library/UefiLib/Console.c
@@ -1,7 +1,7 @@
/** @file
This module provide help function for displaying unicode string.
- Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -22,6 +22,9 @@ typedef struct {
UINT32 Width;
} UNICODE_WIDTH_ENTRY;
+#define NARROW_CHAR 0xFFF0
+#define WIDE_CHAR 0xFFF1
+
GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable[] = {
//
// General script area
@@ -289,6 +292,95 @@ UnicodeStringDisplayLength (
}
/**
+ Count the storage space of a Unicode string.
+
+ This function handles the Unicode string with NARROW_CHAR
+ and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
+ does not count in the resultant output. If a WIDE_CHAR is
+ hit, then 2 Unicode character will consume an output storage
+ space with size of CHAR16 till a NARROW_CHAR is hit.
+
+ @param String The input string to be counted.
+ @param LimitLen Whether need to limit the string length.
+ @param MaxWidth The max length this function supported.
+ @param Offset The max index of the string can be show out.
+
+ @return Storage space for the input string.
+
+**/
+UINTN
+UefiLibGetStringWidth (
+ IN CHAR16 *String,
+ IN BOOLEAN LimitLen,
+ IN UINTN MaxWidth,
+ OUT UINTN *Offset
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN IncrementValue;
+
+ if (String == NULL) {
+ return 0;
+ }
+
+ Index = 0;
+ Count = 0;
+ IncrementValue = 1;
+
+ do {
+ //
+ // Advance to the null-terminator or to the first width directive
+ //
+ for (;(String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
+ Index++, Count = Count + IncrementValue) {
+ if (LimitLen && Count > MaxWidth) {
+ break;
+ }
+ }
+
+ //
+ // We hit the null-terminator, we now have a count
+ //
+ if (String[Index] == 0) {
+ break;
+ }
+
+ if (LimitLen && Count > MaxWidth) {
+ *Offset = Index - 1;
+ break;
+ }
+
+ //
+ // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
+ // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
+ //
+ if (String[Index] == NARROW_CHAR) {
+ //
+ // Skip to the next character
+ //
+ Index++;
+ IncrementValue = 1;
+ } else {
+ //
+ // Skip to the next character
+ //
+ Index++;
+ IncrementValue = 2;
+ }
+ } while (String[Index] != 0);
+
+ //
+ // Increment by one to include the null-terminator in the size
+ //
+ if (!LimitLen) {
+ Count++;
+ }
+
+ return Count * sizeof (CHAR16);
+}
+
+/**
Draws a dialog box to the console output device specified by
ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
from the console input device specified by ConIn defined in the
@@ -336,7 +428,7 @@ CreatePopUp (
MaxLength = 0;
NumberOfLines = 0;
while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {
- MaxLength = MAX (MaxLength, StrLen (String));
+ MaxLength = MAX (MaxLength, UefiLibGetStringWidth (String, FALSE, 0, NULL) / 2);
NumberOfLines++;
}
VA_END (Args);
@@ -409,24 +501,29 @@ CreatePopUp (
//
VA_START (Args, Key);
while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {
- Length = StrLen (String);
SetMem16 (Line, (MaxLength + 2) * 2, L' ');
+ Line[0] = BOXDRAW_VERTICAL;
+ Line[MaxLength + 1] = BOXDRAW_VERTICAL;
+ Line[MaxLength + 2] = L'\0';
+ ConOut->SetCursorPosition (ConOut, Column, Row);
+ ConOut->OutputString (ConOut, Line);
+ Length = UefiLibGetStringWidth (String, FALSE, 0, NULL) / 2;
if (Length <= MaxLength) {
//
// Length <= MaxLength
//
- CopyMem (Line + 1 + (MaxLength - Length) / 2, String , Length * sizeof (CHAR16));
+ ConOut->SetCursorPosition (ConOut, Column + 1 + (MaxLength - Length) / 2, Row++);
+ ConOut->OutputString (ConOut, String);
} else {
//
// Length > MaxLength
//
- CopyMem (Line + 1, String + (Length - MaxLength) / 2 , MaxLength * sizeof (CHAR16));
+ UefiLibGetStringWidth (String, TRUE, MaxLength, &Length);
+ String[Length] = L'\0';
+
+ ConOut->SetCursorPosition (ConOut, Column + 1, Row++);
+ ConOut->OutputString (ConOut, String);
}
- Line[0] = BOXDRAW_VERTICAL;
- Line[MaxLength + 1] = BOXDRAW_VERTICAL;
- Line[MaxLength + 2] = L'\0';
- ConOut->SetCursorPosition (ConOut, Column, Row++);
- ConOut->OutputString (ConOut, Line);
NumberOfLines--;
}
VA_END (Args);