X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/84eb0351d8be4811897c8cf62a69757ff5d14001..70c60eb2f9e5120f609ba5b6f2d82eef26d21c15:/src/ftfont.c diff --git a/src/ftfont.c b/src/ftfont.c index db6b29421d..7858a31be2 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -39,7 +39,7 @@ along with GNU Emacs. If not, see . */ #include "ftfont.h" /* Symbolic type of this font-driver. */ -Lisp_Object Qfreetype; +static Lisp_Object Qfreetype; /* Fontconfig's generic families and their aliases. */ static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif; @@ -160,19 +160,21 @@ static struct static Lisp_Object get_adstyle_property (FcPattern *p) { + FcChar8 *fcstr; char *str, *end; Lisp_Object adstyle; - if (FcPatternGetString (p, FC_STYLE, 0, (FcChar8 **) &str) != FcResultMatch) + if (FcPatternGetString (p, FC_STYLE, 0, &fcstr) != FcResultMatch) return Qnil; + str = (char *) fcstr; for (end = str; *end && *end != ' '; end++); if (*end) { - char *p = alloca (end - str + 1); - memcpy (p, str, end - str); - p[end - str] = '\0'; - end = p + (end - str); - str = p; + char *newstr = alloca (end - str + 1); + memcpy (newstr, str, end - str); + newstr[end - str] = '\0'; + end = newstr + (end - str); + str = newstr; } if (xstrcasecmp (str, "Regular") == 0 || xstrcasecmp (str, "Bold") == 0 @@ -189,19 +191,20 @@ static Lisp_Object ftfont_pattern_entity (FcPattern *p, Lisp_Object extra) { Lisp_Object key, cache, entity; - char *file, *str; - int index; + FcChar8 *str; + char *file; + int idx; int numeric; double dbl; FcBool b; - if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch) + if (FcPatternGetString (p, FC_FILE, 0, &str) != FcResultMatch) return Qnil; - if (FcPatternGetInteger (p, FC_INDEX, 0, &index) != FcResultMatch) + if (FcPatternGetInteger (p, FC_INDEX, 0, &idx) != FcResultMatch) return Qnil; - key = Fcons (make_unibyte_string ((char *) file, strlen ((char *) file)), - make_number (index)); + file = (char *) str; + key = Fcons (make_unibyte_string (file, strlen (file)), make_number (idx)); cache = ftfont_lookup_cache (key, FTFONT_CACHE_FOR_ENTITY); entity = XCAR (cache); if (! NILP (entity)) @@ -211,6 +214,10 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra) for (i = 0; i < FONT_OBJLIST_INDEX; i++) ASET (val, i, AREF (entity, i)); + + ASET (val, FONT_EXTRA_INDEX, Fcopy_sequence (extra)); + font_put_extra (val, QCfont_entity, key); + return val; } entity = font_make_entity (); @@ -219,10 +226,16 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra) ASET (entity, FONT_TYPE_INDEX, Qfreetype); ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); - if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) - ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str), 1)); - if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) - ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str), 1)); + if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) + { + char *s = (char *) str; + ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (s, strlen (s), 1)); + } + if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) + { + char *s = (char *) str; + ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (s, strlen (s), 1)); + } if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) { if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM) @@ -265,7 +278,7 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra) ASET (entity, FONT_ADSTYLE_INDEX, get_adstyle_property (p)); if ((ft_library || FT_Init_FreeType (&ft_library) == 0) - && FT_New_Face (ft_library, file, index, &ft_face) == 0) + && FT_New_Face (ft_library, file, idx, &ft_face) == 0) { BDF_PropertyRec rec; @@ -311,8 +324,9 @@ ftfont_resolve_generic_family (Lisp_Object family, FcPattern *pattern) if (FcPatternGetLangSet (pattern, FC_LANG, 0, &langset) != FcResultMatch) { /* This is to avoid the effect of locale. */ + static const FcChar8 lang[] = "en"; langset = FcLangSetCreate (); - FcLangSetAdd (langset, "en"); + FcLangSetAdd (langset, lang); FcPatternAddLangSet (pattern, FC_LANG, langset); FcLangSetDestroy (langset); } @@ -393,14 +407,14 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for) ? ! cache_data->ft_face : ! cache_data->fc_charset) { char *filename = SSDATA (XCAR (key)); - int index = XINT (XCDR (key)); + int idx = XINT (XCDR (key)); if (cache_for == FTFONT_CACHE_FOR_FACE) { if (! ft_library && FT_Init_FreeType (&ft_library) != 0) return Qnil; - if (FT_New_Face (ft_library, filename, index, &cache_data->ft_face) + if (FT_New_Face (ft_library, filename, idx, &cache_data->ft_face) != 0) return Qnil; } @@ -412,7 +426,7 @@ ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for) FcCharSet *charset = NULL; pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename, - FC_INDEX, FcTypeInteger, index, NULL); + FC_INDEX, FcTypeInteger, idx, NULL); if (! pat) goto finish; objset = FcObjectSetBuild (FC_CHARSET, FC_STYLE, NULL); @@ -490,8 +504,12 @@ static int ftfont_get_bitmap (struct font *, unsigned, struct font_bitmap *, int); static int ftfont_anchor_point (struct font *, unsigned, int, int *, int *); +#ifdef HAVE_LIBOTF static Lisp_Object ftfont_otf_capability (struct font *); +# ifdef HAVE_M17N_FLT static Lisp_Object ftfont_shape (Lisp_Object); +# endif +#endif #ifdef HAVE_OTF_GET_VARIATION_GLYPHS static int ftfont_variation_glyphs (struct font *, int c, @@ -618,6 +636,7 @@ struct OpenTypeSpec (P)[4] = '\0'; \ } while (0) +#ifdef HAVE_LIBOTF #define OTF_TAG_SYM(SYM, TAG) \ do { \ char str[5]; \ @@ -625,6 +644,7 @@ struct OpenTypeSpec OTF_TAG_STR (TAG, str); \ (SYM) = font_intern_prop (str, 4, 1); \ } while (0) +#endif static struct OpenTypeSpec * @@ -666,7 +686,10 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec) if (NILP (val)) continue; len = Flength (val); - spec->features[i] = malloc (sizeof (int) * XINT (len)); + spec->features[i] = + (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len) + ? 0 + : malloc (sizeof (int) * XINT (len))); if (! spec->features[i]) { if (i > 0 && spec->features[0]) @@ -799,7 +822,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots goto err; for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars)) if (CHARACTERP (XCAR (chars)) - && ! FcCharSetAddChar (charset, XUINT (XCAR (chars)))) + && ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars)))) goto err; } } @@ -864,7 +887,6 @@ ftfont_list (Lisp_Object frame, Lisp_Object spec) FcObjectSet *objset = NULL; FcCharSet *charset; Lisp_Object chars = Qnil; - FcResult result; char otlayout[15]; /* For "otlayout:XXXX" */ struct OpenTypeSpec *otspec = NULL; int spacing = -1; @@ -1153,7 +1175,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) FT_Face ft_face; FT_Size ft_size; FT_UInt size; - Lisp_Object val, filename, index, cache, font_object; + Lisp_Object val, filename, idx, cache, font_object; int scalable; int spacing; char name[256]; @@ -1168,7 +1190,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) if (NILP (cache)) return Qnil; filename = XCAR (val); - index = XCDR (val); + idx = XCDR (val); val = XCDR (cache); cache_data = XSAVE_VALUE (XCDR (cache))->pointer; ft_face = cache_data->ft_face; @@ -1210,7 +1232,7 @@ ftfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size) font = XFONT_OBJECT (font_object); ftfont_info = (struct ftfont_info *) font; ftfont_info->ft_size = ft_face->size; - ftfont_info->index = XINT (index); + ftfont_info->index = XINT (idx); #ifdef HAVE_LIBOTF ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; ftfont_info->otf = NULL; @@ -1455,7 +1477,8 @@ ftfont_get_bitmap (struct font *font, unsigned int code, struct font_bitmap *bit } static int -ftfont_anchor_point (struct font *font, unsigned int code, int index, int *x, int *y) +ftfont_anchor_point (struct font *font, unsigned int code, int idx, + int *x, int *y) { struct ftfont_info *ftfont_info = (struct ftfont_info *) font; FT_Face ft_face = ftfont_info->ft_size->face; @@ -1466,10 +1489,10 @@ ftfont_anchor_point (struct font *font, unsigned int code, int index, int *x, in return -1; if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) return -1; - if (index >= ft_face->glyph->outline.n_points) + if (idx >= ft_face->glyph->outline.n_points) return -1; - *x = ft_face->glyph->outline.points[index].x; - *y = ft_face->glyph->outline.points[index].y; + *x = ft_face->glyph->outline.points[idx].x; + *y = ft_face->glyph->outline.points[idx].y; return 0; } @@ -1596,7 +1619,6 @@ ftfont_get_metrics (MFLTFont *font, MFLTGlyphString *gstring, if (g->code != FONT_INVALID_CODE) { FT_Glyph_Metrics *m; - int lbearing, rbearing, ascent, descent, xadv; if (FT_Load_Glyph (ft_face, g->code, FT_LOAD_DEFAULT) != 0) abort (); @@ -1746,15 +1768,10 @@ static OTF_GlyphString otf_gstring; static void setup_otf_gstring (int size) { - if (otf_gstring.size == 0) - { - otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size); - otf_gstring.size = size; - } - else if (otf_gstring.size < size) + if (otf_gstring.size < size) { - otf_gstring.glyphs = xrealloc (otf_gstring.glyphs, - sizeof (OTF_Glyph) * size); + otf_gstring.glyphs = xnrealloc (otf_gstring.glyphs, + size, sizeof (OTF_Glyph)); otf_gstring.size = size; } otf_gstring.used = size; @@ -1851,7 +1868,6 @@ ftfont_drive_otf (MFLTFont *font, { MFLTGlyph *g; int min_from, max_to; - int j; int feature_idx = otfg->positioning_type >> 4; g = out->glyphs + out->used; @@ -2371,8 +2387,8 @@ static Lisp_Object ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, FT_Face ft_face, OTF *otf, FT_Matrix *matrix) { - EMACS_UINT len = LGSTRING_GLYPH_LEN (lgstring); - EMACS_UINT i; + EMACS_INT len = LGSTRING_GLYPH_LEN (lgstring); + EMACS_INT i; struct MFLTFontFT flt_font_ft; MFLT *flt = NULL; int with_variation_selector = 0; @@ -2398,7 +2414,10 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, if (CHAR_VARIATION_SELECTOR_P (c)) with_variation_selector++; } + len = i; + lint_assume (len <= TYPE_MAXIMUM (EMACS_INT) - 2); + if (with_variation_selector) { setup_otf_gstring (len); @@ -2428,17 +2447,19 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, } } + if (INT_MAX / 2 < len) + memory_full (SIZE_MAX); + if (gstring.allocated == 0) { - gstring.allocated = len * 2; gstring.glyph_size = sizeof (MFLTGlyph); - gstring.glyphs = xmalloc (sizeof (MFLTGlyph) * gstring.allocated); + gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyph)); + gstring.allocated = len * 2; } else if (gstring.allocated < len * 2) { + gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, sizeof (MFLTGlyph)); gstring.allocated = len * 2; - gstring.glyphs = xrealloc (gstring.glyphs, - sizeof (MFLTGlyph) * gstring.allocated); } memset (gstring.glyphs, 0, sizeof (MFLTGlyph) * len); for (i = 0; i < len; i++) @@ -2487,9 +2508,11 @@ 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; - gstring.allocated += gstring.allocated; - gstring.glyphs = xrealloc (gstring.glyphs, - sizeof (MFLTGlyph) * gstring.allocated); + if (INT_MAX / 2 < gstring.allocated) + memory_full (SIZE_MAX); + gstring.glyphs = xnrealloc (gstring.glyphs, + gstring.allocated, 2 * sizeof (MFLTGlyph)); + gstring.allocated *= 2; } if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) return Qnil;