mirror of https://github.com/ipxe/ipxe.git
[efi] Work around broken GetFontInfo() implementations
Several UEFI platforms are known to return EFI_NOT_FOUND when asked to retrieve the system default font information via GetFontInfo(). Work around these broken platforms by iterating over the glyphs to find the maximum height used by a printable character. Originally-fixed-by: Jonathan Dieter <jdieter@lesbg.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/44/head
parent
e44f6dcb89
commit
e303a6b387
|
@ -110,7 +110,6 @@ static void efifb_glyph ( unsigned int character, uint8_t *glyph ) {
|
||||||
*/
|
*/
|
||||||
static int efifb_glyphs ( void ) {
|
static int efifb_glyphs ( void ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
EFI_FONT_DISPLAY_INFO *info;
|
|
||||||
EFI_IMAGE_OUTPUT *blt;
|
EFI_IMAGE_OUTPUT *blt;
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
@ -122,16 +121,42 @@ static int efifb_glyphs ( void ) {
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Get font height */
|
/* Get font height. The GetFontInfo() call nominally returns
|
||||||
if ( ( efirc = efifb.hiifont->GetFontInfo ( efifb.hiifont, NULL, NULL,
|
* this information in an EFI_FONT_DISPLAY_INFO structure, but
|
||||||
&info, NULL ) ) != 0 ) {
|
* is known to fail on many UEFI implementations. Instead, we
|
||||||
rc = -EEFI ( efirc );
|
* iterate over all printable characters to find the maximum
|
||||||
DBGC ( &efifb, "EFIFB could not get font information: %s\n",
|
* height.
|
||||||
strerror ( rc ) );
|
*/
|
||||||
goto err_info;
|
efifb.font.height = 0;
|
||||||
|
for ( character = 0 ; character < 256 ; character++ ) {
|
||||||
|
|
||||||
|
/* Skip non-printable characters */
|
||||||
|
if ( ! isprint ( character ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Get glyph */
|
||||||
|
blt = NULL;
|
||||||
|
if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
|
||||||
|
character, NULL, &blt,
|
||||||
|
NULL ) ) != 0 ) {
|
||||||
|
rc = -EEFI ( efirc );
|
||||||
|
DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
|
||||||
|
character, strerror ( rc ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert ( blt != NULL );
|
||||||
|
|
||||||
|
/* Calculate maximum height */
|
||||||
|
if ( efifb.font.height < blt->Height )
|
||||||
|
efifb.font.height = blt->Height;
|
||||||
|
|
||||||
|
/* Free glyph */
|
||||||
|
bs->FreePool ( blt );
|
||||||
|
}
|
||||||
|
if ( ! efifb.font.height ) {
|
||||||
|
DBGC ( &efifb, "EFIFB could not get font height\n" );
|
||||||
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
assert ( info != NULL );
|
|
||||||
efifb.font.height = info->FontInfo.FontSize;
|
|
||||||
|
|
||||||
/* Allocate glyph data */
|
/* Allocate glyph data */
|
||||||
len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
|
len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
|
||||||
|
@ -152,7 +177,7 @@ static int efifb_glyphs ( void ) {
|
||||||
/* Get glyph */
|
/* Get glyph */
|
||||||
blt = NULL;
|
blt = NULL;
|
||||||
if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
|
if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
|
||||||
character, info, &blt,
|
character, NULL, &blt,
|
||||||
NULL ) ) != 0 ) {
|
NULL ) ) != 0 ) {
|
||||||
rc = -EEFI ( efirc );
|
rc = -EEFI ( efirc );
|
||||||
DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
|
DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
|
||||||
|
@ -187,19 +212,16 @@ static int efifb_glyphs ( void ) {
|
||||||
copy_to_user ( efifb.glyphs, offset++, &bitmask,
|
copy_to_user ( efifb.glyphs, offset++, &bitmask,
|
||||||
sizeof ( bitmask ) );
|
sizeof ( bitmask ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free glyph */
|
||||||
bs->FreePool ( blt );
|
bs->FreePool ( blt );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free font information */
|
|
||||||
bs->FreePool ( info );
|
|
||||||
|
|
||||||
efifb.font.glyph = efifb_glyph;
|
efifb.font.glyph = efifb_glyph;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ufree ( efifb.glyphs );
|
ufree ( efifb.glyphs );
|
||||||
err_alloc:
|
err_alloc:
|
||||||
bs->FreePool ( info );
|
|
||||||
err_info:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue