diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-01-25 01:00:10 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-01-25 01:00:11 +0100 |
commit | 9893e71cea5de10193376c1733db627ef0783614 (patch) | |
tree | 391fabceb9d4ff6ba5f3ff2c2ec42acb613eb4ef /src/quick/util | |
parent | 87e7203532d69e0aaa0898a972d1d90fa589d519 (diff) | |
parent | e1b4b267aa8c4d9c53e5af4def54f5e9e14e0103 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Icb61522fb41a35303bb3d201b344a0407f67f9a0
Diffstat (limited to 'src/quick/util')
-rw-r--r-- | src/quick/util/qquickimageprovider.cpp | 8 | ||||
-rw-r--r-- | src/quick/util/qquickpath.cpp | 223 | ||||
-rw-r--r-- | src/quick/util/qquickpath_p.h | 102 | ||||
-rw-r--r-- | src/quick/util/qquickpath_p_p.h | 1 |
4 files changed, 330 insertions, 4 deletions
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index c081d45268..db82b2d807 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -672,17 +672,17 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const return res; const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit(); - const bool formatIsSvg = (format == "svg" || format == "svgz"); + const bool formatIsScalable = (format == "svg" || format == "svgz" || format == "pdf"); - if (!preserveAspectCropOrFit && formatIsSvg && !requestedSize.isEmpty()) + if (!preserveAspectCropOrFit && formatIsScalable && !requestedSize.isEmpty()) return requestedSize; qreal ratio = 0.0; - if (requestedSize.width() && (preserveAspectCropOrFit || formatIsSvg || + if (requestedSize.width() && (preserveAspectCropOrFit || formatIsScalable || requestedSize.width() < originalSize.width())) { ratio = qreal(requestedSize.width()) / originalSize.width(); } - if (requestedSize.height() && (preserveAspectCropOrFit || formatIsSvg || + if (requestedSize.height() && (preserveAspectCropOrFit || formatIsScalable || requestedSize.height() < originalSize.height())) { qreal hr = qreal(requestedSize.height()) / originalSize.height(); if (ratio == 0.0) diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index c855acc185..375d0265e8 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -301,6 +301,8 @@ void QQuickPath::pathElements_append(QQmlListProperty<QQuickPathElement> *proper QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement); if (curve) d->_pathCurves.append(curve); + else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) + d->_pathTexts.append(text); else { QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement); if (attribute && !d->_attributes.contains(attribute->name())) @@ -329,6 +331,7 @@ void QQuickPath::pathElements_clear(QQmlListProperty<QQuickPathElement> *propert d->_pathElements.clear(); d->_pathCurves.clear(); d->_pointCache.clear(); + d->_pathTexts.clear(); } void QQuickPath::interpolate(int idx, const QString &name, qreal value) @@ -478,6 +481,8 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en point.values[percentString] = percent->value(); interpolate(attributePoints, attributePoints.count() - 1, percentString, percent->value()); usesPercent = true; + } else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) { + text->addToPath(path); } } @@ -547,6 +552,9 @@ QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPoint ++index; } + for (QQuickPathText *text : qAsConst(d->_pathTexts)) + text->addToPath(path); + if (closed) { QPointF end = path.currentPosition(); *closed = startX == end.x() && startY == end.y(); @@ -593,6 +601,8 @@ void QQuickPath::gatherAttributes() for (QQuickPathElement *pathElement : qAsConst(d->_pathElements)) { if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(pathElement)) d->_pathCurves.append(curve); + else if (QQuickPathText *text = qobject_cast<QQuickPathText *>(pathElement)) + d->_pathTexts.append(text); else if (QQuickPathAttribute *attribute = qobject_cast<QQuickPathAttribute *>(pathElement)) attributes.insert(attribute->name()); } @@ -2619,6 +2629,219 @@ void QQuickPathMultiline::addToPath(QPainterPath &path, const QQuickPathData &) } } +/*! + \qmltype PathText + \instantiates QQuickPathText + \inqmlmodule QtQuick + \ingroup qtquick-animation-paths + \brief Defines a string in a specified font. + \since QtQuick 2.15 + + This element defines the shape of a specified string in a specified font. The text's + baseline will be translated to the x and y coordinates, and the outlines from the font + will be added to the path accordingly. + + \qml + PathText { + x: 0 + y: font.pixelSize + font.family: "Arial" + font.pixelSize: 100 + text: "Foobar" + } + \endqml + + \sa Path, QPainterPath::setFillRule, PathPolyline, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg, PathMove +*/ + +/*! + \qmlproperty real QtQuick::PathText::x + + The horizontal position of the PathText's baseline. +*/ + +/*! + \qmlproperty real QtQuick::PathText::y + + The vertical position of the PathText's baseline. + + \note This property refers to the position of the baseline of the text, not the top of its bounding box. This may + cause some confusion, e.g. when using the PathText with Qt Quick Shapes. See \l FontMetrics for information on how to + get the ascent of a font, which can be used to translate the text into the expected position. +*/ + +/*! + \qmlproperty string QtQuick::PathText::text + + The text for which this PathText should contain the outlines. +*/ + +/*! + \qmlproperty string QtQuick::PathText::font.family + + Sets the family name of the font. + + The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]". + If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen. + If the family isn't available a family will be set using the font matching algorithm. +*/ + +/*! + \qmlproperty string QtQuick::PathText::font.styleName + + Sets the style name of the font. + + The style name is case insensitive. If set, the font will be matched against style name instead + of the font properties \l font.weight, \l font.bold and \l font.italic. +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.bold + + Sets whether the font weight is bold. +*/ + +/*! + \qmlproperty enumeration QtQuick::PathText::font.weight + + Sets the font's weight. + + The weight can be one of: + \list + \li Font.Thin + \li Font.Light + \li Font.ExtraLight + \li Font.Normal - the default + \li Font.Medium + \li Font.DemiBold + \li Font.Bold + \li Font.ExtraBold + \li Font.Black + \endlist + + \qml + PathText { text: "Hello"; font.weight: Font.DemiBold } + \endqml +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.italic + + Sets whether the font has an italic style. +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.underline + + Sets whether the text is underlined. +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.strikeout + + Sets whether the font has a strikeout style. +*/ + +/*! + \qmlproperty real QtQuick::PathText::font.pointSize + + Sets the font size in points. The point size must be greater than zero. +*/ + +/*! + \qmlproperty int QtQuick::PathText::font.pixelSize + + Sets the font size in pixels. + + Using this function makes the font device dependent. + Use \c pointSize to set the size of the font in a device independent manner. +*/ + +/*! + \qmlproperty real QtQuick::PathText::font.letterSpacing + + Sets the letter spacing for the font. + + Letter spacing changes the default spacing between individual letters in the font. + A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing. +*/ + +/*! + \qmlproperty real QtQuick::PathText::font.wordSpacing + + Sets the word spacing for the font. + + Word spacing changes the default spacing between individual words. + A positive value increases the word spacing by a corresponding amount of pixels, + while a negative value decreases the inter-word spacing accordingly. +*/ + +/*! + \qmlproperty enumeration QtQuick::PathText::font.capitalization + + Sets the capitalization for the text. + + \list + \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied. + \li Font.AllUppercase - This alters the text to be rendered in all uppercase type. + \li Font.AllLowercase - This alters the text to be rendered in all lowercase type. + \li Font.SmallCaps - This alters the text to be rendered in small-caps type. + \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character. + \endlist + + \qml + PathText { text: "Hello"; font.capitalization: Font.AllLowercase } + \endqml +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.kerning + + Enables or disables the kerning OpenType feature when shaping the text. Disabling this may + improve performance when creating or changing the text, at the expense of some cosmetic + features. The default value is true. + + \qml + PathText { text: "OATS FLAVOUR WAY"; font.kerning: false } + \endqml +*/ + +/*! + \qmlproperty bool QtQuick::PathText::font.preferShaping + + Sometimes, a font will apply complex rules to a set of characters in order to + display them correctly. In some writing systems, such as Brahmic scripts, this is + required in order for the text to be legible, but in e.g. Latin script, it is merely + a cosmetic feature. Setting the \c preferShaping property to false will disable all + such features when they are not required, which will improve performance in most cases. + + The default value is true. + + \qml + PathText { text: "Some text"; font.preferShaping: false } + \endqml +*/ + +void QQuickPathText::updatePath() const +{ + if (!_path.isEmpty()) + return; + + _path.addText(_x, _y, _font, _text); + + // Account for distance from baseline to top, since addText() takes baseline position + QRectF brect = _path.boundingRect(); + _path.translate(0.0, -brect.y()); +} + +void QQuickPathText::addToPath(QPainterPath &path) +{ + if (_text.isEmpty()) + return; + updatePath(); + path.addPath(_path); +} + QT_END_NAMESPACE #include "moc_qquickpath_p.cpp" diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index ca0495a90d..159c46d13c 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -63,6 +63,7 @@ QT_REQUIRE_CONFIG(quick_path); #include <QtCore/QObject> #include <QtGui/QPainterPath> +#include <QtGui/QFont> QT_BEGIN_NAMESPACE @@ -598,6 +599,106 @@ public: static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = nullptr); }; +class Q_QUICK_PRIVATE_EXPORT QQuickPathText : public QQuickPathElement +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) + Q_PROPERTY(qreal width READ width NOTIFY changed) + Q_PROPERTY(qreal height READ height NOTIFY changed) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) + QML_NAMED_ELEMENT(PathText) + QML_ADDED_IN_MINOR_VERSION(15) +public: + QQuickPathText(QObject *parent=nullptr) : QQuickPathElement(parent) + { + connect(this, &QQuickPathText::xChanged, this, &QQuickPathElement::changed); + connect(this, &QQuickPathText::yChanged, this, &QQuickPathElement::changed); + connect(this, &QQuickPathText::textChanged, this, &QQuickPathElement::changed); + connect(this, &QQuickPathText::fontChanged, this, &QQuickPathElement::changed); + + connect(this, &QQuickPathElement::changed, this, &QQuickPathText::invalidate); + } + + void addToPath(QPainterPath &path); + + qreal x() const { return _x; } + qreal y() const { return _y; } + QString text() const { return _text; } + QFont font() const { return _font; } + + void setX(qreal x) + { + if (qFuzzyCompare(_x, x)) + return; + + _x = x; + Q_EMIT xChanged(); + } + + void setY(qreal y) + { + if (qFuzzyCompare(_y, y)) + return; + + _y = y; + Q_EMIT yChanged(); + } + + void setText(const QString &text) + { + if (text == _text) + return; + + _text = text; + Q_EMIT textChanged(); + } + + void setFont(const QFont &font) + { + if (font == _font) + return; + + _font = font; + Q_EMIT fontChanged(); + } + + qreal width() const + { + updatePath(); + return _path.boundingRect().width(); + } + + qreal height() const + { + updatePath(); + return _path.boundingRect().height(); + } + +Q_SIGNALS: + void xChanged(); + void yChanged(); + void textChanged(); + void fontChanged(); + +private Q_SLOTS: + void invalidate() + { + _path.clear(); + } + +private: + void updatePath() const; + + QString _text; + qreal _x = qreal(0.0); + qreal _y = qreal(0.0); + QFont _font; + + mutable QPainterPath _path; +}; + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickPathElement) @@ -614,5 +715,6 @@ QML_DECLARE_TYPE(QQuickPathSvg) QML_DECLARE_TYPE(QQuickPathPercent) QML_DECLARE_TYPE(QQuickPathPolyline) QML_DECLARE_TYPE(QQuickPath) +QML_DECLARE_TYPE(QQuickPathText) #endif // QQUICKPATH_H diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h index e26001ec77..5505b876c1 100644 --- a/src/quick/util/qquickpath_p_p.h +++ b/src/quick/util/qquickpath_p_p.h @@ -80,6 +80,7 @@ public: QList<QQuickPath::AttributePoint> _attributePoints; QStringList _attributes; QList<QQuickCurve*> _pathCurves; + QList<QQuickPathText*> _pathTexts; mutable QQuickCachedBezier prevBez; QQmlNullableValue<qreal> startX; QQmlNullableValue<qreal> startY; |