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