Phil,

I'm revisiting a few old issues at the moment. See below.

Phil Race wrote:
> I had a chat with Doug, one of the principal authors of this code.
>
I had a look at the italic adjustment code. It's a lovely piece of code.
 However, there are still discrepancies. The attached images show
individual lines from a paragraph in which the fonts have been changed
at arbitrary points within a word. The line are derived from a
TextMeasurer by successive calls to getLineBreakIndex and getLayout. The
most obvious problem is in line3, where the word "There" is split after
"Th". In line1, "possibility" is pretty tight.

I think this relates to the fact that, AFAICT, the ascents and descents
of the contiguous text that are used for the increment of advance are
the metrics of the whole of the component, or at least of the part in
the TextLine. This may explain why "possibility" is set tighter than
"setting" in line5. The 't's are shorter than the 'i' and 'b' of the
Luxi font, yet line5 also contains 'l' and 'f'.

I think this might also account for the setting of "decidedly" in line 2
and "Nature" in line4. "decidedly" is visually loose, more so than
"Nature", but that is also to do with the south-west curve of the 'e'.
Setting of following italics is, I believe, influenced by the
descenders. In line4 the leading text "d Nat" has no descenders, whereas
in line2 the leading text has a 'g'.

It seems to me that the calculation should be restricted to the
contiguous characters only.

IIUC, the adjustment occurs, slightly differently, between
TextLineComponents and at the end of getAdvanceBetween. At the end, the
effective baseline offset is incremented by the ssOffset (sub-super
offset?) before the calculation. (And incidentally, the pa and pd
variables inherited from the main routine are unused in this block.)

> - The behaviour you see was as I noted intended to account for italic
> overhang. If removed then it is possible that lines which end
> with italic text may be 'clipped' if hard up against some clipping region.
>
> - However getAdvanceBetween() is supposed to return the logical
> advance and did until 1.5 so the behaviour probably should be
> reverted.
>

Have you decided about reverting to logical advance for
getAdvanceBetween? Doing this is going to create inconsistencies between
JDK versions, and, no doubt, between implementations. It seems that this
is an area in which there room for interpretation for implementers,
which is a headache for anyone trying to use Java2D to layout text
destined for custom implementations of Graphics2D, e.g. iText's
PdfGraphics2D or FOP's PDFGraphics2D and PSGraphics2DAdapter.

Given the uncertainty about what getAdvanceBetween will end up as, it
might be useful to provide getBaselineAdvanceBetween and
getItalicAdvanceBetween, to try to provide a common baseline, so to
speak, for implementers. The measurement of italic text seems, in
general, to be underdone. Even if various implementers choose to tweak
the layout of their text for particular devices, there ought to be
enough metrics in common that application developers can get consistent
results cross-platform.

Peter

