コード例 #1
0
ファイル: spiro.c プロジェクト: JasonH1/fontforge
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;
}
コード例 #2
0
ファイル: bezctx_ff.c プロジェクト: IceJacool/fontforge
static void
bezctx_ff_curveto(bezctx *z, double x1, double y1, double x2, double y2,
		  double x3, double y3)
{
    bezctx_ff *bc = (bezctx_ff *)z;
    SplinePoint *sp;

    if ( !finite(x1) || !finite(y1) || !finite(x2) || !finite(y2) || !finite(x3) || !finite(y3)) {
	nancheck(bc);
	x1 = y1 = x2 = y2 = x3 = y3 = 0;
    }
    sp = SplinePointCreate(x3,y3);
    bc->ss->last->nextcp.x = x1;
    bc->ss->last->nextcp.y = y1;
    bc->ss->last->nonextcp = false;
    sp->prevcp.x = x2;
    sp->prevcp.y = y2;
    sp->noprevcp = false;
    SplineMake3(bc->ss->last,sp);
    bc->ss->last = sp;
}
コード例 #3
0
ファイル: bezctx_ff.c プロジェクト: Patsylou/Tsukurimashou
/* Finishes an old FontAnvil bezier context, and returns the contour which was created */
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 {
	 if (SplineMake3(ss->last, ss->first) != NULL)
	    ss->last=ss->first;
      }
   }
   free(bc);
   return (ss);
}
コード例 #4
0
ファイル: mm.c プロジェクト: ystk/debian-fontforge
static char *_MMBlendChar(MMSet *mm, int gid) {
    int i, j, worthit = -1;
    int all, any, any2, all2, anyend, allend, diff;
    SplineChar *sc;
    SplinePointList *spls[MmMax], *spl, *spllast;
    SplinePoint *tos[MmMax], *to;
    RefChar *refs[MmMax], *ref, *reflast;
    KernPair *kp0, *kptest, *kp, *kplast;
    StemInfo *hs[MmMax], *h, *hlast;
    real width;

    for ( i=0; i<mm->instance_count; ++i ) {
	if ( mm->instances[i]->layers[ly_fore].order2 )
return( _("One of the multiple master instances contains quadratic splines. It must be converted to cubic splines before it can be used in a multiple master") );
	if ( gid>=mm->instances[i]->glyphcnt )
return( _("The different instances of this mm have a different number of glyphs") );
	if ( SCWorthOutputting(mm->instances[i]->glyphs[gid]) ) {
	    if ( worthit == -1 ) worthit = true;
	    else if ( worthit != true )
return( _("This glyph is defined in one instance font but not in another") );
	} else {
	    if ( worthit == -1 ) worthit = false;
	    else if ( worthit != false )
return( _("This glyph is defined in one instance font but not in another") );
	}
    }

    sc = mm->normal->glyphs[gid];
    if ( sc!=NULL ) {
	SCClearContents(sc,ly_fore);
	KernPairsFree(sc->kerns);
	sc->kerns = NULL;
	KernPairsFree(sc->vkerns);
	sc->vkerns = NULL;
    }

    if ( !worthit )
return( 0 );

    if ( sc==NULL )
	sc = SFMakeGlyphLike(mm->normal,gid,mm->instances[0]);

	/* Blend references => blend transformation matrices */
    diff = false;
    any = false; all = true;
    for ( i=0; i<mm->instance_count; ++i ) {
	refs[i] = mm->instances[i]->glyphs[gid]->layers[ly_fore].refs;
	if ( refs[i]!=NULL ) any = true;
	else all = false;
    }
    reflast = NULL;
    while ( all ) {
	ref = RefCharCreate();
	*ref = *refs[0];
	ref->layers[0].splines = NULL;
	ref->next = NULL;
	memset(ref->transform,0,sizeof(ref->transform));
	ref->sc = mm->normal->glyphs[refs[0]->sc->orig_pos];
	for ( i=0; i<mm->instance_count; ++i ) {
	    if ( ref->sc->orig_pos!=refs[i]->sc->orig_pos )
		diff = true;
	    for ( j=0; j<6; ++j )
		ref->transform[j] += refs[i]->transform[j]*mm->defweights[i];
	}
	if ( reflast==NULL )
	    sc->layers[ly_fore].refs = ref;
	else
	    reflast->next = ref;
	reflast = ref;
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    refs[i] = refs[i]->next;
	    if ( refs[i]!=NULL ) any = true;
	    else all = false;
	}
    }
    if ( any )
return( _("This glyph contains a different number of references in different instances") );
    if ( diff )
