Skip to content
Permalink
Browse files

dxf export:

* fix support for data-defined properties in SVG export
* remove drawRects and let it fallback to drawPath and drawPolygon
* close arcs
  • Loading branch information
jef-n committed Jun 19, 2015
1 parent b6e059c commit b3c2bd7f21c917af8f7b745c966980b5d0f89e7b
@@ -87,6 +87,10 @@ class QgsSvgCache : QObject
/**Get image data*/
QByteArray getImageData( const QString &path ) const;

/**Get SVG content*/
const QByteArray& svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
double widthScaleFactor, double rasterScaleFactor );

signals:
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
void statusChanged( const QString& theStatusQString );
@@ -859,7 +859,8 @@ void QgsDxfExport::writeBlocks()
writeGroup( 3, block );
writeGroup( 1, "" );

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

writeGroup( 0, "ENDBLK" );
writeHandle();
@@ -84,7 +84,7 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, Poly

if ( mode == QPaintEngine::PolylineMode )
{
if ( mPen.style() != Qt::NoPen )
if ( mPen.style() != Qt::NoPen && mPen.brush().style() != Qt::NoBrush )
mDxf->writePolyline( polygon[0], mLayer, "CONTINUOUS", mPen.color(), currentWidth() );
}
else
@@ -94,25 +94,6 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, Poly
}
}

void QgsDxfPaintEngine::drawRects( const QRectF* rects, int rectCount )
{
if ( !mDxf || !mPaintDevice || !rects || mBrush.style() == Qt::NoBrush )
return;

for ( int i = 0; i < rectCount; ++i )
{
double left = rects[i].left();
double right = rects[i].right();
double top = rects[i].top();
double bottom = rects[i].bottom();
QgsPoint pt1 = toDxfCoordinates( QPointF( left, bottom ) );
QgsPoint pt2 = toDxfCoordinates( QPointF( right, bottom ) );
QgsPoint pt3 = toDxfCoordinates( QPointF( left, top ) );
QgsPoint pt4 = toDxfCoordinates( QPointF( right, top ) );
mDxf->writeSolid( mLayer, mBrush.color(), pt1, pt2, pt3, pt4 );
}
}

void QgsDxfPaintEngine::drawPath( const QPainterPath& path )
{
int pathLength = path.elementCount();
@@ -171,10 +152,8 @@ void QgsDxfPaintEngine::endPolygon()
{
if ( mCurrentPolygon.size() > 1 )
{
#if 0
if ( mPen.style() != Qt::NoPen )
drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
#endif

mPolygon.resize( mPolygon.size() + 1 );
setRing( mPolygon[ mPolygon.size() - 1 ], mCurrentPolygon.constData(), mCurrentPolygon.size() );
@@ -196,7 +175,7 @@ void QgsDxfPaintEngine::endCurve()
if ( mCurrentCurve.size() >= 3 )
{
double t = 0.05;
for ( int i = 1; i < 20; ++i ) //approximate curve with 20 segments
for ( int i = 1; i <= 20; ++i ) //approximate curve with 20 segments
{
mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
t += 0.05;
@@ -39,7 +39,6 @@ class CORE_EXPORT QgsDxfPaintEngine: public QPaintEngine
void drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr ) override;

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

@@ -1549,15 +1549,6 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
Q_UNUSED( layerName );
Q_UNUSED( shift ); //todo...

QSvgRenderer r( mPath );
if ( !r.isValid() )
{
return false;
}

QgsDxfPaintDevice pd( &e );
pd.setDrawingSize( QSizeF( r.defaultSize() ) );

//size
double size = mSize;

@@ -1616,6 +1607,50 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
if ( angle )
outputOffset = _rotatedOffset( outputOffset, angle );

QString path = mPath;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_NAME ) )
{
path = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_NAME, f, mPath ).toString();
}

double outlineWidth = mOutlineWidth;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) )
{
outlineWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH, f, mOutlineWidth ).toDouble();
}

QColor fillColor = mFillColor;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL ) )
{
QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL, f, QVariant(), &ok ).toString();
if ( ok )
fillColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
}

QColor outlineColor = mOutlineColor;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE ) )
{
QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE, f, QVariant(), &ok ).toString();
if ( ok )
outlineColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
}

const QByteArray &svgContent = QgsSvgCache::instance()->svgContent( path, size, fillColor, outlineColor, outlineWidth,
context->renderContext().scaleFactor(),
context->renderContext().rasterScaleFactor() );

//if current entry image is 0: cache image for entry
// checks to see if image will fit into cache
//update stats for memory usage
QSvgRenderer r( svgContent );
if ( !r.isValid() )
{
return false;
}

QgsDxfPaintDevice pd( &e );
pd.setDrawingSize( QSizeF( r.defaultSize() ) );

QPainter p;
p.begin( &pd );
if ( !qgsDoubleNear( angle, 0.0 ) )
@@ -36,13 +36,33 @@
#include <QNetworkReply>
#include <QNetworkRequest>

QgsSvgCacheEntry::QgsSvgCacheEntry(): file( QString() ), size( 0.0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
outline( Qt::black ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
QgsSvgCacheEntry::QgsSvgCacheEntry()
: file( QString() )
, size( 0.0 )
, outlineWidth( 0 )
, widthScaleFactor( 1.0 )
, rasterScaleFactor( 1.0 )
, fill( Qt::black )
, outline( Qt::black )
, image( 0 )
, picture( 0 )
, nextEntry( 0 )
, previousEntry( 0 )
{
}

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 ),
widthScaleFactor( wsf ), rasterScaleFactor( rsf ), fill( fi ), outline( ou ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
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 )
, widthScaleFactor( wsf )
, rasterScaleFactor( rsf )
, fill( fi )
, outline( ou )
, image( 0 )
, picture( 0 )
, nextEntry( 0 )
, previousEntry( 0 )
{
}

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

bool QgsSvgCacheEntry::operator==( const QgsSvgCacheEntry& other ) const
{
return ( other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline );
return other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline;
}

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

QString file;
double size;
double outlineWidth;
double widthScaleFactor;
double rasterScaleFactor;
QColor fill;
QColor outline;

QgsSvgCache* QgsSvgCache::instance()
{
static QgsSvgCache mInstance;
@@ -169,6 +181,16 @@ const QPicture& QgsSvgCache::svgAsPicture( const QString& file, double size, con
return *( currentEntry->picture );
}

const QByteArray& QgsSvgCache::svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
double widthScaleFactor, double rasterScaleFactor )
{
QMutexLocker locker( &mMutex );

QgsSvgCacheEntry *currentEntry = cacheEntry( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor );

return currentEntry->svgContent;
}

QgsSvgCacheEntry* QgsSvgCache::insertSVG( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
double widthScaleFactor, double rasterScaleFactor )
{
@@ -112,6 +112,10 @@ class CORE_EXPORT QgsSvgCache : public QObject
/**Get image data*/
QByteArray getImageData( const QString &path ) const;

/**Get SVG content*/
const QByteArray& svgContent( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
double widthScaleFactor, double rasterScaleFactor );

signals:
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
void statusChanged( const QString& theStatusQString );

0 comments on commit b3c2bd7

Please sign in to comment.
You can’t perform that action at this time.