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