summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c2095
1 files changed, 0 insertions, 2095 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c b/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c
deleted file mode 100644
index 24bd2d5e05c..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/ff-woff/fontforge/ttfspecial.c
+++ /dev/null
@@ -1,2095 +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 <math.h>
-#include <gimage.h> /* For COLOR_DEFAULT */
-
-#include "ttf.h"
-
-/* This file contains routines to generate non-standard true/opentype tables */
-/* The first is the 'PfEd' table containing PfaEdit specific information */
-/* glyph comments & colours ... perhaps other info later */
-
-/* ************************************************************************** */
-/* ************************* The 'PfEd' table ************************* */
-/* ************************* Output ************************* */
-/* ************************************************************************** */
-
-#include "PfEd.h" /* This describes the format of the 'PfEd' table */
- /* and its many subtables. */
-
-#define MAX_SUBTABLE_TYPES 20
-
-struct PfEd_subtabs {
- int next;
- struct {
- FILE *data;
- uint32 tag;
- uint32 offset;
- } subtabs[MAX_SUBTABLE_TYPES];
-};
-
-static void PfEd_FontComment(SplineFont *sf, struct PfEd_subtabs *pfed, uint32 tag ) {
- FILE *fcmt;
- char *pt;
- char *text = tag==fcmt_TAG ? sf->comments : sf->fontlog;
-
- if ( text==NULL || *text=='\0' )
-return;
- pfed->subtabs[pfed->next].tag = tag;
- pfed->subtabs[pfed->next++].data = fcmt = tmpfile2();
-
- putshort(fcmt,1); /* sub-table version number */
- putshort(fcmt,strlen(text));
- for ( pt = text; *pt; ++pt )
- putc(*pt,fcmt);
- putshort(fcmt,0);
- if ( ftell(fcmt)&1 ) putc(0,fcmt);
- if ( ftell(fcmt)&2 ) putshort(fcmt,0);
-}
-
-static void PfEd_GlyphComments(SplineFont *sf, struct PfEd_subtabs *pfed,
- struct glyphinfo *gi ) {
- int i, j, k, any, cnt, last, skipped;
- uint32 offset;
- SplineChar *sc, *sc2;
- FILE *cmnt;
-
- any = 0;
- /* We don't need to check in bygid order. We just want to know existance */
- for ( i=0; i<sf->glyphcnt; ++i ) {
- if ( sf->glyphs[i]!=NULL && sf->glyphs[i]->ttf_glyph!=-1 &&
- sf->glyphs[i]->comment!=NULL ) {
- any = true;
- break;
- }
- }
-
- if ( !any )
-return;
-
- pfed->subtabs[pfed->next].tag = cmnt_TAG;
- pfed->subtabs[pfed->next++].data = cmnt = tmpfile2();
-
- putshort(cmnt,1); /* sub-table version number */
- /* Version 0 used ucs2, version 1 uses utf8 */
-
- offset = 0;
- for ( j=0; j<4; ++j ) {
- cnt = 0;
- for ( i=0; i<gi->gcnt; ++i ) if ( gi->bygid[i]!=-1 ) {
- sc=sf->glyphs[gi->bygid[i]];
- if ( sc!=NULL && sc->comment!=NULL ) {
- last = i; skipped = false;
- for ( k=i+1; k<gi->gcnt; ++k ) {
- if ( gi->bygid[k]!=-1 )
- sc2 = sf->glyphs[gi->bygid[k]];
- if ( (gi->bygid[k]==-1 || sc2->comment==NULL) && skipped )
- break;
- if ( gi->bygid[k]!=-1 && sc2->comment!=NULL ) {
- last = k;
- skipped = false;
- } else
- skipped = true;
- }
- ++cnt;
- if ( j==1 ) {
- putshort(cmnt,i);
- putshort(cmnt,last);
- putlong(cmnt,offset);
- offset += sizeof(uint32)*(last-i+2);
- } else if ( j==2 ) {
- for ( ; i<=last; ++i ) {
- if ( gi->bygid[i]==-1 || (sc=sf->glyphs[gi->bygid[i]])->comment==NULL )
- putlong(cmnt,0);
- else {
- putlong(cmnt,offset);
- offset += strlen(sc->comment)+1;
- }
- }
- putlong(cmnt,offset); /* Guard data, to let us calculate the string lengths */
- } else if ( j==3 ) {
- for ( ; i<=last; ++i ) {
- if ( gi->bygid[i]==-1 || (sc=sf->glyphs[gi->bygid[i]])->comment==NULL )
- continue;
- fputs(sc->comment,cmnt);
- putc('\0',cmnt);
- }
- }
- i = last;
- }
- }
- if ( j==0 ) {
- putshort(cmnt,cnt);
- offset = 2*sizeof(short) + cnt*(2*sizeof(short)+sizeof(uint32));
- }
- }
- if ( ftell(cmnt) & 1 )
- putc('\0',cmnt);
- if ( ftell(cmnt) & 2 )
- putshort(cmnt,0);
-}
-
-static void PfEd_CvtComments(SplineFont *sf, struct PfEd_subtabs *pfed ) {
- FILE *cvtcmt;
- int i, offset;
-
- if ( sf->cvt_names==NULL )
-return;
- pfed->subtabs[pfed->next].tag = cvtc_TAG;
- pfed->subtabs[pfed->next++].data = cvtcmt = tmpfile2();
-
- for ( i=0; sf->cvt_names[i]!=END_CVT_NAMES; ++i);
-
- putshort(cvtcmt,0); /* sub-table version number */
- putshort(cvtcmt,i);
- offset = 2*2 + i*2;
- for ( i=0; sf->cvt_names[i]!=END_CVT_NAMES; ++i) {
- if ( sf->cvt_names[i]==NULL )
- putshort(cvtcmt,0);
- else {
- putshort(cvtcmt,offset);
- offset += strlen(sf->cvt_names[i])+1;
- }
- }
- for ( i=0; sf->cvt_names[i]!=END_CVT_NAMES; ++i) {
- if ( sf->cvt_names[i]!=NULL ) {
- fputs(sf->cvt_names[i],cvtcmt);
- putc('\0',cvtcmt);
- }
- }
- if ( ftell(cvtcmt)&1 ) putc(0,cvtcmt);
- if ( ftell(cvtcmt)&2 ) putshort(cvtcmt,0);
-}
-
-static void PfEd_Colours(SplineFont *sf, struct PfEd_subtabs *pfed, struct glyphinfo *gi ) {
- int i, j, k, any, cnt, last;
- SplineChar *sc, *sc2;
- FILE *colr;
-
- any = 0;
- for ( i=0; i<sf->glyphcnt; ++i ) {
- if ( sf->glyphs[i]!=NULL && sf->glyphs[i]->ttf_glyph!=-1 &&
- sf->glyphs[i]->color!=COLOR_DEFAULT ) {
- any = true;
- break;
- }
- }
-
- if ( !any )
-return;
-
- pfed->subtabs[pfed->next].tag = colr_TAG;
- pfed->subtabs[pfed->next++].data = colr = tmpfile2();
-
- putshort(colr,0); /* sub-table version number */
- for ( j=0; j<2; ++j ) {
- cnt = 0;
- for ( i=0; i<gi->gcnt; ++i ) if ( gi->bygid[i]!=-1 ) {
- sc = sf->glyphs[gi->bygid[i]];
- if ( sc!=NULL && sc->color!=COLOR_DEFAULT ) {
- last = i;
- for ( k=i+1; k<gi->gcnt; ++k ) {
- if ( gi->bygid[k]==-1 )
- break;
- sc2 = sf->glyphs[gi->bygid[k]];
- if ( sc2->color != sc->color )
- break;
- last = k;
- }
- ++cnt;
- if ( j==1 ) {
- putshort(colr,i);
- putshort(colr,last);
- putlong(colr,sc->color);
- }
- i = last;
- }
- }
- if ( j==0 )
- putshort(colr,cnt);
- }
- if ( ftell(colr) & 2 )
- putshort(colr,0);
-}
-
-static void PfEd_Lookups(SplineFont *sf, struct PfEd_subtabs *pfed,
- OTLookup *lookups, uint32 tag) {
- OTLookup *otl;
- int lcnt, scnt, ascnt, acnt, s, a;
- FILE *lkf;
- struct lookup_subtable *subs;
- AnchorClass *ac;
- int sub_info, ac_info, name_info;
-
- if ( lookups==NULL )
-return;
- for ( otl=lookups, lcnt=scnt=acnt=ascnt=0; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- ++lcnt;
- for ( subs = otl->subtables; subs!=NULL; subs=subs->next ) if ( !subs->unused ) {
- ++scnt;
- if ( subs->anchor_classes ) {
- ++ascnt;
- for ( ac=sf->anchor; ac!=NULL; ac=ac->next )
- if ( ac->subtable==subs && ac->has_base && ac->has_mark )
- ++acnt;
- }
- }
- }
-
- pfed->subtabs[pfed->next].tag = tag;
- pfed->subtabs[pfed->next++].data = lkf = tmpfile2();
-
- putshort(lkf,0); /* Subtable version */
- putshort(lkf,lcnt);
-
- sub_info = 4 + 4*lcnt;
- ac_info = sub_info + 2*lcnt + 4*scnt;
- name_info = ac_info + 2*ascnt + 2*acnt;
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- putshort(lkf,name_info);
- name_info += strlen(otl->lookup_name)+1;
- putshort(lkf,sub_info);
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) ++s;
- sub_info += 2 + 4*s;
- }
- if ( sub_info!=ac_info )
- IError("Lookup name data didn't behave as expected");
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) ++s;
- putshort(lkf,s); /* Subtable count */
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) {
- putshort(lkf,name_info);
- name_info += strlen(subs->subtable_name)+1;
- if ( subs->anchor_classes ) {
- putshort(lkf,ac_info);
- for ( ac=sf->anchor, a=0; ac!=NULL; ac=ac->next )
- if ( ac->subtable==subs && ac->has_base && ac->has_mark )
- ++a;
- ac_info += 2 + 2*a;
- } else
- putshort(lkf,0);
- }
- }
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) {
- if ( subs->anchor_classes ) {
- for ( ac=sf->anchor, a=0; ac!=NULL; ac=ac->next )
- if ( ac->subtable==subs && ac->has_base && ac->has_mark )
- ++a;
- putshort(lkf,a);
- for ( ac=sf->anchor, a=0; ac!=NULL; ac=ac->next )
- if ( ac->subtable==subs && ac->has_base && ac->has_mark ) {
- putshort(lkf,name_info);
- name_info += strlen(ac->name)+1;
- }
- }
- }
- }
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- fputs(otl->lookup_name,lkf);
- putc('\0',lkf);
- }
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) {
- fputs(subs->subtable_name,lkf);
- putc('\0',lkf);
- }
- }
- for ( otl=lookups; otl!=NULL; otl=otl->next ) if ( !otl->unused ) {
- for ( subs = otl->subtables, s=0; subs!=NULL; subs=subs->next ) if ( !subs->unused ) {
- for ( ac=sf->anchor, a=0; ac!=NULL; ac=ac->next )
- if ( ac->subtable==subs && ac->has_base && ac->has_mark ) {
- fputs(ac->name,lkf);
- putc('\0',lkf);
- }
- }
- }
- if ( ftell(lkf) & 1 )
- putc('\0',lkf);
- if ( ftell(lkf) & 2 )
- putshort(lkf,0);
-}
-
-static int pfed_mod_type(float val,int last_mod) {
- float ival;
-
- if ( last_mod==V_F )
-return( V_F );
- ival = rint(val);
- if ( ival!=val || ival<-32768 || ival>32767 )
-return( V_F );
- if ( last_mod==V_S || ival<-128 || ival>127 )
-return( V_S );
-
-return( V_B );
-}
-
-static void pfed_write_data(FILE *ttf, float val, int mod) {
- if ( mod==V_F )
- putlong(ttf,(int) rint(val*256.0f));
- else if ( mod==V_S )
- putshort(ttf,(int) rint(val));
- else
- putc(((int) rint(val)), ttf);
-}
-
-static void pfed_glyph_layer(FILE *layr,Layer *layer, int do_spiro) {
- int contour_cnt, image_cnt, ref_cnt, name_off, i,j;
- SplineSet *ss;
- SplinePoint *sp;
- uint32 base;
- int mod, was_implicit;
- RefChar *ref;
-
- contour_cnt = 0;
- for ( ss=layer->splines; ss!=NULL; ss=ss->next )
- ++contour_cnt;
- image_cnt = 0;
- /* I'm not doing images yet (if ever) but I leave space for them */
- ref_cnt = 0;
- for ( ref=layer->refs; ref!=NULL; ref=ref->next )
- ++ref_cnt;
-
- base = ftell(layr);
- putshort(layr,contour_cnt);
- putshort(layr,ref_cnt);
- putshort(layr,image_cnt);
-
- name_off = 2*3 + 4 * contour_cnt + (4*7+2)* ref_cnt;
- for ( ss=layer->splines; ss!=NULL; ss=ss->next ) {
- putshort(layr,0); /* fill in later */
- if ( ss->contour_name!=NULL ) {
- putshort(layr,name_off);
- name_off += strlen(ss->contour_name)+1;
- } else {
- putshort(layr,0);
- }
- }
- for ( ref=layer->refs; ref!=NULL; ref=ref->next ) {
- for ( j=0; j<6; ++j )
- putlong(layr, (int) rint(ref->transform[j]*32768));
- putshort(layr,ref->sc->ttf_glyph);
- }
- for ( ss=layer->splines; ss!=NULL; ss=ss->next ) {
- if ( ss->contour_name!=NULL ) {
- fputs(ss->contour_name,layr);
- putc('\0',layr);
- }
- }
-
- contour_cnt=0;
- for ( ss=layer->splines; ss!=NULL; ss=ss->next, ++contour_cnt ) {
- uint32 pos = ftell(layr);
- fseek( layr, base + 6 + 4*contour_cnt, SEEK_SET);
- putshort( layr, pos-base);
- fseek( layr, pos, SEEK_SET );
-
- if ( !do_spiro ) {
- sp = ss->first;
- mod = pfed_mod_type(sp->me.x, pfed_mod_type(sp->me.y,V_B));
- putc( (V_MoveTo|mod),layr);
- pfed_write_data(layr,sp->me.x,mod);
- pfed_write_data(layr,sp->me.y,mod);
- was_implicit = false;
-
- while ( sp->next!=NULL ) {
- SplinePoint *nsp = sp->next->to;
- float offx = nsp->me.x - sp->me.x;
- float offy = nsp->me.y - sp->me.y;
- if ( offx==0 && offy==0 )
- /* Do Nothing */;
- else if ( sp->next->knownlinear ) {
- mod = pfed_mod_type(offx, pfed_mod_type(offy,V_B));
- if ( offx==0 ) {
- putc( (V_VLineTo|mod), layr);
- pfed_write_data(layr,offy,mod);
- } else if ( offy==0 ) {
- putc( (V_HLineTo|mod), layr);
- pfed_write_data(layr,offx,mod);
- } else {
- putc( (V_LineTo|mod), layr);
- pfed_write_data(layr,offx,mod);
- pfed_write_data(layr,offy,mod);
- }
- } else if ( sp->next->order2 ) {
- float offx1, offx2, offy1, offy2;
- BasePoint *base = was_implicit ? &sp->prevcp : &sp->me;
- offx1 = sp->nextcp.x - base->x;
- offy1 = sp->nextcp.y - base->y;
- mod = pfed_mod_type(offx1, pfed_mod_type(offy1,V_B));
- if ( SPInterpolate(nsp) && nsp!=ss->first ) {
- was_implicit = true;
- if ( offx1==0 ) {
- putc( (V_QVImplicit|mod), layr);
- pfed_write_data(layr,offy1,mod);
- } else if ( offy1==0 ) {
- putc( (V_QHImplicit|mod), layr);
- pfed_write_data(layr,offx1,mod);
- } else {
- putc( (V_QImplicit|mod), layr);
- pfed_write_data(layr,offx1,mod);
- pfed_write_data(layr,offy1,mod);
- }
- } else {
- offx2 = nsp->me.x - sp->nextcp.x;
- offy2 = nsp->me.y - sp->nextcp.y;
- mod = pfed_mod_type(offx2, pfed_mod_type(offy2,mod));
- was_implicit = false;
- putc( (V_QCurveTo|mod), layr);
- pfed_write_data(layr,offx1,mod);
- pfed_write_data(layr,offy1,mod);
- pfed_write_data(layr,offx2,mod);
- pfed_write_data(layr,offy2,mod);
- }
- } else {
- float offx1 = sp->nextcp.x - sp->me.x;
- float offy1 = sp->nextcp.y - sp->me.y;
- float offx2 = nsp->prevcp.x - sp->nextcp.x;
- float offy2 = nsp->prevcp.y - sp->nextcp.y;
- float offx3 = nsp->me.x - nsp->prevcp.x;
- float offy3 = nsp->me.y - nsp->prevcp.y;
- mod = pfed_mod_type(offx1, pfed_mod_type(offy1,V_B));
- mod = pfed_mod_type(offx2, pfed_mod_type(offy2,mod));
- mod = pfed_mod_type(offx3, pfed_mod_type(offy3,mod));
- if ( offx1==0 && offy3==0 ) {
- putc((V_VHCurveTo|mod),layr);
- pfed_write_data(layr,offy1,mod);
- pfed_write_data(layr,offx2,mod);
- pfed_write_data(layr,offy2,mod);
- pfed_write_data(layr,offx3,mod);
- } else if ( offy1==0 && offx3==0 ) {
- putc((V_HVCurveTo|mod),layr);
- pfed_write_data(layr,offx1,mod);
- pfed_write_data(layr,offx2,mod);
- pfed_write_data(layr,offy2,mod);
- pfed_write_data(layr,offy3,mod);
- } else {
- putc((V_CurveTo|mod),layr);
- pfed_write_data(layr,offx1,mod);
- pfed_write_data(layr,offy1,mod);
- pfed_write_data(layr,offx2,mod);
- pfed_write_data(layr,offy2,mod);
- pfed_write_data(layr,offx3,mod);
- pfed_write_data(layr,offy3,mod);
- }
- }
- if ( nsp == ss->first )
- break;
- if ( nsp->next!=NULL && nsp->next->to==ss->first && nsp->next->knownlinear )
- break;
- sp = nsp;
- }
- if ( sp->next==NULL )
- putc(V_End,layr);
- else
- putc(V_Close,layr);
- } else if ( ss->spiro_cnt==0 )
- putc(SPIRO_CLOSE_CONTOUR,layr); /* Mark for an empty spiro contour */
- else {
- for ( i=0; i<ss->spiro_cnt; ++i ) {
- if ( i==ss->spiro_cnt-1 && ss->first->prev==NULL )
- putc(SPIRO_CLOSE_CONTOUR,layr);
- else if ( i==0 && ss->first->prev==NULL ) /* Open */
- putc(SPIRO_OPEN_CONTOUR,layr);
- else
- putc(ss->spiros[i].ty&0x7f,layr);
- putlong(layr,rint(ss->spiros[i].x*256.0));
- putlong(layr,rint(ss->spiros[i].y*256.0));
- }
- putc(SPIRO_END,layr); /* Add the z whether open or not. Might as well */
- }
- }
-}
-
-struct pos_name {
- real pos;
- char *name;
-};
-
-static int pfed_guide_real_comp(const void *_r1, const void *_r2) {
- const struct pos_name *r1 = _r1, *r2 = _r2;
-
- if ( r1->pos>r2->pos )
-return( 1 );
- else if ( r1->pos<r2->pos )
-return( -1 );
- else
-return( 0 );
-}
-
-static int pfed_guide_sortuniq( struct pos_name *array, int cnt) {
- int i,j;
-
- qsort(array,cnt,sizeof(struct pos_name),pfed_guide_real_comp);
- for ( i=j=0; i<cnt; ++i ) {
- if ( array[i].pos<-32768 || array[i].pos>32767 )
- /* Out of bounds, ignore it */;
- else if ( i!=0 && array[i].pos == array[i-1].pos )
- /* Duplicate, ignore it */;
- else
- array[j++] = array[i];
- }
-return( j );
-}
-
-static int pfed_guide_dump_pos_name(FILE *guid, struct pos_name *pn, int namestart ) {
- putshort(guid,(short) rint(pn->pos));
- if ( pn->name!=NULL ) {
- putshort(guid,namestart);
- namestart += strlen(pn->name)+1;
- } else {
- putshort(guid,0);
- }
-return( namestart );
-}
-
-static void PfEd_Guides(SplineFont *sf, struct PfEd_subtabs *pfed ) {
- int h,v, i;
- SplineSet *ss;
- Spline *s, *first;
- FILE *guid;
- struct pos_name hs[100], vs[100];
- int nameoff, namelen;
-
- if ( sf->grid.splines==NULL )
-return;
-
- h=v=0;
- for ( ss=sf->grid.splines; ss!=NULL; ss=ss->next ) {
- first = NULL;
- for ( s=ss->first->next; s!=NULL && s!=first; s=s->to->next ) {
- if ( first==NULL ) first = s;
- if ( s->from->me.x==s->to->me.x ) {
- if ( s->from->me.y!=s->to->me.y && v<100 ) {
- vs[v].name = ss->contour_name;
- vs[v++].pos = s->from->me.x;
- }
- } else if ( s->from->me.y==s->to->me.y ) {
- if ( h<100 ) {
- hs[h].name = ss->contour_name;
- hs[h++].pos = s->from->me.y;
- }
- }
- }
- }
-
- v = pfed_guide_sortuniq(vs,v);
- h = pfed_guide_sortuniq(hs,h);
-
- pfed->subtabs[pfed->next].tag = guid_TAG;
- pfed->subtabs[pfed->next++].data = guid = tmpfile2();
-
- nameoff = 5*2 + (h+v) * 4;
- namelen = 0;
- for ( i=0; i<v; ++i ) if ( vs[i].name!=NULL )
- namelen += strlen( vs[i].name )+1;
- for ( i=0; i<h; ++i ) if ( hs[i].name!=NULL )
- namelen += strlen( hs[i].name )+1;
-
- putshort(guid,1); /* sub-table version number */
- putshort(guid,v);
- putshort(guid,h);
- putshort(guid,0); /* Diagonal lines someday? nothing for now */
- putshort(guid,nameoff+namelen); /* full spline output */
- for ( i=0; i<v; ++i )
- nameoff = pfed_guide_dump_pos_name(guid, &vs[i], nameoff );
- for ( i=0; i<h; ++i )
- nameoff = pfed_guide_dump_pos_name(guid, &hs[i], nameoff );
-
- for ( i=0; i<v; ++i ) if ( vs[i].name!=NULL ) {
- fputs(vs[i].name,guid);
- putc('\0',guid);
- }
- for ( i=0; i<h; ++i ) if ( hs[i].name!=NULL ) {
- fputs(hs[i].name,guid);
- putc('\0',guid);
- }
-
- pfed_glyph_layer(guid,&sf->grid,false);
-
- if ( ftell(guid) & 1 )
- putc('\0',guid);
- if ( ftell(guid) & 2 )
- putshort(guid,0);
-}
-
-static int pfed_has_spiros(Layer *layer) {
- SplineSet *ss;
-
- for ( ss=layer->splines; ss!=NULL; ss=ss->next ) {
- if ( ss->spiro_cnt>1 )
-return( true );
- }
-return( false );
-}
-
-static void PfEd_Layer(SplineFont *sf, struct glyphinfo *gi, int layer, int dospiro,
- FILE *layr) {
- int i, j, k, gid, cnt, last, skipped;
- SplineChar *sc, *sc2;
- uint32 offset;
- uint32 *glyph_data_offset_location;
-
- for ( i=0; i<gi->gcnt; ++i ) if ( gi->bygid[i]!=-1 )
- if ( (sc=sf->glyphs[gi->bygid[i]])!=NULL ) {
- sc->ticked = false;
- if ( (!dospiro && (sc->layers[layer].splines!=NULL || sc->layers[layer].refs!=NULL) ) ||
- (dospiro && pfed_has_spiros(&sc->layers[layer])) )
- sc->ticked=true;
- }
-
- offset = ftell(layr);
- glyph_data_offset_location = calloc(gi->gcnt,sizeof(uint32));
- for ( j=0; j<4; ++j ) {
- cnt = 0;
- for ( i=0; i<gi->gcnt; ++i ) if ( (gid=gi->bygid[i])!=-1 && (sc=sf->glyphs[gid])!=NULL ) {
- if ( sc->ticked ) {
- last = i; skipped = false;
- for ( k=i+1; k<gi->gcnt; ++k ) {
- sc2 = NULL;
- if ( gi->bygid[k]!=-1 )
- sc2 = sf->glyphs[gi->bygid[k]];
- if ( skipped && (sc2==NULL || !sc2->ticked))
- break;
- if ( sc2!=NULL && sc2->ticked ) {
- last = k;
- skipped = false;
- } else
- skipped = true;
- }
- ++cnt;
- if ( j==1 ) {
- putshort(layr,i);
- putshort(layr,last);
- putlong(layr,offset);
- offset += sizeof(uint32)*(last-i+1);
- } else if ( j==2 ) {
- for ( ; i<=last; ++i ) {
- if ( gi->bygid[i]==-1 || !sf->glyphs[gi->bygid[i]]->ticked )
- putlong(layr,0);
- else {
- glyph_data_offset_location[i] = ftell(layr);
- putlong(layr,0);
- }
- }
- } else if ( j==3 ) {
- for ( ; i<=last; ++i ) {
- if ( gi->bygid[i]!=-1 && (sc=sf->glyphs[gi->bygid[i]])->ticked ) {
- uint32 pos = ftell(layr);
- fseek(layr,glyph_data_offset_location[i],SEEK_SET);
- putlong(layr,pos); /* Offset relative to start of subtable==start of file */
- fseek(layr,pos,SEEK_SET);
- pfed_glyph_layer(layr,&sc->layers[layer],dospiro);
- }
- }
- }
- i = last;
- }
- }
- if ( j==0 ) {
- offset += sizeof(short) + cnt*(2*sizeof(short)+sizeof(uint32));
- putshort(layr,cnt);
- }
- }
- free(glyph_data_offset_location);
-}
-
-static void PfEd_Layers(SplineFont *sf, struct PfEd_subtabs *pfed,
- struct glyphinfo *gi ) {
- /* currently we output the following: */
- /* The background layer */
- /* And the spiro representation of the foreground */
- /* if the foreground is cubic and output is quad then the foreground */
- /* Any other layers */
- /* Check if any of these data exist */
- uint8 has_spiro=0;
- uint8 *otherlayers;
- int i, name_off, l, cnt, sofar;
- SplineChar *sc;
- FILE *layr;
-
- otherlayers = calloc(sf->layer_cnt,sizeof(uint8));
-
- /* We don't need to check in bygid order. We just want to know existance */
- /* We don't check for refs because a reference to an empty glyph is empty too */
- for ( i=0; i<sf->glyphcnt; ++i ) {
- if ( (sc=sf->glyphs[i])!=NULL && sc->ttf_glyph!=-1 ) {
- if ( pfed_has_spiros(&sc->layers[ly_fore]))
- has_spiro = true;
- for ( l=ly_back ; l<sf->layer_cnt; ++l )
- if ( sc->layers[l].splines!=NULL )
- otherlayers[l] = true;
- }
- }
- otherlayers[gi->layer] = (!sf->layers[gi->layer].order2 && gi->is_ttf) ||
- ( sf->layers[gi->layer].order2 && !gi->is_ttf);
-
- for ( l=cnt=0; l<sf->layer_cnt; ++l )
- if ( otherlayers[l] )
- ++cnt;
- cnt += has_spiro;
- if ( cnt==0 ) {
- free(otherlayers);
-return;
- }
-
- pfed->subtabs[pfed->next].tag = layr_TAG;
- pfed->subtabs[pfed->next++].data = layr = tmpfile2();
-
- putshort(layr,1); /* sub-table version */
- putshort(layr,cnt); /* layer count */
-
- name_off = 4 + 8 * cnt;
- if ( has_spiro ) {
- putshort(layr,1); /* spiros */
- putshort(layr,name_off);
- name_off += strlen("Spiro")+1;
- putlong(layr,0); /* Fill in later */
- }
- for ( l=0; l<sf->layer_cnt; ++l ) if ( otherlayers[l]) {
- putshort(layr,(sf->layers[l].order2?2:3) | /* Quadratic/cubic */
- (sf->layers[l].background?0:0x100)); /* Fore/Back */
- putshort(layr,name_off);
- if ( l==ly_fore ) name_off += strlen("Old_");
- name_off += strlen(sf->layers[l].name)+1;
- putlong(layr,0); /* Fill in later */
- }
- if ( has_spiro ) {
- fputs("Spiro",layr);
- putc('\0',layr);
- }
- for ( l=0; l<sf->layer_cnt; ++l ) if ( otherlayers[l]) {
- if ( l==ly_fore ) fputs("Old_",layr);
- fputs(sf->layers[l].name,layr);
- putc('\0',layr);
- }
-
- sofar = 0;
- if ( has_spiro ) {
- uint32 pos = ftell(layr);
- fseek(layr, 4 + 0*8 + 4, SEEK_SET);
- putlong(layr,pos);
- fseek(layr, 0, SEEK_END);
- PfEd_Layer(sf, gi, ly_fore, true, layr);
- ++sofar;
- }
- for ( l=0; l<sf->layer_cnt; ++l ) if ( otherlayers[l]) {
- uint32 pos = ftell(layr);
- fseek(layr, 4 + sofar*8 + 4, SEEK_SET);
- putlong(layr,pos);
- fseek(layr, 0, SEEK_END);
- PfEd_Layer(sf, gi, l, false, layr);
- ++sofar;
- }
-
- if ( ftell(layr) & 1 )
- putc('\0',layr);
- if ( ftell(layr) & 2 )
- putshort(layr,0);
- free(otherlayers);
-}
-
-void pfed_dump(struct alltabs *at, SplineFont *sf) {
- struct PfEd_subtabs pfed;
- FILE *file;
- int i;
- uint32 offset;
-
- memset(&pfed,0,sizeof(pfed));
- if ( at->gi.flags & ttf_flag_pfed_comments ) {
- PfEd_FontComment(sf, &pfed, fcmt_TAG );
- PfEd_FontComment(sf, &pfed, flog_TAG );
- PfEd_GlyphComments(sf, &pfed, &at->gi );
- PfEd_CvtComments(sf, &pfed );
- }
- if ( at->gi.flags & ttf_flag_pfed_colors )
- PfEd_Colours(sf, &pfed, &at->gi );
- if ( (at->gi.flags & ttf_flag_pfed_lookupnames) && at->opentypemode ) {
- PfEd_Lookups(sf, &pfed, sf->gsub_lookups, GSUB_TAG );
- PfEd_Lookups(sf, &pfed, sf->gpos_lookups, GPOS_TAG );
- }
- if ( at->gi.flags & ttf_flag_pfed_guides )
- PfEd_Guides(sf, &pfed);
- if ( at->gi.flags & ttf_flag_pfed_layers )
- PfEd_Layers(sf, &pfed, &at->gi);
-
- if ( pfed.next==0 )
-return; /* No subtables */
-
- at->pfed = file = tmpfile2();
- putlong(file, 0x00010000); /* Version number */
- putlong(file, pfed.next); /* sub-table count */
- offset = 2*sizeof(uint32) + 2*pfed.next*sizeof(uint32);
- for ( i=0; i<pfed.next; ++i ) {
- putlong(file,pfed.subtabs[i].tag);
- putlong(file,offset);
- fseek(pfed.subtabs[i].data,0,SEEK_END);
- pfed.subtabs[i].offset = offset;
- offset += ftell(pfed.subtabs[i].data);
- }
- for ( i=0; i<pfed.next; ++i ) {
- fseek(pfed.subtabs[i].data,0,SEEK_SET);
- ttfcopyfile(file,pfed.subtabs[i].data,pfed.subtabs[i].offset,"PfEd-subtable");
- }
- if ( ftell(file)&3 )
- IError("'PfEd' table not properly aligned");
- at->pfedlen = ftell(file);
-}
-
-/* ************************* The 'PfEd' table ************************* */
-/* ************************* Input ************************* */
-
-static void pfed_readfontcomment(FILE *ttf,struct ttfinfo *info,uint32 base,
- uint32 tag) {
- int len;
- char *start, *pt, *end;
- int use_utf8;
-
- fseek(ttf,base,SEEK_SET);
- use_utf8 = getushort(ttf);
- if ( use_utf8!=0 && use_utf8!=1 )
-return; /* Bad version number */
- len = getushort(ttf);
- start = pt = malloc(len+1);
-
- end = pt+len;
- if ( use_utf8 ) {
- while ( pt<end )
- *pt++ = getc(ttf);
- } else {
- while ( pt<end )
- *pt++ = getushort(ttf);
- }
- *pt = '\0';
- if ( !use_utf8 ) {
- pt = latin1_2_utf8_copy(info->fontcomments);
- free(start);
- start = pt;
- }
- if ( tag==flog_TAG )
- info->fontlog = start;
- else
- info->fontcomments = start;
-}
-
-static char *pfed_read_utf8(FILE *ttf, uint32 start) {
- int ch, len;
- char *str, *pt;
-
- fseek( ttf, start, SEEK_SET);
- len = 0;
- while ( (ch=getc(ttf))!='\0' && ch!=EOF )
- ++len;
- fseek( ttf, start, SEEK_SET);
- str = pt = malloc(len+1);
- while ( (ch=getc(ttf))!='\0' && ch!=EOF )
- *pt++ = ch;
- *pt = '\0';
-return( str );
-}
-
-static char *pfed_read_ucs2_len(FILE *ttf,uint32 offset,int len) {
- char *pt, *str;
- uint32 uch, uch2;
- int i;
-
- if ( len<0 )
-return( NULL );
-
- len>>=1;
- if ( (pt=str=malloc(len>0 ? 3*len:1))==NULL )
- return( NULL );
- fseek(ttf,offset,SEEK_SET);
- for ( i=0; i<len; ++i ) {
- uch = getushort(ttf);
- if ( uch>=0xd800 && uch<0xdc00 ) {
- /* Is this a possible utf16 surrogate value? */
- uch2 = getushort(ttf);
- if ( uch2>=0xdc00 && uch2<0xe000 )
- uch = ((uch-0xd800)<<10) | (uch2&0x3ff);
- else {
- pt = utf8_idpb(pt,uch,0);
- uch = uch2;
- }
- }
- pt = utf8_idpb(pt,uch,0);
- }
- *pt++ = 0;
-return( realloc(str,pt-str) );
-}
-
-static char *pfed_read_utf8_len(FILE *ttf,uint32 offset,int len) {
- char *pt, *str;
- int i;
-
- if ( len<0 )
-return( NULL );
-
- pt = str = malloc(len+1);
- fseek(ttf,offset,SEEK_SET);
- for ( i=0; i<len; ++i )
- *pt++ = getc(ttf);
- *pt = '\0';
-return( str );
-}
-
-static void pfed_readcvtcomments(FILE *ttf,struct ttfinfo *info,uint32 base ) {
- int count, i;
- uint16 *offsets;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 )
-return; /* Bad version number */
- count = getushort(ttf);
-
- offsets = malloc(count*sizeof(uint16));
- info->cvt_names = malloc((count+1)*sizeof(char *));
- for ( i=0; i<count; ++i )
- offsets[i] = getushort(ttf);
- for ( i=0; i<count; ++i ) {
- if ( offsets[i]==0 )
- info->cvt_names[i] = NULL;
- else
- info->cvt_names[i] = pfed_read_utf8(ttf,base+offsets[i]);
- }
- free(offsets);
-}
-
-static void pfed_readglyphcomments(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int n, i, j;
- struct grange { int start, end; uint32 offset; } *grange;
- uint32 offset, next;
- int use_utf8;
-
- fseek(ttf,base,SEEK_SET);
- use_utf8 = getushort(ttf);
- if ( use_utf8!=0 && use_utf8!=1 )
-return; /* Bad version number */
- n = getushort(ttf);
- grange = malloc(n*sizeof(struct grange));
- for ( i=0; i<n; ++i ) {
- grange[i].start = getushort(ttf);
- grange[i].end = getushort(ttf);
- grange[i].offset = getlong(ttf);
- if ( grange[i].start>grange[i].end || grange[i].end>info->glyph_cnt ) {
- LogError( _("Bad glyph range specified in glyph comment subtable of PfEd table\n") );
- grange[i].start = 1; grange[i].end = 0;
- }
- }
- for ( i=0; i<n; ++i ) {
- for ( j=grange[i].start; j<=grange[i].end; ++j ) {
- fseek( ttf,base+grange[i].offset+(j-grange[i].start)*sizeof(uint32),SEEK_SET);
- offset = getlong(ttf);
- next = getlong(ttf);
- if ( use_utf8 )
- info->chars[j]->comment = pfed_read_utf8_len(ttf,base+offset,next-offset);
- else
- info->chars[j]->comment = pfed_read_ucs2_len(ttf,base+offset,next-offset);
- if ( info->chars[j]->comment == NULL )
- LogError(_("Invalid comment string (negative length?) in 'PfEd' table for glyph %s."),
- info->chars[j]->name );
- }
- }
- free(grange);
-}
-
-static void pfed_readcolours(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int n, i, j, start, end;
- uint32 col;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 )
-return; /* Bad version number */
- n = getushort(ttf);
- for ( i=0; i<n; ++i ) {
- start = getushort(ttf);
- end = getushort(ttf);
- col = getlong(ttf);
- if ( start>end || end>info->glyph_cnt )
- LogError( _("Bad glyph range specified in color subtable of PfEd table\n") );
- else {
- for ( j=start; j<=end; ++j )
- info->chars[j]->color = col;
- }
- }
-}
-
-static void pfed_readlookupnames(FILE *ttf,struct ttfinfo *info,uint32 base,
- OTLookup *lookups) {
- OTLookup *otl;
- struct lookup_subtable *sub;
- AnchorClass *ac;
- int i, j, k, n, s, a;
- struct lstruct { int name_off, subs_off; } *ls, *ss, *as;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 )
-return; /* Bad version number */
- n = getushort(ttf);
- ls = malloc(n*sizeof(struct lstruct));
- for ( i=0; i<n; ++i ) {
- ls[i].name_off = getushort(ttf);
- ls[i].subs_off = getushort(ttf);
- }
- for ( i=0, otl=lookups; i<n && otl!=NULL; ++i, otl=otl->next ) {
- if ( ls[i].name_off!=0 ) {
- free( otl->lookup_name );
- otl->lookup_name = pfed_read_utf8(ttf,base+ls[i].name_off);
- }
- if ( ls[i].subs_off!=0 ) {
- fseek(ttf,base+ls[i].subs_off,SEEK_SET);
- s = getushort(ttf);
- ss = malloc(s*sizeof(struct lstruct));
- for ( j=0; j<s; ++j ) {
- ss[j].name_off = getushort(ttf);
- ss[j].subs_off = getushort(ttf);
- }
- for ( j=0, sub=otl->subtables; j<s && sub!=NULL; ++j, sub=sub->next ) {
- if ( ss[j].name_off!=0 ) {
- free( sub->subtable_name );
- sub->subtable_name = pfed_read_utf8(ttf,base+ss[j].name_off);
- }
- if ( ss[j].subs_off!=0 ) {
- if ( !sub->anchor_classes )
- LogError(_("Whoops, attempt to name anchors in a subtable which doesn't contain any\n"));
- else {
- fseek(ttf,base+ss[j].subs_off,SEEK_SET);
- a = getushort(ttf);
- as = malloc(a*sizeof(struct lstruct));
- for ( k=0; k<a; ++k ) {
- as[k].name_off = getushort(ttf);
- }
- k=0;
- for ( ac=info->ahead; ac!=NULL; ac=ac->next ) {
- if ( ac->subtable==sub ) {
- if ( as[k].name_off!=0 ) {
- free( ac->name );
- ac->name = pfed_read_utf8(ttf,base+as[k].name_off);
- }
- ++k;
- }
- }
- free(as);
- }
- }
- }
- /* I guess it's ok for some subtables to be unnamed, so no check for sub!=NULL */
- if ( j<s )
- LogError(_("Whoops, more names than subtables of lookup %s\n"), otl->lookup_name );
- free(ss);
- }
- }
- /* I guess it's ok for some lookups to be unnamed, so no check for otf!=NULL */
- if ( i<n )
- LogError(_("Whoops, more names than lookups\n") );
- free(ls);
-}
-
-static float pfed_get_coord(FILE *ttf,int mod) {
- if ( mod==V_B )
-return( (float) (signed char) getc(ttf) );
- else if ( mod==V_S )
-return( (float) (short) getushort(ttf));
- else if ( mod==V_F )
-return( getlong(ttf)/256.0 );
- else {
- LogError(_("Bad data type in contour verb in 'PfEd'\n"));
-return( 0 );
- }
-}
-
-static void pfed_read_normal_contour(FILE *ttf,SplineSet *ss,
- uint32 base, int type) {
- SplinePoint *sp, *current;
- int verb, v, m;
- float offx, offy, offx1, offy1, offx2, offy2;
- int was_implicit=false;
-
- fseek(ttf,base,SEEK_SET);
-
- verb = getc(ttf);
- if ( COM_VERB(verb)!=V_MoveTo ) {
- LogError(_("Whoops, contours must begin with a move to\n") );
- ss->first = ss->last = SplinePointCreate(0,0);
- ss->start_offset = 0;
-return;
- }
- offx = pfed_get_coord(ttf,COM_MOD(verb));
- offy = pfed_get_coord(ttf,COM_MOD(verb));
- ss->first = current = SplinePointCreate(offx,offy);
- ss->start_offset = 0;
- for (;;) {
- verb = getc(ttf);
- v = COM_VERB(verb); m = COM_MOD(verb);
- if ( m==3 ) {
- LogError(_("Bad data modifier in contour command in 'PfEd'\n") );
- break;
- }
- if ( verb==V_Close || verb==V_End )
- break;
- else if ( v>=V_LineTo && v<=V_VLineTo ) {
- offx = offy = 0;
- if ( v==V_LineTo ) {
- offx = pfed_get_coord(ttf,m);
- offy = pfed_get_coord(ttf,m);
- } else if ( v==V_HLineTo )
- offx = pfed_get_coord(ttf,m);
- else if ( v==V_VLineTo )
- offy = pfed_get_coord(ttf,m);
- sp = SplinePointCreate(current->me.x+offx,current->me.y+offy);
- } else if ( v>=V_QCurveTo && v<=V_QVImplicit ) {
- int will_be_implicit = true;
- offx = offy = 0; offx1 = offy1 = 1; /* else implicit points become straight lines too soon */
- if ( v==V_QCurveTo ) {
- offx = pfed_get_coord(ttf,m);
- offy = pfed_get_coord(ttf,m);
- offx1 = pfed_get_coord(ttf,m);
- offy1 = pfed_get_coord(ttf,m);
- will_be_implicit = false;
- } else if ( v==V_QImplicit ) {
- offx = pfed_get_coord(ttf,m);
- offy = pfed_get_coord(ttf,m);
- } else if ( v==V_QHImplicit ) {
- offx = pfed_get_coord(ttf,m);
- } else if ( v==V_QVImplicit ) {
- offy = pfed_get_coord(ttf,m);
- }
-
- current->nextcp.x = current->me.x+offx;
- current->nextcp.y = current->me.y+offy;
- current->nonextcp = false;
- sp = SplinePointCreate(current->nextcp.x+offx1,current->nextcp.y+offy1);
- sp->prevcp = current->nextcp;
- sp->noprevcp = false;
- if ( was_implicit ) {
- current->me.x = (current->prevcp.x + current->nextcp.x)/2;
- current->me.y = (current->prevcp.y + current->nextcp.y)/2;
- SplineRefigure(current->prev);
- }
- was_implicit = will_be_implicit;
- } else if ( v>=V_CurveTo && v<=V_HVCurveTo ) {
- offx=offy=offx2=offy2=0;
- if ( v==V_CurveTo ) {
- offx = pfed_get_coord(ttf,m);
- offy = pfed_get_coord(ttf,m);
- offx1 = pfed_get_coord(ttf,m);
- offy1 = pfed_get_coord(ttf,m);
- offx2 = pfed_get_coord(ttf,m);
- offy2 = pfed_get_coord(ttf,m);
- } else if ( v==V_VHCurveTo ) {
- offy = pfed_get_coord(ttf,m);
- offx1 = pfed_get_coord(ttf,m);
- offy1 = pfed_get_coord(ttf,m);
- offx2 = pfed_get_coord(ttf,m);
- } else if ( v==V_HVCurveTo ) {
- offx = pfed_get_coord(ttf,m);
- offx1 = pfed_get_coord(ttf,m);
- offy1 = pfed_get_coord(ttf,m);
- offy2 = pfed_get_coord(ttf,m);
- }
- current->nextcp.x = current->me.x+offx;
- current->nextcp.y = current->me.y+offy;
- current->nonextcp = false;
- sp = SplinePointCreate(current->nextcp.x+offx1+offx2,current->nextcp.y+offy1+offy2);
- sp->prevcp.x = current->nextcp.x+offx1;
- sp->prevcp.y = current->nextcp.y+offy1;
- sp->noprevcp = false;
- } else {
- LogError(_("Whoops, unexpected verb in contour %d.%d\n"), v, m );
- break;
- }
- SplineMake(current,sp,type==2);
- current = sp;
- }
- if ( verb==V_Close ) {
- if ( was_implicit ) {
- current->me.x = (current->prevcp.x + ss->first->nextcp.x)/2;
- current->me.y = (current->prevcp.y + ss->first->nextcp.y)/2;
- }
- if ( current->me.x==ss->first->me.x && current->me.y==ss->first->me.y ) {
- current->prev->to = ss->first;
- ss->first->prev = current->prev;
- ss->first->prevcp = current->prevcp;
- ss->first->noprevcp = current->noprevcp;
- SplinePointFree(current);
- } else
- SplineMake(current,ss->first,type==2);
- ss->last = ss->first;
- } else {
- ss->last = current;
- }
- SPLCategorizePoints(ss);
-}
-
-static void pfed_read_spiro_contour(FILE *ttf,SplineSet *ss,
- uint32 base, int type) {
- int ch;
-
- fseek(ttf,base,SEEK_SET);
-
- for (; ; ) {
- ch = getc(ttf);
- if ( ch!=SPIRO_OPEN_CONTOUR && ch!=SPIRO_CORNER && ch!=SPIRO_G4 &&
- ch!=SPIRO_G2 && ch!=SPIRO_LEFT && ch!=SPIRO_RIGHT &&
- ch!=SPIRO_END && ch!=SPIRO_CLOSE_CONTOUR ) {
- LogError(_("Whoops, bad spiro command %d\n"), ch);
- break;
- }
- if ( ss->spiro_cnt>=ss->spiro_max )
- ss->spiros = realloc(ss->spiros,(ss->spiro_max+=10)*sizeof(spiro_cp));
- ss->spiros[ss->spiro_cnt].ty = ch;
- if ( ch!=SPIRO_END ) {
- ss->spiros[ss->spiro_cnt].x = getlong(ttf)/256.0;
- ss->spiros[ss->spiro_cnt].y = getlong(ttf)/256.0;
- } else {
- ss->spiros[ss->spiro_cnt].x = 0;
- ss->spiros[ss->spiro_cnt].y = 0;
- }
- ++(ss->spiro_cnt);
- if ( ch==SPIRO_END || ch=='}' )
- break;
- }
- if ( ss->spiro_cnt!=0 && ss->spiros[ss->spiro_cnt-1].ty!= SPIRO_END ) {
- if ( ss->spiros[ss->spiro_cnt-1].ty==SPIRO_CLOSE_CONTOUR )
- ss->spiros[ss->spiro_cnt-1].ty = SPIRO_G4;
- if ( ss->spiro_cnt>=ss->spiro_max )
- ss->spiros = realloc(ss->spiros,(ss->spiro_max+=2)*sizeof(spiro_cp));
- ss->spiros[ss->spiro_cnt].ty = SPIRO_END;
- ss->spiros[ss->spiro_cnt].x = 0;
- ss->spiros[ss->spiro_cnt].y = 0;
- }
-}
-
-static void pfed_read_glyph_layer(FILE *ttf,struct ttfinfo *info,Layer *ly,
- uint32 base, int type, int version) {
- int cc, rc, i, j;
- SplineSet *ss;
- struct contours { int data_off, name_off; SplineSet *ss; } *contours;
- int gid;
- RefChar *last, *cur;
-
- fseek(ttf,base,SEEK_SET);
- cc = getushort(ttf); /* Contours */
- rc = 0;
- if ( version==1 )
- rc = getushort(ttf); /* References */
- contours = malloc(cc*sizeof(struct contours));
- for ( i=0; i<cc; ++i ) {
- contours[i].data_off = getushort(ttf);
- contours[i].name_off = getushort(ttf);
- }
- last = NULL;
- for ( i=0; i<rc; ++i ) {
- cur = RefCharCreate();
- for ( j=0; j<6; ++j )
- cur->transform[j] = getlong(ttf)/32768.0;
- gid = getushort(ttf);
- if ( gid>=info->glyph_cnt ) {
- LogError(_("Bad glyph reference in layer info.\n"));
- break;
- }
- cur->sc = info->chars[gid];
- cur->orig_pos = gid;
- cur->unicode_enc = cur->sc->unicodeenc;
- if ( last==NULL )
- ly->refs = cur;
- else
- last->next = cur;
- last = cur;
- }
-
- ss = ly->splines; /* Only relevant for spiros where they live in someone else's layer */
- for ( i=0; i<cc; ++i ) {
- if ( type!=1 ) { /* Not spiros */
- contours[i].ss = chunkalloc(sizeof(SplineSet));
- if ( i==0 )
- ly->splines = contours[i].ss;
- else
- contours[i-1].ss->next = contours[i].ss;
- if ( contours[i].name_off!=0 )
- contours[i].ss->contour_name = pfed_read_utf8(ttf,base+contours[i].name_off);
- pfed_read_normal_contour(ttf,contours[i].ss,base+contours[i].data_off,type);
- } else { /* Spiros are actually bound to an already existing layer and don't have an independent existance yet */
- contours[i].ss = ss;
- if ( ss!=NULL ) {
- pfed_read_spiro_contour(ttf,ss,base+contours[i].data_off,type);
- ss = ss->next;
- } else
- LogError(_("Whoops, Ran out of spiros\n"));
- }
- }
- free(contours);
-}
-
-static void pfed_readguidelines(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int i,v,h,off;
- int version;
- SplinePoint *sp, *nsp;
- SplineSet *ss;
-
- fseek(ttf,base,SEEK_SET);
- version = getushort(ttf);
- if ( version>1 )
-return; /* Bad version number */
- v = getushort(ttf);
- h = getushort(ttf);
- (void) getushort(ttf);
- off = getushort(ttf);
-
- if ( off!=0 ) {
- pfed_read_glyph_layer(ttf,info,&info->guidelines,base+off,info->to_order2?2:3,version);
- } else {
- struct npos { int pos; int offset; } *vs, *hs;
- vs = malloc(v*sizeof(struct npos));
- hs = malloc(h*sizeof(struct npos));
- for ( i=0; i<v; ++i ) {
- vs[i].pos = (short) getushort(ttf);
- vs[i].offset = getushort(ttf);
- }
- for ( i=0; i<h; ++i ) {
- hs[i].pos = (short) getushort(ttf);
- hs[i].offset = getushort(ttf);
- }
- for ( i=0; i<v; ++i ) {
- sp = SplinePointCreate(vs[i].pos,-info->emsize);
- nsp = SplinePointCreate(vs[i].pos,2*info->emsize);
- SplineMake(sp,nsp,info->to_order2);
- ss = chunkalloc(sizeof(SplineSet));
- ss->first = sp; ss->last = nsp;
- if ( vs[i].offset!=0 )
- ss->contour_name = pfed_read_utf8(ttf,base+vs[i].offset);
- ss->next = info->guidelines.splines;
- info->guidelines.splines = ss;
- }
- for ( i=0; i<h; ++i ) {
- sp = SplinePointCreate(-info->emsize,hs[i].pos);
- nsp = SplinePointCreate(2*info->emsize,hs[i].pos);
- SplineMake(sp,nsp,info->to_order2);
- ss = chunkalloc(sizeof(SplineSet));
- ss->first = sp; ss->last = nsp;
- if ( hs[i].offset!=0 )
- ss->contour_name = pfed_read_utf8(ttf,base+hs[i].offset);
- ss->next = info->guidelines.splines;
- info->guidelines.splines = ss;
- }
- SPLCategorizePoints(info->guidelines.splines);
- free(vs); free(hs);
- }
-}
-
-static void pfed_redo_refs(SplineChar *sc,int layer) {
- RefChar *refs;
-
- sc->ticked = true;
- for ( refs=sc->layers[layer].refs; refs!=NULL; refs=refs->next ) {
- if ( layer==1 && refs->sc==NULL ) /* If main layer has spiros attached, then we'll get here. Any refs will come from the main ttf reading routines and won't be fixed up yet */
- continue;
- if ( !refs->sc->ticked )
- pfed_redo_refs(refs->sc,layer);
- SCReinstanciateRefChar(sc,refs,layer);
- }
-}
-
-static void pfed_read_layer(FILE *ttf,struct ttfinfo *info,int layer,int type, uint32 base,
- uint32 start,int version) {
- uint32 *loca = calloc(info->glyph_cnt,sizeof(uint32));
- int i,j;
- SplineChar *sc;
- int rcnt;
- struct range { int start, last; uint32 offset; } *ranges;
-
- fseek(ttf,start,SEEK_SET);
- rcnt = getushort(ttf);
- ranges = malloc(rcnt*sizeof(struct range));
- for ( i=0; i<rcnt; ++i ) {
- ranges[i].start = getushort(ttf);
- ranges[i].last = getushort(ttf);
- ranges[i].offset = getlong(ttf);
- }
- for ( i=0; i<rcnt; ++i ) {
- fseek(ttf,base+ranges[i].offset,SEEK_SET);
- for ( j=ranges[i].start; j<=ranges[i].last; ++j )
- loca[j] = getlong(ttf);
- for ( j=ranges[i].start; j<=ranges[i].last; ++j ) {
- Layer *ly;
- sc = info->chars[j];
- ly = &sc->layers[layer];
- if ( loca[j]!=0 )
- pfed_read_glyph_layer(ttf,info,ly,base+loca[j],type,version);
- }
- }
- free(ranges); free(loca);
-
- for ( i=0; i<info->glyph_cnt; ++i ) if ( info->chars[i]!=NULL )
- info->chars[i]->ticked = false;
- for ( i=0; i<info->glyph_cnt; ++i ) if ( info->chars[i]!=NULL )
- pfed_redo_refs(info->chars[i],layer);
-}
-
-static void pfed_readotherlayers(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int i, l, lcnt, spiro_index, gid;
- int version;
- struct layer_info { int type, name_off, data_off, sf_layer; char *name; } *layers;
- int non_spiro_cnt=0;
- SplineChar *sc;
-
- fseek(ttf,base,SEEK_SET);
- version = getushort(ttf);
- if ( version>1 )
-return; /* Bad version number */
- lcnt = getushort(ttf);
- layers = malloc(lcnt*sizeof(struct layer_info));
- for ( i=0; i<lcnt; ++i ) {
- layers[i].type = getushort(ttf);
- layers[i].name_off = getushort(ttf);
- layers[i].data_off = getlong(ttf);
- layers[i].sf_layer = -1;
- }
- spiro_index = -1;
- non_spiro_cnt = 0;
- for ( i=0; i<lcnt; ++i ) {
- if ( layers[i].name_off==0 )
- layers[i].name = copy("Unnamed");
- else {
- layers[i].name = pfed_read_utf8(ttf,base+layers[i].name_off);
- if ( layers[i].type==1 && strcmp(layers[i].name,"Spiro")==0 )
- spiro_index = i;
- }
- if ( layers[i].type==2 || layers[i].type==3 || layers[i].type==0x102 || layers[i].type==0x103 )
- ++non_spiro_cnt;
- }
- if ( spiro_index==-1 ) {
- for ( i=0; i<lcnt; ++i )
- if ( layers[i].type==1 ) {
- spiro_index=i;
- break;
- }
- }
-
- if ( non_spiro_cnt!=0 ) {
- info->layer_cnt = non_spiro_cnt+1;
- info->layers = calloc(info->layer_cnt+1,sizeof(LayerInfo));
- info->layers[ly_back].background = true;
- info->layers[ly_fore].order2 = info->to_order2;
- info->layers[ly_fore].background = false;
- l = i = 0;
- if ( (layers[i].type&0xff)==1 )
- ++i;
- if ( layers[i].type&0x100 ) {
- /* first layer output is foreground, so it can't replace the background layer */
- ++info->layer_cnt;
- l = 2;
- info->layers[ly_back].order2 = info->to_order2;
- }
- for ( ; i<lcnt; ++i ) if ( (layers[i].type&0xff)==2 || (layers[i].type&0xff)==3 ) {
- info->layers[l].name = layers[i].name;
- layers[i].name = NULL;
- layers[i].sf_layer = l;
- info->layers[l].order2 = (layers[i].type&0xff)==2;
- info->layers[l].background = (layers[i].type&0x100)?0:1;
- if ( l==0 ) l=2; else ++l;
- }
- if ( info->layer_cnt!=2 ) {
- for ( gid = 0; gid<info->glyph_cnt; ++gid ) if ((sc=info->chars[gid])!=NULL ) {
- sc->layers = realloc(sc->layers,info->layer_cnt*sizeof(Layer));
- memset(sc->layers+2,0,(info->layer_cnt-2)*sizeof(Layer));
- sc->layer_cnt = info->layer_cnt;
- }
- }
- }
- if ( spiro_index!=-1 )
- pfed_read_layer(ttf,info,ly_fore,layers[spiro_index].type,base,base+layers[spiro_index].data_off,version);
- for ( i=0; i<lcnt; ++i ) if ( layers[i].sf_layer!=-1 ) {
- pfed_read_layer(ttf,info,layers[i].sf_layer,layers[i].type&0xff,
- base,base+layers[i].data_off,version);
- }
- for ( i=0; i<lcnt; ++i )
- free( layers[i].name );
- free( layers );
-}
-
-void pfed_read(FILE *ttf,struct ttfinfo *info) {
- int n,i;
- struct tagoff { uint32 tag, offset; } tagoff[MAX_SUBTABLE_TYPES+30];
-
- fseek(ttf,info->pfed_start,SEEK_SET);
-
- if ( getlong(ttf)!=0x00010000 )
-return;
- n = getlong(ttf);
- if ( n>=MAX_SUBTABLE_TYPES+30 )
- n = MAX_SUBTABLE_TYPES+30;
- for ( i=0; i<n; ++i ) {
- tagoff[i].tag = getlong(ttf);
- tagoff[i].offset = getlong(ttf);
- }
- for ( i=0; i<n; ++i ) switch ( tagoff[i].tag ) {
- case fcmt_TAG: case flog_TAG:
- pfed_readfontcomment(ttf,info,info->pfed_start+tagoff[i].offset, tagoff[i].tag);
- break;
- case cvtc_TAG:
- pfed_readcvtcomments(ttf,info,info->pfed_start+tagoff[i].offset);
- break;
- case cmnt_TAG:
- pfed_readglyphcomments(ttf,info,info->pfed_start+tagoff[i].offset);
- break;
- case colr_TAG:
- pfed_readcolours(ttf,info,info->pfed_start+tagoff[i].offset);
- break;
- case GPOS_TAG:
- pfed_readlookupnames(ttf,info,info->pfed_start+tagoff[i].offset,info->gpos_lookups);
- break;
- case GSUB_TAG:
- pfed_readlookupnames(ttf,info,info->pfed_start+tagoff[i].offset,info->gsub_lookups);
- break;
- case layr_TAG:
- pfed_readotherlayers(ttf,info,info->pfed_start+tagoff[i].offset);
- break;
- case guid_TAG:
- pfed_readguidelines(ttf,info,info->pfed_start+tagoff[i].offset);
- break;
- default:
- LogError( _("Unknown subtable '%c%c%c%c' in 'PfEd' table, ignored\n"),
- tagoff[i].tag>>24, (tagoff[i].tag>>16)&0xff, (tagoff[i].tag>>8)&0xff, tagoff[i].tag&0xff );
- break;
- }
-}
-
-/* 'TeX ' table format is as follows... */
-/* uint32 version number 0x00010000 */
-/* uint32 subtable count */
-/* struct { uint32 tab, offset } tag/offset for first subtable */
-/* struct { uint32 tab, offset } tag/offset for second subtable */
-/* ... */
-
-/* 'TeX ' 'ftpm' font parameter subtable format */
-/* short version number 0 */
-/* parameter count */
-/* array of { 4chr tag, value } */
-
-/* 'TeX ' 'htdp' per-glyph height/depth subtable format */
-/* short version number 0 */
-/* short glyph-count */
-/* array[glyph-count] of { int16 height,depth } */
-
-/* 'TeX ' 'itlc' per-glyph italic correction subtable */
-/* short version number 0 */
-/* short glyph-count */
-/* array[glyph-count] of int16 italic_correction */
-
-/* !!!!!!!!!!! OBSOLETE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* 'TeX ' 'sbsp' per-glyph sub/super script positioning subtable */
-/* short version number 0 */
-/* short glyph-count */
-/* array[glyph-count] of { int16 sub,super } */
-
-#undef MAX_SUBTABLE_TYPES
-#define MAX_SUBTABLE_TYPES 4
-
-struct TeX_subtabs {
- int next;
- struct {
- FILE *data;
- uint32 tag;
- uint32 offset;
- } subtabs[MAX_SUBTABLE_TYPES];
-};
-
-static uint32 tex_text_params[] = {
- TeX_Slant,
- TeX_Space,
- TeX_Stretch,
- TeX_Shrink,
- TeX_XHeight,
- TeX_Quad,
- TeX_ExtraSp,
- 0
-};
-static uint32 tex_math_params[] = {
- TeX_Slant,
- TeX_Space,
- TeX_Stretch,
- TeX_Shrink,
- TeX_XHeight,
- TeX_Quad,
- TeX_MathSp,
- TeX_Num1,
- TeX_Num2,
- TeX_Num3,
- TeX_Denom1,
- TeX_Denom2,
- TeX_Sup1,
- TeX_Sup2,
- TeX_Sup3,
- TeX_Sub1,
- TeX_Sub2,
- TeX_SupDrop,
- TeX_SubDrop,
- TeX_Delim1,
- TeX_Delim2,
- TeX_AxisHeight,
- 0};
-static uint32 tex_mathext_params[] = {
- TeX_Slant,
- TeX_Space,
- TeX_Stretch,
- TeX_Shrink,
- TeX_XHeight,
- TeX_Quad,
- TeX_MathSp,
- TeX_DefRuleThick,
- TeX_BigOpSpace1,
- TeX_BigOpSpace2,
- TeX_BigOpSpace3,
- TeX_BigOpSpace4,
- TeX_BigOpSpace5,
- 0};
-
-/* ************************************************************************** */
-/* ************************* The 'TeX ' table ************************* */
-/* ************************* Output ************************* */
-/* ************************************************************************** */
-
-static void TeX_dumpFontParams(SplineFont *sf, struct TeX_subtabs *tex, struct alltabs *at ) {
- FILE *fprm;
- int i,pcnt;
- uint32 *tags;
-
- if ( sf->texdata.type==tex_unset )
-return;
- tex->subtabs[tex->next].tag = CHR('f','t','p','m');
- tex->subtabs[tex->next++].data = fprm = tmpfile2();
-
- putshort(fprm,0); /* sub-table version number */
- pcnt = sf->texdata.type==tex_math ? 22 : sf->texdata.type==tex_mathext ? 13 : 7;
- tags = sf->texdata.type==tex_math ? tex_math_params :
- sf->texdata.type==tex_mathext ? tex_mathext_params :
- tex_text_params;
- putshort(fprm,pcnt);
- for ( i=0; i<pcnt; ++i ) {
- putlong(fprm,tags[i]);
- putlong(fprm,sf->texdata.params[i]);
- }
- /* always aligned */
-}
-
-static void TeX_dumpHeightDepth(SplineFont *sf, struct TeX_subtabs *tex, struct alltabs *at ) {
- FILE *htdp;
- int i,j,k,last_g, gid;
- DBounds b;
-
- for ( i=at->gi.gcnt-1; i>=0; --i ) {
- gid = at->gi.bygid[i];
- if ( gid!=-1 && sf->glyphs[gid]!=NULL &&
- (sf->glyphs[gid]->tex_height!=TEX_UNDEF || sf->glyphs[gid]->tex_depth!=TEX_UNDEF))
- break;
- }
- if ( i<0 ) /* No height/depth info */
-return;
-
- tex->subtabs[tex->next].tag = CHR('h','t','d','p');
- tex->subtabs[tex->next++].data = htdp = tmpfile2();
-
- putshort(htdp,0); /* sub-table version number */
- putshort(htdp,sf->glyphs[gid]->ttf_glyph+1);/* data for this many glyphs */
-
- last_g = -1;
- for ( j=0; j<=i; ++j ) {
- gid = at->gi.bygid[j];
- if ( gid!=-1 && sf->glyphs[gid]!=NULL ) {
- SplineChar *sc = sf->glyphs[gid];
- for ( k=last_g+1; k<sc->ttf_glyph; ++k ) {
- putshort(htdp,0);
- putshort(htdp,0);
- }
- if ( sc->tex_depth==TEX_UNDEF || sc->tex_height==TEX_UNDEF )
- SplineCharFindBounds(sc,&b);
- putshort( htdp, sc->tex_height==TEX_UNDEF ? b.maxy : sc->tex_height );
- putshort( htdp, sc->tex_depth==TEX_UNDEF ? -b.miny : sc->tex_depth );
- last_g = sc->ttf_glyph;
- }
- }
- /* always aligned */
-}
-
-static void TeX_dumpItalicCorr(SplineFont *sf, struct TeX_subtabs *tex, struct alltabs *at ) {
- FILE *itlc;
- int i,j,k,last_g, gid;
-
- for ( i=at->gi.gcnt-1; i>=0; --i ) {
- gid = at->gi.bygid[i];
- if ( gid!=-1 && sf->glyphs[gid]!=NULL &&
- sf->glyphs[gid]->italic_correction!=TEX_UNDEF )
- break;
- }
- if ( i<0 ) /* No italic_correction info */
-return;
-
- tex->subtabs[tex->next].tag = CHR('i','t','l','c');
- tex->subtabs[tex->next++].data = itlc = tmpfile2();
-
- putshort(itlc,0); /* sub-table version number */
- putshort(itlc,sf->glyphs[gid]->ttf_glyph+1);/* data for this many glyphs */
-
- last_g = -1;
- for ( j=0; j<=i; ++j ) {
- gid = at->gi.bygid[j];
- if ( gid!=-1 && sf->glyphs[gid]!=NULL ) {
- SplineChar *sc = sf->glyphs[gid];
- for ( k=last_g+1; k<sc->ttf_glyph; ++k ) {
- putshort(itlc,0);
- putshort(itlc,0);
- }
- putshort( itlc, sc->italic_correction!=TEX_UNDEF ? sc->italic_correction :
- 0 );
- last_g = sc->ttf_glyph;
- }
- }
- /* always aligned */
-}
-
-void tex_dump(struct alltabs *at, SplineFont *sf) {
- struct TeX_subtabs tex;
- FILE *file;
- int i;
- uint32 offset;
-
- if ( !(at->gi.flags & ttf_flag_TeXtable ))
-return;
-
- memset(&tex,0,sizeof(tex));
- TeX_dumpFontParams(sf,&tex,at);
- TeX_dumpHeightDepth(sf,&tex,at);
- TeX_dumpItalicCorr(sf,&tex,at);
-
- if ( tex.next==0 )
-return; /* No subtables */
-
- at->tex = file = tmpfile2();
- putlong(file, 0x00010000); /* Version number */
- putlong(file, tex.next); /* sub-table count */
- offset = 2*sizeof(uint32) + 2*tex.next*sizeof(uint32);
- for ( i=0; i<tex.next; ++i ) {
- putlong(file,tex.subtabs[i].tag);
- putlong(file,offset);
- fseek(tex.subtabs[i].data,0,SEEK_END);
- tex.subtabs[i].offset = offset;
- offset += ftell(tex.subtabs[i].data);
- }
- for ( i=0; i<tex.next; ++i ) {
- fseek(tex.subtabs[i].data,0,SEEK_SET);
- ttfcopyfile(file,tex.subtabs[i].data,tex.subtabs[i].offset,"TeX-subtable");
- }
- if ( ftell(file)&2 )
- putshort(file,0);
- if ( ftell(file)&3 )
- IError("'TeX ' table not properly aligned");
- at->texlen = ftell(file);
-}
-
-/* ************************* The 'TeX ' table ************************* */
-/* ************************* Input ************************* */
-
-static void TeX_readFontParams(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int i,pcnt;
- static uint32 *alltags[] = { tex_text_params, tex_math_params, tex_mathext_params };
- int j,k;
- uint32 tag;
- int32 val;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 ) /* Don't know how to read this version of the subtable */
-return;
- pcnt = getushort(ttf);
- if ( pcnt==22 ) info->texdata.type = tex_math;
- else if ( pcnt==13 ) info->texdata.type = tex_mathext;
- else if ( pcnt>=7 ) info->texdata.type = tex_text;
- for ( i=0; i<pcnt; ++i ) {
- tag = getlong(ttf);
- val = getlong(ttf);
- for ( j=0; j<3; ++j ) {
- for ( k=0; alltags[j][k]!=0; ++k )
- if ( alltags[j][k]==tag )
- break;
- if ( alltags[j][k]==tag )
- break;
- }
- if ( j<3 )
- info->texdata.params[k] = val;
- }
-}
-
-static void TeX_readHeightDepth(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int i,gcnt;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 ) /* Don't know how to read this version of the subtable */
-return;
- gcnt = getushort(ttf);
- for ( i=0; i<gcnt && i<info->glyph_cnt; ++i ) {
- int h, d;
- h = getushort(ttf);
- d = getushort(ttf);
- if ( info->chars[i]!=NULL ) {
- info->chars[i]->tex_height = h;
- info->chars[i]->tex_depth = d;
- }
- }
-}
-
-static void TeX_readItalicCorr(FILE *ttf,struct ttfinfo *info,uint32 base) {
- int i,gcnt;
-
- fseek(ttf,base,SEEK_SET);
- if ( getushort(ttf)!=0 ) /* Don't know how to read this version of the subtable */
-return;
- gcnt = getushort(ttf);
- for ( i=0; i<gcnt && i<info->glyph_cnt; ++i ) {
- int ital;
- ital = getushort(ttf);
- if ( info->chars[i]!=NULL ) {
- info->chars[i]->italic_correction = ital;
- }
- }
-}
-
-void tex_read(FILE *ttf,struct ttfinfo *info) {
- int n,i;
- struct tagoff { uint32 tag, offset; } tagoff[MAX_SUBTABLE_TYPES+30];
-
- fseek(ttf,info->tex_start,SEEK_SET);
-
- if ( getlong(ttf)!=0x00010000 )
-return;
- n = getlong(ttf);
- if ( n>=MAX_SUBTABLE_TYPES+30 )
- n = MAX_SUBTABLE_TYPES+30;
- for ( i=0; i<n; ++i ) {
- tagoff[i].tag = getlong(ttf);
- tagoff[i].offset = getlong(ttf);
- }
- for ( i=0; i<n; ++i ) switch ( tagoff[i].tag ) {
- case CHR('f','t','p','m'):
- TeX_readFontParams(ttf,info,info->tex_start+tagoff[i].offset);
- break;
- case CHR('h','t','d','p'):
- TeX_readHeightDepth(ttf,info,info->tex_start+tagoff[i].offset);
- break;
- case CHR('i','t','l','c'):
- TeX_readItalicCorr(ttf,info,info->tex_start+tagoff[i].offset);
- break;
- default:
- LogError( _("Unknown subtable '%c%c%c%c' in 'TeX ' table, ignored\n"),
- tagoff[i].tag>>24, (tagoff[i].tag>>16)&0xff, (tagoff[i].tag>>8)&0xff, tagoff[i].tag&0xff );
- break;
- }
-}
-
-/* ************************************************************************** */
-/* ************************* The 'BDF ' table ************************* */
-/* ************************* Output ************************* */
-/* ************************************************************************** */
-
-/* the BDF table is used to store BDF properties so that we can do round trip */
-/* conversion from BDF->otb->BDF without losing anything. */
-/* Format:
- USHORT version : 'BDF' table version number, must be 0x0001
- USHORT strikeCount : number of strikes in table
- ULONG stringTable : offset (from start of BDF table) to string table
-
-followed by an array of 'strikeCount' descriptors that look like:
- USHORT ppem : vertical pixels-per-EM for this strike
- USHORT num_items : number of items (properties and atoms), max is 255
-
-this array is followed by 'strikeCount' value sets. Each "value set" is
-an array of (num_items) items that look like:
- ULONG item_name : offset in string table to item name
- USHORT item_type : item type: 0 => non-property string (e.g. COMMENT)
- 1 => non-property atom (e.g. FONT)
- 2 => non-property int32
- 3 => non-property uint32
- 0x10 => flag for a property, ored
- with above value types)
- ULONG item_value : item value.
- strings => an offset into the string table
- to the corresponding string,
- without the surrending double-quotes
-
- atoms => an offset into the string table
-
- integers => the corresponding 32-bit value
-Then the string table of null terminated strings. These strings should be in
-ASCII.
-*/
-
-/* ************************* The 'BDF ' table ************************* */
-/* ************************* Input ************************* */
-
-static char *getstring(FILE *ttf,long start) {
- long here = ftell(ttf);
- int len, ch;
- char *str, *pt;
-
- if ( here<0 ) return( NULL );
- fseek(ttf,start,SEEK_SET);
- for ( len=1; (ch=getc(ttf))>0 ; ++len );
- fseek(ttf,start,SEEK_SET);
- pt = str = malloc(len);
- while ( (ch=getc(ttf))>0 )
- *pt++ = ch;
- *pt = '\0';
- fseek(ttf,here,SEEK_SET);
-return( str );
-}
-
-/* COMMENTS get stored all in one lump by freetype. De-lump them */
-static int CheckForNewlines(BDFFont *bdf,int k) {
- char *pt, *start;
- int cnt, i;
-
- for ( cnt=0, pt = bdf->props[k].u.atom; *pt; ++pt )
- if ( *pt=='\n' )
- ++cnt;
- if ( cnt==0 )
-return( k );
-
- bdf->prop_cnt += cnt;
- bdf->props = realloc(bdf->props, bdf->prop_cnt*sizeof( BDFProperties ));
-
- pt = strchr(bdf->props[k].u.atom,'\n');
- *pt = '\0'; ++pt;
- for ( i=1; i<=cnt; ++i ) {
- start = pt;
- while ( *pt!='\n' && *pt!='\0' ) ++pt;
- bdf->props[k+i].name = copy(bdf->props[k].name);
- bdf->props[k+i].type = bdf->props[k].type;
- bdf->props[k+i].u.atom = copyn(start,pt-start);
- if ( *pt=='\n' ) ++pt;
- }
- pt = copy( bdf->props[k].u.atom );
- free( bdf->props[k].u.atom );
- bdf->props[k].u.atom = pt;
-return( k+cnt );
-}
-
-void ttf_bdf_read(FILE *ttf,struct ttfinfo *info) {
- int strike_cnt, i,j,k;
- long string_start;
- struct bdfinfo { BDFFont *bdf; int cnt; } *bdfinfo;
- BDFFont *bdf;
-
- if ( info->bdf_start==0 )
-return;
- fseek(ttf,info->bdf_start,SEEK_SET);
- if ( getushort(ttf)!=1 )
-return;
- strike_cnt = getushort(ttf);
- string_start = getlong(ttf) + info->bdf_start;
-
- bdfinfo = malloc(strike_cnt*sizeof(struct bdfinfo));
- for ( i=0; i<strike_cnt; ++i ) {
- int ppem, num_items;
- ppem = getushort(ttf);
- num_items = getushort(ttf);
- for ( bdf=info->bitmaps; bdf!=NULL; bdf=bdf->next )
- if ( bdf->pixelsize==ppem )
- break;
- bdfinfo[i].bdf = bdf;
- bdfinfo[i].cnt = num_items;
- }
-
- for ( i=0; i<strike_cnt; ++i ) {
- if ( (bdf = bdfinfo[i].bdf) ==NULL )
- fseek(ttf,10*bdfinfo[i].cnt,SEEK_CUR);
- else {
- bdf->prop_cnt = bdfinfo[i].cnt;
- bdf->props = malloc(bdf->prop_cnt*sizeof(BDFProperties));
- for ( j=k=0; j<bdfinfo[i].cnt; ++j, ++k ) {
- long name = getlong(ttf);
- int type = getushort(ttf);
- long value = getlong(ttf);
- bdf->props[k].type = type;
- bdf->props[k].name = getstring(ttf,string_start+name);
- switch ( type&~prt_property ) {
- case prt_int: case prt_uint:
- bdf->props[k].u.val = value;
- if ( strcmp(bdf->props[k].name,"FONT_ASCENT")==0 &&
- value<=bdf->pixelsize ) {
- bdf->ascent = value;
- bdf->descent = bdf->pixelsize-value;
- }
- break;
- case prt_string: case prt_atom:
- bdf->props[k].u.str = getstring(ttf,string_start+value);
- k = CheckForNewlines(bdf,k);
- break;
- }
- }
- }
- }
- free(bdfinfo);
-}
-
-
-/* ************************************************************************** */
-/* ************************* The 'FFTM' table ************************* */
-/* ************************* Output ************************* */
-/* ************************************************************************** */
-
-/* FontForge timestamp table */
-/* Contains: */
-/* date of fontforge sources */
-/* date of font's (not file's) creation */
-/* date of font's modification */
-int ttf_fftm_dump(SplineFont *sf,struct alltabs *at) {
- int32 results[2];
-
- at->fftmf = tmpfile2();
-
- putlong(at->fftmf,0x00000001); /* Version */
-
- cvt_unix_to_1904(LibFF_ModTime,results);
- putlong(at->fftmf,results[1]);
- putlong(at->fftmf,results[0]);
-
- cvt_unix_to_1904(sf->creationtime,results);
- putlong(at->fftmf,results[1]);
- putlong(at->fftmf,results[0]);
-
- cvt_unix_to_1904(sf->modificationtime,results);
- putlong(at->fftmf,results[1]);
- putlong(at->fftmf,results[0]);
-
- at->fftmlen = ftell(at->fftmf); /* had better be 7*4 */
- /* It will never be misaligned */
- if ( (at->fftmlen&1)!=0 )
- putc(0,at->fftmf);
- if ( ((at->fftmlen+1)&2)!=0 )
- putshort(at->fftmf,0);
-return( true );
-}