Add oblique as a slant.

Some fonts have italic and oblique in the same family, see

http://lucidafonts.com/fonts/family/lucida-sans
http://www.gust.org.pl/projects/e-foundry/latin-modern

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1921903002

Chromium side change at https://crrev.com/1921503006/ .

Review-Url: https://codereview.chromium.org/1921903002
diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp
index eba2b28..ebb9a89 100644
--- a/src/core/SkFontMgr.cpp
+++ b/src/core/SkFontMgr.cpp
@@ -211,6 +211,9 @@
     struct Score {
         int score;
         int index;
+        Score& operator +=(int rhs) { this->score += rhs; return *this; }
+        Score& operator <<=(int rhs) { this->score <<= rhs; return *this; }
+        bool operator <(const Score& that) { return this->score < that.score; }
     };
 
     Score maxScore = { 0, 0 };
@@ -219,58 +222,70 @@
         this->getStyle(i, &current, nullptr);
         Score currentScore = { 0, i };
 
-        // CSS stretch. (This is the width.)
-        // This has the highest priority.
+        // CSS stretch / SkFontStyle::Width
+        // Takes priority over everything else.
         if (pattern.width() <= SkFontStyle::kNormal_Width) {
             if (current.width() <= pattern.width()) {
-                currentScore.score += 10 - pattern.width() + current.width();
+                currentScore += 10 - pattern.width() + current.width();
             } else {
-                currentScore.score += 10 - current.width();
+                currentScore += 10 - current.width();
             }
         } else {
             if (current.width() > pattern.width()) {
-                currentScore.score += 10 + pattern.width() - current.width();
+                currentScore += 10 + pattern.width() - current.width();
             } else {
-                currentScore.score += current.width();
+                currentScore += current.width();
             }
         }
-        currentScore.score *= 1002;
+        currentScore <<= 8;
 
-        // CSS style (italic/oblique)
-        // Being italic trumps all valid weights which are not italic.
-        // Note that newer specs differentiate between italic and oblique.
-        if (pattern.isItalic() == current.isItalic()) {
-            currentScore.score += 1001;
-        }
+        // CSS style (normal, italic, oblique) / SkFontStyle::Slant (upright, italic, oblique)
+        // Takes priority over all valid weights.
+        static_assert(SkFontStyle::kUpright_Slant == 0 &&
+                      SkFontStyle::kItalic_Slant  == 1 &&
+                      SkFontStyle::kOblique_Slant == 2,
+                      "SkFontStyle::Slant values not as required.");
+        SkASSERT(0 <= pattern.slant() && pattern.slant() <= 2 &&
+                 0 <= current.slant() && current.slant() <= 2);
+        static const int score[3][3] = {
+            /*               Upright Italic Oblique  [current]*/
+            /*   Upright */ {   3   ,  1   ,   2   },
+            /*   Italic  */ {   1   ,  3   ,   2   },
+            /*   Oblique */ {   1   ,  2   ,   3   },
+            /* [pattern] */
+        };
+        currentScore += score[pattern.slant()][current.slant()];
+        currentScore <<= 8;
 
-        // Synthetics (weight/style) [no stretch synthetic?]
+        // Synthetics (weight, style) [no stretch synthetic?]
 
+        // CSS weight / SkFontStyle::Weight
         // The 'closer' to the target weight, the higher the score.
         // 1000 is the 'heaviest' recognized weight
         if (pattern.weight() == current.weight()) {
-            currentScore.score += 1000;
+            currentScore += 1000;
         } else if (pattern.weight() <= 500) {
             if (400 <= pattern.weight() && pattern.weight() < 450) {
                 if (450 <= current.weight() && current.weight() <= 500) {
                     // Artificially boost the 500 weight.
                     // TODO: determine correct number to use.
-                    currentScore.score += 500;
+                    currentScore += 500;
                 }
             }
             if (current.weight() <= pattern.weight()) {
-                currentScore.score += 1000 - pattern.weight() + current.weight();
+                currentScore += 1000 - pattern.weight() + current.weight();
             } else {
-                currentScore.score += 1000 - current.weight();
+                currentScore += 1000 - current.weight();
             }
         } else if (pattern.weight() > 500) {
             if (current.weight() > pattern.weight()) {
-                currentScore.score += 1000 + pattern.weight() - current.weight();
+                currentScore += 1000 + pattern.weight() - current.weight();
             } else {
-                currentScore.score += current.weight();
+                currentScore += current.weight();
             }
         }
 
