Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(736)

Unified Diff: src/ports/SkFontHost_mac.cpp

Issue 1590223003: Expose API for gx font variation axes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix FontConfig and Android. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ports/SkFontHost_mac.cpp
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 1d68c433bf2243259cd1f7dfe804741f0b77763b..c4e80b67c0aa8be20d874f35cd73008c13d6347c 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -2371,6 +2371,145 @@ protected:
return create_from_dataProvider(pr);
}
+ static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) {
+ CFIndex ctAxisCount = CFArrayGetCount(ctAxes);
+ for (int i = 0; i < ctAxisCount; ++i) {
+ CFTypeRef ctAxisInfo = CFArrayGetValueAtIndex(ctAxes, i);
+ if (CFDictionaryGetTypeID() != CFGetTypeID(ctAxisInfo)) {
+ return nullptr;
+ }
+ CFDictionaryRef ctAxisInfoDict = static_cast<CFDictionaryRef>(ctAxisInfo);
+
+ CFTypeRef ctAxisName = CFDictionaryGetValue(ctAxisInfoDict,
+ kCTFontVariationAxisNameKey);
+ if (!ctAxisName || CFGetTypeID(ctAxisName) != CFStringGetTypeID()) {
+ return nullptr;
+ }
+
+ if (CFEqual(name, ctAxisName)) {
+ CFTypeRef tag = CFDictionaryGetValue(ctAxisInfoDict,
+ kCTFontVariationAxisIdentifierKey);
+ if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) {
+ return nullptr;
+ }
+ return static_cast<CFNumberRef>(tag);
+ }
+ }
+ return nullptr;
+ }
+ static CFDictionaryRef get_axes(CGFontRef cg, const FontParameters& params) {
+ AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
+ if (!cgAxes) {
+ return nullptr;
+ }
+ CFIndex axisCount = CFArrayGetCount(cgAxes);
+
+ // The CGFont variation data is keyed by name, and lacks the tag.
+ // The CTFont variation data is keyed by tag, and also has the name.
+ // We would like to work with CTFont variaitons, but creating a CTFont font with
+ // CTFont variation dictionary runs into bugs. So use the CTFont variation data
+ // to match names to tags to create the appropriate CGFont.
+ AutoCFRelease<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr));
+ AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
+ if (!ctAxes || CFArrayGetCount(ctAxes) != axisCount) {
+ return nullptr;
+ }
+
+ int paramAxisCount;
+ const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
+
+ CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ for (int i = 0; i < axisCount; ++i) {
+ CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes, i);
+ if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
+ return nullptr;
+ }
+ CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo);
+
+ CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisName);
+ if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
+ return nullptr;
+ }
+
+ CFNumberRef tagNumber = get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes);
+ if (!tagNumber) {
+ // Could not find a tag to go with the name of this index.
+ // This would be a bug in CG/CT.
+ continue;
+ }
+ int64_t tagLong;
+ if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) {
+ return nullptr;
+ }
+
+ // The variation axes can be set to any value, but cg will effectively pin them.
+ // Pin them here to normalize.
+ CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMinValue);
+ CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMaxValue);
+ CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisDefaultValue);
+ if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
+ !max || CFGetTypeID(max) != CFNumberGetTypeID() ||
+ !def || CFGetTypeID(def) != CFNumberGetTypeID())
+ {
+ return nullptr;
+ }
+ CFNumberRef minNumber = static_cast<CFNumberRef>(min);
+ CFNumberRef maxNumber = static_cast<CFNumberRef>(max);
+ CFNumberRef defNumber = static_cast<CFNumberRef>(def);
+ double minDouble;
+ double maxDouble;
+ double defDouble;
+ if (!CFNumberGetValue(minNumber, kCFNumberDoubleType, &minDouble) ||
+ !CFNumberGetValue(maxNumber, kCFNumberDoubleType, &maxDouble) ||
+ !CFNumberGetValue(defNumber, kCFNumberDoubleType, &defDouble))
+ {
+ return nullptr;
+ }
+
+ double value = defDouble;
+ for (int j = 0; j < paramAxisCount; ++j) {
+ if (paramAxes[j].fTag == tagLong) {
+ value = SkTPin(SkScalarToDouble(paramAxes[j].fStyleValue),minDouble,maxDouble);
+ break;
+ }
+ }
+ CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType,
+ &value);
+ CFDictionaryAddValue(dict, axisName, valueNumber);
+ CFRelease(valueNumber);
+ }
+ return dict;
+ }
+ SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override {
+ AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(s));
+ if (nullptr == provider) {
+ return nullptr;
+ }
+ AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
+ if (nullptr == cg) {
+ return nullptr;
+ }
+
+ AutoCFRelease<CFDictionaryRef> cgVariations(get_axes(cg, params));
+ // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was
+ // created from a data provider does not appear to have any ownership of the underlying
+ // data. The original CGFontRef must be kept alive until the copy will no longer be used.
+ AutoCFRelease<CGFontRef> cgVariant;
+ if (cgVariations) {
+ cgVariant.reset(CGFontCreateCopyWithVariations(cg, cgVariations));
+ } else {
+ cgVariant.reset(cg.detach());
+ }
+
+ CTFontRef ct = CTFontCreateWithGraphicsFont(cgVariant, 0, nullptr, nullptr);
+ if (!ct) {
+ return nullptr;
+ }
+ return NewFromFontRef(ct, cg.detach(), nullptr, true);
+ }
+
static CFDictionaryRef get_axes(CGFontRef cg, SkFontData* fontData) {
AutoCFRelease<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg));
if (!cgAxes) {
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698