/*
- * $RCSId: xc/lib/fontconfig/src/fcfreetype.c,v 1.11 2002/08/31 22:17:32 keithp Exp $
+ * fontconfig/src/fcfreetype.c
*
* Copyright © 2001 Keith Packard
*
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
THE SOFTWARE.
*/
+#include "fcint.h"
+#include "fcftint.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <libgen.h>
-#include "fcint.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
#include "ftglue.h"
+#if HAVE_WARNING_CPP_DIRECTIVE
#if !HAVE_FT_GET_BDF_PROPERTY
#warning "No FT_Get_BDF_Property: Please install freetype 2.1.4 or later"
#endif
#if !HAVE_FT_GET_PS_FONT_INFO
#warning "No FT_Get_PS_Font_Info: Please install freetype 2.1.1 or later"
#endif
+#endif
/*
* Keep Han languages separated by eliminating languages
*/
static const struct {
- int bit;
- const FcChar8 *lang;
+ char bit;
+ const FcChar8 lang[6];
} FcCodePageRange[] = {
- { 17, (const FcChar8 *) "ja" },
- { 18, (const FcChar8 *) "zh-cn" },
- { 19, (const FcChar8 *) "ko" },
- { 20, (const FcChar8 *) "zh-tw" },
+ { 17, "ja" },
+ { 18, "zh-cn" },
+ { 19, "ko" },
+ { 20, "zh-tw" },
};
#define NUM_CODE_PAGE_RANGE (int) (sizeof FcCodePageRange / sizeof FcCodePageRange[0])
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_JAPANESE, "SJIS" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, "UTF-16BE" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, "SJIS-WIN" },
- { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, "GB3212" },
+ { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, "GB2312" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, "BIG-5" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, "Wansung" },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, "Johab" },
- { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, "UCS4" },
+ { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, "UCS-2BE" },
{ TT_PLATFORM_ISO, TT_ISO_ID_7BIT_ASCII, "ASCII" },
{ TT_PLATFORM_ISO, TT_ISO_ID_10646, "UCS-2BE" },
{ TT_PLATFORM_ISO, TT_ISO_ID_8859_1, "ISO-8859-1" },
#define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
-#if HAVE_ICONV && HAVE_ICONV_H
-#define USE_ICONV 1
+#if USE_ICONV
#include <iconv.h>
#endif
+/*
+ * A shift-JIS will have many high bits turned on
+ */
+static FcBool
+FcLooksLikeSJIS (FcChar8 *string, int len)
+{
+ int nhigh = 0, nlow = 0;
+
+ while (len-- > 0)
+ {
+ if (*string++ & 0x80) nhigh++;
+ else nlow++;
+ }
+ /*
+ * Heuristic -- if more than 1/3 of the bytes have the high-bit set,
+ * this is likely to be SJIS and not ROMAN
+ */
+ if (nhigh * 2 > nlow)
+ return FcTrue;
+ return FcFalse;
+}
+
static FcChar8 *
FcSfntNameTranscode (FT_SfntName *sname)
{
fromcode = fcFtEncoding[i].fromcode;
/*
- * "real" Mac language IDs are all less than 150.
- * Names using one of the MS language IDs are assumed
- * to use an associated encoding (Yes, this is a kludge)
+ * Many names encoded for TT_PLATFORM_MACINTOSH are broken
+ * in various ways. Kludge around them.
*/
- if (!strcmp (fromcode, FC_ENCODING_MAC_ROMAN) &&
- sname->language_id >= 0x100)
+ if (!strcmp (fromcode, FC_ENCODING_MAC_ROMAN))
{
- int f;
+ if (sname->language_id == TT_MAC_LANGID_ENGLISH &&
+ FcLooksLikeSJIS (sname->string, sname->string_len))
+ {
+ fromcode = "SJIS";
+ }
+ else if (sname->language_id >= 0x100)
+ {
+ /*
+ * "real" Mac language IDs are all less than 150.
+ * Names using one of the MS language IDs are assumed
+ * to use an associated encoding (Yes, this is a kludge)
+ */
+ int f;
- fromcode = NULL;
- for (f = 0; f < NUM_FC_MAC_ROMAN_FAKE; f++)
- if (fcMacRomanFake[f].language_id == sname->language_id)
- {
- fromcode = fcMacRomanFake[f].fromcode;
- break;
- }
- if (!fromcode)
- return 0;
+ fromcode = NULL;
+ for (f = 0; f < NUM_FC_MAC_ROMAN_FAKE; f++)
+ if (fcMacRomanFake[f].language_id == sname->language_id)
+ {
+ fromcode = fcMacRomanFake[f].fromcode;
+ break;
+ }
+ if (!fromcode)
+ return 0;
+ }
}
if (!strcmp (fromcode, "UCS-2BE") || !strcmp (fromcode, "UTF-16BE"))
{
FcSfntNameLanguage (FT_SfntName *sname)
{
int i;
+ FT_UShort platform_id = sname->platform_id;
+ FT_UShort language_id = sname->language_id;
+
+ /*
+ * Many names encoded for TT_PLATFORM_MACINTOSH are broken
+ * in various ways. Kludge around them.
+ */
+ if (platform_id == TT_PLATFORM_MACINTOSH &&
+ sname->encoding_id == TT_MAC_ID_ROMAN &&
+ FcLooksLikeSJIS (sname->string, sname->string_len))
+ {
+ language_id = TT_MAC_LANGID_JAPANESE;
+ }
+
for (i = 0; i < NUM_FC_FT_LANGUAGE; i++)
- if (fcFtLanguage[i].platform_id == sname->platform_id &&
+ if (fcFtLanguage[i].platform_id == platform_id &&
(fcFtLanguage[i].language_id == TT_LANGUAGE_DONT_CARE ||
- fcFtLanguage[i].language_id == sname->language_id))
+ fcFtLanguage[i].language_id == language_id))
{
if (fcFtLanguage[i].lang[0] == '\0')
return NULL;
/* Order is significant. For example, some B&H fonts are hinted by
URW++, and both strings appear in the notice. */
-static const struct {
- const FT_String *notice;
- const FcChar8 *foundry;
-} FcNoticeFoundries[] = {
- { (const FT_String *) "Bigelow", (const FcChar8 *) "b&h" },
- { (const FT_String *) "Adobe", (const FcChar8 *) "adobe" },
- { (const FT_String *) "Bitstream", (const FcChar8 *) "bitstream" },
- { (const FT_String *) "Monotype", (const FcChar8 *) "monotype" },
- { (const FT_String *) "Linotype", (const FcChar8 *) "linotype" },
- { (const FT_String *) "LINOTYPE-HELL",
- (const FcChar8 *) "linotype" },
- { (const FT_String *) "IBM", (const FcChar8 *) "ibm" },
- { (const FT_String *) "URW", (const FcChar8 *) "urw" },
- { (const FT_String *) "International Typeface Corporation",
- (const FcChar8 *) "itc" },
- { (const FT_String *) "Tiro Typeworks",
- (const FcChar8 *) "tiro" },
- { (const FT_String *) "XFree86", (const FcChar8 *) "xfree86" },
- { (const FT_String *) "Microsoft", (const FcChar8 *) "microsoft" },
- { (const FT_String *) "Omega", (const FcChar8 *) "omega" },
- { (const FT_String *) "Font21", (const FcChar8 *) "hwan" },
- { (const FT_String *) "HanYang System",
- (const FcChar8 *) "hanyang" }
+static const char notice_foundry_data[] =
+ "Bigelow\0b&h\0"
+ "Adobe\0adobe\0"
+ "Bitstream\0bitstream\0"
+ "Monotype\0monotype\0"
+ "Linotype\0linotype\0"
+ "LINOTYPE-HELL\0linotype\0"
+ "IBM\0ibm\0"
+ "URW\0urw\0"
+ "International Typeface Corporation\0itc\0"
+ "Tiro Typeworks\0tiro\0"
+ "XFree86\0xfree86\0"
+ "Microsoft\0microsoft\0"
+ "Omega\0omega\0"
+ "Font21\0hwan\0"
+ "HanYang System\0hanyang";
+
+struct _notice_foundry {
+ /* these are the offsets into the
+ * notice_foundry_data array.
+ */
+ unsigned char notice_offset;
+ unsigned char foundry_offset;
+};
+
+static const struct _notice_foundry FcNoticeFoundries[] = {
+ { 0, 8 },
+ { 12, 18 },
+ { 24, 34 },
+ { 44, 53 },
+ { 62, 71 },
+ { 80, 94 },
+ { 103, 107 },
+ { 111, 115 },
+ { 119, 154 },
+ { 158, 173 },
+ { 178, 186 },
+ { 194, 204 },
+ { 214, 220 },
+ { 226, 233 },
+ { 238, 253 }
};
#define NUM_NOTICE_FOUNDRIES (int) (sizeof (FcNoticeFoundries) / sizeof (FcNoticeFoundries[0]))
if (notice)
for(i = 0; i < NUM_NOTICE_FOUNDRIES; i++)
- if (strstr ((const char *) notice, (const char *) FcNoticeFoundries[i].notice))
- return FcNoticeFoundries[i].foundry;
+ {
+ const struct _notice_foundry *nf = &FcNoticeFoundries[i];
+ const char *n = notice_foundry_data + nf->notice_offset;
+ const char *f = notice_foundry_data + nf->foundry_offset;
+
+ if (strstr ((const char *) notice, n))
+ return (const FcChar8 *) f;
+ }
return 0;
}
entries for padding both with spaces and NULs. */
static const struct {
- const FT_Char *vendor;
- const FcChar8 *foundry;
+ const FT_Char vendor[5];
+ const FcChar8 foundry[13];
} FcVendorFoundries[] = {
- { (const FT_Char *) "ADBE", (const FcChar8 *) "adobe"},
- { (const FT_Char *) "AGFA", (const FcChar8 *) "agfa"},
- { (const FT_Char *) "ALTS", (const FcChar8 *) "altsys"},
- { (const FT_Char *) "APPL", (const FcChar8 *) "apple"},
- { (const FT_Char *) "ARPH", (const FcChar8 *) "arphic"},
- { (const FT_Char *) "ATEC", (const FcChar8 *) "alltype"},
- { (const FT_Char *) "B&H", (const FcChar8 *) "b&h"},
- { (const FT_Char *) "BITS", (const FcChar8 *) "bitstream"},
- { (const FT_Char *) "CANO", (const FcChar8 *) "cannon"},
- { (const FT_Char *) "DYNA", (const FcChar8 *) "dynalab"},
- { (const FT_Char *) "EPSN", (const FcChar8 *) "epson"},
- { (const FT_Char *) "FJ", (const FcChar8 *) "fujitsu"},
- { (const FT_Char *) "IBM", (const FcChar8 *) "ibm"},
- { (const FT_Char *) "ITC", (const FcChar8 *) "itc"},
- { (const FT_Char *) "IMPR", (const FcChar8 *) "impress"},
- { (const FT_Char *) "LARA", (const FcChar8 *) "larabiefonts"},
- { (const FT_Char *) "LEAF", (const FcChar8 *) "interleaf"},
- { (const FT_Char *) "LETR", (const FcChar8 *) "letraset"},
- { (const FT_Char *) "LINO", (const FcChar8 *) "linotype"},
- { (const FT_Char *) "MACR", (const FcChar8 *) "macromedia"},
- { (const FT_Char *) "MONO", (const FcChar8 *) "monotype"},
- { (const FT_Char *) "MS", (const FcChar8 *) "microsoft"},
- { (const FT_Char *) "MT", (const FcChar8 *) "monotype"},
- { (const FT_Char *) "NEC", (const FcChar8 *) "nec"},
- { (const FT_Char *) "PARA", (const FcChar8 *) "paratype"},
- { (const FT_Char *) "QMSI", (const FcChar8 *) "qms"},
- { (const FT_Char *) "RICO", (const FcChar8 *) "ricoh"},
- { (const FT_Char *) "URW", (const FcChar8 *) "urw"},
- { (const FT_Char *) "Y&Y", (const FcChar8 *) "y&y"}
+ { "ADBE", "adobe"},
+ { "AGFA", "agfa"},
+ { "ALTS", "altsys"},
+ { "APPL", "apple"},
+ { "ARPH", "arphic"},
+ { "ATEC", "alltype"},
+ { "B&H", "b&h"},
+ { "BITS", "bitstream"},
+ { "CANO", "cannon"},
+ { "DYNA", "dynalab"},
+ { "EPSN", "epson"},
+ { "FJ", "fujitsu"},
+ { "IBM", "ibm"},
+ { "ITC", "itc"},
+ { "IMPR", "impress"},
+ { "LARA", "larabiefonts"},
+ { "LEAF", "interleaf"},
+ { "LETR", "letraset"},
+ { "LINO", "linotype"},
+ { "MACR", "macromedia"},
+ { "MONO", "monotype"},
+ { "MS", "microsoft"},
+ { "MT", "monotype"},
+ { "NEC", "nec"},
+ { "PARA", "paratype"},
+ { "QMSI", "qms"},
+ { "RICO", "ricoh"},
+ { "URW", "urw"},
+ { "Y&Y", "y&y"}
};
#define NUM_VENDOR_FOUNDRIES (int) (sizeof (FcVendorFoundries) / sizeof (FcVendorFoundries[0]))
int i;
for (i = 0; i < nc; i++)
- if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
- return c[i].value;
+ {
+ if (c[i].name[0] == '<')
+ {
+ if (FcStrContainsWord (string, c[i].name + 1))
+ return c[i].value;
+ }
+ else
+ {
+ if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
+ return c[i].value;
+ }
+ }
return -1;
}
{ (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) "superbold", FC_WEIGHT_EXTRABOLD },
{ (FC8) "ultrabold", FC_WEIGHT_ULTRABOLD },
+ { (FC8) "bold", FC_WEIGHT_BOLD },
+ { (FC8) "ultrablack", FC_WEIGHT_ULTRABLACK },
+ { (FC8) "superblack", FC_WEIGHT_EXTRABLACK },
+ { (FC8) "extrablack", FC_WEIGHT_EXTRABLACK },
+ { (FC8) "<ultra", FC_WEIGHT_ULTRABOLD }, /* only if a word */
{ (FC8) "black", FC_WEIGHT_BLACK },
{ (FC8) "heavy", FC_WEIGHT_HEAVY },
};
{ (FC8) "extraexpanded", FC_WIDTH_EXTRAEXPANDED },
{ (FC8) "ultraexpanded", FC_WIDTH_ULTRAEXPANDED },
{ (FC8) "expanded", FC_WIDTH_EXPANDED }, /* must be after *expanded */
+ { (FC8) "extended", FC_WIDTH_EXPANDED },
};
#define NUM_WIDTH_CONSTS (int) (sizeof (widthConsts) / sizeof (widthConsts[0]))
static const FcStringConst slantConsts[] = {
{ (FC8) "italic", FC_SLANT_ITALIC },
+ { (FC8) "kursiv", FC_SLANT_ITALIC },
{ (FC8) "oblique", FC_SLANT_OBLIQUE },
};
#define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
#define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
+static const FcStringConst decorativeConsts[] = {
+ { (FC8) "shadow", FcTrue },
+ { (FC8) "caps", FcTrue },
+ { (FC8) "antiqua", FcTrue },
+ { (FC8) "romansc", FcTrue },
+ { (FC8) "embosed", FcTrue },
+ { (FC8) "dunhill", FcTrue },
+};
+
+#define NUM_DECORATIVE_CONSTS (int) (sizeof (decorativeConsts) / sizeof (decorativeConsts[0]))
+
+#define FcIsDecorative(s) FcStringIsConst(s,decorativeConsts,NUM_DECORATIVE_CONSTS)
+#define FcContainsDecorative(s) FcStringContainsConst (s,decorativeConsts,NUM_DECORATIVE_CONSTS)
+
static double
FcGetPixelSize (FT_Face face, int i)
{
if (!FcStrCmpIgnoreBlanksAndCase (old, string))
{
return FcTrue;
- break;
}
return FcFalse;
}
+static const FT_UShort platform_order[] = {
+ TT_PLATFORM_MICROSOFT,
+ TT_PLATFORM_APPLE_UNICODE,
+ TT_PLATFORM_MACINTOSH,
+};
+#define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
+
+static const FT_UShort nameid_order[] = {
+#ifdef TT_NAME_ID_WWS_FAMILY
+ TT_NAME_ID_WWS_FAMILY,
+#endif
+ TT_NAME_ID_PREFERRED_FAMILY,
+ TT_NAME_ID_FONT_FAMILY,
+ TT_NAME_ID_MAC_FULL_NAME,
+ TT_NAME_ID_FULL_NAME,
+#ifdef TT_NAME_ID_WWS_SUBFAMILY
+ TT_NAME_ID_WWS_SUBFAMILY,
+#endif
+ TT_NAME_ID_PREFERRED_SUBFAMILY,
+ TT_NAME_ID_FONT_SUBFAMILY,
+ TT_NAME_ID_TRADEMARK,
+ TT_NAME_ID_MANUFACTURER,
+};
+
+#define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
FcPattern *
-FcFreeTypeQuery (const FcChar8 *file,
- int id,
- FcBlanks *blanks,
- int *count)
+FcFreeTypeQueryFace (const FT_Face face,
+ const FcChar8 *file,
+ int id,
+ FcBlanks *blanks)
{
- FT_Face face;
FcPattern *pat;
int slant = -1;
int weight = -1;
int width = -1;
+ FcBool decorative = FcFalse;
int i;
FcCharSet *cs;
FcLangSet *ls;
- FT_Library ftLibrary;
#if 0
FcChar8 *family = 0;
#endif
- FcChar8 *complex;
- FcChar8 *file2;
+ FcChar8 *complex_;
const FcChar8 *foundry = 0;
int spacing;
TT_OS2 *os2;
int nstyle_lang = 0;
int nfullname = 0;
int nfullname_lang = 0;
+ int p, platform;
+ int n, nameid;
FcChar8 *style = 0;
int st;
- if (FT_Init_FreeType (&ftLibrary))
- return 0;
-
- if (FT_New_Face (ftLibrary, (char *) file, id, &face))
- goto bail;
-
- *count = face->num_faces;
-
pat = FcPatternCreate ();
if (!pat)
goto bail0;
* of them
*/
snamec = FT_Get_Sfnt_Name_Count (face);
- for (snamei = 0; snamei < snamec; snamei++)
+ for (p = 0; p <= NUM_PLATFORM_ORDER; p++)
{
- FcChar8 *utf8;
- const FcChar8 *lang;
- const char *elt = 0, *eltlang = 0;
- int *np = 0, *nlangp = 0;
-
- if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
- continue;
-
- utf8 = FcSfntNameTranscode (&sname);
- lang = FcSfntNameLanguage (&sname);
+ if (p < NUM_PLATFORM_ORDER)
+ platform = platform_order[p];
+ else
+ platform = 0xffff;
- if (!utf8)
- continue;
-
- switch (sname.name_id) {
- case TT_NAME_ID_FONT_FAMILY:
-#if 0
- case TT_NAME_ID_PS_NAME:
- case TT_NAME_ID_UNIQUE_ID:
-#endif
- if (FcDebug () & FC_DBG_SCANV)
- printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
- sname.name_id, sname.platform_id,
- sname.encoding_id, sname.language_id,
- utf8);
-
- elt = FC_FAMILY;
- eltlang = FC_FAMILYLANG;
- np = &nfamily;
- nlangp = &nfamily_lang;
- break;
- case TT_NAME_ID_FULL_NAME:
- case TT_NAME_ID_MAC_FULL_NAME:
- if (FcDebug () & FC_DBG_SCANV)
- printf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
- sname.name_id, sname.platform_id,
- sname.encoding_id, sname.language_id,
- utf8);
-
- elt = FC_FULLNAME;
- eltlang = FC_FULLNAMELANG;
- np = &nfullname;
- nlangp = &nfullname_lang;
- break;
- case TT_NAME_ID_FONT_SUBFAMILY:
- if (FcDebug () & FC_DBG_SCANV)
- printf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
- sname.name_id, sname.platform_id,
- sname.encoding_id, sname.language_id,
- utf8);
-
- elt = FC_STYLE;
- eltlang = FC_STYLELANG;
- np = &nstyle;
- nlangp = &nstyle_lang;
- break;
- case TT_NAME_ID_TRADEMARK:
- case TT_NAME_ID_MANUFACTURER:
- /* If the foundry wasn't found in the OS/2 table, look here */
- if(!foundry)
- foundry = FcNoticeFoundry((FT_String *) utf8);
- break;
- }
- if (elt)
+ /*
+ * Order nameids so preferred names appear first
+ * in the resulting list
+ */
+ for (n = 0; n < NUM_NAMEID_ORDER; n++)
{
- if (FcStringInPatternElement (pat, elt, utf8))
- {
- free (utf8);
- continue;
- }
+ nameid = nameid_order[n];
- /* add new element */
- if (!FcPatternAddString (pat, elt, utf8))
- {
- free (utf8);
- goto bail1;
- }
- free (utf8);
- if (lang)
+ for (snamei = 0; snamei < snamec; snamei++)
{
- /* pad lang list with 'xx' to line up with elt */
- while (*nlangp < *np)
+ FcChar8 *utf8;
+ const FcChar8 *lang;
+ const char *elt = 0, *eltlang = 0;
+ int *np = 0, *nlangp = 0;
+
+ if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
+ continue;
+ if (sname.name_id != nameid)
+ continue;
+
+ /*
+ * Sort platforms in preference order, accepting
+ * all other platforms last
+ */
+ if (p < NUM_PLATFORM_ORDER)
{
- if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
+ if (sname.platform_id != platform)
+ continue;
+ }
+ else
+ {
+ int sp;
+
+ for (sp = 0; sp < NUM_PLATFORM_ORDER; sp++)
+ if (sname.platform_id == platform_order[sp])
+ break;
+ if (sp != NUM_PLATFORM_ORDER)
+ continue;
+ }
+ utf8 = FcSfntNameTranscode (&sname);
+ lang = FcSfntNameLanguage (&sname);
+
+ if (!utf8)
+ continue;
+
+ switch (sname.name_id) {
+#ifdef TT_NAME_ID_WWS_FAMILY
+ case TT_NAME_ID_WWS_FAMILY:
+#endif
+ case TT_NAME_ID_PREFERRED_FAMILY:
+ case TT_NAME_ID_FONT_FAMILY:
+#if 0
+ case TT_NAME_ID_PS_NAME:
+ case TT_NAME_ID_UNIQUE_ID:
+#endif
+ if (FcDebug () & FC_DBG_SCANV)
+ printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
+ sname.name_id, sname.platform_id,
+ sname.encoding_id, sname.language_id,
+ utf8);
+
+ elt = FC_FAMILY;
+ eltlang = FC_FAMILYLANG;
+ np = &nfamily;
+ nlangp = &nfamily_lang;
+ break;
+ case TT_NAME_ID_MAC_FULL_NAME:
+ case TT_NAME_ID_FULL_NAME:
+ if (FcDebug () & FC_DBG_SCANV)
+ printf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
+ sname.name_id, sname.platform_id,
+ sname.encoding_id, sname.language_id,
+ utf8);
+
+ elt = FC_FULLNAME;
+ eltlang = FC_FULLNAMELANG;
+ np = &nfullname;
+ nlangp = &nfullname_lang;
+ break;
+#ifdef TT_NAME_ID_WWS_SUBFAMILY
+ case TT_NAME_ID_WWS_SUBFAMILY:
+#endif
+ case TT_NAME_ID_PREFERRED_SUBFAMILY:
+ case TT_NAME_ID_FONT_SUBFAMILY:
+ if (FcDebug () & FC_DBG_SCANV)
+ printf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
+ sname.name_id, sname.platform_id,
+ sname.encoding_id, sname.language_id,
+ utf8);
+
+ elt = FC_STYLE;
+ eltlang = FC_STYLELANG;
+ np = &nstyle;
+ nlangp = &nstyle_lang;
+ break;
+ case TT_NAME_ID_TRADEMARK:
+ case TT_NAME_ID_MANUFACTURER:
+ /* If the foundry wasn't found in the OS/2 table, look here */
+ if(!foundry)
+ foundry = FcNoticeFoundry((FT_String *) utf8);
+ break;
+ }
+ if (elt)
+ {
+ if (FcStringInPatternElement (pat, elt, utf8))
+ {
+ free (utf8);
+ continue;
+ }
+
+ /* add new element */
+ if (!FcPatternAddString (pat, elt, utf8))
+ {
+ free (utf8);
goto bail1;
- ++*nlangp;
+ }
+ free (utf8);
+ if (lang)
+ {
+ /* pad lang list with 'xx' to line up with elt */
+ while (*nlangp < *np)
+ {
+ if (!FcPatternAddString (pat, eltlang, (FcChar8 *) "xx"))
+ goto bail1;
+ ++*nlangp;
+ }
+ if (!FcPatternAddString (pat, eltlang, lang))
+ goto bail1;
+ ++*nlangp;
+ }
+ ++*np;
}
- if (!FcPatternAddString (pat, eltlang, lang))
- goto bail1;
- ++*nlangp;
+ else
+ free (utf8);
}
- ++*np;
}
- else
- free (utf8);
}
-
+
if (!nfamily && face->family_name &&
FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->family_name, (FcChar8 *) "") != 0)
{
++nfamily;
}
- /*
- * Walk through FC_FULLNAME entries eliding those in FC_FAMILY
- * or which are simply a FC_FAMILY and FC_STYLE glued together
- */
- {
- int fn, fa, st;
- FcChar8 *full;
- FcChar8 *fam;
- FcChar8 *style;
-
- for (fn = 0; FcPatternGetString (pat, FC_FULLNAME, fn, &full) == FcResultMatch; fn++)
- {
- FcBool remove = FcFalse;
- /*
- * Check each family
- */
- for (fa = 0; !remove &&
- FcPatternGetString (pat, FC_FAMILY,
- fa, &fam) == FcResultMatch;
- fa++)
- {
- /*
- * for exact match
- */
- if (!FcStrCmpIgnoreBlanksAndCase (full, fam))
- {
- remove = FcTrue;
- break;
- }
- /*
- * If the family is in the full name, check the
- * combination of this family with every style
- */
- if (!FcStrContainsIgnoreBlanksAndCase (full, fam))
- continue;
- for (st = 0; !remove &&
- FcPatternGetString (pat, FC_STYLE,
- st, &style) == FcResultMatch;
- st++)
- {
- FcChar8 *both = FcStrPlus (fam, style);
-
- if (both)
- {
- if (FcStrCmpIgnoreBlanksAndCase (full, both) == 0)
- remove = FcTrue;
- free (both);
- }
- }
- }
- if (remove)
- {
- FcPatternRemove (pat, FC_FULLNAME, fn);
- FcPatternRemove (pat, FC_FULLNAMELANG, fn);
- fn--;
- nfullname--;
- nfullname_lang--;
- }
- }
- if (FcDebug () & FC_DBG_SCANV)
- for (fn = 0; FcPatternGetString (pat, FC_FULLNAME, fn, &full) == FcResultMatch; fn++)
- printf ("Saving unique fullname %s\n", full);
- }
-
- file2 = FcStrCopy (file);
- if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)file2)))
- {
- FcStrFree (file2);
+ if (!FcPatternAddString (pat, FC_FILE, file))
goto bail1;
- }
- FcStrFree (file2);
-
- FcPatternAddFullFname (pat, (const char *)FcStrCopy (file));
if (!FcPatternAddInteger (pat, FC_INDEX, id))
goto bail1;
weight = FC_WEIGHT_BOLD;
else if (os2->usWeightClass < 850)
weight = FC_WEIGHT_EXTRABOLD;
- else if (os2->usWeightClass < 950)
+ else if (os2->usWeightClass < 925)
weight = FC_WEIGHT_BLACK;
+ else if (os2->usWeightClass < 1000)
+ weight = FC_WEIGHT_EXTRABLACK;
+ if ((FcDebug() & FC_DBG_SCANV) && weight != -1)
+ printf ("\tos2 weight class %d maps to weight %d\n",
+ os2->usWeightClass, weight);
switch (os2->usWidthClass) {
case 1: width = FC_WIDTH_ULTRACONDENSED; break;
case 8: width = FC_WIDTH_EXTRAEXPANDED; break;
case 9: width = FC_WIDTH_ULTRAEXPANDED; break;
}
+ if ((FcDebug() & FC_DBG_SCANV) && width != -1)
+ printf ("\tos2 width class %d maps to width %d\n",
+ os2->usWidthClass, width);
}
- if (os2 && (complex = FcFontCapabilities(face)))
+ if (os2 && (complex_ = FcFontCapabilities(face)))
{
- if (!FcPatternAddString (pat, FC_CAPABILITY, complex))
+ if (!FcPatternAddString (pat, FC_CAPABILITY, complex_))
{
- free (complex);
+ free (complex_);
goto bail1;
}
- free (complex);
+ free (complex_);
}
/*
if (!foundry)
{
int rc;
- BDF_PropertyRec prop;
rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop);
if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM)
foundry = (FcChar8 *) prop.u.atom;
if (FcDebug() & FC_DBG_SCANV)
printf ("\tStyle %s maps to slant %d\n", style, slant);
}
+ if (decorative == FcFalse)
+ {
+ decorative = FcContainsDecorative (style) > 0;
+ if (FcDebug() & FC_DBG_SCANV)
+ printf ("\tStyle %s maps to decorative %d\n", style, decorative);
+ }
}
/*
* Pull default values from the FreeType flags if more
if (!FcPatternAddString (pat, FC_FOUNDRY, foundry))
goto bail1;
+ if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative))
+ goto bail1;
+
/*
* Compute the unicode coverage for the font
*/
/*
* Skip over PCF fonts that have no encoded characters; they're
* usually just Unicode fonts transcoded to some legacy encoding
- * ftglue.c forces us to approximate whether a font is a PCF font
+ * FT forces us to approximate whether a font is a PCF font
* or not by whether it has any BDF properties. Try PIXEL_SIZE;
* I don't know how to get a list of BDF properties on the font. -PL
*/
for (i = 0; i < face->num_fixed_sizes; i++)
if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE,
FcGetPixelSize (face, i)))
- goto bail1;
- if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
- goto bail1;
-#if HAVE_FT_GET_BDF_PROPERTY
- if(face->num_fixed_sizes == 1) {
- int rc;
- int value;
- BDF_PropertyRec prop;
-
- /* skip bitmap fonts which do not even have a family name */
- rc = FT_Get_BDF_Property(face, "FAMILY_NAME", &prop);
- if (rc != 0 || prop.type != BDF_PROPERTY_TYPE_ATOM)
goto bail2;
-
- rc = FT_Get_BDF_Property(face, "POINT_SIZE", &prop);
- if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
- value = prop.u.integer;
- else if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_CARDINAL)
- value = prop.u.cardinal;
- else
- goto nevermind;
- if(!FcPatternAddDouble(pat, FC_SIZE, value / 10.0))
- goto nevermind;
-
- rc = FT_Get_BDF_Property(face, "RESOLUTION_Y", &prop);
- if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
- value = prop.u.integer;
- else if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_CARDINAL)
- value = prop.u.cardinal;
- else
- goto nevermind;
- if(!FcPatternAddDouble(pat, FC_DPI, (double)value))
- goto nevermind;
-
- }
- nevermind:
- ;
-#endif
+ if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse))
+ goto bail2;
}
#if HAVE_FT_GET_X11_FONT_FORMAT
/*
*/
FcCharSetDestroy (cs);
- /*
- * Deallocate family/style values
- */
-
- FT_Done_Face (face);
- FT_Done_FreeType (ftLibrary);
return pat;
bail2:
bail1:
FcPatternDestroy (pat);
bail0:
+ return NULL;
+}
+
+FcPattern *
+FcFreeTypeQuery(const FcChar8 *file,
+ int id,
+ FcBlanks *blanks,
+ int *count)
+{
+ FT_Face face;
+ FT_Library ftLibrary;
+ FcPattern *pat = NULL;
+
+ if (FT_Init_FreeType (&ftLibrary))
+ return NULL;
+
+ if (FT_New_Face (ftLibrary, (char *) file, id, &face))
+ goto bail;
+
+ *count = face->num_faces;
+
+ pat = FcFreeTypeQueryFace (face, file, id, blanks);
+
FT_Done_Face (face);
bail:
FT_Done_FreeType (ftLibrary);
- return 0;
+ return pat;
}
-
/*
* For our purposes, this approximation is sufficient
*/
{
int i = (int) (ucs4 % FC_GLYPHNAME_HASH);
int r = 0;
- const FcGlyphName *gn;
+ FcGlyphId gn;
- while ((gn = ucs_to_name[i]))
+ while ((gn = ucs_to_name[i]) != -1)
{
- if (gn->ucs == ucs4)
- return gn->name;
+ if (glyphs[gn].ucs == ucs4)
+ return glyphs[gn].name;
if (!r)
{
r = (int) (ucs4 % FC_GLYPHNAME_REHASH);
FcChar32 h = FcHashGlyphName (name);
int i = (int) (h % FC_GLYPHNAME_HASH);
int r = 0;
- const FcGlyphName *gn;
+ FcGlyphId gn;
- while ((gn = name_to_ucs[i]))
+ while ((gn = name_to_ucs[i]) != -1)
{
- if (!strcmp ((char *) name, (char *) gn->name))
- return gn->ucs;
+ if (!strcmp ((char *) name, (char *) glyphs[gn].name))
+ return glyphs[gn].ucs;
if (!r)
{
r = (int) (h % FC_GLYPHNAME_REHASH);
return 0xffff;
}
+/*
+ * Work around a bug in some FreeType versions which fail
+ * to correctly bounds check glyph name buffers and overwrite
+ * the stack. As Postscript names have a limit of 127 characters,
+ * this should be sufficient.
+ */
+
+#if FC_GLYPHNAME_MAXLEN < 127
+# define FC_GLYPHNAME_BUFLEN 127
+#else
+# define FC_GLYPHNAME_BUFLEN FC_GLYPHNAME_MAXLEN
+#endif
+
/*
* Search through a font for a glyph by name. This is
* currently a linear search as there doesn't appear to be
FcFreeTypeGlyphNameIndex (FT_Face face, const FcChar8 *name)
{
FT_UInt gindex;
- FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
+ FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
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 (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
if (!strcmp ((char *) name, (char *) name_buf))
return gindex;
}
int p;
initial = 0;
+
+ if (!face)
+ return 0;
+
/*
* Find the current encoding
*/
static FcBool
FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4,
FT_UInt glyph, FcBlanks *blanks,
- FT_Pos *advance)
+ FT_Pos *advance,
+ FcBool using_strike)
{
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
FT_GlyphSlot slot;
+ if (using_strike)
+ load_flags &= ~FT_LOAD_NO_SCALE;
+
/*
* When using scalable fonts, only report those glyphs
* which can be scaled; otherwise those fonts will
#define FC_ABS(a) ((a) < 0 ? -(a) : (a))
#define APPROXIMATELY_EQUAL(x,y) (FC_ABS ((x) - (y)) <= FC_MAX (FC_ABS (x), FC_ABS (y)) / 33)
-FcCharSet *
-FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+static FcCharSet *
+FcFreeTypeCharSetAndSpacingForSize (FT_Face face, FcBlanks *blanks, int *spacing, FT_Int strike_index)
{
- FcChar32 page, off, max, ucs4;
+ FcChar32 page, off, ucs4;
#ifdef CHECK
FcChar32 font_max = 0;
#endif
FT_UInt glyph;
FT_Pos advance, advance_one = 0, advance_two = 0;
FcBool has_advance = FcFalse, fixed_advance = FcTrue, dual_advance = FcFalse;
+ FcBool using_strike = FcFalse;
fcs = FcCharSetCreate ();
if (!fcs)
goto bail0;
+#if HAVE_FT_SELECT_SIZE
+ if (strike_index >= 0) {
+ if (FT_Select_Size (face, strike_index) != FT_Err_Ok)
+ goto bail1;
+ using_strike = FcTrue;
+ }
+#endif
+
#ifdef CHECK
printf ("Family %s style %s\n", face->family_name, face->style_name);
#endif
ucs4 = map->ent[i].bmp;
glyph = FT_Get_Char_Index (face, map->ent[i].encode);
if (glyph &&
- FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+ FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
{
/*
* ignore glyphs with zero advance. They’re
}
else
{
- FT_UInt gindex;
-
- max = fcFontDecoders[o].max;
- /*
- * Find the first encoded character in the font
- */
- if (FT_Get_Char_Index (face, 0))
- {
- ucs4 = 0;
- gindex = 1;
- }
- else
+ page = ~0;
+ leaf = NULL;
+ ucs4 = FT_Get_First_Char (face, &glyph);
+ while (glyph != 0)
{
- ucs4 = FT_Get_Next_Char (face, 0, &gindex);
- if (!ucs4)
- gindex = 0;
- }
-
- while (gindex)
- {
- page = ucs4 >> 8;
- leaf = 0;
- while ((ucs4 >> 8) == page)
+ if (FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
{
- glyph = FT_Get_Char_Index (face, ucs4);
- if (glyph && FcFreeTypeCheckGlyph (face, ucs4,
- glyph, blanks, &advance))
+ if (advance)
{
- if (advance)
+ if (!has_advance)
{
- if (!has_advance)
- {
- has_advance = FcTrue;
- advance_one = advance;
- }
- else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ has_advance = FcTrue;
+ advance_one = advance;
+ }
+ else if (!APPROXIMATELY_EQUAL (advance, advance_one))
+ {
+ if (fixed_advance)
{
- if (fixed_advance)
- {
- dual_advance = FcTrue;
- fixed_advance = FcFalse;
- advance_two = advance;
- }
- else if (!APPROXIMATELY_EQUAL (advance, advance_two))
- dual_advance = FcFalse;
+ dual_advance = FcTrue;
+ fixed_advance = FcFalse;
+ advance_two = advance;
}
+ else if (!APPROXIMATELY_EQUAL (advance, advance_two))
+ dual_advance = FcFalse;
}
+ }
+ if ((ucs4 >> 8) != page)
+ {
+ page = (ucs4 >> 8);
+ leaf = FcCharSetFindLeafCreate (fcs, ucs4);
if (!leaf)
- {
- leaf = FcCharSetFindLeafCreate (fcs, ucs4);
- if (!leaf)
- goto bail1;
- }
- off = ucs4 & 0xff;
- leaf->map[off >> 5] |= (1 << (off & 0x1f));
+ goto bail1;
+ }
+ off = ucs4 & 0xff;
+ leaf->map[off >> 5] |= (1 << (off & 0x1f));
#ifdef CHECK
- if (ucs4 > font_max)
- font_max = ucs4;
+ if (ucs4 > font_max)
+ font_max = ucs4;
#endif
- }
- ucs4++;
}
- ucs4 = FT_Get_Next_Char (face, ucs4 - 1, &gindex);
- if (!ucs4)
- gindex = 0;
+ ucs4 = FT_Get_Next_Char (face, ucs4, &glyph);
}
#ifdef CHECK
for (ucs4 = 0; ucs4 < 0x10000; ucs4++)
*/
if (FcFreeTypeUseNames (face))
{
- FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
+ FcChar8 name_buf[FC_GLYPHNAME_BUFLEN + 2];
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 (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_BUFLEN+1) == 0)
{
ucs4 = FcGlyphNameToUcs4 (name_buf);
if (ucs4 != 0xffff &&
- FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+ FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
{
if (advance)
{
if (has_char && !has_bit)
{
- if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
+ if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance, using_strike))
printf ("Bitmap missing broken char 0x%x\n", ucs4);
else
printf ("Bitmap missing char 0x%x\n", ucs4);
return 0;
}
+FcCharSet *
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
+{
+ FcCharSet *cs;
+
+ cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, -1);
+ /*
+ * Check for bitmap-only ttf fonts that are missing the glyf table.
+ * In that case, pick a size and look for glyphs in that size instead
+ */
+ if (FcCharSetCount (cs) == 0)
+ {
+ /* Check for non-scalable TT fonts */
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) &&
+ face->num_fixed_sizes > 0 &&
+ FT_Get_Sfnt_Table (face, ft_sfnt_head))
+ {
+ FT_Int strike_index = 0;
+ int i;
+
+ /* Select the face closest to 16 pixels tall */
+ for (i = 1; i < face->num_fixed_sizes; i++) {
+ if (abs (face->available_sizes[i].height - 16) <
+ abs (face->available_sizes[strike_index].height - 16))
+ strike_index = i;
+ }
+ FcCharSetDestroy (cs);
+ cs = FcFreeTypeCharSetAndSpacingForSize (face, blanks, spacing, strike_index);
+ }
+ }
+ return cs;
+}
+
FcCharSet *
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
{
#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
#define TTAG_SILF FT_MAKE_TAG( 'S', 'i', 'l', 'f')
-#define TT_Err_Ok FT_Err_Ok
-#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
-#define TTO_Err_Empty_Script 0x1005
-#define TTO_Err_Invalid_SubTable 0x1001
#define OTLAYOUT_HEAD "otlayout:"
#define OTLAYOUT_HEAD_LEN 9
#define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsSpace(x))
static void
-addtag(FcChar8 *complex, FT_ULong tag)
+addtag(FcChar8 *complex_, FT_ULong tag)
{
FcChar8 tagstring[OTLAYOUT_ID_LEN + 1];
!FcIsValidScript(tagstring[3]))
return;
- if (*complex != '\0')
- strcat ((char *) complex, " ");
- strcat ((char *) complex, "otlayout:");
- strcat ((char *) complex, (char *) tagstring);
+ if (*complex_ != '\0')
+ strcat ((char *) complex_, " ");
+ strcat ((char *) complex_, "otlayout:");
+ strcat ((char *) complex_, (char *) tagstring);
}
static int
}
-static FT_Error
-GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *script_count)
+static int
+GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags)
{
- FT_ULong cur_offset, new_offset, base_offset;
+ FT_ULong cur_offset, new_offset, base_offset;
FT_Stream stream = face->stream;
FT_Error error;
- FT_UShort n, p;
- FT_Memory memory = stream->memory;
+ FT_UShort n, p;
+ FT_Memory memory;
+ int script_count;
+
+ if (!stream)
+ return 0;
- if ( !stream )
- return TT_Err_Invalid_Face_Handle;
+ memory = stream->memory;
if (( error = ftglue_face_goto_table( face, tabletag, stream ) ))
- return error;
+ return 0;
base_offset = ftglue_stream_pos ( stream );
/* skip version */
if ( ftglue_stream_seek ( stream, base_offset + 4L ) || ftglue_stream_frame_enter( stream, 2L ) )
- return error;
+ return 0;
- new_offset = ((FT_UShort)ftglue_stream_get_short ( stream )) + base_offset;
+ new_offset = GET_UShort() + base_offset;
ftglue_stream_frame_exit( stream );
cur_offset = ftglue_stream_pos( stream );
- if ( ftglue_stream_seek( stream, new_offset ) != TT_Err_Ok )
- return error;
+ if ( ftglue_stream_seek( stream, new_offset ) != FT_Err_Ok )
+ return 0;
base_offset = ftglue_stream_pos( stream );
if ( ftglue_stream_frame_enter( stream, 2L ) )
- return error;
+ return 0;
- *script_count = ((FT_UShort)ftglue_stream_get_short ( stream ));
+ script_count = GET_UShort ();
ftglue_stream_frame_exit( stream );
- *stags = ftglue_alloc(memory, *script_count * sizeof( FT_ULong ), &error);
-
- if (error)
- return error;
+ *stags = malloc(script_count * sizeof (FT_ULong));
+ if (!stags)
+ return 0;
p = 0;
- for ( n = 0; n < *script_count; n++ )
+ for ( n = 0; n < script_count; n++ )
{
if ( ftglue_stream_frame_enter( stream, 6L ) )
goto Fail;
- (*stags)[p] = ((FT_ULong)ftglue_stream_get_long ( stream ));
- new_offset = ((FT_UShort)ftglue_stream_get_short ( stream )) + base_offset;
+ (*stags)[p] = GET_ULong ();
+ new_offset = GET_UShort () + base_offset;
ftglue_stream_frame_exit( stream );
cur_offset = ftglue_stream_pos( stream );
- if ( ftglue_stream_seek( stream, new_offset ) )
- goto Fail;
+ error = ftglue_stream_seek( stream, new_offset );
- if ( error == TT_Err_Ok )
+ if ( error == FT_Err_Ok )
p++;
- else if ( error != TTO_Err_Empty_Script )
- goto Fail;
(void)ftglue_stream_seek( stream, cur_offset );
}
if (!p)
- {
- error = TTO_Err_Invalid_SubTable;
goto Fail;
- }
- // sort the tag list before returning it
- qsort(*stags, *script_count, sizeof(FT_ULong), compareulong);
+ /* sort the tag list before returning it */
+ qsort(*stags, script_count, sizeof(FT_ULong), compareulong);
- return TT_Err_Ok;
+ return script_count;
Fail:
- *script_count = 0;
- ftglue_free( memory, *stags );
- return error;
+ free(*stags);
+ *stags = NULL;
+ return 0;
}
static FcChar8 *
FT_UShort gsub_count=0, gpos_count=0;
FT_ULong maxsize;
FT_Memory memory = face->stream->memory;
- FcChar8 *complex = NULL;
+ FcChar8 *complex_ = NULL;
int indx1 = 0, indx2 = 0;
err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
issilgraphitefont = ( err == FT_Err_Ok);
- 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;
-
+ gpos_count = GetScriptTags(face, TTAG_GPOS, &gpostags);
+ gsub_count = GetScriptTags(face, TTAG_GSUB, &gsubtags);
+
if (!issilgraphitefont && !gsub_count && !gpos_count)
goto bail;
maxsize = (((FT_ULong) gpos_count + (FT_ULong) gsub_count) * OTLAYOUT_LEN +
(issilgraphitefont ? 13 : 0));
- complex = malloc (sizeof (FcChar8) * maxsize);
- if (!complex)
+ complex_ = malloc (sizeof (FcChar8) * maxsize);
+ if (!complex_)
goto bail;
- complex[0] = '\0';
+ complex_[0] = '\0';
if (issilgraphitefont)
- strcpy((char *) complex, "ttable:Silf ");
+ strcpy((char *) complex_, "ttable:Silf ");
while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
if (indx1 == gsub_count) {
- addtag(complex, gpostags[indx2]);
+ addtag(complex_, gpostags[indx2]);
indx2++;
} else if ((indx2 == gpos_count) || (gsubtags[indx1] < gpostags[indx2])) {
- addtag(complex, gsubtags[indx1]);
+ addtag(complex_, gsubtags[indx1]);
indx1++;
} else if (gsubtags[indx1] == gpostags[indx2]) {
- addtag(complex, gsubtags[indx1]);
+ addtag(complex_, gsubtags[indx1]);
indx1++;
indx2++;
} else {
- addtag(complex, gpostags[indx2]);
+ addtag(complex_, gpostags[indx2]);
indx2++;
}
}
if (FcDebug () & FC_DBG_SCANV)
- printf("complex features in this font: %s\n", complex);
+ printf("complex_ features in this font: %s\n", complex_);
bail:
- ftglue_free(memory, gsubtags);
- ftglue_free(memory, gpostags);
- return complex;
+ free(gsubtags);
+ free(gpostags);
+ return complex_;
}
+
+#define __fcfreetype__
+#include "fcaliastail.h"
+#include "fcftaliastail.h"
+#undef __fcfreetype__