Skip to content

Commit 1076f70

Browse files
committedJun 30, 2015
backported dxf fixes:
* fix crash when not enabled layers are exported * fix handing of areas with holes when exporting SVGs * fix block, hatch and polyline ownership * fix support for data-defined properties in SVG export * remove drawRects and let it fallback to drawPath and drawPolygon * close arcs * replace writeSolid with writePolygon (backported b4fc413, 2798ab0, b3c2bd7 and 7031cfb)
1 parent 6a7b6da commit 1076f70

File tree

11 files changed

+329
-283
lines changed

11 files changed

+329
-283
lines changed
 

‎python/core/dxf/qgsdxfexport.sip

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,31 +63,45 @@ class QgsDxfExport
6363
void writeGroup( int code, const QgsPoint &p, double z = 0.0, bool skipz = false ) /PyName=writeGroupPoint/;
6464
void writeGroup( QColor color, int exactMatch = 62, int rgbCode = 420, int transparencyCode = 440 );
6565

66+
//! Write handle
6667
int writeHandle( int code = 5, int handle = 0 );
6768

68-
//draw dxf primitives
69+
//! Draw dxf primitives
6970
void writePolyline( const QgsPolyline &line, const QString &layer, const QString &lineStyleName, QColor color,
70-
double width = -1, bool polygon = false );
71+
double width = -1, bool unusedPolygonFlag = false );
7172

73+
//! Draw dxf polygon (HATCH)
7274
void writePolygon( const QgsPolygon &polygon, const QString &layer, const QString &hatchPattern, QColor color );
7375

76+
//! Draw solid
7477
void writeSolid( const QString &layer, QColor color, const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, const QgsPoint &pt4 );
7578

76-
//write line (as a polyline)
79+
//! Write line (as a polyline)
7780
void writeLine( const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, QColor color, double width = -1 );
7881

82+
//! Write point
7983
void writePoint( const QString &layer, QColor color, const QgsPoint &pt );
8084

85+
//! Write filled circle (as hatch)
8186
void writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius );
8287

88+
//! Write circle (as polyline)
8389
void writeCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width );
8490

91+
//! Write text (TEXT)
8592
void writeText( const QString &layer, const QString &text, const QgsPoint &pt, double size, double angle, QColor color );
8693

94+
//! Write mtext (MTEXT)
8795
void writeMText( const QString &layer, const QString &text, const QgsPoint &pt, double width, double angle, QColor color );
8896

8997
static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits );
9098

99+
//! Return cleaned layer name for use in DXF
91100
static QString dxfLayerName( const QString &name );
92101

102+
//! return DXF encoding for Qt encoding
103+
static QString dxfEncoding( const QString &name );
104+
105+
//! return list of available DXF encodings
106+
static QStringList encodings();
93107
};

‎python/core/symbology-ng/qgssvgcache.sip

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class QgsSvgCache : QObject
8787
/**Get image data*/
8888
QByteArray getImageData( const QString &path ) const;
8989

90+
/**Get SVG content*/
91+
const QByteArray& svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
92+
double widthScaleFactor, double rasterScaleFactor );
93+
9094
signals:
9195
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
9296
void statusChanged( const QString& theStatusQString );

‎src/app/qgsdxfexportdialog.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "qgis.h"
2626
#include "qgsfieldcombobox.h"
2727
#include "qgisapp.h"
28-
#include "qgsmapcanvas.h"
28+
#include "qgslayertreemapcanvasbridge.h"
2929
#include "qgsvisibilitypresets.h"
3030

