Chromium Code Reviews| Index: src/ports/SkFontConfigInterface_direct.cpp |
| diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp |
| index f5f494986bab87dcdd5e73b833a03ca54189d09d..53ff470c80eabf04373f1d2852a05f71bfdd2143 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,144 @@ 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); |
| +} |
| + |
| +static int ave(SkFixed a, SkFixed b) { |
| + return SkFixedAve(a, b); |
| +} |
| + |
| +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 ave([i], [i+1]), then from ave([i], [i+1]) to [i+1] |
| + for (int i = 0; i < rangesCount - 1; ++i) { |
| + if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) { |
|
dogben
2016/04/11 20:28:58
I think you would get the same result if you just
bungeman-skia
2016/04/11 21:55:52
This was all copy-pasted from somewhere else, but
|
| + return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, ranges[i+1].old_val), |
| + ranges[i].new_val, ave(ranges[i].new_val, ranges[i+1].new_val)); |
| + } |
| + if (val < ranges[i+1].old_val) { |
| + return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), ranges[i+1].old_val, |
| + ave(ranges[i].new_val, ranges[i+1].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 +557,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 +582,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); |