-        if (currentScore.score > maxScore.score) {
+        if (maxScore < currentScore) {
             maxScore = currentScore;
         }
     }
diff --git a/src/core/SkFontStyle.cpp b/src/core/SkFontStyle.cpp
index c28e721..01628ae 100644
--- a/src/core/SkFontStyle.cpp
+++ b/src/core/SkFontStyle.cpp
@@ -20,7 +20,7 @@
     fUnion.fU32 = 0;
     fUnion.fR.fWeight = SkTPin<int>(weight, kThin_Weight, kBlack_Weight);
     fUnion.fR.fWidth = SkTPin<int>(width, kUltraCondensed_Width, kUltaExpanded_Width);
-    fUnion.fR.fSlant = SkTPin<int>(slant, kUpright_Slant, kItalic_Slant);
+    fUnion.fR.fSlant = SkTPin<int>(slant, kUpright_Slant, kOblique_Slant);
 }
 
 /*static*/SkFontStyle SkFontStyle::FromOldStyle(unsigned oldStyle) {
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 855ef90..d768efc 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -138,14 +138,7 @@
     }
 
     SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
-    bool bold = s & SkTypeface::kBold;
-    bool italic = s & SkTypeface::kItalic;
-    SkFontStyle newStyle = SkFontStyle(bold ? SkFontStyle::kBold_Weight
-                                            : SkFontStyle::kNormal_Weight,
-                                       SkFontStyle::kNormal_Width,
-                                       italic ? SkFontStyle::kItalic_Slant
-                                              : SkFontStyle::kUpright_Slant);
-    return fm->matchFaceStyle(family, newStyle);
+    return fm->matchFaceStyle(family, SkFontStyle::FromOldStyle(s));
 }
 
 SkTypeface* SkTypeface::CreateFromStream(SkStreamAsset* stream, int index) {
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index fedd3dc..9051170 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -168,14 +168,19 @@
 static SkFontStyle make_fontconfig_style(FcPattern* match) {
     int weight = get_int(match, FC_WEIGHT);
     int width = get_int(match, FC_WIDTH);
-    int slant = get_int(match, FC_SLANT);
-//    SkDebugf("old weight %d new weight %d\n", weight, map_range(weight, 0, 80, 0, 400));
+    int fcSlant = get_int(match, FC_SLANT);
 
     // fontconfig weight seems to be 0..200 or so, so we remap it here
     weight = map_range(weight, 0, 80, 0, 400);
     width = map_range(width, 0, 200, 0, 9);
-    return SkFontStyle(weight, width, slant > 0 ? SkFontStyle::kItalic_Slant
-                                                : SkFontStyle::kUpright_Slant);
+    SkFontStyle::Slant skSlant = SkFontStyle::kUpright_Slant;
+    switch (fcSlant) {
+        case FC_SLANT_ROMAN:   skSlant = SkFontStyle::kUpright_Slant; break;
+        case FC_SLANT_ITALIC : skSlant = SkFontStyle::kItalic_Slant ; break;
+        case FC_SLANT_OBLIQUE: skSlant = SkFontStyle::kOblique_Slant; break;
+        default: SkASSERT(false); break;
+    }
+    return SkFontStyle(weight, width, skSlant);
 }
 
 SkFontStyleSet_FC::SkFontStyleSet_FC(FcPattern** matches, int count) {
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index cc80fbe..d384f70 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -387,9 +387,13 @@
     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;
+    SkFS::Slant slant = SkFS::kUpright_Slant;
+    switch (get_int(pattern, FC_SLANT, FC_SLANT_ROMAN)) {
+        case FC_SLANT_ROMAN:   slant = SkFS::kUpright_Slant; break;
+        case FC_SLANT_ITALIC : slant = SkFS::kItalic_Slant ; break;
+        case FC_SLANT_OBLIQUE: slant = SkFS::kOblique_Slant; break;
+        default: SkASSERT(false); break;
+    }
 
     return SkFontStyle(weight, width, slant);
 }
@@ -424,9 +428,17 @@
     };
     int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
 
