[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/xterm.c
From: |
Kim F. Storm |
Subject: |
[Emacs-diffs] Changes to emacs/src/xterm.c |
Date: |
Sun, 16 Mar 2003 15:46:44 -0500 |
Index: emacs/src/xterm.c
diff -c emacs/src/xterm.c:1.779 emacs/src/xterm.c:1.780
*** emacs/src/xterm.c:1.779 Fri Mar 14 14:13:16 2003
--- emacs/src/xterm.c Sun Mar 16 15:46:42 2003
***************
*** 333,351 ****
extern Lisp_Object x_icon_type P_ ((struct frame *));
- /* Enumeration for overriding/changing the face to use for drawing
- glyphs in x_draw_glyphs. */
-
- enum draw_glyphs_face
- {
- DRAW_NORMAL_TEXT,
- DRAW_INVERSE_VIDEO,
- DRAW_CURSOR,
- DRAW_MOUSE_FACE,
- DRAW_IMAGE_RAISED,
- DRAW_IMAGE_SUNKEN
- };
-
static int cursor_in_mouse_face_p P_ ((struct window *));
static int clear_mouse_face P_ ((struct x_display_info *));
static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
--- 333,338 ----
***************
*** 433,447 ****
static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
GC, int));
static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *));
- static void notice_overwritten_cursor P_ ((struct window *, enum
glyph_row_area,
- int, int, int, int));
static void x_flush P_ ((struct frame *f));
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
static void x_draw_vertical_border P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
static INLINE void take_vertical_position_into_account P_ ((struct it *));
- static void x_produce_stretch_glyph P_ ((struct it *));
static struct scroll_bar *x_window_to_scroll_bar P_ ((Window));
static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
enum scroll_bar_part *,
--- 420,431 ----
***************
*** 923,952 ****
/* Function prototypes of this page. */
! static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
! struct glyph *,
! XChar2b *,
! int *));
! static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
! int, XChar2b *, int,
! int));
! static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
! static void x_encode_char P_ ((int, XChar2b *, struct font_info *));
! static void x_append_glyph P_ ((struct it *));
! static void x_append_composite_glyph P_ ((struct it *));
! static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
! int, int, double));
! static void x_produce_glyphs P_ ((struct it *));
! static void x_produce_image_glyph P_ ((struct it *it));
/* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
is not contained in the font. */
! static INLINE XCharStruct *
! x_per_char_metric (font, char2b)
XFontStruct *font;
XChar2b *char2b;
{
/* The result metric information. */
XCharStruct *pcm = NULL;
--- 907,923 ----
/* Function prototypes of this page. */
! static int x_encode_char P_ ((int, XChar2b *, struct font_info *, int *));
/* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
is not contained in the font. */
! static XCharStruct *
! x_per_char_metric (font, char2b, font_type)
XFontStruct *font;
XChar2b *char2b;
+ int font_type; /* unused on X */
{
/* The result metric information. */
XCharStruct *pcm = NULL;
***************
*** 1014,1024 ****
/* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
the two-byte form of C. Encoding is returned in *CHAR2B. */
! static INLINE void
! x_encode_char (c, char2b, font_info)
int c;
XChar2b *char2b;
struct font_info *font_info;
{
int charset = CHAR_CHARSET (c);
XFontStruct *font = font_info->font;
--- 985,996 ----
/* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
the two-byte form of C. Encoding is returned in *CHAR2B. */
! static int
! x_encode_char (c, char2b, font_info, two_byte_p)
int c;
XChar2b *char2b;
struct font_info *font_info;
+ int *two_byte_p;
{
int charset = CHAR_CHARSET (c);
XFontStruct *font = font_info->font;
***************
*** 1066,2135 ****
if (enc == 1 || enc == 3)
char2b->byte2 |= 0x80;
}
- }
-
-
- /* Get face and two-byte form of character C in face FACE_ID on frame
- F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
- means we want to display multibyte text. DISPLAY_P non-zero means
- make sure that X resources for the face returned are allocated.
- Value is a pointer to a realized face that is ready for display if
- DISPLAY_P is non-zero. */
-
- static INLINE struct face *
- x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
- struct frame *f;
- int c, face_id;
- XChar2b *char2b;
- int multibyte_p, display_p;
- {
- struct face *face = FACE_FROM_ID (f, face_id);
-
- if (!multibyte_p)
- {
- /* Unibyte case. We don't have to encode, but we have to make
- sure to use a face suitable for unibyte. */
- char2b->byte1 = 0;
- char2b->byte2 = c;
- face_id = FACE_FOR_CHAR (f, face, c);
- face = FACE_FROM_ID (f, face_id);
- }
- else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
- {
- /* Case of ASCII in a face known to fit ASCII. */
- char2b->byte1 = 0;
- char2b->byte2 = c;
- }
- else
- {
- int c1, c2, charset;
-
- /* Split characters into bytes. If c2 is -1 afterwards, C is
- really a one-byte character so that byte1 is zero. */
- SPLIT_CHAR (c, charset, c1, c2);
- if (c2 > 0)
- char2b->byte1 = c1, char2b->byte2 = c2;
- else
- char2b->byte1 = 0, char2b->byte2 = c1;
-
- /* Maybe encode the character in *CHAR2B. */
- if (face->font != NULL)
- {
- struct font_info *font_info
- = FONT_INFO_FROM_ID (f, face->font_info_id);
- if (font_info)
- x_encode_char (c, char2b, font_info);
- }
- }
-
- /* Make sure X resources of the face are allocated. */
- if (display_p)
- {
- xassert (face != NULL);
- PREPARE_FACE_FOR_DISPLAY (f, face);
- }
-
- return face;
- }
-
-
- /* Get face and two-byte form of character glyph GLYPH on frame F.
- The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
- a pointer to a realized face that is ready for display. */
-
- static INLINE struct face *
- x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
- struct frame *f;
- struct glyph *glyph;
- XChar2b *char2b;
- int *two_byte_p;
- {
- struct face *face;
-
- xassert (glyph->type == CHAR_GLYPH);
- face = FACE_FROM_ID (f, glyph->face_id);
if (two_byte_p)
! *two_byte_p = 0;
! if (!glyph->multibyte_p)
! {
! /* Unibyte case. We don't have to encode, but we have to make
! sure to use a face suitable for unibyte. */
! char2b->byte1 = 0;
! char2b->byte2 = glyph->u.ch;
! }
! else if (glyph->u.ch < 128
! && glyph->face_id < BASIC_FACE_ID_SENTINEL)
! {
! /* Case of ASCII in a face known to fit ASCII. */
! char2b->byte1 = 0;
! char2b->byte2 = glyph->u.ch;
! }
! else
! {
! int c1, c2, charset;
!
! /* Split characters into bytes. If c2 is -1 afterwards, C is
! really a one-byte character so that byte1 is zero. */
! SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
! if (c2 > 0)
! char2b->byte1 = c1, char2b->byte2 = c2;
! else
! char2b->byte1 = 0, char2b->byte2 = c1;
!
! /* Maybe encode the character in *CHAR2B. */
! if (charset != CHARSET_ASCII)
! {
! struct font_info *font_info
! = FONT_INFO_FROM_ID (f, face->font_info_id);
! if (font_info)
! {
! x_encode_char (glyph->u.ch, char2b, font_info);
! if (two_byte_p)
! *two_byte_p
! = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
! }
! }
! }
!
! /* Make sure X resources of the face are allocated. */
! xassert (face != NULL);
! PREPARE_FACE_FOR_DISPLAY (f, face);
! return face;
! }
!
!
! /* Store one glyph for IT->char_to_display in IT->glyph_row.
! Called from x_produce_glyphs when IT->glyph_row is non-null. */
!
! static INLINE void
! x_append_glyph (it)
! struct it *it;
! {
! struct glyph *glyph;
! enum glyph_row_area area = it->area;
!
! xassert (it->glyph_row);
! xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
!
! glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
! if (glyph < it->glyph_row->glyphs[area + 1])
! {
! glyph->charpos = CHARPOS (it->position);
! glyph->object = it->object;
! glyph->pixel_width = it->pixel_width;
! glyph->voffset = it->voffset;
! glyph->type = CHAR_GLYPH;
! glyph->multibyte_p = it->multibyte_p;
! glyph->left_box_line_p = it->start_of_box_run_p;
! glyph->right_box_line_p = it->end_of_box_run_p;
! glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
! || it->phys_descent > it->descent);
! glyph->padding_p = 0;
! glyph->glyph_not_available_p = it->glyph_not_available_p;
! glyph->face_id = it->face_id;
! glyph->u.ch = it->char_to_display;
! ++it->glyph_row->used[area];
! }
! }
!
! /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
! Called from x_produce_glyphs when IT->glyph_row is non-null. */
!
! static INLINE void
! x_append_composite_glyph (it)
! struct it *it;
! {
! struct glyph *glyph;
! enum glyph_row_area area = it->area;
!
! xassert (it->glyph_row);
!
! glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
! if (glyph < it->glyph_row->glyphs[area + 1])
! {
! glyph->charpos = CHARPOS (it->position);
! glyph->object = it->object;
! glyph->pixel_width = it->pixel_width;
! glyph->voffset = it->voffset;
! glyph->type = COMPOSITE_GLYPH;
! glyph->multibyte_p = it->multibyte_p;
! glyph->left_box_line_p = it->start_of_box_run_p;
! glyph->right_box_line_p = it->end_of_box_run_p;
! glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
! || it->phys_descent > it->descent);
! glyph->padding_p = 0;
! glyph->glyph_not_available_p = 0;
! glyph->face_id = it->face_id;
! glyph->u.cmp_id = it->cmp_id;
! ++it->glyph_row->used[area];
! }
! }
!
!
! /* Change IT->ascent and IT->height according to the setting of
! IT->voffset. */
!
! static INLINE void
! take_vertical_position_into_account (it)
! struct it *it;
! {
! if (it->voffset)
! {
! if (it->voffset < 0)
! /* Increase the ascent so that we can display the text higher
! in the line. */
! it->ascent += abs (it->voffset);
! else
! /* Increase the descent so that we can display the text lower
! in the line. */
! it->descent += it->voffset;
! }
! }
!
!
! /* Produce glyphs/get display metrics for the image IT is loaded with.
! See the description of struct display_iterator in dispextern.h for
! an overview of struct display_iterator. */
!
! static void
! x_produce_image_glyph (it)
! struct it *it;
! {
! struct image *img;
! struct face *face;
!
! xassert (it->what == IT_IMAGE);
!
! face = FACE_FROM_ID (it->f, it->face_id);
! img = IMAGE_FROM_ID (it->f, it->image_id);
! xassert (img);
!
! /* Make sure X resources of the face and image are loaded. */
! PREPARE_FACE_FOR_DISPLAY (it->f, face);
! prepare_image_for_display (it->f, img);
!
! it->ascent = it->phys_ascent = image_ascent (img, face);
! it->descent = it->phys_descent = img->height + 2 * img->vmargin -
it->ascent;
! it->pixel_width = img->width + 2 * img->hmargin;
!
! it->nglyphs = 1;
!
! if (face->box != FACE_NO_BOX)
! {
! if (face->box_line_width > 0)
! {
! it->ascent += face->box_line_width;
! it->descent += face->box_line_width;
! }
!
! if (it->start_of_box_run_p)
! it->pixel_width += abs (face->box_line_width);
! if (it->end_of_box_run_p)
! it->pixel_width += abs (face->box_line_width);
! }
!
! take_vertical_position_into_account (it);
!
! if (it->glyph_row)
! {
! struct glyph *glyph;
! enum glyph_row_area area = it->area;
!
! glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
! if (glyph < it->glyph_row->glyphs[area + 1])
! {
! glyph->charpos = CHARPOS (it->position);
! glyph->object = it->object;
! glyph->pixel_width = it->pixel_width;
! glyph->voffset = it->voffset;
! glyph->type = IMAGE_GLYPH;
! glyph->multibyte_p = it->multibyte_p;
! glyph->left_box_line_p = it->start_of_box_run_p;
! glyph->right_box_line_p = it->end_of_box_run_p;
! glyph->overlaps_vertically_p = 0;
! glyph->padding_p = 0;
! glyph->glyph_not_available_p = 0;
! glyph->face_id = it->face_id;
! glyph->u.img_id = img->id;
! ++it->glyph_row->used[area];
! }
! }
! }
!
!
! /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
! of the glyph, WIDTH and HEIGHT are the width and height of the
! stretch. ASCENT is the percentage/100 of HEIGHT to use for the
! ascent of the glyph (0 <= ASCENT <= 1). */
!
! static void
! x_append_stretch_glyph (it, object, width, height, ascent)
! struct it *it;
! Lisp_Object object;
! int width, height;
! double ascent;
! {
! struct glyph *glyph;
! enum glyph_row_area area = it->area;
!
! xassert (ascent >= 0 && ascent <= 1);
!
! glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
! if (glyph < it->glyph_row->glyphs[area + 1])
! {
! glyph->charpos = CHARPOS (it->position);
! glyph->object = object;
! glyph->pixel_width = width;
! glyph->voffset = it->voffset;
! glyph->type = STRETCH_GLYPH;
! glyph->multibyte_p = it->multibyte_p;
! glyph->left_box_line_p = it->start_of_box_run_p;
! glyph->right_box_line_p = it->end_of_box_run_p;
! glyph->overlaps_vertically_p = 0;
! glyph->padding_p = 0;
! glyph->glyph_not_available_p = 0;
! glyph->face_id = it->face_id;
! glyph->u.stretch.ascent = height * ascent;
! glyph->u.stretch.height = height;
! ++it->glyph_row->used[area];
! }
! }
!
!
! /* Produce a stretch glyph for iterator IT. IT->object is the value
! of the glyph property displayed. The value must be a list
! `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
! being recognized:
!
! 1. `:width WIDTH' specifies that the space should be WIDTH *
! canonical char width wide. WIDTH may be an integer or floating
! point number.
!
! 2. `:relative-width FACTOR' specifies that the width of the stretch
! should be computed from the width of the first character having the
! `glyph' property, and should be FACTOR times that width.
!
! 3. `:align-to HPOS' specifies that the space should be wide enough
! to reach HPOS, a value in canonical character units.
!
! Exactly one of the above pairs must be present.
!
! 4. `:height HEIGHT' specifies that the height of the stretch produced
! should be HEIGHT, measured in canonical character units.
!
! 5. `:relative-height FACTOR' specifies that the height of the
! stretch should be FACTOR times the height of the characters having
! the glyph property.
!
! Either none or exactly one of 4 or 5 must be present.
!
! 6. `:ascent ASCENT' specifies that ASCENT percent of the height
! of the stretch should be used for the ascent of the stretch.
! ASCENT must be in the range 0 <= ASCENT <= 100. */
!
! #define NUMVAL(X) \
! ((INTEGERP (X) || FLOATP (X)) \
! ? XFLOATINT (X) \
! : - 1)
!
!
! static void
! x_produce_stretch_glyph (it)
! struct it *it;
! {
! /* (space :width WIDTH :height HEIGHT. */
! #if GLYPH_DEBUG
! extern Lisp_Object Qspace;
! #endif
! extern Lisp_Object QCwidth, QCheight, QCascent;
! extern Lisp_Object QCrelative_width, QCrelative_height;
! extern Lisp_Object QCalign_to;
! Lisp_Object prop, plist;
! double width = 0, height = 0, ascent = 0;
! struct face *face = FACE_FROM_ID (it->f, it->face_id);
! XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
!
! PREPARE_FACE_FOR_DISPLAY (it->f, face);
!
! /* List should start with `space'. */
! xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
! plist = XCDR (it->object);
!
! /* Compute the width of the stretch. */
! if (prop = Fplist_get (plist, QCwidth),
! NUMVAL (prop) > 0)
! /* Absolute width `:width WIDTH' specified and valid. */
! width = NUMVAL (prop) * CANON_X_UNIT (it->f);
! else if (prop = Fplist_get (plist, QCrelative_width),
! NUMVAL (prop) > 0)
! {
! /* Relative width `:relative-width FACTOR' specified and valid.
! Compute the width of the characters having the `glyph'
! property. */
! struct it it2;
! unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
!
! it2 = *it;
! if (it->multibyte_p)
! {
! int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
! - IT_BYTEPOS (*it));
! it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
! }
! else
! it2.c = *p, it2.len = 1;
!
! it2.glyph_row = NULL;
! it2.what = IT_CHARACTER;
! x_produce_glyphs (&it2);
! width = NUMVAL (prop) * it2.pixel_width;
! }
! else if (prop = Fplist_get (plist, QCalign_to),
! NUMVAL (prop) > 0)
! width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
! else
! /* Nothing specified -> width defaults to canonical char width. */
! width = CANON_X_UNIT (it->f);
!
! /* Compute height. */
! if (prop = Fplist_get (plist, QCheight),
! NUMVAL (prop) > 0)
! height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
! else if (prop = Fplist_get (plist, QCrelative_height),
! NUMVAL (prop) > 0)
! height = FONT_HEIGHT (font) * NUMVAL (prop);
! else
! height = FONT_HEIGHT (font);
!
! /* Compute percentage of height used for ascent. If
! `:ascent ASCENT' is present and valid, use that. Otherwise,
! derive the ascent from the font in use. */
! if (prop = Fplist_get (plist, QCascent),
! NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
! ascent = NUMVAL (prop) / 100.0;
! else
! ascent = (double) font->ascent / FONT_HEIGHT (font);
!
! if (width <= 0)
! width = 1;
! if (height <= 0)
! height = 1;
!
! if (it->glyph_row)
! {
! Lisp_Object object = it->stack[it->sp - 1].string;
! if (!STRINGP (object))
! object = it->w->buffer;
! x_append_stretch_glyph (it, object, width, height, ascent);
! }
!
! it->pixel_width = width;
! it->ascent = it->phys_ascent = height * ascent;
! it->descent = it->phys_descent = height - it->ascent;
! it->nglyphs = 1;
!
! if (face->box != FACE_NO_BOX)
! {
! if (face->box_line_width > 0)
! {
! it->ascent += face->box_line_width;
! it->descent += face->box_line_width;
! }
!
! if (it->start_of_box_run_p)
! it->pixel_width += abs (face->box_line_width);
! if (it->end_of_box_run_p)
! it->pixel_width += abs (face->box_line_width);
! }
!
! take_vertical_position_into_account (it);
! }
!
! /* Return proper value to be used as baseline offset of font that has
! ASCENT and DESCENT to draw characters by the font at the vertical
! center of the line of frame F.
!
! Here, out task is to find the value of BOFF in the following figure;
!
! -------------------------+-----------+-
! -+-+---------+-+ | |
! | | | | | |
! | | | | F_ASCENT F_HEIGHT
! | | | ASCENT | |
! HEIGHT | | | | |
! | | |-|-+------+-----------|------- baseline
! | | | | BOFF | |
! | |---------|-+-+ | |
! | | | DESCENT | |
! -+-+---------+-+ F_DESCENT |
! -------------------------+-----------+-
!
! -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
! BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
! DESCENT = FONT->descent
! HEIGHT = FONT_HEIGHT (FONT)
! F_DESCENT = (F->output_data.x->font->descent
! - F->output_data.x->baseline_offset)
! F_HEIGHT = FRAME_LINE_HEIGHT (F)
! */
!
! #define VCENTER_BASELINE_OFFSET(FONT, F) \
! ((FONT)->descent \
! + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
! + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
! - ((F)->output_data.x->font->descent -
(F)->output_data.x->baseline_offset))
!
! /* Produce glyphs/get display metrics for the display element IT is
! loaded with. See the description of struct display_iterator in
! dispextern.h for an overview of struct display_iterator. */
!
! static void
! x_produce_glyphs (it)
! struct it *it;
! {
! it->glyph_not_available_p = 0;
!
! if (it->what == IT_CHARACTER)
! {
! XChar2b char2b;
! XFontStruct *font;
! struct face *face = FACE_FROM_ID (it->f, it->face_id);
! XCharStruct *pcm;
! int font_not_found_p;
! struct font_info *font_info;
! int boff; /* baseline offset */
! /* We may change it->multibyte_p upon unibyte<->multibyte
! conversion. So, save the current value now and restore it
! later.
!
! Note: It seems that we don't have to record multibyte_p in
! struct glyph because the character code itself tells if or
! not the character is multibyte. Thus, in the future, we must
! consider eliminating the field `multibyte_p' in the struct
! glyph. */
! int saved_multibyte_p = it->multibyte_p;
!
! /* Maybe translate single-byte characters to multibyte, or the
! other way. */
! it->char_to_display = it->c;
! if (!ASCII_BYTE_P (it->c))
! {
! if (unibyte_display_via_language_environment
! && SINGLE_BYTE_CHAR_P (it->c)
! && (it->c >= 0240
! || !NILP (Vnonascii_translation_table)))
! {
! it->char_to_display = unibyte_char_to_multibyte (it->c);
! it->multibyte_p = 1;
! it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
! face = FACE_FROM_ID (it->f, it->face_id);
! }
! else if (!SINGLE_BYTE_CHAR_P (it->c)
! && !it->multibyte_p)
! {
! it->multibyte_p = 1;
! it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
! face = FACE_FROM_ID (it->f, it->face_id);
! }
! }
!
! /* Get font to use. Encode IT->char_to_display. */
! x_get_char_face_and_encoding (it->f, it->char_to_display,
! it->face_id, &char2b,
! it->multibyte_p, 0);
! font = face->font;
!
! /* When no suitable font found, use the default font. */
! font_not_found_p = font == NULL;
! if (font_not_found_p)
! {
! font = FRAME_FONT (it->f);
! boff = it->f->output_data.x->baseline_offset;
! font_info = NULL;
! }
! else
! {
! font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
! boff = font_info->baseline_offset;
! if (font_info->vertical_centering)
! boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
! }
!
! if (it->char_to_display >= ' '
! && (!it->multibyte_p || it->char_to_display < 128))
! {
! /* Either unibyte or ASCII. */
! int stretched_p;
!
! it->nglyphs = 1;
!
! pcm = x_per_char_metric (font, &char2b);
! it->ascent = font->ascent + boff;
! it->descent = font->descent - boff;
!
! if (pcm)
! {
! it->phys_ascent = pcm->ascent + boff;
! it->phys_descent = pcm->descent - boff;
! it->pixel_width = pcm->width;
! }
! else
! {
! it->glyph_not_available_p = 1;
! it->phys_ascent = font->ascent + boff;
! it->phys_descent = font->descent - boff;
! it->pixel_width = FONT_WIDTH (font);
! }
!
! /* If this is a space inside a region of text with
! `space-width' property, change its width. */
! stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
! if (stretched_p)
! it->pixel_width *= XFLOATINT (it->space_width);
!
! /* If face has a box, add the box thickness to the character
! height. If character has a box line to the left and/or
! right, add the box line width to the character's width. */
! if (face->box != FACE_NO_BOX)
! {
! int thick = face->box_line_width;
!
! if (thick > 0)
! {
! it->ascent += thick;
! it->descent += thick;
! }
! else
! thick = -thick;
!
! if (it->start_of_box_run_p)
! it->pixel_width += thick;
! if (it->end_of_box_run_p)
! it->pixel_width += thick;
! }
!
! /* If face has an overline, add the height of the overline
! (1 pixel) and a 1 pixel margin to the character height. */
! if (face->overline_p)
! it->ascent += 2;
!
! take_vertical_position_into_account (it);
!
! /* If we have to actually produce glyphs, do it. */
! if (it->glyph_row)
! {
! if (stretched_p)
! {
! /* Translate a space with a `space-width' property
! into a stretch glyph. */
! double ascent = (double) font->ascent / FONT_HEIGHT (font);
! x_append_stretch_glyph (it, it->object, it->pixel_width,
! it->ascent + it->descent, ascent);
! }
! else
! x_append_glyph (it);
!
! /* If characters with lbearing or rbearing are displayed
! in this line, record that fact in a flag of the
! glyph row. This is used to optimize X output code. */
! if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
! it->glyph_row->contains_overlapping_glyphs_p = 1;
! }
! }
! else if (it->char_to_display == '\n')
! {
! /* A newline has no width but we need the height of the line. */
! it->pixel_width = 0;
! it->nglyphs = 0;
! it->ascent = it->phys_ascent = font->ascent + boff;
! it->descent = it->phys_descent = font->descent - boff;
!
! if (face->box != FACE_NO_BOX
! && face->box_line_width > 0)
! {
! it->ascent += face->box_line_width;
! it->descent += face->box_line_width;
! }
! }
! else if (it->char_to_display == '\t')
! {
! int tab_width = it->tab_width * CANON_X_UNIT (it->f);
! int x = it->current_x + it->continuation_lines_width;
! int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
!
! /* If the distance from the current position to the next tab
! stop is less than a canonical character width, use the
! tab stop after that. */
! if (next_tab_x - x < CANON_X_UNIT (it->f))
! next_tab_x += tab_width;
!
! it->pixel_width = next_tab_x - x;
! it->nglyphs = 1;
! it->ascent = it->phys_ascent = font->ascent + boff;
! it->descent = it->phys_descent = font->descent - boff;
!
! if (it->glyph_row)
! {
! double ascent = (double) it->ascent / (it->ascent + it->descent);
! x_append_stretch_glyph (it, it->object, it->pixel_width,
! it->ascent + it->descent, ascent);
! }
! }
! else
! {
! /* A multi-byte character. Assume that the display width of the
! character is the width of the character multiplied by the
! width of the font. */
!
! /* If we found a font, this font should give us the right
! metrics. If we didn't find a font, use the frame's
! default font and calculate the width of the character
! from the charset width; this is what old redisplay code
! did. */
! pcm = x_per_char_metric (font, &char2b);
! if (font_not_found_p || !pcm)
! {
! int charset = CHAR_CHARSET (it->char_to_display);
!
! it->glyph_not_available_p = 1;
! it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
! * CHARSET_WIDTH (charset));
! it->phys_ascent = font->ascent + boff;
! it->phys_descent = font->descent - boff;
! }
! else
! {
! it->pixel_width = pcm->width;
! it->phys_ascent = pcm->ascent + boff;
! it->phys_descent = pcm->descent - boff;
! if (it->glyph_row
! && (pcm->lbearing < 0
! || pcm->rbearing > pcm->width))
! it->glyph_row->contains_overlapping_glyphs_p = 1;
! }
! it->nglyphs = 1;
! it->ascent = font->ascent + boff;
! it->descent = font->descent - boff;
! if (face->box != FACE_NO_BOX)
! {
! int thick = face->box_line_width;
!
! if (thick > 0)
! {
! it->ascent += thick;
! it->descent += thick;
! }
! else
! thick = - thick;
!
! if (it->start_of_box_run_p)
! it->pixel_width += thick;
! if (it->end_of_box_run_p)
! it->pixel_width += thick;
! }
!
! /* If face has an overline, add the height of the overline
! (1 pixel) and a 1 pixel margin to the character height. */
! if (face->overline_p)
! it->ascent += 2;
!
! take_vertical_position_into_account (it);
!
! if (it->glyph_row)
! x_append_glyph (it);
! }
! it->multibyte_p = saved_multibyte_p;
! }
! else if (it->what == IT_COMPOSITION)
! {
! /* Note: A composition is represented as one glyph in the
! glyph matrix. There are no padding glyphs. */
! XChar2b char2b;
! XFontStruct *font;
! struct face *face = FACE_FROM_ID (it->f, it->face_id);
! XCharStruct *pcm;
! int font_not_found_p;
! struct font_info *font_info;
! int boff; /* baseline offset */
! struct composition *cmp = composition_table[it->cmp_id];
!
! /* Maybe translate single-byte characters to multibyte. */
! it->char_to_display = it->c;
! if (unibyte_display_via_language_environment
! && SINGLE_BYTE_CHAR_P (it->c)
! && (it->c >= 0240
! || (it->c >= 0200
! && !NILP (Vnonascii_translation_table))))
! {
! it->char_to_display = unibyte_char_to_multibyte (it->c);
! }
!
! /* Get face and font to use. Encode IT->char_to_display. */
! it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
! face = FACE_FROM_ID (it->f, it->face_id);
! x_get_char_face_and_encoding (it->f, it->char_to_display,
! it->face_id, &char2b, it->multibyte_p, 0);
! font = face->font;
!
! /* When no suitable font found, use the default font. */
! font_not_found_p = font == NULL;
! if (font_not_found_p)
! {
! font = FRAME_FONT (it->f);
! boff = it->f->output_data.x->baseline_offset;
! font_info = NULL;
! }
! else
! {
! font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
! boff = font_info->baseline_offset;
! if (font_info->vertical_centering)
! boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
! }
!
! /* There are no padding glyphs, so there is only one glyph to
! produce for the composition. Important is that pixel_width,
! ascent and descent are the values of what is drawn by
! draw_glyphs (i.e. the values of the overall glyphs composed). */
! it->nglyphs = 1;
!
! /* If we have not yet calculated pixel size data of glyphs of
! the composition for the current face font, calculate them
! now. Theoretically, we have to check all fonts for the
! glyphs, but that requires much time and memory space. So,
! here we check only the font of the first glyph. This leads
! to incorrect display very rarely, and C-l (recenter) can
! correct the display anyway. */
! if (cmp->font != (void *) font)
! {
! /* Ascent and descent of the font of the first character of
! this composition (adjusted by baseline offset). Ascent
! and descent of overall glyphs should not be less than
! them respectively. */
! int font_ascent = font->ascent + boff;
! int font_descent = font->descent - boff;
! /* Bounding box of the overall glyphs. */
! int leftmost, rightmost, lowest, highest;
! int i, width, ascent, descent;
!
! cmp->font = (void *) font;
!
! /* Initialize the bounding box. */
! if (font_info
! && (pcm = x_per_char_metric (font, &char2b)))
! {
! width = pcm->width;
! ascent = pcm->ascent;
! descent = pcm->descent;
! }
! else
! {
! width = FONT_WIDTH (font);
! ascent = font->ascent;
! descent = font->descent;
! }
!
! rightmost = width;
! lowest = - descent + boff;
! highest = ascent + boff;
! leftmost = 0;
!
! if (font_info
! && font_info->default_ascent
! && CHAR_TABLE_P (Vuse_default_ascent)
! && !NILP (Faref (Vuse_default_ascent,
! make_number (it->char_to_display))))
! highest = font_info->default_ascent + boff;
!
! /* Draw the first glyph at the normal position. It may be
! shifted to right later if some other glyphs are drawn at
! the left. */
! cmp->offsets[0] = 0;
! cmp->offsets[1] = boff;
!
! /* Set cmp->offsets for the remaining glyphs. */
! for (i = 1; i < cmp->glyph_len; i++)
! {
! int left, right, btm, top;
! int ch = COMPOSITION_GLYPH (cmp, i);
! int face_id = FACE_FOR_CHAR (it->f, face, ch);
!
! face = FACE_FROM_ID (it->f, face_id);
! x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
! it->multibyte_p, 0);
! font = face->font;
! if (font == NULL)
! {
! font = FRAME_FONT (it->f);
! boff = it->f->output_data.x->baseline_offset;
! font_info = NULL;
! }
! else
! {
! font_info
! = FONT_INFO_FROM_ID (it->f, face->font_info_id);
! boff = font_info->baseline_offset;
! if (font_info->vertical_centering)
! boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
! }
!
! if (font_info
! && (pcm = x_per_char_metric (font, &char2b)))
! {
! width = pcm->width;
! ascent = pcm->ascent;
! descent = pcm->descent;
! }
! else
! {
! width = FONT_WIDTH (font);
! ascent = 1;
! descent = 0;
! }
!
! if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
! {
! /* Relative composition with or without
! alternate chars. */
! left = (leftmost + rightmost - width) / 2;
! btm = - descent + boff;
! if (font_info && font_info->relative_compose
! && (! CHAR_TABLE_P (Vignore_relative_composition)
! || NILP (Faref (Vignore_relative_composition,
! make_number (ch)))))
! {
!
! if (- descent >= font_info->relative_compose)
! /* One extra pixel between two glyphs. */
! btm = highest + 1;
! else if (ascent <= 0)
! /* One extra pixel between two glyphs. */
! btm = lowest - 1 - ascent - descent;
! }
! }
! else
! {
! /* A composition rule is specified by an integer
! value that encodes global and new reference
! points (GREF and NREF). GREF and NREF are
! specified by numbers as below:
!
! 0---1---2 -- ascent
! | |
! | |
! | |
! 9--10--11 -- center
! | |
! ---3---4---5--- baseline
! | |
! 6---7---8 -- descent
! */
! int rule = COMPOSITION_RULE (cmp, i);
! int gref, nref, grefx, grefy, nrefx, nrefy;
!
! COMPOSITION_DECODE_RULE (rule, gref, nref);
! grefx = gref % 3, nrefx = nref % 3;
! grefy = gref / 3, nrefy = nref / 3;
!
! left = (leftmost
! + grefx * (rightmost - leftmost) / 2
! - nrefx * width / 2);
! btm = ((grefy == 0 ? highest
! : grefy == 1 ? 0
! : grefy == 2 ? lowest
! : (highest + lowest) / 2)
! - (nrefy == 0 ? ascent + descent
! : nrefy == 1 ? descent - boff
! : nrefy == 2 ? 0
! : (ascent + descent) / 2));
! }
!
! cmp->offsets[i * 2] = left;
! cmp->offsets[i * 2 + 1] = btm + descent;
!
! /* Update the bounding box of the overall glyphs. */
! right = left + width;
! top = btm + descent + ascent;
! if (left < leftmost)
! leftmost = left;
! if (right > rightmost)
! rightmost = right;
! if (top > highest)
! highest = top;
! if (btm < lowest)
! lowest = btm;
! }
!
! /* If there are glyphs whose x-offsets are negative,
! shift all glyphs to the right and make all x-offsets
! non-negative. */
! if (leftmost < 0)
! {
! for (i = 0; i < cmp->glyph_len; i++)
! cmp->offsets[i * 2] -= leftmost;
! rightmost -= leftmost;
! }
!
! cmp->pixel_width = rightmost;
! cmp->ascent = highest;
! cmp->descent = - lowest;
! if (cmp->ascent < font_ascent)
! cmp->ascent = font_ascent;
! if (cmp->descent < font_descent)
! cmp->descent = font_descent;
! }
!
! it->pixel_width = cmp->pixel_width;
! it->ascent = it->phys_ascent = cmp->ascent;
! it->descent = it->phys_descent = cmp->descent;
!
! if (face->box != FACE_NO_BOX)
! {
! int thick = face->box_line_width;
!
! if (thick > 0)
! {
! it->ascent += thick;
! it->descent += thick;
! }
! else
! thick = - thick;
!
! if (it->start_of_box_run_p)
! it->pixel_width += thick;
! if (it->end_of_box_run_p)
! it->pixel_width += thick;
! }
!
! /* If face has an overline, add the height of the overline
! (1 pixel) and a 1 pixel margin to the character height. */
! if (face->overline_p)
! it->ascent += 2;
!
! take_vertical_position_into_account (it);
!
! if (it->glyph_row)
! x_append_composite_glyph (it);
! }
! else if (it->what == IT_IMAGE)
! x_produce_image_glyph (it);
! else if (it->what == IT_STRETCH)
! x_produce_stretch_glyph (it);
!
! /* Accumulate dimensions. Note: can't assume that it->descent > 0
! because this isn't true for images with `:ascent 100'. */
! xassert (it->ascent >= 0 && it->descent >= 0);
! if (it->area == TEXT_AREA)
! it->current_x += it->pixel_width;
!
! it->descent += it->extra_line_spacing;
!
! it->max_ascent = max (it->max_ascent, it->ascent);
! it->max_descent = max (it->max_descent, it->descent);
! it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
! it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
}
--- 1038,1048 ----
if (enc == 1 || enc == 3)
char2b->byte2 |= 0x80;
}
if (two_byte_p)
! *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
! return FONT_TYPE_UNKNOWN;
}
***************
*** 2165,2336 ****
Glyph display
***********************************************************************/
- /* A sequence of glyphs to be drawn in the same face.
-
- This data structure is not really completely X specific, so it
- could possibly, at least partially, be useful for other systems. It
- is currently not part of the external redisplay interface because
- it's not clear what other systems will need. */
-
- struct glyph_string
- {
- /* X-origin of the string. */
- int x;
-
- /* Y-origin and y-position of the base line of this string. */
- int y, ybase;
-
- /* The width of the string, not including a face extension. */
- int width;
-
- /* The width of the string, including a face extension. */
- int background_width;
-
- /* The height of this string. This is the height of the line this
- string is drawn in, and can be different from the height of the
- font the string is drawn in. */
- int height;
-
- /* Number of pixels this string overwrites in front of its x-origin.
- This number is zero if the string has an lbearing >= 0; it is
- -lbearing, if the string has an lbearing < 0. */
- int left_overhang;
-
- /* Number of pixels this string overwrites past its right-most
- nominal x-position, i.e. x + width. Zero if the string's
- rbearing is <= its nominal width, rbearing - width otherwise. */
- int right_overhang;
-
- /* The frame on which the glyph string is drawn. */
- struct frame *f;
-
- /* The window on which the glyph string is drawn. */
- struct window *w;
-
- /* X display and window for convenience. */
- Display *display;
- Window window;
-
- /* The glyph row for which this string was built. It determines the
- y-origin and height of the string. */
- struct glyph_row *row;
-
- /* The area within row. */
- enum glyph_row_area area;
-
- /* Characters to be drawn, and number of characters. */
- XChar2b *char2b;
- int nchars;
-
- /* A face-override for drawing cursors, mouse face and similar. */
- enum draw_glyphs_face hl;
-
- /* Face in which this string is to be drawn. */
- struct face *face;
-
- /* Font in which this string is to be drawn. */
- XFontStruct *font;
-
- /* Font info for this string. */
- struct font_info *font_info;
- /* Non-null means this string describes (part of) a composition.
- All characters from char2b are drawn composed. */
- struct composition *cmp;
-
- /* Index of this glyph string's first character in the glyph
- definition of CMP. If this is zero, this glyph string describes
- the first character of a composition. */
- int gidx;
-
- /* 1 means this glyph strings face has to be drawn to the right end
- of the window's drawing area. */
- unsigned extends_to_end_of_line_p : 1;
-
- /* 1 means the background of this string has been drawn. */
- unsigned background_filled_p : 1;
-
- /* 1 means glyph string must be drawn with 16-bit functions. */
- unsigned two_byte_p : 1;
-
- /* 1 means that the original font determined for drawing this glyph
- string could not be loaded. The member `font' has been set to
- the frame's default font in this case. */
- unsigned font_not_found_p : 1;
-
- /* 1 means that the face in which this glyph string is drawn has a
- stipple pattern. */
- unsigned stippled_p : 1;
-
- /* 1 means only the foreground of this glyph string must be drawn,
- and we should use the physical height of the line this glyph
- string appears in as clip rect. */
- unsigned for_overlaps_p : 1;
- /* The GC to use for drawing this glyph string. */
- GC gc;
-
- /* A pointer to the first glyph in the string. This glyph
- corresponds to char2b[0]. Needed to draw rectangles if
- font_not_found_p is 1. */
- struct glyph *first_glyph;
-
- /* Image, if any. */
- struct image *img;
-
- struct glyph_string *next, *prev;
- };
-
-
- #if GLYPH_DEBUG
-
- static void
- x_dump_glyph_string (s)
- struct glyph_string *s;
- {
- fprintf (stderr, "glyph string\n");
- fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
- s->x, s->y, s->width, s->height);
- fprintf (stderr, " ybase = %d\n", s->ybase);
- fprintf (stderr, " hl = %d\n", s->hl);
- fprintf (stderr, " left overhang = %d, right = %d\n",
- s->left_overhang, s->right_overhang);
- fprintf (stderr, " nchars = %d\n", s->nchars);
- fprintf (stderr, " extends to end of line = %d\n",
- s->extends_to_end_of_line_p);
- fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
- fprintf (stderr, " bg width = %d\n", s->background_width);
- }
-
- #endif /* GLYPH_DEBUG */
-
-
-
- static void x_append_glyph_string_lists P_ ((struct glyph_string **,
- struct glyph_string **,
- struct glyph_string *,
- struct glyph_string *));
- static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
- struct glyph_string **,
- struct glyph_string *,
- struct glyph_string *));
- static void x_append_glyph_string P_ ((struct glyph_string **,
- struct glyph_string **,
- struct glyph_string *));
- static int x_left_overwritten P_ ((struct glyph_string *));
- static int x_left_overwriting P_ ((struct glyph_string *));
- static int x_right_overwritten P_ ((struct glyph_string *));
- static int x_right_overwriting P_ ((struct glyph_string *));
- static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
- int));
- static void x_init_glyph_string P_ ((struct glyph_string *,
- XChar2b *, struct window *,
- struct glyph_row *,
- enum glyph_row_area, int,
- enum draw_glyphs_face));
- static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
- enum glyph_row_area, int, int,
- enum draw_glyphs_face, int));
static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
static void x_set_glyph_string_gc P_ ((struct glyph_string *));
static void x_draw_glyph_string_background P_ ((struct glyph_string *,
--- 1078,1085 ----
***************
*** 2343,2351 ****
static void x_set_cursor_gc P_ ((struct glyph_string *));
static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
static void x_set_mouse_face_gc P_ ((struct glyph_string *));
- static void x_get_glyph_overhangs P_ ((struct glyph *, struct frame *,
- int *, int *));
- static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
unsigned long *, double, int));
static void x_setup_relief_color P_ ((struct frame *, struct relief *,
--- 1092,1097 ----
***************
*** 2355,2430 ****
static void x_draw_image_relief P_ ((struct glyph_string *));
static void x_draw_image_foreground P_ ((struct glyph_string *));
static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
- static void x_fill_image_glyph_string P_ ((struct glyph_string *));
static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
int, int, int));
static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
int, int, int, int, XRectangle *));
static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
int, int, int, XRectangle *));
! static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
! enum glyph_row_area));
! static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
! struct glyph_row *,
! enum glyph_row_area, int, int));
!
! #if GLYPH_DEBUG
! static void x_check_font P_ ((struct frame *, XFontStruct *));
! #endif
!
!
! /* Append the list of glyph strings with head H and tail T to the list
! with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
!
! static INLINE void
! x_append_glyph_string_lists (head, tail, h, t)
! struct glyph_string **head, **tail;
! struct glyph_string *h, *t;
! {
! if (h)
! {
! if (*head)
! (*tail)->next = h;
! else
! *head = h;
! h->prev = *tail;
! *tail = t;
! }
! }
!
!
! /* Prepend the list of glyph strings with head H and tail T to the
! list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
! result. */
!
! static INLINE void
! x_prepend_glyph_string_lists (head, tail, h, t)
! struct glyph_string **head, **tail;
! struct glyph_string *h, *t;
! {
! if (h)
! {
! if (*head)
! (*head)->prev = t;
! else
! *tail = t;
! t->next = *head;
! *head = h;
! }
! }
!
!
! /* Append glyph string S to the list with head *HEAD and tail *TAIL.
! Set *HEAD and *TAIL to the resulting list. */
! static INLINE void
! x_append_glyph_string (head, tail, s)
! struct glyph_string **head, **tail;
! struct glyph_string *s;
! {
! s->next = s->prev = NULL;
! x_append_glyph_string_lists (head, tail, s, s);
! }
/* Set S->gc to a suitable GC for drawing glyph string S in cursor
--- 1101,1118 ----
static void x_draw_image_relief P_ ((struct glyph_string *));
static void x_draw_image_foreground P_ ((struct glyph_string *));
static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap));
static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
int, int, int));
static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
int, int, int, int, XRectangle *));
static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
int, int, int, XRectangle *));
! static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
! enum glyph_row_area));
! #if GLYPH_DEBUG
! static void x_check_font P_ ((struct frame *, XFontStruct *));
! #endif
/* Set S->gc to a suitable GC for drawing glyph string S in cursor
***************
*** 2674,2683 ****
}
! /* Compute left and right overhang of glyph string S. If S is a glyph
string for a composition, assume overhangs don't exist. */
! static INLINE void
x_compute_glyph_string_overhangs (s)
struct glyph_string *s;
{
--- 1362,1372 ----
}
! /* RIF:
! Compute left and right overhang of glyph string S. If S is a glyph
string for a composition, assume overhangs don't exist. */
! static void
x_compute_glyph_string_overhangs (s)
struct glyph_string *s;
{
***************
*** 2694,2877 ****
}
- /* Compute overhangs and x-positions for glyph string S and its
- predecessors, or successors. X is the starting x-position for S.
- BACKWARD_P non-zero means process predecessors. */
-
- static void
- x_compute_overhangs_and_x (s, x, backward_p)
- struct glyph_string *s;
- int x;
- int backward_p;
- {
- if (backward_p)
- {
- while (s)
- {
- x_compute_glyph_string_overhangs (s);
- x -= s->width;
- s->x = x;
- s = s->prev;
- }
- }
- else
- {
- while (s)
- {
- x_compute_glyph_string_overhangs (s);
- s->x = x;
- x += s->width;
- s = s->next;
- }
- }
- }
-
-
- /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
- frame F. Overhangs of glyphs other than type CHAR_GLYPH are
- assumed to be zero. */
-
- static void
- x_get_glyph_overhangs (glyph, f, left, right)
- struct glyph *glyph;
- struct frame *f;
- int *left, *right;
- {
- *left = *right = 0;
-
- if (glyph->type == CHAR_GLYPH)
- {
- XFontStruct *font;
- struct face *face;
- struct font_info *font_info;
- XChar2b char2b;
- XCharStruct *pcm;
-
- face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
- font = face->font;
- font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
- if (font
- && (pcm = x_per_char_metric (font, &char2b)))
- {
- if (pcm->rbearing > pcm->width)
- *right = pcm->rbearing - pcm->width;
- if (pcm->lbearing < 0)
- *left = -pcm->lbearing;
- }
- }
- }
-
-
- /* Return the index of the first glyph preceding glyph string S that
- is overwritten by S because of S's left overhang. Value is -1
- if no glyphs are overwritten. */
-
- static int
- x_left_overwritten (s)
- struct glyph_string *s;
- {
- int k;
-
- if (s->left_overhang)
- {
- int x = 0, i;
- struct glyph *glyphs = s->row->glyphs[s->area];
- int first = s->first_glyph - glyphs;
-
- for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
- x -= glyphs[i].pixel_width;
-
- k = i + 1;
- }
- else
- k = -1;
-
- return k;
- }
-
-
- /* Return the index of the first glyph preceding glyph string S that
- is overwriting S because of its right overhang. Value is -1 if no
- glyph in front of S overwrites S. */
-
- static int
- x_left_overwriting (s)
- struct glyph_string *s;
- {
- int i, k, x;
- struct glyph *glyphs = s->row->glyphs[s->area];
- int first = s->first_glyph - glyphs;
-
- k = -1;
- x = 0;
- for (i = first - 1; i >= 0; --i)
- {
- int left, right;
- x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
- if (x + right > 0)
- k = i;
- x -= glyphs[i].pixel_width;
- }
-
- return k;
- }
-
-
- /* Return the index of the last glyph following glyph string S that is
- not overwritten by S because of S's right overhang. Value is -1 if
- no such glyph is found. */
-
- static int
- x_right_overwritten (s)
- struct glyph_string *s;
- {
- int k = -1;
-
- if (s->right_overhang)
- {
- int x = 0, i;
- struct glyph *glyphs = s->row->glyphs[s->area];
- int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
- int end = s->row->used[s->area];
-
- for (i = first; i < end && s->right_overhang > x; ++i)
- x += glyphs[i].pixel_width;
-
- k = i;
- }
-
- return k;
- }
-
-
- /* Return the index of the last glyph following glyph string S that
- overwrites S because of its left overhang. Value is negative
- if no such glyph is found. */
-
- static int
- x_right_overwriting (s)
- struct glyph_string *s;
- {
- int i, k, x;
- int end = s->row->used[s->area];
- struct glyph *glyphs = s->row->glyphs[s->area];
- int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
-
- k = -1;
- x = 0;
- for (i = first; i < end; ++i)
- {
- int left, right;
- x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
- if (x - left < 0)
- k = i;
- x += glyphs[i].pixel_width;
- }
-
- return k;
- }
-
-
/* Fill rectangle X, Y, W, H with background color of glyph string S. */
static INLINE void
--- 1383,1388 ----
***************
*** 4410,5072 ****
}
- static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
- struct face **, int));
-
-
- /* Fill glyph string S with composition components specified by S->cmp.
-
- FACES is an array of faces for all components of this composition.
- S->gidx is the index of the first component for S.
- OVERLAPS_P non-zero means S should draw the foreground only, and
- use its physical height for clipping.
-
- Value is the index of a component not in S. */
-
- static int
- x_fill_composite_glyph_string (s, faces, overlaps_p)
- struct glyph_string *s;
- struct face **faces;
- int overlaps_p;
- {
- int i;
-
- xassert (s);
-
- s->for_overlaps_p = overlaps_p;
-
- s->face = faces[s->gidx];
- s->font = s->face->font;
- s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
-
- /* For all glyphs of this composition, starting at the offset
- S->gidx, until we reach the end of the definition or encounter a
- glyph that requires the different face, add it to S. */
- ++s->nchars;
- for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
- ++s->nchars;
-
- /* All glyph strings for the same composition has the same width,
- i.e. the width set for the first component of the composition. */
-
- s->width = s->first_glyph->pixel_width;
-
- /* If the specified font could not be loaded, use the frame's
- default font, but record the fact that we couldn't load it in
- the glyph string so that we can draw rectangles for the
- characters of the glyph string. */
- if (s->font == NULL)
- {
- s->font_not_found_p = 1;
- s->font = FRAME_FONT (s->f);
- }
-
- /* Adjust base line for subscript/superscript text. */
- s->ybase += s->first_glyph->voffset;
-
- xassert (s->face && s->face->gc);
-
- /* This glyph string must always be drawn with 16-bit functions. */
- s->two_byte_p = 1;
-
- return s->gidx + s->nchars;
- }
-
-
- /* Fill glyph string S from a sequence of character glyphs.
-
- FACE_ID is the face id of the string. START is the index of the
- first glyph to consider, END is the index of the last + 1.
- OVERLAPS_P non-zero means S should draw the foreground only, and
- use its physical height for clipping.
-
- Value is the index of the first glyph not in S. */
-
- static int
- x_fill_glyph_string (s, face_id, start, end, overlaps_p)
- struct glyph_string *s;
- int face_id;
- int start, end, overlaps_p;
- {
- struct glyph *glyph, *last;
- int voffset;
- int glyph_not_available_p;
-
- xassert (s->f == XFRAME (s->w->frame));
- xassert (s->nchars == 0);
- xassert (start >= 0 && end > start);
-
- s->for_overlaps_p = overlaps_p,
- glyph = s->row->glyphs[s->area] + start;
- last = s->row->glyphs[s->area] + end;
- voffset = glyph->voffset;
-
- glyph_not_available_p = glyph->glyph_not_available_p;
-
- while (glyph < last
- && glyph->type == CHAR_GLYPH
- && glyph->voffset == voffset
- /* Same face id implies same font, nowadays. */
- && glyph->face_id == face_id
- && glyph->glyph_not_available_p == glyph_not_available_p)
- {
- int two_byte_p;
-
- s->face = x_get_glyph_face_and_encoding (s->f, glyph,
- s->char2b + s->nchars,
- &two_byte_p);
- s->two_byte_p = two_byte_p;
- ++s->nchars;
- xassert (s->nchars <= end - start);
- s->width += glyph->pixel_width;
- ++glyph;
- }
-
- s->font = s->face->font;
- s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
-
- /* If the specified font could not be loaded, use the frame's font,
- but record the fact that we couldn't load it in
- S->font_not_found_p so that we can draw rectangles for the
- characters of the glyph string. */
- if (s->font == NULL || glyph_not_available_p)
- {
- s->font_not_found_p = 1;
- s->font = FRAME_FONT (s->f);
- }
-
- /* Adjust base line for subscript/superscript text. */
- s->ybase += voffset;
-
- xassert (s->face && s->face->gc);
- return glyph - s->row->glyphs[s->area];
- }
-
-
- /* Fill glyph string S from image glyph S->first_glyph. */
-
- static void
- x_fill_image_glyph_string (s)
- struct glyph_string *s;
- {
- xassert (s->first_glyph->type == IMAGE_GLYPH);
- s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
- xassert (s->img);
- s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
- s->font = s->face->font;
- s->width = s->first_glyph->pixel_width;
-
- /* Adjust base line for subscript/superscript text. */
- s->ybase += s->first_glyph->voffset;
- }
-
-
- /* Fill glyph string S from a sequence of stretch glyphs.
-
- ROW is the glyph row in which the glyphs are found, AREA is the
- area within the row. START is the index of the first glyph to
- consider, END is the index of the last + 1.
-
- Value is the index of the first glyph not in S. */
-
- static int
- x_fill_stretch_glyph_string (s, row, area, start, end)
- struct glyph_string *s;
- struct glyph_row *row;
- enum glyph_row_area area;
- int start, end;
- {
- struct glyph *glyph, *last;
- int voffset, face_id;
-
- xassert (s->first_glyph->type == STRETCH_GLYPH);
-
- glyph = s->row->glyphs[s->area] + start;
- last = s->row->glyphs[s->area] + end;
- face_id = glyph->face_id;
- s->face = FACE_FROM_ID (s->f, face_id);
- s->font = s->face->font;
- s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
- s->width = glyph->pixel_width;
- voffset = glyph->voffset;
-
- for (++glyph;
- (glyph < last
- && glyph->type == STRETCH_GLYPH
- && glyph->voffset == voffset
- && glyph->face_id == face_id);
- ++glyph)
- s->width += glyph->pixel_width;
-
- /* Adjust base line for subscript/superscript text. */
- s->ybase += voffset;
-
- /* The case that face->gc == 0 is handled when drawing the glyph
- string by calling PREPARE_FACE_FOR_DISPLAY. */
- xassert (s->face);
- return glyph - s->row->glyphs[s->area];
- }
-
-
- /* Initialize glyph string S. CHAR2B is a suitably allocated vector
- of XChar2b structures for S; it can't be allocated in
- x_init_glyph_string because it must be allocated via `alloca'. W
- is the window on which S is drawn. ROW and AREA are the glyph row
- and area within the row from which S is constructed. START is the
- index of the first glyph structure covered by S. HL is a
- face-override for drawing S. */
-
- static void
- x_init_glyph_string (s, char2b, w, row, area, start, hl)
- struct glyph_string *s;
- XChar2b *char2b;
- struct window *w;
- struct glyph_row *row;
- enum glyph_row_area area;
- int start;
- enum draw_glyphs_face hl;
- {
- bzero (s, sizeof *s);
- s->w = w;
- s->f = XFRAME (w->frame);
- s->display = FRAME_X_DISPLAY (s->f);
- s->window = FRAME_X_WINDOW (s->f);
- s->char2b = char2b;
- s->hl = hl;
- s->row = row;
- s->area = area;
- s->first_glyph = row->glyphs[area] + start;
- s->height = row->height;
- s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
-
- /* Display the internal border below the tool-bar window. */
- if (s->w == XWINDOW (s->f->tool_bar_window))
- s->y -= s->f->output_data.x->internal_border_width;
-
- s->ybase = s->y + row->ascent;
- }
-
-
- /* Set background width of glyph string S. START is the index of the
- first glyph following S. LAST_X is the right-most x-position + 1
- in the drawing area. */
-
- static INLINE void
- x_set_glyph_string_background_width (s, start, last_x)
- struct glyph_string *s;
- int start;
- int last_x;
- {
- /* If the face of this glyph string has to be drawn to the end of
- the drawing area, set S->extends_to_end_of_line_p. */
- struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
-
- if (start == s->row->used[s->area]
- && s->area == TEXT_AREA
- && ((s->hl == DRAW_NORMAL_TEXT
- && (s->row->fill_line_p
- || s->face->background != default_face->background
- || s->face->stipple != default_face->stipple
- || s->row->mouse_face_p))
- || s->hl == DRAW_MOUSE_FACE
- || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
- && s->row->fill_line_p)))
- s->extends_to_end_of_line_p = 1;
-
- /* If S extends its face to the end of the line, set its
- background_width to the distance to the right edge of the drawing
- area. */
- if (s->extends_to_end_of_line_p)
- s->background_width = last_x - s->x + 1;
- else
- s->background_width = s->width;
- }
-
-
- /* Add a glyph string for a stretch glyph to the list of strings
- between HEAD and TAIL. START is the index of the stretch glyph in
- row area AREA of glyph row ROW. END is the index of the last glyph
- in that glyph row area. X is the current output position assigned
- to the new glyph string constructed. HL overrides that face of the
- glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
- is the right-most x-position of the drawing area. */
-
- /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
- and below -- keep them on one line. */
- #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL,
X, LAST_X) \
- do
\
- { \
- s = (struct glyph_string *) alloca (sizeof *s); \
- x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
- START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
- x_append_glyph_string (&HEAD, &TAIL, s); \
- s->x = (X); \
- } \
- while (0)
-
-
- /* Add a glyph string for an image glyph to the list of strings
- between HEAD and TAIL. START is the index of the image glyph in
- row area AREA of glyph row ROW. END is the index of the last glyph
- in that glyph row area. X is the current output position assigned
- to the new glyph string constructed. HL overrides that face of the
- glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
- is the right-most x-position of the drawing area. */
-
- #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X,
LAST_X) \
- do
\
- { \
- s = (struct glyph_string *) alloca (sizeof *s); \
- x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
- x_fill_image_glyph_string (s); \
- x_append_glyph_string (&HEAD, &TAIL, s); \
- ++START; \
- s->x = (X); \
- } \
- while (0)
-
-
- /* Add a glyph string for a sequence of character glyphs to the list
- of strings between HEAD and TAIL. START is the index of the first
- glyph in row area AREA of glyph row ROW that is part of the new
- glyph string. END is the index of the last glyph in that glyph row
- area. X is the current output position assigned to the new glyph
- string constructed. HL overrides that face of the glyph; e.g. it
- is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
- right-most x-position of the drawing area. */
-
- #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X,
LAST_X, OVERLAPS_P) \
- do
\
- { \
- int c, face_id; \
- XChar2b *char2b; \
- \
- c = (ROW)->glyphs[AREA][START].u.ch; \
- face_id = (ROW)->glyphs[AREA][START].face_id; \
- \
- s = (struct glyph_string *) alloca (sizeof *s); \
- char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
- x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
- x_append_glyph_string (&HEAD, &TAIL, s); \
- s->x = (X); \
- START = x_fill_glyph_string (s, face_id, START, END, \
- OVERLAPS_P);
\
- } \
- while (0)
-
-
- /* Add a glyph string for a composite sequence to the list of strings
- between HEAD and TAIL. START is the index of the first glyph in
- row area AREA of glyph row ROW that is part of the new glyph
- string. END is the index of the last glyph in that glyph row area.
- X is the current output position assigned to the new glyph string
- constructed. HL overrides that face of the glyph; e.g. it is
- DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
- x-position of the drawing area. */
-
- #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL,
HL, X, LAST_X, OVERLAPS_P) \
- do {
\
- int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
- int face_id = (ROW)->glyphs[AREA][START].face_id; \
- struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id);
\
- struct composition *cmp = composition_table[cmp_id]; \
- int glyph_len = cmp->glyph_len; \
- XChar2b *char2b; \
- struct face **faces; \
- struct glyph_string *first_s = NULL; \
- int n; \
- \
- base_face = base_face->ascii_face;
\
- char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);
\
- faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
- /* At first, fill in `char2b' and `faces'. */ \
- for (n = 0; n < glyph_len; n++) \
- {
\
- int c = COMPOSITION_GLYPH (cmp, n); \
- int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
- faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
- x_get_char_face_and_encoding (XFRAME (w->frame), c, \
- this_face_id, char2b + n, 1, 1); \
- }
\
- \
- /* Make glyph_strings for each glyph sequence that is drawable by \
- the same face, and append them to HEAD/TAIL. */
\
- for (n = 0; n < cmp->glyph_len;) \
- {
\
- s = (struct glyph_string *) alloca (sizeof *s); \
- x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
- x_append_glyph_string (&(HEAD), &(TAIL), s); \
- s->cmp = cmp; \
- s->gidx = n; \
- s->x = (X); \
- \
- if (n == 0) \
- first_s = s; \
- \
- n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
- }
\
- \
- ++START; \
- s = first_s; \
- } while (0)
-
-
- /* Build a list of glyph strings between HEAD and TAIL for the glyphs
- of AREA of glyph row ROW on window W between indices START and END.
- HL overrides the face for drawing glyph strings, e.g. it is
- DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
- x-positions of the drawing area.
-
- This is an ugly monster macro construct because we must use alloca
- to allocate glyph strings (because x_draw_glyphs can be called
- asynchronously). */
-
- #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X,
LAST_X, OVERLAPS_P) \
- do
\
- { \
- HEAD = TAIL = NULL; \
- while (START < END) \
- { \
- struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
- switch (first_glyph->type)
\
- { \
- case CHAR_GLYPH: \
- BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
- TAIL, HL, X, LAST_X, \
- OVERLAPS_P);
\
- break; \
- \
- case COMPOSITE_GLYPH: \
- BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
- HEAD, TAIL, HL, X, LAST_X,\
- OVERLAPS_P); \
- break; \
- \
- case STRETCH_GLYPH: \
- BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
- HEAD, TAIL, HL, X, LAST_X); \
- break; \
- \
- case IMAGE_GLYPH: \
- BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
- TAIL, HL, X, LAST_X); \
- break; \
- \
- default: \
- abort (); \
- } \
- \
- x_set_glyph_string_background_width (s, START, LAST_X); \
- (X) += s->width; \
- } \
- } \
- while (0)
-
-
- /* Draw glyphs between START and END in AREA of ROW on window W,
- starting at x-position X. X is relative to AREA in W. HL is a
- face-override with the following meaning:
-
- DRAW_NORMAL_TEXT draw normally
- DRAW_CURSOR draw in cursor face
- DRAW_MOUSE_FACE draw in mouse face.
- DRAW_INVERSE_VIDEO draw in mode line face
- DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
- DRAW_IMAGE_RAISED draw an image with a raised relief around it
-
- If OVERLAPS_P is non-zero, draw only the foreground of characters
- and clip to the physical height of ROW.
-
- Value is the x-position reached, relative to AREA of W. */
-
- static int
- x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
- struct window *w;
- int x;
- struct glyph_row *row;
- enum glyph_row_area area;
- int start, end;
- enum draw_glyphs_face hl;
- int overlaps_p;
- {
- struct glyph_string *head, *tail;
- struct glyph_string *s;
- int last_x, area_width;
- int x_reached;
- int i, j;
-
- /* Let's rather be paranoid than getting a SEGV. */
- end = min (end, row->used[area]);
- start = max (0, start);
- start = min (end, start);
-
- /* Translate X to frame coordinates. Set last_x to the right
- end of the drawing area. */
- if (row->full_width_p)
- {
- /* X is relative to the left edge of W, without scroll bars
- or fringes. */
- struct frame *f = XFRAME (w->frame);
- int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
-
- x += window_left_x;
- area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
- last_x = window_left_x + area_width;
-
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
- {
- int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
- if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
- last_x += width;
- else
- x -= width;
- }
-
- x += FRAME_INTERNAL_BORDER_WIDTH (f);
- last_x += FRAME_INTERNAL_BORDER_WIDTH (f);
- }
- else
- {
- x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
- area_width = window_box_width (w, area);
- last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
- }
-
- /* Build a doubly-linked list of glyph_string structures between
- head and tail from what we have to draw. Note that the macro
- BUILD_GLYPH_STRINGS will modify its start parameter. That's
- the reason we use a separate variable `i'. */
- i = start;
- BUILD_GLYPH_STRINGS (w, row, area, i, end, head, tail, hl, x, last_x,
- overlaps_p);
- if (tail)
- x_reached = tail->x + tail->background_width;
- else
- x_reached = x;
-
- /* If there are any glyphs with lbearing < 0 or rbearing > width in
- the row, redraw some glyphs in front or following the glyph
- strings built above. */
- if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
- {
- int dummy_x = 0;
- struct glyph_string *h, *t;
-
- /* Compute overhangs for all glyph strings. */
- for (s = head; s; s = s->next)
- x_compute_glyph_string_overhangs (s);
-
- /* Prepend glyph strings for glyphs in front of the first glyph
- string that are overwritten because of the first glyph
- string's left overhang. The background of all strings
- prepended must be drawn because the first glyph string
- draws over it. */
- i = x_left_overwritten (head);
- if (i >= 0)
- {
- j = i;
- BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t,
- DRAW_NORMAL_TEXT, dummy_x, last_x,
- overlaps_p);
- start = i;
- x_compute_overhangs_and_x (t, head->x, 1);
- x_prepend_glyph_string_lists (&head, &tail, h, t);
- }
-
- /* Prepend glyph strings for glyphs in front of the first glyph
- string that overwrite that glyph string because of their
- right overhang. For these strings, only the foreground must
- be drawn, because it draws over the glyph string at `head'.
- The background must not be drawn because this would overwrite
- right overhangs of preceding glyphs for which no glyph
- strings exist. */
- i = x_left_overwriting (head);
- if (i >= 0)
- {
- BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t,
- DRAW_NORMAL_TEXT, dummy_x, last_x,
- overlaps_p);
- for (s = h; s; s = s->next)
- s->background_filled_p = 1;
- x_compute_overhangs_and_x (t, head->x, 1);
- x_prepend_glyph_string_lists (&head, &tail, h, t);
- }
-
- /* Append glyphs strings for glyphs following the last glyph
- string tail that are overwritten by tail. The background of
- these strings has to be drawn because tail's foreground draws
- over it. */
- i = x_right_overwritten (tail);
- if (i >= 0)
- {
- BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t,
- DRAW_NORMAL_TEXT, x, last_x,
- overlaps_p);
- x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
- x_append_glyph_string_lists (&head, &tail, h, t);
- }
-
- /* Append glyph strings for glyphs following the last glyph
- string tail that overwrite tail. The foreground of such
- glyphs has to be drawn because it writes into the background
- of tail. The background must not be drawn because it could
- paint over the foreground of following glyphs. */
- i = x_right_overwriting (tail);
- if (i >= 0)
- {
- BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t,
- DRAW_NORMAL_TEXT, x, last_x,
- overlaps_p);
- for (s = h; s; s = s->next)
- s->background_filled_p = 1;
- x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
- x_append_glyph_string_lists (&head, &tail, h, t);
- }
- }
-
- /* Draw all strings. */
- for (s = head; s; s = s->next)
- x_draw_glyph_string (s);
-
- if (area == TEXT_AREA
- && !row->full_width_p
- /* When drawing overlapping rows, only the glyph strings'
- foreground is drawn, which doesn't erase a cursor
- completely. */
- && !overlaps_p)
- {
- int x0 = head ? head->x : x;
- int x1 = tail ? tail->x + tail->background_width : x;
-
- x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
- x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
-
- if (XFASTINT (w->left_margin_width) != 0)
- {
- int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
- x0 -= left_area_width;
- x1 -= left_area_width;
- }
-
- notice_overwritten_cursor (w, area, x0, x1,
- row->y, MATRIX_ROW_BOTTOM_Y (row));
- }
-
- /* Value is the x-position up to which drawn, relative to AREA of W.
- This doesn't include parts drawn because of overhangs. */
- x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
- if (!row->full_width_p)
- {
- if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
- x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
- if (area > TEXT_AREA)
- x_reached -= window_box_width (w, TEXT_AREA);
- }
-
- return x_reached;
- }
-
-
/* Fix the display of area AREA of overlapping row ROW in window W. */
static void
--- 2921,2926 ----
***************
*** 11553,11604 ****
Text Cursor
***********************************************************************/
- /* Notice when the text cursor of window W has been completely
- overwritten by a drawing operation that outputs glyphs in AREA
- starting at X0 and ending at X1 in the line starting at Y0 and
- ending at Y1. X coordinates are area-relative. X1 < 0 means all
- the rest of the line after X0 has been written. Y coordinates
- are window-relative. */
-
- static void
- notice_overwritten_cursor (w, area, x0, x1, y0, y1)
- struct window *w;
- enum glyph_row_area area;
- int x0, y0, x1, y1;
- {
- if (area == TEXT_AREA && w->phys_cursor_on_p)
- {
- int cx0 = w->phys_cursor.x;
- int cx1 = cx0 + w->phys_cursor_width;
- int cy0 = w->phys_cursor.y;
- int cy1 = cy0 + w->phys_cursor_height;
-
- if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
- {
- /* The cursor image will be completely removed from the
- screen if the output area intersects the cursor area in
- y-direction. When we draw in [y0 y1[, and some part of
- the cursor is at y < y0, that part must have been drawn
- before. When scrolling, the cursor is erased before
- actually scrolling, so we don't come here. When not
- scrolling, the rows above the old cursor row must have
- changed, and in this case these rows must have written
- over the cursor image.
-
- Likewise if part of the cursor is below y1, with the
- exception of the cursor being in the first blank row at
- the buffer and window end because update_text_area
- doesn't draw that row. (Except when it does, but
- that's handled in update_text_area.) */
-
- if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
- && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
- w->phys_cursor_on_p = 0;
- }
- }
- }
-
-
/* Set clipping for output in glyph row ROW. W is the window in which
we operate. GC is the graphics context to set clipping in.
WHOLE_LINE_P non-zero means include the areas used for truncation
--- 9407,9412 ----
***************
*** 15363,15369 ****
x_clear_mouse_face,
x_get_glyph_overhangs,
x_fix_overlapping_area,
! x_draw_fringe_bitmap
};
void
--- 13171,13181 ----
x_clear_mouse_face,
x_get_glyph_overhangs,
x_fix_overlapping_area,
! x_draw_fringe_bitmap,
! x_per_char_metric,
! x_encode_char,
! x_compute_glyph_string_overhangs,
! x_draw_glyph_string
};
void
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/04
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/08
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/09
- [Emacs-diffs] Changes to emacs/src/xterm.c, Kim F. Storm, 2003/03/12
- [Emacs-diffs] Changes to emacs/src/xterm.c, Andreas Schwab, 2003/03/12
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/14
- [Emacs-diffs] Changes to emacs/src/xterm.c,
Kim F. Storm <=
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/17
- [Emacs-diffs] Changes to emacs/src/xterm.c, Kim F. Storm, 2003/03/21
- [Emacs-diffs] Changes to emacs/src/xterm.c, Kim F. Storm, 2003/03/21
- [Emacs-diffs] Changes to emacs/src/xterm.c, Kim F. Storm, 2003/03/21
- [Emacs-diffs] Changes to emacs/src/xterm.c, Jan Djärv, 2003/03/22
- [Emacs-diffs] Changes to emacs/src/xterm.c, Stefan Monnier, 2003/03/28
- [Emacs-diffs] Changes to emacs/src/xterm.c, Stefan Monnier, 2003/03/28
- [Emacs-diffs] Changes to emacs/src/xterm.c, Stefan Monnier, 2003/03/28
- [Emacs-diffs] Changes to emacs/src/xterm.c, Kim F. Storm, 2003/03/31