From 219f7818dacb5417ab9e481b1fc21a79511e5fe7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 5 Mar 2005 23:34:57 +0000 Subject: [PATCH] Rework GSUB/GPOS script parsing to survive broken fonts. Thanks for the broken font go to Manish Singh --- ChangeLog | 7 ++++++ src/fcfreetype.c | 64 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1c8028..12182a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-03-05 Keith Packard + + * 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 Josselin Mouette: 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++; -- 2.39.2