Conversation
currently, the "text" in exported SVG files is just glyphs with nothing linking them to the original text. with this Typst now adds a transparent <text> element that makes the text selectable in browsers and hopefully readable by screen readers.
now for every Glyph in a TextItem a <tspan> gets generated. thanks to the `user-select: all` CSS property it can only be selected in full, so ligatures work fine! todo: consider collapsing non-ligature tspans into larger tspans with per-character user-select (ie the default value)
uses `textLength` and `lengthAdjust`. sadly not supported in Firefox, but Safari/Chromium looks fine
|
Apparently it has been dealt with. It does not look good on all clients, but I guess there is not much Typst can do about it.
Also the fact that clicking a letter selects it feels pretty awkward. |
From my perspective, it's clearly the latter. |
I think it is still a good thing to support it if it is useful somewhere but since it is not correctly supported everywhere it should be opt-in with warnings in the docs. I feel like this is more of an issue with the SVG specification itself that would affect a lot of tools and users working with putting text in SVG graphics. I don't know how feasible this is nor how much time it would take for it to be accepted and adopted but I think it should be part of the specification to be able to embed text that would look the same everywhere and still be an object that contains the actual text. I can see how practically you would more often just need your text to look the same everywhere and don't need semantic information since SVG's purpose is not describing documents, but it aims to be semantic in how it describes shapes and text so ideally we could encode it in a way that keeps that semantic information. Also it's pretty nice that it keeps text accessible to people who can't read it on screen. So maybe we could make a proposal so we can come up with a cleaner solution in a distant future? Currently, we can apparently embed fonts into the SVG code using When it comes to heaviness of the files, if the file is large enough and you embed the font and optimize it, it goes back to approximately its initial size according to vecta.io. Now on smaller files it would still make it significantly heavier. But we could edit the font file so it contains only the glyphs that are used (and maybe perform other optimizations - I don't know what's possible with font files) before embedding it. As for it not being supported everywhere, it does look like this could be an issue (see caniuse.com) (and this is only browsers, also I don't know if it is testing only with remote webfonts that could be blocked for security reasons, or also base64-encoded ones). In this case I would at least make it possible to generate such outputs, if not default, but leave a "compatibility" option which just operates as the current SVG export. Note: For what's it's worth, the SVG wiki states about embedding fonts "WOFF fonts encoded in data: URIs should suffice." (https://www.w3.org/Graphics/SVG/WG/wiki/SVG_Fonts) Testing compatibility If the left text appears normal and the right text handwritten, the embedded font works. So far I've seen it work in Firefox, Chromium and VSCode and not work in the GTK File Chooser Dialog preview. Also weirdly on my end, here on GitHub, the font works from the preview in the message but clicking the image opens it in a new tab and the font doesn't display there (though it does display when opening the local file).
Isn't it just the browser's responsibility? If when just writing text by hand in an SVG file results in this behaviour it's nothing specific to our use case and trying to fix it makes the UX pretty bad.
|
|
I've looked into this a bit more together with @reknih and we've come to the following results and conclusions:
With this in mind, we've come up with one more approach that I would like to bring to the discussion: What if we mix this PR with an optimized
With this, the font-face rule should lead to correct bounding boxes in Firefox. In addition, we could probably drop a lot of the Thoughts? |
|
@laurmaedje making a font with just the metrics sounds good, i've actually originally intended to do that but decided there ought to be a simpler way (and, well, i wasn't sure if this is even wanted at all, so didn't wanna burn through a lot of effort for nothing. :p) and it's definitely a more robust solution! looked into it a bit, and it seems that for a very basic implementation (i.e. no ligatures, probably no RTL) we'd need to only preserve as for the |
|
Your solution sounds really nice laurmaedje.
Could you give some examples of those manual positioning adjustments you're talking about? With your solution, either the viewer supports Preemptively, all we can do is either use a
I don't really understand that part. But |
@marie-bnl not sure but i believe things like |
There are a couple other tables that are required by the OpenType spec though: https://learn.microsoft.com/en-us/typography/opentype/spec/otff#required-tables
Basically, Typst will emit the text as a bunch of One However, it's not guaranteed that the Notably, in the browser's layout the advance width would always1 be the one from the font because our synthesized font would be so primitive: No kerning, etc.
Footnotes
|





Problem
currently, text in SVG exports is represented by a full of references to the glyphs with nothing saying this is text:
Solution
this makes it so that the
<g>also contains a transparent<text>element that makes it selectable / readable by screen readers.result:


Quirks
the
user-select: allCSS property is used to make it impossible to select only part of a single-glyph ligature, which is not currently supported by Safari.textLengthandlengthAdjustare used to make selection boxes line up perfectly with the glyphs, which is currently not supported by Firefox and derivatives.