From 33026ccf33d8295ea6475f79f34415243a7a2513 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Mon, 6 Aug 2012 09:14:18 +0000 Subject: [PATCH] Enable wide string support for CreatePopUp function in UefiLib. Signed-off-by: Eric Dong Reviewed-by: Liming Gao git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13594 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Library/UefiLib/Console.c | 117 ++++++++++++++++++++++++++++--- 1 file 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.
+ Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
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 @@ -288,6 +291,95 @@ UnicodeStringDisplayLength ( 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 ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke @@ -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); -- 2.39.2