# This is a companion to squarize.py # coding=utf-8 """ Companion to squarize.py, building the stem length config according to various schemas. Copyright (C) 2016-2021 The Gregorio Project (see CONTRIBUTORS.md) This file is part of Gregorio. Gregorio is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gregorio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Gregorio. If not, see . This script takes a very simple .sfd file with a few symbols and builds a complete square notation font. See gregorio-base.sfd for naming conventions of these symbols. To build your own font, look at gregorio-base.sfd, and build your own glyphs from it. The idea here is to return a "stem schema" describing the lengths of all possible stems. Common names of variables: - font_config(dict): the font configuration (ex: content of greciliae.json) - add_suppl(boolean): if we must make queues slightly longer than their reference height. The height difference is font_config[font_config['bottom-add']] - bmu(str): "bottom" or "middle" or "top" - base (int): font_config['base height'] """ def get_default_porrectus(font_config, add_suppl, one_bottom): """ Common subfunction, gets porrectus length. """ suppl = font_config['bottom-add'] if add_suppl else 0 return { "Nothing": { "1": { "short": font_config['bottom-porrectus-1'] + suppl, "long": one_bottom }, "2": { "short": font_config['bottom-porrectus-2'] + suppl, "long": font_config['bottom-porrectus-2'] + suppl }, "3": { "short": font_config['bottom-porrectus-3'] + suppl, "long": font_config['bottom-porrectus-3'] + suppl }, "4": { "short": font_config['bottom-porrectus-4'] + suppl, "long": font_config['bottom-porrectus-4'] + suppl }, "5": { "short": font_config['bottom-porrectus-5'] + suppl, "long": font_config['bottom-porrectus-5'] + suppl } } } def get_conf(font_config, bmu, suffix, add_suppl, second_suffix=''): """ Gets a value from font_config, with fallbacks if not present. - suffix can be 'deminutus', 'oriscus', etc. - second_suffix can be 'lower' or 'upper', currently handling quilisma only. """ suffixed = bmu+'-'+suffix second_suffixed = bmu+'-'+suffix+'-'+second_suffix base = font_config[bmu] if second_suffixed in font_config: base = font_config[second_suffixed] elif suffixed in font_config: base = font_config[suffixed] if add_suppl and bmu == 'bottom': base += font_config['bottom-add'] return base def get_stem_schema_default(font_config): """ This returns Gregorio's default schema. This is adapted from 1934 Antiphonale Monasticum (AM), with a few changes: - values for ancus and salicus (not present in AM) - more consistent short virga stems. AM has a short and longer form. See line 6 page 400 for both figures side to side. The longer form is used. - ih~ and similar have a slightly shorter queue (AM 400 l. 3) - small changes for ambitus generally, queues are slightly shorter - treat similar figures with consistency (gv and ge for instance) List of some figures in the AM: - ih(ih) : AM 367, 3 (p. 367, l. 3) - hg(hg) : AM 367,4 - dc(dc) : AM 366 - ed(ed) : AM 1185,5 - ig(ig) : AM 367,6 - fd(fd) : AM 673,1 - gd(gd) : AM 531,3 - he(he) : AM 420,7 - hd(hd) : AM 1183,1 - ih~(ih~) : AM 396,1 - hg~(hg~) : AM 347,7 - dc~(dc~) : AM 397,4, AM 1182,4 - ed~(ed~) : AM 402,5 - ge~(ge~) : AM 239,4 - gd~(gd~) : AM 239,3 - gc~(gc~) : AM 397,5 """ base = font_config['base height'] # these are used for both virga and flexus deminutus with ambitus one, for coherence virga_long = get_conf(font_config, 'bottom', '', False) - 2*base virga_short = get_conf(font_config, 'middle', '', False) - 2*base virga_open = get_conf(font_config, 'bottom', '', False) - base def get_basic(suffix, add_suppl=False, second_suffix=''): """ Common function for flexus, pes quadratum, pes quassus, etc. """ bottom = get_conf(font_config, 'bottom', suffix, add_suppl, second_suffix) middle = get_conf(font_config, 'middle', suffix, add_suppl, second_suffix) top = get_conf(font_config, 'top', suffix, add_suppl, second_suffix) # using lower version for bottom of quilisma when second is on a line bottom_lower = get_conf(font_config, 'bottom', suffix, add_suppl, 'lower') return { "1": { # ignoring the suffix for coherence "short": virga_short, "long": virga_long, "open": virga_open }, "2": { "short": virga_short, "long": virga_long }, "3": { "short": middle - 3*base, "long": bottom_lower - 3*base }, "4": { "short": top - 4*base, "long": top - 4*base }, "5": { "short": top - 4*base, "long": top - 4*base } } return { "ignore j": True, "Virga": { "Nothing": { "short": virga_short, "open": virga_open, "long": virga_long } }, "Flexus": { "Nothing": get_basic(''), "DeminutusFirst": get_basic('deminutus-first'), "Deminutus": { "1": { "short": font_config['middle'] - 2*base, "long": font_config['top'] - 3*base, "open": font_config['bottom-deminutus'] - base }, "2": { "short": font_config['bottom'] -2*base, "long": font_config['bottom'] - 2*base, }, "3": { "long": font_config['top'] - 3*base, "short": font_config['top'] - 3*base }, "4": { "long": font_config['top'] - 4*base, "short": font_config['top-deminutus'] - 4*base, }, "5": { "long": font_config['top'] - 4*base, "short": font_config['top-deminutus'] - 4*base, } } }, "PesQuilismaQuadratum": { "Nothing": get_basic('quilisma', False, 'upper') }, "PesQuassus": { "Nothing": get_basic('oriscus', False) }, "Porrectus": get_default_porrectus(font_config, False, virga_long) } def get_stem_schema_solesmes(font_config): """ This stem schema has been provided directly by a contact at Abbey of Solesmes. """ base = font_config['base height'] def get_bottom(suffix, add_suppl=True, second_suffix=''): """ Shortcut for get_config with common options """ return get_conf(font_config, 'bottom', suffix, add_suppl, second_suffix) def get_basic(suffix, add_suppl=True, second_suffix=''): """ Common function for flexus, pes quadratum, pes quassus, etc. """ bottom = get_bottom(suffix, add_suppl, second_suffix) # for ambitus one, it must have the same height as the virga for coherece, so ignoing suffix bottom_one = get_bottom('', True, second_suffix) return { "1": { "short": bottom_one - base, "long": bottom_one - 2*base, "open": bottom_one - base }, "2": { "short": bottom - 2*base, "long": bottom - 2*base }, "3": { "short": bottom - 3*base, "long": bottom - 3*base }, "4": { "short": bottom - 4*base, "long": bottom - 4*base }, "5": { "short": bottom - 5*base, "long": bottom - 5*base } } bottom_virga = get_bottom('') return { "ignore j": True, "Virga": { "Nothing": { "short": bottom_virga - base, "open": bottom_virga - base, "long": bottom_virga - 2*base } }, "Flexus": { "Nothing": get_basic(''), "Deminutus": get_basic(''), "DeminutusFirst": get_basic('deminutus-first') }, "PesQuilismaQuadratum": { "Nothing": get_basic('quilisma', False, 'lower') }, "PesQuassus": { "Nothing": get_basic('oriscus', False) }, "Porrectus": get_default_porrectus(font_config, True, bottom_virga - 2*base) } def get_stem_schema(schemaname, font_config): """ Function called by squarize.py, returns the stem schema. """ if schemaname == 'default': return get_stem_schema_default(font_config) elif schemaname == 'solesmes': return get_stem_schema_solesmes(font_config) print('impossible to find schema %s, quitting' % schemaname)