Cache result of CTFontCopyVariationAxes.
CTFontCopyVariationAxes appears to be extremely slow due to localizing the name of the axis. WebKit moved to using the internal SPI CTFontCopyVariationAxesInternal to avoid this cost. Since Skia would like to avoid using internal SPI, just cache this information per typeface to avoid the cost of calling it as often. Bug: https://github.com/flutter/flutter/issues/100523 Bug: https://bugs.webkit.org/show_bug.cgi?id=232690 Change-Id: I175e34e9aa526d58e6b7a4ff54cb13d1ef8a9fd9 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/524760 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
55ec347276
commit
e85afc2b18
@ -563,7 +563,8 @@ protected:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(ct.get(), args);
|
SkUniqueCFRef<CFArrayRef> axes(CTFontCopyVariationAxes(ct.get()));
|
||||||
|
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(ct.get(), axes.get(), args);
|
||||||
|
|
||||||
SkUniqueCFRef<CTFontRef> ctVariant;
|
SkUniqueCFRef<CTFontRef> ctVariant;
|
||||||
if (ctVariation.variation) {
|
if (ctVariation.variation) {
|
||||||
|
@ -718,8 +718,8 @@ void SkScalerContext_Mac::generateFontMetrics(SkFontMetrics* metrics) {
|
|||||||
metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
|
metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
|
||||||
metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
|
metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
|
||||||
|
|
||||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fCTFont.get()));
|
CFArrayRef ctAxes = ((SkTypeface_Mac*)this->getTypeface())->getVariationAxes();
|
||||||
if (ctAxes && CFArrayGetCount(ctAxes.get()) > 0) {
|
if (ctAxes && CFArrayGetCount(ctAxes) > 0) {
|
||||||
// The bounds are only valid for the default variation.
|
// The bounds are only valid for the default variation.
|
||||||
metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
|
metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
|
||||||
}
|
}
|
||||||
|
@ -566,8 +566,8 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ctFont.get()));
|
CFArrayRef ctAxes = this->getVariationAxes();
|
||||||
if (ctAxes && CFArrayGetCount(ctAxes.get()) > 0) {
|
if (ctAxes && CFArrayGetCount(ctAxes) > 0) {
|
||||||
info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
|
info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,14 +787,21 @@ bool SkTypeface_Mac::onGlyphMaskNeedsCurrentColor() const {
|
|||||||
return this->fHasColorGlyphs;
|
return this->fHasColorGlyphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CFArrayRef SkTypeface_Mac::getVariationAxes() const {
|
||||||
|
fInitVariationAxes([this]{
|
||||||
|
fVariationAxes.reset(CTFontCopyVariationAxes(fFontRef.get()));
|
||||||
|
});
|
||||||
|
return fVariationAxes.get();
|
||||||
|
}
|
||||||
|
|
||||||
int SkTypeface_Mac::onGetVariationDesignPosition(
|
int SkTypeface_Mac::onGetVariationDesignPosition(
|
||||||
SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
|
SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
|
||||||
{
|
{
|
||||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef.get()));
|
CFArrayRef ctAxes = this->getVariationAxes();
|
||||||
if (!ctAxes) {
|
if (!ctAxes) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||||
if (!coordinates || coordinateCount < axisCount) {
|
if (!coordinates || coordinateCount < axisCount) {
|
||||||
return axisCount;
|
return axisCount;
|
||||||
}
|
}
|
||||||
@ -807,7 +814,7 @@ int SkTypeface_Mac::onGetVariationDesignPosition(
|
|||||||
|
|
||||||
for (int i = 0; i < axisCount; ++i) {
|
for (int i = 0; i < axisCount; ++i) {
|
||||||
CFDictionaryRef axisInfoDict;
|
CFDictionaryRef axisInfoDict;
|
||||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,15 +1126,15 @@ int SkTypeface_Mac::onCountGlyphs() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a dictionary suitable for setting the axes on a CTFont. */
|
/** Creates a dictionary suitable for setting the axes on a CTFont. */
|
||||||
CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArguments& args) {
|
CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, CFArrayRef ctAxes,
|
||||||
|
const SkFontArguments& args) {
|
||||||
OpszVariation opsz;
|
OpszVariation opsz;
|
||||||
constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');
|
constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');
|
||||||
|
|
||||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
|
|
||||||
if (!ctAxes) {
|
if (!ctAxes) {
|
||||||
return CTFontVariation();
|
return CTFontVariation();
|
||||||
}
|
}
|
||||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||||
|
|
||||||
// On 10.12 and later, this only returns non-default variations.
|
// On 10.12 and later, this only returns non-default variations.
|
||||||
SkUniqueCFRef<CFDictionaryRef> oldCtVariation(CTFontCopyVariation(ct));
|
SkUniqueCFRef<CFDictionaryRef> oldCtVariation(CTFontCopyVariation(ct));
|
||||||
@ -1142,7 +1149,7 @@ CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArgum
|
|||||||
|
|
||||||
for (int i = 0; i < axisCount; ++i) {
|
for (int i = 0; i < axisCount; ++i) {
|
||||||
CFDictionaryRef axisInfoDict;
|
CFDictionaryRef axisInfoDict;
|
||||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||||
return CTFontVariation();
|
return CTFontVariation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1224,7 +1231,9 @@ CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArgum
|
|||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkTypeface> SkTypeface_Mac::onMakeClone(const SkFontArguments& args) const {
|
sk_sp<SkTypeface> SkTypeface_Mac::onMakeClone(const SkFontArguments& args) const {
|
||||||
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(fFontRef.get(), args);
|
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(fFontRef.get(),
|
||||||
|
this->getVariationAxes(),
|
||||||
|
args);
|
||||||
|
|
||||||
SkUniqueCFRef<CTFontRef> ctVariant;
|
SkUniqueCFRef<CTFontRef> ctVariant;
|
||||||
if (ctVariation.variation) {
|
if (ctVariation.variation) {
|
||||||
@ -1273,11 +1282,11 @@ sk_sp<SkTypeface> SkTypeface_Mac::onMakeClone(const SkFontArguments& args) const
|
|||||||
int SkTypeface_Mac::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
|
int SkTypeface_Mac::onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
|
||||||
int parameterCount) const
|
int parameterCount) const
|
||||||
{
|
{
|
||||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef.get()));
|
CFArrayRef ctAxes = this->getVariationAxes();
|
||||||
if (!ctAxes) {
|
if (!ctAxes) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||||
|
|
||||||
if (!parameters || parameterCount < axisCount) {
|
if (!parameters || parameterCount < axisCount) {
|
||||||
return axisCount;
|
return axisCount;
|
||||||
@ -1289,7 +1298,7 @@ int SkTypeface_Mac::onGetVariationDesignParameters(SkFontParameters::Variation::
|
|||||||
|
|
||||||
for (int i = 0; i < axisCount; ++i) {
|
for (int i = 0; i < axisCount; ++i) {
|
||||||
CFDictionaryRef axisInfoDict;
|
CFDictionaryRef axisInfoDict;
|
||||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,8 @@ struct CTFontVariation {
|
|||||||
OpszVariation opsz;
|
OpszVariation opsz;
|
||||||
};
|
};
|
||||||
|
|
||||||
CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArguments& args);
|
CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, CFArrayRef ctAxes,
|
||||||
|
const SkFontArguments& args);
|
||||||
|
|
||||||
SkUniqueCFRef<CTFontRef> SkCTFontCreateExactCopy(CTFontRef baseFont, CGFloat textSize,
|
SkUniqueCFRef<CTFontRef> SkCTFontCreateExactCopy(CTFontRef baseFont, CGFloat textSize,
|
||||||
OpszVariation opsz);
|
OpszVariation opsz);
|
||||||
@ -91,6 +92,15 @@ public:
|
|||||||
const OpszVariation fOpszVariation;
|
const OpszVariation fOpszVariation;
|
||||||
const bool fHasColorGlyphs;
|
const bool fHasColorGlyphs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTFontCopyVariationAxes provides the localized name of all axes, making it very slow.
|
||||||
|
* This is unfortunate, its result is needed just to see if there are any axes at all.
|
||||||
|
* To avoid calling internal APIs cache the result of CTFontCopyVariationAxes.
|
||||||
|
* https://github.com/WebKit/WebKit/commit/1842365d413ed87868e7d33d4fad1691fa3a8129
|
||||||
|
* https://bugs.webkit.org/show_bug.cgi?id=232690
|
||||||
|
*/
|
||||||
|
CFArrayRef getVariationAxes() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int onGetUPEM() const override;
|
int onGetUPEM() const override;
|
||||||
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
|
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
|
||||||
@ -121,8 +131,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::unique_ptr<SkStreamAsset> fStream;
|
mutable std::unique_ptr<SkStreamAsset> fStream;
|
||||||
|
mutable SkUniqueCFRef<CFArrayRef> fVariationAxes;
|
||||||
bool fIsFromStream;
|
bool fIsFromStream;
|
||||||
mutable SkOnce fInitStream;
|
mutable SkOnce fInitStream;
|
||||||
|
mutable SkOnce fInitVariationAxes;
|
||||||
|
|
||||||
using INHERITED = SkTypeface;
|
using INHERITED = SkTypeface;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user