X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/6445ee0fb751ae2c1dfef900d44721b3d952812f..1087305574fd61256d66eb0c995f8bb74bd91afe:/src/ftfont.c diff --git a/src/ftfont.c b/src/ftfont.c index f19933c7ef..57ded171de 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -28,13 +28,9 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "dispextern.h" -#include "frame.h" -#include "blockinput.h" #include "character.h" #include "charset.h" -#include "coding.h" #include "composite.h" -#include "fontset.h" #include "font.h" #include "ftfont.h" @@ -1179,7 +1175,7 @@ ftfont_open2 (struct frame *f, bool scalable; int spacing; int i; - int upEM; + double upEM; val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); if (! CONSP (val)) @@ -1235,9 +1231,9 @@ ftfont_open2 (struct frame *f, && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0); if (scalable) { - font->ascent = ft_face->ascender * size / upEM; - font->descent = - ft_face->descender * size / upEM; - font->height = ft_face->height * size / upEM; + font->ascent = ft_face->ascender * size / upEM + 0.5; + font->descent = - ft_face->descender * size / upEM + 0.5; + font->height = ft_face->height * size / upEM + 0.5; } else { @@ -1255,7 +1251,7 @@ ftfont_open2 (struct frame *f, #endif /* FC_DUAL */ ) font->min_width = font->average_width = font->space_width - = (scalable ? ft_face->max_advance_width * size / upEM + = (scalable ? ft_face->max_advance_width * size / upEM + 0.5 : ft_face->size->metrics.max_advance >> 6); else { @@ -1285,8 +1281,10 @@ ftfont_open2 (struct frame *f, font->vertical_centering = 0; if (scalable) { - font->underline_position = -ft_face->underline_position * size / upEM; - font->underline_thickness = ft_face->underline_thickness * size / upEM; + font->underline_position = (-ft_face->underline_position * size / upEM + + 0.5); + font->underline_thickness = (ft_face->underline_thickness * size / upEM + + 0.5); } else { @@ -1313,6 +1311,10 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) static void ftfont_close (struct font *font) { + /* FIXME: Although this function can be called while garbage-collecting, + the function assumes that Lisp data structures are properly-formed. + This invalid assumption can lead to core dumps (Bug#20890). */ + struct ftfont_info *ftfont_info = (struct ftfont_info *) font; Lisp_Object val, cache; @@ -1568,21 +1570,33 @@ struct MFLTFontFT FT_Matrix *matrix; }; +/* The actual type of elements in the array MFLTGlyphString.glyphs. + We use this structure instead of MFLTGlyph to utilize the new + feature of libotf ver.0.9.15 which requires saving and restoring + the value of OTF_GlyphString.positioning_type in the succeeding + calls of the callback function MFLTFont.drive_otf (which is set to + ftfont_drive_otf). */ + +typedef struct { + MFLTGlyph g; + unsigned int libotf_positioning_type; +} MFLTGlyphFT; + static int ftfont_get_glyph_id (MFLTFont *font, MFLTGlyphString *gstring, int from, int to) { struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font; FT_Face ft_face = flt_font_ft->ft_face; - MFLTGlyph *g; + MFLTGlyphFT *g; - for (g = gstring->glyphs + from; from < to; g++, from++) - if (! g->encoded) + for (g = (MFLTGlyphFT *) (gstring->glyphs) + from; from < to; g++, from++) + if (! g->g.encoded) { - FT_UInt code = FT_Get_Char_Index (ft_face, g->code); + FT_UInt code = FT_Get_Char_Index (ft_face, g->g.code); - g->code = code > 0 ? code : FONT_INVALID_CODE; - g->encoded = 1; + g->g.code = code > 0 ? code : FONT_INVALID_CODE; + g->g.encoded = 1; } return 0; } @@ -1599,16 +1613,16 @@ ftfont_get_metrics (MFLTFont *font, MFLTGlyphString *gstring, { struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font; FT_Face ft_face = flt_font_ft->ft_face; - MFLTGlyph *g; + MFLTGlyphFT *g; - for (g = gstring->glyphs + from; from < to; g++, from++) - if (! g->measured) + for (g = (MFLTGlyphFT *) (gstring->glyphs) + from; from < to; g++, from++) + if (! g->g.measured) { - if (g->code != FONT_INVALID_CODE) + if (g->g.code != FONT_INVALID_CODE) { FT_Glyph_Metrics *m; - if (FT_Load_Glyph (ft_face, g->code, FT_LOAD_DEFAULT) != 0) + if (FT_Load_Glyph (ft_face, g->g.code, FT_LOAD_DEFAULT) != 0) emacs_abort (); m = &ft_face->glyph->metrics; if (flt_font_ft->matrix) @@ -1622,29 +1636,29 @@ ftfont_get_metrics (MFLTFont *font, MFLTGlyphString *gstring, v[1].y = v[3].y = m->horiBearingY - m->height; for (i = 0; i < 4; i++) FT_Vector_Transform (v + i, flt_font_ft->matrix); - g->lbearing = v[0].x < v[1].x ? FLOOR (v[0].x) : FLOOR (v[1].x); - g->rbearing = v[2].x > v[3].x ? CEIL (v[2].x) : CEIL (v[3].x); - g->ascent = v[0].y > v[2].y ? CEIL (v[0].y) : CEIL (v[2].y); - g->descent = v[1].y < v[3].y ? - FLOOR (v[1].y) : - FLOOR (v[3].y); + g->g.lbearing = v[0].x < v[1].x ? FLOOR (v[0].x) : FLOOR (v[1].x); + g->g.rbearing = v[2].x > v[3].x ? CEIL (v[2].x) : CEIL (v[3].x); + g->g.ascent = v[0].y > v[2].y ? CEIL (v[0].y) : CEIL (v[2].y); + g->g.descent = v[1].y < v[3].y ? - FLOOR (v[1].y) : - FLOOR (v[3].y); } else { - g->lbearing = FLOOR (m->horiBearingX); - g->rbearing = CEIL (m->horiBearingX + m->width); - g->ascent = CEIL (m->horiBearingY); - g->descent = - FLOOR (m->horiBearingY - m->height); + g->g.lbearing = FLOOR (m->horiBearingX); + g->g.rbearing = CEIL (m->horiBearingX + m->width); + g->g.ascent = CEIL (m->horiBearingY); + g->g.descent = - FLOOR (m->horiBearingY - m->height); } - g->xadv = ROUND (ft_face->glyph->advance.x); + g->g.xadv = ROUND (ft_face->glyph->advance.x); } else { - g->lbearing = 0; - g->rbearing = g->xadv = flt_font_ft->font->space_width << 6; - g->ascent = flt_font_ft->font->ascent << 6; - g->descent = flt_font_ft->font->descent << 6; + g->g.lbearing = 0; + g->g.rbearing = g->g.xadv = flt_font_ft->font->space_width << 6; + g->g.ascent = flt_font_ft->font->ascent << 6; + g->g.descent = flt_font_ft->font->descent << 6; } - g->yadv = 0; - g->measured = 1; + g->g.yadv = 0; + g->g.measured = 1; } return 0; } @@ -1795,6 +1809,8 @@ ftfont_drive_otf (MFLTFont *font, MFLTGlyphAdjustment *adjustment) { struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font; + MFLTGlyphFT *in_glyphs = (MFLTGlyphFT *) (in->glyphs) + from; + MFLTGlyphFT *out_glyphs = out ? (MFLTGlyphFT *) (out->glyphs) : NULL; FT_Face ft_face = flt_font_ft->ft_face; OTF *otf = flt_font_ft->otf; int len = to - from; @@ -1846,8 +1862,11 @@ ftfont_drive_otf (MFLTFont *font, setup_otf_gstring (len); for (i = 0; i < len; i++) { - otf_gstring.glyphs[i].c = in->glyphs[from + i].c & 0x11FFFF; - otf_gstring.glyphs[i].glyph_id = in->glyphs[from + i].code; + otf_gstring.glyphs[i].c = in_glyphs[i].g.c & 0x11FFFF; + otf_gstring.glyphs[i].glyph_id = in_glyphs[i].g.code; +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + otf_gstring.glyphs[i].positioning_type = in_glyphs[i].libotf_positioning_type; +#endif } OTF_drive_gdef (otf, &otf_gstring); @@ -1855,9 +1874,15 @@ ftfont_drive_otf (MFLTFont *font, if (gsub_features && out) { +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + if (OTF_drive_gsub_features (otf, &otf_gstring, script, langsys, + gsub_features) < 0) + goto simple_copy; +#else if (OTF_drive_gsub_with_log (otf, &otf_gstring, script, langsys, gsub_features) < 0) goto simple_copy; +#endif if (out->allocated < out->used + otf_gstring.used) { SAFE_FREE (); @@ -1866,60 +1891,76 @@ ftfont_drive_otf (MFLTFont *font, features = otf->gsub->FeatureList.Feature; for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) { - MFLTGlyph *g; + MFLTGlyphFT *g; int min_from, max_to; - int feature_idx = otfg->positioning_type >> 4; + int feature_idx; - g = out->glyphs + out->used; - *g = in->glyphs[from + otfg->f.index.from]; - if (g->code != otfg->glyph_id) +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + feature_idx = OTF_POSITIONING_TYPE_GET_FEATURE (otfg); +#else + feature_idx = otfg->positioning_type >> 4; +#endif + g = out_glyphs + out->used; + *g = in_glyphs[otfg->f.index.from]; + if (g->g.code != otfg->glyph_id) { - g->c = 0; - g->code = otfg->glyph_id; - g->measured = 0; + g->g.c = 0; + g->g.code = otfg->glyph_id; + g->g.measured = 0; } out->used++; - min_from = g->from; - max_to = g->to; + min_from = g->g.from; + max_to = g->g.to; if (otfg->f.index.from < otfg->f.index.to) { /* OTFG substitutes multiple glyphs in IN. */ - for (j = from + otfg->f.index.from + 1; - j <= from + otfg->f.index.to; j++) + for (j = otfg->f.index.from + 1; j <= otfg->f.index.to; j++) { - if (min_from > in->glyphs[j].from) - min_from = in->glyphs[j].from; - if (max_to < in->glyphs[j].to) - max_to = in->glyphs[j].to; + if (min_from > in_glyphs[j].g.from) + min_from = in_glyphs[j].g.from; + if (max_to < in_glyphs[j].g.to) + max_to = in_glyphs[j].g.to; } - g->from = min_from; - g->to = max_to; + g->g.from = min_from; + g->g.to = max_to; } if (feature_idx) { unsigned int tag = features[feature_idx - 1].FeatureTag; tag = PACK_OTF_TAG (tag); - g->internal = (g->internal & ~0x1FFFFFFF) | tag; + g->g.internal = (g->g.internal & ~0x1FFFFFFF) | tag; } +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + g->libotf_positioning_type + = otfg->positioning_type & OTF_positioning_type_components_mask; +#endif for (i++, otfg++; (i < otf_gstring.used && otfg->f.index.from == otfg[-1].f.index.from); i++, otfg++) { - g = out->glyphs + out->used; - *g = in->glyphs[from + otfg->f.index.to]; - if (g->code != otfg->glyph_id) + g = out_glyphs + out->used; + *g = in_glyphs[otfg->f.index.to]; + if (g->g.code != otfg->glyph_id) { - g->c = 0; - g->code = otfg->glyph_id; - g->measured = 0; + g->g.c = 0; + g->g.code = otfg->glyph_id; + g->g.measured = 0; } +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + feature_idx = OTF_POSITIONING_TYPE_GET_FEATURE (otfg); +#else feature_idx = otfg->positioning_type >> 4; +#endif if (feature_idx) { unsigned int tag = features[feature_idx - 1].FeatureTag; tag = PACK_OTF_TAG (tag); - g->internal = (g->internal & ~0x1FFFFFFF) | tag; + g->g.internal = (g->g.internal & ~0x1FFFFFFF) | tag; } +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + g->libotf_positioning_type + = otfg->positioning_type & OTF_positioning_type_components_mask; +#endif out->used++; } } @@ -1927,23 +1968,33 @@ ftfont_drive_otf (MFLTFont *font, else if (gsub_features) { /* Just for checking which features will be applied. */ +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + if (OTF_drive_gsub_features (otf, &otf_gstring, script, langsys, + gsub_features) < 0) + goto simple_copy; +#else if (OTF_drive_gsub_with_log (otf, &otf_gstring, script, langsys, gsub_features) < 0) goto simple_copy; +#endif features = otf->gsub->FeatureList.Feature; for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; i++, otfg++) { - int feature_idx = otfg->positioning_type >> 4; - + int feature_idx; +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + feature_idx = OTF_POSITIONING_TYPE_GET_FEATURE (otfg); +#else + feature_idx = otfg->positioning_type >> 4; +#endif if (feature_idx) { unsigned int tag = features[feature_idx - 1].FeatureTag; tag = PACK_OTF_TAG (tag); for (j = otfg->f.index.from; j <= otfg->f.index.to; j++) { - MFLTGlyph *g = in->glyphs + (from + j); - g->internal = (g->internal & ~0x1FFFFFFF) | tag; + MFLTGlyphFT *g = in_glyphs + j; + g->g.internal = (g->g.internal & ~0x1FFFFFFF) | tag; } } } @@ -1956,42 +2007,61 @@ ftfont_drive_otf (MFLTFont *font, return -2; } for (i = 0; i < len; i++) - out->glyphs[out->used++] = in->glyphs[from + i]; + out_glyphs[out->used++] = in_glyphs[i]; } if (gpos_features && out) { - MFLTGlyph *base = NULL, *mark = NULL, *g; + MFLTGlyphFT *base = NULL, *mark = NULL, *g; int x_ppem, y_ppem, x_scale, y_scale; +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + if (OTF_drive_gpos_features (otf, &otf_gstring, script, langsys, + gpos_features) < 0) + { + SAFE_FREE (); + return to; + } +#else if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, gpos_features) < 0) { SAFE_FREE (); return to; } +#endif features = otf->gpos->FeatureList.Feature; x_ppem = ft_face->size->metrics.x_ppem; y_ppem = ft_face->size->metrics.y_ppem; x_scale = ft_face->size->metrics.x_scale; y_scale = ft_face->size->metrics.y_scale; - for (i = 0, otfg = otf_gstring.glyphs, g = out->glyphs + gidx; - i < otf_gstring.used; i++, otfg++, g++) + for (i = 0, otfg = otf_gstring.glyphs, g = out_glyphs + gidx; + i < otf_gstring.used; i++, otfg++) { - MFLTGlyph *prev; - int feature_idx = otfg->positioning_type >> 4; + MFLTGlyphAdjustment *adjust = adjustment; + MFLTGlyphFT *prev; + int positioning_type, feature_idx; +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + positioning_type = OTF_POSITIONING_TYPE_GET_FORMAT (otfg); + feature_idx = OTF_POSITIONING_TYPE_GET_FEATURE (otfg); +#else + positioning_type = otfg->positioning_type & 0xF; + feature_idx = otfg->positioning_type >> 4; +#endif if (feature_idx) { unsigned int tag = features[feature_idx - 1].FeatureTag; tag = PACK_OTF_TAG (tag); - g->internal = (g->internal & ~0x1FFFFFFF) | tag; + g->g.internal = (g->g.internal & ~0x1FFFFFFF) | tag; } if (! otfg->glyph_id) - continue; - switch (otfg->positioning_type & 0xF) + /* This is a pseudo glyph that contains positioning + information to be accumulated to a real glyph. */ + adjust--; + switch (positioning_type) { case 0: break; @@ -2001,30 +2071,30 @@ ftfont_drive_otf (MFLTFont *font, int format = otfg->f.f1.format; if (format & OTF_XPlacement) - adjustment[i].xoff + adjust->xoff = otfg->f.f1.value->XPlacement * x_scale / 0x10000; if (format & OTF_XPlaDevice) - adjustment[i].xoff + adjust->xoff += DEVICE_DELTA (otfg->f.f1.value->XPlaDevice, x_ppem); if (format & OTF_YPlacement) - adjustment[i].yoff + adjust->yoff = - (otfg->f.f1.value->YPlacement * y_scale / 0x10000); if (format & OTF_YPlaDevice) - adjustment[i].yoff + adjust->yoff -= DEVICE_DELTA (otfg->f.f1.value->YPlaDevice, y_ppem); if (format & OTF_XAdvance) - adjustment[i].xadv + adjust->xadv += otfg->f.f1.value->XAdvance * x_scale / 0x10000; if (format & OTF_XAdvDevice) - adjustment[i].xadv + adjust->xadv += DEVICE_DELTA (otfg->f.f1.value->XAdvDevice, x_ppem); if (format & OTF_YAdvance) - adjustment[i].yadv + adjust->yadv += otfg->f.f1.value->YAdvance * y_scale / 0x10000; if (format & OTF_YAdvDevice) - adjustment[i].yadv + adjust->yadv += DEVICE_DELTA (otfg->f.f1.value->YAdvDevice, y_ppem); - adjustment[i].set = 1; + adjust->set = 1; } break; case 3: /* Cursive */ @@ -2040,6 +2110,18 @@ ftfont_drive_otf (MFLTFont *font, if (! mark) break; prev = mark; +#ifdef OTF_POSITIONING_TYPE_GET_FORMAT + { + int distance = OTF_POSITIONING_TYPE_GET_MARKDISTANCE (otfg); + + if (distance > 0) + { + prev = g - distance; + if (prev < out_glyphs) + prev = mark; + } + } +#endif label_adjust_anchor: { @@ -2052,39 +2134,43 @@ ftfont_drive_otf (MFLTFont *font, mark_y = otfg->f.f4.mark_anchor->YCoordinate * y_scale / 0x10000; if (otfg->f.f4.base_anchor->AnchorFormat != 1) - adjust_anchor (ft_face, otfg->f.f4.base_anchor, - prev->code, x_ppem, y_ppem, &base_x, &base_y); + adjust_anchor (ft_face, otfg->f.f4.base_anchor, prev->g.code, + x_ppem, y_ppem, &base_x, &base_y); if (otfg->f.f4.mark_anchor->AnchorFormat != 1) - adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->code, + adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->g.code, x_ppem, y_ppem, &mark_x, &mark_y); - adjustment[i].xoff = (base_x - mark_x); - adjustment[i].yoff = - (base_y - mark_y); - adjustment[i].back = (g - prev); - adjustment[i].xadv = 0; - adjustment[i].advance_is_absolute = 1; - adjustment[i].set = 1; - this_from = g->from; - this_to = g->to; + adjust->xoff = (base_x - mark_x); + adjust->yoff = - (base_y - mark_y); + adjust->back = (g - prev); + adjust->xadv = 0; + adjust->advance_is_absolute = 1; + adjust->set = 1; + this_from = g->g.from; + this_to = g->g.to; for (j = 0; prev + j < g; j++) { - if (this_from > prev[j].from) - this_from = prev[j].from; - if (this_to < prev[j].to) - this_to = prev[j].to; + if (this_from > prev[j].g.from) + this_from = prev[j].g.from; + if (this_to < prev[j].g.to) + this_to = prev[j].g.to; } for (; prev <= g; prev++) { - prev->from = this_from; - prev->to = this_to; + prev->g.from = this_from; + prev->g.to = this_to; } } } - if (otfg->GlyphClass == OTF_GlyphClass0) - base = mark = g; - else if (otfg->GlyphClass == OTF_GlyphClassMark) - mark = g; - else - base = g; + if (otfg->glyph_id) + { + if (otfg->GlyphClass == OTF_GlyphClass0) + base = mark = g; + else if (otfg->GlyphClass == OTF_GlyphClassMark) + mark = g; + else + base = g; + g++, adjustment++; + } } } else if (gpos_features) @@ -2108,8 +2194,8 @@ ftfont_drive_otf (MFLTFont *font, tag = PACK_OTF_TAG (tag); for (j = otfg->f.index.from; j <= otfg->f.index.to; j++) { - MFLTGlyph *g = in->glyphs + (from + j); - g->internal = (g->internal & ~0x1FFFFFFF) | tag; + MFLTGlyphFT *g = in_glyphs + j; + g->g.internal = (g->g.internal & ~0x1FFFFFFF) | tag; } } } @@ -2124,8 +2210,7 @@ ftfont_drive_otf (MFLTFont *font, if (out->allocated < out->used + len) return -2; font->get_metrics (font, in, from, to); - memcpy (out->glyphs + out->used, in->glyphs + from, - sizeof (MFLTGlyph) * len); + memcpy (out->glyphs + out->used, in_glyphs, sizeof (MFLTGlyphFT) * len); out->used += len; return to; } @@ -2145,6 +2230,8 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, MFLTGlyphString *out, MFLTGlyphAdjustment *adjustment) { struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font; + MFLTGlyphFT *in_glyphs = (MFLTGlyphFT *) (in->glyphs) + from; + MFLTGlyphFT *out_glyphs = out ? (MFLTGlyphFT *) (out->glyphs) : NULL; FT_Face ft_face = flt_font_ft->ft_face; OTF *otf = flt_font_ft->otf; int len = to - from; @@ -2195,8 +2282,8 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, setup_otf_gstring (len); for (i = 0; i < len; i++) { - otf_gstring.glyphs[i].c = in->glyphs[from + i].c; - otf_gstring.glyphs[i].glyph_id = in->glyphs[from + i].code; + otf_gstring.glyphs[i].c = in_glyphs[i].g.c; + otf_gstring.glyphs[i].glyph_id = in_glyphs[i].g.code; } OTF_drive_gdef (otf, &otf_gstring); @@ -2214,21 +2301,21 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, } for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) { - MFLTGlyph *g; + MFLTGlyphFT *g; int min_from, max_to; int j; - g = out->glyphs + out->used; - *g = in->glyphs[from + otfg->f.index.from]; - if (g->code != otfg->glyph_id) + g = out_glyphs + out->used; + *g = in_glyphs[otfg->f.index.from]; + if (g->g.code != otfg->glyph_id) { - g->c = 0; - g->code = otfg->glyph_id; - g->measured = 0; + g->g.c = 0; + g->g.code = otfg->glyph_id; + g->g.measured = 0; } out->used++; - min_from = g->from; - max_to = g->to; + min_from = g->g.from; + max_to = g->g.to; if (otfg->f.index.from < otfg->f.index.to) { /* OTFG substitutes multiple glyphs in IN. */ @@ -2240,20 +2327,20 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, if (max_to < in->glyphs[j].to) max_to = in->glyphs[j].to; } - g->from = min_from; - g->to = max_to; + g->g.from = min_from; + g->g.to = max_to; } for (i++, otfg++; (i < otf_gstring.used && otfg->f.index.from == otfg[-1].f.index.from); i++, otfg++) { - g = out->glyphs + out->used; - *g = in->glyphs[from + otfg->f.index.to]; - if (g->code != otfg->glyph_id) + g = out_glyphs + out->used; + *g = in_glyphs[otfg->f.index.to]; + if (g->g.code != otfg->glyph_id) { - g->c = 0; - g->code = otfg->glyph_id; - g->measured = 0; + g->g.c = 0; + g->g.code = otfg->glyph_id; + g->g.measured = 0; } out->used++; } @@ -2267,12 +2354,12 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, return -2; } for (i = 0; i < len; i++) - out->glyphs[out->used++] = in->glyphs[from + i]; + out_glyphs[out->used++] = in_glyphs[i]; } if (gpos_features) { - MFLTGlyph *base = NULL, *mark = NULL, *g; + MFLTGlyphFT *base = NULL, *mark = NULL, *g; int x_ppem, y_ppem, x_scale, y_scale; if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features) @@ -2287,10 +2374,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, x_scale = ft_face->size->metrics.x_scale; y_scale = ft_face->size->metrics.y_scale; - for (i = 0, otfg = otf_gstring.glyphs, g = out->glyphs + gidx; + for (i = 0, otfg = otf_gstring.glyphs, g = out_glyphs + gidx; i < otf_gstring.used; i++, otfg++, g++) { - MFLTGlyph *prev; + MFLTGlyphFT *prev; if (! otfg->glyph_id) continue; @@ -2355,10 +2442,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, mark_y = otfg->f.f4.mark_anchor->YCoordinate * y_scale / 0x10000; if (otfg->f.f4.base_anchor->AnchorFormat != 1) - adjust_anchor (ft_face, otfg->f.f4.base_anchor, - prev->code, x_ppem, y_ppem, &base_x, &base_y); + adjust_anchor (ft_face, otfg->f.f4.base_anchor, prev->g.code, + x_ppem, y_ppem, &base_x, &base_y); if (otfg->f.f4.mark_anchor->AnchorFormat != 1) - adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->code, + adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->g.code, x_ppem, y_ppem, &mark_x, &mark_y); adjustment[i].xoff = (base_x - mark_x); adjustment[i].yoff = - (base_y - mark_y); @@ -2366,19 +2453,19 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, adjustment[i].xadv = 0; adjustment[i].advance_is_absolute = 1; adjustment[i].set = 1; - this_from = g->from; - this_to = g->to; + this_from = g->g.from; + this_to = g->g.to; for (j = 0; prev + j < g; j++) { - if (this_from > prev[j].from) - this_from = prev[j].from; - if (this_to < prev[j].to) - this_to = prev[j].to; + if (this_from > prev[j].g.from) + this_from = prev[j].g.from; + if (this_to < prev[j].g.to) + this_to = prev[j].g.to; } for (; prev <= g; prev++) { - prev->from = this_from; - prev->to = this_to; + prev->g.from = this_from; + prev->g.to = this_to; } } } @@ -2398,8 +2485,8 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, if (out->allocated < out->used + len) return -2; font->get_metrics (font, in, from, to); - memcpy (out->glyphs + out->used, in->glyphs + from, - sizeof (MFLTGlyph) * len); + memcpy (out_glyphs + out->used, in_glyphs, + sizeof (MFLTGlyphFT) * len); out->used += len; return to; } @@ -2419,6 +2506,7 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, struct MFLTFontFT flt_font_ft; MFLT *flt = NULL; bool with_variation_selector = 0; + MFLTGlyphFT *glyphs; if (! m17n_flt_initialized) { @@ -2473,31 +2561,33 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, } } - if (INT_MAX / 2 < len) + int len2; + if (INT_MULTIPLY_WRAPV (len, 2, &len2)) memory_full (SIZE_MAX); if (gstring.allocated == 0) { - gstring.glyph_size = sizeof (MFLTGlyph); - gstring.glyphs = xnmalloc (len * 2, sizeof *gstring.glyphs); - gstring.allocated = len * 2; + gstring.glyph_size = sizeof (MFLTGlyphFT); + gstring.glyphs = xnmalloc (len2, sizeof (MFLTGlyphFT)); + gstring.allocated = len2; } - else if (gstring.allocated < len * 2) + else if (gstring.allocated < len2) { - gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, - sizeof *gstring.glyphs); - gstring.allocated = len * 2; + gstring.glyphs = xnrealloc (gstring.glyphs, len2, + sizeof (MFLTGlyphFT)); + gstring.allocated = len2; } - memset (gstring.glyphs, 0, len * sizeof *gstring.glyphs); + glyphs = (MFLTGlyphFT *) (gstring.glyphs); + memset (glyphs, 0, len * sizeof (MFLTGlyphFT)); for (i = 0; i < len; i++) { Lisp_Object g = LGSTRING_GLYPH (lgstring, i); - gstring.glyphs[i].c = LGLYPH_CHAR (g); + glyphs[i].g.c = LGLYPH_CHAR (g); if (with_variation_selector) { - gstring.glyphs[i].code = LGLYPH_CODE (g); - gstring.glyphs[i].encoded = 1; + glyphs[i].g.code = LGLYPH_CODE (g); + glyphs[i].g.encoded = 1; } } @@ -2535,48 +2625,49 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt); if (result != -2) break; - if (INT_MAX / 2 < gstring.allocated) + int len2; + if (INT_MULTIPLY_WRAPV (gstring.allocated, 2, &len2)) memory_full (SIZE_MAX); gstring.glyphs = xnrealloc (gstring.glyphs, - gstring.allocated, 2 * sizeof (MFLTGlyph)); - gstring.allocated *= 2; + gstring.allocated, 2 * sizeof (MFLTGlyphFT)); + gstring.allocated = len2; } if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) return Qnil; for (i = 0; i < gstring.used; i++) { - MFLTGlyph *g = gstring.glyphs + i; + MFLTGlyphFT *g = (MFLTGlyphFT *) (gstring.glyphs) + i; - g->from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->from)); - g->to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->to)); + g->g.from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->g.from)); + g->g.to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->g.to)); } for (i = 0; i < gstring.used; i++) { Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i); - MFLTGlyph *g = gstring.glyphs + i; + MFLTGlyphFT *g = (MFLTGlyphFT *) (gstring.glyphs) + i; if (NILP (lglyph)) { lglyph = LGLYPH_NEW (); LGSTRING_SET_GLYPH (lgstring, i, lglyph); } - LGLYPH_SET_FROM (lglyph, g->from); - LGLYPH_SET_TO (lglyph, g->to); - LGLYPH_SET_CHAR (lglyph, g->c); - LGLYPH_SET_CODE (lglyph, g->code); - LGLYPH_SET_WIDTH (lglyph, g->xadv >> 6); - LGLYPH_SET_LBEARING (lglyph, g->lbearing >> 6); - LGLYPH_SET_RBEARING (lglyph, g->rbearing >> 6); - LGLYPH_SET_ASCENT (lglyph, g->ascent >> 6); - LGLYPH_SET_DESCENT (lglyph, g->descent >> 6); - if (g->adjusted) + LGLYPH_SET_FROM (lglyph, g->g.from); + LGLYPH_SET_TO (lglyph, g->g.to); + LGLYPH_SET_CHAR (lglyph, g->g.c); + LGLYPH_SET_CODE (lglyph, g->g.code); + LGLYPH_SET_WIDTH (lglyph, g->g.xadv >> 6); + LGLYPH_SET_LBEARING (lglyph, g->g.lbearing >> 6); + LGLYPH_SET_RBEARING (lglyph, g->g.rbearing >> 6); + LGLYPH_SET_ASCENT (lglyph, g->g.ascent >> 6); + LGLYPH_SET_DESCENT (lglyph, g->g.descent >> 6); + if (g->g.adjusted) { Lisp_Object vec = make_uninit_vector (3); - ASET (vec, 0, make_number (g->xoff >> 6)); - ASET (vec, 1, make_number (g->yoff >> 6)); - ASET (vec, 2, make_number (g->xadv >> 6)); + ASET (vec, 0, make_number (g->g.xoff >> 6)); + ASET (vec, 1, make_number (g->g.yoff >> 6)); + ASET (vec, 2, make_number (g->g.xadv >> 6)); LGLYPH_SET_ADJUSTMENT (lglyph, vec); } } @@ -2674,7 +2765,6 @@ syms_of_ftfont (void) /* Fontconfig's generic families and their aliases. */ DEFSYM (Qmonospace, "monospace"); DEFSYM (Qsans_serif, "sans-serif"); - DEFSYM (Qserif, "serif"); DEFSYM (Qsans, "sans"); DEFSYM (Qsans__serif, "sans serif");