7#include "QskColorFilter.h"
8#include "QskGraphicPaintEngine.h"
9#include "QskPainterCommand.h"
11#include <qguiapplication.h>
14#include <qpaintengine.h>
16#include <qpainterpath.h>
18#include <qhashfunctions.h>
21#include <private/qpainter_p.h>
24static inline qreal qskDevicePixelRatio()
26 return qGuiApp ? qGuiApp->devicePixelRatio() : 1.0;
29static bool qskHasScalablePen(
const QPainter* painter )
31 const QPen pen = painter->pen();
33 bool scalablePen =
false;
35 if ( pen.style() != Qt::NoPen && pen.brush().style() != Qt::NoBrush )
37 scalablePen = !pen.isCosmetic();
43static QRectF qskStrokedPathRect(
44 const QPainter* painter,
const QPainterPath& path )
46 const auto pen = painter->pen();
48 QPainterPathStroker stroker;
49 stroker.setWidth( pen.widthF() );
50 stroker.setCapStyle( pen.capStyle() );
51 stroker.setJoinStyle( pen.joinStyle() );
52 stroker.setMiterLimit( pen.miterLimit() );
55 if ( qskHasScalablePen( painter ) )
57 const QPainterPath stroke = stroker.createStroke( path );
58 rect = painter->transform().map( stroke ).boundingRect();
62 QPainterPath mappedPath = painter->transform().map( path );
63 mappedPath = stroker.createStroke( mappedPath );
65 rect = mappedPath.boundingRect();
71static inline void qskExecCommand(
74 QskGraphic::RenderHints renderHints,
75 const QTransform& transform,
76 const QTransform* initialTransform )
84 if ( painter->transform().isScaling() )
86 if ( painter->pen().isCosmetic() )
91 doMap = painter->paintEngine()->type() == QPaintEngine::OpenGL2;
95 doMap = renderHints.testFlag( QskGraphic::RenderPensUnscaled );
101 const QTransform tr = painter->transform();
103 painter->resetTransform();
105 QPainterPath path = tr.map( *cmd.path() );
106 if ( initialTransform )
108 painter->setTransform( *initialTransform );
109 path = initialTransform->inverted().map( path );
112 painter->drawPath( path );
114 painter->setTransform( tr );
118 painter->drawPath( *cmd.path() );
124 const auto data = cmd.pixmapData();
125 painter->drawPixmap( data->rect, data->pixmap, data->subRect );
130 const auto data = cmd.imageData();
131 painter->drawImage( data->rect, data->image,
132 data->subRect, data->flags );
137 const auto data = cmd.stateData();
139 if ( data->flags & QPaintEngine::DirtyPen )
140 painter->setPen( colorFilter.substituted( data->pen ) );
142 if ( data->flags & QPaintEngine::DirtyBrush )
143 painter->setBrush( colorFilter.substituted( data->brush ) );
145 if ( data->flags & QPaintEngine::DirtyBrushOrigin )
146 painter->setBrushOrigin( data->brushOrigin );
148 if ( data->flags & QPaintEngine::DirtyFont )
149 painter->setFont( data->font );
151 if ( data->flags & QPaintEngine::DirtyBackground )
153 painter->setBackgroundMode( data->backgroundMode );
154 painter->setBackground( colorFilter.substituted( data->backgroundBrush ) );
157 if ( data->flags & QPaintEngine::DirtyTransform )
159 painter->setTransform( data->transform * transform );
162 if ( data->flags & QPaintEngine::DirtyClipEnabled )
163 painter->setClipping( data->isClipEnabled );
165 if ( data->flags & QPaintEngine::DirtyClipRegion )
167 painter->setClipRegion( data->clipRegion,
168 data->clipOperation );
171 if ( data->flags & QPaintEngine::DirtyClipPath )
173 painter->setClipPath( data->clipPath, data->clipOperation );
176 if ( data->flags & QPaintEngine::DirtyHints )
179 auto& state = QPainterPrivate::get( painter )->state;
180 state->renderHints = data->renderHints;
183 const auto hint = QPainter::SmoothPixmapTransform;
184 painter->setRenderHint( hint, data->renderHints.testFlag( hint ) );
186 for (
int i = 0; i < 8; i++ )
188 const auto hint =
static_cast< QPainter::RenderHint
>( 1 << i );
189 painter->setRenderHint( hint, data->renderHints.testFlag( hint ) );
194 if ( data->flags & QPaintEngine::DirtyCompositionMode )
195 painter->setCompositionMode( data->compositionMode );
197 if ( data->flags & QPaintEngine::DirtyOpacity )
198 painter->setOpacity( data->opacity );
211namespace QskGraphicPrivate
217 : m_scalablePen( false )
222 PathInfo(
const QRectF& pointRect,
223 const QRectF& boundingRect,
bool scalablePen )
224 : m_pointRect( pointRect )
225 , m_boundingRect( boundingRect )
226 , m_scalablePen( scalablePen )
230 inline QRectF scaledBoundingRect( qreal sx, qreal sy,
bool scalePens )
const
232 if ( sx == 1.0 && sy == 1.0 )
233 return m_boundingRect;
235 QTransform transform;
236 transform.scale( sx, sy );
239 if ( scalePens && m_scalablePen )
241 rect = transform.mapRect( m_boundingRect );
245 rect = transform.mapRect( m_pointRect );
247 const qreal l = qAbs( m_pointRect.left() - m_boundingRect.left() );
248 const qreal r = qAbs( m_pointRect.right() - m_boundingRect.right() );
249 const qreal t = qAbs( m_pointRect.top() - m_boundingRect.top() );
250 const qreal b = qAbs( m_pointRect.bottom() - m_boundingRect.bottom() );
252 rect.adjust( -l, -t, r, b );
258 inline double scaleFactorX(
const QRectF& pathRect,
259 const QRectF& targetRect,
const QRectF& graphicBoundingRect,
bool scalePens )
const
261 if ( pathRect.width() <= 0.0 )
264 const QPointF p0 = m_pointRect.center();
266 const auto p = pathRect.united( m_boundingRect );
268 const qreal l = qAbs( p.left() - p0.x() );
269 const qreal r = qAbs( p.right() - p0.x() );
271 const double w = 2.0 * qMin( l, r ) *
272 targetRect.width() / graphicBoundingRect.width();
275 if ( scalePens && m_scalablePen )
277 sx = w / m_boundingRect.width();
281 const qreal pw = qMax(
282 qAbs( m_boundingRect.left() - m_pointRect.left() ),
283 qAbs( m_boundingRect.right() - m_pointRect.right() ) );
285 sx = ( w - 2 * pw ) / m_pointRect.width();
291 inline double scaleFactorY(
const QRectF& pathRect,
292 const QRectF& targetRect,
const QRectF& graphicBoundingRect,
bool scalePens )
const
294 if ( pathRect.height() <= 0.0 )
297 const QPointF p0 = m_pointRect.center();
299 const auto p = pathRect.united( m_boundingRect );
301 const qreal t = qAbs( p.top() - p0.y() );
302 const qreal b = qAbs( p.bottom() - p0.y() );
304 const double h = 2.0 * qMin( t, b ) *
305 targetRect.height() / graphicBoundingRect.height();
308 if ( scalePens && m_scalablePen )
310 sy = h / m_boundingRect.height();
315 qMax( qAbs( m_boundingRect.top() - m_pointRect.top() ),
316 qAbs( m_boundingRect.bottom() - m_pointRect.bottom() ) );
318 sy = ( h - 2 * pw ) / m_pointRect.height();
326 QRectF m_boundingRect;
331class QskGraphic::PrivateData :
public QSharedData
340 PrivateData(
const PrivateData& other )
341 : QSharedData( other )
342 , viewBox( other.viewBox )
343 , commands( other.commands )
344 , pathInfos( other.pathInfos )
345 , boundingRect( other.boundingRect )
346 , pointRect( other.pointRect )
347 , modificationId( other.modificationId )
348 , commandTypes( other.commandTypes )
349 , renderHints( other.renderHints )
353 inline bool operator==(
const PrivateData& other )
const
355 return ( modificationId == other.modificationId ) &&
356 ( renderHints == other.renderHints ) &&
357 ( viewBox == other.viewBox );
366 boundingRect = pointRect = { 0.0, 0.0, -1.0, -1.0 };
375 static QAtomicInteger< quint64 > nextId( 1 );
376 modificationId = nextId.fetchAndAddRelaxed( 1 );
379 QRectF viewBox = { 0.0, 0.0, -1.0, -1.0 };
380 QVector< QskPainterCommand > commands;
381 QVector< QskGraphicPrivate::PathInfo > pathInfos;
383 QRectF boundingRect = { 0.0, 0.0, -1.0, -1.0 };
384 QRectF pointRect = { 0.0, 0.0, -1.0, -1.0 };
386 quint64 modificationId = 0;
388 uint commandTypes : 4;
389 uint renderHints : 4;
392QskGraphic::QskGraphic()
393 : m_data( new PrivateData() )
394 , m_paintEngine( nullptr )
398QskGraphic::QskGraphic(
const QskGraphic& other )
400 , m_data( other.m_data )
401 , m_paintEngine( nullptr )
406 : m_data( std::move( other.m_data ) )
407 , m_paintEngine( nullptr )
411QskGraphic::~QskGraphic()
413 delete m_paintEngine;
418 delete m_paintEngine;
419 m_data = other.m_data;
420 m_paintEngine =
nullptr;
427 m_data = std::move( other.m_data );
428 m_paintEngine =
nullptr;
432bool QskGraphic::operator==(
const QskGraphic& other )
const
434 return *m_data == *other.m_data;
437QPaintEngine* QskGraphic::paintEngine()
const
439 if ( m_paintEngine ==
nullptr )
442 return m_paintEngine;
445int QskGraphic::metric( PaintDeviceMetric deviceMetric )
const
449 switch ( deviceMetric )
453 value = qCeil( defaultSize().width() );
458 value = qCeil( defaultSize().height() );
471 case PdmPhysicalDpiX:
472 case PdmPhysicalDpiY:
481 value = qRound( metric( PdmWidth ) * 25.4 / metric( PdmDpiX ) );
486 value = qRound( metric( PdmHeight ) * 25.4 / metric( PdmDpiY ) );
489 case PdmDevicePixelRatio:
494 case PdmDevicePixelRatioScaled:
496 value = metric( PdmDevicePixelRatio ) * devicePixelRatioFScale();
499#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
500 case PdmDevicePixelRatioF_EncodedA:
501 case PdmDevicePixelRatioF_EncodedB:
504 value = QPaintDevice::encodeMetricF( metric, devicePixelRatio() );
514void QskGraphic::reset()
516 m_data->resetCommands();
518 m_data->viewBox = { 0.0, 0.0, -1.0, -1.0 };
520 delete m_paintEngine;
521 m_paintEngine =
nullptr;
524bool QskGraphic::isNull()
const
526 return m_data->commands.isEmpty();
529bool QskGraphic::isEmpty()
const
531 return m_data->boundingRect.isEmpty();
534QskGraphic::CommandTypes QskGraphic::commandTypes()
const
536 return static_cast< CommandTypes
>( m_data->commandTypes );
539void QskGraphic::setRenderHint( RenderHint hint,
bool on )
542 m_data->renderHints |= hint;
544 m_data->renderHints &= ~hint;
547bool QskGraphic::testRenderHint( RenderHint hint )
const
549 return m_data->renderHints & hint;
552QskGraphic::RenderHints QskGraphic::renderHints()
const
554 return static_cast< QskGraphic::RenderHints
>( m_data->renderHints );
557QRectF QskGraphic::boundingRect()
const
559 if ( m_data->boundingRect.width() < 0 )
562 return m_data->boundingRect;
565QRectF QskGraphic::controlPointRect()
const
567 if ( m_data->pointRect.width() < 0 )
570 return m_data->pointRect;
573QRectF QskGraphic::scaledBoundingRect( qreal sx, qreal sy )
const
575 if ( sx == 1.0 && sy == 1.0 )
576 return m_data->boundingRect;
578 const bool scalePens = !( m_data->renderHints & RenderPensUnscaled );
580 QTransform transform;
581 transform.scale( sx, sy );
583 QRectF rect = transform.mapRect( m_data->pointRect );
585 for (
const auto& info : std::as_const( m_data->pathInfos ) )
586 rect |= info.scaledBoundingRect( sx, sy, scalePens );
591QSize QskGraphic::sizeMetrics()
const
593 const QSizeF sz = defaultSize();
594 return QSize( qCeil( sz.width() ), qCeil( sz.height() ) );
597void QskGraphic::setViewBox(
const QRectF& rect )
599 m_data->viewBox = rect;
602QRectF QskGraphic::viewBox()
const
604 return m_data->viewBox;
607QSizeF QskGraphic::defaultSize()
const
609 if ( !m_data->viewBox.isEmpty() )
610 return m_data->viewBox.size();
612 return boundingRect().size();
615qreal QskGraphic::heightForWidth( qreal width )
const
617 const auto sz = defaultSize();
621 return sz.height() * width / sz.width();
624qreal QskGraphic::widthForHeight( qreal height )
const
626 const auto sz = defaultSize();
630 return sz.width() * height / sz.height();
633qreal QskGraphic::aspectRatio()
const
635 const auto sz = defaultSize();
639 return sz.width() / sz.height();
642void QskGraphic::render( QPainter* painter )
const
647void QskGraphic::render( QPainter* painter,
648 const QskColorFilter& colorFilter, QTransform* initialTransform )
const
653 const int numCommands = m_data->commands.size();
654 const auto commands = m_data->commands.constData();
656 const auto transform = painter->transform();
657 const QskGraphic::RenderHints renderHints( m_data->renderHints );
661 for (
int i = 0; i < numCommands; i++ )
663 qskExecCommand( painter, commands[ i ], colorFilter,
664 renderHints, transform, initialTransform );
670void QskGraphic::render( QPainter* painter,
const QSizeF& size,
671 Qt::AspectRatioMode aspectRatioMode )
const
673 const QRectF r( 0.0, 0.0, size.width(), size.height() );
674 render( painter, r, aspectRatioMode );
677void QskGraphic::render( QPainter* painter,
const QRectF& rect,
678 Qt::AspectRatioMode aspectRatioMode )
const
683void QskGraphic::render( QPainter* painter,
const QRectF& rect,
684 const QskColorFilter& colorFilter, Qt::AspectRatioMode aspectRatioMode )
const
686 if ( isEmpty() || rect.isEmpty() )
689 const bool scalePens = !( m_data->renderHints & RenderPensUnscaled );
694 QRectF boundingBox = m_data->viewBox;
696 if ( !boundingBox.isEmpty() )
698 sx = rect.width() / boundingBox.width();
699 sy = rect.height() / boundingBox.height();
703 boundingBox = m_data->boundingRect;
705 if ( m_data->pointRect.width() > 0.0 )
706 sx = rect.width() / m_data->pointRect.width();
708 if ( m_data->pointRect.height() > 0.0 )
709 sy = rect.height() / m_data->pointRect.height();
711 for (
const auto& info : std::as_const( m_data->pathInfos ) )
713 const qreal ssx = info.scaleFactorX( m_data->pointRect,
714 rect, m_data->boundingRect, scalePens );
717 sx = qMin( sx, ssx );
719 const qreal ssy = info.scaleFactorY( m_data->pointRect,
720 rect, m_data->boundingRect, scalePens );
723 sy = qMin( sy, ssy );
727 if ( aspectRatioMode == Qt::KeepAspectRatio )
729 sx = sy = qMin( sx, sy );
731 else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding )
733 sx = sy = qMax( sx, sy );
739 const auto rc = rect.center();
742 rc.x() - 0.5 * sx * boundingBox.width(),
743 rc.y() - 0.5 * sy * boundingBox.height() );
745 tr.translate( -boundingBox.x(), -boundingBox.y() );
748 const auto transform = painter->transform();
750 painter->setTransform( tr,
true );
752 if ( !scalePens && transform.isScaling() )
760 QTransform initialTransform;
761 initialTransform.scale( transform.m11(), transform.m22() );
763 render( painter, colorFilter, &initialTransform );
767 render( painter, colorFilter,
nullptr );
770 painter->setTransform( transform );
773void QskGraphic::render( QPainter* painter,
774 const QPointF& pos, Qt::Alignment alignment )
const
776 QRectF r( pos, defaultSize() );
778 if ( alignment & Qt::AlignLeft )
780 r.moveLeft( pos.x() );
782 else if ( alignment & Qt::AlignHCenter )
784 r.moveCenter( QPointF( pos.x(), r.center().y() ) );
786 else if ( alignment & Qt::AlignRight )
788 r.moveRight( pos.x() );
791 if ( alignment & Qt::AlignTop )
793 r.moveTop( pos.y() );
795 else if ( alignment & Qt::AlignVCenter )
797 r.moveCenter( QPointF( r.center().x(), pos.y() ) );
799 else if ( alignment & Qt::AlignBottom )
801 r.moveBottom( pos.y() );
804 render( painter, r );
807QPixmap QskGraphic::toPixmap( qreal devicePixelRatio )
const
812 if ( devicePixelRatio <= 0.0 )
813 devicePixelRatio = qskDevicePixelRatio();
815 const QSizeF sz = defaultSize();
817 const int w = qCeil( sz.width() * devicePixelRatio );
818 const int h = qCeil( sz.height() * devicePixelRatio );
820 QPixmap pixmap( w, h );
821 pixmap.setDevicePixelRatio( devicePixelRatio );
822 pixmap.fill( Qt::transparent );
824 const QRectF r( 0.0, 0.0, sz.width(), sz.height() );
826 QPainter painter( &pixmap );
827 render( &painter, r, Qt::KeepAspectRatio );
833QPixmap QskGraphic::toPixmap(
const QSize& size,
834 Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio )
const
836 if ( devicePixelRatio <= 0.0 )
837 devicePixelRatio = qskDevicePixelRatio();
839 const int w = qCeil( size.width() * devicePixelRatio );
840 const int h = qCeil( size.height() * devicePixelRatio );
842 QPixmap pixmap( w, h );
843 pixmap.setDevicePixelRatio( devicePixelRatio );
844 pixmap.fill( Qt::transparent );
846 const QRect r( 0, 0, size.width(), size.height() );
848 QPainter painter( &pixmap );
849 render( &painter, r, aspectRatioMode );
855QImage QskGraphic::toImage(
const QSize& size,
856 Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio )
const
858 if ( devicePixelRatio <= 0.0 )
859 devicePixelRatio = qskDevicePixelRatio();
861 const int w = qCeil( size.width() * devicePixelRatio );
862 const int h = qCeil( size.height() * devicePixelRatio );
864 QImage image( w, h, QImage::Format_ARGB32_Premultiplied );
865 image.setDevicePixelRatio( devicePixelRatio );
868 const QRect r( 0, 0, size.width(), size.height() );
870 QPainter painter( &image );
871 render( &painter, r, aspectRatioMode );
877QImage QskGraphic::toImage( qreal devicePixelRatio )
const
882 if ( devicePixelRatio <= 0.0 )
883 devicePixelRatio = qskDevicePixelRatio();
885 const QSizeF sz = defaultSize();
887 const int w = qCeil( sz.width() * devicePixelRatio );
888 const int h = qCeil( sz.height() * devicePixelRatio );
890 QImage image( w, h, QImage::Format_ARGB32 );
891 image.setDevicePixelRatio( devicePixelRatio );
894 const QRect r( 0, 0, sz.width(), sz.height() );
896 QPainter painter( &image );
897 render( &painter, r, Qt::KeepAspectRatio );
903void QskGraphic::drawPath(
const QPainterPath& path )
905 const auto painter = paintEngine()->painter();
906 if ( painter ==
nullptr )
910 m_data->commandTypes |= QskGraphic::VectorData;
912 if ( !path.isEmpty() )
914 const auto scaledPath = painter->transform().map( path );
916 QRectF pointRect = scaledPath.boundingRect();
917 QRectF boundingRect = pointRect;
919 if ( painter->pen().style() != Qt::NoPen &&
920 painter->pen().brush().style() != Qt::NoBrush )
922 boundingRect = qskStrokedPathRect( painter, path );
925 updateControlPointRect( pointRect );
926 updateBoundingRect( boundingRect );
928 m_data->pathInfos += QskGraphicPrivate::PathInfo( pointRect,
929 boundingRect, qskHasScalablePen( painter ) );
933void QskGraphic::drawPixmap(
const QRectF& rect,
934 const QPixmap& pixmap,
const QRectF& subRect )
936 const auto painter = paintEngine()->painter();
937 if ( painter ==
nullptr )
941 m_data->commandTypes |= QskGraphic::RasterData;
943 const QRectF r = painter->transform().mapRect( rect );
944 updateControlPointRect( r );
945 updateBoundingRect( r );
948void QskGraphic::drawImage(
const QRectF& rect,
const QImage& image,
949 const QRectF& subRect, Qt::ImageConversionFlags flags )
951 const auto painter = paintEngine()->painter();
952 if ( painter ==
nullptr )
956 m_data->commandTypes |= QskGraphic::RasterData;
958 const QRectF r = painter->transform().mapRect( rect );
960 updateControlPointRect( r );
961 updateBoundingRect( r );
964void QskGraphic::updateState(
const QPaintEngineState& state )
968 if ( state.state() & QPaintEngine::DirtyTransform )
970 if ( !( m_data->commandTypes & QskGraphic::Transformation ) )
977 if ( state.transform().isScaling() )
978 m_data->commandTypes |= QskGraphic::Transformation;
983void QskGraphic::updateBoundingRect(
const QRectF& rect )
987 if (
const auto painter = paintEngine()->painter() )
989 if ( painter->hasClipping() )
991 QRectF cr = painter->clipRegion().boundingRect();
992 cr = painter->transform().mapRect( cr );
998 if ( m_data->boundingRect.width() < 0 )
999 m_data->boundingRect = br;
1001 m_data->boundingRect |= br;
1004void QskGraphic::updateControlPointRect(
const QRectF& rect )
1006 if ( m_data->pointRect.width() < 0.0 )
1007 m_data->pointRect = rect;
1009 m_data->pointRect |= rect;
1012const QVector< QskPainterCommand >& QskGraphic::commands()
const
1014 return m_data->commands;
1017void QskGraphic::setCommands(
const QVector< QskPainterCommand >& commands )
1019 m_data->resetCommands();
1021 const int numCommands = commands.size();
1022 if ( numCommands <= 0 )
1028 const auto cmds = commands.constData();
1031 const QTransform noTransform;
1033 QPainter painter(
this );
1035 for (
int i = 0; i < numCommands; i++ )
1037 qskExecCommand( &painter, cmds[ i ],
1038 noFilter, RenderHints(), noTransform,
nullptr );
1044quint64 QskGraphic::modificationId()
const
1046 return m_data->modificationId;
1049QskHashValue QskGraphic::hash( QskHashValue seed )
const
1051 auto hash = qHash( m_data->renderHints, seed );
1052 hash = qHashBits( &m_data->viewBox,
sizeof( QRectF ), hash );
1054 return qHash( m_data->modificationId, hash );
1057QskGraphic QskGraphic::fromImage(
const QImage& image )
1061 if ( !image.isNull() )
1063 QPainter painter( &graphic );
1064 painter.drawImage( 0, 0, image );
1071QskGraphic QskGraphic::fromPixmap(
const QPixmap& pixmap )
1075 if ( !pixmap.isNull() )
1077 QPainter painter( &graphic );
1078 painter.drawPixmap( 0, 0, pixmap );
1085QskGraphic QskGraphic::fromPixmapAsImage(
const QPixmap& pixmap )
1099 return fromImage( pixmap.toImage() );
1105 if ( colorFilter.isIdentity() )
1110 QPainter painter( &recoloredGraphic );
1111 graphic.render( &painter, colorFilter );
1114 return recoloredGraphic;
1117#ifndef QT_NO_DEBUG_STREAM
1121QDebug operator<<( QDebug debug,
const QskGraphic& graphic )
1123 QDebugStateSaver saver( debug );
1125 debug <<
"Graphic" <<
'(';
1126 debug <<
"\n boundingRect:" << graphic.boundingRect();
1127 debug <<
"\n controlPointsRect:" << graphic.boundingRect();
1128 debug <<
"\n commandTypes:" << graphic.commandTypes();
1130 for (
const auto& command : graphic.commands() )
1132 switch ( command.type() )
1136 const auto& path = *command.path();
1138 debug <<
"\n Path(" << path.elementCount() <<
")";
1140 const char* types[] = {
"MoveTo",
"LineTo",
"CurveTo",
"CurveToData" };
1142 for (
int i = 0; i < path.elementCount(); i++ )
1146 const auto el = path.elementAt(i);
1147 debug << types[ el.type] << el.x << el.y;
1154 const auto& pixmapData = *command.pixmapData();
1156 debug <<
"\n Pixmap:";
1157 debug <<
"\n " << pixmapData.pixmap;
1158 debug <<
"\n Rect:" << pixmapData.rect;
1159 debug <<
"\n SubRect:" << pixmapData.subRect;
1164 const auto& imageData = *command.imageData();
1166 debug <<
"\n Image:";
1167 debug <<
"\n " << imageData.image;
1168 debug <<
"\n ConversionFlags" << imageData.flags;
1169 debug <<
"\n Rect:" << imageData.rect;
1170 debug <<
"\n SubRect:" << imageData.subRect;
1176 const auto& stateData = *command.stateData();
1177 const auto flags = stateData.flags;
1179 debug <<
"\n State:";
1181 const char indent[] =
"\n ";
1183 if ( flags & QPaintEngine::DirtyPen )
1185 debug << indent <<
"Pen:" << stateData.pen;
1188 if ( flags & QPaintEngine::DirtyBrush )
1190 debug << indent <<
"Brush:" << stateData.brush;
1193 if ( flags & QPaintEngine::DirtyBrushOrigin )
1195 debug << indent <<
"BrushOrigin:" << stateData.brushOrigin;
1198 if ( flags & QPaintEngine::DirtyFont )
1200 debug << indent <<
"Font:" << stateData.font;
1203 if ( flags & QPaintEngine::DirtyBackground )
1205 debug << indent <<
"Background:"
1206 << stateData.backgroundMode
1207 << stateData.backgroundBrush;
1210 if ( flags & QPaintEngine::DirtyTransform )
1212 debug << indent <<
"Transform: " << stateData.transform;
1215 if ( flags & QPaintEngine::DirtyClipEnabled )
1217 debug << indent <<
"ClipEnabled: " << stateData.isClipEnabled;
1220 if ( flags & QPaintEngine::DirtyClipRegion )
1222 debug << indent <<
"ClipRegion: " << stateData.clipOperation;
1225 if ( flags & QPaintEngine::DirtyClipPath )
1227 debug << indent <<
"ClipPath:" << stateData.clipOperation;
1230 if ( flags & QPaintEngine::DirtyHints )
1232 debug << indent <<
"RenderHints:" << stateData.renderHints;
1235 if ( flags & QPaintEngine::DirtyCompositionMode )
1237 debug << indent <<
"CompositionMode:" << stateData.compositionMode;
1240 if ( flags & QPaintEngine::DirtyOpacity )
1242 debug << indent <<
"Opacity:" << stateData.opacity;
1259#include "moc_QskGraphic.cpp"
A paint device for scalable graphics.
@ Path
Draw a QPainterPath.
@ State
QPainter state change.
Type type() const noexcept