diff options
author | Keith Packard <keithp@keithp.com> | 2005-03-05 23:34:57 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2005-03-05 23:34:57 +0000 |
commit | 219f7818dacb5417ab9e481b1fc21a79511e5fe7 (patch) | |
tree | dae3687f9e28a0c6626b0dea5329cd99d8b5cead | |
parent | 97bde49a2b791de9ad66aed97ca07c22302da60d (diff) |
Rework GSUB/GPOS script parsing to survive broken fonts. Thanks for the
broken font go to Manish Singh
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | src/fcfreetype.c | 64 |
2 files changed, 51 insertions, 20 deletions
@@ -1,5 +1,12 @@ 2005-03-05 Keith Packard <keithp@keithp.com> + * src/fcfreetype.c: (addtag), (GetScriptTags), + (FcFontCapabilities): + Rework GSUB/GPOS script parsing to survive broken fonts. + Thanks for the broken font go to Manish Singh + +2005-03-05 Keith Packard <keithp@keithp.com> + Josselin Mouette: * debian/changelog: * debian/control: diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 39aaa79..7f6ca37 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -2643,17 +2643,38 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks) #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) + +#define FcIsNumber(x) (060 <= (x) && (x) <= 071) +#define FcIsAlNum(x) (FcIsLower(x) || FcIsUpper (x) || FcIsNumber (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 alphanumeric, under the assumption that + * they're probably broken + */ + if (!FcIsAlNum(tagstring[0]) || + !FcIsAlNum(tagstring[1]) || + !FcIsAlNum(tagstring[2]) || + !FcIsAlNum(tagstring[3])) + return; + + if (*complex != '\0') + strcat (complex, " "); + strcat (complex, "otlayout:"); + strcat (complex, tagstring); } static int @@ -2745,6 +2766,7 @@ GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *scri return TT_Err_Ok; Fail: + *script_count = 0; FT_FREE( *stags ); return error; } @@ -2756,7 +2778,8 @@ FcFontCapabilities(FT_Face face) 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; @@ -2764,25 +2787,26 @@ FcFontCapabilities(FT_Face face) 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, ""); - } while ((indx1 < gsub_count) || (indx2 < gpos_count)) { + int len = strlen (complex); if (indx1 == gsub_count) { addtag(complex, gpostags[indx2]); indx2++; |