6#include "QskGraphicIO.h"
8#include "QskPainterCommand.h"
11#include <qdatastream.h>
17static const char qskMagicNumber[] =
"QSKG";
24static const int qskDataStreamVersion = QDataStream::Qt_5_15;
26static inline void qskWritePathData(
27 const QPainterPath& path, QDataStream& s )
32static inline void qskReadPathData(
33 QDataStream& s, QVector< QskPainterCommand >& commands )
41static inline void qskWritePixmapData(
42 const QskPainterCommand::PixmapData& data, QDataStream& s )
44 s << data.rect << data.pixmap << data.subRect;
47static inline void qskReadPixmapData(
48 QDataStream& s, QVector< QskPainterCommand >& commands )
50 QskPainterCommand::PixmapData data;
59static inline void qskWriteImageData(
60 const QskPainterCommand::ImageData& data, QDataStream& s )
62 s << data.rect << data.image << data.subRect;
65static inline void qskReadImageData(
66 QDataStream& s, QVector< QskPainterCommand >& commands )
68 QskPainterCommand::ImageData data;
76 data.flags =
static_cast< Qt::ImageConversionFlags
>( flags );
81static inline void qskWriteStateData(
82 const QskPainterCommand::StateData& data, QDataStream& s )
84 s << static_cast< quint16 >( data.flags );
86 if ( data.flags & QPaintEngine::DirtyPen )
89 if ( data.flags & QPaintEngine::DirtyBrush )
92 if ( data.flags & QPaintEngine::DirtyBrushOrigin )
93 s << data.brushOrigin;
95 if ( data.flags & QPaintEngine::DirtyFont )
98 if ( data.flags & QPaintEngine::DirtyBackground )
100 s << static_cast< quint8 >( data.backgroundMode );
101 s << data.backgroundBrush;
104 if ( data.flags & QPaintEngine::DirtyTransform )
107 if ( data.flags & QPaintEngine::DirtyClipEnabled )
108 s << data.isClipEnabled;
110 if ( data.flags & QPaintEngine::DirtyClipRegion )
112 s << data.clipRegion;
113 s << static_cast< quint8 >( data.clipOperation );
116 if ( data.flags & QPaintEngine::DirtyClipPath )
119 s << static_cast< quint8 >( data.clipOperation );
122 if ( data.flags & QPaintEngine::DirtyHints )
123 s << static_cast< qint32 >( data.renderHints );
125 if ( data.flags & QPaintEngine::DirtyCompositionMode )
126 s << static_cast< qint16 >( data.compositionMode );
128 if ( data.flags & QPaintEngine::DirtyOpacity )
132static inline void qskReadStateData(
133 QDataStream& s, QVector< QskPainterCommand >& commands )
135 QskPainterCommand::StateData data;
140 data.flags =
static_cast< QPaintEngine::DirtyFlags
>( flags );
142 if ( data.flags & QPaintEngine::DirtyPen )
145 if ( data.flags & QPaintEngine::DirtyBrush )
148 if ( data.flags & QPaintEngine::DirtyBrushOrigin )
149 s >> data.brushOrigin;
151 if ( data.flags & QPaintEngine::DirtyFont )
154 if ( data.flags & QPaintEngine::DirtyBackground )
156 quint8 bgMode = data.backgroundMode;
157 s >> bgMode >> data.backgroundBrush;
158 data.backgroundMode =
static_cast< Qt::BGMode
>( bgMode );
161 if ( data.flags & QPaintEngine::DirtyTransform )
164 if ( data.flags & QPaintEngine::DirtyClipEnabled )
165 s >> data.isClipEnabled;
167 if ( data.flags & QPaintEngine::DirtyClipRegion )
169 s >> data.clipRegion;
171 quint8 clipOperation;
173 data.clipOperation =
static_cast< Qt::ClipOperation
>( clipOperation );
176 if ( data.flags & QPaintEngine::DirtyClipPath )
180 quint8 clipOperation;
182 data.clipOperation =
static_cast< Qt::ClipOperation
>( clipOperation );
185 if ( data.flags & QPaintEngine::DirtyHints )
189 data.renderHints =
static_cast< QPainter::RenderHints
>( renderHints );
192 if ( data.flags & QPaintEngine::DirtyCompositionMode )
194 qint16 compositionMode;
195 s >> compositionMode;
196 data.compositionMode =
static_cast< QPainter::CompositionMode
>( compositionMode );
199 if ( data.flags & QPaintEngine::DirtyOpacity )
205QskGraphic QskGraphicIO::read(
const QString& fileName )
207 QFile file( fileName );
208 if ( file.open( QIODevice::ReadOnly ) ==
false )
210 qWarning(
"QskGraphicIO::read can't open %s", qPrintable( fileName ) );
214 return read( &file );
217QskGraphic QskGraphicIO::read(
const QByteArray& data )
220 buffer.setData( data );
222 return read( &buffer );
225QskGraphic QskGraphicIO::read( QIODevice* dev )
227 if ( dev ==
nullptr )
230 QDataStream stream( dev );
232 stream.setVersion( qskDataStreamVersion );
234 stream.setByteOrder( QDataStream::BigEndian );
236 char magicNumber[ 4 ];
237 stream.readRawData( magicNumber, 4 );
238 if ( memcmp( magicNumber, qskMagicNumber, 4 ) != 0 )
240 qWarning(
"QskGraphicIO::read: bad magic number" );
248 stream >> numCommands;
250 QVector< QskPainterCommand > commands;
251 commands.reserve( numCommands );
253 for ( uint i = 0; i < numCommands; i++ )
262 qskReadPathData( stream, commands );
267 qskReadPixmapData( stream, commands );
272 qskReadImageData( stream, commands );
277 qskReadStateData( stream, commands );
286 graphic.setViewBox( viewBox );
287 graphic.setCommands( commands );
292bool QskGraphicIO::write(
const QskGraphic& graphic,
const QString& fileName )
294 QFile file( fileName );
295 if ( file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ==
false )
297 qWarning(
"QskGraphicIO::write can't open %s", qPrintable( fileName ) );
301 return write( graphic, &file );
304bool QskGraphicIO::write(
const QskGraphic& graphic, QByteArray& data )
306 QBuffer buffer( &data );
307 return write( graphic, &buffer );
310bool QskGraphicIO::write(
const QskGraphic& graphic, QIODevice* dev )
312 if ( dev ==
nullptr )
315 QDataStream stream( dev );
317 stream.setVersion( qskDataStreamVersion );
319 stream.setByteOrder( QDataStream::BigEndian );
320 stream.writeRawData( qskMagicNumber, 4 );
322 stream << graphic.viewBox();
324 const auto numCommands = graphic.commands().size();
327 stream << static_cast< quint32 >( numCommands );
329 for (
int i = 0; i < numCommands; i++ )
331 stream << static_cast< quint8 >( cmds[ i ].type() );
333 switch ( cmds[ i ].type() )
337 qskWritePathData( *cmds[ i ].path(), stream );
342 qskWritePixmapData( *cmds[ i ].pixmapData(), stream );
347 qskWriteImageData( *cmds[ i ].imageData(), stream );
352 qskWriteStateData( *cmds[ i ].stateData(), stream );
A paint device for scalable graphics.
@ Path
Draw a QPainterPath.
@ State
QPainter state change.