googlefonts / fez

Font Engineering made eaZy
BSD 3-Clause "New" or "Revised" License
17 stars 2 forks source link

Multiple `Routine` declarations inside a `Feature` block causes Feature duplications in resulting `.fea` #15

Closed kalapi closed 1 year ago

kalapi commented 1 year ago

I have FEZ code like so:

Feature cjct {
    Routine triConsonantConjunctsWithRaphala {
        Substitute k-beng tta-beng $raphala -> k_tt_ra-beng;
        Substitute k-beng ssa-beng $raphala -> k_ss_ra-beng;
        ...
    } <<bng2/dflt>>;

    Routine triConsonantConjunctsWithBaphala {
        Substitute g-beng dha-beng $baphala -> g_dh_ba-beng;
        Substitute c-beng cha-beng $baphala -> c_ch_ba-beng;
        ...
    } <<bng2/dflt>>;

    Routine triConsonantConjuncts {
        Substitute n-beng s-beng tta-beng -> n_s_tta-beng;
        Substitute l-beng dd-beng rra-beng -> l_dd_rra-beng;
        ...
    } <<bng2/dflt>>;

    Routine biConsonantConjunctsWithRaphala {
        Substitute ka-beng $raphala -> k_ra-beng;
        Substitute kha-beng $raphala -> kh_ra-beng;
        ...
    } <<bng2/dflt>>;

    Routine biConsonantConjunctsWithBaphala {
        Substitute ka-beng $baphala -> k_ba-beng;
        Substitute kha-beng $baphala -> kh_ba-beng;
        ...
    } <<bng2/dflt>>;
};

This is the output i'm getting:

feature cjct {
    script bng2;
    language dflt;
            lookup triConsonantConjunctsWithRaphala;

} cjct;

feature cjct {
    script bng2;
    language dflt;
            lookup triConsonantConjunctsWithBaphala;

} cjct;

feature cjct {
    script bng2;
    language dflt;
            lookup triConsonantConjuncts;

} cjct;

feature cjct {
    script bng2;
    language dflt;
            lookup biConsonantConjunctsWithRaphala;

} cjct;

feature cjct {
    script bng2;
    language dflt;
            lookup biConsonantConjunctsWithBaphala;

} cjct;

Instead of:

feature cjct {
    script bng2;
    language dflt;
            lookup triConsonantConjunctsWithRaphala;
            lookup triConsonantConjunctsWithBaphala;
            lookup triConsonantConjuncts;
            lookup biConsonantConjunctsWithRaphala;
            lookup biConsonantConjunctsWithBaphala;
} cjct;
ctrlcctrlv commented 1 year ago

why is this a problem?

kalapi commented 1 year ago

Interesting! I'm rethinking so many of my pre-conceptions regarding feature file do–s and don't–s.

I just compiled the file and it's exactly the same as the one with all of them combined!

I apologies in advance! I'm going to ask more stupid questions, that way I can document the process and have useful notes for others.


Unrelated question: Is there are equivalent to ignore sub? If not how do you recommend implementing it?

Sample code could be something like this:

lookup abc {
    ignore substitute f [a e] d';
    ignore substitute a d' d;
    substitute [a e n] d' by d.alt;
} abc;
simoncozens commented 1 year ago

When I first started writing Fez/FontFeatures, I tried to make the .fea output look as "humanly written" as possible. But I soon gave that up because it was much easier to manage and my .fea files were going to be thousands of lines long anything. Just treat .fea as binary, and don't look too closely at it. :-)

For ignore sub, you should be writing your contextuals as chain rules anyway, so this works:

Routine abc {
    Chain f [a e] (d);
    Chain a (d) d;
    Chain [a e n] (d ^ToAlt);
};

But of course the real power of Fez is when you start writing your own plugins...

ctrlcctrlv commented 1 year ago

@kalapi In general, FEZ makes...overly verbose FEA code, but not incorrect code. In this case Simon's way is actually better, as to join feature blocks together, you have to do a process of determining which blocks have the same properties. Doing that can introduce subtle bugs if you get it wrong.