void SSRegenerateFromSpiros(SplineSet *spl) { SplineSet *temp; if ( spl->spiro_cnt<=1 ) return; if ( !has_spiro) return; SplineSetBeziersClear(spl); temp = SpiroCP2SplineSet(spl->spiros); if ( temp!=NULL ) { spl->first = temp->first; spl->last = temp->last; chunkfree(temp,sizeof(SplineSet)); } else { /* didn't converge... or something */ int i; SplinePoint *sp, *last; last = spl->first = SplinePointCreate(spl->spiros[0].x, spl->spiros[0].y); for ( i=1; i<spl->spiro_cnt; ++i ) { sp = SplinePointCreate(spl->spiros[i].x, spl->spiros[i].y); SplineMake3(last,sp); last = sp; } if ( SPIRO_SPL_OPEN(spl)) spl->last = last; else { SplineMake3(last,spl->first); spl->last = spl->first; } } spl->beziers_need_optimizer = true; }
void nlt_exprfree(struct expr *e) { if ( e==NULL ) return; nlt_exprfree(e->op1); nlt_exprfree(e->op2); nlt_exprfree(e->op3); chunkfree(e,sizeof(*e)); }
static void TraceDataFree(TraceData *td) { TraceData *next; while ( td!=NULL ) { next = td->next; chunkfree(td,sizeof(TraceData)); td = next; } }
static int DoDelayedEvents(gpointer data) { struct delayed_event *info = (struct delayed_event *) data; if ( info!=NULL ) { (info->func)(info->data); chunkfree(info,sizeof(struct delayed_event)); } return( FALSE ); /* cancel timer */ }
static void AnchorD_FreeAll(AnchorDlg *a) { struct state *old, *oldnext; free(a->xadjust.corrections); free(a->yadjust.corrections); for ( old = a->orig_vals; old!=NULL; old=oldnext ) { oldnext = old->next; chunkfree(old,sizeof(struct state)); } AnchorD_FreeChar(a); }
void GroupFree(Group *g) { int i; if ( g==NULL ) return; free(g->name); free(g->glyphs); for ( i=0; i<g->kid_cnt; ++i ) GroupFree(g->kids[i]); free(g->kids); chunkfree(g,sizeof(Group)); }
int indicator_constrs_ASL(ASL *asl, void *v, Add_Indicator add_indic, int errinfo[2]) { LCADJ_Info lci; cde *logc; int i, n, nlogc, rc; real chunk1[Gulp]; static char who[] = "indicator_constrs_ASL"; ASL_CHECK(asl, ASL_read_fg, who); if (!(nlogc = n_lcon)) return 0; memset(&lci, 0, sizeof(lci)); lci.v = v; lci.tfree0 = chunk1; n = n_var; lci.s = (ograd**)Malloc(n*(sizeof(int) + sizeof(ograd*))); lci.z = (int*)(lci.s + n); memset(lci.s, 0, n*sizeof(ograd*)); lci.n1lc = (sizeof(Lconstr) + sizeof(real) - 1) / sizeof(real); lci.n1og = (sizeof(ograd) + sizeof(real) - 1) / sizeof(real); lci.asl = asl; lci.nlv[1] = i = nlvb; lci.nlv[0] = i - nlvbi; lci.nlv[3] = i = nlvc; lci.nlv[2] = i - nlvci; if (nlvo > nlvc) i = nlvo; lci.nlv[5] = i; lci.nlv[4] = i - nlvoi; lci.errinfo = errinfo; lci.add_indic = add_indic; logc = ((ASL_fg*)asl)->I.lcon_de_; for(i = rc = 0; i < nlogc; ++i) if ((rc = add_indicator(i, &lci, logc[i].e))) break; if (lci.tchunks) chunkfree(&lci); free(lci.s); return rc; }
void SSRegenerateFromSpiros(SplineSet * spl) { /* Regenerate an updated SplineSet from SpiroCPs after edits are done. */ if (spl->spiro_cnt <= 1 || !has_spiro) return; SplineSet *temp=SpiroCP2SplineSet(spl->spiros); if (temp != NULL) { /* Regenerated new SplineSet. Discard old copy. Keep new copy. */ SplineSetBeziersClear(spl); spl->first=temp->first; spl->last=temp->last; chunkfree(temp, sizeof(SplineSet)); } else { /* Didn't converge... or something ...therefore let's fake-it. */ int i; SplinePoint *sp, *first, *last; if ((last=first = SplinePointCreate(spl->spiros[0].x, spl->spiros[0].y))==NULL) return; for (i=1; i < spl->spiro_cnt; ++i) { if ((sp=SplinePointCreate(spl->spiros[i].x, spl->spiros[i].y))) { SplineMake3(last, sp); last=sp; } else break; /* ...have problem, but keep what we got so far */ } /* dump the prior SplineSet and now show this line-art instead */ SplineSetBeziersClear(spl); spl->first=first; if (SPIRO_SPL_OPEN(spl)) spl->last=last; else { SplineMake3(last, spl->first); spl->last=spl->first; } } spl->beziers_need_optimizer=true; }
void SCRemoveSelectedMinimumDistances(SplineChar *sc,int inx) { /* Remove any minimum distance where at least one of the two points is */ /* selected */ MinimumDistance *md, *prev, *next; SplineSet *ss; SplinePoint *sp; prev = NULL; for ( md = sc->md; md!=NULL; md = next ) { next = md->next; if ( (inx==2 || inx==md->x) && ((md->sp1!=NULL && md->sp1->selected) || (md->sp2!=NULL && md->sp2->selected))) { if ( prev==NULL ) sc->md = next; else prev->next = next; chunkfree(md,sizeof(MinimumDistance)); } else prev = md; } for ( ss=sc->layers[ly_fore].splines; ss!=NULL; ss=ss->next ) { for ( sp=ss->first; ; ) { if ( sp->selected ) { if ( inx==2 ) sp->roundx = sp->roundy = false; else if ( inx==1 ) sp->roundx = false; else sp->roundy = false; } if ( sp->next==NULL ) break; sp = sp->next->to; if ( sp==ss->first ) break; } } }
struct splinepointlist * bezctx_ff_close(bezctx *z) { bezctx_ff *bc = (bezctx_ff *)z; SplineSet *ss = bc->ss; if (!bc->is_open && ss!=NULL ) { if ( ss->first!=ss->last && RealNear(ss->first->me.x,ss->last->me.x) && RealNear(ss->first->me.y,ss->last->me.y)) { ss->first->prevcp = ss->last->prevcp; ss->first->noprevcp = ss->last->noprevcp; ss->first->prev = ss->last->prev; ss->first->prev->to = ss->first; SplinePointFree(ss->last); ss->last = ss->first; } else { SplineMake3(ss->last,ss->first); ss->last = ss->first; } } chunkfree(bc,sizeof(bezctx_ff)); return( ss ); }
void AW_KernRemoveBelowThreshold(SplineFont *sf,int threshold) { int i; KernPair *kp, *prev, *next; if ( threshold==0 ) return; for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) { prev = NULL; for ( kp = sf->glyphs[i]->kerns; kp!=NULL; kp = next ) { next = kp->next; if ( kp->off>=threshold || kp->off<=-threshold ) prev = kp; else { if ( prev==NULL ) sf->glyphs[i]->kerns = next; else prev->next = next; chunkfree(kp,sizeof(KernPair)); } } } MVReKernAll(sf); }
SplineSet *SpiroCP2SplineSet(spiro_cp *spiros) { /* Create a SplineSet from the given spiros_code_points.*/ int n; int any = 0; SplineSet *ss; int lastty = 0; if ( spiros==NULL ) return( NULL ); for ( n=0; spiros[n].ty!=SPIRO_END; ++n ) if ( SPIRO_SELECTED(&spiros[n]) ) ++any; if ( n==0 ) return( NULL ); if ( n==1 ) { /* Spiro only haS 1 code point sofar (no conversion needed yet) */ if ( (ss=chunkalloc(sizeof(SplineSet)))==NULL || \ (ss->first=ss->last=SplinePointCreate(spiros[0].x,spiros[0].y))==NULL ) { chunkfree(ss,sizeof(SplineSet)); return( NULL ); } } else { /* Spiro needs to be converted to bezier curves using libspiro. */ bezctx *bc; if ( (bc=new_bezctx_ff())==NULL ) return( NULL ); if ( (spiros[0].ty&0x7f)=='{' ) { lastty = spiros[n-1].ty; spiros[n-1].ty = '}'; } if ( !any ) { #if _LIBSPIRO_FUN if ( TaggedSpiroCPsToBezier0(spiros,bc)==0 ) { if ( lastty ) spiros[n-1].ty = lastty; free(bc); return( NULL ); } #else TaggedSpiroCPsToBezier(spiros,bc); #endif } else { int i; spiro_cp *nspiros; if ( (nspiros=malloc((n+1)*sizeof(spiro_cp)))==NULL ) { if ( lastty ) spiros[n-1].ty = lastty; free(bc); return( NULL ); } memcpy(nspiros,spiros,(n+1)*sizeof(spiro_cp)); for ( i=0; nspiros[i].ty!=SPIRO_END; ++i ) nspiros[i].ty &= ~0x80; #if _LIBSPIRO_FUN if ( TaggedSpiroCPsToBezier0(nspiros,bc)==0 ) { if ( lastty ) spiros[n-1].ty = lastty; free(nspiros); free(bc); return( NULL ); } #else TaggedSpiroCPsToBezier(nspiros,bc); #endif free(nspiros); } if ( lastty ) spiros[n-1].ty = lastty; if ( (ss=bezctx_ff_close(bc))==NULL ) return( NULL ); } ss->spiros = spiros; ss->spiro_cnt = ss->spiro_max = n+1; SPLCatagorizePoints(ss); return( ss ); }
void SFD_AssignLookups(SplineFont1*sf) { PST1 *pst, *pst2; int isv; KernPair1 *kp, *kp2; KernClass1 *kc, *kc2; FPST1 *fpst; ASM1 *sm; AnchorClass1 *ac, *ac2; int gid, gid2, cnt, i, k, isgpos; SplineFont1 *subsf; SplineChar *sc, *sc2; OTLookup *otl, **all; struct lookup_subtable *sub; /* Fix up some gunk from really old versions of the sfd format */ SFDCleanupAnchorClasses(&sf->sf); if (sf->sf.uni_interp==ui_unset) sf->sf.uni_interp=interp_from_encoding(sf->sf.map->enc, ui_none); /* Fixup for an old bug */ if (sf->sf.pfminfo.os2_winascent<sf->sf.ascent/4 && !sf->sf.pfminfo.winascent_add) { sf->sf.pfminfo.winascent_add=true; sf->sf.pfminfo.os2_winascent=0; sf->sf.pfminfo.windescent_add=true; sf->sf.pfminfo.os2_windescent=0; } /* First handle the PSTs, no complications here */ k=0; do { subsf = sf->sf.subfontcnt==0?sf:(SplineFont1 *) (sf->sf.subfonts[k]); for (gid=0; gid<subsf->sf.glyphcnt; ++gid) if ((sc=subsf->sf.glyphs[gid]) != NULL) { for (pst=(PST1 *) (sc->possub); pst != NULL; pst=(PST1 *) (pst->pst.next)) { if (pst->pst.type==pst_lcaret || pst->pst.subtable != NULL) continue; /* Nothing to do, or already done */ otl = CreateLookup(sf, pst->tag, pst->script_lang_index, pst->flags, pst->pst.type); sub=CreateSubtable(otl, sf); /* There might be another PST with the same flags on this glyph */ /* And we must fixup the current pst */ for (pst2=pst; pst2 != NULL; pst2=(PST1 *) (pst2->pst.next)) { if (pst2->tag==pst->tag && pst2->script_lang_index==pst->script_lang_index && pst2->flags==pst->flags && pst2->pst.type==pst->pst.type) pst2->pst.subtable=sub; } for (gid2=gid+1; gid2<subsf->sf.glyphcnt; ++gid2) if ((sc2=subsf->sf.glyphs[gid2]) != NULL) { for (pst2=(PST1 *) (sc2->possub); pst2 != NULL; pst2=(PST1 *) (pst2->pst.next)) { if (pst2->tag==pst->tag && pst2->script_lang_index == pst->script_lang_index && pst2->flags==pst->flags && pst2->pst.type==pst->pst.type) pst2->pst.subtable=sub; } } } } ++k; } while (k<sf->sf.subfontcnt); /* Now kerns. May need to merge kernclasses to kernpair lookups (different subtables, of course */ for (isv=0; isv<2; ++isv) { k=0; do { subsf = sf->sf.subfontcnt == 0?sf:(SplineFont1 *) (sf->sf.subfonts[k]); for (gid=0; gid<subsf->sf.glyphcnt; ++gid) if ((sc=subsf->sf.glyphs[gid]) != NULL) { for (kp=(KernPair1 *) (isv?sc->vkerns:sc->kerns); kp != NULL; kp=(KernPair1 *) (kp->kp.next)) { if (kp->kp.subtable != NULL) continue; /* already done */ otl = CreateLookup(sf, isv?CHR('v', 'k', 'r', 'n'):CHR('k', 'e', 'r', 'n'), kp->sli, kp->flags, pst_pair); sub=CreateSubtable(otl, sf); /* There might be another kp with the same flags on this glyph */ /* And we must fixup the current kp */ for (kp2=kp; kp2 != NULL; kp2=(KernPair1 *) (kp2->kp.next)) { if (kp2->sli==kp->sli && kp2->flags==kp->flags) kp2->kp.subtable=sub; } for (gid2=gid+1; gid2<subsf->sf.glyphcnt; ++gid2) if ((sc2=subsf->sf.glyphs[gid2]) != NULL) { for (kp2 = (KernPair1 *) (isv?sc2->vkerns:sc2->kerns); kp2 != NULL; kp2=(KernPair1 *) (kp2->kp.next)) { if (kp2->sli==kp->sli && kp2->flags==kp->flags) kp2->kp.subtable=sub; } } /* And there might be a kerning class... */ for (kc = (KernClass1 *) (isv?sf->sf.vkerns:sf->sf.kerns); kc != NULL; kc=(KernClass1 *) (kc->kc.next)) { if (kc->sli==kp->sli && kc->flags==kp->flags && kc->kc.subtable==NULL) { sub=CreateSubtable(otl, sf); sub->per_glyph_pst_or_kern=false; sub->kc=&kc->kc; kc->kc.subtable=sub; } } } } ++k; } while (k<sf->sf.subfontcnt); /* Or there might be a kerning class all by its lonesome */ for (kc=(KernClass1 *) (isv?sf->sf.vkerns:sf->sf.kerns); kc != NULL; kc=(KernClass1 *) (kc->kc.next)) { if (kc->kc.subtable==NULL) { otl = CreateLookup(sf, isv?CHR('v', 'k', 'r', 'n'):CHR('k', 'e', 'r', 'n'), kc->sli, kc->flags, pst_pair); for (kc2=kc; kc2 != NULL; kc2=(KernClass1 *) (kc2->kc.next)) { if (kc->sli==kc2->sli && kc->flags==kc2->flags && kc2->kc.subtable==NULL) { sub=CreateSubtable(otl, sf); sub->per_glyph_pst_or_kern=false; sub->kc=&kc2->kc; kc2->kc.subtable=sub; } } } } } /* Every FPST and ASM lives in its own lookup with one subtable */ /* But the old format refered to nested lookups by tag, and now we refer */ /* to the lookup itself, so fix that up */ for (fpst=(FPST1 *) sf->sf.possub; fpst != NULL; fpst=((FPST1 *) fpst->fpst.next)) { otl = CreateLookup(sf, fpst->tag, fpst->script_lang_index, fpst->flags, fpst->fpst.type); sub=CreateSubtable(otl, sf); sub->per_glyph_pst_or_kern=false; sub->fpst=&fpst->fpst; fpst->fpst.subtable=sub; FPSTReplaceTagsWithLookups(&fpst->fpst, sf); } for (sm=(ASM1 *) sf->sf.sm; sm != NULL; sm=((ASM1 *) sm->sm.next)) { otl=CreateMacLookup(sf, sm); sub=CreateSubtable(otl, sf); sub->per_glyph_pst_or_kern=false; sub->sm=&sm->sm; sm->sm.subtable=sub; if (sm->sm.type==asm_context) ASMReplaceTagsWithLookups(&sm->sm, sf); } /* We retained the old nested feature tags so we could do the above conversion */ /* of tag to lookup. Get rid of them now */ for (isgpos=0;isgpos<2;isgpos++) { for (otl=sf->sf.gsplookups[isgpos];otl!=NULL;otl=otl->next) { if (otl->features != NULL && otl->features->scripts==NULL) { chunkfree(otl->features, sizeof(FeatureScriptLangList)); otl->features=NULL; } } } /* Anchor classes are complicated, because I foolishly failed to distinguish */ /* between mark to base and mark to ligature classes. So one AC might have */ /* both. If so we need to turn it into two ACs, and have separate lookups */ /* for each */ for (ac=(AnchorClass1 *) (sf->sf.anchor); ac != NULL; ac=(AnchorClass1 *) ac->ac.next) { ACHasBaseLig(sf, ac); if (ac->has_ligatures && !ac->has_bases) ac->ac.type=act_mklg; else if (ac->has_ligatures && ac->has_bases) ACDisassociateLigatures(sf, ac); } for (ac=(AnchorClass1 *) (sf->sf.anchor); ac != NULL; ac=(AnchorClass1 *) ac->ac.next) { if (ac->ac.subtable==NULL) { otl=CreateACLookup(sf, ac); sub=CreateSubtable(otl, sf); for (ac2=ac; ac2 != NULL; ac2=(AnchorClass1 *) ac2->ac.next) { if (ac2->feature_tag==ac->feature_tag && ac2->script_lang_index==ac->script_lang_index && ac2->flags==ac->flags && ac2->ac.type==ac->ac.type && ac2->merge_with==ac->merge_with) ac2->ac.subtable=sub; } } } /* Now I want to order the gsub lookups. I shan't bother with the gpos */ /* lookups because I didn't before */ for (otl=sf->sf.gsplookups[0], cnt=0; otl != NULL; otl=otl->next, ++cnt); if (cnt != 0) { all=malloc(cnt * sizeof(OTLookup *)); for (otl=sf->sf.gsplookups[0], cnt=0; otl != NULL; otl=otl->next, ++cnt) { all[cnt]=otl; otl->lookup_index=GSubOrder(sf, otl->features); } qsort(all, cnt, sizeof(OTLookup *), order_lookups); sf->sf.gsplookups[0]=all[0]; for (i=1; i<cnt; ++i) all[i-1]->next=all[i]; all[cnt-1]->next=NULL; free(all); } for (isgpos=0;isgpos<2;isgpos++) { for (otl=sf->sf.gsplookups[isgpos],cnt=0;otl!=NULL;otl=otl->next) { otl->lookup_index=cnt++; NameOTLookup(otl,&sf->sf); } } }
static int add_indicator(int ci, LCADJ_Info *lci, expr *e) { Lconstr *lc; int compl, i, j, k, sense, vk; real *LU, rhs; if (lci->tchunks) chunkfree(lci); lci->freeog = 0; lci->tfree = lci->tfree0; lci->ntfree = Gulp; for(i = 0; i < 2; ++i) *(lci->plc[i] = &lci->lc[i]) = 0; k = lcadj(lci, e); if (!k) { lci->errinfo[0] = ci; return 1; } vk = lci->vk; rhs = lci->rhs; compl = 0; switch(lci->b[0]) { case 0: /* > */ if (rhs < 0. || rhs >= 1.) { bad_cmpop: lci->errinfo[0] = ci; lci->errinfo[1] = vk; return 2; } break; case 1: /* >= */ if (rhs <= 0. || rhs > 1.) goto bad_cmpop; break; case 2: /* <= */ if (rhs < 0. || rhs >= 1.) goto bad_cmpop; compl = 1; break; case 3: /* < */ if (rhs <= 0. || rhs > 1.) goto bad_cmpop; compl = 1; break; case 4: /* == */ if (rhs == 1.) break; if (rhs == 0.) { compl = 1; break; } goto bad_cmpop; case 5: /* != */ if (rhs == 0.) break; if (rhs == 1.) { compl = 1; break; } goto bad_cmpop; } for(j = 0; j < k; j++, compl = 1 - compl) { for(lc = lci->lc[j]; lc; lc = lc->next) { LU = lc->LU; if (LU[0] > negInfinity) { rhs = LU[0]; sense = LU[1] == rhs ? 2: 1; } else { rhs = LU[1]; sense = 0; } if ((i = lci->add_indic(lci->v, vk, compl, sense, lc->nx, lc->z, lc->x, rhs))) { badret: lci->errinfo[0] = i; return 3; } if (sense == 1 && LU[1] < Infinity && (i = lci->add_indic(lci->v, vk, compl, sense, lc->nx, lc->z, lc->x, rhs))) goto badret; } } return 0; }