2 This module provide help function for displaying unicode string.
4 Copyright (c) 2006 - 2009, 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
318 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
319 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
332 // Determine the length of the longest line in the popup and the the total
333 // number of lines in the popup
335 VA_START (Args
, Key
);
338 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
) {
339 MaxLength
= MAX (MaxLength
, StrLen (String
));
345 // If the total number of lines in the popup is zero, then ASSERT()
347 ASSERT (NumberOfLines
!= 0);
350 // If the maximum length of all the strings is zero, then ASSERT()
352 ASSERT (MaxLength
!= 0);
355 // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
357 ConOut
= gST
->ConOut
;
360 // Save the current console cursor position and attributes
362 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
365 // Retrieve the number of columns and rows in the current console mode
367 ConOut
->QueryMode (ConOut
, SavedConsoleMode
.Mode
, &Columns
, &Rows
);
370 // Disable cursor and set the foreground and background colors specified by Attribute
372 ConOut
->EnableCursor (ConOut
, FALSE
);
373 ConOut
->SetAttribute (ConOut
, Attribute
);
376 // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
378 NumberOfLines
= MIN (NumberOfLines
, Rows
- 3);
381 // Limit MaxLength to width of the screen minus 2 columns for the box itself
383 MaxLength
= MIN (MaxLength
, Columns
- 2);
386 // Compute the starting row and starting column for the popup
388 Row
= (Rows
- (NumberOfLines
+ 3)) / 2;
389 Column
= (Columns
- (MaxLength
+ 2)) / 2;
392 // Allocate a buffer for a single line of the popup with borders and a Null-terminator
394 Line
= AllocateZeroPool ((MaxLength
+ 3) * sizeof (CHAR16
));
395 ASSERT (Line
!= NULL
);
398 // Draw top of popup box
400 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
401 Line
[0] = BOXDRAW_DOWN_RIGHT
;
402 Line
[MaxLength
+ 1] = BOXDRAW_DOWN_LEFT
;
403 Line
[MaxLength
+ 2] = L
'\0';
404 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
405 ConOut
->OutputString (ConOut
, Line
);
408 // Draw middle of the popup with strings
410 VA_START (Args
, Key
);
411 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
&& NumberOfLines
> 0) {
412 Length
= StrLen (String
);
413 SetMem16 (Line
, (MaxLength
+ 2) * 2, L
' ');
414 if (Length
<= MaxLength
) {
416 // Length <= MaxLength
418 CopyMem (Line
+ 1 + (MaxLength
- Length
) / 2, String
, Length
* sizeof (CHAR16
));
421 // Length > MaxLength
423 CopyMem (Line
+ 1, String
+ (Length
- MaxLength
) / 2 , MaxLength
* sizeof (CHAR16
));
425 Line
[0] = BOXDRAW_VERTICAL
;
426 Line
[MaxLength
+ 1] = BOXDRAW_VERTICAL
;
427 Line
[MaxLength
+ 2] = L
'\0';
428 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
429 ConOut
->OutputString (ConOut
, Line
);
435 // Draw bottom of popup box
437 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
438 Line
[0] = BOXDRAW_UP_RIGHT
;
439 Line
[MaxLength
+ 1] = BOXDRAW_UP_LEFT
;
440 Line
[MaxLength
+ 2] = L
'\0';
441 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
442 ConOut
->OutputString (ConOut
, Line
);
445 // Free the allocated line buffer
450 // Restore the cursor visibility, position, and attributes
452 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
453 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
454 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
457 // Wait for a keystroke
460 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
461 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, Key
);