static MFontDriver xfont_driver =
{ xfont_select, xfont_open,
xfont_find_metric, xfont_has_char, xfont_encode_char,
- xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability };
+ xfont_render, xfont_list, xfont_list_family_names, xfont_check_capability
+ };
static int
font_compare (const void *p1, const void *p2)
rfont->ascent = xfont->ascent + rfont->baseline_offset;
rfont->descent = xfont->descent - rfont->baseline_offset;
rfont->max_advance = xfont->max_bounds.width;
+ rfont->x_ppem = rfont->y_ppem = size / 10;
rfont->fontp = xfont;
rfont->next = MPLIST_VAL (frame->realized_font_list);
MPLIST_VAL (frame->realized_font_list) = rfont;
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
- {
- if (g->code == MCHAR_INVALID_CODE)
- {
- g->lbearing = xfont->max_bounds.lbearing;
- g->rbearing = xfont->max_bounds.rbearing;
- g->width = xfont->max_bounds.width;
- g->ascent = xfont->ascent;
- g->descent = xfont->descent;
- }
- else
- {
- int byte1 = g->code >> 8, byte2 = g->code & 0xFF;
- XCharStruct *pcm = NULL;
-
- if (xfont->per_char != NULL)
- {
- if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
- {
- if (byte1 == 0
- && byte2 >= xfont->min_char_or_byte2
- && byte2 <= xfont->max_char_or_byte2)
- pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
- }
- else
- {
- if (byte1 >= xfont->min_byte1
- && byte1 <= xfont->max_byte1
- && byte2 >= xfont->min_char_or_byte2
- && byte2 <= xfont->max_char_or_byte2)
- {
- pcm = (xfont->per_char
- + ((xfont->max_char_or_byte2
- - xfont->min_char_or_byte2 + 1)
- * (byte1 - xfont->min_byte1))
- + (byte2 - xfont->min_char_or_byte2));
- }
- }
- }
-
- if (pcm)
- {
- g->lbearing = pcm->lbearing;
- g->rbearing = pcm->rbearing;
- g->width = pcm->width;
- g->ascent = pcm->ascent;
- g->descent = pcm->descent;
- }
- else
- {
- /* If the per_char pointer is null, all glyphs between
- the first and last character indexes inclusive have
- the same information, as given by both min_bounds and
- max_bounds. */
- g->lbearing = 0;
- g->rbearing = xfont->max_bounds.width;
- g->width = xfont->max_bounds.width;
- g->ascent = xfont->ascent;
- g->descent = xfont->descent;
- }
- }
- g->ascent += rfont->baseline_offset;
- g->descent -= rfont->baseline_offset;
- }
+ if (! g->g.measured)
+ {
+ continue;
+ if (g->g.code == MCHAR_INVALID_CODE)
+ {
+ g->g.lbearing = xfont->max_bounds.lbearing << 6;
+ g->g.rbearing = xfont->max_bounds.rbearing << 6;
+ g->g.xadv = xfont->max_bounds.width << 6;
+ g->g.ascent = xfont->ascent << 6;
+ g->g.descent = xfont->descent << 6;
+ }
+ else
+ {
+ int byte1 = g->g.code >> 8, byte2 = g->g.code & 0xFF;
+ XCharStruct *pcm = NULL;
+
+ if (xfont->per_char != NULL)
+ {
+ if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
+ {
+ if (byte1 == 0
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
+ }
+ else
+ {
+ if (byte1 >= xfont->min_byte1
+ && byte1 <= xfont->max_byte1
+ && byte2 >= xfont->min_char_or_byte2
+ && byte2 <= xfont->max_char_or_byte2)
+ {
+ pcm = (xfont->per_char
+ + ((xfont->max_char_or_byte2
+ - xfont->min_char_or_byte2 + 1)
+ * (byte1 - xfont->min_byte1))
+ + (byte2 - xfont->min_char_or_byte2));
+ }
+ }
+ }
+
+ if (pcm)
+ {
+ g->g.lbearing = pcm->lbearing << 6;
+ g->g.rbearing = pcm->rbearing << 6;
+ g->g.xadv = pcm->width << 6;
+ g->g.ascent = pcm->ascent << 6;
+ g->g.descent = pcm->descent << 6;
+ }
+ else
+ {
+ /* If the per_char pointer is null, all glyphs between
+ the first and last character indexes inclusive have
+ the same information, as given by both min_bounds and
+ max_bounds. */
+ g->g.lbearing = 0;
+ g->g.rbearing = xfont->max_bounds.width << 6;
+ g->g.xadv = xfont->max_bounds.width << 6;
+ g->g.ascent = xfont->ascent << 6;
+ g->g.descent = xfont->descent << 6;
+ }
+ }
+ g->g.ascent += rfont->baseline_offset << 6;
+ g->g.descent -= rfont->baseline_offset << 6;
+ g->g.measured = 1;
+ }
}
code = (XChar2b *) alloca (sizeof (XChar2b) * (to - from));
for (i = 0, g = from; g < to; i++, g++)
{
- code[i].byte1 = g->code >> 8;
- code[i].byte2 = g->code & 0xFF;
+ code[i].byte1 = g->g.code >> 8;
+ code[i].byte2 = g->g.code & 0xFF;
}
g = from;
while (g < to)
{
if (g->type == GLYPH_PAD)
- x += g++->width;
+ x += g++->g.xadv;
else if (g->type == GLYPH_SPACE)
for (; g < to && g->type == GLYPH_SPACE; g++)
- x += g->width;
+ x += g->g.xadv;
else if (! g->rface->rfont)
{
- if ((g->c >= 0x200B && g->c <= 0x200F)
- || (g->c >= 0x202A && g->c <= 0x202E))
- x += g++->width;
+ if ((g->g.c >= 0x200B && g->g.c <= 0x200F)
+ || (g->g.c >= 0x202A && g->g.c <= 0x202E))
+ x += g++->g.xadv;
else
{
/* As a font is not found for this character, draw an
empty box. */
- int box_width = g->width;
+ int box_width = g->g.xadv;
int box_height = gstring->ascent + gstring->descent;
if (box_width > 4)
box_height -= 2;
XDrawRectangle (display, (Window) win, gc,
x, y - gstring->ascent, box_width, box_height);
- x += g++->width;
+ x += g++->g.xadv;
}
}
- else if (g->xoff != 0 || g->yoff != 0 || g->right_padding)
+ else if (g->g.xoff != 0 || g->g.yoff != 0 || g->right_padding)
{
XDrawString16 (display, (Window) win, gc,
- x + g->xoff, y + g->yoff - baseline_offset,
+ x + g->g.xoff, y + g->g.yoff - baseline_offset,
code + (g - from), 1);
- x += g->width;
+ x += g->g.xadv;
g++;
}
else
int code_idx = g - from;
for (i = 0;
- g < to && g->type == GLYPH_CHAR && g->xoff == 0 && g->yoff == 0;
+ g < to && g->type == GLYPH_CHAR && g->g.xoff == 0 && g->g.yoff == 0;
i++, g++)
- x += g->width;
+ x += g->g.xadv;
XDrawString16 (display, (Window) win, gc,
orig_x, y - baseline_offset, code + code_idx, i);
}
static void xft_render (MDrawWindow, int, int, MGlyphString *,
MGlyph *, MGlyph *, int, MDrawRegion);
static int xft_check_capability (MRealizedFont *rfont, MSymbol capability);
+static int xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec);
+static int xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to,
+ MFLTGlyphString *out,
+ MFLTGlyphAdjustment *adjustment);
static MFontDriver xft_driver =
{ NULL, xft_open,
xft_find_metric, xft_has_char, xft_encode_char, xft_render, NULL, NULL,
- xft_check_capability
+ xft_check_capability, NULL, NULL, xft_check_otf, xft_drive_otf
};
static void
rfont->max_advance = max_advance;
rfont->average_width = average_width;
rfont->baseline_offset = baseline_offset;
+ rfont->x_ppem = ft_face->size->metrics.x_ppem;
+ rfont->y_ppem = ft_face->size->metrics.y_ppem;
rfont->fontp = xft_font;
rfont->next = MPLIST_VAL (frame->realized_font_list);
MPLIST_VAL (frame->realized_font_list) = rfont;
MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
for (; g != gend; g++)
- {
- if (g->code == MCHAR_INVALID_CODE)
- {
- g->lbearing = 0;
- g->rbearing = xft_font->max_advance_width;
- g->width = g->rbearing;
- g->ascent = xft_font->ascent;
- g->descent = xft_font->descent;
- }
- else
- {
- XGlyphInfo extents;
-
- XftGlyphExtents (display, xft_font, &g->code, 1, &extents);
- g->lbearing = - extents.x;
- g->rbearing = extents.width - extents.x;
- g->width = extents.xOff;
- g->ascent = extents.y;
- g->descent = extents.height - extents.y;
- }
- }
+ if (! g->g.measured)
+ {
+ if (g->g.code == MCHAR_INVALID_CODE)
+ {
+ g->g.lbearing = 0;
+ g->g.rbearing = xft_font->max_advance_width << 6;
+ g->g.xadv = g->g.rbearing << 6;
+ g->g.ascent = xft_font->ascent << 6;
+ g->g.descent = xft_font->descent << 6;
+ }
+ else
+ {
+ XGlyphInfo extents;
+
+ XftGlyphExtents (display, xft_font, &g->g.code, 1, &extents);
+ g->g.lbearing = (- extents.x) << 6;
+ g->g.rbearing = (extents.width - extents.x) << 6;
+ g->g.xadv = extents.xOff << 6;
+ g->g.ascent = extents.y << 6;
+ g->g.descent = (extents.height - extents.y) << 6;
+ }
+ }
}
static int
y -= rfont->baseline_offset;
glyphs = alloca (sizeof (FT_UInt) * (to - from));
- for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->width)
+ for (last_x = x, nglyphs = 0, g = from; g < to; x += g++->g.xadv)
{
- if (g->xoff == 0 && g->yoff == 0 && !g->left_padding && !g->right_padding)
- glyphs[nglyphs++] = g->code;
+ if (g->g.xoff == 0 && g->g.yoff == 0 && !g->left_padding && !g->right_padding)
+ glyphs[nglyphs++] = g->g.code;
else
{
if (nglyphs > 0)
last_x, y, glyphs, nglyphs);
nglyphs = 0;
XftDrawGlyphs (xft_draw, xft_color, xft_font,
- x + g->xoff, y + g->yoff, (FT_UInt *) &g->code, 1);
- last_x = x + g->width;
+ x + g->g.xoff, y + g->g.yoff, (FT_UInt *) &g->g.code, 1);
+ last_x = x + g->g.xadv;
}
}
if (nglyphs > 0)
return result;
}
+static int
+xft_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.check_otf (font, spec);
+ rfont->info = rfont_xft;
+ return result;
+}
+
+static int
+xft_drive_otf (MFLTFont *font, MFLTOtfSpec *spec,
+ MFLTGlyphString *in, int from, int to,
+ MFLTGlyphString *out,
+ MFLTGlyphAdjustment *adjustment)
+{
+ MRealizedFont *rfont = ((MFLTFontForRealized *) font)->rfont;
+ MRealizedFontXft *rfont_xft = rfont->info;
+ int result;
+
+ rfont->info = rfont_xft->info;
+ result = mfont__ft_driver.drive_otf (font, spec, in, from, to, out,
+ adjustment);
+ rfont->info = rfont_xft;
+ return result;
+}
+
#endif /* HAVE_XFT2 */
\f
for (; from < to; from++)
{
XDrawRectangle (display, (Window) win, gc,
- x, y - gstring->ascent + 1, from->width - 1,
+ x, y - gstring->ascent + 1, from->g.xadv - 1,
gstring->ascent + gstring->descent - 2);
- x += from->width;
+ x += from->g.xadv;
}
}
int x0, x1;
if (g->left_padding)
- x0 = x + box->outer_hmargin, x1 = x + g->width - 1;
+ x0 = x + box->outer_hmargin, x1 = x + g->g.xadv - 1;
else
- x0 = x, x1 = x + g->width - box->outer_hmargin - 1;
+ x0 = x, x1 = x + g->g.xadv - box->outer_hmargin - 1;
/* Draw the top side. */
for (i = 0; i < box->width; i++)