6#ifndef QT_NO_SVGGENERATOR
10#include "private/qpaintengine_p.h"
11#include "private/qtextengine_p.h"
12#include "private/qdrawhelper_p.h"
49 pattern_string->
chop(1);
133 return QPaintEngine::PaintEngineFeatures(
174 d_func()->size =
size;
185 d_func()->attributes.document_title =
title;
190 d_func()->attributes.document_description = description;
196 d_func()->outputDevice =
device;
210 if (!d_func()->savedPatternMasks.contains(maskId)) {
215 str <<
"<mask id=\"" << maskId <<
"\" x=\"0\" y=\"0\" width=\"8\" height=\"8\" "
216 <<
"stroke=\"none\" fill=\"#ffffff\" patternUnits=\"userSpaceOnUse\" >" <<
Qt::endl;
220 d_func()->savedPatternMasks.append(maskId);
228 if (!d_func()->savedPatternBrushes.contains(patternId)) {
235 d_func()->savedPatternBrushes.append(patternId);
276 qWarning(
"svg's don't support conical gradients!");
283 bool constantAlpha =
true;
284 int alpha = stops.
at(0).second.alpha();
285 for (
int i = 1;
i < stops.
size(); ++
i)
286 constantAlpha &= (stops.
at(
i).second.alpha() ==
alpha);
288 if (!constantAlpha) {
293 for (
int i = 0;
i + 1 < stops.
size(); ++
i) {
299 qreal step = (stops.
at(
i + 1).first - stops.
at(
i).first) / parts;
300 for (
int j = 1;
j < parts; ++
j) {
335 *d_func()->stream <<
QLatin1String(
"fill-rule=\"evenodd\" ");
336 *d_func()->stream <<
QLatin1String(
"stroke-linecap=\"square\" ");
337 *d_func()->stream <<
QLatin1String(
"stroke-linejoin=\"bevel\" ");
342 return *d_func()->stream;
348 d_func()->pen = spen;
350 switch (spen.
style()) {
355 d_func()->attributes.strokeOpacity =
QString();
363 d_func()->attributes.stroke =
color;
364 d_func()->attributes.strokeOpacity = colorOpacity;
385 d_func()->attributes.stroke =
color;
386 d_func()->attributes.strokeOpacity = colorOpacity;
387 d_func()->attributes.dashPattern = dashPattern;
388 d_func()->attributes.dashOffset = dashOffset;
402 stream() <<
"stroke-width=\"1\" ";
408 stream() <<
"stroke-linecap=\"butt\" ";
411 stream() <<
"stroke-linecap=\"square\" ";
414 stream() <<
"stroke-linecap=\"round\" ";
422 stream() <<
"stroke-linejoin=\"miter\" "
423 "stroke-miterlimit=\""<<spen.
miterLimit()<<
"\" ";
426 stream() <<
"stroke-linejoin=\"bevel\" ";
429 stream() <<
"stroke-linejoin=\"round\" ";
437 d_func()->brush = sbrush;
438 switch (sbrush.
style()) {
444 << colorOpacity <<
"\" ";
446 d_func()->attributes.fillOpacity = colorOpacity;
466 stream() <<
"fill=\"" << patternRef <<
"\" fill-opacity=\"" << colorOpacity <<
"\" ";
467 d_func()->attributes.
fill = patternRef;
468 d_func()->attributes.fillOpacity = colorOpacity;
474 d_func()->attributes.fillOpacity =
QString();
480 d_func()->attributes.fillOpacity =
QString();
486 d_func()->attributes.fillOpacity =
QString();
492 d_func()->attributes.fillOpacity =
QString();
505 if (
d->font.pixelSize() == -1)
511 d->attributes.font_family =
d->font.family();
514 *
d->stream <<
"font-family=\"" <<
d->attributes.font_family <<
"\" "
515 "font-size=\"" <<
d->attributes.font_size <<
"\" "
516 "font-weight=\"" <<
d->attributes.font_weight <<
"\" "
517 "font-style=\"" <<
d->attributes.font_style <<
"\" "
596 d->owns_iodevice =
false;
605 if (
d->owns_iodevice)
606 delete d->engine->outputDevice();
620 return d->engine->documentTitle();
627 d->engine->setDocumentTitle(
title);
640 return d->engine->documentDescription();
667 return d->engine->size();
673 if (
d->engine->isActive()) {
674 qWarning(
"QSvgGenerator::setSize(), cannot set size while SVG is being generated");
677 d->engine->setSize(
size);
697 return d->engine->viewBox();
710 return d->engine->viewBox().toRect();
716 if (
d->engine->isActive()) {
717 qWarning(
"QSvgGenerator::setViewBox(), cannot set viewBox while SVG is being generated");
744 if (
d->engine->isActive()) {
745 qWarning(
"QSvgGenerator::setFileName(), cannot set file name while SVG is being generated");
749 if (
d->owns_iodevice)
750 delete d->engine->outputDevice();
752 d->owns_iodevice =
true;
756 d->engine->setOutputDevice(
file);
772 return d->engine->outputDevice();
778 if (
d->engine->isActive()) {
779 qWarning(
"QSvgGenerator::setOutputDevice(), cannot set output device while SVG is being generated");
782 d->owns_iodevice =
false;
800 return d->engine->resolution();
806 d->engine->setResolution(dpi);
818 return d->engine->svgVersion();
841 return d->engine->size().width();
843 return d->engine->size().height();
845 return d->engine->resolution();
847 return d->engine->resolution();
849 return qRound(
d->engine->size().height() * 25.4 /
d->engine->resolution());
851 return qRound(
d->engine->size().width() * 25.4 /
d->engine->resolution());
855 return d->engine->resolution();
857 return d->engine->resolution();
863 qWarning(
"QSvgGenerator::metric(), unhandled metric %d\n",
metric);
876 if (!
d->outputDevice) {
877 qWarning(
"QSvgPaintEngine::begin(), no output device");
881 if (!
d->outputDevice->isOpen()) {
883 qWarning(
"QSvgPaintEngine::begin(), could not open output device: '%s'",
887 }
else if (!
d->outputDevice->isWritable()) {
888 qWarning(
"QSvgPaintEngine::begin(), could not write to read-only output device: '%s'",
896 *
d->stream <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" <<
Qt::endl <<
"<svg";
898 if (
d->size.isValid()) {
899 qreal wmm =
d->size.width() * 25.4 /
d->resolution;
900 qreal hmm =
d->size.height() * 25.4 /
d->resolution;
901 *
d->stream <<
" width=\"" << wmm <<
"mm\" height=\"" << hmm <<
"mm\"" <<
Qt::endl;
904 if (
d->viewBox.isValid()) {
905 *
d->stream <<
" viewBox=\"" <<
d->viewBox.left() <<
' ' <<
d->viewBox.top();
906 *
d->stream <<
' ' <<
d->viewBox.width() <<
' ' <<
d->viewBox.height() <<
'\"' <<
Qt::endl;
909 *
d->stream <<
" xmlns=\"http://www.w3.org/2000/svg\""
910 " xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
911 switch (
d->svgVersion) {
913 *
d->stream <<
" version=\"1.2\" baseProfile=\"tiny\">";
916 *
d->stream <<
" version=\"1.1\">";
921 if (!
d->attributes.document_title.isEmpty()) {
922 *
d->stream <<
"<title>" <<
d->attributes.document_title.toHtmlEscaped() <<
"</title>" <<
Qt::endl;
925 if (!
d->attributes.document_description.isEmpty()) {
926 *
d->stream <<
"<desc>" <<
d->attributes.document_description.toHtmlEscaped() <<
"</desc>" <<
Qt::endl;
929 d->stream->setString(&
d->defs);
930 *
d->stream <<
"<defs>\n";
932 d->stream->setString(&
d->body);
945 d->stream->setString(&
d->defs);
946 *
d->stream <<
"</defs>\n";
948 d->stream->setDevice(
d->outputDevice);
950 *
d->stream <<
d->header;
951 *
d->stream <<
d->defs;
952 *
d->stream <<
d->body;
953 if (
d->hasEmittedClipGroup)
954 *
d->stream <<
"</g>";
955 if (
d->afterFirstUpdate)
974 Qt::ImageConversionFlags
flags)
987 stream() <<
"x=\""<<
r.x()<<
"\" "
989 "width=\""<<
r.width()<<
"\" "
990 "height=\""<<
r.height()<<
"\" "
991 "preserveAspectRatio=\"none\" "
992 "image-rendering=\""<<quality<<
"\" ";
999 stream() <<
"xlink:href=\"data:image/png;base64,"
1010 if (
d->hasEmittedClipGroup)
1011 *
d->stream <<
"</g>\n";
1012 if (
d->afterFirstUpdate)
1013 *
d->stream <<
"</g>\n\n";
1017 if (
d->isClippingEffective()) {
1018 *
d->stream <<
QStringLiteral(
"<g clip-path=\"url(#%1)\">").arg(
d->currentClipPathName);
1019 d->hasEmittedClipGroup =
true;
1021 d->hasEmittedClipGroup =
false;
1024 *
d->stream <<
"<g ";
1030 *
d->stream <<
"transform=\"matrix(" <<
d->matrix.m11() <<
','
1031 <<
d->matrix.m12() <<
','
1032 <<
d->matrix.m21() <<
',' <<
d->matrix.m22() <<
','
1033 <<
d->matrix.dx() <<
',' <<
d->matrix.dy()
1044 d->afterFirstUpdate =
true;
1050 switch (
d->svgVersion) {
1061 if (clippingChanged) {
1064 d->clipEnabled =
false;
1065 d->clipPath.reset();
1077 if (
d->isClippingEffective() && clippingChanged) {
1078 d->stream->setString(&
d->defs);
1079 *
d->stream <<
QLatin1String(
"<clipPath id=\"%1\">\n").
arg(
d->generateClipPathName());
1081 *
d->stream <<
"</clipPath>\n";
1082 d->stream->setString(&
d->body);
1090 const bool isCircle =
r.width() ==
r.height();
1091 *
d->stream <<
'<' << (isCircle ?
"circle" :
"ellipse");
1093 *
d->stream <<
" vector-effect=\"non-scaling-stroke\"";
1095 *
d->stream <<
" cx=\"" <<
c.x() <<
"\" cy=\"" <<
c.y();
1097 *
d->stream <<
"\" r=\"" <<
r.width() /
qreal(2.0);
1099 *
d->stream <<
"\" rx=\"" <<
r.width() /
qreal(2.0) <<
"\" ry=\"" <<
r.height() /
qreal(2.0);
1107 *
d->stream <<
"<path vector-effect=\""
1109 <<
"\" fill-rule=\""
1113 for (
int i=0;
i<
p.elementCount(); ++
i) {
1117 *
d->stream <<
'M' <<
e.x <<
',' <<
e.y;
1120 *
d->stream <<
'L' <<
e.x <<
',' <<
e.y;
1123 *
d->stream <<
'C' <<
e.x <<
',' <<
e.y;
1125 while (
i <
p.elementCount()) {
1132 *
d->stream <<
e.x <<
',' <<
e.y;
1139 if (
i !=
p.elementCount() - 1) {
1155 for (
int i=1;
i<pointCount; ++
i)
1159 stream() <<
"<polyline fill=\"none\" vector-effect=\""
1162 for (
int i = 0;
i < pointCount; ++
i) {
1164 stream() << pt.
x() <<
',' << pt.
y() <<
' ';
1168 path.closeSubpath();
1177 for (
int i=0;
i < rectCount; ++
i) {
1179 *
d->stream <<
"<rect";
1181 *
d->stream <<
" vector-effect=\"non-scaling-stroke\"";
1182 *
d->stream <<
" x=\"" <<
rect.x() <<
"\" y=\"" <<
rect.y()
1183 <<
"\" width=\"" <<
rect.width() <<
"\" height=\"" <<
rect.height()
1199 *
d->stream <<
"<text "
1200 "fill=\"" <<
d->attributes.stroke <<
"\" "
1201 "fill-opacity=\"" <<
d->attributes.strokeOpacity <<
"\" "
1203 "xml:space=\"preserve\" "
1204 "x=\"" << pt.
x() <<
"\" y=\"" << pt.
y() <<
"\" ";
1207 <<
s.toHtmlEscaped()
IOBluetoothDevice * device
static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat=QImage::Format_MonoLSB)
Constructs a bitmap with the given size, and sets the contents to the bits supplied.
const QGradient * gradient() const
Returns the gradient describing this brush.
const QColor & color() const
Returns the brush color.
Qt::BrushStyle style() const
Returns the brush style.
\inmodule QtCore \reentrant
The QColor class provides colors based on RGB, HSV or CMYK values.
static QColor fromRgba(QRgb rgba) noexcept
Static convenience function that returns a QColor constructed from the given QRgb value rgba.
CoordinateMode coordinateMode() const
\inmodule QtCore \reentrant
constexpr QLatin1Char first() const
QString arg(Args &&...args) const
QPointF start() const
Returns the start point of this linear gradient in logical coordinates.
QPointF finalStop() const
Returns the final stop point of this linear gradient in logical coordinates.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
@ PdmDevicePixelRatioScaled
static qreal devicePixelRatioFScale()
The QPaintEngineState class provides information about the active paint engine's current state....
QTransform transform() const
Qt::ClipOperation clipOperation() const
Returns the clip operation in the current paint engine state.
bool isClipEnabled() const
Returns whether clipping is enabled or not in the current paint engine state.
QBrush brush() const
Returns the brush in the current paint engine state.
QPainter::RenderHints renderHints() const
Returns the render hints in the current paint engine state.
QFont font() const
Returns the font in the current paint engine state.
QPen pen() const
Returns the pen in the current paint engine state.
QPaintEngine::DirtyFlags state() const
Returns a combination of flags identifying the set of properties that need to be updated when updatin...
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
PolygonDrawMode
\value OddEvenMode The polygon should be drawn using OddEven fill rule.
QPainter * painter() const
Returns the paint engine's painter.
QPaintEngineState * state
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
Type
\value X11 \value Windows \value MacPrinter \value CoreGraphics \macos's Quartz2D (CoreGraphics) \val...
const QTransform & transform() const
Alias for worldTransform().
qreal widthF() const
Returns the pen width with floating point precision.
QList< qreal > dashPattern() const
Returns the dash pattern of this pen.
bool isCosmetic() const
Returns true if the pen is cosmetic; otherwise returns false.
QColor color() const
Returns the color of this pen's brush.
int width() const
Returns the pen width with integer precision.
Qt::PenCapStyle capStyle() const
Returns the pen's cap style.
Qt::PenJoinStyle joinStyle() const
Returns the pen's join style.
qreal miterLimit() const
Returns the miter limit of the pen.
qreal dashOffset() const
Returns the dash offset for the pen.
Qt::PenStyle style() const
Returns the pen style.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QImage toImage() const
Converts the pixmap to a QImage.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
QPointF center() const
Returns the center of this radial gradient in logical coordinates.
QPointF focalPoint() const
Returns the focal point of this radial gradient in logical coordinates.
qreal radius() const
Returns the radius of this radial gradient in logical coordinates.
\inmodule QtCore\reentrant
QRectF normalized() const noexcept
Returns a normalized rectangle; i.e., a rectangle that has a non-negative width and height.
\inmodule QtCore\reentrant
The QRegion class specifies a clip region for a painter.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString & fill(QChar c, qsizetype size=-1)
Sets every character in the string to character ch.
void chop(qsizetype n)
Removes n characters from the end of the string.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
static QString fromRawData(const QChar *, qsizetype size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setDescription(const QString &description)
void setResolution(int dpi)
QString fileName
the target filename for the generated SVG drawing
QSize size
the size of the generated SVG drawing
void setOutputDevice(QIODevice *outputDevice)
QString description
the description of the generated SVG drawing
SvgVersion svgVersion() const
void setViewBox(const QRect &viewBox)
int resolution
the resolution of the generated output
QSvgGenerator()
Constructs a new generator using the SVG Tiny 1.2 profile.
~QSvgGenerator()
Destroys the generator.
QIODevice * outputDevice
the output device for the generated SVG drawing
QRectF viewBox
the viewBox of the generated SVG drawing
int metric(QPaintDevice::PaintDeviceMetric metric) const override
\reimp
void setFileName(const QString &fileName)
QString title
the title of the generated SVG drawing
QPaintEngine * paintEngine() const override
Returns the paint engine used to render graphics to be converted to SVG format information.
void setSize(const QSize &size)
void setTitle(const QString &title)
QString generateClipPathName()
std::optional< QPainterPath > clipPath
bool isClippingEffective() const
QString currentGradientName
QSvgGenerator::SvgVersion svgVersion
struct QSvgPaintEnginePrivate::_attributes attributes
QStringList savedPatternMasks
QStringList savedPatternBrushes
QString currentClipPathName
QSvgPaintEnginePrivate(QSvgGenerator::SvgVersion version)
QString generateGradientName()
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) override
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
bool end() override
Reimplement this function to finish painting on the current paint device.
void saveLinearGradientBrush(const QGradient *g)
QString savePatternMask(Qt::BrushStyle style)
void qfontToSvg(const QFont &sfont)
void qpenToSvg(const QPen &spen)
void setSize(const QSize &size)
QIODevice * outputDevice() const
void saveGradientStops(QTextStream &str, const QGradient *g)
void drawEllipse(const QRectF &r) override
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect.
void setDocumentTitle(const QString &title)
QString documentDescription() const
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
void updateClipState(const QPaintEngineState &state)
void saveConicalGradientBrush(const QGradient *)
void saveRadialGradientBrush(const QGradient *g)
void qbrushToSvg(const QBrush &sbrush)
QString documentTitle() const
void drawTextItem(const QPointF &pt, const QTextItem &item) override
This function draws the text item textItem at position p.
void setViewBox(const QRectF &viewBox)
void setResolution(int resolution)
QSvgGenerator::SvgVersion svgVersion() const
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
void setDocumentDescription(const QString &description)
void setOutputDevice(QIODevice *device)
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
QPaintEngine::Type type() const override
Reimplement this function to return the paint engine \l{Type}.
bool begin(QPaintDevice *device) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
void generateQtDefaults()
void drawRects(const QRectF *rects, int rectCount) override
Draws the first rectCount rectangles in the buffer rects.
QString savePatternBrush(const QString &color, const QBrush &brush)
QSvgPaintEngine(QSvgGenerator::SvgVersion version)
void saveGradientUnits(QTextStream &str, const QGradient *gradient)
QFont font() const
Returns the font that should be used to draw the text.
Combined button and popup list for selecting options.
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
QPair< qreal, QColor > QGradientStop
static uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
bool qFuzzyIsNull(qfloat16 f) noexcept
int qRound(qfloat16 d) noexcept
QColor toColor(const QStringView &color)
QLatin1String fromColor(const QColor &color)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfixed GLfixed GLint GLint GLfixed points
GLsizei const GLchar *const * path
GLfloat GLfloat GLfloat alpha
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
QRgb qUnpremultiply(QRgb p)
constexpr QRgb qPremultiply(QRgb x)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
static void translate_dashPattern(const QList< qreal > &pattern, qreal width, QString *pattern_string)
static QPaintEngine::PaintEngineFeatures svgEngineFeatures()
static QT_BEGIN_NAMESPACE void translate_color(const QColor &color, QString *color_string, QString *opacity_string)
\inmodule QtCore \reentrant
QString document_description