From 2188c2d237eab62054ad0e746fa624cb1c85a795 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 24 Jan 2022 18:06:46 +0000 Subject: [PATCH] also add soft-light to flags from emoji_aliases.txt --- colrv1_add_soft_light_to_flags.py | 91 ++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 20 deletions(-) diff --git a/colrv1_add_soft_light_to_flags.py b/colrv1_add_soft_light_to_flags.py index c23a751db..0acd767b7 100644 --- a/colrv1_add_soft_light_to_flags.py +++ b/colrv1_add_soft_light_to_flags.py @@ -5,10 +5,35 @@ from fontTools import ttLib from fontTools.ttLib.tables import otTables as ot from fontTools.ttLib.tables.C_P_A_L_ import Color from fontTools.colorLib.builder import LayerListBuilder +from add_aliases import read_default_emoji_aliases from flag_glyph_name import flag_code_to_glyph_name from map_pua_emoji import get_glyph_name_from_gsub +REGIONAL_INDICATOR_RANGE = range(0x1F1E6, 0x1F1FF + 1) +BLACK_FLAG = 0x1F3F4 +CANCEL_TAG = 0xE007F +TAG_RANGE = range(0xE0000, CANCEL_TAG + 1) + + +def is_flag(sequence): + # regular region flags are comprised of regional indicators + if all(cp in REGIONAL_INDICATOR_RANGE for cp in sequence): + return True + + # subdivision flags start with black flag, contain some tag characters and end with + # a cancel tag + if ( + len(sequence) > 2 + and sequence[0] == BLACK_FLAG + and sequence[-1] == CANCEL_TAG + and all(cp in TAG_RANGE for cp in sequence[1:-1]) + ): + return True + + return False + + def read_makefile_variable(var_name): # see `print-%` command in Makefile value = subprocess.run( @@ -26,6 +51,19 @@ def flag_code_to_sequence(flag_code): return tuple(int(v, 16) for v in name[1:].split("_")) +def all_flag_sequences(): + """Return the set of all noto-emoji's region and subdivision flag sequences. + These include those in SELECTED_FLAGS Makefile variable plus those listed + in the 'emoji_aliases.txt' file. + """ + result = { + flag_code_to_sequence(flag_code) + for flag_code in read_makefile_variable("SELECTED_FLAGS").split() + } + result.update(seq for seq in read_default_emoji_aliases() if is_flag(seq)) + return result + + _builder = LayerListBuilder() @@ -96,6 +134,38 @@ def _soft_light_gradient(cpal): ) +def flag_ligature_glyphs(font): + """Yield ligature glyph names for all the region/subdivision flags in the font.""" + for flag_sequence in all_flag_sequences(): + flag_name = get_glyph_name_from_gsub(flag_sequence, font) + if flag_name is not None: + yield flag_name + + +def add_soft_light_to_flags(font, flag_glyph_names=None): + """Add soft-light effect to region and subdivision flags in CORLv1 font.""" + if flag_glyph_names is None: + flag_glyph_names = flag_ligature_glyphs(font) + + colr_glyphs = { + rec.BaseGlyph: rec + for rec in font["COLR"].table.BaseGlyphList.BaseGlyphPaintRecord + } + cpal = font["CPAL"] + + for flag_name in flag_glyph_names: + flag = colr_glyphs[flag_name] + flag.Paint = _paint_composite( + source=_paint_composite( + source=_soft_light_gradient(cpal), + mode=ot.CompositeMode.SRC_IN, + backdrop=flag.Paint, + ), + mode=ot.CompositeMode.SOFT_LIGHT, + backdrop=flag.Paint, + ) + + def main(): try: input_file, output_file = sys.argv[1:] @@ -109,26 +179,7 @@ def main(): print("error: missing required COLRv1 table") return 1 - colr_glyphs = { - rec.BaseGlyph: rec - for rec in font["COLR"].table.BaseGlyphList.BaseGlyphPaintRecord - } - cpal = font["CPAL"] - - for flag_code in read_makefile_variable("SELECTED_FLAGS").split(): - flag_sequence = flag_code_to_sequence(flag_code) - flag_name = get_glyph_name_from_gsub(flag_sequence, font) - if flag_name is not None: - flag = colr_glyphs[flag_name] - flag.Paint = _paint_composite( - source=_paint_composite( - source=_soft_light_gradient(cpal), - mode=ot.CompositeMode.SRC_IN, - backdrop=flag.Paint, - ), - mode=ot.CompositeMode.SOFT_LIGHT, - backdrop=flag.Paint, - ) + add_soft_light_to_flags(font) font.save(output_file)