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