Mercurial > emacs
changeset 50098:0b192c622b66
The following changes consolidates the fringe handling from
xterm.c, w32term.c, and macterm.c into xdisp.c.
* xdisp.c: Consolidate fringe handling code here.
(left_bits, right_bits, continued_bits, continuation_bits)
(ov_bits, zv_bits): Define fringe bitmaps.
(fringe_bitmaps): New array holding fringe bitmaps.
(draw_fringe_bitmap): Draw a specific bitmap; call display
specific drawing routine via rif->draw_fringe_bitmap.
(draw_row_fringe_bitmaps): Generic replacement for
x_draw_row_fringe_bitmaps; all callers changed.
(compute_fringe_widths): Generic replacement for
x_compute_fringe_widths; all callers changed.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Wed, 12 Mar 2003 12:11:00 +0000 |
parents | ee703213acfa |
children | a62497b91c74 |
files | src/xdisp.c |
diffstat | 1 files changed, 275 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/xdisp.c Wed Mar 12 12:10:36 2003 +0000 +++ b/src/xdisp.c Wed Mar 12 12:11:00 2003 +0000 @@ -8136,6 +8136,281 @@ +/*********************************************************************** + Fringes + ***********************************************************************/ + +#ifdef HAVE_WINDOW_SYSTEM + +/* An arrow like this: `<-'. */ +static unsigned char left_bits[] = { + 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18}; + +/* Right truncation arrow bitmap `->'. */ +static unsigned char right_bits[] = { + 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18}; + +/* Marker for continued lines. */ +static unsigned char continued_bits[] = { + 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c}; + +/* Marker for continuation lines. */ +static unsigned char continuation_bits[] = { + 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e}; + +/* Overlay arrow bitmap. A triangular arrow. */ +static unsigned char ov_bits[] = { + 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03}; + +/* Bitmap drawn to indicate lines not displaying text if + `indicate-empty-lines' is non-nil. */ +static unsigned char zv_bits[] = { + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00}; + +struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] = +{ + { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ }, + { 8, sizeof (left_bits), 0, left_bits }, + { 8, sizeof (right_bits), 0, right_bits }, + { 8, sizeof (continued_bits), 0, continued_bits }, + { 8, sizeof (continuation_bits), 0, continuation_bits }, + { 8, sizeof (ov_bits), 0, ov_bits }, + { 8, sizeof (zv_bits), 3, zv_bits } +}; + + +/* Draw the bitmap WHICH in one of the left or right fringes of + window W. ROW is the glyph row for which to display the bitmap; it + determines the vertical position at which the bitmap has to be + drawn. */ + +static void +draw_fringe_bitmap (w, row, which, left_p) + struct window *w; + struct glyph_row *row; + enum fringe_bitmap_type which; + int left_p; +{ + struct frame *f = XFRAME (WINDOW_FRAME (w)); + struct draw_fringe_bitmap_params p; + + /* Convert row to frame coordinates. */ + p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); + + p.which = which; + p.wd = fringe_bitmaps[which].width; + + p.h = fringe_bitmaps[which].height; + p.dh = (fringe_bitmaps[which].period + ? (p.y % fringe_bitmaps[which].period) + : 0); + p.h -= p.dh; + /* Clip bitmap if too high. */ + if (p.h > row->height) + p.h = row->height; + + p.face = FACE_FROM_ID (f, FRINGE_FACE_ID); + PREPARE_FACE_FOR_DISPLAY (f, p.face); + + /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill + the fringe. */ + p.bx = -1; + if (left_p) + { + if (p.wd > FRAME_X_LEFT_FRINGE_WIDTH (f)) + p.wd = FRAME_X_LEFT_FRINGE_WIDTH (f); + p.x = (WINDOW_TO_FRAME_PIXEL_X (w, 0) + - p.wd + - (FRAME_X_LEFT_FRINGE_WIDTH (f) - p.wd) / 2); + if (p.wd < FRAME_X_LEFT_FRINGE_WIDTH (f) || row->height > p.h) + { + /* If W has a vertical border to its left, don't draw over it. */ + int border = ((XFASTINT (w->left) > 0 + && !FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + ? 1 : 0); + p.bx = (window_box_left (w, -1) + - FRAME_X_LEFT_FRINGE_WIDTH (f) + + border); + p.nx = (FRAME_X_LEFT_FRINGE_WIDTH (f) - border); + } + } + else + { + if (p.wd > FRAME_X_RIGHT_FRINGE_WIDTH (f)) + p.wd = FRAME_X_RIGHT_FRINGE_WIDTH (f); + p.x = (window_box_right (w, -1) + + (FRAME_X_RIGHT_FRINGE_WIDTH (f) - p.wd) / 2); + /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill + the fringe. */ + if (p.wd < FRAME_X_RIGHT_FRINGE_WIDTH (f) || row->height > p.h) + { + p.bx = window_box_right (w, -1); + p.nx = FRAME_X_RIGHT_FRINGE_WIDTH (f); + } + } + + if (p.bx >= 0) + { + int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); + + p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y)); + p.ny = row->visible_height; + } + + /* Adjust y to the offset in the row to start drawing the bitmap. */ + p.y += (row->height - p.h) / 2; + + rif->draw_fringe_bitmap (w, row, &p); +} + +/* Draw fringe bitmaps for glyph row ROW on window W. Call this + function with input blocked. */ + +void +draw_row_fringe_bitmaps (w, row) + struct window *w; + struct glyph_row *row; +{ + struct frame *f = XFRAME (w->frame); + enum fringe_bitmap_type bitmap; + + xassert (interrupt_input_blocked); + + /* If row is completely invisible, because of vscrolling, we + don't have to draw anything. */ + if (row->visible_height <= 0) + return; + + if (FRAME_X_LEFT_FRINGE_WIDTH (f) != 0) + { + /* Decide which bitmap to draw in the left fringe. */ + if (row->overlay_arrow_p) + bitmap = OVERLAY_ARROW_BITMAP; + else if (row->truncated_on_left_p) + bitmap = LEFT_TRUNCATION_BITMAP; + else if (MATRIX_ROW_CONTINUATION_LINE_P (row)) + bitmap = CONTINUATION_LINE_BITMAP; + else if (row->indicate_empty_line_p) + bitmap = ZV_LINE_BITMAP; + else + bitmap = NO_FRINGE_BITMAP; + + draw_fringe_bitmap (w, row, bitmap, 1); + } + + if (FRAME_X_RIGHT_FRINGE_WIDTH (f) != 0) + { + /* Decide which bitmap to draw in the right fringe. */ + if (row->truncated_on_right_p) + bitmap = RIGHT_TRUNCATION_BITMAP; + else if (row->continued_p) + bitmap = CONTINUED_LINE_BITMAP; + else if (row->indicate_empty_line_p && FRAME_X_LEFT_FRINGE_WIDTH (f) == 0) + bitmap = ZV_LINE_BITMAP; + else + bitmap = NO_FRINGE_BITMAP; + + draw_fringe_bitmap (w, row, bitmap, 0); + } +} + + +/* Compute actual fringe widths */ + +void +compute_fringe_widths (f, redraw) + struct frame *f; + int redraw; +{ + int o_left = FRAME_X_LEFT_FRINGE_WIDTH (f); + int o_right = FRAME_X_RIGHT_FRINGE_WIDTH (f); + int o_cols = FRAME_X_FRINGE_COLS (f); + + Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist); + Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist); + int left_fringe_width, right_fringe_width; + + if (!NILP (left_fringe)) + left_fringe = Fcdr (left_fringe); + if (!NILP (right_fringe)) + right_fringe = Fcdr (right_fringe); + + left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 : + XINT (left_fringe)); + right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 : + XINT (right_fringe)); + + if (left_fringe_width || right_fringe_width) + { + int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width; + int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width; + int conf_wid = left_wid + right_wid; + int font_wid = FONT_WIDTH (f->output_data.x->font); + int cols = (left_wid + right_wid + font_wid-1) / font_wid; + int real_wid = cols * font_wid; + if (left_wid && right_wid) + { + if (left_fringe_width < 0) + { + /* Left fringe width is fixed, adjust right fringe if necessary */ + FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid; + } + else if (right_fringe_width < 0) + { + /* Right fringe width is fixed, adjust left fringe if necessary */ + FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid; + } + else + { + /* Adjust both fringes with an equal amount. + Note that we are doing integer arithmetic here, so don't + lose a pixel if the total width is an odd number. */ + int fill = real_wid - conf_wid; + FRAME_X_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2; + } + } + else if (left_fringe_width) + { + FRAME_X_LEFT_FRINGE_WIDTH (f) = real_wid; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0; + } + else + { + FRAME_X_LEFT_FRINGE_WIDTH (f) = 0; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = real_wid; + } + FRAME_X_FRINGE_COLS (f) = cols; + FRAME_X_FRINGE_WIDTH (f) = real_wid; + } + else + { + FRAME_X_LEFT_FRINGE_WIDTH (f) = 0; + FRAME_X_RIGHT_FRINGE_WIDTH (f) = 0; + FRAME_X_FRINGE_COLS (f) = 0; + FRAME_X_FRINGE_WIDTH (f) = 0; + } + + if (redraw && FRAME_VISIBLE_P (f)) + if (o_left != FRAME_X_LEFT_FRINGE_WIDTH (f) || + o_right != FRAME_X_RIGHT_FRINGE_WIDTH (f) || + o_cols != FRAME_X_FRINGE_COLS (f)) + redraw_frame (f); +} + +#endif /* HAVE_WINDOW_SYSTEM */ + + + /************************************************************************ Horizontal scrolling ************************************************************************/