> - But in part the problem arises because getAdvanceBetween()
>  is there not to measure substrings. Its there to help you estimate
>  line break positions. In fact what you are doing is in general
>  not valid because ligatures, optional or required, and combining
>  marks mean that drawing the text as substrings may not produce
>  the same glyphs or measurement. So a few calls to getAdvanceBetween()
>   might be used to find the break point that most closely fits some
>   desired width. Then get a TextLayout for the *whole* line.
>  Also if you want to fit a  particular known width  line then just
>  use getLineBreakIndex().
>
> - We do not really understand the purpose of getting 'fragments'
>  It seems to be an unnatural use of this class. Also the many
>  calls to getAdvanceBetween() particularly as you apparently
>  use it in the first PNG image, probably contribute significantly
> to your performance problems,
>
> -phil.
>
> Phil Race wrote:
>> PS
>> > You could try compensating by that amount and see if it helps.
>>
>> I guess I didn't really finish that thought.
>> I wouldn't compensate in exactly that way - if you did then it
>> would be ignorant of whether we fixed this API to return
>> the logical advance as opposed to the visual advance.
>>
>> What you probably need to adjust by is the difference between this API
>> and the logical advance as returned by Font.getStringBounds()
>> for that last character. That way if this API need to fixed it should be
>> a no-op.
>>
>> -phil.
>>
>> Phil Race wrote:
>>> An internal class - TextLine - used by TextLayout and TextMeasurer
>>> is trying to compensate for italic overhang to the right that if
>>> ignored might mean visually text did not fit into the space it
>>> claimed it would occupy.
>>> It only needs to pad the rightmost character in the line this way.
>>> However if you, or TextMeasurer, starts to use these values to
>>> *position* subsequent text then that might well cause the effect
>>> you are seeing.
>>> TextMeasurer.getAdvanceBetween() I think should be logical
>>> advance but I'd need to think about it.
>>> The calculation that's causing your problem is roughly
>>> and usually getAscent() * font.getItalicAngle().
>>>
>>> That is what is getting added on to the advance.
>>>
>>> You could try compensating by that amount and see if it helps.
>>>
>>> -phil.
>>>
>>> Peter B. West wrote:
>>>> I wrote a couple of small test programs to look at the behaviour of
>>>> TextMeasurer, especially in situations where the text is in mixed
>>>> fonts.
>>>>
>>>> The fonts I used for the test are from the Luxi font set, available
>>>> with
>>>> X distributions.
>>>>
>>>> The first one measures "aaaa" in an italic and in a regular font,
>>>> looking at the total advance, the increment of the total advance, and
>>>> the advance of the character itself. Results follow.
>>>>
>>>> Ita i 1  adv_to_i 6.364563  increment 6.364563  adv_i_only 6.364563
>>>> Ita i 2  adv_to_i 10.80304  increment 4.4384766  adv_i_only 6.364563
>>>> Ita i 3  adv_to_i 15.241516  increment 4.4384766  adv_i_only 6.364563
>>>> Ita i 4  adv_to_i 19.679993  increment 4.4384766  adv_i_only 6.364563
>>>>
>>>> Reg i 1  adv_0_to_i 4.4384766  increment 4.4384766  adv_i_only
>>>> 4.4384766
>>>> Reg i 2  adv_0_to_i 8.876953  increment 4.4384766  adv_i_only 4.4384766
>>>> Reg i 3  adv_0_to_i 13.31543  increment 4.4384766  adv_i_only 4.4384766
>>>> Reg i 4  adv_0_to_i 17.753906  increment 4.4384766  adv_i_only
>>>> 4.4384766
>>>>
>>>> There are a couple of interesting things here. Firstly, the advance of
>>>> single characters of the italic fonts is greater than the increment of
>>>> characters other than the first, presumably representing an inherent
>>>> kerning effect of italic fonts. The increment of subsequent characters
>>>> is the same as the advance of the corresponding regular character, as
>>>> shown in the lower group of the first set, above.
>>>>
>>>> More interesting is the actual measurement. The ratio of the advance of
>>>> the italic character to the advance of its regular peer is 1.43395213!
>>>> When I examine the individual characters from the two fonts with
>>>> FontForge, I get these values: regular 'a' width 909 LBearing  75
>>>> RBearing  5
>>>> italic 'a'  width 909 LBearing 123 RBearing -48
>>>>
>>>> The largest difference I can manufacture from those figures is 957/904,
>>>> or 1.05862831, which is not in the same ball-park as the TextMeasurer
>>>> figures.
>>>>
>>>> The second test repeats the first, with one change. In the first set,
>>>> the two inner characters are in the italic font, while the two
>>>> outermost
>>>> are in a regular font.
>>>>
>>>> Mix i 1  adv_to_i 4.4384766  increment 4.4384766  adv_i_only 4.4384766
>>>> Mix i 2  adv_to_i 11.212321  increment 6.7738447  adv_i_only 6.364563
>>>> Mix i 3  adv_to_i 15.650798  increment 4.4384766  adv_i_only 6.364563
>>>> Mix i 4  adv_to_i 20.089275  increment 4.4384775  adv_i_only 4.4384766
>>>>
>>>> Reg i 1  adv_0_to_i 4.4384766  increment 4.4384766  adv_i_only
>>>> 4.4384766
>>>> Reg i 2  adv_0_to_i 8.876953  increment 4.4384766  adv_i_only 4.4384766
>>>> Reg i 3  adv_0_to_i 13.31543  increment 4.4384766  adv_i_only 4.4384766
>>>> Reg i 4  adv_0_to_i 17.753906  increment 4.4384766  adv_i_only
>>>> 4.4384766
>>>>
>>>> Similar observations hold. However, the increment value for the first
>>>> italic character following a regular character (the second line of the
>>>> upper group) is greater than the advance value for the isolated
>>>> character, and greater than any value for the italic only group (upper
>>>> group of the first set of observations.)
>>>>
>>>> My interest is that I am using TextMeasurer to perform paragraph line
>>>> breaking in situations where I may have mixed-font text. I measure the
>>>> complete paragraph, but, in order to perform the line-breaking
>>>> algorithm, I need also to know the measurement of individual fragments
>>>> of text. Fragments are the pieces between possible break points, which
>>>> include spaces and potential hyphenation points.
>>>>
>>>> The effect that I'm seeing (and I haven't yet confirmed that this is
>>>> entirely a TextMeasurer problem) is illustrated in the attached
>>>> measurement.png. The fragments of the text are placed at offsets from
>>>> one another as calculated by their measurements. In the png, the
>>>> measurement of a fragment is determined by asking a TextMeasurer,
>>>> defined across the whole paragraph, for an advance from the
>>>> beginning of
>>>> the fragment to the beginning of the following fragment. This works
>>>> beautifully for the regular text, but the italicised text is, as you
>>>> can
>>>> see, being measured larger than it actually is.
>>>>
>>>> Further, the right margin of the line is extended. This indicates that
>>>> the measurement of the entire line differed from the sum of the
>>>> individual measurements. I attempted to compensate for this by
>>>> measuring
>>>> fragments as the difference between the total advance from the
>>>> beginning
>>>> of the text to the beginning of the following fragment, and the total
>>>> advance from the beginning of the text to the beginning of the
>>>> fragment.
>>>> This seems to overcome the margin drift to the right, but does not
>>>> solve
>>>> the problem, as illustrated in measurement2.png.
>>>>
>>>> My reason or switching from using GlyphVectors to using TextMeasurers
>>>> was to gain performance improvements.  The logic is also considerably
>>>> simpler. However, GlyphVector measurement works, whilst taking
>>>> measurement differentials from the beginning of the text leads to
>>>> quadratic increases in time with paragraph length. Even with the more
>>>> unreliable mode of measuring from the beginning to the end of a
>>>> fragment, the time taken to perform the layout increases more steeply
>>>> with increasing paragraph size than the corresponding GlyphVector
>>>> method.


--
Peter B. West <http://cv.pbw.id.au/>
Folio <http://defoe.sourceforge.net/folio/>

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

PNG image

PNG image

PNG image

PNG image

PNG image

Reply via email to