EFI_NARROW_GLYPH/EFI_WIDE_GLYPH 형식 조사 및 *.woff 글꼴 파일에서 GLYPH 배열 구성
UNI 파일은 UEFI의 로컬화를 위한 것이다. 지금까지 우리는, UNI 파일에서 영어와 프랑스어만 출력해 보았다. 이 두 언어의 공통점은, 라틴어 문자 집합의 기호를 사용한다는 점에서 같다.
다른 문자 집합에서 문자열을 출력하려면 올바른 문장이 출력되지 않는다. 예를 들어, 간단하게 Hello를 러시아어로 출력하려면,
Print(L"Привет!\n");
다음과 같이 출력된다.
nographic 모드에서는 다음과 같이 출력될 것이다.
FS0:\> HIIFont.efi
?@825B!
이 출력을 구현하는 것에는 신경쓰지 말자. 이는 다른 번역 레벨에서 발생하는 것이고, 이번 장에서는 UEFI Graphic(Native 또는 VNC)을 살펴보도록 하자.
어쨌건 출력으로 보이듯이, ! 하나만 출력된 것을 볼 수 있다. UEFI 시스템 자체에는 러시아어 글꼴이 없기 때문에 위와 같은 일이 발생한 것이다.
컴퓨터의 언어로 해석하자면, 러시아어 유니코드 기호 코드를 기호 이미지로 변환하는 방법을 UEFI 시스템은 모르기 때문이다.
글꼴 정보는 HII DB에 저장되므로, 문제를 해결하려면 러시아 코드가 있는 유니코드 기호에 대한 "그림"이 있는 글꼴 유형 패키지가 포함된 패키지 목록을 제공하기만 하면 된다.
UEFI는 작게는 8x19에 넓게는 16x19 글꼴은 사용한다. 코드에서 기호 데이터는 EFI_NARROW_GLYPH 및 EFI_WIDE_GLYPH(UefiInternalFormRepresentation.h) 구조로 인코딩된다.
$ cat MdePkg/Include/Uefi/UefiInternalFormRepresentation.h
---
#define EFI_GLYPH_HEIGHT 19
#define EFI_GLYPH_WIDTH 8
///@}
///
/// The EFI_NARROW_GLYPH has a preferred dimension (w x h) of 8 x 19 pixels.
///
typedef struct {
///
/// The Unicode representation of the glyph. The term weight is the
/// technical term for a character code.
///
CHAR16 UnicodeWeight;
///
/// The data element containing the glyph definitions.
///
UINT8 Attributes;
///
/// The column major glyph representation of the character. Bits
/// with values of one indicate that the corresponding pixel is to be
/// on when normally displayed; those with zero are off.
///
UINT8 GlyphCol1[EFI_GLYPH_HEIGHT];
} EFI_NARROW_GLYPH;
///
/// The EFI_WIDE_GLYPH has a preferred dimension (w x h) of 16 x 19 pixels, which is large enough
/// to accommodate logographic characters.
///
typedef struct {
///
/// The Unicode representation of the glyph. The term weight is the
/// technical term for a character code.
///
CHAR16 UnicodeWeight;
///
/// The data element containing the glyph definitions.
///
UINT8 Attributes;
///
/// The column major glyph representation of the character. Bits
/// with values of one indicate that the corresponding pixel is to be
/// on when normally displayed; those with zero are off.
///
UINT8 GlyphCol1[EFI_GLYPH_HEIGHT];
///
/// The column major glyph representation of the character. Bits
/// with values of one indicate that the corresponding pixel is to be
/// on when normally displayed; those with zero are off.
///
UINT8 GlyphCol2[EFI_GLYPH_HEIGHT];
///
/// Ensures that sizeof (EFI_WIDE_GLYPH) is twice the
/// sizeof (EFI_NARROW_GLYPH). The contents of Pad must
/// be zero.
///
UINT8 Pad[3];
} EFI_WIDE_GLYPH;
이유는 모르겠지만, mFontBin 구조의 String.c에서 일부 히브리어 문자에 대한 예를 찾아볼 수 있었다. 이 구조에서 유니코드 0x05d2가 있는 기호 하나를 살펴보도록 하겠다.
GlyphCol1 배열을 보고, 이진 시스템에서 배열 데이터를 인쇄해보자. X/-로도 표현해 보았다.
이 gUsStdNarrowGlyphData 배열은 글꼴 패키지를 생성하고, HII 데이터베이스에 등록하는 데 사용된다. 실제 코드는 MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c 파일의 RegisterFontPackage 함수를 참조하도록 하자.
constunicode_start_code=0x0400;constunicode_end_code=0x045F;var f =newFontFace('AST','url(web_ast_premiumexec.woff)');f.load().then(function() {document.write(UnicodeToGlyphs(unicode_start_code, unicode_end_code));})
글꼴이 로드되면, canvas에 U+0400에서 U+045F까지의 유니코드 기호를 인쇄하고, 데이터를 조사하고 화면의 UEFI에 대한 최종 C 배열을 출력하는 사용자 지정 함수 UnicodeToGlyphs를 실행한다.
그리고 여기에 나머지 자바스크립트코드가 있다. 이는 매우 간단하므로, 이해하기 어렵지 않을 것이라 생각한다.