Commit 6b6bd726 authored by Kim F. Storm's avatar Kim F. Storm

Remove consolidated defines and code.

(BUILD_WCHAR_T, BYTE1, BYTE2): Macros removed; callers changed
to use STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2 instead.
(w32_per_char_metric): Change font_type arg to int for RIF.
(w32_encode_char): Return int according to RIF requirements.
(w32_compute_glyph_string_overhangs): Adapt to RIF.
(w32_get_glyph_overhangs): New function for RIF.  Uses generic
x_get_glyph_overhangs.
(w32_redisplay_interface): Add new members.
parent e83074af
...@@ -260,19 +260,6 @@ extern int errno; ...@@ -260,19 +260,6 @@ extern int errno;
extern EMACS_INT extra_keyboard_modifiers; extern EMACS_INT extra_keyboard_modifiers;
/* 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 void x_update_window_end P_ ((struct window *, int, int)); static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void w32_delete_display P_ ((struct w32_display_info *)); void w32_delete_display P_ ((struct w32_display_info *));
...@@ -344,9 +331,6 @@ void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); ...@@ -344,9 +331,6 @@ void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
HDC, int)); HDC, int));
static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *)); static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
static void notice_overwritten_cursor P_ ((struct window *,
enum glyph_row_area,
int, int, int, int));
static Lisp_Object Qvendor_specific_keysyms; static Lisp_Object Qvendor_specific_keysyms;
...@@ -897,35 +881,9 @@ w32_cursor_to (vpos, hpos, y, x) ...@@ -897,35 +881,9 @@ w32_cursor_to (vpos, hpos, y, x)
/* Function prototypes of this page. */ /* Function prototypes of this page. */
static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
struct glyph *,
wchar_t *,
int *));
static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
int, wchar_t *, int));
static XCharStruct *w32_per_char_metric P_ ((XFontStruct *, static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
wchar_t *, wchar_t *, int));
enum w32_char_font_type)); static int w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
static enum w32_char_font_type
w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
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));
/* Dealing with bits of wchar_t as if they were an XChar2B. */
#define BUILD_WCHAR_T(byte1, byte2) \
((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
#define BYTE1(ch) \
(((ch) & 0xff00) >> 8)
#define BYTE2(ch) \
((ch) & 0x00ff)
/* Get metrics of character CHAR2B in FONT. Value is always non-null. /* Get metrics of character CHAR2B in FONT. Value is always non-null.
...@@ -946,8 +904,8 @@ w32_bdf_per_char_metric (font, char2b, dim, pcm) ...@@ -946,8 +904,8 @@ w32_bdf_per_char_metric (font, char2b, dim, pcm)
buf[0] = (char)(*char2b); buf[0] = (char)(*char2b);
else else
{ {
buf[0] = BYTE1 (*char2b); buf[0] = XCHAR2B_BYTE1 (char2b);
buf[1] = BYTE2 (*char2b); buf[1] = XCHAR2B_BYTE2 (char2b);
} }
bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim); bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
...@@ -1065,7 +1023,7 @@ static XCharStruct * ...@@ -1065,7 +1023,7 @@ static XCharStruct *
w32_per_char_metric (font, char2b, font_type) w32_per_char_metric (font, char2b, font_type)
XFontStruct *font; XFontStruct *font;
wchar_t *char2b; wchar_t *char2b;
enum w32_char_font_type font_type; int /* enum w32_char_font_type */ font_type;
{ {
/* The result metric information. */ /* The result metric information. */
XCharStruct *pcm; XCharStruct *pcm;
...@@ -1166,7 +1124,7 @@ w32_use_unicode_for_codepage (codepage) ...@@ -1166,7 +1124,7 @@ w32_use_unicode_for_codepage (codepage)
/* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
the two-byte form of C. Encoding is returned in *CHAR2B. */ the two-byte form of C. Encoding is returned in *CHAR2B. */
static INLINE enum w32_char_font_type static int /* enum w32_char_font_type */
w32_encode_char (c, char2b, font_info, two_byte_p) w32_encode_char (c, char2b, font_info, two_byte_p)
int c; int c;
wchar_t *char2b; wchar_t *char2b;
...@@ -1181,7 +1139,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1181,7 +1139,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
xassert (two_byte_p); xassert (two_byte_p);
*two_byte_p = w32_font_is_double_byte (font); if (two_byte_p)
*two_byte_p = w32_font_is_double_byte (font);
/* FONT_INFO may define a scheme by which to encode byte1 and byte2. /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
This may be either a program in a special encoder language or a This may be either a program in a special encoder language or a
...@@ -1194,14 +1153,14 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1194,14 +1153,14 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
if (CHARSET_DIMENSION (charset) == 1) if (CHARSET_DIMENSION (charset) == 1)
{ {
ccl->reg[0] = charset; ccl->reg[0] = charset;
ccl->reg[1] = BYTE2 (*char2b); ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
ccl->reg[2] = -1; ccl->reg[2] = -1;
} }
else else
{ {
ccl->reg[0] = charset; ccl->reg[0] = charset;
ccl->reg[1] = BYTE1 (*char2b); ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
ccl->reg[2] = BYTE2 (*char2b); ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
} }
ccl_driver (ccl, NULL, NULL, 0, 0, NULL); ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
...@@ -1209,9 +1168,9 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1209,9 +1168,9 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
/* We assume that MSBs are appropriately set/reset by CCL /* We assume that MSBs are appropriately set/reset by CCL
program. */ program. */
if (!*two_byte_p) /* 1-byte font */ if (!*two_byte_p) /* 1-byte font */
*char2b = BUILD_WCHAR_T (0, ccl->reg[1]); STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
else else
*char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]); STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
} }
else if (font_info->encoding[charset]) else if (font_info->encoding[charset])
{ {
...@@ -1221,18 +1180,18 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1221,18 +1180,18 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
if ((enc == 1 || enc == 2) if ((enc == 1 || enc == 2)
&& CHARSET_DIMENSION (charset) == 2) && CHARSET_DIMENSION (charset) == 2)
*char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b)); STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b));
if (enc == 1 || enc == 3 if (enc == 1 || enc == 3
|| (enc == 4 && CHARSET_DIMENSION (charset) == 1)) || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
*char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80); STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80);
else if (enc == 4) else if (enc == 4)
{ {
int sjis1, sjis2; int sjis1, sjis2;
ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b), ENCODE_SJIS (XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b),
sjis1, sjis2); sjis1, sjis2);
*char2b = BUILD_WCHAR_T (sjis1, sjis2); STORE_XCHAR2B (char2b, sjis1, sjis2);
} }
} }
codepage = font_info->codepage; codepage = font_info->codepage;
...@@ -1244,8 +1203,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1244,8 +1203,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
&& charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC) && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC)
{ {
char temp[3]; char temp[3];
temp[0] = BYTE1 (*char2b); temp[0] = XCHAR2B_BYTE1 (char2b);
temp[1] = BYTE2 (*char2b); temp[1] = XCHAR2B_BYTE2 (char2b);
temp[2] = '\0'; temp[2] = '\0';
if (codepage != CP_UNICODE) if (codepage != CP_UNICODE)
{ {
...@@ -1270,1091 +1229,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p) ...@@ -1270,1091 +1229,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p)
} }
/* 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. Value is a pointer to a
realized face that is ready for display. */
static INLINE struct face *
x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
struct frame *f;
int c, face_id;
wchar_t *char2b;
int multibyte_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 = BUILD_WCHAR_T (0, 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 = BUILD_WCHAR_T (0, 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 = BUILD_WCHAR_T (c1, c2);
else
*char2b = BUILD_WCHAR_T (0, 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)
w32_encode_char (c, char2b, font_info, &multibyte_p);
}
}
/* Make sure X resources of the face are allocated. */
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;
wchar_t *char2b;
int *two_byte_p;
{
struct face *face;
int dummy = 0;
xassert (glyph->type == CHAR_GLYPH);
face = FACE_FROM_ID (f, glyph->face_id);
if (two_byte_p)
*two_byte_p = 0;
else
two_byte_p = &dummy;
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 = BUILD_WCHAR_T (0, 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 = BUILD_WCHAR_T (0, 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 = BUILD_WCHAR_T (c1, c2);
else
*char2b = BUILD_WCHAR_T (0, 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)
{
glyph->w32_font_type
= w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
}
}
}
/* 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;
glyph->w32_font_type = UNKNOWN_FONT;
++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;
glyph->w32_font_type = UNKNOWN_FONT;
++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;
glyph->w32_font_type = UNKNOWN_FONT;
++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;
glyph->w32_font_type = UNKNOWN_FONT;
++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_BASE (font) / FONT_HEIGHT (font);
if (width <= 0)
width = 1;
if (height <= 0)
height = 1;