On Fri, 9 Feb 2024 23:48:15 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:

>> There are a number of tickets open related to text rendering:
>> 
>> https://bugs.openjdk.org/browse/JDK-8314215
>> 
>> https://bugs.openjdk.org/browse/JDK-8145496
>> 
>> https://bugs.openjdk.org/browse/JDK-8129014
>> 
>> They have in common that wrapped text is taking the trailing spaces on each 
>> wrapped line into account when calculating where to wrap.  This looks okay 
>> for text that is left aligned (as the spaces will be trailing the lines and 
>> generally aren't a problem, but looks weird with CENTER and RIGHT 
>> alignments.  Even with LEFT alignment there are artifacts of this behavior, 
>> where a line like `AAA  BBB  CCC` (note the **double** spaces) gets split up 
>> into `AAA  `, `BBB  ` and `CCC`, but if space reduces further, it will wrap 
>> **too** early because the space is taken into account (ie. `AAA` may still 
>> have fit just fine, but `AAA  ` doesn't, so the engine wraps it to `AA` + `A 
>>  ` or something).
>> 
>> The fix for this is two fold; first the individual lines of text should not 
>> include any trailing spaces into their widths; second, the code that is 
>> taking the trailing space into account when wrapping should ignore all 
>> trailing spaces (currently it is ignoring all but one trailing space).  With 
>> these two fixes, the layout in LEFT/CENTER/RIGHT alignments all look great, 
>> and there is no more early wrapping due to a space being taking into account 
>> while the actual text still would have fit (this is annoying in tight 
>> layouts, where a line can be wrapped early even though it looks like it 
>> would have fit).
>> 
>> If it were that simple, we'd be done, but there may be another issue here 
>> that needs solving: wrapped aligned TextArea's.
>> 
>> TextArea don't directly support text alignment (via a setTextAlignment 
>> method like Label) but you can change it via CSS.
>> 
>> For Left alignment + wrapping, TextArea will ignore any spaces typed before 
>> a line that was wrapped.  In other words, you can type spaces as much as you 
>> want, and they won't show up and the cursor won't move.  The spaces are all 
>> getting appended to the previous line.  When you cursor through these 
>> spaces, the cursor can be rendered out of the control's bounds.  To 
>> illustrate, if you have the text `AAA                 BBB CCC`, and the text 
>> gets wrapped to `AAA`, `BBB`, `CCC`, typing spaces before `BBB` will not 
>> show up.  If you cursor back, the cursor may be outside the control bounds 
>> because so many spaces are trailing `AAA`.
>> 
>> The above behavior has NOT changed, is pretty standard for wrapped text 
>> controls,...
>
> John Hendrikx has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Add failing test to confirm build is running the TextLayoutTest

Results on my local Windows 11 system:


$ gradle --info -PFULL_TEST=true :systemTests:test --tests TextLayoutTest
...
> Task :systemTests:test FAILED

TextLayoutTest > shouldIgnoreAlignmentWhenWrappingIsDisabled() FAILED
    org.opentest4j.AssertionFailedError: line 0 ==> expected: <RectBounds { 
minX:0.0, minY:-12.0, maxX:309.6504, maxY:4.001953} (w:309.6504, h:16.001953)> 
but was: <RectBounds { minX:0.0, minY:-12.949219, maxX:237.88477, 
maxY:3.0117188} (w:237.88477, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.assertLineBounds(TextLayoutTest.java:98)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.shouldIgnoreAlignmentWhenWrappingIsDisabled(TextLayoutTest.java:314)

TextLayoutTest > fail() FAILED
    org.opentest4j.AssertionFailedError: Check if this system test actually 
runs on the build environment; font loaded was [System Regular, System, 
Regular, System Regular, 12.0] and [Tahoma, Tahoma, Regular, Tahoma, 12.0] ==> 
expected: <true> but was: <false>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at app//org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:40)
        at app//org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:210)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.fail(TextLayoutTest.java:570)

TextLayoutTest > caseTest(Case) > [1] NO_WRAP FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps over the lazy dog, 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=0.0, lineWidths=[309.6504], ascent=12.0, descent=4.001953] ==> 
expected: <RectBounds { minX:0.0, minY:-12.0, maxX:309.6504, maxY:4.001953} 
(w:309.6504, h:16.001953)> but was: <RectBounds { minX:0.0, minY:-12.949219, 
maxX:237.88477, maxY:3.0117188} (w:237.88477, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [2] HARD_WRAP FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps
    over the lazy dog, font=Font[name=System Regular, family=System, 
style=Regular, size=12.0], wrapWidth=0.0, lineWidths=[180.0293, 122.41992], 
ascent=12.0, descent=4.001953] ==> expected: <RectBounds { minX:0.0, 
minY:-12.0, maxX:180.0293, maxY:4.001953} (w:180.0293, h:16.001953)> but was: 
<RectBounds { minX:0.0, minY:-12.949219, maxX:142.96875, maxY:3.0117188} 
(w:142.96875, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [3] HARD_WRAP_WITH_EXTRA_TRAILING_SPACE FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps           
    over the lazy dog           , font=Font[name=System Regular, family=System, 
style=Regular, size=12.0], wrapWidth=0.0, lineWidths=[259.2422, 201.63281], 
ascent=12.0, descent=4.001953] ==> expected: <RectBounds { minX:0.0, 
minY:-12.0, maxX:259.2422, maxY:4.001953} (w:259.2422, h:16.001953)> but was: 
<RectBounds { minX:0.0, minY:-12.949219, maxX:179.12695, maxY:3.0117188} 
(w:179.12695, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [4] HARD_WRAP_WITH_TABS FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=    A A
    x   A A
    xx  A A, font=Font[name=System Regular, family=System, style=Regular, 
size=12.0], wrapWidth=0.0, lineWidths=[79.21289, 79.21289, 79.21289], 
ascent=12.0, descent=4.001953] ==> expected: <RectBounds { minX:0.0, 
minY:-12.0, maxX:79.21289, maxY:4.001953} (w:79.21289, h:16.001953)> but was: 
<RectBounds { minX:0.0, minY:-12.949219, maxX:45.064453, maxY:3.0117188} 
(w:45.064453, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [5] HARD_WRAP_WITH_MULTIPLE_TABS FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=    
                
                        , font=Font[name=System Regular, family=System, 
style=Regular, size=12.0], wrapWidth=0.0, lineWidths=[57.609375, 115.21875, 
172.82812], ascent=12.0, descent=4.001953] ==> expected: <RectBounds { 
minX:0.0, minY:-12.0, maxX:57.609375, maxY:4.001953} (w:57.609375, 
h:16.001953)> but was: <RectBounds { minX:0.0, minY:-12.949219, maxX:26.296875, 
maxY:3.0117188} (w:26.296875, h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [6] SOFT_WRAP FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps over the lazy dog, 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=200.0, lineWidths=[180.0293, 122.41992], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:180.0293, maxY:4.001953} (w:180.0293, h:16.001953)> but was: <RectBounds { 
minX:0.0, minY:-12.949219, maxX:189.90234, maxY:3.0117188} (w:189.90234, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [7] SOFT_WRAP_WITH_LEADING_SPACE FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=    The quick brown fox jumps over the lazy dog, 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=200.0, lineWidths=[165.62695, 165.62695], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:165.62695, maxY:4.001953} (w:165.62695, h:16.001953)> but was: <RectBounds 
{ minX:0.0, minY:-12.949219, maxX:182.63086, maxY:3.0117188} (w:182.63086, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [8] SOFT_WRAP_WITH_TRAILING_SPACE FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps over the lazy dog    , 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=200.0, lineWidths=[180.0293, 151.22461], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:180.0293, maxY:4.001953} (w:180.0293, h:16.001953)> but was: <RectBounds { 
minX:0.0, minY:-12.949219, maxX:189.90234, maxY:3.0117188} (w:189.90234, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [9] SOFT_WRAP_WITH_EXTRA_SPACE FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown fox jumps           over the lazy dog, 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=200.0, lineWidths=[180.0293, 122.41992], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:180.0293, maxY:4.001953} (w:180.0293, h:16.001953)> but was: <RectBounds { 
minX:0.0, minY:-12.949219, maxX:142.96875, maxY:3.0117188} (w:142.96875, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [10] SOFT_WRAP_WITH_COMPLEX_TEXT FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown ?????? jumps over the lazy ??????, 
font=Font[name=System Regular, family=System, style=Regular, size=12.0], 
wrapWidth=200.0, lineWidths=[189.89648, 122.583984], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:189.89648, maxY:4.001953} (w:189.89648, h:16.001953)> but was: <RectBounds 
{ minX:0.0, minY:-12.949219, maxX:184.6582, maxY:3.0117188} (w:184.6582, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > caseTest(Case) > [11] 
SOFT_WRAP_WITH_COMPLEX_TEXT_AND_EXTRA_TRAILING_SPACE FAILED
    org.opentest4j.AssertionFailedError: left aligned rich text (spans): line 0 
for Parameters[text=The quick brown ?????? jumps           over the lazy 
??????, font=Font[name=System Regular, family=System, style=Regular, 
size=12.0], wrapWidth=200.0, lineWidths=[189.89648, 122.583984], ascent=12.0, 
descent=4.001953] ==> expected: <RectBounds { minX:0.0, minY:-12.0, 
maxX:189.89648, maxY:4.001953} (w:189.89648, h:16.001953)> but was: <RectBounds 
{ minX:0.0, minY:-12.949219, maxX:158.14453, maxY:3.0117188} (w:158.14453, 
h:15.9609375)>
        at 
app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at 
app//org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at 
app//org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at 
app//org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1152)
        at 
app//test.com.sun.javafx.text.TextLayoutTest.caseTest(TextLayoutTest.java:509)

TextLayoutTest > complexTestsThatAreBrokenSince2013() SKIPPED

17 tests completed, 13 failed, 1 skipped

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1236#issuecomment-1936770039

Reply via email to