typemytype / drawbot

http://www.drawbot.com
Other
402 stars 62 forks source link

Return open type feature default settings #178

Open typemytype opened 6 years ago

typemytype commented 6 years ago

get the default open type feature settings for a given font:

instead of return a list of fea tags, it could also be a dict where the fea tags are the keys and an on off state, see

import CoreText
from drawBot.context.tools.openType import *

fontName = "HoeflerText-Regular"

descriptor = CoreText.NSFontDescriptor.fontDescriptorWithName_size_(fontName, 12)
featureDescriptions = CoreText.CTFontDescriptorCopyAttribute(descriptor, CoreText.kCTFontFeaturesAttribute)

def getFeatureTagsForDescriptions(featureDescriptions):
    featureTags = {}
    for featureDescription in featureDescriptions:
        featureType = featureDescription[CoreText.NSFontFeatureTypeIdentifierKey]
        for selector in featureDescription["CTFeatureTypeSelectors"]:
            featureSelector = selector[CoreText.NSFontFeatureSelectorIdentifierKey]
            featureTag = reversedFeatureMap.get((featureType, featureSelector))
            if featureTag:
                featureTag = featureTag.replace("_off", "")
                featureTags[featureTag] = "_off" not in featureTag  
    return featureTags

print(getFeatureTagsForDescriptions(featureDescriptions))
justvanrossum commented 6 years ago

Hmm, it doesn't give the correct default settings. For example, dlig is off by default.

import CoreText
from drawBot.context.tools.openType import *

def getFeatureTagsForDescriptions(featureDescriptions):
    featureTags = {}
    for featureDescription in featureDescriptions:
        featureType = featureDescription[CoreText.NSFontFeatureTypeIdentifierKey]
        for selector in featureDescription["CTFeatureTypeSelectors"]:
            featureSelector = selector[CoreText.NSFontFeatureSelectorIdentifierKey]
            featureTag = reversedFeatureMap.get((featureType, featureSelector))
            if featureTag:
                featureTags[featureTag.replace("_off", "")] = "_off" not in featureTag  
    return featureTags

fontName = "HoeflerText-Regular"

descriptor = CoreText.NSFontDescriptor.fontDescriptorWithName_size_(fontName, 12)
featureDescriptions = CoreText.CTFontDescriptorCopyAttribute(descriptor, CoreText.kCTFontFeaturesAttribute)
features = getFeatureTagsForDescriptions(featureDescriptions)
print(features)

size(500, 250)
font(fontName)
fontSize(50)
text("Hoefler Facts #123", (10, 150))
openTypeFeatures(**features)
text("Hoefler Facts #123", (10, 70))
{'liga': True, 'dlig': True, 'tnum': True, 'pnum': True, 'titl': False, 'onum': True, 'lnum': True}

opentypefeaturetest

justvanrossum commented 6 years ago

The idea should be that:

features = openTypeFeatures()
openTypeFeatures(**features)

results in no change in behavior at all.

typemytype commented 6 years ago

that must be the idea :)

typemytype commented 6 years ago

this will do:

import CoreText
from drawBot.context.tools.openType import *

def getFeatureTagsForDescriptions(featureDescriptions):
    featureTags = {}
    for featureDescription in featureDescriptions:
        featureType = featureDescription[CoreText.NSFontFeatureTypeIdentifierKey]
        for selector in featureDescription["CTFeatureTypeSelectors"]:
            featureSelector = selector[CoreText.NSFontFeatureSelectorIdentifierKey]
            featureTag = reversedFeatureMap.get((featureType, featureSelector))
            if featureTag:
                featureTag = featureTag.replace("_off", "")
                featureTags[featureTag] =  selector.get(CoreText.kCTFontFeatureSelectorDefaultKey, False)
    return featureTags

fontName = "HoeflerText-Regular"

descriptor = CoreText.NSFontDescriptor.fontDescriptorWithName_size_(fontName, 12)
featureDescriptions = CoreText.CTFontDescriptorCopyAttribute(descriptor, CoreText.kCTFontFeaturesAttribute)
features = getFeatureTagsForDescriptions(featureDescriptions)

print(features)

size(830, 330)
font(fontName)
fontSize(50)
text("Hofiefler Facts #123 default", (10, 270))
openTypeFeatures(**features)
text("Hofiefler Facts #123 set from default", (10, 210))
openTypeFeatures(**{k: False for k in features})
text("Hofiefler Facts #123 all False", (10, 150))
openTypeFeatures(**{k: True for k in features})
text("Hofiefler Facts #123 all True", (10, 90))
openTypeFeatures(resetFeatures=True)
text("Hofiefler Facts #123 reset", (10, 30))

screen shot 2018-01-22 at 11 12 37

justvanrossum commented 6 years ago

Very nice!

typemytype commented 6 years ago

see https://github.com/typemytype/drawbot/pull/180

justvanrossum commented 6 years ago

Wasn't this issue resolved with #180?