+    int slant = FC_SLANT_ROMAN;
+    switch (style.slant()) {
+        case SkFS::kUpright_Slant: slant = FC_SLANT_ROMAN  ; break;
+        case SkFS::kItalic_Slant : slant = FC_SLANT_ITALIC ; break;
+        case SkFS::kOblique_Slant: slant = FC_SLANT_OBLIQUE; break;
+        default: SkASSERT(false); break;
+    }
+
     FcPatternAddInteger(pattern, FC_WEIGHT, weight);
-    FcPatternAddInteger(pattern, FC_WIDTH, width);
-    FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+    FcPatternAddInteger(pattern, FC_WIDTH , width);
+    FcPatternAddInteger(pattern, FC_SLANT , slant);
 }
 
 }  // anonymous namespace
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 3b1a5b2..82648c3 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -1696,6 +1696,11 @@
     if (os2 && os2->version != 0xffff) {
         weight = os2->usWeightClass;
         width = os2->usWidthClass;
+
+        // OS/2::fsSelection bit 9 indicates oblique.
+        if (SkToBool(os2->fsSelection & (1u << 9))) {
+            slant = SkFontStyle::kOblique_Slant;
+        }
     } else if (0 == FT_Get_PS_Font_Info(face, &psFontInfo) && psFontInfo.weight) {
         static const struct {
             char const * const name;
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 02c5464..72d4690 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -417,7 +417,7 @@
     return SkFontStyle(unit_weight_to_fontstyle(weight),
                        unit_width_to_fontstyle(width),
                        slant ? SkFontStyle::kItalic_Slant
-                       : SkFontStyle::kUpright_Slant);
+                             : SkFontStyle::kUpright_Slant);
 }
 
 #define WEIGHT_THRESHOLD    ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_Weight)/2)
@@ -2151,7 +2151,7 @@
 static int compute_metric(const SkFontStyle& a, const SkFontStyle& b) {
     return sqr(a.weight() - b.weight()) +
            sqr((a.width() - b.width()) * 100) +
-           sqr((a.isItalic() != b.isItalic()) * 900);
+           sqr((a.slant() != b.slant()) * 900);
 }
 
 static SkTypeface* createFromDesc(CTFontDescriptorRef desc) {
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 5ded39c..db90915 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -2508,7 +2508,7 @@
         }
 
         lf.lfWeight = style.weight();
-        lf.lfItalic = style.isItalic() ? TRUE : FALSE;
+        lf.lfItalic = style.slant() == SkFontStyle::kUpright_Slant ? FALSE : TRUE;
         return SkCreateTypefaceFromLOGFONT(lf);
     }
 
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index ed5a4d5..4aea047 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -257,7 +257,7 @@
     static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
         int score = 0;
         score += SkTAbs((pattern.width() - candidate.width()) * 100);
-        score += SkTAbs((pattern.isItalic() == candidate.isItalic()) ? 0 : 1000);
+        score += SkTAbs((pattern.slant() == candidate.slant()) ? 0 : 1000);
         score += SkTAbs(pattern.weight() - candidate.weight());
         return score;
     }
diff --git a/src/ports/SkFontMgr_custom.cpp b/src/ports/SkFontMgr_custom.cpp
index 20d6f78..6401d55 100644
--- a/src/ports/SkFontMgr_custom.cpp
+++ b/src/ports/SkFontMgr_custom.cpp
@@ -149,7 +149,7 @@
     static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) {
         int score = 0;
         score += (pattern.width() - candidate.width()) * 100;
-        score += (pattern.isItalic() == candidate.isItalic()) ? 0 : 1000;
+        score += (pattern.slant() == candidate.slant()) ? 0 : 1000;
         score += pattern.weight() - candidate.weight();
         return score;
     }
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index 4b26f41..610a300 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -345,9 +345,13 @@
     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;
