The substitution BLACK_FLAG + CANCEL_TAG => UNKNOWN_FLAG is alrady handled by the _add_fallback_subs_for_unknown_flags method, added in the previous commit.
There's no BLACK_FLAG + CANCEL_TAG => BLACK_FLAG substituion in the current NotoColorEmoji.ttf CBDT font.
In fact, it makes much more sense that all unsupported subdivision flag sequences, i.e. BLACK_FLAG + (zero or more non-cancel tags) + CANCEL_TAG, are all displayed with the unknown flag. No reason to special case BLACK_FLAG + CANCEL_TAG.
I'm not sure where the conclusion about the BLACK_FLAG + CANCEL_TAG => BLACK_FLAG came from (got to ask Rod).
Any invalid/unsupported emoji flag sequence (whether using regional indicators or subdivision tags) gets replaced by the 'unknown flag' (PUA 0xFE28B), a flag with a blue question mark in the middle.
The logic is mutated from the GSUB table of NotoColorEmoji.tmpl.ttx. We build these extra lookups using feaLib on an temporary empty font (that matches the glyph order of our destination CORLv1 font), then update our font's GSUB with them.
The PUA for the unknown flag is then removed from the cmap, as it's no longer needed. It's also deleted from the CBDT NotoColorEmoji (see emoji_builder.py).
copy values from CBDT font, adapt to the different UPEM (CBDT has 2048, COLRv1 has 1024, nanoemoji's default)
Maybe we shold just make the UPEM the same for both?