QskGraphic::Commandtypes added

This commit is contained in:
Uwe Rathmann 2019-12-04 18:33:30 +01:00
parent 7fc772e891
commit 3046650f0d
4 changed files with 51 additions and 18 deletions

View File

@ -339,7 +339,7 @@ class QskGraphic::PrivateData : public QSharedData
PrivateData() PrivateData()
: boundingRect( 0.0, 0.0, -1.0, -1.0 ) : boundingRect( 0.0, 0.0, -1.0, -1.0 )
, pointRect( 0.0, 0.0, -1.0, -1.0 ) , pointRect( 0.0, 0.0, -1.0, -1.0 )
, hasRasterData( false ) , commandTypes( 0 )
, renderHints( 0 ) , renderHints( 0 )
{ {
} }
@ -351,7 +351,7 @@ class QskGraphic::PrivateData : public QSharedData
, pathInfos( other.pathInfos ) , pathInfos( other.pathInfos )
, boundingRect( other.boundingRect ) , boundingRect( other.boundingRect )
, pointRect( other.pointRect ) , pointRect( other.pointRect )
, hasRasterData( other.hasRasterData ) , commandTypes( other.commandTypes )
, renderHints( other.renderHints ) , renderHints( other.renderHints )
{ {
} }
@ -373,7 +373,7 @@ class QskGraphic::PrivateData : public QSharedData
QRectF boundingRect; QRectF boundingRect;
QRectF pointRect; QRectF pointRect;
bool hasRasterData : 1; uint commandTypes : 4;
uint renderHints : 4; uint renderHints : 4;
}; };
@ -484,7 +484,8 @@ void QskGraphic::reset()
{ {
m_data->commands.clear(); m_data->commands.clear();
m_data->pathInfos.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->boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
m_data->pointRect = 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(); 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 ) void QskGraphic::setRenderHint( RenderHint hint, bool on )
@ -840,10 +841,11 @@ QImage QskGraphic::toImage( qreal devicePixelRatio ) const
void QskGraphic::drawPath( const QPainterPath& path ) void QskGraphic::drawPath( const QPainterPath& path )
{ {
const QPainter* painter = paintEngine()->painter(); const QPainter* painter = paintEngine()->painter();
if ( painter == NULL ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( path ); m_data->commands += QskPainterCommand( path );
m_data->commandTypes |= QskGraphic::VectorData;
if ( !path.isEmpty() ) if ( !path.isEmpty() )
{ {
@ -869,12 +871,12 @@ void QskGraphic::drawPath( const QPainterPath& path )
void QskGraphic::drawPixmap( const QRectF& rect, void QskGraphic::drawPixmap( const QRectF& rect,
const QPixmap& pixmap, const QRectF& subRect ) const QPixmap& pixmap, const QRectF& subRect )
{ {
const QPainter* painter = paintEngine()->painter(); const auto painter = paintEngine()->painter();
if ( painter == NULL ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( rect, pixmap, subRect ); m_data->commands += QskPainterCommand( rect, pixmap, subRect );
m_data->hasRasterData = true; m_data->commandTypes |= QskGraphic::RasterData;
const QRectF r = painter->transform().mapRect( rect ); const QRectF r = painter->transform().mapRect( rect );
updateControlPointRect( r ); updateControlPointRect( r );
@ -884,12 +886,12 @@ void QskGraphic::drawPixmap( const QRectF& rect,
void QskGraphic::drawImage( const QRectF& rect, const QImage& image, void QskGraphic::drawImage( const QRectF& rect, const QImage& image,
const QRectF& subRect, Qt::ImageConversionFlags flags ) const QRectF& subRect, Qt::ImageConversionFlags flags )
{ {
const QPainter* painter = paintEngine()->painter(); const auto painter = paintEngine()->painter();
if ( painter == NULL ) if ( painter == nullptr )
return; return;
m_data->commands += QskPainterCommand( rect, image, subRect, flags ); m_data->commands += QskPainterCommand( rect, image, subRect, flags );
m_data->hasRasterData = true; m_data->commandTypes |= QskGraphic::RasterData;
const QRectF r = painter->transform().mapRect( rect ); 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 ) void QskGraphic::updateState( const QPaintEngineState& state )
{ {
m_data->commands += QskPainterCommand( 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 ) void QskGraphic::updateBoundingRect( const QRectF& rect )
{ {
QRectF br = rect; QRectF br = rect;
const QPainter* painter = paintEngine()->painter(); const auto painter = paintEngine()->painter();
if ( painter && painter->hasClipping() ) if ( painter && painter->hasClipping() )
{ {
QRectF cr = painter->clipRegion().boundingRect(); QRectF cr = painter->clipRegion().boundingRect();

View File

@ -23,13 +23,26 @@ class QPaintEngineState;
class QSK_EXPORT QskGraphic : public QPaintDevice class QSK_EXPORT QskGraphic : public QPaintDevice
{ {
Q_GADGET
public: public:
enum RenderHint enum RenderHint
{ {
RenderPensUnscaled = 0x1 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();
QskGraphic( const QskGraphic& ); QskGraphic( const QskGraphic& );
@ -47,7 +60,8 @@ class QSK_EXPORT QskGraphic : public QPaintDevice
bool isNull() const; bool isNull() const;
bool isEmpty() const; bool isEmpty() const;
bool isScalable() const;
CommandTypes commandTypes() const;
void render( QPainter* ) const; void render( QPainter* ) const;
void render( QPainter*, const QskColorFilter& filter, 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::RenderHints )
Q_DECLARE_OPERATORS_FOR_FLAGS( QskGraphic::CommandTypes )
Q_DECLARE_METATYPE( QskGraphic ) Q_DECLARE_METATYPE( QskGraphic )
#endif #endif

View File

@ -53,7 +53,9 @@ void QskGraphicNode::setGraphic(
QSize textureSize; QSize textureSize;
if ( graphic.isScalable() ) constexpr auto mask = QskGraphic::VectorData | QskGraphic::Transformation;
if ( graphic.commandTypes() & mask )
{ {
textureSize = rect.size().toSize(); textureSize = rect.size().toSize();
@ -66,6 +68,11 @@ void QskGraphicNode::setGraphic(
} }
else 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(); textureSize = graphic.defaultSize().toSize();
} }

View File

@ -53,7 +53,7 @@ int main( int argc, char* argv[] )
renderer.render( &painter ); renderer.render( &painter );
painter.end(); painter.end();
if ( !graphic.isScalable() ) if ( graphic.commandTypes() & QskGraphic::RasterData )
qWarning() << argv[1] << "contains non scalable parts."; qWarning() << argv[1] << "contains non scalable parts.";
QskGraphicIO::write( graphic, argv[2] ); QskGraphicIO::write( graphic, argv[2] );