Closed vitto32 closed 5 years ago
I change the font after typesetting via CSS:
svg tspan {
font-family: simonetta, VerovioText !important;
}
For example:
http://www.tassomusic.org/work/?id=Trm1049a&k=e
(Notice that the text of the page and the music matches).
The size of the font is close to Times, but it would be nice to be able to typeset with a font other than Times (and when generating PDF with the PDF toolkit, the resulting font substitution has a smaller font size).
Thank you @craigsapp . That's the approach I'm already using (through CSS) and I changed the font size in style.h (DEFAULT_LYRIC_SIZE) to get smaller lyrics.
What I'd like to do now is to set the font metrics to match a less condensed font. I think Times.xml in data folder is the key but I don't know how to generate a similar file with a different font. I've tried the tools in the font folder but they seems more targeted to notation fonts (Bravura etc..).
The Times.xml (and related files) where generated offline and include the bounding boxes of some text characters. The font itself is not included and is always the one provided by the SVG viewer. For this reason it makes sense to do this only with a standard fonts, such as Times. (Otherwise, the font is quite likely to be missing and will be replaced by something else, which will cause layout problems. Already with Times this is not exactly the same in all plateform / browsers). We can look at including other standard fonts in the same way (e.g., Georgia, Arial) but this will make sense to have a styling mechanism in place.
Another option is to include the font itself (or a font url) but this raises other issues.
@lpugin I am forced to use a specific font for a project. Could you please consider adding your script for calculating the Times.xml
to the repo? That would be super helpful!
I guess, the script was/is somewhat similar to the generate-bbox.js
in the fonts
folder. Unfortunately, it relies on the abandoned "phantomjs". I'll try to find some time in the near future to come up with something more general.
This is a general feature request
To summarize what has to be done here:
--text-font
and --smufl-text-font
)First step would be to support just one alternative text and "music text" font, respectively.
@lpugin Can we re-open for discussion? We want to work on this.
I recently had to use a custom font for the text so I came up with my own python script to generate the bounding boxes needed by Verovio. Maybe it is of use for others.
I also had to replace all occurrences of the font name Times
with VerovioText
(random choice) in the code base and load my custom font with that name via CSS when using the SVG output in the browser.
The script only depends on fonttools
- No PhantomJS or other browser-based rendering needed.
from pathlib import Path
from fontTools.ttLib import TTFont
from fontTools.pens.boundsPen import BoundsPen
def main(args):
output_dir = args.output_dir
output_dir.mkdir(exist_ok=True)
with open(output_dir / "VerovioText-Regular.xml", "w") as f:
f.write(extract_glyphs(args.regular_path))
with open(output_dir / "VerovioText-Bold.xml", "w") as f:
f.write(extract_glyphs(args.bold_path))
with open(output_dir / "VerovioText-Italic.xml", "w") as f:
f.write(extract_glyphs(args.italic_path))
with open(output_dir / "VerovioText-BoldItalic.xml", "w") as f:
f.write(extract_glyphs(args.bold_italic_path))
def extract_glyphs(font_path: Path):
font = TTFont(str(font_path))
glyph_set = font.getGlyphSet()
glyph_order = font.getGlyphOrder()
name_to_unicode = font["cmap"].buildReversed()
bp = BoundsPen(glyph_set)
result = '<?xml version="1.0" encoding="UTF-8"?>\n<bounding-boxes font-family="VerovioText" units-per-em="2048">\n'
for glyph_name in glyph_order:
if glyph_name not in name_to_unicode:
continue
bp.init()
glyph = glyph_set[glyph_name]
glyph.draw(bp)
bbox = bp.bounds
if bbox is None:
continue
x_min, y_min, x_max, y_max = bbox
width = x_max - x_min
height = y_max - y_min
if width == 0 or height == 0:
continue
for unicode in name_to_unicode[glyph_name]:
c = hex(unicode)[2:].upper()
result += f' <g c="{c}" x="{float(x_min)}" y="{(float(y_min))}" w="{float(width)}" h="{float(height)}" h-a-x="{float(glyph.width)}" />\n'
result += "</bounding-boxes>"
return result
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Extract glyph bounding boxes from font files.")
parser.add_argument("output_dir", type=Path, help="Path to output directory. Usually <verovio-root>/data/text/")
parser.add_argument("-r", "--regular_path", type=Path, help="Path to regular font file.", required=True)
parser.add_argument("-b", "--bold_path", type=Path, help="Path to bold font file.", required=True)
parser.add_argument("-i", "--italic_path", type=Path, help="Path to italic font file.", required=True)
parser.add_argument("-bi", "--bold_italic_path", type=Path, help="Path to bold italic font file.", required=True)
args = parser.parse_args()
main(args)
There are still some details to be covered when using a custom text font. The most apparent one is "incorrect" placement of dashes in lyrics:
In order to move them up to be roughly in the middle of the font's x-height the (for now constant) multiplier has to be adjusted in https://github.com/rism-digital/verovio/blob/fd201a9635f207ba34e38746d0d7359a0bbdc219/src/view_control.cpp#L1330 Example:
- y += (m_options->m_lyricSize.GetValue() * m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 5);
+ y += (m_options->m_lyricSize.GetValue() * m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 3.7);
Thanks! Would you be able to make a PR?
Thanks! Would you be able to make a PR?
This is too hacky to be a comprehensive solution for now. A few things are still missing:
If the fonts are not included, there are some other issues:
@font-face {
font-family: 'VerovioText';
font-style: normal;
font-weight: 400;
src: url('/fonts/WhateverFont-Regular.woff2') format('woff2');
}
Though I'm not sure how this should be done with regard to font paths etc.
I could help with the Python stuff and make it a proper script that outputs all needed data. However, I am not really familiar with Verovio's actual codebase (or C in general), so I am a bit lost here. Also, this would introduce a hard dependency on Python with the fonttools
package.
EDIT Fonts could potentially be included by encoding them in base64 and including them in Verovio's CSS style block:
@font-face {
font-family: 'VerovioText';
font-style: normal;
font-weight: 400;
src: url(data:font/woff2;charset=utf-8;base64,<base64_encoded>) format('woff2');
}
I'm trying to change the default font (Times.xml) but I have no clue where to start from. I've tried using saxon9ee on an svg font but i get and empty xml.