Giter VIP home page Giter VIP logo

python-modules's Introduction

codecov

AFDKO Python Modules

Installation

pip3 install git+https://github.com/adobe-type-tools/python-modules

kernFeatureWriter.py

This tool exports the kerning and groups data within a UFO to a makeotf-compatible GPOS kern feature file.

Default functionality:

  • writing of a sorted kern.fea file, which organizes pairs in order of specificity (exceptions first, then glyph-to-glyph, then group pairs)
  • filtering of small pairs (often results of interpolation).
    Exceptions (even though they may be small) are not filtered.
  • processing of right-to-left pairs (given that kerning groups containing those glyphs are suffixed with _ARA, _HEB, or _RTL)

Optional functionality:

  • dissolving single-element groups into glyph pairs – this helps with subtable optimization, and can be seen as a means to avoid kerning overflow
  • subtable measuring and automatic insertion of subtable breaks
  • specifying a maximum subtable size
  • identification of glyph-to-glyph RTL pairs by way of a global RTL_KERNING reference group
  • specifying a glyph name suffix for glyphs to be ignored when writing the kern feature

Usage:

    # write a basic kern feature file
    python kernFeatureWriter.py font.ufo

    # write a kern feature file with minimum absolute kerning value of 5
    python kernFeatureWriter.py -min 5 font.ufo

    # write a kern feature with subtable breaks
    python kernFeatureWriter.py -s font.ufo

    # further usage information
    python kernFeatureWriter.py -h

markFeatureWriter.py

This tool interprets glyphs and anchor points within a UFO to write a makeotf-compatible GPOS mark feature file.

The input UFO file needs to have base glyphs and zero-width combining marks. Base- and mark glyphs attach via anchor pairs (e.g. above and _above, or top, and _top). Combining marks must be members of a COMBINING_MARKS reference group.

Default functionality:

  • writing a mark.fea file, which contains mark classes/groups, and per-anchor mark-to-base positioning lookups (GPOS lookup type 4)
  • writing mark-to-ligature positioning lookups (GPOS lookup type 5). This requires anchor names to be suffixed with an ordinal (1ST, 2ND, 3RD, etc). For example – if a mark with an _above anchor is to be attached to a ligature, the ligature’s anchor names would be above1ST, above2ND, etc – depending on the amount of ligature elements.

Optional functionality:

  • writing mkmk.fea, for mark-to-mark positioning (GPOS lookup type 6)

  • writing abvm.fea/blwm.fea files, as used in Indic scripts (anchor pairs are abvm, _abvm, and blwm, _blwm, respectively)

  • writing mark classes into a separate file (in case classes need to be shared across multiple lookup types)

  • trimming casing tags (UC, LC, or SC)

    Trimming tags is a somewhat specific feature, but it is quite essential: In a UFO, anchors can be used to build composite glyphs – for example aacute, and Aacute. Since those glyphs would often receive a differently-shaped accent, the anchor pairs (on bases a/A and marks acutecmb/acutecmb.cap) would be aboveLC/_aboveLC, and aboveUC/_aboveUC, respectively.

    When writing the mark feature, we care more about which group of combining marks triggers a certain behavior, so removing those casing tags allows grouping all _above marks together, hence attaching to a base glyph – no matter if it is upper- or lowercase. The aesthetic substitution of the mark (e.g. smaller mark on the uppercase letter) can happen later, in the ccmp feature.

Usage:

    # write a basic mark feature
    python markFeatureWriter.py font.ufo

    # write mark and mkmk feature files
    python markFeatureWriter.py -m font.ufo

    # trim casing tags
    python markFeatureWriter.py -t font.ufo

    # further usage information
    python markFeatureWriter.py -h

Both kern- and mark feature writers export raw feature data, which still needs to be wrapped with feature “fence”. This is easily achieved with an include statement:

feature kern{
    include(kern.fea);

} kern;

The benefit of this is that different feature flags can be used (example), or that mark groups can be shared across mark/mkmk features. Also, the (sometimes volatile) GPOS feature data can be re-generated periodically without affecting the overall structure of the feature tree.


  • flKernExport.py
    FLS5 script to export class kerning to UFO. Superseded by vfb3ufo.

Other modules are FontLab scripts which were used in pre-UFO days in a FLS5 environment. Those modules are not in active development.

  • AdobeFontLabUtils.py
    Support module for FontLab scripts. Defines commonly used functions and globals.

  • BezChar.py
    This module converts between a FontLab glyph and a bez file data string. Used by the OutlineCheck and AutoHint scripts, to convert FL glyphs to bez programs as needed by C libraries that do the hard work.

  • WriteFeaturesKernFDK.py
    Former kern feature writer.

  • WriteFeaturesMarkFDK.py
    Former mark feature writer.

python-modules's People

Contributors

arialcrime avatar arno-enslin avatar benkiel avatar codacy-badger avatar ethancohen avatar frankrolf avatar miguelsousa avatar pauldhunt avatar readroberts avatar roberto-arista avatar typoman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-modules's Issues

