Skip to content

[aat] Map smcp to kLetterCase feature if old style smcp feature is present #1342

@drott

Description

@drott

Apple Chancery from Mac OS 10.12 (and 10.13 in this case) has an old style "Letter Case" small caps feature, kLetterCaseType = 3 (from SFNTLayoutTypes.h).

When activating --features=smcp in hb-shape, this feature is not invoked.

$ ./hb-shape --shaper=ot --font-funcs=ot /Library/Fonts/Apple\ Chancery.ttf "hhh"
[h=0+1090|h=1+1090|h=2+1090]
$ ./hb-shape --shaper=ot --font-funcs=ot --features=smcp /Library/Fonts/Apple\ Chancery.ttf "hhh"
[h=0+1090|h=1+1090|h=2+1090]

However, for a font that has new style "Lower Case" and "Upper Case" small caps and c2sc equivalents, these features are mapped correctly.

$ ./hb-shape --shaper=ot --font-funcs=ot --features=smcp,c2sc /System/Library/Fonts/SFNSText.ttf "hhhHHH"
[gid1654=0+1315|gid1654=1+1315|gid1654=2+1315|gid1654=3+1315|gid1654=4+1315|gid1654=5+1315]
$ ./hb-shape --shaper=ot --font-funcs=ot  /System/Library/Fonts/SFNSText.ttf "hhhHHH"
[gid698=0+1216|gid698=1+1216|gid698=2+1216|gid117=3+1520|gid117=4+1520|gid117=5+1520]

I suspect the static const hb_aat_feature_mapping_t feature_mappings[] can be improved by special casing old style kLetterCase smcp and mapping that to kLetterCase with selector kSmallCapsSelector = 3.

Apple Chancery from Mac OS 10.13 feature dump using CTFontDescriptorCopyAttribute(font_descriptor, kCTFontFeaturesAttribute);

(
        {
        CTFeatureTypeIdentifier = 1;
        CTFeatureTypeName = Ligatures;
        CTFeatureTypeNameID = 258;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = "Common Ligatures";
                CTFeatureSelectorNameID = 260;
            },
                        {
                CTFeatureSelectorIdentifier = 4;
                CTFeatureSelectorName = "Rare Ligatures";
                CTFeatureSelectorNameID = 259;
            },
                        {
                CTFeatureSelectorIdentifier = 10;
                CTFeatureSelectorName = "Diphthong Ligatures";
                CTFeatureSelectorNameID = 304;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 3;
        CTFeatureTypeName = "Letter Case";
        CTFeatureTypeNameID = 261;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "No Change";
                CTFeatureSelectorNameID = 309;
            },
                        {
                CTFeatureSelectorIdentifier = 1;
                CTFeatureSelectorName = "All Capitals";
                CTFeatureSelectorNameID = 263;
            },
                        {
                CTFeatureSelectorIdentifier = 3;
                CTFeatureSelectorName = "Small Caps";
                CTFeatureSelectorNameID = 264;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 6;
        CTFeatureTypeName = "Number Spacing";
        CTFeatureTypeNameID = 265;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "Monospaced Numbers";
                CTFeatureSelectorNameID = 266;
            },
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 1;
                CTFeatureSelectorName = "Proportional Numbers";
                CTFeatureSelectorNameID = 267;
            }
        );
    },
        {
        CTFeatureTypeIdentifier = 8;
        CTFeatureTypeName = "Smart Swashes";
        CTFeatureTypeNameID = 268;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "Word Initial Swashes";
                CTFeatureSelectorNameID = 271;
            },
                        {
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = "Word Final Swashes";
                CTFeatureSelectorNameID = 272;
            },
                        {
                CTFeatureSelectorIdentifier = 8;
                CTFeatureSelectorName = "Non-Final Swashes";
                CTFeatureSelectorNameID = 273;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 10;
        CTFeatureTypeName = "Vertical Position";
        CTFeatureTypeNameID = 274;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "No Change";
                CTFeatureSelectorNameID = 309;
            },
                        {
                CTFeatureSelectorIdentifier = 1;
                CTFeatureSelectorName = Superiors;
                CTFeatureSelectorNameID = 275;
            },
                        {
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = Inferiors;
                CTFeatureSelectorNameID = 277;
            },
                        {
                CTFeatureSelectorIdentifier = 3;
                CTFeatureSelectorName = Ordinals;
                CTFeatureSelectorNameID = 278;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 11;
        CTFeatureTypeName = Fractions;
        CTFeatureTypeNameID = 279;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "No Change";
                CTFeatureSelectorNameID = 309;
            },
                        {
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = "Diagonal Fractions";
                CTFeatureSelectorNameID = 280;
            }
        );
    },
        {
        CTFeatureTypeIdentifier = 13;
        CTFeatureTypeName = "Overlapping Characters";
        CTFeatureTypeNameID = 282;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "Prevent Overlap";
                CTFeatureSelectorNameID = 283;
            }
        );
    },
        {
        CTFeatureTypeIdentifier = 14;
        CTFeatureTypeName = "Typographic Extras";
        CTFeatureTypeNameID = 307;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 8;
                CTFeatureSelectorName = "Smart Quotes";
                CTFeatureSelectorNameID = 308;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 16;
        CTFeatureTypeName = "Ornament Sets";
        CTFeatureTypeNameID = 287;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "No Change";
                CTFeatureSelectorNameID = 309;
            },
                        {
                CTFeatureSelectorIdentifier = 3;
                CTFeatureSelectorName = Fleurons;
                CTFeatureSelectorNameID = 289;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 18;
        CTFeatureTypeName = "Design Complexity";
        CTFeatureTypeNameID = 293;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "Simple Design Level";
                CTFeatureSelectorNameID = 294;
            },
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 1;
                CTFeatureSelectorName = "Elegant Design Level";
                CTFeatureSelectorNameID = 295;
            },
                        {
                CTFeatureSelectorIdentifier = 2;
                CTFeatureSelectorName = "Flourishes Set A";
                CTFeatureSelectorNameID = 296;
            },
                        {
                CTFeatureSelectorIdentifier = 3;
                CTFeatureSelectorName = "Flourishes Set B";
                CTFeatureSelectorNameID = 297;
            }
        );
    },
        {
        CTFeatureTypeExclusive = 1;
        CTFeatureTypeIdentifier = 21;
        CTFeatureTypeName = "Number Case";
        CTFeatureTypeNameID = 299;
        CTFeatureTypeSelectors =         (
                        {
                CTFeatureSelectorDefault = 1;
                CTFeatureSelectorIdentifier = 0;
                CTFeatureSelectorName = "No Change";
                CTFeatureSelectorNameID = 309;
            },
                        {
                CTFeatureSelectorIdentifier = 1;
                CTFeatureSelectorName = "Lining Numbers";
                CTFeatureSelectorNameID = 301;
            }
        );
    }
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    ChromeChrome/Chromium project related issues and requests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions