@@ -62,6 +62,10 @@ void QgsDxfPaintEngine::updateState( const QPaintEngineState& state )
62
62
{
63
63
mPen = state.pen ();
64
64
}
65
+ if ( state.state () & QPaintEngine::DirtyBrush )
66
+ {
67
+ mBrush = state.brush ();
68
+ }
65
69
}
66
70
67
71
void QgsDxfPaintEngine::drawPolygon ( const QPointF* points, int pointCount, PolygonDrawMode mode )
@@ -79,7 +83,7 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF* points, int pointCount, Poly
79
83
}
80
84
81
85
bool closed = ( pointCount > 3 && points[0 ] == points[pointCount - 1 ] );
82
- mDxf ->writePolyline ( polyline, mLayer , " CONTINUOUS" , currentPenColor (), currentWidth (), closed );
86
+ mDxf ->writePolyline ( polyline, mLayer , " CONTINUOUS" , currentColor (), currentWidth (), closed );
83
87
}
84
88
85
89
void QgsDxfPaintEngine::drawRects ( const QRectF* rects, int rectCount )
@@ -99,7 +103,7 @@ void QgsDxfPaintEngine::drawRects( const QRectF* rects, int rectCount )
99
103
QgsPoint pt2 = toDxfCoordinates ( QPointF ( right, bottom ) );
100
104
QgsPoint pt3 = toDxfCoordinates ( QPointF ( left, top ) );
101
105
QgsPoint pt4 = toDxfCoordinates ( QPointF ( right, top ) );
102
- mDxf ->writeSolid ( mLayer , currentPenColor (), pt1, pt2, pt3, pt4 );
106
+ mDxf ->writeSolid ( mLayer , currentColor (), pt1, pt2, pt3, pt4 );
103
107
}
104
108
}
105
109
@@ -110,58 +114,60 @@ void QgsDxfPaintEngine::drawEllipse( const QRectF& rect )
110
114
// a circle
111
115
if ( qgsDoubleNear ( rect.width (), rect.height () ) )
112
116
{
113
- mDxf ->writeCircle ( mLayer , currentPenColor (), toDxfCoordinates ( midPoint ), rect.width () / 2.0 );
117
+ mDxf ->writeCircle ( mLayer , currentColor (), toDxfCoordinates ( midPoint ), rect.width () / 2.0 );
114
118
}
115
119
116
120
// todo: create polyline for real ellises
117
121
}
118
122
119
123
void QgsDxfPaintEngine::drawPath ( const QPainterPath& path )
120
124
{
121
- /* QList<QPolygonF> polygonList = path.toFillPolygons();
122
- QList<QPolygonF>::const_iterator pIt = polygonList.constBegin();
123
- for ( ; pIt != polygonList.constEnd(); ++pIt )
124
- {
125
- drawPolygon( pIt->constData(), pIt->size(), pIt->isClosed() ? QPaintEngine::OddEvenMode : QPaintEngine::PolylineMode );
126
- }*/
127
-
128
125
int pathLength = path.elementCount ();
129
126
for ( int i = 0 ; i < pathLength; ++i )
130
127
{
131
128
const QPainterPath::Element& pathElem = path.elementAt ( i );
132
- if ( pathElem.isMoveTo () )
129
+ if ( pathElem.type == QPainterPath::MoveToElement )
133
130
{
134
131
moveTo ( pathElem.x , pathElem.y );
135
132
}
136
- else if ( pathElem.isLineTo () )
133
+ else if ( pathElem.type == QPainterPath::LineToElement )
137
134
{
138
135
lineTo ( pathElem.x , pathElem.y );
139
136
}
140
- else if ( pathElem.isCurveTo () )
137
+ else if ( pathElem.type == QPainterPath::CurveToElement )
141
138
{
142
139
curveTo ( pathElem.x , pathElem.y );
143
140
}
141
+ else if ( pathElem.type == QPainterPath::CurveToDataElement )
142
+ {
143
+ mCurrentCurve .append ( QPointF ( pathElem.x , pathElem.y ) );
144
+ }
144
145
}
146
+ endCurve ();
145
147
endPolygon ();
146
148
}
147
149
148
150
void QgsDxfPaintEngine::moveTo ( double dx, double dy )
149
151
{
150
- if ( mCurrentPolygon .size () < 0 )
151
- {
152
- endPolygon ();
153
- }
152
+ endCurve ();
153
+ endPolygon ();
154
154
mCurrentPolygon .append ( QPointF ( dx, dy ) );
155
155
}
156
156
157
157
void QgsDxfPaintEngine::lineTo ( double dx, double dy )
158
158
{
159
+ endCurve ();
159
160
mCurrentPolygon .append ( QPointF ( dx, dy ) );
160
161
}
161
162
162
163
void QgsDxfPaintEngine::curveTo ( double dx, double dy )
163
164
{
164
- mCurrentPolygon .append ( QPointF ( dx, dy ) ); // todo...
165
+ endCurve ();
166
+ if ( mCurrentPolygon .size () > 0 )
167
+ {
168
+ mCurrentCurve .append ( mCurrentPolygon .last () );
169
+ }
170
+ mCurrentCurve .append ( QPointF ( dx, dy ) );
165
171
}
166
172
167
173
void QgsDxfPaintEngine::endPolygon ()
@@ -173,6 +179,35 @@ void QgsDxfPaintEngine::endPolygon()
173
179
mCurrentPolygon .clear ();
174
180
}
175
181
182
+ void QgsDxfPaintEngine::endCurve ()
183
+ {
184
+ if ( mCurrentCurve .size () < 1 )
185
+ {
186
+ return ;
187
+ }
188
+ if ( mCurrentPolygon .size () < 1 )
189
+ {
190
+ mCurrentCurve .clear ();
191
+ return ;
192
+ }
193
+ // mCurrentCurve.prepend( mCurrentPolygon.last() );
194
+
195
+ if ( mCurrentCurve .size () >= 3 )
196
+ {
197
+ double t = 0.05 ;
198
+ for ( int i = 1 ; i < 20 ; ++i ) // approximate curve with 20 segments
199
+ {
200
+ mCurrentPolygon .append ( bezierPoint ( mCurrentCurve , t ) );
201
+ t += 0.05 ;
202
+ }
203
+ }
204
+ else if ( mCurrentCurve .size () == 2 )
205
+ {
206
+ mCurrentPolygon .append ( mCurrentCurve .at ( 1 ) );
207
+ }
208
+ mCurrentCurve .clear ();
209
+ }
210
+
176
211
void QgsDxfPaintEngine::drawLines ( const QLineF* lines, int lineCount )
177
212
{
178
213
if ( !mDxf || !mPaintDevice || !lines )
@@ -184,7 +219,7 @@ void QgsDxfPaintEngine::drawLines( const QLineF* lines, int lineCount )
184
219
{
185
220
QgsPoint pt1 = toDxfCoordinates ( lines[i].p1 () );
186
221
QgsPoint pt2 = toDxfCoordinates ( lines[i].p2 () );
187
- mDxf ->writeLine ( pt1, pt2, mLayer , " CONTINUOUS" , currentPenColor (), currentWidth () );
222
+ mDxf ->writeLine ( pt1, pt2, mLayer , " CONTINUOUS" , currentColor (), currentWidth () );
188
223
}
189
224
}
190
225
@@ -199,14 +234,19 @@ QgsPoint QgsDxfPaintEngine::toDxfCoordinates( const QPointF& pt ) const
199
234
return QgsPoint ( dxfPt.x (), dxfPt.y () );
200
235
}
201
236
202
- int QgsDxfPaintEngine::currentPenColor () const
237
+ int QgsDxfPaintEngine::currentColor () const
203
238
{
204
239
if ( !mDxf )
205
240
{
206
241
return 0 ;
207
242
}
208
243
209
- return mDxf ->closestColorMatch ( mPen .color ().rgb () );
244
+ QColor c = mPen .color ();
245
+ if ( mPen .style () == Qt::NoPen )
246
+ {
247
+ c = mBrush .color ();
248
+ }
249
+ return mDxf ->closestColorMatch ( c.rgb () );
210
250
}
211
251
212
252
double QgsDxfPaintEngine::currentWidth () const
@@ -218,3 +258,108 @@ double QgsDxfPaintEngine::currentWidth() const
218
258
219
259
return mPen .widthF () * mPaintDevice ->widthScaleFactor ();
220
260
}
261
+
262
+ QPointF QgsDxfPaintEngine::bezierPoint ( const QList<QPointF>& controlPolygon, double t )
263
+ {
264
+ /* if ( p && mControlPoly )
265
+ {
266
+ p->setX( 0 );
267
+ p->setY( 0 );
268
+ p->setZ( 0 );
269
+
270
+ for ( int n = 1; n <= int( mControlPoly->count() ); n++ )
271
+ {
272
+ double bernst = MathUtils::calcBernsteinPoly( mControlPoly->count() - 1, n - 1, t );
273
+ p->setX( p->getX() + ( *mControlPoly )[n-1]->getX()*bernst );
274
+ p->setY( p->getY() + ( *mControlPoly )[n-1]->getY()*bernst );
275
+ p->setZ( p->getZ() + ( *mControlPoly )[n-1]->getZ()*bernst );
276
+ }
277
+ }
278
+
279
+ else
280
+ {
281
+ QgsDebugMsg( "warning: null pointer" );
282
+ }*/
283
+
284
+ double x = 0 ;
285
+ double y = 0 ;
286
+ int cPolySize = controlPolygon.size ();
287
+ double bPoly = 0 ;
288
+
289
+ QList<QPointF>::const_iterator it = controlPolygon.constBegin ();
290
+ int i = 0 ;
291
+ for ( ; it != controlPolygon.constEnd (); ++it )
292
+ {
293
+ bPoly = bernsteinPoly ( cPolySize - 1 , i, t );
294
+ x += ( it->x () * bPoly );
295
+ y += ( it->y () * bPoly );
296
+ ++i;
297
+ }
298
+
299
+ return QPointF ( x, y );
300
+ }
301
+
302
+ double QgsDxfPaintEngine::bernsteinPoly ( int n, int i, double t )
303
+ {
304
+ if ( i < 0 )
305
+ {
306
+ return 0 ;
307
+ }
308
+
309
+ return lower ( n, i )*power ( t, i )*power (( 1 - t ), ( n - i ) );
310
+ }
311
+
312
+ int QgsDxfPaintEngine::lower ( int n, int i )
313
+ {
314
+ if ( i >= 0 && i <= n )
315
+ {
316
+ return faculty ( n ) / ( faculty ( i )*faculty ( n - i ) );
317
+ }
318
+ else
319
+ {
320
+ return 0 ;
321
+ }
322
+ }
323
+
324
+ double QgsDxfPaintEngine::power ( double a, int b )
325
+ {
326
+ if ( b == 0 )
327
+ {
328
+ return 1 ;
329
+ }
330
+ double tmp = a;
331
+ for ( int i = 2 ; i <= qAbs (( double )b ); i++ )
332
+ {
333
+
334
+ a *= tmp;
335
+ }
336
+ if ( b > 0 )
337
+ {
338
+ return a;
339
+ }
340
+ else
341
+ {
342
+ return ( 1.0 / a );
343
+ }
344
+ }
345
+
346
+ int QgsDxfPaintEngine::faculty ( int n )
347
+ {
348
+ if ( n < 0 )// Is faculty also defined for negative integers?
349
+ {
350
+ return 0 ;
351
+ }
352
+ int i;
353
+ int result = n;
354
+
355
+ if ( n == 0 || n == 1 )
356
+ {
357
+ return 1 ;
358
+ }// faculty of 0 is 1!
359
+
360
+ for ( i = n - 1 ; i >= 2 ; i-- )
361
+ {
362
+ result *= i;
363
+ }
364
+ return result;
365
+ }
0 commit comments