PathCutting.cpp revision 77eda576f455eeb23c7b92510f38bc60738473ab
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh/*
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * PathCutting.cpp
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * nlivarot
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh *
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Created by fred on someday in 2004.
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * public domain
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh *
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Additional Code by Authors:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Richard Hughes <cyreve@users.sf.net>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh *
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Copyright (C) 2005 Richard Hughes
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh *
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh * Released under GNU GPL, read the file 'COPYING' for more information
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh */
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <cstring>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <string>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <cstdio>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <typeinfo>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include "Path.h"
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include "style.h"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh#include "livarot/path-description.h"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh#include "libnr/nr-point-matrix-ops.h"
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include "libnr/nr-convert2geom.h"
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <2geom/pathvector.h>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <2geom/point.h>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <2geom/matrix.h>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <2geom/sbasis-to-bezier.h>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include <2geom/curves.h>
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include "../display/canvas-bpath.h"
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh#include "helper/geom-curves.h"
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshvoid Path::DashPolyline(float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( nbD <= 0 || body <= 0.0001 ) return; // pas de tirets, en fait
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh std::vector<path_lineto> orig_pts = pts;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh pts.clear();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int lastMI=-1;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int curP = 0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int lastMP = -1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh for (int i = 0; i < int(orig_pts.size()); i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( orig_pts[curP].isMoveTo == polyline_moveto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( lastMI >= 0 && lastMI < i-1 ) { // au moins 2 points
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh DashSubPath(i-lastMI,lastMP, orig_pts, head,tail,body,nbD,dashs,stPlain,stOffset);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastMI=i;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastMP=curP;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curP++;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( lastMI >= 0 && lastMI < int(orig_pts.size()) - 1 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh DashSubPath(orig_pts.size() - lastMI, lastMP, orig_pts, head, tail, body, nbD, dashs, stPlain, stOffset);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emikloshvoid Path::DashPolylineFromStyle(SPStyle *style, float scale, float min_len)
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh{
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if (style->stroke_dash.n_dash) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh double dlen = 0.0;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh for (int i = 0; i < style->stroke_dash.n_dash; i++) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dlen += style->stroke_dash.dash[i] * scale;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if (dlen >= min_len) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh NRVpathDash dash;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dash.offset = style->stroke_dash.offset * scale;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dash.n_dash = style->stroke_dash.n_dash;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dash.dash = g_new(double, dash.n_dash);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh for (int i = 0; i < dash.n_dash; i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dash.dash[i] = style->stroke_dash.dash[i] * scale;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int nbD=dash.n_dash;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh float *dashs=(float*)malloc((nbD+1)*sizeof(float));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh while ( dash.offset >= dlen ) dash.offset-=dlen;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh dashs[0]=dash.dash[0];
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh for (int i=1; i<nbD; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dashs[i]=dashs[i-1]+dash.dash[i];
68664e00e2372534b4df2fdc5f54f836bafece18miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh // modulo dlen
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh this->DashPolyline(0.0, 0.0, dlen, nbD, dashs, true, dash.offset);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh free(dashs);
a4d12a5147f3d1d6b568a326e39ef5dca384248dmiklosh g_free(dash.dash);
1667116521643e2475184b048e0abb77a2aa9735miklosh }
cb814cb0df20053ca3ef16ce55da474435daf045miklosh }
cb814cb0df20053ca3ef16ce55da474435daf045miklosh}
cb814cb0df20053ca3ef16ce55da474435daf045miklosh
cb814cb0df20053ca3ef16ce55da474435daf045miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshvoid Path::DashSubPath(int spL, int spP, std::vector<path_lineto> const &orig_pts, float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( spL <= 0 || spP == -1 ) return;
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double totLength=0;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh NR::Point lastP;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh lastP = orig_pts[spP].p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int i=1;i<spL;i++) {
cb814cb0df20053ca3ef16ce55da474435daf045miklosh NR::Point const n = orig_pts[spP + i].p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point d=n-lastP;
1667116521643e2475184b048e0abb77a2aa9735miklosh double nl=NR::L2(d);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( nl > 0.0001 ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh totLength+=nl;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP=n;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
1667116521643e2475184b048e0abb77a2aa9735miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( totLength <= head+tail ) return; // tout mange par la tete et la queue
1667116521643e2475184b048e0abb77a2aa9735miklosh
1667116521643e2475184b048e0abb77a2aa9735miklosh double curLength=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh double dashPos=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh int dashInd=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh bool dashPlain=false;
1667116521643e2475184b048e0abb77a2aa9735miklosh double lastT=0;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh int lastPiece=-1;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh lastP = orig_pts[spP].p;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh for (int i=1;i<spL;i++) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh NR::Point n;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh int nPiece=-1;
1667116521643e2475184b048e0abb77a2aa9735miklosh double nT=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( back ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh n = orig_pts[spP + i].p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh nPiece = orig_pts[spP + i].piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nT = orig_pts[spP + i].t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh n = orig_pts[spP + i].p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point d=n-lastP;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double nl=NR::L2(d);
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if ( nl > 0.0001 ) {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh double stLength=curLength;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh double enLength=curLength+nl;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh // couper les bouts en trop
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if ( curLength <= head && curLength+nl > head ) {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh nl-=head-curLength;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh curLength=head;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh dashInd=0;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh dashPos=stOffset;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh bool nPlain=stPlain;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh while ( dashs[dashInd] < stOffset ) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dashInd++;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh nPlain=!(nPlain);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if ( dashInd >= nbD ) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dashPos=0;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh dashInd=0;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if ( nPlain == true && dashPlain == false ) {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh NR::Point p=(enLength-curLength)*lastP+(curLength-stLength)*n;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh p/=(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( back ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double pT=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( nPiece == lastPiece ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh pT=(lastT*(enLength-curLength)+nT*(curLength-stLength))/(enLength-stLength);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh pT=(nPiece*(curLength-stLength))/(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh AddPoint(p,nPiece,pT,true);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddPoint(p,true);
1667116521643e2475184b048e0abb77a2aa9735miklosh }
1667116521643e2475184b048e0abb77a2aa9735miklosh } else if ( nPlain == false && dashPlain == true ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dashPlain=nPlain;
1667116521643e2475184b048e0abb77a2aa9735miklosh }
1667116521643e2475184b048e0abb77a2aa9735miklosh // faire les tirets
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( curLength >= head /*&& curLength+nl <= totLength-tail*/ ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh while ( curLength <= totLength-tail && nl > 0 ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( enLength <= totLength-tail ) nl=enLength-curLength; else nl=totLength-tail-curLength;
1667116521643e2475184b048e0abb77a2aa9735miklosh double leftInDash=body-dashPos;
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( dashInd < nbD ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh leftInDash=dashs[dashInd]-dashPos;
1667116521643e2475184b048e0abb77a2aa9735miklosh }
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( leftInDash <= nl ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh bool nPlain=false;
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( dashInd < nbD ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh dashPos=dashs[dashInd];
1667116521643e2475184b048e0abb77a2aa9735miklosh dashInd++;
1667116521643e2475184b048e0abb77a2aa9735miklosh if ( dashPlain ) nPlain=false; else nPlain=true;
1667116521643e2475184b048e0abb77a2aa9735miklosh } else {
1667116521643e2475184b048e0abb77a2aa9735miklosh dashInd=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh dashPos=0;
1667116521643e2475184b048e0abb77a2aa9735miklosh //nPlain=stPlain;
1667116521643e2475184b048e0abb77a2aa9735miklosh nPlain=dashPlain;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if ( nPlain == true && dashPlain == false ) {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh NR::Point p=(enLength-curLength-leftInDash)*lastP+(curLength+leftInDash-stLength)*n;
1cda9431ef400135f5e1bd899a94b921bdad0eafmiklosh p/=(enLength-stLength);
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if ( back ) {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh double pT=0;
68664e00e2372534b4df2fdc5f54f836bafece18miklosh if ( nPiece == lastPiece ) {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh pT=(lastT*(enLength-curLength-leftInDash)+nT*(curLength+leftInDash-stLength))/(enLength-stLength);
68664e00e2372534b4df2fdc5f54f836bafece18miklosh } else {
68664e00e2372534b4df2fdc5f54f836bafece18miklosh pT=(nPiece*(curLength+leftInDash-stLength))/(enLength-stLength);
68664e00e2372534b4df2fdc5f54f836bafece18miklosh }
68664e00e2372534b4df2fdc5f54f836bafece18miklosh AddPoint(p,nPiece,pT,true);
68664e00e2372534b4df2fdc5f54f836bafece18miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddPoint(p,true);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else if ( nPlain == false && dashPlain == true ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point p=(enLength-curLength-leftInDash)*lastP+(curLength+leftInDash-stLength)*n;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh p/=(enLength-stLength);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( back ) {
1667116521643e2475184b048e0abb77a2aa9735miklosh double pT=0;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh if ( nPiece == lastPiece ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh pT=(lastT*(enLength-curLength-leftInDash)+nT*(curLength+leftInDash-stLength))/(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh pT=(nPiece*(curLength+leftInDash-stLength))/(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddPoint(p,nPiece,pT,false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh AddPoint(p,false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dashPlain=nPlain;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curLength+=leftInDash;
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh nl-=leftInDash;
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh } else {
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh dashPos+=nl;
fba63a357654d8b3e84c60007e40aa698cd45d19miklosh curLength+=nl;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nl=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( dashPlain ) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh if ( back ) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh AddPoint(n,nPiece,nT,false);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddPoint(n,false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nl=enLength-curLength;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curLength <= totLength-tail && curLength+nl > totLength-tail ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nl=totLength-tail-curLength;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dashInd=0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh dashPos=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bool nPlain=false;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( nPlain == true && dashPlain == false ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( nPlain == false && dashPlain == true ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point p=(enLength-curLength)*lastP+(curLength-stLength)*n;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh p/=(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( back ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double pT=0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( nPiece == lastPiece ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh pT=(lastT*(enLength-curLength)+nT*(curLength-stLength))/(enLength-stLength);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh pT=(nPiece*(curLength-stLength))/(enLength-stLength);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddPoint(p,nPiece,pT,false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh AddPoint(p,false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh dashPlain=nPlain;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // continuer
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curLength=enLength;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP=n;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastPiece=nPiece;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastT=nT;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshGeom::PathVector *
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshPath::MakePathVector()
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::PathVector *pv = new Geom::PathVector();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Path * currentpath = NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point lastP,bezSt,bezEn;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int bezNb=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i=0;i<int(descr_cmd.size());i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int const typ = descr_cmd[i]->getType();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh switch ( typ ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_close:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->close(true);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_lineto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::LineSegment>(Geom::Point(nData->p[0], nData->p[1]));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_moveto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh pv->push_back(Geom::Path());
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath = &pv->back();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->start(Geom::Point(nData->p[0], nData->p[1]));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_arcto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh /* TODO: add testcase for this descr_arcto case */
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::SVGEllipticalArc>( nData->rx, nData->ry, nData->angle, nData->large, !nData->clockwise, to_2geom(nData->p) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_cubicto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x1=lastP[0]+0.333333*nData->start[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y1=lastP[1]+0.333333*nData->start[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x2=nData->p[0]-0.333333*nData->end[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y2=nData->p[1]-0.333333*nData->end[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x3=nData->p[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y3=nData->p[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::CubicBezier>( Geom::Point(x1,y1) , Geom::Point(x2,y2) , Geom::Point(x3,y3) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_bezierto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( nData->nb <= 0 ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::LineSegment>( Geom::Point(nData->p[0], nData->p[1]) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezNb=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else if ( nData->nb == 1 ){
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrIntermBezierTo *iData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i+1]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x1=0.333333*(lastP[0]+2*iData->p[0]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y1=0.333333*(lastP[1]+2*iData->p[1]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x2=0.333333*(nData->p[0]+2*iData->p[0]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y2=0.333333*(nData->p[1]+2*iData->p[1]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x3=nData->p[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y3=nData->p[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::CubicBezier>( Geom::Point(x1,y1) , Geom::Point(x2,y2) , Geom::Point(x3,y3) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezNb=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezSt = 2*lastP-nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezEn = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezNb = nData->nb;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastP = nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_interm_bezier:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( bezNb > 0 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point p_m=nData->p,p_s=0.5*(bezSt+p_m),p_e;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( bezNb > 1 ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrIntermBezierTo *iData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i+1]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh p_e=0.5*(p_m+iData->p);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh p_e=bezEn;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point cp1=0.333333*(p_s+2*p_m),cp2=0.333333*(2*p_m+p_e);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x1=cp1[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y1=cp1[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x2=cp2[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y2=cp2[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble x3=p_e[0];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh gdouble y3=p_e[1];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh currentpath->appendNew<Geom::CubicBezier>( Geom::Point(x1,y1) , Geom::Point(x2,y2) , Geom::Point(x3,y3) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bezNb--;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh return pv;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshvoid Path::AddCurve(Geom::Curve const &c)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if( is_straight_curve(c) )
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh LineTo( from_2geom(c.finalPoint()) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh /*
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const *>(c)) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh ...
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh */
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const *>(&c)) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Point tmp = (*cubic_bezier)[3];
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Point tms = 3 * ((*cubic_bezier)[1] - (*cubic_bezier)[0]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Point tme = 3 * ((*cubic_bezier)[3] - (*cubic_bezier)[2]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh CubicTo (from_2geom(tmp), from_2geom(tms), from_2geom(tme));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc const *>(&c)) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh ArcTo( from_2geom(svg_elliptical_arc->finalPoint()),
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh svg_elliptical_arc->ray(0), svg_elliptical_arc->ray(1),
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh svg_elliptical_arc->rotation_angle(),
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh svg_elliptical_arc->large_arc_flag(), !svg_elliptical_arc->sweep_flag() );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh //this case handles sbasis as well as all other curve types
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(c.toSBasis(), 0.1);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh //recurse to convert the new path resulting from the sbasis to svgd
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddCurve(*iter);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh/** append is false by default: it means that the path should be resetted. If it is true, the path is not resetted and Geom::Path will be appended as a new path
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh */
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshvoid Path::LoadPath(Geom::Path const &path, Geom::Matrix const &tr, bool doTransformation, bool append)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (!append) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh SetBackData (false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Reset();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (path.empty())
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh return;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // TODO: this can be optimized by not generating a new path here, but doing the transform in AddCurve
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // directly on the curve parameters
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Path const pathtr = doTransformation ? path * tr : path;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh MoveTo( from_2geom(pathtr.initialPoint()) );
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for(Geom::Path::const_iterator cit = pathtr.begin(); cit != pathtr.end_open(); ++cit) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddCurve(*cit);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if (pathtr.closed()) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh // check if closing segment is empty before adding it
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Geom::Curve const &crv = pathtr.back_closed();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( !crv.isDegenerate() ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh AddCurve(crv);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh Close();
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh }
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh}
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020mikloshvoid Path::LoadPathVector(Geom::PathVector const &pv)
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh{
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh LoadPathVector(pv, Geom::Matrix(), false);
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh}
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020mikloshvoid Path::LoadPathVector(Geom::PathVector const &pv, Geom::Matrix const &tr, bool doTransformation)
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh{
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh SetBackData (false);
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh Reset();
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for(Geom::PathVector::const_iterator it = pv.begin(); it != pv.end(); ++it) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh LoadPath(*it, tr, doTransformation, true);
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh }
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh}
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh/**
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh * \return Length of the lines in the pts vector.
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh */
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020mikloshdouble Path::Length()
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh{
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh if ( pts.empty() ) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh return 0;
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh }
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh NR::Point lastP = pts[0].p;
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh double len = 0;
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (std::vector<path_lineto>::const_iterator i = pts.begin(); i != pts.end(); i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh if ( i->isMoveTo != polyline_moveto ) {
1db439af43130c9695dbbb661e893d56006bb072miklosh len += NR::L2(i->p - lastP);
1db439af43130c9695dbbb661e893d56006bb072miklosh }
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072miklosh lastP = i->p;
1db439af43130c9695dbbb661e893d56006bb072miklosh }
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072miklosh return len;
1db439af43130c9695dbbb661e893d56006bb072miklosh}
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072mikloshdouble Path::Surface()
1db439af43130c9695dbbb661e893d56006bb072miklosh{
1db439af43130c9695dbbb661e893d56006bb072miklosh if ( pts.empty() ) {
1db439af43130c9695dbbb661e893d56006bb072miklosh return 0;
1db439af43130c9695dbbb661e893d56006bb072miklosh }
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072miklosh NR::Point lastM = pts[0].p;
1db439af43130c9695dbbb661e893d56006bb072miklosh NR::Point lastP = lastM;
1db439af43130c9695dbbb661e893d56006bb072miklosh
1db439af43130c9695dbbb661e893d56006bb072miklosh double surf = 0;
1db439af43130c9695dbbb661e893d56006bb072miklosh for (std::vector<path_lineto>::const_iterator i = pts.begin(); i != pts.end(); i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh if ( i->isMoveTo == polyline_moveto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh surf += NR::cross(lastM - lastP, lastM);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP = lastM = i->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh surf += NR::cross(i->p - lastP, i->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP = i->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh return surf;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshPath** Path::SubPaths(int &outNb,bool killNoSurf)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int nbRes=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Path** res=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Path* curAdd=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
920fbbf5386a5d3b1d0a1304cb71eb48112abe0dmiklosh for (int i=0;i<int(descr_cmd.size());i++) {
920fbbf5386a5d3b1d0a1304cb71eb48112abe0dmiklosh int const typ = descr_cmd[i]->getType();
920fbbf5386a5d3b1d0a1304cb71eb48112abe0dmiklosh switch ( typ ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_moveto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd->descr_cmd.size() > 1 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd->Convert(1.0);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double addSurf=curAdd->Surface();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh res[nbRes++]=curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete curAdd;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh delete curAdd;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd=new Path;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd->SetBackData(false);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd->MoveTo(nData->p);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_close:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->Close();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_lineto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd->LineTo(nData->p);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_cubicto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->CubicTo(nData->p,nData->start,nData->end);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_arcto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_bezierto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curAdd->BezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_interm_bezier:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->IntermBezierTo(nData->p);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh default:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd->descr_cmd.size() > 1 ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->Convert(1.0);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh double addSurf=curAdd->Surface();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh res[nbRes++]=curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete curAdd;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh curAdd=NULL;
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh outNb=nbRes;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return res;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9mikloshPath** Path::SubPathsWithNesting(int &outNb,bool killNoSurf,int nbNest,int* nesting,int* conts)
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int nbRes=0;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Path** res=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh Path* curAdd=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bool increment=false;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i=0;i<int(descr_cmd.size());i++) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int const typ = descr_cmd[i]->getType();
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh switch ( typ ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh case descr_moveto:
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( curAdd && increment == false ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( curAdd->descr_cmd.size() > 1 ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh // sauvegarder descr_cmd[0]->associated
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh int savA=curAdd->descr_cmd[0]->associated;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->Convert(1.0);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->descr_cmd[0]->associated=savA; // associated n'est pas utilise apres
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh double addSurf=curAdd->Surface();
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*));
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh res[nbRes++]=curAdd;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh } else {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh delete curAdd;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh } else {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh delete curAdd;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd=NULL;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh Path* hasDad=NULL;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh for (int j=0;j<nbNest;j++) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( conts[j] == i && nesting[j] >= 0 ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh int dadMvt=conts[nesting[j]];
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh for (int k=0;k<nbRes;k++) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( res[k] && res[k]->descr_cmd.empty() == false && res[k]->descr_cmd[0]->associated == dadMvt ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh hasDad=res[k];
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh break;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( conts[j] > i ) break;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh if ( hasDad ) {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd=hasDad;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh increment=true;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh } else {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd=new Path;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->SetBackData(false);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh increment=false;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh int mNo=curAdd->MoveTo(nData->p);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->descr_cmd[mNo]->associated=i;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh break;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh case descr_close:
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->Close();
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh break;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh case descr_lineto:
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh {
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh curAdd->LineTo(nData->p);
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh }
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh break;
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh case descr_cubicto:
dc4f69a188c203f2fdc65f22d0d57904a8c52dd7miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->CubicTo(nData->p,nData->start,nData->end);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_arcto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_bezierto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->BezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_interm_bezier:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->IntermBezierTo(nData->p);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh default:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd && increment == false ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( curAdd->descr_cmd.size() > 1 ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd->Convert(1.0);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double addSurf=curAdd->Surface();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*));
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh res[nbRes++]=curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh } else {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh delete curAdd;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh curAdd=NULL;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh outNb=nbRes;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh return res;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh}
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
d27f5758e12c3107ee69e66702043931e0756f6bmikloshvoid Path::ConvertForcedToVoid()
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh{
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh for (int i=0; i < int(descr_cmd.size()); i++) {
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh if ( descr_cmd[i]->getType() == descr_forced) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh delete descr_cmd[i];
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh descr_cmd.erase(descr_cmd.begin() + i);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh}
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020miklosh
3686c32a570c3df738a09b34e85fc5d6bd50d020mikloshvoid Path::ConvertForcedToMoveTo()
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point lastSeen(0, 0);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh NR::Point lastMove(0, 0);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh NR::Point lastPos(0, 0);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh for (int i = int(descr_cmd.size()) - 1; i >= 0; i--) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh int const typ = descr_cmd[i]->getType();
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh switch ( typ ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_forced:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrForced *d = dynamic_cast<PathDescrForced *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh d->p = lastPos;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_close:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrClose *d = dynamic_cast<PathDescrClose *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh d->p = lastPos;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_moveto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrMoveTo *d = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastPos = d->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh case descr_lineto:
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh PathDescrLineTo *d = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh lastPos = d->p;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh break;
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh }
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh case descr_arcto:
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh {
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh PathDescrArcTo *d = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
c53f16f52840e8c0f2be9c1cc3af633c0ba1552emiklosh lastPos = d->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_cubicto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrCubicTo *d = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastPos = d->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_bezierto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrBezierTo *d = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastPos = d->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_interm_bezier:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrIntermBezierTo *d = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastPos = d->p;
8ec52d39f409ecf67125cd4d878b844e9391e7e8miklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
8ec52d39f409ecf67125cd4d878b844e9391e7e8miklosh default:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
8ec52d39f409ecf67125cd4d878b844e9391e7e8miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh bool hasMoved = false;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh for (int i = 0; i < int(descr_cmd.size()); i++) {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh int const typ = descr_cmd[i]->getType();
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh switch ( typ ) {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_forced:
8ec52d39f409ecf67125cd4d878b844e9391e7e8miklosh if ( i < int(descr_cmd.size()) - 1 && hasMoved ) { // sinon il termine le chemin
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh delete descr_cmd[i];
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh descr_cmd[i] = new PathDescrMoveTo(lastSeen);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastMove = lastSeen;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh hasMoved = true;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_moveto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastMove = lastSeen = nData->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh hasMoved = true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_close:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastSeen=lastMove;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_lineto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastSeen=nData->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_cubicto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh lastSeen=nData->p;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh }
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh break;
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh case descr_arcto:
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh {
d27f5758e12c3107ee69e66702043931e0756f6bmiklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastSeen=nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh break;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh case descr_bezierto:
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh {
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh lastSeen=nData->p;
7a7fa095a483e8b652af9f00e5169f62c84f09b9miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_interm_bezier:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastSeen=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh default:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh}
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshstatic int CmpPosition(const void * p1, const void * p2) {
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh Path::cut_position *cp1=(Path::cut_position*)p1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh Path::cut_position *cp2=(Path::cut_position*)p2;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( cp1->piece < cp2->piece ) return -1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( cp1->piece > cp2->piece ) return 1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( cp1->t < cp2->t ) return -1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( cp1->t > cp2->t ) return 1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh return 0;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh}
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshstatic int CmpCurv(const void * p1, const void * p2) {
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh double *cp1=(double*)p1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh double *cp2=(double*)p2;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( *cp1 < *cp2 ) return -1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( *cp1 > *cp2 ) return 1;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh return 0;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh}
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshPath::cut_position* Path::CurvilignToPosition(int nbCv, double *cvAbs, int &nbCut)
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh{
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if ( nbCv <= 0 || pts.empty() || back == false ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return NULL;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh qsort(cvAbs, nbCv, sizeof(double), CmpCurv);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh cut_position *res = NULL;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nbCut = 0;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh int curCv = 0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double len = 0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double lastT = 0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int lastPiece = -1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point lastM = pts[0].p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point lastP = lastM;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (std::vector<path_lineto>::const_iterator i = pts.begin(); i != pts.end(); i++) {
082cac3fb4c7fc60e92bbd4de269550801dcea6bmiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( i->isMoveTo == polyline_moveto ) {
082cac3fb4c7fc60e92bbd4de269550801dcea6bmiklosh
082cac3fb4c7fc60e92bbd4de269550801dcea6bmiklosh lastP = lastM = i->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastT = i->t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPiece = i->piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double const add = NR::L2(i->p - lastP);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh double curPos = len;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double curAdd = add;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh while ( curAdd > 0.0001 && curCv < nbCv && curPos + curAdd >= cvAbs[curCv] ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double const theta = (cvAbs[curCv] - len) / add;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res = (cut_position*) g_realloc(res, (nbCut + 1) * sizeof(cut_position));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res[nbCut].piece = i->piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res[nbCut].t = theta * i->t + (1 - theta) * ( (lastPiece != i->piece) ? 0 : lastT);
77364929ced3ec0bc5c9f47440606615c559084emiklosh nbCut++;
77364929ced3ec0bc5c9f47440606615c559084emiklosh curAdd -= cvAbs[curCv] - curPos;
77364929ced3ec0bc5c9f47440606615c559084emiklosh curPos = cvAbs[curCv];
77364929ced3ec0bc5c9f47440606615c559084emiklosh curCv++;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh }
77364929ced3ec0bc5c9f47440606615c559084emiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh len += add;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPiece = i->piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP = i->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastT = i->t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh return res;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh}
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh/*
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshMoved from Layout-TNG-OutIter.cpp
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshTODO: clean up uses of the original function and remove
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshOriginal Comment:
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh"this function really belongs to Path. I'll probably move it there eventually,
c4723fe0caa2096d00cb31a7d1506351ba8102dbmikloshhence the Path-esque coding style"
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh*/
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshtemplate<typename T> inline static T square(T x) {return x*x;}
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshPath::cut_position Path::PointToCurvilignPosition(NR::Point const &pos, unsigned seg) const
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // if the parameter "seg" == 0, then all segments will be considered
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // In however e.g. "seg" == 6 , then only the 6th segment will be considered
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh unsigned bestSeg = 0;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh double bestRangeSquared = DBL_MAX;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double bestT = 0.0; // you need a sentinel, or make sure that you prime with correct values.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh for (unsigned i = 1 ; i < pts.size() ; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (pts[i].isMoveTo == polyline_moveto || (seg > 0 && i != seg)) continue;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh NR::Point p1, p2, localPos;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double thisRangeSquared;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (pts[i - 1].p == pts[i].p) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh thisRangeSquared = square(pts[i].p[NR::X] - pos[NR::X]) + square(pts[i].p[NR::Y] - pos[NR::Y]);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh t = 0.0;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh } else {
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh // we rotate all our coordinates so we're always looking at a mostly vertical line.
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh if (fabs(pts[i - 1].p[NR::X] - pts[i].p[NR::X]) < fabs(pts[i - 1].p[NR::Y] - pts[i].p[NR::Y])) {
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh p1 = pts[i - 1].p;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh p2 = pts[i].p;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh localPos = pos;
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh } else {
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh p1 = pts[i - 1].p.cw();
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh p2 = pts[i].p.cw();
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh localPos = pos.cw();
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh double gradient = (p2[NR::X] - p1[NR::X]) / (p2[NR::Y] - p1[NR::Y]);
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh double intersection = p1[NR::X] - gradient * p1[NR::Y];
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh /*
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh orthogonalGradient = -1.0 / gradient; // you are going to have numerical problems here.
c4723fe0caa2096d00cb31a7d1506351ba8102dbmiklosh orthogonalIntersection = localPos[NR::X] - orthogonalGradient * localPos[NR::Y];
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nearestY = (orthogonalIntersection - intersection) / (gradient - orthogonalGradient);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh expand out nearestY fully :
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nearestY = (localPos[NR::X] - (-1.0 / gradient) * localPos[NR::Y] - intersection) / (gradient - (-1.0 / gradient));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh multiply top and bottom by gradient:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nearestY = (localPos[NR::X] * gradient - (-1.0) * localPos[NR::Y] - intersection * gradient) / (gradient * gradient - (-1.0));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh and simplify to get:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh */
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double nearestY = (localPos[NR::X] * gradient + localPos[NR::Y] - intersection * gradient)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh / (gradient * gradient + 1.0);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh t = (nearestY - p1[NR::Y]) / (p2[NR::Y] - p1[NR::Y]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (t <= 0.0) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh thisRangeSquared = square(p1[NR::X] - localPos[NR::X]) + square(p1[NR::Y] - localPos[NR::Y]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh t = 0.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if (t >= 1.0) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh thisRangeSquared = square(p2[NR::X] - localPos[NR::X]) + square(p2[NR::Y] - localPos[NR::Y]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh t = 1.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh thisRangeSquared = square(nearestY * gradient + intersection - localPos[NR::X]) + square(nearestY - localPos[NR::Y]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (thisRangeSquared < bestRangeSquared) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bestSeg = i;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bestRangeSquared = thisRangeSquared;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bestT = t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh Path::cut_position result;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (bestSeg == 0) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh result.piece = 0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh result.t = 0.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh result.piece = pts[bestSeg].piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (result.piece == pts[bestSeg - 1].piece) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh result.t = pts[bestSeg - 1].t * (1.0 - bestT) + pts[bestSeg].t * bestT;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh result.t = pts[bestSeg].t * bestT;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh return result;
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh}
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh/*
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh this one also belongs to Path
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh returns the length of the path up to the position indicated by t (0..1)
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh
fd39535b3a5276f8962a3f99072668f3e63421edmiklosh TODO: clean up uses of the original function and remove
77364929ced3ec0bc5c9f47440606615c559084emiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh should this take a cut_position as a parameter?
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh*/
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshdouble Path::PositionToLength(int piece, double t)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double length = 0.0;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (unsigned i = 1 ; i < pts.size() ; i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (pts[i].isMoveTo == polyline_moveto) continue;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (pts[i].piece == piece && t < pts[i].t) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh length += NR::L2((t - pts[i - 1].t) / (pts[i].t - pts[i - 1].t) * (pts[i].p - pts[i - 1].p));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh length += NR::L2(pts[i].p - pts[i - 1].p);
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh return length;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh}
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh
e45563a3c46261d8c32014f8e516857ba01bd7b7mikloshvoid Path::ConvertPositionsToForced(int nbPos, cut_position *poss)
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh{
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh if ( nbPos <= 0 ) {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh return;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh }
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh NR::Point lastPos(0, 0);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh for (int i = int(descr_cmd.size()) - 1; i >= 0; i--) {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh int const typ = descr_cmd[i]->getType();
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh switch ( typ ) {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh case descr_forced:
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh PathDescrForced *d = dynamic_cast<PathDescrForced *>(descr_cmd[i]);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh d->p = lastPos;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh break;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh case descr_close:
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh {
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh delete descr_cmd[i];
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh descr_cmd[i] = new PathDescrLineTo(NR::Point(0, 0));
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh int fp = i - 1;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh while ( fp >= 0 && (descr_cmd[fp]->getType()) != descr_moveto ) {
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh fp--;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh if ( fp >= 0 ) {
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh PathDescrMoveTo *oData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[fp]);
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh dynamic_cast<PathDescrLineTo*>(descr_cmd[i])->p = oData->p;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh break;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh case descr_bezierto:
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh {
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh NR::Point theP = nData->p;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh if ( nData->nb == 0 ) {
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh lastPos = theP;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh }
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh break;
03e63790ef0fa2919fc5f9f3e0d018adf317919dmiklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_moveto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrMoveTo *d = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPos = d->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_lineto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *d = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPos = d->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh case descr_arcto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *d = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPos = d->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh case descr_cubicto:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *d = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPos = d->p;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh break;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh case descr_interm_bezier:
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *d = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastPos = d->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh default:
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh break;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh qsort(poss, nbPos, sizeof(cut_position), CmpPosition);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int curP=0;curP<nbPos;curP++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int cp=poss[curP].piece;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( cp < 0 || cp >= int(descr_cmd.size()) ) break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh float ct=poss[curP].t;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( ct < 0 ) continue;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( ct > 1 ) continue;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int const typ = descr_cmd[cp]->getType();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( typ == descr_moveto || typ == descr_forced || typ == descr_close ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // ponctuel= rien a faire
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh } else if ( typ == descr_lineto || typ == descr_arcto || typ == descr_cubicto ) {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh // facile: creation d'un morceau et d'un forced -> 2 commandes
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh NR::Point theP;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh NR::Point theT;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point startP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh startP=PrevPoint(cp-1);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( typ == descr_cubicto ) {
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh double len,rad;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point stD,enD,endP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *oData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[cp]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh stD=oData->start;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh enD=oData->end;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh endP=oData->p;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh TangentOnCubAt (ct, startP, *oData,true, theP,theT,len,rad);
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh }
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh theT*=len;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh InsertCubicTo(endP,(1-ct)*theT,(1-ct)*enD,cp+1);
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh InsertForcePoint(cp+1);
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[cp]);
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh nData->start=ct*stD;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh nData->end=ct*theT;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh nData->p=theP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int j=curP+1;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=2;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].t=(poss[j].t-ct)/(1-ct);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=2;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh } else if ( typ == descr_lineto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point endP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *oData = dynamic_cast<PathDescrLineTo *>(descr_cmd[cp]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh endP=oData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh theP=ct*endP+(1-ct)*startP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh InsertLineTo(endP,cp+1);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh InsertForcePoint(cp+1);
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[cp]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->p=theP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh for (int j=curP+1;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=2;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh poss[j].t=(poss[j].t-ct)/(1-ct);
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh } else {
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh poss[j].piece+=2;
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh }
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh }
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh } else if ( typ == descr_arcto ) {
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh NR::Point endP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double rx,ry,angle;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bool clockw,large;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh double delta=0;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh PathDescrArcTo *oData = dynamic_cast<PathDescrArcTo *>(descr_cmd[cp]);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh endP=oData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh rx=oData->rx;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh ry=oData->ry;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh angle=oData->angle;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh clockw=oData->clockwise;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh large=oData->large;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
522aa9b8f493ba0c8e8b0bb536a563c96f5430a8miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh double sang,eang;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ArcAngles(startP,endP,rx,ry,angle,large,clockw,sang,eang);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if (clockw) {
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh if ( sang < eang ) sang += 2*M_PI;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh delta=eang-sang;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( sang > eang ) sang -= 2*M_PI;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh delta=eang-sang;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( delta < 0 ) delta=-delta;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PointAt (cp,ct, theP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( delta*(1-ct) > M_PI ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertArcTo(endP,rx,ry,angle,true,clockw,cp+1);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertArcTo(endP,rx,ry,angle,false,clockw,cp+1);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertForcePoint(cp+1);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[cp]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->p=theP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( delta*ct > M_PI ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->clockwise=true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->clockwise=false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int j=curP+1;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=2;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].t=(poss[j].t-ct)/(1-ct);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=2;
797add969622b3786436365fdd275aff9a9a6373miklosh }
797add969622b3786436365fdd275aff9a9a6373miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_bezierto || typ == descr_interm_bezier ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // dur
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int theBDI=cp;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh while ( theBDI >= 0 && (descr_cmd[theBDI]->getType()) != descr_bezierto ) theBDI--;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh if ( (descr_cmd[theBDI]->getType()) == descr_bezierto ) {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh PathDescrBezierTo theBD=*(dynamic_cast<PathDescrBezierTo *>(descr_cmd[theBDI]));
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( cp >= theBDI && cp < theBDI+theBD.nb ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( theBD.nb == 1 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point endP=theBD.p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point midP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point startP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh startP=PrevPoint(theBDI-1);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[theBDI+1]);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh midP=nData->p;
7ec85862d9730e449ed5c2a86201bc9ca1daa0aamiklosh }
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh NR::Point aP=ct*midP+(1-ct)*startP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point bP=ct*endP+(1-ct)*midP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point knotP=ct*bP+(1-ct)*aP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertIntermBezierTo(bP,theBDI+2);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertBezierTo(knotP,1,theBDI+2);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertForcePoint(theBDI+2);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[theBDI+1]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->p=aP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[theBDI]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->p=knotP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int j=curP+1;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=3;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].t=(poss[j].t-ct)/(1-ct);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=3;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decouper puis repasser
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( cp > theBDI ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point pcP,ncP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[cp]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh pcP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[cp+1]);
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh ncP=nData->p;
e45563a3c46261d8c32014f8e516857ba01bd7b7miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point knotP=0.5*(pcP+ncP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertBezierTo(knotP,theBD.nb-(cp-theBDI),cp+1);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[theBDI]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->nb=cp-theBDI;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int j=curP;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curP--;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point pcP,ncP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[cp+1]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh pcP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[cp+2]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ncP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point knotP=0.5*(pcP+ncP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh InsertBezierTo(knotP,theBD.nb-1,cp+2);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[theBDI]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nData->nb=1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // decalages dans le tableau des positions de coupe
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int j=curP;j<nbPos;j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( poss[j].piece == cp ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh// poss[j].piece+=1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh poss[j].piece+=1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh curP--;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // on laisse aussi tomber
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // on laisse tomber
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh}
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322mikloshvoid Path::ConvertPositionsToMoveTo(int nbPos,cut_position* poss)
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh{
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh ConvertPositionsToForced(nbPos,poss);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh// ConvertForcedToMoveTo();
cb814cb0df20053ca3ef16ce55da474435daf045miklosh // on fait une version customizee a la place
cb814cb0df20053ca3ef16ce55da474435daf045miklosh
cb814cb0df20053ca3ef16ce55da474435daf045miklosh Path* res=new Path;
cb814cb0df20053ca3ef16ce55da474435daf045miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point lastP(0,0);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int i=0;i<int(descr_cmd.size());i++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int const typ = descr_cmd[i]->getType();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( typ == descr_moveto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point np;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrMoveTo *nData = dynamic_cast<PathDescrMoveTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh np=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point endP;
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh bool hasClose=false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int hasForced=-1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh bool doesClose=false;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int j=i+1;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (;j<int(descr_cmd.size());j++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int const ntyp = descr_cmd[j]->getType();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( ntyp == descr_moveto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh j--;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_forced ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( hasForced < 0 ) hasForced=j;
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh } else if ( ntyp == descr_close ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh hasClose=true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh break;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_lineto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[j]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh endP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_arcto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[j]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh endP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_cubicto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[j]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh endP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_bezierto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[j]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh endP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( NR::LInfty(endP-np) < 0.00001 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh doesClose=true;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( ( doesClose || hasClose ) && hasForced >= 0 ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // printf("nasty i=%i j=%i frc=%i\n",i,j,hasForced);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // aghhh.
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point nMvtP=PrevPoint(hasForced);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->MoveTo(nMvtP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh NR::Point nLastP=nMvtP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh for (int k = hasForced + 1; k < j; k++) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh int ntyp=descr_cmd[k]->getType();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh if ( ntyp == descr_moveto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // ne doit pas arriver
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_forced ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->MoveTo(nLastP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_close ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // rien a faire ici; de plus il ne peut y en avoir qu'un
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_lineto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->LineTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_arcto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_cubicto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->CubicTo(nData->p,nData->start,nData->end);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_bezierto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[k]);
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh res->BezierTo(nData->p);
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh nLastP=nData->p;
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh } else if ( ntyp == descr_interm_bezier ) {
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[k]);
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh res->IntermBezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh }
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh }
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh if ( doesClose == false ) res->LineTo(np);
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh nLastP=np;
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh for (int k=i+1;k<hasForced;k++) {
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh int ntyp=descr_cmd[k]->getType();
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh if ( ntyp == descr_moveto ) {
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh // ne doit pas arriver
1dd83d492fcbfaebb3603846cc163296d1256c97miklosh } else if ( ntyp == descr_forced ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->MoveTo(nLastP);
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh } else if ( ntyp == descr_close ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // rien a faire ici; de plus il ne peut y en avoir qu'un
5afaaeaa19bbb236d2556135e75afd28007b6c9fmiklosh } else if ( ntyp == descr_lineto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->LineTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_arcto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_cubicto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->CubicTo(nData->p,nData->start,nData->end);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_bezierto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->BezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh nLastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( ntyp == descr_interm_bezier ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[k]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->IntermBezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=nMvtP;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh i=j;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh // regular, just move on
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->MoveTo(np);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=np;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_close ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->Close();
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_forced ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->MoveTo(lastP);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_lineto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrLineTo *nData = dynamic_cast<PathDescrLineTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->LineTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_arcto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrArcTo *nData = dynamic_cast<PathDescrArcTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_cubicto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrCubicTo *nData = dynamic_cast<PathDescrCubicTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->CubicTo(nData->p,nData->start,nData->end);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_bezierto ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrBezierTo *nData = dynamic_cast<PathDescrBezierTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->BezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh lastP=nData->p;
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else if ( typ == descr_interm_bezier ) {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh PathDescrIntermBezierTo *nData = dynamic_cast<PathDescrIntermBezierTo *>(descr_cmd[i]);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh res->IntermBezierTo(nData->p);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh } else {
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh }
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh Copy(res);
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh delete res;
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh return;
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh}
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh/*
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh Local Variables:
ed09b99cb3592f9afb57d2ae3fb88e7f1aca0eb4miklosh mode:c++
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh c-file-style:"stroustrup"
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh indent-tabs-mode:nil
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh fill-column:99
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh End:
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh*/
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
3711b3e25395437ee0a09dbbb2a76d999c4ef322miklosh