dxf export:

* fix support for data-defined properties in SVG export
* remove drawRects and let it fallback to drawPath and drawPolygon
* close arcs
This commit is contained in:
Juergen E. Fischer 2015-06-19 22:22:16 +02:00
parent b6e059c655
commit b3c2bd7f21
7 changed files with 92 additions and 48 deletions

View File

@ -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 );

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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 ) )

View File

@ -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 )
{

View File

@ -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 );