From fcec6f721d5254b9010814023f98f541ca798b02 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 19 May 2016 11:12:02 -0700 Subject: Bug 766148 - CT font weights do not map correctly to PangoWeight --- pango/pangocoretext-fontmap.c | 76 ++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'pango') diff --git a/pango/pangocoretext-fontmap.c b/pango/pangocoretext-fontmap.c index 27132c4d..0d7d793f 100644 --- a/pango/pangocoretext-fontmap.c +++ b/pango/pangocoretext-fontmap.c @@ -106,25 +106,29 @@ static PangoCoreTextFontsetKey *pango_core_text_fontset_get_key (PangoCoreTextFo typedef struct { - float bound; - PangoWeight weight; + float ct_weight; + PangoWeight pango_weight; } PangoCTWeight; -const float ct_weight_min = -1.00f; -const float ct_weight_max = 1.00f; +const float ct_weight_min = -0.7f; +const float ct_weight_max = 0.8f; -static const PangoCTWeight ct_weight_limits[] = { - { -0.00, PANGO_WEIGHT_THIN }, - { -0.75, PANGO_WEIGHT_ULTRALIGHT }, - { -0.50, PANGO_WEIGHT_LIGHT }, - { -0.25, PANGO_WEIGHT_SEMILIGHT }, - { -0.10, PANGO_WEIGHT_BOOK }, +/* This map is based on empirical data from analyzing a large collection of + * fonts and comparing the opentype value with the value that OSX returns. + * see: https://bugzilla.gnome.org/show_bug.cgi?id=766148 + */ + +static const PangoCTWeight ct_weight_map[] = { + { ct_weight_min, PANGO_WEIGHT_THIN }, + { -0.5, PANGO_WEIGHT_ULTRALIGHT }, + { -0.23, PANGO_WEIGHT_LIGHT }, + { -0.115, PANGO_WEIGHT_SEMILIGHT }, { 0.00, PANGO_WEIGHT_NORMAL }, - { 0.10, PANGO_WEIGHT_MEDIUM }, - { 0.25, PANGO_WEIGHT_SEMIBOLD }, - { 0.50, PANGO_WEIGHT_BOLD }, - { 0.75, PANGO_WEIGHT_ULTRABOLD }, - { 1.00, PANGO_WEIGHT_HEAVY } + { 0.2, PANGO_WEIGHT_MEDIUM }, + { 0.3, PANGO_WEIGHT_SEMIBOLD }, + { 0.4, PANGO_WEIGHT_BOLD }, + { 0.6, PANGO_WEIGHT_ULTRABOLD }, + { ct_weight_max, PANGO_WEIGHT_HEAVY } }; static const char * @@ -285,6 +289,13 @@ cf_font_descriptor_copy_with_traits (CTFontDescriptorRef desc, return new_desc; } +static int +lerp(float x, float x1, float x2, int y1, int y2) { + float dx = x2 - x1; + int dy = y2 - y1; + return y1 + (dy*(x-x1) + dx/2) / dx; +} + static PangoWeight ct_font_descriptor_get_weight (CTFontDescriptorRef desc) { @@ -299,25 +310,24 @@ ct_font_descriptor_get_weight (CTFontDescriptorRef desc) if (cf_number != NULL && CFNumberGetValue (cf_number, kCFNumberCGFloatType, &value)) { - if (value < ct_weight_min || value > ct_weight_max) - { - /* This is really an error */ - weight = PANGO_WEIGHT_NORMAL; - } - else - { - guint i; - for (i = 0; i < G_N_ELEMENTS(ct_weight_limits); i++) - if (value < ct_weight_limits[i].bound) - { - /* TODO interpolate weight. */ - weight = ct_weight_limits[i].weight; - break; - } - } + if (value < ct_weight_min || value > ct_weight_max) + { + /* This is really an error */ + weight = PANGO_WEIGHT_NORMAL; + } + else + { + guint i; + for (i = 1; value > ct_weight_map[i].ct_weight; ++i) + ; + + weight = lerp(value, ct_weight_map[i-1].ct_weight, ct_weight_map[i].ct_weight, + ct_weight_map[i-1].pango_weight, ct_weight_map[i].pango_weight); + + } } - else - weight = PANGO_WEIGHT_NORMAL; + else + weight = PANGO_WEIGHT_NORMAL; CFRelease (dict); -- cgit v1.2.1