Font rendering (on OS-X)
Phil Race
philip.race at oracle.com
Fri Jan 9 17:37:00 UTC 2015
Glyphs advances are accumulated in floating point and the rendering of
the glyph sub-pixel positioned.
The nodes however are I expect, positioned at an integer position and in
any case I am pretty sure that the fractional advance at the end of
"ABC" is not passed
on to the start of drawing "DEF".
So I think you are just seeing a subtle consequence of rounding because the
starting position of the first glyph in the 2nd text node/string is not
the same as you will get if
you draw it as one string. Where exactly it happens (at which glyph)
will depend on
the way the numbers work out. Whether it happens elsewhere will depend
on the advances the platform returns, but its possible.
Its possible that with some amount of work that TextFlow could pass on this
information so that its less apparent but I don't know off-hand what would
be involved or how complete a fix it would be. Nor whether its actually
worth
the effort for this case.
-phil.
On 1/9/15 8:27 AM, Tom Schindl wrote:
> Hi,
>
> I know font rendering has been discussed a lot already on this forum but
> I don't want to talk about sharpness of text but very strange effects of
> glyph positioning.
>
> The program below switches between 1 and 2 text-nodes which results in
> strange effects at least on my OS-X box.
>
> With a font size 15 you see the 2nd text shifting a bit to the right now
> you could explain this with rounding but it gets even more interesting
> if you make the font size 25 suddenly the F is changing its position!
>
> I recorded a video showing the behavior on my system at
> http://efxclipse.bestsolution.at/ScreenFlow.mp4
>
> My questions are:
> a) does that happen on other OSes as well
> b) does anyone have an idea where I could start searching
> c) do you think this can be fixed?
>
>
>> package application;
>>
>>
>> import javafx.application.Application;
>> import javafx.scene.Node;
>> import javafx.scene.Scene;
>> import javafx.scene.control.Button;
>> import javafx.scene.control.TextField;
>> import javafx.scene.layout.VBox;
>> import javafx.scene.text.Font;
>> import javafx.scene.text.Text;
>> import javafx.scene.text.TextFlow;
>> import javafx.stage.Stage;
>>
>> public class TestMe extends Application {
>>
>> private TextField fontSize;
>> private TextField text;
>>
>> @Override
>> public void start(Stage primaryStage) throws Exception {
>> VBox b = new VBox();
>>
>> text = new TextField("ABCDEF");
>> b.getChildren().add(text);
>>
>> fontSize = new TextField("15");
>> b.getChildren().add(fontSize);
>>
>> TextFlow f = new TextFlow(createText(text.getText()));
>>
>> b.getChildren().add(f);
>> Button bu = new Button("Split text");
>> bu.setOnAction((e) -> {
>> if( f.getChildren().size() == 1 ) {
>> int l = text.getText().length() / 2;
>>
>> f.getChildren().setAll(createText(text.getText().substring(0, l)),createText(text.getText().substring(l)));
>> bu.setText("One Text");
>> } else {
>> f.getChildren().setAll(createText(text.getText()));
>> bu.setText("Split text");
>> }
>> });
>> b.getChildren().add(bu);
>>
>> Scene s = new Scene(b);
>> s.getStylesheets().add(TestMe.class.getResource("application.css").toExternalForm());
>> primaryStage.setScene(s);
>> primaryStage.show();
>> }
>>
>> private Node createText(String text) {
>> Text t = new Text(text);
>> // t.setSmooth(false);
>> t.setFont(Font.font(Integer.parseInt(fontSize.getText())));
>> return t;
>> }
>>
>> public static void main(String[] args) {
>> Application.launch(args);
>> }
>> }
>
> Tom
>
More information about the openjfx-dev
mailing list