VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c@ 105670

最後變更 在這個檔案從105670是 101291,由 vboxsync 提交於 18 月 前

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 98.7 KB
 
1/** @file
2Implementation for EFI_HII_FONT_PROTOCOL.
3
4
5Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include "HiiDatabase.h"
11
12EFI_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**/
49EFI_STATUS
50NewCell (
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**/
97EFI_STATUS
98GetCell (
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**/
150EFI_STATUS
151GetGlyphBuffer (
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**/
285VOID
286NarrowGlyphToBlt (
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**/
364VOID
365GlyphToBlt (
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**/
480VOID
481GlyphToImage (
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**/
602EFI_STATUS
603WriteOutputParam (
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**/
657EFI_STATUS
658FindGlyphBlock (
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**/
955EFI_STATUS
956SaveFontName (
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**/
992EFI_STATUS
993GetSystemFont (
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**/
1055BOOLEAN
1056IsSystemFontInfo (
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
1142Exit:
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**/
1174BOOLEAN
1175IsFontInfoExisted (
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**/
1501INT8
1502IsLineBreak (
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**/
1622EFI_STATUS
1623EFIAPI
1624HiiStringToImage (
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 FontInfo = NULL;
1749 RowInfo = NULL;
1750 Status = EFI_SUCCESS;
1751 StringIn2 = NULL;
1752 SystemDefault = NULL;
1753 StringIn = NULL;
1754
1755 //
1756 // Calculate the string output information, including specified color and font .
1757 // If StringInfo does not points to system font info, it must indicate an existing
1758 // EFI_FONT_INFO.
1759 //
1760 StringInfoOut = NULL;
1761 FontHandle = NULL;
1762 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
1763 SysFontFlag = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
1764
1765 if (SysFontFlag) {
1766 ASSERT (SystemDefault != NULL);
1767 FontInfo = NULL;
1768 Height = SystemDefault->FontInfo.FontSize;
1769 BaseLine = SystemDefault->FontInfo.FontSize;
1770 Foreground = SystemDefault->ForegroundColor;
1771 Background = SystemDefault->BackgroundColor;
1772 } else {
1773 //
1774 // StringInfo must not be NULL if it is not system info.
1775 //
1776 ASSERT (StringInfo != NULL);
1777 Status = HiiGetFontInfo (This, &FontHandle, (EFI_FONT_DISPLAY_INFO *)StringInfo, &StringInfoOut, NULL);
1778 if (Status == EFI_NOT_FOUND) {
1779 //
1780 // The specified EFI_FONT_DISPLAY_INFO does not exist in current database.
1781 // Use the system font instead. Still use the color specified by StringInfo.
1782 //
1783 SysFontFlag = TRUE;
1784 FontInfo = NULL;
1785 Height = SystemDefault->FontInfo.FontSize;
1786 BaseLine = SystemDefault->FontInfo.FontSize;
1787 Foreground = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->ForegroundColor;
1788 Background = ((EFI_FONT_DISPLAY_INFO *)StringInfo)->BackgroundColor;
1789 } else if (Status == EFI_SUCCESS) {
1790 FontInfo = &StringInfoOut->FontInfo;
1791 if (IsFontInfoExisted (Private, FontInfo, NULL, NULL, &GlobalFont)) {
1792 Height = GlobalFont->FontPackage->Height;
1793 BaseLine = GlobalFont->FontPackage->BaseLine;
1794 Foreground = StringInfoOut->ForegroundColor;
1795 Background = StringInfoOut->BackgroundColor;
1796 } else {
1797 goto Exit;
1798 }
1799 } else {
1800 goto Exit;
1801 }
1802 }
1803
1804 //
1805 // Use the maximum height of font as the base line.
1806 // And, use the maximum height as line height.
1807 //
1808 LineHeight = Height;
1809 LastLineHeight = Height;
1810 BaseLineOffset = Height - BaseLine;
1811
1812 //
1813 // Parse the string to be displayed to drop some ignored characters.
1814 //
1815
1816 StringPtr = String;
1817
1818 //
1819 // Ignore line-break characters only. Hyphens or dash character will be displayed
1820 // without line-break opportunity.
1821 //
1822 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == EFI_HII_IGNORE_LINE_BREAK) {
1823 StringIn = AllocateZeroPool (StrSize (StringPtr));
1824 if (StringIn == NULL) {
1825 Status = EFI_OUT_OF_RESOURCES;
1826 goto Exit;
1827 }
1828
1829 StringTmp = StringIn;
1830 while (*StringPtr != 0) {
1831 if (IsLineBreak (*StringPtr) == 0) {
1832 StringPtr++;
1833 } else {
1834 *StringTmp++ = *StringPtr++;
1835 }
1836 }
1837
1838 *StringTmp = 0;
1839 StringPtr = StringIn;
1840 }
1841
1842 //
1843 // If EFI_HII_IGNORE_IF_NO_GLYPH is set, then characters which have no glyphs
1844 // are not drawn. Otherwise they are replaced with Unicode character 0xFFFD.
1845 //
1846 StringIn2 = AllocateZeroPool (StrSize (StringPtr));
1847 if (StringIn2 == NULL) {
1848 Status = EFI_OUT_OF_RESOURCES;
1849 goto Exit;
1850 }
1851
1852 Index = 0;
1853 StringTmp = StringIn2;
1854 StrLength = StrLen (StringPtr);
1855 while (*StringPtr != 0 && Index < StrLength) {
1856 if (IsLineBreak (*StringPtr) == 0) {
1857 *StringTmp++ = *StringPtr++;
1858 Index++;
1859 continue;
1860 }
1861
1862 Status = GetGlyphBuffer (Private, *StringPtr, FontInfo, &GlyphBuf[Index], &Cell[Index], &Attributes[Index]);
1863 if (Status == EFI_NOT_FOUND) {
1864 if ((Flags & EFI_HII_IGNORE_IF_NO_GLYPH) == EFI_HII_IGNORE_IF_NO_GLYPH) {
1865 GlyphBuf[Index] = NULL;
1866 ZeroMem (&Cell[Index], sizeof (Cell[Index]));
1867 Status = EFI_SUCCESS;
1868 } else {
1869 //
1870 // Unicode 0xFFFD must exist in current hii database if this flag is not set.
1871 //
1872 Status = GetGlyphBuffer (
1873 Private,
1874 REPLACE_UNKNOWN_GLYPH,
1875 FontInfo,
1876 &GlyphBuf[Index],
1877 &Cell[Index],
1878 &Attributes[Index]
1879 );
1880 if (EFI_ERROR (Status)) {
1881 Status = EFI_INVALID_PARAMETER;
1882 }
1883 }
1884 }
1885
1886 if (EFI_ERROR (Status)) {
1887 goto Exit;
1888 }
1889
1890 *StringTmp++ = *StringPtr++;
1891 Index++;
1892 }
1893
1894 *StringTmp = 0;
1895 StringPtr = StringIn2;
1896
1897 //
1898 // Draw the string according to the specified EFI_HII_OUT_FLAGS and Blt.
1899 // If Blt is not NULL, then EFI_HII_OUT_FLAG_CLIP is implied, render this string
1900 // to an existing image (bitmap or screen depending on flags) pointed by "*Blt".
1901 // Otherwise render this string to a new allocated image and output it.
1902 //
1903 Image = *Blt;
1904 BufferPtr = Image->Image.Bitmap + Image->Width * BltY + BltX;
1905 if (Image->Height < BltY) {
1906 //
1907 // the top edge of the image should be in Image resolution scope.
1908 //
1909 Status = EFI_INVALID_PARAMETER;
1910 goto Exit;
1911 }
1912
1913 MaxRowNum = (UINT16)((Image->Height - BltY) / Height);
1914 if ((Image->Height - BltY) % Height != 0) {
1915 LastLineHeight = (Image->Height - BltY) % Height;
1916 MaxRowNum++;
1917 }
1918
1919 RowInfo = (EFI_HII_ROW_INFO *)AllocateZeroPool (MaxRowNum * sizeof (EFI_HII_ROW_INFO));
1920 if (RowInfo == NULL) {
1921 Status = EFI_OUT_OF_RESOURCES;
1922 goto Exit;
1923 }
1924
1925 //
1926 // Format the glyph buffer according to flags.
1927 //
1928 Transparent = (BOOLEAN)((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT ? TRUE : FALSE);
1929
1930 for (RowIndex = 0, Index = 0; RowIndex < MaxRowNum && StringPtr[Index] != 0; ) {
1931 LineWidth = 0;
1932 LineBreak = FALSE;
1933
1934 //
1935 // Clip the final row if the row's bottom-most on pixel cannot fit when
1936 // EFI_HII_OUT_FLAG_CLEAN_Y is set.
1937 //
1938 if (RowIndex == MaxRowNum - 1) {
1939 if (((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y) && (LastLineHeight < LineHeight)) {
1940 //
1941 // Don't draw at all if the row's bottom-most on pixel cannot fit.
1942 //
1943 break;
1944 }
1945
1946 LineHeight = LastLineHeight;
1947 }
1948
1949 //
1950 // Calculate how many characters there are in a row.
1951 //
1952 RowInfo[RowIndex].StartIndex = Index;
1953
1954 while (LineWidth + BltX < Image->Width && StringPtr[Index] != 0) {
1955 if (((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) &&
1956 (IsLineBreak (StringPtr[Index]) == 0))
1957 {
1958 //
1959 // It forces a line break that ends this row.
1960 //
1961 Index++;
1962 LineBreak = TRUE;
1963 break;
1964 }
1965
1966 //
1967 // If the glyph of the character is existing, then accumulate the actual printed width
1968 //
1969 LineWidth += (UINTN)Cell[Index].AdvanceX;
1970
1971 Index++;
1972 }
1973
1974 //
1975 // Record index of next char.
1976 //
1977 NextIndex = Index;
1978 //
1979 // Return to the previous char.
1980 //
1981 Index--;
1982 if (LineBreak && (Index > 0)) {
1983 //
1984 // Return the previous non line break char.
1985 //
1986 Index--;
1987 }
1988
1989 //
1990 // If this character is the last character of a row, we need not
1991 // draw its (AdvanceX - Width - OffsetX) for next character.
1992 //
1993 LineWidth -= (Cell[Index].AdvanceX - Cell[Index].Width - Cell[Index].OffsetX);
1994
1995 //
1996 // Clip the right-most character if cannot fit when EFI_HII_OUT_FLAG_CLEAN_X is set.
1997 //
1998 if ((LineWidth + BltX <= Image->Width) ||
1999 ((LineWidth + BltX > Image->Width) && ((Flags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) == 0)))
2000 {
2001 //
2002 // Record right-most character in RowInfo even if it is partially displayed.
2003 //
2004 RowInfo[RowIndex].EndIndex = Index;
2005 RowInfo[RowIndex].LineWidth = LineWidth;
2006 RowInfo[RowIndex].LineHeight = LineHeight;
2007 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
2008 } else {
2009 //
2010 // When EFI_HII_OUT_FLAG_CLEAN_X is set, it will not draw a character
2011 // if its right-most on pixel cannot fit.
2012 //
2013 if (Index > RowInfo[RowIndex].StartIndex) {
2014 //
2015 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
2016 //
2017 LineWidth -= (Cell[Index].Width + Cell[Index].OffsetX);
2018 LineWidth -= (Cell[Index - 1].AdvanceX - Cell[Index - 1].Width - Cell[Index - 1].OffsetX);
2019 RowInfo[RowIndex].EndIndex = Index - 1;
2020 RowInfo[RowIndex].LineWidth = LineWidth;
2021 RowInfo[RowIndex].LineHeight = LineHeight;
2022 RowInfo[RowIndex].BaselineOffset = BaseLineOffset;
2023 } else {
2024 //
2025 // There is no enough column to draw any character, so set current line width to zero.
2026 // And go to draw Next line if LineBreak is set.
2027 //
2028 RowInfo[RowIndex].LineWidth = 0;
2029 goto NextLine;
2030 }
2031 }
2032
2033 //
2034 // EFI_HII_OUT_FLAG_WRAP will wrap the text at the right-most line-break
2035 // opportunity prior to a character whose right-most extent would exceed Width.
2036 // Search the right-most line-break opportunity here.
2037 //
2038 if (((Flags & EFI_HII_OUT_FLAG_WRAP) == EFI_HII_OUT_FLAG_WRAP) &&
2039 ((RowInfo[RowIndex].LineWidth + BltX > Image->Width) || (StringPtr[NextIndex] != 0)) &&
2040 !LineBreak)
2041 {
2042 if ((Flags & EFI_HII_IGNORE_LINE_BREAK) == 0) {
2043 LineWidth = RowInfo[RowIndex].LineWidth;
2044 for (Index1 = RowInfo[RowIndex].EndIndex; Index1 >= RowInfo[RowIndex].StartIndex; Index1--) {
2045 if (Index1 == RowInfo[RowIndex].EndIndex) {
2046 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
2047 } else {
2048 LineWidth -= Cell[Index1].AdvanceX;
2049 }
2050
2051 if (IsLineBreak (StringPtr[Index1]) > 0) {
2052 LineBreak = TRUE;
2053 if (Index1 > RowInfo[RowIndex].StartIndex) {
2054 RowInfo[RowIndex].EndIndex = Index1 - 1;
2055 }
2056
2057 //
2058 // relocate to the character after the right-most line break opportunity of this line
2059 //
2060 NextIndex = Index1 + 1;
2061 break;
2062 }
2063
2064 //
2065 // If don't find a line break opportunity from EndIndex to StartIndex,
2066 // then jump out.
2067 //
2068 if (Index1 == RowInfo[RowIndex].StartIndex) {
2069 break;
2070 }
2071 }
2072
2073 //
2074 // Update LineWidth to the real width
2075 //
2076 if (IsLineBreak (StringPtr[Index1]) > 0) {
2077 if (Index1 == RowInfo[RowIndex].StartIndex) {
2078 LineWidth = 0;
2079 } else {
2080 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
2081 }
2082
2083 RowInfo[RowIndex].LineWidth = LineWidth;
2084 }
2085 }
2086
2087 //
2088 // If no line-break opportunity can be found, then the text will
2089 // behave as if EFI_HII_OUT_FLAG_CLEAN_X is set.
2090 //
2091 if (!LineBreak) {
2092 LineWidth = RowInfo[RowIndex].LineWidth;
2093 Index1 = RowInfo[RowIndex].EndIndex;
2094 if (LineWidth + BltX > Image->Width) {
2095 if (Index1 > RowInfo[RowIndex].StartIndex) {
2096 //
2097 // Don't draw the last char on this row. And, don't draw the second last char (AdvanceX - Width - OffsetX).
2098 //
2099 LineWidth -= (Cell[Index1].Width + Cell[Index1].OffsetX);
2100 LineWidth -= (Cell[Index1 - 1].AdvanceX - Cell[Index1 - 1].Width - Cell[Index1 - 1].OffsetX);
2101 RowInfo[RowIndex].EndIndex = Index1 - 1;
2102 RowInfo[RowIndex].LineWidth = LineWidth;
2103 } else {
2104 //
2105 // There is no enough column to draw any character, so set current line width to zero.
2106 // And go to draw Next line if LineBreak is set.
2107 //
2108 RowInfo[RowIndex].LineWidth = 0;
2109 goto NextLine;
2110 }
2111 }
2112 }
2113 }
2114
2115 //
2116 // LineWidth can't exceed Image width.
2117 //
2118 if (RowInfo[RowIndex].LineWidth + BltX > Image->Width) {
2119 RowInfo[RowIndex].LineWidth = Image->Width - BltX;
2120 }
2121
2122 //
2123 // Draw it to screen or existing bitmap depending on whether
2124 // EFI_HII_DIRECT_TO_SCREEN is set.
2125 //
2126 LineOffset = 0;
2127 if ((Flags & EFI_HII_DIRECT_TO_SCREEN) == EFI_HII_DIRECT_TO_SCREEN) {
2128 BltBuffer = NULL;
2129 if (RowInfo[RowIndex].LineWidth != 0) {
2130 BltBuffer = AllocatePool (RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2131 if (BltBuffer == NULL) {
2132 Status = EFI_OUT_OF_RESOURCES;
2133 goto Exit;
2134 }
2135
2136 //
2137 // Initialize the background color.
2138 //
2139 PreInitBkgnd = Background.Blue | Background.Green << 8 | Background.Red << 16;
2140 SetMem32 (BltBuffer, RowInfo[RowIndex].LineWidth * RowInfo[RowIndex].LineHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), PreInitBkgnd);
2141 //
2142 // Set BufferPtr to Origin by adding baseline to the starting position.
2143 //
2144 BufferPtr = BltBuffer + BaseLine * RowInfo[RowIndex].LineWidth;
2145 }
2146
2147 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2148 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
2149 //
2150 // Only BLT these character which have corresponding glyph in font database.
2151 //
2152 GlyphToImage (
2153 GlyphBuf[Index1],
2154 Foreground,
2155 Background,
2156 (UINT16)RowInfo[RowIndex].LineWidth,
2157 BaseLine,
2158 RowInfo[RowIndex].LineWidth - LineOffset,
2159 RowInfo[RowIndex].LineHeight,
2160 Transparent,
2161 &Cell[Index1],
2162 Attributes[Index1],
2163 &BufferPtr
2164 );
2165 }
2166
2167 if (ColumnInfoArray != NULL) {
2168 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
2169 || (RowInfo[RowIndex].LineWidth == 0))
2170 {
2171 *ColumnInfoArray = (UINTN) ~0;
2172 } else {
2173 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2174 }
2175
2176 ColumnInfoArray++;
2177 }
2178
2179 LineOffset += Cell[Index1].AdvanceX;
2180 }
2181
2182 if (BltBuffer != NULL) {
2183 Status = Image->Image.Screen->Blt (
2184 Image->Image.Screen,
2185 BltBuffer,
2186 EfiBltBufferToVideo,
2187 0,
2188 0,
2189 BltX,
2190 BltY,
2191 RowInfo[RowIndex].LineWidth,
2192 RowInfo[RowIndex].LineHeight,
2193 0
2194 );
2195 if (EFI_ERROR (Status)) {
2196 FreePool (BltBuffer);
2197 goto Exit;
2198 }
2199
2200 FreePool (BltBuffer);
2201 }
2202 } else {
2203 //
2204 // Save the starting position for calculate the starting position of next row.
2205 //
2206 RowBufferPtr = BufferPtr;
2207 //
2208 // Set BufferPtr to Origin by adding baseline to the starting position.
2209 //
2210 BufferPtr = BufferPtr + BaseLine * Image->Width;
2211 for (Index1 = RowInfo[RowIndex].StartIndex; Index1 <= RowInfo[RowIndex].EndIndex; Index1++) {
2212 if ((RowInfo[RowIndex].LineWidth > 0) && (RowInfo[RowIndex].LineWidth > LineOffset)) {
2213 //
2214 // Only BLT these character which have corresponding glyph in font database.
2215 //
2216 GlyphToImage (
2217 GlyphBuf[Index1],
2218 Foreground,
2219 Background,
2220 Image->Width,
2221 BaseLine,
2222 RowInfo[RowIndex].LineWidth - LineOffset,
2223 RowInfo[RowIndex].LineHeight,
2224 Transparent,
2225 &Cell[Index1],
2226 Attributes[Index1],
2227 &BufferPtr
2228 );
2229 }
2230
2231 if (ColumnInfoArray != NULL) {
2232 if ( ((GlyphBuf[Index1] == NULL) && (Cell[Index1].AdvanceX == 0))
2233 || (RowInfo[RowIndex].LineWidth == 0))
2234 {
2235 *ColumnInfoArray = (UINTN) ~0;
2236 } else {
2237 *ColumnInfoArray = LineOffset + Cell[Index1].OffsetX + BltX;
2238 }
2239
2240 ColumnInfoArray++;
2241 }
2242
2243 LineOffset += Cell[Index1].AdvanceX;
2244 }
2245
2246 //
2247 // Jump to starting position of next row.
2248 //
2249 if (RowIndex == 0) {
2250 BufferPtr = RowBufferPtr - BltX + LineHeight * Image->Width;
2251 } else {
2252 BufferPtr = RowBufferPtr + LineHeight * Image->Width;
2253 }
2254 }
2255
2256NextLine:
2257 //
2258 // Recalculate the start point of Y axis to draw multi-lines with the order of top-to-down
2259 //
2260 BltY += RowInfo[RowIndex].LineHeight;
2261
2262 RowIndex++;
2263 Index = NextIndex;
2264
2265 if (!LineBreak) {
2266 //
2267 // If there is not a mandatory line break or line break opportunity, only render one line to image
2268 //
2269 break;
2270 }
2271 }
2272
2273 //
2274 // Write output parameters.
2275 //
2276 RowInfoSize = RowIndex * sizeof (EFI_HII_ROW_INFO);
2277 if (RowInfoArray != NULL) {
2278 if (RowInfoSize > 0) {
2279 *RowInfoArray = AllocateZeroPool (RowInfoSize);
2280 if (*RowInfoArray == NULL) {
2281 Status = EFI_OUT_OF_RESOURCES;
2282 goto Exit;
2283 }
2284
2285 CopyMem (*RowInfoArray, RowInfo, RowInfoSize);
2286 } else {
2287 *RowInfoArray = NULL;
2288 }
2289 }
2290
2291 if (RowInfoArraySize != NULL) {
2292 *RowInfoArraySize = RowIndex;
2293 }
2294
2295 Status = EFI_SUCCESS;
2296
2297Exit:
2298
2299 for (Index = 0; Index < StrLength; Index++) {
2300 if (GlyphBuf[Index] != NULL) {
2301 FreePool (GlyphBuf[Index]);
2302 }
2303 }
2304
2305 if (StringIn != NULL) {
2306 FreePool (StringIn);
2307 }
2308
2309 if (StringIn2 != NULL) {
2310 FreePool (StringIn2);
2311 }
2312
2313 if (StringInfoOut != NULL) {
2314 FreePool (StringInfoOut);
2315 }
2316
2317 if (RowInfo != NULL) {
2318 FreePool (RowInfo);
2319 }
2320
2321 if (SystemDefault != NULL) {
2322 FreePool (SystemDefault);
2323 }
2324
2325 if (GlyphBuf != NULL) {
2326 FreePool (GlyphBuf);
2327 }
2328
2329 if (Cell != NULL) {
2330 FreePool (Cell);
2331 }
2332
2333 if (Attributes != NULL) {
2334 FreePool (Attributes);
2335 }
2336
2337 return Status;
2338}
2339
2340/**
2341 Render a string to a bitmap or the screen containing the contents of the specified string.
2342
2343 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
2344 @param Flags Describes how the string is to be drawn.
2345 @param PackageList The package list in the HII database to search
2346 for the specified string.
2347 @param StringId The string's id, which is unique within
2348 PackageList.
2349 @param Language Points to the language for the retrieved string.
2350 If NULL, then the current system language is
2351 used.
2352 @param StringInfo Points to the string output information,
2353 including the color and font. If NULL, then the
2354 string will be output in the default system font
2355 and color.
2356 @param Blt If this points to a non-NULL on entry, this
2357 points to the image, which is Width pixels wide
2358 and Height pixels high. The string will be drawn
2359 onto this image and
2360 EFI_HII_OUT_FLAG_CLIP is implied. If this points
2361 to a NULL on entry, then a buffer
2362 will be allocated to hold the generated image and
2363 the pointer updated on exit. It is the caller's
2364 responsibility to free this buffer.
2365 @param BltX Specifies the offset from the left and top edge
2366 of the image of the first character cell in the
2367 image.
2368 @param BltY Specifies the offset from the left and top edge
2369 of the image of the first character cell in the
2370 image.
2371 @param RowInfoArray If this is non-NULL on entry, then on exit, this
2372 will point to an allocated buffer containing
2373 row information and RowInfoArraySize will be
2374 updated to contain the number of elements.
2375 This array describes the characters which were at
2376 least partially drawn and the heights of the
2377 rows. It is the caller's responsibility to free
2378 this buffer.
2379 @param RowInfoArraySize If this is non-NULL on entry, then on exit it
2380 contains the number of elements in RowInfoArray.
2381 @param ColumnInfoArray If this is non-NULL, then on return it will be
2382 filled with the horizontal offset for each
2383 character in the string on the row where it is
2384 displayed. Non-printing characters will have
2385 the offset ~0. The caller is responsible to
2386 allocate a buffer large enough so that there
2387 is one entry for each character in the string,
2388 not including the null-terminator. It is possible
2389 when character display is normalized that some
2390 character cells overlap.
2391
2392 @retval EFI_SUCCESS The string was successfully rendered.
2393 @retval EFI_OUT_OF_RESOURCES Unable to allocate an output buffer for
2394 RowInfoArray or Blt.
2395 @retval EFI_INVALID_PARAMETER The Blt or PackageList was NULL.
2396 @retval EFI_INVALID_PARAMETER Flags were invalid combination.
2397 @retval EFI_NOT_FOUND The specified PackageList is not in the Database or the string id is not
2398 in the specified PackageList.
2399
2400**/
2401EFI_STATUS
2402EFIAPI
2403HiiStringIdToImage (
2404 IN CONST EFI_HII_FONT_PROTOCOL *This,
2405 IN EFI_HII_OUT_FLAGS Flags,
2406 IN EFI_HII_HANDLE PackageList,
2407 IN EFI_STRING_ID StringId,
2408 IN CONST CHAR8 *Language,
2409 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
2410 IN OUT EFI_IMAGE_OUTPUT **Blt,
2411 IN UINTN BltX,
2412 IN UINTN BltY,
2413 OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
2414 OUT UINTN *RowInfoArraySize OPTIONAL,
2415 OUT UINTN *ColumnInfoArray OPTIONAL
2416 )
2417{
2418 EFI_STATUS Status;
2419 HII_DATABASE_PRIVATE_DATA *Private;
2420 EFI_HII_STRING_PROTOCOL *HiiString;
2421 EFI_STRING String;
2422 UINTN StringSize;
2423 UINTN FontLen;
2424 UINTN NameSize;
2425 EFI_FONT_INFO *StringFontInfo;
2426 EFI_FONT_DISPLAY_INFO *NewStringInfo;
2427 CHAR8 TempSupportedLanguages;
2428 CHAR8 *SupportedLanguages;
2429 UINTN SupportedLanguagesSize;
2430 CHAR8 *CurrentLanguage;
2431 CHAR8 *BestLanguage;
2432
2433 if ((This == NULL) || (PackageList == NULL) || (Blt == NULL) || (PackageList == NULL)) {
2434 return EFI_INVALID_PARAMETER;
2435 }
2436
2437 if (!IsHiiHandleValid (PackageList)) {
2438 return EFI_NOT_FOUND;
2439 }
2440
2441 //
2442 // Initialize string pointers to be NULL
2443 //
2444 SupportedLanguages = NULL;
2445 CurrentLanguage = NULL;
2446 BestLanguage = NULL;
2447 String = NULL;
2448 StringFontInfo = NULL;
2449 NewStringInfo = NULL;
2450
2451 //
2452 // Get the string to be displayed.
2453 //
2454 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2455 HiiString = &Private->HiiString;
2456
2457 //
2458 // Get the size of supported language.
2459 //
2460 SupportedLanguagesSize = 0;
2461 Status = HiiString->GetLanguages (
2462 HiiString,
2463 PackageList,
2464 &TempSupportedLanguages,
2465 &SupportedLanguagesSize
2466 );
2467 if (Status != EFI_BUFFER_TOO_SMALL) {
2468 return Status;
2469 }
2470
2471 SupportedLanguages = AllocatePool (SupportedLanguagesSize);
2472 if (SupportedLanguages == NULL) {
2473 return EFI_OUT_OF_RESOURCES;
2474 }
2475
2476 Status = HiiString->GetLanguages (
2477 HiiString,
2478 PackageList,
2479 SupportedLanguages,
2480 &SupportedLanguagesSize
2481 );
2482 if (EFI_ERROR (Status)) {
2483 goto Exit;
2484 }
2485
2486 if (Language == NULL) {
2487 Language = "";
2488 }
2489
2490 GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&CurrentLanguage, NULL);
2491 BestLanguage = GetBestLanguage (
2492 SupportedLanguages,
2493 FALSE,
2494 Language,
2495 (CurrentLanguage == NULL) ? CurrentLanguage : "",
2496 (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang),
2497 NULL
2498 );
2499 if (BestLanguage == NULL) {
2500 Status = EFI_NOT_FOUND;
2501 goto Exit;
2502 }
2503
2504 StringSize = MAX_STRING_LENGTH;
2505 String = (EFI_STRING)AllocateZeroPool (StringSize);
2506 if (String == NULL) {
2507 Status = EFI_OUT_OF_RESOURCES;
2508 goto Exit;
2509 }
2510
2511 Status = HiiString->GetString (
2512 HiiString,
2513 BestLanguage,
2514 PackageList,
2515 StringId,
2516 String,
2517 &StringSize,
2518 &StringFontInfo
2519 );
2520 if (Status == EFI_BUFFER_TOO_SMALL) {
2521 FreePool (String);
2522 String = (EFI_STRING)AllocateZeroPool (StringSize);
2523 if (String == NULL) {
2524 Status = EFI_OUT_OF_RESOURCES;
2525 goto Exit;
2526 }
2527
2528 Status = HiiString->GetString (
2529 HiiString,
2530 BestLanguage,
2531 PackageList,
2532 StringId,
2533 String,
2534 &StringSize,
2535 NULL
2536 );
2537 }
2538
2539 if (EFI_ERROR (Status)) {
2540 goto Exit;
2541 }
2542
2543 //
2544 // When StringInfo specifies that string will be output in the system default font and color,
2545 // use particular stringfontinfo described in string package instead if exists.
2546 // StringFontInfo equals NULL means system default font attaches with the string block.
2547 //
2548 if ((StringFontInfo != NULL) && IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, NULL, NULL)) {
2549 NameSize = StrSize (StringFontInfo->FontName);
2550 FontLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (CHAR16) + NameSize;
2551 NewStringInfo = AllocateZeroPool (FontLen);
2552 if (NewStringInfo == NULL) {
2553 Status = EFI_OUT_OF_RESOURCES;
2554 goto Exit;
2555 }
2556
2557 NewStringInfo->FontInfoMask = EFI_FONT_INFO_SYS_FORE_COLOR | EFI_FONT_INFO_SYS_BACK_COLOR;
2558 NewStringInfo->FontInfo.FontStyle = StringFontInfo->FontStyle;
2559 NewStringInfo->FontInfo.FontSize = StringFontInfo->FontSize;
2560 StrCpyS (NewStringInfo->FontInfo.FontName, NameSize / sizeof (CHAR16), StringFontInfo->FontName);
2561
2562 Status = HiiStringToImage (
2563 This,
2564 Flags,
2565 String,
2566 NewStringInfo,
2567 Blt,
2568 BltX,
2569 BltY,
2570 RowInfoArray,
2571 RowInfoArraySize,
2572 ColumnInfoArray
2573 );
2574 goto Exit;
2575 }
2576
2577 Status = HiiStringToImage (
2578 This,
2579 Flags,
2580 String,
2581 StringInfo,
2582 Blt,
2583 BltX,
2584 BltY,
2585 RowInfoArray,
2586 RowInfoArraySize,
2587 ColumnInfoArray
2588 );
2589
2590Exit:
2591 if (SupportedLanguages != NULL) {
2592 FreePool (SupportedLanguages);
2593 }
2594
2595 if (CurrentLanguage != NULL) {
2596 FreePool (CurrentLanguage);
2597 }
2598
2599 if (BestLanguage != NULL) {
2600 FreePool (BestLanguage);
2601 }
2602
2603 if (String != NULL) {
2604 FreePool (String);
2605 }
2606
2607 if (StringFontInfo != NULL) {
2608 FreePool (StringFontInfo);
2609 }
2610
2611 if (NewStringInfo != NULL) {
2612 FreePool (NewStringInfo);
2613 }
2614
2615 return Status;
2616}
2617
2618/**
2619 Convert the glyph for a single character into a bitmap.
2620
2621 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
2622 @param Char Character to retrieve.
2623 @param StringInfo Points to the string font and color information
2624 or NULL if the string should use the default
2625 system font and color.
2626 @param Blt Thus must point to a NULL on entry. A buffer will
2627 be allocated to hold the output and the pointer
2628 updated on exit. It is the caller's
2629 responsibility to free this buffer.
2630 @param Baseline Number of pixels from the bottom of the bitmap to
2631 the baseline.
2632
2633 @retval EFI_SUCCESS Glyph bitmap created.
2634 @retval EFI_OUT_OF_RESOURCES Unable to allocate the output buffer Blt.
2635 @retval EFI_WARN_UNKNOWN_GLYPH The glyph was unknown and was replaced with the
2636 glyph for Unicode character 0xFFFD.
2637 @retval EFI_INVALID_PARAMETER Blt is NULL or *Blt is not NULL.
2638
2639**/
2640EFI_STATUS
2641EFIAPI
2642HiiGetGlyph (
2643 IN CONST EFI_HII_FONT_PROTOCOL *This,
2644 IN CHAR16 Char,
2645 IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
2646 OUT EFI_IMAGE_OUTPUT **Blt,
2647 OUT UINTN *Baseline OPTIONAL
2648 )
2649{
2650 EFI_STATUS Status;
2651 HII_DATABASE_PRIVATE_DATA *Private;
2652 EFI_IMAGE_OUTPUT *Image;
2653 UINT8 *GlyphBuffer;
2654 EFI_FONT_DISPLAY_INFO *SystemDefault;
2655 EFI_FONT_DISPLAY_INFO *StringInfoOut;
2656 BOOLEAN Default;
2657 EFI_FONT_HANDLE FontHandle;
2658 EFI_STRING String;
2659 EFI_HII_GLYPH_INFO Cell;
2660 EFI_FONT_INFO *FontInfo;
2661 UINT8 Attributes;
2662 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
2663 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
2664 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
2665 UINT16 BaseLine;
2666
2667 if ((This == NULL) || (Blt == NULL) || (*Blt != NULL)) {
2668 return EFI_INVALID_PARAMETER;
2669 }
2670
2671 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2672
2673 Default = FALSE;
2674 Image = NULL;
2675 SystemDefault = NULL;
2676 FontHandle = NULL;
2677 String = NULL;
2678 GlyphBuffer = NULL;
2679 StringInfoOut = NULL;
2680 FontInfo = NULL;
2681
2682 ZeroMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2683 ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2684
2685 Default = IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfo, &SystemDefault, NULL);
2686
2687 if (!Default) {
2688 //
2689 // Find out a EFI_FONT_DISPLAY_INFO which could display the character in
2690 // the specified color and font.
2691 //
2692 String = (EFI_STRING)AllocateZeroPool (sizeof (CHAR16) * 2);
2693 if (String == NULL) {
2694 Status = EFI_OUT_OF_RESOURCES;
2695 goto Exit;
2696 }
2697
2698 *String = Char;
2699 *(String + 1) = 0;
2700
2701 Status = HiiGetFontInfo (This, &FontHandle, StringInfo, &StringInfoOut, String);
2702 if (EFI_ERROR (Status)) {
2703 goto Exit;
2704 }
2705
2706 ASSERT (StringInfoOut != NULL);
2707 FontInfo = &StringInfoOut->FontInfo;
2708 Foreground = StringInfoOut->ForegroundColor;
2709 Background = StringInfoOut->BackgroundColor;
2710 } else {
2711 ASSERT (SystemDefault != NULL);
2712 Foreground = SystemDefault->ForegroundColor;
2713 Background = SystemDefault->BackgroundColor;
2714 }
2715
2716 Status = GetGlyphBuffer (Private, Char, FontInfo, &GlyphBuffer, &Cell, &Attributes);
2717 if (EFI_ERROR (Status)) {
2718 goto Exit;
2719 }
2720
2721 Image = (EFI_IMAGE_OUTPUT *)AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));
2722 if (Image == NULL) {
2723 Status = EFI_OUT_OF_RESOURCES;
2724 goto Exit;
2725 }
2726
2727 Image->Width = Cell.Width;
2728 Image->Height = Cell.Height;
2729
2730 if (Image->Width * Image->Height > 0) {
2731 Image->Image.Bitmap = AllocateZeroPool (Image->Width * Image->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
2732 if (Image->Image.Bitmap == NULL) {
2733 FreePool (Image);
2734 Status = EFI_OUT_OF_RESOURCES;
2735 goto Exit;
2736 }
2737
2738 //
2739 // Set BaseLine to the char height.
2740 //
2741 BaseLine = (UINT16)(Cell.Height + Cell.OffsetY);
2742 //
2743 // Set BltBuffer to the position of Origin.
2744 //
2745 BltBuffer = Image->Image.Bitmap + (Cell.Height + Cell.OffsetY) * Image->Width - Cell.OffsetX;
2746 GlyphToImage (
2747 GlyphBuffer,
2748 Foreground,
2749 Background,
2750 Image->Width,
2751 BaseLine,
2752 Cell.Width + Cell.OffsetX,
2753 BaseLine - Cell.OffsetY,
2754 FALSE,
2755 &Cell,
2756 Attributes,
2757 &BltBuffer
2758 );
2759 }
2760
2761 *Blt = Image;
2762 if (Baseline != NULL) {
2763 *Baseline = Cell.OffsetY;
2764 }
2765
2766 Status = EFI_SUCCESS;
2767
2768Exit:
2769
2770 if (Status == EFI_NOT_FOUND) {
2771 //
2772 // Glyph is unknown and replaced with the glyph for unicode character 0xFFFD
2773 //
2774 if (Char != REPLACE_UNKNOWN_GLYPH) {
2775 Status = HiiGetGlyph (This, REPLACE_UNKNOWN_GLYPH, StringInfo, Blt, Baseline);
2776 if (!EFI_ERROR (Status)) {
2777 Status = EFI_WARN_UNKNOWN_GLYPH;
2778 }
2779 } else {
2780 Status = EFI_WARN_UNKNOWN_GLYPH;
2781 }
2782 }
2783
2784 if (SystemDefault != NULL) {
2785 FreePool (SystemDefault);
2786 }
2787
2788 if (StringInfoOut != NULL) {
2789 FreePool (StringInfoOut);
2790 }
2791
2792 if (String != NULL) {
2793 FreePool (String);
2794 }
2795
2796 if (GlyphBuffer != NULL) {
2797 FreePool (GlyphBuffer);
2798 }
2799
2800 return Status;
2801}
2802
2803/**
2804 This function iterates through fonts which match the specified font, using
2805 the specified criteria. If String is non-NULL, then all of the characters in
2806 the string must exist in order for a candidate font to be returned.
2807
2808 @param This A pointer to the EFI_HII_FONT_PROTOCOL instance.
2809 @param FontHandle On entry, points to the font handle returned by a
2810 previous call to GetFontInfo() or NULL to start
2811 with the first font. On return, points to the
2812 returned font handle or points to NULL if there
2813 are no more matching fonts.
2814 @param StringInfoIn Upon entry, points to the font to return information
2815 about. If NULL, then the information about the system
2816 default font will be returned.
2817 @param StringInfoOut Upon return, contains the matching font's information.
2818 If NULL, then no information is returned. This buffer
2819 is allocated with a call to the Boot Service AllocatePool().
2820 It is the caller's responsibility to call the Boot
2821 Service FreePool() when the caller no longer requires
2822 the contents of StringInfoOut.
2823 @param String Points to the string which will be tested to
2824 determine if all characters are available. If
2825 NULL, then any font is acceptable.
2826
2827 @retval EFI_SUCCESS Matching font returned successfully.
2828 @retval EFI_NOT_FOUND No matching font was found.
2829 @retval EFI_INVALID_PARAMETER StringInfoIn->FontInfoMask is an invalid combination.
2830 @retval EFI_OUT_OF_RESOURCES There were insufficient resources to complete the
2831 request.
2832
2833**/
2834EFI_STATUS
2835EFIAPI
2836HiiGetFontInfo (
2837 IN CONST EFI_HII_FONT_PROTOCOL *This,
2838 IN OUT EFI_FONT_HANDLE *FontHandle,
2839 IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn OPTIONAL,
2840 OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
2841 IN CONST EFI_STRING String OPTIONAL
2842 )
2843{
2844 HII_DATABASE_PRIVATE_DATA *Private;
2845 EFI_STATUS Status;
2846 EFI_FONT_DISPLAY_INFO *SystemDefault;
2847 EFI_FONT_DISPLAY_INFO InfoOut;
2848 UINTN StringInfoOutLen;
2849 EFI_FONT_INFO *FontInfo;
2850 HII_GLOBAL_FONT_INFO *GlobalFont;
2851 EFI_STRING StringIn;
2852 EFI_FONT_HANDLE LocalFontHandle;
2853
2854 if (This == NULL) {
2855 return EFI_INVALID_PARAMETER;
2856 }
2857
2858 StringInfoOutLen = 0;
2859 FontInfo = NULL;
2860 SystemDefault = NULL;
2861 LocalFontHandle = NULL;
2862 if (FontHandle != NULL) {
2863 LocalFontHandle = *FontHandle;
2864 }
2865
2866 Private = HII_FONT_DATABASE_PRIVATE_DATA_FROM_THIS (This);
2867
2868 //
2869 // Already searched to the end of the whole list, return directly.
2870 //
2871 if (LocalFontHandle == &Private->FontInfoList) {
2872 LocalFontHandle = NULL;
2873 Status = EFI_NOT_FOUND;
2874 goto Exit;
2875 }
2876
2877 //
2878 // Get default system display info, if StringInfoIn points to
2879 // system display info, return it directly.
2880 //
2881 if (IsSystemFontInfo (Private, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, &SystemDefault, &StringInfoOutLen)) {
2882 //
2883 // System font is the first node. When handle is not NULL, system font can not
2884 // be found any more.
2885 //
2886 if (LocalFontHandle == NULL) {
2887 if (StringInfoOut != NULL) {
2888 *StringInfoOut = AllocateCopyPool (StringInfoOutLen, SystemDefault);
2889 if (*StringInfoOut == NULL) {
2890 Status = EFI_OUT_OF_RESOURCES;
2891 LocalFontHandle = NULL;
2892 goto Exit;
2893 }
2894 }
2895
2896 LocalFontHandle = Private->FontInfoList.ForwardLink;
2897 Status = EFI_SUCCESS;
2898 goto Exit;
2899 } else {
2900 LocalFontHandle = NULL;
2901 Status = EFI_NOT_FOUND;
2902 goto Exit;
2903 }
2904 }
2905
2906 //
2907 // StringInfoIn must not be NULL if it is not system default font info.
2908 //
2909 ASSERT (StringInfoIn != NULL);
2910 //
2911 // Check the font information mask to make sure it is valid.
2912 //
2913 if (((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
2914 (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
2915 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
2916 (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
2917 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
2918 (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
2919 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
2920 (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
2921 ((StringInfoIn->FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
2922 (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
2923 {
2924 return EFI_INVALID_PARAMETER;
2925 }
2926
2927 //
2928 // Parse the font information mask to find a matching font.
2929 //
2930
2931 CopyMem (&InfoOut, (EFI_FONT_DISPLAY_INFO *)StringInfoIn, sizeof (EFI_FONT_DISPLAY_INFO));
2932
2933 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FONT) == EFI_FONT_INFO_SYS_FONT) {
2934 Status = SaveFontName (SystemDefault->FontInfo.FontName, &FontInfo);
2935 } else {
2936 Status = SaveFontName (((EFI_FONT_DISPLAY_INFO *)StringInfoIn)->FontInfo.FontName, &FontInfo);
2937 }
2938
2939 if (EFI_ERROR (Status)) {
2940 goto Exit;
2941 }
2942
2943 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_SIZE) == EFI_FONT_INFO_SYS_SIZE) {
2944 InfoOut.FontInfo.FontSize = SystemDefault->FontInfo.FontSize;
2945 }
2946
2947 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_STYLE) == EFI_FONT_INFO_SYS_STYLE) {
2948 InfoOut.FontInfo.FontStyle = SystemDefault->FontInfo.FontStyle;
2949 }
2950
2951 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) == EFI_FONT_INFO_SYS_FORE_COLOR) {
2952 InfoOut.ForegroundColor = SystemDefault->ForegroundColor;
2953 }
2954
2955 if ((StringInfoIn->FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) == EFI_FONT_INFO_SYS_BACK_COLOR) {
2956 InfoOut.BackgroundColor = SystemDefault->BackgroundColor;
2957 }
2958
2959 ASSERT (FontInfo != NULL);
2960 FontInfo->FontSize = InfoOut.FontInfo.FontSize;
2961 FontInfo->FontStyle = InfoOut.FontInfo.FontStyle;
2962
2963 if (IsFontInfoExisted (Private, FontInfo, &InfoOut.FontInfoMask, LocalFontHandle, &GlobalFont)) {
2964 //
2965 // Test to guarantee all characters are available in the found font.
2966 //
2967 if (String != NULL) {
2968 StringIn = String;
2969 while (*StringIn != 0) {
2970 Status = FindGlyphBlock (GlobalFont->FontPackage, *StringIn, NULL, NULL, NULL);
2971 if (EFI_ERROR (Status)) {
2972 LocalFontHandle = NULL;
2973 goto Exit;
2974 }
2975
2976 StringIn++;
2977 }
2978 }
2979
2980 //
2981 // Write to output parameter
2982 //
2983 if (StringInfoOut != NULL) {
2984 StringInfoOutLen = sizeof (EFI_FONT_DISPLAY_INFO) - sizeof (EFI_FONT_INFO) + GlobalFont->FontInfoSize;
2985 *StringInfoOut = (EFI_FONT_DISPLAY_INFO *)AllocateZeroPool (StringInfoOutLen);
2986 if (*StringInfoOut == NULL) {
2987 Status = EFI_OUT_OF_RESOURCES;
2988 LocalFontHandle = NULL;
2989 goto Exit;
2990 }
2991
2992 CopyMem (*StringInfoOut, &InfoOut, sizeof (EFI_FONT_DISPLAY_INFO));
2993 CopyMem (&(*StringInfoOut)->FontInfo, GlobalFont->FontInfo, GlobalFont->FontInfoSize);
2994 }
2995
2996 LocalFontHandle = GlobalFont->Entry.ForwardLink;
2997 Status = EFI_SUCCESS;
2998 goto Exit;
2999 }
3000
3001 Status = EFI_NOT_FOUND;
3002
3003Exit:
3004
3005 if (FontHandle != NULL) {
3006 *FontHandle = LocalFontHandle;
3007 }
3008
3009 if (SystemDefault != NULL) {
3010 FreePool (SystemDefault);
3011 }
3012
3013 if (FontInfo != NULL) {
3014 FreePool (FontInfo);
3015 }
3016
3017 return Status;
3018}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette