Adjust luminance gamma for Mac.

It appears that on macOS 10.13 smoothed subpixel antialiased black glyphs
are blit with a gamma of 2.0, but white are blit with a gamma of ~1.4 with
a smooth trasition between these. In macOS 10.14 smoothed black glyphs are
blit with a gamma of 2.0, but white are blit with a gamma ~1.0 with a
smooth transition between. The reason for this is to tone down the high
dilation of the outlines after autohinting.

In order to render like the platform, emulate this behavior by adjusting
the luminance value used to pick the mask gamma.

Bug: chromium:933137
Change-Id: I02d73c29bee1a3506b43598d78f07a03c968349f
Reviewed-on: https://skia-review.googlesource.com/c/196501
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
Ben Wagner 2019-02-28 16:40:20 -05:00 committed by Skia Commit-Bot
parent 5043c09b8b
commit c025aa9638
2 changed files with 26 additions and 7 deletions

View File

@ -96,6 +96,7 @@ public:
}
SkScalar getContrast() const {
sk_ignore_unused_variable(fReservedAlign);
return SkIntToScalar(fContrast) / ((1 << 8) - 1);
}
void setContrast(SkScalar c) {
@ -206,11 +207,6 @@ public:
return static_cast<SkMask::Format>(fMaskFormat);
}
private:
// TODO: get rid of these bad friends.
friend class SkScalerContext;
friend class SkScalerContext_DW;
SkColor getLuminanceColor() const {
return fLumBits;
}
@ -220,6 +216,10 @@ private:
void setLuminanceColor(SkColor c) {
fLumBits = SkColorSetRGB(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c));
}
private:
// TODO: remove
friend class SkScalerContext;
};
SK_END_REQUIRE_DENSE

View File

@ -2227,7 +2227,7 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
rec->fFlags &= ~flagsWeDontSupport;
SmoothBehavior smoothBehavior = smooth_behavior();
const SmoothBehavior smoothBehavior = smooth_behavior();
// Only two levels of hinting are supported.
// kNo_Hinting means avoid CoreGraphics outline dilation (smoothing).
@ -2288,7 +2288,26 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
rec->ignorePreBlend();
#endif
} else {
//CoreGraphics dialates smoothed text as needed.
#ifndef SK_IGNORE_MAC_BLENDING_MATCH_FIX
SkColor color = rec->getLuminanceColor();
if (smoothBehavior == SmoothBehavior::some) {
// CoreGraphics smoothed text without subpixel coverage blitting goes from a gamma of
// 2.0 for black foreground to a gamma of 1.0 for white foreground. Emulate this
// through the mask gamma by reducing the color values to 1/2.
color = SkColorSetRGB(SkColorGetR(color) * 1/2,
SkColorGetG(color) * 1/2,
SkColorGetB(color) * 1/2);
} else if (smoothBehavior == SmoothBehavior::subpixel) {
// CoreGraphics smoothed text with subpixel coverage blitting goes from a gamma of
// 2.0 for black foreground to a gamma of ~1.4? for white foreground. Emulate this
// through the mask gamma by reducing the color values to 3/4.
color = SkColorSetRGB(SkColorGetR(color) * 3/4,
SkColorGetG(color) * 3/4,
SkColorGetB(color) * 3/4);
}
rec->setLuminanceColor(color);
#endif
// CoreGraphics dialates smoothed text to provide contrast.
rec->setContrast(0);
}
}