Rev 18114 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/
#include "scribushelper.h"
// Functions to convert from lib2geom to FPointArray and vice versa
void scribus_curve(FPointArray *cr, Geom::Curve const& c)
{
if(Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&c))
{
cr->addPoint(currentPoint);
cr->addPoint(currentPoint);
cr->addPoint((*line_segment)[1][0], (*line_segment)[1][1]);
cr->addPoint((*line_segment)[1][0], (*line_segment)[1][1]);
currentPoint = FPoint((*line_segment)[1][0], (*line_segment)[1][1]);
}
else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const*>(&c))
{
std::vector<Geom::Point> points = quadratic_bezier->points();
Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]);
Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]);
cr->addPoint(currentPoint);
cr->addPoint(b1[0], b1[1]);
cr->addPoint(points[2][0], points[2][1]);
cr->addPoint(b2[0], b2[1]);
currentPoint = FPoint(points[2][0], points[2][1]);
}
else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const*>(&c))
{
std::vector<Geom::Point> points = cubic_bezier->points();
cr->addPoint(currentPoint);
cr->addPoint(points[1][0], points[1][1]);
cr->addPoint(points[3][0], points[3][1]);
cr->addPoint(points[2][0], points[2][1]);
currentPoint = FPoint(points[3][0], points[3][1]);
}
else
{
//this case handles sbasis as well as all other curve types
Geom::Path sbasis_path = Geom::path_from_sbasis(c.toSBasis(), 0.1);
currentPoint = FPoint(sbasis_path.initialPoint()[0], sbasis_path.initialPoint()[1]);
//recurse to convert the new path resulting from the sbasis to svgd
for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter)
{
scribus_curve(cr, *iter);
}
}
}
void geomPath2FPointArray(FPointArray *p, Geom::Path &pp)
{
currentPoint = FPoint(pp.initialPoint()[0], pp.initialPoint()[1]);
for(Geom::Path::iterator iter(pp.begin()), end(pp.end()); iter != end; ++iter)
{
scribus_curve(p, *iter);
}
if (pp.closed())
p->setMarker();
}
void Piecewise2FPointArray(FPointArray *p, Geom::Piecewise<Geom::D2<Geom::SBasis> > &pp)
{
std::vector<Geom::Path> pa = path_from_piecewise( pp, 0.1);
std::vector<Geom::Path>::iterator it(pa.begin());
for(; it != pa.end(); it++)
{
geomPath2FPointArray(p, *it);
}
}
void D2sb2d2FPointArray(FPointArray* cr, Geom::D2<Geom::SBasis2d> const &sb2, int num, double width)
{
Geom::D2<Geom::SBasis> B;
for(int ui = 0; ui <= num; ui++)
{
double u = ui / static_cast<double>(num);
B[0] = extract_u(sb2[0], u);// + Linear(u);
B[1] = extract_u(sb2[1], u);
for(unsigned i = 0; i < 2; i ++)
{
B[i] = B[i]*(width/2) + Geom::Linear(width/4);
}
Geom::Path pp = path_from_sbasis(B, 0.1);
geomPath2FPointArray(cr, pp);
cr->setMarker();
}
for(int vi = 0; vi <= num; vi++)
{
double v = vi / static_cast<double>(num);
B[1] = extract_v(sb2[1], v);// + Linear(v);
B[0] = extract_v(sb2[0], v);
for(unsigned i = 0; i < 2; i ++)
{
B[i] = B[i]*(width/2) + Geom::Linear(width/4);
}
Geom::Path pp = path_from_sbasis(B, 0.1);
geomPath2FPointArray(cr, pp);
cr->setMarker();
}
}
std::vector<Geom::Path> FPointArray2geomPath(FPointArray &p, bool closed)
{
std::vector<Geom::Path> pa;
Geom::Path ret = Geom::Path();
Geom::Point cur;
FPoint np, np1, np2, np3;
bool nPath = true;
if (p.size() > 3)
{
for (int poi=0; poi < p.size()-3; poi += 4)
{
if (p.isMarker(poi))
{
if (closed)
ret.close();
pa.push_back(ret);
ret.clear();
nPath = true;
continue;
}
if (nPath)
{
np = p.point(poi);
cur = Geom::Point(np.x(), np.y());
nPath = false;
}
np = p.point(poi);
np1 = p.point(poi+1);
np2 = p.point(poi+3);
np3 = p.point(poi+2);
if ((np == np1) && (np2 == np3))
{
// Geom::Point pe = Geom::Point(np3.x(), np3.y());
// ret.append(Geom::LineSegment(cur, pe));
Geom::Point pc1 = Geom::Point(np1.x()+0.001, np1.y()+0.001);
Geom::Point pc2 = Geom::Point(np2.x()+0.001, np2.y()+0.001);
Geom::Point pe = Geom::Point(np3.x(), np3.y());
ret.append(Geom::CubicBezier(cur, pc1, pc2, pe));
cur = pe;
}
else
{
Geom::Point pc1 = Geom::Point(np1.x(), np1.y());
Geom::Point pc2 = Geom::Point(np2.x(), np2.y());
Geom::Point pe = Geom::Point(np3.x(), np3.y());
ret.append(Geom::CubicBezier(cur, pc1, pc2, pe));
cur = pe;
}
}
}
if (closed)
ret.close();
pa.push_back(ret);
return pa;
}
Geom::Piecewise<Geom::D2<Geom::SBasis> > FPointArray2Piecewise(FPointArray &p, bool closed)
{
Geom::Piecewise<Geom::D2<Geom::SBasis> > patternpwd2;
std::vector<Geom::Path> originald = FPointArray2geomPath(p, closed);
for (unsigned int i=0; i < originald.size(); i++)
{
patternpwd2.concat( originald[i].toPwSb() );
}
return patternpwd2;
}
// Functions to convert from lib2geom to QPainterPath and vice versa
void arthur_curve(QPainterPath *cr, Geom::Curve const& c)
{
if(Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&c))
{
cr->lineTo(QPointF((*line_segment)[1][0], (*line_segment)[1][1]));
}
else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const*>(&c))
{
std::vector<Geom::Point> points = quadratic_bezier->points();
Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]);
Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]);
cr->cubicTo(b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]);
}
else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const*>(&c))
{
std::vector<Geom::Point> points = cubic_bezier->points();
cr->cubicTo(points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]);
}
else
{
//this case handles sbasis as well as all other curve types
Geom::Path sbasis_path = Geom::path_from_sbasis(c.toSBasis(), 0.1);
cr->moveTo(sbasis_path.initialPoint()[0], sbasis_path.initialPoint()[1]);
//recurse to convert the new path resulting from the sbasis to svgd
for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter)
{
arthur_curve(cr, *iter);
}
}
}
void geomPath2QPainterPath(QPainterPath *p, Geom::Path &pp)
{
p->moveTo(pp.initialPoint()[0], pp.initialPoint()[1]);
for(Geom::Path::iterator iter(pp.begin()), end(pp.end()); iter != end; ++iter)
{
arthur_curve(p, *iter);
}
if (pp.closed())
p->closeSubpath();
}
void Piecewise2QPainterPath(QPainterPath *p, Geom::Piecewise<Geom::D2<Geom::SBasis> > &pp)
{
std::vector<Geom::Path> pa = path_from_piecewise( pp, 0.1);
std::vector<Geom::Path>::iterator it(pa.begin());
for(; it != pa.end(); it++)
{
geomPath2QPainterPath(p, *it);
}
}
void D2sb2d2QPainterPath(QPainterPath* cr, Geom::D2<Geom::SBasis2d> const &sb2, int num, double width)
{
Geom::D2<Geom::SBasis> B;
for(int ui = 0; ui <= num; ui++)
{
double u = ui / static_cast<double>(num);
B[0] = extract_u(sb2[0], u);// + Linear(u);
B[1] = extract_u(sb2[1], u);
for(unsigned i = 0; i < 2; i ++)
{
B[i] = B[i]*(width/2) + Geom::Linear(width/4);
}
Geom::Path pp = path_from_sbasis(B, 0.1);
geomPath2QPainterPath(cr, pp);
// cr->setMarker();
}
for(int vi = 0; vi <= num; vi++)
{
double v = vi / static_cast<double>(num);
B[1] = extract_v(sb2[1], v);// + Linear(v);
B[0] = extract_v(sb2[0], v);
for(unsigned i = 0; i < 2; i ++)
{
B[i] = B[i]*(width/2) + Geom::Linear(width/4);
}
Geom::Path pp = path_from_sbasis(B, 0.1);
geomPath2QPainterPath(cr, pp);
// cr->setMarker();
}
}
std::vector<Geom::Path> QPainterPath2geomPath(QPainterPath &p, bool closed)
{
std::vector<Geom::Path> pa;
Geom::Path ret = Geom::Path();
Geom::Point cur;
bool WasM = false;
for (int i = 0; i < p.elementCount(); ++i)
{
const QPainterPath::Element &elm = p.elementAt(i);
switch (elm.type)
{
case QPainterPath::MoveToElement:
if (WasM)
{
if (closed)
ret.close();
pa.push_back(ret);
ret.clear();
}
WasM = true;
cur = Geom::Point(elm.x, elm.y);
break;
case QPainterPath::LineToElement:
ret.append(Geom::LineSegment(cur, Geom::Point(elm.x, elm.y)));
cur = Geom::Point(elm.x, elm.y);
break;
case QPainterPath::CurveToElement:
{
Geom::Point pc1 = Geom::Point(elm.x, elm.y);
Geom::Point pc2 = Geom::Point(p.elementAt(i+1).x, p.elementAt(i+1).y);
Geom::Point pe = Geom::Point(p.elementAt(i+2).x, p.elementAt(i+2).y);
ret.append(Geom::CubicBezier(cur, pc1, pc2, pe));
cur = pe;
}
break;
default:
break;
}
}
if (closed)
ret.close();
pa.push_back(ret);
return pa;
}
Geom::Piecewise<Geom::D2<Geom::SBasis> > QPainterPath2Piecewise(QPainterPath &p, bool closed)
{
Geom::Piecewise<Geom::D2<Geom::SBasis> > patternpwd2;
std::vector<Geom::Path> originald = QPainterPath2geomPath(p, closed);
for (unsigned int i=0; i < originald.size(); i++)
{
patternpwd2.concat( originald[i].toPwSb() );
}
return patternpwd2;
}