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