Music Text

Congratulations on making it to the first mention of music in these docs!

Neoscore is able to draw thousands of common and uncommon musical glyphs by writing them as text in musical fonts.

font = MusicFont("Bravura", Mm(2))
MusicText(ORIGIN, None, "gClef", font)
/_static/rendered_examples/6K2RLT7SO6B6DOM22ATY2JNSRV2B5Q64.png

MusicFont and MusicText are used much like their plaintext counterparts, but instead of specifying text as plain strings you provide glyph names. These glyph names are used as keys to look up their corresponding unicode codepoints in the Standard Music Font Layout (SMuFL) schema with which all supported music fonts comply.

Unlike text fonts which are sized to a given line height, music fonts are sized to a given staff unit - the distance between two staff lines. This size may be given either as a unit value or a unit type where unit(1) is that distance.

MusicText(ORIGIN, None, "ornamentTurn", MusicFont("Bravura", Mm))
MusicText((Mm(3), ZERO), None, "ornamentTurn", MusicFont("Bravura", Mm(1)))
MusicText((Mm(6), ZERO), None, "ornamentTurn", MusicFont("Bravura", Mm(2)))
MusicText((Mm(11), ZERO), None, "noteheadBlack", MusicFont("Bravura", Mm(2)))
/_static/rendered_examples/LLTBWNTT3VNUBZH6BBDKWMN5KPGEWABG.png

The way glyphs are aligned relative to the given MusicText position varies based on the SMuFL schema. For example noteheads are locally aligned such that they can be placed at the Y position of a staff line or space-center, while the treble clef glyph expects to be placed on the fourth staff line.

font = MusicFont("Bravura", Mm(2))
Path.straight_line(ORIGIN, None, (Mm(30), ZERO))
MusicText(ORIGIN, None, "gClef", font)
MusicText((Mm(8), ZERO), None, "fClef", font)
MusicText((Mm(16), ZERO), None, "cClef", font)
MusicText((Mm(24), ZERO), None, "noteheadWhole", font)
/_static/rendered_examples/WUMZPPQ6KVPFORDOZXF4E7ZTAIHKFHTD.png

While the vast majority of MusicText objects consist of just a single glyph, multi-character text can be specified by passing a list instead.

font = MusicFont("Bravura", Mm(2))
MusicText(ORIGIN, None,
    ["noteheadBlack", "noteheadHalf", "noteheadWhole"], font)
/_static/rendered_examples/7IQPE3DVJBCTABJXVIQYJJXICVZCDC3X.png

Glyphs with SMuFL alternate codes can be specified with tuples.

font = MusicFont("Bravura", Mm(2))
MusicText(ORIGIN, None, "flag16thUp", font)
# straight-flagged alternate, aka "flag16thUpStraight"
MusicText((Mm(4), ZERO), None, ("flag16thUp", 1), font)
# short-flagged alternate, also accessible with the "flag16thUpShort" glyph name
MusicText((Mm(8), ZERO), None, ("flag16thUp", 2), font)
/_static/rendered_examples/PHPIH7EPZ4YFWPTLH6DPMD6U7FEITLIM.png

Each resolved MusicChar is placed in MusicText.music_chars, through which you can access rich glyph metadata provided by SMuFL:

>>> font = MusicFont("Bravura", Mm)
>>> mt = MusicText(ORIGIN, None, "gClef", font)
>>> mt.text
'\ue050'
>>> mt.music_chars[0].glyph_info
GlyphInfo(canonical_name='gClef', codepoint='\ue050', description='G clef',
    bounding_rect=Rect(x=Mm(0.0), y=Mm(-4.392), width=Mm(2.684), height=Mm(7.024)),
    advance_width=Mm(2.684), anchors=None)

If you expect to use music text often, we strongly recommend getting familiar with the SMuFL documentation, both to understand how it works and what metadata it offers, and to get a sense of what kinds of glyphs it offers.

Using other music fonts

In theory, neoscore should support all SMuFL-compliant music fonts, not just Bravura, but we haven’t tested this much yet. See Issue #29.