aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports/SkFontConfigInterface_direct.cpp
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2016-04-12 13:45:06 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-12 13:45:06 -0700
commit11a77c6e0634e2feb6fe4e74806db2fdd2a799ec (patch)
treed62d216858bbe136c4b41b9ec563ea35bd7ff1ed /src/ports/SkFontConfigInterface_direct.cpp
parent0586f5cc9713268238394411a5daa2c7758b092b (diff)
Begin switch to SkFontStyle for legacy calls.
This adds SK_VERY_LEGACY_CREATE_TYPEFACE which, when defined, provides only the old interface. Ideally, everyone would switch directly to SkFontMgr and use one of the newer calls, but there is currently no path for current users to get there. This updates all the internals to use SkFontStyle, after switching these over the higher level APIs can be switched. The Chromium follow on patch can be seen at https://crrev.com/1877673002 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1873923002 TBR=reed This doesn't really change API, just modernizes it. Review URL: https://codereview.chromium.org/1873923002
Diffstat (limited to 'src/ports/SkFontConfigInterface_direct.cpp')
-rw-r--r--src/ports/SkFontConfigInterface_direct.cpp145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index f5f494986b..1c42e2d37e 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -9,6 +9,7 @@
#include "SkBuffer.h"
#include "SkDataTable.h"
+#include "SkFixed.h"
#include "SkFontConfigInterface_direct.h"
#include "SkFontStyle.h"
#include "SkMutex.h"
@@ -304,6 +305,7 @@ bool IsFallbackFontAllowed(const SkString& family) {
}
// Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|.
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
SkTypeface::Style GetFontStyle(FcPattern* font) {
int resulting_bold;
if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold))
@@ -335,6 +337,136 @@ SkTypeface::Style GetFontStyle(FcPattern* font) {
return (SkTypeface::Style)styleBits;
}
+#else
+
+static int get_int(FcPattern* pattern, const char object[], int missing) {
+ int value;
+ if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
+ return missing;
+ }
+ return value;
+}
+
+static int map_range(SkFixed value,
+ SkFixed old_min, SkFixed old_max,
+ SkFixed new_min, SkFixed new_max)
+{
+ SkASSERT(old_min < old_max);
+ SkASSERT(new_min <= new_max);
+ return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
+}
+
+struct MapRanges {
+ SkFixed old_val;
+ SkFixed new_val;
+};
+
+static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) {
+ // -Inf to [0]
+ if (val < ranges[0].old_val) {
+ return ranges[0].new_val;
+ }
+
+ // Linear from [i] to [i+1]
+ for (int i = 0; i < rangesCount - 1; ++i) {
+ if (val < ranges[i+1].old_val) {
+ return map_range(val, ranges[i].old_val, ranges[i+1].old_val,
+ ranges[i].new_val, ranges[i+1].new_val);
+ }
+ }
+
+ // From [n] to +Inf
+ // if (fcweight < Inf)
+ return ranges[rangesCount-1].new_val;
+}
+
+static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
+ return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount));
+}
+
+template<int n> struct SkTFixed {
+ static_assert(-32768 <= n && n <= 32767, "SkTFixed_n_not_in_range");
+ static const SkFixed value = static_cast<SkFixed>(n << 16);
+};
+
+static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
+ typedef SkFontStyle SkFS;
+
+ static const MapRanges weightRanges[] = {
+ { SkTFixed<FC_WEIGHT_THIN>::value, SkTFixed<SkFS::kThin_Weight>::value },
+ { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value },
+ { SkTFixed<FC_WEIGHT_LIGHT>::value, SkTFixed<SkFS::kLight_Weight>::value },
+ { SkTFixed<FC_WEIGHT_REGULAR>::value, SkTFixed<SkFS::kNormal_Weight>::value },
+ { SkTFixed<FC_WEIGHT_MEDIUM>::value, SkTFixed<SkFS::kMedium_Weight>::value },
+ { SkTFixed<FC_WEIGHT_DEMIBOLD>::value, SkTFixed<SkFS::kSemiBold_Weight>::value },
+ { SkTFixed<FC_WEIGHT_BOLD>::value, SkTFixed<SkFS::kBold_Weight>::value },
+ { SkTFixed<FC_WEIGHT_EXTRABOLD>::value, SkTFixed<SkFS::kExtraBold_Weight>::value },
+ { SkTFixed<FC_WEIGHT_BLACK>::value, SkTFixed<SkFS::kBlack_Weight>::value },
+ { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value },
+ };
+ int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
+ weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+ static const MapRanges widthRanges[] = {
+ { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value },
+ { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value },
+ { SkTFixed<FC_WIDTH_CONDENSED>::value, SkTFixed<SkFS::kCondensed_Width>::value },
+ { SkTFixed<FC_WIDTH_SEMICONDENSED>::value, SkTFixed<SkFS::kSemiCondensed_Width>::value },
+ { SkTFixed<FC_WIDTH_NORMAL>::value, SkTFixed<SkFS::kNormal_Width>::value },
+ { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value, SkTFixed<SkFS::kSemiExpanded_Width>::value },
+ { SkTFixed<FC_WIDTH_EXPANDED>::value, SkTFixed<SkFS::kExpanded_Width>::value },
+ { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value, SkTFixed<SkFS::kExtraExpanded_Width>::value },
+ { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value, SkTFixed<SkFS::kUltaExpanded_Width>::value },
+ };
+ int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
+ widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+ SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0
+ ? SkFS::kItalic_Slant
+ : SkFS::kUpright_Slant;
+
+ return SkFontStyle(weight, width, slant);
+}
+
+static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
+ typedef SkFontStyle SkFS;
+
+ static const MapRanges weightRanges[] = {
+ { SkTFixed<SkFS::kThin_Weight>::value, SkTFixed<FC_WEIGHT_THIN>::value },
+ { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value },
+ { SkTFixed<SkFS::kLight_Weight>::value, SkTFixed<FC_WEIGHT_LIGHT>::value },
+ { SkTFixed<SkFS::kNormal_Weight>::value, SkTFixed<FC_WEIGHT_REGULAR>::value },
+ { SkTFixed<SkFS::kMedium_Weight>::value, SkTFixed<FC_WEIGHT_MEDIUM>::value },
+ { SkTFixed<SkFS::kSemiBold_Weight>::value, SkTFixed<FC_WEIGHT_DEMIBOLD>::value },
+ { SkTFixed<SkFS::kBold_Weight>::value, SkTFixed<FC_WEIGHT_BOLD>::value },
+ { SkTFixed<SkFS::kExtraBold_Weight>::value, SkTFixed<FC_WEIGHT_EXTRABOLD>::value },
+ { SkTFixed<SkFS::kBlack_Weight>::value, SkTFixed<FC_WEIGHT_BLACK>::value },
+ { SkTFixed<1000>::value, SkTFixed<FC_WEIGHT_EXTRABLACK>::value },
+ };
+ int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+ static const MapRanges widthRanges[] = {
+ { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value },
+ { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value },
+ { SkTFixed<SkFS::kCondensed_Width>::value, SkTFixed<FC_WIDTH_CONDENSED>::value },
+ { SkTFixed<SkFS::kSemiCondensed_Width>::value, SkTFixed<FC_WIDTH_SEMICONDENSED>::value },
+ { SkTFixed<SkFS::kNormal_Width>::value, SkTFixed<FC_WIDTH_NORMAL>::value },
+ { SkTFixed<SkFS::kSemiExpanded_Width>::value, SkTFixed<FC_WIDTH_SEMIEXPANDED>::value },
+ { SkTFixed<SkFS::kExpanded_Width>::value, SkTFixed<FC_WIDTH_EXPANDED>::value },
+ { SkTFixed<SkFS::kExtraExpanded_Width>::value, SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value },
+ { SkTFixed<SkFS::kUltaExpanded_Width>::value, SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value },
+ };
+ int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+ FcPatternAddInteger(pattern, FC_WEIGHT, weight);
+ FcPatternAddInteger(pattern, FC_WIDTH, width);
+ FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+}
+
+SkFontStyle GetFontStyle(FcPattern* font) {
+ return skfontstyle_from_fcpattern(font);
+}
+#endif
} // anonymous namespace
@@ -417,11 +549,19 @@ FcPattern* SkFontConfigInterfaceDirect::MatchFont(FcFontSet* font_set,
return match;
}
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
SkTypeface::Style style,
FontIdentity* outIdentity,
SkString* outFamilyName,
SkTypeface::Style* outStyle) {
+#else
+bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
+ SkFontStyle style,
+ FontIdentity* outIdentity,
+ SkString* outFamilyName,
+ SkFontStyle* outStyle) {
+#endif
SkString familyStr(familyName ? familyName : "");
if (familyStr.size() > kMaxFontFamilyLength) {
return false;
@@ -434,12 +574,17 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
if (familyName) {
FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
}
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
FcPatternAddInteger(pattern, FC_WEIGHT,
(style & SkTypeface::kBold) ? FC_WEIGHT_BOLD
: FC_WEIGHT_NORMAL);
FcPatternAddInteger(pattern, FC_SLANT,
(style & SkTypeface::kItalic) ? FC_SLANT_ITALIC
: FC_SLANT_ROMAN);
+#else
+ fcpattern_from_skfontstyle(style, pattern);
+#endif
+
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(nullptr, pattern, FcMatchPattern);