I have enough datapoints to report some findings from my comparison of the 
appearance of fonts across platforms, in particular on the length of strings in 
fields and text baselines, and to correct some of my previous statements. My 
intention is to compile a database for some 7000+ fonts in 7 different font 
sizes ranging from 9pt to 18pt on Mac Windows and Linux system; but for now 
(for reasons given below) I looked at four basic fonts in common use: Arial, 
Times New Roman, Noto Sans and Noto Serif.

The good news is that the horrible problem of different strings lengths is no 
longer a problem, as long as your target platforms are just Mac or Windows 10. 
For each of these four fonts, strings in (right or left justified) fields have 
the same rendered length (they differ between fonts of course). I would be 
confident that holds for all TrueType fonts installed on these platforms, 
starting from the advent of Windows 10. My former claim about a difference 
between High Sierra and Monterey on the Mac is incorrect, the result of a 
coding error. Of course the field or stack must have a font assigned: leaving 
the font to empty will result in the system using its own font, which will be 
consistent with the look-and-feel of the platform/system version, but which 
will certainly be quite different between platforms.

On LInux (Ubuntu 18.x) however, string lengths for all the fonts in all sizes 
are quite different, sometimes longer and sometimes shorter than on the other 
platforms. The biggest difference was for Noto Sans 9pt, the sample Linux 
string being 14% longer; this was an outlier, mostly the Linux strings were 
less than 8% longer. In the other directions was Arial 15pt, where Linux was 5% 
shorter. So if Linux is a target platform, allow some extra length for your 
fields (on the right  for a left justified field, on the left for a right 
justified label).

A more difficult problem is the vertical placement of text. With the default 
settings for fields, strings in Windows will typically appear 2 or 3 pixels 
lower than on a Mac, which can mess with your layout — text carefully 
positioned on one platform will appear too close to nearby objects on the 
other, or will not align with text in adjacent fields. This can be fixed by 
adjusting the topMargin of the field, but the details are not straightforward..

The baseline for rendered strings is determined by the font metrics and the 
font size; unfortunately Mac Windows and Linux all use different metrics from 
each other. It would be nice if LC had a function which returned the baseline 
for the rendered string, but I couldn’t find such a function. The closest 
formula I can get is (for text using the textFont and textSize of the owner 
field, and consigning to oblivion the formula I had previously proposed which 
was caused by the aforementioned error plus a glitch in the data processing 
unit, ie my brain.)

     first baseline relative to the top of the field = the topMargin of the 
field + fontAscent - 6
 where
    fontAscent = - (item 2 of measureText(fld <fldname>,fld <fldname>,”bounds”)

Why the magic number -6? It seems this places text in a common font such as 
Time New Roman or Arial in medium range textSizes such as 11 to 15 so that the 
top of the lower case character “x” is at ...approximately... the topMargin of 
the field. This would be the ideal placement for text at all fonts and sizes, 
but of course in general 6 is nothing like the difference between the 
fontAscent (the height of the capital “A” above the baseline) and the height of 
“x”, and anyway the fontAscent is not the actual height of the font, so for 
other sizes and fonts the placement is wildly different from the ideal. The 
simplification is probably a legacy of a decision originally made for speed 
given the complications of dealing with different font formats; a correction 
now would break all existing stacks.

Actually while my formula fits precisely most of the time, it occasionally is 
out by 1 pixel. And that precision holds for all fonts I have looked at, even 
for the gorgeously extravagant Zapfino at 64pt. So the discrepancy is probably 
some floating point rounding from the correct formula. If anyone (LC 
engineer’s?) can provide the correct formula that would be nice, but I have the 
feeling it may involve a font metric not directly exposed by the LC api.

The formula can be used to adjust the topMargin so that the baseline is fixed, 
to within 1 pixel anyway The adjustment would have to be done at runtime, or 
applied to a stack before building a standalone for a particular platform, 
using a pre-cooked fontAscent. Hence my database project. Just at the moment 
this has hit a bit of snag: as far as I can see, fonts have to be added to 
Windows 10 one at a time -- on a Mac you just dump a folder of fonts onto Font 
Book. Does anyone know how to do this in Windows and Linux? If necessary, 
following Ralph’s post I believe I could work out where the Mac and Windows 10 
systems pick up their ascent parameters by parsing the ttf metadata (horrors!), 
but the Linux values are another mystery. 

The apparently obvious solution to the problem is to set fixedLineHeight to 
true, but unfortunately this does not work. The bottom of each character glyph 
will I guess be placed on a fixed line independently of the font, size or 
platform, but that is not the baseline, which will still be dependent on font 
metrics. The result is that even with fixedLineHeight true baselines are 
different for different sizes of a given font, and for different fonts for a 
given size even on the same platform (so adjacent fields with different fonts 
or sizes will not align baselines), and also different for a given font and 
size on different platforms so the layout looks sloppy.

 My formula for the first baseline for a field with fixed line height is

        baseline =  the topMargin of the field + the textHeight of the field - 
item 2 of measureText(the field,the text,"size”) + fontAscent - 7

which again seems to be accurate except for a few (different!) cases where it 
is 1 pixel out. Again, if anyone knows the exact formula I would be grateful to 
hear it. 

Possibly an enhancement to LC could provide a fixedBaseline,baseline pair of 
properties for fields, which would set the first baseline at a user value, 
bleeding the text into the top margin, thus eliminating this problem.


Neville




_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to