Enable wide string support for CreatePopUp function in UefiLib.

Signed-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@13594 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ydong10 2012-08-06 09:14:18 +00:00
parent 8f3a9e5862
commit 33026ccf33
1 changed files with 107 additions and 10 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
This module provide help function for displaying unicode string. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -22,6 +22,9 @@ typedef struct {
UINT32 Width; UINT32 Width;
} UNICODE_WIDTH_ENTRY; } UNICODE_WIDTH_ENTRY;
#define NARROW_CHAR 0xFFF0
#define WIDE_CHAR 0xFFF1
GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable[] = { GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable[] = {
// //
// General script area // General script area
@ -288,6 +291,95 @@ UnicodeStringDisplayLength (
return Length; return Length;
} }
/**
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 Draws a dialog box to the console output device specified by
ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
@ -336,7 +428,7 @@ CreatePopUp (
MaxLength = 0; MaxLength = 0;
NumberOfLines = 0; NumberOfLines = 0;
while ((String = VA_ARG (Args, CHAR16 *)) != NULL) { while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {
MaxLength = MAX (MaxLength, StrLen (String)); MaxLength = MAX (MaxLength, UefiLibGetStringWidth (String, FALSE, 0, NULL) / 2);
NumberOfLines++; NumberOfLines++;
} }
VA_END (Args); VA_END (Args);
@ -409,24 +501,29 @@ CreatePopUp (
// //
VA_START (Args, Key); VA_START (Args, Key);
while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) { while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {
Length = StrLen (String);
SetMem16 (Line, (MaxLength + 2) * 2, L' '); 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) { if (Length <= MaxLength) {
// //
// 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 { } else {
// //
// Length > MaxLength // 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--; NumberOfLines--;
} }
VA_END (Args); VA_END (Args);