return face;
}
+static MGlyphString work_gstring;
+
\f
/* Internal API */
mface_yellow->property[MFACE_FOREGROUND] = (void *) msymbol ("yellow");
mface_magenta = mface ();
mface_magenta->property[MFACE_FOREGROUND] = (void *) msymbol ("magenta");
+
+ work_gstring.glyphs = malloc (sizeof (MGlyph) * 2);
+ work_gstring.size = 2;
+ work_gstring.used = 0;
+ work_gstring.inc = 1;
return 0;
}
{
rface->rfont = rfont;
g.otf_encoded = 0;
- mfont__get_metric (rfont, &g);
- rface->space_width = g.width;
- g.code = MCHAR_INVALID_CODE;
- mfont__get_metric (rface->rfont, &g);
- rface->ascent = g.ascent;
- rface->descent = g.descent;
+ work_gstring.glyphs[0] = g;
+ work_gstring.glyphs[0].rface = rface;
+ work_gstring.glyphs[1].code = MCHAR_INVALID_CODE;
+ work_gstring.glyphs[1].rface = rface;
+ mfont__get_metric (&work_gstring, 0, 2);
+ rface->space_width = work_gstring.glyphs[0].width;
+ rface->ascent = work_gstring.glyphs[1].ascent;
+ rface->descent = work_gstring.glyphs[1].descent;
}
else
{
*rface = *from_g->rface->ascii_rface;
rface->rfont = rfont;
{
- MGlyph tmp;
-
- tmp.code = MCHAR_INVALID_CODE;
- mfont__get_metric (rfont, &tmp);
- rface->ascent = tmp.ascent;
- rface->descent = tmp.descent;
+ work_gstring.glyphs[0].code = MCHAR_INVALID_CODE;
+ work_gstring.glyphs[0].rface = rface;
+ mfont__get_metric (&work_gstring, 0, 1);
+ rface->ascent = work_gstring.glyphs[0].ascent;
+ rface->descent = work_gstring.glyphs[0].descent;
}
mwin__realize_face (rface);
mplist_add (from_g->rface->frame->realized_face_list, Mt, rface);
static MRealizedFont *ft_select (MFrame *, MFont *, MFont *, int);
static int ft_open (MRealizedFont *);
static void ft_close (MRealizedFont *);
-static void ft_find_metric (MRealizedFont *, MGlyph *);
+static void ft_find_metric (MRealizedFont *, MGlyphString *, int, int);
static unsigned ft_encode_char (MRealizedFont *, int, unsigned);
static void ft_render (MDrawWindow, int, int, MGlyphString *,
MGlyph *, MGlyph *, int, MDrawRegion);
/* The FreeType font driver function FIND_METRIC. */
static void
-ft_find_metric (MRealizedFont *rfont, MGlyph *g)
+ft_find_metric (MRealizedFont *rfont, MGlyphString *gstring,
+ int from, int to)
{
MFTInfo *ft_info = (MFTInfo *) rfont->info;
FT_Face ft_face = ft_info->ft_face;
+ MGlyph *g = MGLYPH (from), *gend = MGLYPH (to);
+ FT_Int32 load_flags = FT_LOAD_RENDER;
- if (g->code == MCHAR_INVALID_CODE)
+ if (! gstring->anti_alias)
{
- unsigned unitsPerEm = ft_face->units_per_EM;
- int size = rfont->font.property[MFONT_SIZE] / 10;
-
- g->lbearing = 0;
- g->rbearing = ft_face->max_advance_width * size / unitsPerEm;
- g->width = ft_face->max_advance_width * size / unitsPerEm;
- g->ascent = ft_face->ascender * size / unitsPerEm;
- g->descent = (- ft_face->descender) * size / unitsPerEm;
+#ifdef FT_LOAD_TARGET_MONO
+ load_flags |= FT_LOAD_TARGET_MONO;
+#else
+ load_flags |= FT_LOAD_MONOCHROME;
+#endif
}
- else
- {
- FT_Glyph_Metrics *metrics;
- FT_UInt code;
- if (g->otf_encoded)
- code = g->code;
+ for (; g != gend; g++)
+ {
+ if (g->code == MCHAR_INVALID_CODE)
+ {
+ unsigned unitsPerEm = ft_face->units_per_EM;
+ int size = rfont->font.property[MFONT_SIZE] / 10;
+
+ g->lbearing = 0;
+ g->rbearing = ft_face->max_advance_width * size / unitsPerEm;
+ g->width = ft_face->max_advance_width * size / unitsPerEm;
+ g->ascent = ft_face->ascender * size / unitsPerEm;
+ g->descent = (- ft_face->descender) * size / unitsPerEm;
+ }
else
- code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
-
- FT_Load_Glyph (ft_face, code, FT_LOAD_RENDER);
- metrics = &ft_face->glyph->metrics;
- g->lbearing = (metrics->horiBearingX >> 6);
- g->rbearing = (metrics->horiBearingX + metrics->width) >> 6;
- g->width = metrics->horiAdvance >> 6;
- g->ascent = metrics->horiBearingY >> 6;
- g->descent = (metrics->height - metrics->horiBearingY) >> 6;
+ {
+ FT_Glyph_Metrics *metrics;
+ FT_UInt code;
+
+ if (g->otf_encoded)
+ code = g->code;
+ else
+ code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
+
+ FT_Load_Glyph (ft_face, code, FT_LOAD_RENDER);
+ metrics = &ft_face->glyph->metrics;
+ g->lbearing = (metrics->horiBearingX >> 6);
+ g->rbearing = (metrics->horiBearingX + metrics->width) >> 6;
+ g->width = metrics->horiAdvance >> 6;
+ g->ascent = metrics->horiBearingY >> 6;
+ g->descent = (metrics->height - metrics->horiBearingY) >> 6;
+ }
}
}
/* The FreeType font driver function RENDER. */
-struct {
- int size, inc, used;
- MDrawPoint *points;
-} point_table[8];
+#define NUM_POINTS 0x1000
+
+typedef struct {
+ MDrawPoint points[NUM_POINTS];
+ MDrawPoint *p;
+} MPointTable;
static void
ft_render (MDrawWindow win, int x, int y,
MGlyphString *gstring, MGlyph *from, MGlyph *to,
int reverse, MDrawRegion region)
{
- MRealizedFace *rface;
- MFrame *frame;
+ MRealizedFace *rface = from->rface;
+ MFrame *frame = rface->frame;
MFTInfo *ft_info;
FT_Face ft_face = NULL;
FT_Int32 load_flags = FT_LOAD_RENDER;
MGlyph *g;
int i, j;
+ MPointTable point_table[8];
if (from == to)
return;
- if (! gstring->control.anti_alias)
+ if (! gstring->anti_alias)
{
#ifdef FT_LOAD_TARGET_MONO
load_flags |= FT_LOAD_TARGET_MONO;
/* It is assured that the all glyphs in the current range use the
same realized face. */
- rface = from->rface;
- frame = rface->frame;
ft_info = (MFTInfo *) rface->rfont->info;
ft_face = ft_info->ft_face;
for (i = 0; i < 8; i++)
- MLIST_RESET (point_table + i);
+ point_table[i].p = point_table[i].points;
for (g = from; g < to; x += g++->width)
{
FT_UInt code;
unsigned char *bmp;
- MDrawPoint p;
int intensity;
+ MPointTable *ptable;
+ int xoff, yoff;
if (g->otf_encoded)
code = g->code;
else
code = FT_Get_Char_Index (ft_face, (FT_ULong) g->code);
FT_Load_Glyph (ft_face, code, load_flags);
+ yoff = y - ft_face->glyph->bitmap_top + g->yoff;
bmp = ft_face->glyph->bitmap.buffer;
- if (gstring->control.anti_alias)
- {
- for (i = 0; i < ft_face->glyph->bitmap.rows;
- i++, bmp += ft_face->glyph->bitmap.pitch)
- for (j = 0; j < ft_face->glyph->bitmap.width; j++)
+ if (gstring->anti_alias)
+ for (i = 0; i < ft_face->glyph->bitmap.rows;
+ i++, bmp += ft_face->glyph->bitmap.pitch, yoff++)
+ {
+ xoff = x + ft_face->glyph->bitmap_left + g->xoff;
+ for (j = 0; j < ft_face->glyph->bitmap.width; j++, xoff++)
{
intensity = bmp[j] >> 5;
if (intensity)
{
- p.x = x + ft_face->glyph->bitmap_left + g->xoff + j;
- p.y = y - ft_face->glyph->bitmap_top + g->yoff + i;
- MLIST_APPEND1 (point_table + intensity, points, p,
- MERROR_FONT_FT);
+ ptable = point_table + intensity;
+ ptable->p->x = xoff;
+ ptable->p->y = yoff;
+ ptable->p++;
+ if (ptable->p - ptable->points == NUM_POINTS)
+ {
+ mwin__draw_points (frame, win, rface,
+ reverse ? 7 - intensity : intensity,
+ ptable->points, NUM_POINTS, region);
+ ptable->p = ptable->points;
+ }
}
}
- }
+ }
else
- {
- for (i = 0; i < ft_face->glyph->bitmap.rows;
- i++, bmp += ft_face->glyph->bitmap.pitch)
- for (j = 0; j < ft_face->glyph->bitmap.width; j++)
+ for (i = 0; i < ft_face->glyph->bitmap.rows;
+ i++, bmp += ft_face->glyph->bitmap.pitch, yoff++)
+ {
+ xoff = x + ft_face->glyph->bitmap_left + g->xoff;
+ for (j = 0; j < ft_face->glyph->bitmap.width; j++, xoff++)
{
intensity = bmp[j / 8] & (1 << (7 - (j % 8)));
if (intensity)
{
- p.x = x + ft_face->glyph->bitmap_left + g->xoff + j;
- p.y = y - ft_face->glyph->bitmap_top + g->yoff + i;
- MLIST_APPEND1 (point_table, points, p,
- MERROR_FONT_FT);
+ ptable = point_table;
+ ptable->p->x = xoff;
+ ptable->p->y = yoff;
+ ptable->p++;
+ if (ptable->p - ptable->points == NUM_POINTS)
+ {
+ mwin__draw_points (frame, win, rface,
+ reverse ? 0 : 7,
+ ptable->points, NUM_POINTS, region);
+ ptable->p = ptable->points;
+ }
}
}
}
}
- if (gstring->control.anti_alias)
+ if (gstring->anti_alias)
{
for (i = 1; i < 8; i++)
- if (point_table[i].used)
+ if (point_table[i].p != point_table[i].points)
mwin__draw_points (frame, win, rface, reverse ? 7 - i : i,
- point_table[i].points, point_table[i].used,
- gstring->control.anti_alias);
+ point_table[i].points,
+ point_table[i].p - point_table[i].points, region);
}
else
{
- mwin__draw_points (frame, win, rface, reverse ? 7 : 0,
- point_table[0].points, point_table[0].used,
- gstring->control.anti_alias);
+ if (point_table[0].p != point_table[0].points)
+ mwin__draw_points (frame, win, rface, reverse ? 0 : 7,
+ point_table[0].points,
+ point_table[0].p - point_table[0].points, region);
}
}
mfont__driver_list[MFONT_TYPE_FT] = &ft_driver;
- for (i = 0; i < 8; i++)
- MLIST_INIT1 (point_table + i, points, 0x1000);
-
return 0;
}