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

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

1032 {
1033 QString familySimplified;
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();
1038 }
1039
1040 auto presentInLocalizedNames = [&familySimplified, &family](const QHash<QLocale, QString> &localizedFontFamilies) {
1041 auto matchingLocalizedFamilyIt = std::find_if(
1042 localizedFontFamilies.begin(),
1043 localizedFontFamilies.end(),
1044 [&](const QString &localizedFamily) {
1045 return localizedFamily.contains(family, Qt::CaseInsensitive)
1046 || (!familySimplified.isEmpty() && localizedFamily.contains(familySimplified, Qt::CaseInsensitive));
1047 });
1048
1049 return matchingLocalizedFamilyIt != localizedFontFamilies.end();
1050 };
1051
1052 for (; it != endIt; it++) {
1053 if (it.state() == KisForestDetail::Enter) {
1054 continue;
1055 }
1056
1057 if (childBegin(it) == childEnd(it)) {
1058 if (
1059 // For the lowest nodes, we only want to test the full name.
1060 presentInLocalizedNames(it->localizedFullName)
1061
1062 // For some fonts, the full name is the exact same as the typographic family name,
1063 // in which case, we want to ignore the full name.
1064 || presentInLocalizedNames(it->localizedFontFamilies)) {
1065
1066 break;
1067 } else {
1068 continue;
1069 }
1070 }
1071
1072 if (it->fontFamily.compare(family, Qt::CaseInsensitive) == 0
1073 || (!familySimplified.isEmpty() && it->fontFamily.compare(familySimplified, Qt::CaseInsensitive) == 0)
1074 || presentInLocalizedNames(it->localizedFontFamilies)) {
1075 break;
1076 }
1077 }
1078 return it;
1079}
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.