summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2015-10-14 21:42:42 +0200
committerMichael Brown2015-10-14 23:16:40 +0200
commitbc69777a4044c09cfed65d84f11988448b2db277 (patch)
treeda8e8429415473fe7e817e2af93deb9f5b05d8c9
parent[efi] Import EFI_HII_FONT_PROTOCOL definitions (diff)
downloadipxe-bc69777a4044c09cfed65d84f11988448b2db277.tar.gz
ipxe-bc69777a4044c09cfed65d84f11988448b2db277.tar.xz
ipxe-bc69777a4044c09cfed65d84f11988448b2db277.zip
[fbcon] Allow character height to be selected at runtime
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/i386/interface/pcbios/vesafb.c28
-rw-r--r--src/core/fbcon.c19
-rw-r--r--src/include/ipxe/fbcon.h20
3 files changed, 44 insertions, 23 deletions
diff --git a/src/arch/i386/interface/pcbios/vesafb.c b/src/arch/i386/interface/pcbios/vesafb.c
index 9cf2bf29e..4742f956b 100644
--- a/src/arch/i386/interface/pcbios/vesafb.c
+++ b/src/arch/i386/interface/pcbios/vesafb.c
@@ -66,6 +66,9 @@ struct console_driver bios_console __attribute__ (( weak ));
#define CONSOLE_VESAFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#endif
+/** Character height */
+#define VESAFB_CHAR_HEIGHT 16
+
/** Font corresponding to selected character width and height */
#define VESAFB_FONT VBE_FONT_8x16
@@ -86,6 +89,8 @@ struct vesafb {
struct fbcon_colour_map map;
/** Font definition */
struct fbcon_font font;
+ /** Character glyphs */
+ struct segoff glyphs;
/** Saved VGA mode */
uint8_t saved_mode;
};
@@ -119,11 +124,23 @@ static int vesafb_rc ( unsigned int status ) {
}
/**
+ * Get character glyph
+ *
+ * @v character Character
+ * @v glyph Character glyph to fill in
+ */
+static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
+ size_t offset = ( character * VESAFB_CHAR_HEIGHT );
+
+ copy_from_real ( glyph, vesafb.glyphs.segment,
+ ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
+}
+
+/**
* Get font definition
*
*/
static void vesafb_font ( void ) {
- struct segoff font;
/* Get font information
*
@@ -144,13 +161,14 @@ static void vesafb_font ( void ) {
"movw %%es, %%cx\n\t"
"movw %%bp, %%dx\n\t"
"popw %%bp\n\t" /* gcc bug */ )
- : "=c" ( font.segment ),
- "=d" ( font.offset )
+ : "=c" ( vesafb.glyphs.segment ),
+ "=d" ( vesafb.glyphs.offset )
: "a" ( VBE_GET_FONT ),
"b" ( VESAFB_FONT ) );
DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
- VESAFB_FONT, font.segment, font.offset );
- vesafb.font.start = real_to_user ( font.segment, font.offset );
+ VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
+ vesafb.font.height = VESAFB_CHAR_HEIGHT;
+ vesafb.font.glyph = vesafb_glyph;
}
/**
diff --git a/src/core/fbcon.c b/src/core/fbcon.c
index 6d8b0086d..90139c709 100644
--- a/src/core/fbcon.c
+++ b/src/core/fbcon.c
@@ -156,7 +156,7 @@ static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
*/
static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
unsigned int xpos, unsigned int ypos ) {
- struct fbcon_font_glyph glyph;
+ uint8_t glyph[fbcon->font->height];
size_t offset;
size_t pixel_len;
size_t skip_len;
@@ -167,9 +167,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
void *src;
/* Get font character */
- copy_from_user ( &glyph, fbcon->font->start,
- ( cell->character * sizeof ( glyph ) ),
- sizeof ( glyph ) );
+ fbcon->font->glyph ( cell->character, glyph );
/* Calculate pixel geometry */
offset = ( fbcon->indent +
@@ -182,7 +180,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
transparent = ( cell->background == FBCON_TRANSPARENT );
/* Draw character rows */
- for ( row = 0 ; row < FBCON_CHAR_HEIGHT ; row++ ) {
+ for ( row = 0 ; row < fbcon->font->height ; row++ ) {
/* Draw background picture, if applicable */
if ( transparent ) {
@@ -197,7 +195,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
}
/* Draw character row */
- for ( column = FBCON_CHAR_WIDTH, bitmask = glyph.bitmask[row] ;
+ for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
column ; column--, bitmask <<= 1, offset += pixel_len ) {
if ( bitmask & 0x80 ) {
src = &cell->foreground;
@@ -614,7 +612,8 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
/* Expand margin to accommodate whole characters */
width = ( pixel->width - margin->left - margin->right );
height = ( pixel->height - margin->top - margin->bottom );
- if ( ( width < FBCON_CHAR_WIDTH ) || ( height < FBCON_CHAR_HEIGHT ) ) {
+ if ( ( width < FBCON_CHAR_WIDTH ) ||
+ ( height < ( ( int ) font->height ) ) ) {
DBGC ( fbcon, "FBCON %p has unusable character area "
"[%d-%d),[%d-%d)\n", fbcon,
margin->left, ( pixel->width - margin->right ),
@@ -623,7 +622,7 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
goto err_margin;
}
xgap = ( width % FBCON_CHAR_WIDTH );
- ygap = ( height % FBCON_CHAR_HEIGHT );
+ ygap = ( height % font->height );
fbcon->margin.left = ( margin->left + ( xgap / 2 ) );
fbcon->margin.top = ( margin->top + ( ygap / 2 ) );
fbcon->margin.right = ( margin->right + ( xgap - ( xgap / 2 ) ) );
@@ -633,9 +632,9 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
/* Derive character geometry from pixel geometry */
fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
- fbcon->character.height = ( height / FBCON_CHAR_HEIGHT );
+ fbcon->character.height = ( height / font->height );
fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
- fbcon->character.stride = ( pixel->stride * FBCON_CHAR_HEIGHT );
+ fbcon->character.stride = ( pixel->stride * font->height );
DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
"[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
fbcon->pixel->height, fbcon->character.width,
diff --git a/src/include/ipxe/fbcon.h b/src/include/ipxe/fbcon.h
index d442bb918..7837845ed 100644
--- a/src/include/ipxe/fbcon.h
+++ b/src/include/ipxe/fbcon.h
@@ -18,9 +18,6 @@ struct pixel_buffer;
/** Character width, in pixels */
#define FBCON_CHAR_WIDTH 9
-/** Character height, in pixels */
-#define FBCON_CHAR_HEIGHT 16
-
/** Bold colour modifier (RGB value) */
#define FBCON_BOLD 0x555555
@@ -30,14 +27,21 @@ struct pixel_buffer;
/** A font glyph */
struct fbcon_font_glyph {
/** Row bitmask */
- uint8_t bitmask[FBCON_CHAR_HEIGHT];
-} __attribute__ (( packed ));
+ uint8_t bitmask[0];
+};
/** A font definition */
struct fbcon_font {
- /** Character glyphs */
- userptr_t start;
-} __attribute__ (( packed ));
+ /** Character height (in pixels) */
+ unsigned int height;
+ /**
+ * Get character glyph
+ *
+ * @v character Character
+ * @v glyph Character glyph to fill in
+ */
+ void ( * glyph ) ( unsigned int character, uint8_t *glyph );
+};
/** A frame buffer geometry
*