From 3046650f0d34aeb6079492901bc68ad774b3e92d Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 4 Dec 2019 18:33:30 +0100 Subject: [PATCH] QskGraphic::Commandtypes added --- src/graphic/QskGraphic.cpp | 39 +++++++++++++++++++++++------------- src/graphic/QskGraphic.h | 19 ++++++++++++++++-- src/nodes/QskGraphicNode.cpp | 9 ++++++++- tools/svg2qvg/main.cpp | 2 +- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/graphic/QskGraphic.cpp b/src/graphic/QskGraphic.cpp index a2148eaf..3c84ff2c 100644 --- a/src/graphic/QskGraphic.cpp +++ b/src/graphic/QskGraphic.cpp @@ -339,7 +339,7 @@ class QskGraphic::PrivateData : public QSharedData PrivateData() : boundingRect( 0.0, 0.0, -1.0, -1.0 ) , pointRect( 0.0, 0.0, -1.0, -1.0 ) - , hasRasterData( false ) + , commandTypes( 0 ) , renderHints( 0 ) { } @@ -351,7 +351,7 @@ class QskGraphic::PrivateData : public QSharedData , pathInfos( other.pathInfos ) , boundingRect( other.boundingRect ) , pointRect( other.pointRect ) - , hasRasterData( other.hasRasterData ) + , commandTypes( other.commandTypes ) , renderHints( other.renderHints ) { } @@ -373,7 +373,7 @@ class QskGraphic::PrivateData : public QSharedData QRectF boundingRect; QRectF pointRect; - bool hasRasterData : 1; + uint commandTypes : 4; uint renderHints : 4; }; @@ -484,7 +484,8 @@ void QskGraphic::reset() { m_data->commands.clear(); m_data->pathInfos.clear(); - m_data->hasRasterData = false; + + m_data->commandTypes = 0; m_data->boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); m_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 ); @@ -504,9 +505,9 @@ bool QskGraphic::isEmpty() const return m_data->boundingRect.isEmpty(); } -bool QskGraphic::isScalable() const +QskGraphic::CommandTypes QskGraphic::commandTypes() const { - return !m_data->hasRasterData; + return static_cast< CommandTypes >( m_data->commandTypes ); } void QskGraphic::setRenderHint( RenderHint hint, bool on ) @@ -840,10 +841,11 @@ QImage QskGraphic::toImage( qreal devicePixelRatio ) const void QskGraphic::drawPath( const QPainterPath& path ) { const QPainter* painter = paintEngine()->painter(); - if ( painter == NULL ) + if ( painter == nullptr ) return; m_data->commands += QskPainterCommand( path ); + m_data->commandTypes |= QskGraphic::VectorData; if ( !path.isEmpty() ) { @@ -869,12 +871,12 @@ void QskGraphic::drawPath( const QPainterPath& path ) void QskGraphic::drawPixmap( const QRectF& rect, const QPixmap& pixmap, const QRectF& subRect ) { - const QPainter* painter = paintEngine()->painter(); - if ( painter == NULL ) + const auto painter = paintEngine()->painter(); + if ( painter == nullptr ) return; m_data->commands += QskPainterCommand( rect, pixmap, subRect ); - m_data->hasRasterData = true; + m_data->commandTypes |= QskGraphic::RasterData; const QRectF r = painter->transform().mapRect( rect ); updateControlPointRect( r ); @@ -884,12 +886,12 @@ void QskGraphic::drawPixmap( const QRectF& rect, void QskGraphic::drawImage( const QRectF& rect, const QImage& image, const QRectF& subRect, Qt::ImageConversionFlags flags ) { - const QPainter* painter = paintEngine()->painter(); - if ( painter == NULL ) + const auto painter = paintEngine()->painter(); + if ( painter == nullptr ) return; m_data->commands += QskPainterCommand( rect, image, subRect, flags ); - m_data->hasRasterData = true; + m_data->commandTypes |= QskGraphic::RasterData; const QRectF r = painter->transform().mapRect( rect ); @@ -900,13 +902,22 @@ void QskGraphic::drawImage( const QRectF& rect, const QImage& image, void QskGraphic::updateState( const QPaintEngineState& state ) { m_data->commands += QskPainterCommand( state ); + + if ( state.state() & QPaintEngine::DirtyTransform ) + { + if ( !( m_data->commandTypes & QskGraphic::Transformation ) ) + { + if ( !state.transform().isTranslating() ) + m_data->commandTypes |= QskGraphic::Transformation; + } + } } void QskGraphic::updateBoundingRect( const QRectF& rect ) { QRectF br = rect; - const QPainter* painter = paintEngine()->painter(); + const auto painter = paintEngine()->painter(); if ( painter && painter->hasClipping() ) { QRectF cr = painter->clipRegion().boundingRect(); diff --git a/src/graphic/QskGraphic.h b/src/graphic/QskGraphic.h index 4644079d..d4e427ea 100644 --- a/src/graphic/QskGraphic.h +++ b/src/graphic/QskGraphic.h @@ -23,13 +23,26 @@ class QPaintEngineState; class QSK_EXPORT QskGraphic : public QPaintDevice { + Q_GADGET + public: enum RenderHint { RenderPensUnscaled = 0x1 }; - typedef QFlags< RenderHint > RenderHints; + Q_ENUM( RenderHint ) + Q_DECLARE_FLAGS( RenderHints, RenderHint ) + + enum CommandType + { + VectorData = 1 << 0, + RasterData = 1 << 1, + Transformation = 1 << 2 + }; + + Q_ENUM( CommandType ) + Q_DECLARE_FLAGS( CommandTypes, CommandType ) QskGraphic(); QskGraphic( const QskGraphic& ); @@ -47,7 +60,8 @@ class QSK_EXPORT QskGraphic : public QPaintDevice bool isNull() const; bool isEmpty() const; - bool isScalable() const; + + CommandTypes commandTypes() const; void render( QPainter* ) const; void render( QPainter*, const QskColorFilter& filter, @@ -132,6 +146,7 @@ inline bool QskGraphic::operator!=( const QskGraphic& other ) const } Q_DECLARE_OPERATORS_FOR_FLAGS( QskGraphic::RenderHints ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QskGraphic::CommandTypes ) Q_DECLARE_METATYPE( QskGraphic ) #endif diff --git a/src/nodes/QskGraphicNode.cpp b/src/nodes/QskGraphicNode.cpp index 117c57d3..fe4d5022 100644 --- a/src/nodes/QskGraphicNode.cpp +++ b/src/nodes/QskGraphicNode.cpp @@ -53,7 +53,9 @@ void QskGraphicNode::setGraphic( QSize textureSize; - if ( graphic.isScalable() ) + constexpr auto mask = QskGraphic::VectorData | QskGraphic::Transformation; + + if ( graphic.commandTypes() & mask ) { textureSize = rect.size().toSize(); @@ -66,6 +68,11 @@ void QskGraphicNode::setGraphic( } else { + /* + simple raster data - usually a QImage/QPixmap only. + There is no benefit in rescaling it into the target rectangle + by the CPU and creating a new texture. + */ textureSize = graphic.defaultSize().toSize(); } diff --git a/tools/svg2qvg/main.cpp b/tools/svg2qvg/main.cpp index 16e79ce3..233c98f9 100644 --- a/tools/svg2qvg/main.cpp +++ b/tools/svg2qvg/main.cpp @@ -53,7 +53,7 @@ int main( int argc, char* argv[] ) renderer.render( &painter ); painter.end(); - if ( !graphic.isScalable() ) + if ( graphic.commandTypes() & QskGraphic::RasterData ) qWarning() << argv[1] << "contains non scalable parts."; QskGraphicIO::write( graphic, argv[2] );