]> 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
813acf3a 908 Check whether EFI_FONT_DISPLAY_INFO points to system default font and color or\r
909 returns the system default according to the optional inputs.\r
93e3992d 910\r
911 @param Private HII database driver private data.\r
912 @param StringInfo Points to the string output information,\r
913 including the color and font.\r
813acf3a 914 @param SystemInfo If not NULL, points to system default font and color.\r
915\r
93e3992d 916 @param SystemInfoLen If not NULL, output the length of default system\r
917 info.\r
918\r
919 @retval TRUE Yes, it points to system default.\r
920 @retval FALSE No.\r
921\r
922**/\r
923STATIC\r
924BOOLEAN\r
925IsSystemFontInfo (\r
926 IN HII_DATABASE_PRIVATE_DATA *Private,\r
927 IN EFI_FONT_DISPLAY_INFO *StringInfo,\r
928 OUT EFI_FONT_DISPLAY_INFO **SystemInfo, OPTIONAL\r
929 OUT UINTN *SystemInfoLen OPTIONAL\r
930 )\r
931{\r
932 EFI_STATUS Status;\r
933 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
934 UINTN DefaultLen;\r
813acf3a 935 BOOLEAN Flag;\r
93e3992d 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
93e3992d 943 Status = GetSystemFont (Private, &SystemDefault, &DefaultLen);\r
944 ASSERT_EFI_ERROR (Status);\r
945\r
813acf3a 946 //\r
947 // Record the system default info.\r
948 //\r
93e3992d 949 if (SystemInfo != NULL) {\r
950 *SystemInfo = SystemDefault;\r
93e3992d 951 }\r
952\r
953 if (SystemInfoLen != NULL) {\r
954 *SystemInfoLen = DefaultLen;\r
955 }\r
956\r
813acf3a 957 if (StringInfo == NULL) {\r
93e3992d 958 return TRUE;\r
959 }\r
960\r
813acf3a 961 Flag = FALSE;\r
962 //\r
963 // Check the FontInfoMask to see whether it is retrieving system info.\r
964 //\r
965 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == 0) {\r
966 if (StrCmp (StringInfo->FontInfo.FontName, SystemDefault->FontInfo.FontName) != 0) {\r
967 goto Exit;\r
968 }\r
969 }\r
970 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == 0) {\r
971 if (StringInfo->FontInfo.FontSize != SystemDefault->FontInfo.FontSize) {\r
972 goto Exit;\r
973 }\r
974 }\r
975 if ((StringInfo->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == 0) {\r
976 if (StringInfo->FontInfo.FontStyle != SystemDefault->FontInfo.FontStyle) {\r
977 goto Exit;\r
978 }\r
979 }\r
980 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == 0) {\r
981 if (CompareMem (\r
982 &StringInfo->ForegroundColor, \r
983 &SystemDefault->ForegroundColor, \r
984 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
985 ) != 0) {\r
986 goto Exit;\r
987 }\r
988 }\r
989 if ((StringInfo->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == 0) {\r
990 if (CompareMem (\r
991 &StringInfo->BackgroundColor, \r
992 &SystemDefault->BackgroundColor, \r
993 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
994 ) != 0) {\r
995 goto Exit;\r
996 }\r
997 }\r
998\r
999 Flag = TRUE;\r
1000\r
1001Exit:\r
1002 if (SystemInfo == NULL) {\r
1003 SafeFreePool (SystemDefault); \r
1004 }\r
1005 return Flag;\r
93e3992d 1006}\r
1007\r
1008\r
1009/**\r
1010 This function checks whether EFI_FONT_INFO exists in current database. If\r
1011 FontInfoMask is specified, check what options can be used to make a match.\r
1012 Note that the masks relate to where the system default should be supplied\r
1013 are ignored by this function.\r
1014\r
1015 @param Private Hii database private structure.\r
1016 @param FontInfo Points to EFI_FONT_INFO structure.\r
1017 @param FontInfoMask If not NULL, describes what options can be used\r
1018 to make a match between the font requested and\r
1019 the font available. The caller must guarantee\r
1020 this mask is valid.\r
1021 @param FontHandle On entry, Points to the font handle returned by a\r
1022 previous call to GetFontInfo() or NULL to start\r
1023 with the first font.\r
1024 @param GlobalFontInfo If not NULL, output the corresponding globa font\r
1025 info.\r
1026\r
1027 @retval TRUE Existed\r
1028 @retval FALSE Not existed\r
1029\r
1030**/\r
1031BOOLEAN\r
1032IsFontInfoExisted (\r
1033 IN HII_DATABASE_PRIVATE_DATA *Private,\r
1034 IN EFI_FONT_INFO *FontInfo,\r
1035 IN EFI_FONT_INFO_MASK *FontInfoMask, OPTIONAL\r
1036 IN EFI_FONT_HANDLE FontHandle, OPTIONAL\r
1037 OUT HII_GLOBAL_FONT_INFO **GlobalFontInfo OPTIONAL\r
1038 )\r
1039{\r
1040 HII_GLOBAL_FONT_INFO *GlobalFont;\r
1041 HII_GLOBAL_FONT_INFO *GlobalFontBackup1;\r
1042 HII_GLOBAL_FONT_INFO *GlobalFontBackup2;\r
1043 LIST_ENTRY *Link;\r
1044 EFI_FONT_INFO_MASK Mask;\r
1045 BOOLEAN Matched;\r
1046 BOOLEAN VagueMatched1;\r
1047 BOOLEAN VagueMatched2;\r
1048\r
1049 ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE);\r
1050 ASSERT (FontInfo != NULL);\r
1051\r
1052 //\r
1053 // Matched flag represents an exactly match; VagueMatched1 repensents a RESIZE\r
1054 // or RESTYLE match; VagueMatched2 represents a RESIZE | RESTYLE match.\r
1055 //\r
1056 Matched = FALSE;\r
1057 VagueMatched1 = FALSE;\r
1058 VagueMatched2 = FALSE;\r
1059\r
1060 Mask = 0;\r
1061 GlobalFontBackup1 = NULL;\r
1062 GlobalFontBackup2 = NULL;\r
1063\r
1064 // The process of where the system default should be supplied instead of\r
1065 // the specified font info beyonds this function's scope.\r
1066 //\r
1067 if (FontInfoMask != NULL) {\r
1068 Mask = *FontInfoMask & (~SYS_FONT_INFO_MASK);\r
1069 }\r
1070\r
1071 //\r
1072 // If not NULL, FontHandle points to the next node of the last searched font\r
1073 // node by previous call.\r
1074 //\r
1075 if (FontHandle == NULL) {\r
1076 Link = Private->FontInfoList.ForwardLink;\r
1077 } else {\r
1078 Link = (LIST_ENTRY *) FontHandle;\r
1079 }\r
1080\r
1081 for (; Link != &Private->FontInfoList; Link = Link->ForwardLink) {\r
1082 GlobalFont = CR (Link, HII_GLOBAL_FONT_INFO, Entry, HII_GLOBAL_FONT_INFO_SIGNATURE);\r
1083 if (FontInfoMask == NULL) {\r
1084 if (CompareMem (GlobalFont->FontInfo, FontInfo, GlobalFont->FontInfoSize) == 0) {\r
1085 if (GlobalFontInfo != NULL) {\r
1086 *GlobalFontInfo = GlobalFont;\r
1087 }\r
1088 return TRUE;\r
1089 }\r
1090 } else {\r
1091 //\r
1092 // Check which options could be used to make a match.\r
1093 //\r
1094 switch (Mask) {\r
1095 case EFI_FONT_INFO_ANY_FONT:\r
1096 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle &&\r
1097 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1098 Matched = TRUE;\r
1099 }\r
1100 break;\r
1101 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE:\r
1102 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1103 Matched = TRUE;\r
1104 }\r
1105 break;\r
1106 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE:\r
1107 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1108 Matched = TRUE;\r
1109 }\r
1110 break;\r
1111 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_ANY_STYLE:\r
1112 Matched = TRUE;\r
1113 break;\r
1114 //\r
1115 // If EFI_FONT_INFO_RESTYLE is specified, then the system may attempt to\r
1116 // remove some of the specified styles to meet the style requested.\r
1117 //\r
1118 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE:\r
1119 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1120 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1121 Matched = TRUE;\r
1122 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1123 VagueMatched1 = TRUE;\r
1124 GlobalFontBackup1 = GlobalFont;\r
1125 }\r
1126 }\r
1127 break;\r
1128 //\r
1129 // If EFI_FONT_INFO_RESIZE is specified, then the sytem may attempt to\r
1130 // stretch or shrink a font to meet the size requested.\r
1131 //\r
1132 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESIZE:\r
1133 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1134 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1135 Matched = TRUE;\r
1136 } else {\r
1137 VagueMatched1 = TRUE;\r
1138 GlobalFontBackup1 = GlobalFont;\r
1139 }\r
1140 }\r
1141 break;\r
1142 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_RESIZE:\r
1143 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1144 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1145 Matched = TRUE;\r
1146 } else {\r
1147 VagueMatched1 = TRUE;\r
1148 GlobalFontBackup1 = GlobalFont;\r
1149 }\r
1150 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1151 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1152 VagueMatched1 = TRUE;\r
1153 GlobalFontBackup1 = GlobalFont;\r
1154 } else {\r
1155 VagueMatched2 = TRUE;\r
1156 GlobalFontBackup2 = GlobalFont;\r
1157 }\r
1158 }\r
1159 break;\r
1160 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
1161 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1162 Matched = TRUE;\r
1163 } else {\r
1164 VagueMatched1 = TRUE;\r
1165 GlobalFontBackup1 = GlobalFont;\r
1166 }\r
1167 break;\r
1168 case EFI_FONT_INFO_ANY_FONT | EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
1169 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1170 Matched = TRUE;\r
1171 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1172 VagueMatched1 = TRUE;\r
1173 GlobalFontBackup1 = GlobalFont;\r
1174 }\r
1175 break;\r
1176 case EFI_FONT_INFO_ANY_STYLE:\r
1177 if ((CompareMem (\r
1178 GlobalFont->FontInfo->FontName,\r
1179 FontInfo->FontName,\r
1180 StrSize (FontInfo->FontName)\r
1181 ) == 0) &&\r
1182 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1183 Matched = TRUE;\r
1184 }\r
1185 break;\r
1186 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_ANY_SIZE:\r
1187 if (CompareMem (\r
1188 GlobalFont->FontInfo->FontName,\r
1189 FontInfo->FontName,\r
1190 StrSize (FontInfo->FontName)\r
1191 ) == 0) {\r
1192 Matched = TRUE;\r
1193 }\r
1194 break;\r
1195 case EFI_FONT_INFO_ANY_STYLE | EFI_FONT_INFO_RESIZE:\r
1196 if (CompareMem (\r
1197 GlobalFont->FontInfo->FontName,\r
1198 FontInfo->FontName,\r
1199 StrSize (FontInfo->FontName)\r
1200 ) == 0) {\r
1201 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1202 Matched = TRUE;\r
1203 } else {\r
1204 VagueMatched1 = TRUE;\r
1205 GlobalFontBackup1 = GlobalFont;\r
1206 }\r
1207 }\r
1208 break;\r
1209 case EFI_FONT_INFO_ANY_SIZE:\r
1210 if ((CompareMem (\r
1211 GlobalFont->FontInfo->FontName,\r
1212 FontInfo->FontName,\r
1213 StrSize (FontInfo->FontName)\r
1214 ) == 0) &&\r
1215 GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1216 Matched = TRUE;\r
1217 }\r
1218 break;\r
1219 case EFI_FONT_INFO_ANY_SIZE | EFI_FONT_INFO_RESTYLE:\r
1220 if (CompareMem (\r
1221 GlobalFont->FontInfo->FontName,\r
1222 FontInfo->FontName,\r
1223 StrSize (FontInfo->FontName)\r
1224 ) == 0) {\r
1225 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1226 Matched = TRUE;\r
1227 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1228 VagueMatched1 = TRUE;\r
1229 GlobalFontBackup1 = GlobalFont;\r
1230 }\r
1231 }\r
1232 break;\r
1233 case EFI_FONT_INFO_RESTYLE:\r
1234 if ((CompareMem (\r
1235 GlobalFont->FontInfo->FontName,\r
1236 FontInfo->FontName,\r
1237 StrSize (FontInfo->FontName)\r
1238 ) == 0) &&\r
1239 GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1240\r
1241 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1242 Matched = TRUE;\r
1243 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1244 VagueMatched1 = TRUE;\r
1245 GlobalFontBackup1 = GlobalFont;\r
1246 }\r
1247 }\r
1248 break;\r
1249 case EFI_FONT_INFO_RESIZE:\r
1250 if ((CompareMem (\r
1251 GlobalFont->FontInfo->FontName,\r
1252 FontInfo->FontName,\r
1253 StrSize (FontInfo->FontName)\r
1254 ) == 0) &&\r
1255 GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1256\r
1257 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1258 Matched = TRUE;\r
1259 } else {\r
1260 VagueMatched1 = TRUE;\r
1261 GlobalFontBackup1 = GlobalFont;\r
1262 }\r
1263 }\r
1264 break;\r
1265 case EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_RESTYLE:\r
1266 if (CompareMem (\r
1267 GlobalFont->FontInfo->FontName,\r
1268 FontInfo->FontName,\r
1269 StrSize (FontInfo->FontName)\r
1270 ) == 0) {\r
1271 if (GlobalFont->FontInfo->FontStyle == FontInfo->FontStyle) {\r
1272 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1273 Matched = TRUE;\r
1274 } else {\r
1275 VagueMatched1 = TRUE;\r
1276 GlobalFontBackup1 = GlobalFont;\r
1277 }\r
1278 } else if ((GlobalFont->FontInfo->FontStyle & FontInfo->FontStyle) == FontInfo->FontStyle) {\r
1279 if (GlobalFont->FontInfo->FontSize == FontInfo->FontSize) {\r
1280 VagueMatched1 = TRUE;\r
1281 GlobalFontBackup1 = GlobalFont;\r
1282 } else {\r
1283 VagueMatched2 = TRUE;\r
1284 GlobalFontBackup2 = GlobalFont;\r
1285 }\r
1286 }\r
1287 }\r
1288 break;\r
1289 default:\r
1290 break;\r
1291 }\r
1292\r
1293 if (Matched) {\r
1294 if (GlobalFontInfo != NULL) {\r
1295 *GlobalFontInfo = GlobalFont;\r
1296 }\r
1297 return TRUE;\r
1298 }\r
1299 }\r
1300 }\r
1301\r
1302 if (VagueMatched1) {\r
1303 if (GlobalFontInfo != NULL) {\r
1304 *GlobalFontInfo = GlobalFontBackup1;\r
1305 }\r
1306 return TRUE;\r
1307 } else if (VagueMatched2) {\r
1308 if (GlobalFontInfo != NULL) {\r
1309 *GlobalFontInfo = GlobalFontBackup2;\r
1310 }\r
1311 return TRUE;\r
1312 }\r
1313\r
1314 return FALSE;\r
1315}\r
1316\r
1317\r
1318/**\r
1319 Check whether the unicode represents a line break or not.\r
1320\r
1321 @param Char Unicode character\r
1322\r
1323 @retval 0 Yes, it is a line break.\r
1324 @retval 1 Yes, it is a hyphen that desires a line break\r
1325 after this character.\r
1326 @retval 2 Yes, it is a dash that desires a line break\r
1327 before and after it.\r
1328 @retval -1 No, it is not a link break.\r
1329\r
1330**/\r
1331STATIC\r
1332INT8\r
1333IsLineBreak (\r
1334 IN CHAR16 Char\r
1335 )\r
1336{\r
1337 UINT8 Byte1;\r
1338 UINT8 Byte2;\r
1339\r
1340 //\r
1341 // In little endian, Byte1 is the low byte of Char, Byte2 is the high byte of Char.\r
1342 //\r
1343 Byte1 = *((UINT8 *) (&Char));\r
1344 Byte2 = *(((UINT8 *) (&Char) + 1));\r
1345\r
1346 if (Byte2 == 0x20) {\r
1347 switch (Byte1) {\r
1348 case 0x00:\r
1349 case 0x01:\r
1350 case 0x02:\r
1351 case 0x03:\r
1352 case 0x04:\r
1353 case 0x05:\r
1354 case 0x06:\r
1355 case 0x08:\r
1356 case 0x09:\r
1357 case 0x0A:\r
1358 case 0x0B:\r
1359 case 0x28:\r
1360 case 0x29:\r
1361 case 0x5F:\r
1362 return 0;\r
1363 case 0x10:\r
1364 case 0x12:\r
1365 case 0x13:\r
1366 return 1;\r
1367 case 0x14:\r
1368 //\r
1369 // BUGBUG: Does it really require line break before it and after it?\r
1370 //\r
1371 return 2;\r
1372 }\r
1373 } else if (Byte2 == 0x00) {\r
1374 switch (Byte1) {\r
1375 case 0x20:\r
1376 case 0x0C:\r
1377 case 0x0D:\r
1378 return 0;\r
1379 }\r
1380 }\r
1381\r
1382 switch (Char) {\r
1383 case 0x1680:\r
1384 return 0;\r
1385 case 0x058A:\r
1386 case 0x0F0B:\r
1387 case 0x1361:\r
1388 case 0x17D5:\r
1389 return 1;\r
1390 }\r
1391\r
1392 return -1;\r
1393}\r
1394\r
1395\r
1396/**\r
1397 Renders a string to a bitmap or to the display.\r
1398\r
1399 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
1400 @param Flags Describes how the string is to be drawn.\r
1401 @param String Points to the null-terminated string to be\r
1402 displayed.\r
1403 @param StringInfo Points to the string output information,\r
1404 including the color and font. If NULL, then the\r
1405 string will be output in the default system font\r
1406 and color.\r
1407 @param Blt If this points to a non-NULL on entry, this\r
1408 points to the image, which is Width pixels wide\r
1409 and Height pixels high. The string will be drawn\r
1410 onto this image and\r
1411 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
1412 to a NULL on entry, then a buffer\r
1413 will be allocated to hold the generated image and\r
ac644614 1414 the pointer updated on exit. It is the caller's\r
93e3992d 1415 responsibility to free this buffer.\r
1416 @param BltX,BLTY Specifies the offset from the left and top edge\r
1417 of the image of the first character cell in the\r
1418 image.\r
1419 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
1420 will point to an allocated buffer containing\r
1421 row information and RowInfoArraySize will be\r
1422 updated to contain the number of elements.\r
1423 This array describes the characters which were at\r
1424 least partially drawn and the heights of the\r
ac644614 1425 rows. It is the caller's responsibility to free\r
93e3992d 1426 this buffer.\r
1427 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
1428 contains the number of elements in RowInfoArray.\r
1429 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
1430 filled with the horizontal offset for each\r
1431 character in the string on the row where it is\r
1432 displayed. Non-printing characters will have\r
1433 the offset ~0. The caller is responsible to\r
1434 allocate a buffer large enough so that there\r
1435 is one entry for each character in the string,\r
1436 not including the null-terminator. It is possible\r
1437 when character display is normalized that some\r
1438 character cells overlap.\r
1439\r
1440 @retval EFI_SUCCESS The string was successfully rendered.\r
1441 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
1442 RowInfoArray or Blt.\r
1443 @retval EFI_INVALID_PARAMETER The String or Blt was NULL.\r
813acf3a 1444 @retval EFI_INVALID_PARAMETER Flags were invalid combination..\r
93e3992d 1445\r
1446**/\r
1447EFI_STATUS\r
1448EFIAPI\r
1449HiiStringToImage (\r
1450 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
1451 IN EFI_HII_OUT_FLAGS Flags,\r
1452 IN CONST EFI_STRING String,\r
1453 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
1454 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
1455 IN UINTN BltX,\r
1456 IN UINTN BltY,\r
1457 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
1458 OUT UINTN *RowInfoArraySize OPTIONAL,\r
1459 OUT UINTN *ColumnInfoArray OPTIONAL\r
1460 )\r
1461{\r
1462 EFI_STATUS Status;\r
1463 HII_DATABASE_PRIVATE_DATA *Private;\r
1464 UINT8 **GlyphBuf;\r
1465 EFI_HII_GLYPH_INFO *Cell;\r
1466 UINT8 *Attributes;\r
1467 EFI_IMAGE_OUTPUT *Image;\r
1468 EFI_STRING StringPtr;\r
1469 EFI_STRING StringTmp;\r
1470 EFI_HII_ROW_INFO *RowInfo;\r
1471 UINTN LineWidth;\r
1472 UINTN LineHeight;\r
1473 UINTN BaseLineOffset;\r
1474 UINT16 MaxRowNum;\r
1475 UINT16 RowIndex;\r
1476 UINTN Index;\r
1477 UINTN Index1;\r
1478 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
1479 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
1480 EFI_FONT_HANDLE FontHandle;\r
1481 EFI_STRING StringIn;\r
1482 EFI_STRING StringIn2;\r
1483 UINT16 Height;\r
1484 EFI_FONT_INFO *FontInfo;\r
1485 BOOLEAN SysFontFlag;\r
1486 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
1487 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
1488 BOOLEAN Transparent;\r
1489 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
1490 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BufferPtr;\r
1491 UINTN RowInfoSize;\r
1492 BOOLEAN LineBreak;\r
1493\r
1494 //\r
1495 // Check incoming parameters.\r
1496 //\r
1497\r
1498 if (This == NULL || String == NULL || Blt == NULL) {\r
1499 return EFI_INVALID_PARAMETER;\r
1500 }\r
1501 if (*Blt == NULL) {\r
1502 //\r
1503 // These two flag cannot be used if Blt is NULL upon entry.\r
1504 //\r
1505 if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT) {\r
1506 return EFI_INVALID_PARAMETER;\r
1507 }\r
1508 if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP) {\r
1509 return EFI_INVALID_PARAMETER;\r
1510 }\r
1511 }\r
1512 //\r
1513 // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.\r
1514 //\r
813acf3a 1515 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X) {\r
93e3992d 1516 return EFI_INVALID_PARAMETER;\r
1517 }\r
813acf3a 1518 if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
93e3992d 1519 return EFI_INVALID_PARAMETER;\r
1520 }\r
1521 //\r
1522 // This flag cannot be used with EFI_HII_OUT_FLAG_CLEAN_X.\r
1523 //\r
813acf3a 1524 if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) {\r
93e3992d 1525 return EFI_INVALID_PARAMETER;\r
1526 }\r
1527\r
1528 GlyphBuf = (UINT8 **) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8 *));\r
1529 ASSERT (GlyphBuf != NULL);\r
1530 Cell = (EFI_HII_GLYPH_INFO *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (EFI_HII_GLYPH_INFO));\r
1531 ASSERT (Cell != NULL);\r
1532 Attributes = (UINT8 *) AllocateZeroPool (MAX_STRING_LENGTH * sizeof (UINT8));\r
1533 ASSERT (Attributes != NULL);\r
1534\r
1535 RowInfo = NULL;\r
1536 Status = EFI_SUCCESS;\r
1537 StringIn2 = NULL;\r
1538 SystemDefault = NULL;\r
1539\r
1540 //\r
1541 // Calculate the string output information, including specified color and font .\r
1542 // If StringInfo does not points to system font info, it must indicate an existing\r
1543 // EFI_FONT_INFO.\r
1544 //\r
1545 StringInfoOut = NULL;\r
1546 FontHandle = NULL;\r
1547 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
1548 SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
1549\r
1550 if (SysFontFlag) {\r
1551 FontInfo = NULL;\r
1552 Height = SystemDefault->FontInfo.FontSize;\r
1553 Foreground = SystemDefault->ForegroundColor;\r
1554 Background = SystemDefault->BackgroundColor;\r
1555\r
1556 } else {\r
1557 Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *) StringInfo, &StringInfoOut, NULL);\r
1558 if (Status == EFI_NOT_FOUND) {\r
1559 //\r
1560 // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.\r
1561 // Use the system font instead. Still use the color specified by StringInfo.\r
1562 //\r
1563 SysFontFlag = TRUE;\r
1564 FontInfo = NULL;\r
1565 Height = SystemDefault->FontInfo.FontSize;\r
1566 Foreground = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->ForegroundColor;\r
1567 Background = ((EFI_FONT_DISPLAY_INFO *) StringInfo)->BackgroundColor;\r
1568\r
1569 } else {\r
1570 FontInfo = &StringInfoOut->FontInfo;\r
1571 Height = StringInfoOut->FontInfo.FontSize;\r
1572 Foreground = StringInfoOut->ForegroundColor;\r
1573 Background = StringInfoOut->BackgroundColor;\r
1574 }\r
1575 }\r
1576\r
1577 //\r
1578 // Parse the string to be displayed to drop some ignored characters.\r
1579 //\r
1580\r
1581 StringPtr = String;\r
1582 StringIn = NULL;\r
1583\r
1584 //\r
1585 // Ignore line-break characters only. Hyphens or dash character will be displayed\r
1586 // without line-break opportunity.\r
1587 //\r
1588 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {\r
1589 StringIn = AllocateZeroPool (StrSize (StringPtr));\r
1590 if (StringIn == NULL) {\r
1591 Status = EFI_OUT_OF_RESOURCES;\r
1592 goto Exit;\r
1593 }\r
1594 StringTmp = StringIn;\r
1595 while (*StringPtr != 0) {\r
1596 if (IsLineBreak (*StringPtr) == 0) {\r
1597 StringPtr++;\r
1598 } else {\r
1599 *StringTmp++ = *StringPtr++;\r
1600 }\r
1601 }\r
1602 *StringTmp = 0;\r
1603 StringPtr = StringIn;\r
1604 }\r
1605 //\r
1606 // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs\r
1607 // are not drawn. Otherwise they are replaced wth Unicode character 0xFFFD.\r
1608 //\r
1609 StringIn2 = AllocateZeroPool (StrSize (StringPtr));\r
1610 if (StringIn2 == NULL) {\r
1611 Status = EFI_OUT_OF_RESOURCES;\r
1612 goto Exit;\r
1613 }\r
1614 Index = 0;\r
1615 StringTmp = StringIn2;\r
1616\r
1617 while (*StringPtr != 0 && Index < MAX_STRING_LENGTH) {\r
1618 Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);\r
1619 if (Status == EFI_NOT_FOUND) {\r
1620 if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {\r
1621 SafeFreePool (GlyphBuf[Index]);\r
1622 GlyphBuf[Index] = NULL;\r
1623 StringPtr++;\r
1624 } else {\r
1625 //\r
1626 // Unicode 0xFFFD must exist in current hii database if this flag is not set.\r
1627 //\r
1628 Status = GetGlyphBuffer (\r
1629 Private,\r
1630 REPLACE_UNKNOWN_GLYPH,\r
1631 FontInfo,\r
1632 &GlyphBuf[Index],\r
1633 &Cell[Index],\r
1634 &Attributes[Index]\r
1635 );\r
1636 if (EFI_ERROR (Status)) {\r
1637 Status = EFI_INVALID_PARAMETER;\r
1638 goto Exit;\r
1639 }\r
1640 *StringTmp++ = *StringPtr++;\r
1641 Index++;\r
1642 }\r
1643 } else if (EFI_ERROR (Status)) {\r
1644 goto Exit;\r
1645 } else {\r
1646 *StringTmp++ = *StringPtr++;\r
1647 Index++;\r
1648 }\r
1649 }\r
1650 *StringTmp = 0;\r
1651 StringPtr = StringIn2;\r
1652\r
1653 //\r
1654 // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.\r
1655 // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string\r
1656 // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".\r
1657 // Otherwise render this string to a new allocated image and output it.\r
1658 //\r
1659 if (*Blt != NULL) {\r
1660 Image = *Blt;\r
1661 BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;\r
1662 MaxRowNum = (UINT16) (Image->Height / Height);\r
1663 if (Image->Height % Height != 0) {\r
1664 MaxRowNum++;\r
1665 }\r
1666\r
1667 RowInfo = (EFI_HII_ROW_INFO *) AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));\r
1668 if (RowInfo == NULL) {\r
1669 Status = EFI_OUT_OF_RESOURCES;\r
1670 goto Exit;\r
1671 }\r
1672\r
1673 //\r
1674 // Format the glyph buffer according to flags.\r
1675 //\r
1676\r
1677 Transparent = (BOOLEAN) ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);\r
813acf3a 1678 if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
93e3992d 1679 //\r
1680 // Don't draw at all if there is only one row and\r
1681 // the row's bottom-most on pixel cannot fit.\r
1682 //\r
1683 if (MaxRowNum == 1 && SysFontFlag) {\r
1684 Status = EFI_SUCCESS;\r
1685 goto Exit;\r
1686 }\r
1687 }\r
1688\r
1689 for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {\r
1690 LineWidth = 0;\r
1691 LineHeight = 0;\r
1692 BaseLineOffset = 0;\r
1693 LineBreak = FALSE;\r
1694\r
1695 //\r
1696 // Calculate how many characters there are in a row.\r
1697 //\r
1698 RowInfo[RowIndex].StartIndex = Index;\r
1699\r
1700 while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {\r
1701 LineWidth += (UINTN) Cell[Index].AdvanceX;\r
1702 if (LineHeight < Cell[Index].Height) {\r
1703 LineHeight = (UINTN) Cell[Index].Height;\r
1704 }\r
1705 BaseLineOffset += (UINTN) Cell[Index].OffsetY;\r
1706\r
1707 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0 &&\r
1708 (Flags & EFI_HII_OUT_FLAG_WRAP) == 0 &&\r
1709 IsLineBreak (StringPtr[Index]) > 0) {\r
1710 //\r
1711 // It is a line break that ends this row.\r
1712 //\r
1713 Index++;\r
1714 break;\r
1715 }\r
1716\r
1717 Index++;\r
1718 }\r
1719\r
1720 //\r
1721 // If this character is the last character of a row, we need not\r
1722 // draw its (AdvanceX - Width) for next character.\r
1723 //\r
1724 Index--;\r
1725 if (!SysFontFlag) {\r
1726 LineWidth -= (UINTN) (Cell[Index].AdvanceX - Cell[Index].Width);\r
1727 }\r
1728\r
1729 //\r
1730 // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break\r
1731 // opportunity prior to a character whose right-most extent would exceed Width.\r
1732 // Search the right-most line-break opportunity here.\r
1733 //\r
1734 if ((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) {\r
1735 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {\r
1736 for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {\r
1737 if (IsLineBreak (StringPtr[Index1]) > 0) {\r
1738 LineBreak = TRUE;\r
1739 RowInfo[RowIndex].EndIndex = Index1 - 1;\r
1740 break;\r
1741 }\r
1742 }\r
1743 }\r
1744 //\r
1745 // If no line-break opportunity can be found, then the text will\r
1746 // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.\r
1747 //\r
1748 if (!LineBreak) {\r
1749 Flags &= (~ (EFI_HII_OUT_FLAGS) EFI_HII_OUT_FLAG_WRAP);\r
813acf3a 1750 Flags |= EFI_HII_OUT_FLAG_CLIP_CLEAN_X;\r
93e3992d 1751 }\r
1752 }\r
1753\r
1754 //\r
1755 // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.\r
1756 //\r
1757 if (LineWidth + BltX <= Image->Width ||\r
813acf3a 1758 (LineWidth + BltX > Image->Width && (Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)) {\r
93e3992d 1759 //\r
1760 // Record right-most character in RowInfo even if it is partially displayed.\r
1761 //\r
1762 RowInfo[RowIndex].EndIndex = Index;\r
1763 RowInfo[RowIndex].LineWidth = LineWidth;\r
1764 RowInfo[RowIndex].LineHeight = LineHeight;\r
1765 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;\r
1766 } else {\r
1767 //\r
1768 // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character\r
1769 // if its right-most on pixel cannot fit.\r
1770 //\r
1771 if (Index > 0) {\r
1772 RowInfo[RowIndex].EndIndex = Index - 1;\r
1773 RowInfo[RowIndex].LineWidth = LineWidth - Cell[Index].AdvanceX;\r
1774 RowInfo[RowIndex].BaselineOffset = BaseLineOffset - Cell[Index].OffsetY;\r
1775 if (LineHeight > Cell[Index - 1].Height) {\r
1776 LineHeight = Cell[Index - 1].Height;\r
1777 }\r
1778 RowInfo[RowIndex].LineHeight = LineHeight;\r
1779 } else {\r
1780 //\r
1781 // There is only one column and it can not be drawn so that return directly.\r
1782 //\r
1783 Status = EFI_SUCCESS;\r
1784 goto Exit;\r
1785 }\r
1786 }\r
1787\r
1788 //\r
1789 // Clip the final row if the row's bottom-most on pixel cannot fit when\r
1790 // EFI_HII_OUT_FLAG_CLEAN_Y is set.\r
1791 //\r
1792 if (RowIndex == MaxRowNum - 1 && Image->Height < LineHeight) {\r
1793 LineHeight = Image->Height;\r
813acf3a 1794 if ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) {\r
93e3992d 1795 //\r
1796 // Don't draw at all if the row's bottom-most on pixel cannot fit.\r
1797 //\r
1798 break;\r
1799 }\r
1800 }\r
1801\r
1802 //\r
1803 // Draw it to screen or existing bitmap depending on whether\r
1804 // EFI_HII_DIRECT_TO_SCREEN is set.\r
1805 //\r
1806 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {\r
1807 BltBuffer = AllocateZeroPool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1808 if (BltBuffer == NULL) {\r
1809 Status = EFI_OUT_OF_RESOURCES;\r
1810 goto Exit;\r
1811 }\r
1812 BufferPtr = BltBuffer;\r
1813 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
1814 GlyphToImage (\r
1815 GlyphBuf[Index1],\r
1816 Foreground,\r
1817 Background,\r
1818 RowInfo[RowIndex].LineWidth,\r
1819 RowInfo[RowIndex].LineHeight,\r
1820 Transparent,\r
50b39985 1821 &Cell[Index1],\r
93e3992d 1822 Attributes[Index1],\r
1823 &BufferPtr\r
1824 );\r
1825 if (ColumnInfoArray != NULL) {\r
1826 if (Index1 == RowInfo[RowIndex].StartIndex) {\r
1827 *ColumnInfoArray = 0;\r
1828 } else {\r
1829 *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
1830 }\r
1831 ColumnInfoArray++;\r
1832 }\r
1833 }\r
1834 Status = Image->Image.Screen->Blt (\r
1835 Image->Image.Screen,\r
1836 BltBuffer,\r
1837 EfiBltBufferToVideo,\r
1838 0,\r
1839 0,\r
1840 BltX,\r
1841 BltY,\r
1842 RowInfo[RowIndex].LineWidth,\r
1843 RowInfo[RowIndex].LineHeight,\r
1844 0\r
1845 );\r
1846 if (EFI_ERROR (Status)) {\r
1847 SafeFreePool (BltBuffer);\r
1848 goto Exit;\r
1849 }\r
1850\r
1851 SafeFreePool (BltBuffer);\r
1852\r
1853 } else {\r
1854 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {\r
1855 GlyphToImage (\r
1856 GlyphBuf[Index1],\r
1857 Foreground,\r
1858 Background,\r
1859 Image->Width,\r
1860 Image->Height,\r
1861 Transparent,\r
50b39985 1862 &Cell[Index1],\r
93e3992d 1863 Attributes[Index1],\r
1864 &BufferPtr\r
1865 );\r
1866 if (ColumnInfoArray != NULL) {\r
1867 if (Index1 == RowInfo[RowIndex].StartIndex) {\r
1868 *ColumnInfoArray = 0;\r
1869 } else {\r
1870 *ColumnInfoArray = Cell[Index1 -1].AdvanceX;\r
1871 }\r
1872 ColumnInfoArray++;\r
1873 }\r
1874 }\r
1875 //\r
1876 // Jump to next row\r
1877 //\r
1878 BufferPtr += BltX + Image->Width * (LineHeight - 1);\r
1879 }\r
1880\r
1881 Index++;\r
1882 RowIndex++;\r
1883\r
1884 }\r
1885\r
1886 //\r
1887 // Write output parameters.\r
1888 //\r
1889 RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);\r
1890 if (RowInfoArray != NULL) {\r
1891 *RowInfoArray = AllocateZeroPool (RowInfoSize);\r
1892 if (*RowInfoArray == NULL) {\r
1893 Status = EFI_OUT_OF_RESOURCES;\r
1894 goto Exit;\r
1895 }\r
1896 CopyMem (*RowInfoArray, RowInfo, RowInfoSize);\r
1897 }\r
1898 if (RowInfoArraySize != NULL) {\r
1899 *RowInfoArraySize = RowIndex;\r
1900 }\r
1901\r
1902 } else {\r
1903 //\r
1904 // Create a new bitmap and draw the string onto this image.\r
1905 //\r
1906 Image = AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
1907 if (Image == NULL) {\r
1908 return EFI_OUT_OF_RESOURCES;\r
1909 }\r
1910 Image->Width = 800;\r
1911 Image->Height = 600;\r
1912 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height *sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
1913 if (Image->Image.Bitmap == NULL) {\r
1914 SafeFreePool (Image);\r
1915 return EFI_OUT_OF_RESOURCES;\r
1916 }\r
1917\r
1918 //\r
1919 // Other flags are not permitted when Blt is NULL.\r
1920 //\r
1921 Flags &= EFI_HII_OUT_FLAG_WRAP | EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_IGNORE_LINE_BREAK;\r
1922 Status = HiiStringToImage (\r
1923 This,\r
1924 Flags,\r
1925 String,\r
1926 StringInfo,\r
1927 &Image,\r
1928 BltX,\r
1929 BltY,\r
1930 RowInfoArray,\r
1931 RowInfoArraySize,\r
1932 ColumnInfoArray\r
1933 );\r
1934 if (EFI_ERROR (Status)) {\r
1935 return Status;\r
1936 }\r
1937\r
1938 *Blt = Image;\r
1939 }\r
1940\r
1941 Status = EFI_SUCCESS;\r
1942\r
1943Exit:\r
1944\r
1945 for (Index = 0; Index < MAX_STRING_LENGTH; Index++) {\r
1946 SafeFreePool (GlyphBuf[Index]);\r
1947 }\r
1948 SafeFreePool (StringIn);\r
1949 SafeFreePool (StringIn2);\r
1950 SafeFreePool (StringInfoOut);\r
1951 SafeFreePool (RowInfo);\r
1952 SafeFreePool (SystemDefault);\r
1953 SafeFreePool (GlyphBuf);\r
1954 SafeFreePool (Cell);\r
1955 SafeFreePool (Attributes);\r
1956\r
1957 return Status;\r
1958}\r
1959\r
1960\r
1961/**\r
1962 Render a string to a bitmap or the screen containing the contents of the specified string.\r
1963\r
1964 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
1965 @param Flags Describes how the string is to be drawn.\r
1966 @param PackageList The package list in the HII database to search\r
1967 for the specified string.\r
ac644614 1968 @param StringId The string's id, which is unique within\r
93e3992d 1969 PackageList.\r
1970 @param Language Points to the language for the retrieved string.\r
1971 If NULL, then the current system language is\r
1972 used.\r
1973 @param StringInfo Points to the string output information,\r
1974 including the color and font. If NULL, then the\r
1975 string will be output in the default system font\r
1976 and color.\r
1977 @param Blt If this points to a non-NULL on entry, this\r
1978 points to the image, which is Width pixels wide\r
1979 and Height pixels high. The string will be drawn\r
1980 onto this image and\r
1981 EFI_HII_OUT_FLAG_CLIP is implied. If this points\r
1982 to a NULL on entry, then a buffer\r
1983 will be allocated to hold the generated image and\r
ac644614 1984 the pointer updated on exit. It is the caller's\r
93e3992d 1985 responsibility to free this buffer.\r
1986 @param BltX,BLTY Specifies the offset from the left and top edge\r
1987 of the image of the first character cell in the\r
1988 image.\r
1989 @param RowInfoArray If this is non-NULL on entry, then on exit, this\r
1990 will point to an allocated buffer containing\r
1991 row information and RowInfoArraySize will be\r
1992 updated to contain the number of elements.\r
1993 This array describes the characters which were at\r
1994 least partially drawn and the heights of the\r
ac644614 1995 rows. It is the caller's responsibility to free\r
93e3992d 1996 this buffer.\r
1997 @param RowInfoArraySize If this is non-NULL on entry, then on exit it\r
1998 contains the number of elements in RowInfoArray.\r
1999 @param ColumnInfoArray If this is non-NULL, then on return it will be\r
2000 filled with the horizontal offset for each\r
2001 character in the string on the row where it is\r
2002 displayed. Non-printing characters will have\r
2003 the offset ~0. The caller is responsible to\r
2004 allocate a buffer large enough so that there\r
2005 is one entry for each character in the string,\r
2006 not including the null-terminator. It is possible\r
2007 when character display is normalized that some\r
2008 character cells overlap.\r
2009\r
2010 @retval EFI_SUCCESS The string was successfully rendered.\r
2011 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for\r
2012 RowInfoArray or Blt.\r
813acf3a 2013 @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.\r
2014 @retval EFI_INVALID_PARAMETER Flags were invalid combination.\r
2015 @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the stringid is not \r
2016 in the specified PackageList. \r
93e3992d 2017\r
2018**/\r
2019EFI_STATUS\r
2020EFIAPI\r
2021HiiStringIdToImage (\r
2022 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2023 IN EFI_HII_OUT_FLAGS Flags,\r
2024 IN EFI_HII_HANDLE PackageList,\r
2025 IN EFI_STRING_ID StringId,\r
2026 IN CONST CHAR8* Language,\r
2027 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,\r
2028 IN OUT EFI_IMAGE_OUTPUT **Blt,\r
2029 IN UINTN BltX,\r
2030 IN UINTN BltY,\r
2031 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,\r
2032 OUT UINTN *RowInfoArraySize OPTIONAL,\r
2033 OUT UINTN *ColumnInfoArray OPTIONAL\r
2034 )\r
2035{\r
2036 EFI_STATUS Status;\r
2037 HII_DATABASE_PRIVATE_DATA *Private;\r
2038 EFI_STRING String;\r
2039 UINTN StringSize;\r
813acf3a 2040 UINTN FontLen;\r
2041 EFI_FONT_INFO *StringFontInfo;\r
2042 EFI_FONT_DISPLAY_INFO *NewStringInfo;\r
2043 CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];\r
93e3992d 2044\r
2045 if (This == NULL || PackageList == NULL || Blt == NULL || PackageList == NULL) {\r
2046 return EFI_INVALID_PARAMETER;\r
2047 }\r
2048\r
2049 if (!IsHiiHandleValid (PackageList)) {\r
2050 return EFI_NOT_FOUND;\r
2051 }\r
2052\r
813acf3a 2053 //\r
2054 // When Language points to NULL, current system language is used.\r
2055 //\r
2056 if (Language != NULL) {\r
2057 AsciiStrCpy (CurrentLang, (CHAR8 *) Language);\r
2058 } else {\r
2059 HiiLibGetCurrentLanguage (CurrentLang);\r
2060 }\r
93e3992d 2061\r
2062 //\r
2063 // Get the string to be displayed.\r
2064 //\r
2065\r
2066 StringSize = MAX_STRING_LENGTH;\r
2067 String = (EFI_STRING) AllocateZeroPool (StringSize);\r
2068 if (String == NULL) {\r
2069 return EFI_OUT_OF_RESOURCES;\r
2070 }\r
2071\r
813acf3a 2072 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2073 StringFontInfo = NULL;\r
2074 NewStringInfo = NULL;\r
2075 \r
93e3992d 2076 Status = Private->HiiString.GetString (\r
2077 &Private->HiiString,\r
813acf3a 2078 CurrentLang,\r
93e3992d 2079 PackageList,\r
2080 StringId,\r
2081 String,\r
2082 &StringSize,\r
813acf3a 2083 &StringFontInfo\r
93e3992d 2084 );\r
2085 if (Status == EFI_BUFFER_TOO_SMALL) {\r
2086 SafeFreePool (String);\r
2087 String = (EFI_STRING) AllocateZeroPool (StringSize);\r
2088 if (String == NULL) {\r
2089 return EFI_OUT_OF_RESOURCES;\r
2090 }\r
2091 Status = Private->HiiString.GetString (\r
2092 &Private->HiiString,\r
2093 Language,\r
2094 PackageList,\r
2095 StringId,\r
2096 String,\r
2097 &StringSize,\r
2098 NULL\r
2099 );\r
2100\r
2101 }\r
2102\r
2103 if (EFI_ERROR (Status)) {\r
813acf3a 2104 goto Exit;\r
2105 }\r
2106 \r
2107 //\r
2108 // When StringInfo specifies that string will be output in the system default font and color,\r
2109 // use particular stringfontinfo described in string package instead if exists. \r
2110 // StringFontInfo equals NULL means system default font attaches with the string block.\r
2111 //\r
2112 if (StringFontInfo != NULL && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, NULL, NULL)) {\r
2113 FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + StrSize (StringFontInfo->FontName);\r
2114 NewStringInfo = AllocateZeroPool (FontLen);\r
2115 if (NewStringInfo == NULL) { \r
2116 Status = EFI_OUT_OF_RESOURCES;\r
2117 goto Exit;\r
2118 }\r
2119 NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;\r
2120 NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;\r
2121 NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize; \r
2122 StrCpy (NewStringInfo->FontInfo.FontName, StringFontInfo->FontName);\r
2123 \r
2124 Status = HiiStringToImage (\r
2125 This, \r
2126 Flags, \r
2127 String, \r
2128 NewStringInfo, \r
2129 Blt, \r
2130 BltX, \r
2131 BltY, \r
2132 RowInfoArray,\r
2133 RowInfoArraySize,\r
2134 ColumnInfoArray\r
2135 );\r
2136 goto Exit;\r
93e3992d 2137 }\r
2138\r
813acf3a 2139 Status = HiiStringToImage (\r
93e3992d 2140 This,\r
2141 Flags,\r
2142 String,\r
2143 StringInfo,\r
2144 Blt,\r
2145 BltX,\r
2146 BltY,\r
2147 RowInfoArray,\r
2148 RowInfoArraySize,\r
2149 ColumnInfoArray\r
2150 );\r
2151\r
813acf3a 2152Exit:\r
2153 SafeFreePool (String);\r
2154 SafeFreePool (StringFontInfo);\r
2155 SafeFreePool (NewStringInfo);\r
2156\r
2157 return Status;\r
93e3992d 2158}\r
2159\r
2160\r
2161/**\r
2162 Convert the glyph for a single character into a bitmap.\r
2163\r
2164 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2165 @param Char Character to retrieve.\r
2166 @param StringInfo Points to the string font and color information\r
2167 or NULL if the string should use the default\r
2168 system font and color.\r
2169 @param Blt Thus must point to a NULL on entry. A buffer will\r
2170 be allocated to hold the output and the pointer\r
ac644614 2171 updated on exit. It is the caller's\r
93e3992d 2172 responsibility to free this buffer.\r
2173 @param Baseline Number of pixels from the bottom of the bitmap to\r
2174 the baseline.\r
2175\r
2176 @retval EFI_SUCCESS Glyph bitmap created.\r
2177 @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.\r
2178 @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the\r
2179 glyph for Unicode character 0xFFFD.\r
2180 @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.\r
2181\r
2182**/\r
2183EFI_STATUS\r
2184EFIAPI\r
2185HiiGetGlyph (\r
2186 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2187 IN CHAR16 Char,\r
2188 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,\r
2189 OUT EFI_IMAGE_OUTPUT **Blt,\r
2190 OUT UINTN *Baseline OPTIONAL\r
2191 )\r
2192{\r
2193 EFI_STATUS Status;\r
2194 HII_DATABASE_PRIVATE_DATA *Private;\r
2195 EFI_IMAGE_OUTPUT *Image;\r
2196 UINT8 *GlyphBuffer;\r
2197 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2198 EFI_FONT_DISPLAY_INFO *StringInfoOut;\r
2199 BOOLEAN Default;\r
2200 EFI_FONT_HANDLE FontHandle;\r
2201 EFI_STRING String;\r
2202 EFI_HII_GLYPH_INFO Cell;\r
2203 EFI_FONT_INFO *FontInfo;\r
2204 UINT8 Attributes;\r
2205 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
2206 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
2207 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
2208\r
2209 if (This == NULL || Blt == NULL || *Blt != NULL) {\r
2210 return EFI_INVALID_PARAMETER;\r
2211 }\r
2212\r
2213 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2214\r
2215 Default = FALSE;\r
2216 Image = NULL;\r
2217 SystemDefault = NULL;\r
2218 FontHandle = NULL;\r
2219 String = NULL;\r
2220 GlyphBuffer = NULL;\r
2221 StringInfoOut = NULL;\r
2222 FontInfo = NULL;\r
2223\r
2224 ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2225 ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2226\r
2227 Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfo, &SystemDefault, NULL);\r
2228\r
2229 if (!Default) {\r
2230 //\r
2231 // Find out a EFI_FONT_DISPLAY_INFO which could display the character in\r
2232 // the specified color and font.\r
2233 //\r
2234 String = (EFI_STRING) AllocateZeroPool (sizeof (CHAR16) * 2);\r
2235 if (String == NULL) {\r
2236 Status = EFI_OUT_OF_RESOURCES;\r
2237 goto Exit;\r
2238 }\r
2239 *String = Char;\r
2240 *(String + 1) = 0;\r
2241\r
2242 Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);\r
2243 if (EFI_ERROR (Status)) {\r
2244 goto Exit;\r
2245 }\r
2246 FontInfo = &StringInfoOut->FontInfo;\r
2247 Foreground = StringInfoOut->ForegroundColor;\r
2248 Background = StringInfoOut->BackgroundColor;\r
2249 } else {\r
2250 Foreground = SystemDefault->ForegroundColor;\r
2251 Background = SystemDefault->BackgroundColor;\r
2252 }\r
2253\r
2254 Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);\r
2255 if (EFI_ERROR (Status)) {\r
2256 goto Exit;\r
2257 }\r
2258\r
2259 Image = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
2260 if (Image == NULL) {\r
2261 Status = EFI_OUT_OF_RESOURCES;\r
2262 goto Exit;\r
2263 }\r
2264 Image->Width = Cell.Width;\r
2265 Image->Height = Cell.Height;\r
2266\r
2267 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
2268 if (Image->Image.Bitmap == NULL) {\r
2269 SafeFreePool (Image);\r
2270 Status = EFI_OUT_OF_RESOURCES;\r
2271 goto Exit;\r
2272 }\r
2273\r
2274 BltBuffer = Image->Image.Bitmap;\r
2275 GlyphToImage (\r
2276 GlyphBuffer,\r
2277 Foreground,\r
2278 Background,\r
2279 Image->Width,\r
2280 Image->Height,\r
2281 FALSE,\r
50b39985 2282 &Cell,\r
93e3992d 2283 Attributes,\r
2284 &BltBuffer\r
2285 );\r
2286\r
2287 *Blt = Image;\r
2288 if (Baseline != NULL) {\r
2289 *Baseline = Cell.OffsetY;\r
2290 }\r
2291\r
2292 Status = EFI_SUCCESS;\r
2293\r
2294Exit:\r
2295\r
2296 if (Status == EFI_NOT_FOUND) {\r
2297 //\r
2298 // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD\r
2299 //\r
2300 if (Char != REPLACE_UNKNOWN_GLYPH) {\r
2301 Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);\r
2302 if (!EFI_ERROR (Status)) {\r
2303 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2304 }\r
2305 } else {\r
2306 Status = EFI_WARN_UNKNOWN_GLYPH;\r
2307 }\r
2308 }\r
2309\r
2310 SafeFreePool (SystemDefault);\r
2311 SafeFreePool (StringInfoOut);\r
2312 SafeFreePool (String);\r
2313 SafeFreePool (GlyphBuffer);\r
2314\r
2315 return Status;\r
2316}\r
2317\r
2318\r
2319/**\r
2320 This function iterates through fonts which match the specified font, using\r
2321 the specified criteria. If String is non-NULL, then all of the characters in\r
2322 the string must exist in order for a candidate font to be returned.\r
2323\r
2324 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.\r
2325 @param FontHandle On entry, points to the font handle returned by a\r
2326 previous call to GetFontInfo() or NULL to start\r
2327 with the first font. On return, points to the\r
2328 returned font handle or points to NULL if there\r
2329 are no more matching fonts.\r
2330 @param StringInfoIn Upon entry, points to the font to return\r
813acf3a 2331 information about. \r
2332 If NULL, then the information about the system default \r
2333 font will be returned.\r
ac644614 2334 @param StringInfoOut Upon return, contains the matching font's\r
93e3992d 2335 information. If NULL, then no information is\r
2336 returned. It's caller's responsibility to free\r
2337 this buffer.\r
2338 @param String Points to the string which will be tested to\r
2339 determine if all characters are available. If\r
2340 NULL, then any font is acceptable.\r
2341\r
2342 @retval EFI_SUCCESS Matching font returned successfully.\r
2343 @retval EFI_NOT_FOUND No matching font was found.\r
813acf3a 2344 @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.\r
93e3992d 2345 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the\r
2346 request.\r
2347\r
2348**/\r
2349EFI_STATUS\r
2350EFIAPI\r
2351HiiGetFontInfo (\r
2352 IN CONST EFI_HII_FONT_PROTOCOL *This,\r
2353 IN OUT EFI_FONT_HANDLE *FontHandle,\r
813acf3a 2354 IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn, OPTIONAL\r
93e3992d 2355 OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,\r
2356 IN CONST EFI_STRING String OPTIONAL\r
2357 )\r
2358{\r
2359 HII_DATABASE_PRIVATE_DATA *Private;\r
2360 EFI_STATUS Status;\r
2361 EFI_FONT_DISPLAY_INFO *SystemDefault;\r
2362 EFI_FONT_DISPLAY_INFO InfoOut;\r
2363 UINTN StringInfoOutLen;\r
2364 EFI_FONT_INFO *FontInfo;\r
2365 HII_GLOBAL_FONT_INFO *GlobalFont;\r
2366 EFI_STRING StringIn;\r
2367 EFI_FONT_HANDLE LocalFontHandle;\r
2368\r
813acf3a 2369 if (This == NULL) {\r
93e3992d 2370 return EFI_INVALID_PARAMETER;\r
2371 }\r
2372\r
2373 FontInfo = NULL;\r
813acf3a 2374 SystemDefault = NULL;\r
93e3992d 2375 LocalFontHandle = NULL;\r
2376 if (FontHandle != NULL) {\r
2377 LocalFontHandle = *FontHandle;\r
2378 }\r
2379\r
813acf3a 2380 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);\r
2381\r
2382 //\r
2383 // Already searched to the end of the whole list, return directly.\r
2384 //\r
2385 if (LocalFontHandle == &Private->FontInfoList) {\r
2386 LocalFontHandle = NULL;\r
2387 Status = EFI_NOT_FOUND;\r
2388 goto Exit;\r
2389 }\r
2390\r
93e3992d 2391 //\r
2392 // Get default system display info, if StringInfoIn points to\r
2393 // system display info, return it directly.\r
2394 //\r
93e3992d 2395 if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, &SystemDefault, &StringInfoOutLen)) {\r
813acf3a 2396 //\r
2397 // System font is the first node. When handle is not NULL, system font can not\r
2398 // be found any more.\r
2399 //\r
2400 if (LocalFontHandle == NULL) {\r
2401 if (StringInfoOut != NULL) {\r
2402 *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);\r
2403 if (*StringInfoOut == NULL) {\r
2404 Status = EFI_OUT_OF_RESOURCES;\r
2405 LocalFontHandle = NULL;\r
2406 goto Exit;\r
2407 }\r
93e3992d 2408 }\r
813acf3a 2409\r
2410 LocalFontHandle = Private->FontInfoList.ForwardLink;\r
2411 Status = EFI_SUCCESS;\r
2412 goto Exit;\r
2413 } else {\r
2414 LocalFontHandle = NULL;\r
2415 Status = EFI_NOT_FOUND;\r
2416 goto Exit;\r
93e3992d 2417 }\r
813acf3a 2418 }\r
93e3992d 2419\r
813acf3a 2420 //\r
2421 // Check the font information mask to make sure it is valid.\r
2422 //\r
2423 if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) == \r
2424 (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||\r
2425 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) == \r
2426 (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||\r
2427 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) == \r
2428 (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||\r
2429 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) == \r
2430 (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) || \r
2431 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) == \r
2432 (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE))) {\r
2433 return EFI_INVALID_PARAMETER;\r
93e3992d 2434 }\r
2435\r
2436 //\r
2437 // Parse the font information mask to find a matching font.\r
2438 //\r
2439\r
2440 CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *) StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));\r
2441\r
2442 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {\r
2443 Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);\r
2444 } else {\r
2445 Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *) StringInfoIn)->FontInfo.FontName, &FontInfo);\r
2446 }\r
2447 if (EFI_ERROR (Status)) {\r
2448 goto Exit;\r
2449 }\r
2450\r
2451 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {\r
2452 InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;\r
813acf3a 2453 } \r
2454 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {\r
93e3992d 2455 InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;\r
813acf3a 2456 }\r
2457 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {\r
93e3992d 2458 InfoOut.ForegroundColor = SystemDefault->ForegroundColor;\r
813acf3a 2459 }\r
2460 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {\r
93e3992d 2461 InfoOut.BackgroundColor = SystemDefault->BackgroundColor;\r
2462 }\r
813acf3a 2463 \r
93e3992d 2464\r
2465 FontInfo->FontSize = InfoOut.FontInfo.FontSize;\r
2466 FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;\r
2467\r
2468 if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {\r
2469 if (String != NULL) {\r
2470 //\r
2471 // Test to guarantee all characters are available in the found font.\r
2472 //\r
2473 StringIn = String;\r
2474 while (*StringIn != 0) {\r
2475 Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);\r
2476 if (EFI_ERROR (Status)) {\r
2477 LocalFontHandle = NULL;\r
2478 goto Exit;\r
2479 }\r
2480 StringIn++;\r
2481 }\r
2482\r
2483 //\r
2484 // Write to output parameter\r
2485 //\r
2486 if (StringInfoOut != NULL) {\r
2487 StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;\r
2488 *StringInfoOut = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (StringInfoOutLen);\r
2489 if (*StringInfoOut == NULL) {\r
2490 Status = EFI_OUT_OF_RESOURCES;\r
2491 LocalFontHandle = NULL;\r
2492 goto Exit;\r
2493 }\r
2494 CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));\r
2495 CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);\r
2496 }\r
2497 LocalFontHandle = GlobalFont->Entry.ForwardLink;\r
2498\r
2499 Status = EFI_SUCCESS;\r
2500 goto Exit;\r
2501 }\r
2502 } else {\r
2503 LocalFontHandle = NULL;\r
2504 }\r
2505\r
2506 Status = EFI_NOT_FOUND;\r
2507\r
2508Exit:\r
2509\r
2510 if (FontHandle != NULL) {\r
2511 *FontHandle = LocalFontHandle;\r
2512 }\r
2513\r
2514 SafeFreePool (SystemDefault);\r
2515 SafeFreePool (FontInfo);\r
2516 return Status;\r
2517}\r
2518\r
813acf3a 2519\r