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 942 of file KoFFWWSConverter.cpp.

942 {
943 KoFontFamilyWWSRepresentation representation;
944 representation.fontFamilyName = wws->fontFamily;
945 representation.localizedFontFamilyNames = wws->localizedFontFamilies;
946 if (!singleFamily) {
947 // This funnels the typographic family to the resource, so that resources may potentially be sorted by their typographic family.
948 representation.typographicFamilyName = typographic->fontFamily;
949 representation.localizedTypographicFamily = typographic->localizedFontFamilies;
950 representation.localizedTypographicStyles = wws->localizedTypographicStyle;
951 }
952 representation.isVariable = wws->isVariable;
953 representation.colorBitMap = wws->colorBitMap;
954 representation.colorClrV0 = wws->colorClrV0;
955 representation.colorClrV1 = wws->colorClrV1;
956 representation.colorSVG = wws->colorSVG;
957 representation.type = wws->type;
958
959 for (auto subFamily = childBegin(wws); subFamily != childEnd(wws); subFamily++) {
961 if (subFamily == childBegin(wws)
962 || representation.lastModified < subFamily->lastModified) {
963 representation.lastModified = subFamily->lastModified;
964 }
965 representation.sampleStrings.insert(subFamily->sampleStrings);
966 Q_FOREACH(const QLocale &locale, subFamily->supportedLanguages) {
967 if (!representation.supportedLanguages.contains(locale)) {
968 representation.supportedLanguages.append(locale);
969 }
970 }
971
972 for (int a = 0; a < subFamily->axes.size(); a++) {
973 QString key = subFamily->axes.keys().at(a);
974 KoSvgText::FontFamilyAxis axis = subFamily->axes.value(key);
975 KoSvgText::FontFamilyAxis mainAxis = representation.axes.value(key);
976 mainAxis.min = qMin(mainAxis.min, axis.min);
977 mainAxis.defaultValue = axis.defaultValue;
978 mainAxis.max = qMax(mainAxis.max, axis.max);
979 mainAxis.localizedLabels.insert(axis.localizedLabels);
980 mainAxis.tag = axis.tag;
981 mainAxis.axisHidden = axis.axisHidden;
982 representation.axes.insert(mainAxis.tag, mainAxis);
983
984 if (!subFamily->isVariable) {
985 style.instanceCoords.insert(key, axis.value);
986 }
987 }
988 if (!subFamily->isVariable) {
989 if (!subFamily->localizedWWSStyle.isEmpty()) {
990 style.localizedLabels = subFamily->localizedWWSStyle;
991 } else if (!subFamily->localizedTypographicStyle.isEmpty()) {
992 style.localizedLabels = subFamily->localizedTypographicStyle;
993 } else if (!subFamily->localizedFontStyle.isEmpty()) {
994 style.localizedLabels = subFamily->localizedFontStyle;
995 } else {
996 style.localizedLabels.insert(QLocale(QLocale::English), subFamily->fontStyle);
997 }
998 style.isItalic = subFamily->isItalic;
999 style.isOblique = subFamily->isOblique;
1000 representation.styles.append(style);
1001 } else {
1002 for (int i = 0; i < subFamily->styleInfo.size(); i++) {
1003 KoSvgText::FontFamilyStyleInfo styleInfo = subFamily->styleInfo.at(i);
1004 if (!styleInfo.localizedLabels.isEmpty()) {
1005 styleInfo.isItalic = subFamily->isItalic;
1006 styleInfo.isOblique = subFamily->isOblique;
1007 representation.styles.append(styleInfo);
1008 }
1009 }
1010 }
1011 }
1012 return representation;
1013}
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 1115 of file KoFFWWSConverter.cpp.

1115 {
1116 QVector<FontFamilyNode> candidates;
1117 QVector<qreal> values;
1118 Q_FOREACH (const FontFamilyNode &node, nodes) {
1119 qreal selectingVal = defaultValue;
1120
1121 if (node.axes.keys().contains(axisTag)) {
1122 KoSvgText::FontFamilyAxis axis = node.axes.value(axisTag);
1123 selectingVal = axis.value;
1124 if (axis.variableAxis) {
1125 if (value >= axis.min && value <= axis.max) {
1126 candidates.append(node);
1127 selectingVal = value;
1128 } else {
1129 values.append(axis.min);
1130 values.append(axis.max);
1131 }
1132 continue;
1133 }
1134 values.append(selectingVal);
1135 }
1136 }
1137 // We found some variable fonts already, so lets return early.
1138 if (!candidates.isEmpty()) {
1139 return candidates;
1140 }
1141
1142 // follow the CSS Fonts selection mechanism.
1143 bool shouldNotReturnDefault = ((axisTag == ITALIC_TAG || axisTag == SLANT_TAG) && value != defaultValue);
1144 qreal selectedValue = KoCssTextUtils::cssSelectFontStyleValue(values, value, defaultValue, defaultValueUpper, shouldNotReturnDefault);
1145
1146 Q_FOREACH (const FontFamilyNode &node, nodes) {
1147 if (node.axes.keys().contains(axisTag)) {
1148 KoSvgText::FontFamilyAxis axis = node.axes.value(axisTag);
1149 if (axis.value == selectedValue) {
1150 candidates.append(node);
1151 }
1152 } else if (value == defaultValue && !shouldNotReturnDefault) {
1153 candidates.append(node);
1154 }
1155 }
1156 return candidates;
1157}
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 1031 of file KoFFWWSConverter.cpp.

1031 {
1032 QString familySimplified = family;
1033 QString familyLower = family.toLower();
1034 // Qt's fontdatabase would add the vendor in [] behind the font name, when there were duplicates,
1035 // though sometimes there was no such explanation, so we should check against that...
1036 if (family.endsWith("]") && family.contains("[")) {
1037 familySimplified = family.split("[", Qt::SkipEmptyParts).first().trimmed().toLower();
1038 }
1039 for (; it != endIt; it++) {
1040 if (it.state() == KisForestDetail::Enter) {
1041 continue;
1042 }
1043
1044 if (childBegin(it) == childEnd(it)) {
1045 // For the lowest nodes, we only want to test the full name.
1046 QStringList local = it->localizedFullName.values();
1047
1048 // For some fonts, the full name is the exact same as the typographic family name,
1049 // in which case, we want to ignore the full name.
1050 QStringList localFamily = it->localizedFontFamilies.values();
1051 bool inLocalFamilyToo = (localFamily.contains(familySimplified, Qt::CaseInsensitive)
1052 || localFamily.contains(familyLower, Qt::CaseInsensitive));
1053
1054 if (local.contains(familySimplified, Qt::CaseInsensitive)
1055 || local.contains(familyLower, Qt::CaseInsensitive)) {
1056 if (inLocalFamilyToo) continue;
1057 break;
1058 } else {
1059 continue;
1060 }
1061 }
1062
1063 QStringList local = it->localizedFontFamilies.values();
1064 QString itFamilyLower = QString(it->fontFamily).toLower();
1065 if (itFamilyLower == familySimplified
1066 || itFamilyLower == familyLower
1067 || local.contains(familySimplified, Qt::CaseInsensitive)
1068 || local.contains(familyLower, Qt::CaseInsensitive)) {
1069 break;
1070 }
1071
1072 }
1073 return it;
1074}
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.