7#include "QskColorFilter.h"
8#include "QskGraphicPaintEngine.h"
9#include "QskPainterCommand.h"
10#include "QskInternalMacros.h"
12#include <qguiapplication.h>
15#include <qpaintengine.h>
17#include <qpainterpath.h>
19#include <qhashfunctions.h>
22#include <private/qpainter_p.h>
25static inline qreal qskDevicePixelRatio()
27 return qGuiApp ? qGuiApp->devicePixelRatio() : 1.0;
30static bool qskHasScalablePen(
const QPainter* painter )
32 const QPen pen = painter->pen();
34 bool scalablePen =
false;
36 if ( pen.style() != Qt::NoPen && pen.brush().style() != Qt::NoBrush )
38 scalablePen = !pen.isCosmetic();
44static QRectF qskStrokedPathRect(
45 const QPainter* painter,
const QPainterPath& path )
47 const auto pen = painter->pen();
49 QPainterPathStroker stroker;
50 stroker.setWidth( pen.widthF() );
51 stroker.setCapStyle( pen.capStyle() );
52 stroker.setJoinStyle( pen.joinStyle() );
53 stroker.setMiterLimit( pen.miterLimit() );
56 if ( qskHasScalablePen( painter ) )
58 const QPainterPath stroke = stroker.createStroke( path );
59 rect = painter->transform().map( stroke ).boundingRect();
63 QPainterPath mappedPath = painter->transform().map( path );
64 mappedPath = stroker.createStroke( mappedPath );
66 rect = mappedPath.boundingRect();
72static inline void qskExecCommand(
75 QskGraphic::RenderHints renderHints,
76 const QTransform& transform,
77 const QTransform* initialTransform )
81 case QskPainterCommand::Path:
85 if ( painter->transform().isScaling() )
87 if ( painter->pen().isCosmetic() )
92 doMap = painter->paintEngine()->type() == QPaintEngine::OpenGL2;
96 doMap = renderHints.testFlag( QskGraphic::RenderPensUnscaled );
102 const QTransform tr = painter->transform();
104 painter->resetTransform();
106 QPainterPath path = tr.map( *cmd.path() );
107 if ( initialTransform )
109 painter->setTransform( *initialTransform );
110 path = initialTransform->inverted().map( path );
113 painter->drawPath( path );
115 painter->setTransform( tr );
119 painter->drawPath( *cmd.path() );
123 case QskPainterCommand::Pixmap:
125 const auto data = cmd.pixmapData();
126 painter->drawPixmap( data->rect, data->pixmap, data->subRect );
129 case QskPainterCommand::Image:
131 const auto data = cmd.imageData();
132 painter->drawImage( data->rect, data->image,
133 data->subRect, data->flags );
136 case QskPainterCommand::State:
138 const auto data = cmd.stateData();
140 if ( data->flags & QPaintEngine::DirtyPen )
141 painter->setPen( colorFilter.substituted( data->pen ) );
143 if ( data->flags & QPaintEngine::DirtyBrush )
144 painter->setBrush( colorFilter.substituted( data->brush ) );
146 if ( data->flags & QPaintEngine::DirtyBrushOrigin )
147 painter->setBrushOrigin( data->brushOrigin );
149 if ( data->flags & QPaintEngine::DirtyFont )
150 painter->setFont( data->font );
152 if ( data->flags & QPaintEngine::DirtyBackground )
154 painter->setBackgroundMode( data->backgroundMode );
155 painter->setBackground( colorFilter.substituted( data->backgroundBrush ) );
158 if ( data->flags & QPaintEngine::DirtyTransform )
160 painter->setTransform( data->transform * transform );
163 if ( data->flags & QPaintEngine::DirtyClipEnabled )
164 painter->setClipping( data->isClipEnabled );
166 if ( data->flags & QPaintEngine::DirtyClipRegion )
168 painter->setClipRegion( data->clipRegion,
169 data->clipOperation );
172 if ( data->flags & QPaintEngine::DirtyClipPath )
174 painter->setClipPath( data->clipPath, data->clipOperation );
177 if ( data->flags & QPaintEngine::DirtyHints )
180 auto& state = QPainterPrivate::get( painter )->state;
181 state->renderHints = data->renderHints;
184 const auto hint = QPainter::SmoothPixmapTransform;
185 painter->setRenderHint( hint, data->renderHints.testFlag( hint ) );
187 for (
int i = 0; i < 8; i++ )
189 const auto hint =
static_cast< QPainter::RenderHint
>( 1 << i );
190 painter->setRenderHint( hint, data->renderHints.testFlag( hint ) );
195 if ( data->flags & QPaintEngine::DirtyCompositionMode )
196 painter->setCompositionMode( data->compositionMode );
198 if ( data->flags & QPaintEngine::DirtyOpacity )
199 painter->setOpacity( data->opacity );
212namespace QskGraphicPrivate
218 : m_scalablePen( false )
223 PathInfo(
const QRectF& pointRect,
224 const QRectF& boundingRect,
bool scalablePen )
225 : m_pointRect( pointRect )
226 , m_boundingRect( boundingRect )
227 , m_scalablePen( scalablePen )
231 inline QRectF scaledBoundingRect( qreal sx, qreal sy,
bool scalePens )
const
233 if ( sx == 1.0 && sy == 1.0 )
234 return m_boundingRect;
236 QTransform transform;
237 transform.scale( sx, sy );
240 if ( scalePens && m_scalablePen )
242 rect = transform.mapRect( m_boundingRect );
246 rect = transform.mapRect( m_pointRect );
248 const qreal l = qAbs( m_pointRect.left() - m_boundingRect.left() );
249 const qreal r = qAbs( m_pointRect.right() - m_boundingRect.right() );
250 const qreal t = qAbs( m_pointRect.top() - m_boundingRect.top() );
251 const qreal b = qAbs( m_pointRect.bottom() - m_boundingRect.bottom() );
253 rect.adjust( -l, -t, r, b );
259 inline double scaleFactorX(
const QRectF& pathRect,
260 const QRectF& targetRect,
const QRectF& graphicBoundingRect,
bool scalePens )
const
262 if ( pathRect.width() <= 0.0 )
265 const QPointF p0 = m_pointRect.center();
267 const auto p = pathRect.united( m_boundingRect );
269 const qreal l = qAbs( p.left() - p0.x() );
270 const qreal r = qAbs( p.right() - p0.x() );
272 const double w = 2.0 * qMin( l, r ) *
273 targetRect.width() / graphicBoundingRect.width();
276 if ( scalePens && m_scalablePen )
278 sx = w / m_boundingRect.width();
282 const qreal pw = qMax(
283 qAbs( m_boundingRect.left() - m_pointRect.left() ),
284 qAbs( m_boundingRect.right() - m_pointRect.right() ) );
286 sx = ( w - 2 * pw ) / m_pointRect.width();
292 inline double scaleFactorY(
const QRectF& pathRect,
293 const QRectF& targetRect,
const QRectF& graphicBoundingRect,
bool scalePens )
const
295 if ( pathRect.height() <= 0.0 )
298 const QPointF p0 = m_pointRect.center();
300 const auto p = pathRect.united( m_boundingRect );
302 const qreal t = qAbs( p.top() - p0.y() );
303 const qreal b = qAbs( p.bottom() - p0.y() );
305 const double h = 2.0 * qMin( t, b ) *
306 targetRect.height() / graphicBoundingRect.height();
309 if ( scalePens && m_scalablePen )
311 sy = h / m_boundingRect.height();
316 qMax( qAbs( m_boundingRect.top() - m_pointRect.top() ),
317 qAbs( m_boundingRect.bottom() - m_pointRect.bottom() ) );
319 sy = ( h - 2 * pw ) / m_pointRect.height();
327 QRectF m_boundingRect;
332class QskGraphic::PrivateData :
public QSharedData
341 PrivateData(
const PrivateData& other )
342 : QSharedData( other )
343 , viewBox( other.viewBox )
344 , commands( other.commands )
345 , pathInfos( other.pathInfos )
346 , boundingRect( other.boundingRect )
347 , pointRect( other.pointRect )
348 , modificationId( other.modificationId )
349 , commandTypes( other.commandTypes )
350 , renderHints( other.renderHints )
354 inline bool operator==(
const PrivateData& other )
const
356 return ( modificationId == other.modificationId ) &&
357 ( renderHints == other.renderHints ) &&
358 ( viewBox == other.viewBox );
367 boundingRect = pointRect = { 0.0, 0.0, -1.0, -1.0 };
376 static QAtomicInteger< quint64 > nextId( 1 );
377 modificationId = nextId.fetchAndAddRelaxed( 1 );
380 QRectF viewBox = { 0.0, 0.0, -1.0, -1.0 };
381 QVector< QskPainterCommand > commands;
382 QVector< QskGraphicPrivate::PathInfo > pathInfos;
384 QRectF boundingRect = { 0.0, 0.0, -1.0, -1.0 };
385 QRectF pointRect = { 0.0, 0.0, -1.0, -1.0 };
387 quint64 modificationId = 0;
389 uint commandTypes : 4;
390 uint renderHints : 4;
393QskGraphic::QskGraphic()
394 : m_data( new PrivateData() )
395 , m_paintEngine( nullptr )
399QskGraphic::QskGraphic(
const QskGraphic& other )
401 , m_data( other.m_data )
402 , m_paintEngine( nullptr )
407 : m_data( std::move( other.m_data ) )
408 , m_paintEngine( nullptr )
412QskGraphic::~QskGraphic()
414 delete m_paintEngine;
419 delete m_paintEngine;
420 m_data = other.m_data;
421 m_paintEngine =
nullptr;
428 m_data = std::move( other.m_data );
429 m_paintEngine =
nullptr;
433bool QskGraphic::operator==(
const QskGraphic& other )
const
435 return *m_data == *other.m_data;
438QPaintEngine* QskGraphic::paintEngine()
const
440 if ( m_paintEngine ==
nullptr )
443 return m_paintEngine;
446int QskGraphic::metric( PaintDeviceMetric deviceMetric )
const
450 switch ( deviceMetric )
454 value = qCeil( defaultSize().width() );
459 value = qCeil( defaultSize().height() );
472 case PdmPhysicalDpiX:
473 case PdmPhysicalDpiY:
482 value = qRound( metric( PdmWidth ) * 25.4 / metric( PdmDpiX ) );
487 value = qRound( metric( PdmHeight ) * 25.4 / metric( PdmDpiY ) );
490 case PdmDevicePixelRatio:
495 case PdmDevicePixelRatioScaled:
497 value = metric( PdmDevicePixelRatio ) * devicePixelRatioFScale();
500#if QT_VERSION >= QT_VERSION_CHECK( 6, 8, 0 )
501 case PdmDevicePixelRatioF_EncodedA:
502 case PdmDevicePixelRatioF_EncodedB:
505 value = QPaintDevice::encodeMetricF( metric, devicePixelRatio() );
515void QskGraphic::reset()
517 m_data->resetCommands();
519 m_data->viewBox = { 0.0, 0.0, -1.0, -1.0 };
521 delete m_paintEngine;
522 m_paintEngine =
nullptr;
525bool QskGraphic::isNull()
const
527 return m_data->commands.isEmpty();
530bool QskGraphic::isEmpty()
const
532 return m_data->boundingRect.isEmpty();
535QskGraphic::CommandTypes QskGraphic::commandTypes()
const
537 return static_cast< CommandTypes
>( m_data->commandTypes );
540void QskGraphic::setRenderHint( RenderHint hint,
bool on )
543 m_data->renderHints |= hint;
545 m_data->renderHints &= ~hint;
548bool QskGraphic::testRenderHint( RenderHint hint )
const
550 return m_data->renderHints & hint;
553QskGraphic::RenderHints QskGraphic::renderHints()
const
555 return static_cast< QskGraphic::RenderHints
>( m_data->renderHints );
558QRectF QskGraphic::boundingRect()
const
560 if ( m_data->boundingRect.width() < 0 )
563 return m_data->boundingRect;
566QRectF QskGraphic::controlPointRect()
const
568 if ( m_data->pointRect.width() < 0 )
571 return m_data->pointRect;
574QRectF QskGraphic::scaledBoundingRect( qreal sx, qreal sy )
const
576 if ( sx == 1.0 && sy == 1.0 )
577 return m_data->boundingRect;
579 const bool scalePens = !( m_data->renderHints & RenderPensUnscaled );
581 QTransform transform;
582 transform.scale( sx, sy );
584 QRectF rect = transform.mapRect( m_data->pointRect );
586 for (
const auto& info : std::as_const( m_data->pathInfos ) )
587 rect |= info.scaledBoundingRect( sx, sy, scalePens );
592QSize QskGraphic::sizeMetrics()
const
594 const QSizeF sz = defaultSize();
595 return QSize( qCeil( sz.width() ), qCeil( sz.height() ) );
598void QskGraphic::setViewBox(
const QRectF& rect )
600 m_data->viewBox = rect;
603QRectF QskGraphic::viewBox()
const
605 return m_data->viewBox;
608QSizeF QskGraphic::defaultSize()
const
610 if ( !m_data->viewBox.isEmpty() )
611 return m_data->viewBox.size();
613 return boundingRect().size();
616qreal QskGraphic::heightForWidth( qreal width )
const
618 const auto sz = defaultSize();
622 return sz.height() * width / sz.width();
625qreal QskGraphic::widthForHeight( qreal height )
const
627 const auto sz = defaultSize();
631 return sz.width() * height / sz.height();
634qreal QskGraphic::aspectRatio()
const
636 const auto sz = defaultSize();
640 return sz.width() / sz.height();
643void QskGraphic::render( QPainter* painter )
const
648void QskGraphic::render( QPainter* painter,
649 const QskColorFilter& colorFilter, QTransform* initialTransform )
const
654 const int numCommands = m_data->commands.size();
655 const auto commands = m_data->commands.constData();
657 const auto transform = painter->transform();
658 const QskGraphic::RenderHints renderHints( m_data->renderHints );
662 for (
int i = 0; i < numCommands; i++ )
664 qskExecCommand( painter, commands[ i ], colorFilter,
665 renderHints, transform, initialTransform );
671void QskGraphic::render( QPainter* painter,
const QSizeF& size,
672 Qt::AspectRatioMode aspectRatioMode )
const
674 const QRectF r( 0.0, 0.0, size.width(), size.height() );
675 render( painter, r, aspectRatioMode );
678void QskGraphic::render( QPainter* painter,
const QRectF& rect,
679 Qt::AspectRatioMode aspectRatioMode )
const
684void QskGraphic::render( QPainter* painter,
const QRectF& rect,
685 const QskColorFilter& colorFilter, Qt::AspectRatioMode aspectRatioMode )
const
687 if ( isEmpty() || rect.isEmpty() )
690 const bool scalePens = !( m_data->renderHints & RenderPensUnscaled );
695 QRectF boundingBox = m_data->viewBox;
697 if ( !boundingBox.isEmpty() )
699 sx = rect.width() / boundingBox.width();
700 sy = rect.height() / boundingBox.height();
704 boundingBox = m_data->boundingRect;
706 if ( m_data->pointRect.width() > 0.0 )
707 sx = rect.width() / m_data->pointRect.width();
709 if ( m_data->pointRect.height() > 0.0 )
710 sy = rect.height() / m_data->pointRect.height();
712 for (
const auto& info : std::as_const( m_data->pathInfos ) )
714 const qreal ssx = info.scaleFactorX( m_data->pointRect,
715 rect, m_data->boundingRect, scalePens );
718 sx = qMin( sx, ssx );
720 const qreal ssy = info.scaleFactorY( m_data->pointRect,
721 rect, m_data->boundingRect, scalePens );
724 sy = qMin( sy, ssy );
728 if ( aspectRatioMode == Qt::KeepAspectRatio )
730 sx = sy = qMin( sx, sy );
732 else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding )
734 sx = sy = qMax( sx, sy );
740 const auto rc = rect.center();
743 rc.x() - 0.5 * sx * boundingBox.width(),
744 rc.y() - 0.5 * sy * boundingBox.height() );
746 tr.translate( -boundingBox.x(), -boundingBox.y() );
749 const auto transform = painter->transform();
751 painter->setTransform( tr,
true );
753 if ( !scalePens && transform.isScaling() )
761 QTransform initialTransform;
762 initialTransform.scale( transform.m11(), transform.m22() );
764 render( painter, colorFilter, &initialTransform );
768 render( painter, colorFilter,
nullptr );
771 painter->setTransform( transform );
774void QskGraphic::render( QPainter* painter,
775 const QPointF& pos, Qt::Alignment alignment )
const
777 QRectF r( pos, defaultSize() );
779 if ( alignment & Qt::AlignLeft )
781 r.moveLeft( pos.x() );
783 else if ( alignment & Qt::AlignHCenter )
785 r.moveCenter( QPointF( pos.x(), r.center().y() ) );
787 else if ( alignment & Qt::AlignRight )
789 r.moveRight( pos.x() );
792 if ( alignment & Qt::AlignTop )
794 r.moveTop( pos.y() );
796 else if ( alignment & Qt::AlignVCenter )
798 r.moveCenter( QPointF( r.center().x(), pos.y() ) );
800 else if ( alignment & Qt::AlignBottom )
802 r.moveBottom( pos.y() );
805 render( painter, r );
808QPixmap QskGraphic::toPixmap( qreal devicePixelRatio )
const
813 if ( devicePixelRatio <= 0.0 )
814 devicePixelRatio = qskDevicePixelRatio();
816 const QSizeF sz = defaultSize();
818 const int w = qCeil( sz.width() * devicePixelRatio );
819 const int h = qCeil( sz.height() * devicePixelRatio );
821 QPixmap pixmap( w, h );
822 pixmap.setDevicePixelRatio( devicePixelRatio );
823 pixmap.fill( Qt::transparent );
825 const QRectF r( 0.0, 0.0, sz.width(), sz.height() );
827 QPainter painter( &pixmap );
828 render( &painter, r, Qt::KeepAspectRatio );
834QPixmap QskGraphic::toPixmap(
const QSize& size,
835 Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio )
const
837 if ( devicePixelRatio <= 0.0 )
838 devicePixelRatio = qskDevicePixelRatio();
840 const int w = qCeil( size.width() * devicePixelRatio );
841 const int h = qCeil( size.height() * devicePixelRatio );
843 QPixmap pixmap( w, h );
844 pixmap.setDevicePixelRatio( devicePixelRatio );
845 pixmap.fill( Qt::transparent );
847 const QRect r( 0, 0, size.width(), size.height() );
849 QPainter painter( &pixmap );
850 render( &painter, r, aspectRatioMode );
856QImage QskGraphic::toImage(
const QSize& size,
857 Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio )
const
859 if ( devicePixelRatio <= 0.0 )
860 devicePixelRatio = qskDevicePixelRatio();
862 const int w = qCeil( size.width() * devicePixelRatio );
863 const int h = qCeil( size.height() * devicePixelRatio );
865 QImage image( w, h, QImage::Format_ARGB32_Premultiplied );
866 image.setDevicePixelRatio( devicePixelRatio );
869 const QRect r( 0, 0, size.width(), size.height() );
871 QPainter painter( &image );
872 render( &painter, r, aspectRatioMode );
878QImage QskGraphic::toImage( qreal devicePixelRatio )
const
883 if ( devicePixelRatio <= 0.0 )
884 devicePixelRatio = qskDevicePixelRatio();
886 const QSizeF sz = defaultSize();
888 const int w = qCeil( sz.width() * devicePixelRatio );
889 const int h = qCeil( sz.height() * devicePixelRatio );
891 QImage image( w, h, QImage::Format_ARGB32 );
892 image.setDevicePixelRatio( devicePixelRatio );
895 const QRect r( 0, 0, sz.width(), sz.height() );
897 QPainter painter( &image );
898 render( &painter, r, Qt::KeepAspectRatio );
904void QskGraphic::drawPath(
const QPainterPath& path )
906 const auto painter = paintEngine()->painter();
907 if ( painter ==
nullptr )
911 m_data->commandTypes |= QskGraphic::VectorData;
913 if ( !path.isEmpty() )
915 const auto scaledPath = painter->transform().map( path );
917 QRectF pointRect = scaledPath.boundingRect();
918 QRectF boundingRect = pointRect;
920 if ( painter->pen().style() != Qt::NoPen &&
921 painter->pen().brush().style() != Qt::NoBrush )
923 boundingRect = qskStrokedPathRect( painter, path );
926 updateControlPointRect( pointRect );
927 updateBoundingRect( boundingRect );
929 m_data->pathInfos += QskGraphicPrivate::PathInfo( pointRect,
930 boundingRect, qskHasScalablePen( painter ) );
934void QskGraphic::drawPixmap(
const QRectF& rect,
935 const QPixmap& pixmap,
const QRectF& subRect )
937 const auto painter = paintEngine()->painter();
938 if ( painter ==
nullptr )
942 m_data->commandTypes |= QskGraphic::RasterData;
944 const QRectF r = painter->transform().mapRect( rect );
945 updateControlPointRect( r );
946 updateBoundingRect( r );
949void QskGraphic::drawImage(
const QRectF& rect,
const QImage& image,
950 const QRectF& subRect, Qt::ImageConversionFlags flags )
952 const auto painter = paintEngine()->painter();
953 if ( painter ==
nullptr )
957 m_data->commandTypes |= QskGraphic::RasterData;
959 const QRectF r = painter->transform().mapRect( rect );
961 updateControlPointRect( r );
962 updateBoundingRect( r );
965void QskGraphic::updateState(
const QPaintEngineState& state )
969 if ( state.state() & QPaintEngine::DirtyTransform )
971 if ( !( m_data->commandTypes & QskGraphic::Transformation ) )
978 if ( state.transform().isScaling() )
979 m_data->commandTypes |= QskGraphic::Transformation;
986 m_data->addCommand( command );
989void QskGraphic::updateBoundingRect(
const QRectF& rect )
993 if (
const auto painter = paintEngine()->painter() )
995 if ( painter->hasClipping() )
997 QRectF cr = painter->clipRegion().boundingRect();
998 cr = painter->transform().mapRect( cr );
1004 if ( m_data->boundingRect.width() < 0 )
1005 m_data->boundingRect = br;
1007 m_data->boundingRect |= br;
1010void QskGraphic::updateControlPointRect(
const QRectF& rect )
1012 if ( m_data->pointRect.width() < 0.0 )
1013 m_data->pointRect = rect;
1015 m_data->pointRect |= rect;
1018const QVector< QskPainterCommand >& QskGraphic::commands()
const
1020 return m_data->commands;
1023void QskGraphic::setCommands(
const QVector< QskPainterCommand >& commands )
1025 m_data->resetCommands();
1027 const int numCommands = commands.size();
1028 if ( numCommands <= 0 )
1034 const auto cmds = commands.constData();
1037 const QTransform noTransform;
1039 QPainter painter(
this );
1041 for (
int i = 0; i < numCommands; i++ )
1043 qskExecCommand( &painter, cmds[ i ],
1044 noFilter, RenderHints(), noTransform,
nullptr );
1050quint64 QskGraphic::modificationId()
const
1052 return m_data->modificationId;
1055QskHashValue QskGraphic::hash( QskHashValue seed )
const
1057 auto hash = qHash( m_data->renderHints, seed );
1058 hash = qHashBits( &m_data->viewBox,
sizeof( QRectF ), hash );
1060 return qHash( m_data->modificationId, hash );
1063QskGraphic QskGraphic::fromImage(
const QImage& image )
1067 if ( !image.isNull() )
1069 QPainter painter( &graphic );
1070 painter.drawImage( 0, 0, image );
1077QskGraphic QskGraphic::fromPixmap(
const QPixmap& pixmap )
1081 if ( !pixmap.isNull() )
1083 QPainter painter( &graphic );
1084 painter.drawPixmap( 0, 0, pixmap );
1091QskGraphic QskGraphic::fromPixmapAsImage(
const QPixmap& pixmap )
1105 return fromImage( pixmap.toImage() );
1111 if ( colorFilter.isIdentity() )
1116 QPainter painter( &recoloredGraphic );
1117 graphic.render( &painter, colorFilter );
1120 return recoloredGraphic;
1123#ifndef QT_NO_DEBUG_STREAM
1127QDebug operator<<( QDebug debug,
const QskGraphic& graphic )
1129 QDebugStateSaver saver( debug );
1131 debug <<
"Graphic" <<
'(';
1132 debug <<
"\n boundingRect:" << graphic.boundingRect();
1133 debug <<
"\n controlPointsRect:" << graphic.boundingRect();
1134 debug <<
"\n commandTypes:" << graphic.commandTypes();
1136 for (
const auto& command : graphic.commands() )
1138 switch ( command.type() )
1140 case QskPainterCommand::Path:
1142 const auto& path = *command.path();
1144 debug <<
"\n Path(" << path.elementCount() <<
")";
1146 const char* types[] = {
"MoveTo",
"LineTo",
"CurveTo",
"CurveToData" };
1148 for (
int i = 0; i < path.elementCount(); i++ )
1152 const auto el = path.elementAt(i);
1153 debug << types[ el.type] << el.x << el.y;
1158 case QskPainterCommand::Pixmap:
1160 const auto& pixmapData = *command.pixmapData();
1162 debug <<
"\n Pixmap:";
1163 debug <<
"\n " << pixmapData.pixmap;
1164 debug <<
"\n Rect:" << pixmapData.rect;
1165 debug <<
"\n SubRect:" << pixmapData.subRect;
1168 case QskPainterCommand::Image:
1170 const auto& imageData = *command.imageData();
1172 debug <<
"\n Image:";
1173 debug <<
"\n " << imageData.image;
1174 debug <<
"\n ConversionFlags" << imageData.flags;
1175 debug <<
"\n Rect:" << imageData.rect;
1176 debug <<
"\n SubRect:" << imageData.subRect;
1180 case QskPainterCommand::State:
1182 const auto& stateData = *command.stateData();
1183 const auto flags = stateData.flags;
1185 debug <<
"\n State:";
1187 const char indent[] =
"\n ";
1189 if ( flags & QPaintEngine::DirtyPen )
1191 debug << indent <<
"Pen:" << stateData.pen;
1194 if ( flags & QPaintEngine::DirtyBrush )
1196 debug << indent <<
"Brush:" << stateData.brush;
1199 if ( flags & QPaintEngine::DirtyBrushOrigin )
1201 debug << indent <<
"BrushOrigin:" << stateData.brushOrigin;
1204 if ( flags & QPaintEngine::DirtyFont )
1206 debug << indent <<
"Font:" << stateData.font;
1209 if ( flags & QPaintEngine::DirtyBackground )
1211 debug << indent <<
"Background:"
1212 << stateData.backgroundMode
1213 << stateData.backgroundBrush;
1216 if ( flags & QPaintEngine::DirtyTransform )
1218 debug << indent <<
"Transform: " << stateData.transform;
1221 if ( flags & QPaintEngine::DirtyClipEnabled )
1223 debug << indent <<
"ClipEnabled: " << stateData.isClipEnabled;
1226 if ( flags & QPaintEngine::DirtyClipRegion )
1228 debug << indent <<
"ClipRegion: " << stateData.clipOperation;
1231 if ( flags & QPaintEngine::DirtyClipPath )
1233 debug << indent <<
"ClipPath:" << stateData.clipOperation;
1236 if ( flags & QPaintEngine::DirtyHints )
1238 debug << indent <<
"RenderHints:" << stateData.renderHints;
1241 if ( flags & QPaintEngine::DirtyCompositionMode )
1243 debug << indent <<
"CompositionMode:" << stateData.compositionMode;
1246 if ( flags & QPaintEngine::DirtyOpacity )
1248 debug << indent <<
"Opacity:" << stateData.opacity;
1265#include "moc_QskGraphic.cpp"
A paint device for scalable graphics.