2 This module provide help function for displaying unicode string.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "UefiLibInternal.h"
23 } UNICODE_WIDTH_ENTRY
;
25 GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable
[] = {
27 // General script area
31 * Merge the blocks and replace them with the above entry as they fall to
32 * the same category and they are all narrow glyph. This will reduce search
33 * time and table size. The merge will omit the reserved code.
35 * Remove the above item if below is un-commented.
37 {(CHAR16)0x007F, 1}, // C0 controls and basic Latin. 0x0000-0x007F
38 {(CHAR16)0x00FF, 1}, // C1 controls and Latin-1 support. 0x0080-0x00FF
39 {(CHAR16)0x017F, 1}, // Latin extended-A. 0x0100-0x017F
40 {(CHAR16)0x024F, 1}, // Latin extended-B. 0x0180-0x024F
41 {(CHAR16)0x02AF, 1}, // IPA extensions. 0x0250-0x02AF
42 {(CHAR16)0x02FF, 1}, // Spacing modifier letters. 0x02B0-0x02FF
43 {(CHAR16)0x036F, 1}, // Combining diacritical marks. 0x0300-0x036F
44 {(CHAR16)0x03FF, 1}, // Greek. 0x0370-0x03FF
45 {(CHAR16)0x04FF, 1}, // Cyrillic. 0x0400-0x04FF
46 {(CHAR16)0x052F, 0}, // Unassigned. As Armenian in ver3.0. 0x0500-0x052F
47 {(CHAR16)0x058F, 1}, // Armenian. 0x0530-0x058F
48 {(CHAR16)0x05FF, 1}, // Hebrew. 0x0590-0x05FF
49 {(CHAR16)0x06FF, 1}, // Arabic. 0x0600-0x06FF
50 {(CHAR16)0x08FF, 0}, // Unassigned. 0x0700-0x08FF
51 {(CHAR16)0x097F, 1}, // Devanagari. 0x0900-0x097F
52 {(CHAR16)0x09FF, 1}, // Bengali. 0x0980-0x09FF
53 {(CHAR16)0x0A7F, 1}, // Gurmukhi. 0x0A00-0x0A7F
54 {(CHAR16)0x0AFF, 1}, // Gujarati. 0x0A80-0x0AFF
55 {(CHAR16)0x0B7F, 1}, // Oriya. 0x0B00-0x0B7F
56 {(CHAR16)0x0BFF, 1}, // Tamil. (See page 7-92). 0x0B80-0x0BFF
57 {(CHAR16)0x0C7F, 1}, // Telugu. 0x0C00-0x0C7F
58 {(CHAR16)0x0CFF, 1}, // Kannada. (See page 7-100). 0x0C80-0x0CFF
59 {(CHAR16)0x0D7F, 1}, // Malayalam (See page 7-104). 0x0D00-0x0D7F
60 {(CHAR16)0x0DFF, 0}, // Unassigned. 0x0D80-0x0DFF
61 {(CHAR16)0x0E7F, 1}, // Thai. 0x0E00-0x0E7F
62 {(CHAR16)0x0EFF, 1}, // Lao. 0x0E80-0x0EFF
63 {(CHAR16)0x0FBF, 1}, // Tibetan. 0x0F00-0x0FBF
64 {(CHAR16)0x109F, 0}, // Unassigned. 0x0FC0-0x109F
65 {(CHAR16)0x10FF, 1}, // Georgian. 0x10A0-0x10FF
66 {(CHAR16)0x11FF, 1}, // Hangul Jamo. 0x1100-0x11FF
67 {(CHAR16)0x1DFF, 0}, // Unassigned. 0x1200-0x1DFF
68 {(CHAR16)0x1EFF, 1}, // Latin extended additional. 0x1E00-0x1EFF
69 {(CHAR16)0x1FFF, 1}, // Greek extended. 0x1F00-0x1FFF
78 * Merge the blocks and replace them with the above entry as they fall to
79 * the same category and they are all narrow glyph. This will reduce search
80 * time and table size. The merge will omit the reserved code.
82 * Remove the above item if below is un-commented.
84 {(CHAR16)0x206F, 1}, // General punctuation. (See page7-154). 0x200-0x206F
85 {(CHAR16)0x209F, 1}, // Superscripts and subscripts. 0x2070-0x209F
86 {(CHAR16)0x20CF, 1}, // Currency symbols. 0x20A0-0x20CF
87 {(CHAR16)0x20FF, 1}, // Combining diacritical marks for symbols. 0x20D0-0x20FF
88 {(CHAR16)0x214F, 1}, // Letterlike sympbols. 0x2100-0x214F
89 {(CHAR16)0x218F, 1}, // Number forms. 0x2150-0x218F
90 {(CHAR16)0x21FF, 1}, // Arrows. 0x2190-0x21FF
91 {(CHAR16)0x22FF, 1}, // Mathematical operators. 0x2200-0x22FF
92 {(CHAR16)0x23FF, 1}, // Miscellaneous technical. 0x2300-0x23FF
93 {(CHAR16)0x243F, 1}, // Control pictures. 0x2400-0x243F
94 {(CHAR16)0x245F, 1}, // Optical character recognition. 0x2440-0x245F
95 {(CHAR16)0x24FF, 1}, // Enclosed alphanumerics. 0x2460-0x24FF
96 {(CHAR16)0x257F, 1}, // Box drawing. 0x2500-0x257F
97 {(CHAR16)0x259F, 1}, // Block elements. 0x2580-0x259F
98 {(CHAR16)0x25FF, 1}, // Geometric shapes. 0x25A0-0x25FF
99 {(CHAR16)0x26FF, 1}, // Miscellaneous symbols. 0x2600-0x26FF
100 {(CHAR16)0x27BF, 1}, // Dingbats. 0x2700-0x27BF
101 {(CHAR16)0x2FFF, 0}, // Reserved. 0x27C0-0x2FFF
106 // CJK phonetics and symbol area
110 * Merge the blocks and replace them with the above entry as they fall to
111 * the same category and they are all wide glyph. This will reduce search
112 * time and table size. The merge will omit the reserved code.
114 * Remove the above item if below is un-commented.
116 {(CHAR16)0x303F, 2}, // CJK symbols and punctuation. 0x3000-0x303F
117 {(CHAR16)0x309F, 2}, // Hiragana. 0x3040-0x309F
118 {(CHAR16)0x30FF, 2}, // Katakana. 0x30A0-0x30FF
119 {(CHAR16)0x312F, 2}, // Bopomofo. 0x3100-0x312F
120 {(CHAR16)0x318F, 2}, // Hangul compatibility jamo. 0x3130-0x318F
121 {(CHAR16)0x319F, 2}, // Kanbun. 0x3190-0x319F
122 {(CHAR16)0x31FF, 0}, // Reserved. As Bopomofo extended in ver3.0. 0x31A0-0x31FF
123 {(CHAR16)0x32FF, 2}, // Enclosed CJK letters and months. 0x3200-0x32FF
124 {(CHAR16)0x33FF, 2}, // CJK compatibility. 0x3300-0x33FF
129 // CJK ideograph area
133 * Merge the blocks and replace them with the above entry as they fall to
134 * the same category and they are all wide glyph. This will reduce search
135 * time and table size. The merge will omit the reserved code.
137 * Remove the above item if below is un-commented.
139 {(CHAR16)0x4DFF, 0}, // Reserved. 0x3400-0x4DBF as CJK unified ideographs
140 // extension A in ver3.0. 0x3400-0x4DFF
141 {(CHAR16)0x9FFF, 2}, // CJK unified ideographs. 0x4E00-0x9FFF
148 {(CHAR16
)0xABFF, 0}, // Reserved. 0xA000-0xA490 as Yi syllables. 0xA490-0xA4D0
149 // as Yi radicals in ver3.0. 0xA000-0xABFF
155 * Merge the blocks and replace them with the above entry as they fall to
156 * the same category and they are all wide glyph. This will reduce search
157 * time and table size. The merge will omit the reserved code.
159 * Remove the above item if below is un-commented.
161 {(CHAR16)0xD7A3, 2}, // Hangul syllables. 0xAC00-0xD7A3
162 {(CHAR16)0xD7FF, 0}, // Reserved. 0xD7A3-0xD7FF
169 {(CHAR16
)0xDFFF, 0}, // Surrogates, not used now. 0xD800-0xDFFF
174 {(CHAR16
)0xF8FF, 0}, // Private use area. 0xE000-0xF8FF
177 // Compatibility area and specials
179 {(CHAR16
)0xFAFF, 2}, // CJK compatibility ideographs. 0xF900-0xFAFF
180 {(CHAR16
)0xFB4F, 1}, // Alphabetic presentation forms. 0xFB00-0xFB4F
181 {(CHAR16
)0xFDFF, 1}, // Arabic presentation forms-A. 0xFB50-0xFDFF
182 {(CHAR16
)0xFE1F, 0}, // Reserved. As variation selectors in ver3.0. 0xFE00-0xFE1F
183 {(CHAR16
)0xFE2F, 1}, // Combining half marks. 0xFE20-0xFE2F
184 {(CHAR16
)0xFE4F, 2}, // CJK compatibility forms. 0xFE30-0xFE4F
185 {(CHAR16
)0xFE6F, 1}, // Small Form Variants. 0xFE50-0xFE6F
186 {(CHAR16
)0xFEFF, 1}, // Arabic presentation forms-B. 0xFE70-0xFEFF
187 {(CHAR16
)0xFFEF, 1}, // Half width and full width forms. 0xFF00-0xFFEF
188 {(CHAR16
)0xFFFF, 0}, // Speicials. 0xFFF0-0xFFFF
192 Retrieves the width of a Unicode character.
194 This function computes and returns the width of the Unicode character specified
197 @param UnicodeChar A Unicode character.
199 @retval 0 The width if UnicodeChar could not be determined.
200 @retval 1 UnicodeChar is a narrow glyph.
201 @retval 2 UnicodeChar is a wide glyph.
207 IN CHAR16 UnicodeChar
213 CONST UNICODE_WIDTH_ENTRY
*Item
;
217 High
= (sizeof (mUnicodeWidthTable
)) / (sizeof (UNICODE_WIDTH_ENTRY
)) - 1;
218 while (Low
<= High
) {
219 Index
= (Low
+ High
) >> 1;
220 Item
= &(mUnicodeWidthTable
[Index
]);
222 if (UnicodeChar
<= Item
->WChar
) {
229 if (UnicodeChar
> Item
->WChar
) {
231 } else if (UnicodeChar
<= mUnicodeWidthTable
[Index
- 1].WChar
) {
235 // Index - 1 < UnicodeChar <= Index. Found
249 Computes the display length of a Null-terminated Unicode String.
251 This function computes and returns the display length of the Null-terminated Unicode
252 string specified by String. If String is NULL then 0 is returned. If any of the widths
253 of the Unicode characters in String can not be determined, then 0 is returned. The display
254 width of String can be computed by summing the display widths of each Unicode character
255 in String. Unicode characters that are narrow glyphs have a width of 1, and Unicode
256 characters that are width glyphs have a width of 2.
257 If String is not aligned on a 16-bit boundary, then ASSERT().
259 @param String A pointer to a Null-terminated Unicode string.
261 @return The display length of the Null-terminated Unicode string specified by String.
266 UnicodeStringDisplayLength (
267 IN CONST CHAR16
*String
273 if (String
== NULL
) {
278 while (*String
!= 0) {
279 Width
= GetGlyphWidth (*String
);
292 Draws a dialog box to the console output device specified by
293 ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
294 from the console input device specified by ConIn defined in the
297 If there are no strings in the variable argument list, then ASSERT().
298 If all the strings in the variable argument list are empty, then ASSERT().
300 @param[in] Attribute Specifies the foreground and background color of the popup.
301 @param[out] Key A pointer to the EFI_KEY value of the key that was
302 pressed. This is an optional parameter that may be NULL.
303 If it is NULL then no wait for a keypress will be performed.
304 @param[in] ... The variable argument list that contains pointers to Null-
305 terminated Unicode strings to display in the dialog box.
306 The variable argument list is terminated by a NULL.
313 OUT EFI_INPUT_KEY
*Key
, OPTIONAL
319 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
320 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
333 // Determine the length of the longest line in the popup and the the total
334 // number of lines in the popup
336 VA_START (Args
, Key
);
339 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
) {
340 MaxLength
= MAX (MaxLength
, StrLen (String
));
346 // If the total number of lines in the popup is zero, then ASSERT()
348 ASSERT (NumberOfLines
!= 0);
351 // If the maximum length of all the strings is zero, then ASSERT()
353 ASSERT (MaxLength
!= 0);
356 // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
358 ConOut
= gST
->ConOut
;
361 // Save the current console cursor position and attributes
363 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
366 // Retrieve the number of columns and rows in the current console mode
368 ConOut
->QueryMode (ConOut
, SavedConsoleMode
.Mode
, &Columns
, &Rows
);
371 // Disable cursor and set the foreground and background colors specified by Attribute
373 ConOut
->EnableCursor (ConOut
, FALSE
);
374 ConOut
->SetAttribute (ConOut
, Attribute
);
377 // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
379 NumberOfLines
= MIN (NumberOfLines
, Rows
- 3);
382 // Limit MaxLength to width of the screen minus 2 columns for the box itself
384 MaxLength
= MIN (MaxLength
, Columns
- 2);
387 // Compute the starting row and starting column for the popup
389 Row
= (Rows
- (NumberOfLines
+ 3)) / 2;
390 Column
= (Columns
- (MaxLength
+ 2)) / 2;
393 // Allocate a buffer for a single line of the popup with borders and a Null-terminator
395 Line
= AllocateZeroPool ((MaxLength
+ 3) * sizeof (CHAR16
));
396 ASSERT (Line
!= NULL
);
399 // Draw top of popup box
401 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
402 Line
[0] = BOXDRAW_DOWN_RIGHT
;
403 Line
[MaxLength
+ 1] = BOXDRAW_DOWN_LEFT
;
404 Line
[MaxLength
+ 2] = L
'\0';
405 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
406 ConOut
->OutputString (ConOut
, Line
);
409 // Draw middle of the popup with strings
411 VA_START (Args
, Key
);
412 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
&& NumberOfLines
> 0) {
413 Length
= StrLen (String
);
414 SetMem16 (Line
, (MaxLength
+ 2) * 2, L
' ');
415 if (Length
<= MaxLength
) {
417 // Length <= MaxLength
419 CopyMem (Line
+ 1 + (MaxLength
- Length
) / 2, String
, Length
* sizeof (CHAR16
));
422 // Length > MaxLength
424 CopyMem (Line
+ 1, String
+ (Length
- MaxLength
) / 2 , MaxLength
* sizeof (CHAR16
));
426 Line
[0] = BOXDRAW_VERTICAL
;
427 Line
[MaxLength
+ 1] = BOXDRAW_VERTICAL
;
428 Line
[MaxLength
+ 2] = L
'\0';
429 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
430 ConOut
->OutputString (ConOut
, Line
);
436 // Draw bottom of popup box
438 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
439 Line
[0] = BOXDRAW_UP_RIGHT
;
440 Line
[MaxLength
+ 1] = BOXDRAW_UP_LEFT
;
441 Line
[MaxLength
+ 2] = L
'\0';
442 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
443 ConOut
->OutputString (ConOut
, Line
);
446 // Free the allocated line buffer
451 // Restore the cursor visibility, position, and attributes
453 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
454 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
455 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
458 // Wait for a keystroke
462 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, Key
);
463 if (!EFI_ERROR (Status
)) {
468 // If we encounter error, continue to read another key in.
470 if (Status
!= EFI_NOT_READY
) {
473 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);