#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <libgen.h>
#include "fcint.h"
#include <ft2build.h>
#include FT_FREETYPE_H
{ 20, (const FcChar8 *) "zh-tw" },
};
-#define NUM_CODE_PAGE_RANGE (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
+#define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
FcBool
FcFreeTypeIsExclusiveLang (const FcChar8 *lang)
}
typedef struct {
- FT_UShort platform_id;
- FT_UShort encoding_id;
- char *fromcode;
+ const FT_UShort platform_id;
+ const FT_UShort encoding_id;
+ const char fromcode[12];
} FcFtEncoding;
#define TT_ENCODING_DONT_CARE 0xffff
{ TT_PLATFORM_ISO, TT_ISO_ID_8859_1, "ISO-8859-1" },
};
-#define NUM_FC_FT_ENCODING (sizeof (fcFtEncoding) / sizeof (fcFtEncoding[0]))
+#define NUM_FC_FT_ENCODING (int) (sizeof (fcFtEncoding) / sizeof (fcFtEncoding[0]))
typedef struct {
- FT_UShort platform_id;
- FT_UShort language_id;
- char *lang;
+ const FT_UShort platform_id;
+ const FT_UShort language_id;
+ const char lang[8];
} FcFtLanguage;
#define TT_LANGUAGE_DONT_CARE 0xffff
static const FcFtLanguage fcFtLanguage[] = {
- { TT_PLATFORM_APPLE_UNICODE, TT_LANGUAGE_DONT_CARE, 0 },
+ { TT_PLATFORM_APPLE_UNICODE, TT_LANGUAGE_DONT_CARE, "" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_ENGLISH, "en" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_FRENCH, "fr" },
{ TT_PLATFORM_MACINTOSH, TT_MAC_LANGID_GERMAN, "de" },
{ TT_PLATFORM_MICROSOFT, TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES,"pap" },
};
-#define NUM_FC_FT_LANGUAGE (sizeof (fcFtLanguage) / sizeof (fcFtLanguage[0]))
+#define NUM_FC_FT_LANGUAGE (int) (sizeof (fcFtLanguage) / sizeof (fcFtLanguage[0]))
typedef struct {
FT_UShort language_id;
- char *fromcode;
+ char fromcode[12];
} FcMacRomanFake;
static const FcMacRomanFake fcMacRomanFake[] = {
static FcChar8 *
FcFontCapabilities(FT_Face face);
-#define NUM_FC_MAC_ROMAN_FAKE (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
+#define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
#if HAVE_ICONV && HAVE_ICONV_H
#define USE_ICONV 1
static FcChar8 *
FcSfntNameTranscode (FT_SfntName *sname)
{
- int i;
- char *fromcode;
+ int i;
+ const char *fromcode;
#if USE_ICONV
iconv_t cd;
#endif
{
int f;
- fromcode = 0;
+ fromcode = NULL;
for (f = 0; f < NUM_FC_MAC_ROMAN_FAKE; f++)
if (fcMacRomanFake[f].language_id == sname->language_id)
{
if (!fromcode)
return 0;
}
-#if USE_ICONV
- cd = iconv_open ("UTF-8", fromcode);
- if (cd)
- {
- size_t in_bytes_left = sname->string_len;
- size_t out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN;
- char *inbuf, *outbuf;
-
- utf8 = malloc (out_bytes_left + 1);
- if (!utf8)
- return 0;
-
- outbuf = (char *) utf8;
- inbuf = (char *) sname->string;
-
- while (in_bytes_left)
- {
- size_t did = iconv (cd,
- &inbuf, &in_bytes_left,
- &outbuf, &out_bytes_left);
- if (did == (size_t) (-1))
- {
- free (utf8);
- return 0;
- }
- }
- *outbuf = '\0';
- goto done;
- }
-#endif
if (!strcmp (fromcode, "UCS-2BE") || !strcmp (fromcode, "UTF-16BE"))
{
FcChar8 *src = sname->string;
*u8 = '\0';
goto done;
}
+#if USE_ICONV
+ cd = iconv_open ("UTF-8", fromcode);
+ if (cd && cd != (iconv_t) (-1))
+ {
+ size_t in_bytes_left = sname->string_len;
+ size_t out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN;
+ char *inbuf, *outbuf;
+
+ utf8 = malloc (out_bytes_left + 1);
+ if (!utf8)
+ {
+ iconv_close (cd);
+ return 0;
+ }
+
+ outbuf = (char *) utf8;
+ inbuf = (char *) sname->string;
+
+ while (in_bytes_left)
+ {
+ size_t did = iconv (cd,
+ &inbuf, &in_bytes_left,
+ &outbuf, &out_bytes_left);
+ if (did == (size_t) (-1))
+ {
+ iconv_close (cd);
+ free (utf8);
+ return 0;
+ }
+ }
+ iconv_close (cd);
+ *outbuf = '\0';
+ goto done;
+ }
+#endif
return 0;
done:
- if (FcStrCmpIgnoreBlanksAndCase (utf8, "") == 0)
+ if (FcStrCmpIgnoreBlanksAndCase (utf8, (FcChar8 *) "") == 0)
{
free (utf8);
return 0;
return utf8;
}
-static FcChar8 *
+static const FcChar8 *
FcSfntNameLanguage (FT_SfntName *sname)
{
int i;
if (fcFtLanguage[i].platform_id == sname->platform_id &&
(fcFtLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
fcFtLanguage[i].language_id == sname->language_id))
- return fcFtLanguage[i].lang;
+ {
+ if (fcFtLanguage[i].lang[0] == '\0')
+ return NULL;
+ else
+ return (FcChar8 *) fcFtLanguage[i].lang;
+ }
return 0;
}
(const FcChar8 *) "hanyang" }
};
-#define NUM_NOTICE_FOUNDRIES (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
+#define NUM_NOTICE_FOUNDRIES (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
static const FcChar8 *
FcNoticeFoundry(const FT_String *notice)
/* vendor is not necessarily NUL-terminated. */
int i, len;
- len = strlen(vendor_string);
+ len = strlen((char *) vendor_string);
if (memcmp(vendor, vendor_string, len) != 0)
return FcFalse;
for (i = len; i < 4; i++)
{ (const FT_Char *) "Y&Y", (const FcChar8 *) "y&y"}
};
-#define NUM_VENDOR_FOUNDRIES (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
+#define NUM_VENDOR_FOUNDRIES (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
static const FcChar8 *
FcVendorFoundry(const FT_Char vendor[4])
return -1;
}
+typedef FcChar8 *FC8;
+
static const FcStringConst weightConsts[] = {
- { "thin", FC_WEIGHT_THIN },
- { "extralight", FC_WEIGHT_EXTRALIGHT },
- { "ultralight", FC_WEIGHT_ULTRALIGHT },
- { "light", FC_WEIGHT_LIGHT },
- { "book", FC_WEIGHT_BOOK },
- { "regular", FC_WEIGHT_REGULAR },
- { "normal", FC_WEIGHT_NORMAL },
- { "medium", FC_WEIGHT_MEDIUM },
- { "demibold", FC_WEIGHT_DEMIBOLD },
- { "demi", FC_WEIGHT_DEMIBOLD },
- { "semibold", FC_WEIGHT_SEMIBOLD },
- { "bold", FC_WEIGHT_BOLD },
- { "extrabold", FC_WEIGHT_EXTRABOLD },
- { "ultrabold", FC_WEIGHT_ULTRABOLD },
- { "black", FC_WEIGHT_BLACK },
- { "heavy", FC_WEIGHT_HEAVY },
+ { (FC8) "thin", FC_WEIGHT_THIN },
+ { (FC8) "extralight", FC_WEIGHT_EXTRALIGHT },
+ { (FC8) "ultralight", FC_WEIGHT_ULTRALIGHT },
+ { (FC8) "light", FC_WEIGHT_LIGHT },
+ { (FC8) "book", FC_WEIGHT_BOOK },
+ { (FC8) "regular", FC_WEIGHT_REGULAR },
+ { (FC8) "normal", FC_WEIGHT_NORMAL },
+ { (FC8) "medium", FC_WEIGHT_MEDIUM },
+ { (FC8) "demibold", FC_WEIGHT_DEMIBOLD },
+ { (FC8) "demi", FC_WEIGHT_DEMIBOLD },
+ { (FC8) "semibold", FC_WEIGHT_SEMIBOLD },
+ { (FC8) "bold", FC_WEIGHT_BOLD },
+ { (FC8) "extrabold", FC_WEIGHT_EXTRABOLD },
+ { (FC8) "ultrabold", FC_WEIGHT_ULTRABOLD },
+ { (FC8) "black", FC_WEIGHT_BLACK },
+ { (FC8) "heavy", FC_WEIGHT_HEAVY },
};
-#define NUM_WEIGHT_CONSTS (sizeof (weightConsts) / sizeof (weightConsts[0]))
+#define NUM_WEIGHT_CONSTS (int) (sizeof (weightConsts) / sizeof (weightConsts[0]))
#define FcIsWeight(s) FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
#define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
static const FcStringConst widthConsts[] = {
- { "ultracondensed", FC_WIDTH_ULTRACONDENSED },
- { "extracondensed", FC_WIDTH_EXTRACONDENSED },
- { "semicondensed", FC_WIDTH_SEMICONDENSED },
- { "condensed", FC_WIDTH_CONDENSED }, /* must be after *condensed */
- { "normal", FC_WIDTH_NORMAL },
- { "semiexpanded", FC_WIDTH_SEMIEXPANDED },
- { "extraexpanded", FC_WIDTH_EXTRAEXPANDED },
- { "ultraexpanded", FC_WIDTH_ULTRAEXPANDED },
- { "expanded", FC_WIDTH_EXPANDED }, /* must be after *expanded */
+ { (FC8) "ultracondensed", FC_WIDTH_ULTRACONDENSED },
+ { (FC8) "extracondensed", FC_WIDTH_EXTRACONDENSED },
+ { (FC8) "semicondensed", FC_WIDTH_SEMICONDENSED },
+ { (FC8) "condensed", FC_WIDTH_CONDENSED }, /* must be after *condensed */
+ { (FC8) "normal", FC_WIDTH_NORMAL },
+ { (FC8) "semiexpanded", FC_WIDTH_SEMIEXPANDED },
+ { (FC8) "extraexpanded", FC_WIDTH_EXTRAEXPANDED },
+ { (FC8) "ultraexpanded", FC_WIDTH_ULTRAEXPANDED },
+ { (FC8) "expanded", FC_WIDTH_EXPANDED }, /* must be after *expanded */
};
-#define NUM_WIDTH_CONSTS (sizeof (widthConsts) / sizeof (widthConsts[0]))
+#define NUM_WIDTH_CONSTS (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
#define FcIsWidth(s) FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
#define FcContainsWidth(s) FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
static const FcStringConst slantConsts[] = {
- { "italic", FC_SLANT_ITALIC },
- { "oblique", FC_SLANT_OBLIQUE },
+ { (FC8) "italic", FC_SLANT_ITALIC },
+ { (FC8) "oblique", FC_SLANT_OBLIQUE },
};
-#define NUM_SLANT_CONSTS (sizeof (slantConsts) / sizeof (slantConsts[0]))
+#define NUM_SLANT_CONSTS (int) (sizeof (slantConsts) / sizeof (slantConsts[0]))
#define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
#define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
}
static FcBool
-FcStringInPatternElement (FcPattern *pat, char *elt, FcChar8 *string)
+FcStringInPatternElement (FcPattern *pat, const char *elt, FcChar8 *string)
{
int e;
FcChar8 *old;
for (snamei = 0; snamei < snamec; snamei++)
{
FcChar8 *utf8;
- FcChar8 *lang;
- char *elt = 0, *eltlang = 0;
+ const FcChar8 *lang;
+ const char *elt = 0, *eltlang = 0;
int *np = 0, *nlangp = 0;
if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
/* pad lang list with 'xx' to line up with elt */
while (*nlangp < *np)
{
- if (!FcPatternAddString (pat, eltlang, "xx"))
+ if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
goto bail1;
++*nlangp;
}
}
if (!nfamily && face->family_name &&
- FcStrCmpIgnoreBlanksAndCase (face->family_name, "") != 0)
+ FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->family_name, (FcChar8 *) "") != 0)
{
if (FcDebug () & FC_DBG_SCANV)
printf ("using FreeType family \"%s\"\n", face->family_name);
- if (!FcPatternAddString (pat, FC_FAMILY, face->family_name))
+ if (!FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) face->family_name))
goto bail1;
++nfamily;
}
if (!nstyle && face->style_name &&
- FcStrCmpIgnoreBlanksAndCase (face->style_name, "") != 0)
+ FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->style_name, (FcChar8 *) "") != 0)
{
if (FcDebug () & FC_DBG_SCANV)
printf ("using FreeType style \"%s\"\n", face->style_name);
- if (!FcPatternAddString (pat, FC_STYLE, face->style_name))
+ if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name))
goto bail1;
++nstyle;
}
printf ("Saving unique fullname %s\n", full);
}
- if (!FcPatternAddString (pat, FC_FILE, file))
+ if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)FcStrCopy(file))))
goto bail1;
+ FcPatternAddFullFname (pat, (const char *)file);
+
if (!FcPatternAddInteger (pat, FC_INDEX, id))
goto bail1;
{
if (weight == -1 && psfontinfo.weight)
{
- weight = FcIsWeight (psfontinfo.weight);
+ weight = FcIsWeight ((FcChar8 *) psfontinfo.weight);
if (FcDebug() & FC_DBG_SCANV)
printf ("\tType1 weight %s maps to %d\n",
psfontinfo.weight, weight);
BDF_PropertyRec prop;
rc = MY_Get_BDF_Property(face, "FOUNDRY", &prop);
if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM)
- foundry = prop.u.atom;
+ foundry = (FcChar8 *) prop.u.atom;
}
if (width == -1)
MY_Get_BDF_Property (face, "SETWIDTH_NAME", &prop) == 0 &&
prop.type == BDF_PROPERTY_TYPE_ATOM)
{
- width = FcIsWidth (prop.u.atom);
+ width = FcIsWidth ((FcChar8 *) prop.u.atom);
if (FcDebug () & FC_DBG_SCANV)
printf ("\tsetwidth %s maps to %d\n", prop.u.atom, width);
}
width = FC_WIDTH_NORMAL;
if (foundry == 0)
- foundry = "unknown";
+ foundry = (FcChar8 *) "unknown";
if (!FcPatternAddInteger (pat, FC_SLANT, slant))
goto bail1;
{
const char *font_format = FT_Get_X11_Font_Format (face);
if (font_format)
- FcPatternAddString (pat, FC_FONTFORMAT, font_format);
+ FcPatternAddString (pat, FC_FONTFORMAT, (FcChar8 *) font_format);
}
#endif
{ ft_encoding_apple_roman, &AppleRoman, (1 << 16) - 1 },
};
-#define NUM_DECODE (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
+#define NUM_DECODE (int) (sizeof (fcFontDecoders) / sizeof (fcFontDecoders[0]))
+
+static const FcChar32 prefer_unicode[] = {
+ 0x20ac, /* EURO SIGN */
+};
+
+#define NUM_PREFER_UNICODE (int) (sizeof (prefer_unicode) / sizeof (prefer_unicode[0]))
FcChar32
FcFreeTypeUcs4ToPrivate (FcChar32 ucs4, const FcCharMap *map)
return FcFalse;
}
-static FcChar8 *
+static const FcChar8 *
FcUcs4ToGlyphName (FcChar32 ucs4)
{
int i = (int) (ucs4 % FC_GLYPHNAME_HASH);
int r = 0;
- FcGlyphName *gn;
+ const FcGlyphName *gn;
while ((gn = ucs_to_name[i]))
{
FcChar32 h = FcHashGlyphName (name);
int i = (int) (h % FC_GLYPHNAME_HASH);
int r = 0;
- FcGlyphName *gn;
+ const FcGlyphName *gn;
while ((gn = name_to_ucs[i]))
{
* any defined order within the font
*/
static FT_UInt
-FcFreeTypeGlyphNameIndex (FT_Face face, FcChar8 *name)
+FcFreeTypeGlyphNameIndex (FT_Face face, const FcChar8 *name)
{
FT_UInt gindex;
FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
- for (gindex = 0; gindex < face->num_glyphs; gindex++)
+ for (gindex = 0; gindex < (FT_UInt) face->num_glyphs; gindex++)
{
if (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
if (!strcmp ((char *) name, (char *) name_buf))
int initial, offset, decode;
FT_UInt glyphindex;
FcChar32 charcode;
+ int p;
initial = 0;
/*
if (initial == NUM_DECODE)
initial = 0;
}
+ for (p = 0; p < NUM_PREFER_UNICODE; p++)
+ if (ucs4 == prefer_unicode[p])
+ {
+ initial = 0;
+ break;
+ }
/*
* Check each encoding for the glyph, starting with the current one
*/
if (fcFontDecoders[decode].map)
{
charcode = FcFreeTypeUcs4ToPrivate (ucs4, fcFontDecoders[decode].map);
- if (charcode == ~0)
+ if (charcode == ~0U)
continue;
}
else
*/
if (FcFreeTypeUseNames (face))
{
- FcChar8 *name = FcUcs4ToGlyphName (ucs4);
+ const FcChar8 *name = FcUcs4ToGlyphName (ucs4);
if (name)
{
glyphindex = FcFreeTypeGlyphNameIndex (face, name);
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
FT_GlyphSlot slot;
- /*
- * For bitmap-only fonts, assume that they're OK.
- */
- if ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
- return FcTrue;
-
/*
* When using scalable fonts, only report those glyphs
* which can be scaled; otherwise those fonts will
if (glyph &&
FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
{
- if (!has_advance)
+ /*
+ * ignore glyphs with zero advance. They’re
+ * combining characters, and while their behaviour
+ * isn’t well defined for monospaced applications in
+ * Unicode, there are many fonts which include
+ * zero-width combining characters in otherwise
+ * monospaced fonts.
+ */
+ if (advance)
{
- has_advance = FcTrue;
- advance_one = advance;
+ if (!has_advance)
+ {
+ has_advance = FcTrue;
+ advance_one = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
}
- else if (!APPROXIMATELY_EQUAL (advance, advance_one))
- {
- if (fixed_advance)
- {
- dual_advance = FcTrue;
- fixed_advance = FcFalse;
- advance_two = advance;
- }
- else if (!APPROXIMATELY_EQUAL (advance, advance_two))
- dual_advance = FcFalse;
- }
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf)
if (glyph && FcFreeTypeCheckGlyph (face, ucs4,
glyph, blanks, &advance))
{
- if (!has_advance)
+ if (advance)
{
- has_advance = FcTrue;
- advance_one = advance;
+ if (!has_advance)
+ {
+ has_advance = FcTrue;
+ advance_one = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
}
- else if (!APPROXIMATELY_EQUAL (advance, advance_one))
- {
- if (fixed_advance)
- {
- dual_advance = FcTrue;
- fixed_advance = FcFalse;
- advance_two = advance;
- }
- else if (!APPROXIMATELY_EQUAL (advance, advance_two))
- dual_advance = FcFalse;
- }
if (!leaf)
{
{
FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
- for (glyph = 0; glyph < face->num_glyphs; glyph++)
+ for (glyph = 0; glyph < (FT_UInt) face->num_glyphs; glyph++)
{
if (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
{
if (ucs4 != 0xffff &&
FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
{
- if (!has_advance)
+ if (advance)
{
- has_advance = FcTrue;
- advance_one = advance;
+ if (!has_advance)
+ {
+ has_advance = FcTrue;
+ advance_one = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
+ {
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
+ }
}
- else if (!APPROXIMATELY_EQUAL (advance, advance_one))
- {
- if (fixed_advance)
- {
- dual_advance = FcTrue;
- fixed_advance = FcFalse;
- advance_two = advance;
- }
- else if (!APPROXIMATELY_EQUAL (advance, advance_two))
- dual_advance = FcFalse;
- }
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf)
goto bail1;
#define TTO_Err_Empty_Script 0x1005
#define TTO_Err_Invalid_SubTable 0x1001
+#define OTLAYOUT_HEAD "otlayout:"
+#define OTLAYOUT_HEAD_LEN 9
+#define OTLAYOUT_ID_LEN 4
+/* space + head + id */
+#define OTLAYOUT_LEN (1 + OTLAYOUT_HEAD_LEN + OTLAYOUT_ID_LEN)
+/*
+ * This is a bit generous; the registry has only lower case and space
+ * except for 'DFLT'.
+ */
+#define FcIsSpace(x) (040 == (x))
+#define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsSpace(x))
+
static void
addtag(FcChar8 *complex, FT_ULong tag)
{
- FcChar8 tagstring[15];
- sprintf (tagstring, "otlayout:%c%c%c%c ",
- (unsigned char)(tag >> 24),
- (unsigned char)((tag & 0xff0000) >> 16),
- (unsigned char)((tag & 0xff00) >> 8),
- (unsigned char)(tag & 0xff));
- strncat(complex, tagstring, 14);
+ FcChar8 tagstring[OTLAYOUT_ID_LEN + 1];
+
+ tagstring[0] = (FcChar8)(tag >> 24),
+ tagstring[1] = (FcChar8)(tag >> 16),
+ tagstring[2] = (FcChar8)(tag >> 8),
+ tagstring[3] = (FcChar8)(tag);
+ tagstring[4] = '\0';
+
+ /* skip tags which aren't alphabetic, under the assumption that
+ * they're probably broken
+ */
+ if (!FcIsValidScript(tagstring[0]) ||
+ !FcIsValidScript(tagstring[1]) ||
+ !FcIsValidScript(tagstring[2]) ||
+ !FcIsValidScript(tagstring[3]))
+ return;
+
+ if (*complex != '\0')
+ strcat ((char *) complex, " ");
+ strcat ((char *) complex, "otlayout:");
+ strcat ((char *) complex, (char *) tagstring);
}
static int
return TT_Err_Ok;
Fail:
+ *script_count = 0;
FT_FREE( *stags );
return error;
}
FT_Error err;
FT_ULong len = 0;
FT_ULong *gsubtags=NULL, *gpostags=NULL;
- FT_UShort gsub_count=0, gpos_count=0, maxsize;
+ FT_UShort gsub_count=0, gpos_count=0;
+ FT_ULong maxsize;
FT_Memory memory = face->stream->memory;
FcChar8 *complex = NULL;
int indx1 = 0, indx2 = 0;
err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
issilgraphitefont = ( err == FT_Err_Ok);
- err = GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count);
- err = GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count);
+ if (GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count) != FT_Err_Ok)
+ gpos_count = 0;
+ if (GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count) != FT_Err_Ok)
+ gsub_count = 0;
+
if (!issilgraphitefont && !gsub_count && !gpos_count)
- {
goto bail;
- }
- maxsize = ((gpos_count + gsub_count) * 15) + (issilgraphitefont ? 13 : 0);
+ maxsize = (((FT_ULong) gpos_count + (FT_ULong) gsub_count) * OTLAYOUT_LEN +
+ (issilgraphitefont ? 13 : 0));
complex = malloc (sizeof (FcChar8) * maxsize);
+ if (!complex)
+ goto bail;
+
+ complex[0] = '\0';
if (issilgraphitefont)
- {
- strcpy(complex, "ttable:Silf ");
- }
- else
- {
- strcpy(complex, "");
- }
+ strcpy((char *) complex, "ttable:Silf ");
while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
if (indx1 == gsub_count) {