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