diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c | 820 |
1 files changed, 0 insertions, 820 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c deleted file mode 100644 index 436ab39f428..00000000000 --- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c +++ /dev/null @@ -1,820 +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 "ttf.h" -#include <math.h> - -static int PtNumbersAreSet(SplineChar *sc) { - struct splinecharlist *dep; - - if ( sc==NULL ) -return( false ); - - if ( sc->ttf_instrs!=NULL ) -return( true ); - for ( dep= sc->dependents; dep!=NULL ; dep=dep->next ) - if ( dep->sc->ttf_instrs!=NULL ) -return( true ); - -return( false ); -} - -static int AssignPtNumbers(MMSet *mm,int gid) { - /* None of the instances has fixed point numbers. Make them match */ - int cnt=0; - SplineSet **ss; - SplinePoint **sp; - int i; - int allavg, alllines, stillmore, ret=true; - - ss = malloc((mm->instance_count+1)*sizeof(SplineSet *)); - sp = malloc((mm->instance_count+1)*sizeof(SplinePoint *)); - for ( i=0; i<mm->instance_count; ++i ) - ss[i] = mm->instances[i]->glyphs[gid]->layers[ly_fore].splines; - ss[i] = mm->normal->glyphs[gid]->layers[ly_fore].splines; - - if ( ss[0]==NULL ) { - stillmore = false; - for ( i=0; i<=mm->instance_count; ++i ) - if ( ss[i]!=NULL ) stillmore = true; - free(ss); - free(sp); - if ( stillmore ) -return( false ); -return( true ); - } else { - stillmore = true; - for ( i=0; i<=mm->instance_count; ++i ) - if ( ss[i]==NULL ) stillmore = false; - if ( !stillmore ) -{ -free(ss); -free(sp); -return( false ); -} - } - - for (;;) { - for ( i=0; i<=mm->instance_count; ++i ) - sp[i] = ss[i]->first; - for (;;) { - allavg = alllines = true; - for ( i=0; i<=mm->instance_count; ++i ) { - if ( !RealNear(sp[i]->me.x,(sp[i]->nextcp.x+sp[i]->prevcp.x)/2) || - !RealNear(sp[i]->me.y,(sp[i]->nextcp.y+sp[i]->prevcp.y)/2) ) - allavg = false; - if ( !sp[i]->nonextcp ) - alllines = false; - } - if ( sp[0] == ss[0]->first ) - allavg = false; - for ( i=0; i<=mm->instance_count; ++i ) { - if ( allavg ) - sp[i]->ttfindex = 0xffff; - else - sp[i]->ttfindex = cnt; - } - if ( !allavg ) - ++cnt; - for ( i=0; i<=mm->instance_count; ++i ) { - if ( alllines ) - sp[i]->nextcpindex = 0xffff; - else - sp[i]->nextcpindex = cnt; - } - if ( !alllines ) - ++cnt; - - if ( sp[0]->next==NULL ) { - stillmore = false; - for ( i=1; i<=mm->instance_count; ++i ) - if ( sp[i]->next!=NULL ) - stillmore = true; - if ( stillmore ) - ret = false; - break; - } - for ( i=1; i<=mm->instance_count; ++i ) - if ( sp[i]->next==NULL ) - stillmore = false; - if ( !stillmore ) { - ret = false; - break; - } - sp[0] = sp[0]->next->to; - for ( i=1; i<=mm->instance_count; ++i ) - sp[i] = sp[i]->next->to; - if ( sp[0]==ss[0]->first ) { - stillmore = false; - for ( i=1; i<=mm->instance_count; ++i ) - if ( sp[i]!=ss[i]->first ) - stillmore = true; - if ( stillmore ) - ret = false; - break; - } - for ( i=1; i<=mm->instance_count; ++i ) { - if ( sp[i]==ss[i]->first ) - stillmore = false; - } - if ( !stillmore ) { - ret = false; - break; - } - } - if ( !ret ) - break; - stillmore = true; - for ( i=0; i<=mm->instance_count; ++i ) - ss[i] = ss[i]->next; - if ( ss[0]==NULL ) { - stillmore=false; - for ( i=1; i<=mm->instance_count; ++i ) - if ( ss[i]!=NULL ) - stillmore = true; - if ( stillmore ) - ret = true; - break; - } - for ( i=1; i<=mm->instance_count; ++i ) - if ( ss[i]==NULL ) - stillmore = false; - if ( !stillmore ) { - ret = true; - break; - } - } - free(ss); - free(sp); -return( ret ); -} - -static int MatchPoints(SplineFont *sffixed, SplineFont *sfother, int gid) { - SplineChar *fixed, *other; - SplineSet *ss1, *ss2; - SplinePoint *sp1, *sp2; - - fixed = sffixed->glyphs[gid]; other = sfother->glyphs[gid]; - - if ( PtNumbersAreSet(other)) { - /* Point numbers must match exactly, both are fixed */ - for ( ss1=fixed->layers[ly_fore].splines, - ss2=other->layers[ly_fore].splines; - ss1!=NULL && ss2!=NULL ; - ss1 = ss1->next, ss2=ss2->next ) { - for ( sp1=ss1->first, sp2=ss2->first; ; ) { - if ( sp1->ttfindex!=sp2->ttfindex || - sp1->nextcpindex!=sp2->nextcpindex ) -return( false ); - if ( sp1->next==NULL || sp2->next==NULL ) { - if ( sp1->next!=NULL || sp2->next!=NULL ) -return( false ); - break; - } - sp1 = sp1->next->to; sp2=sp2->next->to; - if ( sp1==ss1->first || sp2==ss2->first ) { - if ( sp1!=ss1->first || sp2!=ss2->first ) -return( false ); - break; - } - } - } -return( ss1==NULL && ss2==NULL ); - } else { - for ( ss1=fixed->layers[ly_fore].splines, - ss2=other->layers[ly_fore].splines; - ss1!=NULL && ss2!=NULL ; - ss1 = ss1->next, ss2=ss2->next ) { - for ( sp1=ss1->first, sp2=ss2->first; ; ) { - if ( sp1->ttfindex!=0xffff ) - sp2->ttfindex = sp1->ttfindex; - else if ( !RealNear(sp2->me.x,(sp2->nextcp.x+sp2->prevcp.x)/2) || - !RealNear(sp2->me.y,(sp2->nextcp.y+sp2->prevcp.y)/2) ) -return( false ); - else - sp2->ttfindex = 0xffff; - if ( sp1->nextcpindex!=0xffff ) - sp2->nextcpindex = sp1->nextcpindex; - else if ( !sp2->nonextcp ) -return( false ); - else - sp2->nextcpindex = 0xffff; - if ( sp1->next==NULL || sp2->next==NULL ) { - if ( sp1->next!=NULL || sp2->next!=NULL ) -return( false ); - break; - } - sp1 = sp1->next->to; sp2=sp2->next->to; - if ( sp1==ss1->first || sp2==ss2->first ) { - if ( sp1!=ss1->first || sp2!=ss2->first ) -return( false ); - break; - } - } - } -return( ss1==NULL && ss2==NULL ); - } -} - -int ContourPtNumMatch(MMSet *mm, int gid) { - SplineFont *sf; - int i; - - if ( !mm->apple ) -return( false ); - - if ( gid>=mm->normal->glyphcnt ) -return( false ); - if ( !SCWorthOutputting(mm->normal->glyphs[gid] ) ) { - for ( i=0; i<mm->instance_count; ++i ) { - if ( gid>=mm->instances[i]->glyphcnt ) -return( false ); - if ( SCWorthOutputting(mm->instances[i]->glyphs[gid])) -return( false ); - } -return( true ); /* None is not worth outputting, and that's ok, they match */ - } else { - for ( i=0; i<mm->instance_count; ++i ) { - if ( gid>=mm->instances[i]->glyphcnt ) -return( false ); - if ( !SCWorthOutputting(mm->instances[i]->glyphs[gid])) -return( false ); - } - /* All are worth outputting */ - } - - if ( mm->normal->glyphs[gid]->layers[ly_fore].refs!=NULL && mm->normal->glyphs[gid]->layers[ly_fore].splines!=NULL ) -return( false ); - for ( i=0; i<mm->instance_count; ++i ) { - if ( mm->instances[i]->glyphs[gid]->layers[ly_fore].refs!=NULL && mm->instances[i]->glyphs[gid]->layers[ly_fore].splines!=NULL ) -return( false ); - } - if ( mm->normal->glyphs[gid]->layers[ly_fore].refs!=NULL ) { - RefChar *r; - int cnt, c; - for ( r=mm->normal->glyphs[gid]->layers[ly_fore].refs, cnt=0; r!=NULL; r=r->next ) - ++cnt; - for ( i=0; i<mm->instance_count; ++i ) { - for ( r=mm->instances[i]->glyphs[gid]->layers[ly_fore].refs, c=0; r!=NULL; r=r->next ) - ++c; - if ( c!=cnt ) -return( false ); - } - } - - sf = NULL; - if ( PtNumbersAreSet(mm->normal->glyphs[gid]) ) - sf = mm->normal; - else { - for ( i=0; i<mm->instance_count; ++i ) { - if ( PtNumbersAreSet(mm->instances[i]->glyphs[gid])) { - sf = mm->instances[i]; - break; - } - } - } - if ( sf==NULL ) - /* No instance has fixed points. Make sure all fonts are consistent */ -return( AssignPtNumbers(mm,gid)); - - if ( sf!=mm->normal && !MatchPoints(sf,mm->normal,gid)) -return( false ); - for ( i=0; i<mm->instance_count; ++i ) if ( sf!=mm->instances[i] ) { - if ( !MatchPoints(sf, mm->instances[i],gid) ) -return( false ); - } -return( true ); -} - -static int SCPointCount(SplineChar *sc) { - int ptcnt=0; - RefChar *r; - - ptcnt = SSTtfNumberPoints(sc->layers[ly_fore].splines); - for ( r=sc->layers[ly_fore].refs; r!=NULL ; r=r->next ) - ++ptcnt; -return( ptcnt ); -} - -int16 **SCFindDeltas(MMSet *mm, int gid, int *_ptcnt) { - /* When figuring out the deltas the first thing we must do is figure */ - /* out each point's number */ - int i, j, k, l, cnt, ptcnt; - int16 **deltas; - SplineSet *ss1, *ss2; - SplinePoint *sp1, *sp2; - RefChar *r1, *r2; - - if ( !ContourPtNumMatch(mm,gid)) -return( NULL ); - if ( !SCWorthOutputting(mm->normal->glyphs[gid])) -return( NULL ); - - *_ptcnt = ptcnt = SCPointCount(mm->normal->glyphs[gid])+4; - deltas = malloc(2*mm->instance_count*sizeof(int16 *)); - for ( i=0; i<2*mm->instance_count; ++i ) - deltas[i] = calloc(ptcnt,sizeof(int16)); - for ( i=0; i<mm->instance_count; ++i ) { - for ( ss1=mm->normal->glyphs[gid]->layers[ly_fore].splines, - ss2=mm->instances[i]->glyphs[gid]->layers[ly_fore].splines; - ss1!=NULL && ss2!=NULL ; - ss1 = ss1->next, ss2=ss2->next ) { - for ( sp1=ss1->first, sp2=ss2->first; ; ) { - if ( sp1->ttfindex!=0xffff ) { - deltas[2*i][sp1->ttfindex] = rint(sp2->me.x)-rint(sp1->me.x); - deltas[2*i+1][sp1->ttfindex] = rint(sp2->me.y)-rint(sp1->me.y); - } - if ( sp1->nextcpindex != 0xffff ) { - deltas[2*i][sp1->nextcpindex] = rint(sp2->nextcp.x)-rint(sp1->nextcp.x); - deltas[2*i+1][sp1->nextcpindex] = rint(sp2->nextcp.y)-rint(sp1->nextcp.y); - } - if ( sp1->next==NULL ) - break; - sp1 = sp1->next->to; sp2 = sp2->next->to; - if ( sp1==ss1->first ) - break; - } - } - for ( cnt=0, - r1=mm->normal->glyphs[gid]->layers[ly_fore].refs, - r2=mm->instances[i]->glyphs[gid]->layers[ly_fore].refs; - r1!=NULL && r2!=NULL; - r1=r1->next, r2=r2->next, ++cnt ) { - deltas[2*i][cnt] = r2->transform[4]-r1->transform[4]; - deltas[2*i+1][cnt] = r2->transform[5]-r1->transform[5]; - } - /* Phantom points */ - deltas[2*i][ptcnt-4] = 0; deltas[2*i+1][ptcnt-4] = 0; /* lbearing */ - deltas[2*i][ptcnt-3] = mm->instances[i]->glyphs[gid]->width -mm->normal->glyphs[gid]->width; - deltas[2*i+1][ptcnt-3] = 0; /* horizontal advance */ - deltas[2*i][ptcnt-2] = 0; deltas[2*i+1][ptcnt-2] = 0; /* top bearing */ - deltas[2*i][ptcnt-1] = 0; /* vertical advance */ - deltas[2*i+1][ptcnt-1] = mm->instances[i]->glyphs[gid]->vwidth -mm->normal->glyphs[gid]->vwidth; /* horizontal advance */ - } - - /* Ok, each delta now contains the difference between the instance[i] points */ - /* and the base points. But that isn't good enough. We must subtract */ - /* [0,1] and [1,0] from [1,1], and then subtract [1,1,0] [1,0,1] [0,1,1] */ - /* from [1,1,1] and so on (also [-1,0] from [-1,1], etc.) */ - for ( j=1; j<mm->axis_count; ++j ) { - for ( i=0; i<mm->instance_count; ++i ) { - for ( k=cnt=0; k<mm->axis_count; ++k ) - if ( mm->positions[i*mm->axis_count+k]!=0 ) - ++cnt; - if ( cnt==j ) { - for ( l = 0; l<mm->instance_count; ++l ) if ( l!=i ) { - for ( k=0; k<mm->axis_count; ++k ) - if ( mm->positions[i*mm->axis_count+k]!=0 && - mm->positions[l*mm->axis_count+k]!=mm->positions[i*mm->axis_count+k]) - break; - if ( k==mm->axis_count ) { - for ( k=0; k<ptcnt; ++k ) { - deltas[2*l][k] -= deltas[2*i][k]; - deltas[2*l+1][k] -= deltas[2*i+1][k]; - } - } - } - } - } - } - - /* If all variants of the glyph are the same, no point in having a gvar */ - /* entry for it */ - for ( i=0 ; i<mm->instance_count; ++i ) { - for ( j=0; j<ptcnt; ++j ) - if ( deltas[i][j]!=0 ) - break; - if ( j!=ptcnt ) - break; - } - if ( i==mm->instance_count ) { - /* All zeros */ - for ( i=0 ; i<mm->instance_count; ++i ) - free(deltas[i]); - free(deltas); -return( NULL ); - } - -return( deltas ); -} - -int16 **CvtFindDeltas(MMSet *mm, int *_ptcnt) { - int i, j, k, l, cnt, ptcnt; - int16 **deltas; - struct ttf_table *cvt, *icvt; - for ( cvt = mm->normal->ttf_tables; cvt!=NULL && cvt->tag!=CHR('c','v','t',' '); cvt=cvt->next ); - - if ( cvt==NULL ) -return( NULL ); - - icvt = NULL; - for ( i=0; i<mm->instance_count; ++i ) - if ( (icvt=mm->instances[i]->ttf_tables)!=NULL ) - break; - if ( icvt==NULL ) /* No other cvt tables => no variation */ -return( NULL ); - - *_ptcnt = ptcnt = cvt->len/2; - deltas = calloc(mm->instance_count,sizeof(int16 *)); - for ( i=0; i<mm->instance_count; ++i ) if ( (icvt=mm->instances[i]->ttf_tables)!=NULL ) { - deltas[i] = calloc(ptcnt,sizeof(int16)); - for ( j=0; j<ptcnt; ++j ) - deltas[i][j] = memushort(icvt->data,icvt->len, sizeof(uint16)*j)- - memushort(cvt->data,cvt->len, sizeof(uint16)*j); - } - - /* Ok, each delta now contains the difference between the instance[i] points */ - /* and the base points. But that isn't good enough. We must subtract */ - /* [0,1] and [1,0] from [1,1], and then subtract [1,1,0] [1,0,1] [0,1,1] */ - /* from [1,1,1] and so on (also [-1,0] from [-1,1], etc.) */ - for ( j=1; j<mm->axis_count; ++j ) { - for ( i=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { - for ( k=cnt=0; k<mm->axis_count; ++k ) - if ( mm->positions[i*mm->axis_count+k]!=0 ) - ++cnt; - if ( cnt==j ) { - for ( l = 0; l<mm->instance_count; ++l ) if ( l!=i && deltas[l]!=NULL ) { - for ( k=0; k<mm->axis_count; ++k ) - if ( mm->positions[i*mm->axis_count+k]!=0 && - mm->positions[l*mm->axis_count+k]!=mm->positions[i*mm->axis_count+k]) - break; - if ( k==mm->axis_count ) { - for ( k=0; k<ptcnt; ++k ) - deltas[l][k] -= deltas[i][k]; - } - } - } - } - } - - /* If all variants of the cvt are the same, no point in having a gvar */ - /* entry for it */ - for ( i=0 ; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { - for ( j=0; j<ptcnt; ++j ) - if ( deltas[i][j]!=0 ) - break; - if ( j==ptcnt ) { - free(deltas[i]); - deltas[i] = NULL; - } - } - for ( i=0 ; i<mm->instance_count; ++i ) - if ( deltas[i]!=NULL ) - break; - if ( i==mm->instance_count ) { - /* All zeros */ - free(deltas); -return( NULL ); - } - -return( deltas ); -} - -static void ttf_dumpcvar(struct alltabs *at, MMSet *mm) { - int16 **deltas; - int ptcnt, cnt, pcnt; - int i,j,rj,big; - int tuple_size; - uint32 start, end; - uint16 *pts; - - deltas = CvtFindDeltas(mm,&ptcnt); - if ( deltas == NULL ) return; - for ( i=cnt=0; i<mm->instance_count; ++i ) - if ( deltas[i]!=NULL ) - ++cnt; - if ( cnt==0 ) { - free(deltas); -return; - } - - tuple_size = 4+2*mm->axis_count; - at->cvar = tmpfile2(); - putlong( at->cvar, 0x00010000 ); /* Format */ - putshort( at->cvar, cnt ); /* Number of instances with cvt tables (tuple count of interesting tuples) */ - putshort( at->cvar, 8+cnt*tuple_size ); /* Offset to data */ - - for ( i=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { - putshort( at->cvar, 0 ); /* tuple data size, figure out later */ - putshort( at->cvar, 0xa000 ); /* tuple coords follow, private points in data */ - for ( j=0; j<mm->axis_count; ++j ) - putshort( at->cvar, rint(16384*mm->positions[i*mm->axis_count+j]) ); - } - if ( ftell( at->cvar )!=8+cnt*tuple_size ) - IError( "Data offset wrong" ); - - for ( i=cnt=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { - start = ftell(at->cvar); - for ( j=pcnt=0; j<ptcnt; ++j ) - if ( deltas[i][j]!=0 ) - ++pcnt; - pts = malloc(pcnt*sizeof(uint16)); - for ( j=pcnt=0; j<ptcnt; ++j ) - if ( deltas[i][j]!=0 ) - pts[pcnt++]=j; - - if ( pcnt>0x7f ) { - putc(0x80|(pcnt>>8), at->cvar ); - putc(pcnt&0xff, at->cvar); - } else - putc(pcnt, at->cvar); - for ( j=0; j<pcnt; ) { - big = pts[j]>=0x80 ? 0x80 : 0; - for ( rj=j+1 ; rj<j+0x80 && rj<pcnt && !big; ++rj ) - if ( pts[rj]-pts[rj-1]>=0x80 ) - big = 0x80; - - putc((rj-j-1)|big,at->cvar); - if ( big ) { - putshort(at->cvar,pts[j]); - for ( ++j; j<rj; ++j ) - putshort(at->cvar,pts[j]-pts[j-1]); - } else { - putc(pts[j],at->cvar); - for ( ++j; j<rj; ++j ) - putc(pts[j]-pts[j-1],at->cvar); - } - } - /* Now output the corresponding deltas for those points */ - for ( j=0; j<pcnt; ) { - if ( deltas[i][j]>0x7f || deltas[i][j]<0x80 ) { - for ( rj=j+1; rj<j+0x40 && rj<pcnt; ++rj ) { - if ( deltas[i][pts[rj]]>0x7f || deltas[i][pts[rj]]<0x80 || - (rj+1<j+0x40 && rj+1<pcnt && (deltas[i][pts[rj+1]]>0x7f || deltas[i][pts[rj+1]]<0x80)) ) - /* Keep going with a big run */; - else - break; - } - putc( (rj-j-1)|0x40,at->cvar ); - for ( ; j<rj ; ++j ) - putshort( at->cvar, deltas[i][pts[j]] ); - } else { - for ( rj=j+1; rj<j+0x40 && rj<pcnt; ++rj ) { - if ( deltas[i][pts[rj]]>0x7f || deltas[i][pts[rj]]<0x80 ) - break; - } - putc( rj-j-1,at->cvar ); - for ( ; j<rj ; ++j ) - putc( deltas[i][pts[j]], at->cvar ); - } - } - free(pts); - end = ftell(at->cvar); - fseek(at->cvar, 8+cnt*tuple_size, SEEK_SET); - putshort(at->cvar,end-start); - fseek(at->cvar, end, SEEK_SET); - ++cnt; - } - - for ( i=0; i<mm->instance_count; ++i ) - free( deltas[i] ); - free(deltas); - - at->cvarlen = ftell(at->cvar); - if ( at->cvarlen&1 ) - putc('\0',at->cvar ); - if ( ftell(at->cvar)&2 ) - putshort(at->cvar,0); -} - -static void dumpdeltas(struct alltabs *at,int16 *deltas,int ptcnt) { - int j,rj; - - for ( j=0; j<ptcnt; ) { - for ( rj=j; rj<ptcnt && rj<j+0x40 && deltas[rj]==0; ++rj ); - if ( rj!=j ) { - putc((rj-j-1)|0x80,at->gvar); - j = rj; - continue; - } - if ( deltas[j]>0x7f || deltas[j]<0x80 ) { - for ( rj=j+1; rj<j+0x40 && rj<ptcnt; ++rj ) { - if ( deltas[rj]>0x7f || deltas[rj]<0x80 || - (rj+1<j+0x40 && rj+1<ptcnt && (deltas[rj+1]>0x7f || deltas[rj+1]<0x80)) ) - /* Keep going with a big run */; - else - break; - } - putc( (rj-j-1)|0x40,at->gvar ); - for ( ; j<rj ; ++j ) - putshort( at->gvar, deltas[j] ); - } else { - for ( rj=j+1; rj<j+0x40 && rj<ptcnt; ++rj ) { - if ( deltas[rj]>0x7f || deltas[rj]<0x80 || - (deltas[rj]==0 && rj+1<j+0x40 && rj+1<ptcnt && - deltas[rj+1]<=0x7f && deltas[rj+1]>=0x80 && deltas[rj+1]!=0 )) - break; - } - putc( rj-j-1,at->gvar ); - for ( ; j<rj ; ++j ) - putc( deltas[j], at->gvar ); - } - } -} - -static void ttf_dumpgvar(struct alltabs *at, MMSet *mm) { - int i,j, last; - uint32 gcoordoff, glyphoffs, start, here, tupledataend, tupledatastart; - int16 **deltas; - int ptcnt; - - at->gvar = tmpfile2(); - putlong( at->gvar, 0x00010000 ); /* Format */ - putshort( at->gvar, mm->axis_count ); - putshort( at->gvar, mm->instance_count ); /* Number of global tuples */ - gcoordoff = ftell(at->gvar); - putlong( at->gvar, 0 ); /* Offset to global tuples, fix later */ - putshort( at->gvar,at->maxp.numGlyphs ); - putshort( at->gvar, 1 ); /* always output 32bit offsets */ - putlong( at->gvar, ftell(at->gvar)+4 + (at->maxp.numGlyphs+1)*4); - glyphoffs = ftell(at->gvar); - for ( i=0; i<=at->maxp.numGlyphs; ++i ) - putlong( at->gvar,0 ); - - start = ftell( at->gvar ); - last = -1; - for ( i=0; i<at->gi.gcnt; ++i ) if ( at->gi.bygid[i]!=-1 ) { - deltas = SCFindDeltas(mm,at->gi.bygid[i],&ptcnt); - if ( deltas==NULL ) - continue; - here = ftell(at->gvar); - fseek(at->gvar,glyphoffs+(last+1)*4,SEEK_SET); - for ( ; last< i; ++last ) - putlong(at->gvar,here-start); - fseek(at->gvar,here,SEEK_SET); - putshort(at->gvar,mm->instance_count); - putshort(at->gvar,4+4*mm->instance_count); /* offset to data */ - for ( j=0; j<mm->instance_count; ++j ) { - putshort(at->gvar,0); /* tuple data size, fix later */ - putshort(at->gvar,0x2000|j); /* private points, tuple i */ - } - for ( j=0; j<mm->instance_count; ++j ) { - tupledatastart = ftell(at->gvar); - putc('\0',at->gvar); /* Point list, all points */ - dumpdeltas(at,deltas[2*j],ptcnt); - dumpdeltas(at,deltas[2*j+1],ptcnt); - tupledataend = ftell(at->gvar); - fseek(at->gvar,here+4+4*j,SEEK_SET); - putshort( at->gvar,tupledataend-tupledatastart); - fseek(at->gvar,tupledataend,SEEK_SET); - free(deltas[2*j]); free(deltas[2*j+1]); - } - free(deltas); - } - here = ftell(at->gvar); - fseek(at->gvar,glyphoffs+(last+1)*4,SEEK_SET); - for ( ; last< at->maxp.numGlyphs; ++last ) - putlong(at->gvar,here-start); - fseek(at->gvar,gcoordoff,SEEK_SET); - putlong(at->gvar,here); - fseek(at->gvar,here,SEEK_SET); - for ( j=0; j<mm->instance_count; ++j ) { - for ( i=0; i<mm->axis_count; ++i ) - putshort(at->gvar,rint(16384*mm->positions[j*mm->axis_count+i])); - } - - at->gvarlen = ftell(at->gvar); - if ( at->gvarlen&1 ) - putc('\0',at->gvar ); - if ( ftell(at->gvar)&2 ) - putshort(at->gvar,0); -} - - -static void ttf_dumpavar(struct alltabs *at, MMSet *mm) { - int i,j; - - for ( i=0; i<mm->axis_count; ++i ) { - if ( mm->axismaps[i].points>3 ) - break; - } - if ( i==mm->axis_count ) /* We only have simple axes */ -return; /* No need for a variation table */ - - at->avar = tmpfile2(); - putlong( at->avar, 0x00010000 ); /* Format */ - putlong( at->avar, mm->axis_count ); - for ( i=0; i<mm->axis_count; ++i ) { - putshort( at->avar, mm->axismaps[i].points ); - for ( j=0; j<mm->axismaps[i].points; ++j ) { - if ( mm->axismaps[i].designs[j]<mm->axismaps[i].def ) - putshort( at->avar, (mm->axismaps[i].designs[j]-mm->axismaps[i].def)*16384/ - (mm->axismaps[i].def-mm->axismaps[i].min)); - else - putshort( at->avar, (mm->axismaps[i].designs[j]-mm->axismaps[i].def)*16384/ - (mm->axismaps[i].max-mm->axismaps[i].def)); - putshort( at->avar, mm->axismaps[i].blends[j]*16384); - } - } - - at->avarlen = ftell(at->avar); - if ( at->avarlen&2 ) - putshort(at->avar,0); -} - -static uint32 AxisNameToTag(char *name) { - char buf[4]; - int i; - - if ( strmatch(name,"Weight")==0 ) -return( CHR('w','g','h','t')); - if ( strmatch(name,"Width")==0 ) -return( CHR('w','d','t','h')); - if ( strmatch(name,"OpticalSize")==0 ) -return( CHR('o','p','s','z')); - if ( strmatch(name,"Slant")==0 ) -return( CHR('s','l','n','t')); - - memset(buf,0,sizeof(buf)); - for ( i=0; i<4 && name[i]!='\0'; ++i ) - buf[i] = name[i]; -return( CHR(buf[0],buf[1],buf[2],buf[3])); -} - -static int AllocateStrId(struct alltabs *at,struct macname *mn) { - struct other_names *on; - - if ( mn==NULL ) -return( 0 ); - - on = chunkalloc(sizeof(struct other_names)); - on->strid = at->next_strid++; - on->mn = mn; - on->next = at->other_names; - at->other_names = on; -return( on->strid ); -} - -static void ttf_dumpfvar(struct alltabs *at, MMSet *mm) { - int i,j; - - at->fvar = tmpfile2(); - putlong( at->fvar, 0x00010000 ); /* Format */ - putshort( at->fvar, 16 ); /* Offset to first axis data */ - putshort( at->fvar, 2 ); /* Size count pairs */ - putshort( at->fvar, mm->axis_count ); - putshort( at->fvar, 20 ); /* Size of each axis record */ - putshort( at->fvar, mm->named_instance_count ); - putshort( at->fvar, 4+4*mm->axis_count ); - - /* For each axis ... */ - for ( i=0; i<mm->axis_count; ++i ) { - putlong( at->fvar, AxisNameToTag(mm->axes[i]) ); - putlong( at->fvar, rint(mm->axismaps[i].min*65536)); - putlong( at->fvar, rint(mm->axismaps[i].def*65536)); - putlong( at->fvar, rint(mm->axismaps[i].max*65536)); - putshort(at->fvar, 0 ); /* No flags defined for axes */ - putshort(at->fvar, AllocateStrId(at,mm->axismaps[i].axisnames)); - } - - /* For each named font ... */ - for ( i=0; i<mm->named_instance_count; ++i ) { - putshort(at->fvar, AllocateStrId(at,mm->named_instances[i].names)); - putshort(at->fvar, 0 ); /* No flags here either */ - for ( j=0; j<mm->axis_count; ++j ) - putlong(at->fvar, rint(65536*mm->named_instances[i].coords[j])); - } - - at->fvarlen = ftell(at->fvar); - if ( at->fvarlen&2 ) /* I don't think this is ever hit */ - putshort(at->fvar,0); -} - -void ttf_dumpvariations(struct alltabs *at, SplineFont *sf) { - MMSet *mm = sf->mm; - int i,j; - - for ( j=0; j<sf->glyphcnt; ++j ) if ( sf->glyphs[j]!=NULL ) { - for ( i=0; i<mm->instance_count; ++i ) if ( mm->instances[i]->glyphs[j]!=NULL ) - mm->instances[i]->glyphs[j]->ttf_glyph = sf->glyphs[j]->ttf_glyph; - } - - ttf_dumpfvar(at,mm); - ttf_dumpgvar(at,mm); - ttf_dumpcvar(at,mm); - ttf_dumpavar(at,mm); -} |