3131
#include <QFileDialog>
@@ -254,7 +254,7 @@ bool QgsVectorLayerAndAttributeModel::setData( const QModelIndex &index, const Q
254254
QList< QPair<QgsVectorLayer *, int> > QgsVectorLayerAndAttributeModel::layers() const
255255
{
256256
QList< QPair<QgsVectorLayer *, int> > layers;
257-
QHash< QgsMapLayer *, int > layerIdx;
257+
QHash< QString, int > layerIdx;
258258

259259
foreach ( const QModelIndex &idx, mCheckedLeafs )
260260
{
@@ -265,9 +265,9 @@ QList< QPair<QgsVectorLayer *, int> > QgsVectorLayerAndAttributeModel::layers()
265265
{
266266
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( treeLayer->layer() );
267267
Q_ASSERT( vl );
268-
if ( !layerIdx.contains( vl ) )
268+
if ( !layerIdx.contains( vl->id() ) )
269269
{
270-
layerIdx.insert( vl, layers.size() );
270+
layerIdx.insert( vl->id(), layers.size() );
271271
layers << qMakePair<QgsVectorLayer *, int>( vl, mAttributeIdx.value( vl, -1 ) );
272272
}
273273
}
@@ -276,15 +276,16 @@ QList< QPair<QgsVectorLayer *, int> > QgsVectorLayerAndAttributeModel::layers()
276276
{
277277
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer *>( QgsLayerTree::toLayer( node )->layer() );
278278
Q_ASSERT( vl );
279-
if ( !layerIdx.contains( vl ) )
279+
if ( !layerIdx.contains( vl->id() ) )
280280
{
281-
layerIdx.insert( vl, layers.size() );
281+
layerIdx.insert( vl->id(), layers.size() );
282282
layers << qMakePair<QgsVectorLayer *, int>( vl, mAttributeIdx.value( vl, -1 ) );
283283
}
284284
}
285285
}
286286

287-
QList<QgsMapLayer*> inDrawingOrder = QgisApp::instance()->mapCanvas()->layers();
287+
QgsLayerTreeMapCanvasBridge* bridge = QgisApp::instance()->layerTreeCanvasBridge();
288+
QStringList inDrawingOrder = bridge->hasCustomLayerOrder() ? bridge->customLayerOrder() : bridge->defaultLayerOrder();
288289
QList< QPair<QgsVectorLayer *, int> > layersInROrder;
289290

290291
for ( int i = inDrawingOrder.size() - 1; i >= 0; i-- )

‎src/core/dxf/qgsdxfexport.cpp

Lines changed: 78 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,10 @@ QgsDxfExport::QgsDxfExport()
359359
, mSymbolLayerCounter( 0 )
360360
, mNextHandleId( DXF_HANDSEED )
361361
, mBlockCounter( 0 )
362-
, mModelSpaceBR( 0 )
363362
{
364363
}
365364

366365
QgsDxfExport::QgsDxfExport( const QgsDxfExport& dxfExport )
367-
: mModelSpaceBR( 0 )
368366
{
369367
*this = dxfExport;
370368
}
@@ -588,23 +586,15 @@ void QgsDxfExport::writeTables()
588586

589587
writeGroup( 100, "AcDbSymbolTable" );
590588
writeGroup( 70, 0 );
591-
writeGroup( 0, "BLOCK_RECORD" );
592-
mModelSpaceBR = writeHandle();
593-
writeGroup( 100, "AcDbSymbolTableRecord" );
594-
writeGroup( 100, "AcDbBlockTableRecord" );
595-
writeGroup( 2, "*Model_Space" );
596589

597-
writeGroup( 0, "BLOCK_RECORD" );
598-
writeHandle();
599-
writeGroup( 100, "AcDbSymbolTableRecord" );
600-
writeGroup( 100, "AcDbBlockTableRecord" );
601-
writeGroup( 2, "*Paper_Space" );
602-
603-
writeGroup( 0, "BLOCK_RECORD" );
604-
writeHandle();
605-
writeGroup( 100, "AcDbSymbolTableRecord" );
606-
writeGroup( 100, "AcDbBlockTableRecord" );
607-
writeGroup( 2, "*Paper_Space0" );
590+
foreach ( QString block, QStringList() << "*Model_Space" << "*Paper_Space" << "*Paper_Space0" )
591+
{
592+
writeGroup( 0, "BLOCK_RECORD" );
593+
mBlockHandles.insert( block, writeHandle() );
594+
writeGroup( 100, "AcDbSymbolTableRecord" );
595+
writeGroup( 100, "AcDbBlockTableRecord" );
596+
writeGroup( 2, block );
597+
}
608598

609599
int i = 0;
610600
slIt = slList.constBegin();
@@ -617,11 +607,12 @@ void QgsDxfExport::writeTables()
617607
if ( hasDataDefinedProperties( ml, slIt->second ) )
618608
continue;
619609

610+
QString name = QString( "symbolLayer%1" ).arg( i++ );
620611
writeGroup( 0, "BLOCK_RECORD" );
621-
writeHandle();
612+
mBlockHandles.insert( name, writeHandle() );
622613
writeGroup( 100, "AcDbSymbolTableRecord" );
623614
writeGroup( 100, "AcDbBlockTableRecord" );
624-
writeGroup( 2, QString( "symbolLayer%1" ).arg( i++ ) );
615+
writeGroup( 2, name );
625616
}
626617

627618
writeGroup( 0, "ENDTAB" );
@@ -802,53 +793,25 @@ void QgsDxfExport::writeBlocks()
802793
startSection();
803794
writeGroup( 2, "BLOCKS" );
804795

805-
writeGroup( 0, "BLOCK" );
806-
writeHandle();
807-
writeGroup( 100, "AcDbEntity" );
808-
writeGroup( 8, "0" );
809-
writeGroup( 100, "AcDbBlockBegin" );
810-
writeGroup( 2, "*Model_Space" );
811-
writeGroup( 70, 0 );
812-
writeGroup( 0, QgsPoint( 0.0, 0.0 ) );
813-
writeGroup( 3, "*Model_Space" );
814-
writeGroup( 1, "" );
815-
writeGroup( 0, "ENDBLK" );
816-
writeHandle();
817-
writeGroup( 100, "AcDbEntity" );
818-
writeGroup( 8, "0" );
819-
writeGroup( 100, "AcDbBlockEnd" );
820-
821-
writeGroup( 0, "BLOCK" );
822-
writeHandle();
823-
writeGroup( 100, "AcDbEntity" );
824-
writeGroup( 8, "0" );
825-
writeGroup( 100, "AcDbBlockBegin" );
826-
writeGroup( 2, "*Paper_Space" );
827-
writeGroup( 70, 0 );
828-
writeGroup( 0, QgsPoint( 0.0, 0.0 ) );
829-
writeGroup( 3, "*Paper_Space" );
830-
writeGroup( 1, "" );
831-
writeGroup( 0, "ENDBLK" );
832-
writeHandle();
833-
writeGroup( 100, "AcDbEntity" );
834-
writeGroup( 8, "0" );
835-
writeGroup( 100, "AcDbBlockEnd" );
836-
837-
writeGroup( 0, "BLOCK" );
838-
writeHandle();
839-
writeGroup( 100, "AcDbEntity" );
840-
writeGroup( 8, "0" );
841-
writeGroup( 100, "AcDbBlockBegin" );
842-
writeGroup( 2, "*Paper_Space0" );
843-
writeGroup( 70, 0 );
844-
writeGroup( 0, QgsPoint( 0.0, 0.0 ) );
845-
writeGroup( 3, "*Paper_Space0" );
846-
writeGroup( 1, "" );
847-
writeGroup( 0, "ENDBLK" );
848-
writeHandle();
849-
writeGroup( 100, "AcDbEntity" );
850-
writeGroup( 8, "0" );
851-
writeGroup( 100, "AcDbBlockEnd" );
796+
foreach ( QString block, QStringList() << "*Model_Space" << "*Paper_Space" << "*Paper_Space0" )
797+
{
798+
writeGroup( 0, "BLOCK" );
799+
writeHandle();
800+
writeGroup( 330, QString( "%1" ).arg( mBlockHandles[ block ], 0, 16 ) );
801+
writeGroup( 100, "AcDbEntity" );
802+
writeGroup( 8, "0" );
803+
writeGroup( 100, "AcDbBlockBegin" );
804+
writeGroup( 2, block );
805+
writeGroup( 70, 0 );
806+
writeGroup( 0, QgsPoint( 0.0, 0.0 ) );
807+
writeGroup( 3, block );
808+
writeGroup( 1, "" );
809+
writeGroup( 0, "ENDBLK" );
810+
writeHandle();
811+
writeGroup( 100, "AcDbEntity" );
812+
writeGroup( 8, "0" );
813+
writeGroup( 100, "AcDbBlockEnd" );
814+
}
852815

853816
// Iterate through all layers and get symbol layer pointers
854817
QList< QPair< QgsSymbolLayerV2*, QgsSymbolV2* > > slList;
@@ -876,33 +839,36 @@ void QgsDxfExport::writeBlocks()
876839
// ml->stopRender( ctx );
877840
}
878841

