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

Unified Diff: src/ports/SkFontHost_mac.cpp

Issue 1027373002: Font variations. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Initial Mac implementation (buggy). Created 5 years, 8 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_linux.cpp ('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 5eaf7df6036b281fe08560d07baeef9e418fa7fe..b42f348c9b92c9cafc502c212948fa8c1c958811 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -466,6 +466,7 @@ public:
protected:
int onGetUPEM() const override;
SkStreamAsset* onOpenStream(int* ttcIndex) const override;
+ SkFontData* onCreateFontData() const override;
void onGetFamilyName(SkString* familyName) const override;
SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
int onGetTableTags(SkFontTableTag tags[]) const override;
@@ -1764,6 +1765,102 @@ SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
return stream;
}
+#include <limits>
+
+struct Context {
+ SkFontData::Axis* axes;
+ int index;
+ CFArrayRef ctAxes;
+};
+static void accumulateAxes(CFTypeRef key, CFTypeRef value, void* context) {
+ Context* c = static_cast<Context*>(context);
+
+ // The key is supposed to be a CFNumber 'FourCharCode'.
+ // However, if the font was originally selected by style, the key is a CFString with a name.
+ // See http://lists.apple.com/archives/coretext-dev/2012/Aug/msg00006.html .
+ // This issue observed in 10.10.3.
+ // So if the key is a CFString convert it into CFNumber by going throught the axis information.
+ // Amusingly, if a CFString is specified as the key on the descriptor on a request,
+ // an uncaught exception is thrown (normally causing a crash).
+ SkFourByteTag tag = 0;
+ if (CFGetTypeID(key) == CFStringGetTypeID()) {
+ CFStringRef keyString = static_cast<CFStringRef>(key);
+ for (CFIndex i = 0; i < CFArrayGetCount(c->ctAxes); ++i) {
+ CFTypeRef variations = CFArrayGetValueAtIndex(c->ctAxes, i);
+ if (CFGetTypeID(variations) != CFDictionaryGetTypeID()) {
+ continue;
+ }
+
+ CFDictionaryRef variationsDict = static_cast<CFDictionaryRef>(variations);
+ CFTypeRef axisName;
+ if (!CFDictionaryGetValueIfPresent(variationsDict, kCTFontVariationAxisNameKey, &axisName)) {
+ continue;
+ }
+ if (CFGetTypeID(axisName) != CFStringGetTypeID()) {
+ continue;
+ }
+ CFStringRef axisNameString = static_cast<CFStringRef>(axisName);
+ if (CFStringCompare(keyString, axisNameString, 0) == kCFCompareEqualTo) {
+ CFTypeRef axisIdentifier;
+ if (!CFDictionaryGetValueIfPresent(variationsDict, kCTFontVariationAxisIdentifierKey, &axisIdentifier)) {
+ continue;
+ }
+ if (CFGetTypeID(axisIdentifier) != CFNumberGetTypeID()) {
+ continue;
+ }
+ CFNumberRef axisIdentifierNumber = static_cast<CFNumberRef>(axisIdentifier);
+ int64_t axisIdentifier64;
+ if (CFNumberGetValue(axisIdentifierNumber, CFNumberType::kCFNumberSInt64Type, &axisIdentifier64)
+ && 0 <= axisIdentifier64 && axisIdentifier64 <= std::numeric_limits<uint32_t>::max())
+ {
+ tag = axisIdentifier64;
+ break;
+ }
+ }
+ }
+ } else if (CFGetTypeID(key) == CFNumberGetTypeID()) {
+ CFNumberRef axisIdentifierNumber = static_cast<CFNumberRef>(key);
+ int64_t axisIdentifier64;
+ if (CFNumberGetValue(axisIdentifierNumber, CFNumberType::kCFNumberSInt64Type, &axisIdentifier64)
+ && 0 <= axisIdentifier64 && axisIdentifier64 <= std::numeric_limits<uint32_t>::max())
+ {
+ tag = axisIdentifier64;
+ }
+ }
+
+ SkFixed valueFixed = SK_Fixed1; // should this be SK_FixedNaN?
+ if (CFGetTypeID(value) == CFNumberGetTypeID()) {
+ CFNumberRef valueNumber = static_cast<CFNumberRef>(value);
+ double valueDouble;
+ if (CFNumberGetValue(valueNumber, CFNumberType::kCFNumberDoubleType, &valueDouble)
+ && SkFixedToDouble(SK_FixedMin) <= valueDouble && valueDouble <= SkFixedToDouble(SK_FixedMax)) // better check?
+ {
+ valueFixed = SkDoubleToFixed(valueDouble);
+ }
+ }
+ c->axes[c->index].fTag = tag;
+ c->axes[c->index].fValue = valueFixed;
+ ++c->index;
+}
+SkFontData* SkTypeface_Mac::onCreateFontData() const {
+ int index;
+ SkAutoTDelete<SkStreamAsset> stream(this->onOpenStream(&index));
+
+ AutoCFRelease<CFDictionaryRef> variations(CTFontCopyVariation(fFontRef));
+ // If a font has no variations CTFontCopyVariation returns NULL instead of an empty dict.
+ if (variations.get()) {
+ CFIndex variationCount = CFDictionaryGetCount(variations);
+ SkAutoSTMalloc<4, SkFontData::Axis> axes(variationCount);
+ AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef));
+ Context c = { axes.get(), 0, ctAxes.get() };
+ CFDictionaryApplyFunction(variations, accumulateAxes, &c);
+ axes[0].fValue = 4 * SK_Fixed1;
bungeman-skia 2015/04/23 21:16:34 This is a test to see what happens when a variatio
+ return new SkFontData(stream.detach(), index, variationCount, axes.get());
+ } else {
+ return new SkFontData(stream.detach(), index, 0, NULL);
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -2267,6 +2364,49 @@ protected:
return create_from_dataProvider(pr);
}
+ SkTypeface* onCreateFromFontData(SkFontData* fontData) const override {
+ AutoCFRelease<CGDataProviderRef> provider(SkCreateDataProviderFromStream(fontData->transferStream()));
+ if (NULL == provider) {
+ return NULL;
+ }
+ AutoCFRelease<CGFontRef> cg(CGFontCreateWithDataProvider(provider));
+ if (NULL == cg) {
+ return NULL;
+ }
+ SkAutoSTMalloc<4, CFTypeRef> keys(fontData->getAxisCount());
+ SkAutoSTMalloc<4, CFTypeRef> values(fontData->getAxisCount());
+
+ for (int i = 0; i < fontData->getAxisCount(); ++i) {
+ int64_t key = fontData->getAxis()[i].fTag;
+ keys[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &key);
+
+ double value = SkFixedToDouble(fontData->getAxis()[i].fValue);
+ values[i] = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value);
+ }
+ AutoCFRelease<CFDictionaryRef> variations(CFDictionaryCreate(kCFAllocatorDefault, keys.get(), values.get(), fontData->getAxisCount(),
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CFDictionaryRef variationLValue = variations.get();
+ AutoCFRelease<CFDictionaryRef> attributes(CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontVariationAttribute, (const void**)&variationLValue, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ AutoCFRelease<CTFontDescriptorRef> descriptor(CTFontDescriptorCreateWithAttributes(attributes));
+ //AutoCFRelease<CGFontRef> cgWithAxes(CGFontCreateCopyWithVariations(cg, variations));
+ CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, descriptor);
bungeman-skia 2015/04/23 21:16:34 So this starts the buggy. This will create a CTFon
+ if (!ct) {
+ return NULL;
+ }
+ AutoCFRelease<CFDictionaryRef> ctvariations(CTFontCopyVariation(ct));
+ ///AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(ct));
+ //CFShow(desc);
+ //AutoCFRelease<CTFontDescriptorRef> desc1(CTFontDescriptorCreateCopyWithVariation(desc, (CFNumberRef)keys[0], 1.0));
+ //CFShow(desc1);
+ AutoCFRelease<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct));
+ CFShow(ctAxes);
+ SkTypeface* typeface = NewFromFontRef(ct, NULL, true);
+ SkFontData* fontData1 = typeface->createFontData();
+ delete fontData1;
+ return typeface;
+ }
+
SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
if (NULL == pr) {
@@ -2308,3 +2448,4 @@ protected:
SkFontMgr* SkFontMgr::Factory() {
return SkNEW(SkFontMgr_Mac);
}
+
« no previous file with comments | « src/ports/SkFontHost_linux.cpp ('k') | src/ports/SkFontMgr_android.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698