X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcfreetype.c;h=3cf1686d96c3f3b5a48ecebc1c5e9295af94e9fa;hb=c2c6976d1a88cc35143ffcc34f3c38d0a28d34f4;hp=8a42fdb1a139368e2cbd78b65120c7e8ad750c86;hpb=e77c17184a6172d6368dd3193c791c4027065bbd;p=fontconfig.git diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 8a42fdb..3cf1686 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -44,35 +44,27 @@ THE SOFTWARE. */ +#include "fcint.h" #include #include #include -#include -#include "fcint.h" #include #include FT_FREETYPE_H -#include FT_INTERNAL_OBJECTS_H #include FT_TRUETYPE_TABLES_H #include FT_SFNT_NAMES_H #include FT_TRUETYPE_IDS_H #include FT_TYPE1_TABLES_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H -#include FT_INTERNAL_TRUETYPE_TYPES_H #if HAVE_FT_GET_X11_FONT_FORMAT #include FT_XFREE86_H #endif - #if HAVE_FT_GET_BDF_PROPERTY #include FT_BDF_H #include FT_MODULE_H -#define HAS_BDF_PROPERTY(f) ((f) && (f)->driver && \ - (f)->driver->root.clazz->get_interface) -#define MY_Get_BDF_Property(f,n,p) (HAS_BDF_PROPERTY(f) ? \ - FT_Get_BDF_Property(f,n,p) : \ - FT_Err_Invalid_Argument) #endif +#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 @@ -80,6 +72,7 @@ #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 @@ -105,7 +98,7 @@ FcFreeTypeIsExclusiveLang (const FcChar8 *lang) for (i = 0; i < NUM_CODE_PAGE_RANGE; i++) { - if (FcLangCompare (lang, FcCodePageRange[i].lang) != FcLangDifferentLang) + if (FcLangCompare (lang, FcCodePageRange[i].lang) == FcLangEqual) return FcTrue; } return FcFalse; @@ -563,11 +556,32 @@ FcFontCapabilities(FT_Face face); #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 #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) { @@ -588,24 +602,35 @@ 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")) { @@ -746,10 +771,24 @@ static const FcChar8 * 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; @@ -915,9 +954,10 @@ static const FcStringConst weightConsts[] = { { (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) "black", FC_WEIGHT_BLACK }, { (FC8) "heavy", FC_WEIGHT_HEAVY }, }; @@ -946,6 +986,7 @@ static const FcStringConst widthConsts[] = { static const FcStringConst slantConsts[] = { { (FC8) "italic", FC_SLANT_ITALIC }, + { (FC8) "kursiv", FC_SLANT_ITALIC }, { (FC8) "oblique", FC_SLANT_OBLIQUE }, }; @@ -954,6 +995,20 @@ static const FcStringConst slantConsts[] = { #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) "smallcaps", FcTrue }, + { (FC8) "antiqua", FcTrue }, + { (FC8) "romansc", FcTrue }, + { (FC8) "embosed", FcTrue }, + { (FC8) "romansmallcaps", 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) { @@ -963,7 +1018,7 @@ FcGetPixelSize (FT_Face face, int i) BDF_PropertyRec prop; int rc; - rc = MY_Get_BDF_Property (face, "PIXEL_SIZE", &prop); + rc = FT_Get_BDF_Property (face, "PIXEL_SIZE", &prop); if (rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER) return (double) prop.u.integer; } @@ -984,7 +1039,6 @@ FcStringInPatternElement (FcPattern *pat, const char *elt, FcChar8 *string) if (!FcStrCmpIgnoreBlanksAndCase (old, string)) { return FcTrue; - break; } return FcFalse; } @@ -1000,6 +1054,7 @@ FcFreeTypeQuery (const FcChar8 *file, int slant = -1; int weight = -1; int width = -1; + FcBool decorative = FcFalse; int i; FcCharSet *cs; FcLangSet *ls; @@ -1229,7 +1284,7 @@ FcFreeTypeQuery (const FcChar8 *file, * or which are simply a FC_FAMILY and FC_STYLE glued together */ { - int fn, fa, st; + int fn, fa; FcChar8 *full; FcChar8 *fam; FcChar8 *style; @@ -1288,11 +1343,9 @@ FcFreeTypeQuery (const FcChar8 *file, printf ("Saving unique fullname %s\n", full); } - if (!FcPatternAddString (pat, FC_FILE, (FcChar8 *)basename((char *)file))) + if (!FcPatternAddString (pat, FC_FILE, file)) goto bail1; - FcPatternAddFullFname (pat, (const char *)file); - if (!FcPatternAddInteger (pat, FC_INDEX, id)) goto bail1; @@ -1377,6 +1430,9 @@ FcFreeTypeQuery (const FcChar8 *file, weight = FC_WEIGHT_EXTRABOLD; else if (os2->usWeightClass < 950) weight = FC_WEIGHT_BLACK; + 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; @@ -1389,6 +1445,9 @@ FcFreeTypeQuery (const FcChar8 *file, 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))) { @@ -1441,15 +1500,14 @@ FcFreeTypeQuery (const FcChar8 *file, if (!foundry) { int rc; - BDF_PropertyRec prop; - rc = MY_Get_BDF_Property(face, "FOUNDRY", &prop); + rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop); if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) foundry = (FcChar8 *) prop.u.atom; } if (width == -1) { - if (MY_Get_BDF_Property(face, "RELATIVE_SETWIDTH", &prop) == 0 && + if (FT_Get_BDF_Property(face, "RELATIVE_SETWIDTH", &prop) == 0 && (prop.type == BDF_PROPERTY_TYPE_INTEGER || prop.type == BDF_PROPERTY_TYPE_CARDINAL)) { @@ -1472,7 +1530,7 @@ FcFreeTypeQuery (const FcChar8 *file, } } if (width == -1 && - MY_Get_BDF_Property (face, "SETWIDTH_NAME", &prop) == 0 && + FT_Get_BDF_Property (face, "SETWIDTH_NAME", &prop) == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { width = FcIsWidth ((FcChar8 *) prop.u.atom); @@ -1505,6 +1563,12 @@ FcFreeTypeQuery (const FcChar8 *file, 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 @@ -1542,6 +1606,9 @@ FcFreeTypeQuery (const FcChar8 *file, if (!FcPatternAddString (pat, FC_FOUNDRY, foundry)) goto bail1; + if (!FcPatternAddBool (pat, FC_DECORATIVE, decorative)) + goto bail1; + /* * Compute the unicode coverage for the font */ @@ -1552,7 +1619,7 @@ FcFreeTypeQuery (const FcChar8 *file, #if HAVE_FT_GET_BDF_PROPERTY /* For PCF fonts, override the computed spacing with the one from the property */ - if(MY_Get_BDF_Property(face, "SPACING", &prop) == 0 && + if(FT_Get_BDF_Property(face, "SPACING", &prop) == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { if(!strcmp(prop.u.atom, "c") || !strcmp(prop.u.atom, "C")) spacing = FC_CHARCELL; @@ -1566,11 +1633,16 @@ FcFreeTypeQuery (const FcChar8 *file, /* * 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 + * 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 */ if (FcCharSetCount (cs) == 0) { - if (!strcmp(FT_MODULE_CLASS(&face->driver->root)->module_name, "pcf")) +#if HAVE_FT_GET_BDF_PROPERTY + if(FT_Get_BDF_Property(face, "PIXEL_SIZE", &prop) == 0) goto bail2; +#endif } if (!FcPatternAddCharSet (pat, FC_CHARSET, cs)) @@ -1597,16 +1669,20 @@ FcFreeTypeQuery (const FcChar8 *file, for (i = 0; i < face->num_fixed_sizes; i++) if (!FcPatternAddDouble (pat, FC_PIXEL_SIZE, FcGetPixelSize (face, i))) - goto bail1; + goto bail2; if (!FcPatternAddBool (pat, FC_ANTIALIAS, FcFalse)) - goto bail1; + goto bail2; #if HAVE_FT_GET_BDF_PROPERTY if(face->num_fixed_sizes == 1) { int rc; int value; - BDF_PropertyRec prop; - rc = MY_Get_BDF_Property(face, "POINT_SIZE", &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) @@ -1616,7 +1692,7 @@ FcFreeTypeQuery (const FcChar8 *file, if(!FcPatternAddDouble(pat, FC_SIZE, value / 10.0)) goto nevermind; - rc = MY_Get_BDF_Property(face, "RESOLUTION_Y", &prop); + 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) @@ -2305,6 +2381,10 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4) int p; initial = 0; + + if (!face) + return 0; + /* * Find the current encoding */ @@ -2425,7 +2505,7 @@ FcFreeTypeCheckGlyph (FT_Face face, FcChar32 ucs4, FcCharSet * FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing) { - FcChar32 page, off, max, ucs4; + FcChar32 page, off, ucs4; #ifdef CHECK FcChar32 font_max = 0; #endif @@ -2506,7 +2586,6 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing) { FT_UInt gindex; - max = fcFontDecoders[o].max; /* * Find the first encoded character in the font */ @@ -2734,68 +2813,68 @@ static FT_Error GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *script_count) { FT_ULong cur_offset, new_offset, base_offset; - TT_Face tt_face = (TT_Face)face; FT_Stream stream = face->stream; FT_Error error; FT_UShort n, p; - FT_Memory memory = stream->memory; + FT_Memory memory; if ( !stream ) return TT_Err_Invalid_Face_Handle; - if (( error = tt_face->goto_table( tt_face, tabletag, stream, 0 ) )) + memory = stream->memory; + + if (( error = ftglue_face_goto_table( face, tabletag, stream ) )) return error; - base_offset = FT_STREAM_POS(); + base_offset = ftglue_stream_pos ( stream ); /* skip version */ - if ( FT_STREAM_SEEK( base_offset + 4L ) || FT_FRAME_ENTER( 2L ) ) + if ( ftglue_stream_seek ( stream, base_offset + 4L ) || ftglue_stream_frame_enter( stream, 2L ) ) return error; - new_offset = FT_GET_USHORT() + base_offset; + new_offset = GET_UShort() + base_offset; - FT_FRAME_EXIT(); + ftglue_stream_frame_exit( stream ); - cur_offset = FT_STREAM_POS(); + cur_offset = ftglue_stream_pos( stream ); - if ( FT_STREAM_SEEK( new_offset ) != TT_Err_Ok ) + if ( ftglue_stream_seek( stream, new_offset ) != TT_Err_Ok ) return error; - base_offset = FT_STREAM_POS(); + base_offset = ftglue_stream_pos( stream ); - if ( FT_FRAME_ENTER( 2L ) ) + if ( ftglue_stream_frame_enter( stream, 2L ) ) return error; - *script_count = FT_GET_USHORT(); + *script_count = GET_UShort (); + + ftglue_stream_frame_exit( stream ); - FT_FRAME_EXIT(); + *stags = ftglue_alloc(memory, *script_count * sizeof( FT_ULong ), &error); - if ( FT_SET_ERROR (FT_MEM_ALLOC_ARRAY( *stags, *script_count, FT_ULong )) ) + if (error) return error; p = 0; for ( n = 0; n < *script_count; n++ ) { - if ( FT_FRAME_ENTER( 6L ) ) + if ( ftglue_stream_frame_enter( stream, 6L ) ) goto Fail; - (*stags)[p] = FT_GET_ULONG(); - new_offset = FT_GET_USHORT() + base_offset; + (*stags)[p] = GET_ULong (); + new_offset = GET_UShort () + base_offset; - FT_FRAME_EXIT(); + ftglue_stream_frame_exit( stream ); - cur_offset = FT_STREAM_POS(); + cur_offset = ftglue_stream_pos( stream ); - if ( FT_STREAM_SEEK( new_offset ) ) - goto Fail; + error = ftglue_stream_seek( stream, new_offset ); if ( error == TT_Err_Ok ) p++; - else if ( error != TTO_Err_Empty_Script ) - goto Fail; - (void)FT_STREAM_SEEK( cur_offset ); + (void)ftglue_stream_seek( stream, cur_offset ); } if (!p) @@ -2804,14 +2883,15 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri goto Fail; } - // sort the tag list before returning it + /* sort the tag list before returning it */ qsort(*stags, *script_count, sizeof(FT_ULong), compareulong); return TT_Err_Ok; Fail: *script_count = 0; - FT_FREE( *stags ); + ftglue_free( memory, *stags ); + *stags = NULL; return error; } @@ -2868,7 +2948,7 @@ FcFontCapabilities(FT_Face face) if (FcDebug () & FC_DBG_SCANV) printf("complex features in this font: %s\n", complex); bail: - FT_FREE(gsubtags); - FT_FREE(gpostags); + ftglue_free(memory, gsubtags); + ftglue_free(memory, gpostags); return complex; }