]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/HiiDatabaseDxe/Font.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[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
1002 Info->BackgroundColor = mHiiEfiColors[Private->Attribute >> 4];\r
93e3992d 1003 Info->FontInfoMask = EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_SYS_STYLE;\r
1004 Info->FontInfo.FontStyle = 0;\r
1005 Info->FontInfo.FontSize = EFI_GLYPH_HEIGHT;\r
5ad66ec6 1006 StrCpyS (Info->FontInfo.FontName, NameSize / sizeof (CHAR16), L"sysdefault");\r
93e3992d 1007\r
1008 *FontInfo = Info;\r
1009 if (FontInfoSize != NULL) {\r
1010 *FontInfoSize = InfoSize;\r
1011 }\r
1012 return EFI_SUCCESS;\r
1013}\r
1014\r
1015\r
1016/**\r
813acf3a 1017 Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or\r
1018 returns the system default according to the optional inputs.\r
93e3992d 1019\r
e90b081a 1020 This is a internal function.\r
1021\r
93e3992d 1022 @param Private HII database driver private data.\r
1023 @param StringInfo Points to the string output information,\r
1024 including the color and font.\r
813acf3a 1025 @param SystemInfo If not NULL, points to system default font and color.\r
1026\r
93e3992d 1027 @param SystemInfoLen If not NULL, output the length of default system\r
1028 info.\r
1029\r
1030 @retval TRUE Yes, it points to system default.\r
1031 @retval FALSE No.\r
1032\r
1033**/\r
93e3992d 1034BOOLEAN\r
1035IsSystemFontInfo (\r
1036 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1037 IN EFI_FONT_DISPLAY_INFO *StringInfo,\r
1038 OUT EFI_FONT_DISPLAY_INFO **SystemInfo, OPTIONAL\r
1039 OUT UINTN *SystemInfoLen OPTIONAL\r
1040 )\r
1041{\r
1042 EFI_STATUS Status;\r
1043 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
1044 UINTN DefaultLen;\r
813acf3a 1045 BOOLEAN Flag;\r
93e3992d 1046\r
1047 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
1048\r
1049 if (StringInfo == NULL && SystemInfo == NULL) {\r
1050 return TRUE;\r
1051 }\r
1052\r
523f48e7
ED
1053 SystemDefault = NULL;\r
1054 DefaultLen = 0;\r
1055\r
93e3992d 1056 Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
1057 ASSERT_EFI_ERROR (Status);\r
523f48e7 1058 ASSERT ((SystemDefault != NULL) && (DefaultLen != 0));\r
93e3992d 1059\r
813acf3a 1060 //\r
1061 // Record the system default info.\r
1062 //\r
93e3992d 1063 if (SystemInfo != NULL) {\r
1064 *SystemInfo = SystemDefault;\r
93e3992d 1065 }\r
1066\r
1067 if (SystemInfoLen != NULL) {\r
1068 *SystemInfoLen = DefaultLen;\r
1069 }\r
1070\r
813acf3a 1071 if (StringInfo == NULL) {\r
93e3992d 1072 return TRUE;\r
1073 }\r
1074\r
813acf3a 1075 Flag = FALSE;\r
1076 //\r
1077 // Check the FontInfoMask to see whether it is retrieving system info.\r
1078 //\r
1079 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {\r
1080 if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {\r
1081 goto Exit;\r
1082 }\r
1083 }\r
1084 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {\r
1085 if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {\r
1086 goto Exit;\r
1087 }\r
1088 }\r
1089 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {\r
1090 if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {\r
1091 goto Exit;\r
1092 }\r
1093 }\r
1094 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {\r
1095 if (CompareMem (\r
d1102dba
LG
1096 &StringInfo->ForegroundColor,\r
1097 &SystemDefault->ForegroundColor,\r
813acf3a 1098 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1099 ) != 0) {\r
1100 goto Exit;\r
1101 }\r
1102 }\r
1103 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {\r
1104 if (CompareMem (\r
d1102dba
LG
1105 &StringInfo->BackgroundColor,\r
1106 &SystemDefault->BackgroundColor,\r
813acf3a 1107 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
1108 ) != 0) {\r
1109 goto Exit;\r
1110 }\r
1111 }\r
1112\r
1113 Flag = TRUE;\r
1114\r
1115Exit:\r
1116 if (SystemInfo == NULL) {\r
676df92c 1117 if (SystemDefault != NULL) {\r
1118 FreePool (SystemDefault);\r
1119 }\r
813acf3a 1120 }\r
1121 return Flag;\r
93e3992d 1122}\r
1123\r
1124\r
1125/**\r
1126 This function checks whether EFI_FONT_INFO exists in current database. If\r
1127 FontInfoMask is specified, check what options can be used to make a match.\r
1128 Note that the masks relate to where the system default should be supplied\r
1129 are ignored by this function.\r
1130\r
1131 @param Private Hii database private structure.\r
1132 @param FontInfo Points to EFI_FONT_INFO structure.\r
1133 @param FontInfoMask If not NULL, describes what options can be used\r
1134 to make a match between the font requested and\r
1135 the font available. The caller must guarantee\r
1136 this mask is valid.\r
1137 @param FontHandle On entry, Points to the font handle returned by a\r
1138 previous call to GetFontInfo() or NULL to start\r
1139 with the first font.\r
4a429716 1140 @param GlobalFontInfo If not NULL, output the corresponding global font\r
93e3992d 1141 info.\r
1142\r
1143 @retval TRUE Existed\r
1144 @retval FALSE Not existed\r
1145\r
1146**/\r
1147BOOLEAN\r
1148IsFontInfoExisted (\r
1149 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1150 IN EFI_FONT_INFO *FontInfo,\r
1151 IN EFI_FONT_INFO_MASK *FontInfoMask, OPTIONAL\r
1152 IN EFI_FONT_HANDLE FontHandle, OPTIONAL\r
1153 OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL\r
1154 )\r
1155{\r
1156 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1157 HII_GLOBAL_FONT_INFO *GlobalFontBackup1;\r
1158 HII_GLOBAL_FONT_INFO *GlobalFontBackup2;\r
1159 LIST_ENTRY *Link;\r
1160 EFI_FONT_INFO_MASK Mask;\r
1161 BOOLEAN Matched;\r
1162 BOOLEAN VagueMatched1;\r
1163 BOOLEAN VagueMatched2;\r
1164\r
1165 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
1166 ASSERT (FontInfo != NULL);\r
1167\r
1168 //\r
4a429716 1169 // Matched flag represents an exactly match; VagueMatched1 represents a RESIZE\r
93e3992d 1170 // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.\r
1171 //\r
1172 Matched = FALSE;\r
1173 VagueMatched1 = FALSE;\r
1174 VagueMatched2 = FALSE;\r
1175\r
1176 Mask = 0;\r
1177 GlobalFontBackup1 = NULL;\r
1178 GlobalFontBackup2 = NULL;\r
1179\r
1180 // The process of where the system default should be supplied instead of\r
1181 // the specified font info beyonds this function's scope.\r
1182 //\r
1183 if (FontInfoMask != NULL) {\r
1184 Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);\r
1185 }\r
1186\r
1187 //\r
1188 // If not NULL, FontHandle points to the next node of the last searched font\r
1189 // node by previous call.\r
1190 //\r
1191 if (FontHandle == NULL) {\r
1192 Link = Private->FontInfoList.ForwardLink;\r
1193 } else {\r
1194 Link = (LIST_ENTRY *) FontHandle;\r
1195 }\r
1196\r
1197 for (; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
1198 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1199 if (FontInfoMask == NULL) {\r
1200 if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {\r
1201 if (GlobalFontInfo != NULL) {\r
1202 *GlobalFontInfo = GlobalFont;\r
1203 }\r
1204 return TRUE;\r
1205 }\r
1206 } else {\r
1207 //\r
1208 // Check which options could be used to make a match.\r
1209 //\r
1210 switch (Mask) {\r
1211 case EFI_FONT_INFO_ANY_FONT:\r
1212 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle &&\r
1213 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1214 Matched = TRUE;\r
1215 }\r
1216 break;\r
1217 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:\r
1218 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1219 Matched = TRUE;\r
1220 }\r
1221 break;\r
1222 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:\r
1223 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1224 Matched = TRUE;\r
1225 }\r
1226 break;\r
1227 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:\r
1228 Matched = TRUE;\r
1229 break;\r
1230 //\r
1231 // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to\r
1232 // remove some of the specified styles to meet the style requested.\r
1233 //\r
1234 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:\r
1235 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1236 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1237 Matched = TRUE;\r
1238 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1239 VagueMatched1 = TRUE;\r
1240 GlobalFontBackup1 = GlobalFont;\r
1241 }\r
1242 }\r
1243 break;\r
1244 //\r
4a429716 1245 // If EFI_FONT_INFO_RESIZE is specified, then the system may attempt to\r
93e3992d 1246 // stretch or shrink a font to meet the size requested.\r
1247 //\r
1248 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:\r
1249 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1250 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1251 Matched = TRUE;\r
1252 } else {\r
1253 VagueMatched1 = TRUE;\r
1254 GlobalFontBackup1 = GlobalFont;\r
1255 }\r
1256 }\r
1257 break;\r
1258 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:\r
1259 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1260 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1261 Matched = TRUE;\r
1262 } else {\r
1263 VagueMatched1 = TRUE;\r
1264 GlobalFontBackup1 = GlobalFont;\r
1265 }\r
1266 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1267 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1268 VagueMatched1 = TRUE;\r
1269 GlobalFontBackup1 = GlobalFont;\r
1270 } else {\r
1271 VagueMatched2 = TRUE;\r
1272 GlobalFontBackup2 = GlobalFont;\r
1273 }\r
1274 }\r
1275 break;\r
1276 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
1277 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1278 Matched = TRUE;\r
1279 } else {\r
1280 VagueMatched1 = TRUE;\r
1281 GlobalFontBackup1 = GlobalFont;\r
1282 }\r
1283 break;\r
1284 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
1285 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1286 Matched = TRUE;\r
1287 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1288 VagueMatched1 = TRUE;\r
1289 GlobalFontBackup1 = GlobalFont;\r
1290 }\r
1291 break;\r
1292 case EFI_FONT_INFO_ANY_STYLE:\r
1293 if ((CompareMem (\r
1294 GlobalFont->FontInfo->FontName,\r
1295 FontInfo->FontName,\r
1296 StrSize (FontInfo->FontName)\r
1297 ) == 0) &&\r
1298 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1299 Matched = TRUE;\r
1300 }\r
1301 break;\r
1302 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:\r
1303 if (CompareMem (\r
1304 GlobalFont->FontInfo->FontName,\r
1305 FontInfo->FontName,\r
1306 StrSize (FontInfo->FontName)\r
1307 ) == 0) {\r
1308 Matched = TRUE;\r
1309 }\r
1310 break;\r
1311 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
1312 if (CompareMem (\r
1313 GlobalFont->FontInfo->FontName,\r
1314 FontInfo->FontName,\r
1315 StrSize (FontInfo->FontName)\r
1316 ) == 0) {\r
1317 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1318 Matched = TRUE;\r
1319 } else {\r
1320 VagueMatched1 = TRUE;\r
1321 GlobalFontBackup1 = GlobalFont;\r
1322 }\r
1323 }\r
1324 break;\r
1325 case EFI_FONT_INFO_ANY_SIZE:\r
1326 if ((CompareMem (\r
1327 GlobalFont->FontInfo->FontName,\r
1328 FontInfo->FontName,\r
1329 StrSize (FontInfo->FontName)\r
1330 ) == 0) &&\r
1331 GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1332 Matched = TRUE;\r
1333 }\r
1334 break;\r
1335 case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
1336 if (CompareMem (\r
1337 GlobalFont->FontInfo->FontName,\r
1338 FontInfo->FontName,\r
1339 StrSize (FontInfo->FontName)\r
1340 ) == 0) {\r
1341 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1342 Matched = TRUE;\r
1343 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1344 VagueMatched1 = TRUE;\r
1345 GlobalFontBackup1 = GlobalFont;\r
1346 }\r
1347 }\r
1348 break;\r
1349 case EFI_FONT_INFO_RESTYLE:\r
1350 if ((CompareMem (\r
1351 GlobalFont->FontInfo->FontName,\r
1352 FontInfo->FontName,\r
1353 StrSize (FontInfo->FontName)\r
1354 ) == 0) &&\r
1355 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1356\r
1357 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1358 Matched = TRUE;\r
1359 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1360 VagueMatched1 = TRUE;\r
1361 GlobalFontBackup1 = GlobalFont;\r
1362 }\r
1363 }\r
1364 break;\r
1365 case EFI_FONT_INFO_RESIZE:\r
1366 if ((CompareMem (\r
1367 GlobalFont->FontInfo->FontName,\r
1368 FontInfo->FontName,\r
1369 StrSize (FontInfo->FontName)\r
1370 ) == 0) &&\r
1371 GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1372\r
1373 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1374 Matched = TRUE;\r
1375 } else {\r
1376 VagueMatched1 = TRUE;\r
1377 GlobalFontBackup1 = GlobalFont;\r
1378 }\r
1379 }\r
1380 break;\r
1381 case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:\r
1382 if (CompareMem (\r
1383 GlobalFont->FontInfo->FontName,\r
1384 FontInfo->FontName,\r
1385 StrSize (FontInfo->FontName)\r
1386 ) == 0) {\r
1387 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1388 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1389 Matched = TRUE;\r
1390 } else {\r
1391 VagueMatched1 = TRUE;\r
1392 GlobalFontBackup1 = GlobalFont;\r
1393 }\r
1394 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1395 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1396 VagueMatched1 = TRUE;\r
1397 GlobalFontBackup1 = GlobalFont;\r
1398 } else {\r
1399 VagueMatched2 = TRUE;\r
1400 GlobalFontBackup2 = GlobalFont;\r
1401 }\r
1402 }\r
1403 }\r
1404 break;\r
1405 default:\r
1406 break;\r
1407 }\r
1408\r
1409 if (Matched) {\r
1410 if (GlobalFontInfo != NULL) {\r
1411 *GlobalFontInfo = GlobalFont;\r
1412 }\r
1413 return TRUE;\r
1414 }\r
1415 }\r
1416 }\r
1417\r
1418 if (VagueMatched1) {\r
1419 if (GlobalFontInfo != NULL) {\r
1420 *GlobalFontInfo = GlobalFontBackup1;\r
1421 }\r
1422 return TRUE;\r
1423 } else if (VagueMatched2) {\r
1424 if (GlobalFontInfo != NULL) {\r
1425 *GlobalFontInfo = GlobalFontBackup2;\r
1426 }\r
1427 return TRUE;\r
1428 }\r
1429\r
1430 return FALSE;\r
1431}\r
1432\r
1433\r
1434/**\r
1435 Check whether the unicode represents a line break or not.\r
1436\r
4772ce75 1437 This is a internal function. Please see Section 27.2.6 of the UEFI Specification\r
1438 for a description of the supported string format.\r
e90b081a 1439\r
93e3992d 1440 @param Char Unicode character\r
1441\r
4772ce75 1442 @retval 0 Yes, it forces a line break.\r
1443 @retval 1 Yes, it presents a line break opportunity\r
1444 @retval 2 Yes, it requires a line break happen before and after it.\r
93e3992d 1445 @retval -1 No, it is not a link break.\r
1446\r
1447**/\r
93e3992d 1448INT8\r
1449IsLineBreak (\r
1450 IN CHAR16 Char\r
1451 )\r
1452{\r
93e3992d 1453 switch (Char) {\r
4772ce75 1454 //\r
1455 // Mandatory line break characters, which force a line-break\r
1456 //\r
2d9cdfd8 1457 case 0x000A:\r
4772ce75 1458 case 0x000C:\r
1459 case 0x000D:\r
1460 case 0x2028:\r
1461 case 0x2029:\r
93e3992d 1462 return 0;\r
4772ce75 1463 //\r
1464 // Space characters, which is taken as a line-break opportunity\r
1465 //\r
1466 case 0x0020:\r
1467 case 0x1680:\r
1468 case 0x2000:\r
1469 case 0x2001:\r
1470 case 0x2002:\r
1471 case 0x2003:\r
1472 case 0x2004:\r
1473 case 0x2005:\r
1474 case 0x2006:\r
1475 case 0x2008:\r
1476 case 0x2009:\r
1477 case 0x200A:\r
1478 case 0x205F:\r
1479 //\r
1480 // In-Word Break Opportunities\r
1481 //\r
1482 case 0x200B:\r
1483 return 1;\r
1484 //\r
1485 // A space which is not a line-break opportunity\r
1486 //\r
1487 case 0x00A0:\r
1488 case 0x202F:\r
1489 //\r
1490 // A hyphen which is not a line-break opportunity\r
1491 //\r
1492 case 0x2011:\r
1493 return -1;\r
1494 //\r
1495 // Hyphen characters which describe line break opportunities after the character\r
1496 //\r
93e3992d 1497 case 0x058A:\r
4772ce75 1498 case 0x2010:\r
1499 case 0x2012:\r
1500 case 0x2013:\r
93e3992d 1501 case 0x0F0B:\r
1502 case 0x1361:\r
1503 case 0x17D5:\r
1504 return 1;\r
4772ce75 1505 //\r
1506 // A hyphen which describes line break opportunities before and after them, but not between a pair of them\r
1507 //\r
1508 case 0x2014:\r
1509 return 2;\r
93e3992d 1510 }\r
93e3992d 1511 return -1;\r
1512}\r
1513\r
1514\r
1515/**\r
1516 Renders a string to a bitmap or to the display.\r
1517\r
1518 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
1519 @param Flags Describes how the string is to be drawn.\r
1520 @param String Points to the null-terminated string to be\r
1521 displayed.\r
1522 @param StringInfo Points to the string output information,\r
1523 including the color and font. If NULL, then the\r
1524 string will be output in the default system font\r
1525 and color.\r
1526 @param Blt If this points to a non-NULL on entry, this\r
1527 points to the image, which is Width pixels wide\r
1528 and Height pixels high. The string will be drawn\r
1529 onto this image and\r
1530 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
1531 to a NULL on entry, then a buffer\r
1532 will be allocated to hold the generated image and\r
ac644614 1533 the pointer updated on exit. It is the caller's\r
93e3992d 1534 responsibility to free this buffer.\r
e90b081a 1535 @param BltX Specifies the offset from the left and top edge\r
1536 of the image of the first character cell in the\r
1537 image.\r
1538 @param BltY Specifies the offset from the left and top edge\r
93e3992d 1539 of the image of the first character cell in the\r
1540 image.\r
1541 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
1542 will point to an allocated buffer containing\r
1543 row information and RowInfoArraySize will be\r
1544 updated to contain the number of elements.\r
1545 This array describes the characters which were at\r
1546 least partially drawn and the heights of the\r
ac644614 1547 rows. It is the caller's responsibility to free\r
93e3992d 1548 this buffer.\r
1549 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
1550 contains the number of elements in RowInfoArray.\r
1551 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
1552 filled with the horizontal offset for each\r
1553 character in the string on the row where it is\r
1554 displayed. Non-printing characters will have\r
1555 the offset ~0. The caller is responsible to\r
1556 allocate a buffer large enough so that there\r
1557 is one entry for each character in the string,\r
1558 not including the null-terminator. It is possible\r
1559 when character display is normalized that some\r
1560 character cells overlap.\r
1561\r
1562 @retval EFI_SUCCESS The string was successfully rendered.\r
1563 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
1564 RowInfoArray or Blt.\r
1565 @retval EFI_INVALID_PARAMETER The String or Blt was NULL.\r
813acf3a 1566 @retval EFI_INVALID_PARAMETER Flags were invalid combination..\r
93e3992d 1567\r
1568**/\r
1569EFI_STATUS\r
1570EFIAPI\r
1571HiiStringToImage (\r
1572 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
1573 IN EFI_HII_OUT_FLAGS Flags,\r
1574 IN CONST EFI_STRING String,\r
1575 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
1576 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
1577 IN UINTN BltX,\r
1578 IN UINTN BltY,\r
1579 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
1580 OUT UINTN *RowInfoArraySize OPTIONAL,\r
1581 OUT UINTN *ColumnInfoArray OPTIONAL\r
1582 )\r
1583{\r
1584 EFI_STATUS Status;\r
1585 HII_DATABASE_PRIVATE_DATA *Private;\r
1586 UINT8 **GlyphBuf;\r
1587 EFI_HII_GLYPH_INFO *Cell;\r
1588 UINT8 *Attributes;\r
1589 EFI_IMAGE_OUTPUT *Image;\r
1590 EFI_STRING StringPtr;\r
1591 EFI_STRING StringTmp;\r
1592 EFI_HII_ROW_INFO *RowInfo;\r
1593 UINTN LineWidth;\r
1594 UINTN LineHeight;\r
f6cf5cf8
LG
1595 UINTN LineOffset;\r
1596 UINTN LastLineHeight;\r
93e3992d 1597 UINTN BaseLineOffset;\r
1598 UINT16 MaxRowNum;\r
1599 UINT16 RowIndex;\r
1600 UINTN Index;\r
f6cf5cf8 1601 UINTN NextIndex;\r
93e3992d 1602 UINTN Index1;\r
1603 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
1604 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
1605 EFI_FONT_HANDLE FontHandle;\r
1606 EFI_STRING StringIn;\r
1607 EFI_STRING StringIn2;\r
1608 UINT16 Height;\r
f6cf5cf8 1609 UINT16 BaseLine;\r
93e3992d 1610 EFI_FONT_INFO *FontInfo;\r
1611 BOOLEAN SysFontFlag;\r
1612 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1613 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1614 BOOLEAN Transparent;\r
1615 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
1616 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;\r
1617 UINTN RowInfoSize;\r
1618 BOOLEAN LineBreak;\r
4772ce75 1619 UINTN StrLength;\r
f6cf5cf8
LG
1620 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *RowBufferPtr;\r
1621 HII_GLOBAL_FONT_INFO *GlobalFont;\r
0672c2cd 1622 UINT32 PreInitBkgnd;\r
93e3992d 1623\r
1624 //\r
1625 // Check incoming parameters.\r
1626 //\r
1627\r
1628 if (This == NULL || String == NULL || Blt == NULL) {\r
1629 return EFI_INVALID_PARAMETER;\r
1630 }\r
1631 if (*Blt == NULL) {\r
1632 //\r
1633 // These two flag cannot be used if Blt is NULL upon entry.\r
1634 //\r
1635 if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {\r
1636 return EFI_INVALID_PARAMETER;\r
1637 }\r
1638 if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {\r
1639 return EFI_INVALID_PARAMETER;\r
1640 }\r
1641 }\r
1642 //\r
1643 // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.\r
1644 //\r
813acf3a 1645 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {\r
93e3992d 1646 return EFI_INVALID_PARAMETER;\r
1647 }\r
813acf3a 1648 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
93e3992d 1649 return EFI_INVALID_PARAMETER;\r
1650 }\r
1651 //\r
1652 // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\r
1653 //\r
813acf3a 1654 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 1655 return EFI_INVALID_PARAMETER;\r
1656 }\r
1657\r
4772ce75 1658 if (*Blt == NULL) {\r
1659 //\r
1660 // Create a new bitmap and draw the string onto this image.\r
1661 //\r
1662 Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1663 if (Image == NULL) {\r
1664 return EFI_OUT_OF_RESOURCES;\r
1665 }\r
1666 Image->Width = 800;\r
1667 Image->Height = 600;\r
1668 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1669 if (Image->Image.Bitmap == NULL) {\r
1670 FreePool (Image);\r
1671 return EFI_OUT_OF_RESOURCES;\r
1672 }\r
1673\r
1674 //\r
1675 // Other flags are not permitted when Blt is NULL.\r
1676 //\r
1677 Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
1678 *Blt = Image;\r
1679 }\r
1680\r
1681 StrLength = StrLen(String);\r
1682 GlyphBuf = (UINT8 **) AllocateZeroPool (StrLength * sizeof (UINT8 *));\r
93e3992d 1683 ASSERT (GlyphBuf != NULL);\r
4772ce75 1684 Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (StrLength * sizeof (EFI_HII_GLYPH_INFO));\r
93e3992d 1685 ASSERT (Cell != NULL);\r
4772ce75 1686 Attributes = (UINT8 *) AllocateZeroPool (StrLength * sizeof (UINT8));\r
93e3992d 1687 ASSERT (Attributes != NULL);\r
1688\r
1689 RowInfo = NULL;\r
1690 Status = EFI_SUCCESS;\r
1691 StringIn2 = NULL;\r
1692 SystemDefault = NULL;\r
96ff65a1 1693 StringIn = NULL;\r
93e3992d 1694\r
1695 //\r
1696 // Calculate the string output information, including specified color and font .\r
1697 // If StringInfo does not points to system font info, it must indicate an existing\r
1698 // EFI_FONT_INFO.\r
1699 //\r
1700 StringInfoOut = NULL;\r
1701 FontHandle = NULL;\r
1702 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1703 SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
1704\r
1705 if (SysFontFlag) {\r
523f48e7 1706 ASSERT (SystemDefault != NULL);\r
93e3992d 1707 FontInfo = NULL;\r
1708 Height = SystemDefault->FontInfo.FontSize;\r
f6cf5cf8 1709 BaseLine = SystemDefault->FontInfo.FontSize;\r
93e3992d 1710 Foreground = SystemDefault->ForegroundColor;\r
1711 Background = SystemDefault->BackgroundColor;\r
1712\r
1713 } else {\r
7b06dc8a 1714 //\r
1715 // StringInfo must not be NULL if it is not system info.\r
1716 //\r
1717 ASSERT (StringInfo != NULL);\r
93e3992d 1718 Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *) StringInfo, &StringInfoOut, NULL);\r
1719 if (Status == EFI_NOT_FOUND) {\r
1720 //\r
1721 // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.\r
1722 // Use the system font instead. Still use the color specified by StringInfo.\r
1723 //\r
1724 SysFontFlag = TRUE;\r
1725 FontInfo = NULL;\r
1726 Height = SystemDefault->FontInfo.FontSize;\r
f6cf5cf8 1727 BaseLine = SystemDefault->FontInfo.FontSize;\r
93e3992d 1728 Foreground = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;\r
1729 Background = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;\r
1730\r
96ff65a1 1731 } else if (Status == EFI_SUCCESS) {\r
93e3992d 1732 FontInfo = &StringInfoOut->FontInfo;\r
f6cf5cf8
LG
1733 IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont);\r
1734 Height = GlobalFont->FontPackage->Height;\r
1735 BaseLine = GlobalFont->FontPackage->BaseLine;\r
93e3992d 1736 Foreground = StringInfoOut->ForegroundColor;\r
1737 Background = StringInfoOut->BackgroundColor;\r
96ff65a1 1738 } else {\r
1739 goto Exit;\r
93e3992d 1740 }\r
1741 }\r
d1102dba 1742\r
f6cf5cf8 1743 //\r
4a429716
RN
1744 // Use the maximum height of font as the base line.\r
1745 // And, use the maximum height as line height.\r
f6cf5cf8
LG
1746 //\r
1747 LineHeight = Height;\r
1748 LastLineHeight = Height;\r
1749 BaseLineOffset = Height - BaseLine;\r
d1102dba 1750\r
93e3992d 1751 //\r
1752 // Parse the string to be displayed to drop some ignored characters.\r
1753 //\r
1754\r
1755 StringPtr = String;\r
93e3992d 1756\r
1757 //\r
1758 // Ignore line-break characters only. Hyphens or dash character will be displayed\r
1759 // without line-break opportunity.\r
1760 //\r
1761 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {\r
1762 StringIn = AllocateZeroPool (StrSize (StringPtr));\r
1763 if (StringIn == NULL) {\r
1764 Status = EFI_OUT_OF_RESOURCES;\r
1765 goto Exit;\r
1766 }\r
1767 StringTmp = StringIn;\r
1768 while (*StringPtr != 0) {\r
1769 if (IsLineBreak (*StringPtr) == 0) {\r
1770 StringPtr++;\r
1771 } else {\r
1772 *StringTmp++ = *StringPtr++;\r
1773 }\r
1774 }\r
1775 *StringTmp = 0;\r
1776 StringPtr = StringIn;\r
1777 }\r
1778 //\r
1779 // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs\r
4a429716 1780 // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.\r
93e3992d 1781 //\r
1782 StringIn2 = AllocateZeroPool (StrSize (StringPtr));\r
1783 if (StringIn2 == NULL) {\r
1784 Status = EFI_OUT_OF_RESOURCES;\r
1785 goto Exit;\r
1786 }\r
1787 Index = 0;\r
1788 StringTmp = StringIn2;\r
4772ce75 1789 StrLength = StrLen(StringPtr);\r
1790 while (*StringPtr != 0 && Index < StrLength) {\r
f6cf5cf8
LG
1791 if (IsLineBreak (*StringPtr) == 0) {\r
1792 *StringTmp++ = *StringPtr++;\r
1793 Index++;\r
1794 continue;\r
1795 }\r
d1102dba 1796\r
93e3992d 1797 Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
1798 if (Status == EFI_NOT_FOUND) {\r
1799 if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
93e3992d 1800 GlyphBuf[Index] = NULL;\r
f6cf5cf8
LG
1801 ZeroMem (&Cell[Index], sizeof (Cell[Index]));\r
1802 Status = EFI_SUCCESS;\r
93e3992d 1803 } else {\r
1804 //\r
1805 // Unicode 0xFFFD must exist in current hii database if this flag is not set.\r
1806 //\r
1807 Status = GetGlyphBuffer (\r
1808 Private,\r
1809 REPLACE_UNKNOWN_GLYPH,\r
1810 FontInfo,\r
1811 &GlyphBuf[Index],\r
1812 &Cell[Index],\r
1813 &Attributes[Index]\r
1814 );\r
1815 if (EFI_ERROR (Status)) {\r
1816 Status = EFI_INVALID_PARAMETER;\r
93e3992d 1817 }\r
93e3992d 1818 }\r
f6cf5cf8
LG
1819 }\r
1820\r
1821 if (EFI_ERROR (Status)) {\r
93e3992d 1822 goto Exit;\r
93e3992d 1823 }\r
f6cf5cf8
LG
1824\r
1825 *StringTmp++ = *StringPtr++;\r
1826 Index++;\r
93e3992d 1827 }\r
1828 *StringTmp = 0;\r
1829 StringPtr = StringIn2;\r
1830\r
1831 //\r
1832 // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.\r
1833 // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string\r
1834 // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
1835 // Otherwise render this string to a new allocated image and output it.\r
1836 //\r
4772ce75 1837 Image = *Blt;\r
1838 BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
5cfe4234
LG
1839 if (Image->Height < BltY) {\r
1840 //\r
1841 // the top edge of the image should be in Image resolution scope.\r
1842 //\r
1843 Status = EFI_INVALID_PARAMETER;\r
1844 goto Exit;\r
1845 }\r
f6cf5cf8
LG
1846 MaxRowNum = (UINT16) ((Image->Height - BltY) / Height);\r
1847 if ((Image->Height - BltY) % Height != 0) {\r
1848 LastLineHeight = (Image->Height - BltY) % Height;\r
4772ce75 1849 MaxRowNum++;\r
1850 }\r
93e3992d 1851\r
4772ce75 1852 RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));\r
1853 if (RowInfo == NULL) {\r
1854 Status = EFI_OUT_OF_RESOURCES;\r
1855 goto Exit;\r
1856 }\r
1857\r
1858 //\r
1859 // Format the glyph buffer according to flags.\r
1860 //\r
4772ce75 1861 Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
4772ce75 1862\r
1863 for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
1864 LineWidth = 0;\r
4772ce75 1865 LineBreak = FALSE;\r
93e3992d 1866\r
f6cf5cf8
LG
1867 //\r
1868 // Clip the final row if the row's bottom-most on pixel cannot fit when\r
1869 // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
1870 //\r
1871 if (RowIndex == MaxRowNum - 1) {\r
1872 if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y && LastLineHeight < LineHeight ) {\r
1873 //\r
1874 // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
1875 //\r
1876 break;\r
1877 }\r
1878 LineHeight = LastLineHeight;\r
1879 }\r
1880\r
93e3992d 1881 //\r
4772ce75 1882 // Calculate how many characters there are in a row.\r
93e3992d 1883 //\r
4772ce75 1884 RowInfo[RowIndex].StartIndex = Index;\r
93e3992d 1885\r
4772ce75 1886 while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
1887 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&\r
4772ce75 1888 IsLineBreak (StringPtr[Index]) == 0) {\r
1889 //\r
1890 // It forces a line break that ends this row.\r
1891 //\r
1892 Index++;\r
35c218d7 1893 LineBreak = TRUE;\r
4772ce75 1894 break;\r
93e3992d 1895 }\r
93e3992d 1896\r
1897 //\r
4772ce75 1898 // If the glyph of the character is existing, then accumulate the actual printed width\r
93e3992d 1899 //\r
f6cf5cf8 1900 LineWidth += (UINTN) Cell[Index].AdvanceX;\r
93e3992d 1901\r
4772ce75 1902 Index++;\r
1903 }\r
93e3992d 1904\r
4772ce75 1905 //\r
f6cf5cf8
LG
1906 // Record index of next char.\r
1907 //\r
1908 NextIndex = Index;\r
1909 //\r
1910 // Return to the previous char.\r
4772ce75 1911 //\r
1912 Index--;\r
f6cf5cf8
LG
1913 if (LineBreak && Index > 0 ) {\r
1914 //\r
1915 // Return the previous non line break char.\r
1916 //\r
1917 Index --;\r
4772ce75 1918 }\r
93e3992d 1919\r
f6cf5cf8
LG
1920 //\r
1921 // If this character is the last character of a row, we need not\r
1922 // draw its (AdvanceX - Width - OffsetX) for next character.\r
1923 //\r
16f69227 1924 LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);\r
f6cf5cf8 1925\r
4772ce75 1926 //\r
1927 // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
1928 //\r
1929 if (LineWidth + BltX <= Image->Width ||\r
1930 (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {\r
93e3992d 1931 //\r
4772ce75 1932 // Record right-most character in RowInfo even if it is partially displayed.\r
93e3992d 1933 //\r
4772ce75 1934 RowInfo[RowIndex].EndIndex = Index;\r
1935 RowInfo[RowIndex].LineWidth = LineWidth;\r
1936 RowInfo[RowIndex].LineHeight = LineHeight;\r
1937 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
1938 } else {\r
93e3992d 1939 //\r
4772ce75 1940 // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
1941 // if its right-most on pixel cannot fit.\r
93e3992d 1942 //\r
fbf82a2c 1943 if (Index > RowInfo[RowIndex].StartIndex) {\r
f6cf5cf8
LG
1944 //\r
1945 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
1946 //\r
16f69227
HW
1947 LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);\r
1948 LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);\r
4772ce75 1949 RowInfo[RowIndex].EndIndex = Index - 1;\r
f6cf5cf8 1950 RowInfo[RowIndex].LineWidth = LineWidth;\r
4772ce75 1951 RowInfo[RowIndex].LineHeight = LineHeight;\r
f6cf5cf8 1952 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
4772ce75 1953 } else {\r
93e3992d 1954 //\r
fbf82a2c
LG
1955 // There is no enough column to draw any character, so set current line width to zero.\r
1956 // And go to draw Next line if LineBreak is set.\r
93e3992d 1957 //\r
fbf82a2c
LG
1958 RowInfo[RowIndex].LineWidth = 0;\r
1959 goto NextLine;\r
93e3992d 1960 }\r
4772ce75 1961 }\r
93e3992d 1962\r
4772ce75 1963 //\r
1964 // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break\r
1965 // opportunity prior to a character whose right-most extent would exceed Width.\r
1966 // Search the right-most line-break opportunity here.\r
1967 //\r
d1102dba
LG
1968 if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP &&\r
1969 (RowInfo[RowIndex].LineWidth + BltX > Image->Width || StringPtr[NextIndex] != 0) &&\r
fbf82a2c 1970 !LineBreak) {\r
4772ce75 1971 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {\r
f6cf5cf8 1972 LineWidth = RowInfo[RowIndex].LineWidth;\r
4772ce75 1973 for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {\r
f6cf5cf8
LG
1974 if (Index1 == RowInfo[RowIndex].EndIndex) {\r
1975 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
1976 } else {\r
1977 LineWidth -= Cell[Index1].AdvanceX;\r
1978 }\r
4772ce75 1979 if (IsLineBreak (StringPtr[Index1]) > 0) {\r
1980 LineBreak = TRUE;\r
f6cf5cf8
LG
1981 if (Index1 > RowInfo[RowIndex].StartIndex) {\r
1982 RowInfo[RowIndex].EndIndex = Index1 - 1;\r
1983 }\r
4772ce75 1984 //\r
1985 // relocate to the character after the right-most line break opportunity of this line\r
1986 //\r
f6cf5cf8 1987 NextIndex = Index1 + 1;\r
4772ce75 1988 break;\r
1989 }\r
35c218d7 1990 //\r
1991 // If don't find a line break opportunity from EndIndex to StartIndex,\r
1992 // then jump out.\r
1993 //\r
1994 if (Index1 == RowInfo[RowIndex].StartIndex)\r
1995 break;\r
4772ce75 1996 }\r
f6cf5cf8
LG
1997\r
1998 //\r
1999 // Update LineWidth to the real width\r
2000 //\r
2001 if (IsLineBreak (StringPtr[Index1]) > 0) {\r
2002 if (Index1 == RowInfo[RowIndex].StartIndex) {\r
2003 LineWidth = 0;\r
2004 } else {\r
16f69227 2005 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
f6cf5cf8
LG
2006 }\r
2007 RowInfo[RowIndex].LineWidth = LineWidth;\r
2008 }\r
4772ce75 2009 }\r
93e3992d 2010 //\r
4772ce75 2011 // If no line-break opportunity can be found, then the text will\r
2012 // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
93e3992d 2013 //\r
4772ce75 2014 if (!LineBreak) {\r
fbf82a2c
LG
2015 LineWidth = RowInfo[RowIndex].LineWidth;\r
2016 Index1 = RowInfo[RowIndex].EndIndex;\r
2017 if (LineWidth + BltX > Image->Width) {\r
2018 if (Index1 > RowInfo[RowIndex].StartIndex) {\r
2019 //\r
2020 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).\r
2021 //\r
16f69227
HW
2022 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);\r
2023 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);\r
fbf82a2c
LG
2024 RowInfo[RowIndex].EndIndex = Index1 - 1;\r
2025 RowInfo[RowIndex].LineWidth = LineWidth;\r
2026 } else {\r
2027 //\r
2028 // There is no enough column to draw any character, so set current line width to zero.\r
2029 // And go to draw Next line if LineBreak is set.\r
2030 //\r
2031 RowInfo[RowIndex].LineWidth = 0;\r
2032 goto NextLine;\r
2033 }\r
2034 }\r
4772ce75 2035 }\r
2036 }\r
d1102dba 2037\r
4772ce75 2038 //\r
f6cf5cf8 2039 // LineWidth can't exceed Image width.\r
4772ce75 2040 //\r
f6cf5cf8
LG
2041 if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {\r
2042 RowInfo[RowIndex].LineWidth = Image->Width - BltX;\r
4772ce75 2043 }\r
93e3992d 2044\r
4772ce75 2045 //\r
2046 // Draw it to screen or existing bitmap depending on whether\r
2047 // EFI_HII_DIRECT_TO_SCREEN is set.\r
2048 //\r
f6cf5cf8 2049 LineOffset = 0;\r
4772ce75 2050 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
f6cf5cf8
LG
2051 BltBuffer = NULL;\r
2052 if (RowInfo[RowIndex].LineWidth != 0) {\r
a52aed37 2053 BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
f6cf5cf8
LG
2054 if (BltBuffer == NULL) {\r
2055 Status = EFI_OUT_OF_RESOURCES;\r
2056 goto Exit;\r
2057 }\r
2058 //\r
0672c2cd
DB
2059 // Initialize the background color.\r
2060 //\r
2061 PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;\r
2062 SetMem32 (BltBuffer,RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),PreInitBkgnd);\r
2063 //\r
f6cf5cf8
LG
2064 // Set BufferPtr to Origin by adding baseline to the starting position.\r
2065 //\r
2066 BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;\r
4772ce75 2067 }\r
4772ce75 2068 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
f6cf5cf8 2069 if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {\r
93e3992d 2070 //\r
4a429716 2071 // Only BLT these character which have corresponding glyph in font database.\r
93e3992d 2072 //\r
93e3992d 2073 GlyphToImage (\r
2074 GlyphBuf[Index1],\r
2075 Foreground,\r
2076 Background,\r
f6cf5cf8
LG
2077 (UINT16) RowInfo[RowIndex].LineWidth,\r
2078 BaseLine,\r
2079 RowInfo[RowIndex].LineWidth - LineOffset,\r
93e3992d 2080 RowInfo[RowIndex].LineHeight,\r
2081 Transparent,\r
50b39985 2082 &Cell[Index1],\r
93e3992d 2083 Attributes[Index1],\r
2084 &BufferPtr\r
4772ce75 2085 );\r
93e3992d 2086 }\r
4772ce75 2087 if (ColumnInfoArray != NULL) {\r
d1102dba 2088 if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)\r
f6cf5cf8
LG
2089 || RowInfo[RowIndex].LineWidth == 0) {\r
2090 *ColumnInfoArray = (UINTN) ~0;\r
4772ce75 2091 } else {\r
f6cf5cf8 2092 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
4772ce75 2093 }\r
2094 ColumnInfoArray++;\r
93e3992d 2095 }\r
f6cf5cf8 2096 LineOffset += Cell[Index1].AdvanceX;\r
4772ce75 2097 }\r
93e3992d 2098\r
f6cf5cf8
LG
2099 if (BltBuffer != NULL) {\r
2100 Status = Image->Image.Screen->Blt (\r
2101 Image->Image.Screen,\r
2102 BltBuffer,\r
2103 EfiBltBufferToVideo,\r
2104 0,\r
2105 0,\r
2106 BltX,\r
2107 BltY,\r
2108 RowInfo[RowIndex].LineWidth,\r
2109 RowInfo[RowIndex].LineHeight,\r
2110 0\r
2111 );\r
2112 if (EFI_ERROR (Status)) {\r
2113 FreePool (BltBuffer);\r
2114 goto Exit;\r
2115 }\r
d1102dba 2116\r
676df92c 2117 FreePool (BltBuffer);\r
4772ce75 2118 }\r
4772ce75 2119 } else {\r
f6cf5cf8 2120 //\r
4a429716 2121 // Save the starting position for calculate the starting position of next row.\r
f6cf5cf8
LG
2122 //\r
2123 RowBufferPtr = BufferPtr;\r
2124 //\r
2125 // Set BufferPtr to Origin by adding baseline to the starting position.\r
2126 //\r
2127 BufferPtr = BufferPtr + BaseLine * Image->Width;\r
4772ce75 2128 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
f6cf5cf8 2129 if (RowInfo[RowIndex].LineWidth > 0 && RowInfo[RowIndex].LineWidth > LineOffset) {\r
4772ce75 2130 //\r
4a429716 2131 // Only BLT these character which have corresponding glyph in font database.\r
4772ce75 2132 //\r
93e3992d 2133 GlyphToImage (\r
2134 GlyphBuf[Index1],\r
2135 Foreground,\r
2136 Background,\r
2137 Image->Width,\r
f6cf5cf8
LG
2138 BaseLine,\r
2139 RowInfo[RowIndex].LineWidth - LineOffset,\r
2140 RowInfo[RowIndex].LineHeight,\r
93e3992d 2141 Transparent,\r
50b39985 2142 &Cell[Index1],\r
93e3992d 2143 Attributes[Index1],\r
2144 &BufferPtr\r
4772ce75 2145 );\r
2146 }\r
2147 if (ColumnInfoArray != NULL) {\r
d1102dba 2148 if ((GlyphBuf[Index1] == NULL && Cell[Index1].AdvanceX == 0)\r
f6cf5cf8
LG
2149 || RowInfo[RowIndex].LineWidth == 0) {\r
2150 *ColumnInfoArray = (UINTN) ~0;\r
4772ce75 2151 } else {\r
f6cf5cf8 2152 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;\r
93e3992d 2153 }\r
4772ce75 2154 ColumnInfoArray++;\r
93e3992d 2155 }\r
f6cf5cf8 2156 LineOffset += Cell[Index1].AdvanceX;\r
93e3992d 2157 }\r
f6cf5cf8 2158\r
4772ce75 2159 //\r
f6cf5cf8 2160 // Jump to starting position of next row.\r
4772ce75 2161 //\r
f6cf5cf8
LG
2162 if (RowIndex == 0) {\r
2163 BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;\r
2164 } else {\r
2165 BufferPtr = RowBufferPtr + LineHeight * Image->Width;\r
2166 }\r
93e3992d 2167 }\r
2168\r
fbf82a2c 2169NextLine:\r
f6cf5cf8 2170 //\r
3a2718d7 2171 // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down\r
f6cf5cf8 2172 //\r
f6cf5cf8
LG
2173 BltY += RowInfo[RowIndex].LineHeight;\r
2174\r
4772ce75 2175 RowIndex++;\r
f6cf5cf8 2176 Index = NextIndex;\r
93e3992d 2177\r
35c218d7 2178 if (!LineBreak) {\r
4772ce75 2179 //\r
35c218d7 2180 // If there is not a mandatory line break or line break opportunity, only render one line to image\r
4772ce75 2181 //\r
2182 break;\r
93e3992d 2183 }\r
4772ce75 2184 }\r
93e3992d 2185\r
4772ce75 2186 //\r
2187 // Write output parameters.\r
2188 //\r
2189 RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
2190 if (RowInfoArray != NULL) {\r
f6cf5cf8
LG
2191 if (RowInfoSize > 0) {\r
2192 *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
2193 if (*RowInfoArray == NULL) {\r
2194 Status = EFI_OUT_OF_RESOURCES;\r
2195 goto Exit;\r
2196 }\r
2197 CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
2198 } else {\r
2199 *RowInfoArray = NULL;\r
93e3992d 2200 }\r
4772ce75 2201 }\r
2202 if (RowInfoArraySize != NULL) {\r
2203 *RowInfoArraySize = RowIndex;\r
93e3992d 2204 }\r
2205\r
2206 Status = EFI_SUCCESS;\r
2207\r
2208Exit:\r
2209\r
4772ce75 2210 for (Index = 0; Index < StrLength; Index++) {\r
676df92c 2211 if (GlyphBuf[Index] != NULL) {\r
2212 FreePool (GlyphBuf[Index]);\r
2213 }\r
2214 }\r
2215 if (StringIn != NULL) {\r
2216 FreePool (StringIn);\r
2217 }\r
2218 if (StringIn2 != NULL) {\r
2219 FreePool (StringIn2);\r
2220 }\r
2221 if (StringInfoOut != NULL) {\r
2222 FreePool (StringInfoOut);\r
2223 }\r
2224 if (RowInfo != NULL) {\r
2225 FreePool (RowInfo);\r
2226 }\r
2227 if (SystemDefault != NULL) {\r
2228 FreePool (SystemDefault);\r
2229 }\r
2230 if (GlyphBuf != NULL) {\r
2231 FreePool (GlyphBuf);\r
2232 }\r
2233 if (Cell != NULL) {\r
2234 FreePool (Cell);\r
2235 }\r
2236 if (Attributes != NULL) {\r
2237 FreePool (Attributes);\r
93e3992d 2238 }\r
93e3992d 2239\r
2240 return Status;\r
2241}\r
2242\r
2243\r
2244/**\r
2245 Render a string to a bitmap or the screen containing the contents of the specified string.\r
2246\r
2247 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2248 @param Flags Describes how the string is to be drawn.\r
2249 @param PackageList The package list in the HII database to search\r
2250 for the specified string.\r
ac644614 2251 @param StringId The string's id, which is unique within\r
93e3992d 2252 PackageList.\r
2253 @param Language Points to the language for the retrieved string.\r
2254 If NULL, then the current system language is\r
2255 used.\r
2256 @param StringInfo Points to the string output information,\r
2257 including the color and font. If NULL, then the\r
2258 string will be output in the default system font\r
2259 and color.\r
2260 @param Blt If this points to a non-NULL on entry, this\r
2261 points to the image, which is Width pixels wide\r
2262 and Height pixels high. The string will be drawn\r
2263 onto this image and\r
2264 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
2265 to a NULL on entry, then a buffer\r
2266 will be allocated to hold the generated image and\r
ac644614 2267 the pointer updated on exit. It is the caller's\r
93e3992d 2268 responsibility to free this buffer.\r
e90b081a 2269 @param BltX Specifies the offset from the left and top edge\r
2270 of the image of the first character cell in the\r
2271 image.\r
2272 @param BltY Specifies the offset from the left and top edge\r
93e3992d 2273 of the image of the first character cell in the\r
2274 image.\r
2275 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
2276 will point to an allocated buffer containing\r
2277 row information and RowInfoArraySize will be\r
2278 updated to contain the number of elements.\r
2279 This array describes the characters which were at\r
2280 least partially drawn and the heights of the\r
ac644614 2281 rows. It is the caller's responsibility to free\r
93e3992d 2282 this buffer.\r
2283 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
2284 contains the number of elements in RowInfoArray.\r
2285 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
2286 filled with the horizontal offset for each\r
2287 character in the string on the row where it is\r
2288 displayed. Non-printing characters will have\r
2289 the offset ~0. The caller is responsible to\r
2290 allocate a buffer large enough so that there\r
2291 is one entry for each character in the string,\r
2292 not including the null-terminator. It is possible\r
2293 when character display is normalized that some\r
2294 character cells overlap.\r
2295\r
4a429716
RN
2296 @retval EFI_SUCCESS The string was successfully rendered.\r
2297 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
2298 RowInfoArray or Blt.\r
813acf3a 2299 @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.\r
2300 @retval EFI_INVALID_PARAMETER Flags were invalid combination.\r
4a429716
RN
2301 @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the string id is not\r
2302 in the specified PackageList.\r
93e3992d 2303\r
2304**/\r
2305EFI_STATUS\r
2306EFIAPI\r
2307HiiStringIdToImage (\r
2308 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2309 IN EFI_HII_OUT_FLAGS Flags,\r
2310 IN EFI_HII_HANDLE PackageList,\r
2311 IN EFI_STRING_ID StringId,\r
2312 IN CONST CHAR8* Language,\r
2313 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
2314 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
2315 IN UINTN BltX,\r
2316 IN UINTN BltY,\r
2317 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
2318 OUT UINTN *RowInfoArraySize OPTIONAL,\r
2319 OUT UINTN *ColumnInfoArray OPTIONAL\r
2320 )\r
2321{\r
2322 EFI_STATUS Status;\r
2323 HII_DATABASE_PRIVATE_DATA *Private;\r
bf9af1b9 2324 EFI_HII_STRING_PROTOCOL *HiiString;\r
93e3992d 2325 EFI_STRING String;\r
2326 UINTN StringSize;\r
813acf3a 2327 UINTN FontLen;\r
5ad66ec6 2328 UINTN NameSize;\r
813acf3a 2329 EFI_FONT_INFO *StringFontInfo;\r
2330 EFI_FONT_DISPLAY_INFO *NewStringInfo;\r
bf9af1b9 2331 CHAR8 TempSupportedLanguages;\r
2332 CHAR8 *SupportedLanguages;\r
2333 UINTN SupportedLanguagesSize;\r
2334 CHAR8 *CurrentLanguage;\r
2335 CHAR8 *BestLanguage;\r
93e3992d 2336\r
2337 if (This == NULL || PackageList == NULL || Blt == NULL || PackageList == NULL) {\r
2338 return EFI_INVALID_PARAMETER;\r
2339 }\r
2340\r
2341 if (!IsHiiHandleValid (PackageList)) {\r
2342 return EFI_NOT_FOUND;\r
2343 }\r
2344\r
813acf3a 2345 //\r
bf9af1b9 2346 // Initialize string pointers to be NULL\r
813acf3a 2347 //\r
bf9af1b9 2348 SupportedLanguages = NULL;\r
2349 CurrentLanguage = NULL;\r
2350 BestLanguage = NULL;\r
2351 String = NULL;\r
bf9af1b9 2352 StringFontInfo = NULL;\r
2353 NewStringInfo = NULL;\r
93e3992d 2354\r
2355 //\r
2356 // Get the string to be displayed.\r
2357 //\r
bf9af1b9 2358 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2359 HiiString = &Private->HiiString;\r
2360\r
2361 //\r
2362 // Get the size of supported language.\r
2363 //\r
2364 SupportedLanguagesSize = 0;\r
2365 Status = HiiString->GetLanguages (\r
2366 HiiString,\r
2367 PackageList,\r
2368 &TempSupportedLanguages,\r
2369 &SupportedLanguagesSize\r
2370 );\r
2371 if (Status != EFI_BUFFER_TOO_SMALL) {\r
2372 return Status;\r
2373 }\r
2374\r
2375 SupportedLanguages = AllocatePool (SupportedLanguagesSize);\r
2376 if (SupportedLanguages == NULL) {\r
2377 return EFI_OUT_OF_RESOURCES;\r
2378 }\r
93e3992d 2379\r
bf9af1b9 2380 Status = HiiString->GetLanguages (\r
2381 HiiString,\r
2382 PackageList,\r
2383 SupportedLanguages,\r
2384 &SupportedLanguagesSize\r
2385 );\r
2386 if (EFI_ERROR (Status)) {\r
2387 goto Exit;\r
2388 }\r
d1102dba 2389\r
bf9af1b9 2390 if (Language == NULL) {\r
2391 Language = "";\r
2392 }\r
f01b91ae 2393 GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLanguage, NULL);\r
bf9af1b9 2394 BestLanguage = GetBestLanguage (\r
2395 SupportedLanguages,\r
2396 FALSE,\r
2397 Language,\r
2398 (CurrentLanguage == NULL) ? CurrentLanguage : "",\r
2399 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
2400 NULL\r
2401 );\r
2402 if (BestLanguage == NULL) {\r
2403 Status = EFI_NOT_FOUND;\r
2404 goto Exit;\r
2405 }\r
d1102dba 2406\r
93e3992d 2407 StringSize = MAX_STRING_LENGTH;\r
2408 String = (EFI_STRING) AllocateZeroPool (StringSize);\r
2409 if (String == NULL) {\r
bf9af1b9 2410 Status = EFI_OUT_OF_RESOURCES;\r
2411 goto Exit;\r
93e3992d 2412 }\r
2413\r
bf9af1b9 2414 Status = HiiString->GetString (\r
2415 HiiString,\r
2416 BestLanguage,\r
2417 PackageList,\r
2418 StringId,\r
2419 String,\r
2420 &StringSize,\r
2421 &StringFontInfo\r
2422 );\r
93e3992d 2423 if (Status == EFI_BUFFER_TOO_SMALL) {\r
676df92c 2424 FreePool (String);\r
93e3992d 2425 String = (EFI_STRING) AllocateZeroPool (StringSize);\r
2426 if (String == NULL) {\r
bf9af1b9 2427 Status = EFI_OUT_OF_RESOURCES;\r
2428 goto Exit;\r
93e3992d 2429 }\r
bf9af1b9 2430 Status = HiiString->GetString (\r
2431 HiiString,\r
2432 BestLanguage,\r
2433 PackageList,\r
2434 StringId,\r
2435 String,\r
2436 &StringSize,\r
2437 NULL\r
2438 );\r
93e3992d 2439 }\r
2440\r
2441 if (EFI_ERROR (Status)) {\r
bf9af1b9 2442 goto Exit;\r
813acf3a 2443 }\r
d1102dba 2444\r
813acf3a 2445 //\r
2446 // When StringInfo specifies that string will be output in the system default font and color,\r
d1102dba 2447 // use particular stringfontinfo described in string package instead if exists.\r
813acf3a 2448 // StringFontInfo equals NULL means system default font attaches with the string block.\r
2449 //\r
2450 if (StringFontInfo != NULL && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, NULL, NULL)) {\r
5ad66ec6
DB
2451 NameSize = StrSize (StringFontInfo->FontName);\r
2452 FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;\r
813acf3a 2453 NewStringInfo = AllocateZeroPool (FontLen);\r
d1102dba 2454 if (NewStringInfo == NULL) {\r
813acf3a 2455 Status = EFI_OUT_OF_RESOURCES;\r
2456 goto Exit;\r
2457 }\r
2458 NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;\r
2459 NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;\r
d1102dba 2460 NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;\r
5ad66ec6 2461 StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);\r
d1102dba 2462\r
813acf3a 2463 Status = HiiStringToImage (\r
d1102dba
LG
2464 This,\r
2465 Flags,\r
2466 String,\r
2467 NewStringInfo,\r
2468 Blt,\r
2469 BltX,\r
2470 BltY,\r
813acf3a 2471 RowInfoArray,\r
2472 RowInfoArraySize,\r
2473 ColumnInfoArray\r
2474 );\r
2475 goto Exit;\r
93e3992d 2476 }\r
2477\r
813acf3a 2478 Status = HiiStringToImage (\r
93e3992d 2479 This,\r
2480 Flags,\r
2481 String,\r
2482 StringInfo,\r
2483 Blt,\r
2484 BltX,\r
2485 BltY,\r
2486 RowInfoArray,\r
2487 RowInfoArraySize,\r
2488 ColumnInfoArray\r
2489 );\r
2490\r
813acf3a 2491Exit:\r
bf9af1b9 2492 if (SupportedLanguages != NULL) {\r
2493 FreePool (SupportedLanguages);\r
2494 }\r
2495 if (CurrentLanguage != NULL) {\r
2496 FreePool (CurrentLanguage);\r
2497 }\r
2498 if (BestLanguage != NULL) {\r
2499 FreePool (BestLanguage);\r
2500 }\r
676df92c 2501 if (String != NULL) {\r
2502 FreePool (String);\r
2503 }\r
2504 if (StringFontInfo != NULL) {\r
2505 FreePool (StringFontInfo);\r
2506 }\r
2507 if (NewStringInfo != NULL) {\r
2508 FreePool (NewStringInfo);\r
2509 }\r
813acf3a 2510\r
2511 return Status;\r
93e3992d 2512}\r
2513\r
2514\r
2515/**\r
2516 Convert the glyph for a single character into a bitmap.\r
2517\r
2518 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2519 @param Char Character to retrieve.\r
2520 @param StringInfo Points to the string font and color information\r
2521 or NULL if the string should use the default\r
2522 system font and color.\r
2523 @param Blt Thus must point to a NULL on entry. A buffer will\r
2524 be allocated to hold the output and the pointer\r
ac644614 2525 updated on exit. It is the caller's\r
93e3992d 2526 responsibility to free this buffer.\r
2527 @param Baseline Number of pixels from the bottom of the bitmap to\r
2528 the baseline.\r
2529\r
2530 @retval EFI_SUCCESS Glyph bitmap created.\r
2531 @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.\r
2532 @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the\r
2533 glyph for Unicode character 0xFFFD.\r
2534 @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.\r
2535\r
2536**/\r
2537EFI_STATUS\r
2538EFIAPI\r
2539HiiGetGlyph (\r
2540 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2541 IN CHAR16 Char,\r
2542 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,\r
2543 OUT EFI_IMAGE_OUTPUT **Blt,\r
2544 OUT UINTN *Baseline OPTIONAL\r
2545 )\r
2546{\r
2547 EFI_STATUS Status;\r
2548 HII_DATABASE_PRIVATE_DATA *Private;\r
2549 EFI_IMAGE_OUTPUT *Image;\r
2550 UINT8 *GlyphBuffer;\r
2551 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2552 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
2553 BOOLEAN Default;\r
2554 EFI_FONT_HANDLE FontHandle;\r
2555 EFI_STRING String;\r
2556 EFI_HII_GLYPH_INFO Cell;\r
2557 EFI_FONT_INFO *FontInfo;\r
2558 UINT8 Attributes;\r
2559 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
2560 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
2561 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
f6cf5cf8 2562 UINT16 BaseLine;\r
93e3992d 2563\r
2564 if (This == NULL || Blt == NULL || *Blt != NULL) {\r
2565 return EFI_INVALID_PARAMETER;\r
2566 }\r
2567\r
2568 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2569\r
2570 Default = FALSE;\r
2571 Image = NULL;\r
2572 SystemDefault = NULL;\r
2573 FontHandle = NULL;\r
2574 String = NULL;\r
2575 GlyphBuffer = NULL;\r
2576 StringInfoOut = NULL;\r
2577 FontInfo = NULL;\r
2578\r
2579 ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2580 ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2581\r
2582 Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
2583\r
2584 if (!Default) {\r
2585 //\r
2586 // Find out a EFI_FONT_DISPLAY_INFO which could display the character in\r
2587 // the specified color and font.\r
2588 //\r
2589 String = (EFI_STRING) AllocateZeroPool (sizeof (CHAR16) * 2);\r
2590 if (String == NULL) {\r
2591 Status = EFI_OUT_OF_RESOURCES;\r
2592 goto Exit;\r
2593 }\r
2594 *String = Char;\r
2595 *(String + 1) = 0;\r
2596\r
2597 Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);\r
2598 if (EFI_ERROR (Status)) {\r
2599 goto Exit;\r
2600 }\r
1b2bf3ca 2601 ASSERT (StringInfoOut != NULL);\r
93e3992d 2602 FontInfo = &StringInfoOut->FontInfo;\r
2603 Foreground = StringInfoOut->ForegroundColor;\r
2604 Background = StringInfoOut->BackgroundColor;\r
2605 } else {\r
523f48e7 2606 ASSERT (SystemDefault != NULL);\r
93e3992d 2607 Foreground = SystemDefault->ForegroundColor;\r
2608 Background = SystemDefault->BackgroundColor;\r
2609 }\r
2610\r
2611 Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);\r
2612 if (EFI_ERROR (Status)) {\r
2613 goto Exit;\r
2614 }\r
2615\r
2616 Image = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
2617 if (Image == NULL) {\r
2618 Status = EFI_OUT_OF_RESOURCES;\r
2619 goto Exit;\r
2620 }\r
2621 Image->Width = Cell.Width;\r
2622 Image->Height = Cell.Height;\r
2623\r
f6cf5cf8
LG
2624 if (Image->Width * Image->Height > 0) {\r
2625 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2626 if (Image->Image.Bitmap == NULL) {\r
2627 FreePool (Image);\r
2628 Status = EFI_OUT_OF_RESOURCES;\r
2629 goto Exit;\r
2630 }\r
93e3992d 2631\r
f6cf5cf8
LG
2632 //\r
2633 // Set BaseLine to the char height.\r
2634 //\r
2635 BaseLine = (UINT16) (Cell.Height + Cell.OffsetY);\r
2636 //\r
d1102dba 2637 // Set BltBuffer to the position of Origin.\r
f6cf5cf8
LG
2638 //\r
2639 BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;\r
2640 GlyphToImage (\r
2641 GlyphBuffer,\r
2642 Foreground,\r
2643 Background,\r
2644 Image->Width,\r
2645 BaseLine,\r
2646 Cell.Width + Cell.OffsetX,\r
2647 BaseLine - Cell.OffsetY,\r
2648 FALSE,\r
2649 &Cell,\r
2650 Attributes,\r
2651 &BltBuffer\r
2652 );\r
2653 }\r
93e3992d 2654\r
2655 *Blt = Image;\r
2656 if (Baseline != NULL) {\r
2657 *Baseline = Cell.OffsetY;\r
2658 }\r
2659\r
2660 Status = EFI_SUCCESS;\r
2661\r
2662Exit:\r
2663\r
2664 if (Status == EFI_NOT_FOUND) {\r
2665 //\r
2666 // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD\r
2667 //\r
2668 if (Char != REPLACE_UNKNOWN_GLYPH) {\r
2669 Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);\r
2670 if (!EFI_ERROR (Status)) {\r
2671 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2672 }\r
2673 } else {\r
2674 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2675 }\r
2676 }\r
2677\r
676df92c 2678 if (SystemDefault != NULL) {\r
2679 FreePool (SystemDefault);\r
2680 }\r
2681 if (StringInfoOut != NULL) {\r
2682 FreePool (StringInfoOut);\r
2683 }\r
2684 if (String != NULL) {\r
2685 FreePool (String);\r
2686 }\r
2687 if (GlyphBuffer != NULL) {\r
2688 FreePool (GlyphBuffer);\r
2689 }\r
93e3992d 2690\r
2691 return Status;\r
2692}\r
2693\r
2694\r
2695/**\r
2696 This function iterates through fonts which match the specified font, using\r
2697 the specified criteria. If String is non-NULL, then all of the characters in\r
2698 the string must exist in order for a candidate font to be returned.\r
2699\r
2700 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2701 @param FontHandle On entry, points to the font handle returned by a\r
2702 previous call to GetFontInfo() or NULL to start\r
2703 with the first font. On return, points to the\r
2704 returned font handle or points to NULL if there\r
2705 are no more matching fonts.\r
c0a3c3da
ED
2706 @param StringInfoIn Upon entry, points to the font to return information\r
2707 about. If NULL, then the information about the system\r
2708 default font will be returned.\r
2709 @param StringInfoOut Upon return, contains the matching font's information.\r
2710 If NULL, then no information is returned. This buffer\r
2711 is allocated with a call to the Boot Service AllocatePool().\r
d1102dba 2712 It is the caller's responsibility to call the Boot\r
c0a3c3da
ED
2713 Service FreePool() when the caller no longer requires\r
2714 the contents of StringInfoOut.\r
93e3992d 2715 @param String Points to the string which will be tested to\r
2716 determine if all characters are available. If\r
2717 NULL, then any font is acceptable.\r
2718\r
2719 @retval EFI_SUCCESS Matching font returned successfully.\r
2720 @retval EFI_NOT_FOUND No matching font was found.\r
813acf3a 2721 @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.\r
93e3992d 2722 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the\r
2723 request.\r
2724\r
2725**/\r
2726EFI_STATUS\r
2727EFIAPI\r
2728HiiGetFontInfo (\r
2729 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2730 IN OUT EFI_FONT_HANDLE *FontHandle,\r
813acf3a 2731 IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn, OPTIONAL\r
93e3992d 2732 OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,\r
2733 IN CONST EFI_STRING String OPTIONAL\r
2734 )\r
2735{\r
2736 HII_DATABASE_PRIVATE_DATA *Private;\r
2737 EFI_STATUS Status;\r
2738 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2739 EFI_FONT_DISPLAY_INFO InfoOut;\r
2740 UINTN StringInfoOutLen;\r
2741 EFI_FONT_INFO *FontInfo;\r
2742 HII_GLOBAL_FONT_INFO *GlobalFont;\r
2743 EFI_STRING StringIn;\r
2744 EFI_FONT_HANDLE LocalFontHandle;\r
2745\r
813acf3a 2746 if (This == NULL) {\r
93e3992d 2747 return EFI_INVALID_PARAMETER;\r
2748 }\r
2749\r
523f48e7 2750 StringInfoOutLen = 0;\r
93e3992d 2751 FontInfo = NULL;\r
813acf3a 2752 SystemDefault = NULL;\r
93e3992d 2753 LocalFontHandle = NULL;\r
2754 if (FontHandle != NULL) {\r
2755 LocalFontHandle = *FontHandle;\r
2756 }\r
2757\r
813acf3a 2758 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2759\r
2760 //\r
2761 // Already searched to the end of the whole list, return directly.\r
2762 //\r
2763 if (LocalFontHandle == &Private->FontInfoList) {\r
2764 LocalFontHandle = NULL;\r
2765 Status = EFI_NOT_FOUND;\r
2766 goto Exit;\r
2767 }\r
2768\r
93e3992d 2769 //\r
2770 // Get default system display info, if StringInfoIn points to\r
2771 // system display info, return it directly.\r
2772 //\r
93e3992d 2773 if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, &SystemDefault, &StringInfoOutLen)) {\r
813acf3a 2774 //\r
2775 // System font is the first node. When handle is not NULL, system font can not\r
2776 // be found any more.\r
2777 //\r
2778 if (LocalFontHandle == NULL) {\r
2779 if (StringInfoOut != NULL) {\r
2780 *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);\r
2781 if (*StringInfoOut == NULL) {\r
2782 Status = EFI_OUT_OF_RESOURCES;\r
2783 LocalFontHandle = NULL;\r
2784 goto Exit;\r
2785 }\r
93e3992d 2786 }\r
813acf3a 2787\r
2788 LocalFontHandle = Private->FontInfoList.ForwardLink;\r
2789 Status = EFI_SUCCESS;\r
2790 goto Exit;\r
2791 } else {\r
2792 LocalFontHandle = NULL;\r
2793 Status = EFI_NOT_FOUND;\r
2794 goto Exit;\r
93e3992d 2795 }\r
813acf3a 2796 }\r
d1102dba 2797\r
bd37f971 2798 //\r
2799 // StringInfoIn must not be NULL if it is not system default font info.\r
2800 //\r
2801 ASSERT (StringInfoIn != NULL);\r
813acf3a 2802 //\r
2803 // Check the font information mask to make sure it is valid.\r
2804 //\r
d1102dba 2805 if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==\r
813acf3a 2806 (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||\r
d1102dba 2807 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==\r
813acf3a 2808 (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||\r
d1102dba 2809 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==\r
813acf3a 2810 (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||\r
d1102dba
LG
2811 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==\r
2812 (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||\r
2813 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==\r
813acf3a 2814 (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {\r
2815 return EFI_INVALID_PARAMETER;\r
93e3992d 2816 }\r
2817\r
2818 //\r
2819 // Parse the font information mask to find a matching font.\r
2820 //\r
2821\r
2822 CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));\r
2823\r
2824 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {\r
2825 Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);\r
2826 } else {\r
2827 Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *) StringInfoIn)->FontInfo.FontName, &FontInfo);\r
2828 }\r
2829 if (EFI_ERROR (Status)) {\r
2830 goto Exit;\r
2831 }\r
2832\r
2833 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {\r
2834 InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;\r
d1102dba 2835 }\r
813acf3a 2836 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
93e3992d 2837 InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
813acf3a 2838 }\r
2839 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
93e3992d 2840 InfoOut.ForegroundColor = SystemDefault->ForegroundColor;\r
813acf3a 2841 }\r
2842 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
93e3992d 2843 InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
2844 }\r
d1102dba 2845\r
1b2bf3ca 2846 ASSERT (FontInfo != NULL);\r
93e3992d 2847 FontInfo->FontSize = InfoOut.FontInfo.FontSize;\r
2848 FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
2849\r
2850 if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
08e6463a 2851 //\r
2852 // Test to guarantee all characters are available in the found font.\r
d1102dba 2853 //\r
93e3992d 2854 if (String != NULL) {\r
93e3992d 2855 StringIn = String;\r
2856 while (*StringIn != 0) {\r
2857 Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);\r
2858 if (EFI_ERROR (Status)) {\r
2859 LocalFontHandle = NULL;\r
2860 goto Exit;\r
2861 }\r
2862 StringIn++;\r
2863 }\r
08e6463a 2864 }\r
2865 //\r
2866 // Write to output parameter\r
2867 //\r
2868 if (StringInfoOut != NULL) {\r
2869 StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
d1102dba 2870 *StringInfoOut = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);\r
08e6463a 2871 if (*StringInfoOut == NULL) {\r
2872 Status = EFI_OUT_OF_RESOURCES;\r
2873 LocalFontHandle = NULL;\r
2874 goto Exit;\r
93e3992d 2875 }\r
d1102dba 2876\r
08e6463a 2877 CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
2878 CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
93e3992d 2879 }\r
d1102dba
LG
2880\r
2881 LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
08e6463a 2882 Status = EFI_SUCCESS;\r
2883 goto Exit;\r
d1102dba 2884 }\r
93e3992d 2885\r
2886 Status = EFI_NOT_FOUND;\r
2887\r
2888Exit:\r
2889\r
2890 if (FontHandle != NULL) {\r
2891 *FontHandle = LocalFontHandle;\r
2892 }\r
2893\r
676df92c 2894 if (SystemDefault != NULL) {\r
2895 FreePool (SystemDefault);\r
2896 }\r
2897 if (FontInfo != NULL) {\r
2898 FreePool (FontInfo);\r
2899 }\r
93e3992d 2900 return Status;\r
2901}\r
2902\r
813acf3a 2903\r