--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ Fonts.c\r
+\r
+Abstract:\r
+\r
+ This file contains the Glyph/Font processing code to the HII database.\r
+\r
+--*/\r
+\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
+\r
+#include "HiiDatabase.h"\r
+\r
+//\r
+// We only need to define a wide glyph, since we will seed the narrow glyph with EFI_NARROW_GLYPH size of\r
+// this data structure\r
+//\r
+UINT8 mUnknownGlyph[38] = {\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xAA,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xaa,\r
+ 0x55,\r
+ 0xAA\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGetGlyph (\r
+ IN EFI_HII_PROTOCOL *This,\r
+ IN CHAR16 *Source,\r
+ IN OUT UINT16 *Index,\r
+ OUT UINT8 **GlyphBuffer,\r
+ OUT UINT16 *BitWidth,\r
+ IN OUT UINT32 *InternalStatus\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Translates a Unicode character into the corresponding font glyph. \r
+ If the Source was pointing to a non-spacing character, the next Source[*Index]\r
+ character will be parsed and OR'd to the GlyphBuffer until a spacing character\r
+ is found in the Source. Since non-spacing characters are considered to be the\r
+ same pixel width as a regular character their BitWidth will be reflected correctly\r
+ however due to their special attribute, they are considered to be zero advancing width.\r
+ This basically means that the cursor would not advance, thus the character that follows\r
+ it would overlay the non-spacing character. The Index is modified to reflect both the\r
+ incoming array entry into the Source string but also the outgoing array entry after having\r
+ parsed the equivalent of a single Glyph's worth of data.\r
+\r
+Arguments:\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+ EFI_HII_GLOBAL_DATA *GlobalData;\r
+ EFI_HII_DATA *HiiData;\r
+ UINTN Count;\r
+ BOOLEAN Narrow;\r
+ UINTN Location;\r
+ UINTN SearchLocation;\r
+ UINTN Value;\r
+ CHAR16 Character;\r
+ UINTN Attributes;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ HiiData = EFI_HII_DATA_FROM_THIS (This);\r
+\r
+ GlobalData = HiiData->GlobalData;\r
+ Count = sizeof (GlobalData->NarrowGlyphs->GlyphCol1);\r
+\r
+ Location = *Index;\r
+ SearchLocation = *Index;\r
+ Narrow = TRUE;\r
+\r
+ if (Source[Location] == NARROW_CHAR || Source[Location] == WIDE_CHAR) {\r
+ *InternalStatus = 0;\r
+ }\r
+ //\r
+ // We don't know what glyph database to look in - let's figure it out\r
+ //\r
+ if (*InternalStatus == 0) {\r
+ //\r
+ // Determine if we are looking for narrow or wide glyph data\r
+ //\r
+ do {\r
+ if (Source[SearchLocation] == NARROW_CHAR || Source[SearchLocation] == WIDE_CHAR) {\r
+ //\r
+ // We found something that identifies what glyph database to look in\r
+ //\r
+ if (Source[SearchLocation] == WIDE_CHAR) {\r
+ Narrow = FALSE;\r
+ *BitWidth = WIDE_WIDTH;\r
+ *InternalStatus = WIDE_CHAR;\r
+ Location++;\r
+ break;\r
+ } else {\r
+ Narrow = TRUE;\r
+ *BitWidth = NARROW_WIDTH;\r
+ *InternalStatus = NARROW_CHAR;\r
+ Location++;\r
+ break;\r
+ }\r
+ }\r
+ } while (SearchLocation-- > 0);\r
+ }\r
+\r
+ if (*InternalStatus == NARROW_CHAR) {\r
+ Narrow = TRUE;\r
+ *BitWidth = NARROW_WIDTH;\r
+ } else if (*InternalStatus == WIDE_CHAR) {\r
+ Narrow = FALSE;\r
+ *BitWidth = WIDE_WIDTH;\r
+ } else {\r
+ //\r
+ // Without otherwise knowing what the width is narrow (e.g. someone passed in a string with index of 0\r
+ // we wouldn't be able to determine the width of the data.)\r
+ // BUGBUG - do we go to wide database and if exist, ignore narrow? Check Unicode spec....\r
+ //\r
+ Narrow = TRUE;\r
+ *BitWidth = NARROW_WIDTH;\r
+ }\r
+\r
+ Character = Source[Location];\r
+\r
+ if (Narrow) {\r
+ if (GlobalData->NarrowGlyphs[Character].UnicodeWeight != 0x0000) {\r
+ *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);\r
+ Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+ } else {\r
+ //\r
+ // Glyph is uninitialized - return an error, but hand back the glyph\r
+ //\r
+ *GlyphBuffer = (UINT8 *) (&GlobalData->NarrowGlyphs[Character]);\r
+ *Index = (UINT16) (Location + 1);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ } else {\r
+ //\r
+ // Wide character\r
+ //\r
+ if (GlobalData->WideGlyphs[Character].UnicodeWeight != 0x0000) {\r
+ *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);\r
+ Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+ } else {\r
+ //\r
+ // Glyph is uninitialized - return an error, but hand back the glyph\r
+ //\r
+ *GlyphBuffer = (UINT8 *) (&GlobalData->WideGlyphs[Character]);\r
+ *Index = (UINT16) (Location + 1);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+ //\r
+ // This is a non-spacing character. It will be followed by either more non-spacing\r
+ // characters or a regular character. We need to OR together the data associated with each.\r
+ //\r
+ for (; Attributes != 0; Location++) {\r
+ //\r
+ // Character is the Unicode value which is the index into the Glyph array.\r
+ //\r
+ Character = Source[Location];\r
+\r
+ if (Narrow) {\r
+ for (Value = 0; Value != Count; Value++) {\r
+ *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] |\r
+ GlobalData->NarrowGlyphs[Character].GlyphCol1[Value]);\r
+ }\r
+\r
+ Attributes = GlobalData->NarrowGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+ } else {\r
+ for (Value = 0; Value != Count; Value++) {\r
+ *GlyphBuffer[Location + Value] = (UINT8) (*GlyphBuffer[Location + Value] | \r
+ GlobalData->WideGlyphs[Character].GlyphCol1[Value]);\r
+ *GlyphBuffer[Location + Value + Count] = (UINT8) (*GlyphBuffer[Location + Value + Count] |\r
+ GlobalData->WideGlyphs[Character].GlyphCol2[Value]);\r
+ }\r
+\r
+ Attributes = GlobalData->WideGlyphs[Character].Attributes & EFI_GLYPH_NON_SPACING;\r
+ }\r
+ }\r
+ //\r
+ // Source[*Index] should point to the next character to process\r
+ //\r
+ *Index = (UINT16) (Location + 1);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+HiiGlyphToBlt (\r
+ IN EFI_HII_PROTOCOL *This,\r
+ IN UINT8 *GlyphBuffer,\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground,\r
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background,\r
+ IN UINTN Count,\r
+ IN UINTN Width,\r
+ IN UINTN Height,\r
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer\r
+ )\r
+{\r
+ UINTN X;\r
+ UINTN Y;\r
+\r
+ //\r
+ // Convert Monochrome bitmap of the Glyph to BltBuffer structure\r
+ //\r
+ for (Y = 0; Y < Height; Y++) {\r
+ for (X = 0; X < Width; X++) {\r
+ if ((((EFI_NARROW_GLYPH *) GlyphBuffer)->GlyphCol1[Y] & (1 << X)) != 0) {\r
+ BltBuffer[Y * Width * Count + (Width - X - 1)] = Foreground;\r
+ } else {\r
+ BltBuffer[Y * Width * Count + (Width - X - 1)] = Background;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r