diff options
Diffstat (limited to 'Build')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h | 1 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c | 1110 |
2 files changed, 0 insertions, 1111 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h index a15b6b75325..d777f530f44 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinefont.h @@ -1914,7 +1914,6 @@ struct glyphdata; extern int UnitsParallel(BasePoint *u1,BasePoint *u2,int strict); extern int CvtPsStem3(struct growbuf *gb, SplineChar *scs[MmMax], int instance_count, int ishstem, int round); -extern struct pschars *CID2ChrsSubrs(SplineFont *cidmaster,struct cidbytes *cidbytes,int flags,int layer); extern struct pschars *SplineFont2ChrsSubrs2(SplineFont *sf, int nomwid, int defwid, const int *bygid, int cnt, int flags, struct pschars **_subrs,int layer); diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c index f387856eb75..68345708ad1 100644 --- a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/splinesave.c @@ -538,766 +538,6 @@ return( true ); return( true ); } -static void CvtPsHints(GrowBuf *gb, SplineChar *scs[MmMax], int instance_count, - int ishstem, int round, int iscjk, real *offsets ) { - StemInfo *hs[MmMax]; - real data[MmMax][6]; - int i; - real off; - - for ( i=0; i<instance_count; ++i ) - hs[i] = ishstem ? scs[i]->hstem : scs[i]->vstem; - - if ( hs[0]!=NULL && hs[0]->next!=NULL && hs[0]->next->next!=NULL && - hs[0]->next->next->next==NULL ) - if ( !iscjk && CvtPsStem3(gb, scs, instance_count, ishstem, round)) -return; - - while ( hs[0]!=NULL ) { - for ( i=0; i<instance_count; ++i ) { - off = offsets!=NULL ? offsets[i] : - ishstem ? 0 : scs[i]->lsidebearing; - if ( hs[i]->ghost ) { - data[i][0] = hs[i]->start-off+hs[i]->width; - data[i][1] = -hs[i]->width; - } else { - data[i][0] = hs[i]->start-off; - data[i][1] = hs[i]->width; - } - } - AddData(gb,data,instance_count,2,round); - if ( gb->pt+1>=gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = ishstem?1:3; /* h/v stem */ - for ( i=0; i<instance_count; ++i ) - hs[i] = hs[i]->next; - } -} - -static void CvtPsMasked(GrowBuf *gb,SplineChar *scs[MmMax], int instance_count, - int ishstem, int round, uint8 mask[12] ) { - StemInfo *hs[MmMax]; - real data[MmMax][6], off; - int i; - - for ( i=0; i<instance_count; ++i ) - hs[i] = ishstem ? scs[i]->hstem : scs[i]->vstem; - - while ( hs[0]!=NULL ) { - if ( hs[0]->hintnumber!=-1 && - (mask[hs[0]->hintnumber>>3]&(0x80>>(hs[0]->hintnumber&7))) ) { - for ( i=0; i<instance_count; ++i ) { - off = ishstem ? 0 : scs[i]->lsidebearing; - if ( hs[i]->ghost ) { - data[i][0] = hs[i]->start-off+hs[i]->width; - data[i][1] = -hs[i]->width; - } else { - data[i][0] = hs[i]->start-off; - data[i][1] = hs[i]->width; - } - } - AddData(gb,data,instance_count,2,round); - if ( gb->pt+1>=gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = ishstem?1:3; /* h/v stem */ - } - for ( i=0; i<instance_count; ++i ) - hs[i] = hs[i]->next; - } -} - -static int FigureCounters(StemInfo *stems,real *hints,int base,real offset, - int countermask_cnt, HintMask *counters) { - StemInfo *h; - int pos = base+1, subbase, cnt=0; - real last = offset; - int i; - - for ( i=0; i<countermask_cnt; ++i ) { - subbase = pos; - for ( h=stems; h!=NULL ; h=h->next ) { - if ( h->hintnumber!=-1 && (counters[i][h->hintnumber>>3]&(0x80>>(h->hintnumber&7))) ) { - hints[pos++] = h->start-last; - hints[pos++] = h->width; - last = h->start+h->width; - } - } - if ( pos!=subbase ) { - hints[pos-2] += hints[pos-1]; - hints[pos-1] = -hints[pos-1]; /* Mark end of group */ - last = offset; /* Each new group starts at 0 or lbearing */ - ++cnt; - } - } - hints[base] = cnt; -return( pos ); -} - -static void CounterHints1(GrowBuf *gb, SplineChar *sc, int round) { - real hints[HntMax*2+2]; /* At most 96 hints, no hint used more than once */ - int pos, i, j; - - if ( sc->countermask_cnt==0 ) -return; - - pos = FigureCounters(sc->hstem,hints,0,0,sc->countermask_cnt, - sc->countermasks); - /* Adobe's docs (T1_Supp.pdf, section 2.4) say these should be offset from*/ - /* the left side bearing. The example (T1_Supp.pdf, 2.6) shows them offset*/ - /* from 0. I've no idea which is correct, so I'll follow the words, think-*/ - /* that the lbearing might have been set to 0 even though it shouldn't */ - /* have been. */ - pos = FigureCounters(sc->vstem,hints,pos,sc->lsidebearing,sc->countermask_cnt, - sc->countermasks); - if ( pos==2 ) /* => no counters, one byte to say 0 h counters, one byte for 0 v counters */ -return; - for ( i=pos; i>22; i-=22 ) { - for ( j=i-22; j<i; ++j ) - AddNumber(gb,hints[j],round); - AddNumber(gb,22,round); - AddNumber(gb,12,round); - if ( gb->pt+2>=gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = 12; - *(gb->pt)++ = 16; /* CallOtherSubr */ - } - for ( j=0; j<i; ++j ) - AddNumber(gb,hints[j],round); - AddNumber(gb,i,round); - AddNumber(gb,13,round); - if ( gb->pt+2>=gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = 12; - *(gb->pt)++ = 16; /* CallOtherSubr */ -} - -static void SubrsCheck(struct pschars *subrs) { - /* <subr number presumed to be on stack> 1 3 callother pop callsubr */ - - if ( subrs->next>=subrs->cnt ) { - subrs->cnt += 100; - subrs->values = grealloc(subrs->values,subrs->cnt*sizeof(uint8 *)); - subrs->lens = grealloc(subrs->lens,subrs->cnt*sizeof(int)); - if ( subrs->keys!=NULL ) { - int i; - subrs->keys = grealloc(subrs->keys,subrs->cnt*sizeof(char *)); - for ( i=subrs->cnt-100; i<subrs->cnt; ++i ) - subrs->keys[i] = NULL; - } - } -} - -/* Does the hintmask we need already exist in a subroutine? if so return that */ -/* subr. Else build a new subr with the hints we need. Note we can only use */ -/* *stem3 commands if there are no conflicts in that coordinate, it isn't cjk*/ -/* and all the other conditions are met */ -static int FindOrBuildHintSubr(struct hintdb *hdb, uint8 mask[12], int round) { - struct mhlist *mh; - GrowBuf gb; - - for ( mh=hdb->sublist; mh!=NULL; mh=mh->next ) { - if ( memcmp(mask,mh->mask,sizeof(mask))==0 ) -return( mh->subr ); -#if 0 - /* If we find a subr for which we have all the bits set (with extras */ - /* since we didn't match) then it is safe to replace the old subr */ - /* with ours. This will save use one subr entry, and maybe a call */ - - /* Hmm. Adobe doesn't do this in their code. Doubtless they know more */ - /* about what hints imply about counters than I do */ - for ( i=0; i<12; ++i ) - if ( (mh->mask[i]&mask[i])!=mh->mask[i] ) - break; - if ( i==12 ) - break; -#endif - } - SubrsCheck(hdb->subrs); - - memset(&gb,0,sizeof(gb)); - if ( !hdb->scs[0]->hconflicts ) - CvtPsHints(&gb,hdb->scs,hdb->instance_count,true,round,hdb->iscjk,NULL); - else - CvtPsMasked(&gb,hdb->scs,hdb->instance_count,true,round,mask); - if ( !hdb->scs[0]->vconflicts ) - CvtPsHints(&gb,hdb->scs,hdb->instance_count,false,round,hdb->iscjk,NULL); - else - CvtPsMasked(&gb,hdb->scs,hdb->instance_count,false,round,mask); - if ( gb.pt+1 >= gb.end ) - GrowBuffer(&gb); - *gb.pt++ = 11; /* return */ - - /* Replace an old subroutine */ - if ( mh!=NULL ) { - free( hdb->subrs->values[mh->subr]); - hdb->subrs->values[mh->subr] = (uint8 *) copyn((char *) gb.base,gb.pt-gb.base); - hdb->subrs->lens[mh->subr] = gb.pt-gb.base; - memcpy(mh->mask,mask,sizeof(mh->mask)); - } else { - hdb->subrs->values[hdb->subrs->next] = (uint8 *) copyn((char *) gb.base,gb.pt-gb.base); - hdb->subrs->lens[hdb->subrs->next] = gb.pt-gb.base; - - mh = gcalloc(1,sizeof(struct mhlist)); - memcpy(mh->mask,mask,sizeof(mh->mask)); - mh->subr = hdb->subrs->next++; - mh->next = hdb->sublist; - hdb->sublist = mh; - } - free(gb.base); - -return( mh->subr ); -} - -static void CallTransformedHintSubr(GrowBuf *gb,struct hintdb *hdb, - SplineChar *scs[MmMax], RefChar *refs[MmMax], BasePoint trans[MmMax], - int instance_count, int round) { - HintMask hm; - int s; - - if ( HintMaskFromTransformedRef(refs[0],&trans[0],scs[0],&hm)==NULL ) -return; - s = FindOrBuildHintSubr(hdb, hm, round); - AddNumber(gb,s,round); - AddNumber(gb,4,round); /* subr 4 is (my) magic subr that does the hint subs call */ - if ( gb->pt+1 >= gb->end ) - GrowBuffer(gb); - *gb->pt++ = 10; /* callsubr */ -} - -static void HintSetup(GrowBuf *gb,struct hintdb *hdb, SplinePoint *to, - int round, int break_subr ) { - int s; - int i; - - if ( to->hintmask==NULL || hdb->noconflicts ) -return; - if ( hdb->scs[0]->hstem==NULL && hdb->scs[0]->vstem==NULL ) /* Hints are turned off. Hint mask still remains though */ -return; - for ( i=0; i<HntMax/8; ++i ) - if ( to->hintmask[i]!=0 ) - break; - if ( i==HntMax/8 ) /* Empty mask */ -return; - - s = FindOrBuildHintSubr(hdb,*to->hintmask,round); - memcpy(hdb->mask,*to->hintmask,sizeof(HintMask)); - if ( hdb->cursub == s ) { /* If we were able to redefine */ -return; /* the subroutine currently */ - } /* active then we are done */ - - if ( break_subr ) - BreakSubroutine(gb,hdb); - - AddNumber(gb,s,round); - AddNumber(gb,4,round); /* subr 4 is (my) magic subr that does the hint subs call */ - if ( gb->pt+1 >= gb->end ) - GrowBuffer(gb); - *gb->pt++ = 10; /* callsubr */ - hdb->cursub = s; - if ( break_subr ) - StartNextSubroutine(gb,hdb); -} - -static void _moveto(GrowBuf *gb,BasePoint *current,BasePoint *to,int instance_count, - int line, int round, struct hintdb *hdb) { - BasePoint temp[MmMax]; - int i, samex, samey; - real data[MmMax][6]; - - if ( gb->pt+18 >= gb->end ) - GrowBuffer(gb); - -#if 0 - if ( current->x==to->x && current->y==to->y ) { - /* we're already here */ /* Yes, but sometimes a move is required anyway */ - } else -#endif - for ( i=0; i<instance_count; ++i ) { - temp[i].x = myround(to[i].x,round); - temp[i].y = myround(to[i].y,round); - } - to = temp; - samex = samey = true; - for ( i=0; i<instance_count; ++i ) { - if ( current[i].x!=to[i].x ) samex = false; - if ( current[i].y!=to[i].y ) samey = false; - } - if ( samex ) { - for ( i=0; i<instance_count; ++i ) - data[i][0] = to[i].y-current[i].y; - AddData(gb,data,instance_count,1,round); - *(gb->pt)++ = line ? 7 : 4; /* v move/line to */ - } else if ( samey ) { - for ( i=0; i<instance_count; ++i ) - data[i][0] = to[i].x-current[i].x; - AddData(gb,data,instance_count,1,round); - *(gb->pt)++ = line ? 6 : 22; /* h move/line to */ - } else { - for ( i=0; i<instance_count; ++i ) { - data[i][0] = to[i].x-current[i].x; - data[i][1] = to[i].y-current[i].y; - } - AddData(gb,data,instance_count,2,round); - *(gb->pt)++ = line ? 5 : 21; /* r move/line to */ - } - for ( i=0; i<instance_count; ++i ) - current[i] = to[i]; - if ( !line ) - StartNextSubroutine(gb,hdb); -} - -static void moveto(GrowBuf *gb,BasePoint *current,Spline *splines[MmMax], - int instance_count, int line, int round, struct hintdb *hdb) { - BasePoint to[MmMax]; - int i; - - if ( !line) BreakSubroutine(gb,hdb); - if ( hdb!=NULL ) HintSetup(gb,hdb,splines[0]->to,round,line); - for ( i=0; i<instance_count; ++i ) - to[i] = splines[i]->to->me; - _moveto(gb,current,to,instance_count,line,round,hdb); -} - -static void splmoveto(GrowBuf *gb,BasePoint *current,SplineSet *spl[MmMax], - int instance_count, int line, int round, struct hintdb *hdb) { - BasePoint to[MmMax]; - int i; - - if ( !line) BreakSubroutine(gb,hdb); - if ( hdb!=NULL ) HintSetup(gb,hdb,spl[0]->first,round,line); - for ( i=0; i<instance_count; ++i ) - to[i] = spl[i]->first->me; - _moveto(gb,current,to,instance_count,line,round,hdb); -} - -static int NeverConflicts(RefChar *refs[MmMax], int instance_count) { - int i; - for ( i=0; i<instance_count; ++i ) - if ( refs[i]->sc->hconflicts || refs[i]->sc->vconflicts ) -return( false ); - -return( true ); -} - -static int AllStationary(RefChar *refs[MmMax], BasePoint trans[MmMax], int instance_count) { - int i; - for ( i=0; i<instance_count; ++i ) - if ( !refs[i]->justtranslated || - refs[i]->transform[4]+trans[i].x!=0 || - refs[i]->transform[5]+trans[i].y!=0 ) -return( false ); - -return( true ); -} - -static int AnyRefs(SplineChar *sc,int layer) { - -return( sc->layers[layer].refs!=NULL ); -} - -static void refmoveto(GrowBuf *gb,BasePoint *current,BasePoint rpos[MmMax], - int instance_count, int line, int round, struct hintdb *hdb, RefChar *refs[MmMax]) { - BasePoint to[MmMax]; - int i; - - if ( !line) BreakSubroutine(gb,hdb); - for ( i=0; i<instance_count; ++i ) { - to[i] = rpos[i]; - if ( refs!=NULL ) { - to[i].x += refs[i]->transform[4]; - to[i].y += refs[i]->transform[5]; - } - } - _moveto(gb,current,to,instance_count,line,round,hdb); -} - -static void curveto(GrowBuf *gb,BasePoint *current,Spline *splines[MmMax],int instance_count, - int round, struct hintdb *hdb) { - BasePoint temp1[MmMax], temp2[MmMax], temp3[MmMax], *c0[MmMax], *c1[MmMax], *s1[MmMax]; - real data[MmMax][6]; - int i, op, opcnt; - int vh, hv; - - if ( hdb!=NULL ) HintSetup(gb,hdb,splines[0]->to,round,true); - - if ( gb->pt+50 >= gb->end ) - GrowBuffer(gb); - - vh = hv = true; - for ( i=0; i<instance_count; ++i ) { - c0[i] = &splines[i]->from->nextcp; - c1[i] = &splines[i]->to->prevcp; - s1[i] = &splines[i]->to->me; - temp1[i].x = myround(c0[i]->x,round); - temp1[i].y = myround(c0[i]->y,round); - c0[i] = &temp1[i]; - temp2[i].x = myround(c1[i]->x,round); - temp2[i].y = myround(c1[i]->y,round); - c1[i] = &temp2[i]; - temp3[i].x = myround(s1[i]->x,round); - temp3[i].y = myround(s1[i]->y,round); - s1[i] = &temp3[i]; - if ( current[i].x != c0[i]->x || c1[i]->y!=s1[i]->y ) vh = false; - if ( current[i].y != c0[i]->y || c1[i]->x!=s1[i]->x ) hv = false; - } - if ( vh ) { - for ( i=0; i<instance_count; ++i ) { - data[i][0] = c0[i]->y-current[i].y; - data[i][1] = c1[i]->x-c0[i]->x; - data[i][2] = c1[i]->y-c0[i]->y; - data[i][3] = s1[i]->x-c1[i]->x; - } - op = 30; /* vhcurveto */ - opcnt = 4; - } else if ( hv ) { - for ( i=0; i<instance_count; ++i ) { - data[i][0] = c0[i]->x-current[i].x; - data[i][1] = c1[i]->x-c0[i]->x; - data[i][2] = c1[i]->y-c0[i]->y; - data[i][3] = s1[i]->y-c1[i]->y; - } - op = 31; /* hvcurveto */ - opcnt = 4; - } else { - for ( i=0; i<instance_count; ++i ) { - data[i][0] = c0[i]->x-current[i].x; - data[i][1] = c0[i]->y-current[i].y; - data[i][2] = c1[i]->x-c0[i]->x; - data[i][3] = c1[i]->y-c0[i]->y; - data[i][4] = s1[i]->x-c1[i]->x; - data[i][5] = s1[i]->y-c1[i]->y; - } - op = 8; /* rrcurveto */ - opcnt=6; - } - AddData(gb,data,instance_count,opcnt,false); - if ( gb->pt+1 >= gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = op; - - for ( i=0; i<instance_count; ++i ) - current[i] = *s1[i]; -} - -static int SplinesAreFlexible(Spline *splines[MmMax], int instance_count) { - int i, x=false, y=false; - - for ( i=0; i<instance_count; ++i ) { - if ( !splines[i]->to->flexx && !splines[i]->to->flexy ) -return( false ); - if (( x && splines[i]->to->flexy ) || ( y && splines[i]->to->flexx )) -return( false ); - x = splines[i]->to->flexx; - y = splines[i]->to->flexy; - } -return( true ); -} - -static void flexto(GrowBuf *gb,BasePoint current[MmMax],Spline *pspline[MmMax], - int instance_count,int round, struct hintdb *hdb) { - BasePoint *c0, *c1, *mid, *end=NULL; - Spline *nspline; - BasePoint offsets[MmMax][8]; - int i,j; - BasePoint temp1, temp2, temp3, temp; - real data[MmMax][6]; - - for ( j=0; j<instance_count; ++j ) { - c0 = &pspline[j]->from->nextcp; - c1 = &pspline[j]->to->prevcp; - mid = &pspline[j]->to->me; - - temp1.x = myround(c0->x,round); - temp1.y = myround(c0->y,round); - c0 = &temp1; - temp2.x = myround(c1->x,round); - temp2.y = myround(c1->y,round); - c1 = &temp2; - temp.x = myround(mid->x,round); - temp.y = myround(mid->y,round); - mid = &temp; -/* reference point is same level as current point */ - if ( current[j].y==pspline[j]->to->next->to->me.y ) { - offsets[j][0].x = mid->x-current[j].x; offsets[j][0].y = 0; - offsets[j][1].x = c0->x-mid->x; offsets[j][1].y = c0->y-current[j].y; - } else { - offsets[j][0].x = 0; offsets[j][0].y = mid->y-current[j].y; - offsets[j][1].x = c0->x-current[j].x; offsets[j][1].y = c0->y-mid->y; - } - offsets[j][2].x = c1->x-c0->x; offsets[j][2].y = c1->y-c0->y; - offsets[j][3].x = mid->x-c1->x; offsets[j][3].y = mid->y-c1->y; - nspline = pspline[j]->to->next; - c0 = &nspline->from->nextcp; - c1 = &nspline->to->prevcp; - end = &nspline->to->me; - - temp1.x = myround(c0->x,round); - temp1.y = myround(c0->y,round); - c0 = &temp1; - temp2.x = myround(c1->x,round); - temp2.y = myround(c1->y,round); - c1 = &temp2; - temp3.x = myround(end->x,round); - temp3.y = myround(end->y,round); - end = &temp3; - - offsets[j][4].x = c0->x-mid->x; offsets[j][4].y = c0->y-mid->y; - offsets[j][5].x = c1->x-c0->x; offsets[j][5].y = c1->y-c0->y; - offsets[j][6].x = end->x-c1->x; offsets[j][6].y = end->y-c1->y; - offsets[j][7].x = end->x; offsets[j][7].y = end->y; - current[j] = *end; - } - - if ( hdb!=NULL ) - HintSetup(gb,hdb,pspline[0]->to->next->to,round,false); - - if ( gb->pt+2 >= gb->end ) - GrowBuffer(gb); - - *(gb->pt)++ = 1+139; /* 1 */ - *(gb->pt)++ = 10; /* callsubr */ - for ( i=0; i<7; ++i ) { - if ( gb->pt+20 >= gb->end ) - GrowBuffer(gb); - for ( j=0; j<instance_count; ++j ) { - data[j][0] = offsets[j][i].x; - data[j][1] = offsets[j][i].y; - } - AddData(gb,data,instance_count,2,round); - *(gb->pt)++ = 21; /* rmoveto */ - *(gb->pt)++ = 2+139; /* 2 */ - *(gb->pt)++ = 10; /* callsubr */ - } - if ( gb->pt+20 >= gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = 50+139; /* 50, .50 pixels */ - for ( j=0; j<instance_count; ++j ) { - data[j][0] = offsets[j][7].x; - data[j][1] = offsets[j][7].y; - } - AddData(gb,data,instance_count,2,round); - *(gb->pt)++ = 0+139; /* 0 */ - *(gb->pt)++ = 10; /* callsubr */ - - *current = *end; -} - -static void _CvtPsSplineSet(GrowBuf *gb, SplinePointList *spl[MmMax], int instance_count, - BasePoint current[MmMax], - int round, struct hintdb *hdb, int is_order2, int stroked ) { - Spline *spline[MmMax], *first; - SplinePointList temp[MmMax], *freeme=NULL; - int i; - - if ( is_order2 ) { - freeme = spl[0] = SplineSetsPSApprox(spl[0]); - instance_count = 1; - } - while ( spl[0]!=NULL ) { - first = NULL; - for ( i=0; i<instance_count; ++i ) - SplineSetReverse(spl[i]); - /* For some reason fontographer reads its spline in in the reverse */ - /* order from that I use. I'm not sure how they do that. The result */ - /* being that what I call clockwise they call counter. Oh well. */ - /* If I reverse the splinesets after reading them in, and then again*/ - /* when saving them out, all should be well */ - if ( spl[0]->first->flexy || spl[0]->first->flexx ) { - /* can't handle a flex (mid) point as the first point. rotate the */ - /* list by one, this is possible because only closed paths have */ - /* points marked as flex, and because we can't have two flex mid- */ - /* points in a row */ - for ( i = 0; i<instance_count; ++i ) { - temp[i] = *spl[i]; - temp[i].first = temp[i].last = spl[i]->first->next->to; - spl[i] = &temp[i]; - } - if ( spl[0]->first->flexy || spl[0]->first->flexx ) { - /* well, well, well. We did have two flexes in a row */ - for ( i = 0; i<instance_count; ++i ) { - spl[i]->first->flexx = spl[i]->first->flexy = false; - } - } - } - splmoveto(gb,current,spl,instance_count,false,round,hdb); - for ( i=0; i<instance_count; ++i ) - spline[i] = spl[i]->first->next; - while ( spline[0]!=NULL && spline[0]!=first ) { - if ( first==NULL ) first = spline[0]; - if ( SplinesAreFlexible(spline,instance_count) && - (hdb->noconflicts || spline[0]->to->hintmask==NULL)) { - flexto(gb,current,spline,instance_count,round,hdb); /* does two adjacent splines */ - for ( i=0; i<instance_count; ++i ) - spline[i] = spline[i]->to->next; - } else if ( spline[0]->knownlinear && spline[0]->to==spl[0]->first ) { - /* We can finish this off with the closepath */ - break; - } else if ( spline[0]->knownlinear ) - moveto(gb,current,spline,instance_count,true,round,hdb); - else - curveto(gb,current,spline,instance_count,round,hdb); - for ( i=0; i<instance_count; ++i ) - spline[i] = spline[i]->to->next; - } - if ( !stroked || spl[0]->first->prev!=NULL ) { - if ( gb->pt+1 >= gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = 9; /* closepath */ - } - for ( i=0; i<instance_count; ++i ) { - SplineSetReverse(spl[i]); - /* Of course, I have to Reverse again to get back to my convention after*/ - /* saving */ - spl[i] = spl[i]->next; - } - } - SplinePointListsFree(freeme); -} - - -static int IsPSSeacable(SplineChar *sc,int layer) { - RefChar *ref; - - if ( sc->layers[layer].refs==NULL || sc->layers[layer].splines!=NULL ) -return( false ); - - for ( ref=sc->layers[layer].refs; ref!=NULL; ref=ref->next ) { - if ( !ref->justtranslated ) -return( false ); - } -return( true ); -} - -static RefChar *RefFindAdobe(RefChar *r, RefChar *t,int layer) { - *t = *r; - while ( t->adobe_enc==-1 && t->sc->layers[layer].refs!=NULL && - t->sc->layers[layer].refs->next==NULL && - t->sc->layers[layer].splines==NULL && - t->sc->layers[layer].refs->justtranslated ) { - t->transform[4] += t->sc->layers[layer].refs->transform[4]; - t->transform[5] += t->sc->layers[layer].refs->transform[5]; - t->adobe_enc = t->sc->layers[layer].refs->adobe_enc; - t->orig_pos = t->sc->layers[layer].refs->orig_pos; - t->sc = t->sc->layers[layer].refs->sc; - } -return( t ); -} - -static int IsSeacable(GrowBuf *gb, SplineChar *scs[MmMax], - int instance_count, int round,int layer) { - /* can be at most two chars in a seac (actually must be exactly 2, but */ - /* I'll put in a space if there's only one (and if splace is blank) */ - RefChar *r1, *r2, *rt, *refs; - RefChar space, t1, t2; - DBounds b; - int i, j, swap; - real data[MmMax][6]; - - for ( j=0 ; j<instance_count; ++j ) - if ( !IsPSSeacable(scs[j],layer)) -return( false ); - - refs = scs[0]->layers[layer].refs; - if ( refs==NULL ) -return( false ); - - r1 = refs; - if ((r2 = r1->next)==NULL ) { - RefChar *refs = r1->sc->layers[layer].refs; - if ( refs!=NULL && refs->next!=NULL && refs->next->next==NULL && - r1->sc->layers[layer].splines==NULL && - refs->adobe_enc!=-1 && refs->next->adobe_enc!=-1 ) { - r2 = refs->next; - r1 = refs; - } - } - if ( r2==NULL ) { - r2 = &space; - memset(r2,'\0',sizeof(space)); - space.adobe_enc = ' '; - space.transform[0] = space.transform[3] = 1.0; - for ( i=0; i<scs[0]->parent->glyphcnt; ++i ) - if ( scs[0]->parent->glyphs[i]!=NULL && - strcmp(scs[0]->parent->glyphs[i]->name,"space")==0 ) - break; - if ( i==scs[0]->parent->glyphcnt ) - r2 = NULL; /* No space???? */ - else { - space.sc = scs[0]->parent->glyphs[i]; - if ( space.sc->layers[layer].splines!=NULL || space.sc->layers[layer].refs!=NULL ) - r2 = NULL; - } - } else if ( r2->next!=NULL ) - r2 = NULL; - - /* check for something like "AcyrillicBreve" which has a ref to Acyril */ - /* (which doesn't have an adobe enc) which in turn has a ref to A (which */ - /* does) */ - if ( r2!=NULL ) { - if ( r1->adobe_enc==-1 ) - r1 = RefFindAdobe(r1,&t1,layer); - if ( r2->adobe_enc==-1 ) - r2 = RefFindAdobe(r2,&t2,layer); - } - -/* CID fonts have no encodings. So we can't use seac to reference characters */ -/* in them. The other requirements are just those of seac */ - if ( r2==NULL || - r1->adobe_enc==-1 || - r2->adobe_enc==-1 || - ((r1->transform[4]!=0 || r1->transform[5]!=0 || r1->sc->width!=scs[0]->width ) && - (r2->transform[4]!=0 || r2->transform[5]!=0 || r2->sc->width!=scs[0]->width)) ) -return( false ); - - swap = false; - if ( r1->transform[4]!=0 || r1->transform[5]!=0 ) { - rt = r1; r1 = r2; r2 = rt; - swap = !swap; - } - - SplineCharFindBounds(r1->sc,&b); - r1->sc->lsidebearing = round?rint(b.minx):b.minx; - SplineCharFindBounds(r2->sc,&b); - r2->sc->lsidebearing = round?rint(b.minx):b.minx; - - if ( (r1->sc->width!=scs[0]->width || r1->sc->lsidebearing!=scs[0]->lsidebearing) && - r2->sc->width==scs[0]->width && r2->sc->lsidebearing==scs[0]->lsidebearing && - r2->transform[4]==0 && r2->transform[5]==0 ) { - rt = r1; r1 = r2; r2 = rt; - swap = !swap; - } - if ( r1->sc->width!=scs[0]->width || r1->sc->lsidebearing!=scs[0]->lsidebearing || - r1->transform[4]!=0 || r1->transform[5]!=0 ) -return( false ); - - for ( j=0; j<instance_count; ++j ) { - SplineChar *r2sc = scs[j]->parent->glyphs[r2->sc->orig_pos]; - RefChar *r3, t3; - - SplineCharFindBounds(r2sc,&b); - if ( scs[j]->layers[layer].refs!=NULL && scs[j]->layers[layer].refs->next==NULL ) - r3 = r2; /* Space, not offset */ - else if ( swap ) - r3 = RefFindAdobe(scs[j]->layers[layer].refs,&t3,layer); - else - r3 = RefFindAdobe(scs[j]->layers[layer].refs->next,&t3,layer); - - b.minx = myround(b.minx,round); - data[j][0] = b.minx; - data[j][1] = r3->transform[4] + b.minx-scs[j]->lsidebearing; - data[j][2] = r3->transform[5]; - } - AddData(gb,data,instance_count,3,round); - AddNumber(gb,r1->adobe_enc,round); - AddNumber(gb,r2->adobe_enc,round); - if ( gb->pt+2>gb->end ) - GrowBuffer(gb); - *(gb->pt)++ = 12; - *(gb->pt)++ = 6; /* seac 12,6 */ - -return( true ); -} - static int _SCNeedsSubsPts(SplineChar *sc,int layer) { RefChar *ref; @@ -1330,266 +570,6 @@ return( false ); } } -static void ExpandRef1(GrowBuf *gb, SplineChar *scs[MmMax], int instance_count, - struct hintdb *hdb, RefChar *r[MmMax], BasePoint trans[MmMax], - BasePoint current[MmMax], - struct pschars *subrs, int round, int iscjk, int layer) { - BasePoint *bpt; - BasePoint rtrans[MmMax], rpos[MmMax]; - int i; - - for ( i=0; i<instance_count; ++i ) { - rtrans[i].x = r[i]->transform[4]+trans[i].x; - rtrans[i].y = r[i]->transform[5]+trans[i].y; - if ( round ) { - rtrans[i].x = rint(rtrans[i].x); - rtrans[i].y = rint(rtrans[i].y); - } - } - - BreakSubroutine(gb,hdb); - if ( r[0]->sc == scs[0] ) { - /* Hints for self */ - if ( hdb->cnt>0 && !hdb->noconflicts && NeverConflicts(r,instance_count)) { - CvtPsHints(gb,scs,instance_count,true,round,iscjk,NULL); - CvtPsHints(gb,scs,instance_count,false,round,iscjk,NULL); - } - } else { - /* Hints for a real reference */ - if ( !NeverConflicts(r,instance_count) || r[0]->sc->layers[layer].anyflexes || AnyRefs(r[0]->sc,layer) ) - /* Hints already done */; - else if ( hdb->noconflicts ) - /* Hints already done */; - else if ( r[0]->sc->hstem!=NULL || r[0]->sc->vstem!=NULL ) - CallTransformedHintSubr(gb,hdb,scs,r,trans,instance_count,round); - } - - if ( hdb!=NULL && hdb->gi!=NULL ) - bpt = hdb->gi->psubrs[r[0]->sc->ttf_glyph].startstop; - else - bpt = (BasePoint *) (subrs->keys[r[0]->sc->ttf_glyph]); - for ( i=0; i<instance_count; ++i ) { - rpos[i].x = bpt[2*i].x + rtrans[i].x; - rpos[i].y = bpt[2*i].y + rtrans[i].y; - } - refmoveto(gb,current,rpos, instance_count,false,round,hdb,NULL); - hdb->startset = true; - - if ( hdb!=NULL && hdb->gi!=NULL ) { - GlyphInfo *gi = hdb->gi; - StartNextSubroutine(gb,hdb); - gi->bits[gi->bcnt].psub_index = r[0]->sc->ttf_glyph; - ++gi->bcnt; - gi->justbroken = true; - } else { - AddNumber(gb,r[0]->sc->ttf_glyph,round); - if ( gb->pt+1>=gb->end ) - GrowBuffer(gb); - *gb->pt++ = 10; - } - - for ( i=0; i<instance_count; ++i ) { - current[i].x = bpt[2*i+1].x + rtrans[i].x; - current[i].y = bpt[2*i+1].y + rtrans[i].y; - } -} - -static void RSC2PS1(GrowBuf *gb, SplineChar *base[MmMax],SplineChar *rsc[MmMax], - struct hintdb *hdb, BasePoint *trans, struct pschars *subrs, - BasePoint current[MmMax], int flags, int iscjk, - int instance_count, int layer ) { - BasePoint subtrans[MmMax]; - SplineChar *rscs[MmMax]; - int round = (flags&ps_flag_round)? true : false; - RefChar *refs[MmMax]; - SplineSet *spls[MmMax], *freeme[MmMax]; - int i; - int wasntconflicted = hdb->noconflicts; - - for ( i=0; i<instance_count; ++i ) { - spls[i] = rsc[i]->layers[layer].splines; - if ( base[0]!=rsc[0] ) - spls[i] = freeme[i] = SPLCopyTranslatedHintMasks(spls[i],base[i],rsc[i],&trans[i]); - } - _CvtPsSplineSet(gb,spls,instance_count,current,round,hdb, - base[0]->layers[layer].order2,base[0]->parent->strokedfont); - if ( base[0]!=rsc[0] ) - for ( i=0; i<instance_count; ++i ) - SplinePointListsFree(freeme[i]); - - for ( i=0; i<instance_count; ++i ) - refs[i] = rsc[i]->layers[layer].refs; - while ( refs[0]!=NULL ) { - for ( i=0; i<instance_count; ++i ) - spls[i] = refs[i]->layers[0].splines; - if ( !refs[0]->justtranslated ) { - for ( i=0; i<instance_count; ++i ) - spls[i] = freeme[i] = SPLCopyTransformedHintMasks(refs[i],base[i],&trans[i],layer); - if ( NeverConflicts(refs,instance_count) && !hdb->noconflicts && - refs[0]->transform[1]==0 && refs[0]->transform[2]==0 ) - CallTransformedHintSubr(gb,hdb,base,refs,trans,instance_count,round); - _CvtPsSplineSet(gb,spls,instance_count,current,round,hdb, - base[0]->layers[layer].order2,base[0]->parent->strokedfont); - for ( i=0; i<instance_count; ++i ) - SplinePointListsFree(freeme[i]); - } else if ( refs[0]->sc->ttf_glyph!=0x7fff && - ((flags&ps_flag_nohints) || - !refs[0]->sc->layers[layer].anyflexes || - (refs[0]->transform[4]+trans[0].x==0 && refs[0]->transform[5]+trans[0].y==0)) && - ((flags&ps_flag_nohints) || - NeverConflicts(refs,instance_count) || - AllStationary(refs,trans,instance_count)) ) { - ExpandRef1(gb,base,instance_count,hdb,refs,trans, - current,subrs,round,iscjk,layer); - } else { - for ( i=0; i<instance_count; ++i ) { - subtrans[i].x = trans[i].x + refs[i]->transform[4]; - subtrans[i].y = trans[i].y + refs[i]->transform[5]; - rscs[i] = refs[i]->sc; - } - if ( !hdb->noconflicts && NeverConflicts(refs,instance_count)) { - CallTransformedHintSubr(gb,hdb,base,refs,trans,instance_count,round); - hdb->noconflicts = true; - } - RSC2PS1(gb,base,rscs,hdb,subtrans,subrs,current,flags,iscjk, - instance_count,layer); - hdb->noconflicts = wasntconflicted; - } - for ( i=0; i<instance_count; ++i ) - refs[i] = refs[i]->next; - } -} - -static unsigned char *SplineChar2PS(SplineChar *sc,int *len,int round,int iscjk, - struct pschars *subrs,int flags,enum fontformat format, - GlyphInfo *gi) { - DBounds b; - GrowBuf gb; - BasePoint current[MmMax]; - unsigned char *ret; - struct hintdb hintdb, *hdb=NULL; - StemInfo *oldh[MmMax], *oldv[MmMax]; - int hc[MmMax], vc[MmMax]; - BasePoint trans[MmMax]; - int instance_count, i; - SplineChar *scs[MmMax]; - real data[MmMax][6]; - MMSet *mm = sc->parent->mm; - HintMask *hm[MmMax]; - int fixuphm = false; - hm[0] = 0; - - if ( !(flags&ps_flag_nohints) && SCNeedsSubsPts(sc,format,gi->layer)) - SCFigureHintMasks(sc,gi->layer); - - if ( (format==ff_mma || format==ff_mmb) && mm!=NULL ) { - instance_count = mm->instance_count; - if ( instance_count>16 ) - instance_count = 16; - for ( i=0; i<instance_count; ++i ) - scs[i] = mm->instances[i]->glyphs[sc->orig_pos]; - } else { - instance_count = 1; - scs[0] = sc; - mm = NULL; - } - - if ( flags&ps_flag_nohints ) { - for ( i=0; i<instance_count; ++i ) { - oldh[i] = scs[i]->hstem; oldv[i] = scs[i]->vstem; - hc[i] = scs[i]->hconflicts; vc[i] = scs[i]->vconflicts; - scs[i]->hstem = NULL; scs[i]->vstem = NULL; - scs[i]->hconflicts = false; scs[i]->vconflicts = false; - } - } else { - for ( i=0; i<instance_count; ++i ) - if ( scs[i]->vconflicts || scs[i]->hconflicts ) - break; - if ( scs[0]->layers[gi->layer].splines!=NULL && i==instance_count ) { /* No conflicts */ - fixuphm = true; - for ( i=0; i<instance_count; ++i ) { - hm[i] = scs[i]->layers[gi->layer].splines->first->hintmask; - scs[i]->layers[gi->layer].splines->first->hintmask = NULL; - } - } - } - - memset(&gb,'\0',sizeof(gb)); - memset(current,'\0',sizeof(current)); - for ( i=0; i<instance_count; ++i ) { - SplineCharFindBounds(scs[i],&b); - scs[i]->lsidebearing = current[i].x = round?rint(b.minx):b.minx; - data[i][0] = b.minx; - data[i][1] = scs[i]->width; - } - AddData(&gb,data,instance_count,2,round); - *gb.pt++ = 13; /* hsbw, lbearing & width */ - - memset(&hintdb,0,sizeof(hintdb)); - hintdb.subrs = subrs; hintdb.iscjk = iscjk&~0x100; hintdb.scs = scs; - hintdb.instance_count = instance_count; - hintdb.cnt = NumberHints(scs,instance_count); - hintdb.noconflicts = true; - hintdb.gi = gi; - for ( i=0; i<instance_count; ++i ) - if ( scs[i]->hconflicts || scs[i]->vconflicts ) - hintdb.noconflicts = false; - hdb = &hintdb; - if ( gi!=NULL ) - gi->bcnt = -1; - - /* If this char is being placed in a subroutine, then we don't want to */ - /* use seac because somebody is going to call that subroutine and */ - /* add another reference to it later. CID keyed fonts also can't use */ - /* seac (they have no encoding so it doesn't work), that's what iscjk&0x100 */ - /* tests for */ - if ( scs[0]->ttf_glyph==0x7fff && !(iscjk&0x100) && !(flags&ps_flag_noseac) && - IsSeacable(&gb,scs,instance_count,round,gi->layer)) { - if ( gi ) - gi->active->wasseac = true; - /* in MM fonts, all should share the same refs, so all should be */ - /* seac-able if one is */ - } else { - iscjk &= ~0x100; - if ( iscjk && instance_count==1 ) - CounterHints1(&gb,sc,round); /* Must come immediately after hsbw */ - if ( hintdb.noconflicts ) { - CvtPsHints(&gb,scs,instance_count,true,round,iscjk,NULL); - CvtPsHints(&gb,scs,instance_count,false,round,iscjk,NULL); - } - memset(&trans,0,sizeof(trans)); - RSC2PS1(&gb,scs,scs,hdb,trans,subrs,current,flags,iscjk, - instance_count,gi->layer); - } - if ( gi->bcnt==-1 ) { /* If it's whitespace */ - gi->bcnt = 0; - StartNextSubroutine(&gb,hdb); - } - BreakSubroutine(&gb,hdb); - MoveSubrsToChar(gi); - ret = NULL; - - if ( hdb!=NULL ) { - struct mhlist *mh, *mhnext; - for ( mh=hdb->sublist; mh!=NULL; mh=mhnext ) { - mhnext = mh->next; - free(mh); - } - } - free(gb.base); - if ( flags&ps_flag_nohints ) { - for ( i=0; i<instance_count; ++i ) { - scs[i]->hstem = oldh[i]; scs[i]->vstem = oldv[i]; - scs[i]->hconflicts = hc[i]; scs[i]->vconflicts = vc[i]; - } - } else if ( fixuphm ) { - for ( i=0; i<instance_count; ++i ) - scs[i]->layers[gi->layer].splines->first->hintmask = hm[i]; - } -return( ret ); -} - - /* Mark those glyphs which can live totally in subrs */ static void SplineFont2FullSubrs1(int flags,GlyphInfo *gi) { int i; @@ -1773,96 +753,6 @@ static void SetupType1Chrs(struct pschars *chrs,struct pschars *subrs,GlyphInfo } } - -struct pschars *CID2ChrsSubrs(SplineFont *cidmaster,struct cidbytes *cidbytes,int flags,int layer) { - struct pschars *chrs = gcalloc(1,sizeof(struct pschars)); - int i, cnt, cid; - SplineFont *sf = NULL; - struct fddata *fd; - int round = (flags&ps_flag_round)? true : false; - /* I don't support mm cid files. I don't think adobe does either */ - GlyphInfo gi; - int notdef_subfont; - SplineChar dummynotdef, *sc; - - cnt = 0; notdef_subfont = -1; - for ( i=0; i<cidmaster->subfontcnt; ++i ) { - if ( cnt<cidmaster->subfonts[i]->glyphcnt ) - cnt = cidmaster->subfonts[i]->glyphcnt; - if ( cidmaster->subfonts[i]->glyphcnt>0 && - SCWorthOutputting(cidmaster->subfonts[i]->glyphs[0]) ) - notdef_subfont = i; - } - cidbytes->cidcnt = cnt; - - if ( notdef_subfont==-1 ) { - memset(&dummynotdef,0,sizeof(dummynotdef)); - dummynotdef.name = ".notdef"; - dummynotdef.parent = cidmaster->subfonts[0]; - dummynotdef.layer_cnt = layer+1; - dummynotdef.layers = gcalloc(layer+1,sizeof(Layer));; - dummynotdef.width = SFOneWidth(dummynotdef.parent); - if ( dummynotdef.width==-1 ) - dummynotdef.width = (dummynotdef.parent->ascent+dummynotdef.parent->descent); - } - - memset(&gi,0,sizeof(gi)); - gi.instance_count = 1; - gi.glyphcnt = cnt; - gi.gb = galloc(cnt*sizeof(struct glyphbits)); - gi.pmax = 3*cnt; - gi.psubrs = galloc(gi.pmax*sizeof(struct potentialsubrs)); - gi.layer = layer; - - chrs->cnt = cnt; - chrs->lens = gcalloc(cnt,sizeof(int)); - chrs->values = gcalloc(cnt,sizeof(unsigned char *)); - cidbytes->fdind = galloc(cnt*sizeof(unsigned char *)); - memset(cidbytes->fdind,-1,cnt*sizeof(unsigned char *)); - - /* In a type1 CID-keyed font we must handle subroutines subfont by subfont*/ - /* as there are no global subrs */ - for ( i=0; i<cidmaster->subfontcnt; ++i ) { - gi.sf = sf = cidmaster->subfonts[i]; - MarkTranslationRefs(sf,layer); - fd = &cidbytes->fds[i]; - memset(&gi.hashed,-1,sizeof(gi.hashed)); - gi.instance_count = 1; - gi.glyphcnt = sf->glyphcnt; - memset(gi.gb,0,sf->glyphcnt*sizeof(struct glyphbits)); - for ( cid=0; cid<cnt && cid<sf->glyphcnt; ++cid ) { - if ( cid==0 && notdef_subfont==-1 && i==cidmaster->subfontcnt-1 ) - gi.gb[0].sc = &dummynotdef; - else if ( SCWorthOutputting(sf->glyphs[cid]) && - strcmp(sf->glyphs[cid]->name,".notdef")!=0) /* We've already added .notdef */ - gi.gb[cid].sc = sf->glyphs[cid]; - if ( gi.gb[cid].sc!=NULL ) - cidbytes->fdind[cid] = i; - } - SplineFont2FullSubrs1(flags,&gi); - - for ( cid=0; cid<cnt && cid<sf->glyphcnt; ++cid ) { - if ( (sc = gi.gb[cid].sc)==NULL ) - continue; - gi.active = &gi.gb[cid]; - SplineChar2PS(sc,NULL, round,fd->iscjk|0x100,fd->subrs, - flags,ff_cid,&gi); - if ( !ff_progress_next()) { - PSCharsFree(chrs); - GIFree(&gi,&dummynotdef); -return( NULL ); - } - } - - SetupType1Subrs(fd->subrs,&gi); - SetupType1Chrs(chrs,fd->subrs,&gi,true); - GIContentsFree(&gi,&dummynotdef); - } - GIFree(&gi,&dummynotdef); - chrs->next = cnt; -return( chrs ); -} - /* ************************************************************************** */ /* ********************** Type2 PostScript CharStrings ********************** */ /* ************************************************************************** */ |