+    SkFS::Slant slant = SkFS::kUpright_Slant;
+    switch (get_int(pattern, FC_SLANT, FC_SLANT_ROMAN)) {
+        case FC_SLANT_ROMAN:   slant = SkFS::kUpright_Slant; break;
+        case FC_SLANT_ITALIC : slant = SkFS::kItalic_Slant ; break;
+        case FC_SLANT_OBLIQUE: slant = SkFS::kOblique_Slant; break;
+        default: SkASSERT(false); break;
+    }
 
     return SkFontStyle(weight, width, slant);
 }
@@ -384,9 +388,17 @@
     };
     int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
 
+    int slant = FC_SLANT_ROMAN;
+    switch (style.slant()) {
+        case SkFS::kUpright_Slant: slant = FC_SLANT_ROMAN  ; break;
+        case SkFS::kItalic_Slant : slant = FC_SLANT_ITALIC ; break;
+        case SkFS::kOblique_Slant: slant = FC_SLANT_OBLIQUE; break;
+        default: SkASSERT(false); break;
+    }
+
     FcPatternAddInteger(pattern, FC_WEIGHT, weight);
-    FcPatternAddInteger(pattern, FC_WIDTH, width);
-    FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+    FcPatternAddInteger(pattern, FC_WIDTH , width);
+    FcPatternAddInteger(pattern, FC_SLANT , slant);
 }
 
 class SkTypeface_stream : public SkTypeface_FreeType {
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
index fc86bad..e6e52d9 100644
--- a/src/ports/SkFontMgr_win_dw.cpp
+++ b/src/ports/SkFontMgr_win_dw.cpp
@@ -984,11 +984,8 @@
     }
 
     SkTScopedComPtr<IDWriteFont> font;
-    DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)style.weight();
-    DWRITE_FONT_STRETCH stretch = (DWRITE_FONT_STRETCH)style.width();
-    DWRITE_FONT_STYLE italic = style.isItalic() ? DWRITE_FONT_STYLE_ITALIC
-                                                : DWRITE_FONT_STYLE_NORMAL;
-    HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font),
+    DWriteStyle dwStyle(style);
+    HRNM(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWidth, dwStyle.fSlant, &font),
          "Could not get matching font.");
 
     SkTScopedComPtr<IDWriteFontFace> fontFace;
@@ -1018,23 +1015,7 @@
     HRVM(fFontFamily->GetFont(index, &font), "Could not get font.");
 
     if (fs) {
-        SkFontStyle::Slant slant;
-        switch (font->GetStyle()) {
-        case DWRITE_FONT_STYLE_NORMAL:
-            slant = SkFontStyle::kUpright_Slant;
-            break;
-        case DWRITE_FONT_STYLE_OBLIQUE:
-        case DWRITE_FONT_STYLE_ITALIC:
-            slant = SkFontStyle::kItalic_Slant;
-            break;
-        default:
-            SkASSERT(false);
-        }
-
-        int weight = font->GetWeight();
-        int width = font->GetStretch();
-
-        *fs = SkFontStyle(weight, width, slant);
+        *fs = get_style(font.get());
     }
 
     if (styleName) {
@@ -1046,24 +1027,10 @@
 }
 
 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) {
-    DWRITE_FONT_STYLE slant;
-    switch (pattern.slant()) {
-    case SkFontStyle::kUpright_Slant:
-        slant = DWRITE_FONT_STYLE_NORMAL;
-        break;
-    case SkFontStyle::kItalic_Slant:
-        slant = DWRITE_FONT_STYLE_ITALIC;
-        break;
-    default:
-        SkASSERT(false);
-    }
-
-    DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
-    DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
-
     SkTScopedComPtr<IDWriteFont> font;
+    DWriteStyle dwStyle(pattern);
     // TODO: perhaps use GetMatchingFonts and get the least simulated?
-    HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
+    HRNM(fFontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWidth, dwStyle.fSlant, &font),
          "Could not match font in family.");
 
     SkTScopedComPtr<IDWriteFontFace> fontFace;
