10#include <QGlobalStatic>
12#include <QRegularExpression>
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;
140 }
else if (!onlyFontAndLineHeight) {
146 if (onlyFontAndLineHeight)
return;
151 for (
auto it = this->
m_d->properties.begin(); it != this->
m_d->properties.end(); it++) {
160 it.value() = QVariant::fromValue(
length);
166 it.value() = QVariant::fromValue(val);
172 it.value() = QVariant::fromValue(tabSize);
179 it.value() = QVariant::fromValue(indent);
191 for (
auto it =
m_d->properties.constBegin(); it !=
m_d->properties.constEnd(); ++it) {
192 if (!
m_d->isInheritable(it.key())) {
201 auto it =
properties.m_d->properties.constBegin();
202 for (; it !=
properties.m_d->properties.constEnd(); ++it) {
203 if (
m_d->isInheritable(it.key())) {
213 for (
auto it = this->
m_d->properties.begin(); it != this->
m_d->properties.end(); ++it) {
216 if (
length.unit != absoluteUnit)
continue;
220 length.value *= scaleInline;
222 it.value() = QVariant::fromValue(
length);
225 if (info.
length.
unit != absoluteUnit)
continue;
227 it.value() = QVariant::fromValue(info);
230 if (info.
length.
unit != absoluteUnit)
continue;
232 it.value() = QVariant::fromValue(info);
235 if (info.
length.
unit != absoluteUnit)
continue;
237 it.value() = QVariant::fromValue(info);
240 if (info.
isAuto)
continue;
243 it.value() = QVariant::fromValue(info);
254 for (; it !=
m_d->properties.constEnd(); ++it) {
256 || parentProperties.
property(it.key()) != it.value()) {
269QPair<QString, QString>
parseTag(QString taggedValue) {
270 QPair<QString, QString> tag;
271 tag.first = taggedValue.mid(1, 4);
272 if (taggedValue.length() > 6) {
273 tag.second = taggedValue.remove(0, 6).trimmed();
279 QVariantMap settings;
280 for (
int i = 0; i < features.size(); i++) {
281 QString feature = features.at(i).trimmed();
282 if ((!feature.startsWith(
'\'') && !feature.startsWith(
'\"')) || feature.isEmpty()) {
285 QPair<QString, QString> tag =
parseTag(feature);
287 double featureVal = tag.second.toDouble(&ok);
289 if (ok && !tag.first.isEmpty()) {
290 settings.insert(tag.first, QVariant(featureVal));
297 QVariantMap settings;
298 for (
int i = 0; i < features.size(); i++) {
299 QString feature = features.at(i).trimmed();
300 if ((!feature.startsWith(
'\'') && !feature.startsWith(
'\"')) || feature.isEmpty()) {
303 QPair<QString, QString> tag =
parseTag(feature);
304 if (tag.second.isEmpty()) {
305 settings.insert(tag.first, QVariant(1));
308 int featureVal = tag.second.toInt(&ok);
309 if (tag.second.toLower() ==
"on") {
312 }
else if (tag.second.toLower() ==
"off") {
316 if (ok && !tag.first.isEmpty()) {
317 settings.insert(tag.first, QVariant(featureVal));
326 if (command ==
"writing-mode") {
328 }
else if (command ==
"glyph-orientation-vertical") {
333 acceptedOrientations <<
"auto"
338 if (acceptedOrientations.contains(
value.toLower())) {
345 }
else if (command ==
"text-orientation") {
347 }
else if (command ==
"direction") {
349 }
else if (command ==
"unicode-bidi") {
351 }
else if (command ==
"text-anchor") {
353 }
else if (command ==
"dominant-baseline") {
355 }
else if (command ==
"alignment-baseline") {
357 }
else if (command ==
"baseline-shift") {
364 }
else if (command ==
"vertical-align") {
365 QRegularExpression digits = QRegularExpression(
"\\d");
366 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
367 bool paramContains = param.contains(digits);
369 if (param ==
"sub" || param ==
"super" || param ==
"top" || param ==
"bottom" || paramContains) {
375 }
else if (command ==
"kerning" || command ==
"font-kerning") {
377 if (
value ==
"none") {
380 }
else if (
value ==
"normal") {
387 }
else if (command ==
"letter-spacing") {
389 }
else if (command ==
"word-spacing") {
391 }
else if (command ==
"font-family") {
393 Q_FOREACH (
const QString &fam,
value.split(
',', Qt::SkipEmptyParts)) {
394 QString family = fam.trimmed();
395 if ((family.startsWith(
'\"') && family.endsWith(
'\"')) ||
396 (family.startsWith(
'\'') && family.endsWith(
'\''))) {
398 family = family.mid(1, family.size() - 2);
400 familiesList.append(family);
404 }
else if (command ==
"font-style") {
406 }
else if (command ==
"font-variant" || command ==
"font-variant-ligatures" || command ==
"font-variant-position" || command ==
"font-variant-caps"
407 || command ==
"font-variant-numeric" || command ==
"font-variant-east-asian" || command ==
"font-variant-alternates") {
409 Q_FOREACH (
const QString f, features) {
410 bool commandFontVariant = (command ==
"font-variant");
411 if (commandFontVariant || command ==
"font-variant-ligatures") {
416 if (commandFontVariant || command ==
"font-variant-position") {
421 if (commandFontVariant || command ==
"font-variant-caps") {
426 if (commandFontVariant || command ==
"font-variant-numeric") {
431 if (commandFontVariant || command ==
"font-variant-east-asian") {
438 }
else if (command ==
"font-feature-settings") {
440 }
else if (command ==
"font-stretch") {
441 int newStretch = 100;
447 }
else if (command ==
"font-weight") {
452 }
else if (command ==
"font-size") {
454 if (pointSize.
value > 0.0) {
457 }
else if (command ==
"font-size-adjust") {
460 }
else if (command ==
"font-optical-sizing") {
462 }
else if (command ==
"font-variation-settings") {
464 }
else if (command ==
"text-decoration" || command ==
"text-decoration-line" || command ==
"text-decoration-style" || command ==
"text-decoration-color"
465 || command ==
"text-decoration-position") {
469 if (command ==
"text-decoration" || command ==
"text-decoration-line") {
477 bool setPosition =
false;
479 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
480 if (param ==
"line-through") {
481 deco |= DecorationLineThrough;
482 }
else if (param ==
"underline") {
483 deco |= DecorationUnderline;
484 }
else if (param ==
"overline") {
485 deco |= DecorationOverline;
486 }
else if (param ==
"solid") {
488 }
else if (param ==
"double") {
490 }
else if (param ==
"dotted") {
492 }
else if (param ==
"dashed") {
494 }
else if (param ==
"wavy") {
496 }
else if (param ==
"auto") {
499 }
else if (param ==
"under") {
502 }
else if (param ==
"left") {
505 }
else if (param ==
"right") {
508#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
509 }
else if (QColor::isValidColor(param)) {
511 }
else if (QColor::isValidColorName(param)) {
514 textDecorationColor = QColor(param);
518 if (command ==
"text-decoration" || command ==
"text-decoration-line") {
521 if (command ==
"text-decoration" || command ==
"text-decoration-style") {
524 if (command ==
"text-decoration" || command ==
"text-decoration-color") {
527 if ((command ==
"text-decoration" || command ==
"text-decoration-position") && setPosition) {
531 }
else if (command ==
"xml:lang") {
533 }
else if (command ==
"text-transform") {
535 }
else if (command ==
"white-space") {
546 }
else if (command ==
"xml:space") {
550 }
else if (command ==
"word-break") {
552 }
else if (command ==
"line-break") {
554 }
else if (command ==
"text-align" || command ==
"text-align-all" || command ==
"text-align-last") {
556 if (command ==
"text-align" || command ==
"text-align-all") {
558 if (
value ==
"justify-all") {
562 if (command ==
"text-align" && params.size() > 1) {
565 if (command ==
"text-align-last") {
568 }
else if (command ==
"line-height") {
570 }
else if (command ==
"text-indent") {
572 }
else if (command ==
"hanging-punctuation") {
573 KoSvgText::HangingPunctuations hang;
574 Q_FOREACH (
const QString ¶m,
value.split(
' ', Qt::SkipEmptyParts)) {
575 if (param ==
"first") {
577 }
else if (param ==
"last") {
579 }
else if (param ==
"allow-end") {
582 }
else if (param ==
"force-end") {
588 }
else if (command ==
"inline-size") {
590 }
else if (command ==
"overflow") {
592 }
else if (command ==
"text-overflow") {
594 }
else if (command ==
"overflow-wrap" || command ==
"word-wrap") {
599 }
else if (command ==
"tab-size") {
601 }
else if (command ==
"shape-padding") {
604 }
else if (command ==
"shape-margin") {
607 }
else if (command ==
"font-synthesis") {
612 if (
value !=
"none") {
614 if (params.contains(
"position")) {
617 if (params.contains(
"weight")) {
620 if (params.contains(
"style")) {
623 if (params.contains(
"small-caps")) {
627 }
else if (command ==
"font-synthesis-weight") {
629 }
else if (command ==
"font-synthesis-style") {
631 }
else if (command ==
"font-synthesis-small-caps") {
633 }
else if (command ==
"font-synthesis-position") {
635 }
else if (command ==
"text-rendering") {
638 qFatal(
"FATAL: Unknown SVG property: %s = %s", command.toUtf8().data(),
value.toUtf8().data());
646 QMap<QString, QString> result;
657 QString
value =
"auto";
658 if (orientation == OrientationUpright) {
660 }
else if (orientation == OrientationSideWays) {
663 result.insert(
"glyph-orientation-vertical",
value);
685 bool writeSeparate =
true;
688 if (mode == ShiftLineTop || mode == ShiftLineBottom) {
689 writeSeparate =
false;
700 result.insert(
"baseline-shift",
713 if (!verticalAlign.isEmpty()) {
714 result.insert(
"vertical-align", verticalAlign.join(
" "));
720 result.insert(
"kerning", writeAutoValue(
property(
KerningId).value<AutoValue>()));
724 result.insert(
"font-kerning",
"auto");
726 result.insert(
"font-kerning",
"none");
728 result.insert(
"font-kerning",
"normal");
735 result.insert(
"letter-spacing", writeAutoLengthPercentage(
property(
LetterSpacingId).value<AutoLengthPercentage>(),
"normal",
true));
739 result.insert(
"word-spacing", writeAutoLengthPercentage(
property(
WordSpacingId).value<AutoLengthPercentage>(),
"normal",
true));
753 result.insert(
"font-variant-ligatures", writeFontFeatureLigatures(feat));
757 result.insert(
"font-variant-position", writeFontFeaturePosition(feat));
761 result.insert(
"font-variant-caps", writeFontFeatureCaps(feat));
765 result.insert(
"font-variant-numeric", writeFontFeatureNumeric(feat));
769 result.insert(
"font-variant-east-asian", writeFontFeatureEastAsian(feat));
774 for(
auto it = vals.begin(); it != vals.end(); it++) {
775 settings.append(QString(
"'%1' %2").arg(it.key()).arg(it.value().toDouble()));
777 result.insert(
"font-feature-settings", settings.join(
", "));
782 result.insert(
"font-optical-sizing",
"none");
788 for(
auto it = vals.begin(); it != vals.end(); it++) {
789 settings.append(QString(
"'%1' %2").arg(it.key()).arg(it.value().toDouble()));
791 result.insert(
"font-variation-settings", settings.join(
", "));
796 static constexpr std::array<int, 9> fontStretches = {50, 62, 75, 87, 100, 112, 125, 150, 200};
797 if (svg1_1 || std::find(fontStretches.begin(), fontStretches.end(), stretch) != fontStretches.end()) {
798 const auto it = std::lower_bound(fontStretches.begin(), fontStretches.end(), stretch);
799 if (it != fontStretches.end()) {
800 const auto index = std::distance(fontStretches.begin(), it);
814 result.insert(
"font-size", writeLengthPercentage(
fontSize()));
825 if (deco.testFlag(DecorationUnderline)) {
826 decoStrings.append(
"underline");
829 if (deco.testFlag(DecorationOverline)) {
830 decoStrings.append(
"overline");
833 if (deco.testFlag(DecorationLineThrough)) {
834 decoStrings.append(
"line-through");
837 if (deco != DecorationNone) {
841 if (style == Solid) {
842 decoStrings.append(
"solid");
843 }
else if (style == Double) {
844 decoStrings.append(
"double");
845 }
else if (style == Dotted) {
846 decoStrings.append(
"dotted");
847 }
else if (style == Dashed) {
848 decoStrings.append(
"dashed");
849 }
else if (style == Wavy) {
850 decoStrings.append(
"wavy");
855 if (color.isValid()) {
856 decoStrings.append(color.name());
860 if (!decoStrings.isEmpty()) {
861 result.insert(
"text-decoration", decoStrings.join(
' '));
869 decoPositionStrings.append(
"under");
871 decoPositionStrings.append(
"auto");
874 decoPositionStrings.append(
"right");
876 decoPositionStrings.append(
"left");
878 if (!decoPositionStrings.isEmpty()) {
879 result.insert(
"text-decoration-position", decoPositionStrings.join(
' '));
901 result.insert(
"xml:space", writeXmlSpace(collapse));
903 result.insert(
"white-space", writeWhiteSpaceValue(collapse, wrap, trims));
917 if (hang.testFlag(HangFirst)) {
918 value.append(
"first");
920 if (hang.testFlag(HangLast)) {
921 value.append(
"last");
923 if (hang.testFlag(HangEnd)) {
924 if (hang.testFlag(HangForce)) {
925 value.append(
"force-end");
927 value.append(
"allow-end");
931 if (!
value.isEmpty()) {
932 result.insert(
"hanging-punctuation",
value.join(
" "));
938 if (overflow == OverflowWrapAnywhere) {
939 result.insert(
"overflow-wrap",
"anywhere");
940 }
else if (overflow == OverflowWrapBreakWord) {
941 result.insert(
"overflow-wrap",
"break-word");
946 if (overflow == OverFlowClip) {
947 result.insert(
"overflow",
"clip");
948 result.insert(
"text-overflow",
"clip");
949 }
else if (overflow == OverFlowEllipse) {
950 result.insert(
"overflow",
"visible");
951 result.insert(
"text-overflow",
"ellipse");
953 result.insert(
"overflow",
"visible");
954 result.insert(
"text-overflow",
"clip");
965 if (!weight && !italic && !caps && !super) {
966 result.insert(
"font-synthesis",
"none");
969 if (weight) params.append(
"weight");
970 if (italic) params.append(
"style");
971 if (caps) params.append(
"small-caps");
972 if (super) params.append(
"position");
973 result.insert(
"font-synthesis", params.join(
" "));
1000 QMap<QString, QString> result;
1002 result.insert(
"inline-size", writeAutoValue(
property(
InlineSizeId).value<AutoValue>(),
"auto"));
1009 result.insert(
"text-align", writeTextAlign(all));
1011 if (last != all || last != AlignLastAuto) {
1012 result.insert(
"text-align-last", writeTextAlign(last));
1016 result.insert(
"shape-padding", writeLengthPercentage(
property(
ShapePaddingId).value<CssLengthPercentage>()));
1019 result.insert(
"shape-margin", writeLengthPercentage(
property(
ShapeMarginId).value<CssLengthPercentage>()));
1030 if (!familiesList.isEmpty()) {
1031 fontFamily = familiesList.first();
1033 const QFont::Style style =
1039 QFont font(fontFamily
1042 , style != QFont::StyleNormal);
1043 font.setStyle(style);
1057 font.setStrikeOut(deco & DecorationLineThrough);
1058 font.setUnderline(deco & DecorationUnderline);
1059 font.setOverline(deco & DecorationOverline);
1061 struct FakePaintDevice :
public QPaintDevice
1063 QPaintEngine *paintEngine()
const override {
1067 int metric(QPaintDevice::PaintDeviceMetric metric)
const override {
1069 if (metric == QPaintDevice::PdmDpiX || metric == QPaintDevice::PdmDpiY) {
1074 return QPaintDevice::metric(metric);
1080 FakePaintDevice fake72DpiPaintDevice;
1081 return QFont(font, &fake72DpiPaintDevice);
1092 return fontSizeVal * 0.5;
1103 if (offsetByBaseline) {
1147 QString openTypeTag =
"kern";
1148 openTypeTag += QString(
"[%1:%2]").arg(start).arg(start +
length);
1149 openTypeTag +=
"=0";
1150 fontFeatures.append(openTypeTag);
1151 openTypeTag =
"vkrn";
1152 openTypeTag += QString(
"[%1:%2]").arg(start).arg(start +
length);
1153 openTypeTag +=
"=0";
1154 fontFeatures.append(openTypeTag);
1159 for (
int i = 0; i < features.keys().size(); i++) {
1160 const QString key = features.keys().at(i);
1161 QString openTypeTag = QString(
"%1[%2:%3]=%4").arg(key).arg(start).arg(start +
length).arg(features.value(key).toInt());
1162 fontFeatures.append(openTypeTag);
1166 return fontFeatures;
1188 for (
auto it = features.begin(); it != features.end(); it++) {
1189 info.
axisSettings.insert(it.key(), it.value().toDouble());
1218 attributes <<
"writing-mode"
1219 <<
"glyph-orientation-vertical"
1220 <<
"glyph-orientation-horizontal"
1224 <<
"dominant-baseline"
1225 <<
"alignment-baseline"
1232 <<
"text-rendering";
1242 if (!s_defaultProperties.exists()) {
1245 s_defaultProperties->setProperty(
WritingModeId, HorizontalTB);
1246 s_defaultProperties->setProperty(
DirectionId, DirectionLeftToRight);
1247 s_defaultProperties->setProperty(
UnicodeBidiId, BidiNormal);
1248 s_defaultProperties->setProperty(
TextAnchorId, AnchorStart);
1258 s_defaultProperties->setProperty(
FontFamiliesId, QStringLiteral(
"sans-serif"));
1274 TextDecorations deco = DecorationNone;
1282 s_defaultProperties->setProperty(
TextWrapId, Wrap);
1283 TextSpaceTrims trim = TrimNone;
1284 s_defaultProperties->setProperty(
TextTrimId, QVariant::fromValue(trim));
1285 s_defaultProperties->setProperty(
LineBreakId, LineBreakAuto);
1286 s_defaultProperties->setProperty(
WordBreakId, WordBreakNormal);
1292 HangingPunctuations hang = HangNone;
1296 return *s_defaultProperties;
1311 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)
KoSvgText::FontMetrics metrics(const bool withResolvedLineHeight=true, const bool offsetByBaseline=false) const
metrics Return the metrics of the first available font.
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 inheritFrom(const KoSvgTextProperties &parentProperties, bool resolve=false, bool onlyFontAndLineHeight=false)
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.
void resolveRelativeValues(const KoSvgText::FontMetrics metrics=KoSvgText::FontMetrics(12.0, true), const qreal fontSize=12.0, bool onlyFontAndLineHeight=false)
resolveRelativeValues resolve the font-relative values.
KoSvgTextProperties ownProperties(const KoSvgTextProperties &parentProperties, bool keepFontSize=false) const
static QStringList supportedXmlAttributes()
QVariant propertyOrDefault(PropertyId id) const
KoSvgText::CssLengthPercentage fontSize() const
QRectF currentBoundingBox
the current bound box used for bounding box units
Contains data used for loading svg.
KoSvgTextProperties resolvedProperties(bool onlyFontAndLineHeight=false) const
SvgGraphicsContext * currentGC() const
Returns the current graphics context.
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.
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.
@ BaselineAlphabetic
Use 'romn' or the baseline for LCG scripts.
@ BaselineNoChange
Use parent baseline table.
@ BaselineCentral
Use the center between the ideographic over and under.
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.
void offsetMetricsToNewOrigin(const Baseline baseline)
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