2 This module provide help function for displaying unicode string.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "UefiLibInternal.h"
17 } UNICODE_WIDTH_ENTRY
;
19 GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable
[] = {
21 // General script area
25 * Merge the blocks and replace them with the above entry as they fall to
26 * the same category and they are all narrow glyph. This will reduce search
27 * time and table size. The merge will omit the reserved code.
29 * Remove the above item if below is un-commented.
31 {(CHAR16)0x007F, 1}, // C0 controls and basic Latin. 0x0000-0x007F
32 {(CHAR16)0x00FF, 1}, // C1 controls and Latin-1 support. 0x0080-0x00FF
33 {(CHAR16)0x017F, 1}, // Latin extended-A. 0x0100-0x017F
34 {(CHAR16)0x024F, 1}, // Latin extended-B. 0x0180-0x024F
35 {(CHAR16)0x02AF, 1}, // IPA extensions. 0x0250-0x02AF
36 {(CHAR16)0x02FF, 1}, // Spacing modifier letters. 0x02B0-0x02FF
37 {(CHAR16)0x036F, 1}, // Combining diacritical marks. 0x0300-0x036F
38 {(CHAR16)0x03FF, 1}, // Greek. 0x0370-0x03FF
39 {(CHAR16)0x04FF, 1}, // Cyrillic. 0x0400-0x04FF
40 {(CHAR16)0x052F, 0}, // Unassigned. As Armenian in ver3.0. 0x0500-0x052F
41 {(CHAR16)0x058F, 1}, // Armenian. 0x0530-0x058F
42 {(CHAR16)0x05FF, 1}, // Hebrew. 0x0590-0x05FF
43 {(CHAR16)0x06FF, 1}, // Arabic. 0x0600-0x06FF
44 {(CHAR16)0x08FF, 0}, // Unassigned. 0x0700-0x08FF
45 {(CHAR16)0x097F, 1}, // Devanagari. 0x0900-0x097F
46 {(CHAR16)0x09FF, 1}, // Bengali. 0x0980-0x09FF
47 {(CHAR16)0x0A7F, 1}, // Gurmukhi. 0x0A00-0x0A7F
48 {(CHAR16)0x0AFF, 1}, // Gujarati. 0x0A80-0x0AFF
49 {(CHAR16)0x0B7F, 1}, // Oriya. 0x0B00-0x0B7F
50 {(CHAR16)0x0BFF, 1}, // Tamil. (See page 7-92). 0x0B80-0x0BFF
51 {(CHAR16)0x0C7F, 1}, // Telugu. 0x0C00-0x0C7F
52 {(CHAR16)0x0CFF, 1}, // Kannada. (See page 7-100). 0x0C80-0x0CFF
53 {(CHAR16)0x0D7F, 1}, // Malayalam (See page 7-104). 0x0D00-0x0D7F
54 {(CHAR16)0x0DFF, 0}, // Unassigned. 0x0D80-0x0DFF
55 {(CHAR16)0x0E7F, 1}, // Thai. 0x0E00-0x0E7F
56 {(CHAR16)0x0EFF, 1}, // Lao. 0x0E80-0x0EFF
57 {(CHAR16)0x0FBF, 1}, // Tibetan. 0x0F00-0x0FBF
58 {(CHAR16)0x109F, 0}, // Unassigned. 0x0FC0-0x109F
59 {(CHAR16)0x10FF, 1}, // Georgian. 0x10A0-0x10FF
60 {(CHAR16)0x11FF, 1}, // Hangul Jamo. 0x1100-0x11FF
61 {(CHAR16)0x1DFF, 0}, // Unassigned. 0x1200-0x1DFF
62 {(CHAR16)0x1EFF, 1}, // Latin extended additional. 0x1E00-0x1EFF
63 {(CHAR16)0x1FFF, 1}, // Greek extended. 0x1F00-0x1FFF
72 * Merge the blocks and replace them with the above entry as they fall to
73 * the same category and they are all narrow glyph. This will reduce search
74 * time and table size. The merge will omit the reserved code.
76 * Remove the above item if below is un-commented.
78 {(CHAR16)0x206F, 1}, // General punctuation. (See page7-154). 0x200-0x206F
79 {(CHAR16)0x209F, 1}, // Superscripts and subscripts. 0x2070-0x209F
80 {(CHAR16)0x20CF, 1}, // Currency symbols. 0x20A0-0x20CF
81 {(CHAR16)0x20FF, 1}, // Combining diacritical marks for symbols. 0x20D0-0x20FF
82 {(CHAR16)0x214F, 1}, // Letterlike sympbols. 0x2100-0x214F
83 {(CHAR16)0x218F, 1}, // Number forms. 0x2150-0x218F
84 {(CHAR16)0x21FF, 1}, // Arrows. 0x2190-0x21FF
85 {(CHAR16)0x22FF, 1}, // Mathematical operators. 0x2200-0x22FF
86 {(CHAR16)0x23FF, 1}, // Miscellaneous technical. 0x2300-0x23FF
87 {(CHAR16)0x243F, 1}, // Control pictures. 0x2400-0x243F
88 {(CHAR16)0x245F, 1}, // Optical character recognition. 0x2440-0x245F
89 {(CHAR16)0x24FF, 1}, // Enclosed alphanumerics. 0x2460-0x24FF
90 {(CHAR16)0x257F, 1}, // Box drawing. 0x2500-0x257F
91 {(CHAR16)0x259F, 1}, // Block elements. 0x2580-0x259F
92 {(CHAR16)0x25FF, 1}, // Geometric shapes. 0x25A0-0x25FF
93 {(CHAR16)0x26FF, 1}, // Miscellaneous symbols. 0x2600-0x26FF
94 {(CHAR16)0x27BF, 1}, // Dingbats. 0x2700-0x27BF
95 {(CHAR16)0x2FFF, 0}, // Reserved. 0x27C0-0x2FFF
100 // CJK phonetics and symbol area
104 * Merge the blocks and replace them with the above entry as they fall to
105 * the same category and they are all wide glyph. This will reduce search
106 * time and table size. The merge will omit the reserved code.
108 * Remove the above item if below is un-commented.
110 {(CHAR16)0x303F, 2}, // CJK symbols and punctuation. 0x3000-0x303F
111 {(CHAR16)0x309F, 2}, // Hiragana. 0x3040-0x309F
112 {(CHAR16)0x30FF, 2}, // Katakana. 0x30A0-0x30FF
113 {(CHAR16)0x312F, 2}, // Bopomofo. 0x3100-0x312F
114 {(CHAR16)0x318F, 2}, // Hangul compatibility jamo. 0x3130-0x318F
115 {(CHAR16)0x319F, 2}, // Kanbun. 0x3190-0x319F
116 {(CHAR16)0x31FF, 0}, // Reserved. As Bopomofo extended in ver3.0. 0x31A0-0x31FF
117 {(CHAR16)0x32FF, 2}, // Enclosed CJK letters and months. 0x3200-0x32FF
118 {(CHAR16)0x33FF, 2}, // CJK compatibility. 0x3300-0x33FF
123 // CJK ideograph area
127 * Merge the blocks and replace them with the above entry as they fall to
128 * the same category and they are all wide glyph. This will reduce search
129 * time and table size. The merge will omit the reserved code.
131 * Remove the above item if below is un-commented.
133 {(CHAR16)0x4DFF, 0}, // Reserved. 0x3400-0x4DBF as CJK unified ideographs
134 // extension A in ver3.0. 0x3400-0x4DFF
135 {(CHAR16)0x9FFF, 2}, // CJK unified ideographs. 0x4E00-0x9FFF
142 {(CHAR16
)0xABFF, 0}, // Reserved. 0xA000-0xA490 as Yi syllables. 0xA490-0xA4D0
143 // as Yi radicals in ver3.0. 0xA000-0xABFF
149 * Merge the blocks and replace them with the above entry as they fall to
150 * the same category and they are all wide glyph. This will reduce search
151 * time and table size. The merge will omit the reserved code.
153 * Remove the above item if below is un-commented.
155 {(CHAR16)0xD7A3, 2}, // Hangul syllables. 0xAC00-0xD7A3
156 {(CHAR16)0xD7FF, 0}, // Reserved. 0xD7A3-0xD7FF
163 {(CHAR16
)0xDFFF, 0}, // Surrogates, not used now. 0xD800-0xDFFF
168 {(CHAR16
)0xF8FF, 0}, // Private use area. 0xE000-0xF8FF
171 // Compatibility area and specials
173 {(CHAR16
)0xFAFF, 2}, // CJK compatibility ideographs. 0xF900-0xFAFF
174 {(CHAR16
)0xFB4F, 1}, // Alphabetic presentation forms. 0xFB00-0xFB4F
175 {(CHAR16
)0xFDFF, 1}, // Arabic presentation forms-A. 0xFB50-0xFDFF
176 {(CHAR16
)0xFE1F, 0}, // Reserved. As variation selectors in ver3.0. 0xFE00-0xFE1F
177 {(CHAR16
)0xFE2F, 1}, // Combining half marks. 0xFE20-0xFE2F
178 {(CHAR16
)0xFE4F, 2}, // CJK compatibility forms. 0xFE30-0xFE4F
179 {(CHAR16
)0xFE6F, 1}, // Small Form Variants. 0xFE50-0xFE6F
180 {(CHAR16
)0xFEFF, 1}, // Arabic presentation forms-B. 0xFE70-0xFEFF
181 {(CHAR16
)0xFFEF, 1}, // Half width and full width forms. 0xFF00-0xFFEF
182 {(CHAR16
)0xFFFF, 0}, // Speicials. 0xFFF0-0xFFFF
186 Retrieves the width of a Unicode character.
188 This function computes and returns the width of the Unicode character specified
191 @param UnicodeChar A Unicode character.
193 @retval 0 The width if UnicodeChar could not be determined.
194 @retval 1 UnicodeChar is a narrow glyph.
195 @retval 2 UnicodeChar is a wide glyph.
201 IN CHAR16 UnicodeChar
207 CONST UNICODE_WIDTH_ENTRY
*Item
;
211 High
= (sizeof (mUnicodeWidthTable
)) / (sizeof (UNICODE_WIDTH_ENTRY
)) - 1;
212 while (Low
<= High
) {
213 Index
= (Low
+ High
) >> 1;
214 Item
= &(mUnicodeWidthTable
[Index
]);
216 if (UnicodeChar
<= Item
->WChar
) {
223 if (UnicodeChar
> Item
->WChar
) {
225 } else if (UnicodeChar
<= mUnicodeWidthTable
[Index
- 1].WChar
) {
229 // Index - 1 < UnicodeChar <= Index. Found
243 Computes the display length of a Null-terminated Unicode String.
245 This function computes and returns the display length of the Null-terminated Unicode
246 string specified by String. If String is NULL then 0 is returned. If any of the widths
247 of the Unicode characters in String can not be determined, then 0 is returned. The display
248 width of String can be computed by summing the display widths of each Unicode character
249 in String. Unicode characters that are narrow glyphs have a width of 1, and Unicode
250 characters that are width glyphs have a width of 2.
251 If String is not aligned on a 16-bit boundary, then ASSERT().
253 @param String A pointer to a Null-terminated Unicode string.
255 @return The display length of the Null-terminated Unicode string specified by String.
260 UnicodeStringDisplayLength (
261 IN CONST CHAR16
*String
267 if (String
== NULL
) {
272 while (*String
!= 0) {
273 Width
= GetGlyphWidth (*String
);
286 Draws a dialog box to the console output device specified by
287 ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
288 from the console input device specified by ConIn defined in the
291 If there are no strings in the variable argument list, then ASSERT().
292 If all the strings in the variable argument list are empty, then ASSERT().
294 @param[in] Attribute Specifies the foreground and background color of the popup.
295 @param[out] Key A pointer to the EFI_KEY value of the key that was
296 pressed. This is an optional parameter that may be NULL.
297 If it is NULL then no wait for a keypress will be performed.
298 @param[in] ... The variable argument list that contains pointers to Null-
299 terminated Unicode strings to display in the dialog box.
300 The variable argument list is terminated by a NULL.
307 OUT EFI_INPUT_KEY
*Key
, OPTIONAL
313 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
314 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
327 // Determine the length of the longest line in the popup and the the total
328 // number of lines in the popup
330 VA_START (Args
, Key
);
333 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
) {
334 MaxLength
= MAX (MaxLength
, StrLen (String
));
340 // If the total number of lines in the popup is zero, then ASSERT()
342 ASSERT (NumberOfLines
!= 0);
345 // If the maximum length of all the strings is zero, then ASSERT()
347 ASSERT (MaxLength
!= 0);
350 // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
352 ConOut
= gST
->ConOut
;
355 // Save the current console cursor position and attributes
357 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
360 // Retrieve the number of columns and rows in the current console mode
362 ConOut
->QueryMode (ConOut
, SavedConsoleMode
.Mode
, &Columns
, &Rows
);
365 // Disable cursor and set the foreground and background colors specified by Attribute
367 ConOut
->EnableCursor (ConOut
, FALSE
);
368 ConOut
->SetAttribute (ConOut
, Attribute
);
371 // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
373 NumberOfLines
= MIN (NumberOfLines
, Rows
- 3);
376 // Limit MaxLength to width of the screen minus 2 columns for the box itself
378 MaxLength
= MIN (MaxLength
, Columns
- 2);
381 // Compute the starting row and starting column for the popup
383 Row
= (Rows
- (NumberOfLines
+ 3)) / 2;
384 Column
= (Columns
- (MaxLength
+ 2)) / 2;
387 // Allocate a buffer for a single line of the popup with borders and a Null-terminator
389 Line
= AllocateZeroPool ((MaxLength
+ 3) * sizeof (CHAR16
));
390 ASSERT (Line
!= NULL
);
393 // Draw top of popup box
395 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
396 Line
[0] = BOXDRAW_DOWN_RIGHT
;
397 Line
[MaxLength
+ 1] = BOXDRAW_DOWN_LEFT
;
398 Line
[MaxLength
+ 2] = L
'\0';
399 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
400 ConOut
->OutputString (ConOut
, Line
);
403 // Draw middle of the popup with strings
405 VA_START (Args
, Key
);
406 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
&& NumberOfLines
> 0) {
407 Length
= StrLen (String
);
408 SetMem16 (Line
, (MaxLength
+ 2) * 2, L
' ');
409 if (Length
<= MaxLength
) {
411 // Length <= MaxLength
413 CopyMem (Line
+ 1 + (MaxLength
- Length
) / 2, String
, Length
* sizeof (CHAR16
));
416 // Length > MaxLength
418 CopyMem (Line
+ 1, String
+ (Length
- MaxLength
) / 2 , MaxLength
* sizeof (CHAR16
));
420 Line
[0] = BOXDRAW_VERTICAL
;
421 Line
[MaxLength
+ 1] = BOXDRAW_VERTICAL
;
422 Line
[MaxLength
+ 2] = L
'\0';
423 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
424 ConOut
->OutputString (ConOut
, Line
);
430 // Draw bottom of popup box
432 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
433 Line
[0] = BOXDRAW_UP_RIGHT
;
434 Line
[MaxLength
+ 1] = BOXDRAW_UP_LEFT
;
435 Line
[MaxLength
+ 2] = L
'\0';
436 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
437 ConOut
->OutputString (ConOut
, Line
);
440 // Free the allocated line buffer
445 // Restore the cursor visibility, position, and attributes
447 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
448 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
449 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
452 // Wait for a keystroke
456 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, Key
);
457 if (!EFI_ERROR (Status
)) {
462 // If we encounter error, continue to read another key in.
464 if (Status
!= EFI_NOT_READY
) {
467 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);