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