2018-10-09

SVG, font metrics, am I being thick?

I really hope someone tells me I have missed the bleeding obvious for a change.

I think SVG lacks two key features.

1. The ability to set a maximin size on a line of text, i.e. so that if it works out longer it will be squashed in some way. There is a way to set a calculated size and have either the spacing or the spacing and glyphs adjusted to match that, but I cannot find a way to say "squash, but only if it would be too big".

2. The ability to take a block of text, give it a width (and height, why not) and line spacing and have it fill the box, breaking on spaces between words.

If there is svg magic (and I don't mean javascript to run on a web site that will do the business later), just plain svg that will easily convert to png or pdf, and still work, that is what I want.

The alternative, for which I am still massively failing to find a solution, is a simple Debian installed C code library (not C++ please) that allows me to ask "how wide is this string in this font". I found qfontmetrics which looks spot on, but is C++. Obviously, including emojis!

With this I can make the tools I current have which produce svg output (to later be converted to PDF or PNG, etc) work out when to set a line width, or break blocks of text, and work with normal svg.

All of this is a doddle in postscript, but unless someone has a patch for gs to handle utf-8 strings natively and handle a fuller character set with the likes of emojis, I need to move away from postscript, hence using svg. Just hitting this key stumbling block for now.

Update: Thanks for all the comments. I am looking at freetype at the moment. It looks like it has exactly what I need, but slightly struggling with Emojis and the like at the moment :-)

Update: Yes, FreeType has simple C functions to load a font/face and find the size of glyphs based on unicode characters, and simple to tell it does not have the character and use a noto/emoji font instead, etc. This should be simple to then work out line wrapping and sizes for SVG with tspan for emojis and the like. Now I know it is all possible and how to do it, I have to think about the project for which I was asking this - a new system for designing printed plastic cards...

6 comments:

  1. Don't know about point 1) (some fiddling with text paths perhaps) but auto-wrap looks like it is going to be in SVG 2

    https://www.w3.org/TR/SVG2/text.html#TextLayoutAuto

    ReplyDelete
  2. Probably easier to fix PostScript to keep it relevant.

    ReplyDelete
    Replies
    1. I'd love that, but gs is a bit big to dive in to. It would need a flag to tell it strings are UTF8 and to treat as arrays of long rather than arrays of byte, and the font mappings handling the character codes, but that would be great.

      Delete
  3. Have you looked at Cairo? I don't know a huge amount about it (so don't know if it does everything you need), but it has a C API, has calls to get the extent of text, can output to SVG, PS, PNG etc, and I'd be surprised if it wasn't a standard Debian package. May not be a full solution, but perhaps a piece in the jigsaw?

    ReplyDelete
    Replies
    1. I wonder if https://cairographics.org/manual/cairo-text.html#cairo-text-extents is any help...

      Delete
  4. https://www.pango.org/ might be a good starting point - it's what I used in a past job for text layout stuff, including metrics data.

    ReplyDelete

Comments are moderated purely to filter out obvious spam, but it means they may not show immediately.