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();
    64   if ( state.state() & QPaintEngine::DirtyOpacity )
    66     mOpacity = state.opacity();
    70 void QgsDxfPaintEngine::setRing( 
QgsPointSequence &polyline, 
const QPointF *points, 
int pointCount )
    73   for ( 
int i = 0; i < pointCount; ++i )
    74     polyline.append( toDxfCoordinates( points[i] ) );
    80   if ( !mDxf || !mPaintDevice )
    85   setRing( polygon.last(), points, pointCount );
    87   if ( mode == QPaintEngine::PolylineMode )
    89     if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
    90       mDxf->
writePolyline( polygon.at( 0 ), mLayer, QStringLiteral( 
"CONTINUOUS" ), penColor(), currentWidth() );
    94     if ( mBrush.style() != Qt::NoBrush )
    95       mDxf->
writePolygon( polygon, mLayer, QStringLiteral( 
"SOLID" ), brushColor() );
   101   int pathLength = path.elementCount();
   102   for ( 
int i = 0; i < pathLength; ++i )
   104     const QPainterPath::Element &pathElem = path.elementAt( i );
   105     if ( pathElem.type == QPainterPath::MoveToElement )
   107       moveTo( pathElem.x, pathElem.y );
   109     else if ( pathElem.type == QPainterPath::LineToElement )
   111       lineTo( pathElem.x, pathElem.y );
   113     else if ( pathElem.type == QPainterPath::CurveToElement )
   115       curveTo( pathElem.x, pathElem.y );
   117     else if ( pathElem.type == QPainterPath::CurveToDataElement )
   119       mCurrentCurve.append( QPointF( pathElem.x, pathElem.y ) );
   125   if ( !mPolygon.isEmpty() && mBrush.style() != Qt::NoBrush )
   126     mDxf->
writePolygon( mPolygon, mLayer, QStringLiteral( 
"SOLID" ), brushColor() );
   131 void QgsDxfPaintEngine::moveTo( 
double dx, 
double dy )
   135   mCurrentPolygon.append( QPointF( dx, dy ) );
   138 void QgsDxfPaintEngine::lineTo( 
double dx, 
double dy )
   141   mCurrentPolygon.append( QPointF( dx, dy ) );
   144 void QgsDxfPaintEngine::curveTo( 
double dx, 
double dy )
   147   if ( !mCurrentPolygon.isEmpty() )
   148     mCurrentCurve.append( mCurrentPolygon.last() );
   150   mCurrentCurve.append( QPointF( dx, dy ) );
   153 void QgsDxfPaintEngine::endPolygon()
   155   if ( mCurrentPolygon.size() > 1 )
   157     if ( mPen.style() != Qt::NoPen )
   158       drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
   161     setRing( mPolygon.last(), mCurrentPolygon.constData(), mCurrentPolygon.size() );
   163   mCurrentPolygon.clear();
   166 void QgsDxfPaintEngine::endCurve()
   168   if ( mCurrentCurve.empty() )
   171   if ( mCurrentPolygon.empty() )
   173     mCurrentCurve.clear();
   177   if ( mCurrentCurve.size() >= 3 )
   180     for ( 
int i = 1; i <= 20; ++i ) 
   182       mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
   186   else if ( mCurrentCurve.size() == 2 )
   188     mCurrentPolygon.append( mCurrentCurve.at( 1 ) );
   190   mCurrentCurve.clear();
   195   if ( !mDxf || !mPaintDevice || !lines || mPen.style() == Qt::NoPen )
   198   for ( 
int i = 0; i < lineCount; ++i )
   200     mDxf->
writeLine( toDxfCoordinates( lines[i].p1() ),
   201                      toDxfCoordinates( lines[i].p2() ),
   202                      mLayer, QStringLiteral( 
"CONTINUOUS" ), penColor(), currentWidth() );
   206 QgsPoint QgsDxfPaintEngine::toDxfCoordinates( QPointF pt )
 const   208   if ( !mPaintDevice || !mDxf )
   211   QPointF dxfPt = mPaintDevice->
dxfCoordinates( mTransform.map( pt ) ) + mShift;
   212   return QgsPoint( dxfPt.x(), dxfPt.y() );
   216 double QgsDxfPaintEngine::currentWidth()
 const   224 QPointF QgsDxfPaintEngine::bezierPoint( 
const QList<QPointF> &controlPolygon, 
double t )
   228   int cPolySize = controlPolygon.size();
   231   QList<QPointF>::const_iterator it = controlPolygon.constBegin();
   233   for ( ; it != controlPolygon.constEnd(); ++it )
   235     bPoly = bernsteinPoly( cPolySize - 1, i, t );
   236     x += ( it->x() * bPoly );
   237     y += ( it->y() * bPoly );
   241   return QPointF( x, y );
   244 double QgsDxfPaintEngine::bernsteinPoly( 
int n, 
int i, 
double t )
   249   return lower( n, i ) * power( t, i ) * power( ( 1 - t ), ( n - i ) );
   252 int QgsDxfPaintEngine::lower( 
int n, 
int i )
   254   if ( i >= 0 && i <= n )
   256     return faculty( n ) / ( faculty( i ) * faculty( n - i ) );
   264 double QgsDxfPaintEngine::power( 
double a, 
int b )
   270   for ( 
int i = 2; i <= std::abs( b ); i++ )
   279 int QgsDxfPaintEngine::faculty( 
int n )
   287   if ( n == 0 || n == 1 )
   290   for ( i = n - 1; i >= 2; i-- )
   296 QColor QgsDxfPaintEngine::penColor()
 const   302   QColor 
c = mPen.color();
   303   c.setAlphaF( c.alphaF() * mOpacity );
   307 QColor QgsDxfPaintEngine::brushColor()
 const   311     return mBrush.color();
   313   QColor 
c = mBrush.color();
   314   c.setAlphaF( c.alphaF() * mOpacity );
 QPointF dxfCoordinates(QPointF pt) const 
Converts a point from device coordinates to dxf coordinates. 
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) 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference) 
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) 
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
double widthScaleFactor() const 
Returns scale factor for line width. 
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
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
QPaintEngine::Type type() const override
bool begin(QPaintDevice *pdev) override