diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2010-04-04 13:55:46 +0000 |
commit | f372862c42d234710b6057449b46818e63181c90 (patch) | |
tree | a9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge | |
parent | 2dad291ab056f30816e0aea61970f38033c2f6a5 (diff) |
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf
git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge')
11 files changed, 1939 insertions, 930 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c index a55a3d3d637..38e3b1b3b48 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/autohint.c @@ -94,17 +94,21 @@ void FindBlues( SplineFont *sf, int layer, real blues[14], real otherblues[10]) for ( i=0; i<sf->glyphcnt; ++i ) { if ( sf->glyphs[i]!=NULL && sf->glyphs[i]->layers[layer].splines!=NULL ) { int enc = sf->glyphs[i]->unicodeenc; +#ifndef LUA_FF_LIB const unichar_t *upt; +#endif if ( enc<0x10000 && isalnum(enc) && ((enc>=32 && enc<128 ) || enc == 0xfe || enc==0xf0 || enc==0xdf || enc==0x131 || (enc>=0x391 && enc<=0x3f3 ) || (enc>=0x400 && enc<=0x4e9 ) )) { /* no accented characters (or ligatures) */ +#ifndef LUA_FF_LIB if ( unicode_alternates[enc>>8]!=NULL && (upt =unicode_alternates[enc>>8][enc&0xff])!=NULL && upt[1]!='\0' ) continue; +#endif SplineCharFindBounds(sf->glyphs[i],&b); if ( b.miny==0 && b.maxy==0 ) continue; @@ -256,16 +260,20 @@ void FindBlues( SplineFont *sf, int layer, real blues[14], real otherblues[10]) base[3] = base[4] = 0; for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) { int enc = sf->glyphs[i]->unicodeenc; +#ifndef LUA_FF_LIB const unichar_t *upt; +#endif if ( enc<0x10000 && isalnum(enc) && ((enc>=32 && enc<128 ) || enc == 0xfe || enc==0xf0 || enc==0xdf || (enc>=0x391 && enc<=0x3f3 ) || (enc>=0x400 && enc<=0x4e9 ) )) { /* no accented characters (or ligatures) */ +#ifndef LUA_FF_LIB if ( unicode_alternates[enc>>8]!=NULL && (upt =unicode_alternates[enc>>8][enc&0xff])!=NULL && upt[1]!='\0' ) continue; +#endif SplineCharFindBounds(sf->glyphs[i],&b); if ( b.miny==0 && b.maxy==0 ) continue; diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c index 6fccf29e8ae..b4be6b5b5fe 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/encoding.c @@ -289,16 +289,8 @@ return( &unicodefull ); /* Mac seems to work ok */ if ( strcasecmp(name,"win")==0 || strcasecmp(name,"ansi")==0 ) iconv_name = "MS-ANSI"; /* "WINDOWS-1252";*/ - else if ( strncasecmp(name,"jis208",6)==0 || strncasecmp(name,"jisx0208",8)==0 ) - iconv_name = "ISO-2022-JP"; - else if ( strncasecmp(name,"jis212",6)==0 || strncasecmp(name,"jisx0212",8)==0 ) - iconv_name = "ISO-2022-JP-2"; - else if ( strncasecmp(name,"ksc5601",7)==0 ) - iconv_name = "ISO-2022-KR"; else if ( strcasecmp(name,"gb2312pk")==0 || strcasecmp(name,"gb2312packed")==0 ) - iconv_name = "EUC-CN"; - else if ( strncasecmp(name,"gb2312",6)==0 ) - iconv_name = "ISO-2022-CN"; + iconv_name = "EUC-CN"; else if ( strcasecmp(name,"wansung")==0 ) iconv_name = "EUC-KR"; else if ( strcasecmp(name,"EUC-CN")==0 ) { @@ -720,8 +712,7 @@ return( maybe ); maybefile = NULL; } } else { - file = utf82def_copy(uret); - free(uret); + file = uret; /* no utf82def() call for luatex */ } } diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c index 2f92df3e03e..63212410578 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/macbinary.c @@ -36,15 +36,15 @@ #include "ttf.h" #include "psfont.h" #ifdef LUA_FF_LIB -#undef __Mac +# undef __Mac #endif #if __Mac -# include <ctype.h> -# include </Developer/Headers/FlatCarbon/Files.h> +# include <ctype.h> +# include </Developer/Headers/FlatCarbon/Files.h> #else -# include <utype.h> -#undef __Mac -#define __Mac 0 +# include <utype.h> +# undef __Mac +# define __Mac 0 #endif const int mac_dpi = 72; @@ -123,82 +123,90 @@ struct resourcetype { struct macbinaryheader { char *macfilename; - char *binfilename; /* if macfilename is null and this is set we will figure out macfilename by removing .bin */ + char *binfilename; /* if macfilename is null and this is set we will figure out macfilename by removing .bin */ uint32 type; uint32 creator; }; - + enum psstyle_flags { psf_bold = 1, psf_italic = 2, psf_outline = 4, - psf_shadow = 0x8, psf_condense = 0x10, psf_extend = 0x20 }; + psf_shadow = 0x8, psf_condense = 0x10, psf_extend = 0x20 +}; -uint16 _MacStyleCode( char *styles, SplineFont *sf, uint16 *psstylecode ) { - unsigned short stylecode= 0, psstyle=0; +uint16 _MacStyleCode(char *styles, SplineFont * sf, uint16 * psstylecode) +{ + unsigned short stylecode = 0, psstyle = 0; - if ( strstrmatch( styles, "Bold" ) || strstrmatch(styles,"Demi") || - strstrmatch( styles,"Heav") || strstrmatch(styles,"Blac") || + if (strstrmatch(styles, "Bold") || strstrmatch(styles, "Demi") || + strstrmatch(styles, "Heav") || strstrmatch(styles, "Blac") || /* A few fonts have German/French styles in their names */ - strstrmatch( styles,"Fett") || strstrmatch(styles,"Gras") ) { - stylecode = sf_bold; - psstyle = psf_bold; - } else if ( sf!=NULL && sf->weight!=NULL && - (strstrmatch( sf->weight, "Bold" ) || strstrmatch(sf->weight,"Demi") || - strstrmatch( sf->weight,"Heav") || strstrmatch(sf->weight,"Blac") || - strstrmatch( sf->weight,"Fett") || strstrmatch(sf->weight,"Gras")) ) { - stylecode = sf_bold; - psstyle = psf_bold; + strstrmatch(styles, "Fett") || strstrmatch(styles, "Gras")) { + stylecode = sf_bold; + psstyle = psf_bold; + } else if (sf != NULL && sf->weight != NULL && + (strstrmatch(sf->weight, "Bold") + || strstrmatch(sf->weight, "Demi") + || strstrmatch(sf->weight, "Heav") + || strstrmatch(sf->weight, "Blac") + || strstrmatch(sf->weight, "Fett") + || strstrmatch(sf->weight, "Gras"))) { + stylecode = sf_bold; + psstyle = psf_bold; } /* URW uses four leter abbreviations of Italic and Oblique */ /* Somebody else uses two letter abbrevs */ - if ( (sf!=NULL && sf->italicangle!=0) || - strstrmatch( styles, "Ital" ) || - strstrmatch( styles, "Obli" ) || - strstrmatch(styles, "Slanted") || - strstrmatch(styles, "Kurs") || - strstr( styles,"It" ) ) { - stylecode |= sf_italic; - psstyle |= psf_italic; + if ((sf != NULL && sf->italicangle != 0) || + strstrmatch(styles, "Ital") || + strstrmatch(styles, "Obli") || + strstrmatch(styles, "Slanted") || + strstrmatch(styles, "Kurs") || strstr(styles, "It")) { + stylecode |= sf_italic; + psstyle |= psf_italic; } - if ( strstrmatch( styles, "Underline" ) ) { - stylecode |= sf_underline; + if (strstrmatch(styles, "Underline")) { + stylecode |= sf_underline; } - if ( strstrmatch( styles, "Outl" ) ) { - stylecode |= sf_outline; - psstyle |= psf_outline; + if (strstrmatch(styles, "Outl")) { + stylecode |= sf_outline; + psstyle |= psf_outline; } - if ( strstr(styles,"Shadow")!=NULL ) { - stylecode |= sf_shadow; - psstyle |= psf_shadow; + if (strstr(styles, "Shadow") != NULL) { + stylecode |= sf_shadow; + psstyle |= psf_shadow; } - if ( strstrmatch( styles, "Cond" ) || strstr( styles,"Cn") || - strstrmatch( styles, "Narrow") ) { - stylecode |= sf_condense; - psstyle |= psf_condense; + if (strstrmatch(styles, "Cond") || strstr(styles, "Cn") || + strstrmatch(styles, "Narrow")) { + stylecode |= sf_condense; + psstyle |= psf_condense; } - if ( strstrmatch( styles, "Exte" ) || strstr( styles,"Ex") ) { - stylecode |= sf_extend; - psstyle |= psf_extend; + if (strstrmatch(styles, "Exte") || strstr(styles, "Ex")) { + stylecode |= sf_extend; + psstyle |= psf_extend; } - if ( (psstyle&psf_extend) && (psstyle&psf_condense) ) { - if ( sf!=NULL ) - LogError( _("Warning: %s(%s) is both extended and condensed. That's impossible.\n"), - sf->fontname, sf->origname ); - else - LogError( _("Warning: Both extended and condensed. That's impossible.\n") ); - psstyle &= ~psf_extend; - stylecode &= ~sf_extend; + if ((psstyle & psf_extend) && (psstyle & psf_condense)) { + if (sf != NULL) + LogError(_ + ("Warning: %s(%s) is both extended and condensed. That's impossible.\n"), + sf->fontname, sf->origname); + else + LogError(_ + ("Warning: Both extended and condensed. That's impossible.\n")); + psstyle &= ~psf_extend; + stylecode &= ~sf_extend; } - if ( psstylecode!=NULL ) - *psstylecode = psstyle; -return( stylecode ); + if (psstylecode != NULL) + *psstylecode = psstyle; + return (stylecode); } /* ******************************** Reading ********************************* */ -static SplineFont *SearchPostscriptResources(FILE *f,long rlistpos,int subcnt,long rdata_pos, - long name_list, int flags) { +static SplineFont *SearchPostscriptResources(FILE * f, long rlistpos, + int subcnt, long rdata_pos, + long name_list, int flags) +{ long here = ftell(f); long *offsets, lenpos; int rname = -1, tmp; @@ -209,242 +217,257 @@ static SplineFont *SearchPostscriptResources(FILE *f,long rlistpos,int subcnt,lo /* postscript font. It appears to be split up into chunks where the */ /* maximum chunk size is 0x800, each section (ascii, binary, ascii, eof) */ /* has its own set of chunks (ie chunks don't cross sections) */ - char *buffer=NULL; + char *buffer = NULL; int max = 0; FILE *pfb; FontDict *fd; SplineFont *sf; - (void)name_list; - fseek(f,rlistpos,SEEK_SET); - rsrcids = gcalloc(subcnt,sizeof(short)); - offsets = gcalloc(subcnt,sizeof(long)); - for ( i=0; i<subcnt; ++i ) { - rsrcids[i] = getushort(f); - tmp = (short) getushort(f); - if ( rname==-1 ) rname = tmp; - /* flags = */ getc(f); - ch1 = getc(f); ch2 = getc(f); - offsets[i] = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f)); - /* mbz = */ getlong(f); + (void) name_list; + fseek(f, rlistpos, SEEK_SET); + rsrcids = gcalloc(subcnt, sizeof(short)); + offsets = gcalloc(subcnt, sizeof(long)); + for (i = 0; i < subcnt; ++i) { + rsrcids[i] = getushort(f); + tmp = (short) getushort(f); + if (rname == -1) + rname = tmp; + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + offsets[i] = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); } pfb = tmpfile(); - if ( pfb==NULL ) { - LogError( _("Can't open temporary file for postscript output\n") ); - fseek(f,here,SEEK_SET ); - free(offsets); -return(NULL); + if (pfb == NULL) { + LogError(_("Can't open temporary file for postscript output\n")); + fseek(f, here, SEEK_SET); + free(offsets); + return (NULL); } - putc(0x80,pfb); - putc(1,pfb); + putc(0x80, pfb); + putc(1, pfb); lenpos = ftell(pfb); - putc(0,pfb); - putc(0,pfb); - putc(0,pfb); - putc(0,pfb); - len = 0; type = 1; + putc(0, pfb); + putc(0, pfb); + putc(0, pfb); + putc(0, pfb); + len = 0; + type = 1; id = 501; - for ( i=0; i<subcnt; ++i ) { - for ( j=0; j<subcnt; ++j ) - if ( rsrcids[j]==id ) - break; - if ( j == subcnt ) { - LogError( _("Missing POST resource %u\n"), id ); - break; - } - id = id + 1; - fseek(f,offsets[j],SEEK_SET); - rlen = getlong(f); - ch1 = getc(f); ch2 = getc(f); - rlen -= 2; /* those two bytes don't count as real data */ - if ( ch1==type ) - len += rlen; - else { - long hold = ftell(pfb); - fseek(pfb,lenpos,SEEK_SET); - putc(len>>24,pfb); - putc((len>>16)&0xff,pfb); - putc((len>>8)&0xff,pfb); - putc(len&0xff,pfb); - fseek(pfb,hold,SEEK_SET); - if ( ch1==5 ) /* end of font mark */ - break; - putc(0x80,pfb); - putc(ch1,pfb); - lenpos = ftell(pfb); - putc(0,pfb); - putc(0,pfb); - putc(0,pfb); - putc(0,pfb); - type = ch1; - len = rlen; - } - if ( rlen>max ) { - free(buffer); - max = rlen; - if ( max<0x800 ) max = 0x800; - buffer=galloc(max); - if ( buffer==NULL ) { - LogError( _("Out of memory\n") ); - exit( 1 ); - } - } - fread(buffer,1,rlen,f); - fwrite(buffer,1,rlen,pfb); + for (i = 0; i < subcnt; ++i) { + for (j = 0; j < subcnt; ++j) + if (rsrcids[j] == id) + break; + if (j == subcnt) { + LogError(_("Missing POST resource %u\n"), id); + break; + } + id = id + 1; + fseek(f, offsets[j], SEEK_SET); + rlen = getlong(f); + ch1 = getc(f); + ch2 = getc(f); + rlen -= 2; /* those two bytes don't count as real data */ + if (ch1 == type) + len += rlen; + else { + long hold = ftell(pfb); + fseek(pfb, lenpos, SEEK_SET); + putc(len >> 24, pfb); + putc((len >> 16) & 0xff, pfb); + putc((len >> 8) & 0xff, pfb); + putc(len & 0xff, pfb); + fseek(pfb, hold, SEEK_SET); + if (ch1 == 5) /* end of font mark */ + break; + putc(0x80, pfb); + putc(ch1, pfb); + lenpos = ftell(pfb); + putc(0, pfb); + putc(0, pfb); + putc(0, pfb); + putc(0, pfb); + type = ch1; + len = rlen; + } + if (rlen > max) { + free(buffer); + max = rlen; + if (max < 0x800) + max = 0x800; + buffer = galloc(max); + if (buffer == NULL) { + LogError(_("Out of memory\n")); + exit(1); + } + } + fread(buffer, 1, rlen, f); + fwrite(buffer, 1, rlen, pfb); } free(buffer); free(offsets); - free(rsrcids); - putc(0x80,pfb); - putc(3,pfb); - fseek(pfb,lenpos,SEEK_SET); - putc(len>>24,pfb); - putc((len>>16)&0xff,pfb); - putc((len>>8)&0xff,pfb); - putc(len&0xff,pfb); - fseek(f,here,SEEK_SET); + free(rsrcids); + putc(0x80, pfb); + putc(3, pfb); + fseek(pfb, lenpos, SEEK_SET); + putc(len >> 24, pfb); + putc((len >> 16) & 0xff, pfb); + putc((len >> 8) & 0xff, pfb); + putc(len & 0xff, pfb); + fseek(f, here, SEEK_SET); rewind(pfb); - if ( flags&ttf_onlynames ) -return( (SplineFont *) _NamesReadPostscript(pfb) ); /* This closes the font for us */ + if (flags & ttf_onlynames) + return ((SplineFont *) _NamesReadPostscript(pfb)); /* This closes the font for us */ fd = _ReadPSFont(pfb); sf = NULL; - if ( fd!=NULL ) { - sf = SplineFontFromPSFont(fd); - PSFontFree(fd); - /* There is no FOND in a postscript file, so we can't read any kerning*/ + if (fd != NULL) { + sf = SplineFontFromPSFont(fd); + PSFontFree(fd); + /* There is no FOND in a postscript file, so we can't read any kerning */ } fclose(pfb); -return( sf ); + return (sf); } -static SplineFont *SearchTtfResources(FILE *f,long rlistpos,int subcnt,long rdata_pos, - long name_list,char *filename,int flags,enum openflags openflags) { +static SplineFont *SearchTtfResources(FILE * f, long rlistpos, int subcnt, + long rdata_pos, long name_list, + char *filename, int flags, + enum openflags openflags) +{ long here, start = ftell(f); long roff; int rname = -1; int ch1, ch2; int len, i, rlen, ilen; /* The sfnt resource is just a copy of the ttf file */ - char *buffer=NULL; + char *buffer = NULL; int max = 0; FILE *ttf; SplineFont *sf; int which = 0; char **names; - char *pt,*lparen, *rparen; - char *chosenname=NULL; - (void)name_list; - fseek(f,rlistpos,SEEK_SET); - if ( subcnt>1 || (flags&ttf_onlynames) ) { - names = gcalloc(subcnt+1,sizeof(char *)); - for ( i=0; i<subcnt; ++i ) { - /* resource id = */ getushort(f); - /* rname = (short) */ getushort(f); - /* flags = */ getc(f); - ch1 = getc(f); ch2 = getc(f); - roff = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f)); - /* mbz = */ getlong(f); - here = ftell(f); - names[i] = TTFGetFontName(f,roff+4,roff+4); - if ( names[i]==NULL ) { - char buffer[32]; - sprintf( buffer, "Nameless%d", i ); - names[i] = copy(buffer); - } - fseek(f,here,SEEK_SET); - } - if ( flags&ttf_onlynames ) { -return( (SplineFont *) names ); - } - if ((pt = strrchr(filename,'/'))==NULL ) pt = filename; - /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */ - /* that ff wouldn't open it */ - /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */ - if ( (lparen = strrchr(pt,'('))!=NULL && - (rparen = strrchr(lparen,')'))!=NULL && - rparen[1]=='\0' ) { - char *find = copy(lparen+1); - pt = strchr(find,')'); - if ( pt!=NULL ) *pt='\0'; - for ( which=subcnt-1; which>=0; --which ) - if ( strcmp(names[which],find)==0 ) - break; - if ( which==-1 ) { - char *end; - which = strtol(find,&end,10); - if ( *end!='\0' ) - which = -1; - } - if ( which==-1 ) { - char *fn = copy(filename); - fn[lparen-filename] = '\0'; - ff_post_error(_("Not in Collection"),_("%s is not in %.100s"),find,fn); - free(fn); - } - free(find); - } else - which = 0; - if ( lparen==NULL && which!=-1 ) - chosenname = copy(names[which]); - for ( i=0; i<subcnt; ++i ) - free(names[i]); - free(names); - fseek(f,rlistpos,SEEK_SET); + char *pt, *lparen, *rparen; + char *chosenname = NULL; + (void) name_list; + fseek(f, rlistpos, SEEK_SET); + if (subcnt > 1 || (flags & ttf_onlynames)) { + names = gcalloc(subcnt + 1, sizeof(char *)); + for (i = 0; i < subcnt; ++i) { + /* resource id = */ getushort(f); + /* rname = (short) */ getushort(f); + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); + here = ftell(f); + names[i] = TTFGetFontName(f, roff + 4, roff + 4); + if (names[i] == NULL) { + char buffer[32]; + sprintf(buffer, "Nameless%d", i); + names[i] = copy(buffer); + } + fseek(f, here, SEEK_SET); + } + if (flags & ttf_onlynames) { + return ((SplineFont *) names); + } + if ((pt = strrchr(filename, '/')) == NULL) + pt = filename; + /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */ + /* that ff wouldn't open it */ + /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */ + if ((lparen = strrchr(pt, '(')) != NULL && + (rparen = strrchr(lparen, ')')) != NULL && rparen[1] == '\0') { + char *find = copy(lparen + 1); + pt = strchr(find, ')'); + if (pt != NULL) + *pt = '\0'; + for (which = subcnt - 1; which >= 0; --which) + if (strcmp(names[which], find) == 0) + break; + if (which == -1) { + char *end; + which = strtol(find, &end, 10); + if (*end != '\0') + which = -1; + } + if (which == -1) { + char *fn = copy(filename); + fn[lparen - filename] = '\0'; + ff_post_error(_("Not in Collection"), _("%s is not in %.100s"), + find, fn); + free(fn); + } + free(find); + } else + which = 0; + if (lparen == NULL && which != -1) + chosenname = copy(names[which]); + for (i = 0; i < subcnt; ++i) + free(names[i]); + free(names); + fseek(f, rlistpos, SEEK_SET); } - for ( i=0; i<subcnt; ++i ) { - /* resource id = */ getushort(f); - rname = (short) getushort(f); - /* flags = */ getc(f); - ch1 = getc(f); ch2 = getc(f); - roff = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f)); - /* mbz = */ getlong(f); - if ( i!=which ) - continue; - here = ftell(f); - - ttf = tmpfile(); - if ( ttf==NULL ) { - LogError( _("Can't open temporary file for truetype output.\n") ); - continue; - } - - fseek(f,roff,SEEK_SET); - ilen = rlen = getlong(f); - if ( rlen>16*1024 ) - ilen = 16*1024; - if ( ilen>max ) { - free(buffer); - max = ilen; - if ( max<0x800 ) max = 0x800; - buffer=malloc(max); - } - for ( len=0; len<rlen; ) { - int temp = ilen; - if ( rlen-len<ilen ) temp = rlen-len; - temp = fread(buffer,1,temp,f); - if ( temp==EOF ) - break; - fwrite(buffer,1,temp,ttf); - len += temp; - } - rewind(ttf); - sf = _SFReadTTF(ttf,flags,openflags,NULL,NULL); - fclose(ttf); - if ( sf!=NULL ) { - free(buffer); - fseek(f,start,SEEK_SET); - if ( sf->chosenname==NULL ) sf->chosenname = chosenname; -return( sf ); - } - fseek(f,here,SEEK_SET); + for (i = 0; i < subcnt; ++i) { + /* resource id = */ getushort(f); + rname = (short) getushort(f); + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); + if (i != which) + continue; + here = ftell(f); + + ttf = tmpfile(); + if (ttf == NULL) { + LogError(_("Can't open temporary file for truetype output.\n")); + continue; + } + + fseek(f, roff, SEEK_SET); + ilen = rlen = getlong(f); + if (rlen > 16 * 1024) + ilen = 16 * 1024; + if (ilen > max) { + free(buffer); + max = ilen; + if (max < 0x800) + max = 0x800; + buffer = malloc(max); + } + for (len = 0; len < rlen;) { + int temp = ilen; + if (rlen - len < ilen) + temp = rlen - len; + temp = fread(buffer, 1, temp, f); + if (temp == EOF) + break; + fwrite(buffer, 1, temp, ttf); + len += temp; + } + rewind(ttf); + sf = _SFReadTTF(ttf, flags, openflags, NULL, NULL); + fclose(ttf); + if (sf != NULL) { + free(buffer); + fseek(f, start, SEEK_SET); + if (sf->chosenname == NULL) + sf->chosenname = chosenname; + return (sf); + } + fseek(f, here, SEEK_SET); } free(chosenname); free(buffer); - fseek(f,start,SEEK_SET); -return( NULL ); + fseek(f, start, SEEK_SET); + return (NULL); } typedef struct fond { @@ -452,69 +475,70 @@ typedef struct fond { int first, last; int assoc_cnt; struct assoc { - short size, style, id; + short size, style, id; } *assoc; - /* size==0 => scalable */ - /* style>>8 is the bit depth (0=>1, 1=>2, 2=>4, 3=>8) */ - /* search order for ID is sfnt, NFNT, FONT */ + /* size==0 => scalable */ + /* style>>8 is the bit depth (0=>1, 1=>2, 2=>4, 3=>8) */ + /* search order for ID is sfnt, NFNT, FONT */ int stylewidthcnt; struct stylewidths { - short style; - short *widthtab; /* 4.12 fixed number with the width specified as a fraction of an em */ + short style; + short *widthtab; /* 4.12 fixed number with the width specified as a fraction of an em */ } *stylewidths; int stylekerncnt; struct stylekerns { - short style; - int kernpairs; - struct kerns { - unsigned char ch1, ch2; - short offset; /* 4.12 */ - } *kerns; + short style; + int kernpairs; + struct kerns { + unsigned char ch1, ch2; + short offset; /* 4.12 */ + } *kerns; } *stylekerns; char *psnames[48]; struct fond *next; } FOND; struct MacFontRec { - short fontType; - short firstChar; - short lastChar; - short widthMax; - short kernMax; /* bb learing */ - short Descent; /* maximum negative distance below baseline*/ - short fRectWidth; /* bounding box width */ - short fRectHeight; /* bounding box height */ - unsigned short *offsetWidths;/* offset to start of offset/width table */ - /* 0xffff => undefined, else high byte is offset in locTable, */ - /* low byte is width */ - short ascent; - short descent; - short leading; - short rowWords; /* shorts per row */ - unsigned short *fontImage; /* rowWords*fRectHeight */ - /* Images for all characters plus one extra for undefined */ - unsigned short *locs; /* lastchar-firstchar+3 words */ - /* Horizontal offset to start of n'th character. Note: applies */ - /* to each row. Missing characters have same loc as following */ + short fontType; + short firstChar; + short lastChar; + short widthMax; + short kernMax; /* bb learing */ + short Descent; /* maximum negative distance below baseline */ + short fRectWidth; /* bounding box width */ + short fRectHeight; /* bounding box height */ + unsigned short *offsetWidths; /* offset to start of offset/width table */ + /* 0xffff => undefined, else high byte is offset in locTable, */ + /* low byte is width */ + short ascent; + short descent; + short leading; + short rowWords; /* shorts per row */ + unsigned short *fontImage; /* rowWords*fRectHeight */ + /* Images for all characters plus one extra for undefined */ + unsigned short *locs; /* lastchar-firstchar+3 words */ + /* Horizontal offset to start of n'th character. Note: applies */ + /* to each row. Missing characters have same loc as following */ }; -static void FondListFree(FOND *list) { +static void FondListFree(FOND * list) +{ FOND *next; int i; - while ( list!=NULL ) { - next = list->next; - free(list->assoc); - for ( i=0; i<list->stylewidthcnt; ++i ) - free(list->stylewidths[i].widthtab); - free(list->stylewidths); - for ( i=0; i<list->stylekerncnt; ++i ) - free(list->stylekerns[i].kerns); - free(list->stylekerns); - for ( i=0; i<48; ++i ) - free(list->psnames[i]); - free(list); - list = next; + while (list != NULL) { + next = list->next; + free(list->assoc); + for (i = 0; i < list->stylewidthcnt; ++i) + free(list->stylewidths[i].widthtab); + free(list->stylewidths); + for (i = 0; i < list->stylekerncnt; ++i) + free(list->stylekerns[i].kerns); + free(list->stylekerns); + for (i = 0; i < 48; ++i) + free(list->psnames[i]); + free(list); + list = next; } } @@ -526,180 +550,190 @@ static void FondListFree(FOND *list) { /* to get the font association tables */ /* to get the style flags */ /* http://developer.apple.com/techpubs/mac/Text/Text-269.html */ -static FOND *BuildFondList(FILE *f,long rlistpos,int subcnt,long rdata_pos, - long name_list,int flags) { +static FOND *BuildFondList(FILE * f, long rlistpos, int subcnt, long rdata_pos, + long name_list, int flags) +{ long here, start = ftell(f); long offset; int rname = -1; char name[300]; int ch1, ch2; int i, j, k, cnt, isfixed; - FOND *head=NULL, *cur; + FOND *head = NULL, *cur; long widoff, kernoff, styleoff; - fseek(f,rlistpos,SEEK_SET); - for ( i=0; i<subcnt; ++i ) { - /* resource id = */ getushort(f); - rname = (short) getushort(f); - /* flags = */ getc(f); - ch1 = getc(f); ch2 = getc(f); - offset = rdata_pos+((ch1<<16)|(ch2<<8)|getc(f)); - /* mbz = */ getlong(f); - here = ftell(f); - - cur = gcalloc(1,sizeof(FOND)); - cur->next = head; - head = cur; - - if ( rname!=-1 ) { - fseek(f,name_list+rname,SEEK_SET); - ch1 = getc(f); - fread(name,1,ch1,f); - name[ch1] = '\0'; - cur->fondname = copy(name); - } - - offset += 4; - fseek(f,offset,SEEK_SET); - isfixed = getushort(f)&0x8000?1:0; - /* family id = */ getushort(f); - cur->first = getushort(f); - cur->last = getushort(f); + fseek(f, rlistpos, SEEK_SET); + for (i = 0; i < subcnt; ++i) { + /* resource id = */ getushort(f); + rname = (short) getushort(f); + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + offset = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); + here = ftell(f); + + cur = gcalloc(1, sizeof(FOND)); + cur->next = head; + head = cur; + + if (rname != -1) { + fseek(f, name_list + rname, SEEK_SET); + ch1 = getc(f); + fread(name, 1, ch1, f); + name[ch1] = '\0'; + cur->fondname = copy(name); + } + + offset += 4; + fseek(f, offset, SEEK_SET); + isfixed = getushort(f) & 0x8000 ? 1 : 0; + /* family id = */ getushort(f); + cur->first = getushort(f); + cur->last = getushort(f); /* on a 1 point font... */ - /* ascent = */ getushort(f); - /* descent = (short) */ getushort(f); - /* leading = */ getushort(f); - /* widmax = */ getushort(f); - if ( (widoff = getlong(f))!=0 ) widoff += offset; - if ( (kernoff = getlong(f))!=0 ) kernoff += offset; - if ( (styleoff = getlong(f))!=0 ) styleoff += offset; - for ( j=0; j<9; ++j ) - getushort(f); - /* internal & undefined, for international scripts = */ getlong(f); - /* version = */ getushort(f); - cur->assoc_cnt = getushort(f)+1; - cur->assoc = gcalloc(cur->assoc_cnt,sizeof(struct assoc)); - for ( j=0; j<cur->assoc_cnt; ++j ) { - cur->assoc[j].size = getushort(f); - cur->assoc[j].style = getushort(f); - cur->assoc[j].id = getushort(f); - } - if ( widoff!=0 ) { - fseek(f,widoff,SEEK_SET); - cnt = getushort(f)+1; - cur->stylewidthcnt = cnt; - cur->stylewidths = gcalloc(cnt,sizeof(struct stylewidths)); - for ( j=0; j<cnt; ++j ) { - cur->stylewidths[j].style = getushort(f); - cur->stylewidths[j].widthtab = galloc((cur->last-cur->first+3)*sizeof(short)); - for ( k=cur->first; k<=cur->last+2; ++k ) - cur->stylewidths[j].widthtab[k] = getushort(f); - } - } - if ( kernoff!=0 && (flags&ttf_onlykerns) ) { - fseek(f,kernoff,SEEK_SET); - cnt = getushort(f)+1; - cur->stylekerncnt = cnt; - cur->stylekerns = gcalloc(cnt,sizeof(struct stylekerns)); - for ( j=0; j<cnt; ++j ) { - cur->stylekerns[j].style = getushort(f); - cur->stylekerns[j].kernpairs = getushort(f); - cur->stylekerns[j].kerns = galloc(cur->stylekerns[j].kernpairs*sizeof(struct kerns)); - for ( k=0; k<cur->stylekerns[j].kernpairs; ++k ) { - cur->stylekerns[j].kerns[k].ch1 = getc(f); - cur->stylekerns[j].kerns[k].ch2 = getc(f); - cur->stylekerns[j].kerns[k].offset = getushort(f); - } - } - } - if ( styleoff!=0 ) { - uint8 stringoffsets[48]; - int strcnt, stringlen, format; - char **strings, *pt; - fseek(f,styleoff,SEEK_SET); - /* class = */ getushort(f); - /* glyph encoding offset = */ getlong(f); - /* reserved = */ getlong(f); - for ( j=0; j<48; ++j ) - stringoffsets[j] = getc(f); - strcnt = getushort(f); - strings = galloc(strcnt*sizeof(char *)); - for ( j=0; j<strcnt; ++j ) { - stringlen = getc(f); - strings[j] = galloc(stringlen+2); - strings[j][0] = stringlen; - strings[j][stringlen+1] = '\0'; - for ( k=0; k<stringlen; ++k ) - strings[j][k+1] = getc(f); - } - for ( j=0; j<48; ++j ) { - for ( k=j-1; k>=0; --k ) - if ( stringoffsets[j]==stringoffsets[k] ) - break; - if ( k!=-1 ) - continue; /* this style doesn't exist */ - format = stringoffsets[j]-1; - stringlen = strings[0][0]; - if ( format!=0 ) - for ( k=0; k<strings[format][0]; ++k ) - stringlen += strings[ strings[format][k+1]-1 ][0]; - pt = cur->psnames[j] = galloc(stringlen+1); - strcpy(pt,strings[ 0 ]+1); - pt += strings[ 0 ][0]; - if ( format!=0 ) - for ( k=0; k<strings[format][0]; ++k ) { - strcpy(pt,strings[ strings[format][k+1]-1 ]+1); - pt += strings[ strings[format][k+1]-1 ][0]; - } - *pt = '\0'; - } - for ( j=0; j<strcnt; ++j ) - free(strings[j]); - free(strings); - } - fseek(f,here,SEEK_SET); + /* ascent = */ getushort(f); + /* descent = (short) */ getushort(f); + /* leading = */ getushort(f); + /* widmax = */ getushort(f); + if ((widoff = getlong(f)) != 0) + widoff += offset; + if ((kernoff = getlong(f)) != 0) + kernoff += offset; + if ((styleoff = getlong(f)) != 0) + styleoff += offset; + for (j = 0; j < 9; ++j) + getushort(f); + /* internal & undefined, for international scripts = */ getlong(f); + /* version = */ getushort(f); + cur->assoc_cnt = getushort(f) + 1; + cur->assoc = gcalloc(cur->assoc_cnt, sizeof(struct assoc)); + for (j = 0; j < cur->assoc_cnt; ++j) { + cur->assoc[j].size = getushort(f); + cur->assoc[j].style = getushort(f); + cur->assoc[j].id = getushort(f); + } + if (widoff != 0) { + fseek(f, widoff, SEEK_SET); + cnt = getushort(f) + 1; + cur->stylewidthcnt = cnt; + cur->stylewidths = gcalloc(cnt, sizeof(struct stylewidths)); + for (j = 0; j < cnt; ++j) { + cur->stylewidths[j].style = getushort(f); + cur->stylewidths[j].widthtab = + galloc((cur->last - cur->first + 3) * sizeof(short)); + for (k = cur->first; k <= cur->last + 2; ++k) + cur->stylewidths[j].widthtab[k] = getushort(f); + } + } + if (kernoff != 0 && (flags & ttf_onlykerns)) { + fseek(f, kernoff, SEEK_SET); + cnt = getushort(f) + 1; + cur->stylekerncnt = cnt; + cur->stylekerns = gcalloc(cnt, sizeof(struct stylekerns)); + for (j = 0; j < cnt; ++j) { + cur->stylekerns[j].style = getushort(f); + cur->stylekerns[j].kernpairs = getushort(f); + cur->stylekerns[j].kerns = + galloc(cur->stylekerns[j].kernpairs * sizeof(struct kerns)); + for (k = 0; k < cur->stylekerns[j].kernpairs; ++k) { + cur->stylekerns[j].kerns[k].ch1 = getc(f); + cur->stylekerns[j].kerns[k].ch2 = getc(f); + cur->stylekerns[j].kerns[k].offset = getushort(f); + } + } + } + if (styleoff != 0) { + uint8 stringoffsets[48]; + int strcnt, stringlen, format; + char **strings, *pt; + fseek(f, styleoff, SEEK_SET); + /* class = */ getushort(f); + /* glyph encoding offset = */ getlong(f); + /* reserved = */ getlong(f); + for (j = 0; j < 48; ++j) + stringoffsets[j] = getc(f); + strcnt = getushort(f); + strings = galloc(strcnt * sizeof(char *)); + for (j = 0; j < strcnt; ++j) { + stringlen = getc(f); + strings[j] = galloc(stringlen + 2); + strings[j][0] = stringlen; + strings[j][stringlen + 1] = '\0'; + for (k = 0; k < stringlen; ++k) + strings[j][k + 1] = getc(f); + } + for (j = 0; j < 48; ++j) { + for (k = j - 1; k >= 0; --k) + if (stringoffsets[j] == stringoffsets[k]) + break; + if (k != -1) + continue; /* this style doesn't exist */ + format = stringoffsets[j] - 1; + stringlen = strings[0][0]; + if (format != 0) + for (k = 0; k < strings[format][0]; ++k) + stringlen += strings[strings[format][k + 1] - 1][0]; + pt = cur->psnames[j] = galloc(stringlen + 1); + strcpy(pt, strings[0] + 1); + pt += strings[0][0]; + if (format != 0) + for (k = 0; k < strings[format][0]; ++k) { + strcpy(pt, strings[strings[format][k + 1] - 1] + 1); + pt += strings[strings[format][k + 1] - 1][0]; + } + *pt = '\0'; + } + for (j = 0; j < strcnt; ++j) + free(strings[j]); + free(strings); + } + fseek(f, here, SEEK_SET); } - fseek(f,start,SEEK_SET); -return( head ); + fseek(f, start, SEEK_SET); + return (head); } -static char *BuildName(char *family,int style) { +static char *BuildName(char *family, int style) +{ char buffer[350]; - strncpy(buffer,family,200); - if ( style!=0 ) - strcat(buffer,"-"); - if ( style&sf_bold ) - strcat(buffer,"Bold"); - if ( style&sf_italic ) - strcat(buffer,"Italic"); - if ( style&sf_underline ) - strcat(buffer,"Underline"); - if ( style&sf_outline ) - strcat(buffer,"Outline"); - if ( style&sf_shadow ) - strcat(buffer,"Shadow"); - if ( style&sf_condense ) - strcat(buffer,"Condensed"); - if ( style&sf_extend ) - strcat(buffer,"Extended"); -return( copy(buffer)); + strncpy(buffer, family, 200); + if (style != 0) + strcat(buffer, "-"); + if (style & sf_bold) + strcat(buffer, "Bold"); + if (style & sf_italic) + strcat(buffer, "Italic"); + if (style & sf_underline) + strcat(buffer, "Underline"); + if (style & sf_outline) + strcat(buffer, "Outline"); + if (style & sf_shadow) + strcat(buffer, "Shadow"); + if (style & sf_condense) + strcat(buffer, "Condensed"); + if (style & sf_extend) + strcat(buffer, "Extended"); + return (copy(buffer)); } -static int GuessStyle(char *fontname,int *styles,int style_cnt) { +static int GuessStyle(char *fontname, int *styles, int style_cnt) +{ int which, style; - char *stylenames = _GetModifiers(fontname,NULL,NULL); + char *stylenames = _GetModifiers(fontname, NULL, NULL); - style = _MacStyleCode(stylenames,NULL,NULL); - for ( which = style_cnt; which>=0; --which ) - if ( styles[which] == style ) -return( which ); + style = _MacStyleCode(stylenames, NULL, NULL); + for (which = style_cnt; which >= 0; --which) + if (styles[which] == style) + return (which); -return( -1 ); + return (-1); } -static FOND *PickFOND(FOND *fondlist,char *filename,char **name, int *style) { - int i,j; +static FOND *PickFOND(FOND * fondlist, char *filename, char **name, int *style) +{ + int i, j; FOND *test; uint8 stylesused[96]; char **names; @@ -709,163 +743,180 @@ static FOND *PickFOND(FOND *fondlist,char *filename,char **name, int *style) { char *pt, *lparen; char *find = NULL; - if ((pt = strrchr(filename,'/'))!=NULL ) pt = filename; - if ( (lparen = strchr(filename,'('))!=NULL && strchr(lparen,')')!=NULL ) { - find = copy(lparen+1); - pt = strchr(find,')'); - if ( pt!=NULL ) *pt='\0'; - for ( test=fondlist; test!=NULL; test=test->next ) { - for ( i=0; i<48; ++i ) - if ( test->psnames[i]!=NULL && strcmp(find,test->psnames[i])==0 ) { - *style = (i&3) | ((i&~3)<<1); /* PS styles skip underline bit */ - *name = copy(test->psnames[i]); -return( test ); - } - } + if ((pt = strrchr(filename, '/')) != NULL) + pt = filename; + if ((lparen = strchr(filename, '(')) != NULL && strchr(lparen, ')') != NULL) { + find = copy(lparen + 1); + pt = strchr(find, ')'); + if (pt != NULL) + *pt = '\0'; + for (test = fondlist; test != NULL; test = test->next) { + for (i = 0; i < 48; ++i) + if (test->psnames[i] != NULL + && strcmp(find, test->psnames[i]) == 0) { + *style = (i & 3) | ((i & ~3) << 1); /* PS styles skip underline bit */ + *name = copy(test->psnames[i]); + return (test); + } + } } /* The file may contain multiple families, and each family may contain */ /* multiple styles (and each style may contain multiple sizes, but that's */ /* not an issue for us here) */ names = NULL; - for ( i=0; i<2; ++i ) { - cnt = 0; - for ( test=fondlist; test!=NULL; test=test->next ) if ( test->fondname!=NULL ) { - memset(stylesused,0,sizeof(stylesused)); - for ( j=0; j<test->assoc_cnt; ++j ) { - if ( test->assoc[j].size!=0 && !stylesused[test->assoc[j].style]) { - stylesused[test->assoc[j].style]=true; - if ( names!=NULL ) { - names[cnt] = BuildName(test->fondname,test->assoc[j].style); - styles[cnt] = test->assoc[j].style; - fonds[cnt] = test; - } - ++cnt; - } - } - } - if ( names==NULL ) { - names = gcalloc(cnt+1,sizeof(char *)); - fonds = galloc(cnt*sizeof(FOND *)); - styles = galloc(cnt*sizeof(int)); - } + for (i = 0; i < 2; ++i) { + cnt = 0; + for (test = fondlist; test != NULL; test = test->next) + if (test->fondname != NULL) { + memset(stylesused, 0, sizeof(stylesused)); + for (j = 0; j < test->assoc_cnt; ++j) { + if (test->assoc[j].size != 0 + && !stylesused[test->assoc[j].style]) { + stylesused[test->assoc[j].style] = true; + if (names != NULL) { + names[cnt] = + BuildName(test->fondname, test->assoc[j].style); + styles[cnt] = test->assoc[j].style; + fonds[cnt] = test; + } + ++cnt; + } + } + } + if (names == NULL) { + names = gcalloc(cnt + 1, sizeof(char *)); + fonds = galloc(cnt * sizeof(FOND *)); + styles = galloc(cnt * sizeof(int)); + } } - if ( find!=NULL ) { - for ( which=cnt-1; which>=0; --which ) - if ( strcmp(names[which],find)==0 ) - break; - if ( which==-1 && strstrmatch(find,test->fondname)!=NULL ) - which = GuessStyle(find,styles,cnt); - if ( which==-1 ) { - char *fn = copy(filename); - fn[lparen-filename] = '\0'; - ff_post_error(_("Not in Collection"),_("%s is not in %.100s"),find,fn); - free(fn); - } - free(find); - } else - which = 0; - - if ( which!=-1 ) { - fond = fonds[which]; - *name = copy(names[which]); - *style = styles[which]; + if (find != NULL) { + for (which = cnt - 1; which >= 0; --which) + if (strcmp(names[which], find) == 0) + break; + if (which == -1 && strstrmatch(find, test->fondname) != NULL) + which = GuessStyle(find, styles, cnt); + if (which == -1) { + char *fn = copy(filename); + fn[lparen - filename] = '\0'; + ff_post_error(_("Not in Collection"), _("%s is not in %.100s"), + find, fn); + free(fn); + } + free(find); + } else + which = 0; + + if (which != -1) { + fond = fonds[which]; + *name = copy(names[which]); + *style = styles[which]; } - for ( i=0; i<cnt; ++i ) - free(names[i]); - free(names); free(fonds); free(styles); - if ( which==-1 ) -return( NULL ); - -return( fond ); + for (i = 0; i < cnt; ++i) + free(names[i]); + free(names); + free(fonds); + free(styles); + if (which == -1) + return (NULL); + + return (fond); } /* Look for kerning info and merge it into the currently existing font "into" */ -static SplineFont *FindFamilyStyleKerns(SplineFont *into,EncMap *map,FOND *fondlist,char *filename) { +static SplineFont *FindFamilyStyleKerns(SplineFont * into, EncMap * map, + FOND * fondlist, char *filename) +{ char *name; int style; FOND *fond; - int i,j; + int i, j; int ch1, ch2, offset; KernPair *kp; SplineChar *sc1, *sc2; - fond = PickFOND(fondlist,filename,&name,&style); - if ( fond==NULL || into==NULL ) -return( NULL ); - for ( i=0; i<fond->stylekerncnt; ++i ) - if ( fond->stylekerns[i].style==style ) - break; - if ( i==fond->stylekerncnt ) { - LogError(_("No kerning table for %s\n"), name ); - free(name); -return( NULL ); + fond = PickFOND(fondlist, filename, &name, &style); + if (fond == NULL || into == NULL) + return (NULL); + for (i = 0; i < fond->stylekerncnt; ++i) + if (fond->stylekerns[i].style == style) + break; + if (i == fond->stylekerncnt) { + LogError(_("No kerning table for %s\n"), name); + free(name); + return (NULL); } - for ( j=0; j<fond->stylekerns[i].kernpairs; ++j ) { - ch1 = fond->stylekerns[i].kerns[j].ch1; - ch2 = fond->stylekerns[i].kerns[j].ch2; - offset = (fond->stylekerns[i].kerns[j].offset*(into->ascent+into->descent)+(1<<11))>>12; - sc1 = SFMakeChar(into,map,ch1); - sc2 = SFMakeChar(into,map,ch2); - for ( kp=sc1->kerns; kp!=NULL; kp=kp->next ) - if ( kp->sc==sc2 ) - break; - if ( kp==NULL ) { - uint32 script; - kp = chunkalloc(sizeof(KernPair)); - kp->sc = sc2; - kp->next = sc1->kerns; - sc1->kerns = kp; - script = SCScriptFromUnicode(sc1); - if ( script==DEFAULT_SCRIPT ) - script = SCScriptFromUnicode(sc2); - kp->subtable = SFSubTableFindOrMake(sc1->parent,CHR('k','e','r','n'), - script, gpos_pair); - } - kp->off = offset; + for (j = 0; j < fond->stylekerns[i].kernpairs; ++j) { + ch1 = fond->stylekerns[i].kerns[j].ch1; + ch2 = fond->stylekerns[i].kerns[j].ch2; + offset = + (fond->stylekerns[i].kerns[j].offset * + (into->ascent + into->descent) + (1 << 11)) >> 12; + sc1 = SFMakeChar(into, map, ch1); + sc2 = SFMakeChar(into, map, ch2); + for (kp = sc1->kerns; kp != NULL; kp = kp->next) + if (kp->sc == sc2) + break; + if (kp == NULL) { + uint32 script; + kp = chunkalloc(sizeof(KernPair)); + kp->sc = sc2; + kp->next = sc1->kerns; + sc1->kerns = kp; + script = SCScriptFromUnicode(sc1); + if (script == DEFAULT_SCRIPT) + script = SCScriptFromUnicode(sc2); + kp->subtable = + SFSubTableFindOrMake(sc1->parent, CHR('k', 'e', 'r', 'n'), + script, gpos_pair); + } + kp->off = offset; } -return( into ); + return (into); } /* Look for a bare truetype font in a binhex/macbinary wrapper */ -static SplineFont *MightBeTrueType(FILE *binary,int32 pos,int32 dlen,int flags, - enum openflags openflags) { +static SplineFont *MightBeTrueType(FILE * binary, int32 pos, int32 dlen, + int flags, enum openflags openflags) +{ FILE *temp = tmpfile(); char *buffer = galloc(8192); int len; SplineFont *sf; - if ( flags&ttf_onlynames ) { - char **ret; - char *temp = TTFGetFontName(binary,pos,pos); - if ( temp==NULL ) -return( NULL ); - ret = galloc(2*sizeof(char *)); - ret[0] = temp; - ret[1] = NULL; -return( (SplineFont *) ret ); + if (flags & ttf_onlynames) { + char **ret; + char *temp = TTFGetFontName(binary, pos, pos); + if (temp == NULL) + return (NULL); + ret = galloc(2 * sizeof(char *)); + ret[0] = temp; + ret[1] = NULL; + return ((SplineFont *) ret); } - fseek(binary,pos,SEEK_SET); - while ( dlen>0 ) { - len = dlen > 8192 ? 8192 : dlen; - len = fread(buffer,1,dlen > 8192 ? 8192 : dlen,binary); - if ( len==0 ) - break; - fwrite(buffer,1,len,temp); - dlen -= len; + fseek(binary, pos, SEEK_SET); + while (dlen > 0) { + len = dlen > 8192 ? 8192 : dlen; + len = fread(buffer, 1, dlen > 8192 ? 8192 : dlen, binary); + if (len == 0) + break; + fwrite(buffer, 1, len, temp); + dlen -= len; } rewind(temp); - sf = _SFReadTTF(temp,flags,openflags,NULL,NULL); + sf = _SFReadTTF(temp, flags, openflags, NULL, NULL); fclose(temp); free(buffer); -return( sf ); + return (sf); } -static SplineFont *IsResourceFork(FILE *f, long offset,char *filename,int flags, - enum openflags openflags, SplineFont *into,EncMap *map) { +static SplineFont *IsResourceFork(FILE * f, long offset, char *filename, + int flags, enum openflags openflags, + SplineFont * into, EncMap * map) +{ /* If it is a good resource fork then the first 16 bytes are repeated */ /* at the location specified in bytes 4-7 */ /* We include an offset because if we are looking at a mac binary file */ @@ -876,326 +927,599 @@ static SplineFont *IsResourceFork(FILE *f, long offset,char *filename,int flags, int32 rdata_len, map_len; uint32 nfnt_pos, font_pos, fond_pos; unsigned long tag; - int i, cnt, subcnt, nfnt_subcnt=0, font_subcnt=0, fond_subcnt=0; + int i, cnt, subcnt, nfnt_subcnt = 0, font_subcnt = 0, fond_subcnt = 0; SplineFont *sf; - FOND *fondlist=NULL; - fond_pos=0; - fseek(f,offset,SEEK_SET); - if ( fread(buffer,1,16,f)!=16 ) -return( NULL ); - rdata_pos = offset + ((buffer[0]<<24)|(buffer[1]<<16)|(buffer[2]<<8)|buffer[3]); - map_pos = offset + ((buffer[4]<<24)|(buffer[5]<<16)|(buffer[6]<<8)|buffer[7]); - rdata_len = ((buffer[8]<<24)|(buffer[9]<<16)|(buffer[10]<<8)|buffer[11]); - map_len = ((buffer[12]<<24)|(buffer[13]<<16)|(buffer[14]<<8)|buffer[15]); - if ( rdata_pos+rdata_len!=map_pos || rdata_len==0 ) -return( NULL ); - fseek(f,map_pos,SEEK_SET); - buffer2[15] = buffer[15]+1; /* make it be different */ - if ( fread(buffer2,1,16,f)!=16 ) -return( NULL ); + FOND *fondlist = NULL; + fond_pos = 0; + fseek(f, offset, SEEK_SET); + if (fread(buffer, 1, 16, f) != 16) + return (NULL); + rdata_pos = + offset + + ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); + map_pos = + offset + + ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]); + rdata_len = + ((buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | + buffer[11]); + map_len = + ((buffer[12] << 24) | (buffer[13] << 16) | (buffer[14] << 8) | + buffer[15]); + if (rdata_pos + rdata_len != map_pos || rdata_len == 0) + return (NULL); + fseek(f, map_pos, SEEK_SET); + buffer2[15] = buffer[15] + 1; /* make it be different */ + if (fread(buffer2, 1, 16, f) != 16) + return (NULL); /* Apple's data fork resources appear to have a bunch of zeroes here instead */ /* of a copy of the first 16 bytes */ - for ( i=0; i<16; ++i ) - if ( buffer2[i]!=0 ) - break; - if ( i!=16 ) { - for ( i=0; i<16; ++i ) - if ( buffer[i]!=buffer2[i] ) -return( NULL ); + for (i = 0; i < 16; ++i) + if (buffer2[i] != 0) + break; + if (i != 16) { + for (i = 0; i < 16; ++i) + if (buffer[i] != buffer2[i]) + return (NULL); } - getlong(f); /* skip the handle to the next resource map */ - getushort(f); /* skip the file resource number */ - getushort(f); /* skip the attributes */ + getlong(f); /* skip the handle to the next resource map */ + getushort(f); /* skip the file resource number */ + getushort(f); /* skip the attributes */ type_list = map_pos + getushort(f); name_list = map_pos + getushort(f); - fseek(f,type_list,SEEK_SET); - cnt = getushort(f)+1; - for ( i=0; i<cnt; ++i ) { - tag = getlong(f); - /* printf( "%c%c%c%c\n", tag>>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff );*/ - subcnt = getushort(f)+1; - rpos = type_list+getushort(f); - sf = NULL; - if ( tag==CHR('P','O','S','T') && !(flags&(ttf_onlystrikes|ttf_onlykerns))) /* No FOND */ - sf = SearchPostscriptResources(f,rpos,subcnt,rdata_pos,name_list,flags); - else if ( tag==CHR('s','f','n','t') && !(flags&ttf_onlykerns)) - sf = SearchTtfResources(f,rpos,subcnt,rdata_pos,name_list,filename,flags,openflags); - else if ( tag==CHR('N','F','N','T') ) { - nfnt_pos = rpos; - nfnt_subcnt = subcnt; - } else if ( tag==CHR('F','O','N','T') ) { - font_pos = rpos; - font_subcnt = subcnt; - } else if ( tag==CHR('F','O','N','D') ) { - fond_pos = rpos; - fond_subcnt = subcnt; - } - if ( sf!=NULL ) -return( sf ); + fseek(f, type_list, SEEK_SET); + cnt = getushort(f) + 1; + for (i = 0; i < cnt; ++i) { + tag = getlong(f); + /* printf( "%c%c%c%c\n", tag>>24, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff ); */ + subcnt = getushort(f) + 1; + rpos = type_list + getushort(f); + sf = NULL; + if (tag == CHR('P', 'O', 'S', 'T') && !(flags & (ttf_onlystrikes | ttf_onlykerns))) /* No FOND */ + sf = SearchPostscriptResources(f, rpos, subcnt, rdata_pos, + name_list, flags); + else if (tag == CHR('s', 'f', 'n', 't') && !(flags & ttf_onlykerns)) + sf = SearchTtfResources(f, rpos, subcnt, rdata_pos, name_list, + filename, flags, openflags); + else if (tag == CHR('N', 'F', 'N', 'T')) { + nfnt_pos = rpos; + nfnt_subcnt = subcnt; + } else if (tag == CHR('F', 'O', 'N', 'T')) { + font_pos = rpos; + font_subcnt = subcnt; + } else if (tag == CHR('F', 'O', 'N', 'D')) { + fond_pos = rpos; + fond_subcnt = subcnt; + } + if (sf != NULL) + return (sf); } - if ( flags&ttf_onlynames ) /* Not interested in bitmap resources here */ -return( NULL ); - - if ( flags&ttf_onlykerns ) { /* For kerns */ - if ( fond_subcnt!=0 ) - fondlist = BuildFondList(f,fond_pos,fond_subcnt,rdata_pos,name_list,flags); - into = FindFamilyStyleKerns(into,map,fondlist,filename); - FondListFree(fondlist); -return( into ); + if (flags & ttf_onlynames) /* Not interested in bitmap resources here */ + return (NULL); + + if (flags & ttf_onlykerns) { /* For kerns */ + if (fond_subcnt != 0) + fondlist = + BuildFondList(f, fond_pos, fond_subcnt, rdata_pos, name_list, + flags); + into = FindFamilyStyleKerns(into, map, fondlist, filename); + FondListFree(fondlist); + return (into); } /* Ok. If no outline font, try for a bitmap */ - if ( nfnt_subcnt==0 ) { - nfnt_pos = font_pos; - nfnt_subcnt = font_subcnt; + if (nfnt_subcnt == 0) { + nfnt_pos = font_pos; + nfnt_subcnt = font_subcnt; } -return( (SplineFont *) -1 ); /* It's a valid resource file, but just has no fonts */ + return ((SplineFont *) - 1); /* It's a valid resource file, but just has no fonts */ } -static SplineFont *IsResourceInBinary(FILE *f,char *filename,int flags, - enum openflags openflags, SplineFont *into,EncMap *map) { +static SplineFont *IsResourceInBinary(FILE * f, char *filename, int flags, + enum openflags openflags, + SplineFont * into, EncMap * map) +{ unsigned char header[128]; unsigned long offset, dlen, rlen; - if ( fread(header,1,128,f)!=128 ) -return( NULL ); - if ( header[0]!=0 || header[74]!=0 || header[82]!=0 || header[1]<=0 || - header[1]>33 || header[63]!=0 || header[2+header[1]]!=0 ) -return( NULL ); - dlen = ((header[0x53]<<24)|(header[0x54]<<16)|(header[0x55]<<8)|header[0x56]); - rlen = ((header[0x57]<<24)|(header[0x58]<<16)|(header[0x59]<<8)|header[0x5a]); - /* 128 bytes for header, then the dlen is padded to a 128 byte boundary */ - offset = 128 + ((dlen+127)&~127); + if (fread(header, 1, 128, f) != 128) + return (NULL); + if (header[0] != 0 || header[74] != 0 || header[82] != 0 || header[1] <= 0 + || header[1] > 33 || header[63] != 0 || header[2 + header[1]] != 0) + return (NULL); + dlen = + ((header[0x53] << 24) | (header[0x54] << 16) | (header[0x55] << 8) | + header[0x56]); + rlen = + ((header[0x57] << 24) | (header[0x58] << 16) | (header[0x59] << 8) | + header[0x5a]); + /* 128 bytes for header, then the dlen is padded to a 128 byte boundary */ + offset = 128 + ((dlen + 127) & ~127); /* Look for a bare truetype font in a binhex/macbinary wrapper */ - if ( dlen!=0 && rlen<=dlen) { - int pos = ftell(f); - fread(header,1,4,f); - header[5] = '\0'; - if ( strcmp((char *) header,"OTTO")==0 || strcmp((char *) header,"true")==0 || - strcmp((char *) header,"ttcf")==0 || - (header[0]==0 && header[1]==1 && header[2]==0 && header[3]==0)) -return( MightBeTrueType(f,pos,dlen,flags,openflags)); + if (dlen != 0 && rlen <= dlen) { + int pos = ftell(f); + fread(header, 1, 4, f); + header[5] = '\0'; + if (strcmp((char *) header, "OTTO") == 0 + || strcmp((char *) header, "true") == 0 + || strcmp((char *) header, "ttcf") == 0 || (header[0] == 0 + && header[1] == 1 + && header[2] == 0 + && header[3] == 0)) + return (MightBeTrueType(f, pos, dlen, flags, openflags)); } -return( IsResourceFork(f,offset,filename,flags,openflags,into,map)); + return (IsResourceFork(f, offset, filename, flags, openflags, into, map)); } -static int lastch=0, repeat = 0; -static void outchr(FILE *binary, int ch) { +static int lastch = 0, repeat = 0; +static void outchr(FILE * binary, int ch) +{ int i; - if ( repeat ) { - if ( ch==0 ) { - /* no repeat, output a literal 0x90 (the repeat flag) */ - lastch=0x90; - putc(lastch,binary); - } else { - for ( i=1; i<ch; ++i ) - putc(lastch,binary); - } - repeat = 0; - } else if ( ch==0x90 ) { - repeat = 1; + if (repeat) { + if (ch == 0) { + /* no repeat, output a literal 0x90 (the repeat flag) */ + lastch = 0x90; + putc(lastch, binary); + } else { + for (i = 1; i < ch; ++i) + putc(lastch, binary); + } + repeat = 0; + } else if (ch == 0x90) { + repeat = 1; } else { - putc(ch,binary); - lastch = ch; + putc(ch, binary); + lastch = ch; } } -static SplineFont *IsResourceInHex(FILE *f,char *filename,int flags,enum openflags openflags, - SplineFont *into,EncMap *map) { +static SplineFont *IsResourceInHex(FILE * f, char *filename, int flags, + enum openflags openflags, SplineFont * into, + EncMap * map) +{ /* convert file from 6bit to 8bit */ /* interesting data is enclosed between two colons */ FILE *binary = tmpfile(); - char *sixbit = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; + char *sixbit = + "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; int ch, val, cnt, i, dlen, rlen; - unsigned char header[20]; char *pt; + unsigned char header[20]; + char *pt; SplineFont *ret; - if ( binary==NULL ) { - LogError( _("can't create temporary file\n") ); -return( NULL ); + if (binary == NULL) { + LogError(_("can't create temporary file\n")); + return (NULL); } lastch = repeat = 0; - while ( (ch=getc(f))!=':' ); /* There may be comments before file start */ + while ((ch = getc(f)) != ':'); /* There may be comments before file start */ cnt = val = 0; - while ( (ch=getc(f))!=':' ) { - if ( isspace(ch)) - continue; - for ( pt=sixbit; *pt!=ch && *pt!='\0'; ++pt ); - if ( *pt=='\0' ) { - fclose(binary); -return( NULL ); - } - val = (val<<6) | (pt-sixbit); - if ( ++cnt==4 ) { - outchr(binary,(val>>16)&0xff); - outchr(binary,(val>>8)&0xff); - outchr(binary,val&0xff); - val = cnt = 0; - } + while ((ch = getc(f)) != ':') { + if (isspace(ch)) + continue; + for (pt = sixbit; *pt != ch && *pt != '\0'; ++pt); + if (*pt == '\0') { + fclose(binary); + return (NULL); + } + val = (val << 6) | (pt - sixbit); + if (++cnt == 4) { + outchr(binary, (val >> 16) & 0xff); + outchr(binary, (val >> 8) & 0xff); + outchr(binary, val & 0xff); + val = cnt = 0; + } } - if ( cnt!=0 ) { - if ( cnt==1 ) - outchr(binary,val<<2); - else if ( cnt==2 ) { - val<<=4; - outchr(binary,(val>>8)&0xff); - outchr(binary,val&0xff); - } else if ( cnt==3 ) { - val<<=6; - outchr(binary,(val>>16)&0xff); - outchr(binary,(val>>8)&0xff); - outchr(binary,val&0xff); - } + if (cnt != 0) { + if (cnt == 1) + outchr(binary, val << 2); + else if (cnt == 2) { + val <<= 4; + outchr(binary, (val >> 8) & 0xff); + outchr(binary, val & 0xff); + } else if (cnt == 3) { + val <<= 6; + outchr(binary, (val >> 16) & 0xff); + outchr(binary, (val >> 8) & 0xff); + outchr(binary, val & 0xff); + } } rewind(binary); - ch = getc(binary); /* Name length */ + ch = getc(binary); /* Name length */ /* skip name */ - for ( i=0; i<ch; ++i ) - getc(binary); - if ( getc(binary)!='\0' ) { - fclose(binary); -return( NULL ); + for (i = 0; i < ch; ++i) + getc(binary); + if (getc(binary) != '\0') { + fclose(binary); + return (NULL); } - fread(header,1,20,binary); - dlen = (header[10]<<24)|(header[11]<<16)|(header[12]<<8)|header[13]; - rlen = (header[14]<<24)|(header[15]<<16)|(header[16]<<8)|header[17]; + fread(header, 1, 20, binary); + dlen = + (header[10] << 24) | (header[11] << 16) | (header[12] << 8) | + header[13]; + rlen = + (header[14] << 24) | (header[15] << 16) | (header[16] << 8) | + header[17]; /* Look for a bare truetype font in a binhex/macbinary wrapper */ - if ( dlen!=0 && rlen<dlen ) { - int pos = ftell(binary); - fread(header,1,4,binary); - header[5] = '\0'; - if ( strcmp((char *) header,"OTTO")==0 || strcmp((char *) header,"true")==0 || - strcmp((char *) header,"ttcf")==0 || - (header[0]==0 && header[1]==1 && header[2]==0 && header[3]==0)) { - ret = MightBeTrueType(binary,pos,dlen,flags,openflags); - fclose(binary); -return( ret ); - } + if (dlen != 0 && rlen < dlen) { + int pos = ftell(binary); + fread(header, 1, 4, binary); + header[5] = '\0'; + if (strcmp((char *) header, "OTTO") == 0 + || strcmp((char *) header, "true") == 0 + || strcmp((char *) header, "ttcf") == 0 || (header[0] == 0 + && header[1] == 1 + && header[2] == 0 + && header[3] == 0)) { + ret = MightBeTrueType(binary, pos, dlen, flags, openflags); + fclose(binary); + return (ret); + } } - if ( rlen==0 ) { - fclose(binary); -return( NULL ); + if (rlen == 0) { + fclose(binary); + return (NULL); } - ret = IsResourceFork(binary,ftell(binary)+dlen+2,filename,flags,openflags,into,map); + ret = + IsResourceFork(binary, ftell(binary) + dlen + 2, filename, flags, + openflags, into, map); fclose(binary); -return( ret ); + return (ret); } -static SplineFont *IsResourceInFile(char *filename,int flags,enum openflags openflags, - SplineFont *into, EncMap *map) { +static SplineFont *IsResourceInFile(char *filename, int flags, + enum openflags openflags, SplineFont * into, + EncMap * map) +{ FILE *f; char *spt, *pt; SplineFont *sf; - char *temp=filename, *lparen; + char *temp = filename, *lparen; - if (( pt=strrchr(filename,'/'))==NULL ) pt = filename; - if ( (lparen = strchr(pt,'('))!=NULL && strchr(lparen,')')!=NULL ) { - temp = copy(filename); - temp[lparen-filename] = '\0'; + if ((pt = strrchr(filename, '/')) == NULL) + pt = filename; + if ((lparen = strchr(pt, '(')) != NULL && strchr(lparen, ')') != NULL) { + temp = copy(filename); + temp[lparen - filename] = '\0'; } - f = fopen(temp,"rb"); - if ( temp!=filename ) free(temp); - if ( f==NULL ) -return( NULL ); - spt = strrchr(filename,'/'); - if ( spt==NULL ) spt = filename; - pt = strrchr(spt,'.'); - if ( pt!=NULL && (pt[1]=='b' || pt[1]=='B') && (pt[2]=='i' || pt[2]=='I') && - (pt[3]=='n' || pt[3]=='N') && (pt[4]=='\0' || pt[4]=='(') ) { - if ( (sf = IsResourceInBinary(f,filename,flags,openflags,into,map))) { - fclose(f); -return( sf ); - } - } else if ( pt!=NULL && (pt[1]=='h' || pt[1]=='H') && (pt[2]=='q' || pt[2]=='Q') && - (pt[3]=='x' || pt[3]=='X') && (pt[4]=='\0' || pt[4]=='(')) { - if ( (sf = IsResourceInHex(f,filename,flags,openflags,into,map))) { - fclose(f); -return( sf ); - } + f = fopen(temp, "rb"); + if (temp != filename) + free(temp); + if (f == NULL) + return (NULL); + spt = strrchr(filename, '/'); + if (spt == NULL) + spt = filename; + pt = strrchr(spt, '.'); + if (pt != NULL && (pt[1] == 'b' || pt[1] == 'B') + && (pt[2] == 'i' || pt[2] == 'I') && (pt[3] == 'n' || pt[3] == 'N') + && (pt[4] == '\0' || pt[4] == '(')) { + if ((sf = IsResourceInBinary(f, filename, flags, openflags, into, map))) { + fclose(f); + return (sf); + } + } else if (pt != NULL && (pt[1] == 'h' || pt[1] == 'H') + && (pt[2] == 'q' || pt[2] == 'Q') && (pt[3] == 'x' + || pt[3] == 'X') + && (pt[4] == '\0' || pt[4] == '(')) { + if ((sf = IsResourceInHex(f, filename, flags, openflags, into, map))) { + fclose(f); + return (sf); + } } - sf = IsResourceFork(f,0,filename,flags,openflags,into,map); + sf = IsResourceFork(f, 0, filename, flags, openflags, into, map); fclose(f); #if __Mac - if ( sf==NULL ) - sf = HasResourceFork(filename,flags,openflags,into,map); + if (sf == NULL) + sf = HasResourceFork(filename, flags, openflags, into, map); #endif -return( sf ); + return (sf); } -static SplineFont *FindResourceFile(char *filename,int flags,enum openflags openflags, - SplineFont *into,EncMap *map) { +static SplineFont *FindResourceFile(char *filename, int flags, + enum openflags openflags, SplineFont * into, + EncMap * map) +{ char *spt, *pt, *dpt; char buffer[1400]; SplineFont *sf; - if ( (sf = IsResourceInFile(filename,flags,openflags,into,map))) -return( sf ); + if ((sf = IsResourceInFile(filename, flags, openflags, into, map))) + return (sf); /* Well, look in the resource fork directory (if it exists), the resource */ /* fork is placed there in a seperate file on (some) non-Mac disks */ - strcpy(buffer,filename); - spt = strrchr(buffer,'/'); - if ( spt==NULL ) { spt = buffer; pt = filename; } - else { ++spt; pt = filename + (spt-buffer); } - strcpy(spt,"resource.frk/"); - strcat(spt,pt); - if ( (sf=IsResourceInFile(buffer,flags,openflags,into,map))) -return( sf ); + strcpy(buffer, filename); + spt = strrchr(buffer, '/'); + if (spt == NULL) { + spt = buffer; + pt = filename; + } else { + ++spt; + pt = filename + (spt - buffer); + } + strcpy(spt, "resource.frk/"); + strcat(spt, pt); + if ((sf = IsResourceInFile(buffer, flags, openflags, into, map))) + return (sf); /* however the resource fork does not appear to do long names properly */ /* names are always lower case 8.3, do some simple things to check */ - spt = strrchr(buffer,'/')+1; - for ( pt=spt; *pt; ++pt ) - if ( isupper( *pt )) - *pt = tolower( *pt ); - dpt = strchr(spt,'.'); - if ( dpt==NULL ) dpt = spt+strlen(spt); - if ( dpt-spt>8 || strlen(dpt)>4 ) { - char exten[8]; - strncpy(exten,dpt,7); - exten[4] = '\0'; /* it includes the dot */ - if ( dpt-spt>6 ) - dpt = spt+6; - *dpt++ = '~'; - *dpt++ = '1'; - strcpy(dpt,exten); + spt = strrchr(buffer, '/') + 1; + for (pt = spt; *pt; ++pt) + if (isupper(*pt)) + *pt = tolower(*pt); + dpt = strchr(spt, '.'); + if (dpt == NULL) + dpt = spt + strlen(spt); + if (dpt - spt > 8 || strlen(dpt) > 4) { + char exten[8]; + strncpy(exten, dpt, 7); + exten[4] = '\0'; /* it includes the dot */ + if (dpt - spt > 6) + dpt = spt + 6; + *dpt++ = '~'; + *dpt++ = '1'; + strcpy(dpt, exten); + } + return (IsResourceInFile(buffer, flags, openflags, into, map)); +} + + +static char *createtmpfile(char *filename) +{ + char *p, *tempname; + p = strrchr(filename,'/'); + if (p != NULL) { + filename = p+1; + } + assert(strlen(filename)>=5); + tempname = malloc(strlen(filename)+2); + if (tempname == NULL) { + LogError(_("Out of memory\n")); + exit(1); + } + strcpy(tempname,filename); + strcpy(tempname+strlen(tempname)-5,"XXXXXX"); /* dfont -> XXXXXX */ + +#ifdef HAVE_MKSTEMP + int i = mkstemp(tempname); + if (i) { + close(i); } -return( IsResourceInFile(buffer,flags,openflags,into,map)); +#else + mktemp(tempname); +#endif + return tempname; } -SplineFont *SFReadMacBinary(char *filename,int flags,enum openflags openflags) { - SplineFont *sf = FindResourceFile(filename,flags,openflags,NULL,NULL); +static char *SearchTtfResourcesFile(FILE * f, long rlistpos, int subcnt, + long rdata_pos, long name_list, + char *filename, char *fontname) +{ + long here; + long roff; + int rname = -1; + int ch1, ch2; + int len, i, rlen, ilen; + /* The sfnt resource is just a copy of the ttf file */ + char *buffer = NULL; + int max = 0; + FILE *ttf; + char *sf = NULL; + int which = 0; + char **names; + (void)name_list; + fseek(f, rlistpos, SEEK_SET); + if (subcnt > 1) { + names = gcalloc(subcnt + 1, sizeof(char *)); + for (i = 0; i < subcnt; ++i) { + /* resource id = */ getushort(f); + /* rname = (short) */ getushort(f); + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); + here = ftell(f); + names[i] = TTFGetPSFontName(f, roff + 4, roff + 4); + if (names[i] == NULL) { + char buffer[32]; + sprintf(buffer, "Nameless%d", i); + names[i] = copy(buffer); + } + fseek(f, here, SEEK_SET); + } + if (1) { + char *find = fontname; + for (which = subcnt - 1; which >= 0; --which) + if (strcmp(names[which], find) == 0) + break; + if (which == -1) { + char *end; + which = strtol(find, &end, 10); + if (*end != '\0') + which = -1; + } + if (which == -1) { + ff_post_error(_("Not in Collection"), _("%s is not in %.100s"), + find, filename); + } + } else { + which = 0; + } + for (i = 0; i < subcnt; ++i) + free(names[i]); + free(names); + fseek(f, rlistpos, SEEK_SET); + } + + for (i = 0; i < subcnt; ++i) { + /* resource id = */ getushort(f); + rname = (short) getushort(f); + /* flags = */ getc(f); + ch1 = getc(f); + ch2 = getc(f); + roff = rdata_pos + ((ch1 << 16) | (ch2 << 8) | getc(f)); + /* mbz = */ getlong(f); + if (i != which) + continue; + here = ftell(f); + + sf = createtmpfile(filename); + ttf = fopen(sf, "wb"); + if (ttf == NULL) { + LogError(_("Can't open temporary file for truetype output.\n")); + continue; + } + + fseek(f, roff, SEEK_SET); + ilen = rlen = getlong(f); + if (rlen > 16 * 1024) + ilen = 16 * 1024; + if (ilen > max) { + free(buffer); + max = ilen; + if (max < 0x800) + max = 0x800; + buffer = malloc(max); + } + for (len = 0; len < rlen;) { + int temp = ilen; + if (rlen - len < ilen) + temp = rlen - len; + temp = fread(buffer, 1, temp, f); + if (temp == EOF) + break; + fwrite(buffer, 1, temp, ttf); + len += temp; + } + fclose(ttf); + } + free(buffer); + return sf; +} + +static char *IsResourceForkFile(FILE * f, char *filename, char *fontname) +{ + /* If it is a good resource fork then the first 16 bytes are repeated */ + /* at the location specified in bytes 4-7 */ + /* We include an offset because if we are looking at a mac binary file */ + /* the resource fork will actually start somewhere in the middle of the */ + /* file, not at the beginning */ + unsigned char buffer[16], buffer2[16]; + long rdata_pos, map_pos, type_list, name_list, rpos; + int32 rdata_len, map_len; + uint32 fond_pos; + unsigned long tag; + int i, cnt, subcnt; + char *sf = NULL; + fond_pos = 0; + fseek(f, 0, SEEK_SET); + if (fread(buffer, 1, 16, f) != 16) + return (NULL); + rdata_pos = + ((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); + map_pos = + ((buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]); + rdata_len = + ((buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | + buffer[11]); + map_len = + ((buffer[12] << 24) | (buffer[13] << 16) | (buffer[14] << 8) | + buffer[15]); + if (rdata_pos + rdata_len != map_pos || rdata_len == 0) + return (NULL); + fseek(f, map_pos, SEEK_SET); + buffer2[15] = buffer[15] + 1; /* make it be different */ + if (fread(buffer2, 1, 16, f) != 16) + return (NULL); + for (i = 0; i < 16; ++i) + if (buffer2[i] != 0) + break; + if (i != 16) { + for (i = 0; i < 16; ++i) + if (buffer[i] != buffer2[i]) + return (NULL); + } + getlong(f); /* skip the handle to the next resource map */ + getushort(f); /* skip the file resource number */ + getushort(f); /* skip the attributes */ + type_list = map_pos + getushort(f); + name_list = map_pos + getushort(f); + fseek(f, type_list, SEEK_SET); + cnt = getushort(f) + 1; + for (i = 0; i < cnt; ++i) { + tag = getlong(f); + subcnt = getushort(f) + 1; + rpos = type_list + getushort(f); + sf = NULL; + if (tag == CHR('s', 'f', 'n', 't')) { + sf = SearchTtfResourcesFile(f, rpos, subcnt, rdata_pos, name_list, + filename, fontname); + } + if (sf != NULL) + return (sf); + } + return NULL; +} + + +/* filename "/opt/tex/texmf-fonts/fonts/data/LucidaGrande.dfont", + fontname "Lucida Grande Bold" + */ +char *FindResourceTtfFont(char *filename, char *fontname) +{ + char *sf = NULL; + FILE *f = fopen(filename, "rb"); + if (f == NULL) + return (NULL); + sf = IsResourceForkFile(f, filename, fontname); + fclose(f); + return sf; +} - if ( sf==NULL ) - LogError( _("Couldn't find a font file named %s\n"), filename ); - else if ( sf==(SplineFont *) (-1) ) { - LogError( _("%s is a mac resource file but contains no postscript or truetype fonts\n"), filename ); - sf = NULL; +SplineFont *SFReadMacBinary(char *filename, int flags, enum openflags openflags) +{ + SplineFont *sf = FindResourceFile(filename, flags, openflags, NULL, NULL); + + if (sf == NULL) + LogError(_("Couldn't find a font file named %s\n"), filename); + else if (sf == (SplineFont *) (-1)) { + LogError(_ + ("%s is a mac resource file but contains no postscript or truetype fonts\n"), + filename); + sf = NULL; } -return( sf ); + return (sf); } -char **NamesReadMacBinary(char *filename) { -return( (char **) FindResourceFile(filename,ttf_onlynames,0,NULL,NULL)); +char **NamesReadMacBinary(char *filename) +{ + return ((char **) FindResourceFile(filename, ttf_onlynames, 0, NULL, NULL)); } /* should try to optimize this */ -SplineFont *SFReadMacBinaryInfo(char *filename,int flags,enum openflags openflags) { - SplineFont *sf = FindResourceFile(filename,flags,openflags,NULL,NULL); - - if ( sf==NULL ) - LogError( _("Couldn't find a font file named %s\n"), filename ); - else if ( sf==(SplineFont *) (-1) ) { - LogError( _("%s is a mac resource file but contains no postscript or truetype fonts\n"), filename ); - sf = NULL; +SplineFont *SFReadMacBinaryInfo(char *filename, int flags, + enum openflags openflags) +{ + SplineFont *sf = FindResourceFile(filename, flags, openflags, NULL, NULL); + + if (sf == NULL) + LogError(_("Couldn't find a font file named %s\n"), filename); + else if (sf == (SplineFont *) (-1)) { + LogError(_ + ("%s is a mac resource file but contains no postscript or truetype fonts\n"), + filename); + sf = NULL; } -return( sf ); + return (sf); } diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c index d3199f05ee7..3eb886c352f 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/nouiutil.c @@ -42,7 +42,7 @@ static void NOUI_IError(const char *format,...) { static void NOUI__LogError(const char *format,va_list ap) { char buffer[400], *str; vsnprintf(buffer,sizeof(buffer),format,ap); - str = utf82def_copy(buffer); + str = (char *)buffer; fprintf(stderr,"%s",str); if ( str[strlen(str)-1]!='\n' ) putc('\n',stderr); diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c index 1f75c22cddc..9ccd1d393dd 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettf.c @@ -33,11 +33,19 @@ #include <gwidget.h> #include "ttf.h" +extern char *AdobeStandardEncoding[], *AdobeExpertEncoding[]; +extern const char *ttfstandardnames[]; +extern int ask_user_for_cmap; +extern char *SaveTablesPref; + #ifdef LUA_FF_LIB SplineFont *_SFReadTTFInfo(FILE *ttf, int flags,enum openflags openflags, char *filename,struct fontdict *fd); void THPatchSplineChar(SplineChar *sc); #endif +int THtest_duplicate_glyph_names = 0; +int THread_ttf_glyph_data = 0; + char *SaveTablesPref; int ask_user_for_cmap = false; @@ -579,6 +587,57 @@ return( NULL ); return( _readencstring(ttf,stringoffset+fullstr,fulllen,fullplat,fullspec,fulllang)); } + +char *TTFGetPSFontName(FILE *ttf,int32 offset,int32 off2) { + int i,num; + int32 tag, length, stringoffset; + int name, len, off; + int32 nameoffset = 0; + + fseek(ttf,offset,SEEK_SET); + /* version = */ getlong(ttf); + num = getushort(ttf); + /* srange = */ getushort(ttf); + /* esel = */ getushort(ttf); + /* rshift = */ getushort(ttf); + for ( i=0; i<num; ++i ) { + tag = getlong(ttf); + /* checksum = */ getlong(ttf); + nameoffset = off2+getlong(ttf); + length = getlong(ttf); + if ( tag==CHR('n','a','m','e')) + break; + } + if ( i==num ) + return( NULL ); + + fseek(ttf,nameoffset,SEEK_SET); + /* format = */ getushort(ttf); + num = getushort(ttf); + stringoffset = nameoffset+getushort(ttf); + + for ( i=0; i<num; ++i ) { + /* plat */ getushort(ttf); + /* spec */ getushort(ttf); + /* lang */ getushort(ttf); + name = getushort(ttf); + len = getushort(ttf); + off = getushort(ttf); + if (name == 6) { + char *str = malloc(len+1); + if (str) { + fseek (ttf, stringoffset+off, SEEK_SET); + if(fread(str,1,len,ttf)==(size_t)len) { + str[len] = '\0'; + return str; + } + free(str); + } + } + } + return NULL; +} + static int PickTTFFont(FILE *ttf,char *filename,char **chosenname) { int32 *offsets, cnt, i, choice, j; char **names; @@ -660,7 +719,6 @@ return( choice ); } static void ParseSaveTablesPref(struct ttfinfo *info) { - extern char *SaveTablesPref; char *pt, *spt; int cnt; @@ -2185,26 +2243,23 @@ return( sc ); sc->xmax = getushort(ttf); sc->ymax = getushort(ttf); sc->lsidebearing = sc->xmin; -#else - /* xmin = */ sc->lsidebearing = getushort(ttf); - /* ymin = */ getushort(ttf); - /* xmax = */ getushort(ttf); - /* ymax = */ /* sc->lsidebearing = */ getushort(ttf); /* what was this for? */ #endif - if ( path_cnt>=0 ) + if (THread_ttf_glyph_data) { + if ( path_cnt>=0 ) readttfsimpleglyph(ttf,info,sc,path_cnt); - else + else readttfcompositglyph(ttf,info,sc,info->glyph_start+end); - if ( start>end ) { + if ( start>end ) { LogError(_("Bad glyph (%d), disordered 'loca' table (start comes after end)\n"), gid ); info->bad_glyph_data = true; - } else if ( ftell(ttf)>info->glyph_start+end ) { + } else if ( ftell(ttf)>(long)(info->glyph_start+end) ) { LogError(_("Bad glyph (%d), its definition extends beyond the space allowed for it\n"), gid ); info->bad_glyph_data = true; + } + + /* find the bb */ + THPatchSplineChar(sc); } - - /* find the bb */ - THPatchSplineChar(sc); return( sc ); } @@ -3284,7 +3339,6 @@ return( strings[sid-nStdStrings]); static void readcffenc(FILE *ttf,struct topdicts *dict,struct ttfinfo *info, char **strings, int scnt) { int format, cnt, i, j, pos, first, last, dupenc, sid; - extern char *AdobeStandardEncoding[], *AdobeExpertEncoding[]; const char *name; EncMap *map; @@ -3722,7 +3776,7 @@ static void cfffigure(struct ttfinfo *info, struct topdicts *dict, info->chars = gcalloc(info->glyph_cnt,sizeof(SplineChar *)); for ( i=0; i<info->glyph_cnt; ++i ) { - info->chars[i] = PSCharStringToSplines( + info->chars[i] = PSCharStringToBB( dict->glyphs.values[i], dict->glyphs.lens[i],&pscontext, subrs,gsubrs,FFgetsid(dict->charset[i],strings,scnt,info)); info->chars[i]->vwidth = info->emsize; @@ -3805,7 +3859,7 @@ static void cidfigure(struct ttfinfo *info, struct topdicts *dict, cid = dict->charset[i]; /*encmap->map[cid] = cid;*/ uni = CID2NameUni(map,cid,buffer,sizeof(buffer)); - info->chars[i] = PSCharStringToSplines( + info->chars[i] = PSCharStringToBB( dict->glyphs.values[i], dict->glyphs.lens[i],&pscontext, subrs,gsubrs,buffer); info->chars[i]->vwidth = sf->ascent+sf->descent; @@ -4129,6 +4183,7 @@ static int umodenc(int enc,int modtype, struct ttfinfo *info) { return( -1 ); if ( modtype<=1 /* Unicode */ ) { /* No conversion needed, already unicode */; +#ifdef FROM_CJK_ICONV } else if ( modtype==2 /* SJIS */ ) { if ( enc<=127 ) { /* Latin */ @@ -4186,6 +4241,10 @@ return( -1 ); enc = unicode_from_johab[enc-0x8400]; else if ( enc>0x100 ) enc = badencoding(info); +#else + } else { + enc = badencoding(info); +#endif } if ( enc==0 ) enc = -1; @@ -4464,7 +4523,6 @@ static void readttfencodings(FILE *ttf,struct ttfinfo *info, int justinuse) { Encoding *temp; EncMap *map; struct cmap_encs *cmap_encs, desired_cmaps[2], *dcmap; - extern int ask_user_for_cmap; fseek(ttf,info->encoding_start,SEEK_SET); version = getushort(ttf); @@ -5093,7 +5151,6 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) { const char *name; char buffer[30]; uint16 *indexes; - extern const char *ttfstandardnames[]; int notdefwarned = false; int anynames = false; @@ -5211,7 +5268,7 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) { name = NULL; } else { name = StdGlyphName(buffer,info->chars[i]->unicodeenc,info->uni_interp,NULL); - if ( anynames ) { + if (THtest_duplicate_glyph_names && anynames ) { for ( j=0; j<info->glyph_cnt; ++j ) { if ( info->chars[j]!=NULL && j!=i && info->chars[j]->name!=NULL ) { if ( strcmp(info->chars[j]->name,name)==0 ) { @@ -5942,56 +5999,6 @@ return; map->backmap[map->map[i]] = i; } -void TTF_PSDupsDefault(SplineFont *sf) { - struct ttflangname *english; - char versionbuf[40]; - - /* Ok, if we've just loaded a ttf file then we've got a bunch of langnames*/ - /* we copied some of them (copyright, family, fullname, etc) into equiv */ - /* postscript entries in the sf. If we then use FontInfo and change the */ - /* obvious postscript entries we are left with the old ttf entries. If */ - /* we generate a ttf file and then load it the old values pop up. */ - /* Solution: Anything we can generate by default should be set to NULL */ - for ( english=sf->names; english!=NULL && english->lang!=0x409; english=english->next ); - if ( english==NULL ) -return; - if ( english->names[ttf_family]!=NULL && - strcmp(english->names[ttf_family],sf->familyname)==0 ) { - free(english->names[ttf_family]); - english->names[ttf_family]=NULL; - } - if ( english->names[ttf_copyright]!=NULL && - strcmp(english->names[ttf_copyright],sf->copyright)==0 ) { - free(english->names[ttf_copyright]); - english->names[ttf_copyright]=NULL; - } - if ( english->names[ttf_fullname]!=NULL && - strcmp(english->names[ttf_fullname],sf->fullname)==0 ) { - free(english->names[ttf_fullname]); - english->names[ttf_fullname]=NULL; - } - if ( sf->subfontcnt!=0 || sf->version!=NULL ) { - if ( sf->subfontcnt!=0 ) - sprintf( versionbuf, "Version %f", sf->cidversion ); - else - sprintf(versionbuf,"Version %.20s ", sf->version); - if ( english->names[ttf_version]!=NULL && - strcmp(english->names[ttf_version],versionbuf)==0 ) { - free(english->names[ttf_version]); - english->names[ttf_version]=NULL; - } - } - if ( english->names[ttf_subfamily]!=NULL && - strcmp(english->names[ttf_subfamily],SFGetModifiers(sf))==0 ) { - free(english->names[ttf_subfamily]); - english->names[ttf_subfamily]=NULL; - } - - /* User should not be allowed any access to this one, not ever */ - free(english->names[ttf_postscriptname]); - english->names[ttf_postscriptname]=NULL; -} - static SplineFont *SFFillFromTTF(struct ttfinfo *info) { SplineFont *sf, *_sf; int i,k; @@ -6175,21 +6182,6 @@ static SplineFont *SFFillFromTTF(struct ttfinfo *info) { sf->subfonts[i]->hasvmetrics = sf->hasvmetrics; } } - TTF_PSDupsDefault(sf); -#if 0 - if ( info->gsub_start==0 && info->mort_start==0 && info->morx_start==0 ) { - /* Get default ligature values, etc. */ - k=0; - do { - _sf = k<sf->subfontcnt?sf->subfonts[k]:sf; - for ( i=0; i<sf->glyphcnt; ++i ) { - if ( _sf->glyphs[i]!=NULL ) /* Might be null in ttc files */ - SCLigDefault(_sf->glyphs[i]); - } - ++k; - } while ( k<sf->subfontcnt ); - } -#endif /* I thought the languages were supposed to be ordered, but it seems */ /* that is not always the case. Order everything, just in case */ @@ -6382,11 +6374,13 @@ return( SFFillFromTTFInfo(&info)); SplineFont *SFReadTTFInfo(char *filename, int flags, enum openflags openflags) { FILE *ttf; SplineFont *sf; - char *temp=filename, *pt, *lparen; + char *temp=filename, *pt, *lparen, *rparen; pt = strrchr(filename,'/'); if ( pt==NULL ) pt = filename; - if ( (lparen=strchr(pt,'('))!=NULL && strchr(lparen,')')!=NULL ) { + if ( (lparen = strrchr(pt,'('))!=NULL && + (rparen = strrchr(lparen,')'))!=NULL && + rparen[1]=='\0' ) { temp = copy(filename); pt = temp + (lparen-filename); *pt = '\0'; diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c index 8b86752fc20..fa466564027 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/parsettfatt.c @@ -316,7 +316,10 @@ static uint16 *getClassDefTable(FILE *ttf, int classdef_offset, struct ttfinfo * } else if ( ftell(ttf)+2*glyphcnt > g_bounds ) { LogError( _("Class definition sub-table extends beyond end of table\n") ); info->bad_ot = true; - glyphcnt = (g_bounds-ftell(ttf))/2; + if (g_bounds<ftell(ttf)) + glyphcnt = 0; + else + glyphcnt = (g_bounds-ftell(ttf))/2; } for ( i=0; i<glyphcnt; ++i ) glist[start+i] = getushort(ttf); diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c index c5e4958d0f5..cb3b0676699 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/psread.c @@ -36,6 +36,10 @@ # include <ieeefp.h> /* Solaris defines isnan in ieeefp rather than math.h */ #endif +int THdo_hint_guessing = 0; +int THdo_set_reversing = 0; +int THdo_catagorize = 0; + typedef struct _io { char *macro, *start; FILE *ps, *fog; @@ -2673,7 +2677,7 @@ static void EntityDefaultStrokeFill(Entity *ent) { static SplinePointList *SplinesFromEntityChar(EntityChar *ec,int *flags,int is_stroked) { Entity *ent, *next; - SplinePointList *head=NULL, *last, *new, *nlast, *temp, *each, *transed; + SplinePointList *head=NULL, *last=NULL, *new, *nlast=NULL, *temp, *each, *transed; StrokeInfo si; real inversetrans[6]; /*SplineSet *spl;*/ @@ -4072,7 +4076,8 @@ SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *conte done: if ( pcsp!=0 ) LogError( _("end of subroutine reached with no return in %s\n"), name ); - SCCatagorizePoints(ret); + if (THdo_catagorize) + SCCatagorizePoints(ret); ret->hstem = HintsAppend(ret->hstem,activeh); activeh=NULL; ret->vstem = HintsAppend(ret->vstem,activev); activev=NULL; @@ -4097,27 +4102,699 @@ SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *conte SplineMake3(cur->last,cur->first); cur->last = cur->first; } - /* Oh, I see. PS and TT disagree on which direction to use, so Fontographer*/ /* chose the TT direction and we must reverse postscript */ - for ( cur = ret->layers[ly_fore].splines; cur!=NULL; cur = cur->next ) + if (THdo_set_reversing) { + for ( cur = ret->layers[ly_fore].splines; cur!=NULL; cur = cur->next ) SplineSetReverse(cur); + } if ( ret->hstem==NULL && ret->vstem==NULL ) ret->manualhints = false; if ( !is_type2 && context->instance_count!=0 ) { UnblendFree(ret->hstem); UnblendFree(ret->vstem); } - ret->hstem = HintCleanup(ret->hstem,true,context->instance_count); - ret->vstem = HintCleanup(ret->vstem,true,context->instance_count); - SCGuessHHintInstancesList(ret,ly_fore); - SCGuessVHintInstancesList(ret,ly_fore); - ret->hconflicts = StemListAnyConflicts(ret->hstem); - ret->vconflicts = StemListAnyConflicts(ret->vstem); - if ( context->instance_count==1 && !ret->hconflicts && !ret->vconflicts ) + if (THdo_hint_guessing) { + ret->hstem = HintCleanup(ret->hstem,true,context->instance_count); + ret->vstem = HintCleanup(ret->vstem,true,context->instance_count); + SCGuessHHintInstancesList(ret,ly_fore); + SCGuessVHintInstancesList(ret,ly_fore); + ret->hconflicts = StemListAnyConflicts(ret->hstem); + ret->vconflicts = StemListAnyConflicts(ret->vstem); + if ( context->instance_count==1 && !ret->hconflicts && !ret->vconflicts ) SCClearHintMasks(ret,ly_fore,false); - HintsRenumber(ret); + HintsRenumber(ret); + } if ( name!=NULL && strcmp(name,".notdef")!=0 ) ret->widthset = true; return( ret ); } + + +/* This finds the 'connect-the-dots' boundingbox of a Type2 charstring */ +/* It is a simplified version of PSCharStringToSplines, above */ + +SplineChar *PSCharStringToBB(uint8 *type1, int len, struct pscontext *context, + struct pschars *subrs, struct pschars *gsubrs, const char *name) { + real stack[50]; int sp=0, v; /* Type1 stack is about 25 long, Type2 stack is 48 */ + real transient[32]; + SplineChar *ret = SplineCharCreate(2); + + DBasePoint current, ll, ur; + real dx, dy, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6=0, dy6; + + int first = 1; /* to flag extra set width */ + /* subroutines may be nested to a depth of 10 */ + struct substate { unsigned char *type1; int len; int subnum; } pcstack[11]; + int pcsp=0; + + real pops[30]; + int popsp=0; + int base, polarity; + + struct pschars *s; + int hint_cnt = 0; + + int last_was_b1=false, old_last_was_b1; + + ret->name = copy( name ); + ret->unicodeenc = -1; + ret->width = (int16) 0x8000; + if ( name==NULL ) name = "unnamed"; + ret->manualhints = true; + if ( !context->is_type2 ) { + LogError( _("Quick boundingbox mode only does CFF charstrings, not Type1 (font %s)\n"), name ); + return (ret); + } + + current.x = current.y = 0; + ll.x = ll.y = (int16) 0x7FFF; + ur.x = ur.y = (int16) -0x7FFF; + + while ( len>0 ) { + if ( sp>48 ) { + LogError( _("Stack got too big in %s\n"), name ); + sp = 48; + } + base = 0; + --len; + if ( (v = *type1++)>=32 ) { + if ( v<=246) { + stack[sp++] = v - 139; + } else if ( v<=250 ) { + stack[sp++] = (v-247)*256 + *type1++ + 108; + --len; + } else if ( v<=254 ) { + stack[sp++] = -(v-251)*256 - *type1++ - 108; + --len; + } else { + int val = (*type1<<24) | (type1[1]<<16) | (type1[2]<<8) | type1[3]; + stack[sp++] = val; + type1 += 4; + len -= 4; + stack[sp-1] /= 65536.; + } + } else if ( v==28 ) { + stack[sp++] = (short) ((type1[0]<<8) | type1[1]); + type1 += 2; + len -= 2; + /* In the Dict tables of CFF, a 5byte fixed value is prefixed by a */ + /* 29 code. In Type2 strings the prefix is 255. */ + } else if ( v==12 ) { + old_last_was_b1 = last_was_b1; last_was_b1 = false; + v = *type1++; + --len; + switch ( v ) { + case 0: /* dotsection */ + sp = 0; + break; + case 1: /* vstem3 */ /* specifies three v hints zones at once */ + if ( sp<6 ) LogError( _("Stack underflow on vstem3 in %s\n"), name ); + /* according to the standard, if there is a vstem3 there can't */ + /* be any vstems, so there can't be any confusion about hint order */ + /* so we don't need to worry about unblended stuff */ + hint_cnt+=3; + sp = 0; + break; + case 2: /* hstem3 */ /* specifies three h hints zones at once */ + if ( sp<6 ) LogError( _("Stack underflow on hstem3 in %s\n"), name ); + hint_cnt+=3; + sp = 0; + break; + case 6: /* seac */ /* build accented characters */ + seac: + if ( sp<5 ) LogError( _("Stack underflow on seac in %s\n"), name ); + /* stack[0] must be the lsidebearing of the accent. I'm not sure why */ + sp = 0; + break; + case 7: /* sbw */ /* generalized width/sidebearing command */ + if ( sp<4 ) LogError( _("Stack underflow on sbw in %s\n"), name ); + ret->lsidebearing = stack[0]; + /* stack[1] is lsidebearing y (only for vertical writing styles, CJK) */ + ret->width = stack[2]; + /* stack[3] is height (for vertical writing styles, CJK) */ + sp = 0; + break; + case 5: case 9: case 14: case 26: + if ( sp<1 ) LogError( _("Stack underflow on unary operator in %s\n"), name ); + switch ( v ) { + case 5: stack[sp-1] = (stack[sp-1]==0); break; /* not */ + case 9: if ( stack[sp-1]<0 ) stack[sp-1]= -stack[sp-1]; break; /* abs */ + case 14: stack[sp-1] = -stack[sp-1]; break; /* neg */ + case 26: stack[sp-1] = sqrt(stack[sp-1]); break; /* sqrt */ + } + break; + case 3: case 4: case 10: case 11: case 12: case 15: case 24: + if ( sp<2 ) LogError( _("Stack underflow on binary operator in %s\n"), name ); + else switch ( v ) { + case 3: /* and */ + stack[sp-2] = (stack[sp-1]!=0 && stack[sp-2]!=0); + break; + case 4: /* and */ + stack[sp-2] = (stack[sp-1]!=0 || stack[sp-2]!=0); + break; + case 10: /* add */ + stack[sp-2] += stack[sp-1]; + break; + case 11: /* sub */ + stack[sp-2] -= stack[sp-1]; + break; + case 12: /* div */ + stack[sp-2] /= stack[sp-1]; + break; + case 24: /* mul */ + stack[sp-2] *= stack[sp-1]; + break; + case 15: /* eq */ + stack[sp-2] = (stack[sp-1]==stack[sp-2]); + break; + } + --sp; + break; + case 22: /* ifelse */ + if ( sp<4 ) LogError( _("Stack underflow on ifelse in %s\n"), name ); + else { + if ( stack[sp-2]>stack[sp-1] ) + stack[sp-4] = stack[sp-3]; + sp -= 3; + } + break; + case 23: /* random */ + /* This function returns something (0,1]. It's not clear to me*/ + /* if rand includes 0 and RAND_MAX or not, but this approach */ + /* should work no matter what */ + do { + stack[sp] = (rand()/(RAND_MAX-1)); + } while ( stack[sp]==0 || stack[sp]>1 ); + ++sp; + break; + case 20: /* put */ + if ( sp<2 ) LogError( _("Too few items on stack for put in %s\n"), name ); + else if ( stack[sp-1]<0 || stack[sp-1]>=32 ) LogError( _("Reference to transient memory out of bounds in put in %s\n"), name ); + else { + transient[(int)stack[sp-1]] = stack[sp-2]; + sp -= 2; + } + break; + case 21: /* get */ + if ( sp<1 ) LogError( _("Too few items on stack for get in %s\n"), name ); + else if ( stack[sp-1]<0 || stack[sp-1]>=32 ) LogError( _("Reference to transient memory out of bounds in put in %s\n"), name ); + else + stack[sp-1] = transient[(int)stack[sp-1]]; + break; + case 17: /* pop */ + /* pops something from the postscript stack and pushes it on ours */ + /* used to get a return value from an othersubr call */ + /* Bleah. Adobe wants the pops to return the arguments if we */ + /* don't understand the call. What use is the subroutine then?*/ + if ( popsp<=0 ) + LogError( _("Pop stack underflow on pop in %s\n"), name ); + else + stack[sp++] = pops[--popsp]; + break; + case 18: /* drop */ + if ( sp>0 ) --sp; + break; + case 27: /* dup */ + if ( sp>=1 ) { + stack[sp] = stack[sp-1]; + ++sp; + } + break; + case 28: /* exch */ + if ( sp>=2 ) { + real temp = stack[sp-1]; + stack[sp-1] = stack[sp-2]; stack[sp-2] = temp; + } + break; + case 29: /* index */ + if ( sp>=1 ) { + int index = stack[--sp]; + if ( index<0 || sp<index+1 ) + LogError( _("Index out of range in %s\n"), name ); + else { + stack[sp] = stack[sp-index-1]; + ++sp; + } + } + break; + case 30: /* roll */ + if ( sp>=2 ) { + int j = stack[sp-1], N=stack[sp-2]; + if ( N>sp || j>=N || j<0 || N<0 ) + LogError( _("roll out of range in %s\n"), name ); + else if ( j==0 || N==0 ) + /* No op */; + else { + real *temp = galloc(N*sizeof(real)); + int i; + for ( i=0; i<N; ++i ) + temp[i] = stack[sp-N+i]; + for ( i=0; i<N; ++i ) + stack[sp-N+i] = temp[(i+j)%N]; + free(temp); + } + } + break; + case 33: /* setcurrentpoint */ + if ( sp<2 ) LogError( _("Stack underflow on setcurrentpoint in %s\n"), name ); + else { + current.x = stack[0]; + current.y = stack[1]; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + } + sp = 0; + break; + case 34: /* hflex */ + case 35: /* flex */ + case 36: /* hflex1 */ + case 37: /* flex1 */ + dy = dy3 = dy4 = dy5 = dy6 = 0; + dx = stack[base++]; + if ( v!=34 ) + dy = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dx3 = stack[base++]; + if ( v!=34 && v!=36 ) + dy3 = stack[base++]; + dx4 = stack[base++]; + if ( v!=34 && v!=36 ) + dy4 = stack[base++]; + dx5 = stack[base++]; + if ( v==34 ) + dy5 = -dy2; + else + dy5 = stack[base++]; + switch ( v ) { + real xt, yt; + case 35: /* flex */ + dx6 = stack[base++]; + dy6 = stack[base++]; + break; + case 34: /* hflex */ + dx6 = stack[base++]; + break; + case 36: /* hflex1 */ + dx6 = stack[base++]; + dy6 = -dy-dy2-dy5; + break; + case 37: /* flex1 */ + xt = dx+dx2+dx3+dx4+dx5; + yt = dy+dy2+dy3+dy4+dy5; + if ( xt<0 ) xt= -xt; + if ( yt<0 ) yt= -yt; + if ( xt>yt ) { + dx6 = stack[base++]; + dy6 = -dy-dy2-dy3-dy4-dy5; + } else { + dy6 = stack[base++]; + dx6 = -dx-dx2-dx3-dx4-dx5; + } + break; + } + current.x = current.x+dx; current.y = current.y+dy; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx2; current.y = current.y+dy2; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx3; current.y = current.y+dy3; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + + current.x = current.x+dx4; current.y = current.y+dy4; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx5; current.y = current.y+dy5; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx6; current.y = current.y+dy6; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + sp = 0; + break; + default: + LogError( _("Uninterpreted opcode 12,%d in %s\n"), v, name ); + break; + } + } else { last_was_b1 = false; switch ( v ) { + case 1: /* hstem */ + case 18: /* hstemhm */ + base = 0; + if ( (sp&1) && ret->width == (int16) 0x8000 ) + ret->width = stack[0]; + if ( sp&1 ) + base=1; + if ( sp-base<2 ) + LogError( _("Stack underflow on hstem in %s\n"), name ); + /* stack[0] is absolute y for start of horizontal hint */ + /* (actually relative to the y specified as lsidebearing y in sbw*/ + /* stack[1] is relative y for height of hint zone */ + + + while ( sp-base>=2 ) { + hint_cnt++; + base+=2; + } + sp = 0; + break; + case 19: /* hintmask */ + case 20: /* cntrmask */ + /* If there's anything on the stack treat it as a vstem hint */ + case 3: /* vstem */ + case 23: /* vstemhm */ + base = 0; + if ( first || v==3 || v==23 ) { + if ( (sp&1) && ret->width == (int16) 0x8000 ) { + ret->width = stack[0]; + } + if ( sp&1 ) + base=1; + if ( sp-base<2 && v!=19 && v!=20 ) + LogError( _("Stack underflow on vstem in %s\n"), name ); + /* stack[0] is absolute x for start of vertical hint */ + /* (actually relative to the x specified as lsidebearing in h/sbw*/ + /* stack[1] is relative x for height of hint zone */ + + + while ( sp-base>=2 ) { + hint_cnt++; + base+=2; + } + sp = 0; + } + if ( v==19 || v==20 ) { /* hintmask, cntrmask */ + unsigned bytes = (hint_cnt+7)/8; + if ( bytes>sizeof(HintMask) ) bytes = sizeof(HintMask); + if ( bytes!=(unsigned)hint_cnt/8 ) { + int mask = 0xff>>(hint_cnt&7); + if ( type1[bytes-1]&mask ) + LogError( _("Hint mask (or counter mask) with too many hints in %s\n"), name ); + } + type1 += bytes; + len -= bytes; + } + break; + case 14: /* endchar */ + /* endchar is allowed to terminate processing even within a subroutine */ + if ( (sp&1) && ret->width == (int16) 0x8000 ) + ret->width = stack[0]; + pcsp = 0; + if ( sp==4 ) { + /* In Type2 strings endchar has a depreciated function of doing */ + /* a seac (which doesn't exist at all). Except enchar takes */ + /* 4 args and seac takes 5. Bleah */ + stack[4] = stack[3]; stack[3] = stack[2]; stack[2] = stack[1]; stack[1] = stack[0]; + stack[0] = 0; + sp = 5; + goto seac; + } else if ( sp==5 ) { + /* same as above except also specified a width */ + stack[0] = 0; + goto seac; + } + /* the docs say that endchar must be the last command in a char */ + goto done; + break; + case 13: /* hsbw (set left sidebearing and width) */ + if ( sp<2 ) LogError( _("Stack underflow on hsbw in %s\n"), name ); + ret->lsidebearing = stack[0]; + current.x = stack[0]; /* sets the current point too */ + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + ret->width = stack[1]; + sp = 0; + break; + case 9: /* closepath */ + sp = 0; + break; + case 21: /* rmoveto */ + case 22: /* hmoveto */ + case 4: /* vmoveto */ + if (( (v==21 && sp==3) || (v!=21 && sp==2)) && ret->width == (int16) 0x8000 ) + /* Character's width may be specified on the first moveto */ + ret->width = stack[0]; + if ( v==21 && sp>2 ) { + stack[0] = stack[sp-2]; stack[1] = stack[sp-1]; + sp = 2; + } else if ( v!=21 && sp>1 ) { + stack[0] = stack[sp-1]; + sp = 1; + } + /* fall through */ + case 5: /* rlineto */ + case 6: /* hlineto */ + case 7: /* vlineto */ + polarity = 0; + base = 0; + while ( base<sp ) { + dx = dy = 0; + if ( v==5 || v==21 ) { + if ( sp<base+2 ) { + LogError( _("Stack underflow on rlineto/rmoveto in %s\n"), name ); + break; + } + dx = stack[base++]; + dy = stack[base++]; + } else if ( (v==6 && !(polarity&1)) || (v==7 && (polarity&1)) || v==22 ) { + if ( sp<=base ) { + LogError( _("Stack underflow on hlineto/hmoveto in %s\n"), name ); + break; + } + dx = stack[base++]; + } else /*if ( (v==7 && !(parity&1)) || (v==6 && (parity&1) || v==4 )*/ { + if ( sp<=base ) { + LogError( _("Stack underflow on vlineto/vmoveto in %s\n"), name ); + break; + } + dy = stack[base++]; + } + ++polarity; + current.x = current.x+dx; current.y = current.y+dy; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + if ( v==4 || v==21 || v==22 ) { + first = 0; + break; + } else { + first = 0; + } + } + sp = 0; + break; + case 25: /* rlinecurve */ + base = 0; + while ( sp>base+6 ) { + current.x = current.x+stack[base++]; current.y = current.y+stack[base++]; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + first = 0; + } + case 24: /* rcurveline */ + case 8: /* rrcurveto */ + case 31: /* hvcurveto */ + case 30: /* vhcurveto */ + case 27: /* hhcurveto */ + case 26: /* vvcurveto */ + polarity = 0; + while ( sp>base+2 ) { + dx = dy = dx2 = dy2 = dx3 = dy3 = 0; + if ( v==8 || v==25 || v==24 ) { + if ( sp<6+base ) { + LogError( _("Stack underflow on rrcurveto in %s\n"), name ); + base = sp; + } else { + dx = stack[base++]; + dy = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dx3 = stack[base++]; + dy3 = stack[base++]; + } + } else if ( v==27 ) { /* hhcurveto */ + if ( sp<4+base ) { + LogError( _("Stack underflow on hhcurveto in %s\n"), name ); + base = sp; + } else { + if ( (sp-base)&1 ) dy = stack[base++]; + dx = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dx3 = stack[base++]; + } + } else if ( v==26 ) { /* vvcurveto */ + if ( sp<4+base ) { + LogError( _("Stack underflow on hhcurveto in %s\n"), name ); + base = sp; + } else { + if ( (sp-base)&1 ) dx = stack[base++]; + dy = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dy3 = stack[base++]; + } + } else if ( (v==31 && !(polarity&1)) || (v==30 && (polarity&1)) ) { + if ( sp<4+base ) { + LogError( _("Stack underflow on hvcurveto in %s\n"), name ); + base = sp; + } else { + dx = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dy3 = stack[base++]; + if ( sp==base+1 ) + dx3 = stack[base++]; + } + } else /*if ( (v==30 && !(polarity&1)) || (v==31 && (polarity&1)) )*/ { + if ( sp<4+base ) { + LogError( _("Stack underflow on vhcurveto in %s\n"), name ); + base = sp; + } else { + dy = stack[base++]; + dx2 = stack[base++]; + dy2 = stack[base++]; + dx3 = stack[base++]; + if ( sp==base+1 ) + dy3 = stack[base++]; + } + } + ++polarity; + current.x = current.x+dx; current.y = current.y+dy; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx2; current.y = current.y+dy2; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + current.x = current.x+dx3; current.y = current.y+dy3; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + } + if ( v==24 ) { + current.x = current.x+stack[base++]; current.y = current.y+stack[base++]; + if (ll.y>current.y) ll.y = current.y; + if (ur.y<current.y) ur.y = current.y; + if (ll.x>current.x) ll.x = current.x; + if (ur.x<current.x) ur.x = current.x; + } + sp = 0; + break; + case 29: /* callgsubr */ + case 10: /* callsubr */ + /* stack[sp-1] contains the number of the subroutine to call */ + if ( sp<1 ) { + LogError( _("Stack underflow on callsubr in %s\n"), name ); + break; + } else if ( pcsp>10 ) { + LogError( _("Too many subroutine calls in %s\n"), name ); + break; + } + s=subrs; if ( v==29 ) s = gsubrs; + if ( s!=NULL ) stack[sp-1] += s->bias; + /* Type2 subrs have a bias that must be added to the subr-number */ + /* Type1 subrs do not. We set the bias on them to 0 */ + if ( s==NULL || stack[sp-1]>=s->cnt || stack[sp-1]<0 || + s->values[(int) stack[sp-1]]==NULL ) + LogError( _("Subroutine number out of bounds in %s\n"), name ); + else { + pcstack[pcsp].type1 = type1; + pcstack[pcsp].len = len; + pcstack[pcsp].subnum = stack[sp-1]; + ++pcsp; + type1 = s->values[(int) stack[sp-1]]; + len = s->lens[(int) stack[sp-1]]; + } + if ( --sp<0 ) sp = 0; + break; + case 11: /* return */ + /* return from a subr outine */ + if ( pcsp<1 ) LogError( _("return when not in subroutine in %s\n"), name ); + else { + --pcsp; + type1 = pcstack[pcsp].type1; + len = pcstack[pcsp].len; + } + break; + case 16: { /* blend -- obsolete type 2 multiple master operator */ + int cnt,i,j; + if ( context->instance_count==0 ) + LogError( _("Attempt to use a multiple master subroutine in a non-mm font.\n") ); + else if ( sp<1 || sp<context->instance_count*stack[sp-1]+1 ) + LogError( _("Too few items on stack for blend in %s\n"), name ); + else { + if ( !context->blend_warn ) { + LogError( _("Use of obsolete blend operator.\n") ); + context->blend_warn = true; + } + cnt = stack[sp-1]; + sp -= context->instance_count*stack[sp-1]+1; + for ( i=0; i<cnt; ++i ) { + for ( j=1; j<context->instance_count; ++j ) + stack[sp+i] += context->blend_values[j]*stack[sp+ + cnt+ i*(context->instance_count-1)+ j-1]; + } + /* there will always be fewer pushes than there were pops */ + /* so I don't bother to check the stack */ + sp += cnt; + } + } + break; + default: + LogError( _("Uninterpreted opcode %d in %s\n"), v, name ); + break; + }} + } +done: + if ( pcsp!=0 ) + LogError( _("end of subroutine reached with no return in %s\n"), name ); + + if ( name!=NULL && strcmp(name,".notdef")!=0 ) + ret->widthset = true; + if (ur.x == -0x7FFF) ur.x = 0; + if (ur.y == -0x7FFF) ur.y = 0; + if (ll.x == 0x7FFF) ll.x = 0; + if (ll.y == 0x7FFF) ll.y = 0; + if (ll.x>ur.x) ll.x = ur.x; + if (ll.y>ur.y) ll.y = ur.y; + + + ret->xmin = rint(ll.x); + ret->ymin = rint(ll.y); + ret->xmax = rint(ur.x); + ret->ymax = rint(ur.y); + /* free the curves */ + if (ret->layers!=NULL && ret->layers[ly_fore].splines != NULL) { + SplinePointListsFree(ret->layers[ly_fore].splines); + ret->layers[ly_fore].splines=NULL; + } + if (ret->layers[ly_fore].refs!=NULL) { + RefCharsFree(ret->layers[ly_fore].refs); + ret->layers[ly_fore].refs = NULL; + } + return( ret ); +} diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c index 1fa40c46072..9f0ed92305f 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.c @@ -498,7 +498,7 @@ return( _ReadSplineFont(NULL,filename,openflags)); SplineFont *ReadSplineFontInfo(char *filename,enum openflags openflags) { SplineFont *sf, *sf_ptr; char **fontlist; - char *pt =NULL, *strippedname=filename, *paren=NULL, *fullname=filename; + char *pt =NULL, *strippedname=filename, *paren=NULL, *rparen=NULL, *fullname=filename; FILE *foo = NULL; int checked = 0; char s[512] = {0}; @@ -508,9 +508,14 @@ return( NULL ); pt = strrchr(filename,'/'); if ( pt==NULL ) pt = filename; - if ( (paren=strchr(pt,'('))!=NULL && strchr(paren,')')!=NULL ) { - strippedname = copy(filename); - strippedname[paren-filename] = '\0'; + /* Someone gave me a font "Nafees Nastaleeq(Updated).ttf" and complained */ + /* that ff wouldn't open it */ + /* Now someone will complain about "Nafees(Updated).ttc(fo(ob)ar)" */ + if ( (paren = strrchr(pt,'('))!=NULL && + (rparen = strrchr(paren,')'))!=NULL && + rparen[1]=='\0' ) { + strippedname = copy(filename); + strippedname[paren-filename] = '\0'; } sf = NULL; diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h index fa989d61543..a15b6b75325 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h @@ -1866,8 +1866,11 @@ struct findsel; struct charprocs; struct enc; -extern void *chunkalloc(int size); -extern void chunkfree(void *, int size); +/* extern void *chunkalloc(int size); */ +/* extern void chunkfree(void *, int size); */ + +#define chunkalloc(size) gcalloc(1,size) +#define chunkfree(item,size) free(item) extern char *strconcat(const char *str, const char *str2); extern char *strconcat3(const char *str, const char *str2, const char *str3); @@ -1946,7 +1949,6 @@ extern long mactime(void); extern int WriteSVGFont(char *fontname,SplineFont *sf,enum fontformat format,int flags,EncMap *enc,int layer); extern int WriteUFOFont(char *fontname,SplineFont *sf,enum fontformat format,int flags,EncMap *enc,int layer); extern void SfListFree(struct sflist *sfs); -extern void TTF_PSDupsDefault(SplineFont *sf); extern void DefaultTTFEnglishNames(struct ttflangname *dummy, SplineFont *sf); extern void TeXDefaultParams(SplineFont *sf); extern int AlreadyMSSymbolArea(SplineFont *sf,EncMap *map); @@ -2506,6 +2508,7 @@ extern SplineFont *_SFDRead(char *filename,FILE *sfd); extern SplineFont *SFDirRead(char *filename); extern SplineChar *SFDReadOneChar(SplineFont *sf,const char *name); extern char *TTFGetFontName(FILE *ttf,int32 offset,int32 off2); +extern char *TTFGetPSFontName(FILE *ttf,int32 offset,int32 off2); extern void TTFLoadBitmaps(FILE *ttf,struct ttfinfo *info, int onlyone); enum ttfflags { ttf_onlystrikes=1, ttf_onlyonestrike=2, ttf_onlykerns=4, ttf_onlynames=8 }; extern SplineFont *_SFReadTTF(FILE *ttf,int flags,enum openflags openflags, @@ -2601,6 +2604,8 @@ struct pscontext { extern int UnblendedCompare(real u1[MmMax], real u2[MmMax], int cnt); extern SplineChar *PSCharStringToSplines(uint8 *type1, int len, struct pscontext *context, struct pschars *subrs, struct pschars *gsubrs, const char *name); +extern SplineChar *PSCharStringToBB(uint8 *type1, int len, struct pscontext *context, + struct pschars *subrs, struct pschars *gsubrs, const char *name); extern void MatMultiply(real m1[6], real m2[6], real to[6]); extern int NameToEncoding(SplineFont *sf,EncMap *map,const char *uname); diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c index 43626aec6dc..ce80d837f87 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splineutil2.c @@ -1377,7 +1377,7 @@ Spline *SplineAddExtrema(Spline *s,int always,real lenbound, real offsetbound, uint8 rmfrom[4], rmto[4]; int p, i,j, p_s, mini; SplinePoint *sp; - real len; + real len = 0; /* Init variable to silence compiler warnings */ if ( !always ) { real xlen, ylen; diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c index e5722cfc27d..559867543f2 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/tottfaat.c @@ -95,6 +95,8 @@ return( false ); if ( features->ismac || OTTagToMacFeature(features->featuretag,&ft,&fs)) return( true ); } + default: /* handle this to silence compiler warnings */ + break; } return( false ); } |