Krita Source Code Documentation
Loading...
Searching...
No Matches
SvgTextShortCuts.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6#include "SvgTextShortCuts.h"
7#include <QAction>
9
11
16struct SvgTextShortcutInfo : public boost::equality_comparable<SvgTextShortcutInfo> {
17
21 Increase, //< Will increase by value 1.
22 Decrease //< Will decrease by value 1.
23 };
25
27 QVariant _value1, QVariant _value2, QVariant _testValue) {
29 info.propertyId = _propertyId;
30 info.type = Toggle;
31 info.value1 = _value1;
32 info.value2 = _value2;
33 info.testValue = _testValue;
34 return info;
35 }
36
37 static SvgTextShortcutInfo propertyChange(KoSvgTextProperties::PropertyId _propertyId, QVariant _value1, bool _increase) {
39 info.propertyId = _propertyId;
40 info.type = _increase? Increase: Decrease;
41 info.value1 = _value1;
42 return info;
43 }
44
45 static SvgTextShortcutInfo propertySet(KoSvgTextProperties::PropertyId _propertyId, QVariant _value1) {
47 info.propertyId = _propertyId;
48 info.type = Set;
49 info.value1 = _value1;
50 return info;
51 }
52
55 QVariant value1;
56 QVariant value2;
57 QVariant testValue;
58
59
60
61 bool operator==(const SvgTextShortcutInfo & other) const {
62 return (propertyId == other.propertyId
63 && type == other.type
64 && value1 == other.value1
65 && value2 == other.value2
66 && testValue == other.testValue);
67 }
68};
69
71
73 qRegisterMetaType<SvgTextShortcutInfo>("SvgTextShortcutInfo");
74#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
75 QMetaType::registerEqualsComparator<SvgTextShortcutInfo>();
76#endif
77}
78
79const QMap<QString, SvgTextShortcutInfo> textShortCuts = {
80 {
81 "svg_weight_bold",
83 QVariant(400), QVariant(700), QVariant(500))
84 },
85
86 {
87 "svg_weight_normal",
89 QVariant(400))
90 },
91 {
92 "svg_weight_demi",
94 QVariant(600))
95 },
96 {
97 "svg_weight_black",
99 QVariant(900))
100 },
101 {
102 "svg_weight_light",
104 QVariant(300))
105 },
106
107 {
108 "svg_format_italic",
110 QVariant::fromValue(KoSvgText::CssFontStyleData(QFont::StyleNormal)),
111 QVariant::fromValue(KoSvgText::CssFontStyleData(QFont::StyleItalic)),
112 QVariant::fromValue(KoSvgText::CssFontStyleData(QFont::StyleNormal)))
113 },
114
115 {
116 "svg_increase_font_size",
118 QVariant::fromValue(1), true)
119 },
120
121 {
122 "svg_decrease_font_size",
124 QVariant::fromValue(1), false)
125 },
126
127 {
128 "svg_format_underline",
130 QVariant(true), QVariant(false), QVariant(KoSvgText::DecorationUnderline))
131 },
132 {
133 "svg_format_strike_through",
135 QVariant(true), QVariant(false), QVariant(KoSvgText::DecorationLineThrough))
136 },
137 {
138 "svg_font_kerning",
140 QVariant(true), QVariant(false), QVariant(true))
141 },
142 {
143 "svg_align_right",
145 QVariant(KoSvgText::AlignStart))
146 },
147 {
148 "svg_align_left",
150 QVariant(KoSvgText::AlignEnd))
151 },
152 {
153 "svg_align_center",
155 QVariant(KoSvgText::AlignCenter))
156 },
157 {
158 "svg_align_justified",
160 QVariant(KoSvgText::AlignJustify))
161 },
162 {
163 "svg_format_subscript",
165 QVariant(KoSvgText::ShiftSub))
166 },
167 {
168 "svg_format_superscript",
170 QVariant(KoSvgText::ShiftSuper))
171 }
172};
173
178
179bool SvgTextShortCuts::configureAction(QAction *action, const QString &name)
180{
181 if (!textShortCuts.contains(name)) return false;
182 if (!action) return false;
183 SvgTextShortcutInfo info = textShortCuts.value(name);
184 action->setData(QVariant::fromValue(info));
185 return true;
186}
194{
195 const QVariant testValue = info.type == SvgTextShortcutInfo::Toggle? info.testValue: info.value1;
196
197 for (auto properties = currentProperties.begin(); properties != currentProperties.end(); properties++) {
198 const QVariant oldValue = properties->propertyOrDefault(info.propertyId);
199
200
201 if (oldValue.canConvert<KoSvgText::TextDecorations>() && info.propertyId == KoSvgTextProperties::TextDecorationLineId) {
202
203 const KoSvgText::TextDecorations oldDecor = oldValue.value<KoSvgText::TextDecorations>();
204 return oldDecor.testFlag(KoSvgText::TextDecoration(testValue.toInt()));
205
206 } else if (oldValue.canConvert<KoSvgText::CssFontStyleData>()) {
207 const KoSvgText::CssFontStyleData testVal = testValue.value<KoSvgText::CssFontStyleData>();
208 const KoSvgText::CssFontStyleData currentVal = oldValue.value<KoSvgText::CssFontStyleData>();
209 return (testVal.style == currentVal.style);
210 } else if (oldValue.canConvert<KoSvgText::AutoValue>()) {
211 const KoSvgText::AutoValue currentVal = oldValue.value<KoSvgText::AutoValue>();
212 if (testValue.canConvert<KoSvgText::AutoValue>()) {
213 return (testValue == oldValue);
214 } else if (testValue.canConvert<double>()) {
215 return currentVal.customValue == testValue.toDouble();
216 } else {
217 return currentVal.isAuto == testValue.toBool();
218 }
219 } else if (oldValue.canConvert<KoSvgText::CssLengthPercentage>()) {
220 const KoSvgText::CssLengthPercentage currentVal = oldValue.value<KoSvgText::CssLengthPercentage>();
221 if (testValue.canConvert<KoSvgText::CssLengthPercentage>()) {
222 return (testValue == oldValue);
223 } else {
224 return currentVal.value >= testValue.toDouble();
225 }
226 } else if (oldValue.canConvert<KoSvgText::AutoLengthPercentage>()) {
227 const KoSvgText::AutoLengthPercentage currentVal = oldValue.value<KoSvgText::CssLengthPercentage>();
228 if (testValue.canConvert<KoSvgText::AutoLengthPercentage>()) {
229 return (testValue == oldValue);
230 } else if (testValue.canConvert<KoSvgText::CssLengthPercentage>()) {
231 return (testValue == QVariant::fromValue(currentVal.length));
232 } else {
233 return currentVal.length.value == testValue.toDouble();
234 }
235 } else if (oldValue.canConvert<KoSvgText::LineHeightInfo>()) {
236 const KoSvgText::LineHeightInfo currentVal = oldValue.value<KoSvgText::LineHeightInfo>();
237 if (testValue.canConvert<KoSvgText::LineHeightInfo>()) {
238 return (testValue == oldValue);
239 } else if (testValue.canConvert<KoSvgText::CssLengthPercentage>()) {
240 return (testValue == QVariant::fromValue(currentVal.length));
241 } else {
242 return currentVal.length.value == testValue.toDouble();
243 }
244 }
245 return (testValue.toDouble() <= oldValue.toDouble());
246 }
247 return false;
248}
249
250bool SvgTextShortCuts::actionEnabled(QAction *action, const QList<KoSvgTextProperties> currentProperties) {
251 if (!action || !action->isCheckable() || !action->data().canConvert<SvgTextShortcutInfo>()) return action->isChecked();
252 SvgTextShortcutInfo info = action->data().value<SvgTextShortcutInfo>();
253
255 return false;
256 }
257
258 return testPropertyEnabled(info, currentProperties);
259}
260
266QVariant toggleProperty(SvgTextShortcutInfo info, bool checked, QList<KoSvgTextProperties> currentProperties) {
267 QVariant newVal;
268
269 if (currentProperties.isEmpty()) return newVal;
270
271 QVariant oldValue = currentProperties.first().propertyOrDefault(info.propertyId);
272 if (oldValue.canConvert<KoSvgText::TextDecorations>() && info.propertyId == KoSvgTextProperties::TextDecorationLineId) {
274 KoSvgText::TextDecorations newDecor;
275 newDecor.setFlag(decor, checked);
276 newVal = QVariant::fromValue(newDecor);
277
278 } else {
279 if (checked) {
280 newVal = info.value2;
281 } else {
282 newVal = info.value1;
283 }
284 }
285
286 return newVal;
287}
288
296QVariant adjustValue(SvgTextShortcutInfo info, QVariant oldValue) {
297 QVariant newVal;
298
299 if (oldValue.canConvert<KoSvgText::CssLengthPercentage>()) {
302 length.value += info.value1.toDouble();
303 } else {
304 length.value -= info.value1.toDouble();
305 }
306 newVal = QVariant::fromValue(length);
307 } else if (oldValue.canConvert<KoSvgText::AutoLengthPercentage>()) {
309 length.isAuto = false;
311 length.length.value += info.value1.toDouble();
312 } else {
313 length.length.value -= info.value1.toDouble();
314 }
315 newVal = QVariant::fromValue(length);
316 } else if (oldValue.canConvert<KoSvgText::AutoValue>()) {
318 value.isAuto = false;
320 value.customValue += info.value1.toDouble();
321 } else {
322 value.customValue -= info.value1.toDouble();
323 }
324 newVal = QVariant::fromValue(value);
325 } else if (oldValue.canConvert<double>()) {
326 double value = oldValue.toDouble();
328 value += info.value1.toDouble();
329 } else {
330 value -= info.value1.toDouble();
331 }
332 newVal = QVariant::fromValue(value);
333 } else if (oldValue.canConvert<int>()) {
334 int value = oldValue.toInt();
336 value += info.value1.toInt();
337 } else {
338 value -= info.value1.toInt();
339 }
340 newVal = QVariant::fromValue(value);
341 }
342
343 return newVal;
344}
345
347{
348 if (!action || !action->data().canConvert<SvgTextShortcutInfo>() || currentProperties.isEmpty()) return KoSvgTextProperties();
349 SvgTextShortcutInfo info = action->data().value<SvgTextShortcutInfo>();
350
351 QVariant newVal;
352 if (info.type == SvgTextShortcutInfo::Toggle) {
353 newVal = toggleProperty(info, action->isChecked(), currentProperties);
354 } else if (info.type == SvgTextShortcutInfo::Set) {
355 KoSvgTextProperties properties = currentProperties.first();
356 QVariant oldValue = properties.propertyOrDefault(info.propertyId);
357
358 if (oldValue.canConvert<int>()) {
359 newVal = info.value1;
360 }
361 } else {
362 KoSvgTextProperties properties = currentProperties.first();
363 QVariant oldValue = properties.propertyOrDefault(info.propertyId);
364
365 newVal = adjustValue(info, oldValue);
366 }
367 KoSvgTextProperties newProperties;
368 newProperties.setProperty(info.propertyId, newVal);
369 return newProperties;
370}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
float value(const T *src, size_t ch)
const QMap< QString, SvgTextShortcutInfo > textShortCuts
QVariant toggleProperty(SvgTextShortcutInfo info, bool checked, QList< KoSvgTextProperties > currentProperties)
toggleProperty Handles toggling properties for getModifiedProperties split out to make code easier to...
QVariant adjustValue(SvgTextShortcutInfo info, QVariant oldValue)
adjustValue Handles increase/decrease value for getModifiedProperties, split out to make code easier ...
KIS_DECLARE_STATIC_INITIALIZER
bool testPropertyEnabled(const SvgTextShortcutInfo &info, const QList< KoSvgTextProperties > currentProperties)
testPropertyEnabled
@ TextAlignAllId
KoSvgText::TextAlign.
@ FontStyleId
KoSvgText::CssSlantData.
@ BaselineShiftModeId
KoSvgText::BaselineShiftMode.
@ TextDecorationLineId
Flags, KoSvgText::TextDecorations.
@ KerningId
KoSvgText::AutoValue.
void setProperty(PropertyId id, const QVariant &value)
QVariant propertyOrDefault(PropertyId id) const
static bool actionEnabled(QAction *action, const QList< KoSvgTextProperties > currentProperties)
static QStringList possibleActions()
static KoSvgTextProperties getModifiedProperties(const QAction *action, QList< KoSvgTextProperties > currentProperties)
static bool configureAction(QAction *action, const QString &name)
Q_DECLARE_METATYPE(KisPaintopLodLimitations)
@ AlignCenter
Center text in line.
Definition KoSvgText.h:173
@ ShiftSuper
Use parent font metric for 'superscript'.
Definition KoSvgText.h:243
@ ShiftSub
Use parent font metric for 'subscript'.
Definition KoSvgText.h:242
TextDecoration
Flags for text-decoration, for underline, overline and strikethrough.
Definition KoSvgText.h:257
@ DecorationLineThrough
Definition KoSvgText.h:261
@ DecorationUnderline
Definition KoSvgText.h:259
CssLengthPercentage length
Definition KoSvgText.h:466
When style is oblique, a custom slant value can be specified for variable fonts.
Definition KoSvgText.h:475
CssLengthPercentage length
Definition KoSvgText.h:693
The SvgTextShortcutInfo class This is a struct that describes a text property shortcut.
static SvgTextShortcutInfo propertySet(KoSvgTextProperties::PropertyId _propertyId, QVariant _value1)
KoSvgTextProperties::PropertyId propertyId
static SvgTextShortcutInfo propertyChange(KoSvgTextProperties::PropertyId _propertyId, QVariant _value1, bool _increase)
@ Set
Will set value1, cannot be toggled.
@ Toggle
Toggle will test "testValue", and toggle between value1 and value 2;.
bool operator==(const SvgTextShortcutInfo &other) const
static SvgTextShortcutInfo propertyToggle(KoSvgTextProperties::PropertyId _propertyId, QVariant _value1, QVariant _value2, QVariant _testValue)