Browse Source

[fbcon] Allow character height to be selected at runtime

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
bc69777a40
3 changed files with 44 additions and 23 deletions
  1. 23
    5
      src/arch/i386/interface/pcbios/vesafb.c
  2. 9
    10
      src/core/fbcon.c
  3. 12
    8
      src/include/ipxe/fbcon.h

+ 23
- 5
src/arch/i386/interface/pcbios/vesafb.c View File

@@ -66,6 +66,9 @@ struct console_driver bios_console __attribute__ (( weak ));
66 66
 #define CONSOLE_VESAFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
67 67
 #endif
68 68
 
69
+/** Character height */
70
+#define VESAFB_CHAR_HEIGHT 16
71
+
69 72
 /** Font corresponding to selected character width and height */
70 73
 #define VESAFB_FONT VBE_FONT_8x16
71 74
 
@@ -86,6 +89,8 @@ struct vesafb {
86 89
 	struct fbcon_colour_map map;
87 90
 	/** Font definition */
88 91
 	struct fbcon_font font;
92
+	/** Character glyphs */
93
+	struct segoff glyphs;
89 94
 	/** Saved VGA mode */
90 95
 	uint8_t saved_mode;
91 96
 };
@@ -118,12 +123,24 @@ static int vesafb_rc ( unsigned int status ) {
118 123
 	return ( code ? -EIO_VBE ( code ) : 0 );
119 124
 }
120 125
 
126
+/**
127
+ * Get character glyph
128
+ *
129
+ * @v character		Character
130
+ * @v glyph		Character glyph to fill in
131
+ */
132
+static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
133
+	size_t offset = ( character * VESAFB_CHAR_HEIGHT );
134
+
135
+	copy_from_real ( glyph, vesafb.glyphs.segment,
136
+			 ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
137
+}
138
+
121 139
 /**
122 140
  * Get font definition
123 141
  *
124 142
  */
125 143
 static void vesafb_font ( void ) {
126
-	struct segoff font;
127 144
 
128 145
 	/* Get font information
129 146
 	 *
@@ -144,13 +161,14 @@ static void vesafb_font ( void ) {
144 161
 					   "movw %%es, %%cx\n\t"
145 162
 					   "movw %%bp, %%dx\n\t"
146 163
 					   "popw %%bp\n\t" /* gcc bug */ )
147
-			       : "=c" ( font.segment ),
148
-				 "=d" ( font.offset )
164
+			       : "=c" ( vesafb.glyphs.segment ),
165
+				 "=d" ( vesafb.glyphs.offset )
149 166
 			       : "a" ( VBE_GET_FONT ),
150 167
 				 "b" ( VESAFB_FONT ) );
151 168
 	DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
152
-	       VESAFB_FONT, font.segment, font.offset );
153
-	vesafb.font.start = real_to_user ( font.segment, font.offset );
169
+	       VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
170
+	vesafb.font.height = VESAFB_CHAR_HEIGHT;
171
+	vesafb.font.glyph = vesafb_glyph;
154 172
 }
155 173
 
156 174
 /**

+ 9
- 10
src/core/fbcon.c View File

@@ -156,7 +156,7 @@ static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
156 156
  */
157 157
 static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
