mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
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:
parent
b6e059c655
commit
b3c2bd7f21
@ -87,6 +87,10 @@ class QgsSvgCache : QObject
|
|||||||
/**Get image data*/
|
/**Get image data*/
|
||||||
QByteArray getImageData( const QString &path ) const;
|
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:
|
signals:
|
||||||
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
|
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
|
||||||
void statusChanged( const QString& theStatusQString );
|
void statusChanged( const QString& theStatusQString );
|
||||||
|
@ -859,7 +859,8 @@ void QgsDxfExport::writeBlocks()
|
|||||||
writeGroup( 3, block );
|
writeGroup( 3, block );
|
||||||
writeGroup( 1, "" );
|
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" );
|
writeGroup( 0, "ENDBLK" );
|
||||||
writeHandle();
|
writeHandle();
|
||||||
|
@ -84,7 +84,7 @@ void QgsDxfPaintEngine::drawPolygon( const QPointF *points, int pointCount, Poly
|
|||||||
|
|
||||||
if ( mode == QPaintEngine::PolylineMode )
|
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() );
|
mDxf->writePolyline( polygon[0], mLayer, "CONTINUOUS", mPen.color(), currentWidth() );
|
||||||
}
|
}
|
||||||
else
|
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 )
|
void QgsDxfPaintEngine::drawPath( const QPainterPath& path )
|
||||||
{
|
{
|
||||||
int pathLength = path.elementCount();
|
int pathLength = path.elementCount();
|
||||||
@ -171,10 +152,8 @@ void QgsDxfPaintEngine::endPolygon()
|
|||||||
{
|
{
|
||||||
if ( mCurrentPolygon.size() > 1 )
|
if ( mCurrentPolygon.size() > 1 )
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if ( mPen.style() != Qt::NoPen )
|
if ( mPen.style() != Qt::NoPen )
|
||||||
drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
|
drawPolygon( mCurrentPolygon.constData(), mCurrentPolygon.size(), QPaintEngine::PolylineMode );
|
||||||
#endif
|
|
||||||
|
|
||||||
mPolygon.resize( mPolygon.size() + 1 );
|
mPolygon.resize( mPolygon.size() + 1 );
|
||||||
setRing( mPolygon[ mPolygon.size() - 1 ], mCurrentPolygon.constData(), mCurrentPolygon.size() );
|
setRing( mPolygon[ mPolygon.size() - 1 ], mCurrentPolygon.constData(), mCurrentPolygon.size() );
|
||||||
@ -196,7 +175,7 @@ void QgsDxfPaintEngine::endCurve()
|
|||||||
if ( mCurrentCurve.size() >= 3 )
|
if ( mCurrentCurve.size() >= 3 )
|
||||||
{
|
{
|
||||||
double t = 0.05;
|
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 ) );
|
mCurrentPolygon.append( bezierPoint( mCurrentCurve, t ) );
|
||||||
t += 0.05;
|
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 drawPixmap( const QRectF& r, const QPixmap& pm, const QRectF& sr ) override;
|
||||||
|
|
||||||
void drawPolygon( const QPointF * points, int pointCount, PolygonDrawMode mode ) 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 drawPath( const QPainterPath& path ) override;
|
||||||
void drawLines( const QLineF* lines, int lineCount ) 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( layerName );
|
||||||
Q_UNUSED( shift ); //todo...
|
Q_UNUSED( shift ); //todo...
|
||||||
|
|
||||||
QSvgRenderer r( mPath );
|
|
||||||
if ( !r.isValid() )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsDxfPaintDevice pd( &e );
|
|
||||||
pd.setDrawingSize( QSizeF( r.defaultSize() ) );
|
|
||||||
|
|
||||||
//size
|
//size
|
||||||
double size = mSize;
|
double size = mSize;
|
||||||
|
|
||||||
@ -1616,6 +1607,50 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
|
|||||||
if ( angle )
|
if ( angle )
|
||||||
outputOffset = _rotatedOffset( outputOffset, 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;
|
QPainter p;
|
||||||
p.begin( &pd );
|
p.begin( &pd );
|
||||||
if ( !qgsDoubleNear( angle, 0.0 ) )
|
if ( !qgsDoubleNear( angle, 0.0 ) )
|
||||||
|
@ -36,13 +36,33 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
|
|
||||||
QgsSvgCacheEntry::QgsSvgCacheEntry(): file( QString() ), size( 0.0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
|
QgsSvgCacheEntry::QgsSvgCacheEntry()
|
||||||
outline( Qt::black ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
|
: 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 ),
|
QgsSvgCacheEntry::QgsSvgCacheEntry( const QString& f, double s, double ow, double wsf, double rsf, const QColor& fi, const QColor& ou )
|
||||||
widthScaleFactor( wsf ), rasterScaleFactor( rsf ), fill( fi ), outline( ou ), image( 0 ), picture( 0 ), nextEntry( 0 ), previousEntry( 0 )
|
: 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
|
bool QgsSvgCacheEntry::operator==( const QgsSvgCacheEntry& other ) const
|
||||||
{
|
{
|
||||||
return ( other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
|
return other.file == file && other.size == size && other.outlineWidth == outlineWidth && other.widthScaleFactor == widthScaleFactor
|
||||||
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline );
|
&& other.rasterScaleFactor == rasterScaleFactor && other.fill == fill && other.outline == outline;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QgsSvgCacheEntry::dataSize() const
|
int QgsSvgCacheEntry::dataSize() const
|
||||||
@ -73,14 +93,6 @@ int QgsSvgCacheEntry::dataSize() const
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString file;
|
|
||||||
double size;
|
|
||||||
double outlineWidth;
|
|
||||||
double widthScaleFactor;
|
|
||||||
double rasterScaleFactor;
|
|
||||||
QColor fill;
|
|
||||||
QColor outline;
|
|
||||||
|
|
||||||
QgsSvgCache* QgsSvgCache::instance()
|
QgsSvgCache* QgsSvgCache::instance()
|
||||||
{
|
{
|
||||||
static QgsSvgCache mInstance;
|
static QgsSvgCache mInstance;
|
||||||
@ -169,6 +181,16 @@ const QPicture& QgsSvgCache::svgAsPicture( const QString& file, double size, con
|
|||||||
return *( currentEntry->picture );
|
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,
|
QgsSvgCacheEntry* QgsSvgCache::insertSVG( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
|
||||||
double widthScaleFactor, double rasterScaleFactor )
|
double widthScaleFactor, double rasterScaleFactor )
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,10 @@ class CORE_EXPORT QgsSvgCache : public QObject
|
|||||||
/**Get image data*/
|
/**Get image data*/
|
||||||
QByteArray getImageData( const QString &path ) const;
|
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:
|
signals:
|
||||||
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
|
/** Emit a signal to be caught by qgisapp and display a msg on status bar */
|
||||||
void statusChanged( const QString& theStatusQString );
|
void statusChanged( const QString& theStatusQString );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user