diff --git a/src/ports/SkRemotableFontMgr_win_dw.cpp b/src/ports/SkRemotableFontMgr_win_dw.cpp
index cdf186c..ea5562c 100644
--- a/src/ports/SkRemotableFontMgr_win_dw.cpp
+++ b/src/ports/SkRemotableFontMgr_win_dw.cpp
@@ -17,7 +17,7 @@
 #include "SkString.h"
 #include "SkTArray.h"
 #include "SkTScopedComPtr.h"
-#include "SkTypeface_win.h"
+#include "SkTypeface_win_dw.h"
 #include "SkTypes.h"
 #include "SkUtils.h"
 
@@ -137,23 +137,7 @@
         fontId->fTtcIndex = fontFace->GetIndex();
 
         // style
-        SkFontStyle::Slant slant;
-        switch (font->GetStyle()) {
-        case DWRITE_FONT_STYLE_NORMAL:
-            slant = SkFontStyle::kUpright_Slant;
-            break;
-        case DWRITE_FONT_STYLE_OBLIQUE:
-        case DWRITE_FONT_STYLE_ITALIC:
-            slant = SkFontStyle::kItalic_Slant;
-            break;
-        default:
-            SkASSERT(false);
-        }
-
-        int weight = font->GetWeight();
-        int width = font->GetStretch();
-
-        fontId->fFontStyle = SkFontStyle(weight, width, slant);
+        fontId->fFontStyle = get_style(font);
         return S_OK;
     }
 
diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h
index b1237c0..3e429f4 100644
--- a/src/ports/SkTypeface_win_dw.h
+++ b/src/ports/SkTypeface_win_dw.h
@@ -25,13 +25,16 @@
 struct SkScalerContextRec;
 
 static SkFontStyle get_style(IDWriteFont* font) {
-    DWRITE_FONT_STYLE dwStyle = font->GetStyle();
-    return SkFontStyle(font->GetWeight(),
-                       font->GetStretch(),
-                       (DWRITE_FONT_STYLE_OBLIQUE == dwStyle ||
-                        DWRITE_FONT_STYLE_ITALIC  == dwStyle)
-                                                   ? SkFontStyle::kItalic_Slant
-                                                   : SkFontStyle::kUpright_Slant);
+    int weight = font->GetWeight();
+    int width = font->GetStretch();
+    SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
+    switch (font->GetStyle()) {
+        case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
+        case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
+        case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
+        default: SkASSERT(false); break;
+    }
+    return SkFontStyle(weight, width, slant);
 }
 
 class DWriteFontTypeface : public SkTypeface {
diff --git a/src/utils/win/SkDWrite.h b/src/utils/win/SkDWrite.h
index 60e6a11..ddcbc6c 100644
--- a/src/utils/win/SkDWrite.h
+++ b/src/utils/win/SkDWrite.h
@@ -90,23 +90,18 @@
 
 struct DWriteStyle {
     explicit DWriteStyle(const SkFontStyle& pattern) {
-        switch (pattern.slant()) {
-        case SkFontStyle::kUpright_Slant:
-            fSlant = DWRITE_FONT_STYLE_NORMAL;
-            break;
-        case SkFontStyle::kItalic_Slant:
-            fSlant = DWRITE_FONT_STYLE_ITALIC;
-            break;
-        default:
-            SkASSERT(false);
-        }
-
         fWeight = (DWRITE_FONT_WEIGHT)pattern.weight();
         fWidth = (DWRITE_FONT_STRETCH)pattern.width();
+        switch (pattern.slant()) {
+            case SkFontStyle::kUpright_Slant: fSlant = DWRITE_FONT_STYLE_NORMAL ; break;
+            case SkFontStyle::kItalic_Slant:  fSlant = DWRITE_FONT_STYLE_ITALIC ; break;
+            case SkFontStyle::kOblique_Slant: fSlant = DWRITE_FONT_STYLE_OBLIQUE; break;
+            default: SkASSERT(false); break;
+        }
     }
-    DWRITE_FONT_STYLE fSlant;
     DWRITE_FONT_WEIGHT fWeight;
     DWRITE_FONT_STRETCH fWidth;
+    DWRITE_FONT_STYLE fSlant;
 };
 
 #endif