Krita Source Code Documentation
Loading...
Searching...
No Matches
KoFFWWSConverter.cpp File Reference
#include "KoFFWWSConverter.h"
#include <KisForest.h>
#include <KisStaticInitializer.h>
#include <kis_assert.h>
#include <hb.h>
#include <hb-ft.h>
#include <QFileInfo>
#include <KoWritingSystemUtils.h>
#include <KoCssTextUtils.h>

Go to the source code of this file.

Classes

struct  FontFamilyNode
 
struct  FontFamilySizeInfo
 The FontFamilySizeInfo class Some font-families have different designs for different sizes. These are largely differences in weight, spacing and small glyph changes. There's four places opentype stores the design size information: More...
 
struct  KoFFWWSConverter::Private
 

Functions

KoFontFamilyWWSRepresentation createRepresentation (KisForest< FontFamilyNode >::child_iterator wws, KisForest< FontFamilyNode >::child_iterator typographic, bool singleFamily)
 
QVector< FontFamilyNodefindNodesByAxis (const QVector< FontFamilyNode > &nodes, const QString axisTag, const qreal &value, const qreal &defaultValue, const qreal &defaultValueUpper)
 
QDebug operator<< (QDebug dbg, const FontFamilyNode &node)
 
QDebug operator<< (QDebug dbg, const FontFamilySizeInfo &info)
 
KisForest< FontFamilyNode >::composition_iterator searchNodes (KisForest< FontFamilyNode >::composition_iterator it, KisForest< FontFamilyNode >::composition_iterator endIt, const QString family)
 

Variables

const QString ITALIC_TAG = "ital"
 
const QString OPTICAL_TAG = "opsz"
 
constexpr unsigned OS2_BOLD = 1u << 5
 Is italic.
 
constexpr unsigned OS2_ITALIC = 1u << 0
 
constexpr unsigned OS2_OBLIQUE = 1u << 9
 Indicates that the given font is primarily a WWS family and requires no further processing.
 
constexpr unsigned OS2_REGULAR = 1u << 6
 Is bold.
 
constexpr unsigned OS2_USE_TYPO_METRICS = 1u << 7
 
constexpr unsigned OS2_WWS = 1u << 8
 Is truly regular (instead of italic or oblique)
 
const QString SLANT_TAG = "slnt"
 
const QString WEIGHT_TAG = "wght"
 
const QString WIDTH_TAG = "wdth"
 

Function Documentation

◆ createRepresentation()

KoFontFamilyWWSRepresentation createRepresentation ( KisForest< FontFamilyNode >::child_iterator wws,
KisForest< FontFamilyNode >::child_iterator typographic,
bool singleFamily )

Definition at line 898 of file KoFFWWSConverter.cpp.

