summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/tottfvar.c
diff options
context:
space:
mode:
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.c820
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);
-}