diff options
author | dumbbell <dumbbell@FreeBSD.org> | 2014-08-25 19:06:31 +0000 |
---|---|---|
committer | dumbbell <dumbbell@FreeBSD.org> | 2014-08-25 19:06:31 +0000 |
commit | a5aa919ddafe73ca47d77a8c52535f313fa8e778 (patch) | |
tree | 7b2b23dc301451432b594c056eba51ee37e7cb8e | |
parent | 9c2354b6686d5daebb9ee5966febe565b77063fa (diff) | |
download | FreeBSD-src-a5aa919ddafe73ca47d77a8c52535f313fa8e778.zip FreeBSD-src-a5aa919ddafe73ca47d77a8c52535f313fa8e778.tar.gz |
vt(4): Store a rectangle for the drawable area, not just the top-left corner
This allows backends to verify they do not draw outside of this area.
This fixes a bug in vt_vga where the text was happily drawn over the
right and bottom margins, when using the Gallant font.
MFC after: 1 week
-rw-r--r-- | sys/dev/fb/creator_vt.c | 14 | ||||
-rw-r--r-- | sys/dev/vt/hw/fb/vt_fb.c | 14 | ||||
-rw-r--r-- | sys/dev/vt/hw/ofwfb/ofwfb.c | 14 | ||||
-rw-r--r-- | sys/dev/vt/hw/vga/vt_vga.c | 53 | ||||
-rw-r--r-- | sys/dev/vt/vt.h | 2 | ||||
-rw-r--r-- | sys/dev/vt/vt_core.c | 22 |
6 files changed, 68 insertions, 51 deletions
diff --git a/sys/dev/fb/creator_vt.c b/sys/dev/fb/creator_vt.c index 6bed29d..18a42b9 100644 --- a/sys/dev/fb/creator_vt.c +++ b/sys/dev/fb/creator_vt.c @@ -236,8 +236,10 @@ creatorfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) { for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col; ++col) { - x = col * vf->vf_width + vw->vw_offset.tp_col; - y = row * vf->vf_height + vw->vw_offset.tp_row; + x = col * vf->vf_width + + vw->vw_draw_area.tr_begin.tp_col; + y = row * vf->vf_height + + vw->vw_draw_area.tr_begin.tp_row; c = VTBUF_GET_FIELD(&vw->vw_buf, row, col); pattern = vtfont_lookup(vf, c); @@ -257,13 +259,13 @@ creatorfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, term_rect_t drawn_area; drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; if (vt_is_cursor_in_area(vd, &drawn_area)) { creatorfb_bitblt_bitmap(vd, vw, diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c index 04023c0..3cae588 100644 --- a/sys/dev/vt/hw/fb/vt_fb.c +++ b/sys/dev/vt/hw/fb/vt_fb.c @@ -331,8 +331,10 @@ vt_fb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) { for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col; ++col) { - x = col * vf->vf_width + vw->vw_offset.tp_col; - y = row * vf->vf_height + vw->vw_offset.tp_row; + x = col * vf->vf_width + + vw->vw_draw_area.tr_begin.tp_col; + y = row * vf->vf_height + + vw->vw_draw_area.tr_begin.tp_row; c = VTBUF_GET_FIELD(&vw->vw_buf, row, col); pattern = vtfont_lookup(vf, c); @@ -352,13 +354,13 @@ vt_fb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, term_rect_t drawn_area; drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; if (vt_is_cursor_in_area(vd, &drawn_area)) { vt_fb_bitblt_bitmap(vd, vw, diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c index 2a31d16..835a07d 100644 --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -209,8 +209,10 @@ ofwfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) { for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col; ++col) { - x = col * vf->vf_width + vw->vw_offset.tp_col; - y = row * vf->vf_height + vw->vw_offset.tp_row; + x = col * vf->vf_width + + vw->vw_draw_area.tr_begin.tp_col; + y = row * vf->vf_height + + vw->vw_draw_area.tr_begin.tp_row; c = VTBUF_GET_FIELD(&vw->vw_buf, row, col); pattern = vtfont_lookup(vf, c); @@ -230,13 +232,13 @@ ofwfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, term_rect_t drawn_area; drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width + - vw->vw_offset.tp_col; + vw->vw_draw_area.tr_begin.tp_col; drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height + - vw->vw_offset.tp_row; + vw->vw_draw_area.tr_begin.tp_row; if (vt_is_cursor_in_area(vd, &drawn_area)) { ofwfb_bitblt_bitmap(vd, vw, diff --git a/sys/dev/vt/hw/vga/vt_vga.c b/sys/dev/vt/hw/vga/vt_vga.c index e21a9a1..135845d 100644 --- a/sys/dev/vt/hw/vga/vt_vga.c +++ b/sys/dev/vt/hw/vga/vt_vga.c @@ -556,16 +556,17 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd, memset(pattern_2colors, 0, sizeof(pattern_2colors)); memset(pattern_ncolors, 0, sizeof(pattern_ncolors)); - if (i < vw->vw_offset.tp_col) { + if (i < vw->vw_draw_area.tr_begin.tp_col) { /* * i is in the margin used to center the text area on * the screen. */ - i = vw->vw_offset.tp_col; + i = vw->vw_draw_area.tr_begin.tp_col; } - while (i < x + VT_VGA_PIXELS_BLOCK) { + while (i < x + VT_VGA_PIXELS_BLOCK && + i < vw->vw_draw_area.tr_end.tp_col) { /* * Find which character is drawn on this pixel in the * pixels block. @@ -573,8 +574,8 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd, * While here, record what colors it uses. */ - col = (i - vw->vw_offset.tp_col) / vf->vf_width; - row = (y - vw->vw_offset.tp_row) / vf->vf_height; + col = (i - vw->vw_draw_area.tr_begin.tp_col) / vf->vf_width; + row = (y - vw->vw_draw_area.tr_begin.tp_row) / vf->vf_height; c = VTBUF_GET_FIELD(vb, row, col); src = vtfont_lookup(vf, c); @@ -605,11 +606,15 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd, * character. */ - src_x = i - (col * vf->vf_width + vw->vw_offset.tp_col); - x_count = min( - (col + 1) * vf->vf_width + vw->vw_offset.tp_col, - x + VT_VGA_PIXELS_BLOCK); - x_count -= col * vf->vf_width + vw->vw_offset.tp_col; + src_x = i - + (col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col); + x_count = min(min( + (col + 1) * vf->vf_width + + vw->vw_draw_area.tr_begin.tp_col, + x + VT_VGA_PIXELS_BLOCK), + vw->vw_draw_area.tr_end.tp_col); + x_count -= col * vf->vf_width + + vw->vw_draw_area.tr_begin.tp_col; x_count -= src_x; /* Copy a portion of the character. */ @@ -643,14 +648,16 @@ vga_bitblt_one_text_pixels_block(struct vt_device *vd, unsigned int dst_x, src_y, dst_y, y_count; cursor = vd->vd_mcursor; - mx = vd->vd_mx_drawn + vw->vw_offset.tp_col; - my = vd->vd_my_drawn + vw->vw_offset.tp_row; + mx = vd->vd_mx_drawn + vw->vw_draw_area.tr_begin.tp_col; + my = vd->vd_my_drawn + vw->vw_draw_area.tr_begin.tp_row; /* Compute the portion of the cursor we want to copy. */ src_x = x > mx ? x - mx : 0; dst_x = mx > x ? mx - x : 0; - x_count = min( - min(cursor->width - src_x, x + VT_VGA_PIXELS_BLOCK - mx), + x_count = min(min(min( + cursor->width - src_x, + x + VT_VGA_PIXELS_BLOCK - mx), + vw->vw_draw_area.tr_end.tp_col - mx), VT_VGA_PIXELS_BLOCK); /* @@ -725,10 +732,10 @@ vga_bitblt_text_gfxmode(struct vt_device *vd, const struct vt_window *vw, col = area->tr_begin.tp_col; row = area->tr_begin.tp_row; - x1 = (int)((col * vf->vf_width + vw->vw_offset.tp_col) + x1 = (int)((col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col) / VT_VGA_PIXELS_BLOCK) * VT_VGA_PIXELS_BLOCK; - y1 = row * vf->vf_height + vw->vw_offset.tp_row; + y1 = row * vf->vf_height + vw->vw_draw_area.tr_begin.tp_row; /* * Compute the bottom right pixel position, again, aligned with @@ -740,19 +747,15 @@ vga_bitblt_text_gfxmode(struct vt_device *vd, const struct vt_window *vw, col = area->tr_end.tp_col; row = area->tr_end.tp_row; - x2 = (int)((col * vf->vf_width + vw->vw_offset.tp_col + x2 = (int)((col * vf->vf_width + vw->vw_draw_area.tr_begin.tp_col + VT_VGA_PIXELS_BLOCK - 1) / VT_VGA_PIXELS_BLOCK) * VT_VGA_PIXELS_BLOCK; - y2 = row * vf->vf_height + vw->vw_offset.tp_row; + y2 = row * vf->vf_height + vw->vw_draw_area.tr_begin.tp_row; - /* - * Clip the area to the screen size. - * - * FIXME: Take vw_offset into account. - */ - x2 = min(x2, vd->vd_width - 1); - y2 = min(y2, vd->vd_height - 1); + /* Clip the area to the screen size. */ + x2 = min(x2, vw->vw_draw_area.tr_end.tp_col); + y2 = min(y2, vw->vw_draw_area.tr_end.tp_row); /* * Now, we take care of N pixels line at a time (the first for diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h index 55c5b18..89d3de4 100644 --- a/sys/dev/vt/vt.h +++ b/sys/dev/vt/vt.h @@ -258,7 +258,7 @@ struct vt_window { struct terminal *vw_terminal; /* (c) Terminal. */ struct vt_buf vw_buf; /* (u) Screen buffer. */ struct vt_font *vw_font; /* (d) Graphical font. */ - term_pos_t vw_offset; /* (?) Pixel offset. */ + term_rect_t vw_draw_area; /* (?) Drawable area. */ unsigned int vw_number; /* (c) Window number. */ int vw_kbdmode; /* (?) Keyboard mode. */ char *vw_kbdsq; /* Escape sequence queue*/ diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 32887c8..ae1e97b 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -828,8 +828,8 @@ vt_is_cursor_in_area(const struct vt_device *vd, const term_rect_t *area) * We use the cursor position saved during the current refresh, * in case the cursor moved since. */ - mx = vd->vd_mx_drawn + vd->vd_curwindow->vw_offset.tp_col; - my = vd->vd_my_drawn + vd->vd_curwindow->vw_offset.tp_row; + mx = vd->vd_mx_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_col; + my = vd->vd_my_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_row; x1 = area->tr_begin.tp_col; y1 = area->tr_begin.tp_row; @@ -1202,8 +1202,8 @@ vt_set_border(struct vt_window *vw, struct vt_font *vf, term_color_t c) x = vd->vd_width - 1; y = vd->vd_height - 1; - off_x = vw->vw_offset.tp_col; - off_y = vw->vw_offset.tp_row; + off_x = vw->vw_draw_area.tr_begin.tp_col; + off_y = vw->vw_draw_area.tr_begin.tp_row; /* Top bar. */ if (off_y > 0) @@ -1257,9 +1257,17 @@ vt_change_font(struct vt_window *vw, struct vt_font *vf) vt_termsize(vd, vf, &size); vt_winsize(vd, vf, &wsz); - /* Save offset to font aligned area. */ - vw->vw_offset.tp_col = (vd->vd_width % vf->vf_width) / 2; - vw->vw_offset.tp_row = (vd->vd_height % vf->vf_height) / 2; + + /* + * Compute the drawable area, so that the text is centered on + * the screen. + */ + vw->vw_draw_area.tr_begin.tp_col = (vd->vd_width % vf->vf_width) / 2; + vw->vw_draw_area.tr_begin.tp_row = (vd->vd_height % vf->vf_height) / 2; + vw->vw_draw_area.tr_end.tp_col = vw->vw_draw_area.tr_begin.tp_col + + vd->vd_width / vf->vf_width * vf->vf_width; + vw->vw_draw_area.tr_end.tp_row = vw->vw_draw_area.tr_begin.tp_row + + vd->vd_height / vf->vf_height * vf->vf_height; /* Grow the screen buffer and terminal. */ terminal_mute(tm, 1); |