summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c4669
1 files changed, 0 insertions, 4669 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c
deleted file mode 100644
index 1f6ca428f93..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/sfd.c
+++ /dev/null
@@ -1,4669 +0,0 @@
-/* Copyright (C) 2000-2012 by George Williams */
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
-
- * The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
-
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "fontforge.h"
-#include <utype.h>
-#include <sys/stat.h>
-
-#ifndef NAME_MAX
-# ifndef _POSIX_NAME_MAX
-# define _POSIX_NAME_MAX 512
-# endif
-# define NAME_MAX _POSIX_NAME_MAX
-#endif
-
-static const char *joins[] = { "miter", "round", "bevel", "inher", NULL };
-static const char *caps[] = { "butt", "round", "square", "inher", NULL };
-static const char *spreads[] = { "pad", "reflect", "repeat", NULL };
-
-#define SFD_PTFLAG_TYPE_MASK 0x3
-#define SFD_PTFLAG_IS_SELECTED 0x4
-#define SFD_PTFLAG_NEXTCP_IS_DEFAULT 0x8
-#define SFD_PTFLAG_PREVCP_IS_DEFAULT 0x10
-#define SFD_PTFLAG_ROUND_IN_X 0x20
-#define SFD_PTFLAG_ROUND_IN_Y 0x40
-#define SFD_PTFLAG_INTERPOLATE 0x80
-#define SFD_PTFLAG_INTERPOLATE_NEVER 0x100
-#define SFD_PTFLAG_PREV_EXTREMA_MARKED_ACCEPTABLE 0x200
-#define SFD_PTFLAG_FORCE_OPEN_PATH 0x400
-
-
-
-
-/* I will retain this list in case there are still some really old sfd files */
-/* including numeric encodings. This table maps them to string encodings */
-static const char *charset_names[] = {
- "custom",
- "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5",
- "iso8859-6", "iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10",
- "iso8859-11", "iso8859-13", "iso8859-14", "iso8859-15",
- "koi8-r",
- "jis201",
- "win", "mac", "symbol", "zapfding", "adobestandard",
- "jis208", "jis212", "ksc5601", "gb2312", "big5", "big5hkscs", "johab",
- "unicode", "unicode4", "sjis", "wansung", "gb2312pk", NULL};
-
-static const char *unicode_interp_names[] = { "none", "adobe", "greek",
- "japanese", "tradchinese", "simpchinese", "korean", "ams", NULL };
-
-/* sfdir files and extensions */
-#define FONT_PROPS "font.props"
-#define STRIKE_PROPS "strike.props"
-#define EXT_CHAR '.'
-#define GLYPH_EXT ".glyph"
-#define BITMAP_EXT ".bitmap"
-#define STRIKE_EXT ".strike"
-#define SUBFONT_EXT ".subfont"
-#define INSTANCE_EXT ".instance"
-
-signed char inbase64[256] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static const char *end_tt_instrs = "EndTTInstrs";
-static RefChar *SFDGetRef(FILE *sfd, int was_enc);
-static AnchorPoint *SFDReadAnchorPoints(FILE *sfd,SplineChar *sc,AnchorPoint** alist, AnchorPoint *lastap);
-static StemInfo *SFDReadHints(FILE *sfd);
-static DStemInfo *SFDReadDHints( SplineFont *sf,FILE *sfd,int old );
-extern uint8 *_IVParse(SplineFont *sf, char *text, int *len, void (*IVError)(void *,char *, int), void *iv);
-
-static int PeekMatch(FILE *stream, const char * target) {
- // This returns 1 if target matches the next characters in the stream.
- int pos1 = 0;
- int lastread = getc(stream);
- while (target[pos1] != '\0' && lastread != EOF && lastread == target[pos1]) {
- pos1 ++; lastread = getc(stream);
- }
-
- int rewind_amount = pos1 + ((lastread == EOF) ? 0 : 1);
- fseek(stream, -rewind_amount, SEEK_CUR);
- return (target[pos1] == '\0');
-}
-
-/* Long lines can be broken by inserting \\\n (backslash newline) */
-/* into the line. I don't think this is ever ambiguous as I don't */
-/* think a line can end with backslash */
-/* UPDATE: it can... that's handled in getquotedeol() below. */
-static int nlgetc(FILE *sfd) {
- int ch, ch2;
-
- ch=getc(sfd);
- if ( ch!='\\' )
-return( ch );
- ch2 = getc(sfd);
- if ( ch2=='\n' )
-return( nlgetc(sfd));
- ungetc(ch2,sfd);
-return( ch );
-}
-
-static char *SFDReadUTF7Str(FILE *sfd) {
- char *buffer = NULL, *pt, *end = NULL;
- int ch1, ch2, ch3, ch4, done, c;
- int prev_cnt=0, prev=0, in=0;
-
- ch1 = nlgetc(sfd);
- while ( isspace(ch1) && ch1!='\n' && ch1!='\r') ch1 = nlgetc(sfd);
- if ( ch1=='\n' || ch1=='\r' )
- ungetc(ch1,sfd);
- if ( ch1!='"' )
-return( NULL );
- pt = 0;
- while ( (ch1=nlgetc(sfd))!=EOF && ch1!='"' ) {
- done = 0;
- if ( !done && !in ) {
- if ( ch1=='+' ) {
- ch1 = nlgetc(sfd);
- if ( ch1=='-' ) {
- ch1 = '+';
- done = true;
- } else {
- in = true;
- prev_cnt = 0;
- }
- } else
- done = true;
- }
- if ( !done ) {
- if ( ch1=='-' ) {
- in = false;
- } else if ( inbase64[ch1]==-1 ) {
- in = false;
- done = true;
- } else {
- ch1 = inbase64[ch1];
- ch2 = inbase64[c = nlgetc(sfd)];
- if ( ch2==-1 ) {
- ungetc(c, sfd);
- ch2 = ch3 = ch4 = 0;
- } else {
- ch3 = inbase64[c = nlgetc(sfd)];
- if ( ch3==-1 ) {
- ungetc(c, sfd);
- ch3 = ch4 = 0;
- } else {
- ch4 = inbase64[c = nlgetc(sfd)];
- if ( ch4==-1 ) {
- ungetc(c, sfd);
- ch4 = 0;
- }
- }
- }
- ch1 = (ch1<<18) | (ch2<<12) | (ch3<<6) | ch4;
- if ( prev_cnt==0 ) {
- prev = ch1&0xff;
- ch1 >>= 8;
- prev_cnt = 1;
- } else /* if ( prev_cnt == 1 ) */ {
- ch1 |= (prev<<24);
- prev = (ch1&0xffff);
- ch1 = (ch1>>16)&0xffff;
- prev_cnt = 2;
- }
- done = true;
- }
- }
- if ( pt+10>=end ) {
- if ( buffer==NULL ) {
- pt = buffer = malloc(400);
- end = buffer+400;
- } else if (pt) {
- char *temp = realloc(buffer,end-buffer+400);
- pt = temp+(pt-buffer);
- end = temp+(end-buffer+400);
- buffer = temp;
- }
- }
- if ( pt && done )
- pt = utf8_idpb(pt,ch1,0);
- if ( prev_cnt==2 ) {
- prev_cnt = 0;
- if ( pt && prev!=0 )
- pt = utf8_idpb(pt,prev,0);
- }
- if ( pt==0 ) {
- free(buffer);
- return( NULL );
- }
- }
- if ( buffer==NULL )
-return( NULL );
- *pt = '\0';
- pt = copy(buffer);
- free(buffer );
-return( pt );
-}
-
-struct enc85 {
- FILE *sfd;
- unsigned char sofar[4];
- int pos;
- int ccnt;
-};
-
-static void *SFDUnPickle(FILE *sfd, int python_data_has_lists) {
- int ch, quoted;
- static int max = 0;
- static char *buf = NULL;
- char *pt, *end;
- int cnt;
-
- pt = buf; end = buf+max;
- while ( (ch=nlgetc(sfd))!='"' && ch!='\n' && ch!=EOF );
- if ( ch!='"' )
-return( NULL );
-
- quoted = false;
- while ( ((ch=nlgetc(sfd))!='"' || quoted) && ch!=EOF ) {
- if ( !quoted && ch=='\\' )
- quoted = true;
- else {
- if ( pt>=end ) {
- cnt = pt-buf;
- buf = realloc(buf,(max+=200)+1);
- pt = buf+cnt;
- end = buf+max;
- }
- *pt++ = ch;
- quoted = false;
- }
- }
- if ( pt==buf )
-return( NULL );
- *pt='\0';
-#ifdef _NO_PYTHON
-return( copy(buf));
-#else
-return( PyFF_UnPickleMeToObjects(buf));
-#endif
- /* buf is a static buffer, I don't free it, I'll reuse it next time */
-}
-
-/* ********************************* INPUT ********************************** */
-#include "sfd1.h"
-
-char *getquotedeol(FILE *sfd) {
- char *pt, *str, *end;
- int ch;
-
- pt = str = malloc(101); end = str+100;
- while ( isspace(ch = nlgetc(sfd)) && ch!='\r' && ch!='\n' );
- while ( ch!='\n' && ch!='\r' && ch!=EOF ) {
- if ( ch=='\\' ) {
- /* We can't use nlgetc() here, because it would misinterpret */
- /* double backslash at the end of line. Multiline strings, */
- /* broken with backslash + newline, are just handled above. */
- ch = getc(sfd);
- if ( ch=='n' ) ch='\n';
- /* else if ( ch=='\\' ) ch=='\\'; */ /* second backslash of '\\' */
-
- /* FontForge doesn't write other escape sequences in this context. */
- /* So any other value of ch is assumed impossible. */
- }
- if ( pt>=end ) {
- pt = realloc(str,end-str+101);
- end = pt+(end-str)+100;
- str = pt;
- pt = end-100;
- }
- *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
- /* these strings should be in utf8 now, but some old sfd files might have */
- /* latin1. Not a severe problems because they SHOULD be in ASCII. So any */
- /* non-ascii strings are erroneous anyway */
- if ( !utf8_valid(str) ) {
- pt = latin1_2_utf8_copy(str);
- free(str);
- str = pt;
- }
-return( str );
-}
-
-static int geteol(FILE *sfd, char *tokbuf) {
- char *pt=tokbuf, *end = tokbuf+2000-2; int ch;
-
- while ( isspace(ch = nlgetc(sfd)) && ch!='\r' && ch!='\n' );
- while ( ch!='\n' && ch!='\r' && ch!=EOF ) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
-return( pt!=tokbuf?1:ch==EOF?-1: 0 );
-}
-
-static int getprotectedname(FILE *sfd, char *tokbuf) {
- char *pt=tokbuf, *end = tokbuf+100-2; int ch;
-
- while ( (ch = nlgetc(sfd))==' ' || ch=='\t' );
- while ( ch!=EOF && !isspace(ch) && ch!='[' && ch!=']' && ch!='{' && ch!='}' && ch!='<' && ch!='%' ) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- if ( pt==tokbuf && ch!=EOF )
- *pt++ = ch;
- else
- ungetc(ch,sfd);
- *pt='\0';
-return( pt!=tokbuf?1:ch==EOF?-1: 0 );
-}
-
-int getname(FILE *sfd, char *tokbuf) {
- int ch;
-
- while ( isspace(ch = nlgetc(sfd)));
- ungetc(ch,sfd);
-return( getprotectedname(sfd,tokbuf));
-}
-
-static uint32 gettag(FILE *sfd) {
- int ch, quoted;
- uint32 tag;
-
- while ( (ch=nlgetc(sfd))==' ' );
- if ( (quoted = (ch=='\'')) ) ch = nlgetc(sfd);
- tag = (ch<<24)|(nlgetc(sfd)<<16);
- tag |= nlgetc(sfd)<<8;
- tag |= nlgetc(sfd);
- if ( quoted ) (void) nlgetc(sfd);
-return( tag );
-}
-
-static int getint(FILE *sfd, int *val) {
- char tokbuf[100]; int ch;
- char *pt=tokbuf, *end = tokbuf+100-2;
-
- while ( isspace(ch = nlgetc(sfd)));
- if ( ch=='-' || ch=='+' ) {
- *pt++ = ch;
- ch = nlgetc(sfd);
- }
- while ( isdigit(ch)) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
- ungetc(ch,sfd);
- *val = strtol(tokbuf,NULL,10);
-return( pt!=tokbuf?1:ch==EOF?-1: 0 );
-}
-
-static int getlonglong(FILE *sfd, long long *val) {
- char tokbuf[100]; int ch;
- char *pt=tokbuf, *end = tokbuf+100-2;
-
- while ( isspace(ch = nlgetc(sfd)));
- if ( ch=='-' || ch=='+' ) {
- *pt++ = ch;
- ch = nlgetc(sfd);
- }
- while ( isdigit(ch)) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
- ungetc(ch,sfd);
- *val = strtoll(tokbuf,NULL,10);
-return( pt!=tokbuf?1:ch==EOF?-1: 0 );
-}
-
-static int gethex(FILE *sfd, uint32 *val) {
- char tokbuf[100]; int ch;
- char *pt=tokbuf, *end = tokbuf+100-2;
-
- while ( isspace(ch = nlgetc(sfd)));
- if ( ch=='#' )
- ch = nlgetc(sfd);
- if ( ch=='-' || ch=='+' ) {
- *pt++ = ch;
- ch = nlgetc(sfd);
- }
- if ( ch=='0' ) {
- ch = nlgetc(sfd);
- if ( ch=='x' || ch=='X' )
- ch = nlgetc(sfd);
- else {
- ungetc(ch,sfd);
- ch = '0';
- }
- }
- while ( isdigit(ch) || (ch>='a' && ch<='f') || (ch>='A' && ch<='F')) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
- ungetc(ch,sfd);
- *val = strtoul(tokbuf,NULL,16);
-return( pt!=tokbuf?1:ch==EOF?-1: 0 );
-}
-
-static int gethexints(FILE *sfd, uint32 *val, int cnt) {
- int i, ch;
-
- for ( i=0; i<cnt; ++i ) {
- if ( i!=0 ) {
- ch = nlgetc(sfd);
- if ( ch!='.' ) ungetc(ch,sfd);
- }
- if ( !gethex(sfd,&val[i]))
-return( false );
- }
-return( true );
-}
-
-static int getsint(FILE *sfd, int16 *val) {
- int val2;
- int ret = getint(sfd,&val2);
- *val = val2;
-return( ret );
-}
-
-static int getusint(FILE *sfd, uint16 *val) {
- int val2;
- int ret = getint(sfd,&val2);
- *val = val2;
-return( ret );
-}
-
-static int getreal(FILE *sfd, real *val) {
- char tokbuf[100];
- int ch;
- char *pt=tokbuf, *end = tokbuf+100-2, *nend;
-
- while ( isspace(ch = nlgetc(sfd)));
- if ( ch!='e' && ch!='E' ) /* real's can't begin with exponants */
- while ( isdigit(ch) || ch=='-' || ch=='+' || ch=='e' || ch=='E' || ch=='.' || ch==',' ) {
- if ( pt<end ) *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt='\0';
- ungetc(ch,sfd);
- *val = strtod(tokbuf,&nend);
- /* Beware of different locals! */
- if ( *nend!='\0' ) {
- if ( *nend=='.' )
- *nend = ',';
- else if ( *nend==',' )
- *nend = '.';
- *val = strtod(tokbuf,&nend);
- }
-return( pt!=tokbuf && *nend=='\0'?1:ch==EOF?-1: 0 );
-}
-
-/* Don't use nlgetc here. We carefully control newlines when dumping in 85 */
-/* but backslashes can occur at end of line. */
-static int Dec85(struct enc85 *dec) {
- int ch1, ch2, ch3, ch4, ch5;
- unsigned int val;
-
- if ( dec->pos<0 ) {
- while ( isspace(ch1=getc(dec->sfd)));
- if ( ch1=='z' ) {
- dec->sofar[0] = dec->sofar[1] = dec->sofar[2] = dec->sofar[3] = 0;
- dec->pos = 3;
- } else {
- while ( isspace(ch2=getc(dec->sfd)));
- while ( isspace(ch3=getc(dec->sfd)));
- while ( isspace(ch4=getc(dec->sfd)));
- while ( isspace(ch5=getc(dec->sfd)));
- val = ((((ch1-'!')*85+ ch2-'!')*85 + ch3-'!')*85 + ch4-'!')*85 + ch5-'!';
- dec->sofar[3] = val>>24;
- dec->sofar[2] = val>>16;
- dec->sofar[1] = val>>8;
- dec->sofar[0] = val;
- dec->pos = 3;
- }
- }
-return( dec->sofar[dec->pos--] );
-}
-
-static void SFDGetType1(FILE *sfd) {
- /* We've read the OrigType1 token (this is now obselete, but parse it in case there are any old sfds) */
- int len;
- struct enc85 dec;
-
- memset(&dec,'\0', sizeof(dec)); dec.pos = -1;
- dec.sfd = sfd;
-
- getint(sfd,&len);
- while ( --len >= 0 )
- Dec85(&dec);
-}
-
-static void SFDGetTtfInstrs(FILE *sfd, SplineChar *sc) {
- /* We've read the TtfInstr token, it is followed by a byte count */
- /* and then the instructions in enc85 format */
- int i,len;
- struct enc85 dec;
-
- memset(&dec,'\0', sizeof(dec)); dec.pos = -1;
- dec.sfd = sfd;
-
- getint(sfd,&len);
- sc->ttf_instrs = malloc(len);
- sc->ttf_instrs_len = len;
- for ( i=0; i<len; ++i )
- sc->ttf_instrs[i] = Dec85(&dec);
-}
-
-static void tterr(void *UNUSED(rubbish), char *message, int UNUSED(pos)) {
- LogError(_("When loading tt instrs from sfd: %s\n"), message );
-}
-
-static void SFDGetTtInstrs(FILE *sfd, SplineChar *sc) {
- /* We've read the TtInstr token, it is followed by text versions of */
- /* the instructions, slurp it all into a big buffer, and then parse that */
- char *buf=NULL, *pt=buf, *end=buf;
- int ch;
- int backlen = strlen(end_tt_instrs);
- int instr_len;
-
- while ( (ch=nlgetc(sfd))!=EOF ) {
- if ( pt>=end ) {
- char *newbuf = realloc(buf,(end-buf+200));
- pt = newbuf+(pt-buf);
- end = newbuf+(end+200-buf);
- buf = newbuf;
- }
- *pt++ = ch;
- if ( pt-buf>backlen && strncmp(pt-backlen,end_tt_instrs,backlen)==0 ) {
- pt -= backlen;
- break;
- }
- }
- *pt = '\0';
-
- sc->ttf_instrs = _IVParse(sc->parent,buf,&instr_len,tterr,NULL);
- sc->ttf_instrs_len = instr_len;
-
- free(buf);
-}
-
-static struct ttf_table *SFDGetTtfTable(FILE *sfd, SplineFont *sf,struct ttf_table *lasttab[2]) {
- /* We've read the TtfTable token, it is followed by a tag and a byte count */
- /* and then the instructions in enc85 format */
- int i,len;
- int which;
- struct enc85 dec;
- struct ttf_table *tab = chunkalloc(sizeof(struct ttf_table));
-
- memset(&dec,'\0', sizeof(dec)); dec.pos = -1;
- dec.sfd = sfd;
-
- tab->tag = gettag(sfd);
-
- if ( tab->tag==CHR('f','p','g','m') || tab->tag==CHR('p','r','e','p') ||
- tab->tag==CHR('c','v','t',' ') || tab->tag==CHR('m','a','x','p'))
- which = 0;
- else
- which = 1;
-
- getint(sfd,&len);
- tab->data = malloc(len);
- tab->len = len;
- for ( i=0; i<len; ++i )
- tab->data[i] = Dec85(&dec);
-
- if ( lasttab[which]!=NULL )
- lasttab[which]->next = tab;
- else if ( which==0 )
- sf->ttf_tables = tab;
- else
- sf->ttf_tab_saved = tab;
- lasttab[which] = tab;
-return( tab );
-}
-
-static struct ttf_table *SFDGetShortTable(FILE *sfd, SplineFont *sf,struct ttf_table *lasttab[2]) {
- /* We've read the ShortTable token, it is followed by a tag and a word count */
- /* and then the (text) values of the words that make up the cvt table */
- int i,len, ch;
- uint8 *pt;
- int which, iscvt, started;
- struct ttf_table *tab = chunkalloc(sizeof(struct ttf_table));
-
- tab->tag = gettag(sfd);
-
- if ( tab->tag==CHR('f','p','g','m') || tab->tag==CHR('p','r','e','p') ||
- tab->tag==CHR('c','v','t',' ') || tab->tag==CHR('m','a','x','p'))
- which = 0;
- else
- which = 1;
- iscvt = tab->tag==CHR('c','v','t',' ');
-
- getint(sfd,&len);
- pt = tab->data = malloc(2*len);
- tab->len = 2*len;
- started = false;
- for ( i=0; i<len; ++i ) {
- int num;
- getint(sfd,&num);
- *pt++ = num>>8;
- *pt++ = num&0xff;
- if ( iscvt ) {
- ch = nlgetc(sfd);
- if ( ch==' ' ) {
- if ( !started ) {
- sf->cvt_names = calloc(len+1,sizeof(char *));
- sf->cvt_names[len] = END_CVT_NAMES;
- started = true;
- }
- sf->cvt_names[i] = SFDReadUTF7Str(sfd);
- } else
- ungetc(ch,sfd);
- }
- }
-
- if ( lasttab[which]!=NULL )
- lasttab[which]->next = tab;
- else if ( which==0 )
- sf->ttf_tables = tab;
- else
- sf->ttf_tab_saved = tab;
- lasttab[which] = tab;
-return( tab );
-}
-
-static struct ttf_table *SFDGetTtTable(FILE *sfd, SplineFont *sf,struct ttf_table *lasttab[2]) {
- /* We've read the TtTable token, it is followed by a tag */
- /* and then the instructions in text format */
- int ch;
- int which;
- struct ttf_table *tab = chunkalloc(sizeof(struct ttf_table));
- char *buf=NULL, *pt=buf, *end=buf;
- int backlen = strlen(end_tt_instrs);
-
- tab->tag = gettag(sfd);
-
- if ( tab->tag==CHR('f','p','g','m') || tab->tag==CHR('p','r','e','p') ||
- tab->tag==CHR('c','v','t',' ') || tab->tag==CHR('m','a','x','p'))
- which = 0;
- else
- which = 1;
-
- while ( (ch=nlgetc(sfd))!=EOF ) {
- if ( pt>=end ) {
- char *newbuf = realloc(buf,(end-buf+200));
- pt = newbuf+(pt-buf);
- end = newbuf+(end+200-buf);
- buf = newbuf;
- }
- *pt++ = ch;
- if ( pt-buf>backlen && strncmp(pt-backlen,end_tt_instrs,backlen)==0 ) {
- pt -= backlen;
- break;
- }
- }
- *pt = '\0';
- tab->data = _IVParse(sf,buf,(int*)&tab->len,tterr,NULL);
- free(buf);
-
- if ( lasttab[which]!=NULL )
- lasttab[which]->next = tab;
- else if ( which==0 )
- sf->ttf_tables = tab;
- else
- sf->ttf_tab_saved = tab;
- lasttab[which] = tab;
-return( tab );
-}
-
-static int SFDCloseCheck(SplinePointList *spl,int order2) {
- if ( spl->first!=spl->last &&
- RealNear(spl->first->me.x,spl->last->me.x) &&
- RealNear(spl->first->me.y,spl->last->me.y)) {
- SplinePoint *oldlast = spl->last;
- spl->first->prevcp = oldlast->prevcp;
- spl->first->noprevcp = oldlast->noprevcp;
- oldlast->prev->from->next = NULL;
- spl->last = oldlast->prev->from;
- chunkfree(oldlast->prev,sizeof(*oldlast));
- chunkfree(oldlast->hintmask,sizeof(HintMask));
- chunkfree(oldlast,sizeof(*oldlast));
- SplineMake(spl->last,spl->first,order2);
- spl->last = spl->first;
-return( true );
- }
-return( false );
-}
-
-static void SFDGetHintMask(FILE *sfd,HintMask *hintmask) {
- int nibble = 0, ch;
-
- memset(hintmask,0,sizeof(HintMask));
- for (;;) {
- ch = nlgetc(sfd);
- if ( isdigit(ch))
- ch -= '0';
- else if ( ch>='a' && ch<='f' )
- ch -= 'a'-10;
- else if ( ch>='A' && ch<='F' )
- ch -= 'A'-10;
- else {
- ungetc(ch,sfd);
- break;
- }
- if ( nibble<2*HntMax/8 )
- (*hintmask)[nibble>>1] |= ch<<(4*(1-(nibble&1)));
- ++nibble;
- }
-}
-
-static void SFDGetSpiros(FILE *sfd,SplineSet *cur) {
- int ch;
- spiro_cp cp;
-
- ch = nlgetc(sfd); /* S */
- ch = nlgetc(sfd); /* p */
- ch = nlgetc(sfd); /* i */
- ch = nlgetc(sfd); /* r */
- ch = nlgetc(sfd); /* o */
- while ( fscanf(sfd,"%lg %lg %c", &cp.x, &cp.y, &cp.ty )==3 ) {
- if ( cur!=NULL ) {
- if ( cur->spiro_cnt>=cur->spiro_max )
- cur->spiros = realloc(cur->spiros,(cur->spiro_max+=10)*sizeof(spiro_cp));
- cur->spiros[cur->spiro_cnt++] = cp;
- }
- }
- if ( cur!=NULL && (cur->spiros[cur->spiro_cnt-1].ty&0x7f)!=SPIRO_END ) {
- if ( cur->spiro_cnt>=cur->spiro_max )
- cur->spiros = realloc(cur->spiros,(cur->spiro_max+=1)*sizeof(spiro_cp));
- memset(&cur->spiros[cur->spiro_cnt],0,sizeof(spiro_cp));
- cur->spiros[cur->spiro_cnt++].ty = SPIRO_END;
- }
- ch = nlgetc(sfd);
- if ( ch=='E' ) {
- ch = nlgetc(sfd); /* n */
- ch = nlgetc(sfd); /* d */
- ch = nlgetc(sfd); /* S */
- ch = nlgetc(sfd); /* p */
- ch = nlgetc(sfd); /* i */
- ch = nlgetc(sfd); /* r */
- ch = nlgetc(sfd); /* o */
- } else
- ungetc(ch,sfd);
-}
-
-static SplineSet *SFDGetSplineSet(FILE *sfd,int order2) {
- SplinePointList *cur=NULL, *head=NULL;
- BasePoint current;
- real stack[100];
- int sp=0;
- SplinePoint *pt = NULL;
- int ch;
- int ch2;
- char tok[100];
- int ttfindex = 0;
- int lastacceptable;
-
- current.x = current.y = 0;
- lastacceptable = 0;
- while ( 1 ) {
- int have_read_val = 0;
- int val = 0;
-
- while ( getreal(sfd,&stack[sp])==1 )
- if ( sp<99 )
- ++sp;
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch=='E' || ch=='e' || ch==EOF )
- break;
- if ( ch=='S' ) {
- ungetc(ch,sfd);
- SFDGetSpiros(sfd,cur);
- continue;
- } else if (( ch=='N' ) &&
- nlgetc(sfd)=='a' && /* a */
- nlgetc(sfd)=='m' && /* m */
- nlgetc(sfd)=='e' && /* e */
- nlgetc(sfd)=='d' ) /* d */ {
- ch2 = nlgetc(sfd); /* : */
- // We are either fetching a splineset name (Named:) or a point name (NamedP:).
- if (ch2=='P') { if ((nlgetc(sfd)==':') && (pt!=NULL)) { if (pt->name!=NULL) {free(pt->name);} pt->name = SFDReadUTF7Str(sfd); } }
- else if (ch2==':') { if (cur != NULL) cur->contour_name = SFDReadUTF7Str(sfd); else { char * freetmp = SFDReadUTF7Str(sfd); free(freetmp); freetmp = NULL; } }
- continue;
- } else if ( ch=='P' && PeekMatch(sfd,"ath") ) {
- int flags;
- nlgetc(sfd); /* a */
- nlgetc(sfd); /* t */
- nlgetc(sfd); /* h */
- if (PeekMatch(sfd,"Flags:")) {
- nlgetc(sfd); /* F */
- nlgetc(sfd); /* l */
- nlgetc(sfd); /* a */
- nlgetc(sfd); /* g */
- nlgetc(sfd); /* s */
- nlgetc(sfd); /* : */
- getint(sfd,&flags);
- if (cur != NULL) cur->is_clip_path = flags&1;
- } else if (PeekMatch(sfd,"Start:")) {
- nlgetc(sfd); /* S */
- nlgetc(sfd); /* t */
- nlgetc(sfd); /* a */
- nlgetc(sfd); /* r */
- nlgetc(sfd); /* t */
- nlgetc(sfd); /* : */
- getint(sfd,&flags);
- if (cur != NULL) cur->start_offset = flags;
- }
- }
- pt = NULL;
- if ( ch=='l' || ch=='m' ) {
- if ( sp>=2 ) {
- current.x = stack[sp-2];
- current.y = stack[sp-1];
- sp -= 2;
- pt = chunkalloc(sizeof(SplinePoint));
- pt->me = current;
- pt->noprevcp = true; pt->nonextcp = true;
- if ( ch=='m' ) {
- SplinePointList *spl = chunkalloc(sizeof(SplinePointList));
- spl->first = spl->last = pt;
- spl->start_offset = 0;
- if ( cur!=NULL ) {
- if ( SFDCloseCheck(cur,order2))
- --ttfindex;
- cur->next = spl;
- } else
- head = spl;
- cur = spl;
- } else {
- if ( cur!=NULL && cur->first!=NULL && (cur->first!=cur->last || cur->first->next==NULL) ) {
- if ( cur->last->nextcpindex==0xfffe )
- cur->last->nextcpindex = 0xffff;
- SplineMake(cur->last,pt,order2);
- cur->last->nonextcp = 1;
- pt->noprevcp = 1;
- cur->last = pt;
- }
- }
- } else
- sp = 0;
- } else if ( ch=='c' ) {
- if ( sp>=6 ) {
- getint(sfd,&val);
- have_read_val = 1;
-
-
- current.x = stack[sp-2];
- current.y = stack[sp-1];
- real original_current_x = current.x;
- if( val & SFD_PTFLAG_FORCE_OPEN_PATH )
- {
- // Find somewhere vacant to put the point.x for now
- // we need to do this check in case we choose a point that is already
- // on the spline and this connect back to that point instead of creating
- // an open path
- while( 1 )
- {
- real offset = 0.1;
- current.x += offset;
- if( !cur || !SplinePointListContainsPointAtX( cur, current.x ))
- {
- break;
- }
- }
- }
-
- if ( cur!=NULL && cur->first!=NULL && (cur->first!=cur->last || cur->first->next==NULL) ) {
- cur->last->nextcp.x = stack[sp-6];
- cur->last->nextcp.y = stack[sp-5];
- cur->last->nonextcp = false;
- pt = chunkalloc(sizeof(SplinePoint));
- pt->prevcp.x = stack[sp-4];
- pt->prevcp.y = stack[sp-3];
- pt->me = current;
- pt->nonextcp = true;
- if ( cur->last->nextcpindex==0xfffe )
- cur->last->nextcpindex = ttfindex++;
- else if ( cur->last->nextcpindex!=0xffff )
- ttfindex = cur->last->nextcpindex+1;
- SplineMake(cur->last,pt,order2);
- cur->last = pt;
- // pt->me is a copy of 'current' so we should now move
- // the x coord of pt->me back to where it should be.
- // The whole aim here is that this spline remains an open path
- // when PTFLAG_FORCE_OPEN_PATH is set.
- pt->me.x = original_current_x;
- }
-
- // Move the point back to the same location it was
- // but do not connect it back to the point that is
- // already there.
- if( val & SFD_PTFLAG_FORCE_OPEN_PATH )
- {
- current.x = original_current_x;
- }
-
- sp -= 6;
- } else
- sp = 0;
- }
- if ( pt!=NULL ) {
- if( !have_read_val )
- getint(sfd,&val);
-
- pt->pointtype = (val & SFD_PTFLAG_TYPE_MASK);
- pt->selected = (val & SFD_PTFLAG_IS_SELECTED) > 0;
- pt->nextcpdef = (val & SFD_PTFLAG_NEXTCP_IS_DEFAULT) > 0;
- pt->prevcpdef = (val & SFD_PTFLAG_PREVCP_IS_DEFAULT) > 0;
- pt->roundx = (val & SFD_PTFLAG_ROUND_IN_X) > 0;
- pt->roundy = (val & SFD_PTFLAG_ROUND_IN_Y) > 0;
- pt->dontinterpolate = (val & SFD_PTFLAG_INTERPOLATE_NEVER) > 0;
- if ( pt->prev!=NULL )
- pt->prev->acceptableextrema = (val & SFD_PTFLAG_PREV_EXTREMA_MARKED_ACCEPTABLE) > 0;
- else
- lastacceptable = (val & SFD_PTFLAG_PREV_EXTREMA_MARKED_ACCEPTABLE) > 0;
- if ( val&0x80 )
- pt->ttfindex = 0xffff;
- else
- pt->ttfindex = ttfindex++;
- pt->nextcpindex = 0xfffe;
- ch = nlgetc(sfd);
- if ( ch=='x' ) {
- pt->hintmask = chunkalloc(sizeof(HintMask));
- SFDGetHintMask(sfd,pt->hintmask);
- } else if ( ch!=',' )
- ungetc(ch,sfd);
- else {
- ch = nlgetc(sfd);
- if ( ch==',' )
- pt->ttfindex = 0xfffe;
- else {
- ungetc(ch,sfd);
- getint(sfd,&val);
- pt->ttfindex = val;
- nlgetc(sfd); /* skip comma */
- if ( val!=-1 )
- ttfindex = val+1;
- }
- ch = nlgetc(sfd);
- if ( ch=='\r' || ch=='\n' )
- ungetc(ch,sfd);
- else {
- ungetc(ch,sfd);
- getint(sfd,&val);
- pt->nextcpindex = val;
- if ( val!=-1 )
- ttfindex = val+1;
- }
- }
- }
- }
- if ( cur!=NULL )
- SFDCloseCheck(cur,order2);
- if ( lastacceptable && cur->last->prev!=NULL )
- cur->last->prev->acceptableextrema = true;
- getname(sfd,tok);
-return( head );
-}
-
-static void SFDGetMinimumDistances(FILE *sfd, SplineChar *sc) {
- SplineSet *ss;
- SplinePoint *sp;
- int pt,i, val, err;
- int ch;
- SplinePoint **mapping=NULL;
- MinimumDistance *last, *md, *mdhead=NULL;
-
- for ( i=0; i<2; ++i ) {
- pt = 0;
- for ( ss = sc->layers[ly_fore].splines; ss!=NULL; ss=ss->next ) {
- for ( sp=ss->first; ; ) {
- if ( mapping!=NULL ) mapping[pt] = sp;
- pt++;
- if ( sp->next == NULL )
- break;
- sp = sp->next->to;
- if ( sp==ss->first )
- break;
- }
- }
- if ( mapping==NULL )
- mapping = calloc(pt,sizeof(SplinePoint *));
- }
-
- last = NULL;
- for ( ch=nlgetc(sfd); ch!=EOF && ch!='\n'; ch=nlgetc(sfd)) {
- err = false;
- while ( isspace(ch) && ch!='\n' ) ch=nlgetc(sfd);
- if ( ch=='\n' )
- break;
- md = chunkalloc(sizeof(MinimumDistance));
- if ( ch=='x' ) md->x = true;
- getint(sfd,&val);
- if ( val<-1 || val>=pt ) {
- IError( "Minimum Distance specifies bad point (%d) in sfd file\n", val );
- err = true;
- } else if ( val!=-1 ) {
- md->sp1 = mapping[val];
- md->sp1->dontinterpolate = true;
- }
- ch = nlgetc(sfd);
- if ( ch!=',' ) {
- IError( "Minimum Distance lacks a comma where expected\n" );
- err = true;
- }
- getint(sfd,&val);
- if ( val<-1 || val>=pt ) {
- IError( "Minimum Distance specifies bad point (%d) in sfd file\n", val );
- err = true;
- } else if ( val!=-1 ) {
- md->sp2 = mapping[val];
- md->sp2->dontinterpolate = true;
- }
- if ( !err ) {
- if ( last!=NULL )
- last->next = md;
- last = md;
- } else
- chunkfree(md,sizeof(MinimumDistance));
- }
- free(mapping);
-
- /* Obsolete concept */
- MinimumDistancesFree(mdhead);
-}
-
-static HintInstance *SFDReadHintInstances(FILE *sfd, StemInfo *stem) {
- HintInstance *head=NULL, *last=NULL, *cur;
- real begin, end;
- int ch;
-
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- if ( ch=='G' && stem != NULL ) {
- stem->ghost = true;
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- }
- if ( ch!='<' ) {
- ungetc(ch,sfd);
-return(NULL);
- }
- while ( getreal(sfd,&begin)==1 && getreal(sfd,&end)) {
- cur = chunkalloc(sizeof(HintInstance));
- cur->begin = begin;
- cur->end = end;
- if ( head == NULL )
- head = cur;
- else
- last->next = cur;
- last = cur;
- }
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- if ( ch!='>' )
- ungetc(ch,sfd);
-return( head );
-}
-
-static StemInfo *SFDReadHints(FILE *sfd) {
- StemInfo *head=NULL, *last=NULL, *cur;
- real start, width;
-
- while ( getreal(sfd,&start)==1 && getreal(sfd,&width)) {
- cur = chunkalloc(sizeof(StemInfo));
- cur->start = start;
- cur->width = width;
- cur->where = SFDReadHintInstances(sfd,cur);
- if ( head == NULL )
- head = cur;
- else
- last->next = cur;
- last = cur;
- }
-return( head );
-}
-
-static DStemInfo *SFDReadDHints( SplineFont *sf,FILE *sfd,int old ) {
- DStemInfo *head=NULL, *last=NULL, *cur;
- int i;
- BasePoint bp[4], *bpref[4], left, right, unit;
- double rstartoff, rendoff, lendoff;
-
- if ( old ) {
- for ( i=0 ; i<4 ; i++ ) bpref[i] = &bp[i];
-
- while ( getreal( sfd,&bp[0].x ) && getreal( sfd,&bp[0].y ) &&
- getreal( sfd,&bp[1].x ) && getreal( sfd,&bp[1].y ) &&
- getreal( sfd,&bp[2].x ) && getreal( sfd,&bp[2].y ) &&
- getreal( sfd,&bp[3].x ) && getreal( sfd,&bp[3].y )) {
-
- /* Ensure point coordinates specified in the sfd file do */
- /* form a diagonal line */
- if ( PointsDiagonalable( sf,bpref,&unit )) {
- cur = chunkalloc( sizeof( DStemInfo ));
- cur->left = *bpref[0];
- cur->right = *bpref[1];
- cur->unit = unit;
- /* Generate a temporary hint instance, so that the hint can */
- /* be visible in charview even if subsequent rebuilding instances */
- /* fails (e. g. for composite characters) */
- cur->where = chunkalloc( sizeof( HintInstance ));
- rstartoff = ( cur->right.x - cur->left.x ) * cur->unit.x +
- ( cur->right.y - cur->left.y ) * cur->unit.y;
- rendoff = ( bpref[2]->x - cur->left.x ) * cur->unit.x +
- ( bpref[2]->y - cur->left.y ) * cur->unit.y;
- lendoff = ( bpref[3]->x - cur->left.x ) * cur->unit.x +
- ( bpref[3]->y - cur->left.y ) * cur->unit.y;
- cur->where->begin = ( rstartoff > 0 ) ? rstartoff : 0;
- cur->where->end = ( rendoff > lendoff ) ? lendoff : rendoff;
- MergeDStemInfo( sf,&head,cur );
- }
- }
- } else {
- while ( getreal( sfd,&left.x ) && getreal( sfd,&left.y ) &&
- getreal( sfd,&right.x ) && getreal( sfd,&right.y ) &&
- getreal( sfd,&unit.x ) && getreal( sfd,&unit.y )) {
- cur = chunkalloc( sizeof( DStemInfo ));
- cur->left = left;
- cur->right = right;
- cur->unit = unit;
- cur->where = SFDReadHintInstances( sfd,NULL );
- if ( head == NULL )
- head = cur;
- else
- last->next = cur;
- last = cur;
- }
- }
-return( head );
-}
-
-static DeviceTable *SFDReadDeviceTable(FILE *sfd,DeviceTable *adjust) {
- int i, junk, first, last, ch, len;
-
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='{' ) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='}' )
-return(NULL);
- else
- ungetc(ch,sfd);
- getint(sfd,&first);
- ch = nlgetc(sfd); /* Should be '-' */
- getint(sfd,&last);
- len = last-first+1;
- if ( len<=0 ) {
- IError( "Bad device table, invalid length.\n" );
-return(NULL);
- }
- if ( adjust==NULL )
- adjust = chunkalloc(sizeof(DeviceTable));
- adjust->first_pixel_size = first;
- adjust->last_pixel_size = last;
- adjust->corrections = malloc(len);
- for ( i=0; i<len; ++i ) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=',' ) ungetc(ch,sfd);
- getint(sfd,&junk);
- adjust->corrections[i] = junk;
- }
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!='}' ) ungetc(ch,sfd);
- } else
- ungetc(ch,sfd);
-return( adjust );
-}
-
-static ValDevTab *SFDReadValDevTab(FILE *sfd) {
- int i, j, ch;
- ValDevTab vdt;
- char buf[4];
-
- memset(&vdt,0,sizeof(vdt));
- buf[3] = '\0';
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='[' ) {
- for ( i=0; i<4; ++i ) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch==']' )
- break;
- buf[0]=ch;
- for ( j=1; j<3; ++j ) buf[j]=nlgetc(sfd);
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!='=' ) ungetc(ch,sfd);
- SFDReadDeviceTable(sfd,
- strcmp(buf,"ddx")==0 ? &vdt.xadjust :
- strcmp(buf,"ddy")==0 ? &vdt.yadjust :
- strcmp(buf,"ddh")==0 ? &vdt.xadv :
- strcmp(buf,"ddv")==0 ? &vdt.yadv :
- (&vdt.xadjust) + i );
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=']' ) ungetc(ch,sfd);
- else
- break;
- }
- if ( vdt.xadjust.corrections!=NULL || vdt.yadjust.corrections!=NULL ||
- vdt.xadv.corrections!=NULL || vdt.yadv.corrections!=NULL ) {
- ValDevTab *v = chunkalloc(sizeof(ValDevTab));
- *v = vdt;
-return( v );
- }
- } else
- ungetc(ch,sfd);
-return( NULL );
-}
-
-static AnchorPoint *SFDReadAnchorPoints(FILE *sfd,SplineChar *sc,AnchorPoint** alist, AnchorPoint *lastap)
-{
- AnchorPoint *ap = chunkalloc(sizeof(AnchorPoint));
- AnchorClass *an;
- char *name;
- char tok[200];
- int ch;
-
- name = SFDReadUTF7Str(sfd);
- if ( name==NULL ) {
- LogError(_("Anchor Point with no class name: %s"), sc->name );
- AnchorPointsFree(ap);
-return( lastap );
- }
- for ( an=sc->parent->anchor; an!=NULL && strcmp(an->name,name)!=0; an=an->next );
- free(name);
- ap->anchor = an;
- getreal(sfd,&ap->me.x);
- getreal(sfd,&ap->me.y);
- ap->type = -1;
- if ( getname(sfd,tok)==1 ) {
- if ( strcmp(tok,"mark")==0 )
- ap->type = at_mark;
- else if ( strcmp(tok,"basechar")==0 )
- ap->type = at_basechar;
- else if ( strcmp(tok,"baselig")==0 )
- ap->type = at_baselig;
- else if ( strcmp(tok,"basemark")==0 )
- ap->type = at_basemark;
- else if ( strcmp(tok,"entry")==0 )
- ap->type = at_centry;
- else if ( strcmp(tok,"exit")==0 )
- ap->type = at_cexit;
- }
- getsint(sfd,&ap->lig_index);
- ch = nlgetc(sfd);
- ungetc(ch,sfd);
- if ( ch==' ' ) {
- SFDReadDeviceTable(sfd,&ap->xadjust);
- SFDReadDeviceTable(sfd,&ap->yadjust);
- ch = nlgetc(sfd);
- ungetc(ch,sfd);
- if ( isdigit(ch)) {
- getsint(sfd,(int16 *) &ap->ttf_pt_index);
- ap->has_ttf_pt = true;
- }
- }
- if ( ap->anchor==NULL || ap->type==-1 ) {
- LogError(_("Bad Anchor Point: %s"), sc->name );
- AnchorPointsFree(ap);
-return( lastap );
- }
- if ( lastap==NULL )
- (*alist) = ap;
- else
- lastap->next = ap;
-
- return( ap );
-}
-
-static RefChar *SFDGetRef(FILE *sfd, int was_enc) {
- RefChar *rf;
- int temp=0, ch;
-
- rf = RefCharCreate();
- getint(sfd,&rf->orig_pos);
- rf->encoded = was_enc;
- if ( getint(sfd,&temp))
- rf->unicode_enc = temp;
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch=='S' ) rf->selected = true;
- getreal(sfd,&rf->transform[0]);
- getreal(sfd,&rf->transform[1]);
- getreal(sfd,&rf->transform[2]);
- getreal(sfd,&rf->transform[3]);
- getreal(sfd,&rf->transform[4]);
- getreal(sfd,&rf->transform[5]);
- while ( (ch=nlgetc(sfd))==' ');
- ungetc(ch,sfd);
- if ( isdigit(ch) ) {
- getint(sfd,&temp);
- rf->use_my_metrics = temp&1;
- rf->round_translation_to_grid = (temp&2)?1:0;
- rf->point_match = (temp&4)?1:0;
- if ( rf->point_match ) {
- getsint(sfd,(int16 *) &rf->match_pt_base);
- getsint(sfd,(int16 *) &rf->match_pt_ref);
- while ( (ch=nlgetc(sfd))==' ');
- if ( ch=='O' )
- rf->point_match_out_of_date = true;
- else
- ungetc(ch,sfd);
- }
- }
-return( rf );
-}
-
-/* I used to create multiple ligatures by putting ";" between them */
-/* that is the component string for "ffi" was "ff i ; f f i" */
-/* Now I want to have separate ligature structures for each */
-static PST1 *LigaCreateFromOldStyleMultiple(PST1 *liga) {
- char *pt;
- PST1 *new, *last=liga;
- while ( (pt = strrchr(liga->pst.u.lig.components,';'))!=NULL ) {
- new = chunkalloc(sizeof( PST1 ));
- *new = *liga;
- new->pst.u.lig.components = copy(pt+1);
- last->pst.next = (PST *) new;
- last = new;
- *pt = '\0';
- }
-return( last );
-}
-
-#ifdef FONTFORGE_CONFIG_CVT_OLD_MAC_FEATURES
-static struct { int feature, setting; uint32 tag; } formertags[] = {
- { 1, 6, CHR('M','L','O','G') },
- { 1, 8, CHR('M','R','E','B') },
- { 1, 10, CHR('M','D','L','G') },
- { 1, 12, CHR('M','S','L','G') },
- { 1, 14, CHR('M','A','L','G') },
- { 8, 0, CHR('M','S','W','I') },
- { 8, 2, CHR('M','S','W','F') },
- { 8, 4, CHR('M','S','L','I') },
- { 8, 6, CHR('M','S','L','F') },
- { 8, 8, CHR('M','S','N','F') },
- { 22, 1, CHR('M','W','I','D') },
- { 27, 1, CHR('M','U','C','M') },
- { 103, 2, CHR('M','W','I','D') },
- { -1, -1, 0xffffffff },
-};
-
-static void CvtOldMacFeature(PST1 *pst) {
- int i;
-
- if ( pst->macfeature )
-return;
- for ( i=0; formertags[i].feature!=-1 ; ++i ) {
- if ( pst->tag == formertags[i].tag ) {
- pst->macfeature = true;
- pst->tag = (formertags[i].feature<<16) | formertags[i].setting;
-return;
- }
- }
-}
-#endif
-
-static void SFDSetEncMap(SplineFont *sf,int orig_pos,int enc) {
- EncMap *map = sf->map;
-
- if ( map==NULL )
-return;
-
- if ( orig_pos>=map->backmax ) {
- int old = map->backmax;
- map->backmax = orig_pos+10;
- map->backmap = realloc(map->backmap,map->backmax*sizeof(int));
- memset(map->backmap+old,-1,(map->backmax-old)*sizeof(int));
- }
- if ( map->backmap[orig_pos] == -1 ) /* backmap will not be unique if multiple encodings come from same glyph */
- map->backmap[orig_pos] = enc;
- if ( enc>=map->encmax ) {
- int old = map->encmax;
- map->encmax = enc+10;
- map->map = realloc(map->map,map->encmax*sizeof(int));
- memset(map->map+old,-1,(map->encmax-old)*sizeof(int));
- }
- if ( enc>=map->enccount )
- map->enccount = enc+1;
- if ( enc!=-1 )
- map->map[enc] = orig_pos;
-}
-
-static void SCDefaultInterpolation(SplineChar *sc) {
- SplineSet *cur;
- SplinePoint *sp;
- /* We used not to store the dontinterpolate bit. We used to use the */
- /* presence or absence of instructions as that flag */
-
- if ( sc->ttf_instrs_len!=0 ) {
- for ( cur=sc->layers[ly_fore].splines; cur!=NULL; cur=cur->next ) {
- for ( sp=cur->first; ; ) {
- if ( sp->ttfindex!=0xffff && SPInterpolate(sp))
- sp->dontinterpolate = true;
- if ( sp->next==NULL )
- break;
- sp=sp->next->to;
- if ( sp==cur->first )
- break;
- }
- }
- }
-}
-
-static void SFDParseMathValueRecord(FILE *sfd,int16 *value,DeviceTable **devtab) {
- getsint(sfd,value);
- *devtab = SFDReadDeviceTable(sfd,NULL);
-}
-
-static struct glyphvariants *SFDParseGlyphComposition(FILE *sfd,
- struct glyphvariants *gv, char *tok) {
- int i;
-
- if ( gv==NULL )
- gv = chunkalloc(sizeof(struct glyphvariants));
- getint(sfd,&gv->part_cnt);
- gv->parts = calloc(gv->part_cnt,sizeof(struct gv_part));
- for ( i=0; i<gv->part_cnt; ++i ) {
- int temp, ch;
- getname(sfd,tok);
- gv->parts[i].component = copy(tok);
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!='%' ) ungetc(ch,sfd);
- getint(sfd,&temp);
- gv->parts[i].is_extender = temp;
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=',' ) ungetc(ch,sfd);
- getint(sfd,&temp);
- gv->parts[i].startConnectorLength=temp;
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=',' ) ungetc(ch,sfd);
- getint(sfd,&temp);
- gv->parts[i].endConnectorLength = temp;
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=',' ) ungetc(ch,sfd);
- getint(sfd,&temp);
- gv->parts[i].fullAdvance = temp;
- }
-return( gv );
-}
-
-static void SFDParseVertexKern(FILE *sfd, struct mathkernvertex *vertex) {
- int i,ch;
-
- getint(sfd,&vertex->cnt);
- vertex->mkd = calloc(vertex->cnt,sizeof(struct mathkerndata));
- for ( i=0; i<vertex->cnt; ++i ) {
- SFDParseMathValueRecord(sfd,&vertex->mkd[i].height,&vertex->mkd[i].height_adjusts);
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!=EOF && ch!=',' )
- ungetc(ch,sfd);
- SFDParseMathValueRecord(sfd,&vertex->mkd[i].kern,&vertex->mkd[i].kern_adjusts);
- }
-}
-
-static struct gradient *SFDParseGradient(FILE *sfd,char *tok) {
- struct gradient *grad = chunkalloc(sizeof(struct gradient));
- int ch, i;
-
- getreal(sfd,&grad->start.x);
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!=';' ) ungetc(ch,sfd);
- getreal(sfd,&grad->start.y);
-
- getreal(sfd,&grad->stop.x);
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!=';' ) ungetc(ch,sfd);
- getreal(sfd,&grad->stop.y);
-
- getreal(sfd,&grad->radius);
-
- getname(sfd,tok);
- for ( i=0; spreads[i]!=NULL; ++i )
- if ( strmatch(spreads[i],tok)==0 )
- break;
- if ( spreads[i]==NULL ) i=0;
- grad->sm = i;
-
- getint(sfd,&grad->stop_cnt);
- grad->grad_stops = calloc(grad->stop_cnt,sizeof(struct grad_stops));
- for ( i=0; i<grad->stop_cnt; ++i ) {
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!='{' ) ungetc(ch,sfd);
- getreal( sfd, &grad->grad_stops[i].offset );
- gethex( sfd, &grad->grad_stops[i].col );
- getreal( sfd, &grad->grad_stops[i].opacity );
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!='}' ) ungetc(ch,sfd);
- }
-return( grad );
-}
-
-static struct pattern *SFDParsePattern(FILE *sfd,char *tok) {
- struct pattern *pat = chunkalloc(sizeof(struct pattern));
- int ch;
-
- getname(sfd,tok);
- pat->pattern = copy(tok);
-
- getreal(sfd,&pat->width);
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!=';' ) ungetc(ch,sfd);
- getreal(sfd,&pat->height);
-
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!='[' ) ungetc(ch,sfd);
- getreal(sfd,&pat->transform[0]);
- getreal(sfd,&pat->transform[1]);
- getreal(sfd,&pat->transform[2]);
- getreal(sfd,&pat->transform[3]);
- getreal(sfd,&pat->transform[4]);
- getreal(sfd,&pat->transform[5]);
- while ( isspace(ch=nlgetc(sfd)));
- if ( ch!=']' ) ungetc(ch,sfd);
-return( pat );
-}
-
-
-static int orig_pos;
-
-static SplineChar *SFDGetChar(FILE *sfd,SplineFont *sf, int had_sf_layer_cnt) {
- SplineChar *sc;
- char tok[2000], ch;
- RefChar *lastr=NULL, *ref;
- AnchorPoint *lastap = NULL;
- int isliga = 0, ispos, issubs=0, ismult=0, islcar=0, ispair=0, temp, i;
- PST *last = NULL;
- uint32 script = 0;
- int current_layer = ly_fore;
- int had_old_dstems = false;
- SplineFont *sli_sf = sf->cidmaster ? sf->cidmaster : sf;
- struct altuni *altuni;
- int oldback = false;
-
- if ( getname(sfd,tok)!=1 )
-return( NULL );
- if ( strcmp(tok,"StartChar:")!=0 )
-return( NULL );
- while ( isspace(ch=nlgetc(sfd)));
- ungetc(ch,sfd);
- sc = SFSplineCharCreate(sf);
- if ( ch!='"' ) {
- if ( getname(sfd,tok)!=1 ) {
- SplineCharFree(sc);
-return( NULL );
- }
- sc->name = copy(tok);
- } else {
- sc->name = SFDReadUTF7Str(sfd);
- if ( sc->name==NULL ) {
- SplineCharFree(sc);
-return( NULL );
- }
- }
- sc->vwidth = sf->ascent+sf->descent;
- sc->parent = sf;
- while ( 1 ) {
- if ( getname(sfd,tok)!=1 ) {
- SplineCharFree(sc);
-return( NULL );
- }
- if ( strmatch(tok,"Encoding:")==0 ) {
- int enc;
- getint(sfd,&enc);
- getint(sfd,&sc->unicodeenc);
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- ungetc(ch,sfd);
- if ( ch!='\n' && ch!='\r' ) {
- getint(sfd,&sc->orig_pos);
- if ( sc->orig_pos==65535 )
- sc->orig_pos = orig_pos++;
- /* An old mark meaning: "I don't know" */
- if ( sc->orig_pos<sf->glyphcnt && sf->glyphs[sc->orig_pos]!=NULL )
- sc->orig_pos = sf->glyphcnt;
- if ( sc->orig_pos>=sf->glyphcnt ) {
- if ( sc->orig_pos>=sf->glyphmax )
- sf->glyphs = realloc(sf->glyphs,(sf->glyphmax = sc->orig_pos+10)*sizeof(SplineChar *));
- memset(sf->glyphs+sf->glyphcnt,0,(sc->orig_pos+1-sf->glyphcnt)*sizeof(SplineChar *));
- sf->glyphcnt = sc->orig_pos+1;
- }
- if ( sc->orig_pos+1 > orig_pos )
- orig_pos = sc->orig_pos+1;
- } else if ( sf->cidmaster!=NULL ) { /* In cid fonts the orig_pos is just the cid */
- sc->orig_pos = enc;
- } else {
- sc->orig_pos = orig_pos++;
- }
- SFDSetEncMap(sf,sc->orig_pos,enc);
- } else if ( strmatch(tok,"AltUni:")==0 ) {
- int uni;
- while ( getint(sfd,&uni)==1 ) {
- altuni = chunkalloc(sizeof(struct altuni));
- altuni->unienc = uni;
- altuni->vs = -1;
- altuni->fid = 0;
- altuni->next = sc->altuni;
- sc->altuni = altuni;
- }
- } else if ( strmatch(tok,"AltUni2:")==0 ) {
- uint32 uni[3];
- while ( gethexints(sfd,uni,3) ) {
- altuni = chunkalloc(sizeof(struct altuni));
- altuni->unienc = uni[0];
- altuni->vs = uni[1];
- altuni->fid = uni[2];
- altuni->next = sc->altuni;
- sc->altuni = altuni;
- }
- } else if ( strmatch(tok,"OldEncoding:")==0 ) {
- int old_enc; /* Obsolete info */
- getint(sfd,&old_enc);
- } else if ( strmatch(tok,"Script:")==0 ) {
- /* Obsolete. But still used for parsing obsolete ligature/subs tags */
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- if ( ch=='\n' || ch=='\r' )
- script = 0;
- else {
- ungetc(ch,sfd);
- script = gettag(sfd);
- }
- } else if ( strmatch(tok,"GlifName:")==0 ) {
- while ( isspace(ch=nlgetc(sfd)));
- ungetc(ch,sfd);
- if ( ch!='"' ) {
- if ( getname(sfd,tok)!=1 ) {
- LogError(_("Invalid glif name.\n"));
- }
- sc->glif_name = copy(tok);
- } else {
- sc->glif_name = SFDReadUTF7Str(sfd);
- if ( sc->glif_name==NULL ) {
- LogError(_("Invalid glif name.\n"));
- }
- }
- } else if ( strmatch(tok,"Width:")==0 ) {
- getsint(sfd,&sc->width);
- } else if ( strmatch(tok,"VWidth:")==0 ) {
- getsint(sfd,&sc->vwidth);
- } else if ( strmatch(tok,"GlyphClass:")==0 ) {
- getint(sfd,&temp);
- sc->glyph_class = temp;
- } else if ( strmatch(tok,"UnlinkRmOvrlpSave:")==0 ) {
- getint(sfd,&temp);
- sc->unlink_rm_ovrlp_save_undo = temp;
- } else if ( strmatch(tok,"InSpiro:")==0 ) {
- getint(sfd,&temp);
- sc->inspiro = temp;
- } else if ( strmatch(tok,"LigCaretCntFixed:")==0 ) {
- getint(sfd,&temp);
- sc->lig_caret_cnt_fixed = temp;
- } else if ( strmatch(tok,"Flags:")==0 ) {
- while ( isspace(ch=nlgetc(sfd)) && ch!='\n' && ch!='\r');
- while ( ch!='\n' && ch!='\r' ) {
- if ( ch=='H' ) sc->changedsincelasthinted=true;
- else if ( ch=='M' ) sc->manualhints = true;
- else if ( ch=='W' ) sc->widthset = true;
- else if ( ch=='O' ) sc->wasopen = true;
- else if ( ch=='I' ) sc->instructions_out_of_date = true;
- ch = nlgetc(sfd);
- }
- if ( sf->multilayer || sf->strokedfont || sc->layers[ly_fore].order2 )
- sc->changedsincelasthinted = false;
- } else if ( strmatch(tok,"TeX:")==0 ) {
- getsint(sfd,&sc->tex_height);
- getsint(sfd,&sc->tex_depth);
- while ( isspace(ch=nlgetc(sfd)) && ch!='\n' && ch!='\r');
- ungetc(ch,sfd);
- if ( ch!='\n' && ch!='\r' ) {
- int16 old_tex;
- /* Used to store two extra values here */
- getsint(sfd,&old_tex);
- getsint(sfd,&old_tex);
- if ( sc->tex_height==0 && sc->tex_depth==0 ) /* Fixup old bug */
- sc->tex_height = sc->tex_depth = TEX_UNDEF;
- }
- } else if ( strmatch(tok,"ItalicCorrection:")==0 ) {
- SFDParseMathValueRecord(sfd,&sc->italic_correction,&sc->italic_adjusts);
- } else if ( strmatch(tok,"TopAccentHorizontal:")==0 ) {
- SFDParseMathValueRecord(sfd,&sc->top_accent_horiz,&sc->top_accent_adjusts);
- } else if ( strmatch(tok,"GlyphCompositionVerticalIC:")==0 ) {
- if ( sc->vert_variants==NULL )
- sc->vert_variants = chunkalloc(sizeof(struct glyphvariants));
- SFDParseMathValueRecord(sfd,&sc->vert_variants->italic_correction,&sc->vert_variants->italic_adjusts);
- } else if ( strmatch(tok,"GlyphCompositionHorizontalIC:")==0 ) {
- if ( sc->horiz_variants==NULL )
- sc->horiz_variants = chunkalloc(sizeof(struct glyphvariants));
- SFDParseMathValueRecord(sfd,&sc->horiz_variants->italic_correction,&sc->horiz_variants->italic_adjusts);
- } else if ( strmatch(tok,"IsExtendedShape:")==0 ) {
- int temp;
- getint(sfd,&temp);
- sc->is_extended_shape = temp;
- } else if ( strmatch(tok,"GlyphVariantsVertical:")==0 ) {
- if ( sc->vert_variants==NULL )
- sc->vert_variants = chunkalloc(sizeof(struct glyphvariants));
- geteol(sfd,tok);
- sc->vert_variants->variants = copy(tok);
- } else if ( strmatch(tok,"GlyphVariantsHorizontal:")==0 ) {
- if ( sc->horiz_variants==NULL )
- sc->horiz_variants = chunkalloc(sizeof(struct glyphvariants));
- geteol(sfd,tok);
- sc->horiz_variants->variants = copy(tok);
- } else if ( strmatch(tok,"GlyphCompositionVertical:")==0 ) {
- sc->vert_variants = SFDParseGlyphComposition(sfd, sc->vert_variants,tok);
- } else if ( strmatch(tok,"GlyphCompositionHorizontal:")==0 ) {
- sc->horiz_variants = SFDParseGlyphComposition(sfd, sc->horiz_variants,tok);
- } else if ( strmatch(tok,"TopRightVertex:")==0 ) {
- if ( sc->mathkern==NULL )
- sc->mathkern = chunkalloc(sizeof(struct mathkern));
- SFDParseVertexKern(sfd, &sc->mathkern->top_right);
- } else if ( strmatch(tok,"TopLeftVertex:")==0 ) {
- if ( sc->mathkern==NULL )
- sc->mathkern = chunkalloc(sizeof(struct mathkern));
- SFDParseVertexKern(sfd, &sc->mathkern->top_left);
- } else if ( strmatch(tok,"BottomRightVertex:")==0 ) {
- if ( sc->mathkern==NULL )
- sc->mathkern = chunkalloc(sizeof(struct mathkern));
- SFDParseVertexKern(sfd, &sc->mathkern->bottom_right);
- } else if ( strmatch(tok,"BottomLeftVertex:")==0 ) {
- if ( sc->mathkern==NULL )
- sc->mathkern = chunkalloc(sizeof(struct mathkern));
- SFDParseVertexKern(sfd, &sc->mathkern->bottom_left);
-#if HANYANG
- } else if ( strmatch(tok,"CompositionUnit:")==0 ) {
- getsint(sfd,&sc->jamo);
- getsint(sfd,&sc->varient);
- sc->compositionunit = true;
-#endif
- } else if ( strmatch(tok,"HStem:")==0 ) {
- sc->hstem = SFDReadHints(sfd);
- sc->hconflicts = StemListAnyConflicts(sc->hstem);
- } else if ( strmatch(tok,"VStem:")==0 ) {
- sc->vstem = SFDReadHints(sfd);
- sc->vconflicts = StemListAnyConflicts(sc->vstem);
- } else if ( strmatch(tok,"DStem:")==0 ) {
- sc->dstem = SFDReadDHints( sc->parent,sfd,true );
- had_old_dstems = true;
- } else if ( strmatch(tok,"DStem2:")==0 ) {
- sc->dstem = SFDReadDHints( sc->parent,sfd,false );
- } else if ( strmatch(tok,"CounterMasks:")==0 ) {
- getsint(sfd,&sc->countermask_cnt);
- sc->countermasks = calloc(sc->countermask_cnt,sizeof(HintMask));
- for ( i=0; i<sc->countermask_cnt; ++i ) {
- int ch;
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- SFDGetHintMask(sfd,&sc->countermasks[i]);
- }
- } else if ( strmatch(tok,"AnchorPoint:")==0 ) {
- lastap = SFDReadAnchorPoints(sfd,sc,&sc->anchor,lastap);
- } else if ( strmatch(tok,"Fore")==0 ) {
- while ( isspace(ch = nlgetc(sfd)));
- ungetc(ch,sfd);
- if ( ch!='I' && ch!='R' && ch!='S' && ch!='V' && ch!=' ' && ch!='\n' &&
- !PeekMatch(sfd, "Pickled") && !PeekMatch(sfd, "EndChar") &&
- !PeekMatch(sfd, "Fore") && !PeekMatch(sfd, "Back") && !PeekMatch(sfd, "Layer") ) {
- /* Old format, without a SplineSet token */
- sc->layers[ly_fore].splines = SFDGetSplineSet(sfd,sc->layers[ly_fore].order2);
- }
- current_layer = ly_fore;
- } else if ( strmatch(tok,"MinimumDistance:")==0 ) {
- SFDGetMinimumDistances(sfd,sc);
- } else if ( strmatch(tok,"Validated:")==0 ) {
- getsint(sfd,(int16 *) &sc->layers[current_layer].validation_state);
- } else if ( strmatch(tok,"Back")==0 ) {
- while ( isspace(ch=nlgetc(sfd)));
- ungetc(ch,sfd);
- if ( ch!='I' && ch!='R' && ch!='S' && ch!='V' && ch!=' ' && ch!='\n' &&
- !PeekMatch(sfd, "Pickled") && !PeekMatch(sfd, "EndChar") &&
- !PeekMatch(sfd, "Fore") && !PeekMatch(sfd, "Back") && !PeekMatch(sfd, "Layer") ) {
- /* Old format, without a SplineSet token */
- sc->layers[ly_back].splines = SFDGetSplineSet(sfd,sc->layers[ly_back].order2);
- oldback = true;
- }
- current_layer = ly_back;
- } else if ( strmatch(tok,"LayerCount:")==0 ) {
- getint(sfd,&temp);
- if ( temp>sc->layer_cnt ) {
- sc->layers = realloc(sc->layers,temp*sizeof(Layer));
- memset(sc->layers+sc->layer_cnt,0,(temp-sc->layer_cnt)*sizeof(Layer));
- }
- sc->layer_cnt = temp;
- current_layer = ly_fore;
- } else if ( strmatch(tok,"Layer:")==0 ) {
- int layer;
- int dofill, dostroke, fillfirst, linejoin, linecap;
- uint32 fillcol, strokecol;
- real fillopacity, strokeopacity, strokewidth, trans[4];
- DashType dashes[DASH_MAX];
- int i;
- getint(sfd,&layer);
- if ( layer>=sc->layer_cnt ) {
- sc->layers = realloc(sc->layers,(layer+1)*sizeof(Layer));
- memset(sc->layers+sc->layer_cnt,0,(layer+1-sc->layer_cnt)*sizeof(Layer));
- }
- if ( sc->parent->multilayer ) {
- getint(sfd,&dofill);
- getint(sfd,&dostroke);
- getint(sfd,&fillfirst);
- gethex(sfd,&fillcol);
- getreal(sfd,&fillopacity);
- gethex(sfd,&strokecol);
- getreal(sfd,&strokeopacity);
- getreal(sfd,&strokewidth);
- getname(sfd,tok);
- for ( i=0; joins[i]!=NULL; ++i )
- if ( strmatch(joins[i],tok)==0 )
- break;
- if ( joins[i]==NULL ) --i;
- linejoin = i;
- getname(sfd,tok);
- for ( i=0; caps[i]!=NULL; ++i )
- if ( strmatch(caps[i],tok)==0 )
- break;
- if ( caps[i]==NULL ) --i;
- linecap = i;
- while ( (ch=nlgetc(sfd))==' ' || ch=='[' );
- ungetc(ch,sfd);
- getreal(sfd,&trans[0]);
- getreal(sfd,&trans[1]);
- getreal(sfd,&trans[2]);
- getreal(sfd,&trans[3]);
- while ( (ch=nlgetc(sfd))==' ' || ch==']' );
- if ( ch=='[' ) {
- for ( i=0;; ++i ) { int temp;
- if ( !getint(sfd,&temp) )
- break;
- else if ( i<DASH_MAX )
- dashes[i] = temp;
- }
- if ( i<DASH_MAX )
- dashes[i] = 0;
- } else {
- ungetc(ch,sfd);
- memset(dashes,0,sizeof(dashes));
- }
- sc->layers[layer].dofill = dofill;
- sc->layers[layer].dostroke = dostroke;
- sc->layers[layer].fillfirst = fillfirst;
- sc->layers[layer].fill_brush.col = fillcol;
- sc->layers[layer].fill_brush.opacity = fillopacity;
- sc->layers[layer].stroke_pen.brush.col = strokecol;
- sc->layers[layer].stroke_pen.brush.opacity = strokeopacity;
- sc->layers[layer].stroke_pen.width = strokewidth;
- sc->layers[layer].stroke_pen.linejoin = linejoin;
- sc->layers[layer].stroke_pen.linecap = linecap;
- memcpy(sc->layers[layer].stroke_pen.dashes,dashes,sizeof(dashes));
- memcpy(sc->layers[layer].stroke_pen.trans,trans,sizeof(trans));
- }
- current_layer = layer;
- lastr = NULL;
- } else if ( strmatch(tok,"FillGradient:")==0 ) {
- sc->layers[current_layer].fill_brush.gradient = SFDParseGradient(sfd,tok);
- } else if ( strmatch(tok,"FillPattern:")==0 ) {
- sc->layers[current_layer].fill_brush.pattern = SFDParsePattern(sfd,tok);
- } else if ( strmatch(tok,"StrokeGradient:")==0 ) {
- sc->layers[current_layer].stroke_pen.brush.gradient = SFDParseGradient(sfd,tok);
- } else if ( strmatch(tok,"StrokePattern:")==0 ) {
- sc->layers[current_layer].stroke_pen.brush.pattern = SFDParsePattern(sfd,tok);
- } else if ( strmatch(tok,"SplineSet")==0 ) {
- sc->layers[current_layer].splines = SFDGetSplineSet(sfd,sc->layers[current_layer].order2);
- } else if ( strmatch(tok,"Ref:")==0 || strmatch(tok,"Refer:")==0 ) {
- /* I should be depending on the version number here, but I made */
- /* a mistake and bumped the version too late. So the version is */
- /* not an accurate mark, but the presence of a LayerCount keyword*/
- /* in the font is an good mark. Before the LayerCount was added */
- /* (version 2) only the foreground layer could have references */
- /* after that (eventually version 3) any layer could. */
- if ( oldback || !had_sf_layer_cnt ) current_layer = ly_fore;
- ref = SFDGetRef(sfd,strmatch(tok,"Ref:")==0);
- if ( sc->layers[current_layer].refs==NULL )
- sc->layers[current_layer].refs = ref;
- else
- lastr->next = ref;
- lastr = ref;
- } else if ( strmatch(tok,"PickledData:")==0 ) {
- if (current_layer < sc->layer_cnt) {
- sc->layers[current_layer].python_persistent = SFDUnPickle(sfd, 0);
- sc->layers[current_layer].python_persistent_has_lists = 0;
- }
- } else if ( strmatch(tok,"PickledDataWithLists:")==0 ) {
- if (current_layer < sc->layer_cnt) {
- sc->layers[current_layer].python_persistent = SFDUnPickle(sfd, 1);
- sc->layers[current_layer].python_persistent_has_lists = 1;
- }
- } else if ( strmatch(tok,"OrigType1:")==0 ) { /* Accept, slurp, ignore contents */
- SFDGetType1(sfd);
- } else if ( strmatch(tok,"TtfInstrs:")==0 ) { /* Binary format */
- SFDGetTtfInstrs(sfd,sc);
- } else if ( strmatch(tok,"TtInstrs:")==0 ) { /* ASCII format */
- SFDGetTtInstrs(sfd,sc);
- } else if ( strmatch(tok,"Kerns2:")==0 ||
- strmatch(tok,"VKerns2:")==0 ) {
- KernPair *kp, *last=NULL;
- int isv = *tok=='V';
- int off, index;
- struct lookup_subtable *sub;
-
- while ( fscanf(sfd,"%d %d", &index, &off )==2 ) {
- sub = SFFindLookupSubtableAndFreeName(sf,SFDReadUTF7Str(sfd));
- if ( sub==NULL ) {
- LogError(_("KernPair with no subtable name.\n"));
- break;
- }
- kp = chunkalloc(sizeof(KernPair1));
- kp->sc = (SplineChar *) (intpt) index;
- kp->kcid = true;
- kp->off = off;
- kp->subtable = sub;
- kp->next = NULL;
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( ch=='{' ) {
- kp->adjust = SFDReadDeviceTable(sfd, NULL);
- }
- if ( last != NULL )
- last->next = kp;
- else if ( isv )
- sc->vkerns = kp;
- else
- sc->kerns = kp;
- last = kp;
- }
- } else if ( (ispos = (strmatch(tok,"Position:")==0)) ||
- ( ispos = (strmatch(tok,"Position2:")==0)) ||
- ( ispair = (strmatch(tok,"PairPos:")==0)) ||
- ( ispair = (strmatch(tok,"PairPos2:")==0)) ||
- ( islcar = (strmatch(tok,"LCarets:")==0)) ||
- ( islcar = (strmatch(tok,"LCarets2:")==0)) ||
- ( isliga = (strmatch(tok,"Ligature:")==0)) ||
- ( isliga = (strmatch(tok,"Ligature2:")==0)) ||
- ( issubs = (strmatch(tok,"Substitution:")==0)) ||
- ( issubs = (strmatch(tok,"Substitution2:")==0)) ||
- ( ismult = (strmatch(tok,"MultipleSubs:")==0)) ||
- ( ismult = (strmatch(tok,"MultipleSubs2:")==0)) ||
- strmatch(tok,"AlternateSubs:")==0 ||
- strmatch(tok,"AlternateSubs2:")==0 ) {
- PST *pst;
- int old, type;
- type = ispos ? pst_position :
- ispair ? pst_pair :
- islcar ? pst_lcaret :
- isliga ? pst_ligature :
- issubs ? pst_substitution :
- ismult ? pst_multiple :
- pst_alternate;
- if ( strchr(tok,'2')!=NULL ) {
- old = false;
- pst = chunkalloc(sizeof(PST));
- if ( type!=pst_lcaret )
- pst->subtable = SFFindLookupSubtableAndFreeName(sf,SFDReadUTF7Str(sfd));
- } else {
- old = true;
- pst = chunkalloc(sizeof(PST1));
- ((PST1 *) pst)->tag = CHR('l','i','g','a');
- ((PST1 *) pst)->script_lang_index = 0xffff;
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- if ( isdigit(ch)) {
- int temp;
- ungetc(ch,sfd);
- getint(sfd,&temp);
- ((PST1 *) pst)->flags = temp;
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- } else
- ((PST1 *) pst)->flags = 0 /*PSTDefaultFlags(type,sc)*/;
- if ( isdigit(ch)) {
- ungetc(ch,sfd);
- getusint(sfd,&((PST1 *) pst)->script_lang_index);
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- } else
- ((PST1 *) pst)->script_lang_index = SFFindBiggestScriptLangIndex(sf,
- script!=0?script:SCScriptFromUnicode(sc),DEFAULT_LANG);
- if ( ch=='\'' ) {
- ungetc(ch,sfd);
- ((PST1 *) pst)->tag = gettag(sfd);
- } else if ( ch=='<' ) {
- getint(sfd,&temp);
- ((PST1 *) pst)->tag = temp<<16;
- nlgetc(sfd); /* comma */
- getint(sfd,&temp);
- ((PST1 *) pst)->tag |= temp;
- nlgetc(sfd); /* close '>' */
- ((PST1 *) pst)->macfeature = true;
- } else
- ungetc(ch,sfd);
- if ( type==pst_lcaret ) {
- /* These are meaningless for lcarets, set them to innocuous values */
- ((PST1 *) pst)->script_lang_index = SLI_UNKNOWN;
- ((PST1 *) pst)->tag = CHR(' ',' ',' ',' ');
- } else if ( ((PST1 *) pst)->script_lang_index>=((SplineFont1 *) sli_sf)->sli_cnt && ((PST1 *) pst)->script_lang_index!=SLI_NESTED ) {
- static int complained=false;
- if ( !complained )
- IError("'%c%c%c%c' in %s has a script index out of bounds: %d",
- (((PST1 *) pst)->tag>>24), (((PST1 *) pst)->tag>>16)&0xff, (((PST1 *) pst)->tag>>8)&0xff, ((PST1 *) pst)->tag&0xff,
- sc->name, ((PST1 *) pst)->script_lang_index );
- else
- IError( "'%c%c%c%c' in %s has a script index out of bounds: %d\n",
- (((PST1 *) pst)->tag>>24), (((PST1 *) pst)->tag>>16)&0xff, (((PST1 *) pst)->tag>>8)&0xff, ((PST1 *) pst)->tag&0xff,
- sc->name, ((PST1 *) pst)->script_lang_index );
- ((PST1 *) pst)->script_lang_index = SFFindBiggestScriptLangIndex(sli_sf,
- SCScriptFromUnicode(sc),DEFAULT_LANG);
- complained = true;
- }
- }
- if ( (sf->sfd_version<2)!=old ) {
- IError( "Version mixup in PST of sfd file." );
-exit(1);
- }
- if ( last==NULL )
- sc->possub = pst;
- else
- last->next = pst;
- last = pst;
- pst->type = type;
- if ( pst->type==pst_position ) {
- fscanf( sfd, " dx=%hd dy=%hd dh=%hd dv=%hd",
- &pst->u.pos.xoff, &pst->u.pos.yoff,
- &pst->u.pos.h_adv_off, &pst->u.pos.v_adv_off);
- pst->u.pos.adjust = SFDReadValDevTab(sfd);
- ch = nlgetc(sfd); /* Eat new line */
- } else if ( pst->type==pst_pair ) {
- getname(sfd,tok);
- pst->u.pair.paired = copy(tok);
- pst->u.pair.vr = chunkalloc(sizeof(struct vr [2]));
- fscanf( sfd, " dx=%hd dy=%hd dh=%hd dv=%hd",
- &pst->u.pair.vr[0].xoff, &pst->u.pair.vr[0].yoff,
- &pst->u.pair.vr[0].h_adv_off, &pst->u.pair.vr[0].v_adv_off);
- pst->u.pair.vr[0].adjust = SFDReadValDevTab(sfd);
- fscanf( sfd, " dx=%hd dy=%hd dh=%hd dv=%hd",
- &pst->u.pair.vr[1].xoff, &pst->u.pair.vr[1].yoff,
- &pst->u.pair.vr[1].h_adv_off, &pst->u.pair.vr[1].v_adv_off);
- pst->u.pair.vr[0].adjust = SFDReadValDevTab(sfd);
- ch = nlgetc(sfd);
- } else if ( pst->type==pst_lcaret ) {
- int i;
- fscanf( sfd, " %d", &pst->u.lcaret.cnt );
- pst->u.lcaret.carets = malloc(pst->u.lcaret.cnt*sizeof(int16));
- for ( i=0; i<pst->u.lcaret.cnt; ++i )
- fscanf( sfd, " %hd", &pst->u.lcaret.carets[i]);
- geteol(sfd,tok);
- } else {
- geteol(sfd,tok);
- pst->u.lig.components = copy(tok); /* it's in the same place for all formats */
- if ( isliga ) {
- pst->u.lig.lig = sc;
- if ( old )
- last = (PST *) LigaCreateFromOldStyleMultiple((PST1 *) pst);
- }
- }
-#ifdef FONTFORGE_CONFIG_CVT_OLD_MAC_FEATURES
- if ( old )
- CvtOldMacFeature((PST1 *) pst);
-#endif
- } else if ( strmatch(tok,"Colour:")==0 ) {
- uint32 temp;
- gethex(sfd,&temp);
- sc->color = temp;
- } else if ( strmatch(tok,"Comment:")==0 ) {
- sc->comment = SFDReadUTF7Str(sfd);
- } else if ( strmatch(tok,"TileMargin:")==0 ) {
- getreal(sfd,&sc->tile_margin);
- } else if ( strmatch(tok,"TileBounds:")==0 ) {
- getreal(sfd,&sc->tile_bounds.minx);
- getreal(sfd,&sc->tile_bounds.miny);
- getreal(sfd,&sc->tile_bounds.maxx);
- getreal(sfd,&sc->tile_bounds.maxy);
- } else if ( strmatch(tok,"EndChar")==0 ) {
- if ( sc->orig_pos<sf->glyphcnt )
- sf->glyphs[sc->orig_pos] = sc;
- /* Recalculating hint active zones may be needed for old .sfd files. */
- /* Do this when we have finished with other glyph components, */
- /* so that splines are already available */
- if ( had_old_dstems && sc->layers[ly_fore].splines != NULL )
- SCGuessHintInstancesList( sc,ly_fore,NULL,NULL,sc->dstem,false,true );
- if ( sc->layers[ly_fore].order2 )
- SCDefaultInterpolation(sc);
-return( sc );
- } else {
- geteol(sfd,tok);
- }
- }
-}
-
-static void SFDFixupRef(SplineChar *sc,RefChar *ref,int layer) {
- RefChar *rf;
- int ly;
-
- if ( sc->parent->multilayer ) {
- for ( ly=ly_fore; ly<ref->sc->layer_cnt; ++ly ) {
- for ( rf = ref->sc->layers[ly].refs; rf!=NULL; rf=rf->next ) {
- if ( rf->sc==sc ) { /* Huh? */
- ref->sc->layers[ly].refs = NULL;
- break;
- }
- if ( rf->layers[0].splines==NULL )
- SFDFixupRef(ref->sc,rf,layer);
- }
- }
- } else {
- for ( rf = ref->sc->layers[layer].refs; rf!=NULL; rf=rf->next ) {
- if ( rf->sc==sc ) { /* Huh? */
- ref->sc->layers[layer].refs = NULL;
- break;
- }
- if ( rf->layers[0].splines==NULL )
- SFDFixupRef(ref->sc,rf,layer);
- }
- }
- SCReinstanciateRefChar(sc,ref,layer);
- SCMakeDependent(sc,ref->sc);
-}
-
-/* Look for character duplicates, such as might be generated by having the same */
-/* glyph at two encoding slots */
-/* This is an obsolete convention, supported now only in sfd files */
-/* I think it is ok if something depends on this character, because the */
-/* code that handles references will automatically unwrap it down to be base */
-static SplineChar *SCDuplicate(SplineChar *sc) {
- SplineChar *matched = sc;
-
- if ( sc==NULL || sc->parent==NULL || sc->parent->cidmaster!=NULL )
-return( sc ); /* Can't do this in CID keyed fonts */
-
- if ( sc->layer_cnt!=2 )
-return( sc );
-
- while ( sc->layers[ly_fore].refs!=NULL &&
- sc->layers[ly_fore].refs->sc!=NULL && /* Can happen if we are called during font loading before references are fixed up */
- sc->layers[ly_fore].refs->next==NULL &&
- sc->layers[ly_fore].refs->transform[0]==1 && sc->layers[ly_fore].refs->transform[1]==0 &&
- sc->layers[ly_fore].refs->transform[2]==0 && sc->layers[ly_fore].refs->transform[3]==1 &&
- sc->layers[ly_fore].refs->transform[4]==0 && sc->layers[ly_fore].refs->transform[5]==0 ) {
- char *basename = sc->layers[ly_fore].refs->sc->name;
- if ( strcmp(sc->name,basename)!=0 )
- break;
- matched = sc->layers[ly_fore].refs->sc;
- sc = sc->layers[ly_fore].refs->sc;
- }
-return( matched );
-}
-
-
-void SFDFixupRefs(SplineFont *sf) {
- int i, isv;
- RefChar *refs, *rnext, *rprev;
- /*int isautorecovery = sf->changed;*/
- KernPair *kp, *prev, *next;
- EncMap *map = sf->map;
- int layer;
- int k,l;
- SplineFont *cidmaster = sf, *ksf;
-
- k = 1;
- if ( sf->subfontcnt!=0 )
- sf = sf->subfonts[0];
-
- ff_progress_change_line2(_("Interpreting Glyphs"));
- for (;;) {
- for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
- SplineChar *sc = sf->glyphs[i];
- /* A changed character is one that has just been recovered */
- /* unchanged characters will already have been fixed up */
- /* Er... maybe not. If the character being recovered is refered to */
- /* by another character then we need to fix up that other char too*/
- /*if ( isautorecovery && !sc->changed )*/
- /*continue;*/
- for ( layer = 0; layer<sc->layer_cnt; ++layer ) {
- rprev = NULL;
- for ( refs = sc->layers[layer].refs; refs!=NULL; refs=rnext ) {
- rnext = refs->next;
- if ( refs->encoded ) { /* Old sfd format */
- if ( refs->orig_pos<map->encmax && map->map[refs->orig_pos]!=-1 )
- refs->orig_pos = map->map[refs->orig_pos];
- else
- refs->orig_pos = sf->glyphcnt;
- refs->encoded = false;
- }
- if ( refs->orig_pos<sf->glyphcnt && refs->orig_pos>=0 )
- refs->sc = sf->glyphs[refs->orig_pos];
- if ( refs->sc!=NULL ) {
- refs->unicode_enc = refs->sc->unicodeenc;
- refs->adobe_enc = getAdobeEnc(refs->sc->name);
- rprev = refs;
- if ( refs->use_my_metrics ) {
- if ( sc->width != refs->sc->width ) {
- LogError(_("Bad sfd file. Glyph %s has width %d even though it should be\n bound to the width of %s which is %d.\n"),
- sc->name, sc->width, refs->sc->name, refs->sc->width );
- sc->width = refs->sc->width;
- }
- }
- } else {
- RefCharFree(refs);
- if ( rprev!=NULL )
- rprev->next = rnext;
- else
- sc->layers[layer].refs = rnext;
- }
- }
- }
- /* In old sfd files we used a peculiar idiom to represent a multiply */
- /* encoded glyph. Fix it up now. Remove the fake glyph and adjust the*/
- /* map */
- /*if ( isautorecovery && !sc->changed )*/
- /*continue;*/
- for ( isv=0; isv<2; ++isv ) {
- for ( prev = NULL, kp=isv?sc->vkerns : sc->kerns; kp!=NULL; kp=next ) {
- int index = (intpt) (kp->sc);
-
- next = kp->next;
- // be impotent if the reference is already to the correct location
- if ( !kp->kcid ) { /* It's encoded (old sfds), else orig */
- if ( index>=map->encmax || map->map[index]==-1 )
- index = sf->glyphcnt;
- else
- index = map->map[index];
- }
- kp->kcid = false;
- ksf = sf;
- if ( cidmaster!=sf ) {
- for ( l=0; l<cidmaster->subfontcnt; ++l ) {
- ksf = cidmaster->subfonts[l];
- if ( index<ksf->glyphcnt && ksf->glyphs[index]!=NULL )
- break;
- }
- }
- if ( index>=ksf->glyphcnt || ksf->glyphs[index]==NULL ) {
- IError( "Bad kerning information in glyph %s\n", sc->name );
- kp->sc = NULL;
- } else {
- kp->sc = ksf->glyphs[index];
- }
-
- if ( kp->sc!=NULL )
- prev = kp;
- else{
- if ( prev!=NULL )
- prev->next = next;
- else if ( isv )
- sc->vkerns = next;
- else
- sc->kerns = next;
- chunkfree(kp,sizeof(KernPair));
- }
- }
- }
- if ( SCDuplicate(sc)!=sc ) {
- SplineChar *base = SCDuplicate(sc);
- int orig = sc->orig_pos, enc = sf->map->backmap[orig], uni = sc->unicodeenc;
- SplineCharFree(sc);
- sf->glyphs[i]=NULL;
- sf->map->backmap[orig] = -1;
- sf->map->map[enc] = base->orig_pos;
- AltUniAdd(base,uni);
- }
- }
- for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
- SplineChar *sc = sf->glyphs[i];
- for ( layer=0; layer<sc->layer_cnt; ++layer ) {
- for ( refs = sf->glyphs[i]->layers[layer].refs; refs!=NULL; refs=refs->next ) {
- SFDFixupRef(sf->glyphs[i],refs,layer);
- }
- }
- ff_progress_next();
- }
- if ( sf->cidmaster==NULL )
- for ( i=sf->glyphcnt-1; i>=0 && sf->glyphs[i]==NULL; --i )
- sf->glyphcnt = i;
- if ( k>=cidmaster->subfontcnt )
- break;
- sf = cidmaster->subfonts[k++];
- }
-}
-
-static void SFDGetPrivate(FILE *sfd,SplineFont *sf) {
- int i, cnt, len;
- char name[200];
- char *pt, *end;
-
- sf->private = calloc(1,sizeof(struct psdict));
- getint(sfd,&cnt);
- sf->private->next = sf->private->cnt = cnt;
- sf->private->values = calloc(cnt,sizeof(char *));
- sf->private->keys = calloc(cnt,sizeof(char *));
- for ( i=0; i<cnt; ++i ) {
- getname(sfd,name);
- sf->private->keys[i] = copy(name);
- getint(sfd,&len);
- nlgetc(sfd); /* skip space */
- pt = sf->private->values[i] = malloc(len+1);
- for ( end = pt+len; pt<end; ++pt )
- *pt = nlgetc(sfd);
- *pt='\0';
- }
-}
-
-static void SFDGetSubrs(FILE *sfd) {
- /* Obselete, parse it in case there are any old sfds */
- int i, cnt, tot, len;
- struct enc85 dec;
-
- getint(sfd,&cnt);
- tot = 0;
- for ( i=0; i<cnt; ++i ) {
- getint(sfd,&len);
- tot += len;
- }
-
- memset(&dec,'\0', sizeof(dec)); dec.pos = -1;
- dec.sfd = sfd;
- for ( i=0; i<tot; ++i )
- Dec85(&dec);
-}
-
-static struct ttflangname *SFDGetLangName(FILE *sfd,struct ttflangname *old) {
- struct ttflangname *cur = chunkalloc(sizeof(struct ttflangname)), *prev;
- int i;
-
- getint(sfd,&cur->lang);
- for ( i=0; i<ttf_namemax; ++i )
- cur->names[i] = SFDReadUTF7Str(sfd);
- if ( old==NULL )
-return( cur );
- for ( prev = old; prev->next !=NULL; prev = prev->next );
- prev->next = cur;
-return( old );
-}
-
-static void SFDGetGasp(FILE *sfd,SplineFont *sf) {
- int i;
-
- getsint(sfd,(int16 *) &sf->gasp_cnt);
- sf->gasp = malloc(sf->gasp_cnt*sizeof(struct gasp));
- for ( i=0; i<sf->gasp_cnt; ++i ) {
- getsint(sfd,(int16 *) &sf->gasp[i].ppem);
- getsint(sfd,(int16 *) &sf->gasp[i].flags);
- }
- getsint(sfd,(int16 *) &sf->gasp_version);
-}
-
-static void SFDGetDesignSize(FILE *sfd,SplineFont *sf) {
- int ch;
- struct otfname *cur;
-
- getsint(sfd,(int16 *) &sf->design_size);
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( isdigit(ch)) {
- getsint(sfd,(int16 *) &sf->design_range_bottom);
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch!='-' )
- ungetc(ch,sfd);
- getsint(sfd,(int16 *) &sf->design_range_top);
- getsint(sfd,(int16 *) &sf->fontstyle_id);
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( !isdigit(ch))
- break;
- cur = chunkalloc(sizeof(struct otfname));
- cur->next = sf->fontstyle_name;
- sf->fontstyle_name = cur;
- getsint(sfd,(int16 *) &cur->lang);
- cur->name = SFDReadUTF7Str(sfd);
- }
- }
-}
-
-static void SFDGetOtfFeatName(FILE *sfd,SplineFont *sf) {
- int ch;
- struct otfname *cur;
- struct otffeatname *fn;
-
- fn = chunkalloc(sizeof(struct otffeatname));
- fn->tag = gettag(sfd);
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( !isdigit(ch))
- break;
- cur = chunkalloc(sizeof(struct otfname));
- cur->next = fn->names;
- fn->names = cur;
- getsint(sfd,(int16 *) &cur->lang);
- cur->name = SFDReadUTF7Str(sfd);
- }
- fn->next = sf->feat_names;
- sf->feat_names = fn;
-}
-
-static Encoding *SFDGetEncoding(FILE *sfd, char *tok) {
- Encoding *enc = NULL;
- int encname;
-
- if ( getint(sfd,&encname) ) {
- if ( encname<(int)(sizeof(charset_names)/sizeof(charset_names[0])-1) )
- enc = FindOrMakeEncoding(charset_names[encname]);
- } else {
- geteol(sfd,tok);
- enc = FindOrMakeEncoding(tok);
- }
- if ( enc==NULL )
- enc = &custom;
-return( enc );
-}
-
-static enum uni_interp SFDGetUniInterp(FILE *sfd, char *tok, SplineFont *sf) {
- int uniinterp = ui_none;
- int i;
-
- geteol(sfd,tok);
- for ( i=0; unicode_interp_names[i]!=NULL; ++i )
- if ( strcmp(tok,unicode_interp_names[i])==0 ) {
- uniinterp = i;
- break;
- }
- /* These values are now handled by namelists */
- if ( uniinterp == ui_adobe ) {
- sf->for_new_glyphs = NameListByName("AGL with PUA");
- uniinterp = ui_none;
- } else if ( uniinterp == ui_greek ) {
- sf->for_new_glyphs = NameListByName("Greek small caps");
- uniinterp = ui_none;
- } else if ( uniinterp == ui_ams ) {
- sf->for_new_glyphs = NameListByName("AMS Names");
- uniinterp = ui_none;
- }
-
-return( uniinterp );
-}
-
-static void SFDGetNameList(FILE *sfd, char *tok, SplineFont *sf) {
- NameList *nl;
-
- geteol(sfd,tok);
- nl = NameListByName(tok);
- if ( nl==NULL )
- LogError(_("Failed to find NameList: %s"), tok);
- else
- sf->for_new_glyphs = nl;
-}
-
-
-static OTLookup *SFD_ParseNestedLookup(FILE *sfd, SplineFont *sf, int old) {
- uint32 tag;
- int ch, isgpos;
- OTLookup *otl;
- char *name;
-
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='~' )
-return( NULL );
- else if ( old ) {
- if ( ch!='\'' )
-return( NULL );
-
- ungetc(ch,sfd);
- tag = gettag(sfd);
-return( (OTLookup *) (intpt) tag );
- } else {
- ungetc(ch,sfd);
- name = SFDReadUTF7Str(sfd);
- if ( name==NULL )
-return( NULL );
- for ( isgpos=0; isgpos<2; ++isgpos ) {
- for ( otl=isgpos ? sf->gpos_lookups : sf->gsub_lookups; otl!=NULL; otl=otl->next ) {
- if ( strcmp(name,otl->lookup_name )==0 )
- goto break2;
- }
- }
- break2:
- free(name);
-return( otl );
- }
-}
-
-static void SFDParseChainContext(FILE *sfd,SplineFont *sf,FPST *fpst, char *tok, int old) {
- int ch, i, j, k, temp;
- SplineFont *sli_sf = sf->cidmaster ? sf->cidmaster : sf;
-
- fpst->type = strnmatch(tok,"ContextPos",10)==0 ? pst_contextpos :
- strnmatch(tok,"ContextSub",10)==0 ? pst_contextsub :
- strnmatch(tok,"ChainPos",8)==0 ? pst_chainpos :
- strnmatch(tok,"ChainSub",8)==0 ? pst_chainsub : pst_reversesub;
- getname(sfd,tok);
- fpst->format = strmatch(tok,"glyph")==0 ? pst_glyphs :
- strmatch(tok,"class")==0 ? pst_class :
- strmatch(tok,"coverage")==0 ? pst_coverage : pst_reversecoverage;
- if ( old ) {
- fscanf(sfd, "%hu %hu", &((FPST1 *) fpst)->flags, &((FPST1 *) fpst)->script_lang_index );
- if ( ((FPST1 *) fpst)->script_lang_index>=((SplineFont1 *) sli_sf)->sli_cnt && ((FPST1 *) fpst)->script_lang_index!=SLI_NESTED ) {
- static int complained=false;
- if ( ((SplineFont1 *) sli_sf)->sli_cnt==0 )
- IError("'%c%c%c%c' has a script index out of bounds: %d\nYou MUST fix this manually",
- (((FPST1 *) fpst)->tag>>24), (((FPST1 *) fpst)->tag>>16)&0xff, (((FPST1 *) fpst)->tag>>8)&0xff, ((FPST1 *) fpst)->tag&0xff,
- ((FPST1 *) fpst)->script_lang_index );
- else if ( !complained )
- IError("'%c%c%c%c' has a script index out of bounds: %d",
- (((FPST1 *) fpst)->tag>>24), (((FPST1 *) fpst)->tag>>16)&0xff, (((FPST1 *) fpst)->tag>>8)&0xff, ((FPST1 *) fpst)->tag&0xff,
- ((FPST1 *) fpst)->script_lang_index );
- else
- IError("'%c%c%c%c' has a script index out of bounds: %d\n",
- (((FPST1 *) fpst)->tag>>24), (((FPST1 *) fpst)->tag>>16)&0xff, (((FPST1 *) fpst)->tag>>8)&0xff, ((FPST1 *) fpst)->tag&0xff,
- ((FPST1 *) fpst)->script_lang_index );
- if ( ((SplineFont1 *) sli_sf)->sli_cnt!=0 )
- ((FPST1 *) fpst)->script_lang_index = ((SplineFont1 *) sli_sf)->sli_cnt-1;
- complained = true;
- }
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- if ( ch=='\'' ) {
- ungetc(ch,sfd);
- ((FPST1 *) fpst)->tag = gettag(sfd);
- } else
- ungetc(ch,sfd);
- } else {
- fpst->subtable = SFFindLookupSubtableAndFreeName(sf,SFDReadUTF7Str(sfd));
- if ( !fpst->subtable )
- LogError(_("Missing Subtable definition found in chained context"));
- else
- fpst->subtable->fpst = fpst;
- }
- fscanf(sfd, "%hu %hu %hu %hu", &fpst->nccnt, &fpst->bccnt, &fpst->fccnt, &fpst->rule_cnt );
- if ( fpst->nccnt!=0 || fpst->bccnt!=0 || fpst->fccnt!=0 ) {
- fpst->nclass = malloc(fpst->nccnt*sizeof(char *));
- fpst->nclassnames = calloc(fpst->nccnt,sizeof(char *));
- if ( fpst->nccnt!=0 ) fpst->nclass[0] = NULL;
- if ( fpst->bccnt!=0 || fpst->fccnt!=0 ) {
- fpst->bclass = malloc(fpst->bccnt*sizeof(char *));
- fpst->bclassnames = calloc(fpst->bccnt,sizeof(char *));
- if (fpst->bccnt!=0 ) fpst->bclass[0] = NULL;
- fpst->fclass = malloc(fpst->fccnt*sizeof(char *));
- fpst->fclassnames = calloc(fpst->fccnt,sizeof(char *));
- if (fpst->fccnt!=0 ) fpst->fclass[0] = NULL;
- }
- }
-
- for ( j=0; j<3; ++j ) {
- for ( i=1; i<(&fpst->nccnt)[j]; ++i ) {
- getname(sfd,tok);
- if ( i==1 && j==0 && strcmp(tok,"Class0:")==0 )
- i=0;
- getint(sfd,&temp);
- (&fpst->nclass)[j][i] = malloc(temp+1); (&fpst->nclass)[j][i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread((&fpst->nclass)[j][i],1,temp,sfd);
- }
- }
-
- fpst->rules = calloc(fpst->rule_cnt,sizeof(struct fpst_rule));
- for ( i=0; i<fpst->rule_cnt; ++i ) {
- switch ( fpst->format ) {
- case pst_glyphs:
- for ( j=0; j<3; ++j ) {
- getname(sfd,tok);
- getint(sfd,&temp);
- (&fpst->rules[i].u.glyph.names)[j] = malloc(temp+1);
- (&fpst->rules[i].u.glyph.names)[j][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread((&fpst->rules[i].u.glyph.names)[j],1,temp,sfd);
- }
- break;
- case pst_class:
- fscanf( sfd, "%d %d %d", &fpst->rules[i].u.class.ncnt, &fpst->rules[i].u.class.bcnt, &fpst->rules[i].u.class.fcnt );
- for ( j=0; j<3; ++j ) {
- getname(sfd,tok);
- (&fpst->rules[i].u.class.nclasses)[j] = malloc((&fpst->rules[i].u.class.ncnt)[j]*sizeof(uint16));
- for ( k=0; k<(&fpst->rules[i].u.class.ncnt)[j]; ++k ) {
- getusint(sfd,&(&fpst->rules[i].u.class.nclasses)[j][k]);
- }
- }
- break;
- case pst_coverage:
- case pst_reversecoverage:
- fscanf( sfd, "%d %d %d", &fpst->rules[i].u.coverage.ncnt, &fpst->rules[i].u.coverage.bcnt, &fpst->rules[i].u.coverage.fcnt );
- for ( j=0; j<3; ++j ) {
- (&fpst->rules[i].u.coverage.ncovers)[j] = malloc((&fpst->rules[i].u.coverage.ncnt)[j]*sizeof(char *));
- for ( k=0; k<(&fpst->rules[i].u.coverage.ncnt)[j]; ++k ) {
- getname(sfd,tok);
- getint(sfd,&temp);
- (&fpst->rules[i].u.coverage.ncovers)[j][k] = malloc(temp+1);
- (&fpst->rules[i].u.coverage.ncovers)[j][k][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread((&fpst->rules[i].u.coverage.ncovers)[j][k],1,temp,sfd);
- }
- }
- break;
- default:
- break;
- }
- switch ( fpst->format ) {
- case pst_glyphs:
- case pst_class:
- case pst_coverage:
- getint(sfd,&fpst->rules[i].lookup_cnt);
- fpst->rules[i].lookups = malloc(fpst->rules[i].lookup_cnt*sizeof(struct seqlookup));
- for ( j=k=0; j<fpst->rules[i].lookup_cnt; ++j ) {
- getname(sfd,tok);
- getint(sfd,&fpst->rules[i].lookups[j].seq);
- fpst->rules[i].lookups[k].lookup = SFD_ParseNestedLookup(sfd,sf,old);
- if ( fpst->rules[i].lookups[k].lookup!=NULL )
- ++k;
- }
- fpst->rules[i].lookup_cnt = k;
- break;
- case pst_reversecoverage:
- getname(sfd,tok);
- getint(sfd,&temp);
- fpst->rules[i].u.rcoverage.replacements = malloc(temp+1);
- fpst->rules[i].u.rcoverage.replacements[temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(fpst->rules[i].u.rcoverage.replacements,1,temp,sfd);
- break;
- default:
- break;
- }
- }
- getname(sfd,tok); /* EndFPST, or one of the ClassName tokens (in newer sfds) */
- while ( strcmp(tok,"ClassNames:")==0 || strcmp(tok,"BClassNames:")==0 ||
- strcmp(tok,"FClassNames:")==0 ) {
- int which = strcmp(tok,"ClassNames:")==0 ? 0 :
- strcmp(tok,"BClassNames:")==0 ? 1 : 2;
- int cnt = (&fpst->nccnt)[which];
- char **classnames = (&fpst->nclassnames)[which];
- int i;
-
- for ( i=0; i<cnt; ++i )
- classnames[i] = SFDReadUTF7Str(sfd);
- getname(sfd,tok); /* EndFPST, or one of the ClassName tokens (in newer sfds) */
- }
-
-}
-
-static void SFDParseStateMachine(FILE *sfd,SplineFont *sf,ASM *sm, char *tok,int old) {
- int i, temp;
-
- sm->type = strnmatch(tok,"MacIndic",8)==0 ? asm_indic :
- strnmatch(tok,"MacContext",10)==0 ? asm_context :
- strnmatch(tok,"MacLigature",11)==0 ? asm_lig :
- strnmatch(tok,"MacSimple",9)==0 ? asm_simple :
- strnmatch(tok,"MacKern",7)==0 ? asm_kern : asm_insert;
- if ( old ) {
- getusint(sfd,&((ASM1 *) sm)->feature);
- nlgetc(sfd); /* Skip comma */
- getusint(sfd,&((ASM1 *) sm)->setting);
- } else {
- sm->subtable = SFFindLookupSubtableAndFreeName(sf,SFDReadUTF7Str(sfd));
- sm->subtable->sm = sm;
- }
- getusint(sfd,&sm->flags);
- getusint(sfd,&sm->class_cnt);
- getusint(sfd,&sm->state_cnt);
-
- sm->classes = malloc(sm->class_cnt*sizeof(char *));
- sm->classes[0] = sm->classes[1] = sm->classes[2] = sm->classes[3] = NULL;
- for ( i=4; i<sm->class_cnt; ++i ) {
- getname(sfd,tok);
- getint(sfd,&temp);
- sm->classes[i] = malloc(temp+1); sm->classes[i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(sm->classes[i],1,temp,sfd);
- }
-
- sm->state = malloc(sm->class_cnt*sm->state_cnt*sizeof(struct asm_state));
- for ( i=0; i<sm->class_cnt*sm->state_cnt; ++i ) {
- getusint(sfd,&sm->state[i].next_state);
- getusint(sfd,&sm->state[i].flags);
- if ( sm->type == asm_context ) {
- sm->state[i].u.context.mark_lookup = SFD_ParseNestedLookup(sfd,sf,old);
- sm->state[i].u.context.cur_lookup = SFD_ParseNestedLookup(sfd,sf,old);
- } else if ( sm->type == asm_insert ) {
- getint(sfd,&temp);
- if ( temp==0 )
- sm->state[i].u.insert.mark_ins = NULL;
- else {
- sm->state[i].u.insert.mark_ins = malloc(temp+1); sm->state[i].u.insert.mark_ins[temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(sm->state[i].u.insert.mark_ins,1,temp,sfd);
- }
- getint(sfd,&temp);
- if ( temp==0 )
- sm->state[i].u.insert.cur_ins = NULL;
- else {
- sm->state[i].u.insert.cur_ins = malloc(temp+1); sm->state[i].u.insert.cur_ins[temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(sm->state[i].u.insert.cur_ins,1,temp,sfd);
- }
- } else if ( sm->type == asm_kern ) {
- int j;
- getint(sfd,&sm->state[i].u.kern.kcnt);
- if ( sm->state[i].u.kern.kcnt!=0 )
- sm->state[i].u.kern.kerns = malloc(sm->state[i].u.kern.kcnt*sizeof(int16));
- for ( j=0; j<sm->state[i].u.kern.kcnt; ++j ) {
- getint(sfd,&temp);
- sm->state[i].u.kern.kerns[j] = temp;
- }
- }
- }
- getname(sfd,tok); /* EndASM */
-}
-
-static struct macname *SFDParseMacNames(FILE *sfd, char *tok) {
- struct macname *head=NULL, *last=NULL, *cur;
- int enc, lang, len;
- char *pt;
- int ch;
-
- while ( strcmp(tok,"MacName:")==0 ) {
- cur = chunkalloc(sizeof(struct macname));
- if ( last==NULL )
- head = cur;
- else
- last->next = cur;
- last = cur;
-
- getint(sfd,&enc);
- getint(sfd,&lang);
- getint(sfd,&len);
- cur->enc = enc;
- cur->lang = lang;
- cur->name = pt = malloc(len+1);
-
- while ( (ch=nlgetc(sfd))==' ');
- if ( ch=='"' )
- ch = nlgetc(sfd);
- while ( ch!='"' && ch!=EOF && pt<cur->name+len ) {
- if ( ch=='\\' ) {
- *pt = (nlgetc(sfd)-'0')<<6;
- *pt |= (nlgetc(sfd)-'0')<<3;
- *pt |= (nlgetc(sfd)-'0');
- } else
- *pt++ = ch;
- ch = nlgetc(sfd);
- }
- *pt = '\0';
- getname(sfd,tok);
- }
-return( head );
-}
-
-MacFeat *SFDParseMacFeatures(FILE *sfd, char *tok) {
- MacFeat *cur, *head=NULL, *last=NULL;
- struct macsetting *slast, *scur;
- int feat, ism, def, set;
-
- while ( strcmp(tok,"MacFeat:")==0 ) {
- cur = chunkalloc(sizeof(MacFeat));
- if ( last==NULL )
- head = cur;
- else
- last->next = cur;
- last = cur;
-
- getint(sfd,&feat); getint(sfd,&ism); getint(sfd, &def);
- cur->feature = feat; cur->ismutex = ism; cur->default_setting = def;
- getname(sfd,tok);
- cur->featname = SFDParseMacNames(sfd,tok);
- slast = NULL;
- while ( strcmp(tok,"MacSetting:")==0 ) {
- scur = chunkalloc(sizeof(struct macsetting));
- if ( slast==NULL )
- cur->settings = scur;
- else
- slast->next = scur;
- slast = scur;
-
- getint(sfd,&set);
- scur->setting = set;
- getname(sfd,tok);
- scur->setname = SFDParseMacNames(sfd,tok);
- }
- }
-return( head );
-}
-
-static char *SFDParseMMSubroutine(FILE *sfd) {
- char buffer[400], *sofar=calloc(1,1);
- const char *endtok = "EndMMSubroutine";
- int len = 0, blen, first=true;
-
- while ( fgets(buffer,sizeof(buffer),sfd)!=NULL ) {
- if ( strncmp(buffer,endtok,strlen(endtok))==0 )
- break;
- if ( first ) {
- first = false;
- if ( strcmp(buffer,"\n")==0 )
- continue;
- }
- blen = strlen(buffer);
- sofar = realloc(sofar,len+blen+1);
- strcpy(sofar+len,buffer);
- len += blen;
- }
- if ( len>0 && sofar[len-1]=='\n' )
- sofar[len-1] = '\0';
-return( sofar );
-}
-
-static void MMInferStuff(MMSet *mm) {
- int i,j;
-
- if ( mm==NULL )
-return;
- if ( mm->apple ) {
- for ( i=0; i<mm->axis_count; ++i ) {
- for ( j=0; j<mm->axismaps[i].points; ++j ) {
- real val = mm->axismaps[i].blends[j];
- if ( val == -1. )
- mm->axismaps[i].min = mm->axismaps[i].designs[j];
- else if ( val==0 )
- mm->axismaps[i].def = mm->axismaps[i].designs[j];
- else if ( val==1 )
- mm->axismaps[i].max = mm->axismaps[i].designs[j];
- }
- }
- }
-}
-
-static void SFDSizeMap(EncMap *map,int glyphcnt,int enccnt) {
- if ( glyphcnt>map->backmax ) {
- map->backmap = realloc(map->backmap,glyphcnt*sizeof(int));
- memset(map->backmap+map->backmax,-1,(glyphcnt-map->backmax)*sizeof(int));
- map->backmax = glyphcnt;
- }
- if ( enccnt>map->encmax ) {
- map->map = realloc(map->map,enccnt*sizeof(int));
- memset(map->map+map->backmax,-1,(enccnt-map->encmax)*sizeof(int));
- map->encmax = map->enccount = enccnt;
- }
-}
-
-static SplineFont *SFD_GetFont(FILE *sfd,SplineFont *cidmaster,char *tok,
- int fromdir, char *dirname, float sfdversion);
-
-static void SFD_DoAltUnis(SplineFont *sf) {
- int i;
- struct altuni *alt;
- SplineChar *sc;
-
- for ( i=0; i<sf->glyphcnt; ++i ) if ( (sc = sf->glyphs[i])!=NULL ) {
- for ( alt = sc->altuni; alt!=NULL; alt = alt->next ) {
- if ( alt->vs==-1 && alt->fid==0 ) {
- int enc = EncFromUni(alt->unienc,sf->map->enc);
- if ( enc!=-1 )
- SFDSetEncMap(sf,sc->orig_pos,enc);
- }
- }
- }
-}
-
-static void SFDParseLookup(FILE *sfd,OTLookup *otl) {
- int ch;
- struct lookup_subtable *sub, *lastsub;
- FeatureScriptLangList *fl, *lastfl;
- struct scriptlanglist *sl, *lastsl;
- int i, lcnt, lmax=0;
- uint32 *langs=NULL;
- char *subname;
-
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='{' ) {
- lastsub = NULL;
- while ( (subname = SFDReadUTF7Str(sfd))!=NULL ) {
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- sub = chunkalloc(sizeof(struct lookup_subtable));
- sub->subtable_name = subname;
- sub->lookup = otl;
- switch ( otl->lookup_type ) {
- case gsub_single:
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='(' ) {
- sub->suffix = SFDReadUTF7Str(sfd);
- while ( (ch=nlgetc(sfd))==' ' );
- /* slurp final paren */
- } else
- ungetc(ch,sfd);
- sub->per_glyph_pst_or_kern = true;
- break;
- case gsub_multiple: case gsub_alternate: case gsub_ligature:
- case gpos_single:
- sub->per_glyph_pst_or_kern = true;
- break;
- case gpos_pair:
- if ( (ch=nlgetc(sfd))=='(' ) {
- ch = nlgetc(sfd);
- sub->vertical_kerning = (ch=='1');
- nlgetc(sfd); /* slurp final paren */
- ch=nlgetc(sfd);
- }
- if ( ch=='[' ) {
- getsint(sfd,&sub->separation);
- nlgetc(sfd); /* slurp comma */
- getsint(sfd,&sub->minkern);
- nlgetc(sfd); /* slurp comma */
- ch = nlgetc(sfd);
- sub->kerning_by_touch = ((ch-'0')&1)?1:0;
- sub->onlyCloser = ((ch-'0')&2)?1:0;
- sub->dontautokern = ((ch-'0')&4)?1:0;
- nlgetc(sfd); /* slurp final bracket */
- } else {
- ungetc(ch,sfd);
- }
- sub->per_glyph_pst_or_kern = true;
- break;
- case gpos_cursive: case gpos_mark2base: case gpos_mark2ligature: case gpos_mark2mark:
- sub->anchor_classes = true;
- break;
- default:
- break;
- }
- if ( lastsub==NULL )
- otl->subtables = sub;
- else
- lastsub->next = sub;
- lastsub = sub;
- }
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='}' )
- ch = nlgetc(sfd);
- }
- while ( ch==' ' )
- ch = nlgetc(sfd);
- if ( ch=='[' ) {
- lastfl = NULL;
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch==']' )
- break;
- fl = chunkalloc(sizeof(FeatureScriptLangList));
- if ( lastfl==NULL )
- otl->features = fl;
- else
- lastfl->next = fl;
- lastfl = fl;
- if ( ch=='<' ) {
- int ft=0,fs=0;
- fscanf(sfd,"%d,%d>", &ft, &fs );
- fl->ismac = true;
- fl->featuretag = (ft<<16) | fs;
- } else if ( ch=='\'' ) {
- ungetc(ch,sfd);
- fl->featuretag = gettag(sfd);
- }
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='(' ) {
- lastsl = NULL;
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch==')' )
- break;
- sl = chunkalloc(sizeof(struct scriptlanglist));
- if ( lastsl==NULL )
- fl->scripts = sl;
- else
- lastsl->next = sl;
- lastsl = sl;
- if ( ch=='\'' ) {
- ungetc(ch,sfd);
- sl->script = gettag(sfd);
- }
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='<' ) {
- lcnt = 0;
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='>' )
- break;
- if ( ch=='\'' ) {
- ungetc(ch,sfd);
- if ( lcnt>=lmax )
- langs = realloc(langs,(lmax+=10)*sizeof(uint32));
- langs[lcnt++] = gettag(sfd);
- }
- }
- sl->lang_cnt = lcnt;
- if ( lcnt>MAX_LANG )
- sl->morelangs = malloc((lcnt-MAX_LANG)*sizeof(uint32));
- for ( i=0; i<lcnt; ++i ) {
- if ( i<MAX_LANG )
- sl->langs[i] = langs[i];
- else
- sl->morelangs[i-MAX_LANG] = langs[i];
- }
- }
- }
- }
- }
- }
- free(langs);
-}
-
-static void SFDParseMathItem(FILE *sfd,SplineFont *sf,char *tok) {
- /* The first five characters of a math item's keyword will be "MATH:" */
- /* the rest will be one of the entries in math_constants_descriptor */
- int i;
- struct MATH *math;
-
- if ( (math = sf->MATH) == NULL )
- math = sf->MATH = calloc(1,sizeof(struct MATH));
- for ( i=0; math_constants_descriptor[i].script_name!=NULL; ++i ) {
- char *name = math_constants_descriptor[i].script_name;
- int len = strlen( name );
- if ( strncmp(tok+5,name,len)==0 && tok[5+len] == ':' && tok[6+len]=='\0' ) {
- int16 *pos = (int16 *) (((char *) (math)) + math_constants_descriptor[i].offset );
- getsint(sfd,pos);
- if ( math_constants_descriptor[i].devtab_offset != -1 ) {
- DeviceTable **devtab = (DeviceTable **) (((char *) (math)) + math_constants_descriptor[i].devtab_offset );
- *devtab = SFDReadDeviceTable(sfd,*devtab);
- break;
- }
- }
- }
-}
-
-static struct baselangextent *ParseBaseLang(FILE *sfd) {
- struct baselangextent *bl;
- struct baselangextent *cur, *last;
- int ch;
-
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='{' ) {
- bl = chunkalloc(sizeof(struct baselangextent));
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( ch=='\'' )
- bl->lang = gettag(sfd); /* Lang or Feature tag, or nothing */
- getsint(sfd,&bl->descent);
- getsint(sfd,&bl->ascent);
- last = NULL;
- while ( (ch=nlgetc(sfd))==' ' );
- while ( ch=='{' ) {
- ungetc(ch,sfd);
- cur = ParseBaseLang(sfd);
- if ( last==NULL )
- bl->features = cur;
- else
- last->next = cur;
- last = cur;
- while ( (ch=nlgetc(sfd))==' ' );
- }
- if ( ch!='}' ) ungetc(ch,sfd);
-return( bl );
- }
-return( NULL );
-}
-
-static struct basescript *SFDParseBaseScript(FILE *sfd,struct Base *base) {
- struct basescript *bs;
- int i, ch;
- struct baselangextent *last, *cur;
-
- if ( base==NULL )
-return(NULL);
-
- bs = chunkalloc(sizeof(struct basescript));
-
- bs->script = gettag(sfd);
- getint(sfd,&bs->def_baseline);
- if ( base->baseline_cnt!=0 ) {
- bs->baseline_pos = calloc(base->baseline_cnt,sizeof(int16));
- for ( i=0; i<base->baseline_cnt; ++i )
- getsint(sfd, &bs->baseline_pos[i]);
- }
- while ( (ch=nlgetc(sfd))==' ' );
- last = NULL;
- while ( ch=='{' ) {
- ungetc(ch,sfd);
- cur = ParseBaseLang(sfd);
- if ( last==NULL )
- bs->langs = cur;
- else
- last->next = cur;
- last = cur;
- while ( (ch=nlgetc(sfd))==' ' );
- }
-return( bs );
-}
-
-static struct Base *SFDParseBase(FILE *sfd) {
- struct Base *base = chunkalloc(sizeof(struct Base));
- int i;
-
- getint(sfd,&base->baseline_cnt);
- if ( base->baseline_cnt!=0 ) {
- base->baseline_tags = malloc(base->baseline_cnt*sizeof(uint32));
- for ( i=0; i<base->baseline_cnt; ++i )
- base->baseline_tags[i] = gettag(sfd);
- }
-return( base );
-}
-
-static OTLookup **SFDLookupList(FILE *sfd,SplineFont *sf) {
- int ch;
- OTLookup *space[100], **buf=space, *otl, **ret;
- int lcnt=0, lmax=100;
- char *name;
-
- for (;;) {
- while ( (ch=nlgetc(sfd))==' ' );
- if ( ch=='\n' || ch==EOF )
- break;
- ungetc(ch,sfd);
- name = SFDReadUTF7Str(sfd);
- otl = SFFindLookup(sf,name);
- free(name);
- if ( otl!=NULL ) {
- if ( lcnt>lmax ) {
- if ( buf==space ) {
- buf = malloc((lmax=lcnt+50)*sizeof(OTLookup *));
- memcpy(buf,space,sizeof(space));
- } else
- buf = realloc(buf,(lmax+=50)*sizeof(OTLookup *));
- }
- buf[lcnt++] = otl;
- }
- }
- if ( lcnt==0 )
-return( NULL );
-
- ret = malloc((lcnt+1)*sizeof(OTLookup *));
- memcpy(ret,buf,lcnt*sizeof(OTLookup *));
- ret[lcnt] = NULL;
-return( ret );
-}
-
-static void SFDParseJustify(FILE *sfd, SplineFont *sf, char *tok) {
- Justify *last=NULL, *cur;
- struct jstf_lang *jlang, *llast;
- int p = 0,ch;
-
- while ( strcmp(tok,"Justify:")==0 ) {
- cur = chunkalloc(sizeof(Justify));
- if ( last==NULL )
- sf->justify = cur;
- else
- last->next = cur;
- last = cur;
- llast = jlang = NULL;
- cur->script = gettag(sfd);
- while ( getname(sfd,tok)>0 ) {
- if ( strcmp(tok,"Justify:")==0 || strcmp(tok,"EndJustify")==0 )
- break;
- if ( strcmp(tok,"JstfExtender:")==0 ) {
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- geteol(sfd,tok);
- cur->extenders = copy(tok);
- } else if ( strcmp(tok,"JstfLang:")==0 ) {
- jlang = chunkalloc(sizeof(struct jstf_lang));
- if ( llast==NULL )
- cur->langs = jlang;
- else
- llast->next = jlang;
- llast = jlang;
- jlang->lang = gettag(sfd);
- p = -1;
- getint(sfd,&jlang->cnt);
- if ( jlang->cnt!=0 )
- jlang->prios = calloc(jlang->cnt,sizeof(struct jstf_prio));
- } else if ( strcmp(tok,"JstfPrio:")==0 ) {
- if ( jlang!=NULL ) {
- ++p;
- if ( p>= jlang->cnt ) {
- jlang->prios = realloc(jlang->prios,(p+1)*sizeof(struct jstf_prio));
- memset(jlang->prios+jlang->cnt,0,(p+1-jlang->cnt)*sizeof(struct jstf_prio));
- jlang->cnt = p+1;
- }
- }
- } else if ( strcmp(tok,"JstfEnableShrink:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].enableShrink = SFDLookupList(sfd,sf);
- } else if ( strcmp(tok,"JstfDisableShrink:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].disableShrink = SFDLookupList(sfd,sf);
- } else if ( strcmp(tok,"JstfMaxShrink:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].maxShrink = SFDLookupList(sfd,sf);
- } else if ( strcmp(tok,"JstfEnableExtend:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].enableExtend = SFDLookupList(sfd,sf);
- } else if ( strcmp(tok,"JstfDisableExtend:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].disableExtend = SFDLookupList(sfd,sf);
- } else if ( strcmp(tok,"JstfMaxExtend:" )==0 ) {
- if ( p<0 ) p=0;
- if ( jlang!=NULL && p<jlang->cnt )
- jlang->prios[p].maxExtend = SFDLookupList(sfd,sf);
- } else
- geteol(sfd,tok);
- }
- }
-}
-
-
-
-void SFD_GetFontMetaDataData_Init( SFD_GetFontMetaDataData* d )
-{
- memset( d, 0, sizeof(SFD_GetFontMetaDataData));
-}
-
-/**
- *
- * @return true if the function matched the current token. If true
- * is returned the caller should avoid further processing of 'tok'
- * a return of false means that the caller might try
- * to handle the token with another function or drop it.
- */
-bool SFD_GetFontMetaData( FILE *sfd,
- char *tok,
- SplineFont *sf,
- SFD_GetFontMetaDataData* d )
-{
- int ch;
- int i;
- KernClass* kc = 0;
- int old;
- char val[2000];
-
- // This allows us to assume we can dereference d
- // at all times
- static SFD_GetFontMetaDataData my_static_d;
- static int my_static_d_is_virgin = 1;
- if( !d )
- {
- if( my_static_d_is_virgin )
- {
- my_static_d_is_virgin = 0;
- SFD_GetFontMetaDataData_Init( &my_static_d );
- }
- d = &my_static_d;
- }
-
- if ( strmatch(tok,"FontName:")==0 )
- {
- geteol(sfd,val);
- sf->fontname = copy(val);
- }
- else if ( strmatch(tok,"FullName:")==0 )
- {
- geteol(sfd,val);
- sf->fullname = copy(val);
- }
- else if ( strmatch(tok,"FamilyName:")==0 )
- {
- geteol(sfd,val);
- sf->familyname = copy(val);
- }
- else if ( strmatch(tok,"DefaultBaseFilename:")==0 )
- {
- geteol(sfd,val);
- sf->defbasefilename = copy(val);
- }
- else if ( strmatch(tok,"Weight:")==0 )
- {
- getprotectedname(sfd,val);
- sf->weight = copy(val);
- }
- else if ( strmatch(tok,"Copyright:")==0 )
- {
- sf->copyright = getquotedeol(sfd);
- }
- else if ( strmatch(tok,"Comments:")==0 )
- {
- char *temp = getquotedeol(sfd);
- sf->comments = latin1_2_utf8_copy(temp);
- free(temp);
- }
- else if ( strmatch(tok,"UComments:")==0 )
- {
- sf->comments = SFDReadUTF7Str(sfd);
- }
- else if ( strmatch(tok,"FontLog:")==0 )
- {
- sf->fontlog = SFDReadUTF7Str(sfd);
- }
- else if ( strmatch(tok,"Version:")==0 )
- {
- geteol(sfd,val);
- sf->version = copy(val);
- }
- else if ( strmatch(tok,"StyleMapFamilyName:")==0 )
- {
- sf->styleMapFamilyName = SFDReadUTF7Str(sfd);
- }
- /* Legacy attribute for StyleMapFamilyName. Deprecated. */
- else if ( strmatch(tok,"OS2FamilyName:")==0 )
- {
- if (sf->styleMapFamilyName == NULL)
- sf->styleMapFamilyName = SFDReadUTF7Str(sfd);
- }
- else if ( strmatch(tok,"FONDName:")==0 )
- {
- geteol(sfd,val);
- sf->fondname = copy(val);
- }
- else if ( strmatch(tok,"ItalicAngle:")==0 )
- {
- getreal(sfd,&sf->italicangle);
- }
- else if ( strmatch(tok,"StrokeWidth:")==0 )
- {
- getreal(sfd,&sf->strokewidth);
- }
- else if ( strmatch(tok,"UnderlinePosition:")==0 )
- {
- getreal(sfd,&sf->upos);
- }
- else if ( strmatch(tok,"UnderlineWidth:")==0 )
- {
- getreal(sfd,&sf->uwidth);
- }
- else if ( strmatch(tok,"ModificationTime:")==0 )
- {
- getlonglong(sfd,&sf->modificationtime);
- }
- else if ( strmatch(tok,"CreationTime:")==0 )
- {
- getlonglong(sfd,&sf->creationtime);
- d->hadtimes = true;
- }
- else if ( strmatch(tok,"PfmFamily:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->pfminfo.pfmfamily = temp;
- sf->pfminfo.pfmset = true;
- }
- else if ( strmatch(tok,"LangName:")==0 )
- {
- sf->names = SFDGetLangName(sfd,sf->names);
- }
- else if ( strmatch(tok,"GaspTable:")==0 )
- {
- SFDGetGasp(sfd,sf);
- }
- else if ( strmatch(tok,"DesignSize:")==0 )
- {
- SFDGetDesignSize(sfd,sf);
- }
- else if ( strmatch(tok,"OtfFeatName:")==0 )
- {
- SFDGetOtfFeatName(sfd,sf);
- }
- else if ( strmatch(tok,"PfmWeight:")==0 || strmatch(tok,"TTFWeight:")==0 )
- {
- getsint(sfd,&sf->pfminfo.weight);
- sf->pfminfo.pfmset = true;
- }
- else if ( strmatch(tok,"TTFWidth:")==0 )
- {
- getsint(sfd,&sf->pfminfo.width);
- sf->pfminfo.pfmset = true;
- }
- else if ( strmatch(tok,"Panose:")==0 )
- {
- int temp,i;
- for ( i=0; i<10; ++i )
- {
- getint(sfd,&temp);
- sf->pfminfo.panose[i] = temp;
- }
- sf->pfminfo.panose_set = true;
- }
- else if ( strmatch(tok,"LineGap:")==0 )
- {
- getsint(sfd,&sf->pfminfo.linegap);
- sf->pfminfo.pfmset = true;
- }
- else if ( strmatch(tok,"VLineGap:")==0 )
- {
- getsint(sfd,&sf->pfminfo.vlinegap);
- sf->pfminfo.pfmset = true;
- }
- else if ( strmatch(tok,"HheadAscent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.hhead_ascent);
- }
- else if ( strmatch(tok,"HheadAOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.hheadascent_add = temp;
- }
- else if ( strmatch(tok,"HheadDescent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.hhead_descent);
- }
- else if ( strmatch(tok,"HheadDOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.hheaddescent_add = temp;
- }
- else if ( strmatch(tok,"OS2TypoLinegap:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_typolinegap);
- }
- else if ( strmatch(tok,"OS2TypoAscent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_typoascent);
- }
- else if ( strmatch(tok,"OS2TypoAOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.typoascent_add = temp;
- }
- else if ( strmatch(tok,"OS2TypoDescent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_typodescent);
- }
- else if ( strmatch(tok,"OS2TypoDOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.typodescent_add = temp;
- }
- else if ( strmatch(tok,"OS2WinAscent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_winascent);
- }
- else if ( strmatch(tok,"OS2WinDescent:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_windescent);
- }
- else if ( strmatch(tok,"OS2WinAOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.winascent_add = temp;
- }
- else if ( strmatch(tok,"OS2WinDOffset:")==0 )
- {
- int temp;
- getint(sfd,&temp); sf->pfminfo.windescent_add = temp;
- }
- else if ( strmatch(tok,"HHeadAscent:")==0 )
- {
- // DUPLICATE OF ABOVE
- getsint(sfd,&sf->pfminfo.hhead_ascent);
- }
- else if ( strmatch(tok,"HHeadDescent:")==0 )
- {
- // DUPLICATE OF ABOVE
- getsint(sfd,&sf->pfminfo.hhead_descent);
- }
-
- else if ( strmatch(tok,"HHeadAOffset:")==0 )
- {
- // DUPLICATE OF ABOVE
- int temp;
- getint(sfd,&temp); sf->pfminfo.hheadascent_add = temp;
- }
- else if ( strmatch(tok,"HHeadDOffset:")==0 )
- {
- // DUPLICATE OF ABOVE
- int temp;
- getint(sfd,&temp); sf->pfminfo.hheaddescent_add = temp;
- }
- else if ( strmatch(tok,"MacStyle:")==0 )
- {
- getsint(sfd,&sf->macstyle);
- }
- else if ( strmatch(tok,"OS2SubXSize:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_subxsize);
- sf->pfminfo.subsuper_set = true;
- }
- else if ( strmatch(tok,"OS2SubYSize:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_subysize);
- }
- else if ( strmatch(tok,"OS2SubXOff:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_subxoff);
- }
- else if ( strmatch(tok,"OS2SubYOff:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_subyoff);
- }
- else if ( strmatch(tok,"OS2SupXSize:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_supxsize);
- }
- else if ( strmatch(tok,"OS2SupYSize:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_supysize);
- }
- else if ( strmatch(tok,"OS2SupXOff:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_supxoff);
- }
- else if ( strmatch(tok,"OS2SupYOff:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_supyoff);
- }
- else if ( strmatch(tok,"OS2StrikeYSize:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_strikeysize);
- }
- else if ( strmatch(tok,"OS2StrikeYPos:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_strikeypos);
- }
- else if ( strmatch(tok,"OS2CapHeight:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_capheight);
- }
- else if ( strmatch(tok,"OS2XHeight:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_xheight);
- }
- else if ( strmatch(tok,"OS2FamilyClass:")==0 )
- {
- getsint(sfd,&sf->pfminfo.os2_family_class);
- }
- else if ( strmatch(tok,"OS2Vendor:")==0 )
- {
- while ( isspace(nlgetc(sfd)));
- sf->pfminfo.os2_vendor[0] = nlgetc(sfd);
- sf->pfminfo.os2_vendor[1] = nlgetc(sfd);
- sf->pfminfo.os2_vendor[2] = nlgetc(sfd);
- sf->pfminfo.os2_vendor[3] = nlgetc(sfd);
- (void) nlgetc(sfd);
- }
- else if ( strmatch(tok,"OS2CodePages:")==0 )
- {
- gethexints(sfd,sf->pfminfo.codepages,2);
- sf->pfminfo.hascodepages = true;
- }
- else if ( strmatch(tok,"OS2UnicodeRanges:")==0 )
- {
- gethexints(sfd,sf->pfminfo.unicoderanges,4);
- sf->pfminfo.hasunicoderanges = true;
- }
- else if ( strmatch(tok,"TopEncoding:")==0 )
- {
- /* Obsolete */
- getint(sfd,&sf->top_enc);
- }
- else if ( strmatch(tok,"Ascent:")==0 )
- {
- getint(sfd,&sf->ascent);
- }
- else if ( strmatch(tok,"Descent:")==0 )
- {
- getint(sfd,&sf->descent);
- }
- else if ( strmatch(tok,"InvalidEm:")==0 )
- {
- getint(sfd,&sf->invalidem);
- }
- else if ( strmatch(tok,"woffMajor:")==0 )
- {
- getint(sfd,&sf->woffMajor);
- }
- else if ( strmatch(tok,"woffMinor:")==0 )
- {
- getint(sfd,&sf->woffMinor);
- }
- else if ( strmatch(tok,"woffMetadata:")==0 )
- {
- sf->woffMetadata = SFDReadUTF7Str(sfd);
- }
- else if ( strmatch(tok,"sfntRevision:")==0 )
- {
- gethex(sfd,(uint32 *)&sf->sfntRevision);
- }
- else if ( strmatch(tok,"LayerCount:")==0 )
- {
- d->had_layer_cnt = true;
- getint(sfd,&sf->layer_cnt);
- if ( sf->layer_cnt>2 ) {
- sf->layers = realloc(sf->layers,sf->layer_cnt*sizeof(LayerInfo));
- memset(sf->layers+2,0,(sf->layer_cnt-2)*sizeof(LayerInfo));
- }
- }
- else if ( strmatch(tok,"Layer:")==0 )
- {
- // TODO: Read the U. F. O. path.
- int layer, o2, bk;
- getint(sfd,&layer);
- if ( layer>=sf->layer_cnt ) {
- sf->layers = realloc(sf->layers,(layer+1)*sizeof(LayerInfo));
- memset(sf->layers+sf->layer_cnt,0,((layer+1)-sf->layer_cnt)*sizeof(LayerInfo));
- sf->layer_cnt = layer+1;
- }
- getint(sfd,&o2);
- sf->layers[layer].order2 = o2;
- sf->layers[layer].background = layer==ly_back;
- /* Used briefly, now background is after layer name */
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( ch!='"' ) {
- getint(sfd,&bk);
- sf->layers[layer].background = bk;
- }
- /* end of section for obsolete format */
- sf->layers[layer].name = SFDReadUTF7Str(sfd);
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( ch!='\n' ) {
- getint(sfd,&bk);
- sf->layers[layer].background = bk;
- }
- while ( (ch=nlgetc(sfd))==' ' );
- ungetc(ch,sfd);
- if ( ch!='\n' ) { sf->layers[layer].ufo_path = SFDReadUTF7Str(sfd); }
- }
- else if ( strmatch(tok,"PreferredKerning:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->preferred_kerning = temp;
- }
- else if ( strmatch(tok,"StrokedFont:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->strokedfont = temp;
- }
- else if ( strmatch(tok,"MultiLayer:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->multilayer = temp;
- }
- else if ( strmatch(tok,"NeedsXUIDChange:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->changed_since_xuidchanged = temp;
- }
- else if ( strmatch(tok,"VerticalOrigin:")==0 )
- {
- // this doesn't seem to be written ever.
- int temp;
- getint(sfd,&temp);
- sf->hasvmetrics = true;
- }
- else if ( strmatch(tok,"HasVMetrics:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->hasvmetrics = temp;
- }
- else if ( strmatch(tok,"Justify:")==0 )
- {
- SFDParseJustify(sfd,sf,tok);
- }
- else if ( strmatch(tok,"BaseHoriz:")==0 )
- {
- sf->horiz_base = SFDParseBase(sfd);
- d->last_base = sf->horiz_base;
- d->last_base_script = NULL;
- }
- else if ( strmatch(tok,"BaseVert:")==0 )
- {
- sf->vert_base = SFDParseBase(sfd);
- d->last_base = sf->vert_base;
- d->last_base_script = NULL;
- }
- else if ( strmatch(tok,"BaseScript:")==0 )
- {
- struct basescript *bs = SFDParseBaseScript(sfd,d->last_base);
- if ( d->last_base==NULL )
- {
- BaseScriptFree(bs);
- bs = NULL;
- }
- else if ( d->last_base_script!=NULL )
- d->last_base_script->next = bs;
- else
- d->last_base->scripts = bs;
- d->last_base_script = bs;
- }
- else if ( strmatch(tok,"StyleMap:")==0 )
- {
- gethex(sfd,(uint32 *)&sf->pfminfo.stylemap);
- }
- /* Legacy attribute for StyleMap. Deprecated. */
- else if ( strmatch(tok,"OS2StyleName:")==0 )
- {
- char* sname = SFDReadUTF7Str(sfd);
- if (sf->pfminfo.stylemap == -1) {
- if (strcmp(sname,"bold italic")==0) sf->pfminfo.stylemap = 0x21;
- else if (strcmp(sname,"bold")==0) sf->pfminfo.stylemap = 0x20;
- else if (strcmp(sname,"italic")==0) sf->pfminfo.stylemap = 0x01;
- else if (strcmp(sname,"regular")==0) sf->pfminfo.stylemap = 0x40;
- }
- free(sname);
- }
- else if ( strmatch(tok,"FSType:")==0 )
- {
- getsint(sfd,&sf->pfminfo.fstype);
- }
- else if ( strmatch(tok,"OS2Version:")==0 )
- {
- getsint(sfd,&sf->os2_version);
- }
- else if ( strmatch(tok,"OS2_WeightWidthSlopeOnly:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->weight_width_slope_only = temp;
- }
- else if ( strmatch(tok,"OS2_UseTypoMetrics:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->use_typo_metrics = temp;
- }
- else if ( strmatch(tok,"UseUniqueID:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->use_uniqueid = temp;
- }
- else if ( strmatch(tok,"UseXUID:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->use_xuid = temp;
- }
- else if ( strmatch(tok,"UniqueID:")==0 )
- {
- getint(sfd,&sf->uniqueid);
- }
- else if ( strmatch(tok,"XUID:")==0 )
- {
- geteol(sfd,tok);
- sf->xuid = copy(tok);
- }
- else if ( strmatch(tok,"Lookup:")==0 )
- {
- OTLookup *otl;
- int temp;
- otl = chunkalloc(sizeof(OTLookup));
- getint(sfd,&temp); otl->lookup_type = temp;
- getint(sfd,&temp); otl->lookup_flags = temp;
- getint(sfd,&temp); otl->store_in_afm = temp;
- otl->lookup_name = SFDReadUTF7Str(sfd);
- if ( otl->lookup_type<gpos_single ) {
- if ( d->lastsotl==NULL )
- sf->gsub_lookups = otl;
- else
- d->lastsotl->next = otl;
- d->lastsotl = otl;
- } else {
- if ( d->lastpotl==NULL )
- sf->gpos_lookups = otl;
- else
- d->lastpotl->next = otl;
- d->lastpotl = otl;
- }
- SFDParseLookup(sfd,otl);
- }
- else if ( strmatch(tok,"MarkAttachClasses:")==0 )
- {
- getint(sfd,&sf->mark_class_cnt);
- sf->mark_classes = malloc(sf->mark_class_cnt*sizeof(char *));
- sf->mark_class_names = malloc(sf->mark_class_cnt*sizeof(char *));
- sf->mark_classes[0] = NULL; sf->mark_class_names[0] = NULL;
- for ( i=1; i<sf->mark_class_cnt; ++i )
- {
- /* Class 0 is unused */
- int temp;
- while ( (temp=nlgetc(sfd))=='\n' || temp=='\r' ); ungetc(temp,sfd);
- sf->mark_class_names[i] = SFDReadUTF7Str(sfd);
- getint(sfd,&temp);
- sf->mark_classes[i] = malloc(temp+1); sf->mark_classes[i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(sf->mark_classes[i],1,temp,sfd);
- }
- }
- else if ( strmatch(tok,"MarkAttachSets:")==0 )
- {
- getint(sfd,&sf->mark_set_cnt);
- sf->mark_sets = malloc(sf->mark_set_cnt*sizeof(char *));
- sf->mark_set_names = malloc(sf->mark_set_cnt*sizeof(char *));
- for ( i=0; i<sf->mark_set_cnt; ++i )
- {
- /* Set 0 is used */
- int temp;
- while ( (temp=nlgetc(sfd))=='\n' || temp=='\r' ); ungetc(temp,sfd);
- sf->mark_set_names[i] = SFDReadUTF7Str(sfd);
- getint(sfd,&temp);
- sf->mark_sets[i] = malloc(temp+1); sf->mark_sets[i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(sf->mark_sets[i],1,temp,sfd);
- }
- }
- else if ( strmatch(tok,"KernClass2:")==0 || strmatch(tok,"VKernClass2:")==0 ||
- strmatch(tok,"KernClass:")==0 || strmatch(tok,"VKernClass:")==0 ||
- strmatch(tok,"KernClass3:")==0 || strmatch(tok,"VKernClass3:")==0 )
- {
- int kernclassversion = 0;
- int isv = tok[0]=='V';
- int kcvoffset = (isv ? 10 : 9); //Offset to read kerning class version
- if (isdigit(tok[kcvoffset])) kernclassversion = tok[kcvoffset] - '0';
- int temp, classstart=1;
- int old = (kernclassversion == 0);
-
- if ( (sf->sfd_version<2)!=old ) {
- IError( "Version mixup in Kerning Classes of sfd file." );
- exit(1);
- }
- kc = chunkalloc(old ? sizeof(KernClass1) : sizeof(KernClass));
- getint(sfd,&kc->first_cnt);
- ch=nlgetc(sfd);
- if ( ch=='+' )
- classstart = 0;
- else
- ungetc(ch,sfd);
- getint(sfd,&kc->second_cnt);
- if ( old ) {
- getint(sfd,&temp); ((KernClass1 *) kc)->sli = temp;
- getint(sfd,&temp); ((KernClass1 *) kc)->flags = temp;
- } else {
- kc->subtable = SFFindLookupSubtableAndFreeName(sf,SFDReadUTF7Str(sfd));
- if ( kc->subtable!=NULL && kc->subtable->kc==NULL )
- kc->subtable->kc = kc;
- else {
- if ( kc->subtable==NULL )
- LogError(_("Bad SFD file, missing subtable in kernclass defn.\n") );
- else
- LogError(_("Bad SFD file, two kerning classes assigned to the same subtable: %s\n"), kc->subtable->subtable_name );
- kc->subtable = NULL;
- }
- }
- kc->firsts = calloc(kc->first_cnt,sizeof(char *));
- kc->seconds = calloc(kc->second_cnt,sizeof(char *));
- kc->offsets = calloc(kc->first_cnt*kc->second_cnt,sizeof(int16));
- kc->adjusts = calloc(kc->first_cnt*kc->second_cnt,sizeof(DeviceTable));
- if (kernclassversion >= 3) {
- kc->firsts_flags = calloc(kc->first_cnt, sizeof(int));
- kc->seconds_flags = calloc(kc->second_cnt, sizeof(int));
- kc->offsets_flags = calloc(kc->first_cnt*kc->second_cnt, sizeof(int));
- kc->firsts_names = calloc(kc->first_cnt, sizeof(char*));
- kc->seconds_names = calloc(kc->second_cnt, sizeof(char*));
- }
- kc->firsts[0] = NULL;
- for ( i=classstart; i<kc->first_cnt; ++i ) {
- if (kernclassversion < 3) {
- getint(sfd,&temp);
- kc->firsts[i] = malloc(temp+1); kc->firsts[i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(kc->firsts[i],1,temp,sfd);
- } else {
- getint(sfd,&kc->firsts_flags[i]);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd); if (ch == '\n' || ch == EOF) continue;
- kc->firsts_names[i] = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd); if (ch == '\n' || ch == EOF) continue;
- kc->firsts[i] = SFDReadUTF7Str(sfd);
- if (kc->firsts[i] == NULL) kc->firsts[i] = copy(""); // In certain places, this must be defined.
- while ((ch=nlgetc(sfd)) == ' ' || ch == '\n'); ungetc(ch, sfd);
- }
- }
- kc->seconds[0] = NULL;
- for ( i=1; i<kc->second_cnt; ++i ) {
- if (kernclassversion < 3) {
- getint(sfd,&temp);
- kc->seconds[i] = malloc(temp+1); kc->seconds[i][temp] = '\0';
- nlgetc(sfd); /* skip space */
- fread(kc->seconds[i],1,temp,sfd);
- } else {
- getint(sfd,&temp);
- kc->seconds_flags[i] = temp;
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd); if (ch == '\n' || ch == EOF) continue;
- kc->seconds_names[i] = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd); if (ch == '\n' || ch == EOF) continue;
- kc->seconds[i] = SFDReadUTF7Str(sfd);
- if (kc->seconds[i] == NULL) kc->seconds[i] = copy(""); // In certain places, this must be defined.
- while ((ch=nlgetc(sfd)) == ' ' || ch == '\n'); ungetc(ch, sfd);
- }
- }
- for ( i=0; i<kc->first_cnt*kc->second_cnt; ++i ) {
- if (kernclassversion >= 3) {
- getint(sfd,&temp);
- kc->offsets_flags[i] = temp;
- }
- getint(sfd,&temp);
- kc->offsets[i] = temp;
- SFDReadDeviceTable(sfd,&kc->adjusts[i]);
- }
- if ( !old && kc->subtable == NULL ) {
- /* Error. Ignore it. Free it. Whatever */;
- } else if ( !isv ) {
- if ( d->lastkc==NULL )
- sf->kerns = kc;
- else
- d->lastkc->next = kc;
- d->lastkc = kc;
- } else {
- if ( d->lastvkc==NULL )
- sf->vkerns = kc;
- else
- d->lastvkc->next = kc;
- d->lastvkc = kc;
- }
- }
- else if ( strmatch(tok,"ContextPos2:")==0 || strmatch(tok,"ContextSub2:")==0 ||
- strmatch(tok,"ChainPos2:")==0 || strmatch(tok,"ChainSub2:")==0 ||
- strmatch(tok,"ReverseChain2:")==0 ||
- strmatch(tok,"ContextPos:")==0 || strmatch(tok,"ContextSub:")==0 ||
- strmatch(tok,"ChainPos:")==0 || strmatch(tok,"ChainSub:")==0 ||
- strmatch(tok,"ReverseChain:")==0 )
- {
- FPST *fpst;
- int old;
- if ( strchr(tok,'2')!=NULL ) {
- old = false;
- fpst = chunkalloc(sizeof(FPST));
- } else {
- old = true;
- fpst = chunkalloc(sizeof(FPST1));
- }
- if ( (sf->sfd_version<2)!=old ) {
- IError( "Version mixup in FPST of sfd file." );
- exit(1);
- }
- if ( d->lastfp==NULL )
- sf->possub = fpst;
- else
- d->lastfp->next = fpst;
- d->lastfp = fpst;
- SFDParseChainContext(sfd,sf,fpst,tok,old);
- }
- else if ( strmatch(tok,"Group:")==0 ) {
- struct ff_glyphclasses *grouptmp = calloc(1, sizeof(struct ff_glyphclasses));
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- grouptmp->classname = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- grouptmp->glyphs = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' ' || ch == '\n'); ungetc(ch, sfd);
- if (d->lastgroup != NULL) d->lastgroup->next = grouptmp; else sf->groups = grouptmp;
- d->lastgroup = grouptmp;
- }
- else if ( strmatch(tok,"GroupKern:")==0 ) {
- int temp = 0;
- struct ff_rawoffsets *kerntmp = calloc(1, sizeof(struct ff_rawoffsets));
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- kerntmp->left = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- kerntmp->right = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- getint(sfd,&temp);
- kerntmp->offset = temp;
- while ((ch=nlgetc(sfd)) == ' ' || ch == '\n'); ungetc(ch, sfd);
- if (d->lastgroupkern != NULL) d->lastgroupkern->next = kerntmp; else sf->groupkerns = kerntmp;
- d->lastgroupkern = kerntmp;
- }
- else if ( strmatch(tok,"GroupVKern:")==0 ) {
- int temp = 0;
- struct ff_rawoffsets *kerntmp = calloc(1, sizeof(struct ff_rawoffsets));
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- kerntmp->left = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- kerntmp->right = SFDReadUTF7Str(sfd);
- while ((ch=nlgetc(sfd)) == ' '); ungetc(ch, sfd);
- getint(sfd,&temp);
- kerntmp->offset = temp;
- while ((ch=nlgetc(sfd)) == ' ' || ch == '\n'); ungetc(ch, sfd);
- if (d->lastgroupvkern != NULL) d->lastgroupvkern->next = kerntmp; else sf->groupvkerns = kerntmp;
- d->lastgroupvkern = kerntmp;
- }
- else if ( strmatch(tok,"MacIndic2:")==0 || strmatch(tok,"MacContext2:")==0 ||
- strmatch(tok,"MacLigature2:")==0 || strmatch(tok,"MacSimple2:")==0 ||
- strmatch(tok,"MacKern2:")==0 || strmatch(tok,"MacInsert2:")==0 ||
- strmatch(tok,"MacIndic:")==0 || strmatch(tok,"MacContext:")==0 ||
- strmatch(tok,"MacLigature:")==0 || strmatch(tok,"MacSimple:")==0 ||
- strmatch(tok,"MacKern:")==0 || strmatch(tok,"MacInsert:")==0 )
- {
- ASM *sm;
- if ( strchr(tok,'2')!=NULL ) {
- old = false;
- sm = chunkalloc(sizeof(ASM));
- } else {
- old = true;
- sm = chunkalloc(sizeof(ASM1));
- }
- if ( (sf->sfd_version<2)!=old ) {
- IError( "Version mixup in state machine of sfd file." );
- exit(1);
- }
- if ( d->lastsm==NULL )
- sf->sm = sm;
- else
- d->lastsm->next = sm;
- d->lastsm = sm;
- SFDParseStateMachine(sfd,sf,sm,tok,old);
- }
- else if ( strmatch(tok,"MacFeat:")==0 )
- {
- sf->features = SFDParseMacFeatures(sfd,tok);
- }
- else if ( strmatch(tok,"TtfTable:")==0 )
- {
- /* Old, binary format */
- /* still used for maxp and unknown tables */
- SFDGetTtfTable(sfd,sf,d->lastttf);
- }
- else if ( strmatch(tok,"TtTable:")==0 )
- {
- /* text instruction format */
- SFDGetTtTable(sfd,sf,d->lastttf);
- }
-
-
- ///////////////////
-
- else if ( strmatch(tok,"ShortTable:")==0 )
- {
- // only read, not written.
- /* text number format */
- SFDGetShortTable(sfd,sf,d->lastttf);
- }
- else
- {
- //
- // We didn't have a match ourselves.
- //
- return false;
- }
- return true;
-}
-
-static SplineFont *SFD_GetFont( FILE *sfd,SplineFont *cidmaster,char *tok,
- int fromdir, char *dirname, float sfdversion )
-{
- SplineFont *sf;
- int realcnt, i, eof, mappos=-1, ch;
- struct table_ordering *lastord = NULL;
- struct axismap *lastaxismap = NULL;
- struct named_instance *lastnamedinstance = NULL;
- int pushedbacktok = false;
- Encoding *enc = &custom;
- struct remap *remap = NULL;
- int haddupenc;
- int old_style_order2 = false;
- int had_layer_cnt=false;
-
- orig_pos = 0; /* Only used for compatibility with extremely old sfd files */
-
- sf = SplineFontEmpty();
- sf->sfd_version = sfdversion;
- sf->cidmaster = cidmaster;
- sf->uni_interp = ui_unset;
- SFD_GetFontMetaDataData d;
- SFD_GetFontMetaDataData_Init( &d );
- while ( 1 ) {
- if ( pushedbacktok )
- pushedbacktok = false;
- else if ( (eof = getname(sfd,tok))!=1 ) {
- if ( eof==-1 )
- break;
- geteol(sfd,tok);
- continue;
- }
-
-
- bool wasMetadata = SFD_GetFontMetaData( sfd, tok, sf, &d );
- had_layer_cnt = d.had_layer_cnt;
- if( wasMetadata )
- {
- // we have handled the token entirely
- // inside SFD_GetFontMetaData() move to next token.
- continue;
- }
-
-
- if ( strmatch(tok,"DisplaySize:")==0 )
- {
- getint(sfd,&sf->display_size);
- }
- else if ( strmatch(tok,"DisplayLayer:")==0 )
- {
- getint(sfd,&sf->display_layer);
- }
- else if ( strmatch(tok,"ExtremaBound:")==0 )
- {
- getint(sfd,&sf->extrema_bound);
- }
- else if ( strmatch(tok,"WidthSeparation:")==0 )
- {
- getint(sfd,&sf->width_separation);
- }
- else if ( strmatch(tok,"WinInfo:")==0 )
- {
- int temp1, temp2;
- getint(sfd,&sf->top_enc);
- getint(sfd,&temp1);
- getint(sfd,&temp2);
- if ( sf->top_enc<=0 ) sf->top_enc=-1;
- if ( temp1<=0 ) temp1 = 16;
- if ( temp2<=0 ) temp2 = 4;
- sf->desired_col_cnt = temp1;
- sf->desired_row_cnt = temp2;
- }
- else if ( strmatch(tok,"AntiAlias:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->display_antialias = temp;
- }
- else if ( strmatch(tok,"FitToEm:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->display_bbsized = temp;
- }
- else if ( strmatch(tok,"Order2:")==0 )
- {
- getint(sfd,&old_style_order2);
- sf->grid.order2 = old_style_order2;
- sf->layers[ly_back].order2 = old_style_order2;
- sf->layers[ly_fore].order2 = old_style_order2;
- }
- else if ( strmatch(tok,"GridOrder2:")==0 )
- {
- int o2;
- getint(sfd,&o2);
- sf->grid.order2 = o2;
- }
- else if ( strmatch(tok,"Encoding:")==0 )
- {
- enc = SFDGetEncoding(sfd,tok);
- if ( sf->map!=NULL ) sf->map->enc = enc;
- }
- else if ( strmatch(tok,"OldEncoding:")==0 )
- {
- /* old_encname =*/ (void) SFDGetEncoding(sfd,tok);
- }
- else if ( strmatch(tok,"UnicodeInterp:")==0 )
- {
- sf->uni_interp = SFDGetUniInterp(sfd,tok,sf);
- }
- else if ( strmatch(tok,"NameList:")==0 )
- {
- SFDGetNameList(sfd,tok,sf);
- }
- else if ( strmatch(tok,"Compacted:")==0 )
- {
- int temp;
- getint(sfd,&temp);
- sf->compacted = temp;
- }
- else if ( strmatch(tok,"Registry:")==0 )
- {
- geteol(sfd,tok);
- sf->cidregistry = copy(tok);
- }
-
-
- //////////
-
-
- else if ( strmatch(tok,"Ordering:")==0 ) {
- geteol(sfd,tok);
- sf->ordering = copy(tok);
- } else if ( strmatch(tok,"Supplement:")==0 ) {
- getint(sfd,&sf->supplement);
- } else if ( strmatch(tok,"RemapN:")==0 ) {
- int n;
- getint(sfd,&n);
- remap = calloc(n+1,sizeof(struct remap));
- remap[n].infont = -1;
- mappos = 0;
- if ( sf->map!=NULL ) sf->map->remap = remap;
- } else if ( strmatch(tok,"Remap:")==0 ) {
- uint32 f, l; int p;
- gethex(sfd,&f);
- gethex(sfd,&l);
- getint(sfd,&p);
- if ( remap!=NULL && remap[mappos].infont!=-1 ) {
- remap[mappos].firstenc = f;
- remap[mappos].lastenc = l;
- remap[mappos].infont = p;
- mappos++;
- }
- } else if ( strmatch(tok,"CIDVersion:")==0 ) {
- real temp;
- getreal(sfd,&temp);
- sf->cidversion = temp;
- } else if ( strmatch(tok,"Grid")==0 ) {
- sf->grid.splines = SFDGetSplineSet(sfd,sf->grid.order2);
- } else if ( strmatch(tok,"ScriptLang:")==0 ) {
- int i,j,k;
- int imax, jmax, kmax;
- if ( sf->sfd_version==0 || sf->sfd_version>=2 ) {
- IError( "Script lang lists should not happen in version 2 sfd files." );
- SplineFontFree(sf);
- return NULL;
- }
- getint(sfd,&imax);
- ((SplineFont1 *) sf)->sli_cnt = imax;
- ((SplineFont1 *) sf)->script_lang = malloc((imax+1)*sizeof(struct script_record *));
- ((SplineFont1 *) sf)->script_lang[imax] = NULL;
- for ( i=0; i<imax; ++i ) {
- getint(sfd,&jmax);
- ((SplineFont1 *) sf)->script_lang[i] = malloc((jmax+1)*sizeof(struct script_record));
- ((SplineFont1 *) sf)->script_lang[i][jmax].script = 0;
- for ( j=0; j<jmax; ++j ) {
- ((SplineFont1 *) sf)->script_lang[i][j].script = gettag(sfd);
- getint(sfd,&kmax);
- ((SplineFont1 *) sf)->script_lang[i][j].langs = malloc((kmax+1)*sizeof(uint32));
- ((SplineFont1 *) sf)->script_lang[i][j].langs[kmax] = 0;
- for ( k=0; k<kmax; ++k ) {
- ((SplineFont1 *) sf)->script_lang[i][j].langs[k] = gettag(sfd);
- }
- }
- }
- } else if ( strmatch(tok,"TeXData:")==0 ) {
- int temp;
- getint(sfd,&temp);
- sf->texdata.type = temp;
- getint(sfd, &temp);
- if ( sf->design_size==0 ) {
- sf->design_size = (5*temp+(1<<18))>>19;
- }
- for ( i=0; i<22; ++i ) {
- int foo;
- getint(sfd,&foo);
- sf->texdata.params[i]=foo;
- }
- } else if ( strnmatch(tok,"AnchorClass",11)==0 ) {
- char *name;
- AnchorClass *lastan = NULL, *an;
- int old = strchr(tok,'2')==NULL;
- while ( (name=SFDReadUTF7Str(sfd))!=NULL ) {
- an = chunkalloc(old ? sizeof(AnchorClass1) : sizeof(AnchorClass));
- an->name = name;
- if ( old ) {
- getname(sfd,tok);
- if ( tok[0]=='0' && tok[1]=='\0' )
- ((AnchorClass1 *) an)->feature_tag = 0;
- else {
- if ( tok[1]=='\0' ) { tok[1]=' '; tok[2] = 0; }
- if ( tok[2]=='\0' ) { tok[2]=' '; tok[3] = 0; }
- if ( tok[3]=='\0' ) { tok[3]=' '; tok[4] = 0; }
- ((AnchorClass1 *) an)->feature_tag = (tok[0]<<24) | (tok[1]<<16) | (tok[2]<<8) | tok[3];
- }
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- ungetc(ch,sfd);
- if ( isdigit(ch)) {
- int temp;
- getint(sfd,&temp);
- ((AnchorClass1 *) an)->flags = temp;
- }
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- ungetc(ch,sfd);
- if ( isdigit(ch)) {
- int temp;
- getint(sfd,&temp);
- ((AnchorClass1 *) an)->script_lang_index = temp;
- } else
- ((AnchorClass1 *) an)->script_lang_index = 0xffff; /* Will be fixed up later */
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- ungetc(ch,sfd);
- if ( isdigit(ch)) {
- int temp;
- getint(sfd,&temp);
- ((AnchorClass1 *) an)->merge_with = temp;
- } else
- ((AnchorClass1 *) an)->merge_with = 0xffff; /* Will be fixed up later */
- } else {
- char *subtable_name = SFDReadUTF7Str(sfd);
- if ( subtable_name!=NULL) /* subtable is optional */
- an->subtable = SFFindLookupSubtableAndFreeName(sf,subtable_name);
- }
- while ( (ch=nlgetc(sfd))==' ' || ch=='\t' );
- ungetc(ch,sfd);
- if ( isdigit(ch) ) {
- /* Early versions of SfdFormat 2 had a number here */
- int temp;
- getint(sfd,&temp);
- an->type = temp;
- } else if ( old ) {
- if ( ((AnchorClass1 *) an)->feature_tag==CHR('c','u','r','s'))
- an->type = act_curs;
- else if ( ((AnchorClass1 *) an)->feature_tag==CHR('m','k','m','k'))
- an->type = act_mkmk;
- else
- an->type = act_mark;
- } else {
- an->type = act_mark;
- if( an->subtable && an->subtable->lookup )
- {
- switch ( an->subtable->lookup->lookup_type )
- {
- case gpos_cursive:
- an->type = act_curs;
- break;
- case gpos_mark2base:
- an->type = act_mark;
- break;
- case gpos_mark2ligature:
- an->type = act_mklg;
- break;
- case gpos_mark2mark:
- an->type = act_mkmk;
- break;
- default:
- an->type = act_mark;
- break;
- }
- }
- }
- if ( lastan==NULL )
- sf->anchor = an;
- else
- lastan->next = an;
- lastan = an;
- }
- } else if ( strncmp(tok,"MATH:",5)==0 ) {
- SFDParseMathItem(sfd,sf,tok);
- } else if ( strmatch(tok,"TableOrder:")==0 ) {
- int temp;
- struct table_ordering *ord;
- if ( sfdversion==0 || sfdversion>=2 ) {
- IError("Table ordering specified in version 2 sfd file.\n" );
- SplineFontFree(sf);
- return NULL;
- }
- ord = chunkalloc(sizeof(struct table_ordering));
- ord->table_tag = gettag(sfd);
- getint(sfd,&temp);
- ord->ordered_features = malloc((temp+1)*sizeof(uint32));
- ord->ordered_features[temp] = 0;
- for ( i=0; i<temp; ++i ) {
- while ( isspace((ch=nlgetc(sfd))) );
- if ( ch=='\'' ) {
- ungetc(ch,sfd);
- ord->ordered_features[i] = gettag(sfd);
- } else if ( ch=='<' ) {
- int f,s;
- fscanf(sfd,"%d,%d>", &f, &s );
- ord->ordered_features[i] = (f<<16)|s;
- }
- }
- if ( lastord==NULL )
- ((SplineFont1 *) sf)->orders = ord;
- else
- lastord->next = ord;
- lastord = ord;
- } else if ( strmatch(tok,"BeginPrivate:")==0 ) {
- SFDGetPrivate(sfd,sf);
- } else if ( strmatch(tok,"BeginSubrs:")==0 ) { /* leave in so we don't croak on old sfd files */
- SFDGetSubrs(sfd);
- } else if ( strmatch(tok,"PickledData:")==0 ) {
- if (sf->python_persistent != NULL) {
-#if defined(_NO_PYTHON)
- free( sf->python_persistent ); /* It's a string of pickled data which we leave as a string */
-#else
- PyFF_FreePythonPersistent(sf->python_persistent);
-#endif
- sf->python_persistent = NULL;
- }
- sf->python_persistent = SFDUnPickle(sfd, 0);
- sf->python_persistent_has_lists = 0;
- } else if ( strmatch(tok,"PickledDataWithLists:")==0 ) {
- if (sf->python_persistent != NULL) {
-#if defined(_NO_PYTHON)
- free( sf->python_persistent ); /* It's a string of pickled data which we leave as a string */
-#else
- PyFF_FreePythonPersistent(sf->python_persistent);
-#endif
- sf->python_persistent = NULL;
- }
- sf->python_persistent = SFDUnPickle(sfd, 1);
- sf->python_persistent_has_lists = 1;
- } else if ( strmatch(tok,"MMCounts:")==0 ) {
- MMSet *mm = sf->mm = chunkalloc(sizeof(MMSet));
- getint(sfd,&mm->instance_count);
- getint(sfd,&mm->axis_count);
- ch = nlgetc(sfd);
- if ( ch!=' ' )
- ungetc(ch,sfd);
- else { int temp;
- getint(sfd,&temp);
- mm->apple = temp;
- getint(sfd,&mm->named_instance_count);
- }
- mm->instances = calloc(mm->instance_count,sizeof(SplineFont *));
- mm->positions = malloc(mm->instance_count*mm->axis_count*sizeof(real));
- mm->defweights = malloc(mm->instance_count*sizeof(real));
- mm->axismaps = calloc(mm->axis_count,sizeof(struct axismap));
- if ( mm->named_instance_count!=0 )
- mm->named_instances = calloc(mm->named_instance_count,sizeof(struct named_instance));
- } else if ( strmatch(tok,"MMAxis:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL ) {
- for ( i=0; i<mm->axis_count; ++i ) {
- getname(sfd,tok);
- mm->axes[i] = copy(tok);
- }
- }
- } else if ( strmatch(tok,"MMPositions:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL ) {
- for ( i=0; i<mm->axis_count*mm->instance_count; ++i )
- getreal(sfd,&mm->positions[i]);
- }
- } else if ( strmatch(tok,"MMWeights:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL ) {
- for ( i=0; i<mm->instance_count; ++i )
- getreal(sfd,&mm->defweights[i]);
- }
- } else if ( strmatch(tok,"MMAxisMap:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL ) {
- int index, points;
- getint(sfd,&index); getint(sfd,&points);
- mm->axismaps[index].points = points;
- mm->axismaps[index].blends = malloc(points*sizeof(real));
- mm->axismaps[index].designs = malloc(points*sizeof(real));
- for ( i=0; i<points; ++i ) {
- getreal(sfd,&mm->axismaps[index].blends[i]);
- while ( (ch=nlgetc(sfd))!=EOF && isspace(ch));
- ungetc(ch,sfd);
- if ( (ch=nlgetc(sfd))!='=' )
- ungetc(ch,sfd);
- else if ( (ch=nlgetc(sfd))!='>' )
- ungetc(ch,sfd);
- getreal(sfd,&mm->axismaps[index].designs[i]);
- }
- lastaxismap = &mm->axismaps[index];
- lastnamedinstance = NULL;
- }
- } else if ( strmatch(tok,"MMNamedInstance:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL ) {
- int index;
- getint(sfd,&index);
- mm->named_instances[index].coords = malloc(mm->axis_count*sizeof(real));
- for ( i=0; i<mm->axis_count; ++i )
- getreal(sfd,&mm->named_instances[index].coords[i]);
- lastnamedinstance = &mm->named_instances[index];
- lastaxismap = NULL;
- }
- } else if ( strmatch(tok,"MacName:")==0 ) {
- struct macname *names = SFDParseMacNames(sfd,tok);
- if ( lastaxismap!=NULL )
- lastaxismap->axisnames = names;
- else if ( lastnamedinstance !=NULL )
- lastnamedinstance->names = names;
- pushedbacktok = true;
- } else if ( strmatch(tok,"MMCDV:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL )
- mm->cdv = SFDParseMMSubroutine(sfd);
- } else if ( strmatch(tok,"MMNDV:")==0 ) {
- MMSet *mm = sf->mm;
- if ( mm!=NULL )
- mm->ndv = SFDParseMMSubroutine(sfd);
- } else if ( strmatch(tok,"BeginMMFonts:")==0 ) {
- int cnt;
- getint(sfd,&cnt);
- getint(sfd,&realcnt);
- ff_progress_change_stages(cnt);
- ff_progress_change_total(realcnt);
- MMInferStuff(sf->mm);
- break;
- } else if ( strmatch(tok,"BeginSubFonts:")==0 ) {
- getint(sfd,&sf->subfontcnt);
- sf->subfonts = calloc(sf->subfontcnt,sizeof(SplineFont *));
- getint(sfd,&realcnt);
- sf->map = EncMap1to1(realcnt);
- ff_progress_change_stages(2);
- ff_progress_change_total(realcnt);
- break;
- } else if ( strmatch(tok,"BeginChars:")==0 ) {
- int charcnt;
- getint(sfd,&charcnt);
- if (charcnt<enc->char_cnt) {
- IError("SFD file specifies too few slots for its encoding.\n" );
-exit( 1 );
- }
- if ( getint(sfd,&realcnt)!=1 || realcnt==-1 )
- realcnt = charcnt;
- else
- ++realcnt; /* value saved is max glyph, not glyph cnt */
- ff_progress_change_total(realcnt);
- sf->glyphcnt = sf->glyphmax = realcnt;
- sf->glyphs = calloc(realcnt,sizeof(SplineChar *));
- if ( cidmaster!=NULL ) {
- sf->map = cidmaster->map;
- } else {
- sf->map = EncMapNew(charcnt,realcnt,enc);
- sf->map->remap = remap;
- }
- SFDSizeMap(sf->map,sf->glyphcnt,charcnt);
- break;
-#if HANYANG
- } else if ( strmatch(tok,"BeginCompositionRules")==0 ) {
- sf->rules = SFDReadCompositionRules(sfd);
-#endif
- } else {
- /* If we don't understand it, skip it */
- geteol(sfd,tok);
- }
- }
-
- if ( sf->subfontcnt!=0 ) {
- ff_progress_change_stages(2*sf->subfontcnt);
- for ( i=0; i<sf->subfontcnt; ++i ) {
- if ( i!=0 )
- ff_progress_next_stage();
- sf->subfonts[i] = SFD_GetFont(sfd,sf,tok,fromdir,dirname,sfdversion);
- }
- } else if ( sf->mm!=NULL ) {
- MMSet *mm = sf->mm;
- ff_progress_change_stages(2*(mm->instance_count+1));
- for ( i=0; i<mm->instance_count; ++i ) {
- if ( i!=0 )
- ff_progress_next_stage();
- mm->instances[i] = SFD_GetFont(sfd,NULL,tok,fromdir,dirname,sfdversion);
- EncMapFree(mm->instances[i]->map); mm->instances[i]->map=NULL;
- mm->instances[i]->mm = mm;
- }
- ff_progress_next_stage();
- mm->normal = SFD_GetFont(sfd,NULL,tok,fromdir,dirname,sfdversion);
- mm->normal->mm = mm;
- sf->mm = NULL;
- SplineFontFree(sf);
- sf = mm->normal;
- if ( sf->map->enc!=&custom ) {
- EncMap *map;
- MMMatchGlyphs(mm); /* sfd files from before the encoding change can have mismatched orig pos */
- map = EncMapFromEncoding(sf,sf->map->enc);
- EncMapFree(sf->map);
- sf->map = map;
- }
- } else {
- while ( SFDGetChar(sfd,sf,had_layer_cnt)!=NULL ) {
- ff_progress_next();
- }
- ff_progress_next_stage();
- }
- haddupenc = false;
- while ( getname(sfd,tok)==1 ) {
- if ( strcmp(tok,"EndSplineFont")==0 || strcmp(tok,"EndSubSplineFont")==0 )
- break;
- else if ( strmatch(tok,"DupEnc:")==0 ) {
- int enc, orig;
- haddupenc = true;
- if ( getint(sfd,&enc) && getint(sfd,&orig) && sf->map!=NULL ) {
- SFDSetEncMap(sf,orig,enc);
- }
- }
- }
- if ( sf->cidmaster==NULL )
- SFDFixupRefs(sf);
-
- if ( !haddupenc )
- SFD_DoAltUnis(sf);
- else
- AltUniFigure(sf,sf->map,true);
- if ( !d.hadtimes )
- SFTimesFromFile(sf,sfd);
-return( sf );
-}
-
-void SFTimesFromFile(SplineFont *sf,FILE *file) {
- struct stat b;
- if ( fstat(fileno(file),&b)!=-1 ) {
- sf->modificationtime = b.st_mtime;
- sf->creationtime = b.st_mtime;
- }
-}
-
-static double SFDStartsCorrectly(FILE *sfd,char *tok) {
- real dval;
- int ch;
-
- if ( getname(sfd,tok)!=1 )
-return( -1 );
- if ( strcmp(tok,"SplineFontDB:")!=0 )
-return( -1 );
- if ( getreal(sfd,&dval)!=1 )
-return( -1 );
- /* We don't yet generate version 4 of sfd. It will contain backslash */
- /* newline in the middle of very long lines. I've put in code to parse */
- /* this sequence, but I don't yet generate it. I want the parser to */
- /* perculate through to users before I introduce the new format so there */
- /* will be fewer complaints when it happens */
- // MIQ: getreal() can give some funky rounding errors it seems
- if ( dval!=2.0 && dval!=3.0
- && !(dval > 3.09 && dval <= 3.11)
- && dval!=4.0 )
- {
- LogError("Bad SFD Version number %.1f", dval );
-return( -1 );
- }
- ch = nlgetc(sfd); ungetc(ch,sfd);
- if ( ch!='\r' && ch!='\n' )
-return( -1 );
-
-return( dval );
-}
-
-static SplineFont *SFD_Read(char *filename,FILE *sfd, int fromdir) {
- SplineFont *sf=NULL;
- char tok[2000];
- double version;
-
- if ( sfd==NULL ) {
- if ( fromdir ) {
- snprintf(tok,sizeof(tok),"%s/" FONT_PROPS, filename );
- sfd = fopen(tok,"r");
- } else
- sfd = fopen(filename,"r");
- }
- if ( sfd==NULL )
-return( NULL );
- ff_locale_t tmplocale, oldlocale; // Declare temporary locale storage.
- switch_to_c_locale(&tmplocale, &oldlocale); // Switch to the C locale temporarily and cache the old locale.
- ff_progress_change_stages(2);
- if ( (version = SFDStartsCorrectly(sfd,tok))!=-1 )
- sf = SFD_GetFont(sfd,NULL,tok,fromdir,filename,version);
- switch_to_old_locale(&tmplocale, &oldlocale); // Switch to the cached locale.
- if ( sf!=NULL ) {
- sf->filename = copy(filename);
- if ( sf->mm!=NULL ) {
- int i;
- for ( i=0; i<sf->mm->instance_count; ++i )
- sf->mm->instances[i]->filename = copy(filename);
- }
- }
- fclose(sfd);
-return( sf );
-}
-
-SplineFont *SFDRead(char *filename) {
-return( SFD_Read(filename,NULL,false));
-}