8#include <private/qsvgvisitor_p.h>
12#include <QTextDocument>
17#include <private/qquickshape_p.h>
18#include <private/qquicktext_p.h>
19#include <private/qquicktranslate_p.h>
20#include <private/qquickitem_p.h>
22#include <private/qquickimagebase_p_p.h>
23#include <private/qquickimage_p.h>
24#include <private/qsgcurveprocessor_p.h>
26#include <private/qquadpath_p.h>
29#include <QtCore/qloggingcategory.h>
43 m_dummyPainter.begin(&m_dummyImage);
46 m_dummyPainter.setPen(defaultPen);
60 if (m_dummyPainter.brush().style() ==
Qt::NoBrush ||
66 fillColor = m_dummyPainter.brush().color();
67 fillColor.
setAlphaF(m_svgState.fillOpacity);
74 return m_svgState.fillOpacity;
80 return m_dummyPainter.brush().gradient();
86 if (m_dummyPainter.pen().brush().style() ==
Qt::NoBrush ||
92 strokeColor = m_dummyPainter.pen().brush().color();
93 strokeColor.
setAlphaF(m_svgState.strokeOpacity);
102 for (
auto &stop : grad.
stops()) {
103 stop.second.setAlphaF(stop.second.alphaF() * opacity);
114 float penWidth = m_dummyPainter.pen().widthF();
115 return penWidth ? penWidth : 1;
120 return m_dummyPainter.pen();
134 bool foundPath =
false;
136 switch (
child->type()) {
163 if (!
child->style().transform.isDefault()) {
170 qCDebug(lcQuickVectorImage) <<
"Unhandled type in switch" <<
child->type();
180 QPen p = styleResolver->currentStroke();
183 srokeStyle.miterLimit =
p.miterLimit();
184 srokeStyle.dashOffset =
p.dashOffset();
185 srokeStyle.dashArray =
p.dashPattern();
186 srokeStyle.color = styleResolver->currentStrokeColor();
187 srokeStyle.width =
p.widthF();
193 : m_svgFileName(svgFileName)
201 qCDebug(lcQuickVectorImage) <<
"No valid QQuickGenerator is set. Genration will stop";
207 qCDebug(lcQuickVectorImage) <<
"Not a valid Svg File : " << m_svgFileName;
216 handleBaseNodeSetup(node);
219 fillCommonNodeInfo(node,
info);
223 handleBaseNodeEnd(node);
229 handleBaseNodeSetup(node);
232 fillCommonNodeInfo(node,
info);
239 handleBaseNodeEnd(node);
266 p.arcTo(
x1,
y2 -
ry * 2,
rx * 2,
ry * 2, 270, -90);
269 p.arcTo(
x1,
y1,
rx * 2,
ry * 2, 180, -90);
271 handlePathNode(node,
p);
281 handlePathNode(node,
p);
286 handlePathNode(node, node->
path());
294 handlePathNode(node,
p);
300 handlePathNode(node,
p);
306 handlePathNode(node,
p);
315 cssDescription +=
" -qt-foreground: qlineargradient("_L1;
316 cssDescription +=
"x1:"_L1 +
QString::number(linearGradient->start().x()) + u
',';
317 cssDescription +=
"y1:"_L1 +
QString::number(linearGradient->start().y()) + u
',';
318 cssDescription +=
"x2:"_L1 +
QString::number(linearGradient->finalStop().x()) + u
',';
319 cssDescription +=
"y2:"_L1 +
QString::number(linearGradient->finalStop().y()) + u
',';
323 cssDescription +=
" -qt-foreground: qradialgradient("_L1;
324 cssDescription +=
"cx:"_L1 +
QString::number(radialGradient->center().x()) + u
',';
325 cssDescription +=
"cy:"_L1 +
QString::number(radialGradient->center().y()) + u
',';
326 cssDescription +=
"fx:"_L1 +
QString::number(radialGradient->focalPoint().x()) + u
',';
327 cssDescription +=
"fy:"_L1 +
QString::number(radialGradient->focalPoint().y()) + u
',';
328 cssDescription +=
"radius:"_L1 +
QString::number(radialGradient->radius()) + u
',';
332 cssDescription +=
" -qt-foreground: qconicalgradient("_L1;
333 cssDescription +=
"cx:"_L1 +
QString::number(conicalGradient->center().x()) + u
',';
334 cssDescription +=
"cy:"_L1 +
QString::number(conicalGradient->center().y()) + u
',';
335 cssDescription +=
"angle:"_L1 +
QString::number(conicalGradient->angle()) + u
',';
338 const QStringList coordinateModes = {
"logical"_L1,
"stretchtodevice"_L1,
"objectbounding"_L1,
"object"_L1 };
339 cssDescription +=
"coordinatemode:"_L1;
340 cssDescription += coordinateModes.at(
int(gradient->
coordinateMode()));
341 cssDescription += u
',';
343 const QStringList spreads = {
"pad"_L1,
"reflect"_L1,
"repeat"_L1 };
344 cssDescription +=
"spread:"_L1;
345 cssDescription += spreads.at(
int(gradient->
spread()));
348 cssDescription +=
",stop:"_L1;
350 cssDescription += u
' ';
354 cssDescription +=
");"_L1;
356 return cssDescription;
368 return cssDescription;
373 handleBaseNodeSetup(node);
377 bool needsRichText =
false;
379 const QGradient *mainGradient = styleResolver->currentFillGradient();
380#if QT_CONFIG(texthtmlparser)
381 bool needsPathNode = mainGradient !=
nullptr;
383 for (
const auto *tspan : node->
tspans()) {
391 handleBaseNodeSetup(tspan);
392 QFont font = styleResolver->painter().font();
417 if (styleResolver->currentFillGradient() !=
nullptr
418 && styleResolver->currentFillGradient() != mainGradient) {
419 const QGradient grad = styleResolver->applyOpacityToGradient(*styleResolver->currentFillGradient(), styleResolver->currentFillOpacity());
420 styleTagContent += gradientCssDescription(&grad) + u
';';
421#if QT_CONFIG(texthtmlparser)
422 needsPathNode =
true;
426 QString strokeColor = colorCssDescription(styleResolver->currentStrokeColor());
428 styleTagContent +=
QStringLiteral(
"-qt-stroke-color:%1;").arg(strokeColor);
429 styleTagContent +=
QStringLiteral(
"-qt-stroke-width:%1;").arg(styleResolver->currentStrokeWidth());
430#if QT_CONFIG(texthtmlparser)
431 needsPathNode =
true;
442 bool fontTag =
false;
443 if (!tspan->style().fill.isDefault()) {
444 auto &
b = tspan->style().
fill->qbrush();
445 qCDebug(lcQuickVectorImage) <<
"tspan FILL:" <<
b;
450 QString spanColor =
b.color().name();
451 fontTag = !spanColor.
isEmpty();
455 QString spanColor = colorCssDescription(
b.color());
461 needsRichText = needsRichText || !styleTagContent.isEmpty();
462 if (!styleTagContent.isEmpty())
483 qCWarning(lcQuickVectorImage) <<
"Title case not implemented for tspan";
499 if (!styleTagContent.isEmpty())
502 handleBaseNodeEnd(tspan);
505 if (preserveWhiteSpace && (needsRichText || styleResolver->currentFillGradient() !=
nullptr))
508 QFont font = styleResolver->painter().font();
512#if QT_CONFIG(texthtmlparser)
515 document.setHtml(
text);
516 if (isTextArea && node->
size().
width() > 0)
517 document.setTextWidth(node->
size().
width());
518 document.setDefaultFont(
font);
519 document.pageCount();
525 if (lout !=
nullptr) {
528 fillCommonNodeInfo(node,
info);
531 info.fillRule = fillStyle->fillRule();
534 info.fillColor =
fmt.foreground().color();
536 info.grad = *
fmt.foreground().gradient();
538 info.fillColor = styleResolver->currentFillColor();
541 info.painterPath =
p;
544 info.strokeStyle.width =
fmt.textOutline().widthF();
545 info.strokeStyle.color =
fmt.textOutline().color();
547 info.strokeStyle.color = styleResolver->currentStrokeColor();
548 info.strokeStyle.width = styleResolver->currentStrokeWidth();
552 info.grad = styleResolver->applyOpacityToGradient(*styleResolver->currentFillGradient(), styleResolver->currentFillOpacity());
561 const QPointF baselineTranslation(0.0, baselineOffset);
562 auto glyphsToPath = [&](QList<QGlyphRun> glyphRuns) {
565 for (
const QGlyphRun &glyphRun : glyphRuns) {
567 QList<quint32> glyphIndexes = glyphRun.glyphIndexes();
568 QList<QPointF>
positions = glyphRun.positions();
571 quint32 glyphIndex = glyphIndexes.at(
j);
575 p.translate(
pos + node->
position() + baselineTranslation);
589 if (!
range.format.anchorNames().isEmpty()
594 range.format.merge(nextRange.format);
602 block = block.
next();
608 fillCommonNodeInfo(node,
info);
614 info.isTextArea = isTextArea;
615 info.needsRichText = needsRichText;
616 info.fillColor = styleResolver->currentFillColor();
617 info.alignment = styleResolver->states().textAnchor;
618 info.strokeColor = styleResolver->currentStrokeColor();
623 handleBaseNodeEnd(node);
632 handleBaseNodeSetup(node);
634 fillCommonNodeInfo(node,
info);
645 handleBaseNodeEnd(node);
657 constexpr bool forceSeparatePaths =
false;
658 handleBaseNodeSetup(node);
662 fillCommonNodeInfo(node,
info);
663 info.forceSeparatePaths = forceSeparatePaths;
664 info.isPathContainer = isPathContainer(node);
672 handleBaseNodeEnd(node);
677 fillCommonNodeInfo(node,
info);
685 handleBaseNodeSetup(node);
688 fillCommonNodeInfo(node,
info);
693 info.isPathContainer = isPathContainer(node);
701 handleBaseNodeEnd(node);
702 qCDebug(lcQuickVectorImage) <<
"REVERT" << node->
nodeId() << node->
type() << (styleResolver->painter().pen().style() !=
Qt::NoPen)
703 << styleResolver->painter().pen().color().
name() << (styleResolver->painter().pen().brush().style() !=
Qt::NoBrush)
704 << styleResolver->painter().pen().brush().color().name();
707 fillCommonNodeInfo(node,
info);
725void QSvgVisitorImpl::handleBaseNodeSetup(
const QSvgNode *node)
727 qCDebug(lcQuickVectorImage) <<
"Before SETUP" << node <<
"fill" << styleResolver->currentFillColor()
728 <<
"stroke" << styleResolver->currentStrokeColor() << styleResolver->currentStrokeWidth()
731 node->
applyStyle(&styleResolver->painter(), styleResolver->states());
733 qCDebug(lcQuickVectorImage) <<
"After SETUP" << node <<
"fill" << styleResolver->currentFillColor()
734 <<
"stroke" << styleResolver->currentStrokeColor()
735 << styleResolver->currentStrokeWidth() << node->
nodeId();
738void QSvgVisitorImpl::handleBaseNode(
const QSvgNode *node)
741 fillCommonNodeInfo(node,
info);
746void QSvgVisitorImpl::handleBaseNodeEnd(
const QSvgNode *node)
748 node->
revertStyle(&styleResolver->painter(), styleResolver->states());
750 qCDebug(lcQuickVectorImage) <<
"After END" << node <<
"fill" << styleResolver->currentFillColor()
751 <<
"stroke" << styleResolver->currentStrokeColor() << styleResolver->currentStrokeWidth()
757 handleBaseNodeSetup(node);
760 fillCommonNodeInfo(node,
info);
763 info.fillRule = fillStyle->fillRule();
766 info.fillColor = styleResolver->currentFillColor();
767 populateStrokeStyle(
info.strokeStyle);
768 if (styleResolver->currentFillGradient() !=
nullptr)
769 info.grad = styleResolver->applyOpacityToGradient(*styleResolver->currentFillGradient(), styleResolver->currentFillOpacity());
773 handleBaseNodeEnd(node);
The QColor class provides colors based on RGB, HSV or CMYK values.
void setAlphaF(float alpha)
Sets the alpha of this color to alpha.
\reentrant \inmodule QtGui
qreal ascent() const
Returns the ascent of the font.
QString family() const
Returns the requested font family name.
int pixelSize() const
Returns the pixel size of the font if it was set with setPixelSize().
bool italic() const
Returns true if the style() of the font is not QFont::StyleNormal.
Capitalization capitalization() const
Weight weight() const
Returns the weight of the font, using the same scale as the \l{QFont::Weight} enumeration.
int pointSize() const
Returns the point size of the font.
void setPixelSize(int)
Sets the font size to pixelSize pixels, with a maxiumum size of an unsigned 16-bit integer.
bool bold() const
Returns true if weight() is a value greater than \l{Weight}{QFont::Medium}; otherwise returns false.
qreal pointSizeF() const
Returns the point size of the font.
The QGlyphRun class provides direct access to the internal glyphs in a font.
Spread spread() const
Returns the spread method use by this gradient.
CoordinateMode coordinateMode() const
void setStops(const QGradientStops &stops)
Replaces the current set of stop points with the given stopPoints.
Type type() const
Returns the type of gradient.
QGradientStops stops() const
Returns the stop points for this gradient.
constexpr QPointF p1() const
Returns the line's start point.
constexpr QPointF p2() const
Returns the line's end point.
void append(parameter_type t)
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
void addEllipse(const QRectF &rect)
Creates an ellipse within the specified boundingRectangle and adds it to the painter path as a closed...
The QPainter class performs low-level painting on widgets and other paint devices.
Qt::PenCapStyle capStyle() const
Returns the pen's cap style.
void setMiterLimit(qreal limit)
Sets the miter limit of this pen to the given limit.
\inmodule QtCore\reentrant
virtual void generatePath(const PathNodeInfo &info)=0
virtual bool generateRootNode(const StructureNodeInfo &info)=0
virtual void generateNodeBase(const NodeInfo &info)=0
virtual bool generateStructureNode(const StructureNodeInfo &info)=0
virtual void generateNode(const NodeInfo &info)=0
virtual bool generateDefsNode(const NodeInfo &info)=0
virtual void generateImageNode(const ImageNodeInfo &info)=0
virtual void generateTextNode(const TextNodeInfo &info)=0
virtual void generateUseNode(const UseNodeInfo &info)=0
The QRawFont class provides access to a single physical instance of a font.
\inmodule QtCore\reentrant
constexpr qreal width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString & fill(QChar c, qsizetype size=-1)
Sets every character in the string to character ch.
QString & replace(qsizetype i, qsizetype len, QChar after)
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
QString toLower() const &
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString toUpper() const &
QString toHtmlEscaped() const
const QImage & image() const
void revertStyle(QPainter *p, QSvgExtraStates &states) const
void applyStyle(QPainter *p, QSvgExtraStates &states) const
DisplayMode displayMode() const
const QSvgStyle & style() const
virtual Type type() const =0
const QPainterPath & path() const
const QPolygonF & polygon() const
const QPolygonF & polygon() const
QList< QSvgNode * > renderers() const
const QGradient * currentFillGradient() const
QColor currentFillColor() const
QSvgExtraStates & states()
static QGradient applyOpacityToGradient(const QGradient &gradient, float opacity)
QPen currentStroke() const
qreal currentFillOpacity() const
float currentStrokeWidth() const
QSvgExtraStates m_svgState
QColor currentStrokeColor() const
QSvgRefCounter< QSvgOpacityStyle > opacity
QSvgRefCounter< QSvgTransformStyle > transform
QSvgRefCounter< QSvgFillStyle > fill
const QList< QSvgTspan * > tspans() const
WhitespaceMode whitespaceMode() const
Type type() const override
Type type() const override
static QSvgTinyDocument * load(const QString &file, QtSvg::Options options={})
void visitPolygonNode(const QSvgPolygon *node) override
void visitEllipseNode(const QSvgEllipse *node) override
void visitPathNode(const QSvgPath *node) override
bool visitDefsNodeStart(const QSvgDefs *node) override
QSvgVisitorImpl(const QString svgFileName, QQuickGenerator *generator)
void visitDocumentNodeEnd(const QSvgTinyDocument *node) override
void visitStructureNodeEnd(const QSvgStructureNode *node) override
void visitRectNode(const QSvgRect *node) override
void visitLineNode(const QSvgLine *node) override
void visitNode(const QSvgNode *node) override
void visitPolylineNode(const QSvgPolyline *node) override
void visitUseNode(const QSvgUse *node) override
bool visitDocumentNodeStart(const QSvgTinyDocument *node) override
void visitImageNode(const QSvgImage *node) override
void visitTextNode(const QSvgText *node) override
bool visitStructureNodeStart(const QSvgStructureNode *node) override
void traverse(const QSvgStructureNode *node)
bool isValid() const
Returns true if this text block is valid; otherwise returns false.
QList< QTextLayout::FormatRange > textFormats() const
QTextBlock next() const
Returns the text block in the document after this block, or an empty text block if this is the last o...
QTextLayout * layout() const
Returns the QTextLayout that is used to lay out and display the block's contents.
\reentrant \inmodule QtGui
QList< QGlyphRun > glyphRuns(int from=-1, int length=-1, GlyphRunRetrievalFlags flags=DefaultRetrievalFlags) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int lineCount() const
Returns the number of lines in this text layout.
QTextLine lineAt(int i) const
Returns the {i}-th line of text in this text layout.
bool isValid() const
Returns true if this text line is valid; otherwise returns false.
qreal ascent() const
Returns the line's ascent.
constexpr QColor Transparent
QPainterPath polygonToPath(const QPolygonF &poly, bool closed)
Combined button and popup list for selecting options.
QPair< qreal, QColor > QGradientStop
static const QCssKnownValue positions[NumKnownPositionModes - 1]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLboolean GLboolean GLboolean b
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint GLfloat GLfloat GLfloat x1
GLfixed GLfixed GLfixed y2
GLsizei const GLchar *const * path
#define QStringLiteral(str)
QVideoFrameFormat::PixelFormat fmt
QRandomGenerator generator(sseq)
\inmodule QtCore \reentrant