842+
QString block( QString( "symbolLayer%1" ).arg( mBlockCounter++ ) );
843+
mBlockHandle = QString( "%1" ).arg( mBlockHandles[ block ], 0, 16 );
844+
879845
writeGroup( 0, "BLOCK" );
880846
writeHandle();
847+
writeGroup( 330, mBlockHandle );
881848
writeGroup( 100, "AcDbEntity" );
882849
writeGroup( 8, "0" );
883850
writeGroup( 100, "AcDbBlockBegin" );
884-
885-
QString blockName = QString( "symbolLayer%1" ).arg( mBlockCounter++ );
886-
writeGroup( 2, blockName );
851+
writeGroup( 2, block );
887852
writeGroup( 70, 0 );
888-
writeGroup( 1, "" );
889853

890854
// x/y/z coordinates of reference point
891855
// todo: consider anchor point
892856
// double size = ml->size();
893857
// size *= mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits );
894858
writeGroup( 0, QgsPoint( 0.0, 0.0 ) );
895-
writeGroup( 3, blockName );
859+
writeGroup( 3, block );
860+
writeGroup( 1, "" );
896861

897-
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits ), "0", &ctx, 0 ); // maplayer 0 -> block receives layer from INSERT statement
862+
// maplayer 0 -> block receives layer from INSERT statement
863+
ml->writeDxf( *this, mapUnitScaleFactor( mSymbologyScaleDenominator, ml->sizeUnit(), mMapUnits ), "0", &ctx, 0 );
898864

899865
writeGroup( 0, "ENDBLK" );
900866
writeHandle();
901867
writeGroup( 100, "AcDbEntity" );
902-
writeGroup( 100, "AcDbBlockEnd" );
903868
writeGroup( 8, "0" );
869+
writeGroup( 100, "AcDbBlockEnd" );
904870

905-
mPointSymbolBlocks.insert( ml, blockName );
871+
mPointSymbolBlocks.insert( ml, block );
906872
ml->stopRender( ctx );
907873
}
908874
endSection();
@@ -913,6 +879,8 @@ void QgsDxfExport::writeEntities()
913879
startSection();
914880
writeGroup( 2, "ENTITIES" );
915881