898 {
899 KoFontFamilyWWSRepresentation representation;
900 representation.fontFamilyName = wws->fontFamily;
901 representation.localizedFontFamilyNames = wws->localizedFontFamilies;
902 if (!singleFamily) {
903 // This funnels the typographic family to the resource, so that resources may potentially be sorted by their typographic family.
904 representation.typographicFamilyName = typographic->fontFamily;
905 representation.localizedTypographicFamily = typographic->localizedFontFamilies;
906 representation.localizedTypographicStyles = wws->localizedTypographicStyle;
907 }
908 representation.isVariable = wws->isVariable;
909 representation.colorBitMap = wws->colorBitMap;
910 representation.colorClrV0 = wws->colorClrV0;
911 representation.colorClrV1 = wws->colorClrV1;
912 representation.colorSVG = wws->colorSVG;
913 representation.type = wws->type;
914
915 for (auto subFamily = childBegin(wws); subFamily != childEnd(wws); subFamily++) {
917 if (subFamily == childBegin(wws)
918 || representation.lastModified < subFamily->lastModified) {
919 representation.lastModified = subFamily->lastModified;
920 }
921 representation.sampleStrings.insert(subFamily->sampleStrings);
922 Q_FOREACH(const QLocale &locale, subFamily->supportedLanguages) {
923 if (!representation.supportedLanguages.contains(locale)) {
924 representation.supportedLanguages.append(locale);
925 }
926 }
927
928 for (int a = 0; a < subFamily->axes.size(); a++) {
929 QString key = subFamily->axes.keys().at(a);
930 KoSvgText::FontFamilyAxis axis = subFamily->axes.value(key);
931 KoSvgText::FontFamilyAxis mainAxis = representation.axes.value(key);
932 mainAxis.min = qMin(mainAxis.min, axis.min);
933 mainAxis.defaultValue = axis.defaultValue;
934 mainAxis.max = qMax(mainAxis.max, axis.max);
935 mainAxis.localizedLabels.insert(axis.localizedLabels);
936 mainAxis.tag = axis.tag;
937 mainAxis.axisHidden = axis.axisHidden;
938 representation.axes.insert(mainAxis.tag, mainAxis);
939
940 if (!subFamily->isVariable) {
941 style.instanceCoords.insert(key, axis.value);
942 }
943 }
944 if (!subFamily->isVariable) {
945 if (!subFamily->localizedWWSStyle.isEmpty()) {
946 style.localizedLabels = subFamily->localizedWWSStyle;
947 } else if (!subFamily->localizedTypographicStyle.isEmpty()) {
948 style.localizedLabels = subFamily->localizedTypographicStyle;
949 } else if (!subFamily->localizedFontStyle.isEmpty()) {
950 style.localizedLabels = subFamily->localizedFontStyle;
951 } else {
952 style.localizedLabels.insert(QLocale(QLocale::English), subFamily->fontStyle);
953 }
954 style.isItalic = subFamily->isItalic;
955 style.isOblique = subFamily->isOblique;
956 representation.styles.append(style);
957 } else {
958 for (int i = 0; i < subFamily->styleInfo.size(); i++) {
959 KoSvgText::FontFamilyStyleInfo styleInfo = subFamily->styleInfo.at(i);
960 if (!styleInfo.localizedLabels.isEmpty()) {
961 styleInfo.isItalic = subFamily->isItalic;
962 styleInfo.isOblique = subFamily->isOblique;
963 representation.styles.append(styleInfo);
964 }
965 }
966 }
967 }
968 return representation;
969}
ChildIterator< value_type, is_const > childBegin(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:290
ChildIterator< value_type, is_const > childEnd(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:300
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
QHash< QLocale, QString > localizedLabels
Definition KoSvgText.h:777
QHash< QString, float > instanceCoords
Definition KoSvgText.h:816
QHash< QLocale, QString > localizedLabels
Definition KoSvgText.h:815

References KoFontFamilyWWSRepresentation::axes, KoSvgText::FontFamilyAxis::axisHidden, KoFontFamilyWWSRepresentation::colorBitMap, KoFontFamilyWWSRepresentation::colorClrV0, KoFontFamilyWWSRepresentation::colorClrV1, KoFontFamilyWWSRepresentation::colorSVG, KoSvgText::FontFamilyAxis::defaultValue, KoFontFamilyWWSRepresentation::fontFamilyName, KoSvgText::FontFamilyStyleInfo::instanceCoords, KoSvgText::FontFamilyStyleInfo::isItalic, KoSvgText::FontFamilyStyleInfo::isOblique, KoFontFamilyWWSRepresentation::isVariable, KoFontFamilyWWSRepresentation::lastModified, KoFontFamilyWWSRepresentation::localizedFontFamilyNames, KoSvgText::FontFamilyAxis::localizedLabels, KoSvgText::FontFamilyStyleInfo::localizedLabels, KoFontFamilyWWSRepresentation::localizedTypographicFamily, KoFontFamilyWWSRepresentation::localizedTypographicStyles, KoSvgText::FontFamilyAxis::max, KoSvgText::FontFamilyAxis::min, KoFontFamilyWWSRepresentation::sampleStrings, KoFontFamilyWWSRepresentation::styles, KoFontFamilyWWSRepresentation::supportedLanguages, KoSvgText::FontFamilyAxis::tag, KoFontFamilyWWSRepresentation::type, KoFontFamilyWWSRepresentation::typographicFamilyName, and KoSvgText::FontFamilyAxis::value.

◆ findNodesByAxis()

QVector< FontFamilyNode > findNodesByAxis ( const QVector< FontFamilyNode > & nodes,
const QString axisTag,
const qreal & value,
const qreal & defaultValue,
const qreal & defaultValueUpper )

Definition at line 1071 of file KoFFWWSConverter.cpp.

1071 {
1072 QVector<FontFamilyNode> candidates;
1073 QVector<qreal> values;
1074 Q_FOREACH (const FontFamilyNode &node, nodes) {
1075 qreal selectingVal = defaultValue;
1076
1077 if (node.axes.keys().contains(axisTag)) {
1078 KoSvgText::FontFamilyAxis axis = node.axes.value(axisTag);
1079 selectingVal = axis.value;
1080 if (axis.variableAxis) {
1081 if (value >= axis.min && value <= axis.max) {
1082 candidates.append(node);
1083 selectingVal = value;
1084 } else {
1085 values.append(axis.min);
1086 values.append(axis.max);
1087 }
1088 continue;
1089 }
1090 values.append(selectingVal);
1091 }
1092 }
1093 // We found some variable fonts already, so lets return early.
1094 if (!candidates.isEmpty()) {
1095 return candidates;
1096 }
1097
1098 // follow the CSS Fonts selection mechanism.
1099 bool shouldNotReturnDefault = ((axisTag == ITALIC_TAG || axisTag == SLANT_TAG) && value != defaultValue);
1100 qreal selectedValue = KoCssTextUtils::cssSelectFontStyleValue(values, value, defaultValue, defaultValueUpper, shouldNotReturnDefault);
1101
1102 Q_FOREACH (const FontFamilyNode &node, nodes) {
1103 if (node.axes.keys().contains(axisTag)) {
1104 KoSvgText::FontFamilyAxis axis = node.axes.value(axisTag);
1105 if (axis.value == selectedValue) {
1106 candidates.append(node);
1107 }
1108 } else if (value == defaultValue && !shouldNotReturnDefault) {
1109 candidates.append(node);
1110 }
1111 }
1112 return candidates;
1113}
float value(const T *src, size_t ch)
const QString SLANT_TAG
const QString ITALIC_TAG
static qreal cssSelectFontStyleValue(const QVector< qreal > &values, const qreal targetValue, const qreal defaultValue, const qreal defaultValueUpper, const bool shouldNotReturnDefault)
cssSelectFontStyleValue Select the closest font style value from the list, following the CSS Fonts se...
QHash< QString, KoSvgText::FontFamilyAxis > axes
axes While typical font-files within the same family are defined by having a single weight or width,...

References FontFamilyNode::axes, KoCssTextUtils::cssSelectFontStyleValue(), ITALIC_TAG, KoSvgText::FontFamilyAxis::max, KoSvgText::FontFamilyAxis::min, SLANT_TAG, KoSvgText::FontFamilyAxis::value, value(), and KoSvgText::FontFamilyAxis::variableAxis.

◆ operator<<() [1/2]

QDebug operator<< ( QDebug dbg,
const FontFamilyNode & node )

Definition at line 218 of file KoFFWWSConverter.cpp.

218 {
219 dbg.nospace() << node.debugInfo();
220 return dbg.space();
221}
QStringList debugInfo() const

References FontFamilyNode::debugInfo().

◆ operator<<() [2/2]

QDebug operator<< ( QDebug dbg,
const FontFamilySizeInfo & info )

Definition at line 60 of file KoFFWWSConverter.cpp.

60 {
61 dbg.nospace() << info.debugInfo();
62 return dbg.space();
63}
QString debugInfo() const

References FontFamilySizeInfo::debugInfo().

◆ searchNodes()

KisForest< FontFamilyNode >::composition_iterator searchNodes ( KisForest< FontFamilyNode >::composition_iterator it,
KisForest< FontFamilyNode >::composition_iterator endIt,
const QString family )

Definition at line 987 of file KoFFWWSConverter.cpp.

987 {
988 QString familySimplified = family;
989 QString familyLower = family.toLower();
990 // Qt's fontdatabase would add the vendor in [] behind the font name, when there were duplicates,
991 // though sometimes there was no such explanation, so we should check against that...
992 if (family.endsWith("]") && family.contains("[")) {
993 familySimplified = family.split("[", Qt::SkipEmptyParts).first().trimmed().toLower();
994 }
995 for (; it != endIt; it++) {
996 if (it.state() == KisForestDetail::Enter) {
997 continue;
998 }
999
1000 if (childBegin(it) == childEnd(it)) {
1001 // For the lowest nodes, we only want to test the full name.
1002 QStringList local = it->localizedFullName.values();
1003
1004 // For some fonts, the full name is the exact same as the typographic family name,
1005 // in which case, we want to ignore the full name.
1006 QStringList localFamily = it->localizedFontFamilies.values();
1007 bool inLocalFamilyToo = (localFamily.contains(familySimplified, Qt::CaseInsensitive)
1008 || localFamily.contains(familyLower, Qt::CaseInsensitive));
1009
1010 if (local.contains(familySimplified, Qt::CaseInsensitive)
1011 || local.contains(familyLower, Qt::CaseInsensitive)) {
1012 if (inLocalFamilyToo) continue;
1013 break;
1014 } else {
1015 continue;
1016 }
1017 }
1018
1019 QStringList local = it->localizedFontFamilies.values();
1020 QString itFamilyLower = QString(it->fontFamily).toLower();
1021 if (itFamilyLower == familySimplified
1022 || itFamilyLower == familyLower
1023 || local.contains(familySimplified, Qt::CaseInsensitive)
1024 || local.contains(familyLower, Qt::CaseInsensitive)) {
1025 break;
1026 }
1027
1028 }
1029 return it;
1030}
traversal_state state() const
Definition KisForest.h:516

References KisForestDetail::Enter, and KisForestDetail::CompositionIterator< T, is_const >::state().

Variable Documentation

◆ ITALIC_TAG

const QString ITALIC_TAG = "ital"

Definition at line 281 of file KoFFWWSConverter.cpp.

◆ OPTICAL_TAG

const QString OPTICAL_TAG = "opsz"

Definition at line 282 of file KoFFWWSConverter.cpp.

◆ OS2_BOLD

constexpr unsigned OS2_BOLD = 1u << 5
constexpr

Is italic.

Definition at line 272 of file KoFFWWSConverter.cpp.

◆ OS2_ITALIC

constexpr unsigned OS2_ITALIC = 1u << 0
constexpr

Definition at line 271 of file KoFFWWSConverter.cpp.

◆ OS2_OBLIQUE

constexpr unsigned OS2_OBLIQUE = 1u << 9
constexpr

Indicates that the given font is primarily a WWS family and requires no further processing.

Definition at line 275 of file KoFFWWSConverter.cpp.

◆ OS2_REGULAR

constexpr unsigned OS2_REGULAR = 1u << 6
constexpr

Is bold.

Definition at line 273 of file KoFFWWSConverter.cpp.

◆ OS2_USE_TYPO_METRICS

constexpr unsigned OS2_USE_TYPO_METRICS = 1u << 7
constexpr

Definition at line 276 of file KoFFWWSConverter.cpp.

◆ OS2_WWS

constexpr unsigned OS2_WWS = 1u << 8
constexpr

Is truly regular (instead of italic or oblique)

Definition at line 274 of file KoFFWWSConverter.cpp.

◆ SLANT_TAG

const QString SLANT_TAG = "slnt"

Definition at line 280 of file KoFFWWSConverter.cpp.

◆ WEIGHT_TAG

const QString WEIGHT_TAG = "wght"

Definition at line 278 of file KoFFWWSConverter.cpp.

◆ WIDTH_TAG

const QString WIDTH_TAG = "wdth"

Definition at line 279 of file KoFFWWSConverter.cpp.