예제 #1
0
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;
}
예제 #2
0
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));
}
예제 #3
0
static void TraceDataFree(TraceData *td) {
    TraceData *next;

    while ( td!=NULL ) {
	next = td->next;
	chunkfree(td,sizeof(TraceData));
	td = next;
    }
}
예제 #4
0
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 */
}
예제 #5
0
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);
}
예제 #6
0
파일: groups.c 프로젝트: Cyclens/fontforge
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));
}
예제 #7
0
파일: indic_cons.c 프로젝트: MiaoLi/Codes
 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;
	}
예제 #8
0
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;
}
예제 #9
0
파일: cvhints.c 프로젝트: Hasimir/fontforge
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;
	}
    }
}
예제 #10
0
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 );
}
예제 #11
0
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);
}
예제 #12
0
파일: spiro.c 프로젝트: JasonH1/fontforge
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 );
}
예제 #13
0
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);
      }
   }
}
예제 #14
0
파일: indic_cons.c 프로젝트: MiaoLi/Codes
 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;
	}