]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / Font.c
CommitLineData
93e3992d 1/** @file\r
e90b081a 2Implementation for EFI_HII_FONT_PROTOCOL.\r
3\r
93e3992d 4\r
d1102dba 5Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
93e3992d 7\r
93e3992d 8**/\r
9\r
93e3992d 10#include "HiiDatabase.h"\r
11\r
1436aea4 12EFI_GRAPHICS_OUTPUT_BLT_PIXEL mHiiEfiColors[16] = {\r
93e3992d 13 //\r
14 // B G R\r
15 //\r
1436aea4
MK
16 { 0x00, 0x00, 0x00, 0x00 }, // BLACK\r
17 { 0x98, 0x00, 0x00, 0x00 }, // BLUE\r
18 { 0x00, 0x98, 0x00, 0x00 }, // GREEN\r
19 { 0x98, 0x98, 0x00, 0x00 }, // CYAN\r
20 { 0x00, 0x00, 0x98, 0x00 }, // RED\r
21 { 0x98, 0x00, 0x98, 0x00 }, // MAGENTA\r
22 { 0x00, 0x98, 0x98, 0x00 }, // BROWN\r
23 { 0x98, 0x98, 0x98, 0x00 }, // LIGHTGRAY\r
24 { 0x30, 0x30, 0x30, 0x00 }, // DARKGRAY - BRIGHT BLACK\r
25 { 0xff, 0x00, 0x00, 0x00 }, // LIGHTBLUE\r
26 { 0x00, 0xff, 0x00, 0x00 }, // LIGHTGREEN\r
27 { 0xff, 0xff, 0x00, 0x00 }, // LIGHTCYAN\r
28 { 0x00, 0x00, 0xff, 0x00 }, // LIGHTRED\r
29 { 0xff, 0x00, 0xff, 0x00 }, // LIGHTMAGENTA\r
30 { 0x00, 0xff, 0xff, 0x00 }, // YELLOW\r
31 { 0xff, 0xff, 0xff, 0x00 }, // WHITE\r
93e3992d 32};\r
33\r
93e3992d 34/**\r
35 Insert a character cell information to the list specified by GlyphInfoList.\r
36\r
e90b081a 37 This is a internal function.\r
38\r
93e3992d 39 @param CharValue Unicode character value, which identifies a glyph\r
40 block.\r
41 @param GlyphInfoList HII_GLYPH_INFO list head.\r
42 @param Cell Incoming character cell information.\r
43\r
44 @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.\r
45 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
46 task.\r
47\r
48**/\r
93e3992d 49EFI_STATUS\r
50NewCell (\r
1436aea4
MK
51 IN CHAR16 CharValue,\r
52 IN LIST_ENTRY *GlyphInfoList,\r
53 IN EFI_HII_GLYPH_INFO *Cell\r
93e3992d 54 )\r
55{\r
1436aea4 56 HII_GLYPH_INFO *GlyphInfo;\r
93e3992d 57\r
58 ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
59\r
1436aea4 60 GlyphInfo = (HII_GLYPH_INFO *)AllocateZeroPool (sizeof (HII_GLYPH_INFO));\r
93e3992d 61 if (GlyphInfo == NULL) {\r
62 return EFI_OUT_OF_RESOURCES;\r
63 }\r
64\r
65 //\r
66 // GlyphInfoList stores a list of default character cell information, each is\r
67 // identified by "CharId".\r
68 //\r
69 GlyphInfo->Signature = HII_GLYPH_INFO_SIGNATURE;\r
70 GlyphInfo->CharId = CharValue;\r
f6cf5cf8
LG
71 if (Cell->AdvanceX == 0) {\r
72 Cell->AdvanceX = Cell->Width;\r
73 }\r
1436aea4 74\r
93e3992d 75 CopyMem (&GlyphInfo->Cell, Cell, sizeof (EFI_HII_GLYPH_INFO));\r
76 InsertTailList (GlyphInfoList, &GlyphInfo->Entry);\r
77\r
78 return EFI_SUCCESS;\r
79}\r
80\r
93e3992d 81/**\r
82 Get a character cell information from the list specified by GlyphInfoList.\r
83\r
e90b081a 84 This is a internal function.\r
85\r
93e3992d 86 @param CharValue Unicode character value, which identifies a glyph\r
87 block.\r
88 @param GlyphInfoList HII_GLYPH_INFO list head.\r
89 @param Cell Buffer which stores output character cell\r
90 information.\r
91\r
92 @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.\r
93 @retval EFI_NOT_FOUND The character info specified by CharValue does\r
94 not exist.\r
95\r
96**/\r
93e3992d 97EFI_STATUS\r
98GetCell (\r
1436aea4
MK
99 IN CHAR16 CharValue,\r
100 IN LIST_ENTRY *GlyphInfoList,\r
101 OUT EFI_HII_GLYPH_INFO *Cell\r
93e3992d 102 )\r
103{\r
1436aea4
MK
104 HII_GLYPH_INFO *GlyphInfo;\r
105 LIST_ENTRY *Link;\r
93e3992d 106\r
107 ASSERT (Cell != NULL && GlyphInfoList != NULL);\r
108\r
109 //\r
110 // Since the EFI_HII_GIBT_DEFAULTS block won't increment CharValueCurrent,\r
111 // the value of "CharId" of a default character cell which is used for a\r
112 // EFI_HII_GIBT_GLYPH_DEFAULT or EFI_HII_GIBT_GLYPHS_DEFAULT should be\r
113 // less or equal to the value of "CharValueCurrent" of this default block.\r
114 //\r
115 // For instance, if the CharId of a GlyphInfoList is {1, 3, 7}, a default glyph\r
116 // with CharValue equals "7" uses the GlyphInfo with CharId = 7;\r
117 // a default glyph with CharValue equals "6" uses the GlyphInfo with CharId = 3.\r
118 //\r
119 for (Link = GlyphInfoList->BackLink; Link != GlyphInfoList; Link = Link->BackLink) {\r
120 GlyphInfo = CR (Link, HII_GLYPH_INFO, Entry, HII_GLYPH_INFO_SIGNATURE);\r
121 if (GlyphInfo->CharId <= CharValue) {\r
122 CopyMem (Cell, &GlyphInfo->Cell, sizeof (EFI_HII_GLYPH_INFO));\r
123 return EFI_SUCCESS;\r
124 }\r
125 }\r
126\r
127 return EFI_NOT_FOUND;\r
128}\r
129\r
93e3992d 130/**\r
131 Convert the glyph for a single character into a bitmap.\r
132\r
e90b081a 133 This is a internal function.\r
134\r
93e3992d 135 @param Private HII database driver private data.\r
136 @param Char Character to retrieve.\r
137 @param StringInfo Points to the string font and color information\r
138 or NULL if the string should use the default\r
139 system font and color.\r
140 @param GlyphBuffer Buffer to store the retrieved bitmap data.\r
141 @param Cell Points to EFI_HII_GLYPH_INFO structure.\r
142 @param Attributes If not NULL, output the glyph attributes if any.\r
143\r
144 @retval EFI_SUCCESS Glyph bitmap outputted.\r
145 @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer GlyphBuffer.\r
146 @retval EFI_NOT_FOUND The glyph was unknown can not be found.\r
147 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
148\r
149**/\r
93e3992d 150EFI_STATUS\r
151GetGlyphBuffer (\r
1436aea4
MK
152 IN HII_DATABASE_PRIVATE_DATA *Private,\r
153 IN CHAR16 Char,\r
154 IN EFI_FONT_INFO *StringInfo,\r
155 OUT UINT8 **GlyphBuffer,\r
156 OUT EFI_HII_GLYPH_INFO *Cell,\r
157 OUT UINT8 *Attributes OPTIONAL\r
93e3992d 158 )\r
159{\r
1436aea4
MK
160 HII_DATABASE_RECORD *Node;\r
161 LIST_ENTRY *Link;\r
162 HII_SIMPLE_FONT_PACKAGE_INSTANCE *SimpleFont;\r
163 LIST_ENTRY *Link1;\r
164 UINT16 Index;\r
165 EFI_NARROW_GLYPH Narrow;\r
166 EFI_WIDE_GLYPH Wide;\r
167 HII_GLOBAL_FONT_INFO *GlobalFont;\r
168 UINTN HeaderSize;\r
169 EFI_NARROW_GLYPH *NarrowPtr;\r
170 EFI_WIDE_GLYPH *WidePtr;\r
171\r
172 if ((GlyphBuffer == NULL) || (Cell == NULL)) {\r
93e3992d 173 return EFI_INVALID_PARAMETER;\r
174 }\r
1436aea4
MK
175\r
176 if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {\r
93e3992d 177 return EFI_INVALID_PARAMETER;\r
178 }\r
179\r
180 ZeroMem (Cell, sizeof (EFI_HII_GLYPH_INFO));\r
181\r
182 //\r
183 // If StringInfo is not NULL, it must point to an existing EFI_FONT_INFO rather\r
184 // than system default font and color.\r
185 // If NULL, try to find the character in simplified font packages since\r
186 // default system font is the fixed font (narrow or wide glyph).\r
187 //\r
188 if (StringInfo != NULL) {\r
1436aea4 189 if (!IsFontInfoExisted (Private, StringInfo, NULL, NULL, &GlobalFont)) {\r
93e3992d 190 return EFI_INVALID_PARAMETER;\r
191 }\r
1436aea4 192\r
93e3992d 193 if (Attributes != NULL) {\r
194 *Attributes = PROPORTIONAL_GLYPH;\r
195 }\r
1436aea4 196\r
93e3992d 197 return FindGlyphBlock (GlobalFont->FontPackage, Char, GlyphBuffer, Cell, NULL);\r
198 } else {\r
199 HeaderSize = sizeof (EFI_HII_SIMPLE_FONT_PACKAGE_HDR);\r
200\r
201 for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {\r
202 Node = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
203 for (Link1 = Node->PackageList->SimpleFontPkgHdr.ForwardLink;\r
204 Link1 != &Node->PackageList->SimpleFontPkgHdr;\r
205 Link1 = Link1->ForwardLink\r
1436aea4
MK
206 )\r
207 {\r
93e3992d 208 SimpleFont = CR (Link1, HII_SIMPLE_FONT_PACKAGE_INSTANCE, SimpleFontEntry, HII_S_FONT_PACKAGE_SIGNATURE);\r
209 //\r
210 // Search the narrow glyph array\r
211 //\r
1436aea4 212 NarrowPtr = (EFI_NARROW_GLYPH *)((UINT8 *)(SimpleFont->SimpleFontPkgHdr) + HeaderSize);\r
93e3992d 213 for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs; Index++) {\r
1436aea4 214 CopyMem (&Narrow, NarrowPtr + Index, sizeof (EFI_NARROW_GLYPH));\r
93e3992d 215 if (Narrow.UnicodeWeight == Char) {\r
1436aea4 216 *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT);\r
93e3992d 217 if (*GlyphBuffer == NULL) {\r
218 return EFI_OUT_OF_RESOURCES;\r
219 }\r
1436aea4 220\r
93e3992d 221 Cell->Width = EFI_GLYPH_WIDTH;\r
222 Cell->Height = EFI_GLYPH_HEIGHT;\r
93e3992d 223 Cell->AdvanceX = Cell->Width;\r
224 CopyMem (*GlyphBuffer, Narrow.GlyphCol1, Cell->Height);\r
225 if (Attributes != NULL) {\r
1436aea4 226 *Attributes = (UINT8)(Narrow.Attributes | NARROW_GLYPH);\r
93e3992d 227 }\r
1436aea4 228\r
93e3992d 229 return EFI_SUCCESS;\r
230 }\r
231 }\r
1436aea4 232\r
93e3992d 233 //\r
234 // Search the wide glyph array\r
235 //\r
1436aea4 236 WidePtr = (EFI_WIDE_GLYPH *)(NarrowPtr + SimpleFont->SimpleFontPkgHdr->NumberOfNarrowGlyphs);\r
93e3992d 237 for (Index = 0; Index < SimpleFont->SimpleFontPkgHdr->NumberOfWideGlyphs; Index++) {\r
238 CopyMem (&Wide, WidePtr + Index, sizeof (EFI_WIDE_GLYPH));\r
239 if (Wide.UnicodeWeight == Char) {\r
1436aea4 240 *GlyphBuffer = (UINT8 *)AllocateZeroPool (EFI_GLYPH_HEIGHT * 2);\r
93e3992d 241 if (*GlyphBuffer == NULL) {\r
242 return EFI_OUT_OF_RESOURCES;\r
243 }\r
1436aea4 244\r
93e3992d 245 Cell->Width = EFI_GLYPH_WIDTH * 2;\r
246 Cell->Height = EFI_GLYPH_HEIGHT;\r
93e3992d 247 Cell->AdvanceX = Cell->Width;\r
248 CopyMem (*GlyphBuffer, Wide.GlyphCol1, EFI_GLYPH_HEIGHT);\r
249 CopyMem (*GlyphBuffer + EFI_GLYPH_HEIGHT, Wide.GlyphCol2, EFI_GLYPH_HEIGHT);\r
250 if (Attributes != NULL) {\r
1436aea4 251 *Attributes = (UINT8)(Wide.Attributes | EFI_GLYPH_WIDE);\r
93e3992d 252 }\r
1436aea4 253\r
93e3992d 254 return EFI_SUCCESS;\r
255 }\r
256 }\r
257 }\r
258 }\r
259 }\r
260\r
261 return EFI_NOT_FOUND;\r
262}\r
263\r
e90b081a 264/**\r
265 Convert bitmap data of the glyph to blt structure.\r
266\r
267 This is a internal function.\r
268\r
269 @param GlyphBuffer Buffer points to bitmap data of glyph.\r
270 @param Foreground The color of the "on" pixels in the glyph in the\r
271 bitmap.\r
272 @param Background The color of the "off" pixels in the glyph in the\r
273 bitmap.\r
f6cf5cf8
LG
274 @param ImageWidth Width of the whole image in pixels.\r
275 @param RowWidth The width of the text on the line, in pixels.\r
276 @param RowHeight The height of the line, in pixels.\r
277 @param Transparent If TRUE, the Background color is ignored and all\r
4a429716 278 "off" pixels in the character's drawn will use the\r
f6cf5cf8
LG
279 pixel value from BltBuffer.\r
280 @param Origin On input, points to the origin of the to be\r
281 displayed character, on output, points to the\r
282 next glyph's origin.\r
e90b081a 283\r
284**/\r
93e3992d 285VOID\r
286NarrowGlyphToBlt (\r
1436aea4
MK
287 IN UINT8 *GlyphBuffer,\r
288 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
289 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
290 IN UINT16 ImageWidth,\r
291 IN UINTN RowWidth,\r
292 IN UINTN RowHeight,\r
293 IN BOOLEAN Transparent,\r
294 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
93e3992d 295 )\r
296{\r
1436aea4
MK
297 UINT8 Xpos;\r
298 UINT8 Ypos;\r
299 UINT8 Height;\r
300 UINT8 Width;\r
301 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;\r
93e3992d 302\r
303 ASSERT (GlyphBuffer != NULL && Origin != NULL && *Origin != NULL);\r
304\r
305 Height = EFI_GLYPH_HEIGHT;\r
306 Width = EFI_GLYPH_WIDTH;\r
d1102dba 307\r
f6cf5cf8
LG
308 //\r
309 // Move position to the left-top corner of char.\r
310 //\r
311 Buffer = *Origin - EFI_GLYPH_HEIGHT * ImageWidth;\r
93e3992d 312\r
f6cf5cf8 313 //\r
d1102dba 314 // Char may be partially displayed when CLIP_X or CLIP_Y is not set.\r
f6cf5cf8
LG
315 //\r
316 if (RowHeight < Height) {\r
1436aea4 317 Height = (UINT8)RowHeight;\r
f6cf5cf8 318 }\r
1436aea4 319\r
f6cf5cf8 320 if (RowWidth < Width) {\r
1436aea4 321 Width = (UINT8)RowWidth;\r
f6cf5cf8 322 }\r
93e3992d 323\r
e90b081a 324 for (Ypos = 0; Ypos < Height; Ypos++) {\r
325 for (Xpos = 0; Xpos < Width; Xpos++) {\r
f6cf5cf8
LG
326 if ((GlyphBuffer[Ypos] & (1 << (EFI_GLYPH_WIDTH - Xpos - 1))) != 0) {\r
327 Buffer[Ypos * ImageWidth + Xpos] = Foreground;\r
93e3992d 328 } else {\r
329 if (!Transparent) {\r
f6cf5cf8 330 Buffer[Ypos * ImageWidth + Xpos] = Background;\r
93e3992d 331 }\r
332 }\r
333 }\r
334 }\r
335\r
f6cf5cf8 336 *Origin = *Origin + EFI_GLYPH_WIDTH;\r
93e3992d 337}\r
338\r
93e3992d 339/**\r
340 Convert bitmap data of the glyph to blt structure.\r
341\r
e90b081a 342 This is a internal function.\r
343\r
93e3992d 344 @param GlyphBuffer Buffer points to bitmap data of glyph.\r
345 @param Foreground The color of the "on" pixels in the glyph in the\r
346 bitmap.\r
347 @param Background The color of the "off" pixels in the glyph in the\r
348 bitmap.\r
f6cf5cf8
LG
349 @param ImageWidth Width of the whole image in pixels.\r
350 @param BaseLine BaseLine in the line.\r
351 @param RowWidth The width of the text on the line, in pixels.\r
352 @param RowHeight The height of the line, in pixels.\r
93e3992d 353 @param Transparent If TRUE, the Background color is ignored and all\r
4a429716 354 "off" pixels in the character's drawn will use the\r
93e3992d 355 pixel value from BltBuffer.\r
e90b081a 356 @param Cell Points to EFI_HII_GLYPH_INFO structure.\r
357 @param Attributes The attribute of incoming glyph in GlyphBuffer.\r
358 @param Origin On input, points to the origin of the to be\r
359 displayed character, on output, points to the\r
360 next glyph's origin.\r
93e3992d 361\r
362\r
363**/\r
93e3992d 364VOID\r
365GlyphToBlt (\r
1436aea4
MK
366 IN UINT8 *GlyphBuffer,\r
367 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
368 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
369 IN UINT16 ImageWidth,\r
370 IN UINT16 BaseLine,\r
371 IN UINTN RowWidth,\r
372 IN UINTN RowHeight,\r
373 IN BOOLEAN Transparent,\r
374 IN CONST EFI_HII_GLYPH_INFO *Cell,\r
375 IN UINT8 Attributes,\r
376 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
93e3992d 377 )\r
378{\r
1436aea4
MK
379 UINT16 Xpos;\r
380 UINT16 Ypos;\r
381 UINT8 Data;\r
382 UINT16 Index;\r
383 UINT16 YposOffset;\r
384 UINTN OffsetY;\r
385 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
93e3992d 386\r
f6cf5cf8 387 ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
93e3992d 388\r
f6cf5cf8
LG
389 //\r
390 // Only adjust origin position if char has no bitmap.\r
391 //\r
392 if (GlyphBuffer == NULL) {\r
393 *Origin = *Origin + Cell->AdvanceX;\r
394 return;\r
395 }\r
1436aea4 396\r
f6cf5cf8
LG
397 //\r
398 // Move position to the left-top corner of char.\r
399 //\r
400 BltBuffer = *Origin + Cell->OffsetX - (Cell->OffsetY + Cell->Height) * ImageWidth;\r
1436aea4 401 YposOffset = (UINT16)(BaseLine - (Cell->OffsetY + Cell->Height));\r
93e3992d 402\r
403 //\r
404 // Since non-spacing key will be printed OR'd with the previous glyph, don't\r
405 // write 0.\r
406 //\r
407 if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {\r
408 Transparent = TRUE;\r
409 }\r
410\r
411 //\r
412 // The glyph's upper left hand corner pixel is the most significant bit of the\r
413 // first bitmap byte.\r
414 //\r
1436aea4 415 for (Ypos = 0; Ypos < Cell->Height && (((UINT32)Ypos + YposOffset) < RowHeight); Ypos++) {\r
e90b081a 416 OffsetY = BITMAP_LEN_1_BIT (Cell->Width, Ypos);\r
93e3992d 417\r
418 //\r
419 // All bits in these bytes are meaningful.\r
420 //\r
e90b081a 421 for (Xpos = 0; Xpos < Cell->Width / 8; Xpos++) {\r
1436aea4
MK
422 Data = *(GlyphBuffer + OffsetY + Xpos);\r
423 for (Index = 0; Index < 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
f6cf5cf8
LG
424 if ((Data & (1 << (8 - Index - 1))) != 0) {\r
425 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
93e3992d 426 } else {\r
427 if (!Transparent) {\r
f6cf5cf8 428 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
93e3992d 429 }\r
430 }\r
431 }\r
432 }\r
433\r
50b39985 434 if (Cell->Width % 8 != 0) {\r
93e3992d 435 //\r
436 // There are some padding bits in this byte. Ignore them.\r
437 //\r
1436aea4
MK
438 Data = *(GlyphBuffer + OffsetY + Xpos);\r
439 for (Index = 0; Index < Cell->Width % 8 && (((UINT32)Xpos * 8 + Index + Cell->OffsetX) < RowWidth); Index++) {\r
93e3992d 440 if ((Data & (1 << (8 - Index - 1))) != 0) {\r
e90b081a 441 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Foreground;\r
93e3992d 442 } else {\r
443 if (!Transparent) {\r
e90b081a 444 BltBuffer[Ypos * ImageWidth + Xpos * 8 + Index] = Background;\r
93e3992d 445 }\r
446 }\r
447 }\r
448 } // end of if (Width % 8...)\r
e90b081a 449 } // end of for (Ypos=0...)\r
93e3992d 450\r
f6cf5cf8 451 *Origin = *Origin + Cell->AdvanceX;\r
93e3992d 452}\r
453\r
93e3992d 454/**\r
455 Convert bitmap data of the glyph to blt structure.\r
456\r
e90b081a 457 This is a internal function.\r
458\r
93e3992d 459 @param GlyphBuffer Buffer points to bitmap data of glyph.\r
460 @param Foreground The color of the "on" pixels in the glyph in the\r
461 bitmap.\r
462 @param Background The color of the "off" pixels in the glyph in the\r
463 bitmap.\r
f6cf5cf8
LG
464 @param ImageWidth Width of the whole image in pixels.\r
465 @param BaseLine BaseLine in the line.\r
466 @param RowWidth The width of the text on the line, in pixels.\r
467 @param RowHeight The height of the line, in pixels.\r
93e3992d 468 @param Transparent If TRUE, the Background color is ignored and all\r
4a429716 469 "off" pixels in the character's drawn will use the\r
93e3992d 470 pixel value from BltBuffer.\r
471 @param Cell Points to EFI_HII_GLYPH_INFO structure.\r
472 @param Attributes The attribute of incoming glyph in GlyphBuffer.\r
473 @param Origin On input, points to the origin of the to be\r
474 displayed character, on output, points to the\r
475 next glyph's origin.\r
476\r
477 @return Points to the address of next origin node in BltBuffer.\r
478\r
479**/\r
93e3992d 480VOID\r
481GlyphToImage (\r
1436aea4
MK
482 IN UINT8 *GlyphBuffer,\r
483 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
484 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
485 IN UINT16 ImageWidth,\r
486 IN UINT16 BaseLine,\r
487 IN UINTN RowWidth,\r
488 IN UINTN RowHeight,\r
489 IN BOOLEAN Transparent,\r
490 IN CONST EFI_HII_GLYPH_INFO *Cell,\r
491 IN UINT8 Attributes,\r
492 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **Origin\r
93e3992d 493 )\r
494{\r
1436aea4 495 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Buffer;\r
93e3992d 496\r
f6cf5cf8 497 ASSERT (Origin != NULL && *Origin != NULL && Cell != NULL);\r
93e3992d 498\r
499 Buffer = *Origin;\r
500\r
501 if ((Attributes & EFI_GLYPH_NON_SPACING) == EFI_GLYPH_NON_SPACING) {\r
502 //\r
503 // This character is a non-spacing key, print it OR'd with the previous glyph.\r
504 // without advancing cursor.\r
505 //\r
f6cf5cf8 506 Buffer -= Cell->AdvanceX;\r
93e3992d 507 GlyphToBlt (\r
508 GlyphBuffer,\r
509 Foreground,\r
510 Background,\r
511 ImageWidth,\r
f6cf5cf8
LG
512 BaseLine,\r
513 RowWidth,\r
514 RowHeight,\r
93e3992d 515 Transparent,\r
516 Cell,\r
517 Attributes,\r
518 &Buffer\r
519 );\r
93e3992d 520 } else if ((Attributes & EFI_GLYPH_WIDE) == EFI_GLYPH_WIDE) {\r
521 //\r
522 // This character is wide glyph, i.e. 16 pixels * 19 pixels.\r
523 // Draw it as two narrow glyphs.\r
524 //\r
525 NarrowGlyphToBlt (\r
526 GlyphBuffer,\r
527 Foreground,\r
528 Background,\r
529 ImageWidth,\r
f6cf5cf8
LG
530 RowWidth,\r
531 RowHeight,\r
93e3992d 532 Transparent,\r
533 Origin\r
534 );\r
535\r
536 NarrowGlyphToBlt (\r
537 GlyphBuffer + EFI_GLYPH_HEIGHT,\r
538 Foreground,\r
539 Background,\r
540 ImageWidth,\r
f6cf5cf8
LG
541 RowWidth,\r
542 RowHeight,\r
93e3992d 543 Transparent,\r
544 Origin\r
545 );\r
93e3992d 546 } else if ((Attributes & NARROW_GLYPH) == NARROW_GLYPH) {\r
547 //\r
548 // This character is narrow glyph, i.e. 8 pixels * 19 pixels.\r
549 //\r
550 NarrowGlyphToBlt (\r
551 GlyphBuffer,\r
552 Foreground,\r
553 Background,\r
554 ImageWidth,\r
f6cf5cf8
LG
555 RowWidth,\r
556 RowHeight,\r
93e3992d 557 Transparent,\r
558 Origin\r
559 );\r
93e3992d 560 } else if ((Attributes & PROPORTIONAL_GLYPH) == PROPORTIONAL_GLYPH) {\r
561 //\r
50b39985 562 // This character is proportional glyph, i.e. Cell->Width * Cell->Height pixels.\r
93e3992d 563 //\r
564 GlyphToBlt (\r
565 GlyphBuffer,\r
566 Foreground,\r
567 Background,\r
568 ImageWidth,\r
f6cf5cf8
LG
569 BaseLine,\r
570 RowWidth,\r
571 RowHeight,\r
93e3992d 572 Transparent,\r
573 Cell,\r
574 Attributes,\r
575 Origin\r
576 );\r
577 }\r
578}\r
579\r
93e3992d 580/**\r
581 Write the output parameters of FindGlyphBlock().\r
582\r
e90b081a 583 This is a internal function.\r
584\r
93e3992d 585 @param BufferIn Buffer which stores the bitmap data of the found\r
586 block.\r
587 @param BufferLen Length of BufferIn.\r
588 @param InputCell Buffer which stores cell information of the\r
589 encoded bitmap.\r
590 @param GlyphBuffer Output the corresponding bitmap data of the found\r
4a429716 591 block. It is the caller's responsibility to free\r
93e3992d 592 this buffer.\r
593 @param Cell Output cell information of the encoded bitmap.\r
594 @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.\r
595\r
596 @retval EFI_SUCCESS The operation is performed successfully.\r
597 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
598 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
599 task.\r
600\r
601**/\r
93e3992d 602EFI_STATUS\r
603WriteOutputParam (\r
1436aea4
MK
604 IN UINT8 *BufferIn,\r
605 IN UINTN BufferLen,\r
606 IN EFI_HII_GLYPH_INFO *InputCell,\r
607 OUT UINT8 **GlyphBuffer OPTIONAL,\r
608 OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,\r
609 OUT UINTN *GlyphBufferLen OPTIONAL\r
93e3992d 610 )\r
611{\r
1436aea4 612 if ((BufferIn == NULL) || (InputCell == NULL)) {\r
93e3992d 613 return EFI_INVALID_PARAMETER;\r
614 }\r
615\r
616 if (Cell != NULL) {\r
617 CopyMem (Cell, InputCell, sizeof (EFI_HII_GLYPH_INFO));\r
618 }\r
619\r
1436aea4
MK
620 if ((GlyphBuffer != NULL) && (BufferLen > 0)) {\r
621 *GlyphBuffer = (UINT8 *)AllocateZeroPool (BufferLen);\r
93e3992d 622 if (*GlyphBuffer == NULL) {\r
623 return EFI_OUT_OF_RESOURCES;\r
624 }\r
1436aea4 625\r
93e3992d 626 CopyMem (*GlyphBuffer, BufferIn, BufferLen);\r
627 }\r
628\r
629 if (GlyphBufferLen != NULL) {\r
630 *GlyphBufferLen = BufferLen;\r
631 }\r
632\r
633 return EFI_SUCCESS;\r
634}\r
635\r
93e3992d 636/**\r
637 Parse all glyph blocks to find a glyph block specified by CharValue.\r
638 If CharValue = (CHAR16) (-1), collect all default character cell information\r
639 within this font package and backup its information.\r
640\r
641 @param FontPackage Hii string package instance.\r
642 @param CharValue Unicode character value, which identifies a glyph\r
643 block.\r
644 @param GlyphBuffer Output the corresponding bitmap data of the found\r
4a429716 645 block. It is the caller's responsibility to free\r
93e3992d 646 this buffer.\r
647 @param Cell Output cell information of the encoded bitmap.\r
648 @param GlyphBufferLen If not NULL, output the length of GlyphBuffer.\r
649\r
650 @retval EFI_SUCCESS The bitmap data is retrieved successfully.\r
651 @retval EFI_NOT_FOUND The specified CharValue does not exist in current\r
652 database.\r
653 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
654 task.\r
655\r
656**/\r
657EFI_STATUS\r
658FindGlyphBlock (\r
1436aea4
MK
659 IN HII_FONT_PACKAGE_INSTANCE *FontPackage,\r
660 IN CHAR16 CharValue,\r
661 OUT UINT8 **GlyphBuffer OPTIONAL,\r
662 OUT EFI_HII_GLYPH_INFO *Cell OPTIONAL,\r
663 OUT UINTN *GlyphBufferLen OPTIONAL\r
93e3992d 664 )\r
665{\r
1436aea4
MK
666 EFI_STATUS Status;\r
667 UINT8 *BlockPtr;\r
668 UINT16 CharCurrent;\r
669 UINT16 Length16;\r
670 UINT32 Length32;\r
671 EFI_HII_GIBT_GLYPHS_BLOCK Glyphs;\r
672 UINTN BufferLen;\r
673 UINT16 Index;\r
674 EFI_HII_GLYPH_INFO DefaultCell;\r
675 EFI_HII_GLYPH_INFO LocalCell;\r
676 INT16 MinOffsetY;\r
677 UINT16 BaseLine;\r
93e3992d 678\r
679 ASSERT (FontPackage != NULL);\r
680 ASSERT (FontPackage->Signature == HII_FONT_PACKAGE_SIGNATURE);\r
1436aea4 681 BaseLine = 0;\r
f6cf5cf8 682 MinOffsetY = 0;\r
d1102dba 683\r
1436aea4 684 if (CharValue == (CHAR16)(-1)) {\r
93e3992d 685 //\r
686 // Collect the cell information specified in font package fixed header.\r
687 // Use CharValue =0 to represent this particular cell.\r
688 //\r
689 Status = NewCell (\r
690 0,\r
691 &FontPackage->GlyphInfoList,\r
1436aea4 692 (EFI_HII_GLYPH_INFO *)((UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32))\r
93e3992d 693 );\r
694 if (EFI_ERROR (Status)) {\r
695 return Status;\r
696 }\r
1436aea4 697\r
f6cf5cf8
LG
698 CopyMem (\r
699 &LocalCell,\r
1436aea4 700 (UINT8 *)FontPackage->FontPkgHdr + 3 * sizeof (UINT32),\r
f6cf5cf8
LG
701 sizeof (EFI_HII_GLYPH_INFO)\r
702 );\r
93e3992d 703 }\r
704\r
705 BlockPtr = FontPackage->GlyphBlock;\r
706 CharCurrent = 1;\r
707 BufferLen = 0;\r
708\r
709 while (*BlockPtr != EFI_HII_GIBT_END) {\r
710 switch (*BlockPtr) {\r
1436aea4
MK
711 case EFI_HII_GIBT_DEFAULTS:\r
712 //\r
713 // Collect all default character cell information specified by\r
714 // EFI_HII_GIBT_DEFAULTS.\r
715 //\r
716 if (CharValue == (CHAR16)(-1)) {\r
717 Status = NewCell (\r
718 CharCurrent,\r
719 &FontPackage->GlyphInfoList,\r
720 (EFI_HII_GLYPH_INFO *)(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))\r
721 );\r
722 if (EFI_ERROR (Status)) {\r
723 return Status;\r
724 }\r
725\r
726 CopyMem (\r
727 &LocalCell,\r
728 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
729 sizeof (EFI_HII_GLYPH_INFO)\r
730 );\r
731 if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {\r
732 BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);\r
733 }\r
734\r
735 if (MinOffsetY > LocalCell.OffsetY) {\r
736 MinOffsetY = LocalCell.OffsetY;\r
737 }\r
93e3992d 738 }\r
1436aea4
MK
739\r
740 BlockPtr += sizeof (EFI_HII_GIBT_DEFAULTS_BLOCK);\r
741 break;\r
742\r
743 case EFI_HII_GIBT_DUPLICATE:\r
744 if (CharCurrent == CharValue) {\r
745 CopyMem (&CharValue, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (CHAR16));\r
746 CharCurrent = 1;\r
747 BlockPtr = FontPackage->GlyphBlock;\r
748 continue;\r
749 }\r
750\r
751 CharCurrent++;\r
752 BlockPtr += sizeof (EFI_HII_GIBT_DUPLICATE_BLOCK);\r
753 break;\r
754\r
755 case EFI_HII_GIBT_EXT1:\r
756 BlockPtr += *(UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8));\r
757 break;\r
758 case EFI_HII_GIBT_EXT2:\r
759 CopyMem (\r
760 &Length16,\r
761 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
762 sizeof (UINT16)\r
763 );\r
764 BlockPtr += Length16;\r
765 break;\r
766 case EFI_HII_GIBT_EXT4:\r
767 CopyMem (\r
768 &Length32,\r
769 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK) + sizeof (UINT8)),\r
770 sizeof (UINT32)\r
771 );\r
772 BlockPtr += Length32;\r
773 break;\r
774\r
775 case EFI_HII_GIBT_GLYPH:\r
f6cf5cf8
LG
776 CopyMem (\r
777 &LocalCell,\r
778 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
779 sizeof (EFI_HII_GLYPH_INFO)\r
780 );\r
1436aea4
MK
781 if (CharValue == (CHAR16)(-1)) {\r
782 if (BaseLine < LocalCell.Height + LocalCell.OffsetY) {\r
783 BaseLine = (UINT16)(LocalCell.Height + LocalCell.OffsetY);\r
784 }\r
93e3992d 785\r
1436aea4
MK
786 if (MinOffsetY > LocalCell.OffsetY) {\r
787 MinOffsetY = LocalCell.OffsetY;\r
788 }\r
f6cf5cf8 789 }\r
f6cf5cf8 790\r
1436aea4
MK
791 BufferLen = BITMAP_LEN_1_BIT (LocalCell.Width, LocalCell.Height);\r
792 if (CharCurrent == CharValue) {\r
93e3992d 793 return WriteOutputParam (\r
1436aea4 794 (UINT8 *)((UINTN)BlockPtr + sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8)),\r
93e3992d 795 BufferLen,\r
1436aea4 796 &LocalCell,\r
93e3992d 797 GlyphBuffer,\r
798 Cell,\r
799 GlyphBufferLen\r
800 );\r
801 }\r
93e3992d 802\r
1436aea4
MK
803 CharCurrent++;\r
804 BlockPtr += sizeof (EFI_HII_GIBT_GLYPH_BLOCK) - sizeof (UINT8) + BufferLen;\r
805 break;\r
806\r
807 case EFI_HII_GIBT_GLYPHS:\r
808 BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK);\r
809 CopyMem (&Glyphs.Cell, BlockPtr, sizeof (EFI_HII_GLYPH_INFO));\r
810 BlockPtr += sizeof (EFI_HII_GLYPH_INFO);\r
811 CopyMem (&Glyphs.Count, BlockPtr, sizeof (UINT16));\r
812 BlockPtr += sizeof (UINT16);\r
813\r
814 if (CharValue == (CHAR16)(-1)) {\r
815 if (BaseLine < Glyphs.Cell.Height + Glyphs.Cell.OffsetY) {\r
816 BaseLine = (UINT16)(Glyphs.Cell.Height + Glyphs.Cell.OffsetY);\r
817 }\r
818\r
819 if (MinOffsetY > Glyphs.Cell.OffsetY) {\r
820 MinOffsetY = Glyphs.Cell.OffsetY;\r
821 }\r
8f88f023 822 }\r
1436aea4
MK
823\r
824 BufferLen = BITMAP_LEN_1_BIT (Glyphs.Cell.Width, Glyphs.Cell.Height);\r
825 for (Index = 0; Index < Glyphs.Count; Index++) {\r
826 if (CharCurrent + Index == CharValue) {\r
827 return WriteOutputParam (\r
828 BlockPtr,\r
829 BufferLen,\r
830 &Glyphs.Cell,\r
831 GlyphBuffer,\r
832 Cell,\r
833 GlyphBufferLen\r
834 );\r
835 }\r
836\r
837 BlockPtr += BufferLen;\r
8f88f023 838 }\r
93e3992d 839\r
1436aea4
MK
840 CharCurrent = (UINT16)(CharCurrent + Glyphs.Count);\r
841 break;\r
842\r
843 case EFI_HII_GIBT_GLYPH_DEFAULT:\r
844 Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
845 if (EFI_ERROR (Status)) {\r
846 return Status;\r
8f88f023 847 }\r
1436aea4
MK
848\r
849 if (CharValue == (CHAR16)(-1)) {\r
850 if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
851 BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);\r
852 }\r
853\r
854 if (MinOffsetY > DefaultCell.OffsetY) {\r
855 MinOffsetY = DefaultCell.OffsetY;\r
856 }\r
8f88f023 857 }\r
1436aea4
MK
858\r
859 BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
860\r
861 if (CharCurrent == CharValue) {\r
93e3992d 862 return WriteOutputParam (\r
1436aea4 863 BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK),\r
93e3992d 864 BufferLen,\r
865 &DefaultCell,\r
866 GlyphBuffer,\r
867 Cell,\r
868 GlyphBufferLen\r
869 );\r
870 }\r
93e3992d 871\r
1436aea4
MK
872 CharCurrent++;\r
873 BlockPtr += sizeof (EFI_HII_GLYPH_BLOCK) + BufferLen;\r
874 break;\r
875\r
876 case EFI_HII_GIBT_GLYPHS_DEFAULT:\r
877 CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
878 Status = GetCell (CharCurrent, &FontPackage->GlyphInfoList, &DefaultCell);\r
879 if (EFI_ERROR (Status)) {\r
880 return Status;\r
881 }\r
882\r
883 if (CharValue == (CHAR16)(-1)) {\r
884 if (BaseLine < DefaultCell.Height + DefaultCell.OffsetY) {\r
885 BaseLine = (UINT16)(DefaultCell.Height + DefaultCell.OffsetY);\r
886 }\r
887\r
888 if (MinOffsetY > DefaultCell.OffsetY) {\r
889 MinOffsetY = DefaultCell.OffsetY;\r
890 }\r
891 }\r
892\r
893 BufferLen = BITMAP_LEN_1_BIT (DefaultCell.Width, DefaultCell.Height);\r
894 BlockPtr += sizeof (EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK) - sizeof (UINT8);\r
895 for (Index = 0; Index < Length16; Index++) {\r
896 if (CharCurrent + Index == CharValue) {\r
897 return WriteOutputParam (\r
898 BlockPtr,\r
899 BufferLen,\r
900 &DefaultCell,\r
901 GlyphBuffer,\r
902 Cell,\r
903 GlyphBufferLen\r
904 );\r
905 }\r
906\r
907 BlockPtr += BufferLen;\r
908 }\r
909\r
910 CharCurrent = (UINT16)(CharCurrent + Length16);\r
911 break;\r
912\r
913 case EFI_HII_GIBT_SKIP1:\r
914 CharCurrent = (UINT16)(CharCurrent + (UINT16)(*(BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK))));\r
915 BlockPtr += sizeof (EFI_HII_GIBT_SKIP1_BLOCK);\r
916 break;\r
917 case EFI_HII_GIBT_SKIP2:\r
918 CopyMem (&Length16, BlockPtr + sizeof (EFI_HII_GLYPH_BLOCK), sizeof (UINT16));\r
919 CharCurrent = (UINT16)(CharCurrent + Length16);\r
920 BlockPtr += sizeof (EFI_HII_GIBT_SKIP2_BLOCK);\r
921 break;\r
922 default:\r
923 ASSERT (FALSE);\r
924 break;\r
93e3992d 925 }\r
926\r
927 if (CharValue < CharCurrent) {\r
928 return EFI_NOT_FOUND;\r
929 }\r
930 }\r
931\r
1436aea4 932 if (CharValue == (CHAR16)(-1)) {\r
f6cf5cf8 933 FontPackage->BaseLine = BaseLine;\r
1436aea4 934 FontPackage->Height = (UINT16)(BaseLine - MinOffsetY);\r
93e3992d 935 return EFI_SUCCESS;\r
936 }\r
937\r
938 return EFI_NOT_FOUND;\r
939}\r
940\r
93e3992d 941/**\r
942 Copy a Font Name to a new created EFI_FONT_INFO structure.\r
943\r
e90b081a 944 This is a internal function.\r
945\r
93e3992d 946 @param FontName NULL-terminated string.\r
947 @param FontInfo a new EFI_FONT_INFO which stores the FontName.\r
948 It's caller's responsibility to free this buffer.\r
949\r
950 @retval EFI_SUCCESS FontInfo is allocated and copied with FontName.\r
951 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
952 task.\r
953\r
954**/\r
93e3992d 955EFI_STATUS\r
956SaveFontName (\r
1436aea4
MK
957 IN EFI_STRING FontName,\r
958 OUT EFI_FONT_INFO **FontInfo\r
93e3992d 959 )\r
960{\r
1436aea4
MK
961 UINTN FontInfoLen;\r
962 UINTN NameSize;\r
93e3992d 963\r
964 ASSERT (FontName != NULL && FontInfo != NULL);\r
965\r
1436aea4 966 NameSize = StrSize (FontName);\r
5ad66ec6 967 FontInfoLen = sizeof (EFI_FONT_INFO) - sizeof (CHAR16) + NameSize;\r
1436aea4 968 *FontInfo = (EFI_FONT_INFO *)AllocateZeroPool (FontInfoLen);\r
93e3992d 969 if (*FontInfo == NULL) {\r
970 return EFI_OUT_OF_RESOURCES;\r
971 }\r
972\r
5ad66ec6 973 StrCpyS ((*FontInfo)->FontName, NameSize / sizeof (CHAR16), FontName);\r
93e3992d 974 return EFI_SUCCESS;\r
975}\r
976\r
93e3992d 977/**\r
978 Retrieve system default font and color.\r
979\r
980 @param Private HII database driver private data.\r
981 @param FontInfo Points to system default font output-related\r
982 information. It's caller's responsibility to free\r
983 this buffer.\r
984 @param FontInfoSize If not NULL, output the size of buffer FontInfo.\r
985\r
986 @retval EFI_SUCCESS Cell information is added to the GlyphInfoList.\r
987 @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the\r
988 task.\r
989 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
990\r
991**/\r
992EFI_STATUS\r
993GetSystemFont (\r
1436aea4
MK
994 IN HII_DATABASE_PRIVATE_DATA *Private,\r
995 OUT EFI_FONT_DISPLAY_INFO **FontInfo,\r
996 OUT UINTN *FontInfoSize OPTIONAL\r
93e3992d 997 )\r
998{\r
1436aea4
MK
999 EFI_FONT_DISPLAY_INFO *Info;\r
1000 UINTN InfoSize;\r
1001 UINTN NameSize;\r
93e3992d 1002\r
1436aea4 1003 if ((Private == NULL) || (Private->Signature != HII_DATABASE_PRIVATE_DATA_SIGNATURE)) {\r
93e3992d 1004 return EFI_INVALID_PARAMETER;\r
1005 }\r
1436aea4 1006\r
93e3992d 1007 if (FontInfo == NULL) {\r
1008 return EFI_INVALID_PARAMETER;\r
1009 }\r
1010\r
1011 //\r
1012 // The standard font always has the name "sysdefault".\r
1013 //\r
5ad66ec6
DB
1014 NameSize = StrSize (L"sysdefault");\r
1015 InfoSize = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
1436aea4 1016 Info = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (InfoSize);\r
93e3992d 1017 if (Info == NULL) {\r
1018 return EFI_OUT_OF_RESOURCES;\r
1019 }\r
1020\r
1436aea4 1021 Info->ForegroundColor = mHiiEfiColors[Private->Attribute & 0x0f];\r
df50c2fc 1022 ASSERT ((Private->Attribute >> 4) < 8);\r
f618b2fa 1023 Info->BackgroundColor = mHiiEfiColors[Private->Attribute >> 4];\r
93e3992d 1024 Info->FontInfoMask = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;\r
1025 Info->FontInfo.FontStyle = 0;\r
1026 Info->FontInfo.FontSize = EFI_GLYPH_HEIGHT;\r
5ad66ec6 1027 StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");\r
93e3992d 1028\r
1029 *FontInfo = Info;\r
1030 if (FontInfoSize != NULL) {\r
1031 *FontInfoSize = InfoSize;\r
1032 }\r
1436aea4 1033\r
93e3992d 1034 return EFI_SUCCESS;\r
1035}\r
1036\r
93e3992d 1037/**\r
813acf3a 1038 Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or\r
1039 returns the system default according to the optional inputs.\r
93e3992d 1040\r
e90b081a 1041 This is a internal function.\r
1042\r
93e3992d 1043 @param Private HII database driver private data.\r
1044 @param StringInfo Points to the string output information,\r
1045 including the color and font.\r
813acf3a 1046 @param SystemInfo If not NULL, points to system default font and color.\r
1047\r
93e3992d 1048 @param SystemInfoLen If not NULL, output the length of default system\r
1049 info.\r
1050\r
1051 @retval TRUE Yes, it points to system default.\r
1052 @retval FALSE No.\r
1053\r
1054**/\r
93e3992d 1055BOOLEAN\r
1056IsSystemFontInfo (\r
1436aea4
MK
1057 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1058 IN EFI_FONT_DISPLAY_INFO *StringInfo,\r
1059 OUT EFI_FONT_DISPLAY_INFO **SystemInfo OPTIONAL,\r
1060 OUT UINTN *SystemInfoLen OPTIONAL\r
93e3992d 1061 )\r
1062{\r
1436aea4
MK
1063 EFI_STATUS Status;\r
1064 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
1065 UINTN DefaultLen;\r
1066 BOOLEAN Flag;\r
93e3992d 1067\r
1068 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
1069\r
1436aea4 1070 if ((StringInfo == NULL) && (SystemInfo == NULL)) {\r
93e3992d 1071 return TRUE;\r
1072 }\r
1073\r
523f48e7
ED
1074 SystemDefault = NULL;\r
1075 DefaultLen = 0;\r
1076\r
93e3992d 1077 Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
1078 ASSERT_EFI_ERROR (Status);\r
523f48e7 1079 ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));\r
93e3992d 1080\r
813acf3a 1081 //\r
1082 // Record the system default info.\r
1083 //\r
93e3992d 1084 if (SystemInfo != NULL) {\r
1085 *SystemInfo = SystemDefault;\r
93e3992d 1086 }\r
1087\r
1088 if (SystemInfoLen != NULL) {\r
1089 *SystemInfoLen = DefaultLen;\r
1090 }\r
1091\r
813acf3a 1092 if (StringInfo == NULL) {\r
93e3992d 1093 return TRUE;\r
1094 }\r
1095\r
813acf3a 1096 Flag = FALSE;\r
1097 //\r
1098 // Check the FontInfoMask to see whether it is retrieving system info.\r
1099 //\r
1100 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {\r
1101 if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {\r
1102 goto Exit;\r
1103 }\r
1104 }\r
1436aea4 1105\r
813acf3a 1106 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {\r
1107 if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {\r
1108 goto Exit;\r
1109 }\r
1110 }\r
1436aea4 1111\r
813acf3a 1112 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {\r
1113 if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {\r
1114 goto Exit;\r
1115 }\r
1116 }\r
1436aea4 1117\r
813acf3a 1118 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {\r
1119 if (CompareMem (\r
d1102dba
LG
1120 &StringInfo->ForegroundColor,\r
1121 &SystemDefault->ForegroundColor,\r
813acf3a 1122 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1436aea4
MK
1123 ) != 0)\r
1124 {\r
813acf3a 1125 goto Exit;\r
1126 }\r
1127 }\r
1436aea4 1128\r
813acf3a 1129 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {\r
1130 if (CompareMem (\r
d1102dba
LG
1131 &StringInfo->BackgroundColor,\r
1132 &SystemDefault->BackgroundColor,\r
813acf3a 1133 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1436aea4
MK
1134 ) != 0)\r
1135 {\r
813acf3a 1136 goto Exit;\r
1137 }\r
1138 }\r
1139\r
1140 Flag = TRUE;\r
1141\r
1142Exit:\r
1143 if (SystemInfo == NULL) {\r
676df92c 1144 if (SystemDefault != NULL) {\r
1145 FreePool (SystemDefault);\r
1146 }\r
813acf3a 1147 }\r
1436aea4 1148\r
813acf3a 1149 return Flag;\r
93e3992d 1150}\r
1151\r
93e3992d 1152/**\r
1153 This function checks whether EFI_FONT_INFO exists in current database. If\r
1154 FontInfoMask is specified, check what options can be used to make a match.\r
1155 Note that the masks relate to where the system default should be supplied\r
1156 are ignored by this function.\r
1157\r
1158 @param Private Hii database private structure.\r
1159 @param FontInfo Points to EFI_FONT_INFO structure.\r
1160 @param FontInfoMask If not NULL, describes what options can be used\r
1161 to make a match between the font requested and\r
1162 the font available. The caller must guarantee\r
1163 this mask is valid.\r
1164 @param FontHandle On entry, Points to the font handle returned by a\r
1165 previous call to GetFontInfo() or NULL to start\r
1166 with the first font.\r
4a429716 1167 @param GlobalFontInfo If not NULL, output the corresponding global font\r
93e3992d 1168 info.\r
1169\r
1170 @retval TRUE Existed\r
1171 @retval FALSE Not existed\r
1172\r
1173**/\r
1174BOOLEAN\r
1175IsFontInfoExisted (\r
1436aea4
MK
1176 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1177 IN EFI_FONT_INFO *FontInfo,\r
1178 IN EFI_FONT_INFO_MASK *FontInfoMask OPTIONAL,\r
1179 IN EFI_FONT_HANDLE FontHandle OPTIONAL,\r
1180 OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL\r
93e3992d 1181 )\r
1182{\r
1436aea4
MK
1183 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1184 HII_GLOBAL_FONT_INFO *GlobalFontBackup1;\r
1185 HII_GLOBAL_FONT_INFO *GlobalFontBackup2;\r
1186 LIST_ENTRY *Link;\r
1187 EFI_FONT_INFO_MASK Mask;\r
1188 BOOLEAN Matched;\r
1189 BOOLEAN VagueMatched1;\r
1190 BOOLEAN VagueMatched2;\r
93e3992d 1191\r
1192 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
1193 ASSERT (FontInfo != NULL);\r
1194\r
1195 //\r
4a429716 1196 // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE\r
93e3992d 1197 // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.\r
1198 //\r
1436aea4
MK
1199 Matched = FALSE;\r
1200 VagueMatched1 = FALSE;\r
1201 VagueMatched2 = FALSE;\r
93e3992d 1202\r
1203 Mask = 0;\r
1204 GlobalFontBackup1 = NULL;\r
1205 GlobalFontBackup2 = NULL;\r
1206\r
1207 // The process of where the system default should be supplied instead of\r
1208 // the specified font info beyonds this function's scope.\r
1209 //\r
1210 if (FontInfoMask != NULL) {\r
1211 Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);\r
1212 }\r
1213\r
1214 //\r
1215 // If not NULL, FontHandle points to the next node of the last searched font\r
1216 // node by previous call.\r
1217 //\r
1218 if (FontHandle == NULL) {\r
1219 Link = Private->FontInfoList.ForwardLink;\r
1220 } else {\r
1436aea4 1221 Link = (LIST_ENTRY *)FontHandle;\r
93e3992d 1222 }\r
1223\r
1436aea4 1224 for ( ; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
93e3992d 1225 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1226 if (FontInfoMask == NULL) {\r
1227 if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {\r
1228 if (GlobalFontInfo != NULL) {\r
1229 *GlobalFontInfo = GlobalFont;\r
1230 }\r
1436aea4 1231\r
93e3992d 1232 return TRUE;\r
1233 }\r
1234 } else {\r
1235 //\r
1236 // Check which options could be used to make a match.\r
1237 //\r
1238 switch (Mask) {\r
1436aea4
MK
1239 case EFI_FONT_INFO_ANY_FONT:\r
1240 if ((GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) &&\r
1241 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))\r
1242 {\r
1243 Matched = TRUE;\r
1244 }\r
1245\r
1246 break;\r
1247 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:\r
1248 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1249 Matched = TRUE;\r
1250 }\r
1251\r
1252 break;\r
1253 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:\r
93e3992d 1254 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1436aea4 1255 Matched = TRUE;\r
93e3992d 1256 }\r
1436aea4
MK
1257\r
1258 break;\r
1259 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:\r
1260 Matched = TRUE;\r
1261 break;\r
1262 //\r
1263 // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to\r
1264 // remove some of the specified styles to meet the style requested.\r
1265 //\r
1266 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:\r
1267 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1268 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1269 Matched = TRUE;\r
1270 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1271 VagueMatched1 = TRUE;\r
1272 GlobalFontBackup1 = GlobalFont;\r
1273 }\r
93e3992d 1274 }\r
1436aea4
MK
1275\r
1276 break;\r
1277 //\r
1278 // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to\r
1279 // stretch or shrink a font to meet the size requested.\r
1280 //\r
1281 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:\r
1282 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1283 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1284 Matched = TRUE;\r
1285 } else {\r
1286 VagueMatched1 = TRUE;\r
1287 GlobalFontBackup1 = GlobalFont;\r
1288 }\r
93e3992d 1289 }\r
1436aea4
MK
1290\r
1291 break;\r
1292 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:\r
1293 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1294 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1295 Matched = TRUE;\r
1296 } else {\r
1297 VagueMatched1 = TRUE;\r
1298 GlobalFontBackup1 = GlobalFont;\r
1299 }\r
1300 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1301 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1302 VagueMatched1 = TRUE;\r
1303 GlobalFontBackup1 = GlobalFont;\r
1304 } else {\r
1305 VagueMatched2 = TRUE;\r
1306 GlobalFontBackup2 = GlobalFont;\r
1307 }\r
93e3992d 1308 }\r
1436aea4
MK
1309\r
1310 break;\r
1311 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
93e3992d 1312 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1436aea4 1313 Matched = TRUE;\r
93e3992d 1314 } else {\r
1315 VagueMatched1 = TRUE;\r
1316 GlobalFontBackup1 = GlobalFont;\r
1317 }\r
1436aea4
MK
1318\r
1319 break;\r
1320 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
93e3992d 1321 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1436aea4 1322 Matched = TRUE;\r
93e3992d 1323 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1324 VagueMatched1 = TRUE;\r
1325 GlobalFontBackup1 = GlobalFont;\r
1326 }\r
93e3992d 1327\r
1436aea4
MK
1328 break;\r
1329 case EFI_FONT_INFO_ANY_STYLE:\r
1330 if ((CompareMem (\r
1331 GlobalFont->FontInfo->FontName,\r
1332 FontInfo->FontName,\r
1333 StrSize (FontInfo->FontName)\r
1334 ) == 0) &&\r
1335 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))\r
1336 {\r
1337 Matched = TRUE;\r
93e3992d 1338 }\r
93e3992d 1339\r
1436aea4
MK
1340 break;\r
1341 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:\r
1342 if (CompareMem (\r
1343 GlobalFont->FontInfo->FontName,\r
1344 FontInfo->FontName,\r
1345 StrSize (FontInfo->FontName)\r
1346 ) == 0)\r
1347 {\r
1348 Matched = TRUE;\r
93e3992d 1349 }\r
1436aea4
MK
1350\r
1351 break;\r
1352 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
1353 if (CompareMem (\r
1354 GlobalFont->FontInfo->FontName,\r
1355 FontInfo->FontName,\r
1356 StrSize (FontInfo->FontName)\r
1357 ) == 0)\r
1358 {\r
93e3992d 1359 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1436aea4 1360 Matched = TRUE;\r
93e3992d 1361 } else {\r
1362 VagueMatched1 = TRUE;\r
1363 GlobalFontBackup1 = GlobalFont;\r
1364 }\r
1436aea4
MK
1365 }\r
1366\r
1367 break;\r
1368 case EFI_FONT_INFO_ANY_SIZE:\r
1369 if ((CompareMem (\r
1370 GlobalFont->FontInfo->FontName,\r
1371 FontInfo->FontName,\r
1372 StrSize (FontInfo->FontName)\r
1373 ) == 0) &&\r
1374 (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))\r
1375 {\r
1376 Matched = TRUE;\r
1377 }\r
1378\r
1379 break;\r
1380 case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
1381 if (CompareMem (\r
1382 GlobalFont->FontInfo->FontName,\r
1383 FontInfo->FontName,\r
1384 StrSize (FontInfo->FontName)\r
1385 ) == 0)\r
1386 {\r
1387 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1388 Matched = TRUE;\r
1389 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
93e3992d 1390 VagueMatched1 = TRUE;\r
1391 GlobalFontBackup1 = GlobalFont;\r
1436aea4
MK
1392 }\r
1393 }\r
1394\r
1395 break;\r
1396 case EFI_FONT_INFO_RESTYLE:\r
1397 if ((CompareMem (\r
1398 GlobalFont->FontInfo->FontName,\r
1399 FontInfo->FontName,\r
1400 StrSize (FontInfo->FontName)\r
1401 ) == 0) &&\r
1402 (GlobalFont->FontInfo->FontSize == FontInfo->FontSize))\r
1403 {\r
1404 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1405 Matched = TRUE;\r
1406 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1407 VagueMatched1 = TRUE;\r
1408 GlobalFontBackup1 = GlobalFont;\r
1409 }\r
1410 }\r
1411\r
1412 break;\r
1413 case EFI_FONT_INFO_RESIZE:\r
1414 if ((CompareMem (\r
1415 GlobalFont->FontInfo->FontName,\r
1416 FontInfo->FontName,\r
1417 StrSize (FontInfo->FontName)\r
1418 ) == 0) &&\r
1419 (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle))\r
1420 {\r
1421 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1422 Matched = TRUE;\r
93e3992d 1423 } else {\r
1436aea4
MK
1424 VagueMatched1 = TRUE;\r
1425 GlobalFontBackup1 = GlobalFont;\r
93e3992d 1426 }\r
1427 }\r
1436aea4
MK
1428\r
1429 break;\r
1430 case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:\r
1431 if (CompareMem (\r
1432 GlobalFont->FontInfo->FontName,\r
1433 FontInfo->FontName,\r
1434 StrSize (FontInfo->FontName)\r
1435 ) == 0)\r
1436 {\r
1437 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1438 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1439 Matched = TRUE;\r
1440 } else {\r
1441 VagueMatched1 = TRUE;\r
1442 GlobalFontBackup1 = GlobalFont;\r
1443 }\r
1444 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1445 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1446 VagueMatched1 = TRUE;\r
1447 GlobalFontBackup1 = GlobalFont;\r
1448 } else {\r
1449 VagueMatched2 = TRUE;\r
1450 GlobalFontBackup2 = GlobalFont;\r
1451 }\r
1452 }\r
1453 }\r
1454\r
1455 break;\r
1456 default:\r
1457 break;\r
93e3992d 1458 }\r
1459\r
1460 if (Matched) {\r
1461 if (GlobalFontInfo != NULL) {\r
1462 *GlobalFontInfo = GlobalFont;\r
1463 }\r
1436aea4 1464\r
93e3992d 1465 return TRUE;\r
1466 }\r
1467 }\r
1468 }\r
1469\r
1470 if (VagueMatched1) {\r
1471 if (GlobalFontInfo != NULL) {\r
1472 *GlobalFontInfo = GlobalFontBackup1;\r
1473 }\r
1436aea4 1474\r
93e3992d 1475 return TRUE;\r
1476 } else if (VagueMatched2) {\r
1477 if (GlobalFontInfo != NULL) {\r
1478 *GlobalFontInfo = GlobalFontBackup2;\r
1479 }\r
1436aea4 1480\r
93e3992d 1481 return TRUE;\r
1482 }\r
1483\r
1484 return FALSE;\r
1485}\r
1486\r
93e3992d 1487/**\r
1488 Check whether the unicode represents a line break or not.\r
1489\r
4772ce75 1490 This is a internal function. Please see Section 27.2.6 of the UEFI Specification\r
1491 for a description of the supported string format.\r
e90b081a 1492\r
93e3992d 1493 @param Char Unicode character\r
1494\r
4772ce75 1495 @retval 0 Yes, it forces a line break.\r
1496 @retval 1 Yes, it presents a line break opportunity\r
1497 @retval 2 Yes, it requires a line break happen before and after it.\r
93e3992d 1498 @retval -1 No, it is not a link break.\r
1499\r
1500**/\r
93e3992d 1501INT8\r
1502IsLineBreak (\r
1436aea4 1503 IN CHAR16 Char\r
93e3992d 1504 )\r
1505{\r
93e3992d 1506 switch (Char) {\r
4772ce75 1507 //\r
1508 // Mandatory line break characters, which force a line-break\r
1509 //\r
2d9cdfd8 1510 case 0x000A:\r
4772ce75 1511 case 0x000C:\r
1512 case 0x000D:\r
1513 case 0x2028:\r
1514 case 0x2029:\r
93e3992d 1515 return 0;\r
4772ce75 1516 //\r
1517 // Space characters, which is taken as a line-break opportunity\r
1518 //\r
1519 case 0x0020:\r
1520 case 0x1680:\r
1521 case 0x2000:\r
1522 case 0x2001:\r
1523 case 0x2002:\r
1524 case 0x2003:\r
1525 case 0x2004:\r
1526 case 0x2005:\r
1527 case 0x2006:\r
1528 case 0x2008:\r
1529 case 0x2009:\r
1530 case 0x200A:\r
1531 case 0x205F:\r
1532 //\r
1533 // In-Word Break Opportunities\r
1534 //\r
1535 case 0x200B:\r
1536 return 1;\r
1537 //\r
1538 // A space which is not a line-break opportunity\r
1539 //\r
1540 case 0x00A0:\r
1541 case 0x202F:\r
1542 //\r
1543 // A hyphen which is not a line-break opportunity\r
1544 //\r
1545 case 0x2011:\r
1546 return -1;\r
1547 //\r
1548 // Hyphen characters which describe line break opportunities after the character\r
1549 //\r
93e3992d 1550 case 0x058A:\r
4772ce75 1551 case 0x2010:\r
1552 case 0x2012:\r
1553 case 0x2013:\r
93e3992d 1554 case 0x0F0B:\r
1555 case 0x1361:\r
1556 case 0x17D5:\r
1557 return 1;\r
4772ce75 1558 //\r
1559 // A hyphen which describes line break opportunities before and after them, but not between a pair of them\r
1560 //\r
1561 case 0x2014:\r
1562 return 2;\r
93e3992d 1563 }\r
1436aea4 1564\r
93e3992d 1565 return -1;\r
1566}\r
1567\r
93e3992d 1568/**\r
1569 Renders a string to a bitmap or to the display.\r
1570\r
1571 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
1572 @param Flags Describes how the string is to be drawn.\r
1573 @param String Points to the null-terminated string to be\r
1574 displayed.\r
1575 @param StringInfo Points to the string output information,\r
1576 including the color and font. If NULL, then the\r
1577 string will be output in the default system font\r
1578 and color.\r
1579 @param Blt If this points to a non-NULL on entry, this\r
1580 points to the image, which is Width pixels wide\r
1581 and Height pixels high. The string will be drawn\r
1582 onto this image and\r
1583 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
1584 to a NULL on entry, then a buffer\r
1585 will be allocated to hold the generated image and\r
ac644614 1586 the pointer updated on exit. It is the caller's\r
93e3992d 1587 responsibility to free this buffer.\r
e90b081a 1588 @param BltX Specifies the offset from the left and top edge\r
1589 of the image of the first character cell in the\r
1590 image.\r
1591 @param BltY Specifies the offset from the left and top edge\r
93e3992d 1592 of the image of the first character cell in the\r
1593 image.\r
1594 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
1595 will point to an allocated buffer containing\r
1596 row information and RowInfoArraySize will be\r
1597 updated to contain the number of elements.\r
1598 This array describes the characters which were at\r
1599 least partially drawn and the heights of the\r
ac644614 1600 rows. It is the caller's responsibility to free\r
93e3992d 1601 this buffer.\r
1602 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
1603 contains the number of elements in RowInfoArray.\r
1604 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
1605 filled with the horizontal offset for each\r
1606 character in the string on the row where it is\r
1607 displayed. Non-printing characters will have\r
1608 the offset ~0. The caller is responsible to\r
1609 allocate a buffer large enough so that there\r
1610 is one entry for each character in the string,\r
1611 not including the null-terminator. It is possible\r
1612 when character display is normalized that some\r
1613 character cells overlap.\r
1614\r
1615 @retval EFI_SUCCESS The string was successfully rendered.\r
1616 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
1617 RowInfoArray or Blt.\r
1618 @retval EFI_INVALID_PARAMETER The String or Blt was NULL.\r
813acf3a 1619 @retval EFI_INVALID_PARAMETER Flags were invalid combination..\r
93e3992d 1620\r
1621**/\r
1622EFI_STATUS\r
1623EFIAPI\r
1624HiiStringToImage (\r
1436aea4
MK
1625 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
1626 IN EFI_HII_OUT_FLAGS Flags,\r
1627 IN CONST EFI_STRING String,\r
1628 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
1629 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
1630 IN UINTN BltX,\r
1631 IN UINTN BltY,\r
1632 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
1633 OUT UINTN *RowInfoArraySize OPTIONAL,\r
1634 OUT UINTN *ColumnInfoArray OPTIONAL\r
93e3992d 1635 )\r
1636{\r
1436aea4
MK
1637 EFI_STATUS Status;\r
1638 HII_DATABASE_PRIVATE_DATA *Private;\r
1639 UINT8 **GlyphBuf;\r
1640 EFI_HII_GLYPH_INFO *Cell;\r
1641 UINT8 *Attributes;\r
1642 EFI_IMAGE_OUTPUT *Image;\r
1643 EFI_STRING StringPtr;\r
1644 EFI_STRING StringTmp;\r
1645 EFI_HII_ROW_INFO *RowInfo;\r
1646 UINTN LineWidth;\r
1647 UINTN LineHeight;\r
1648 UINTN LineOffset;\r
1649 UINTN LastLineHeight;\r
1650 UINTN BaseLineOffset;\r
1651 UINT16 MaxRowNum;\r
1652 UINT16 RowIndex;\r
1653 UINTN Index;\r
1654 UINTN NextIndex;\r
1655 UINTN Index1;\r
1656 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
1657 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
1658 EFI_FONT_HANDLE FontHandle;\r
1659 EFI_STRING StringIn;\r
1660 EFI_STRING StringIn2;\r
1661 UINT16 Height;\r
1662 UINT16 BaseLine;\r
1663 EFI_FONT_INFO *FontInfo;\r
1664 BOOLEAN SysFontFlag;\r
1665 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1666 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1667 BOOLEAN Transparent;\r
1668 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
1669 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;\r
1670 UINTN RowInfoSize;\r
1671 BOOLEAN LineBreak;\r
1672 UINTN StrLength;\r
1673 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *RowBufferPtr;\r
1674 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1675 UINT32 PreInitBkgnd;\r
93e3992d 1676\r
1677 //\r
1678 // Check incoming parameters.\r
1679 //\r
1680\r
1436aea4 1681 if ((This == NULL) || (String == NULL) || (Blt == NULL)) {\r
93e3992d 1682 return EFI_INVALID_PARAMETER;\r
1683 }\r
1436aea4 1684\r
93e3992d 1685 if (*Blt == NULL) {\r
1686 //\r
1687 // These two flag cannot be used if Blt is NULL upon entry.\r
1688 //\r
1689 if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {\r
1690 return EFI_INVALID_PARAMETER;\r
1691 }\r
1436aea4 1692\r
93e3992d 1693 if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {\r
1694 return EFI_INVALID_PARAMETER;\r
1695 }\r
1696 }\r
1436aea4 1697\r
93e3992d 1698 //\r
1699 // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.\r
1700 //\r
813acf3a 1701 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {\r
93e3992d 1702 return EFI_INVALID_PARAMETER;\r
1703 }\r
1436aea4 1704\r
813acf3a 1705 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
93e3992d 1706 return EFI_INVALID_PARAMETER;\r
1707 }\r
1436aea4 1708\r
93e3992d 1709 //\r
1710 // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\r
1711 //\r
813acf3a 1712 if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) {\r
93e3992d 1713 return EFI_INVALID_PARAMETER;\r
1714 }\r
1715\r
4772ce75 1716 if (*Blt == NULL) {\r
1717 //\r
1718 // Create a new bitmap and draw the string onto this image.\r
1719 //\r
1720 Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1721 if (Image == NULL) {\r
1722 return EFI_OUT_OF_RESOURCES;\r
1723 }\r
1436aea4
MK
1724\r
1725 Image->Width = 800;\r
1726 Image->Height = 600;\r
4772ce75 1727 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1728 if (Image->Image.Bitmap == NULL) {\r
1729 FreePool (Image);\r
1730 return EFI_OUT_OF_RESOURCES;\r
1731 }\r
1732\r
1733 //\r
1734 // Other flags are not permitted when Blt is NULL.\r
1735 //\r
1736 Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
1436aea4 1737 *Blt = Image;\r
4772ce75 1738 }\r
1739\r
1436aea4
MK
1740 StrLength = StrLen (String);\r
1741 GlyphBuf = (UINT8 **)AllocateZeroPool (StrLength * sizeof (UINT8 *));\r
93e3992d 1742 ASSERT (GlyphBuf != NULL);\r
1436aea4 1743 Cell = (EFI_HII_GLYPH_INFO *)AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));\r
93e3992d 1744 ASSERT (Cell != NULL);\r
1436aea4 1745 Attributes = (UINT8 *)AllocateZeroPool (StrLength * sizeof (UINT8));\r
93e3992d 1746 ASSERT (Attributes != NULL);\r
1747\r
1748 RowInfo = NULL;\r
1749 Status = EFI_SUCCESS;\r
1750 StringIn2 = NULL;\r
1751 SystemDefault = NULL;\r
96ff65a1 1752 StringIn = NULL;\r
93e3992d 1753\r
1754 //\r
1755 // Calculate the string output information, including specified color and font .\r
1756 // If StringInfo does not points to system font info, it must indicate an existing\r
1757 // EFI_FONT_INFO.\r
1758 //\r
1759 StringInfoOut = NULL;\r
1760 FontHandle = NULL;\r
1761 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1436aea4 1762 SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);\r
93e3992d 1763\r
1764 if (SysFontFlag) {\r
523f48e7 1765 ASSERT (SystemDefault != NULL);\r
93e3992d 1766 FontInfo = NULL;\r
1767 Height = SystemDefault->FontInfo.FontSize;\r
f6cf5cf8 1768 BaseLine = SystemDefault->FontInfo.FontSize;\r
93e3992d 1769 Foreground = SystemDefault->ForegroundColor;\r
1770 Background = SystemDefault->BackgroundColor;\r
93e3992d 1771 } else {\r
7b06dc8a 1772 //\r
1773 // StringInfo must not be NULL if it is not system info.\r
1774 //\r
1775 ASSERT (StringInfo != NULL);\r
1436aea4 1776 Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);\r
93e3992d 1777 if (Status == EFI_NOT_FOUND) {\r
1778 //\r
1779 // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.\r
1780 // Use the system font instead. Still use the color specified by StringInfo.\r
1781 //\r
1782 SysFontFlag = TRUE;\r
1783 FontInfo = NULL;\r
1784 Height = SystemDefault->FontInfo.FontSize;\r
f6cf5cf8 1785 BaseLine = SystemDefault->FontInfo.FontSize;\r
1436aea4
MK
1786 Foreground = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;\r
1787 Background = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;\r
96ff65a1 1788 } else if (Status == EFI_SUCCESS) {\r
1436aea4 1789 FontInfo = &StringInfoOut->FontInfo;\r
f6cf5cf8
LG
1790 IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);\r
1791 Height = GlobalFont->FontPackage->Height;\r
1792 BaseLine = GlobalFont->FontPackage->BaseLine;\r
93e3992d 1793 Foreground = StringInfoOut->ForegroundColor;\r
1794 Background = StringInfoOut->BackgroundColor;\r
96ff65a1 1795 } else {\r
1796 goto Exit;\r
93e3992d 1797 }\r
1798 }\r
d1102dba 1799\r
f6cf5cf8 1800 //\r
4a429716
RN
1801 // Use the maximum height of font as the base line.\r
1802 // And, use the maximum height as line height.\r
f6cf5cf8
LG
1803 //\r
1804 LineHeight = Height;\r
1805 LastLineHeight = Height;\r
1806 BaseLineOffset = Height - BaseLine;\r
d1102dba 1807\r
93e3992d 1808 //\r
1809 // Parse the string to be displayed to drop some ignored characters.\r
1810 //\r
1811\r
1812 StringPtr = String;\r
93e3992d 1813\r
1814 //\r
1815 // Ignore line-break characters only. Hyphens or dash character will be displayed\r
1816 // without line-break opportunity.\r
1817 //\r
1818 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {\r
1819 StringIn = AllocateZeroPool (StrSize (StringPtr));\r
1820 if (StringIn == NULL) {\r
1821 Status = EFI_OUT_OF_RESOURCES;\r
1822 goto Exit;\r
1823 }\r
1436aea4 1824\r
93e3992d 1825 StringTmp = StringIn;\r
1826 while (*StringPtr != 0) {\r
1827 if (IsLineBreak (*StringPtr) == 0) {\r
1828 StringPtr++;\r
1829 } else {\r
1830 *StringTmp++ = *StringPtr++;\r
1831 }\r
1832 }\r
1436aea4 1833\r
93e3992d 1834 *StringTmp = 0;\r
1835 StringPtr = StringIn;\r
1836 }\r
1436aea4 1837\r
93e3992d 1838 //\r
1839 // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs\r
4a429716 1840 // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.\r
93e3992d 1841 //\r
1436aea4 1842 StringIn2 = AllocateZeroPool (StrSize (StringPtr));\r
93e3992d 1843 if (StringIn2 == NULL) {\r
1844 Status = EFI_OUT_OF_RESOURCES;\r
1845 goto Exit;\r
1846 }\r
1436aea4 1847\r
93e3992d 1848 Index = 0;\r
1849 StringTmp = StringIn2;\r
1436aea4 1850 StrLength = StrLen (StringPtr);\r
4772ce75 1851 while (*StringPtr != 0 && Index < StrLength) {\r
f6cf5cf8
LG
1852 if (IsLineBreak (*StringPtr) == 0) {\r
1853 *StringTmp++ = *StringPtr++;\r
1854 Index++;\r
1855 continue;\r
1856 }\r
d1102dba 1857\r
93e3992d 1858 Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
1859 if (Status == EFI_NOT_FOUND) {\r
1860 if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
93e3992d 1861 GlyphBuf[Index] = NULL;\r
f6cf5cf8
LG
1862 ZeroMem (&Cell[Index], sizeof (Cell[Index]));\r
1863 Status = EFI_SUCCESS;\r
93e3992d 1864 } else {\r
1865 //\r
1866 // Unicode 0xFFFD must exist in current hii database if this flag is not set.\r
1867 //\r
1868 Status = GetGlyphBuffer (\r
1869 Private,\r
1870 REPLACE_UNKNOWN_GLYPH,\r
1871 FontInfo,\r
1872 &GlyphBuf[Index],\r
1873 &Cell[Index],\r
1874 &Attributes[Index]\r
1875 );\r
1876 if (EFI_ERROR (Status)) {\r
1877 Status = EFI_INVALID_PARAMETER;\r
93e3992d 1878 }\r
93e3992d 1879 }\r
f6cf5cf8
LG
1880 }\r
1881\r
1882 if (EFI_ERROR (Status)) {\r
93e3992d 1883 goto Exit;\r
93e3992d 1884 }\r
f6cf5cf8
LG
1885\r
1886 *StringTmp++ = *StringPtr++;\r
1887 Index++;\r
93e3992d 1888 }\r
1436aea4 1889\r
93e3992d 1890 *StringTmp = 0;\r
1891 StringPtr = StringIn2;\r
1892\r
1893 //\r
1894 // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.\r
1895 // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string\r
1896 // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
1897 // Otherwise render this string to a new allocated image and output it.\r
1898 //\r
4772ce75 1899 Image = *Blt;\r
1900 BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
5cfe4234
LG
1901 if (Image->Height < BltY) {\r
1902 //\r
1903 // the top edge of the image should be in Image resolution scope.\r
1904 //\r
1905 Status = EFI_INVALID_PARAMETER;\r
1906 goto Exit;\r
1907 }\r
1436aea4
MK
1908\r
1909 MaxRowNum = (UINT16)((Image->Height - BltY) / Height);\r
f6cf5cf8
LG
1910 if ((Image->Height - BltY) % Height != 0) {\r
1911 LastLineHeight = (Image->Height - BltY) % Height;\r
4772ce75 1912 MaxRowNum++;\r
1913 }\r
93e3992d 1914\r
1436aea4 1915 RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));\r
4772ce75 1916 if (RowInfo == NULL) {\r
1917 Status = EFI_OUT_OF_RESOURCES;\r
1918 goto Exit;\r
1919 }\r
1920\r
1921 //\r
1922 // Format the glyph buffer according to flags.\r
1923 //\r
1436aea4 1924 Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
4772ce75 1925\r
1926 for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
1436aea4
MK
1927 LineWidth = 0;\r
1928 LineBreak = FALSE;\r
93e3992d 1929\r
f6cf5cf8
LG
1930 //\r
1931 // Clip the final row if the row's bottom-most on pixel cannot fit when\r
1932 // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
1933 //\r
1934 if (RowIndex == MaxRowNum - 1) {\r
1436aea4 1935 if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {\r
f6cf5cf8
LG
1936 //\r
1937 // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
1938 //\r
1939 break;\r
1940 }\r
1436aea4 1941\r
f6cf5cf8
LG
1942 LineHeight = LastLineHeight;\r
1943 }\r
1944\r
93e3992d 1945 //\r
4772ce75 1946 // Calculate how many characters there are in a row.\r
93e3992d 1947 //\r
4772ce75 1948 RowInfo[RowIndex].StartIndex = Index;\r
93e3992d 1949\r
4772ce75 1950 while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
1436aea4
MK
1951 if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&\r
1952 (IsLineBreak (StringPtr[Index]) == 0))\r
1953 {\r
4772ce75 1954 //\r
1955 // It forces a line break that ends this row.\r
1956 //\r
1957 Index++;\r
35c218d7 1958 LineBreak = TRUE;\r
4772ce75 1959 break;\r
93e3992d 1960 }\r
93e3992d 1961\r
1962 //\r
4772ce75 1963 // If the glyph of the character is existing, then accumulate the actual printed width\r
93e3992d 1964 //\r
1436aea4 1965 LineWidth += (UINTN)Cell[Index].AdvanceX;\r
93e3992d 1966\r
4772ce75 1967 Index++;\r
1968 }\r
93e3992d 1969\r
4772ce75 1970 //\r
f6cf5cf8
LG
1971 // Record index of next char.\r
1972 //\r
1973 NextIndex = Index;\r
1974 //\r
1975 // Return to the previous char.\r
4772ce75 1976 //\r
1977 Index--;\r
1436aea4 1978 if (LineBreak && (Index > 0)) {\r
f6cf5cf8
LG
1979 //\r
1980 // Return the previous non line break char.\r
1981 //\r
1436aea4 1982 Index--;\r
4772ce75 1983 }\r
93e3992d 1984\r
f6cf5cf8
LG
1985 //\r
1986 // If this character is the last character of a row, we need not\r
1987 // draw its (AdvanceX - Width - OffsetX) for next character.\r
1988 //\r
16f69227 1989 LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);\r
f6cf5cf8 1990\r
4772ce75 1991 //\r
1992 // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
1993 //\r
1436aea4
MK
1994 if ((LineWidth + BltX <= Image->Width) ||\r
1995 ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))\r
1996 {\r
93e3992d 1997 //\r
4772ce75 1998 // Record right-most character in RowInfo even if it is partially displayed.\r
93e3992d 1999 //\r
4772ce75 2000 RowInfo[RowIndex].EndIndex = Index;\r
2001 RowInfo[RowIndex].LineWidth = LineWidth;\r
2002 RowInfo[RowIndex].LineHeight = LineHeight;\r
2003 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
2004 } else {\r
93e3992d 2005 //\r
4772ce75 2006 // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
2007 // if its right-most on pixel cannot fit.\r
93e3992d 2008 //\r
fbf82a2c 2009 if (Index > RowInfo[RowIndex].StartIndex) {\r
f6cf5cf8
LG
2010 //\r
2011 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
2012 //\r
1436aea4
MK
2013 LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);\r
2014 LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);\r
4772ce75 2015 RowInfo[RowIndex].EndIndex = Index - 1;\r
f6cf5cf8 2016 RowInfo[RowIndex].LineWidth = LineWidth;\r
4772ce75 2017 RowInfo[RowIndex].LineHeight = LineHeight;\r
f6cf5cf8 2018 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
4772ce75 2019 } else {\r
93e3992d 2020 //\r
fbf82a2c
LG
2021 // There is no enough column to draw any character, so set current line width to zero.\r
2022 // And go to draw Next line if LineBreak is set.\r
93e3992d 2023 //\r
1436aea4 2024 RowInfo[RowIndex].LineWidth = 0;\r
fbf82a2c 2025 goto NextLine;\r
93e3992d 2026 }\r
4772ce75 2027 }\r
93e3992d 2028\r
4772ce75 2029 //\r
2030 // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break\r
2031 // opportunity prior to a character whose right-most extent would exceed Width.\r
2032 // Search the right-most line-break opportunity here.\r
2033 //\r
1436aea4
MK
2034 if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&\r
2035 ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&\r
2036 !LineBreak)\r
2037 {\r
4772ce75 2038 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {\r
f6cf5cf8 2039 LineWidth = RowInfo[RowIndex].LineWidth;\r
4772ce75 2040 for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {\r
f6cf5cf8
LG
2041 if (Index1 == RowInfo[RowIndex].EndIndex) {\r
2042 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
2043 } else {\r
2044 LineWidth -= Cell[Index1].AdvanceX;\r
2045 }\r
1436aea4 2046\r
4772ce75 2047 if (IsLineBreak (StringPtr[Index1]) > 0) {\r
2048 LineBreak = TRUE;\r
f6cf5cf8
LG
2049 if (Index1 > RowInfo[RowIndex].StartIndex) {\r
2050 RowInfo[RowIndex].EndIndex = Index1 - 1;\r
2051 }\r
1436aea4 2052\r
4772ce75 2053 //\r
2054 // relocate to the character after the right-most line break opportunity of this line\r
2055 //\r
f6cf5cf8 2056 NextIndex = Index1 + 1;\r
4772ce75 2057 break;\r
2058 }\r
1436aea4 2059\r
35c218d7 2060 //\r
2061 // If don't find a line break opportunity from EndIndex to StartIndex,\r
2062 // then jump out.\r
2063 //\r
1436aea4 2064 if (Index1 == RowInfo[RowIndex].StartIndex) {\r
35c218d7 2065 break;\r
1436aea4 2066 }\r
4772ce75 2067 }\r
f6cf5cf8
LG
2068\r
2069 //\r
2070 // Update LineWidth to the real width\r
2071 //\r
2072 if (IsLineBreak (StringPtr[Index1]) > 0) {\r
2073 if (Index1 == RowInfo[RowIndex].StartIndex) {\r
2074 LineWidth = 0;\r
2075 } else {\r
16f69227 2076 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
f6cf5cf8 2077 }\r
1436aea4 2078\r
f6cf5cf8
LG
2079 RowInfo[RowIndex].LineWidth = LineWidth;\r
2080 }\r
4772ce75 2081 }\r
1436aea4 2082\r
93e3992d 2083 //\r
4772ce75 2084 // If no line-break opportunity can be found, then the text will\r
2085 // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
93e3992d 2086 //\r
4772ce75 2087 if (!LineBreak) {\r
fbf82a2c
LG
2088 LineWidth = RowInfo[RowIndex].LineWidth;\r
2089 Index1 = RowInfo[RowIndex].EndIndex;\r
2090 if (LineWidth + BltX > Image->Width) {\r
2091 if (Index1 > RowInfo[RowIndex].StartIndex) {\r
2092 //\r
2093 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
2094 //\r
1436aea4
MK
2095 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
2096 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
2097 RowInfo[RowIndex].EndIndex = Index1 - 1;\r
2098 RowInfo[RowIndex].LineWidth = LineWidth;\r
fbf82a2c
LG
2099 } else {\r
2100 //\r
2101 // There is no enough column to draw any character, so set current line width to zero.\r
2102 // And go to draw Next line if LineBreak is set.\r
2103 //\r
2104 RowInfo[RowIndex].LineWidth = 0;\r
2105 goto NextLine;\r
2106 }\r
2107 }\r
4772ce75 2108 }\r
2109 }\r
d1102dba 2110\r
4772ce75 2111 //\r
f6cf5cf8 2112 // LineWidth can't exceed Image width.\r
4772ce75 2113 //\r
f6cf5cf8
LG
2114 if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {\r
2115 RowInfo[RowIndex].LineWidth = Image->Width - BltX;\r
4772ce75 2116 }\r
93e3992d 2117\r
4772ce75 2118 //\r
2119 // Draw it to screen or existing bitmap depending on whether\r
2120 // EFI_HII_DIRECT_TO_SCREEN is set.\r
2121 //\r
f6cf5cf8 2122 LineOffset = 0;\r
4772ce75 2123 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
f6cf5cf8
LG
2124 BltBuffer = NULL;\r
2125 if (RowInfo[RowIndex].LineWidth != 0) {\r
a52aed37 2126 BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
f6cf5cf8
LG
2127 if (BltBuffer == NULL) {\r
2128 Status = EFI_OUT_OF_RESOURCES;\r
2129 goto Exit;\r
2130 }\r
1436aea4 2131\r
f6cf5cf8 2132 //\r
0672c2cd
DB
2133 // Initialize the background color.\r
2134 //\r
2135 PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;\r
1436aea4 2136 SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);\r
0672c2cd 2137 //\r
f6cf5cf8
LG
2138 // Set BufferPtr to Origin by adding baseline to the starting position.\r
2139 //\r
2140 BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;\r
4772ce75 2141 }\r
1436aea4 2142\r
4772ce75 2143 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
1436aea4 2144 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {\r
93e3992d 2145 //\r
4a429716 2146 // Only BLT these character which have corresponding glyph in font database.\r
93e3992d 2147 //\r
93e3992d 2148 GlyphToImage (\r
2149 GlyphBuf[Index1],\r
2150 Foreground,\r
2151 Background,\r
1436aea4 2152 (UINT16)RowInfo[RowIndex].LineWidth,\r
f6cf5cf8
LG
2153 BaseLine,\r
2154 RowInfo[RowIndex].LineWidth - LineOffset,\r
93e3992d 2155 RowInfo[RowIndex].LineHeight,\r
2156 Transparent,\r
50b39985 2157 &Cell[Index1],\r
93e3992d 2158 Attributes[Index1],\r
2159 &BufferPtr\r
1436aea4 2160 );\r
93e3992d 2161 }\r
1436aea4 2162\r
4772ce75 2163 if (ColumnInfoArray != NULL) {\r
1436aea4
MK
2164 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))\r
2165 || (RowInfo[RowIndex].LineWidth == 0))\r
2166 {\r
f6cf5cf8 2167 *ColumnInfoArray = (UINTN) ~0;\r
4772ce75 2168 } else {\r
f6cf5cf8 2169 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
4772ce75 2170 }\r
1436aea4 2171\r
4772ce75 2172 ColumnInfoArray++;\r
93e3992d 2173 }\r
1436aea4 2174\r
f6cf5cf8 2175 LineOffset += Cell[Index1].AdvanceX;\r
4772ce75 2176 }\r
93e3992d 2177\r
f6cf5cf8
LG
2178 if (BltBuffer != NULL) {\r
2179 Status = Image->Image.Screen->Blt (\r
2180 Image->Image.Screen,\r
2181 BltBuffer,\r
2182 EfiBltBufferToVideo,\r
2183 0,\r
2184 0,\r
2185 BltX,\r
2186 BltY,\r
2187 RowInfo[RowIndex].LineWidth,\r
2188 RowInfo[RowIndex].LineHeight,\r
2189 0\r
2190 );\r
2191 if (EFI_ERROR (Status)) {\r
2192 FreePool (BltBuffer);\r
2193 goto Exit;\r
2194 }\r
d1102dba 2195\r
676df92c 2196 FreePool (BltBuffer);\r
4772ce75 2197 }\r
4772ce75 2198 } else {\r
f6cf5cf8 2199 //\r
4a429716 2200 // Save the starting position for calculate the starting position of next row.\r
f6cf5cf8
LG
2201 //\r
2202 RowBufferPtr = BufferPtr;\r
2203 //\r
2204 // Set BufferPtr to Origin by adding baseline to the starting position.\r
2205 //\r
2206 BufferPtr = BufferPtr + BaseLine * Image->Width;\r
4772ce75 2207 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
1436aea4 2208 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {\r
4772ce75 2209 //\r
4a429716 2210 // Only BLT these character which have corresponding glyph in font database.\r
4772ce75 2211 //\r
93e3992d 2212 GlyphToImage (\r
2213 GlyphBuf[Index1],\r
2214 Foreground,\r
2215 Background,\r
2216 Image->Width,\r
f6cf5cf8
LG
2217 BaseLine,\r
2218 RowInfo[RowIndex].LineWidth - LineOffset,\r
2219 RowInfo[RowIndex].LineHeight,\r
93e3992d 2220 Transparent,\r
50b39985 2221 &Cell[Index1],\r
93e3992d 2222 Attributes[Index1],\r
2223 &BufferPtr\r
1436aea4 2224 );\r
4772ce75 2225 }\r
1436aea4 2226\r
4772ce75 2227 if (ColumnInfoArray != NULL) {\r
1436aea4
MK
2228 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))\r
2229 || (RowInfo[RowIndex].LineWidth == 0))\r
2230 {\r
f6cf5cf8 2231 *ColumnInfoArray = (UINTN) ~0;\r
4772ce75 2232 } else {\r
f6cf5cf8 2233 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
93e3992d 2234 }\r
1436aea4 2235\r
4772ce75 2236 ColumnInfoArray++;\r
93e3992d 2237 }\r
1436aea4 2238\r
f6cf5cf8 2239 LineOffset += Cell[Index1].AdvanceX;\r
93e3992d 2240 }\r
f6cf5cf8 2241\r
4772ce75 2242 //\r
f6cf5cf8 2243 // Jump to starting position of next row.\r
4772ce75 2244 //\r
f6cf5cf8
LG
2245 if (RowIndex == 0) {\r
2246 BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;\r
2247 } else {\r
2248 BufferPtr = RowBufferPtr + LineHeight * Image->Width;\r
2249 }\r
93e3992d 2250 }\r
2251\r
fbf82a2c 2252NextLine:\r
f6cf5cf8 2253 //\r
3a2718d7 2254 // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down\r
f6cf5cf8 2255 //\r
f6cf5cf8
LG
2256 BltY += RowInfo[RowIndex].LineHeight;\r
2257\r
4772ce75 2258 RowIndex++;\r
f6cf5cf8 2259 Index = NextIndex;\r
93e3992d 2260\r
35c218d7 2261 if (!LineBreak) {\r
4772ce75 2262 //\r
35c218d7 2263 // If there is not a mandatory line break or line break opportunity, only render one line to image\r
4772ce75 2264 //\r
2265 break;\r
93e3992d 2266 }\r
4772ce75 2267 }\r
93e3992d 2268\r
4772ce75 2269 //\r
2270 // Write output parameters.\r
2271 //\r
2272 RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
2273 if (RowInfoArray != NULL) {\r
f6cf5cf8
LG
2274 if (RowInfoSize > 0) {\r
2275 *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
2276 if (*RowInfoArray == NULL) {\r
2277 Status = EFI_OUT_OF_RESOURCES;\r
2278 goto Exit;\r
2279 }\r
1436aea4 2280\r
f6cf5cf8
LG
2281 CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
2282 } else {\r
2283 *RowInfoArray = NULL;\r
93e3992d 2284 }\r
4772ce75 2285 }\r
1436aea4 2286\r
4772ce75 2287 if (RowInfoArraySize != NULL) {\r
2288 *RowInfoArraySize = RowIndex;\r
93e3992d 2289 }\r
2290\r
2291 Status = EFI_SUCCESS;\r
2292\r
2293Exit:\r
2294\r
4772ce75 2295 for (Index = 0; Index < StrLength; Index++) {\r
676df92c 2296 if (GlyphBuf[Index] != NULL) {\r
2297 FreePool (GlyphBuf[Index]);\r
2298 }\r
2299 }\r
1436aea4 2300\r
676df92c 2301 if (StringIn != NULL) {\r
2302 FreePool (StringIn);\r
2303 }\r
1436aea4 2304\r
676df92c 2305 if (StringIn2 != NULL) {\r
2306 FreePool (StringIn2);\r
2307 }\r
1436aea4 2308\r
676df92c 2309 if (StringInfoOut != NULL) {\r
2310 FreePool (StringInfoOut);\r
2311 }\r
1436aea4 2312\r
676df92c 2313 if (RowInfo != NULL) {\r
2314 FreePool (RowInfo);\r
2315 }\r
1436aea4 2316\r
676df92c 2317 if (SystemDefault != NULL) {\r
2318 FreePool (SystemDefault);\r
2319 }\r
1436aea4 2320\r
676df92c 2321 if (GlyphBuf != NULL) {\r
2322 FreePool (GlyphBuf);\r
2323 }\r
1436aea4 2324\r
676df92c 2325 if (Cell != NULL) {\r
2326 FreePool (Cell);\r
2327 }\r
1436aea4 2328\r
676df92c 2329 if (Attributes != NULL) {\r
2330 FreePool (Attributes);\r
93e3992d 2331 }\r
93e3992d 2332\r
2333 return Status;\r
2334}\r
2335\r
93e3992d 2336/**\r
2337 Render a string to a bitmap or the screen containing the contents of the specified string.\r
2338\r
2339 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2340 @param Flags Describes how the string is to be drawn.\r
2341 @param PackageList The package list in the HII database to search\r
2342 for the specified string.\r
ac644614 2343 @param StringId The string's id, which is unique within\r
93e3992d 2344 PackageList.\r
2345 @param Language Points to the language for the retrieved string.\r
2346 If NULL, then the current system language is\r
2347 used.\r
2348 @param StringInfo Points to the string output information,\r
2349 including the color and font. If NULL, then the\r
2350 string will be output in the default system font\r
2351 and color.\r
2352 @param Blt If this points to a non-NULL on entry, this\r
2353 points to the image, which is Width pixels wide\r
2354 and Height pixels high. The string will be drawn\r
2355 onto this image and\r
2356 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
2357 to a NULL on entry, then a buffer\r
2358 will be allocated to hold the generated image and\r
ac644614 2359 the pointer updated on exit. It is the caller's\r
93e3992d 2360 responsibility to free this buffer.\r
e90b081a 2361 @param BltX Specifies the offset from the left and top edge\r
2362 of the image of the first character cell in the\r
2363 image.\r
2364 @param BltY Specifies the offset from the left and top edge\r
93e3992d 2365 of the image of the first character cell in the\r
2366 image.\r
2367 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
2368 will point to an allocated buffer containing\r
2369 row information and RowInfoArraySize will be\r
2370 updated to contain the number of elements.\r
2371 This array describes the characters which were at\r
2372 least partially drawn and the heights of the\r
ac644614 2373 rows. It is the caller's responsibility to free\r
93e3992d 2374 this buffer.\r
2375 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
2376 contains the number of elements in RowInfoArray.\r
2377 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
2378 filled with the horizontal offset for each\r
2379 character in the string on the row where it is\r
2380 displayed. Non-printing characters will have\r
2381 the offset ~0. The caller is responsible to\r
2382 allocate a buffer large enough so that there\r
2383 is one entry for each character in the string,\r
2384 not including the null-terminator. It is possible\r
2385 when character display is normalized that some\r
2386 character cells overlap.\r
2387\r
4a429716
RN
2388 @retval EFI_SUCCESS The string was successfully rendered.\r
2389 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
2390 RowInfoArray or Blt.\r
813acf3a 2391 @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.\r
2392 @retval EFI_INVALID_PARAMETER Flags were invalid combination.\r
4a429716
RN
2393 @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the string id is not\r
2394 in the specified PackageList.\r
93e3992d 2395\r
2396**/\r
2397EFI_STATUS\r
2398EFIAPI\r
2399HiiStringIdToImage (\r
1436aea4
MK
2400 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2401 IN EFI_HII_OUT_FLAGS Flags,\r
2402 IN EFI_HII_HANDLE PackageList,\r
2403 IN EFI_STRING_ID StringId,\r
2404 IN CONST CHAR8 *Language,\r
2405 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
2406 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
2407 IN UINTN BltX,\r
2408 IN UINTN BltY,\r
2409 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
2410 OUT UINTN *RowInfoArraySize OPTIONAL,\r
2411 OUT UINTN *ColumnInfoArray OPTIONAL\r
93e3992d 2412 )\r
2413{\r
1436aea4
MK
2414 EFI_STATUS Status;\r
2415 HII_DATABASE_PRIVATE_DATA *Private;\r
2416 EFI_HII_STRING_PROTOCOL *HiiString;\r
2417 EFI_STRING String;\r
2418 UINTN StringSize;\r
2419 UINTN FontLen;\r
2420 UINTN NameSize;\r
2421 EFI_FONT_INFO *StringFontInfo;\r
2422 EFI_FONT_DISPLAY_INFO *NewStringInfo;\r
2423 CHAR8 TempSupportedLanguages;\r
2424 CHAR8 *SupportedLanguages;\r
2425 UINTN SupportedLanguagesSize;\r
2426 CHAR8 *CurrentLanguage;\r
2427 CHAR8 *BestLanguage;\r
2428\r
2429 if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {\r
93e3992d 2430 return EFI_INVALID_PARAMETER;\r
2431 }\r
2432\r
2433 if (!IsHiiHandleValid (PackageList)) {\r
2434 return EFI_NOT_FOUND;\r
2435 }\r
2436\r
813acf3a 2437 //\r
bf9af1b9 2438 // Initialize string pointers to be NULL\r
813acf3a 2439 //\r
bf9af1b9 2440 SupportedLanguages = NULL;\r
2441 CurrentLanguage = NULL;\r
2442 BestLanguage = NULL;\r
2443 String = NULL;\r
bf9af1b9 2444 StringFontInfo = NULL;\r
2445 NewStringInfo = NULL;\r
93e3992d 2446\r
2447 //\r
2448 // Get the string to be displayed.\r
2449 //\r
bf9af1b9 2450 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2451 HiiString = &Private->HiiString;\r
2452\r
2453 //\r
2454 // Get the size of supported language.\r
2455 //\r
2456 SupportedLanguagesSize = 0;\r
1436aea4
MK
2457 Status = HiiString->GetLanguages (\r
2458 HiiString,\r
2459 PackageList,\r
2460 &TempSupportedLanguages,\r
2461 &SupportedLanguagesSize\r
2462 );\r
bf9af1b9 2463 if (Status != EFI_BUFFER_TOO_SMALL) {\r
2464 return Status;\r
2465 }\r
2466\r
2467 SupportedLanguages = AllocatePool (SupportedLanguagesSize);\r
2468 if (SupportedLanguages == NULL) {\r
2469 return EFI_OUT_OF_RESOURCES;\r
2470 }\r
93e3992d 2471\r
bf9af1b9 2472 Status = HiiString->GetLanguages (\r
2473 HiiString,\r
2474 PackageList,\r
2475 SupportedLanguages,\r
2476 &SupportedLanguagesSize\r
2477 );\r
2478 if (EFI_ERROR (Status)) {\r
2479 goto Exit;\r
2480 }\r
d1102dba 2481\r
bf9af1b9 2482 if (Language == NULL) {\r
2483 Language = "";\r
2484 }\r
1436aea4
MK
2485\r
2486 GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);\r
bf9af1b9 2487 BestLanguage = GetBestLanguage (\r
2488 SupportedLanguages,\r
2489 FALSE,\r
2490 Language,\r
2491 (CurrentLanguage == NULL) ? CurrentLanguage : "",\r
1436aea4 2492 (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
bf9af1b9 2493 NULL\r
2494 );\r
2495 if (BestLanguage == NULL) {\r
2496 Status = EFI_NOT_FOUND;\r
2497 goto Exit;\r
2498 }\r
d1102dba 2499\r
93e3992d 2500 StringSize = MAX_STRING_LENGTH;\r
1436aea4 2501 String = (EFI_STRING)AllocateZeroPool (StringSize);\r
93e3992d 2502 if (String == NULL) {\r
bf9af1b9 2503 Status = EFI_OUT_OF_RESOURCES;\r
2504 goto Exit;\r
93e3992d 2505 }\r
2506\r
bf9af1b9 2507 Status = HiiString->GetString (\r
2508 HiiString,\r
2509 BestLanguage,\r
2510 PackageList,\r
2511 StringId,\r
2512 String,\r
2513 &StringSize,\r
2514 &StringFontInfo\r
2515 );\r
93e3992d 2516 if (Status == EFI_BUFFER_TOO_SMALL) {\r
676df92c 2517 FreePool (String);\r
1436aea4 2518 String = (EFI_STRING)AllocateZeroPool (StringSize);\r
93e3992d 2519 if (String == NULL) {\r
bf9af1b9 2520 Status = EFI_OUT_OF_RESOURCES;\r
2521 goto Exit;\r
93e3992d 2522 }\r
1436aea4 2523\r
bf9af1b9 2524 Status = HiiString->GetString (\r
2525 HiiString,\r
2526 BestLanguage,\r
2527 PackageList,\r
2528 StringId,\r
2529 String,\r
2530 &StringSize,\r
2531 NULL\r
2532 );\r
93e3992d 2533 }\r
2534\r
2535 if (EFI_ERROR (Status)) {\r
bf9af1b9 2536 goto Exit;\r
813acf3a 2537 }\r
d1102dba 2538\r
813acf3a 2539 //\r
2540 // When StringInfo specifies that string will be output in the system default font and color,\r
d1102dba 2541 // use particular stringfontinfo described in string package instead if exists.\r
813acf3a 2542 // StringFontInfo equals NULL means system default font attaches with the string block.\r
2543 //\r
1436aea4
MK
2544 if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {\r
2545 NameSize = StrSize (StringFontInfo->FontName);\r
2546 FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
813acf3a 2547 NewStringInfo = AllocateZeroPool (FontLen);\r
d1102dba 2548 if (NewStringInfo == NULL) {\r
813acf3a 2549 Status = EFI_OUT_OF_RESOURCES;\r
2550 goto Exit;\r
2551 }\r
1436aea4 2552\r
813acf3a 2553 NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;\r
2554 NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;\r
d1102dba 2555 NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;\r
5ad66ec6 2556 StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);\r
d1102dba 2557\r
813acf3a 2558 Status = HiiStringToImage (\r
d1102dba
LG
2559 This,\r
2560 Flags,\r
2561 String,\r
2562 NewStringInfo,\r
2563 Blt,\r
2564 BltX,\r
2565 BltY,\r
813acf3a 2566 RowInfoArray,\r
2567 RowInfoArraySize,\r
2568 ColumnInfoArray\r
2569 );\r
2570 goto Exit;\r
93e3992d 2571 }\r
2572\r
813acf3a 2573 Status = HiiStringToImage (\r
1436aea4
MK
2574 This,\r
2575 Flags,\r
2576 String,\r
2577 StringInfo,\r
2578 Blt,\r
2579 BltX,\r
2580 BltY,\r
2581 RowInfoArray,\r
2582 RowInfoArraySize,\r
2583 ColumnInfoArray\r
2584 );\r
93e3992d 2585\r
813acf3a 2586Exit:\r
bf9af1b9 2587 if (SupportedLanguages != NULL) {\r
2588 FreePool (SupportedLanguages);\r
2589 }\r
1436aea4 2590\r
bf9af1b9 2591 if (CurrentLanguage != NULL) {\r
2592 FreePool (CurrentLanguage);\r
2593 }\r
1436aea4 2594\r
bf9af1b9 2595 if (BestLanguage != NULL) {\r
2596 FreePool (BestLanguage);\r
2597 }\r
1436aea4 2598\r
676df92c 2599 if (String != NULL) {\r
2600 FreePool (String);\r
2601 }\r
1436aea4 2602\r
676df92c 2603 if (StringFontInfo != NULL) {\r
2604 FreePool (StringFontInfo);\r
2605 }\r
1436aea4 2606\r
676df92c 2607 if (NewStringInfo != NULL) {\r
2608 FreePool (NewStringInfo);\r
2609 }\r
813acf3a 2610\r
2611 return Status;\r
93e3992d 2612}\r
2613\r
93e3992d 2614/**\r
2615 Convert the glyph for a single character into a bitmap.\r
2616\r
2617 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2618 @param Char Character to retrieve.\r
2619 @param StringInfo Points to the string font and color information\r
2620 or NULL if the string should use the default\r
2621 system font and color.\r
2622 @param Blt Thus must point to a NULL on entry. A buffer will\r
2623 be allocated to hold the output and the pointer\r
ac644614 2624 updated on exit. It is the caller's\r
93e3992d 2625 responsibility to free this buffer.\r
2626 @param Baseline Number of pixels from the bottom of the bitmap to\r
2627 the baseline.\r
2628\r
2629 @retval EFI_SUCCESS Glyph bitmap created.\r
2630 @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.\r
2631 @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the\r
2632 glyph for Unicode character 0xFFFD.\r
2633 @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.\r
2634\r
2635**/\r
2636EFI_STATUS\r
2637EFIAPI\r
2638HiiGetGlyph (\r
1436aea4
MK
2639 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2640 IN CHAR16 Char,\r
2641 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,\r
2642 OUT EFI_IMAGE_OUTPUT **Blt,\r
2643 OUT UINTN *Baseline OPTIONAL\r
93e3992d 2644 )\r
2645{\r
1436aea4
MK
2646 EFI_STATUS Status;\r
2647 HII_DATABASE_PRIVATE_DATA *Private;\r
2648 EFI_IMAGE_OUTPUT *Image;\r
2649 UINT8 *GlyphBuffer;\r
2650 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2651 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
2652 BOOLEAN Default;\r
2653 EFI_FONT_HANDLE FontHandle;\r
2654 EFI_STRING String;\r
2655 EFI_HII_GLYPH_INFO Cell;\r
2656 EFI_FONT_INFO *FontInfo;\r
2657 UINT8 Attributes;\r
2658 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
2659 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
2660 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
2661 UINT16 BaseLine;\r
2662\r
2663 if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {\r
93e3992d 2664 return EFI_INVALID_PARAMETER;\r
2665 }\r
2666\r
2667 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2668\r
2669 Default = FALSE;\r
2670 Image = NULL;\r
2671 SystemDefault = NULL;\r
2672 FontHandle = NULL;\r
2673 String = NULL;\r
2674 GlyphBuffer = NULL;\r
2675 StringInfoOut = NULL;\r
2676 FontInfo = NULL;\r
2677\r
2678 ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2679 ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2680\r
1436aea4 2681 Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);\r
93e3992d 2682\r
2683 if (!Default) {\r
2684 //\r
2685 // Find out a EFI_FONT_DISPLAY_INFO which could display the character in\r
2686 // the specified color and font.\r
2687 //\r
1436aea4 2688 String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);\r
93e3992d 2689 if (String == NULL) {\r
2690 Status = EFI_OUT_OF_RESOURCES;\r
2691 goto Exit;\r
2692 }\r
1436aea4
MK
2693\r
2694 *String = Char;\r
93e3992d 2695 *(String + 1) = 0;\r
2696\r
2697 Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);\r
2698 if (EFI_ERROR (Status)) {\r
2699 goto Exit;\r
2700 }\r
1436aea4 2701\r
1b2bf3ca 2702 ASSERT (StringInfoOut != NULL);\r
93e3992d 2703 FontInfo = &StringInfoOut->FontInfo;\r
2704 Foreground = StringInfoOut->ForegroundColor;\r
2705 Background = StringInfoOut->BackgroundColor;\r
2706 } else {\r
523f48e7 2707 ASSERT (SystemDefault != NULL);\r
93e3992d 2708 Foreground = SystemDefault->ForegroundColor;\r
2709 Background = SystemDefault->BackgroundColor;\r
2710 }\r
2711\r
2712 Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);\r
2713 if (EFI_ERROR (Status)) {\r
2714 goto Exit;\r
2715 }\r
2716\r
1436aea4 2717 Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
93e3992d 2718 if (Image == NULL) {\r
2719 Status = EFI_OUT_OF_RESOURCES;\r
2720 goto Exit;\r
2721 }\r
1436aea4
MK
2722\r
2723 Image->Width = Cell.Width;\r
2724 Image->Height = Cell.Height;\r
93e3992d 2725\r
f6cf5cf8
LG
2726 if (Image->Width * Image->Height > 0) {\r
2727 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2728 if (Image->Image.Bitmap == NULL) {\r
2729 FreePool (Image);\r
2730 Status = EFI_OUT_OF_RESOURCES;\r
2731 goto Exit;\r
2732 }\r
93e3992d 2733\r
f6cf5cf8
LG
2734 //\r
2735 // Set BaseLine to the char height.\r
2736 //\r
1436aea4 2737 BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);\r
f6cf5cf8 2738 //\r
d1102dba 2739 // Set BltBuffer to the position of Origin.\r
f6cf5cf8
LG
2740 //\r
2741 BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;\r
2742 GlyphToImage (\r
2743 GlyphBuffer,\r
2744 Foreground,\r
2745 Background,\r
2746 Image->Width,\r
2747 BaseLine,\r
2748 Cell.Width + Cell.OffsetX,\r
2749 BaseLine - Cell.OffsetY,\r
2750 FALSE,\r
2751 &Cell,\r
2752 Attributes,\r
2753 &BltBuffer\r
2754 );\r
2755 }\r
93e3992d 2756\r
2757 *Blt = Image;\r
2758 if (Baseline != NULL) {\r
2759 *Baseline = Cell.OffsetY;\r
2760 }\r
2761\r
2762 Status = EFI_SUCCESS;\r
2763\r
2764Exit:\r
2765\r
2766 if (Status == EFI_NOT_FOUND) {\r
2767 //\r
2768 // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD\r
2769 //\r
2770 if (Char != REPLACE_UNKNOWN_GLYPH) {\r
2771 Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);\r
2772 if (!EFI_ERROR (Status)) {\r
2773 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2774 }\r
2775 } else {\r
2776 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2777 }\r
2778 }\r
2779\r
676df92c 2780 if (SystemDefault != NULL) {\r
1436aea4 2781 FreePool (SystemDefault);\r
676df92c 2782 }\r
1436aea4 2783\r
676df92c 2784 if (StringInfoOut != NULL) {\r
2785 FreePool (StringInfoOut);\r
2786 }\r
1436aea4 2787\r
676df92c 2788 if (String != NULL) {\r
2789 FreePool (String);\r
2790 }\r
1436aea4 2791\r
676df92c 2792 if (GlyphBuffer != NULL) {\r
2793 FreePool (GlyphBuffer);\r
2794 }\r
93e3992d 2795\r
2796 return Status;\r
2797}\r
2798\r
93e3992d 2799/**\r
2800 This function iterates through fonts which match the specified font, using\r
2801 the specified criteria. If String is non-NULL, then all of the characters in\r
2802 the string must exist in order for a candidate font to be returned.\r
2803\r
2804 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2805 @param FontHandle On entry, points to the font handle returned by a\r
2806 previous call to GetFontInfo() or NULL to start\r
2807 with the first font. On return, points to the\r
2808 returned font handle or points to NULL if there\r
2809 are no more matching fonts.\r
c0a3c3da
ED
2810 @param StringInfoIn Upon entry, points to the font to return information\r
2811 about. If NULL, then the information about the system\r
2812 default font will be returned.\r
2813 @param StringInfoOut Upon return, contains the matching font's information.\r
2814 If NULL, then no information is returned. This buffer\r
2815 is allocated with a call to the Boot Service AllocatePool().\r
d1102dba 2816 It is the caller's responsibility to call the Boot\r
c0a3c3da
ED
2817 Service FreePool() when the caller no longer requires\r
2818 the contents of StringInfoOut.\r
93e3992d 2819 @param String Points to the string which will be tested to\r
2820 determine if all characters are available. If\r
2821 NULL, then any font is acceptable.\r
2822\r
2823 @retval EFI_SUCCESS Matching font returned successfully.\r
2824 @retval EFI_NOT_FOUND No matching font was found.\r
813acf3a 2825 @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.\r
93e3992d 2826 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the\r
2827 request.\r
2828\r
2829**/\r
2830EFI_STATUS\r
2831EFIAPI\r
2832HiiGetFontInfo (\r
1436aea4
MK
2833 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2834 IN OUT EFI_FONT_HANDLE *FontHandle,\r
2835 IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL,\r
2836 OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,\r
2837 IN CONST EFI_STRING String OPTIONAL\r
93e3992d 2838 )\r
2839{\r
1436aea4
MK
2840 HII_DATABASE_PRIVATE_DATA *Private;\r
2841 EFI_STATUS Status;\r
2842 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2843 EFI_FONT_DISPLAY_INFO InfoOut;\r
2844 UINTN StringInfoOutLen;\r
2845 EFI_FONT_INFO *FontInfo;\r
2846 HII_GLOBAL_FONT_INFO *GlobalFont;\r
2847 EFI_STRING StringIn;\r
2848 EFI_FONT_HANDLE LocalFontHandle;\r
93e3992d 2849\r
813acf3a 2850 if (This == NULL) {\r
93e3992d 2851 return EFI_INVALID_PARAMETER;\r
2852 }\r
2853\r
523f48e7 2854 StringInfoOutLen = 0;\r
1436aea4
MK
2855 FontInfo = NULL;\r
2856 SystemDefault = NULL;\r
2857 LocalFontHandle = NULL;\r
93e3992d 2858 if (FontHandle != NULL) {\r
2859 LocalFontHandle = *FontHandle;\r
2860 }\r
2861\r
813acf3a 2862 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2863\r
2864 //\r
2865 // Already searched to the end of the whole list, return directly.\r
2866 //\r
2867 if (LocalFontHandle == &Private->FontInfoList) {\r
2868 LocalFontHandle = NULL;\r
1436aea4 2869 Status = EFI_NOT_FOUND;\r
813acf3a 2870 goto Exit;\r
2871 }\r
2872\r
93e3992d 2873 //\r
2874 // Get default system display info, if StringInfoIn points to\r
2875 // system display info, return it directly.\r
2876 //\r
1436aea4 2877 if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {\r
813acf3a 2878 //\r
2879 // System font is the first node. When handle is not NULL, system font can not\r
2880 // be found any more.\r
2881 //\r
2882 if (LocalFontHandle == NULL) {\r
2883 if (StringInfoOut != NULL) {\r
2884 *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);\r
2885 if (*StringInfoOut == NULL) {\r
1436aea4 2886 Status = EFI_OUT_OF_RESOURCES;\r
813acf3a 2887 LocalFontHandle = NULL;\r
2888 goto Exit;\r
2889 }\r
93e3992d 2890 }\r
813acf3a 2891\r
2892 LocalFontHandle = Private->FontInfoList.ForwardLink;\r
1436aea4 2893 Status = EFI_SUCCESS;\r
813acf3a 2894 goto Exit;\r
2895 } else {\r
2896 LocalFontHandle = NULL;\r
1436aea4 2897 Status = EFI_NOT_FOUND;\r
813acf3a 2898 goto Exit;\r
93e3992d 2899 }\r
813acf3a 2900 }\r
d1102dba 2901\r
bd37f971 2902 //\r
2903 // StringInfoIn must not be NULL if it is not system default font info.\r
2904 //\r
2905 ASSERT (StringInfoIn != NULL);\r
813acf3a 2906 //\r
2907 // Check the font information mask to make sure it is valid.\r
2908 //\r
d1102dba 2909 if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==\r
813acf3a 2910 (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||\r
d1102dba 2911 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==\r
813acf3a 2912 (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||\r
d1102dba 2913 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==\r
813acf3a 2914 (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||\r
d1102dba
LG
2915 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==\r
2916 (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||\r
2917 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==\r
1436aea4
MK
2918 (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))\r
2919 {\r
813acf3a 2920 return EFI_INVALID_PARAMETER;\r
93e3992d 2921 }\r
2922\r
2923 //\r
2924 // Parse the font information mask to find a matching font.\r
2925 //\r
2926\r
1436aea4 2927 CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));\r
93e3992d 2928\r
2929 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {\r
2930 Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);\r
2931 } else {\r
1436aea4 2932 Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);\r
93e3992d 2933 }\r
1436aea4 2934\r
93e3992d 2935 if (EFI_ERROR (Status)) {\r
2936 goto Exit;\r
2937 }\r
2938\r
2939 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {\r
2940 InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;\r
d1102dba 2941 }\r
1436aea4 2942\r
813acf3a 2943 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
93e3992d 2944 InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
813acf3a 2945 }\r
1436aea4 2946\r
813acf3a 2947 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
93e3992d 2948 InfoOut.ForegroundColor = SystemDefault->ForegroundColor;\r
813acf3a 2949 }\r
1436aea4 2950\r
813acf3a 2951 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
93e3992d 2952 InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
2953 }\r
d1102dba 2954\r
1b2bf3ca 2955 ASSERT (FontInfo != NULL);\r
93e3992d 2956 FontInfo->FontSize = InfoOut.FontInfo.FontSize;\r
2957 FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
2958\r
2959 if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
08e6463a 2960 //\r
2961 // Test to guarantee all characters are available in the found font.\r
d1102dba 2962 //\r
93e3992d 2963 if (String != NULL) {\r
93e3992d 2964 StringIn = String;\r
2965 while (*StringIn != 0) {\r
2966 Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);\r
2967 if (EFI_ERROR (Status)) {\r
2968 LocalFontHandle = NULL;\r
2969 goto Exit;\r
2970 }\r
1436aea4 2971\r
93e3992d 2972 StringIn++;\r
2973 }\r
08e6463a 2974 }\r
1436aea4 2975\r
08e6463a 2976 //\r
2977 // Write to output parameter\r
2978 //\r
2979 if (StringInfoOut != NULL) {\r
2980 StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
1436aea4 2981 *StringInfoOut = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);\r
08e6463a 2982 if (*StringInfoOut == NULL) {\r
1436aea4 2983 Status = EFI_OUT_OF_RESOURCES;\r
08e6463a 2984 LocalFontHandle = NULL;\r
2985 goto Exit;\r
93e3992d 2986 }\r
d1102dba 2987\r
08e6463a 2988 CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
2989 CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
93e3992d 2990 }\r
d1102dba
LG
2991\r
2992 LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
1436aea4 2993 Status = EFI_SUCCESS;\r
08e6463a 2994 goto Exit;\r
d1102dba 2995 }\r
93e3992d 2996\r
2997 Status = EFI_NOT_FOUND;\r
2998\r
2999Exit:\r
3000\r
3001 if (FontHandle != NULL) {\r
3002 *FontHandle = LocalFontHandle;\r
3003 }\r
3004\r
676df92c 3005 if (SystemDefault != NULL) {\r
1436aea4 3006 FreePool (SystemDefault);\r
676df92c 3007 }\r
1436aea4 3008\r
676df92c 3009 if (FontInfo != NULL) {\r
1436aea4 3010 FreePool (FontInfo);\r
676df92c 3011 }\r
1436aea4 3012\r
93e3992d 3013 return Status;\r
3014}\r