Krita Source Code Documentation
Loading...
Searching...
No Matches
KoFontFamily.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6#include "KoFontFamily.h"
7#include <KoMD5Generator.h>
8#include <KoSvgTextShape.h>
9#include <KoColorBackground.h>
10#include <SvgWriter.h>
11#include <QPainter>
12#include <QBuffer>
13#include <KoShapePainter.h>
14
15const QString TYPOGRAPHIC_NAME = "typographic_name";
16const QString LOCALIZED_TYPOGRAPHIC_NAME = "localized_typographic_name";
17const QString LOCALIZED_TYPOGRAPHIC_STYLE = "localized_typographic_style";
18const QString LOCALIZED_FONT_FAMILY = "localized_font_family";
19const QString AXES = "axes";
20const QString STYLES = "styles";
21const QString FONT_TYPE = "font_type";
22const QString IS_VARIABLE = "is_variable";
23const QString COLOR_BITMAP = "color_bitmap";
24const QString COLOR_CLRV0 = "color_clrv0";
25const QString COLOR_CLRV1 = "color_clrv1";
26const QString COLOR_SVG = "color_svg";
27const QString SAMPLE_STRING = "sample_string";
28const QString SAMPLE_SVG = "sample_svg";
29const QString SAMPLE_BBOX = "sample_bbox";
30const QString LAST_MODIFIED = "last_modified";
31const QString SUPPORTED_LANGUAGES = "supported_languages";
32
35
36QImage generateImage(const QString &sample, const QString &fontFamily, bool isColor) {
38 shape->setResolution(300, 300);
39 shape->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(Qt::black)));
40 KoSvgTextProperties props = shape->textProperties();
41 KoSvgText::CssLengthPercentage fontSize(12.0);
42 props.setProperty(KoSvgTextProperties::FontSizeId, QVariant::fromValue(fontSize));
44 shape->setPropertiesAtPos(-1, props);
45 shape->insertText(0, sample);
46
47 QImage img(256,
48 256,
49 isColor? QImage::Format_ARGB32: QImage::Format_Grayscale8);
50 img.fill(Qt::white);
51
52 KoShapePainter painter;
53 painter.setShapes({shape.data()});
54 painter.paint(img);
55
56 return img;
57}
58
59QString generateSVG(const QString &sample, const QString &fontFamily, QRectF &layoutBox, const QString &lang) {
61 shape->setResolution(300, 300);
62 shape->setBackground(QSharedPointer<KoColorBackground>(new KoColorBackground(Qt::black)));
63 KoSvgTextProperties props = shape->textProperties();
65 KoSvgText::CssLengthPercentage fontSize(12.0);
66 props.setProperty(KoSvgTextProperties::FontSizeId, QVariant::fromValue(fontSize));
67 if (!lang.isEmpty()) {
69 }
70 shape->setPropertiesAtPos(-1, props);
71 shape->insertText(0, sample);
72
73 layoutBox = shape->selectionBoxes(0, shape->posDown(0)).boundingRect();
74
75 SvgWriter writer({shape->textOutline()});
76 QBuffer buffer;
77 buffer.open(QIODevice::WriteOnly);
78 writer.save(buffer, shape->boundingRect().size());
79 buffer.close();
80
81 return QString::fromUtf8(buffer.data());
82}
83
84QMap<QString, QVariant> localeHashtoVariantMap(QHash<QLocale, QString> names) {
85 // Needs to be a map to be accessible in qml (see https://bugreports.qt.io/browse/QTBUG-62014)
86 QMap<QString, QVariant> newNames;
87 Q_FOREACH(const QLocale key, names.keys()) {
88 newNames.insert(key.bcp47Name(), QVariant::fromValue(names.value(key)));
89 }
90 return newNames;
91}
92
94 : KoResource(representation.fontFamilyName)
95 , d(new Private())
96
97{
98 setName(representation.fontFamilyName);
103
104 addMetaData(LAST_MODIFIED, representation.lastModified);
105
106 QMap<QString, QVariant> samples;
107 Q_FOREACH(const QString key, representation.sampleStrings.keys()) {
108 samples.insert(key, QVariant::fromValue(representation.sampleStrings.value(key)));
109 }
110 addMetaData(SAMPLE_STRING, samples);
111 QList<QVariant> supportedLanguages;
112 Q_FOREACH(const QLocale l, representation.supportedLanguages) {
113 QString val = l.bcp47Name();
114 val.replace("_", "-");
115 supportedLanguages.append(QVariant::fromValue(val));
116 }
117 addMetaData(SUPPORTED_LANGUAGES, supportedLanguages);
118
119 addMetaData(FONT_TYPE, representation.type);
120 addMetaData(IS_VARIABLE, representation.isVariable);
121 addMetaData(COLOR_BITMAP, representation.colorBitMap);
122 addMetaData(COLOR_CLRV0, representation.colorClrV0);
123 addMetaData(COLOR_CLRV1, representation.colorClrV1);
124 addMetaData(COLOR_SVG, representation.colorSVG);
125 QVariantHash axes;
126 Q_FOREACH(const QString key, representation.axes.keys()) {
127 axes.insert(key, QVariant::fromValue(representation.axes.value(key)));
128 }
130 QVariantList styles;
131 Q_FOREACH(const KoSvgText::FontFamilyStyleInfo style, representation.styles) {
132 styles.append(QVariant::fromValue(style));
133 }
135 setMD5Sum(KoMD5Generator::generateHash(representation.fontFamilyName.toUtf8()));
136 setValid(true);
137}
138
139KoFontFamily::KoFontFamily(const QString &filename)
140 :KoResource(filename)
141{
143 setValid(false);
144}
145
149
151 : KoResource(QString())
152 , d(new Private(*rhs.d))
153{
154 setFilename(rhs.filename());
155 QMap<QString, QVariant> meta = metadata();
156 Q_FOREACH(const QString key, meta.keys()) {
157 addMetaData(key, meta.value(key));
158 }
159 setValid(true);
160}
161
163{
164 return KoResourceSP(new KoFontFamily(*this));
165}
166
167bool KoFontFamily::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface)
168{
169 Q_UNUSED(dev)
170 Q_UNUSED(resourcesInterface);
171 return false;
172}
173
175{
176 return false;
177}
178
179QPair<QString, QString> KoFontFamily::resourceType() const
180{
181 return QPair<QString, QString>(ResourceType::FontFamilies, "");
182}
183
185{
186 QHash<QString, QVariant> samples = metadata().value(SAMPLE_STRING).toHash();
187 QMap<QString, QVariant> sampleSVG;
188 QMap<QString, QVariant> sampleSVGBbox;
189
190 Q_FOREACH (const QString key, samples.keys()) {
191 QString sample = samples.value(key).toString();
192 QRectF sampleBBox;
193 QString lang = key.startsWith("l_")? key.right(key.size() - 2): "";
194 sampleSVG.insert(key, QVariant::fromValue(generateSVG(sample, filename(), sampleBBox, lang)));
195 sampleSVGBbox.insert(key, QVariant::fromValue(sampleBBox));
196 }
197
198 addMetaData(SAMPLE_SVG, sampleSVG);
199 addMetaData(SAMPLE_BBOX, sampleSVGBbox);
200 const QString sample = samples.isEmpty()? "AaBbGg"
201 : samples.value("s_Latn", samples.values().first()).toString();
202 bool isColor = (metadata().value(COLOR_BITMAP).toBool() || metadata().value(COLOR_CLRV0).toBool());
203 setImage(generateImage(sample, filename(), isColor));
204}
205
207{
208 return metadata().value(TYPOGRAPHIC_NAME).toString();
209}
210
212{
213 QMap<QString, QVariant> names = metadata().value(LOCALIZED_FONT_FAMILY).toMap();
214 QString name = filename();
215 Q_FOREACH(const QString locale, locales) {
216 if (names.keys().contains(locale)) {
217 name = names.value(locale).toString();
218 break;
219 }
220 }
221 return name;
222}
223
225{
226 return metadata().value(IS_VARIABLE).toBool();
227}
228
230{
231 return metadata().value(COLOR_BITMAP).toBool();
232}
233
235{
236 return metadata().value(COLOR_CLRV0).toBool();
237}
238
240{
241 return metadata().value(COLOR_CLRV1).toBool();
242}
243
245{
246 return metadata().value(COLOR_SVG).toBool();
247}
248
250{
251 QVariantHash axes = metadata().value(AXES).toHash();
253 Q_FOREACH(const QString key, axes.keys()) {
254 converted.append(axes.value(key).value<KoSvgText::FontFamilyAxis>());
255 }
256 return converted;
257}
258
260{
261 QVariantList styles = metadata().value(STYLES).toList();
263 Q_FOREACH(const QVariant val, styles) {
264 converted.append(val.value<KoSvgText::FontFamilyStyleInfo>());
265 }
266 return converted;
267}
268
270{
271 return metadata().value(LAST_MODIFIED).toDateTime();
272}
const QString SAMPLE_SVG
QString generateSVG(const KoSvgTextShape *shape)
const QString SAMPLE_SVG
const QString SAMPLE_BBOX
const QString SUPPORTED_LANGUAGES
const QString TYPOGRAPHIC_NAME
const QString COLOR_BITMAP
const QString LOCALIZED_TYPOGRAPHIC_STYLE
const QString COLOR_SVG
const QString LOCALIZED_TYPOGRAPHIC_NAME
QString generateSVG(const QString &sample, const QString &fontFamily, QRectF &layoutBox, const QString &lang)
const QString COLOR_CLRV0
const QString IS_VARIABLE
QMap< QString, QVariant > localeHashtoVariantMap(QHash< QLocale, QString > names)
const QString FONT_TYPE
const QString AXES
const QString LOCALIZED_FONT_FAMILY
const QString STYLES
const QString LAST_MODIFIED
const QString SAMPLE_STRING
QImage generateImage(const QString &sample, const QString &fontFamily, bool isColor)
const QString COLOR_CLRV1
A simple solid color shape background.
The KoFontFamily class Abstract representation of a Weight/Width/Slant font family,...
bool isSerializable() const override
QString translatedFontName(QStringList locales) const
Return the translated name for a given locale...
QList< KoSvgText::FontFamilyAxis > axes() const
bool colorBitmap() const
Font has color bitmaps.
QString typographicFamily() const
Returns the typographic family name, if any.
QList< KoSvgText::FontFamilyStyleInfo > styles() const
KoResourceSP clone() const override
bool colorClrV0() const
Font has colrv0 layers.
bool colorClrV1() const
Font has colrv1 layers – doesn't yet work.
bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override
bool colorSVG() const
Font is SVG.
QPair< QString, QString > resourceType() const override
QDateTime lastModified() const
KoFontFamily(KoFontFamilyWWSRepresentation representation)
bool isVariable() const
Font is variable.
void updateThumbnail() override
updateThumbnail updates the thumbnail for this resource. Reimplement if your thumbnail is something e...
static QString generateHash(const QString &filename)
generateHash reads the given file and generates a hex-encoded md5sum for the file.
void setShapes(const QList< KoShape * > &shapes)
void paint(QPainter &painter)
@ TextLanguage
a language string.
void setProperty(PropertyId id, const QVariant &value)
Implements exporting shapes to SVG.
Definition SvgWriter.h:33
bool save(QIODevice &outputDevice, const QSizeF &pageSize)
Writes svg to specified output device.
Definition SvgWriter.cpp:82
QSharedPointer< KoResource > KoResourceSP
const QString FontFamilies
QList< KoSvgText::FontFamilyStyleInfo > styles
QHash< QString, KoSvgText::FontFamilyAxis > axes
KoSvgText::FontFormatType type
QDateTime lastModified
Value of the most recently modified font family. Used for updates.
QHash< QLocale, QString > localizedTypographicStyles
QList< QLocale > supportedLanguages
sample string used to generate the preview;
QHash< QString, QString > sampleStrings
QHash< QLocale, QString > localizedTypographicFamily
QHash< QLocale, QString > localizedFontFamilyNames
void setValid(bool valid)
void setName(const QString &name)
void addMetaData(QString key, QVariant value)
store the given key, value pair in the resource
void setMD5Sum(const QString &md5sum)
Set the md5sum of this resource. It must be in hex-encoded string format.
void setFilename(const QString &filename)
QString filename
void setImage(const QImage &image)
QMap< QString, QVariant > metadata
QString name