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