return( _("A reference in this glyph refers to a different encoding in different instances") );

	/* Blend Width */
    width = 0;
    for ( i=0; i<mm->instance_count; ++i )
	width += mm->instances[i]->glyphs[gid]->width*mm->defweights[i];
    sc->width = width;
    width = 0;
    for ( i=0; i<mm->instance_count; ++i )
	width += mm->instances[i]->glyphs[gid]->vwidth*mm->defweights[i];
    sc->vwidth = width;

	/* Blend Splines */
    any = false; all = true;
    for ( i=0; i<mm->instance_count; ++i ) {
	spls[i] = mm->instances[i]->glyphs[gid]->layers[ly_fore].splines;
	if ( spls[i]!=NULL ) any = true;
	else all = false;
    }
    spllast = NULL;
    while ( all ) {
	spl = chunkalloc(sizeof(SplinePointList));
	if ( spllast==NULL )
	    sc->layers[ly_fore].splines = spl;
	else
	    spllast->next = spl;
	spllast = spl;
	for ( i=0; i<mm->instance_count; ++i )
	    tos[i] = spls[i]->first;
	all2 = true;
	spl->last = NULL;
	while ( all2 ) {
	    to = chunkalloc(sizeof(SplinePoint));
	    to->nonextcp = tos[0]->nonextcp;
	    to->noprevcp = tos[0]->noprevcp;
	    to->nextcpdef = tos[0]->nextcpdef;
	    to->prevcpdef = tos[0]->prevcpdef;
	    to->pointtype = tos[0]->pointtype;
	    if ( tos[0]->hintmask!=NULL ) {
		to->hintmask = chunkalloc(sizeof(HintMask));
		memcpy(to->hintmask,tos[0]->hintmask,sizeof(HintMask));
	    }
	    for ( i=0; i<mm->instance_count; ++i ) {
		to->me.x += tos[i]->me.x*mm->defweights[i];
		to->me.y += tos[i]->me.y*mm->defweights[i];
		to->nextcp.x += tos[i]->nextcp.x*mm->defweights[i];
		to->nextcp.y += tos[i]->nextcp.y*mm->defweights[i];
		to->prevcp.x += tos[i]->prevcp.x*mm->defweights[i];
		to->prevcp.y += tos[i]->prevcp.y*mm->defweights[i];
	    }
	    if ( spl->last==NULL )
		spl->first = to;
	    else
		SplineMake3(spl->last,to);
	    spl->last = to;
	    any2 = false; all2 = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		if ( tos[i]->next==NULL ) tos[i] = NULL;
		else tos[i] = tos[i]->next->to;
		if ( tos[i]!=NULL ) any2 = true;
		else all2 = false;
	    }
	    if ( !all2 && any2 )
return( _("A contour in this glyph contains a different number of points in different instances") );
	    anyend = false; allend = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		if ( tos[i]==spls[i]->first ) anyend = true;
		else allend = false;
	    }
	    if ( allend ) {
		SplineMake3(spl->last,spl->first);
		spl->last = spl->first;
	break;
	    }
	    if ( anyend )
return( _("A contour in this glyph contains a different number of points in different instances") );
	}
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    spls[i] = spls[i]->next;
	    if ( spls[i]!=NULL ) any = true;
	    else all = false;
	}
    }
    if ( any )
return( _("This glyph contains a different number of contours in different instances") );

	/* Blend hints */
    for ( j=0; j<2; ++j ) {
	any = false; all = true;
	for ( i=0; i<mm->instance_count; ++i ) {
	    hs[i] = j ? mm->instances[i]->glyphs[gid]->hstem : mm->instances[i]->glyphs[gid]->vstem;
	    if ( hs[i]!=NULL ) any = true;
	    else all = false;
	}
	hlast = NULL;
	while ( all ) {
	    h = chunkalloc(sizeof(StemInfo));
	    *h = *hs[0];
	    h->where = NULL;
	    h->next = NULL;
	    h->start = h->width = 0;
	    for ( i=0; i<mm->instance_count; ++i ) {
		h->start += hs[i]->start*mm->defweights[i];
		h->width += hs[i]->width*mm->defweights[i];
	    }
	    if ( hlast!=NULL )
		hlast->next = h;
	    else if ( j )
		sc->hstem = h;
	    else
		sc->vstem = h;
	    hlast = h;
	    any = false; all = true;
	    for ( i=0; i<mm->instance_count; ++i ) {
		hs[i] = hs[i]->next;
		if ( hs[i]!=NULL ) any = true;
		else all = false;
	    }
	}
	if ( any )
return( _("This glyph contains a different number of hints in different instances") );
    }

	/* Blend kernpairs */
    /* I'm not requiring ordered kerning pairs */
    /* I'm not bothering with vertical kerning */
    kp0 = mm->instances[0]->glyphs[gid]->kerns;
    kplast = NULL;
    while ( kp0!=NULL ) {
	int off = kp0->off*mm->defweights[0];
	for ( i=1; i<mm->instance_count; ++i ) {
	    for ( kptest=mm->instances[i]->glyphs[gid]->kerns; kptest!=NULL; kptest=kptest->next )
		if ( kptest->sc->orig_pos==kp0->sc->orig_pos )
	    break;
	    if ( kptest==NULL )
return( _("This glyph contains different kerning pairs in different instances") );
	    off += kptest->off*mm->defweights[i];
	}
	kp = chunkalloc(sizeof(KernPair));
	kp->sc = mm->normal->glyphs[kp0->sc->orig_pos];
	kp->off = off;
	kp->subtable = kp0->subtable;
	if ( kplast!=NULL )
	    kplast->next = kp;
	else
	    sc->kerns = kp;
	kplast = kp;
	kp0 = kp0->next;
    }
return( 0 );
}