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