Bug 1414154 - Store the font smoothing background color on the ScaledFontMac. r?lsalzman draft
authorMarkus Stange <mstange@themasta.com>
Thu, 02 Nov 2017 21:02:30 -0400
changeset 693235 0e64727a114ce311953b9509437014304956cf2d
parent 693234 238fe13c37df6b9052bba601e3db1d7605ee98f3
child 693236 835388d6d1161ca3d66a2fdac6f7e066cfb5b242
push id87732
push userbmo:mstange@themasta.com
push dateSat, 04 Nov 2017 16:42:30 +0000
reviewerslsalzman
bugs1414154
milestone58.0a1
Bug 1414154 - Store the font smoothing background color on the ScaledFontMac. r?lsalzman MozReview-Commit-ID: 9U6CXn1JlYT
gfx/2d/2D.h
gfx/2d/CGTextDrawing.h
gfx/2d/DrawTargetSkia.cpp
gfx/2d/Factory.cpp
gfx/2d/ScaledFontMac.cpp
gfx/2d/ScaledFontMac.h
gfx/src/nsFont.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxMacFont.cpp
gfx/thebes/gfxMacFont.h
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1559,17 +1559,17 @@ public:
   static already_AddRefed<ScaledFont>
     CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern,
                                       const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
 #endif
 
 #ifdef XP_DARWIN
   static already_AddRefed<ScaledFont>
     CreateScaledFontForMacFont(CGFontRef aCGFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
-                               bool aUseFontSmoothing = true);
+                               const Color& aFontSmoothingBackgroundColor, bool aUseFontSmoothing = true);
 #endif
 
   /**
    * This creates a NativeFontResource from TrueType data.
    *
    * @param aData Pointer to the data
    * @param aSize Size of the TrueType data
    * @param aBackendType Type of the reference DrawTarget the font should be created for.
--- a/gfx/2d/CGTextDrawing.h
+++ b/gfx/2d/CGTextDrawing.h
@@ -38,30 +38,26 @@ static CGColorRef
 ColorToCGColor(CGColorSpaceRef aColorSpace, const Color& aColor)
 {
   CGFloat components[4] = {aColor.r, aColor.g, aColor.b, aColor.a};
   return CGColorCreate(aColorSpace, components);
 }
 
 static bool
 SetFontSmoothingBackgroundColor(CGContextRef aCGContext, CGColorSpaceRef aColorSpace,
-                                const GlyphRenderingOptions* aRenderingOptions)
+                                const Color& aFontSmoothingBackgroundColor)
 {
-  if (aRenderingOptions) {
-    Color fontSmoothingBackgroundColor =
-      static_cast<const GlyphRenderingOptionsCG*>(aRenderingOptions)->FontSmoothingBackgroundColor();
-    if (fontSmoothingBackgroundColor.a > 0) {
-      CGContextSetFontSmoothingBackgroundColorFunc setFontSmoothingBGColorFunc =
-        GetCGContextSetFontSmoothingBackgroundColorFunc();
-      if (setFontSmoothingBGColorFunc) {
-        CGColorRef color = ColorToCGColor(aColorSpace, fontSmoothingBackgroundColor);
-        setFontSmoothingBGColorFunc(aCGContext, color);
-        CGColorRelease(color);
-        return true;
-      }
+  if (aFontSmoothingBackgroundColor.a > 0) {
+    CGContextSetFontSmoothingBackgroundColorFunc setFontSmoothingBGColorFunc =
+      GetCGContextSetFontSmoothingBackgroundColorFunc();
+    if (setFontSmoothingBGColorFunc) {
+      CGColorRef color = ColorToCGColor(aColorSpace, aFontSmoothingBackgroundColor);
+      setFontSmoothingBGColorFunc(aCGContext, color);
+      CGColorRelease(color);
+      return true;
     }
   }
 
   return false;
 }
 
 // Font rendering with a non-transparent font smoothing background color
 // can leave pixels in our buffer where the rgb components exceed the alpha
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -1268,20 +1268,21 @@ DrawTargetSkia::FillGlyphsWithCG(ScaledF
 
   Vector<CGGlyph,32> glyphs;
   Vector<CGPoint,32> positions;
   if (!SetupCGGlyphs(cgContext, aBuffer, glyphs, positions)) {
     ReturnCGContext(cgContext);
     return false;
   }
 
-  SetFontSmoothingBackgroundColor(cgContext, mColorSpace, aRenderingOptions);
+  ScaledFontMac* macFont = static_cast<ScaledFontMac*>(aFont);
+  SetFontSmoothingBackgroundColor(cgContext, mColorSpace,
+                                  macFont->FontSmoothingBackgroundColor());
   SetFontColor(cgContext, mColorSpace, aPattern);
 
-  ScaledFontMac* macFont = static_cast<ScaledFontMac*>(aFont);
   if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) {
     ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, glyphs.begin(),
                                        positions.begin(),
                                        aBuffer.mNumGlyphs, cgContext);
   } else {
     CGContextSetFont(cgContext, macFont->mFont);
     CGContextSetFontSize(cgContext, macFont->mSize);
     CGContextShowGlyphsAtPositions(cgContext, glyphs.begin(), positions.begin(),
@@ -1305,32 +1306,32 @@ DrawTargetSkia::FillGlyphsWithCG(ScaledF
 
   EnsureValidPremultipliedData(cgContext, extents);
 
   ReturnCGContext(cgContext);
   return true;
 }
 
 static bool
-HasFontSmoothingBackgroundColor(const GlyphRenderingOptions* aRenderingOptions)
+HasFontSmoothingBackgroundColor(ScaledFont* aFont)
 {
   // This should generally only be true if we have a popup context menu
-  if (aRenderingOptions && aRenderingOptions->GetType() == FontType::MAC) {
+  if (aFont && aFont->GetType() == FontType::MAC) {
     Color fontSmoothingBackgroundColor =
-      static_cast<const GlyphRenderingOptionsCG*>(aRenderingOptions)->FontSmoothingBackgroundColor();
+      static_cast<ScaledFontMac*>(aFont)->FontSmoothingBackgroundColor();
     return fontSmoothingBackgroundColor.a > 0;
   }
 
   return false;
 }
 
 static bool
-ShouldUseCGToFillGlyphs(const GlyphRenderingOptions* aOptions, const Pattern& aPattern)
+ShouldUseCGToFillGlyphs(ScaledFont* aFont, const Pattern& aPattern)
 {
-  return HasFontSmoothingBackgroundColor(aOptions) &&
+  return HasFontSmoothingBackgroundColor(aFont) &&
           aPattern.GetType() == PatternType::COLOR;
 }
 
 #endif
 
 static bool
 CanDrawFont(ScaledFont* aFont)
 {
@@ -1358,18 +1359,18 @@ DrawTargetSkia::DrawGlyphs(ScaledFont* a
   if (!CanDrawFont(aFont)) {
     return;
   }
 
   MarkChanged();
 
 #ifdef MOZ_WIDGET_COCOA
   if (!aStrokeOptions &&
-      ShouldUseCGToFillGlyphs(aRenderingOptions, aPattern)) {
-    if (FillGlyphsWithCG(aFont, aBuffer, aPattern, aOptions, aRenderingOptions)) {
+      ShouldUseCGToFillGlyphs(aFont, aPattern)) {
+    if (FillGlyphsWithCG(aFont, aBuffer, aPattern, aOptions)) {
       return;
     }
   }
 #endif
 
   ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont);
   SkTypeface* typeface = skiaFont->GetSkTypeface();
   if (!typeface) {
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -659,19 +659,22 @@ Factory::CreateScaledFontForFontconfigFo
 }
 #endif
 
 #ifdef XP_DARWIN
 already_AddRefed<ScaledFont>
 Factory::CreateScaledFontForMacFont(CGFontRef aCGFont,
                                     const RefPtr<UnscaledFont>& aUnscaledFont,
                                     Float aSize,
+                                    const Color& aFontSmoothingBackgroundColor,
                                     bool aUseFontSmoothing)
 {
-  return MakeAndAddRef<ScaledFontMac>(aCGFont, aUnscaledFont, aSize, aUseFontSmoothing);
+  return MakeAndAddRef<ScaledFontMac>(
+    aCGFont, aUnscaledFont, aSize,
+    aFontSmoothingBackgroundColor, aUseFontSmoothing);
 }
 #endif
 
 already_AddRefed<DrawTarget>
 Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
 {
   MOZ_ASSERT(targetA && targetB);
 
--- a/gfx/2d/ScaledFontMac.cpp
+++ b/gfx/2d/ScaledFontMac.cpp
@@ -103,20 +103,22 @@ CreateCTFontFromCGFontWithVariations(CGF
         ctFont = CTFontCreateWithGraphicsFont(aCGFont, aSize, nullptr, nullptr);
     }
     return ctFont;
 }
 
 ScaledFontMac::ScaledFontMac(CGFontRef aFont,
                              const RefPtr<UnscaledFont>& aUnscaledFont,
                              Float aSize,
+                             const Color &aFontSmoothingBackgroundColor,
                              bool aUseFontSmoothing,
                              bool aOwnsFont)
   : ScaledFontBase(aUnscaledFont, aSize)
   , mFont(aFont)
+  , mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor)
   , mUseFontSmoothing(aUseFontSmoothing)
 {
   if (!sSymbolLookupDone) {
     CTFontDrawGlyphsPtr =
       (CTFontDrawGlyphsFuncT*)dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs");
     sSymbolLookupDone = true;
   }
 
@@ -516,17 +518,17 @@ UnscaledFontMac::CreateScaledFont(Float 
     CGFontRef varFont =
       CreateCGFontWithVariations(mFont, aNumVariations, aVariations);
     if (varFont) {
       fontRef = varFont;
     }
   }
 
   RefPtr<ScaledFontMac> scaledFont =
-    new ScaledFontMac(fontRef, this, aGlyphSize, true, fontRef != mFont);
+    new ScaledFontMac(fontRef, this, aGlyphSize, Color(), true, fontRef != mFont);
 
   if (!scaledFont->PopulateCairoScaledFont()) {
     gfxWarning() << "Unable to create cairo scaled Mac font.";
     return nullptr;
   }
 
   return scaledFont.forget();
 }
--- a/gfx/2d/ScaledFontMac.h
+++ b/gfx/2d/ScaledFontMac.h
@@ -37,41 +37,46 @@ public:
 private:
   Color mFontSmoothingBackgroundColor;
 };
 
 class ScaledFontMac : public ScaledFontBase
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac, override)
-  ScaledFontMac(CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize, bool aUseFontSmoothing = true, bool aOwnsFont = false);
+  ScaledFontMac(CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
+                const Color &aFontSmoothingBackgroundColor = Color(),
+                bool aUseFontSmoothing = true, bool aOwnsFont = false);
   ~ScaledFontMac();
 
   FontType GetType() const override { return FontType::MAC; }
 #ifdef USE_SKIA
   SkTypeface* GetSkTypeface() override;
 #endif
   already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) override;
 
   bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
 
   bool GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions>* aOutOptions,
                                 Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
                                 std::vector<FontVariation>* aOutVariations) override;
 
   bool CanSerialize() override { return true; }
 
+  Color FontSmoothingBackgroundColor() { return mFontSmoothingBackgroundColor; }
+
 #ifdef USE_CAIRO_SCALED_FONT
   cairo_font_face_t* GetCairoFontFace() override;
 #endif
 
 private:
   friend class DrawTargetSkia;
   CGFontRef mFont;
   CTFontRef mCTFont; // only created if CTFontDrawGlyphs is available, otherwise null
+  Color mFontSmoothingBackgroundColor;
   bool mUseFontSmoothing;
 
   typedef void (CTFontDrawGlyphsFuncT)(CTFontRef,
                                        const CGGlyph[], const CGPoint[],
                                        size_t, CGContextRef);
 
   static bool sSymbolLookupDone;
 
--- a/gfx/src/nsFont.cpp
+++ b/gfx/src/nsFont.cpp
@@ -270,16 +270,18 @@ void nsFont::AddFontFeaturesToStyle(gfxF
 
   // add in features from font-feature-settings
   aStyle->featureSettings.AppendElements(fontFeatureSettings);
 
   // enable grayscale antialiasing for text
   if (smoothing == NS_FONT_SMOOTHING_GRAYSCALE) {
     aStyle->useGrayscaleAntialiasing = true;
   }
+
+  aStyle->fontSmoothingBackgroundColor = fontSmoothingBackgroundColor;
 }
 
 void nsFont::AddFontVariationsToStyle(gfxFontStyle *aStyle) const
 {
   // TODO: add variation settings from specific CSS properties
   // such as weight, width, optical-size
 
   // Add in arbitrary values from font-variation-settings
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -4039,16 +4039,17 @@ gfxFont::RemoveGlyphChangeObserver(Glyph
 }
 
 #define DEFAULT_PIXEL_FONT_SIZE 16.0f
 
 gfxFontStyle::gfxFontStyle() :
     language(nsGkAtoms::x_western),
     size(DEFAULT_PIXEL_FONT_SIZE), sizeAdjust(-1.0f), baselineOffset(0.0f),
     languageOverride(NO_FONT_LANGUAGE_OVERRIDE),
+    fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)),
     weight(NS_FONT_WEIGHT_NORMAL), stretch(NS_FONT_STRETCH_NORMAL),
     style(NS_FONT_STYLE_NORMAL),
     variantCaps(NS_FONT_VARIANT_CAPS_NORMAL),
     variantSubSuper(NS_FONT_VARIANT_POSITION_NORMAL),
     systemFont(true), printerFont(false), useGrayscaleAntialiasing(false),
     allowSyntheticWeight(true), allowSyntheticStyle(true),
     noFallbackVariantFeatures(true),
     explicitLanguage(false)
@@ -4061,16 +4062,17 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyl
                            float aSizeAdjust, bool aSystemFont,
                            bool aPrinterFont,
                            bool aAllowWeightSynthesis,
                            bool aAllowStyleSynthesis,
                            uint32_t aLanguageOverride):
     language(aLanguage),
     size(aSize), sizeAdjust(aSizeAdjust), baselineOffset(0.0f),
     languageOverride(aLanguageOverride),
+    fontSmoothingBackgroundColor(NS_RGBA(0, 0, 0, 0)),
     weight(aWeight), stretch(aStretch),
     style(aStyle),
     variantCaps(NS_FONT_VARIANT_CAPS_NORMAL),
     variantSubSuper(NS_FONT_VARIANT_POSITION_NORMAL),
     systemFont(aSystemFont), printerFont(aPrinterFont),
     useGrayscaleAntialiasing(false),
     allowSyntheticWeight(aAllowWeightSynthesis),
     allowSyntheticStyle(aAllowStyleSynthesis),
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -130,16 +130,20 @@ struct gfxFontStyle {
     // (see above) to control any language-specific rendering, but the author
     // can override this for cases where the options implemented in the font
     // do not directly match the actual language. (E.g. lang may be Macedonian,
     // but the font in use does not explicitly support this; the author can
     // use font-language-override to request the Serbian option in the font
     // in order to get correct glyph shapes.)
     uint32_t languageOverride;
 
+    // The estimated background color behind the text. Enables a special
+    // rendering mode when NS_GET_A(.) > 0. Only used for text in the chrome.
+    nscolor fontSmoothingBackgroundColor;
+
     // The weight of the font: 100, 200, ... 900.
     uint16_t weight;
 
     // The stretch of the font (the sum of various NS_FONT_STRETCH_*
     // constants; see gfxFontConstants.h).
     int8_t stretch;
 
     // The style of font (normal, italic, oblique)
@@ -212,17 +216,18 @@ struct gfxFontStyle {
             (language == other.language) &&
             (baselineOffset == other.baselineOffset) &&
             (*reinterpret_cast<const uint32_t*>(&sizeAdjust) ==
              *reinterpret_cast<const uint32_t*>(&other.sizeAdjust)) &&
             (featureSettings == other.featureSettings) &&
             (alternateValues == other.alternateValues) &&
             (featureValueLookup == other.featureValueLookup) &&
             (variationSettings == other.variationSettings) &&
-            (languageOverride == other.languageOverride);
+            (languageOverride == other.languageOverride) &&
+            (fontSmoothingBackgroundColor == other.fontSmoothingBackgroundColor);
     }
 };
 
 
 /**
  * Font cache design:
  * 
  * The mFonts hashtable contains most fonts, indexed by (gfxFontEntry*, style).
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -26,16 +26,17 @@ using namespace mozilla::gfx;
 gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
                        MacOSFontEntry *aFontEntry,
                        const gfxFontStyle *aFontStyle,
                        bool aNeedsBold)
     : gfxFont(aUnscaledFont, aFontEntry, aFontStyle),
       mCGFont(nullptr),
       mCTFont(nullptr),
       mFontFace(nullptr),
+      mFontSmoothingBackgroundColor(aFontStyle->fontSmoothingBackgroundColor),
       mVariationFont(aFontEntry->HasVariations())
 {
     mApplySyntheticBold = aNeedsBold;
 
     if (mVariationFont && aFontStyle->variationSettings.Length() > 0) {
         CGFontRef baseFont = aUnscaledFont->GetFont();
         if (!baseFont) {
             mIsValid = false;
@@ -519,16 +520,17 @@ gfxMacFont::InitMetricsFromPlatform()
 already_AddRefed<ScaledFont>
 gfxMacFont::GetScaledFont(DrawTarget *aTarget)
 {
     if (!mAzureScaledFont) {
         mAzureScaledFont =
             Factory::CreateScaledFontForMacFont(GetCGFontRef(),
                                                 GetUnscaledFont(),
                                                 GetAdjustedSize(),
+                                                Color::FromABGR(mFontSmoothingBackgroundColor),
                                                 !mStyle.useGrayscaleAntialiasing);
         if (!mAzureScaledFont) {
             return nullptr;
         }
 
         mAzureScaledFont->SetCairoScaledFont(mScaledFont);
     }
 
--- a/gfx/thebes/gfxMacFont.h
+++ b/gfx/thebes/gfxMacFont.h
@@ -104,13 +104,14 @@ protected:
     CTFontRef             mCTFont;
 
     cairo_font_face_t    *mFontFace;
 
     mozilla::UniquePtr<gfxFontShaper> mCoreTextShaper;
 
     Metrics               mMetrics;
     uint32_t              mSpaceGlyph;
+    nscolor               mFontSmoothingBackgroundColor;
 
     bool                  mVariationFont; // true if font has OpenType variations
 };
 
 #endif /* GFX_MACFONT_H */