10#include <QGlobalStatic>
14#include <fontconfig/fontconfig.h>
44 m_d->properties = rhs.
m_d->properties;
56 return m_d->properties == rhs.
m_d->properties;
66 return m_d->properties.contains(
id);
71 return m_d->properties.value(
id, defaultValue);
76 m_d->properties.remove(
id);
81 QVariant
value =
m_d->properties.value(
id);
90 return m_d->properties.keys();
95 return m_d->properties.isEmpty();
106 auto it =
m_d->properties.begin();
107 for (; it !=
m_d->properties.end(); ++it) {
108 if (!
m_d->isInheritable(it.key())) {
116 auto it = parentProperties.
m_d->properties.constBegin();
117 for (; it != parentProperties.
m_d->properties.constEnd(); ++it) {
135 const qreal usedSize = size.value;
148 for (
auto it = this->
m_d->properties.begin(); it != this->
m_d->properties.end(); it++) {
157 it.value() = QVariant::fromValue(
length);
163 it.value() = QVariant::fromValue(val);
169 it.value() = QVariant::fromValue(tabSize);
176 it.value() = QVariant::fromValue(indent);
188 for (
auto it =
m_d->properties.constBegin(); it !=
m_d->properties.constEnd(); ++it) {
189 if (!
m_d->isInheritable(it.key())) {
198 auto it =
properties.m_d->properties.constBegin();
199 for (; it !=
properties.m_d->properties.constEnd(); ++it) {
200 if (
m_d->isInheritable(it.key())) {
210 for (
auto it = this->
m_d->properties.begin(); it != this->
m_d->properties.end(); ++it) {
213 if (
length.unit != absoluteUnit)
continue;
217 length.value *= scaleInline;
219 it.value() = QVariant::fromValue(
length);
222 if (info.
length.
unit != absoluteUnit)
continue;
224 it.value() = QVariant::fromValue(info);
227 if (info.
length.
unit != absoluteUnit)
continue;
229 it.value() = QVariant::fromValue(info);
232 if (info.
length.
unit != absoluteUnit)
continue;
234 it.value() = QVariant::fromValue(info);
237 if (info.
isAuto)
continue;
240 it.value() = QVariant::fromValue(info);
251 for (; it !=
m_d->properties.constEnd(); ++it) {
253 || parentProperties.
property(it.key()) != it.value()) {
266QPair<QString, QString>
parseTag(QString taggedValue) {
267 QPair<QString, QString> tag;
268 tag.first = taggedValue.mid(1, 4);
269 if (taggedValue.length() > 6) {
270 tag.second = taggedValue.remove(0, 6).trimmed();
276 QVariantMap settings;
277 for (
int i = 0; i < features.size(); i++) {
278 QString feature = features.at(i).trimmed();
279 if ((!feature.startsWith(
'\'') && !feature.startsWith(
'\"')) || feature.isEmpty()) {
282 QPair<QString, QString> tag =
parseTag(feature);
284 double featureVal = tag.second.toDouble(&ok);
286 if (ok && !tag.first.isEmpty()) {
287 settings.insert(tag.first, QVariant(featureVal));
294 QVariantMap settings;
295 for (
int i = 0; i < features.size(); i++) {
296 QString feature = features.at(i).trimmed();
297 if ((!feature.startsWith(
'\'') && !feature.startsWith(
'\"')) || feature.isEmpty()) {
300 QPair<QString, QString> tag =
parseTag(feature);
301 if (tag.second.isEmpty()) {
302 settings.insert(tag.first, QVariant(1));
305 int featureVal = tag.second.toInt(&ok);
306 if (tag.second.toLower() ==
"on") {
309 }
else if (tag.second.toLower() ==
"off") {
313 if (ok && !tag.first.isEmpty()) {
314 settings.insert(tag.first, QVariant(featureVal));
323 if (command ==
"writing-mode") {
325 }
else if (command ==
"glyph-orientation-vertical") {
330 acceptedOrientations <<
"auto"
335 if (acceptedOrientations.contains(
value.toLower())) {
342 }
else if (command ==
"text-orientation") {
344 }
else if (command ==
"direction") {
346 }
else if (command ==
"unicode-bidi") {
348 }
else if (command ==
"text-anchor") {
350 }
else if (command ==
"dominant-baseline") {
352 }
else if (command ==
"alignment-baseline") {
354 }
else if (command ==
"baseline-shift") {
361 }
else if (command ==
"vertical-align") {
362 QRegExp digits = QRegExp(
"\\d");
363 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
364#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
365 bool paramContains = param.contains(digits);
367 bool paramContains = (digits.indexIn(param) > 0);
371 if (param ==
"sub" || param ==
"super" || param ==
"top" || param ==
"bottom" || paramContains) {
377 }
else if (command ==
"kerning" || command ==
"font-kerning") {
379 if (
value ==
"none") {
382 }
else if (
value ==
"normal") {
389 }
else if (command ==
"letter-spacing") {
391 }
else if (command ==
"word-spacing") {
393 }
else if (command ==
"font-family") {
395 Q_FOREACH (
const QString &fam,
value.split(
',', Qt::SkipEmptyParts)) {
396 QString family = fam.trimmed();
397 if ((family.startsWith(
'\"') && family.endsWith(
'\"')) ||
398 (family.startsWith(
'\'') && family.endsWith(
'\''))) {
400 family = family.mid(1, family.size() - 2);
402 familiesList.append(family);
406 }
else if (command ==
"font-style") {
408 }
else if (command ==
"font-variant" || command ==
"font-variant-ligatures" || command ==
"font-variant-position" || command ==
"font-variant-caps"
409 || command ==
"font-variant-numeric" || command ==
"font-variant-east-asian" || command ==
"font-variant-alternates") {
411 Q_FOREACH (
const QString f, features) {
412 bool commandFontVariant = (command ==
"font-variant");
413 if (commandFontVariant || command ==
"font-variant-ligatures") {
418 if (commandFontVariant || command ==
"font-variant-position") {
423 if (commandFontVariant || command ==
"font-variant-caps") {
428 if (commandFontVariant || command ==
"font-variant-numeric") {
433 if (commandFontVariant || command ==
"font-variant-east-asian") {
440 }
else if (command ==
"font-feature-settings") {
442 }
else if (command ==
"font-stretch") {
443 int newStretch = 100;
449 }
else if (command ==
"font-weight") {
454 }
else if (command ==
"font-size") {
456 if (pointSize.
value > 0.0) {
459 }
else if (command ==
"font-size-adjust") {
462 }
else if (command ==
"font-optical-sizing") {
464 }
else if (command ==
"font-variation-settings") {
466 }
else if (command ==
"text-decoration" || command ==
"text-decoration-line" || command ==
"text-decoration-style" || command ==
"text-decoration-color"
467 || command ==
"text-decoration-position") {
471 if (command ==
"text-decoration" || command ==
"text-decoration-line") {
479 bool setPosition =
false;
481 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
482 if (param ==
"line-through") {
483 deco |= DecorationLineThrough;
484 }
else if (param ==
"underline") {
485 deco |= DecorationUnderline;
486 }
else if (param ==
"overline") {
487 deco |= DecorationOverline;
488 }
else if (param ==
"solid") {
490 }
else if (param ==
"double") {
492 }
else if (param ==
"dotted") {
494 }
else if (param ==
"dashed") {
496 }
else if (param ==
"wavy") {
498 }
else if (param ==
"auto") {
501 }
else if (param ==
"under") {
504 }
else if (param ==
"left") {
507 }
else if (param ==
"right") {
510 }
else if (QColor::isValidColor(param)) {
512 textDecorationColor = QColor(param);
516 if (command ==
"text-decoration" || command ==
"text-decoration-line") {
519 if (command ==
"text-decoration" || command ==
"text-decoration-style") {
522 if (command ==
"text-decoration" || command ==
"text-decoration-color") {
525 if ((command ==
"text-decoration" || command ==
"text-decoration-position") && setPosition) {
529 }
else if (command ==
"xml:lang") {
531 }
else if (command ==
"text-transform") {
533 }
else if (command ==
"white-space") {
544 }
else if (command ==
"xml:space") {
548 }
else if (command ==
"word-break") {
550 }
else if (command ==
"line-break") {
552 }
else if (command ==
"text-align" || command ==
"text-align-all" || command ==
"text-align-last") {
554 if (command ==
"text-align" || command ==
"text-align-all") {
556 if (
value ==
"justify-all") {
560 if (command ==
"text-align" && params.size() > 1) {
563 if (command ==
"text-align-last") {
566 }
else if (command ==
"line-height") {
568 }
else if (command ==
"text-indent") {
570 }
else if (command ==
"hanging-punctuation") {
571 KoSvgText::HangingPunctuations hang;
572 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
573 if (param ==
"first") {
575 }
else if (param ==
"last") {
577 }
else if (param ==
"allow-end") {
580 }
else if (param ==
"force-end") {
586 }
else if (command ==
"inline-size") {
588 }
else if (command ==
"overflow") {
590 }
else if (command ==
"text-overflow") {
592 }
else if (command ==
"overflow-wrap" || command ==
"word-wrap") {
597 }
else if (command ==
"tab-size") {
599 }
else if (command ==
"shape-padding") {
601 }
else if (command ==
"shape-margin") {
603 }
else if (command ==
"font-synthesis") {
608 if (
value !=
"none") {
610 if (params.contains(
"position")) {
613 if (params.contains(
"weight")) {
616 if (params.contains(
"style")) {
619 if (params.contains(
"small-caps")) {
623 }
else if (command ==
"font-synthesis-weight") {
625 }
else if (command ==
"font-synthesis-style") {
627 }
else if (command ==
"font-synthesis-small-caps") {
629 }
else if (command ==
"font-synthesis-position") {
631 }
else if (command ==
"text-rendering") {
634 qFatal(
"FATAL: Unknown SVG property: %s = %s", command.toUtf8().data(),
value.toUtf8().data());
642 QMap<QString, QString> result;
653 QString
value =
"auto";
654 if (orientation == OrientationUpright) {
656 }
else if (orientation == OrientationSideWays) {
659 result.insert(
"glyph-orientation-vertical",
value);
681 bool writeSeparate =
true;
684 if (mode == ShiftLineTop || mode == ShiftLineBottom) {
685 writeSeparate =
false;
696 result.insert(
"baseline-shift",
709 if (!verticalAlign.isEmpty()) {
710 result.insert(
"vertical-align", verticalAlign.join(
" "));
716 result.insert(
"kerning", writeAutoValue(
property(
KerningId).value<AutoValue>()));
720 result.insert(
"font-kerning",
"auto");
722 result.insert(
"font-kerning",
"none");
724 result.insert(
"font-kerning",
"normal");
731 result.insert(
"letter-spacing", writeAutoLengthPercentage(
property(
LetterSpacingId).value<AutoLengthPercentage>(),
"normal",
true));
735 result.insert(
"word-spacing", writeAutoLengthPercentage(
property(
WordSpacingId).value<AutoLengthPercentage>(),
"normal",
true));
749 result.insert(
"font-variant-ligatures", writeFontFeatureLigatures(feat));
753 result.insert(
"font-variant-position", writeFontFeaturePosition(feat));
757 result.insert(
"font-variant-caps", writeFontFeatureCaps(feat));
761 result.insert(
"font-variant-numeric", writeFontFeatureNumeric(feat));
765 result.insert(
"font-variant-east-asian", writeFontFeatureEastAsian(feat));
770 for(
auto it = vals.begin(); it != vals.end(); it++) {
771 settings.append(QString(
"'%1' %2").arg(it.key()).arg(it.value().toDouble()));
773 result.insert(
"font-feature-settings", settings.join(
", "));
778 result.insert(
"font-optical-sizing",
"none");
784 for(
auto it = vals.begin(); it != vals.end(); it++) {
785 settings.append(QString(
"'%1' %2").arg(it.key()).arg(it.value().toDouble()));
787 result.insert(
"font-variation-settings", settings.join(
", "));
792 static constexpr std::array<int, 9> fontStretches = {50, 62, 75, 87, 100, 112, 125, 150, 200};
793 if (svg1_1 || std::find(fontStretches.begin(), fontStretches.end(), stretch) != fontStretches.end()) {
794 const auto it = std::lower_bound(fontStretches.begin(), fontStretches.end(), stretch);
795 if (it != fontStretches.end()) {
796 const auto index = std::distance(fontStretches.begin(), it);
810 result.insert(
"font-size", writeLengthPercentage(
fontSize()));
821 if (deco.testFlag(DecorationUnderline)) {
822 decoStrings.append(
"underline");
825 if (deco.testFlag(DecorationOverline)) {
826 decoStrings.append(
"overline");
829 if (deco.testFlag(DecorationLineThrough)) {
830 decoStrings.append(
"line-through");
833 if (deco != DecorationNone) {
837 if (style == Solid) {
838 decoStrings.append(
"solid");
839 }
else if (style == Double) {
840 decoStrings.append(
"double");
841 }
else if (style == Dotted) {
842 decoStrings.append(
"dotted");
843 }
else if (style == Dashed) {
844 decoStrings.append(
"dashed");
845 }
else if (style == Wavy) {
846 decoStrings.append(
"wavy");
851 if (color.isValid()) {
852 decoStrings.append(color.name());
856 if (!decoStrings.isEmpty()) {
857 result.insert(
"text-decoration", decoStrings.join(
' '));
865 decoPositionStrings.append(
"under");
867 decoPositionStrings.append(
"auto");
870 decoPositionStrings.append(
"right");
872 decoPositionStrings.append(
"left");
874 if (!decoPositionStrings.isEmpty()) {
875 result.insert(
"text-decoration-position", decoPositionStrings.join(
' '));
897 result.insert(
"xml:space", writeXmlSpace(collapse));
899 result.insert(
"white-space", writeWhiteSpaceValue(collapse, wrap, trims));
913 if (hang.testFlag(HangFirst)) {
914 value.append(
"first");
916 if (hang.testFlag(HangLast)) {
917 value.append(
"last");
919 if (hang.testFlag(HangEnd)) {
920 if (hang.testFlag(HangForce)) {
921 value.append(
"force-end");
923 value.append(
"allow-end");
927 if (!
value.isEmpty()) {
928 result.insert(
"hanging-punctuation",
value.join(
" "));
934 if (overflow == OverflowWrapAnywhere) {
935 result.insert(
"overflow-wrap",
"anywhere");
936 }
else if (overflow == OverflowWrapBreakWord) {
937 result.insert(
"overflow-wrap",
"break-word");
942 if (overflow == OverFlowClip) {
943 result.insert(
"overflow",
"clip");
944 result.insert(
"text-overflow",
"clip");
945 }
else if (overflow == OverFlowEllipse) {
946 result.insert(
"overflow",
"visible");
947 result.insert(
"text-overflow",
"ellipse");
949 result.insert(
"overflow",
"visible");
950 result.insert(
"text-overflow",
"clip");
961 if (!weight && !italic && !caps && !super) {
962 result.insert(
"font-synthesis",
"none");
965 if (weight) params.append(
"weight");
966 if (italic) params.append(
"style");
967 if (caps) params.append(
"small-caps");
968 if (super) params.append(
"position");
969 result.insert(
"font-synthesis", params.join(
" "));
996 QMap<QString, QString> result;
998 result.insert(
"inline-size", writeAutoValue(
property(
InlineSizeId).value<AutoValue>(),
"auto"));
1005 result.insert(
"text-align", writeTextAlign(all));
1007 if (last != all || last != AlignLastAuto) {
1008 result.insert(
"text-align-last", writeTextAlign(last));
1026 if (!familiesList.isEmpty()) {
1027 fontFamily = familiesList.first();
1029 const QFont::Style style =
1035 QFont font(fontFamily
1038 , style != QFont::StyleNormal);
1039 font.setStyle(style);
1053 font.setStrikeOut(deco & DecorationLineThrough);
1054 font.setUnderline(deco & DecorationUnderline);
1055 font.setOverline(deco & DecorationOverline);
1057 struct FakePaintDevice :
public QPaintDevice
1059 QPaintEngine *paintEngine()
const override {
1063 int metric(QPaintDevice::PaintDeviceMetric metric)
const override {
1065 if (metric == QPaintDevice::PdmDpiX || metric == QPaintDevice::PdmDpiY) {
1070 return QPaintDevice::metric(metric);
1076 FakePaintDevice fake72DpiPaintDevice;
1077 return QFont(font, &fake72DpiPaintDevice);
1088 return fontSizeVal * 0.5;
1135 QString openTypeTag =
"kern";
1136 openTypeTag += QString(
"[%1:%2]").arg(start).arg(start +
length);
1137 openTypeTag +=
"=0";
1138 fontFeatures.append(openTypeTag);
1139 openTypeTag =
"vkrn";
1140 openTypeTag += QString(
"[%1:%2]").arg(start).arg(start +
length);
1141 openTypeTag +=
"=0";
1142 fontFeatures.append(openTypeTag);
1147 for (
int i = 0; i < features.keys().size(); i++) {
1148 const QString key = features.keys().at(i);
1149 QString openTypeTag = QString(
"%1[%2:%3]=%4").arg(key).arg(start).arg(start +
length).arg(features.value(key).toInt());
1150 fontFeatures.append(openTypeTag);
1154 return fontFeatures;
1176 for (
auto it = features.begin(); it != features.end(); it++) {
1177 info.
axisSettings.insert(it.key(), it.value().toDouble());
1206 attributes <<
"writing-mode"
1207 <<
"glyph-orientation-vertical"
1208 <<
"glyph-orientation-horizontal"
1212 <<
"dominant-baseline"
1213 <<
"alignment-baseline"
1220 <<
"text-rendering";
1230 if (!s_defaultProperties.exists()) {
1233 s_defaultProperties->setProperty(
WritingModeId, HorizontalTB);
1234 s_defaultProperties->setProperty(
DirectionId, DirectionLeftToRight);
1235 s_defaultProperties->setProperty(
UnicodeBidiId, BidiNormal);
1236 s_defaultProperties->setProperty(
TextAnchorId, AnchorStart);
1246 s_defaultProperties->setProperty(
FontFamiliesId, QStringLiteral(
"sans-serif"));
1262 TextDecorations deco = DecorationNone;
1270 s_defaultProperties->setProperty(
TextWrapId, Wrap);
1271 TextSpaceTrims trim = TrimNone;
1272 s_defaultProperties->setProperty(
TextTrimId, QVariant::fromValue(trim));
1273 s_defaultProperties->setProperty(
LineBreakId, LineBreakAuto);
1274 s_defaultProperties->setProperty(
WordBreakId, WordBreakNormal);
1280 HangingPunctuations hang = HangNone;
1284 return *s_defaultProperties;
1299 return m_d->isInheritable(
id);
qreal length(const QPointF &vec)
float value(const T *src, size_t ch)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
QPair< QString, QString > parseTag(QString taggedValue)
qreal roundToStraightAngle(qreal value)
QVariantMap parseFeatureSettingsStringList(const QStringList features)
QVariantMap parseVariantStringList(const QStringList features)
@ Collapse
Collapse if first or last in line.
KoSvgText::FontMetrics fontMetricsForCSSValues(KoCSSFontInfo info=KoCSSFontInfo(), const bool isHorizontal=true, const KoSvgText::TextRendering rendering=KoSvgText::RenderingAuto, const QString &text="", quint32 xRes=72, quint32 yRes=72, bool disableFontMatching=false, const QString &language=QString())
static KoFontRegistry * instance()
bool hasNonInheritableProperties() const
Test whether it has non-inheritable properties set.
@ TextAnchorId
KoSvgText::TextAnchor.
@ InlineSizeId
KoSvgText::AutoValue.
@ UnicodeBidiId
KoSvgText::UnicodeBidi.
@ FontOpticalSizingId
Bool.
@ FontSynthesisItalicId
Bool.
@ KraTextVersionId
Int, used for handling incorrectly saved files.
@ DominantBaselineId
KoSvgText::Baseline.
@ FontFamiliesId
QStringList.
@ BaselineShiftValueId
Double.
@ TextTrimId
Flags, KoSvgText::TextSpaceTrims.
@ AlignmentBaselineId
KoSvgText::Baseline.
@ LineHeightId
KoSvgText::AutoValue.
@ TextDecorationColorId
QColor.
@ WordSpacingId
KoSvgText::AutoLengthPercentage.
@ LineBreakId
KoSvgText::LineBreak.
@ FontSizeAdjustId
KoSvgText::AutoValue.
@ FontSynthesisSuperSubId
Bool.
@ LetterSpacingId
KoSvgText::AutoLengthPercentage.
@ TextOrientationId
KoSvgText::TextOrientation.
@ FontSynthesisSmallCapsId
Bool.
@ TextAlignAllId
KoSvgText::TextAlign.
@ TextCollapseId
KoSvgText::TextSpaceCollapse.
@ StrokeId
KoSvgText::StrokeProperty.
@ TextDecorationStyleId
KoSvgText::TextDecorationStyle.
@ TextOverFlowId
KoSvgText::WordBreak.
@ TextTransformId
KoSvgText::TextTransformInfo Struct.
@ FillId
KoSvgText::BackgroundProperty.
@ FontStyleId
KoSvgText::CssSlantData.
@ FontFeatureSettingsId
QStringList.
@ WritingModeId
KoSvgText::WritingMode.
@ DirectionId
KoSvgText::Direction.
@ TextWrapId
KoSvgText::TextWrap.
@ HangingPunctuationId
Flags, KoSvgText::HangingPunctuations.
@ FontSynthesisBoldId
Bool.
@ BaselineShiftModeId
KoSvgText::BaselineShiftMode.
@ TextAlignLastId
KoSvgText::TextAlign.
@ FontVariantLigatureId
KoSvgText::FontVariantFeature.
@ TextDecorationPositionId
KoSvgText::TextDecorationUnderlinePosition.
@ TextIndentId
KoSvgText::TextIndentInfo Struct.
@ FontVariationSettingsId
QStringList.
@ WordBreakId
KoSvgText::WordBreak.
@ TextLanguage
a language string.
@ TextDecorationLineId
Flags, KoSvgText::TextDecorations.
@ KerningId
KoSvgText::AutoValue.
QSharedPointer< KoShapeBackground > background() const
void removeProperty(PropertyId id)
KoShapeStrokeModelSP stroke() const
bool propertyIsInheritable(KoSvgTextProperties::PropertyId id) const
QList< PropertyId > properties() const
static bool propertyIsBlockOnly(KoSvgTextProperties::PropertyId id)
QMap< QString, QString > convertToSvgTextAttributes() const
QFont generateFont() const
KoSvgTextProperties & operator=(const KoSvgTextProperties &rhs)
QVariant property(PropertyId id, const QVariant &defaultValue=QVariant()) const
QMap< QString, QString > convertParagraphProperties() const
convertParagraphProperties some properties only apply to the root shape, so we write those separately...
const QScopedPointer< Private > m_d
static const KoSvgTextProperties & defaultProperties()
QStringList fontFeaturesForText(int start, int length) const
fontFeaturesForText Returns a harfbuzz friendly list of opentype font-feature settings using the vari...
bool operator==(const KoSvgTextProperties &rhs) const
void resetNonInheritableToDefault()
void scaleAbsoluteValues(const double scaleInline=1.0, const double scaleBlock=1.0)
scaleAbsoluteValues This scales all absolute values stored in these text properties....
bool inheritsProperty(PropertyId id, const KoSvgTextProperties &parentProperties) const
KoCSSFontInfo cssFontInfo() const
cssFontInfo
bool hasProperty(PropertyId id) const
void resolveRelativeValues(const KoSvgText::FontMetrics metrics=KoSvgText::FontMetrics(12.0, true), const qreal fontSize=12.0)
resolveRelativeValues resolve the font-relative values.
void setAllButNonInheritableProperties(const KoSvgTextProperties &properties)
Used to merge child properties into parent properties.
void setFontSize(const KoSvgText::CssLengthPercentage length)
void parseSvgTextAttribute(const SvgLoadingContext &context, const QString &command, const QString &value)
parseSvgTextAttribute add a property according to an XML attribute value.
void setProperty(PropertyId id, const QVariant &value)
KoSvgText::FontMetrics applyLineHeight(KoSvgText::FontMetrics metrics) const
applyLineHeight Calculate the linegap for the current linegap property.
KoSvgTextProperties ownProperties(const KoSvgTextProperties &parentProperties, bool keepFontSize=false) const
KoSvgText::FontMetrics metrics(const bool withResolvedLineHeight=true) const
metrics Return the metrics of the first available font.
static QStringList supportedXmlAttributes()
QVariant propertyOrDefault(PropertyId id) const
KoSvgText::CssLengthPercentage fontSize() const
void inheritFrom(const KoSvgTextProperties &parentProperties, bool resolve=false)
QRectF currentBoundingBox
the current bound box used for bounding box units
Contains data used for loading svg.
SvgGraphicsContext * currentGC() const
Returns the current graphics context.
KoSvgTextProperties resolvedProperties() const
These are the text properties, completely resolved, ensuring that everything is inherited and the siz...
static KoSvgText::CssLengthPercentage parseTextUnitStruct(SvgGraphicsContext *gc, QStringView unit)
Unit structs for text do not need the percentage to be resolved to viewport in most cases.
static qreal parseUnitXY(SvgGraphicsContext *gc, const KoSvgTextProperties &resolved, const QString &unit)
parses a length attribute in xy-direction
T kisRadiansToDegrees(T radians)
std::enable_if< std::is_floating_point< T >::value, T >::type normalizeAngle(T a)
QString toString(const QString &value)
BaselineShiftMode parseBaselineShiftMode(const QString &value)
BaselineShiftMode
Mode of the baseline shift.
@ ShiftLengthPercentage
Css Length Percentage, percentage is lh.
FontFeatureCaps
Represents font-feature-caps.
bool xmlSpaceToLongHands(const QString &value, TextSpaceCollapse &collapseMethod)
xmlSpaceToLongHands This takes xml:space values and converts them to CSS-Text-4 properties.
AutoValue parseAutoValueY(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword)
TextAnchor
Where the text is anchored for SVG 1.1 text and 'inline-size'.
FontFeaturePosition
The FontFeatureLigatures class This enum represents css font-variant-position.
TabSizeInfo parseTabSize(const QString &value, const SvgLoadingContext &context)
Baseline parseBaseline(const QString &value)
TextDecorationStyle
Style of the text-decoration.
FontFeatureEastAsian parseFontFeatureEastAsian(const QString &value, FontFeatureEastAsian features)
TextAnchor parseTextAnchor(const QString &value)
OverflowWrap
What to do with words that cannot be broken, but still overflow.
@ OverflowWrapAnywhere
Break anywhere as soon as overflow happens.
TextOrientation parseTextOrientation(const QString &value)
WordBreak
Whether to break words.
UnicodeBidi parseUnicodeBidi(const QString &value)
WritingMode parseWritingMode(const QString &value)
TextWrap
Part of "white-space", in practice we only support wrap and nowrap.
QString writeLineHeight(LineHeightInfo lineHeight)
bool whiteSpaceValueToLongHands(const QString &value, TextSpaceCollapse &collapseMethod, TextWrap &wrapMethod, TextSpaceTrims &trimMethod)
whiteSpaceValueToLongHands CSS-Text-4 takes CSS-Text-3 whitespace values and treats them as a shortha...
CssFontStyleData parseFontStyle(const QString &value)
TextRendering parseTextRendering(const QString &value)
Baseline
Baseline values used by dominant-baseline and baseline-align.
AutoValue parseAutoValueAngular(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword)
TextOverflow
How to handle overflow.
@ OverFlowEllipse
Replace the last characters with "U+2026".
@ OverFlowClip
Clip the rendered content.
TextIndentInfo parseTextIndent(const QString &value, const SvgLoadingContext &context)
QString writeTextRendering(TextRendering value)
TextAlign parseTextAlign(const QString &value)
Direction parseDirection(const QString &value)
LineHeightInfo parseLineHeight(const QString &value, const SvgLoadingContext &context)
QVariant fromAutoValue(const KoSvgText::AutoValue &value)
AutoValue parseAutoValueXY(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword)
FontFeaturePosition parseFontFeaturePosition(const QString &value, FontFeaturePosition feature)
QString writeFontStyle(CssFontStyleData value)
LineBreak parseLineBreak(const QString &value)
QStringList fontFeaturesPosition(const FontFeaturePosition &feature, const int start, const int end)
int parseCSSFontWeight(const QString &value, int currentWeight)
TextOrientation parseTextOrientationFromGlyphOrientation(AutoValue value)
static const std::array< const char *, 9 > fontStretchNames
AutoLengthPercentage parseAutoLengthPercentageXY(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword, QRectF bbox, bool percentageIsViewPort)
FontFeatureCaps parseFontFeatureCaps(const QString &value, FontFeatureCaps feature)
FontFeatureLigatures parseFontFeatureLigatures(const QString &value, FontFeatureLigatures features)
int parseCSSFontStretch(const QString &value, int currentStretch)
parseCSSFontStretch For CSS3, the font-stretches were only given as keywords. In Css 4 and above,...
TextOrientation
Orientation of the glyphs, used for vertical writing modes.
TextTransformInfo parseTextTransform(const QString &value)
@ HangForce
Whether to force hanging stops or commas.
@ HangLast
Hang closing brackets and quotes.
@ HangFirst
Hang opening brackets and quotes.
@ HangEnd
Hang stops and commas. Force/Allow is a separate boolean.
@ PreserveSpaces
required for 'xml:space="preserve"' emulation.
WordBreak parseWordBreak(const QString &value)
FontFeatureNumeric parseFontFeatureNumeric(const QString &value, FontFeatureNumeric features)
QStringList fontFeaturesCaps(const FontFeatureCaps &feature, const int start, const int end)
The KoCSSFontInfo class Convenience struct to make it easier to use KoFontRegistry....
bool automaticOpticalSizing
< Size in Pt.
QMap< QString, double > axisSettings
static bool isInheritable(PropertyId id)
QMap< PropertyId, QVariant > properties
CssLengthPercentage length
BackgroundProperty is a special wrapper around KoShapeBackground for managing it in KoSvgTextProperti...
When style is oblique, a custom slant value can be specified for variable fonts.
KoSvgText::AutoValue slantValue
@ Absolute
Pt, everything needs to be converted to pt for this to work.
@ Lh
multiply by width of "U+6C34", represents average full width script advance.
void convertToAbsolute(const KoSvgText::FontMetrics metrics, const qreal fontSize, const UnitType percentageUnit=Em)
QStringList fontFeatures(const int start, const int end)
The FontFeatureLigatures class This struct represents css font-variant-ligatures.
QStringList fontFeatures(const int start, const int end)
The FontFeatureLigatures class This struct represents css font-variant-numeric.
QStringList fontFeatures(const int start, const int end)
The FontMetrics class A class to keep track of a variety of font metrics. Note that values are in Fre...
qint32 xHeight
height of X, defaults to 0.5 fontsize.
qint32 lineGap
additional linegap between consecutive lines.
qint32 fontSize
Currently set size, CSS unit 'em'.
qint32 descender
distance for origin to bottom.
qint32 ascender
distance from origin to top.
bool isNumber
Length or number.
CssLengthPercentage length
bool isNormal
It's a number indicating the lineHeight;.
StrokeProperty is a special wrapper around KoShapeStrokeModel for managing it in KoSvgTextProperties.
qreal value
A length or a number. Length is currently marked 'at-risk'.
CssLengthPercentage length
CssLengthPercentage length
TextDecorationUnderlinePosition verticalPosition
TextDecorationUnderlinePosition horizontalPosition