[L2Ork-dev] font spec

Jonathan Wilkes jon.w.wilkes at gmail.com
Fri Apr 5 18:30:03 EDT 2019

Hi list,

I'd like to draw up a plan for setting an arbitrary font at startup
for Purr Data while some semblance of consistency and sanity across
platforms. This is mostly for myself atm unless someone wants to go
ahead and implement it. Alternatively, if someone wants to make some
screenshot examples for the written explanations I'm giving that would
certainly be helpful.

The reason consistency is important is that a Pd user on OSX has
absolutely no idea how fonts measure on Windows or Linux. And there's no
cross-platform spec (nor even a single platform spec AFAICT) that would
require a font at a given pixel size to actually conform to that pixel size.

That's a problem because Pd users build patches using absolute positioning.
Suppose a Windows user puts one message box [hello( at (0,0) and another
message box [world( at (0, 40). Then they visually confirm that the result does
not cause overlapping boxes and they ship their patch.

Now suppose a user on Ubuntu opens that same patch. Perhaps this
version of Ubuntu renders the font used for the text "hello" and "world"
slightly wider, so that for example the word "hello" takes up 2 more pixels
than it did when rendered in Windows.

It's possible to code up a clever algorithm that checks the font width at
startup and adapts the box size to accommodate the wider rendered text
on Ubuntu. In fact that appears to be what Pd-extended attempted to
do in tcl/tk at some point.

But notice that this behavior actually *breaks* the "hello world" patch
above. While the message box border would be correctly adjusted around the
word "hello", that message box would now overlap with the message box
containing "world." That's not what the Windows user wanted-- after all,
they visually inspected the patch to avoid any overlaps. But overlaps are
what the Ubuntu user sees with such a system.

Now, you might decide to be even *more* clever and code up an algorithm
that scales the origin of object/msg boxes based on the difference between
the width of the rendered font and the ideal font width. But of course you'd
hit nasty problems there with widgets like iemguis and ds scalars which
can use arbitrary shapes and paths. Plus even if you took the time and
complexity to scale those, people can embed images in their patches
which cannot easily be scaled without affecting the quality.

On the other hand, you might decide to be drastically *less* clever and
make a rule that all boxes positioned in a row must leave at least some
amount of empty space in between them to accommodate the possibility
for font discrepancies. However, the same problem applies to
font height and inter-line spacing as applies to font-width. So
multi-line comments can "accordion out" and overlap on the Ubuntu
user's machine
while they look just fine for the Windows user. It's simply too much of a
burden to expect users to keep these subtleties in mind when writing

The only sensible solution I see is to position and size boxes *exactly*
the same on all platforms and then adjust font sizes so that they fit the
default metrics given for each of the available Pd font sizes. This means that
in some cases the boxes aren't tightly fitting around the text (e.g., on
some Ubuntu versions where the fonts are rendered significantly wider than
OSX and Windows). But it also means that a user can write a patch and
be guaranteed that the boxes won't overlap on any of the other platforms.

So here's a rought spec to do that:

1. GUI must hard-code the default font metrics used in Pd Vanilla and send them
off to Pd at startup as part of the "init" method. This will ensure backward
compatibility with box sizing of previous versions of Purr Data and previous
versions of Pd Vanilla. (Unfortunately Pd-extended changed those defaults
for some of the font sizes, but I *think* size 12 is the same so at least that
would be consistent.) This will also ensure forward compatibility with
Purr Data. I hope Pd Vanilla hasn't changed those hard-coded metrics--
if they haven't then we'll get forward compatibility with Pd Vanilla, too.

2. We use an algorithm at startup to pick GUI font sizes that most closely
to the hard-coded Pd default metrics without exceed the default
height/width metrics. This means that a user who chooses Pd font size
"12" isn't
guaranteed to get a pixel-size 12 font. But that was never a guarantee in
the first place, and Deja Vu Sans Mono seems to look quite crisp and readable
even though we're using non-integer GUI font sizes on most platforms.

3. Box borders are *always* drawn based on default Pd font sizing metrics.
This guarantees all boxes in patches will be pixel exact.

4. Comment boxes must show a border in editmode to communicate to the
user the maximum size of the box. This way users can use that border to
avoid overlaps on all platforms.

5. Iemgui fonts-- ugh, I have no idea. Let's just say "you're on your own" and
try to get the *single* sys_fontsize working correctly for arbitrary fonts.

Currently, there's no algorithm to do the size picking at startup.
Instead we're
just checking for that weird Ubuntu wide-font case and scaling things down
so that they fit into the boxes.

So I guess the first thing to do is to implement an algorithm that selects the
GUI font sizes that are hard-coded in font_map and suboptimal_font_map at
startup. If we can generate the values for font_map on the fly then we'll have
a good starting point.

Next thing would be to figure out some sensible interface to replace
gobj_font_y_kludge. Those values were just from testing on each platform,
and luckily the Ubuntu edge-case didn't affect font heights at all. That may
be trickier to get right.

Finally, we need some way to get data about non-Western languages and
how they fit into this. Technically we could get rid of sending font metrics
with the "init" message, but perhaps non-Western characters require a
different set of default metrics for Pd patches to be usable/readable in those
languages. If anyone has some links related to that it would be helpful.


More information about the L2Ork-dev mailing list