- start_pixpos, rb->width,
- &dbox, &dga);
+ rb->object.dglyph.yoffset ,start_pixpos,
+ rb->width, &dbox, &dga);
+ /*rb->object.dglyph.yoffset*/ 0,
- redisplay_calculate_display_boxes (dl, xpos + xoffset, 0,
+ redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, 0,
- start_pixpos, rb->width,
- &dbox, &dga);
+ rb->object.dglyph.yoffset,
+ start_pixpos, rb->width, &dbox, &dga);
--- xemacs-orig/src/redisplay-output.c Sat Apr 13 18:08:05 2002
+++ xemacs/src/redisplay-output.c Sat Apr 13 21:19:29 2002
@@ -230,7 +230,10 @@
else if (crb->type == RUNE_DGLYPH &&
(!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) ||
!EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) ||
- crb->object.dglyph.xoffset != drb->object.dglyph.xoffset))
+ crb->object.dglyph.xoffset != drb->object.dglyph.xoffset ||
+ crb->object.dglyph.yoffset != drb->object.dglyph.yoffset ||
+ crb->object.dglyph.ascent != drb->object.dglyph.ascent ||
+ crb->object.dglyph.descent != drb->object.dglyph.descent))
return 0;
/* Only check dirtiness if we know something has changed. */
else if (crb->type == RUNE_DGLYPH &&
@@ -1789,7 +1792,7 @@
/* Vertical offsets. This works because yoffset can be -ve as well as +ve */
if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height)
{
- if (glyphsrc->yoffset > 0)
+ if ((glyphsrc->yoffset > 0) && (dest->height > glyphsrc->yoffset))
glyphsrc->height = dest->height - glyphsrc->yoffset;
else
glyphsrc->height = dest->height;
@@ -1880,8 +1883,8 @@
****************************************************************************/
int
redisplay_calculate_display_boxes (struct display_line *dl, int xpos,
- int xoffset, int start_pixpos, int width,
- struct display_box* dest,
+ int xoffset, int yoffset, int start_pixpos,
+ int width, struct display_box* dest,
struct display_glyph_area* src)
{
dest->xpos = xpos;
@@ -1890,10 +1893,11 @@
dest->height = DISPLAY_LINE_HEIGHT (dl);
src->xoffset = -xoffset;
- src->yoffset = -dl->top_clip;
src->width = 0;
src->height = 0;
+ src->yoffset = -dl->top_clip + yoffset;
+
if (start_pixpos >=0 && start_pixpos > xpos)
{
/* Oops, we're asking for a start outside of the displayable
diff -druN xemacs-orig/src/redisplay-x.c xemacs/src/redisplay-x.c
--- xemacs-orig/src/redisplay-x.c Sat Apr 13 18:08:06 2002
+++ xemacs/src/redisplay-x.c Sat Apr 13 21:06:14 2002
@@ -439,11 +439,12 @@
Lisp_Object instance;
struct display_box dbox;
struct display_glyph_area dga;
+
redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
- start_pixpos, rb->width,
- &dbox, &dga);
+ rb->object.dglyph.yoffset, start_pixpos,
+ rb->width, &dbox, &dga);
- XSETWINDOW (window, w);
+ XSETWINDOW (window, w);
instance = glyph_image_instance (rb->object.dglyph.glyph,
window, ERROR_ME_NOT, 1);
findex = rb->findex;
diff -druN xemacs-orig/src/redisplay.c xemacs/src/redisplay.c
--- xemacs-orig/src/redisplay.c Sat Apr 13 18:08:06 2002
+++ xemacs/src/redisplay.c Sat Apr 13 21:17:02 2002
@@ -4,6 +4,7 @@
Copyright (C) 1995, 1996 Ben Wing.
Copyright (C) 1995 Sun Microsystems, Inc.
Copyright (C) 1996 Chuck Thompson.
+ Copyright (C) 1997 -- 2002 various XEmacs maintainers.
This file is part of XEmacs.
@@ -147,9 +148,9 @@
to be skipped before anything is displayed. */
Bytind bi_start_col_enabled;
int start_col_xoffset; /* Number of pixels that still need to
- be skipped. This is used for
- horizontal scrolling of glyphs, where we want
- to be able to scroll over part of the glyph. */
+ be skipped. This is used for
+ horizontal scrolling of glyphs, where we want
+ to be able to scroll over part of the glyph. */
int hscroll_glyph_width_adjust; /* how much the width of the hscroll
glyph differs from space_width (w).
@@ -163,18 +164,19 @@
struct extent_fragment *ef;
face_index findex;
- /* The height of a pixmap may either be predetermined if the user
- has set a baseline value, or it may be dependent on whatever the
- line ascent and descent values end up being, based just on font
- information. In the first case we can immediately update the
- values, thus their inclusion here. In the last case we cannot
- determine the actual contribution to the line height until we
- have finished laying out all text on the line. Thus we propagate
- the max height of such pixmaps and do a final calculation after
- all text has been added to the line. */
+ /* The height of a pixmap may either be predetermined if the user has set a
+ baseline value, or it may be dependent on whatever the line ascent and
+ descent values end up being, based just on font and pixmap-ascent
+ information. In the first case we can immediately update the values, thus
+ their inclusion here. In the last case we cannot determine the actual
+ contribution to the line height until we have finished laying out all text
+ on the line. Thus we propagate the max height of such pixmaps and do a
+ final calculation (in calculate_baseline()) after all text has been added
+ to the line. */
int new_ascent;
int new_descent;
int max_pixmap_height;
+ int need_baseline_computation;
Lisp_Object result_str; /* String where we put the result of
generating a formatted string in the modeline. */
@@ -265,6 +267,9 @@
static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
Bufpos point, int no_regen);
static int point_visible (struct window *w, Bufpos point, int type);
+static void calculate_yoffset (struct display_line *dl,
+ struct display_block *fixup);
+static void calculate_baseline (pos_data *data);
/* This used to be 10 but 30 seems to give much better performance. */
#define INIT_MAX_PREEMPTS 30
@@ -680,6 +685,108 @@
return bounds;
}
+/* This takes a display_block and its containing line and corrects the yoffset
+ of each glyph in the block to cater for the ascent of the line as a
+ whole. Must be called *after* the line-ascent is known! */
+
+static void
+calculate_yoffset (struct display_line *dl, struct display_block *fixup)
+{
+ int i;
+ for (i=0; i<Dynarr_length(fixup->runes); i++)
+ {
+ struct rune *r = Dynarr_atp (fixup->runes,i);
+ if (r->type == RUNE_DGLYPH)
+ {
+ if (r->object.dglyph.ascent < dl->ascent)
+ r->object.dglyph.yoffset = dl->ascent - r->object.dglyph.ascent +
+ r->object.dglyph.descent;
+ }
+ }
+}
+
+/* Calculate the textual baseline (the ascent and descent values for the
+ display_line as a whole).
+
+ If the baseline is completely blank, or contains no manually positioned
+ glyphs, then the textual baseline is simply the baseline of the default font.
+ (The `contains no manually positioned glyphs' part is actually done for
+ us by `add_emchar_rune'.)
+
+ If the baseline contains pixmaps, and they're all manually positioned, then
+ the textual baseline location is constrained that way, and we need do no
+ work.
+
+ If the baseline contains pixmaps, and at least one is automatically
+ positioned, then the textual ascent is the largest ascent on the line, and
+ the textual descent is the largest descent (which is how things are set up at
+ entry to this function anyway): except that if the max_ascent + max_descent
+ is too small for the height of the line (say you've adjusted the baseline of
+ a short glyph, and there's a tall one next to it), then take the ascent and
+ descent for the line individually from the largest of the explicitly set
+ ascent/descent, and the rescaled ascent/descent of the default font, scaled
+ such that the largest glyph will fit.
+
+ This means that if you have a short glyph (but taller than the default
+ font's descent) forced right under the baseline, and a really tall
+ automatically positioned glyph, that the descent for the line is just big
+ enough for the manually positioned short glyph, and the tall one uses as
+ much of that space as the default font would were it as tall as the tall
+ glyph; but that the ascent is big enough for the tall glyph to fit.
+
+ This behaviour means that under no circumstances will changing the baseline
+ of a short glyph cause a tall glyph to move around; nor will it move the
+ textual baseline more than necessary. (Changing a tall glyph's baseline
+ might move the text's baseline arbitrarily, of course.) */
+
+static void
+calculate_baseline (pos_data *data)
+{
+ /* Blank line: baseline is default font's baseline. */
+
+ if (!data->new_ascent && !data->new_descent)
+ {
+ /* We've got a blank line so initialize these values from the default
+ face. */
+ default_face_font_info (data->window, &data->new_ascent,
+ &data->new_descent, 0, 0, 0);
+ }
+
+ /* No automatically positioned glyphs? Return at once. */
+ if (!data->need_baseline_computation)
+ return;
+
+ /* Is the tallest glyph on the line automatically positioned?
+ If it's manually positioned, or it's automatically positioned
+ and there's enough room for it anyway, we need do no more work. */
+ if (data->max_pixmap_height > data->new_ascent + data->new_descent)
+ {
+ int default_font_ascent, default_font_descent, default_font_height;
+ int scaled_default_font_ascent, scaled_default_font_descent;
+
+ default_face_font_info (data->window, &default_font_ascent,
+ &default_font_descent, &default_font_height,
+ 0, 0);
+
+ scaled_default_font_ascent = data->max_pixmap_height *
+ default_font_ascent / default_font_height;
+
+ data->new_ascent = max (data->new_ascent, scaled_default_font_ascent);
+
+ /* The ascent may have expanded now. Do we still need to grow the descent,
+ or are things big enough?
+
+ The +1 caters for the baseline row itself. */
+ if (data->max_pixmap_height > data->new_ascent + data->new_descent)
+ {
+ scaled_default_font_descent = (data->max_pixmap_height *
+ default_font_descent / default_font_height) + 1;
+
+ data->new_descent = max (data->new_descent, scaled_default_font_descent);
+ }
+ }
+}
+
/* Given a display line and a starting position, ensure that the
contents of the display line accurately represent the visual
representation of the buffer contents starting from the given
@@ -1622,6 +1729,8 @@
baseline = glyph_baseline (gb->glyph, data->window);
+ rb.object.dglyph.descent = 0; /* Gets reset lower down, if it is known. */
+
if (glyph_contrib_p (gb->glyph, data->window))
{
/* A pixmap that has not had a baseline explicitly set. Its
@@ -1629,6 +1738,7 @@
if (NILP (baseline))
{
int height = ascent + descent;
+ data->need_baseline_computation = 1;
data->max_pixmap_height = max (data->max_pixmap_height, height);
}
@@ -1651,6 +1761,9 @@
data->new_ascent = max (data->new_ascent, pix_ascent);
data->new_descent = max (data->new_descent, pix_descent);
+ data->max_pixmap_height = max (data->max_pixmap_height, height);
+
+ rb.object.dglyph.descent = pix_descent;
}
/* Otherwise something is screwed up. */
@@ -1699,6 +1812,9 @@
rb.object.dglyph.glyph = gb->glyph;
rb.object.dglyph.extent = gb->extent;
rb.object.dglyph.xoffset = xoffset;
+ rb.object.dglyph.ascent = ascent;
+ rb.object.dglyph.yoffset = 0; /* Until we know better, assume that it has
+ a normal (textual) baseline. */
if (allow_cursor)
{
@@ -2585,26 +2701,7 @@
else
db->end_pos = dl->bounds.right_white;
- /* update line height parameters */
- if (!data.new_ascent && !data.new_descent)
- {
- /* We've got a blank line so initialize these values from the default
- face. */
- default_face_font_info (data.window, &data.new_ascent,
- &data.new_descent, 0, 0, 0);
- }
-
- if (data.max_pixmap_height)
- {
- int height = data.new_ascent + data.new_descent;
- int pix_ascent, pix_descent;
-
- pix_descent = data.max_pixmap_height * data.new_descent / height;
- pix_ascent = data.max_pixmap_height - pix_descent;
-
- data.new_ascent = max (data.new_ascent, pix_ascent);
- data.new_descent = max (data.new_descent, pix_descent);
- }
+ calculate_baseline (&data);
dl->ascent = data.new_ascent;
dl->descent = data.new_descent;
@@ -2622,6 +2719,8 @@
dl->descent = descent;
}
+ calculate_yoffset (dl, db);
+
dl->cursor_elt = data.cursor_x;
/* #### lossage lossage lossage! Fix this shit! */
if (data.bi_bufpos > BI_BUF_ZV (b))
@@ -2711,17 +2810,7 @@
add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
}
- if (data.max_pixmap_height)
- {
- int height = data.new_ascent + data.new_descent;
- int pix_ascent, pix_descent;
-
- pix_descent = data.max_pixmap_height * data.new_descent / height;
- pix_ascent = data.max_pixmap_height - pix_descent;
-
- data.new_ascent = max (data.new_ascent, pix_ascent);
- data.new_descent = max (data.new_descent, pix_descent);
- }
+ calculate_baseline (&data);
dl->ascent = data.new_ascent;
dl->descent = data.new_descent;
@@ -2729,6 +2818,8 @@
data.db->start_pos = dl->bounds.left_in;
data.db->end_pos = data.pixpos;
+ calculate_yoffset (dl, data.db);
+
return data.pixpos - dl->bounds.left_in;
}
@@ -2800,20 +2891,13 @@
(reverse ? elt-- : elt++);
}
- if (data.max_pixmap_height)
- {
- int height = data.new_ascent + data.new_descent;
- int pix_ascent, pix_descent;
-
- pix_descent = data.max_pixmap_height * data.new_descent / height;
- pix_ascent = data.max_pixmap_height - pix_descent;
- data.new_ascent = max (data.new_ascent, pix_ascent);
- data.new_descent = max (data.new_descent, pix_descent);
- }
+ calculate_baseline (&data);
dl->ascent = data.new_ascent;
dl->descent = data.new_descent;
+ calculate_yoffset (dl, data.db);
+
return data.pixpos;
}
@@ -4243,9 +4327,9 @@
/***************************************************************************/
-/* */
-/* displayable string routines */
-/* */
+/* */
+/* displayable string routines */
+/* */
/***************************************************************************/
/* Given a position for a string in a window, ensure that the given
@@ -4834,26 +4918,7 @@
else
db->end_pos = dl->bounds.right_white;
- /* update line height parameters */
- if (!data.new_ascent && !data.new_descent)
- {
- /* We've got a blank line so initialize these values from the default
- face. */
- default_face_font_info (data.window, &data.new_ascent,
- &data.new_descent, 0, 0, 0);
- }
-
- if (data.max_pixmap_height)
- {
- int height = data.new_ascent + data.new_descent;
- int pix_ascent, pix_descent;
-
- pix_descent = data.max_pixmap_height * data.new_descent / height;
- pix_ascent = data.max_pixmap_height - pix_descent;
-
- data.new_ascent = max (data.new_ascent, pix_ascent);
- data.new_descent = max (data.new_descent, pix_descent);
- }
+ calculate_baseline (&data);
dl->ascent = data.new_ascent;
dl->descent = data.new_descent;
@@ -4871,6 +4936,8 @@
dl->descent = descent;
}
+ calculate_yoffset (dl, db);
+
dl->cursor_elt = data.cursor_x;
/* #### lossage lossage lossage! Fix this shit! */
if (data.bi_bufpos > bi_string_zv)
diff -druN xemacs-orig/src/redisplay.h xemacs/src/redisplay.h
--- xemacs-orig/src/redisplay.h Sat Apr 13 18:08:06 2002
+++ xemacs/src/redisplay.h Sat Apr 13 18:23:46 2002
@@ -147,6 +147,9 @@
If this is a rune in the modeline
then this might be nil. */
+ int ascent; /* Ascent of this glyph, in pixels. */
+ int descent; /* Descent of this glyph, in pixels. */
+ int yoffset; /* Offset from line top to reach glyph top */
int xoffset; /* Number of pixels that need to be
chopped off the left of the glyph.
This has the effect of shifting the
@@ -768,8 +771,8 @@
face_index findex, int cursor_start, int cursor_width,
int cursor_height, int offset_bitmap);
int redisplay_calculate_display_boxes (struct display_line *dl, int xpos,
- int xoffset, int start_pixpos, int width,
- struct display_box* dest,
+ int xoffset, int yoffset, int start_pixpos,
+ int width, struct display_box* dest,
struct display_glyph_area* src);
int redisplay_normalize_glyph_area (struct display_box* dest,
struct display_glyph_area* glyphsrc);