-
Notifications
You must be signed in to change notification settings - Fork 437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8314215: Trailing Spaces before Line Breaks Affect the Center Alignment of Text #1236
8314215: Trailing Spaces before Line Breaks Affect the Center Alignment of Text #1236
Conversation
👋 Welcome back jhendrikx! A progress list of the required criteria for merging this PR into |
Webrevs
|
@prrace I've done an attempt to make a fix for this behavior, if you could take a look and let me know what you think, that'd be great |
int trailingSpaces = 0; | ||
|
||
for (int i = length + startOffset - 1; i >= startOffset; i--) { | ||
if (chars[i] != ' ') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should Character.isWhitespace()
be used instead (think of symbols like U+2001 that might break, see https://en.wikipedia.org/wiki/Whitespace_character)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure, perhaps Phil Race @prrace could answer that? There are loops that just check for 0x20, but also more complicated loops that use Character.isWhitespace
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this logic needs to support all whitespace characters that might break. Since there is no method in Character to indicate the breaking behavior, I wonder if we ought to either request one, or simply hardcode a list here.
@kevinrushforth I think this PR may be worth consideration, although I am not 100% sure that I haven't missed anything, the examples look a lot better with this fix. |
Here's the program I used to make the screenshots: import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
public class TextFlowProblem2 {
public static void main(String[] args) {
Application.launch(App.class);
}
public static class App extends Application {
/**
* @param args the command line arguments
*/
public static void start(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
Label label1 = new Label("AAA BBB CCC");
label1.setFont(Font.font("courier new", 60));
label1.setWrapText(true);
label1.setTextAlignment(TextAlignment.LEFT);
label1.setStyle("-fx-border-color: red;");
Label label2 = new Label("AAA BBB CCC");
label2.setFont(Font.font("courier new", 60));
label2.setWrapText(true);
label2.setTextAlignment(TextAlignment.CENTER);
label2.setStyle("-fx-border-color: red;");
Label label3 = new Label("AAA BBB CCC");
label3.setFont(Font.font("courier new", 60));
label3.setWrapText(true);
label3.setTextAlignment(TextAlignment.RIGHT);
label3.setStyle("-fx-border-color: red;");
GridPane gridPane = new GridPane();
Label alignmentLabel1 = new Label("Left Aligned");
Label alignmentLabel2 = new Label("Center Aligned");
Label alignmentLabel3 = new Label("Right Aligned");
alignmentLabel1.setMinWidth(100);
alignmentLabel2.setMinWidth(100);
alignmentLabel3.setMinWidth(100);
gridPane.addRow(0, alignmentLabel1, label1);
gridPane.addRow(1, alignmentLabel2, label2);
gridPane.addRow(2, alignmentLabel3, label3);
stage.setScene(new Scene(gridPane));
stage.setWidth(1024);
stage.setHeight(1024);
stage.show();
}
}
} |
@prrace Can you take a look? |
/reviewers 2 |
@kevinrushforth |
I've tested Here's the HTML: <p style="white-space:pre-wrap; font:90pt courier new; text-align:right">AAA BBB CCC</p> Edit: I just discovered that there are more |
For the current rendering that JavaFX does, there is no browser equivalent, although For browsers, Although I definitely think the |
From https://www.unicode.org/reports/tr14-4/
A quick check with (the latest?) MS Word 2208 on Windows shows that, at least with EN QUAD U+2000 it is treated as a regular character (i.e. it is always "displayed" even if right aligned). |
It seems there's no browser equivalent to your proposed behavior, either. While that might be a sensible default behavior, I'm not sure about the "invisible input" behavior that you'd get if you entered spaces at the end of a line. |
Yeah, I missed that somehow. Perhaps Chrome is not doing it quite right? I tested Firefox (also Opera and some others but most of those are Chromium based), and it looks like browsers are disagreeing; Firefox is doing it differently (with Edit: Looks like Firefox will try to wrap too early though (it adds ellipsis too soon) so browsers don't seem to be a really authoritive source for this behavior.
That's done almost everywhere, just try it in the comment box here on Github for example. Type sufficient text to reach the edge of the box, then type a lot of spaces. They seem to "disappear", and they don't appear when the text reflows. If you then cursor back, the cursor won't appear until you passed all the spaces you typed; or if you break the line in some other place, all those spaces are still there. It feels odd, but I think it is not a bad way to handle this kind of thing. The example of MS Word that Nir showed also shows that the extra spaces just go past the margin. Photoshop does the same (it's in one the tickets). |
That's certainly a good description of how the breaking should be handled. |
@hjohn This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
This really deserves to be fixed. Any progress on getting this reviewed? |
Do we want to limit this feature to ASCII spaces explicitly? |
@hjohn This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
keep open |
@hjohn This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
Even if we forget other whitespace characters and use 0x20 spaces, there is a weird problem where "CCC" jumps when changing the width of the window: I am testing this PR branch merged with the latest master and a slightly different test program:
|
@hjohn this pull request can not be integrated into git checkout feature/wrapped-aligned-text-rendering
git fetch https://git.openjdk.org/jfx.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
Hi there, could this fix be merged? As I am creating a typesetting tool, this is very important for it. xulihang/ImageTrans-docs#482 |
This PR is very close to be ready. It looks like there are only two things that block it:
|
…pped-aligned-text-rendering
@karthikpandelu @kevinrushforth @andy-goryachev-oracle I split the failing Mac tests into Windows and Mac variants. However, the Mac specific tests probably still fail. If one of you could post the test errors, I can fix the values used as I don't have a Mac to test on. |
I already left a comment on this before, see here: #1236 (comment) The Duplicating the tests for a new font would require running the tests, checking all the exact metric values, and copying those to the duplicated test. Adding new tests becomes more of a maintenance burden as now two tests need to be maintained and updated (both would fail if one fails). Ideally, these tests should be real Unit tests, with a Font definition stored in |
Here is the result of TextLayoutTest in MacOS M1 system.
Following are the skipped tests:
|
Thanks very much, I've updated the values now, so no tests should fail anymore on Mac.
That looks as expected. |
@@ -0,0 +1,521 @@ | |||
/* | |||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it's been modified, please change the year
Sorry, I stopped doing that, I thought this was automated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
One meta comment (not directly related to this review).
It is optional to update copyrights in a PR for a modified file (new files do need a correctly formatted copyright file with the right year). Ambarish periodically runs a script to update them. If you do update copyrights, you need to make sure that the year is right (if, for example, the PR was started in one year and finished the next yet). I tend to not update them for PRs that I expect to backport, since it increases the likelihood of not being able to use the |
@kevinrushforth This is ready to integrate, but I know the headful tests don't run automatically. Would it be wise to run these once more before integrating? Also, I re-read the issues https://bugs.openjdk.org/browse/JDK-8145496 and https://bugs.openjdk.org/browse/JDK-8129014, and I'm positive they're duplicates that would be fixed by this solution. Shall I add these to this PR? |
Yes, that would be a good idea. I'll do that and report results here.
I think it's better to close JDK-8145496 as a duplicate. As for JDK-8129014, it is already closed (as not an issue), so we could either leave it alone or reopen it and reclose it as a Duplicate. |
The newly added test passes on all platforms. @hjohn I assigned JDK-8145496 to you to verify that it is fixed by this PR. If so, please close it as a duplicate of this bug. Since JDK-8129014 is an old (JDK 7) issue, let's just leave it alone. |
/integrate |
Going to push as commit 398f104.
Your commit was automatically rebased without conflicts. |
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 intoAAA
,BBB
andCCC
, 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, butAAA
doesn't, so the engine wraps it toAA
+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 toAAA
,BBB
,CCC
, typing spaces beforeBBB
will not show up. If you cursor back, the cursor may be outside the control bounds because so many spaces are trailingAAA
.The above behavior has NOT changed, is pretty standard for wrapped text controls, and IMHO does not need further attention.
Now, for RIGHT alignment, the new code does change things a bit. Where before the single trailing space that was not collapsed was shown at the end of each wrapped line, this space is now gone. Typing further spaces after
AAA
will not show up, but they are still there, and moving the cursor through them will move the cursor beyond the right side of the control's bounds (just like LEFT alignment has such a case). Some Text rendering implementations will "clamp" the cursor to prevent this (browsers), while others will render the cursor in the margin (but eventually the cursor disappears if there is not enough margin and there are too many spaces).Personally, I think this is absolutely fine. Wrapped text controls all have this kind of behavior, where typing a space just before the wrapping point seemingly has no effect until a non-space character is typed.
For CENTER alignment, the case is similar to LEFT alignment, except there is a bit less space available to render "invisible" spaces.
Screenshots
Using
Label
s containing the textAAA BBB CCC
(note the doubled space between words)First wrapping point
Before
Note the odd trailing space in Center and Right alignments.
After
Small but text would still fit
Before
Note how the wrapping occurs earlier than needed, leading to "empty" lines that contained invisible spaces
After
Note how everything still fits
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1236/head:pull/1236
$ git checkout pull/1236
Update a local copy of the PR:
$ git checkout pull/1236
$ git pull https://git.openjdk.org/jfx.git pull/1236/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1236
View PR using the GUI difftool:
$ git pr show -t 1236
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1236.diff
Webrev
Link to Webrev Comment