Browse Source

[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>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
e303a6b387
1 changed files with 38 additions and 16 deletions
  1. 38
    16
      src/interface/efi/efi_fbcon.c

+ 38
- 16
src/interface/efi/efi_fbcon.c View File

110
  */
110
  */
111
 static int efifb_glyphs ( void ) {
111
 static int efifb_glyphs ( void ) {
112
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
112
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
113
-	EFI_FONT_DISPLAY_INFO *info;
114
 	EFI_IMAGE_OUTPUT *blt;
113
 	EFI_IMAGE_OUTPUT *blt;
115
 	EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
114
 	EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
116
 	size_t offset;
115
 	size_t offset;
122
 	EFI_STATUS efirc;
121
 	EFI_STATUS efirc;
123
 	int rc;
122
 	int rc;
124
 
123
 
125
-	/* Get font height */
126
-	if ( ( efirc = efifb.hiifont->GetFontInfo ( efifb.hiifont, NULL, NULL,
127
-						    &info, NULL ) ) != 0 ) {
128
-		rc = -EEFI ( efirc );
129
-		DBGC ( &efifb, "EFIFB could not get font information: %s\n",
130
-		       strerror ( rc ) );
131
-		goto err_info;
124
+	/* Get font height.  The GetFontInfo() call nominally returns
125
+	 * this information in an EFI_FONT_DISPLAY_INFO structure, but
126
+	 * is known to fail on many UEFI implementations.  Instead, we
127
+	 * iterate over all printable characters to find the maximum
128
+	 * height.
129
+	 */
130
+	efifb.font.height = 0;
131
+	for ( character = 0 ; character < 256 ; character++ ) {
132
+
133
+		/* Skip non-printable characters */
134
+		if ( ! isprint ( character ) )
135
+			continue;
136
+
137
+		/* Get glyph */
138
+		blt = NULL;
139
+		if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
140
+							 character, NULL, &blt,
141
+							 NULL ) ) != 0 ) {
142
+			rc = -EEFI ( efirc );
143
+			DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
144
+			       character, strerror ( rc ) );
145
+			continue;
146
+		}
147
+		assert ( blt != NULL );
148
+
149
+		/* Calculate maximum height */
150
+		if ( efifb.font.height < blt->Height )
151
+			efifb.font.height = blt->Height;
152
+
153
+		/* Free glyph */
154
+		bs->FreePool ( blt );
155
+	}
156
+	if ( ! efifb.font.height ) {
157
+		DBGC ( &efifb, "EFIFB could not get font height\n" );
158
+		return -ENOENT;
132
 	}
159
 	}
133
-	assert ( info != NULL );
134
-	efifb.font.height = info->FontInfo.FontSize;
135
 
160
 
136
 	/* Allocate glyph data */
161
 	/* Allocate glyph data */
137
 	len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
162
 	len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
152
 		/* Get glyph */
177
 		/* Get glyph */
153
 		blt = NULL;
178
 		blt = NULL;
154
 		if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
179
 		if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
155
-							 character, info, &blt,
180
+							 character, NULL, &blt,
156
 							 NULL ) ) != 0 ) {
181
 							 NULL ) ) != 0 ) {
157
 			rc = -EEFI ( efirc );
182
 			rc = -EEFI ( efirc );
158
 			DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
183
 			DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
187
 			copy_to_user ( efifb.glyphs, offset++, &bitmask,
212
 			copy_to_user ( efifb.glyphs, offset++, &bitmask,
188
 				       sizeof ( bitmask ) );
213
 				       sizeof ( bitmask ) );
189
 		}
214
 		}
215
+
216
+		/* Free glyph */
190
 		bs->FreePool ( blt );
217
 		bs->FreePool ( blt );
191
 	}
218
 	}
192
 
219
 
193
-	/* Free font information */
194
-	bs->FreePool ( info );
195
-
196
 	efifb.font.glyph = efifb_glyph;
220
 	efifb.font.glyph = efifb_glyph;
197
 	return 0;
221
 	return 0;
198
 
222
 
199
 	ufree ( efifb.glyphs );
223
 	ufree ( efifb.glyphs );
200
  err_alloc:
224
  err_alloc:
201
-	bs->FreePool ( info );
202
- err_info:
203
 	return rc;
225
 	return rc;
204
 }
226
 }
205
 
227
 

Loading…
Cancel
Save