Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: src/ports/SkFontHost_mac.cpp

Issue 2171163002: Add test for typeface style round trip. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Name extremes, add comment. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ports/SkFontHost_FreeType.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontHost_mac.cpp
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 68668c248e8ab5a084e511df8ed108b82c06ea19..41cb52b660d29f034ed3103368957c4cc077a57b 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -370,31 +370,90 @@ private:
///////////////////////////////////////////////////////////////////////////////
-static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value) {
+static bool find_dict_CGFloat(CFDictionaryRef dict, CFStringRef name, CGFloat* value) {
CFNumberRef num;
return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
&& CFNumberIsFloatType(num)
- && CFNumberGetValue(num, kCFNumberFloatType, value);
+ && CFNumberGetValue(num, kCFNumberCGFloatType, value);
}
-static int unit_weight_to_fontstyle(float unit) {
- float value;
- if (unit < 0) {
- value = 100 + (1 + unit) * 300;
- } else {
- value = 400 + unit * 500;
+template <typename S, typename D, typename C> struct LinearInterpolater {
+ struct Mapping {
+ S src_val;
+ D dst_val;
+ };
+ constexpr LinearInterpolater(Mapping const mapping[], int mappingCount)
+ : fMapping(mapping), fMappingCount(mappingCount) {}
+
+ static D map(S value, S src_min, S src_max, D dst_min, D dst_max) {
+ SkASSERT(src_min < src_max);
+ SkASSERT(dst_min <= dst_max);
+ return C()(dst_min + (((value - src_min) * (dst_max - dst_min)) / (src_max - src_min)));
}
- return sk_float_round2int(value);
-}
-static int unit_width_to_fontstyle(float unit) {
- float value;
- if (unit < 0) {
- value = 1 + (1 + unit) * 4;
- } else {
- value = 5 + unit * 4;
+ int map(S val) const {
+ // -Inf to [0]
+ if (val < fMapping[0].src_val) {
+ return fMapping[0].dst_val;
+ }
+
+ // Linear from [i] to [i+1]
+ for (int i = 0; i < fMappingCount - 1; ++i) {
+ if (val < fMapping[i+1].src_val) {
+ return map(val, fMapping[i].src_val, fMapping[i+1].src_val,
+ fMapping[i].dst_val, fMapping[i+1].dst_val);
+ }
+ }
+
+ // From [n] to +Inf
+ // if (fcweight < Inf)
+ return fMapping[fMappingCount - 1].dst_val;
}
- return sk_float_round2int(value);
+
+ Mapping const * fMapping;
+ int fMappingCount;
+};
+
+struct RoundCGFloatToInt {
+ int operator()(CGFloat s) { return s + 0.5; }
+};
+
+static int ct_weight_to_fontstyle(CGFloat cgWeight) {
+ using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>;
+
+ // Values determined by creating font data with every weight, creating a CTFont,
+ // and asking the CTFont for its weight. See TypefaceStyle test for basics.
+
+ // Note that Mac supports the old OS2 version A so 0 through 10 are as if multiplied by 100.
+ // However, on this end we can't tell.
+ static constexpr Interpolator::Mapping weightMappings[] = {
+ { -1.00, 0 },
+ { -0.70, 100 },
+ { -0.50, 200 },
+ { -0.23, 300 },
+ { 0.00, 400 },
+ { 0.20, 500 },
+ { 0.30, 600 },
+ { 0.40, 700 },
+ { 0.60, 800 },
+ { 0.80, 900 },
+ { 1.00, 1000 },
+ };
+ static constexpr Interpolator interpolater(weightMappings, SK_ARRAY_COUNT(weightMappings));
+ return interpolater.map(cgWeight);
+}
+
+static int ct_width_to_fontstyle(CGFloat cgWidth) {
+ using Interpolator = LinearInterpolater<CGFloat, int, RoundCGFloatToInt>;
+
+ // Values determined by creating font data with every width, creating a CTFont,
+ // and asking the CTFont for its width. See TypefaceStyle test for basics.
+ static constexpr Interpolator::Mapping widthMappings[] = {
+ { -0.5, 0 },
+ { 0.5, 10 },
+ };
+ static constexpr Interpolator interpolater(widthMappings, SK_ARRAY_COUNT(widthMappings));
+ return interpolater.map(cgWidth);
}
static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) {
@@ -404,19 +463,19 @@ static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc) {
return SkFontStyle();
}
- float weight, width, slant;
- if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) {
+ CGFloat weight, width, slant;
+ if (!find_dict_CGFloat(dict, kCTFontWeightTrait, &weight)) {
weight = 0;
}
- if (!find_dict_float(dict, kCTFontWidthTrait, &width)) {
+ if (!find_dict_CGFloat(dict, kCTFontWidthTrait, &width)) {
width = 0;
}
- if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) {
+ if (!find_dict_CGFloat(dict, kCTFontSlantTrait, &slant)) {
slant = 0;
}
- return SkFontStyle(unit_weight_to_fontstyle(weight),
- unit_width_to_fontstyle(width),
+ return SkFontStyle(ct_weight_to_fontstyle(weight),
+ ct_width_to_fontstyle(width),
slant ? SkFontStyle::kItalic_Slant
: SkFontStyle::kUpright_Slant);
}
« no previous file with comments | « src/ports/SkFontHost_FreeType.cpp ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698