diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c new file mode 100644 index 00000000000..4607ee38819 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesaveafm.c @@ -0,0 +1,261 @@ +/* Copyright (C) 2000-2008 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 "fontforgevw.h" /* For Error */ +#include <stdio.h> +#include "splinefont.h" +#include <utype.h> +#include <ustring.h> +#include <time.h> +#include <math.h> + +#include <sys/types.h> /* For stat */ +#include <sys/stat.h> +#include <unistd.h> + +#ifdef __CygWin + #include <sys/types.h> + #include <sys/stat.h> + #include <unistd.h> +#endif + +static void *mygets(FILE *file,char *buffer,int size) { + char *end = buffer+size-1; + char *pt = buffer; + int ch; + + while ( (ch=getc(file))!=EOF && ch!='\r' && ch!='\n' && pt<end ) + *pt++ = ch; + *pt = '\0'; + if ( ch==EOF && pt==buffer ) +return( NULL ); + if ( ch=='\r' ) { + ch = getc(file); + if ( ch!='\n' ) + ungetc(ch,file); + } +return( buffer ); +} + +/* ************************************************************************** */ +/* **************************** Reading AFM files *************************** */ +/* ************************************************************************** */ +static void KPInsert( SplineChar *sc1, SplineChar *sc2, int off, int isv ) { + KernPair *kp; + int32 script; + + if ( sc1!=NULL && sc2!=NULL ) { + for ( kp=sc1->kerns; kp!=NULL && kp->sc!=sc2; kp = kp->next ); + if ( kp!=NULL ) + kp->off = off; + else if ( off!=0 ) { + kp = chunkalloc(sizeof(KernPair)); + kp->sc = sc2; + kp->off = off; + script = SCScriptFromUnicode(sc1); + if ( script==DEFAULT_SCRIPT ) + script = SCScriptFromUnicode(sc2); + kp->subtable = SFSubTableFindOrMake(sc1->parent, + isv?CHR('v','k','r','n'):CHR('k','e','r','n'), + script, gpos_pair); + if ( isv ) { + kp->next = sc1->vkerns; + sc1->vkerns = kp; + } else { + kp->next = sc1->kerns; + sc1->kerns = kp; + } + } + } +} + +int LoadKerningDataFromAfm(SplineFont *sf, char *filename,EncMap *map) { + FILE *file = fopen(filename,"r"); + char buffer[200], *pt, *ept, ch; + SplineChar *sc1, *sc2; + int off; + char name[44], second[44], lig[44], buf2[100]; + PST *liga; + double scale = (sf->ascent+sf->descent)/1000.0; + + if ( file==NULL ) +return( 0 ); + ff_progress_change_line2(_("Reading AFM file")); + while ( mygets(file,buffer,sizeof(buffer))!=NULL ) { + if ( strncmp(buffer,"KPX",3)==0 || strncmp(buffer,"KPY",3)==0 ) { + int isv = strncmp(buffer,"KPY",3)==0; + for ( pt=buffer+3; isspace(*pt); ++pt); + for ( ept = pt; *ept!='\0' && !isspace(*ept); ++ept ); + ch = *ept; *ept = '\0'; + sc1 = SFGetChar(sf,-1,pt); + *ept = ch; + for ( pt=ept; isspace(*pt); ++pt); + for ( ept = pt; *ept!='\0' && !isspace(*ept); ++ept ); + ch = *ept; *ept = '\0'; + sc2 = SFGetChar(sf,-1,pt); + *ept = ch; + off = strtol(ept,NULL,10); + KPInsert(sc1,sc2,rint(off*scale),isv); + } else if ( buffer[0]=='C' && isspace(buffer[1])) { + char *pt; + sc2 = NULL; + for ( pt= strchr(buffer,';'); pt!=NULL; pt=strchr(pt+1,';') ) { + if ( sscanf( pt, "; N %40s", name )==1 ) + sc2 = SFGetChar(sf,-1,name); + else if ( sc2!=NULL && + sscanf( pt, "; L %40s %40s", second, lig)==2 ) { + sc1 = SFGetChar(sf,-1,lig); + if ( sc1!=NULL ) { + sprintf( buf2, "%s %s", name, second); + for ( liga=sc1->possub; liga!=NULL; liga=liga->next ) { + if ( liga->type == pst_ligature && strcmp(liga->u.lig.components,buf2)==0 ) + break; + } + if ( liga==NULL ) { + liga = chunkalloc(sizeof(PST)); + liga->subtable = SFSubTableFindOrMake(sf, + CHR('l','i','g','a'),SCScriptFromUnicode(sc2), + gsub_ligature); + liga->subtable->lookup->store_in_afm = true; + liga->type = pst_ligature; + liga->next = sc1->possub; + sc1->possub = liga; + liga->u.lig.lig = sc1; + liga->u.lig.components = copy( buf2 ); + } + } + } + } + } + } + fclose(file); +return( 1 ); +} + +static void CheckMMAfmFile(SplineFont *sf,char *amfm_filename,char *fontname,EncMap *map) { + /* the afm file should be in the same directory as the amfm file */ + /* with the fontname as the filename */ + char *temp, *pt; + + free(sf->fontname); + sf->fontname = copy(fontname); + + temp = galloc(strlen(amfm_filename)+strlen(fontname)+strlen(".afm")+1); + strcpy(temp, amfm_filename); + pt = strrchr(temp,'/'); + if ( pt==NULL ) pt = temp; + else ++pt; + strcpy(pt,fontname); + pt += strlen(pt); + strcpy(pt,".afm"); + if ( !LoadKerningDataFromAfm(sf,temp,map) ) { + strcpy(pt,".AFM"); + LoadKerningDataFromAfm(sf,temp,map); + } + free(temp); +} + +int LoadKerningDataFromAmfm(SplineFont *sf, char *filename,EncMap *map) { + FILE *file=NULL; + char buffer[280], *pt, lastname[257]; + int index, i; + MMSet *mm = sf->mm; + + if ( mm!=NULL ) + file = fopen(filename,"r"); + pt = strstrmatch(filename,".amfm"); + if ( pt!=NULL ) { + char *afmname = copy(filename); + strcpy(afmname+(pt-filename),isupper(pt[1])?".AFM":".afm"); + LoadKerningDataFromAfm(mm->normal,afmname,map); + free(afmname); + } + if ( file==NULL ) +return( 0 ); + + ff_progress_change_line2(_("Reading AFM file")); + while ( fgets(buffer,sizeof(buffer),file)!=NULL ) { + if ( strstrmatch(buffer,"StartMaster")!=NULL ) + break; + } + index = -1; lastname[0] = '\0'; + while ( fgets(buffer,sizeof(buffer),file)!=NULL ) { + if ( strstrmatch(buffer,"EndMaster")!=NULL ) { + if ( lastname[0]!='\0' && index!=-1 && index<mm->instance_count ) + CheckMMAfmFile(mm->instances[index],filename,lastname,map); + index = -1; lastname[0] = '\0'; + } else if ( sscanf(buffer,"FontName %256s", lastname )== 1 ) { + /* Do Nothing, all done */ + } else if ( (pt = strstr(buffer,"WeightVector"))!=NULL ) { + pt += strlen("WeightVector"); + while ( *pt==' ' || *pt=='[' ) ++pt; + i = 0; + while ( *pt!=']' && *pt!='\0' ) { + if ( *pt=='0' ) + ++i; + else if ( *pt=='1' ) { + index = i; + break; + } + ++pt; + } + } + } + fclose(file); +return( true ); +} + +int CheckAfmOfPostscript(SplineFont *sf,char *psname, EncMap *map) { + char *new, *pt; + int ret; + int wasuc=false; + + new = galloc(strlen(psname)+6); + strcpy(new,psname); + pt = strrchr(new,'.'); + if ( pt==NULL ) pt = new+strlen(new); + else wasuc = isupper(pt[1]); + + if ( sf->mm!=NULL ) { + strcpy(pt,wasuc?".AMFM":".amfm"); + if ( !LoadKerningDataFromAmfm(sf,new,map)) { + strcpy(pt,wasuc?".amfm":".AMFM"); + ret = LoadKerningDataFromAmfm(sf,new,map); + } else + ret = true; + /* The above routine reads from the afm file if one exist */ + } else { + strcpy(pt,wasuc?".AFM":".afm"); + if ( !LoadKerningDataFromAfm(sf,new,map)) { + strcpy(pt,wasuc?".afm":".AFM"); + ret = LoadKerningDataFromAfm(sf,new,map); + } else + ret = true; + } + free(new); +return( ret ); +} + |