예제 #1
0
static void CVMouseMoveSpiroPoint(CharView *cv, PressedOn *p) {
    spiro_cp *active = cv->active_cp, *merge = p->spiro;
    SplineSet *activess = cv->active_spl;
    int active_index;

    if ( active==NULL )
return;
    if ( cv->info.x==active->x && cv->info.y==active->y )
return;

    if ( !cv->recentchange ) CVPreserveState(&cv->b);

    active->x = cv->info.x;
    active->y = cv->info.y;
    CVSetCharChanged(cv,true);

    active_index = active-activess->spiros;

    if ( active!=merge && merge!=NULL && p->spl!=NULL &&
	    SPIRO_SPL_OPEN(activess) &&
	    SPIRO_SPL_OPEN(p->spl) &&
	    (active_index==0 || active_index==activess->spiro_cnt-2) &&
	    ((merge-p->spl->spiros)==0 || (merge-p->spl->spiros)==p->spl->spiro_cnt-2) ) {
	SplinePoint *activesp = active_index==0 ? activess->first : activess->last;
	SplinePoint *mergesp = (merge-p->spl->spiros)==0 ? p->spl->first : p->spl->last;
	CVMergeSplineSets(cv,activesp,activess,mergesp,p->spl);
    }
    SSRegenerateFromSpiros(activess);
    SCUpdateAll(cv->b.sc);
}
예제 #2
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;
}
예제 #3
0
SplinePointList *CVAnySelPointList(CharView *cv) {
    /* if there is exactly one point selected and it is on an open splineset */
    /*  and it is one of the endpoints of the splineset, then return that */
    /*  splineset */
    SplinePointList *spl, *found=NULL;
    Spline *spline, *first;
    int i;

    for ( spl= cv->b.layerheads[cv->b.drawmode]->splines; spl!=NULL; spl=spl->next ) {
	if ( cv->b.sc->inspiro && hasspiro()) {
	    for ( i = 0; i<spl->spiro_cnt-1; ++i ) {
		if ( SPIRO_SELECTED(&spl->spiros[i])) {
		    /* Only interesting if the single selection is at the */
		    /* start/end of an open contour */
		    if (( i!=0 && i!=spl->spiro_cnt-2 ) ||
			    !SPIRO_SPL_OPEN(spl))
return( NULL );
		    else if ( found==NULL )
			found = spl;
		    else
return( NULL );
		}
	    }
	} else {
	    if ( spl->first->selected ) {
		if ( found!=NULL )
return( NULL );			/* At least two points */
		if ( spl->first->prev!=NULL )
return( NULL );			/* Not an open splineset */
		found = spl;
	    }
	    first = NULL;
	    for ( spline = spl->first->next; spline!=NULL && spline!=first; spline=spline->to->next ) {
		if ( spline->to->selected ) {
		    if ( found!=NULL )
return( NULL );
		    if ( spline->to->next!=NULL )
return( NULL );			/* Selected point is not at end of a splineset */
		    found = spl;
		}
		if ( first==NULL ) first = spline;
	    }
	}
    }
return( found );
}
예제 #4
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;
}
예제 #5
0
static void CVMouseDownSpiroPoint(CharView *cv, GEvent *event) {
    SplineSet *sel, *ss;
    SplineChar *sc = cv->b.sc;
    spiro_cp *base, *cp;
    int base_index, cp_index, i;
    char ty = (cv->active_tool==cvt_curve?SPIRO_G4:
			    cv->active_tool==cvt_hvcurve?SPIRO_G2:
			    cv->active_tool==cvt_corner?SPIRO_CORNER:
			    cv->active_tool==cvt_tangent?SPIRO_LEFT:
			    /*cv->active_tool==cvt_pen?*/SPIRO_RIGHT);

    cv->active_spl = NULL;
    cv->active_sp = NULL;

    sel = CVAnySelPointList(cv);
    if ( sel!=NULL ) {
	if ( SPIRO_SELECTED(&sel->spiros[0]) ) base_index = 0;
	else base_index = sel->spiro_cnt-2;
	base = &sel->spiros[base_index];
	if ( base==cv->p.spiro )
return;			/* We clicked on the active point, that's a no-op */
    }
    CVPreserveState(&cv->b);
    CVClearSel(cv);
    if ( sel!=NULL ) {
	if ( (cp = cv->p.spiro)!=NULL )
	    cp_index = cp-cv->p.spl->spiros;
	cv->lastselcp = base;
	ss = sel;
	if ( base_index!=sel->spiro_cnt-2 ) {
	    SplineSetReverse(sel);
	    base = &sel->spiros[sel->spiro_cnt-2];
	    if ( cv->p.spl==sel ) {
		cp_index = sel->spiro_cnt-2-cp_index;
		cp = &sel->spiros[cp_index];
	    }
	}
	if ( cp==NULL || (cp_index!=0 && cp_index!=cv->p.spl->spiro_cnt-2) ||
		cp==base || !SPIRO_SPL_OPEN(cv->p.spl)) {
	    /* Add a new point */
	    if ( sel->spiro_cnt>=sel->spiro_max )
		sel->spiros = realloc(sel->spiros,(sel->spiro_max += 10)*sizeof(spiro_cp));
	    cp = &sel->spiros[sel->spiro_cnt-1];
	    cp[1] = cp[0];		/* Move the final 'z' */
	    cp->x = cv->p.cx;
	    cp->y = cv->p.cy;
	    cp->ty = ty;
	    SPIRO_DESELECT(cp-1);
	    ++sel->spiro_cnt;
	} else if ( cv->p.spl==sel ) {
	    /* Close the current spline set */
	    sel->spiros[0].ty = ty;
	    cv->joinvalid = true;
	    cv->joincp = *cp; SPIRO_DESELECT(&cv->joincp);
	} else {
	    /* Merge two spline sets */
	    SplinePoint *sp = cp_index==0 ? cv->p.spl->first : cv->p.spl->last;
	    SplinePoint *basesp = base_index==0 ? sel->first : sel->last;
	    cv->joincp = *cp; SPIRO_DESELECT(&cv->joincp);
	    CVMergeSPLS(cv,ss,basesp,sp);
	}
    } else if ( cv->p.spline!=NULL ) {
	/* Add an intermediate point on an already existing spline */
	ss = cv->p.spl;
	if ( ss->spiro_cnt>=ss->spiro_max )
	    ss->spiros = realloc(ss->spiros,(ss->spiro_max += 10)*sizeof(spiro_cp));
	for ( i=ss->spiro_cnt-1; i>cv->p.spiro_index; --i )
	    ss->spiros[i+1] = ss->spiros[i];
	++ss->spiro_cnt;
	cp = &ss->spiros[cv->p.spiro_index+1];
	cp->x = cv->p.cx;
	cp->y = cv->p.cy;
	cp->ty = ty;
	ss = cv->p.spl;
	cv->joinvalid = true;
	cv->joincp = *cp; SPIRO_DESELECT(&cv->joincp);
    } else {
	/* A new point on a new (open) contour */
	ss = chunkalloc(sizeof(SplineSet));
	ss->next = cv->b.layerheads[cv->b.drawmode]->splines;
	cv->b.layerheads[cv->b.drawmode]->splines = ss;
	ss->spiros = malloc((ss->spiro_max=10)*sizeof(spiro_cp));
	cp = &ss->spiros[0];
	cp->x = cv->p.cx;
	cp->y = cv->p.cy;
	cp->ty = SPIRO_OPEN_CONTOUR;
	cp[1].x = cp[1].y = 0; cp[1].ty = 'z';
	ss->spiro_cnt = 2;
    }
    SPIRO_SELECT(cp);

    SSRegenerateFromSpiros(ss);

    cv->active_spl = ss;
    cv->active_cp = cp;
    CVSetCharChanged(cv,true);
    CVInfoDraw(cv,cv->gw);
    SCUpdateAll(sc);
}