markfeaturewriter makes wrong assumptions

The markfeaturewriter assumes the existence of combining mark glyphs based on anchor names in base glyphs. In the attached example UFO, o and u contain hornLC anchors, however no combining horn exists. Nevertheless, the following lookup is written, which will cause a failure downstream (since @MC_hornLC simply is not defined):

lookup MARK_BASE_hornLC {
	pos base O <anchor 469 646> mark @MC_hornLC;
	pos base U <anchor 525 666> mark @MC_hornLC;
	pos base o <anchor 364 486> mark @MC_hornLC;
	pos base u <anchor 411 496> mark @MC_hornLC;
} MARK_BASE_hornLC;

markfeaturewriter bug.zip

[markFeatureWriter] Duplicate mark classes data

Running the script generates the expected markclasses.fea and mark.fea files, but it also prepends the content from the markclasses.fea file to the mark.fea file, which makes makeOTF unhappy, and it will fail to build if you include markclasses.fea.

kernFeatureWriter – streamline subtable report

When writing the kerning (with subtables) for a RTL font, the following output appears:

coverage table size: 1122
max subtable size: 8192
1 subtables created
coverage table size: 1122
max subtable size: 8192
3 subtables created
coverage table size: 1122
max subtable size: 8192
3 subtables created
coverage table size: 1122
max subtable size: 8192
3 subtables created

One for glyph/class, one for class/class, and two more for the RTL equivalent.
This is too much output, and not so interesting for the end user.

[WriteFeaturesKernFDK] Warnings in FontLab, errors in FontValidator

I’m adding a kern feature in FontLab with WriteFeaturesKernFDK.py. The resulting kern feature code generates warnings when compiling the font (as well as in FL or with makeotf). This is the generated kern feature:

feature kern {
@LAT_i_LEFT = [i igrave iacute icircumflex idieresis itilde imacron ibreve iogonek];
@LAT_i_RIGHT = [i igrave iacute icircumflex idieresis itilde imacron ibreve iogonek];

# glyph, glyph:
pos iacute icircumflex 29;
pos iacute igrave 38;
pos ibreve icircumflex 38;
pos icircumflex ibreve 38;
pos icircumflex icircumflex 38;
pos icircumflex idieresis 38;
pos icircumflex imacron 38;
pos icircumflex itilde 55;
pos idieresis icircumflex 38;
pos idieresis itilde 55;
pos imacron icircumflex 38;
pos itilde icircumflex 48;

# glyph, group exceptions:
enum pos icircumflex @LAT_i_RIGHT 14;
enum pos idieresis @LAT_i_RIGHT 19;
enum pos itilde @LAT_i_RIGHT 17;

# group, glyph exceptions:
enum pos @LAT_i_LEFT icircumflex 14;
enum pos @LAT_i_LEFT idieresis 14;
enum pos @LAT_i_LEFT imacron 14;
enum pos @LAT_i_LEFT itilde 14;

# glyph, group:

# group, glyph and group, group:
} kern;

And the warning is:

[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: iacute icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: icircumflex icircumflex
[NOTE] <MarsTestSerif-BoldItalic> Removing duplicate pair positioning in 'kern' feature: icircumflex icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: icircumflex idieresis
[NOTE] <MarsTestSerif-BoldItalic> Removing duplicate pair positioning in 'kern' feature: icircumflex idieresis
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: icircumflex itilde
[NOTE] <MarsTestSerif-BoldItalic> Removing duplicate pair positioning in 'kern' feature: icircumflex itilde
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: icircumflex imacron
[NOTE] <MarsTestSerif-BoldItalic> Removing duplicate pair positioning in 'kern' feature: icircumflex imacron
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: icircumflex ibreve
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis idieresis
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis itilde
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis itilde
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: idieresis imacron
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: itilde icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: itilde icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: itilde idieresis
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: itilde itilde
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: itilde imacron
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: imacron icircumflex
[WARNING] <MarsTestSerif-BoldItalic> Pair positioning has two different values in 'kern' feature; choosing the smaller absolute value: ibreve icircumflex

The FL kerning seems to be valid ...

In addition, there is a problem that makeotf doesn’t actually seem to ignore or choose one of the duplicated positioning entries, so both are written into the GPOS table. This results in a FontValidator error E4101 The array order is incorrect (glyph ids are repeated, thus they are not sorted ascending as required by the OT spec).

I’m not sure if what’s at fault here ... FL, WriteFeaturesKernFDK, or makeotf?

A minimal example VFB is attached: MarsTestSerif-BoldItalic.zip

Disperse repository?

I have an impression the notion of a separate python-modules repo may be somewhat outdated. The only “modules-only” scripts are AdobeFontlabUtils.py and BezChar.py, which could be moved to the FontLab Scripts repo.
With adding a few lines of code, most other modules could be made into directly-useable scripts (some already are), and then placed into the python-scripts repo.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.