882+
mBlockHandle = QString( "%1" ).arg( mBlockHandles[ "*Model_Space" ], 0, 16 );
883+
916884
// label engine
917885
QgsDxfPalLabeling labelEngine( this, mExtent.isEmpty() ? dxfExtent() : mExtent, mSymbologyScaleDenominator, mMapUnits );
918886
QgsRenderContext& ctx = labelEngine.renderContext();
@@ -3341,6 +3309,22 @@ void QgsDxfExport::writePoint( const QgsPoint& pt, const QString& layer, QColor
33413309
void QgsDxfExport::writePolyline( const QgsPolyline& line, const QString& layer, const QString& lineStyleName, QColor color,
33423310
double width, bool )
33433311
{
3312+
int n = line.size();
3313+
if ( n == 0 )
3314+
{
3315+
QgsDebugMsg( QString( "writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer ).arg( lineStyleName ) );
3316+
return;
3317+
}
3318+
3319+
bool polygon = line[0] == line[ line.size() - 1 ];
3320+
if ( polygon )
3321+
--n;
3322+
if ( n < 2 )
3323+
{
3324+
QgsDebugMsg( QString( "writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer ).arg( lineStyleName ) );
3325+
return;
3326+
}
3327+
33443328
writeGroup( 0, "LWPOLYLINE" );
33453329
writeHandle();
33463330
writeGroup( 8, layer );
@@ -3349,11 +3333,6 @@ void QgsDxfExport::writePolyline( const QgsPolyline& line, const QString& layer,
33493333
writeGroup( 6, lineStyleName );
33503334
writeGroup( color );
33513335

3352-
bool polygon = line[0] == line[ line.size() - 1 ];
3353-
int n = line.size();
3354-
if ( polygon )
3355-
--n;
3356-
33573336
writeGroup( 90, n );
33583337
writeGroup( 70, polygon ? 1 : 0 );
33593338
writeGroup( 43, width );
@@ -3366,7 +3345,7 @@ void QgsDxfExport::writePolygon( const QgsPolygon& polygon, const QString& layer
33663345
{
33673346
writeGroup( 0, "HATCH" ); // Entity type
33683347
writeHandle();
3369-
writeGroup( 330, mModelSpaceBR );
3348+
writeGroup( 330, mBlockHandle );
33703349
writeGroup( 100, "AcDbEntity" );
33713350
writeGroup( 8, layer ); // Layer name
33723351
writeGroup( color ); // Color
@@ -3424,19 +3403,19 @@ void QgsDxfExport::writeFilledCircle( const QString &layer, QColor color, const
34243403
{
34253404
writeGroup( 0, "HATCH" ); // Entity type
34263405
writeHandle();
3427-
writeGroup( 330, mModelSpaceBR );
3406+
writeGroup( 330, mBlockHandle );
34283407
writeGroup( 100, "AcDbEntity" );
3408+
writeGroup( 8, layer ); // Layer name
3409+
writeGroup( color ); // Color (0 by block, 256 by layer)
34293410
writeGroup( 100, "AcDbHatch" );
34303411

3431-
writeGroup( 8, layer ); // Layer name
3432-
writeGroup( 0, QgsPoint( 0, 0 ), 0.0 ); // Elevation point (in OCS)
3412+
writeGroup( 0, QgsPoint( 0, 0 ) ); // Elevation point (in OCS)
34333413
writeGroup( 200, QgsPoint( 0, 0 ), 1.0 );
34343414

34353415
writeGroup( 2, "SOLID" ); // Hatch pattern name
34363416
writeGroup( 70, 1 ); // Solid fill flag (solid fill = 1; pattern fill = 0)
34373417
writeGroup( 71, 0 ); // Associativity flag (associative = 1; non-associative = 0)
34383418

3439-
writeGroup( color ); // Color (0 by block, 256 by layer)
34403419

34413420
writeGroup( 91, 1 ); // Number of boundary paths (loops)
34423421

@@ -3464,7 +3443,7 @@ void QgsDxfExport::writeCircle( const QString& layer, QColor color, const QgsPoi
34643443
{
34653444
writeGroup( 0, "LWPOLYLINE" );
34663445
writeHandle();
3467-
writeGroup( 330, mModelSpaceBR );
3446+
writeGroup( 330, mBlockHandle );
34683447
writeGroup( 8, layer );
34693448
writeGroup( 100, "AcDbEntity" );
34703449
writeGroup( 100, "AcDbPolyline" );
@@ -3536,16 +3515,19 @@ void QgsDxfExport::writeMText( const QString& layer, const QString& text, const
35363515

35373516
void QgsDxfExport::writeSolid( const QString& layer, QColor color, const QgsPoint& pt1, const QgsPoint& pt2, const QgsPoint& pt3, const QgsPoint& pt4 )
35383517
{
3539-
writeGroup( 0, "SOLID" );
3540-
writeHandle();
3541-
writeGroup( 100, "AcDbEntity" );
3542-
writeGroup( 100, "AcDbTrace" );
3543-
writeGroup( 8, layer );
3544-
writeGroup( color );
3545-
writeGroup( 0, pt1 );
3546-
writeGroup( 1, pt2 );
3547-
writeGroup( 2, pt3 );
3548-
writeGroup( 3, pt4 );
3518+
// pt1 pt2
3519+
// pt3 pt4
3520+
int i = 0;
3521+
QgsPolygon p( 1 );
3522+
p[0].resize( pt3 != pt4 ? 5 : 4 );
3523+
p[0][i++] = pt1;
3524+
p[0][i++] = pt2;
3525+
p[0][i++] = pt4;
3526+
if ( p[0].size() == 5 )
3527+
p[0][i++] = pt3;
3528+
p[0][i] = pt1;
3529+
3530+
writePolygon( p, layer, "SOLID", color );
35493531
}
35503532

35513533
void QgsDxfExport::writeVertex( const QgsPoint& pt, const QString& layer )

‎src/core/dxf/qgsdxfexport.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,32 +76,40 @@ class CORE_EXPORT QgsDxfExport
7676
void writeGroup( int code, const QgsPoint &p, double z = 0.0, bool skipz = false );
7777
void writeGroup( QColor color, int exactMatch = 62, int rgbCode = 420, int transparencyCode = 440 );
7878

79+
//! Write handle
7980
int writeHandle( int code = 5, int handle = 0 );
8081

8182
//! draw dxf primitives
8283
void writePolyline( const QgsPolyline &line, const QString &layer, const QString &lineStyleName, QColor color,
8384
double width = -1, bool unusedPolygonFlag = false );
8485

86+
//! Draw dxf polygon (HATCH)
8587
void writePolygon( const QgsPolygon &polygon, const QString &layer, const QString &hatchPattern, QColor color );
8688

89+
//! Draw solid
8790
void writeSolid( const QString &layer, QColor color, const QgsPoint &pt1, const QgsPoint &pt2, const QgsPoint &pt3, const QgsPoint &pt4 );
8891

89-
//! write line (as a polyline)
92+
//! Write line (as a polyline)
9093
void writeLine( const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, QColor color, double width = -1 );
9194

95+
//! Write point
9296
void writePoint( const QString &layer, QColor color, const QgsPoint &pt );
9397

98+
//! Write filled circle (as hatch)
9499
void writeFilledCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius );
95100

101+
//! Write circle (as polyline)
96102
void writeCircle( const QString &layer, QColor color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width );
97103

104+
//! Write text (TEXT)
98105
void writeText( const QString &layer, const QString &text, const QgsPoint &pt, double size, double angle, QColor color );
99106

107+
//! Write mtext (MTEXT)
100108
void writeMText( const QString &layer, const QString &text, const QgsPoint &pt, double width, double angle, QColor color );
101109

102110
static double mapUnitScaleFactor( double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits );
103111

104-
//! return cleaned layer name for use in DXF
112+
//! Return cleaned layer name for use in DXF
105113
static QString dxfLayerName( const QString &name );
106114

107115
//! return DXF encoding for Qt encoding
@@ -174,7 +182,8 @@ class CORE_EXPORT QgsDxfExport
174182
static QString lineNameFromPenStyle( Qt::PenStyle style );
175183
bool layerIsScaleBasedVisible( const QgsMapLayer *layer ) const;
176184

177-
int mModelSpaceBR;
185+
QHash<QString, int> mBlockHandles;
186+
QString mBlockHandle;
178187
};
179188

180189
#endif // QGSDXFEXPORT_H

‎src/core/dxf/qgsdxfpaintengine.cpp

Lines changed: 35 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
QgsDxfPaintEngine::QgsDxfPaintEngine( const QgsDxfPaintDevice* dxfDevice, QgsDxfExport* dxf )
2424
: QPaintEngine( QPaintEngine::AllFeatures /*QPaintEngine::PainterPaths | QPaintEngine::PaintOutsidePaintEvent*/ )
25-
, mPaintDevice( dxfDevice ), mDxf( dxf )
25+
, mPaintDevice( dxfDevice )
26+
, mDxf( dxf )
2627
{
2728
}
2829

@@ -48,70 +49,48 @@ QPaintEngine::Type QgsDxfPaintEngine::type() const
4849

4950
void QgsDxfPaintEngine::drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr )
5051
{
51-
Q_UNUSED( r ); Q_UNUSED( pm ); Q_UNUSED( sr );
52+
Q_UNUSED( r );
53+
Q_UNUSED( pm );
54+
Q_UNUSED( sr );
5255
}
5356

5457
void QgsDxfPaintEngine::updateState( const QPaintEngineState& state )
5558
{
5659
if ( state.state() & QPaintEngine::DirtyTransform )
57-
{
5860
mTransform = state.transform();
59-
}
61+
6062
if ( state.state() & QPaintEngine::DirtyPen )
61-
{
6263
mPen = state.pen();
63-
}
64+
6465
if ( state.state() & QPaintEngine::DirtyBrush )
65-
{
6666
mBrush = state.brush();
67-
}
67+
}
68+
69+
void QgsDxfPaintEngine::setRing( QgsPolyline &polyline, const QPointF *points, int pointCount )
70+
{
71+
polyline.resize( pointCount );
72+
for ( int i = 0; i < pointCount; ++i )
73+
polyline[i] = toDxfCoordinates( points[i] );
6874
}
6975

7076
void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, PolygonDrawMode mode )
7177
{
7278
Q_UNUSED( mode );
7379
if ( !mDxf || !mPaintDevice )
74-
{
7580
return;
76-
}
7781

7882
QgsPolygon polygon( 1 );
79-
polygon[0].resize( pointCount );
80-
81-
QgsPolyline &polyline = polygon[0];
82-
for ( int i = 0; i < pointCount; ++i )
83-
{
84-
polyline[i] = toDxfCoordinates( points[i] );
85-
}
83+
setRing( polygon[0], points, pointCount );
8684

8785
if ( mode == QPaintEngine::PolylineMode )
8886
{
89-
mDxf->writePolyline( polyline, mLayer, "CONTINUOUS", mPen.color(), currentWidth(), true );
87+
if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
88+
mDxf->writePolyline( polygon[0], mLayer, "CONTINUOUS", mPen.color(), currentWidth() );
9089
}
9190
else
9291
{
93-
mDxf->writePolygon( polygon, mLayer, "SOLID", mBrush.color() );
94-
}
95-
}
96-
97-
void QgsDxfPaintEngine::drawRects( const QRectF* rects, int rectCount )
98-
{
99-
if ( !mDxf || !mPaintDevice || !rects || mBrush.style() == Qt::NoBrush )
100-
{
101-
return;
102-
}
103-
104-
for ( int i = 0; i < rectCount; ++i )
105-
{
106-
double left = rects[i].left();
107-
double right = rects[i].right();
108-
double top = rects[i].top();
109-
double bottom = rects[i].bottom();
110-
QgsPoint pt1 = toDxfCoordinates( QPointF( left, bottom ) );
111-
QgsPoint pt2 = toDxfCoordinates( QPointF( right, bottom ) );
112-
QgsPoint pt3 = toDxfCoordinates( QPointF( left, top ) );
113-
QgsPoint pt4 = toDxfCoordinates( QPointF( right, top ) );
114-
mDxf->writeSolid( mLayer, mBrush.color(), pt1, pt2, pt3, pt4 );
92+
if ( mBrush.style() != Qt::NoBrush )
93+
mDxf->writePolygon( polygon, mLayer, "SOLID", mBrush.color() );
11594
}
11695
}
11796

@@ -140,6 +119,11 @@ void QgsDxfPaintEngine::drawPath( const QPainterPath& path )
140119
}
141120
endCurve();
142121
endPolygon();
122+
123+
if ( mPolygon.size() > 0 && mBrush.style() != Qt::NoBrush )
124+
mDxf->writePolygon( mPolygon, mLayer, "SOLID", mBrush.color() );
125+
126+
mPolygon.clear();
143127
}
144128

145129
void QgsDxfPaintEngine::moveTo( double dx, double dy )
@@ -159,9 +143,8 @@ void QgsDxfPaintEngine::curveTo( double dx, double dy )
159143
{
160144
endCurve();
161145
if ( mCurrentPolygon.size() > 0 )
162-
{
163146
mCurrentCurve.append( mCurrentPolygon.last() );
164-
}
147+
165148
mCurrentCurve.append( QPointF( dx, dy ) );
166149
}
167150

@@ -171,29 +154,28 @@ void QgsDxfPaintEngine::endPolygon()
171154
{
172155
if ( mPen.style() != Qt::NoPen )
173156
drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
174-
if ( mBrush.style() != Qt::NoBrush )
175-
drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::OddEvenMode );
157+
158+
mPolygon.resize( mPolygon.size() + 1 );
159+
setRing( mPolygon[ mPolygon.size() - 1 ], mCurrentPolygon.constData(), mCurrentPolygon.size() );
176160
}
177161
mCurrentPolygon.clear();
178162
}
179163

180164
void QgsDxfPaintEngine::endCurve()
181165
{
182166
if ( mCurrentCurve.size() < 1 )
183-
{
184167
return;
185-
}
168+
186169
if ( mCurrentPolygon.size() < 1 )
187170
{
188171
mCurrentCurve.clear();
189172
return;
190173
}
191-
//mCurrentCurve.prepend( mCurrentPolygon.last() );
192174

193175
if ( mCurrentCurve.size() >= 3 )
194176
{
195177
double t = 0.05;
196-
for ( int i = 1; i < 20; ++i ) //approximate curve with 20 segments
178+
for ( int i = 1; i <= 20; ++i ) //approximate curve with 20 segments
197179
{
198180
mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
199181
t += 0.05;
@@ -209,9 +191,7 @@ void QgsDxfPaintEngine::endCurve()
209191
void QgsDxfPaintEngine::drawLines( const QLineF* lines, int lineCount )
210192
{
211193
if ( !mDxf || !mPaintDevice || !lines || mPen.style() == Qt::NoPen )
212-
{
213194
return;
214-
}
215195

216196
for ( int i = 0; i < lineCount; ++i )
217197
{
@@ -224,9 +204,7 @@ void QgsDxfPaintEngine::drawLines( const QLineF* lines, int lineCount )
224204
QgsPoint QgsDxfPaintEngine::toDxfCoordinates( const QPointF& pt ) const
225205
{
226206
if ( !mPaintDevice || !mDxf )
227-
{
228207
return QgsPoint( pt.x(), pt.y() );
229-
}
230208

231209
QPointF dxfPt = mPaintDevice->dxfCoordinates( mTransform.map( pt ) ) + mShift;
232210
return QgsPoint( dxfPt.x(), dxfPt.y() );
@@ -236,9 +214,7 @@ QgsPoint QgsDxfPaintEngine::toDxfCoordinates( const QPointF& pt ) const
236214
double QgsDxfPaintEngine::currentWidth() const
237215
{
238216
if ( !mPaintDevice )
239-
{
240217
return 1;
241-
}
242218

243219
return mPen.widthF() * mPaintDevice->widthScaleFactor();
244220
}
@@ -266,9 +242,7 @@ QPointF QgsDxfPaintEngine::bezierPoint( const QList<QPointF>& controlPolygon, do
266242
double QgsDxfPaintEngine::bernsteinPoly( int n, int i, double t )
267243
{
268244
if ( i < 0 )
269-
{
270245
return 0;
271-
}
272246

273247
return lower( n, i )*power( t, i )*power(( 1 - t ), ( n - i ) );
274248
}
@@ -288,41 +262,31 @@ int QgsDxfPaintEngine::lower( int n, int i )
288262
double QgsDxfPaintEngine::power( double a, int b )
289263
{
290264
if ( b == 0 )
291-
{
292265
return 1;
293-
}
266+
294267
double tmp = a;
295268
for ( int i = 2; i <= qAbs(( double )b ); i++ )
296-
{
297269
a *= tmp;
298-
}
270+
299271
if ( b > 0 )
300-
{
301272
return a;
302-
}
303273
else
304-
{
305274
return 1.0 / a;
306-
}
307275
}
308276

309277
int QgsDxfPaintEngine::faculty( int n )
310278
{
311279
if ( n < 0 )//Is faculty also defined for negative integers?
312-
{
313280
return 0;
314-
}
281+
315282
int i;
316283
int result = n;
317284

318285
if ( n == 0 || n == 1 )
319-
{
320-
return 1;
321-
}//faculty of 0 is 1!
286+
return 1; //faculty of 0 is 1!
322287

323288
for ( i = n - 1; i >= 2; i-- )
324-
{
325289
result *= i;
326-
}
290+
327291
return result;
328292
}

‎src/core/dxf/qgsdxfpaintengine.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define QGSDXFPAINTENGINE_H
2020

2121
#include <QPaintEngine>
22+
#include <qgsgeometry.h>
2223

2324
class QgsDxfExport;
2425
class QgsDxfPaintDevice;
@@ -38,7 +39,6 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
3839
void drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr ) override;
3940

4041
void drawPolygon( const QPointF * points, int pointCount, PolygonDrawMode mode ) override;
41-
void drawRects( const QRectF * rects, int rectCount ) override;
4242
void drawPath( const QPainterPath& path ) override;
4343
void drawLines( const QLineF* lines, int lineCount ) override;
4444

@@ -57,6 +57,7 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
5757
QBrush mBrush;
5858
QString mLayer;
5959
QPointF mShift;
60+
QgsPolygon mPolygon;
6061
QPolygonF mCurrentPolygon;
6162
QList<QPointF> mCurrentCurve;
6263

@@ -69,6 +70,8 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
6970
void endPolygon();
7071
void endCurve();
7172

73+
void setRing( QgsPolyline &polyline, const QPointF * points, int pointCount );
74+
7275
//utils for bezier curve calculation
7376
static QPointF bezierPoint( const QList<QPointF>& controlPolygon, double t );
7477
static double bernsteinPoly( int n, int i, double t );

‎src/core/symbology-ng/qgsellipsesymbollayerv2.cpp

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
632632
QgsExpression* heightExpression = expression( "height" );
633633
if ( heightExpression ) //1. priority: data defined setting on symbol layer level
634634
{
635-
symbolHeight = heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
635+
symbolHeight = heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
636636
}
637637
else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
638638
{
@@ -731,41 +731,52 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
731731
}
732732
//close ellipse with first point
733733
line.push_back( line.at( 0 ) );
734-
e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );
734+
if ( mBrush.style() != Qt::NoBrush )
735+
e.writePolygon( QgsPolygon() << line, layerName, "SOLID", fc );
736+
if ( mPen.style() != Qt::NoPen )
737+
e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );
735738
}
736739
}
737740
else if ( symbolName == "rectangle" )
738741
{
739-
QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
740-
QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
741-
QPointF pt3( t.map( QPointF( -halfWidth, halfHeight ) ) );
742-
QPointF pt4( t.map( QPointF( halfWidth, halfHeight ) ) );
743-
e.writeSolid( layerName, fc, pt1, pt2, pt3, pt4 );
742+
QgsPolygon p( 1 );
743+
p[0].resize( 5 );
744+
p[0][0] = t.map( QPointF( -halfWidth, -halfHeight ) );
745+
p[0][1] = t.map( QPointF( halfWidth, -halfHeight ) );
746+
p[0][2] = t.map( QPointF( halfWidth, halfHeight ) );
747+
p[0][3] = t.map( QPointF( -halfWidth, halfHeight ) );
748+
p[0][4] = p[0][0];
749+
if ( mBrush.style() != Qt::NoBrush )
750+
e.writePolygon( p, layerName, "SOLID", fc );
751+
if ( mPen.style() != Qt::NoPen )
752+
e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth );
744753
return true;
745754
}
746-
else if ( symbolName == "cross" )
755+
else if ( symbolName == "cross" && mPen.style() != Qt::NoPen )
747756
{
748-
QgsPolyline line1( 2 );
749-
QPointF pt1( t.map( QPointF( -halfWidth, 0 ) ) );
750-
QPointF pt2( t.map( QPointF( halfWidth, 0 ) ) );
751-
line1[0] = pt1;
752-
line1[1] = pt2;
753-
e.writePolyline( line1, layerName, "CONTINUOUS", oc, outlineWidth, false );
754-
QgsPolyline line2( 2 );
755-
QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
756-
QPointF pt4( t.map( QPointF( 0, -halfHeight ) ) );
757-
line2[0] = pt3;
758-
line2[1] = pt4;
759-
e.writePolyline( line2, layerName, "CONTINUOUS", oc, outlineWidth, false );
757+
QgsPolyline line( 2 );
758+
line[0] = t.map( QPointF( -halfWidth, 0 ) );
759+
line[1] = t.map( QPointF( halfWidth, 0 ) );
760+
e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );
761+
762+
line[0] = t.map( QPointF( 0, halfHeight ) );
763+
line[1] = t.map( QPointF( 0, -halfHeight ) );
764+
e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );
765+
760766
return true;
761767
}
762768
else if ( symbolName == "triangle" )
763769
{
764-
QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
765-
QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
766-
QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
767-
QPointF pt4( t.map( QPointF( 0, halfHeight ) ) );
768-
e.writeSolid( layerName, fc, pt1, pt2, pt3, pt4 );
770+
QgsPolygon p( 1 );
771+
p[0].resize( 4 );
772+
p[0][0] = QPointF( t.map( QPointF( -halfWidth, -halfHeight ) ) );
773+
p[0][1] = QPointF( t.map( QPointF( halfWidth, -halfHeight ) ) );
774+
p[0][2] = QPointF( t.map( QPointF( 0, halfHeight ) ) );
775+
p[0][3] = p[0][0];
776+
if ( mBrush.style() != Qt::NoBrush )
777+
e.writePolygon( p, layerName, "SOLID", fc );
778+
if ( mPen.style() != Qt::NoPen )
779+
e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth );
769780
return true;
770781
}
771782

‎src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

Lines changed: 95 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -932,57 +932,48 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
932932
}
933933
else if ( mName == "square" || mName == "rectangle" )
934934
{
935-
// pt1 pt2
936-
// pt3 pt4
937-
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
938-
QPointF pt2 = t.map( QPointF( halfSize, -halfSize ) );
939-
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
940-
QPointF pt4 = t.map( QPointF( halfSize, halfSize ) );
935+
QgsPolygon p( 1 );
936+
p[0].resize( 5 );
937+
p[0][0] = t.map( QPointF( -halfSize, -halfSize ) );
938+
p[0][1] = t.map( QPointF( -halfSize, halfSize ) );
939+
p[0][2] = t.map( QPointF( halfSize, halfSize ) );
940+
p[0][3] = t.map( QPointF( halfSize, -halfSize ) );
941+
p[0][4] = p[0][0];
941942

942943
if ( mBrush.style() != Qt::NoBrush )
943-
e.writeSolid( layerName, bc, pt1, pt2, pt3, pt4 );
944-
944+
e.writePolygon( p, layerName, "SOLID", bc );
945945
if ( mPen.style() != Qt::NoPen )
946-
{
947-
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
948-
e.writeLine( pt2, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
949-
e.writeLine( pt4, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
950-
e.writeLine( pt3, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
951-
}
946+
e.writePolyline( p[0], layerName, "CONTINUOUS", pc, outlineWidth );
952947
}
953948
else if ( mName == "diamond" )
954949
{
955-
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
956-
QPointF pt2 = t.map( QPointF( 0, -halfSize ) );
957-
QPointF pt3 = t.map( QPointF( 0, halfSize ) );
958-
QPointF pt4 = t.map( QPointF( halfSize, 0 ) );
950+
QgsPolygon p( 1 );
951+
p[0].resize( 5 );
952+
p[0][0] = t.map( QPointF( -halfSize, 0 ) );
953+
p[0][1] = t.map( QPointF( 0, halfSize ) );
954+
p[0][3] = t.map( QPointF( halfSize, 0 ) );
955+
p[0][1] = t.map( QPointF( 0, -halfSize ) );
956+
p[0][4] = p[0][0];
959957

960958
if ( mBrush.style() != Qt::NoBrush )
961-
e.writeSolid( layerName, bc, pt1, pt2, pt3, pt4 );
962-
959+
e.writePolygon( p, layerName, "SOLID", bc );
963960
if ( mPen.style() != Qt::NoPen )
964-
{
965-
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
966-
e.writeLine( pt2, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
967-
e.writeLine( pt3, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
968-
e.writeLine( pt4, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
969-
}
961+
e.writePolyline( p[0], layerName, "CONTINUOUS", pc, outlineWidth );
970962
}
971963
else if ( mName == "triangle" )
972964
{
973-
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
974-
QPointF pt2 = t.map( QPointF( halfSize, -halfSize ) );
975-
QPointF pt3 = t.map( QPointF( 0, halfSize ) );
965+
QgsPolygon p( 1 );
966+
p[0].resize( 4 );
967+
p[0][0] = t.map( QPointF( -halfSize, -halfSize ) );
968+
p[0][1] = t.map( QPointF( halfSize, -halfSize ) );
969+
p[0][1] = t.map( QPointF( 0, halfSize ) );
970+
p[0][2] = p[0][0];
976971

977972
if ( mBrush.style() != Qt::NoBrush )
978-
e.writeSolid( layerName, bc, pt1, pt2, pt3, pt3 );
973+
e.writePolygon( p, layerName, "SOLID", bc );
979974

980975
if ( mPen.style() != Qt::NoPen )
981-
{
982-
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
983-
e.writeLine( pt2, pt3, layerName, "CONTINUOUS", pc, outlineWidth );
984-
e.writeLine( pt3, pt1, layerName, "CONTINUOUS", pc, outlineWidth );
985-
}
976+
e.writePolyline( p[0], layerName, "CONTINUOUS", pc, outlineWidth );
986977
}
987978
#if 0
988979
else if ( mName == "equilateral_triangle" )
@@ -1000,51 +991,53 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
1000991
}
1001992
else if ( mName == "cross" )
1002993
{
1003-
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1004-
QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1005-
QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1006-
QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1007-
1008994
if ( mPen.style() != Qt::NoPen )
1009995
{
996+
QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
997+
QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
998+
QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
999+
QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1000+
10101001
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
10111002
e.writeLine( pt3, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
10121003
}
10131004
}
10141005
else if ( mName == "x" || mName == "cross2" )
10151006
{
1016-
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1017-
QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1018-
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
1019-
QPointF pt4 = t.map( QPointF( halfSize, -halfSize ) );
1020-
10211007
if ( mPen.style() != Qt::NoPen )
10221008
{
1009+
QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1010+
QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1011+
QPointF pt3 = t.map( QPointF( -halfSize, halfSize ) );
1012+
QPointF pt4 = t.map( QPointF( halfSize, -halfSize ) );
1013+
10231014
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
10241015
e.writeLine( pt3, pt4, layerName, "CONTINUOUS", pc, outlineWidth );
10251016
}
10261017
}
10271018
else if ( mName == "arrowhead" )
10281019
{
1029-
QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1030-
QPointF pt2 = t.map( QPointF( 0, 0 ) );
1031-
QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1032-
10331020
if ( mPen.style() != Qt::NoPen )
10341021
{
1022+
QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1023+
QPointF pt2 = t.map( QPointF( 0, 0 ) );
1024+
QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1025+
10351026
e.writeLine( pt1, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
10361027
e.writeLine( pt3, pt2, layerName, "CONTINUOUS", pc, outlineWidth );
10371028
}
10381029
}
10391030
else if ( mName == "filled_arrowhead" )
10401031
{
1041-
QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1042-
QPointF pt2 = t.map( QPointF( 0, 0 ) );
1043-
QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1044-
10451032
if ( mBrush.style() != Qt::NoBrush )
10461033
{
1047-
e.writeSolid( layerName, bc, pt1, pt2, pt3, pt3 );
1034+
QgsPolygon p( 1 );
1035+
p[0].resize( 4 );
1036+
p[0][0] = t.map( QPointF( -halfSize, halfSize ) );
1037+
p[0][1] = t.map( QPointF( 0, 0 ) );
1038+
p[0][2] = t.map( QPointF( -halfSize, -halfSize ) );
1039+
p[0][3] = p[0][0];
1040+
e.writePolygon( p, layerName, "SOLID", bc );
10481041
}
10491042
}
10501043
else
@@ -1608,15 +1601,6 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
16081601
Q_UNUSED( layerName );
16091602
Q_UNUSED( shift ); //todo...
16101603

1611-
QSvgRenderer r( mPath );
1612-
if ( !r.isValid() )
1613-
{
1614-
return false;
1615-
}
1616-
1617-
QgsDxfPaintDevice pd( &e );
1618-
pd.setDrawingSize( QSizeF( r.defaultSize() ) );
1619-
16201604
//size
16211605
double size = mSize;
16221606
QgsExpression* sizeExpression = expression( "size" );
@@ -1674,6 +1658,54 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
16741658
if ( angle )
16751659
outputOffset = _rotatedOffset( outputOffset, angle );
16761660

1661+
QString path = mPath;
1662+
QgsExpression *nameExpression = expression( "name" );
1663+
if ( nameExpression )
1664+
{
1665+
path = nameExpression->evaluate( *f ).toString();
1666+
}
1667+
1668+
double outlineWidth = mOutlineWidth;
1669+
QgsExpression *outlineWidthExpression = expression( "outline_width" );
1670+
if ( outlineWidthExpression )
1671+
{
1672+
outlineWidth = outlineWidthExpression->evaluate( *f ).toDouble();
1673+
}
1674+
1675+
QColor fillColor = mFillColor;
1676+
QgsExpression *fillExpression = expression( "fill" );
1677+
if ( fillExpression )
1678+
{
1679+
QString colorString = fillExpression->evaluate( *f ).toString();
1680+
if ( !fillExpression->hasEvalError() )
1681+
fillColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
1682+
}
1683+
1684+
QColor outlineColor = mOutlineColor;
1685+
QgsExpression *outlineExpression = expression( "outline" );
1686+
if ( outlineExpression )
1687+
{
1688+
QString colorString = outlineExpression->evaluate( *f ).toString();
1689+
if ( !outlineExpression->hasEvalError() )
1690+
outlineColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
1691+
}
1692+
1693+
const QByteArray &svgContent = QgsSvgCache::instance()->svgContent( path, size, fillColor, outlineColor, outlineWidth,
1694+
context->renderContext().scaleFactor(),
1695+
context->renderContext().rasterScaleFactor() );
1696+
1697+
//if current entry image is 0: cache image for entry
1698+
// checks to see if image will fit into cache
1699+
//update stats for memory usage
1700+
QSvgRenderer r( svgContent );
1701+
if ( !r.isValid() )
1702+
{
1703+
return false;
1704+
}
1705+
1706+
QgsDxfPaintDevice pd( &e );
1707+
pd.setDrawingSize( QSizeF( r.defaultSize() ) );
1708+
16771709
QPainter p;
16781710
p.begin( &pd );
16791711
if ( !qgsDoubleNear( angle, 0.0 ) )

‎src/core/symbology-ng/qgssvgcache.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,33 @@
3636
#include <QNetworkReply>
3737
#include <QNetworkRequest>
3838

39-
QgsSvgCacheEntry::QgsSvgCacheEntry(): file( QString() ), size( 0.0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
40-
outline( Qt::black ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
39+
QgsSvgCacheEntry::QgsSvgCacheEntry()
40+
: file( QString() )
41+
, size( 0.0 )
42+
, outlineWidth( 0 )
43+
, widthScaleFactor( 1.0 )
44+
, rasterScaleFactor( 1.0 )
45+
, fill( Qt::black )
46+
, outline( Qt::black )
47+
, image( 0 )
48+
, picture( 0 )
49+
, nextEntry( 0 )
50+
, previousEntry( 0 )
4151
{
4252
}
4353

44-
QgsSvgCacheEntry::QgsSvgCacheEntry( const QString& f, double s, double ow, double wsf, double rsf, const QColor& fi, const QColor& ou ): file( f ), size( s ), outlineWidth( ow ),
45-
widthScaleFactor( wsf ), rasterScaleFactor( rsf ), fill( fi ), outline( ou ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
54+
QgsSvgCacheEntry::QgsSvgCacheEntry( const QString& f, double s, double ow, double wsf, double rsf, const QColor& fi, const QColor& ou )
55+
: file( f )
56+
, size( s )
57+
, outlineWidth( ow )
58+
, widthScaleFactor( wsf )
59+
, rasterScaleFactor( rsf )
60+
, fill( fi )
61+
, outline( ou )
62+
, image( 0 )
63+
, picture( 0 )
64+
, nextEntry( 0 )
65+
, previousEntry( 0 )
4666
{
4767
}
4868

@@ -55,8 +75,8 @@ QgsSvgCacheEntry::~QgsSvgCacheEntry()
5575

5676
bool QgsSvgCacheEntry::operator==( const QgsSvgCacheEntry& other ) const
5777
{
58-
return ( other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
59-
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline );
78+
return other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
79+
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline;
6080
}
6181

6282
int QgsSvgCacheEntry::dataSize() const
@@ -73,14 +93,6 @@ int QgsSvgCacheEntry::dataSize() const
7393
return size;
7494
}
7595

76-
QString file;
77-
double size;
78-
double outlineWidth;
79-
double widthScaleFactor;
80-
double rasterScaleFactor;
81-
QColor fill;
82-
QColor outline;
83-
8496
QgsSvgCache* QgsSvgCache::instance()
8597
{
8698
static QgsSvgCache mInstance;
@@ -169,6 +181,16 @@ const QPicture& QgsSvgCache::svgAsPicture( const QString& file, double size, con
169181
return *( currentEntry->picture );
170182
}
171183

184+
const QByteArray& QgsSvgCache::svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
185+
double widthScaleFactor, double rasterScaleFactor )
186+
{
187+
QMutexLocker locker( &mMutex );
188+
189+
QgsSvgCacheEntry *currentEntry = cacheEntry( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor );
190+
191+
return currentEntry->svgContent;
192+
}
193+
172194
QgsSvgCacheEntry* QgsSvgCache::insertSVG( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
173195
double widthScaleFactor, double rasterScaleFactor )
174196
{

‎src/core/symbology-ng/qgssvgcache.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ class CORE_EXPORT QgsSvgCache : public QObject
112112
/**Get image data*/
113113
QByteArray getImageData( const QString &path ) const;
114114

115+
/**Get SVG content*/
116+
const QByteArray& svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
117+
double widthScaleFactor, double rasterScaleFactor );
118+
115119
signals:
116120
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
117121
void statusChanged( const QString& theStatusQString );

0 commit comments

Comments
 (0)
Please sign in to comment.