24 : QPaintEngine( QPaintEngine::AllFeatures )
25 , mPaintDevice( dxfDevice )
43 return QPaintEngine::User;
55 if ( state.state() & QPaintEngine::DirtyTransform )
56 mTransform = state.transform();
58 if ( state.state() & QPaintEngine::DirtyPen )
61 if ( state.state() & QPaintEngine::DirtyBrush )
62 mBrush = state.brush();
65 void QgsDxfPaintEngine::setRing(
QgsPointSequence &polyline,
const QPointF *points,
int pointCount )
68 for (
int i = 0; i < pointCount; ++i )
69 polyline.append( toDxfCoordinates( points[i] ) );
75 if ( !mDxf || !mPaintDevice )
80 setRing( polygon.last(), points, pointCount );
82 if ( mode == QPaintEngine::PolylineMode )
84 if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
85 mDxf->
writePolyline( polygon.at( 0 ), mLayer, QStringLiteral(
"CONTINUOUS" ), mPen.color(), currentWidth() );
89 if ( mBrush.style() != Qt::NoBrush )
90 mDxf->
writePolygon( polygon, mLayer, QStringLiteral(
"SOLID" ), mBrush.color() );
96 int pathLength = path.elementCount();
97 for (
int i = 0; i < pathLength; ++i )
99 const QPainterPath::Element &pathElem = path.elementAt( i );
100 if ( pathElem.type == QPainterPath::MoveToElement )
102 moveTo( pathElem.x, pathElem.y );
104 else if ( pathElem.type == QPainterPath::LineToElement )
106 lineTo( pathElem.x, pathElem.y );
108 else if ( pathElem.type == QPainterPath::CurveToElement )
110 curveTo( pathElem.x, pathElem.y );
112 else if ( pathElem.type == QPainterPath::CurveToDataElement )
114 mCurrentCurve.append( QPointF( pathElem.x, pathElem.y ) );
120 if ( !mPolygon.isEmpty() && mBrush.style() != Qt::NoBrush )
121 mDxf->
writePolygon( mPolygon, mLayer, QStringLiteral(
"SOLID" ), mBrush.color() );
126 void QgsDxfPaintEngine::moveTo(
double dx,
double dy )
130 mCurrentPolygon.append( QPointF( dx, dy ) );
133 void QgsDxfPaintEngine::lineTo(
double dx,
double dy )
136 mCurrentPolygon.append( QPointF( dx, dy ) );
139 void QgsDxfPaintEngine::curveTo(
double dx,
double dy )
142 if ( !mCurrentPolygon.isEmpty() )
143 mCurrentCurve.append( mCurrentPolygon.last() );
145 mCurrentCurve.append( QPointF( dx, dy ) );
148 void QgsDxfPaintEngine::endPolygon()
150 if ( mCurrentPolygon.size() > 1 )
152 if ( mPen.style() != Qt::NoPen )
153 drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
156 setRing( mPolygon.last(), mCurrentPolygon.constData(), mCurrentPolygon.size() );
158 mCurrentPolygon.clear();
161 void QgsDxfPaintEngine::endCurve()
163 if ( mCurrentCurve.empty() )
166 if ( mCurrentPolygon.empty() )
168 mCurrentCurve.clear();
172 if ( mCurrentCurve.size() >= 3 )
175 for (
int i = 1; i <= 20; ++i )
177 mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
181 else if ( mCurrentCurve.size() == 2 )
183 mCurrentPolygon.append( mCurrentCurve.at( 1 ) );
185 mCurrentCurve.clear();
190 if ( !mDxf || !mPaintDevice || !lines || mPen.style() == Qt::NoPen )
193 for (
int i = 0; i < lineCount; ++i )
195 mDxf->
writeLine( toDxfCoordinates( lines[i].p1() ),
196 toDxfCoordinates( lines[i].p2() ),
197 mLayer, QStringLiteral(
"CONTINUOUS" ), mPen.color(), currentWidth() );
201 QgsPoint QgsDxfPaintEngine::toDxfCoordinates( QPointF pt )
const 203 if ( !mPaintDevice || !mDxf )
206 QPointF dxfPt = mPaintDevice->
dxfCoordinates( mTransform.map( pt ) ) + mShift;
207 return QgsPoint( dxfPt.x(), dxfPt.y() );
211 double QgsDxfPaintEngine::currentWidth()
const 219 QPointF QgsDxfPaintEngine::bezierPoint(
const QList<QPointF> &controlPolygon,
double t )
223 int cPolySize = controlPolygon.size();
226 QList<QPointF>::const_iterator it = controlPolygon.constBegin();
228 for ( ; it != controlPolygon.constEnd(); ++it )
230 bPoly = bernsteinPoly( cPolySize - 1, i, t );
231 x += ( it->x() * bPoly );
232 y += ( it->y() * bPoly );
236 return QPointF( x, y );
239 double QgsDxfPaintEngine::bernsteinPoly(
int n,
int i,
double t )
244 return lower( n, i ) * power( t, i ) * power( ( 1 - t ), ( n - i ) );
247 int QgsDxfPaintEngine::lower(
int n,
int i )
249 if ( i >= 0 && i <= n )
251 return faculty( n ) / ( faculty( i ) * faculty( n - i ) );
259 double QgsDxfPaintEngine::power(
double a,
int b )
265 for (
int i = 2; i <= std::abs( b ); i++ )
274 int QgsDxfPaintEngine::faculty(
int n )
282 if ( n == 0 || n == 1 )
285 for ( i = n - 1; i >= 2; i-- )
void writeLine(const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
A paint device for drawing into dxf files.
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
void drawPath(const QPainterPath &path) override
void updateState(const QPaintEngineState &state) override
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
QgsDxfPaintEngine(const QgsDxfPaintDevice *dxfDevice, QgsDxfExport *dxf)
Point geometry type, with support for z-dimension and m-values.
QVector< QgsPoint > QgsPointSequence
QVector< QgsPointSequence > QgsRingSequence
void drawLines(const QLineF *lines, int lineCount) override
QPointF dxfCoordinates(QPointF pt) const
Converts a point from device coordinates to dxf coordinates.
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
QPaintEngine::Type type() const override
bool begin(QPaintDevice *pdev) override
double widthScaleFactor() const
Returns scale factor for line width.