25 : QPaintEngine( QPaintEngine::AllFeatures )
26 , mPaintDevice( dxfDevice )
44 return QPaintEngine::User;
56 if ( state.state() & QPaintEngine::DirtyTransform )
57 mTransform = state.transform();
59 if ( state.state() & QPaintEngine::DirtyPen )
62 if ( state.state() & QPaintEngine::DirtyBrush )
63 mBrush = state.brush();
65 if ( state.state() & QPaintEngine::DirtyOpacity )
67 mOpacity = state.opacity();
71void QgsDxfPaintEngine::setRing(
QgsPointSequence &polyline,
const QPointF *points,
int pointCount )
74 for (
int i = 0; i < pointCount; ++i )
75 polyline.append( toDxfCoordinates( points[i] ) );
81 if ( !mDxf || !mPaintDevice )
86 setRing( polygon.last(), points, pointCount );
88 if ( mode == QPaintEngine::PolylineMode )
90 if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
91 mDxf->writePolyline( polygon.at( 0 ), mLayer, QStringLiteral(
"CONTINUOUS" ), penColor(), currentWidth() );
95 if ( mBrush.style() != Qt::NoBrush )
96 mDxf->writePolygon( polygon, mLayer, QStringLiteral(
"SOLID" ), brushColor() );
102 const int pathLength = path.elementCount();
103 for (
int i = 0; i < pathLength; ++i )
105 const QPainterPath::Element &pathElem = path.elementAt( i );
106 if ( pathElem.type == QPainterPath::MoveToElement )
108 moveTo( pathElem.x, pathElem.y );
110 else if ( pathElem.type == QPainterPath::LineToElement )
112 lineTo( pathElem.x, pathElem.y );
114 else if ( pathElem.type == QPainterPath::CurveToElement )
116 curveTo( pathElem.x, pathElem.y );
118 else if ( pathElem.type == QPainterPath::CurveToDataElement )
120 mCurrentCurve.append( QPointF( pathElem.x, pathElem.y ) );
126 if ( !mPolygon.isEmpty() && mBrush.style() != Qt::NoBrush )
127 mDxf->writePolygon( mPolygon, mLayer, QStringLiteral(
"SOLID" ), brushColor() );
132void QgsDxfPaintEngine::moveTo(
double dx,
double dy )
136 mCurrentPolygon.append( QPointF( dx, dy ) );
139void QgsDxfPaintEngine::lineTo(
double dx,
double dy )
142 mCurrentPolygon.append( QPointF( dx, dy ) );
145void QgsDxfPaintEngine::curveTo(
double dx,
double dy )
148 if ( !mCurrentPolygon.isEmpty() )
149 mCurrentCurve.append( mCurrentPolygon.last() );
151 mCurrentCurve.append( QPointF( dx, dy ) );
154void QgsDxfPaintEngine::endPolygon()
156 if ( mCurrentPolygon.size() > 1 )
158 if ( mPen.style() != Qt::NoPen )
159 drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
162 setRing( mPolygon.last(), mCurrentPolygon.constData(), mCurrentPolygon.size() );
164 mCurrentPolygon.clear();
167void QgsDxfPaintEngine::endCurve()
169 if ( mCurrentCurve.empty() )
172 if ( mCurrentPolygon.empty() )
174 mCurrentCurve.clear();
178 if ( mCurrentCurve.size() >= 3 )
181 for (
int i = 1; i <= 20; ++i )
183 mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
187 else if ( mCurrentCurve.size() == 2 )
189 mCurrentPolygon.append( mCurrentCurve.at( 1 ) );
191 mCurrentCurve.clear();
196 if ( !mDxf || !mPaintDevice || !lines || mPen.style() == Qt::NoPen )
199 for (
int i = 0; i < lineCount; ++i )
201 mDxf->writeLine( toDxfCoordinates( lines[i].p1() ),
202 toDxfCoordinates( lines[i].p2() ),
203 mLayer, QStringLiteral(
"CONTINUOUS" ), penColor(), currentWidth() );
207QgsPoint QgsDxfPaintEngine::toDxfCoordinates( QPointF pt )
const
209 if ( !mPaintDevice || !mDxf )
212 const QPointF dxfPt = mPaintDevice->
dxfCoordinates( mTransform.map( pt ) ) + mShift;
213 return QgsPoint( dxfPt.x(), dxfPt.y() );
217double QgsDxfPaintEngine::currentWidth()
const
222 return mPen.widthF() * mPaintDevice->widthScaleFactor();
225QPointF QgsDxfPaintEngine::bezierPoint(
const QList<QPointF> &controlPolygon,
double t )
229 const int cPolySize = controlPolygon.size();
232 QList<QPointF>::const_iterator it = controlPolygon.constBegin();
234 for ( ; it != controlPolygon.constEnd(); ++it )
236 bPoly = bernsteinPoly( cPolySize - 1, i, t );
237 x += ( it->x() * bPoly );
238 y += ( it->y() * bPoly );
242 return QPointF( x, y );
245double QgsDxfPaintEngine::bernsteinPoly(
int n,
int i,
double t )
250 return lower( n, i ) * power( t, i ) * power( ( 1 - t ), ( n - i ) );
253int QgsDxfPaintEngine::lower(
int n,
int i )
255 if ( i >= 0 && i <= n )
257 return faculty( n ) / ( faculty( i ) * faculty( n - i ) );
265double QgsDxfPaintEngine::power(
double a,
int b )
270 const double tmp = a;
271 for (
int i = 2; i <= std::abs( b ); i++ )
280int QgsDxfPaintEngine::faculty(
int n )
288 if ( n == 0 || n == 1 )
291 for ( i = n - 1; i >= 2; i-- )
297QColor QgsDxfPaintEngine::penColor()
const
303 QColor
c = mPen.color();
304 c.setAlphaF(
c.alphaF() * mOpacity );
308QColor QgsDxfPaintEngine::brushColor()
const
312 return mBrush.color();
314 QColor
c = mBrush.color();
315 c.setAlphaF(
c.alphaF() * mOpacity );
Exports QGIS layers to the DXF format.
A paint device for drawing into dxf files.
QPointF dxfCoordinates(QPointF pt) const
Converts a point from device coordinates to dxf coordinates.
void drawPath(const QPainterPath &path) override
bool begin(QPaintDevice *pdev) override
QgsDxfPaintEngine(const QgsDxfPaintDevice *dxfDevice, QgsDxfExport *dxf)
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
void updateState(const QPaintEngineState &state) override
void drawLines(const QLineF *lines, int lineCount) override
QPaintEngine::Type type() const override
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Point geometry type, with support for z-dimension and m-values.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence