diff options
Diffstat (limited to 'Master/texmf-dist/fonts/source/gregoriotex/squarize.py')
-rw-r--r-- | Master/texmf-dist/fonts/source/gregoriotex/squarize.py | 2432 |
1 files changed, 2432 insertions, 0 deletions
diff --git a/Master/texmf-dist/fonts/source/gregoriotex/squarize.py b/Master/texmf-dist/fonts/source/gregoriotex/squarize.py new file mode 100644 index 00000000000..2f42bfca794 --- /dev/null +++ b/Master/texmf-dist/fonts/source/gregoriotex/squarize.py @@ -0,0 +1,2432 @@ +# This is a fontforge python script; use fontforge -lang=py -script to run it +# coding=utf-8 +# pylint: disable=too-many-branches, too-many-arguments, too-many-lines +# pylint: disable=import-error, no-member, C0326 + +""" + Python fontforge script to build a square notation font. + + Copyright (C) 2013-2016 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 <http://www.gnu.org/licenses/>. + + 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. +""" + +from __future__ import print_function + +import sys +import os +import os.path +import json +import argparse +import fontforge +import psMat +import stemsschemas + +GPLV3 = """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 this program. If not, see <http://www.gnu.org/licenses/>. + +As a special exception, if you create a document which uses this font, +and embed this font or unaltered portions of this font into the +document, this font does not by itself cause the resulting document to +be covered by the GNU General Public License. This exception does not +however invalidate any other reasons why the document might be covered +by the GNU General Public license. If you modify this font, you may +extend this exception to your version of the font, but you are not +obligated to do so. If you do not wish to do so, delete this exception +statement from your version.""" + +# defines the maximal interval between two notes, the bigger this number is, +# the more glyphs you'll have to generate +MAX_INTERVAL = 5 + +# this dictionary must have a value for 1 up to MAX_INTERVAL +AMBITUS = { + 1: 'One', + 2: 'Two', + 3: 'Three', + 4: 'Four', + 5: 'Five', +} + +GREGORIO_VERSION = '4.1.1' + +# The unicode character at which we start our numbering: +# U+E000 is the start of the BMP Private Use Area +glyphnumber = 0xe000 - 1 + +# see defaults in get_parser() +FONT_CONFIG = None +STEM_SCHEMA = None +oldfont = None +newfont = None +font_name = None +subspecies = None +all_glyph_names = {} + +def get_parser(): + "Return command line parser" + parser = argparse.ArgumentParser( + description="""Converts a small set of glyphs into a complete +gregorian square notation font. The initial glyphs have a name +convention, see gregorio-base.sfd.""") + parser.add_argument('-o', '--outfile', + help='output ttf file name', + action='store', default=False, dest='outfile') + parser.add_argument('-s', '--sub-species', + help='subspecies (can be \'op\')', + action='store', default=False, dest='subspecies') + parser.add_argument('-c', '--config-font', + help='font-specific configuration', + action='store', dest='config_file') + parser.add_argument('-n', '--name', + help='name of the font, should match output file name to be found by luaotfload', + action='store', default=False, dest='font_name') + parser.add_argument('-sc', '--stems-schema', + help='stem length schema, can be \'default\' or \'solesmes\'', + action='store', default='default', dest='stems_schema') + parser.add_argument('base_font', help="input sfd file name", action='store') + return parser + +def main(): + "Main function" + global oldfont, newfont, font_name, subspecies, FONT_CONFIG, STEM_SCHEMA + parser = get_parser() + if len(sys.argv) == 1: + parser.print_help() + sys.exit(1) + args = parser.parse_args() + with open(args.config_file, 'r') as stream: + font_config = json.load(stream) + subspecies = '_%s' % args.subspecies if args.subspecies else '' + if 'base height' not in font_config: + font_config['base height'] = 157.5 + if 'hepisema additional width' not in font_config: + font_config['hepisema additional width'] = 5 + if 'deminutus vertical shift' not in font_config: + font_config['deminutus vertical shift'] = 10 + if 'additional upper queue height' not in font_config: + font_config['additional upper queue height'] = 10 + FONT_CONFIG = font_config + STEM_SCHEMA = stemsschemas.get_stem_schema(args.stems_schema, font_config) + outfile = args.outfile + inputfile = args.base_font + if not outfile: + pre = os.path.splitext(inputfile) + outfile = '%s.ttf' % pre + oldfont = fontforge.open(inputfile) + if args.font_name: + font_name = args.font_name + else: + font_name = oldfont.fontname + if args.subspecies: + font_name = '%s-%s' % (font_name, args.subspecies) + newfont = fontforge.font() + # newfont.encoding = "UnicodeFull" + newfont.encoding = "ISO10646-1" + newfont.fontname = font_name + newfont.fullname = font_name + newfont.familyname = font_name + newfont.version = GREGORIO_VERSION + newfont.copyright = oldfont.copyright.replace('<<GPLV3>>', GPLV3) + newfont.weight = "regular" + initialize_glyphs() + hepisema() + measures() + virga() + pes() + pes_quadratum() + virga_strata() + flexus() + scandicus() + ancus() + salicus() + salicus_flexus() + torculus() + torculus_liquescens() + porrectus() + porrectusflexus() + torculusresupinus() + leading() + fusion() + fusion_pes() + fusion_pes_quadratum() + fusion_flexus() + fusion_porrectus() + # variants must be copied last! + copy_variant_glyphs() + newfont.generate(outfile) + oldfont.close() + newfont.close() + print('last code point in', font_name, 'is', hex(glyphnumber)) + +def new_glyph(): + """ Create a new glyph and select it. + """ + global newfont, glyphnumber + glyphnumber += 1 + if glyphnumber > 0xf8ff: + print("WARNING: exceeded private use area") + newfont.selection.select('u%05x' % glyphnumber) + +def set_glyph_name(name): + """ Sets the name of current glyph. + """ + global all_glyph_names, newfont, glyphnumber + if name in all_glyph_names: + print("ERROR: duplicate glyph name [%s]" % name, file=sys.stderr) + sys.exit(1) + else: + all_glyph_names[name] = True + newfont[glyphnumber].glyphname = name + +def message(glyph_name): + """Prints a message to stdout, so that the user gets less bored when + building the font. + """ + print("generating", glyph_name, "for", font_name) + +def precise_message(glyph_name): + "Prints more information to entertain the user." + print(" *", glyph_name) + +# These names must consist wholly of ASCII letters +DIRECT_GLYPH_NAMES = [ + 'CClef', + 'FClef', + 'CClefChange', + 'FClefChange', + 'Flat', + 'Natural', + 'Virgula', + 'DivisioMinima', + 'DivisioMinor', + 'DivisioMaior', + 'PunctumDeminutus', + 'AuctumMora', + 'Punctum', + 'PunctumInclinatum', + 'Stropha', + 'StrophaAucta', + 'StrophaAuctaLongtail', + 'VirgaBaseLineBL', + 'Quilisma', + 'QuilismaLineTR', + 'Oriscus', + 'OriscusLineBL', + 'OriscusLineTR', + 'OriscusReversus', + 'OriscusReversusLineTL', + 'PunctumInclinatumAuctus', + 'PunctumInclinatumDeminutus', + 'VEpisema', + 'VEpisema.circumflexus', + 'PunctumCavum', + 'LineaPunctum', + 'LineaPunctumCavum', + 'Circulus', + 'Semicirculus', + 'Accentus', + 'CustosUpLong', + 'CustosUpShort', + 'CustosUpMedium', + 'CustosDownLong', + 'CustosDownShort', + 'CustosDownMedium', + 'AccentusReversus', + 'SemicirculusReversus', + 'PunctumAscendens', + 'PunctumDescendens', + 'PunctumCavumHole', + 'LineaPunctumCavumHole', + 'FlatHole', + 'NaturalHole', + 'DivisioDominican', + 'DivisioDominicanAlt', + 'Sharp', + 'SharpHole', + 'Linea', + 'RoundBrace', + 'CurlyBrace', + 'BarBrace', + 'RoundBraceDown', + 'OriscusDeminutus', + 'PunctumSmall', + 'PunctumLineBR', + 'PunctumLineBL', + 'PunctumLineTL', + 'PunctumLineTR', + 'PunctumLineBLBR', + 'PunctumAuctusLineBL', + 'SalicusOriscus', + 'PunctumCavumInclinatum', + 'PunctumCavumInclinatumHole', + 'PunctumCavumInclinatumAuctus', + 'PunctumCavumInclinatumAuctusHole', + 'OriscusCavum', + 'OriscusCavumHole', + 'OriscusCavumReversus', + 'OriscusCavumReversusHole', + 'OriscusCavumDeminutus', + 'OriscusCavumDeminutusHole', +] + +GLYPH_EXISTS = {} + +def glyph_exists(glyph_name): + "returns if glyph named glyphName exists in font (boolean)" + global GLYPH_EXISTS, oldfont + if glyph_name in GLYPH_EXISTS: + return GLYPH_EXISTS[glyph_name] + result = True + try: + oldfont.selection.select(glyph_name) + except: + result = False + GLYPH_EXISTS[glyph_name] = result + return result + +def subspecies_of(glyph_name): + if subspecies and glyph_exists(glyph_name + subspecies): + return glyph_name + subspecies + else: + return glyph_name + +def copy_existing_glyph(glyph_name): + "copies the named glyph, if it exists, and returns whether it was copied" + subglyph_name = subspecies_of(glyph_name) + if subglyph_name != glyph_name and glyph_exists(subglyph_name): + complete_paste(subglyph_name) + set_glyph_name(glyph_name) + return True + elif glyph_exists(glyph_name): + complete_paste(glyph_name) + set_glyph_name(glyph_name) + return True + else: + return False + +# This will be populated by initialize_glyphs +COMMON_DIRECT_VARIANTS = {} + +def initialize_glyphs(): + "Builds the first glyphs." + global newfont, oldfont, font_name + # DIRECT_GLYPH_NAMES are the names of the glyphs that are already in + # gregorio_base, mostly one-note glyphs. + DIRECT_GLYPH_NAMES.sort() + for name in DIRECT_GLYPH_NAMES: + new_glyph() + if glyph_exists(name): + oldfont.selection.select(subspecies_of(name)) + oldfont.copy() + newfont.paste() + set_glyph_name(name) + if name.find('.') > 0: + COMMON_DIRECT_VARIANTS[name] = True + else: + print('Warning: glyph '+name+' missing from '+font_name) + +def copy_variant_glyphs(): + "Copies the variant glyphs." + global newfont, oldfont + for glyph in oldfont.glyphs(): + name = glyph.glyphname + if (glyph.isWorthOutputting() and name.find(".") > 0 and + name.find("_") == -1 and name not in COMMON_DIRECT_VARIANTS): + new_glyph() + oldfont.selection.select(subspecies_of(name)) + oldfont.copy() + newfont.paste() + set_glyph_name(name) + +# this will be populated by get_width +WIDTHS = {} + +def get_width(glyphName): + "Get length of glyph glyphName in the base font." + global oldfont + if glyphName not in WIDTHS: + if glyph_exists(glyphName): + WIDTHS[glyphName] = oldfont[subspecies_of(glyphName)].width + else: + WIDTHS[glyphName] = 0 + return WIDTHS[glyphName] + +# Shapes +S_PES = 'Pes' +S_UPPER_PES = 'UpperPes' +S_LOWER_PES = 'LowerPes' +S_PES_QUADRATUM = 'PesQuadratum' +S_UPPER_PES_QUADRATUM = 'UpperPesQuadratum' +S_LOWER_PES_QUADRATUM = 'LowerPesQuadratum' +S_PES_QUADRATUM_LONGQUEUE = 'PesQuadratumLongqueue' +S_UPPER_PES_QUADRATUM_LONGQUEUE = 'UpperPesQuadratumLongqueue' +S_LOWER_PES_QUADRATUM_LONGQUEUE = 'LowerPesQuadratumLongqueue' +S_PES_QUADRATUM_OPENQUEUE = 'PesQuadratumOpenqueue' +S_UPPER_PES_QUADRATUM_OPENQUEUE = 'UpperPesQuadratumOpenqueue' +S_LOWER_PES_QUADRATUM_OPENQUEUE = 'LowerPesQuadratumOpenqueue' +S_PES_QUILISMA = 'PesQuilisma' +S_PES_QUASSUS = 'PesQuassus' +S_UPPER_PES_QUASSUS = 'UpperPesQuassus' +S_LOWER_PES_QUASSUS = 'LowerPesQuassus' +S_PES_QUASSUS_LONGQUEUE = 'PesQuassusLongqueue' +S_UPPER_PES_QUASSUS_LONGQUEUE = 'UpperPesQuassusLongqueue' +S_LOWER_PES_QUASSUS_LONGQUEUE = 'LowerPesQuassusLongqueue' +S_PES_QUASSUS_OPENQUEUE = 'PesQuassusOpenqueue' +S_UPPER_PES_QUASSUS_OPENQUEUE = 'UpperPesQuassusOpenqueue' +S_LOWER_PES_QUASSUS_OPENQUEUE = 'LowerPesQuassusOpenqueue' +S_PES_QUILISMA_QUADRATUM = 'PesQuilismaQuadratum' +S_PES_QUILISMA_QUADRATUM_LONGQUEUE = 'PesQuilismaQuadratumLongqueue' +S_PES_QUILISMA_QUADRATUM_OPENQUEUE = 'PesQuilismaQuadratumOpenqueue' +S_FLEXUS = 'Flexus' +S_UPPER_FLEXUS = 'UpperFlexus' +S_LOWER_FLEXUS = 'LowerFlexus' +S_FLEXUS_NOBAR = 'FlexusNobar' +S_FLEXUS_LONGQUEUE = 'FlexusLongqueue' +S_FLEXUS_OPENQUEUE = 'FlexusOpenqueue' +S_FLEXUS_ORISCUS = 'FlexusOriscus' +S_LOWER_FLEXUS_ORISCUS = 'LowerFlexusOriscus' +S_PORRECTUS_FLEXUS = 'PorrectusFlexus' +S_PORRECTUS_FLEXUS_LONGQUEUE = 'PorrectusFlexusLongqueue' +S_PORRECTUS_FLEXUS_NOBAR = 'PorrectusFlexusNobar' +S_PORRECTUS = 'Porrectus' +S_PORRECTUS_LONGQUEUE = 'PorrectusLongqueue' +S_PORRECTUS_NOBAR = 'PorrectusNobar' +# for stem length determination only: +S_PORRECTUS_DEMINUTUS_ALT = 'PorrectusDeminutus.alt' +S_TORCULUS = 'Torculus' +S_TORCULUS_RESUPINUS = 'TorculusResupinus' +S_TORCULUS_QUILISMA = 'TorculusQuilisma' +S_TORCULUS_RESUPINUS_QUILISMA = 'TorculusResupinusQuilisma' +S_SCANDICUS = 'Scandicus' +S_ANCUS = 'Ancus' +S_ANCUS_LONGQUEUE = 'AncusLongqueue' +S_ANCUS_OPENQUEUE = 'AncusOpenqueue' +S_VIRGA_STRATA = 'VirgaStrata' +S_SALICUS = 'Salicus' +S_SALICUS_LONGQUEUE = 'SalicusLongqueue' +S_SALICUS_OPENQUEUE = 'SalicusOpenqueue' +S_SALICUS_FLEXUS = 'SalicusFlexus' +S_TORCULUS_LIQUESCENS = 'TorculusLiquescens' +S_TORCULUS_LIQUESCENS_QUILISMA = 'TorculusLiquescensQuilisma' +S_FLEXUS_ORISCUS_SCAPUS = 'FlexusOriscusScapus' +S_FLEXUS_ORISCUS_SCAPUS_LONGQUEUE = 'FlexusOriscusScapusLongqueue' +S_FLEXUS_ORISCUS_SCAPUS_OPENQUEUE = 'FlexusOriscusScapusOpenqueue' +S_LEADING_PUNCTUM = 'LeadingPunctum' +S_LEADING_QUILISMA = 'LeadingQuilisma' +S_LEADING_ORISCUS = 'LeadingOriscus' +S_PUNCTUM = 'Punctum' +S_UPPER_PUNCTUM = 'UpperPunctum' +S_LOWER_PUNCTUM = 'LowerPunctum' +S_QUILISMA = 'Quilisma' +S_ORISCUS = 'Oriscus' +S_ORISCUS_SCAPUS = 'OriscusScapus' +S_ORISCUS_SCAPUS_LONGQUEUE = 'OriscusScapusLongqueue' +S_ORISCUS_SCAPUS_OPENQUEUE = 'OriscusScapusOpenqueue' +S_ORISCUS_REVERSUS_SCAPUS = 'OriscusScapusReversus' +S_ORISCUS_REVERSUS_SCAPUS_LONGQUEUE= 'OriscusScapusReversusLongqueue' +S_ORISCUS_REVERSUS_SCAPUS_OPENQUEUE= 'OriscusScapusReversusOpenqueue' +S_UPPER_ORISCUS = 'UpperOriscus' +S_LOWER_ORISCUS = 'LowerOriscus' +S_VIRGA = 'Virga' +S_VIRGA_LONGQUEUE = 'VirgaLongqueue' +S_VIRGA_OPENQUEUE = 'VirgaOpenqueue' +S_VIRGA_REVERSA = 'VirgaReversa' +S_VIRGA_REVERSA_LONGQUEUE = 'VirgaReversaLongqueue' +S_VIRGA_REVERSA_OPENQUEUE = 'VirgaReversaOpenqueue' + +# Liquescentiae +L_NOTHING = 'Nothing' +L_INITIO_DEBILIS = 'InitioDebilis' +L_DEMINUTUS = 'Deminutus' +L_ASCENDENS = 'Ascendens' +L_DESCENDENS = 'Descendens' +L_UP = 'Up' +L_DOWN = 'Down' +L_INITIO_DEBILIS_DEMINUTUS = 'InitioDebilisDeminutus' +L_INITIO_DEBILIS_ASCENDENS = 'InitioDebilisAscendens' +L_INITIO_DEBILIS_DESCENDENS = 'InitioDebilisDescendens' +L_INITIO_DEBILIS_UP = 'InitioDebilisUp' +# A very special case for stem length: when the queue of ancus must go to the +# bottom of the second note (which is the first note of a deminutus), we use +# this. +L_DEMINUTUS_FIRST = "DeminutusFirst" + +def simple_paste(src): + "Copy and paste a glyph." + global oldfont, newfont, glyphnumber + oldfont.selection.select(subspecies_of(src)) + oldfont.copy() + newfont.selection.select('u%05x' % glyphnumber) + newfont.pasteInto() + +def complete_paste(src): + "Copy and paste a glyph." + global oldfont, newfont, glyphnumber + oldfont.selection.select(subspecies_of(src)) + oldfont.copy() + newfont.selection.select('u%05x' % glyphnumber) + newfont.paste() + +def simplify(): + """ Simplify a glyph. Does nothing in current version of fontforge (seems to + be a bug). + """ + global newfont, glyphnumber + newfont[glyphnumber].simplify(0, ['mergelines']) + newfont[glyphnumber].simplify() + newfont[glyphnumber].removeOverlap() + newfont[glyphnumber].simplify(0, ['mergelines']) + newfont[glyphnumber].simplify() + +def paste_and_move(src, xdimen, ydimen): + "Pastes the src glyph into dst, and moves it with horiz and vert offsets." + global oldfont, newfont, glyphnumber + src = subspecies_of(src) + if xdimen != 0 or ydimen != 0: + oldfont[src].transform(psMat.translate(xdimen, ydimen)) + oldfont.selection.select(src) + oldfont.copy() + newfont.selection.select('u%05x' % glyphnumber) + newfont.pasteInto() + if xdimen != 0 or ydimen != 0: + oldfont[src].transform(psMat.translate(-xdimen, -ydimen)) + +def end_glyph(name): + "Final function to call when building a glyph." + global newfont, glyphnumber + set_glyph_name(name) + newfont[glyphnumber].simplify(0, ['mergelines']) + newfont[glyphnumber].simplify(0) + newfont[glyphnumber].removeOverlap() + newfont[glyphnumber].simplify(0, ['mergelines']) + newfont[glyphnumber].simplify(0) + newfont[glyphnumber].canonicalContours() + newfont[glyphnumber].canonicalStart() + +def scale(xdimen, ydimen): + "Scales a glyph, horizontally by x and vertically by y" + global newfont, glyphnumber + newfont[glyphnumber].transform(psMat.scale(xdimen, ydimen)) + +def move(xdimen, ydimen): + "moves a glyph, horizontally by x and vertically by y" + global newfont, glyphnumber + newfont[glyphnumber].transform(psMat.translate(xdimen, ydimen)) + +def set_width(width): + "Set the width of a glyph" + global newfont, glyphnumber + newfont[glyphnumber].width = width + +def get_queue_glyph(height, rev = False): + "Creates the asked line glyph in tmpglyph" + global oldfont, STEM_SCHEMA + oldfont.selection.select('queuebase') + oldfont.copy() + oldfont.selection.select('tmpglyph') + oldfont.paste() + # Mind height sign here, transform doesn't like negative values + oldfont['tmpglyph'].transform(psMat.scale(1,-height+FONT_CONFIG['stem bottom']+ + FONT_CONFIG['additional upper queue height'])) + oldfont['tmpglyph'].transform(psMat.translate(0,height-FONT_CONFIG['stem bottom'])) + queueglyphname = 'queue' if not rev else 'rqueue' + oldfont.selection.select(queueglyphname) + oldfont[queueglyphname].transform(psMat.translate(0, height-FONT_CONFIG['stem bottom'])) + oldfont.copy() + oldfont.selection.select('tmpglyph') + oldfont.pasteInto() + oldfont[queueglyphname].transform(psMat.translate(0, -height+FONT_CONFIG['stem bottom'])) + oldfont['tmpglyph'].removeOverlap() + oldfont['tmpglyph'].simplify(0) + oldfont['tmpglyph'].simplify(0, ['mergelines']) + return 'tmpglyph' + +def write_line(i, length, height): + "Writes a line in currently selected glyph, with length and height offsets" + if i > 1: + linename = "line%d" % i + paste_and_move(linename, length, height) + +STEM_LIQ_FALLBACKS = { + L_DESCENDENS : L_ASCENDENS, + L_ASCENDENS : L_NOTHING, + L_DEMINUTUS : L_NOTHING, + L_INITIO_DEBILIS: L_DEMINUTUS, + L_INITIO_DEBILIS_DEMINUTUS: L_DEMINUTUS, + L_INITIO_DEBILIS_ASCENDENS: L_ASCENDENS, + L_INITIO_DEBILIS_DESCENDENS: L_DESCENDENS, + L_UP: L_NOTHING, + L_DOWN: L_NOTHING, + L_DEMINUTUS_FIRST: L_NOTHING +} + +STEM_SHAPE_FALLBACKS = { + S_VIRGA_REVERSA : S_VIRGA, + S_ORISCUS_SCAPUS : S_VIRGA, + S_ORISCUS_REVERSUS_SCAPUS: S_VIRGA, + S_FLEXUS_ORISCUS_SCAPUS: S_FLEXUS, + S_PES_QUADRATUM: S_FLEXUS, + S_PES_QUASSUS: S_PES_QUADRATUM, + S_PES_QUILISMA_QUADRATUM: S_PES_QUADRATUM, + S_UPPER_PES_QUADRATUM: S_PES_QUADRATUM, + S_LOWER_PES_QUADRATUM: S_PES_QUADRATUM, + S_UPPER_PES_QUASSUS: S_PES_QUASSUS, + S_LOWER_PES_QUASSUS: S_PES_QUASSUS, + S_PORRECTUS: S_FLEXUS, + S_PORRECTUS_FLEXUS: S_PORRECTUS, + S_PORRECTUS_DEMINUTUS_ALT: S_FLEXUS, + # 3 notes glyphs are handled in a different way, see get_default_shift + #S_ANCUS: S_FLEXUS, + #S_SALICUS: S_PES_QUASSUS, +} + +def get_shift(qtype, shape, liq, i, j): + """Returns the shift corresponding to the arguments in the queue length + schema or False + """ + global STEM_SCHEMA + #print('get shift %s %s %s %d %d' % (qtype, shape, liq, i, j)) + i = str(i) + j = str(j) + if shape not in STEM_SCHEMA: + return False + if liq not in STEM_SCHEMA[shape]: + return False + if i=='0': + return STEM_SCHEMA[shape][liq].get(qtype, False) + elif i not in STEM_SCHEMA[shape][liq]: + return False + elif j=='0': + return STEM_SCHEMA[shape][liq][i].get(qtype, False) + else: + if j in STEM_SCHEMA[shape][liq][i] and qtype in STEM_SCHEMA[shape][liq][i][j]: + return STEM_SCHEMA[shape][liq][i][j][qtype] + else: + return False + return False # Shouldn't happen + +def get_default_shift(qtype, shape, liq, i, j, side): + """Returns the default shift associated with the schema. This + function should be used for ancus or salicus only. The idea + is to take i+j when reasonable, i otherwise. + """ + global STEM_SCHEMA + if i==0: + print('fatal error, this should not happen!') + exit() + if shape == S_ANCUS: + if j==0 or STEM_SCHEMA['ignore j']: + return get_shift(qtype, S_FLEXUS, L_DEMINUTUS_FIRST, i, 0) + else: + if MAX_INTERVAL < (i+j): + return get_shift(qtype, S_FLEXUS, L_DEMINUTUS_FIRST, i, 0) + else: + return get_shift(qtype, S_FLEXUS, L_DEMINUTUS, i+j, 0) + elif shape == S_SALICUS: + # for this shape, i is the second ambitus j is the first one + # so that it's just a mirror of ancus + if j==0 or STEM_SCHEMA['ignore j']: + return get_queue_shift(qtype, S_PES_QUASSUS, L_NOTHING, i, 'right', 0) + else: + if MAX_INTERVAL < (i+j): + return get_queue_shift(qtype, S_PES_QUASSUS, L_NOTHING, i, 'right', 0) + else: + return get_queue_shift(qtype, S_PES_QUADRATUM, L_NOTHING, i+j, 'right', 0) + else: + print('calling get_default_shift with shape %s, this should not happen!' % shape) + exit() + +def get_queue_shift(qtype, shape, liq, i=0, side='left', j=0): + """ Returns the queue shift associated with the arguments in the queue + length schema, applying all fallbacks. + """ + global STEM_SCHEMA + queueshape = shape + shift = False + # kind of do-while loop... + while not shift: + shift = get_shift(qtype, queueshape, liq, i, j) + #print(shift) + queueliq = liq + while not shift and queueliq in STEM_LIQ_FALLBACKS: + queueliq = STEM_LIQ_FALLBACKS[queueliq] + shift = get_shift(qtype, queueshape, queueliq, i, j) + #print(shift) + if queueshape in STEM_SHAPE_FALLBACKS: + queueshape = STEM_SHAPE_FALLBACKS[queueshape] + else: + break + if not shift: + shift = get_default_shift(qtype, shape, liq, i, j, side) + #print(shift) + return shift + +def write_left_queue(i, qtype, stemshape, liq = L_NOTHING, j=0, length=0, shift=0): + """ Write the left queue of a glyph. Non-obvious args: + - i: the ambitus between the first and second note + - j: ambitus between the second and third note in case of an ancus + - length: horizontal shift to apply to the queue + - shift: the vertical shift to apply to the queue + """ + qshift = get_queue_shift(qtype, stemshape, liq, i, 'left', j) + queue_glyph = get_queue_glyph(qshift, False) + paste_and_move(queue_glyph, length, shift) + +def write_right_queue(i, length, qtype, stemshape, liq = L_NOTHING, j=0, shift=0): + """ Write the right queue of a glyph. Same arguments as write_length_queue + """ + qshift = get_queue_shift(qtype, stemshape, liq, i, 'right', j) + queue_glyph = get_queue_glyph(qshift, True) + paste_and_move(queue_glyph, length, shift) + +def write_virga_in(right_queue, firstglyph, qtype, liq, stemshape=S_VIRGA, i=0): + "Draws a virga at height i." + if not right_queue: + write_left_queue(i, qtype, stemshape, liq) + paste_and_move(firstglyph, 0, (i)*FONT_CONFIG['base height']) + first_width = get_width(firstglyph) + if right_queue: + write_right_queue(i, first_width-get_width('line2'), qtype, stemshape) + return first_width + +def write_virga(shape, lique=L_NOTHING, right_queue=False, firstglyph='rvirgabase', + qtype='short', stemshape=S_VIRGA): + "Writes the virga glyphs." + new_glyph() + if lique == L_NOTHING: + glyph_name = shape + else: + glyph_name = '%s%s' % (shape, lique) + if copy_existing_glyph(glyph_name): + return + thislen = write_virga_in(right_queue, firstglyph, qtype, lique, stemshape) + set_width(thislen) + end_glyph(glyph_name) + +def virga(): + "Creates virgas" + message("virgas") + write_virga(S_VIRGA, L_NOTHING, True, + 'virgabase', 'short', S_VIRGA) + write_virga(S_VIRGA_LONGQUEUE, L_NOTHING, True, + 'virgabase', 'long', S_VIRGA) + write_virga(S_VIRGA_OPENQUEUE, L_NOTHING, True, + 'virgabase', 'open', S_VIRGA) + write_virga(S_VIRGA_REVERSA, L_NOTHING, False, + 'rvirgabase', 'short', S_VIRGA_REVERSA) + write_virga(S_VIRGA_REVERSA_LONGQUEUE, L_NOTHING, False, + 'rvirgabase', 'long', S_VIRGA_REVERSA) + write_virga(S_VIRGA_REVERSA_OPENQUEUE, L_NOTHING, False, + 'rvirgabase', 'open', S_VIRGA_REVERSA) + write_virga(S_VIRGA_REVERSA, L_DESCENDENS, False, + 'PunctumAuctusLineBL', 'short', S_VIRGA) + write_virga(S_VIRGA_REVERSA_LONGQUEUE, L_DESCENDENS, False, + 'PunctumAuctusLineBL', 'long', S_VIRGA) + write_virga(S_VIRGA_REVERSA_OPENQUEUE, L_DESCENDENS, False, + 'PunctumAuctusLineBL', 'open', S_VIRGA) + write_virga(S_VIRGA_REVERSA, L_ASCENDENS, False, + 'auctusa2', 'short', S_VIRGA) + write_virga(S_VIRGA_REVERSA_LONGQUEUE, L_ASCENDENS, False, + 'auctusa2', 'long', S_VIRGA) + write_virga(S_VIRGA_REVERSA_OPENQUEUE, L_ASCENDENS, False, + 'auctusa2', 'open', S_VIRGA) + write_virga(S_ORISCUS_SCAPUS, L_NOTHING, False, + 'OriscusLineBL', 'short', S_ORISCUS_SCAPUS) + write_virga(S_ORISCUS_SCAPUS_LONGQUEUE, L_NOTHING, False, + 'OriscusLineBL', 'long', S_ORISCUS_SCAPUS) + write_virga(S_ORISCUS_SCAPUS_OPENQUEUE, L_NOTHING, False, + 'OriscusLineBL', 'open', S_ORISCUS_SCAPUS) + write_virga(S_ORISCUS_REVERSUS_SCAPUS, L_NOTHING, False, + 'OriscusReversusLineBL', 'short', S_ORISCUS_REVERSUS_SCAPUS) + write_virga(S_ORISCUS_REVERSUS_SCAPUS_LONGQUEUE, L_NOTHING, False, + 'OriscusReversusLineBL', 'long', S_ORISCUS_REVERSUS_SCAPUS) + write_virga(S_ORISCUS_REVERSUS_SCAPUS_OPENQUEUE, L_NOTHING, False, + 'OriscusReversusLineBL', 'open', S_ORISCUS_REVERSUS_SCAPUS) + +def write_deminutus(i, j, length=0, tosimplify=0, firstbar=1): + """As the glyph before a deminutus is not the same as a normal glyph, + and always the same, we can call this function each + time. Sometimes we have to simplify before building the last glyph + (tosimplify=1), and length is the offset. + """ + first_glyph_is_complete = False + first_glyph = 'mademinutus' # firstbar == 2 + if firstbar == 1: + first_glyph = 'mdeminutus' + elif firstbar == 0: + first_glyph = 'mnbdeminutus' + if j == 1: + if glyph_exists('%sam1flexus' % first_glyph): + first_glyph = '%sam1flexus' % first_glyph + first_glyph_is_complete = True + elif glyph_exists('%sam1' % first_glyph): + first_glyph = '%sam1flexus' % first_glyph + paste_and_move(first_glyph, length, i*FONT_CONFIG['base height']) + if not first_glyph_is_complete: + write_line(j, length+get_width(first_glyph)-get_width('line2'), + (i-j+1)*FONT_CONFIG['base height']) + if tosimplify: + simplify() + if not first_glyph_is_complete: + paste_and_move("deminutus", + length+get_width(first_glyph)-get_width('deminutus'), + (i-j)*FONT_CONFIG['base height']) + return get_width(first_glyph) + +def measures(): + "Creates glyphs used only for measurement." + message("glyphs for measurement") + new_glyph() + first_glyph = 'PunctumLineBLBR' + second_glyph = 'PunctumLineTL' + simple_paste(first_glyph) + write_line(1, get_width(first_glyph) - get_width('line2'), -FONT_CONFIG['base height']) + paste_and_move(second_glyph, get_width(first_glyph) - get_width('line2'), + -FONT_CONFIG['base height']) + set_width(get_width(first_glyph)+get_width(second_glyph)-get_width('line2')) + end_glyph('FlexusLineBL') + new_glyph() + first_glyph = 'PunctumLineBL' + second_glyph = 'Punctum' + simple_paste(first_glyph) + paste_and_move(second_glyph, get_width(first_glyph), -FONT_CONFIG['base height']) + set_width(get_width(first_glyph)+get_width(second_glyph)) + end_glyph('FlexusAmOneLineBL') + +HEPISEMA_GLYPHS = { + 'HEpisemaPunctum': 'Punctum', + 'HEpisemaFlexusDeminutus': 'mpdeminutus', + 'HEpisemaDebilis': 'idebilis', + 'HEpisemaInclinatum': 'PunctumInclinatum', + 'HEpisemaInclinatumDeminutus': 'PunctumInclinatumDeminutus', + 'HEpisemaStropha': 'Stropha', + 'HEpisemaQuilisma': 'Quilisma', + 'HEpisemaQuilismaLineTR': 'QuilismaLineTR', + 'HEpisemaHighPes': 'PunctumSmall', + 'HEpisemaOriscus': 'Oriscus', + 'HEpisemaVirga': 'rvirgabase', + 'HEpisemaVirgaBaseLineBL': 'VirgaBaseLineBL', + 'HEpisemaOriscusLineTR': 'OriscusLineTR', + 'HEpisemaPunctumLineBR': 'PunctumLineBR', + 'HEpisemaPunctumLineBL': 'PunctumLineBL', + 'HEpisemaPunctumLineTL': 'PunctumLineTL', + 'HEpisemaPunctumLineTR': 'PunctumLineTR', + 'HEpisemaPunctumLineBLBR': 'PunctumLineBLBR', + 'HEpisemaPunctumAuctusLineBL': 'PunctumAuctusLineBL', + 'HEpisemaSalicusOriscus': 'SalicusOriscus', + 'HEpisemaFlat': 'Flat', + 'HEpisemaSharp': 'Sharp', + 'HEpisemaNatural': 'Natural', +} + +def hepisema(): + "Creates horizontal episemata." + message("horizontal episema") + for target, source in HEPISEMA_GLYPHS.items(): + write_hepisema(get_width(source), target) + write_hepisema(get_width(source) * 2.0 / 3.0, target + "Reduced") + reduction = get_width('PunctumSmall') + for i in range(1, MAX_INTERVAL+1): + write_hepisema(get_width("porrectus%d"%i), + 'HEpisemaPorrectus%s' % AMBITUS[i], reduction) + for i in range(1, MAX_INTERVAL+1): + if glyph_exists("porrectusam1%d"%i): + write_hepisema(get_width("porrectusam1%d"%i), + 'HEpisemaPorrectusAmOne%s' % AMBITUS[i], reduction) + else: + write_hepisema(get_width("porrectus%d"%i), + 'HEpisemaPorrectusAmOne%s' % AMBITUS[i], reduction) + # porrectus flexus does not get reduced because the note after is to the right + for i in range(1, MAX_INTERVAL+1): + write_hepisema(get_width("porrectusflexus%d"%i), + 'HEpisemaPorrectusFlexus%s' % AMBITUS[i]) + +def write_hepisema(shape_width, glyphname, reduction=0): + "Writes the horizontal episema glyphs." + global FONT_CONFIG + new_glyph() + simple_paste("hepisema_base") + drawn_width = shape_width - reduction + scale(drawn_width + 2*FONT_CONFIG['hepisema additional width'], 1) + move(-FONT_CONFIG['hepisema additional width'], 0) + if glyph_exists('hepisemaleft'): + paste_and_move("hepisemaleft", -FONT_CONFIG['hepisema additional width'], 0) + if glyph_exists('hepisemaright'): + paste_and_move("hepisemaright", + drawn_width + FONT_CONFIG['hepisema additional width'], 0) + # use the original width for the glyph for the sake of ledger lines + set_width(shape_width) + end_glyph(glyphname) + +def pes(): + "Creates the pes." + message("pes") + precise_message("pes") + for i in range(1, MAX_INTERVAL+1): + write_pes(i, "p2base", S_PES) + precise_message("pes deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "pesdeminutus", S_PES, L_DEMINUTUS) + precise_message("pes quilisma") + for i in range(1, MAX_INTERVAL+1): + write_pes(i, "QuilismaLineTR", S_PES_QUILISMA) + precise_message("pes quilisma deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "QuilismaLineTR", S_PES_QUILISMA, + L_DEMINUTUS) + precise_message("pes quassus deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "OriscusLineTR", S_PES_QUASSUS, + L_DEMINUTUS) + precise_message("pes initio debilis") + for i in range(1, MAX_INTERVAL+1): + write_pes_debilis(i, S_PES, L_INITIO_DEBILIS) + precise_message("pes initio debilis deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_debilis_deminutus(i, S_PES, + L_INITIO_DEBILIS_DEMINUTUS) + +def fusion_pes(): + "Creates the fusion pes." + message("fusion pes") + precise_message("fusion pes") + for i in range(1, MAX_INTERVAL+1): + write_pes(i, "msdeminutus", S_UPPER_PES) + precise_message("fusion pes deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "msdeminutus", S_UPPER_PES, L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "mpdeminutus", S_LOWER_PES, L_DEMINUTUS) + precise_message("fusion pes quassus deminutus") + for i in range(1, MAX_INTERVAL+1): + write_pes_deminutus(i, "SalicusOriscus", S_UPPER_PES_QUASSUS, + L_DEMINUTUS) + +def write_pes(i, first_glyph, shape, lique=L_NOTHING): + "Writes the pes glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + get_width('QuilismaLineTR') + temp_width = 0 + width_difference = get_width(first_glyph)-get_width('PunctumSmall') + if width_difference < 0: + paste_and_move(first_glyph, -width_difference, 0) + else: + simple_paste(first_glyph) + temp_width = get_width(first_glyph)-get_width('line2') + if width_difference < 0: + temp_width = temp_width-width_difference + write_line(i, temp_width, FONT_CONFIG['base height']) + if width_difference != 0: + paste_and_move('PunctumSmall', width_difference, i*FONT_CONFIG['base height']) + else: + paste_and_move('PunctumSmall', 0, i*FONT_CONFIG['base height']) + if width_difference < 0: + set_width(get_width('PunctumSmall')) + else: + set_width(get_width(first_glyph)) + end_glyph(glyph_name) + +def write_pes_debilis(i, shape, lique=L_NOTHING): + "Writes the pes debilis glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + # with a deminutus it is much more beautiful than with a idebilis + simple_paste("deminutus") + write_line(i, get_width('deminutus')-get_width('line2'), FONT_CONFIG['base height']) + simplify() + paste_and_move("PunctumLineBL", get_width('deminutus')-get_width('line2'), + i*FONT_CONFIG['base height']) + set_width(get_width('deminutus')+get_width('PunctumLineBL')-get_width('line2')) + end_glyph(glyph_name) + +def write_pes_deminutus(i, first_glyph, shape, lique=L_NOTHING): + "Writes the pes deminutus glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + simple_paste(first_glyph) + temp_width = get_width(first_glyph)-get_width('line2') + write_line(i, temp_width, FONT_CONFIG['base height']) + paste_and_move("rdeminutus", + get_width(first_glyph)-get_width('rdeminutus'), + i*FONT_CONFIG['base height']) + set_width(get_width(first_glyph)) + end_glyph(glyph_name) + +def write_pes_debilis_deminutus(i, shape, lique=L_NOTHING): + "Writes the pes debilis deminutus glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + simple_paste("deminutus") + write_line(i, get_width('deminutus')-get_width('line2'), FONT_CONFIG['base height']) + simplify() + paste_and_move("rdeminutus", 0, i*FONT_CONFIG['base height']) + set_width(get_width('deminutus')) + end_glyph(glyph_name) + +def pes_quadratum(): + "Makes the pes quadratum." + message("pes quadratum") + precise_message("pes quadratum") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "PunctumLineTR", "VirgaBaseLineBL", + S_PES_QUADRATUM, + stemshape=S_PES_QUADRATUM, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "PunctumLineTR", "VirgaBaseLineBL", + S_PES_QUADRATUM_LONGQUEUE, + stemshape=S_PES_QUADRATUM, qtype='long') + write_pes_quadratum(1, "PunctumLineTR", "VirgaBaseLineBL", + S_PES_QUADRATUM_OPENQUEUE, + stemshape=S_PES_QUADRATUM, qtype='open') + precise_message("pes quassus") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "OriscusLineTR", "VirgaBaseLineBL", + S_PES_QUASSUS, + stemshape=S_PES_QUASSUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "OriscusLineTR", "VirgaBaseLineBL", + S_PES_QUASSUS_LONGQUEUE, + stemshape=S_PES_QUASSUS, qtype='long') + write_pes_quadratum(1, "OriscusLineTR", "VirgaBaseLineBL", S_PES_QUASSUS_OPENQUEUE, + stemshape=S_PES_QUASSUS, qtype='open') + precise_message("pes quilisma quadratum") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "QuilismaLineTR", "VirgaBaseLineBL", + S_PES_QUILISMA_QUADRATUM, + stemshape=S_PES_QUILISMA_QUADRATUM, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "QuilismaLineTR", + "VirgaBaseLineBL", S_PES_QUILISMA_QUADRATUM_LONGQUEUE, + stemshape=S_PES_QUILISMA_QUADRATUM, qtype='long') + write_pes_quadratum(1, "QuilismaLineTR", + "VirgaBaseLineBL", S_PES_QUILISMA_QUADRATUM_OPENQUEUE, + stemshape=S_PES_QUILISMA_QUADRATUM, qtype='open') + precise_message("pes auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "PunctumLineTR", + "auctusa2", S_PES_QUADRATUM, L_ASCENDENS) + precise_message("pes initio debilis auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "idebilis", + "auctusa2", S_PES_QUADRATUM, + L_INITIO_DEBILIS_ASCENDENS) + precise_message("pes quassus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "OriscusLineTR", + "auctusa2", S_PES_QUASSUS, L_ASCENDENS) + precise_message("pes quilisma auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "QuilismaLineTR", + "auctusa2", S_PES_QUILISMA_QUADRATUM, + L_ASCENDENS) + precise_message("pes auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "PunctumLineTR", + "PunctumAuctusLineBL", S_PES_QUADRATUM, L_DESCENDENS) + precise_message("pes initio debilis auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "idebilis", + "PunctumAuctusLineBL", S_PES_QUADRATUM, + L_INITIO_DEBILIS_DESCENDENS) + precise_message("pes quassus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "OriscusLineTR", + "PunctumAuctusLineBL", S_PES_QUASSUS, L_DESCENDENS) + precise_message("pes quilisma auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "QuilismaLineTR", "PunctumAuctusLineBL", + S_PES_QUILISMA_QUADRATUM, L_DESCENDENS) + +def fusion_pes_quadratum(): + "Makes the fusion pes quadratum." + message("fusion pes quadratum") + precise_message("fusion pes quadratum") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "msdeminutus", "VirgaBaseLineBL", + S_UPPER_PES_QUADRATUM, + stemshape=S_UPPER_PES_QUADRATUM, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "base6", "VirgaBaseLineBL", + S_LOWER_PES_QUADRATUM, + stemshape=S_LOWER_PES_QUADRATUM, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "msdeminutus", "VirgaBaseLineBL", + S_UPPER_PES_QUADRATUM_LONGQUEUE, + stemshape=S_UPPER_PES_QUADRATUM, qtype='long') + write_pes_quadratum(1, "msdeminutus", "VirgaBaseLineBL", + S_UPPER_PES_QUADRATUM_OPENQUEUE, + stemshape=S_UPPER_PES_QUADRATUM, qtype='open') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "base6", "VirgaBaseLineBL", + S_LOWER_PES_QUADRATUM_LONGQUEUE, + stemshape=S_LOWER_PES_QUADRATUM, qtype='long') + write_pes_quadratum(1, "base6", "VirgaBaseLineBL", + S_LOWER_PES_QUADRATUM_OPENQUEUE, + stemshape=S_LOWER_PES_QUADRATUM, qtype='open') + precise_message("fusion pes quassus") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "SalicusOriscus", "VirgaBaseLineBL", + S_UPPER_PES_QUASSUS, + stemshape=S_UPPER_PES_QUASSUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "SalicusOriscus", "VirgaBaseLineBL", + S_UPPER_PES_QUASSUS_LONGQUEUE, + stemshape=S_UPPER_PES_QUASSUS, qtype='long') + write_pes_quadratum(1, "SalicusOriscus", "VirgaBaseLineBL", + S_UPPER_PES_QUASSUS_OPENQUEUE, + stemshape=S_UPPER_PES_QUASSUS, qtype='open') + precise_message("fusion pes auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "msdeminutus", "auctusa2", + S_UPPER_PES_QUADRATUM, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "base6", "auctusa2", + S_LOWER_PES_QUADRATUM, L_ASCENDENS) + precise_message("fusion pes quassus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "SalicusOriscus", "auctusa2", + S_UPPER_PES_QUASSUS, L_ASCENDENS) + precise_message("fusion pes auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "msdeminutus", "PunctumAuctusLineBL", + S_UPPER_PES_QUADRATUM, L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "base6", "PunctumAuctusLineBL", + S_LOWER_PES_QUADRATUM, L_DESCENDENS) + precise_message("fusion pes quassus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_pes_quadratum(i, "SalicusOriscus", "PunctumAuctusLineBL", + S_UPPER_PES_QUASSUS, L_DESCENDENS) + +def write_pes_quadratum(i, first_glyph, last_glyph, shape, lique=L_NOTHING, + stemshape=None, qtype=None): + "Writes the pes quadratum glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + if first_glyph == "idebilis": + first_width = get_width('idebilis')-get_width('line2') + elif first_glyph == "PunctumLineTR" or first_glyph == "OriscusLineTR": + if i == 1: + if first_glyph == 'PunctumLineTR': + first_glyph = 'Punctum' + if first_glyph == 'msdeminutus': + first_glyph = 'PunctumLineBL' + if first_glyph == 'base6': + first_glyph = 'PunctumLineTL' + elif first_glyph == 'OriscusLineTR': + first_glyph = 'Oriscus' + elif first_glyph == 'SalicusOriscus': + first_glyph = 'OriscusLineBL' + + if last_glyph == 'PunctumLineTL': + last_glyph = 'Punctum' + elif last_glyph == 'auctusa2': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'PunctumAuctusLineBL': + last_glyph = 'PunctumDescendens' + elif last_glyph == 'VirgaBaseLineBL': + last_glyph = 'virgabase' + + first_width = get_width(first_glyph) + else: + first_width = get_width(first_glyph)-get_width('line2') + else: + first_width = get_width(first_glyph)-get_width('line2') + simple_paste(first_glyph) + if i != 1: + linename = "line%d" % i + paste_and_move(linename, first_width, FONT_CONFIG['base height']) + paste_and_move(last_glyph, first_width, i*FONT_CONFIG['base height']) + width = first_width+get_width(last_glyph) + if qtype: + write_right_queue(i, width-get_width('line2'), qtype, stemshape, lique, + shift=i*FONT_CONFIG['base height']) + set_width(width) + end_glyph(glyph_name) + +def virga_strata(): + "Creates the virga strata." + precise_message("virga strata") + for i in range(1, MAX_INTERVAL+1): + write_virga_strata(i, "PunctumLineTR", "OriscusLineBL", + S_VIRGA_STRATA) + +def write_virga_strata(i, first_glyph, last_glyph, shape, lique=L_NOTHING): + "Writes the virga strata glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + if i == 1: + first_glyph = 'Punctum' + first_width = get_width(first_glyph) + last_glyph = 'Oriscus' + else: + first_width = get_width(first_glyph)-get_width('line2') + simple_paste(first_glyph) + if i != 1: + linename = "line%d" % i + paste_and_move(linename, first_width, FONT_CONFIG['base height']) + paste_and_move(last_glyph, first_width, i*FONT_CONFIG['base height']) + set_width(first_width+get_width(last_glyph)) + end_glyph(glyph_name) + +def salicus(): + "Creates the salicus." + message("salicus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_salicus(i, j, "VirgaBaseLineBL", S_SALICUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_salicus(i, j, "VirgaBaseLineBL", S_SALICUS_LONGQUEUE, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_salicus(i, j, "rdeminutus", S_SALICUS, L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_salicus(i, j, "auctusa2", S_SALICUS, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_salicus(i, j, "PunctumAuctusLineBL", S_SALICUS, + L_DESCENDENS) + +def write_salicus(i, j, last_glyph, shape, lique=L_NOTHING, qtype=None): + "Writes the salicus glyphs." + new_glyph() + glyph_name = '%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], lique) + if copy_existing_glyph(glyph_name): + return + length = draw_salicus(i, j, last_glyph, lique, qtype) + set_width(length) + end_glyph(glyph_name) + +def draw_salicus(i, j, last_glyph, lique=L_NOTHING, qtype=None): + """ Draw a salicus in current glyph. + """ + deminutus = last_glyph == 'rdeminutus' + no_third_glyph = False + if j == 1 and not deminutus and last_glyph == 'VirgaBaseLineBL': + last_glyph = 'virgabase' + if i == 1 and j == 1 and not deminutus: + first_glyph = 'Punctum' + first_width = get_width(first_glyph) + middle_glyph = 'Oriscus' + middle_width = get_width(middle_glyph) + elif i == 1 and (not deminutus or not glyph_exists('PesQuassusOneDeminutus')): + first_glyph = 'Punctum' + first_width = get_width(first_glyph) + middle_glyph = 'OriscusLineTR' + middle_width = get_width(middle_glyph)-get_width('line2') + elif j == 1 and not deminutus: + first_glyph = 'PunctumLineTR' + first_width = get_width(first_glyph)-get_width('line2') + middle_glyph = 'OriscusLineBL' + middle_width = get_width(middle_glyph) + elif (j == 1 and deminutus and glyph_exists('PesQuassusOneDeminutus') and + glyph_exists('UpperPesQuassusOneDeminutus')): + if i == 1: + first_glyph = 'Punctum' + first_width = get_width(first_glyph) + middle_glyph = 'PesQuassusOneDeminutus' + middle_width = get_width(middle_glyph) + else: + first_glyph = 'PunctumLineTR' + first_width = get_width(first_glyph)-get_width('line2') + middle_glyph = 'UpperPesQuassusOneDeminutus' + middle_width = get_width(middle_glyph) + no_third_glyph = True + else: + first_glyph = 'PunctumLineTR' + first_width = get_width(first_glyph)-get_width('line2') + middle_glyph = 'SalicusOriscus' + middle_width = get_width(middle_glyph)-get_width('line2') + simple_paste(first_glyph) + if i != 1: + linename = "line%d" % i + paste_and_move(linename, first_width, FONT_CONFIG['base height']) + paste_and_move(middle_glyph, first_width, i*FONT_CONFIG['base height']) + length = first_width+middle_width + if not no_third_glyph: + if j != 1: + linename = "line%d" % j + paste_and_move(linename, length, (i+1)*FONT_CONFIG['base height']) + elif not deminutus: + length = length-0.01 + if last_glyph == 'auctusa2': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'PunctumAuctusLineBL': + last_glyph = 'PunctumDescendens' + elif last_glyph == 'VirgaBaseLineBL': + last_glyph = 'virgabase' + elif last_glyph == 'PunctumLineBLBR': + last_glyph = 'PunctumLineBR' + elif last_glyph == 'PunctumLineBL': + last_glyph = 'Punctum' + if not last_glyph: + return length + if not deminutus: + paste_and_move(last_glyph, length, (i+j)*FONT_CONFIG['base height']) + length = length + get_width(last_glyph) + if qtype: + write_right_queue(j, length-get_width('line2'), qtype, S_SALICUS, + lique, i, (i+j)*FONT_CONFIG['base height']) + else: + length = length+get_width('line2') + paste_and_move(last_glyph, (length-get_width(last_glyph)), + (i+j)*FONT_CONFIG['base height']) + return length + +def salicus_flexus(): + "Creates the salicus flexus." + message("salicus flexus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_salicus_flexus(i, j, k, "PunctumLineTL") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_salicus_flexus(i, j, k, "deminutus", L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_salicus_flexus(i, j, k, "auctusa1", L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_salicus_flexus(i, j, k, "auctusd1", L_DESCENDENS) + +def write_salicus_flexus(i, j, k, last_glyph, lique=L_NOTHING): + "Writes the salicus glyphs." + new_glyph() + glyph_name = '%s%s%s%s%s' % (S_SALICUS_FLEXUS, AMBITUS[i], AMBITUS[j], + AMBITUS[k], lique) + if copy_existing_glyph(glyph_name): + return + is_deminutus = last_glyph == 'deminutus' + if is_deminutus: + penult_glyph = None + elif k == 1: + penult_glyph = 'PunctumLineBL' + else: + penult_glyph = 'PunctumLineBLBR' + length = draw_salicus(i, j, penult_glyph) + if is_deminutus: + width_dem = write_deminutus(j+i, k, length, + firstbar = 0 if j == 1 else 1) + length = length + width_dem + else: + if k == 1 and not is_deminutus: + length = length-0.01 + if last_glyph == 'PunctumLineTL': + last_glyph = 'Punctum' + elif last_glyph == 'auctusa1': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'auctusd1': + last_glyph = 'PunctumDescendens' + if k != 1: + length = length - get_width('line2') + write_line(k, length, (1+i+j-k)*FONT_CONFIG['base height']) + paste_and_move(last_glyph, length, (i+j-k)*FONT_CONFIG['base height']) + length = length + get_width(last_glyph) + set_width(length) + end_glyph(glyph_name) + +def flexus(): + "Creates the flexus." + message("flexus") + precise_message("flexus") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "PunctumLineBR", 'PunctumLineTL', S_FLEXUS_NOBAR) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "odbase", 'PunctumLineTL', S_FLEXUS_ORISCUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'PunctumLineTL', S_FLEXUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'PunctumLineTL', S_FLEXUS_LONGQUEUE, qtype='long') + write_flexus(1, "rvbase", 'PunctumLineTL', S_FLEXUS_OPENQUEUE, qtype='open') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", 'PunctumLineTL', + S_FLEXUS_ORISCUS_SCAPUS, stemshape=S_FLEXUS_ORISCUS_SCAPUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", 'PunctumLineTL', + S_FLEXUS_ORISCUS_SCAPUS_LONGQUEUE, + stemshape=S_FLEXUS_ORISCUS_SCAPUS, qtype='long') + write_flexus(1, "osbase", 'PunctumLineTL', S_FLEXUS_ORISCUS_SCAPUS_OPENQUEUE, + stemshape=S_FLEXUS_ORISCUS_SCAPUS, qtype='open') + precise_message("flexus deminutus") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mdeminutus", 'PunctumLineTL', + S_FLEXUS_NOBAR, L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "odbase", 'deminutus', + S_FLEXUS_ORISCUS, L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mdeminutus", 'PunctumLineTL', + S_FLEXUS, L_DEMINUTUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mdeminutus", 'PunctumLineTL', + S_FLEXUS_LONGQUEUE, L_DEMINUTUS, qtype='long') + write_flexus(1, "mdeminutus", 'PunctumLineTL', + S_FLEXUS_OPENQUEUE, L_DEMINUTUS, qtype='open') + precise_message("flexus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "PunctumLineBR", 'auctusa1', + S_FLEXUS_NOBAR, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "odbase", 'auctusa1', + S_FLEXUS_ORISCUS, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", + 'auctusa1', S_FLEXUS, L_ASCENDENS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", + 'auctusa1', S_FLEXUS_LONGQUEUE, L_ASCENDENS, qtype='long') + write_flexus(1, "rvbase", + 'auctusa1', S_FLEXUS_OPENQUEUE, L_ASCENDENS, qtype='open') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", + 'auctusa1', S_FLEXUS_ORISCUS_SCAPUS, + L_ASCENDENS, stemshape = S_FLEXUS_ORISCUS_SCAPUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", + 'auctusa1', S_FLEXUS_ORISCUS_SCAPUS_LONGQUEUE, + L_ASCENDENS, stemshape = S_FLEXUS_ORISCUS_SCAPUS, qtype='long') + write_flexus(1, "osbase", + 'auctusa1', S_FLEXUS_ORISCUS_SCAPUS_OPENQUEUE, L_ASCENDENS, + stemshape = S_FLEXUS_ORISCUS_SCAPUS, qtype='open') + precise_message("flexus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "PunctumLineBR", 'auctusd1', S_FLEXUS_NOBAR, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "odbase", 'auctusd1', S_FLEXUS_ORISCUS, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'auctusd1', S_FLEXUS, + L_DESCENDENS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", + 'auctusd1', S_FLEXUS_LONGQUEUE, L_DESCENDENS, qtype='long') + write_flexus(1, "rvbase", + 'auctusd1', S_FLEXUS_OPENQUEUE, L_DESCENDENS, qtype='open') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", + 'auctusd1', S_FLEXUS_ORISCUS_SCAPUS, + L_DESCENDENS, S_FLEXUS_ORISCUS_SCAPUS, + stemshape=S_FLEXUS_ORISCUS_SCAPUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "osbase", + 'auctusd1', S_FLEXUS_ORISCUS_SCAPUS_LONGQUEUE, + L_DESCENDENS, S_FLEXUS_ORISCUS_SCAPUS, + stemshape=S_FLEXUS_ORISCUS_SCAPUS, qtype='long') + write_flexus(1, "osbase", + 'auctusd1', S_FLEXUS_ORISCUS_SCAPUS_OPENQUEUE, L_DESCENDENS, + S_FLEXUS_ORISCUS_SCAPUS, + stemshape=S_FLEXUS_ORISCUS_SCAPUS,qtype='open') + +def fusion_flexus(): + "Creates the fusion flexus." + message("fusion flexus") + precise_message("fusion flexus") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mademinutus", 'PunctumLineTL', S_LOWER_FLEXUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'PunctumLineTL', + S_UPPER_FLEXUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "OriscusReversusLineTLBR", 'PunctumLineTL', + S_LOWER_FLEXUS_ORISCUS) + precise_message("fusion flexus deminutus") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mademinutus", 'deminutus', S_LOWER_FLEXUS, + L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mdeminutus", 'deminutus', S_UPPER_FLEXUS, + L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "OriscusReversusLineTLBR", 'deminutus', + S_LOWER_FLEXUS_ORISCUS, L_DEMINUTUS) + precise_message("fusion flexus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mademinutus", 'auctusa1', S_LOWER_FLEXUS, + L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'auctusa1', S_UPPER_FLEXUS, + L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "OriscusReversusLineTLBR", 'auctusa1', + S_LOWER_FLEXUS_ORISCUS, L_ASCENDENS) + precise_message("fusion flexus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "mademinutus", 'auctusd1', S_LOWER_FLEXUS, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "rvbase", 'auctusd1', S_UPPER_FLEXUS, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + write_flexus(i, "OriscusReversusLineTLBR", 'auctusd1', + S_LOWER_FLEXUS_ORISCUS, L_DESCENDENS) + +def write_flexus(i, first_glyph, last_glyph, shape, lique=L_NOTHING, + firstglyph_amone=None, lastglyph_amone=None, stemshape=S_FLEXUS, qtype=None): + # pylint: disable=too-many-statements + "Writes the flexus glyphs." + new_glyph() + glyph_name = '%s%s%s' % (shape, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + # we add a queue if it is a deminutus + if first_glyph == "mdeminutus" and shape != S_UPPER_FLEXUS: + if shape == S_FLEXUS_NOBAR: + length = write_deminutus(0, i, length=0, tosimplify=1, firstbar=0) + else: + write_left_queue(i, qtype, stemshape, lique) + length = write_deminutus(0, i, length=0, tosimplify=1, firstbar=1) + elif last_glyph == 'deminutus' and (shape == S_UPPER_FLEXUS or shape == S_LOWER_FLEXUS): + firstbar = 1 if first_glyph == 'mdeminutus' else 2 + length = write_deminutus(0, i, length=0, tosimplify=1, firstbar=firstbar) + elif last_glyph == 'deminutus': + simple_paste(first_glyph) + write_line(i, get_width(first_glyph) - get_width('line2'), + (1-i)*FONT_CONFIG['base height']) + simplify() + paste_and_move("deminutus", + get_width(first_glyph) - + get_width(last_glyph), (-i)*FONT_CONFIG['base height']) + length = get_width(first_glyph) + else: + if qtype: + write_left_queue(i, qtype, stemshape, lique) + if i == 1 and first_glyph != 'OriscusReversusLineTLBR': + if last_glyph == 'PunctumLineTL': + last_glyph = 'Punctum' + elif last_glyph == 'auctusa1': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'auctusd1': + last_glyph = 'PunctumDescendens' + + if first_glyph == 'PunctumLineBR': + first_glyph = 'Punctum' + elif first_glyph == 'odbase': + first_glyph = 'OriscusReversus' + elif first_glyph == 'osbase': + first_glyph = 'OriscusLineBL' + elif first_glyph == 'VirgaLineBR': + first_glyph = 'VirgaReversa' + elif first_glyph == 'rvbase': + first_glyph = 'rvirgabase' + elif first_glyph == 'mademinutus': + first_glyph = 'PunctumLineTL' + elif first_glyph == 'PunctumLineBLBR': + first_glyph = 'PunctumLineBL' + + length = get_width(first_glyph) + else: + length = get_width(first_glyph)-get_width('line2') + simple_paste(first_glyph) + if i != 1: + write_line(i, length, (1-i)*FONT_CONFIG['base height']) + paste_and_move(last_glyph, length, (-i)*FONT_CONFIG['base height']) + length = length + get_width(last_glyph) + set_width(length) + end_glyph(glyph_name) + +def porrectus(): + "Creates the porrectus." + message("porrectus") + precise_message("porrectus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, 'PunctumSmall', S_PORRECTUS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + write_porrectus(1, j, 'PunctumSmall', S_PORRECTUS_LONGQUEUE, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, 'PunctumSmall', S_PORRECTUS_NOBAR) + precise_message("porrectus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "auctusa2", S_PORRECTUS, L_ASCENDENS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + write_porrectus(1, j, "auctusa2", S_PORRECTUS_LONGQUEUE, L_ASCENDENS, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "auctusa2", S_PORRECTUS_NOBAR, L_ASCENDENS) + precise_message("porrectus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "PunctumAuctusLineBL", S_PORRECTUS, L_DESCENDENS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + write_porrectus(1, j, "PunctumAuctusLineBL", S_PORRECTUS_LONGQUEUE, + L_DESCENDENS, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "PunctumAuctusLineBL", S_PORRECTUS_NOBAR, L_DESCENDENS) + precise_message("porrectus deminutus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "rdeminutus", S_PORRECTUS, L_DEMINUTUS, qtype='short') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "rdeminutus", S_PORRECTUS_LONGQUEUE, L_DEMINUTUS, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, "rdeminutus", S_PORRECTUS_NOBAR, L_DEMINUTUS) + precise_message("porrectus deminutus alt") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_alt_porrectus_deminutus(i, j) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_alt_porrectus_deminutus(i, j, qtype='long') + +def fusion_porrectus(): + "Write fusion porrectus." + precise_message("porrectus-like fusion") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, '', S_FLEXUS, L_UP, qtype='short') + for j in range(1, MAX_INTERVAL+1): + write_porrectus(1, j, '', S_FLEXUS_LONGQUEUE, L_UP, qtype='long') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_porrectus(i, j, '', S_FLEXUS_NOBAR, L_UP) + +def write_porrectus(i, j, last_glyph, shape, lique=L_NOTHING, qtype=None): + "Writes the porrectus glyphs." + new_glyph() + glyph_name = '%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], lique) + if copy_existing_glyph(glyph_name): + return + first_glyph = "porrectus%d" % i + if j == 1 and glyph_exists("porrectusam1%d" % i): + first_glyph = "porrectusam1%d" % i + if last_glyph == 'auctusa2' or last_glyph == 'PunctumAuctusLineBL' or last_glyph == '': + if j == 1 and last_glyph == '': + first_glyph = "porrectusflexusnb%d" % i + else: + first_glyph = "porrectusflexus%d" % i + if not glyph_exists(first_glyph): + return + if qtype: + write_left_queue(i, qtype, S_PORRECTUS, L_NOTHING) + length = get_width(first_glyph) + simple_paste(first_glyph) + write_line(j, length-get_width('line2'), (-i+1)*FONT_CONFIG['base height']) + length = length-get_width('line2') + if qtype: + simplify() + if last_glyph == 'rdeminutus': + length = length+get_width('line2') + paste_and_move(last_glyph, (length-get_width(last_glyph)), + (j-i)*FONT_CONFIG['base height']) + elif last_glyph == 'auctusa2' or last_glyph == 'PunctumAuctusLineBL': + paste_and_move(last_glyph, (length), (j-i)*FONT_CONFIG['base height']) + length = length + get_width(last_glyph) + elif last_glyph != '': + paste_and_move(last_glyph, + (length-get_width(last_glyph)+get_width('line2')), + (j-i)*FONT_CONFIG['base height']) + length = length+get_width('line2') + elif last_glyph == '' and j == 1: + length = length+get_width('line2') + set_width(length) + end_glyph(glyph_name) + +def write_alt_porrectus_deminutus(i, j, qtype='short'): + "Writes the alternate porrectur deminutus glyphs." + new_glyph() + if qtype=='long': + glyph_name = 'PorrectusLongqueue%s%sDeminutus.alt' % (AMBITUS[i], AMBITUS[j]) + else: + glyph_name = 'Porrectus%s%sDeminutus.alt' % (AMBITUS[i], AMBITUS[j]) + if copy_existing_glyph(glyph_name): + return + write_left_queue(i, qtype, S_PORRECTUS_DEMINUTUS_ALT, L_NOTHING) + if i == 1: + first_glyph = 'PunctumLineBR' + else: + first_glyph = 'PunctumLineBLBR' + simple_paste(first_glyph) + write_line(i, get_width(first_glyph)-get_width('line2'), (-i+1)*FONT_CONFIG['base height']) + simplify() + paste_and_move('mpdeminutus', (get_width(first_glyph)-get_width('line2')), + (-i)*FONT_CONFIG['base height']) + write_line(j, + get_width(first_glyph)+get_width('mpdeminutus')- + 2*get_width('line2'), (-i+1)*FONT_CONFIG['base height']) + paste_and_move('rdeminutus', (get_width(first_glyph) + + get_width('mpdeminutus') - + get_width('line2') - + get_width(('rdeminutus'))), + (j-i)*FONT_CONFIG['base height']) + set_width(get_width(first_glyph)+get_width('mpdeminutus')- + get_width('line2')) + end_glyph(glyph_name) + + +def porrectusflexus(): + "Creates the porrectusflexus." + message("porrectus flexus") + precise_message("porrectus flexus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, "PunctumLineTL", + S_PORRECTUS_FLEXUS_NOBAR) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, "PunctumLineTL", + S_PORRECTUS_FLEXUS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(1, j, k, "PunctumLineTL", + S_PORRECTUS_FLEXUS_LONGQUEUE, qtype='long') + precise_message("porrectus flexus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "auctusd1", + S_PORRECTUS_FLEXUS_NOBAR, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "auctusd1", + S_PORRECTUS_FLEXUS, + L_DESCENDENS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(1, j, k, + "auctusd1", + S_PORRECTUS_FLEXUS_LONGQUEUE, + L_DESCENDENS, qtype='long') + precise_message("porrectus flexus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "auctusa1", + S_PORRECTUS_FLEXUS_NOBAR, + L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "auctusa1", + S_PORRECTUS_FLEXUS, + L_ASCENDENS, qtype='short') + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(1, j, k, + "auctusa1", + S_PORRECTUS_FLEXUS_LONGQUEUE, + L_ASCENDENS, qtype='long') + precise_message("porrectus flexus deminutus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "deminutus", + S_PORRECTUS_FLEXUS_NOBAR, + L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(i, j, k, + "deminutus", + S_PORRECTUS_FLEXUS, L_DEMINUTUS, + qtype='short') + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_porrectusflexus(1, j, k, + "deminutus", + S_PORRECTUS_FLEXUS_LONGQUEUE, + L_DEMINUTUS, qtype='long') + +def write_porrectusflexus(i, j, k, last_glyph, + shape, lique=L_NOTHING, qtype=None): + "Writes the porrectusflexus glyphs." + new_glyph() + glyph_name = '%s%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], AMBITUS[k], lique) + if copy_existing_glyph(glyph_name): + return + if j == 1: + first_glyph = "porrectusflexusnb%d" % i + else: + first_glyph = "porrectusflexus%d" % i + if not glyph_exists(first_glyph): + return + if qtype: + write_left_queue(i, qtype, S_PORRECTUS_FLEXUS, L_NOTHING) + length = get_width(first_glyph) + simple_paste(first_glyph) + write_line(j, length-get_width('line2'), (-i+1)*FONT_CONFIG['base height']) + if last_glyph == "deminutus": + width_dem = write_deminutus(j-i, k, length-get_width('line2'), + qtype != None, firstbar=1) + length = length+width_dem-get_width('line2') + else: + simplify() + middle_glyph = 'PunctumLineBLBR' + if j == 1: + if k == 1: + middle_glyph = 'Punctum' + else: + middle_glyph = 'PunctumLineBR' + else: + length = length-get_width('line2') + if k == 1: + middle_glyph = 'PunctumLineBL' + paste_and_move(middle_glyph, length, (j-i)*FONT_CONFIG['base height']) + if k == 1: + if last_glyph == 'PunctumLineTL': + last_glyph = 'Punctum' + elif last_glyph == 'auctusa1': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'auctusd1': + last_glyph = 'PunctumDescendens' + length = length+get_width(middle_glyph) + else: + write_line(k, length + get_width(middle_glyph) - get_width('line2'), + (j-i-k+1)*FONT_CONFIG['base height']) + length = length + get_width(middle_glyph) - get_width('line2') + paste_and_move(last_glyph, length, (j-i-k)*FONT_CONFIG['base height']) + length = length+get_width(last_glyph) + set_width(length) + end_glyph(glyph_name) + +def torculus(): + "Creates the torculus." + message("torculus") + precise_message("torculus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "PunctumLineTR", "PunctumLineTL", S_TORCULUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "QuilismaLineTR", "PunctumLineTL", S_TORCULUS_QUILISMA) + precise_message("torculus initio debilis") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "idebilis", "PunctumLineTL", S_TORCULUS, + L_INITIO_DEBILIS) + precise_message("torculus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "PunctumLineTR", "auctusd1", S_TORCULUS, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "QuilismaLineTR", "auctusd1", S_TORCULUS_QUILISMA, + L_DESCENDENS) + precise_message("torculus initio debilis auctus descendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "idebilis", "auctusd1", S_TORCULUS, + L_INITIO_DEBILIS_DESCENDENS) + precise_message("torculus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "PunctumLineTR", "auctusa1", + S_TORCULUS, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "QuilismaLineTR", "auctusa1", S_TORCULUS_QUILISMA, + L_ASCENDENS) + precise_message("torculus initio debilis auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "idebilis", "auctusa1", S_TORCULUS, + L_INITIO_DEBILIS_ASCENDENS) + precise_message("torculus deminutus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "PunctumLineTR", "deminutus", S_TORCULUS, + L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "QuilismaLineTR", "deminutus", S_TORCULUS_QUILISMA, + L_DEMINUTUS) + precise_message("torculus initio debilis deminutus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_torculus(i, j, "idebilis", "deminutus", S_TORCULUS, + L_INITIO_DEBILIS_DEMINUTUS) + +def write_torculus(i, j, first_glyph, last_glyph, shape, lique=L_NOTHING): + "Writes the torculus glyphs." + new_glyph() + glyph_name = '%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], lique) + if copy_existing_glyph(glyph_name): + return + length = get_width(first_glyph)-get_width('line2') + if first_glyph == "QuilismaLineTR": + if i == 1: + first_glyph = 'Quilisma' + length = get_width(first_glyph) + elif i == 1 and first_glyph == 'PunctumLineTR': + first_glyph = 'Punctum' + length = length = get_width(first_glyph)+0.1 + simple_paste(first_glyph) + if i != 1: + write_line(i, length, FONT_CONFIG['base height']) + if last_glyph == "deminutus": + if i == 1: + width_dem = write_deminutus(i, j, length, firstbar=0) + else: + width_dem = write_deminutus(i, j, length, firstbar=1) + length = length+ width_dem + else: + if j == 1: + if i == 1: + second_glyph = 'Punctum' + else: + second_glyph = 'PunctumLineBL' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length+get_width(second_glyph) + if last_glyph == 'PunctumLineTL': + last_glyph = 'Punctum' + elif last_glyph == 'auctusa1': + last_glyph = 'PunctumAscendens' + elif last_glyph == 'auctusd1': + last_glyph = 'PunctumDescendens' + else: + if i == 1: + second_glyph = 'PunctumLineBR' + else: + second_glyph = 'PunctumLineBLBR' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length+get_width(second_glyph)-get_width('line2') + write_line(j, length, (i-j+1)*FONT_CONFIG['base height']) + paste_and_move(last_glyph, length, (i-j)*FONT_CONFIG['base height']) + length = length+get_width(last_glyph) + set_width(length) + end_glyph(glyph_name) + +def torculus_liquescens(): + "Creates the torculus liquescens." + precise_message("torculus liquescens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculus_liquescens(i, j, k, 'PunctumLineTR', + S_TORCULUS_LIQUESCENS, L_DEMINUTUS) + precise_message("torculus liquescens quilisma") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculus_liquescens(i, j, k, 'QuilismaLineTR', + S_TORCULUS_LIQUESCENS_QUILISMA, L_DEMINUTUS) + +def write_torculus_liquescens(i, j, k, first_glyph, shape, + lique='deminutus'): + "Writes the torculus liquescens glyphs." + new_glyph() + glyph_name = '%s%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], AMBITUS[k], lique) + if copy_existing_glyph(glyph_name): + return + length = get_width(first_glyph)-get_width('line2') + if first_glyph == "QuilismaLineTR": + if i == 1: + first_glyph = 'Quilisma' + length = get_width(first_glyph) + elif i == 1: + first_glyph = 'Punctum' + length = get_width(first_glyph)+0.1 + simple_paste(first_glyph) + if i != 1: + write_line(i, length, FONT_CONFIG['base height']) + flexus_firstbar = 2 + if j == 1: + flexus_firstbar = 0 + if i == 1: + second_glyph = 'Punctum' + else: + second_glyph = 'PunctumLineBL' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length+get_width(second_glyph) + else: + if i == 1: + second_glyph = 'PunctumLineBR' + else: + second_glyph = 'PunctumLineBLBR' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length+get_width(second_glyph)-get_width('line2') + write_line(j, length, (i-j+1)*FONT_CONFIG['base height']) + width_dem = write_deminutus(i-j, k, length, firstbar=flexus_firstbar) + length = length+width_dem + set_width(length) + end_glyph(glyph_name) + +def torculusresupinus(): + "Creates the torculusresupinus." + message("torculus resupinus") + precise_message("torculus resupinus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'PunctumLineTR', 'PunctumSmall', + S_TORCULUS_RESUPINUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'idebilis', 'PunctumSmall', + S_TORCULUS_RESUPINUS, L_INITIO_DEBILIS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'QuilismaLineTR', 'PunctumSmall', + S_TORCULUS_RESUPINUS_QUILISMA) + precise_message("torculus resupinus deminutus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'PunctumLineTR', 'rdeminutus', + S_TORCULUS_RESUPINUS, L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'idebilis', 'rdeminutus', + S_TORCULUS_RESUPINUS, + L_INITIO_DEBILIS_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'QuilismaLineTR', 'rdeminutus', + S_TORCULUS_RESUPINUS_QUILISMA, + L_DEMINUTUS) + precise_message("torculus resupinus deminutus alt") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_alt_torculusresupinusdeminutus(i, j, k, 'PunctumLineTR', + S_TORCULUS_RESUPINUS, + L_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_alt_torculusresupinusdeminutus(i, j, k, 'idebilis', + S_TORCULUS_RESUPINUS, + L_INITIO_DEBILIS_DEMINUTUS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_alt_torculusresupinusdeminutus(i, j, k, 'QuilismaLineTR', + S_TORCULUS_RESUPINUS_QUILISMA, + L_DEMINUTUS) + precise_message("torculus resupinus auctus ascendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'PunctumLineTR', "auctusa2", + S_TORCULUS_RESUPINUS, L_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'idebilis', "auctusa2", + S_TORCULUS_RESUPINUS, + L_INITIO_DEBILIS_ASCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'QuilismaLineTR', "auctusa2", + S_TORCULUS_RESUPINUS_QUILISMA, + L_ASCENDENS) + precise_message("torculus resupinus auctus descendens") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'PunctumLineTR', "PunctumAuctusLineBL", + S_TORCULUS_RESUPINUS, + L_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'idebilis', "PunctumAuctusLineBL", + S_TORCULUS_RESUPINUS, + L_INITIO_DEBILIS_DESCENDENS) + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + for k in range(1, MAX_INTERVAL+1): + write_torculusresupinus(i, j, k, 'QuilismaLineTR', "PunctumAuctusLineBL", + S_TORCULUS_RESUPINUS_QUILISMA, + L_DESCENDENS) + +def write_torculusresupinus(i, j, k, first_glyph, last_glyph, shape, + lique=L_NOTHING): + "Writes the torculusresupinus glyphs." + new_glyph() + glyph_name = '%s%s%s%s%s' % (shape, AMBITUS[i], AMBITUS[j], AMBITUS[k], lique) + if copy_existing_glyph(glyph_name): + return + middle_glyph = "porrectus%d" % j + if k == 1 and glyph_exists("porrectusam1%d" % j): + middle_glyph = "porrectusam1%d" % j + if last_glyph == 'auctusa2' or last_glyph == 'PunctumAuctusLineBL': + middle_glyph = "porrectusflexus%d" % j + if not glyph_exists(middle_glyph): + return + if i == 1 and first_glyph != 'idebilis': + if first_glyph == 'PunctumLineTR': + first_glyph = 'Punctum' + elif first_glyph == 'QuilismaLineTR': + first_glyph = 'Quilisma' + length = get_width(first_glyph)+0.1 + else: + length = get_width(first_glyph)-get_width('line2') + simple_paste(first_glyph) + if i != 1: + write_line(i, length, FONT_CONFIG['base height']) + paste_and_move(middle_glyph, length, i*FONT_CONFIG['base height']) + length = length + get_width(middle_glyph) + if k != 1: + write_line(k, length-get_width('line2'), (i-j+1)*FONT_CONFIG['base height']) + simplify() + if last_glyph == "rdeminutus": + paste_and_move(last_glyph, + (length-get_width('rdeminutus')), + (i-j+k)*FONT_CONFIG['base height']) + elif last_glyph == 'auctusa2' or last_glyph == 'PunctumAuctusLineBL': + paste_and_move(last_glyph, (length-get_width('line2')), (i-j+k)*FONT_CONFIG['base height']) + length = length - get_width('line2') + get_width(last_glyph) + else: + paste_and_move(last_glyph, (length-get_width(last_glyph)), + (i-j+k)*FONT_CONFIG['base height']) + set_width(length) + end_glyph(glyph_name) + +def write_alt_torculusresupinusdeminutus(i, j, k, first_glyph, + shape, lique=L_NOTHING): + # pylint: disable=invalid-name + "Writes the torculusresupinusdeminutus glyphs." + new_glyph() + glyph_name = '%s%s%s%s%s.alt' % (shape, AMBITUS[i], AMBITUS[j], AMBITUS[k], lique) + if copy_existing_glyph(glyph_name): + return + length = get_width(first_glyph)-get_width('line2') + if i == 1: + if first_glyph == 'PunctumLineTR': + first_glyph = 'Punctum' + length = get_width(first_glyph)+0.1 + elif first_glyph == 'QuilismaLineTR': + first_glyph = 'Quilisma' + length = get_width(first_glyph)+0.1 + simple_paste(first_glyph) + if i != 1: + write_line(i, length, FONT_CONFIG['base height']) + if j == 1 and i == 1: + if first_glyph == "idebilis": + second_glyph = 'PunctumLineBL' + last_glyph = 'mnbpdeminutus' + else: + second_glyph = 'Punctum' + last_glyph = 'mnbpdeminutus' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length + get_width(second_glyph) + elif j == 1: + second_glyph = 'PunctumLineBL' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length + get_width(second_glyph) + last_glyph = 'mnbpdeminutus' + elif i == 1 and first_glyph != "idebilis": + second_glyph = 'PunctumLineBR' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length + get_width(second_glyph)-get_width('line2') + write_line(j, length, (i-j+1)*FONT_CONFIG['base height']) + last_glyph = 'mpdeminutus' + else: + second_glyph = 'PunctumLineBLBR' + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + length = length + get_width(second_glyph)-get_width('line2') + write_line(j, length, (i-j+1)*FONT_CONFIG['base height']) + last_glyph = 'mpdeminutus' + paste_and_move(last_glyph, length, (i-j)*FONT_CONFIG['base height']) + length = length+get_width(last_glyph) + write_line(k, length-get_width('line2'), (i-j+1)*FONT_CONFIG['base height']) + paste_and_move('rdeminutus', + length-get_width('rdeminutus'), (i-j+k)*FONT_CONFIG['base height']) + set_width(length) + end_glyph(glyph_name) + +def scandicus(): + "Creates the scandicus." + message("scandicus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_scandicus(i, j, 'PunctumSmall') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_scandicus(i, j, 'rdeminutus', L_DEMINUTUS) + +def write_scandicus(i, j, last_glyph, lique=L_NOTHING): + "Writes the scandicus glyphs." + new_glyph() + final_vertical_shift = 0 + glyph_name = '%s%s%s%s' % (S_SCANDICUS, AMBITUS[i], AMBITUS[j], lique) + if copy_existing_glyph(glyph_name): + return + # special case of i=j=1, we use glyph 1025 directly + if i == 1 and j == 1 and lique == L_NOTHING: + simple_paste('Punctum') + second_glyph = 'PesOneNothing' + paste_and_move(second_glyph, get_width('Punctum'), FONT_CONFIG['base height']) + set_width(get_width('PesOneNothing')+get_width('Punctum')) + end_glyph(glyph_name) + return + if i == 1: + simple_paste('Punctum') + length = get_width('Punctum') + second_glyph = 'p2base' + if lique == L_DEMINUTUS: + second_glyph = 'mnbpdeminutus' + if j == 1: + final_vertical_shift = FONT_CONFIG['deminutus vertical shift'] + else: + simple_paste('PunctumLineTR') + length = get_width('PunctumLineTR') - get_width('line2') + write_line(i, length, FONT_CONFIG['base height']) + second_glyph = 'msdeminutus' + if j == 1 and glyph_exists('msdeminutusam1'): + second_glyph = 'msdeminutusam1' + if j == 1: + final_vertical_shift = FONT_CONFIG['deminutus vertical shift'] + if j == 1 and lique == L_NOTHING and glyph_exists('UpperPesOneNothing'): + paste_and_move('UpperPesOneNothing', length, i * FONT_CONFIG['base height']) + set_width(length + get_width('UpperPesOneNothing')) + end_glyph(glyph_name) + return + paste_and_move(second_glyph, length, i*FONT_CONFIG['base height']) + if (i == 1) and lique == L_NOTHING: + length = length + get_width('Punctum') + else: + length = length + get_width(second_glyph) + if j != 1: + write_line(j, length - get_width('line2'), (i+1) * FONT_CONFIG['base height']) + if last_glyph == 'rdeminutus': + paste_and_move('rdeminutus', length - + get_width('rdeminutus'), (i+j)*FONT_CONFIG['base height']+ + final_vertical_shift) + else: + paste_and_move(last_glyph, length - get_width(last_glyph), + (i+j)*FONT_CONFIG['base height']+final_vertical_shift) + set_width(length) + end_glyph(glyph_name) + +def ancus(): + "Creates the ancus." + message("ancus") + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_ancus(i, j, 'rvbase', S_ANCUS, 'short') + for i in range(1, MAX_INTERVAL+1): + for j in range(1, MAX_INTERVAL+1): + write_ancus(i, j, 'rvbase', S_ANCUS_LONGQUEUE, 'long') + +def write_ancus(i, j, first_glyph, glyph_type, qtype): + "Writes the ancus glyphs." + new_glyph() + glyph_name = '%s%s%s%s' % (glyph_type, AMBITUS[i], AMBITUS[j], L_DEMINUTUS) + if copy_existing_glyph(glyph_name): + return + write_left_queue(i, qtype, S_ANCUS, L_NOTHING, j) + if i == 1: + first_glyph = 'rvirgabase' + length = get_width(first_glyph) + else: + length = get_width(first_glyph) - get_width('line2') + simple_paste(first_glyph) + if i != 1: + write_line(i, length, (-i+1)*FONT_CONFIG['base height']) + width_dem = write_deminutus(-i, j, length, + firstbar = 0 if i == 1 else 2) + set_width(length+width_dem) + end_glyph(glyph_name) + +def leading(): + "Creates the leading fusion glyphs." + message("leading fusion glyphs") + for i in range(1, MAX_INTERVAL+1): + write_leading(i, 'PunctumLineTR', S_LEADING_PUNCTUM) + for i in range(1, MAX_INTERVAL+1): + write_leading(i, 'idebilis', S_LEADING_PUNCTUM, L_INITIO_DEBILIS) + for i in range(1, MAX_INTERVAL+1): + write_leading(i, 'QuilismaLineTR', S_LEADING_QUILISMA) + for i in range(1, MAX_INTERVAL+1): + write_leading(i, 'OriscusLineTR', S_LEADING_ORISCUS) + +# lique has a slightly different meaning here +def write_leading(i, first_glyph, glyph_type, lique=''): + "Writes the leading fusion glyphs." + new_glyph() + glyph_name = '%s%s%s' % (glyph_type, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + length = -get_width('line2') + if i == 1 and first_glyph != 'idebilis': + length = 0.1 + if first_glyph == 'PunctumLineTR': + first_glyph = 'Punctum' + elif first_glyph == 'QuilismaLineTR': + first_glyph = 'Quilisma' + elif first_glyph == 'OriscusLineTR': + first_glyph = 'Oriscus' + length = get_width(first_glyph) + length + paste_and_move(first_glyph, 0, -i * FONT_CONFIG['base height']) + if i != 1: + write_line(i, length, -(i-1) * FONT_CONFIG['base height']) + simplify() + set_width(length) + end_glyph(glyph_name) + +def fusion(): + "Creates the fusion glyphs." + message("simple fusion glyphs") + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'PunctumLineTR', S_PUNCTUM, L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'msdeminutus', S_UPPER_PUNCTUM, L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'base6', S_LOWER_PUNCTUM, L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'idebilis', S_PUNCTUM, + L_INITIO_DEBILIS_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'QuilismaLineTR', S_QUILISMA, L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'OriscusLineTR', S_ORISCUS, L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'SalicusOriscus', S_UPPER_ORISCUS, + L_UP) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'SalicusOriscus', + S_ORISCUS_SCAPUS, L_UP, qtype='short', + stemshape=S_FLEXUS_ORISCUS_SCAPUS) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'SalicusOriscus', + S_ORISCUS_SCAPUS_LONGQUEUE, L_UP, qtype='long', + stemshape=S_FLEXUS_ORISCUS_SCAPUS) + write_fusion_leading(1, 'SalicusOriscus', + S_ORISCUS_SCAPUS_OPENQUEUE, L_UP, qtype='open', + stemshape=S_FLEXUS_ORISCUS_SCAPUS) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'odbase', S_ORISCUS, L_DOWN) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, "osbase", S_ORISCUS_SCAPUS, L_DOWN, + qtype='short', stemshape=S_FLEXUS_ORISCUS_SCAPUS) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, "osbase", S_ORISCUS_SCAPUS_LONGQUEUE, L_DOWN, + qtype='long', stemshape=S_FLEXUS_ORISCUS_SCAPUS) + write_fusion_leading(1, "osbase", S_ORISCUS_SCAPUS_OPENQUEUE, L_DOWN, + qtype='open', stemshape=S_FLEXUS_ORISCUS_SCAPUS) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'OriscusReversusLineTLBR', S_LOWER_ORISCUS, + L_DOWN) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'PunctumLineBR', S_PUNCTUM, L_DOWN) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'PunctumLineBLBR', S_UPPER_PUNCTUM, + L_DOWN) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'mademinutus', S_LOWER_PUNCTUM, L_DOWN) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'VirgaBaseLineBL', S_VIRGA_REVERSA, L_DOWN, + qtype='short', stemshape=S_FLEXUS) + for i in range(1, MAX_INTERVAL+1): + write_fusion_leading(i, 'VirgaBaseLineBL', S_VIRGA_REVERSA_LONGQUEUE, + L_DOWN, qtype='long', stemshape=S_FLEXUS) + write_fusion_leading(1, 'VirgaBaseLineBL', S_VIRGA_REVERSA_OPENQUEUE, + L_DOWN, qtype='open', stemshape=S_FLEXUS) + +# lique is only for initio debilis here +def write_fusion_leading(i, first_glyph, glyph_type, lique, qtype = None, stemshape = None): + "Writes the fusion glyphs." + new_glyph() + glyph_name = '%s%s%s' % (glyph_type, AMBITUS[i], lique) + if copy_existing_glyph(glyph_name): + return + length = -get_width('line2') + if (i == 1 and first_glyph != 'idebilis' and first_glyph != 'odbase' + and first_glyph != 'OriscusReversusLineTLBR' + and first_glyph != 'osbase'): + length = 0.1 + if first_glyph == 'PunctumLineTR' or first_glyph == 'PunctumLineBR': + first_glyph = 'Punctum' + elif first_glyph == 'QuilismaLineTR': + first_glyph = 'Quilisma' + elif first_glyph == 'OriscusLineTR': + first_glyph = 'Oriscus' + elif first_glyph == 'OriscusScapusLineTR': + first_glyph = 'OriscusScapus' + elif first_glyph == 'OriscusScapusLongqueueLineTR': + first_glyph = 'OriscusScapusLongqueue' + elif first_glyph == 'msdeminutus' or first_glyph == 'PunctumLineBLBR': + first_glyph = 'PunctumLineBL' + elif first_glyph == 'mademinutus' or first_glyph == 'base6': + first_glyph = 'PunctumLineTL' + elif first_glyph == 'SalicusOriscus': + first_glyph = 'OriscusLineBL' + elif first_glyph == 'VirgaBaseLineBL': + first_glyph = 'rvirgabase' + length = get_width(first_glyph) + length + if qtype: + write_left_queue(i, qtype, stemshape, lique) + simple_paste(first_glyph) + if i != 1: + if lique == L_UP or lique == L_INITIO_DEBILIS_UP: + write_line(i, length, FONT_CONFIG['base height']) + elif lique == L_DOWN: + write_line(i, length, -(i - 1) * FONT_CONFIG['base height']) + simplify() + set_width(length) + end_glyph(glyph_name) + +if __name__ == "__main__": + main() |