Port DriverSample.inf, HiiDatabase.inf and SetupBrowser.inf
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / HiiDataBaseDxe / Fonts.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Fonts.c
15
16 Abstract:
17
18 This file contains the Glyph/Font processing code to the HII database.
19
20 --*/
21
22
23 //
24 // Include common header file for this module.
25 //
26 #include "CommonHeader.h"
27
28 #include "HiiDatabase.h"
29
30 //
31 // We only need to define a wide glyph, since we will seed the narrow glyph with EFI_NARROW_GLYPH size of
32 // this data structure
33 //
34 UINT8 mUnknownGlyph[38] = {
35 0xaa,
36 0x55,
37 0xaa,
38 0x55,
39 0xaa,
40 0x55,
41 0xaa,
42 0x55,
43 0xaa,
44 0x55,
45 0xaa,
46 0x55,
47 0xaa,
48 0x55,
49 0xaa,
50 0x55,
51 0xaa,
52 0x55,
53 0xAA,
54 0xaa,
55 0x55,
56 0xaa,
57 0x55,
58 0xaa,
59 0x55,
60 0xaa,
61 0x55,
62 0xaa,
63 0x55,
64 0xaa,
65 0x55,
66 0xaa,
67 0x55,
68 0xaa,
69 0x55,
70 0xaa,
71 0x55,
72 0xAA
73 };
74
75 EFI_STATUS
76 EFIAPI
77 HiiGetGlyph (
78 IN EFI_HII_PROTOCOL *This,
79 IN CHAR16 *Source,
80 IN OUT UINT16 *Index,
81 OUT UINT8 **GlyphBuffer,
82 OUT UINT16 *BitWidth,
83 IN OUT UINT32 *InternalStatus
84 )
85 /*++
86
87 Routine Description:
88 Translates a Unicode character into the corresponding font glyph.
89 If the Source was pointing to a non-spacing character, the next Source[*Index]
90 character will be parsed and OR'd to the GlyphBuffer until a spacing character
91 is found in the Source. Since non-spacing characters are considered to be the
92 same pixel width as a regular character their BitWidth will be reflected correctly
93 however due to their special attribute, they are considered to be zero advancing width.
94 This basically means that the cursor would not advance, thus the character that follows
95 it would overlay the non-spacing character. The Index is modified to reflect both the
96 incoming array entry into the Source string but also the outgoing array entry after having
97 parsed the equivalent of a single Glyph's worth of data.
98
99 Arguments:
100
101 Returns:
102
103 --*/
104 {
105 EFI_HII_GLOBAL_DATA *GlobalData;
106 EFI_HII_DATA *HiiData;
107 UINTN Count;
108 BOOLEAN Narrow;
109 UINTN Location;
110 UINTN SearchLocation;
111 UINTN Value;
112 CHAR16 Character;
113 UINTN Attributes;
114
115 if (This == NULL) {
116 return EFI_INVALID_PARAMETER;
117 }
118
119 HiiData = EFI_HII_DATA_FROM_THIS (This);
120
121 GlobalData = HiiData->GlobalData;
122 Count = sizeof (GlobalData->NarrowGlyphs->GlyphCol1);
123
124 Location = *Index;
125 SearchLocation = *Index;
126 Narrow = TRUE;
127
128 if (Source[Location] == NARROW_CHAR || Source[Location] == WIDE_CHAR) {
129 *InternalStatus = 0;
130 }
131 //
132 // We don't know what glyph database to look in - let's figure it out
133 //
134 if (*InternalStatus == 0) {
135 //
136 // Determine if we are looking for narrow or wide glyph data
137 //
138 do {
139 if (Source[SearchLocation] == NARROW_CHAR || Source[SearchLocation] == WIDE_CHAR) {
140 //
141 // We found something that identifies what glyph database to look in
142 //
143 if (Source[SearchLocation] == WIDE_CHAR) {
144 Narrow = FALSE;
145 *BitWidth = WIDE_WIDTH;
146 *InternalStatus = WIDE_CHAR;
147 Location++;
148 break;
149 } else {
150 Narrow = TRUE;
151 *BitWidth = NARROW_WIDTH;
152 *InternalStatus = NARROW_CHAR;
153 Location++;
154 break;
155 }
156 }
157 } while (SearchLocation-- > 0);
158 }
159
160 if (*InternalStatus == NARROW_CHAR) {
161 Narrow = TRUE;
162 *BitWidth = NARROW_WIDTH;
163 } else if (*InternalStatus == WIDE_CHAR) {
164 Narrow = FALSE;
165 *BitWidth = WIDE_WIDTH;
166 } else {
167 //
168 // Without otherwise knowing what the width is narrow (e.g. someone passed in a string with index of 0
169 // we wouldn't be able to determine the width of the data.)
170 // BUGBUG - do we go to wide database and if exist, ignore narrow? Check Unicode spec....
171 //
172 Narrow = TRUE;
173 *BitWidth = NARROW_WIDTH;
174 }
175
176 Character = Source[Location];
177
178 if (Narrow) {
179 if (GlobalData->NarrowGlyphs[Character].UnicodeWeight != 0x0000) {
180 *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);
181 Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
182 } else {
183 //
184 // Glyph is uninitialized - return an error, but hand back the glyph
185 //
186 *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);
187 *Index = (UINT16) (Location + 1);
188 return EFI_NOT_FOUND;
189 }
190 } else {
191 //
192 // Wide character
193 //
194 if (GlobalData->WideGlyphs[Character].UnicodeWeight != 0x0000) {
195 *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);
196 Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
197 } else {
198 //
199 // Glyph is uninitialized - return an error, but hand back the glyph
200 //
201 *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);
202 *Index = (UINT16) (Location + 1);
203 return EFI_NOT_FOUND;
204 }
205 }
206 //
207 // This is a non-spacing character. It will be followed by either more non-spacing
208 // characters or a regular character. We need to OR together the data associated with each.
209 //
210 for (; Attributes != 0; Location++) {
211 //
212 // Character is the Unicode value which is the index into the Glyph array.
213 //
214 Character = Source[Location];
215
216 if (Narrow) {
217 for (Value = 0; Value != Count; Value++) {
218 *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] |
219 GlobalData->NarrowGlyphs[Character].GlyphCol1[Value]);
220 }
221
222 Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
223 } else {
224 for (Value = 0; Value != Count; Value++) {
225 *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] |
226 GlobalData->WideGlyphs[Character].GlyphCol1[Value]);
227 *GlyphBuffer[Location + Value + Count] = (UINT8) (*GlyphBuffer[Location + Value + Count] |
228 GlobalData->WideGlyphs[Character].GlyphCol2[Value]);
229 }
230
231 Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;
232 }
233 }
234 //
235 // Source[*Index] should point to the next character to process
236 //
237 *Index = (UINT16) (Location + 1);
238 return EFI_SUCCESS;
239 }
240
241 EFI_STATUS
242 EFIAPI
243 HiiGlyphToBlt (
244 IN EFI_HII_PROTOCOL *This,
245 IN UINT8 *GlyphBuffer,
246 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,
247 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,
248 IN UINTN Count,
249 IN UINTN Width,
250 IN UINTN Height,
251 IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
252 )
253 {
254 UINTN X;
255 UINTN Y;
256
257 //
258 // Convert Monochrome bitmap of the Glyph to BltBuffer structure
259 //
260 for (Y = 0; Y < Height; Y++) {
261 for (X = 0; X < Width; X++) {
262 if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {
263 BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;
264 } else {
265 BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;
266 }
267 }
268 }
269
270 return EFI_SUCCESS;
271 }