Measuring font metrics / text width

In order to do custom text drawing, text selection, and text wrapping, I need to be able to measure the width of text accurately – ideally in a cross-platform manner (if using the same font on different platforms). How does one accomplish this in Xojo?

Measuring the on-screen start and end of a run of text with attributes applied, which may be kerned, or use fractional widths, requires access to accurate layout information. Is any of that information Xojo-accessible?

measureing font/character sizes on macOS is going to be WAY more accurate than it will be on Windows
macOS reports them as Single values, while Windows is always an Integer value
so if you measure single characters, the rounding error on Windows will kill you in a short period of time.

Otherwise you’d have to dive into the font files themselves and extract the spacing, width and kerning values

@Dave S – good points.

What I like to do is measure styled RUNS of characters, because it’s very difficult to get the measurement of how the system might run those characters together.

Can Xojo accurately report back the width & height measurement for drawing text into a canvas, independent of resolution?

When I wrote gPDF for Xojo, I faced this same challenge… what I ended up doing (to overcome Windows being integer)
was to measure against a 1000 point font not the actual font size…

Also… bear in mind that the same named font installed on macOS will possibly have different metrics
that is Courier on macOS won’t measure the same as Courier on Windows (for example)

@Dave S –

[quote]When I wrote gPDF for Xojo, I faced this same challenge… what I ended up doing (to overcome Windows being integer)
was to measure against a 1000 point font not the actual font size
[/quote]
I didn’t think you could even create a 1000 point font on the Mac side – least we couldn’t in the bad old QuickDraw days

[quote]Also… bear in mind that the same named font installed on macOS will possibly have different metrics
that is Courier on macOS won’t measure the same as Courier on Windows (for example)
[/quote]
Oh, I know that problem very well. That’s why we have our own high-quality OpenType implementation of Courier, Courier MM Screenwriter.

With Courier(s), you can play very fast-and-loose with the metrics, because a standard script page is always going 10 LPI high and 10 CPI horizontal – no matter what the actual Courier font says.

But – nowadays it seems crazy not to be as accurate as possible with layout – especially with foreign unicode script.

What are the Xojo graphics routines for drawing and measuring text destined for a canvas?

pet peeve… no “Z”

@Dave S – I think the Mac is doing some kind of magical auto-correction, because I picked your correctly-spelled name from a popup menu that only had two choices – you and Dave Simpson. WAIT – I’m looking at THIS VERY MESSAGE – and it was automatically changed again!!!

I see what happened – it IS the Apple MacOS spell checker automatically changing it when I typed two dashes! I wonder why?!

Ah… ok… Wonder why Apple thinks it knows best how my name is spelled :slight_smile:

@Dave S – Don’t know, but I just told the macOS spell checker to “learn” the proper spelling of your name. So I suspect many of your “peeves” were caused by Apple’s autocorrect.

If you’re no longer peeved at ME, then may I ask:

[quote]What are the Xojo graphics routines for drawing and measuring text destined for a canvas?
[/quote]

Thanks!

LOL…
well I use the canvas to measure things

  • create a new picture (any size like 10x10 is fine)
  • get the graphics object of the picture
  • set the font/size on that graphics object
  • extract the StringWidth , TextHeight and TextAscent as required

I’ve done a lot of string measuring, wrapping and placing, and have never had a problem using StringWidth. But perhaps I’m not doing anything as complicated as you are. This was on Windows, by the way.

If you have not already done so I would look at the FTC product by Bob Keeney as that might avoid you doing a lot of heavy lifting. I haven’t used it myself but I have heard good things about it.

If you want to implement this yourself I would first look at using the operating system text APIs rather than native Xojo functions as you will have access to a lot more functionality. The MBS plugins have functions for CoreText - not sure about MS-Windows.
The reason why I say this is that depending on what your text editor is for, you may need to solve one or more of these:

  1. Measuring text runs accurately and in a way that doesn’t break font shaping rules or the Unicode bidi algorithm
  2. Determining word break / line break positions
  3. Drawing text so that it is positioned accurately
  4. Drawing right to left / bidirectional text correctly
  5. Cursor positioning / drawing
  6. Hit-testing

The Xojo functions will allow you to do all of the above but you might have to put in a lot of effort to cover everything you need and do it well. For example, the Xojo IDE code editor which seems to be a custom canvas suffers from small text positioning issues which are possibly caused by measuring and laying out the text using the Xojo functions.

The simplest way to increase font measurement is to do it on a larger font size.

For instance, instead of measuring at size 12 which at 72dots per an inch is around 8 pixels wide, measure at 10x that value.

At 120 points, you get a very accurate measurement on both Mac and windows, and dividing by 100, you get a single value with decimals which prevents rounding errors.

You could use MBS Xojo DynaPDF plugin to cross platform measure text widths.

See DynaPDFFontInfoMBS class for details on system fonts. And GetTextWidth function on DynaPDFMBS class to query width of text with current font. The DynaPDFGlyphOutlineMBS class even can give you outlines for glyphs.

@Kevin Gale – The FTC package appears to be quite impressive. It didn’t have support for hidden text / hidden paragraphs, which I need, or (I think) hooks to control the pagination / layout process, which I also need. Nor is there (at present) an IOS version. But I’m guessing the source code could probably be modified.

I presently have my own source code for an entire Unicode-capable fully back-end cross-platform text editor – the only thing I need to do is hook it up to a front end capable of drawing (and printing) proper Unicode text. Most systems that do unicode drawing and layout ultimately use either pango or harfbuzz or more likely are based on FreeType to handle the specialized aspects of Unicode font shaping, layout and drawing. IOS, Android, Linux, Java and others do. Not sure about Windows itself.

Our unicode C++ backend was written to connect to Java, and also uses Pango/Harfbuzz/FreeType, so any front end that can properly lay out and draw unicode text will work for us.

If Xojo’s text drawing uses any of these, then that’s great – I’m golden. On macOS and IOS, it is likely that Xojo just uses Cocoa or Core Text calls, which means I’m still in good shape.

I also have a complete non-unicode text engine, which may or may not be as easily convertible – my question was primarily exploring for that case.

Maybe @Joe Ranieri and @William Yu could give more insight into how Xojo does its unicode text drawing / layout, especially on the macOS / IOS and Windows side.

I’m the wrong guy to be asking that :stuck_out_tongue:
And the person(s) that can answer this are off until Monday for Thanksgiving

@Norman Palardy – I’m not in a rush. Who should I direct that quest to next week?

@William Yu can answer the Linux & Windows side
@Joe Ranieri the Cocoa side

I doubt there will every be an iOS version. Not impossible, I suppose, but It would be a formidable task. One that I see no reasonable return on investment.

That would require a TextEditCanvas plugin or library be developed by Xojo or someone else. At present, two years after launch of that platform, there is no plugins for Xojo iOS at all.

I tried to develop a multi fonts, multi styles text editor based on UITextView. It is indeed possible, but quite different from what I understand of FTC inner workings.