Support for COLR foreground color in CoreText.
COLR fonts can use a magic palette index value 0xFFFF to indicate the foreground color of the drawing context. Modify the CoreText port to properly indicate when the foreground color is needed and use it. Bug: skia:12576 Change-Id: I14818b34fbe40ee508ed720510be53bc289c748a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/509178 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
85e7f31e6d
commit
c9ca00910a
@ -118,6 +118,7 @@ SkScalerContext_Mac::SkScalerContext_Mac(sk_sp<SkTypeface_Mac> typeface,
|
||||
const SkScalerContextEffects& effects,
|
||||
const SkDescriptor* desc)
|
||||
: INHERITED(std::move(typeface), effects, desc)
|
||||
, fOffscreen(fRec.fForegroundColor)
|
||||
, fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag))
|
||||
|
||||
{
|
||||
@ -150,17 +151,36 @@ static int RoundSize(int dimension) {
|
||||
return SkNextPow2(dimension);
|
||||
}
|
||||
|
||||
static CGColorRef CGColorForSkColor(CGColorSpaceRef rgbcs, SkColor bgra) {
|
||||
CGFloat components[4];
|
||||
components[0] = (CGFloat)SkColorGetR(bgra) * (1/255.0f);
|
||||
components[1] = (CGFloat)SkColorGetG(bgra) * (1/255.0f);
|
||||
components[2] = (CGFloat)SkColorGetB(bgra) * (1/255.0f);
|
||||
// CoreText applies the CGContext fill color as the COLR foreground color.
|
||||
// However, the alpha is applied to the whole glyph drawing (and Skia will do that as well).
|
||||
// For now, cannot really support COLR foreground color alpha.
|
||||
components[3] = 1.0f;
|
||||
return CGColorCreate(rgbcs, components);
|
||||
}
|
||||
|
||||
SkScalerContext_Mac::Offscreen::Offscreen(SkColor foregroundColor)
|
||||
// It doesn't appear to matter what color space is specified.
|
||||
// Regular blends and antialiased text are always (s*a + d*(1-a))
|
||||
// and subpixel antialiased text is always g=2.0.
|
||||
// However, we need to specify one anyway.
|
||||
: fRGBSpace(CGColorSpaceCreateDeviceRGB())
|
||||
, fCG(nullptr)
|
||||
, fForegroundColor(CGColorForSkColor(fRGBSpace.get(), foregroundColor))
|
||||
, fDoAA(false)
|
||||
, fDoLCD(false)
|
||||
{
|
||||
fSize.set(0, 0);
|
||||
}
|
||||
|
||||
CGRGBPixel* SkScalerContext_Mac::Offscreen::getCG(const SkScalerContext_Mac& context,
|
||||
const SkGlyph& glyph, CGGlyph glyphID,
|
||||
size_t* rowBytesPtr,
|
||||
bool generateA8FromLCD) {
|
||||
if (!fRGBSpace) {
|
||||
//It doesn't appear to matter what color space is specified.
|
||||
//Regular blends and antialiased text are always (s*a + d*(1-a))
|
||||
//and subpixel antialiased text is always g=2.0.
|
||||
fRGBSpace.reset(CGColorSpaceCreateDeviceRGB());
|
||||
}
|
||||
|
||||
// default to kBW_Format
|
||||
bool doAA = false;
|
||||
bool doLCD = false;
|
||||
@ -214,8 +234,12 @@ CGRGBPixel* SkScalerContext_Mac::Offscreen::getCG(const SkScalerContext_Mac& con
|
||||
|
||||
CGContextSetTextDrawingMode(fCG.get(), kCGTextFill);
|
||||
|
||||
// Draw black on white to create mask. (Special path exists to speed this up in CG.)
|
||||
CGContextSetGrayFillColor(fCG.get(), 0.0f, 1.0f);
|
||||
if (SkMask::kARGB32_Format != glyph.maskFormat()) {
|
||||
// Draw black on white to create mask. (Special path exists to speed this up in CG.)
|
||||
CGContextSetGrayFillColor(fCG.get(), 0.0f, 1.0f);
|
||||
} else {
|
||||
CGContextSetFillColorWithColor(fCG.get(), fForegroundColor.get());
|
||||
}
|
||||
|
||||
// force our checks below to happen
|
||||
fDoAA = !doAA;
|
||||
|
@ -53,14 +53,7 @@ protected:
|
||||
private:
|
||||
class Offscreen {
|
||||
public:
|
||||
Offscreen()
|
||||
: fRGBSpace(nullptr)
|
||||
, fCG(nullptr)
|
||||
, fDoAA(false)
|
||||
, fDoLCD(false)
|
||||
{
|
||||
fSize.set(0, 0);
|
||||
}
|
||||
Offscreen(SkColor foregroundColor);
|
||||
|
||||
CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
|
||||
CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD);
|
||||
@ -74,6 +67,7 @@ private:
|
||||
|
||||
// cached state
|
||||
SkUniqueCFRef<CGContextRef> fCG;
|
||||
SkUniqueCFRef<CGColorRef> fForegroundColor;
|
||||
SkISize fSize;
|
||||
bool fDoAA;
|
||||
bool fDoLCD;
|
||||
|
@ -780,6 +780,28 @@ std::unique_ptr<SkStreamAsset> SkTypeface_Mac::onOpenExistingStream(int* ttcInde
|
||||
return fStream ? fStream->duplicate() : nullptr;
|
||||
}
|
||||
|
||||
static bool has_table(CTFontRef ctFont, SkFontTableTag tableTag) {
|
||||
SkUniqueCFRef<CFArrayRef> cfArray(
|
||||
CTFontCopyAvailableTables(ctFont, kCTFontTableOptionNoOptions));
|
||||
if (!cfArray) {
|
||||
return 0;
|
||||
}
|
||||
CFIndex count = CFArrayGetCount(cfArray.get());
|
||||
for (CFIndex i = 0; i < count; ++i) {
|
||||
uintptr_t fontTag = reinterpret_cast<uintptr_t>(
|
||||
CFArrayGetValueAtIndex(cfArray.get(), i));
|
||||
if (tableTag == static_cast<SkFontTableTag>(fontTag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool SkTypeface_Mac::onGlyphMaskNeedsCurrentColor() const {
|
||||
constexpr SkFontTableTag cpalTag = SkSetFourByteTag('C', 'P', 'A', 'L');
|
||||
// CoreText only provides the size of a table with a copy, so do not use this->getTableSize().
|
||||
return has_table(fFontRef.get(), cpalTag);
|
||||
}
|
||||
|
||||
int SkTypeface_Mac::onGetVariationDesignPosition(
|
||||
SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
|
||||
{
|
||||
@ -865,9 +887,9 @@ int SkTypeface_Mac::onGetTableTags(SkFontTableTag tags[]) const {
|
||||
if (!cfArray) {
|
||||
return 0;
|
||||
}
|
||||
int count = SkToInt(CFArrayGetCount(cfArray.get()));
|
||||
CFIndex count = CFArrayGetCount(cfArray.get());
|
||||
if (tags) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (CFIndex i = 0; i < count; ++i) {
|
||||
uintptr_t fontTag = reinterpret_cast<uintptr_t>(
|
||||
CFArrayGetValueAtIndex(cfArray.get(), i));
|
||||
tags[i] = static_cast<SkFontTableTag>(fontTag);
|
||||
|
@ -95,7 +95,7 @@ protected:
|
||||
int onGetUPEM() const override;
|
||||
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
|
||||
std::unique_ptr<SkStreamAsset> onOpenExistingStream(int* ttcIndex) const override;
|
||||
bool onGlyphMaskNeedsCurrentColor() const override { return false; }
|
||||
bool onGlyphMaskNeedsCurrentColor() const override;
|
||||
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
|
||||
int coordinateCount) const override;
|
||||
void onGetFamilyName(SkString* familyName) const override;
|
||||
|
Loading…
Reference in New Issue
Block a user