All,

What follows is kind of in 3 parts, but all jumbled in together: partly
me proposing an enhancement to fltk's text handling API, partly me
asking for suggestions for my current problem, and partly me making some
observations on the current method.

Probably this needs broken out as a couple of STR's, but I wanted to see
what folk thought about it first.

Background: 
I had done a little app that used Cairo to render text (as an organised
map) positioning the various strings in specific locations wrt each
other. This worked well, but was surprisingly slow.
So I reworked the code in "plain" fltk. This ran much faster, but
basically did not work.
The reason it did not work was that the extents returned by fl_measure,
fl_height and fl_width for a given string are not really all that useful
- at least not in this context.

So I had a look at the code, here's what I find:

- fl_height (and by extension the height part of fl_measure) is simply
set when the font is loaded (based on reported ascent and descent for
the most part) and does not measure the actual extent of the text at
all.

- No method even exists such as "fl_height(char *)" that could be used
to ascertain the height extent of given string.

- fl_width(char *) (and it's siblings) more or less seem to work,
although I am concerned about the win32 implementation, which seems
suspect to me. (More on that story later...)

Tests:

I ran a few tests, loading the same font (as far as I can tell) in both
fltk and Cairo, then printed the extents of a few strings in each. The
reported widths are similar (although win32 is a bit dodgy) but the
heights vary significantly. 
It is clear that some faces have quite odd ascent/descent settings, and
the height we generate really doesn't match the rendered glyphs at all
well.

In general, the width/height returned by Cairo defines a box that fits
fairly neatly round the actual glyphs, whereas the fltk extents do not,
the bounding box is generally too high. Sometimes very much so. Which
messed up my app.


Proposal 1:

For fltk-1.3 we consider adding a fl_height(char *) function (or set of
functions) analogous to the fl_width(...) family, that returns, as best
we can, the *actual* extent of the passed string, rather than simply
returning the font's default height all the time. The existing
fl_height(void) function will continue as at present for backwards
compatibility.

Proposal 2:

For fltk-1.3 we consider, as above, reworking fl_measure(...) to return
the actual height extent of the passed string. I am not clear on whether
we need a "backwards compatible" fl_measure or not... Anyone?


fl_width and win32:

(I think this is a bug...)
When testing this, I found that the width returned on win32 seemed to be
more "out of step" with the Cairo value than I was seeing from the same
test on OSX.

Looking at the win32 implementation of "double fl_width(const char* c,
int n)" I notice it looks a bit odd; certainly it seems to be out of
step with the OSX and XFT implementations. (It *might* be more
consistent with the implementation of XUtf8TextWidth() in the
fl_font_x.cxx version, but I seldom/never use that variant.)

Anyway, when passed a string, the win32 version of fl_width essentially
computes the width of each individual character, then adds them
together, completely ignoring any kerning or similar that the text
rendering mechanism will apply, so the computed width is generally going
to be a bit bigger than "the truth", possibly by a lot depending on
which actual glyphs are in the string...

Even more strangely, it does this using the function call
GetTextExtentPoint32W(...) which is intended to be passed a string for
measuring, so we have special code in fl_width() to chop the input
string up into individual characters for measuring independently, then
the measured widths are cached in a large (dynamically allocated and
resized) array so we can get the individual glyph sizes more quickly
next time.

Both the XFT and OSX implementations simply measure the passed string
directly, (using XftTextExtents* and ATSUGetUnjustifiedBounds
respectively) so that the returned width reflects kerning and so forth
of the string *as it will be rendered*. No attempt is made to cache
glyph widths. 

The win32 implementation seems wrong to me - we need to know the width
of the string *as it will be drawn* and therefore we need to allow for
kerning and layout, and to this end we must not measure individual
glyphs, and we can not cache the glyph sizes (since the sizes may not be
valid, depending on which glyphs are adjacent in any given string with
kerning, layout, etc...)


And that's about it... Long post, sorry.

- What do people think? Should we have an extended fl_height/fl_measure
mechanism to determine the actual size of the text glyphs to be drawn?
If so, I'll generate some STR's.

- Does anyone have existing code to determine actual glyph height under
fltk? If not, I'll be writing some anyway, so I'll (later) post it onto
any STR's I raise for this. It doesn't look to be all that hard (if we
do it inside the fl_font mechanism) but looks to be a real pain to do in
"user space" under fltk, as we don't have ready access to the actual
platform specific font entities..

- Do folk think the win32 fl_width() mechanism should be brought more
into line with the XFT/OSX implementation? Or should we leave it alone?
Or...?

Cheers,
-- 
Ian




SELEX Sensors and Airborne Systems Limited
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 
3EL
A company registered in England & Wales.  Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to