158 158
 			 unsigned int xpos, unsigned int ypos ) {
159
-	struct fbcon_font_glyph glyph;
159
+	uint8_t glyph[fbcon->font->height];
160 160
 	size_t offset;
161 161
 	size_t pixel_len;
162 162
 	size_t skip_len;
@@ -167,9 +167,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
167 167
 	void *src;
168 168
 
169 169
 	/* Get font character */
170
-	copy_from_user ( &glyph, fbcon->font->start,
171
-			 ( cell->character * sizeof ( glyph ) ),
172
-			 sizeof ( glyph ) );
170
+	fbcon->font->glyph ( cell->character, glyph );
173 171
 
174 172
 	/* Calculate pixel geometry */
175 173
 	offset = ( fbcon->indent +
@@ -182,7 +180,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
182 180
 	transparent = ( cell->background == FBCON_TRANSPARENT );
183 181
 
184 182
 	/* Draw character rows */
185
-	for ( row = 0 ; row < FBCON_CHAR_HEIGHT ; row++ ) {
183
+	for ( row = 0 ; row < fbcon->font->height ; row++ ) {
186 184
 
187 185
 		/* Draw background picture, if applicable */
188 186
 		if ( transparent ) {
@@ -197,7 +195,7 @@ static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
197 195
 		}
198 196
 
199 197
 		/* Draw character row */
200
-		for ( column = FBCON_CHAR_WIDTH, bitmask = glyph.bitmask[row] ;
198
+		for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
201 199
 		      column ; column--, bitmask <<= 1, offset += pixel_len ) {
202 200
 			if ( bitmask & 0x80 ) {
203 201
 				src = &cell->foreground;
@@ -614,7 +612,8 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
614 612
 	/* Expand margin to accommodate whole characters */
615 613
 	width = ( pixel->width - margin->left - margin->right );
616 614
 	height = ( pixel->height - margin->top - margin->bottom );
617
-	if ( ( width < FBCON_CHAR_WIDTH ) || ( height < FBCON_CHAR_HEIGHT ) ) {
615
+	if ( ( width < FBCON_CHAR_WIDTH ) ||
616
+	     ( height < ( ( int ) font->height ) ) ) {
618 617
 		DBGC ( fbcon, "FBCON %p has unusable character area "
619 618
 		       "[%d-%d),[%d-%d)\n", fbcon,
620 619
 		       margin->left, ( pixel->width - margin->right ),
@@ -623,7 +622,7 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
623 622
 		goto err_margin;
624 623
 	}
625 624
 	xgap = ( width % FBCON_CHAR_WIDTH );
626
-	ygap = ( height % FBCON_CHAR_HEIGHT );
625
+	ygap = ( height % font->height );
627 626
 	fbcon->margin.left = ( margin->left + ( xgap / 2 ) );
628 627
 	fbcon->margin.top = ( margin->top + ( ygap / 2 ) );
629 628
 	fbcon->margin.right = ( margin->right + ( xgap - ( xgap / 2 ) ) );
@@ -633,9 +632,9 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start,
633 632
 
634 633
 	/* Derive character geometry from pixel geometry */
635 634
 	fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
636
-	fbcon->character.height = ( height / FBCON_CHAR_HEIGHT );
635
+	fbcon->character.height = ( height / font->height );
637 636
 	fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
638
-	fbcon->character.stride = ( pixel->stride * FBCON_CHAR_HEIGHT );
637
+	fbcon->character.stride = ( pixel->stride * font->height );
639 638
 	DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
640 639
 	       "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
641 640
 	       fbcon->pixel->height, fbcon->character.width,

+ 12
- 8
src/include/ipxe/fbcon.h View File

@@ -18,9 +18,6 @@ struct pixel_buffer;
18 18
 /** Character width, in pixels */
19 19
 #define FBCON_CHAR_WIDTH 9
20 20
 
21
-/** Character height, in pixels */
22
-#define FBCON_CHAR_HEIGHT 16
23
-
24 21
 /** Bold colour modifier (RGB value) */
25 22
 #define FBCON_BOLD 0x555555
26 23
 
@@ -30,14 +27,21 @@ struct pixel_buffer;
30 27
 /** A font glyph */
31 28
 struct fbcon_font_glyph {
32 29
 	/** Row bitmask */
33
-	uint8_t bitmask[FBCON_CHAR_HEIGHT];
34
-} __attribute__ (( packed ));
30
+	uint8_t bitmask[0];
31
+};
35 32
 
36 33
 /** A font definition */
37 34
 struct fbcon_font {
38
-	/** Character glyphs */
39
-	userptr_t start;
40
-} __attribute__ (( packed ));
35
+	/** Character height (in pixels) */
36
+	unsigned int height;
37
+	/**
38
+	 * Get character glyph
39
+	 *
40
+	 * @v character		Character
41
+	 * @v glyph		Character glyph to fill in
42
+	 */
43
+	void ( * glyph ) ( unsigned int character, uint8_t *glyph );
44
+};
41 45
 
42 46
 /** A frame buffer geometry
43 47
  *

Loading…
Cancel
Save