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