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;
|
||||
}
|
||||
|
||||
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(ct.get(), args);
|
||||
SkUniqueCFRef<CFArrayRef> axes(CTFontCopyVariationAxes(ct.get()));
|
||||
CTFontVariation ctVariation = SkCTVariationFromSkFontArguments(ct.get(), axes.get(), args);
|
||||
|
||||
SkUniqueCFRef<CTFontRef> ctVariant;
|
||||
if (ctVariation.variation) {
|
||||
|
@ -718,8 +718,8 @@ void SkScalerContext_Mac::generateFontMetrics(SkFontMetrics* metrics) {
|
||||
metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
|
||||
metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
|
||||
|
||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fCTFont.get()));
|
||||
if (ctAxes && CFArrayGetCount(ctAxes.get()) > 0) {
|
||||
CFArrayRef ctAxes = ((SkTypeface_Mac*)this->getTypeface())->getVariationAxes();
|
||||
if (ctAxes && CFArrayGetCount(ctAxes) > 0) {
|
||||
// The bounds are only valid for the default variation.
|
||||
metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
|
||||
}
|
||||
|
@ -566,8 +566,8 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics(
|
||||
}
|
||||
}
|
||||
|
||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ctFont.get()));
|
||||
if (ctAxes && CFArrayGetCount(ctAxes.get()) > 0) {
|
||||
CFArrayRef ctAxes = this->getVariationAxes();
|
||||
if (ctAxes && CFArrayGetCount(ctAxes) > 0) {
|
||||
info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
|
||||
}
|
||||
|
||||
@ -787,14 +787,21 @@ bool SkTypeface_Mac::onGlyphMaskNeedsCurrentColor() const {
|
||||
return this->fHasColorGlyphs;
|
||||
}
|
||||
|
||||
CFArrayRef SkTypeface_Mac::getVariationAxes() const {
|
||||
fInitVariationAxes([this]{
|
||||
fVariationAxes.reset(CTFontCopyVariationAxes(fFontRef.get()));
|
||||
});
|
||||
return fVariationAxes.get();
|
||||
}
|
||||
|
||||
int SkTypeface_Mac::onGetVariationDesignPosition(
|
||||
SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
|
||||
{
|
||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef.get()));
|
||||
CFArrayRef ctAxes = this->getVariationAxes();
|
||||
if (!ctAxes) {
|
||||
return -1;
|
||||
}
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||
if (!coordinates || coordinateCount < axisCount) {
|
||||
return axisCount;
|
||||
}
|
||||
@ -807,7 +814,7 @@ int SkTypeface_Mac::onGetVariationDesignPosition(
|
||||
|
||||
for (int i = 0; i < axisCount; ++i) {
|
||||
CFDictionaryRef axisInfoDict;
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1119,15 +1126,15 @@ int SkTypeface_Mac::onCountGlyphs() const {
|
||||
}
|
||||
|
||||
/** 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;
|
||||
constexpr const SkFourByteTag opszTag = SkSetFourByteTag('o','p','s','z');
|
||||
|
||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
|
||||
if (!ctAxes) {
|
||||
return CTFontVariation();
|
||||
}
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||
|
||||
// On 10.12 and later, this only returns non-default variations.
|
||||
SkUniqueCFRef<CFDictionaryRef> oldCtVariation(CTFontCopyVariation(ct));
|
||||
@ -1142,7 +1149,7 @@ CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArgum
|
||||
|
||||
for (int i = 0; i < axisCount; ++i) {
|
||||
CFDictionaryRef axisInfoDict;
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||
return CTFontVariation();
|
||||
}
|
||||
|
||||
@ -1224,7 +1231,9 @@ CTFontVariation SkCTVariationFromSkFontArguments(CTFontRef ct, const SkFontArgum
|
||||
}
|
||||
|
||||
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;
|
||||
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 parameterCount) const
|
||||
{
|
||||
SkUniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef.get()));
|
||||
CFArrayRef ctAxes = this->getVariationAxes();
|
||||
if (!ctAxes) {
|
||||
return -1;
|
||||
}
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes.get());
|
||||
CFIndex axisCount = CFArrayGetCount(ctAxes);
|
||||
|
||||
if (!parameters || parameterCount < axisCount) {
|
||||
return axisCount;
|
||||
@ -1289,7 +1298,7 @@ int SkTypeface_Mac::onGetVariationDesignParameters(SkFontParameters::Variation::
|
||||
|
||||
for (int i = 0; i < axisCount; ++i) {
|
||||
CFDictionaryRef axisInfoDict;
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes.get(), i), &axisInfoDict, "Axis")) {
|
||||
if (!SkCFDynamicCast(CFArrayGetValueAtIndex(ctAxes, i), &axisInfoDict, "Axis")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,8 @@ struct CTFontVariation {
|
||||
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,
|
||||
OpszVariation opsz);
|
||||
@ -91,6 +92,15 @@ public:
|
||||
const OpszVariation fOpszVariation;
|
||||
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:
|
||||
int onGetUPEM() const override;
|
||||
std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
|
||||
@ -121,8 +131,10 @@ protected:
|
||||
|
||||
private:
|
||||
mutable std::unique_ptr<SkStreamAsset> fStream;
|
||||
mutable SkUniqueCFRef<CFArrayRef> fVariationAxes;
|
||||
bool fIsFromStream;
|
||||
mutable SkOnce fInitStream;
|
||||
mutable SkOnce fInitVariationAxes;
|
||||
|
||||
using INHERITED = SkTypeface;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user