piccolo2d/piccolo2d.java

Disabling FRACTIONAL_METRICS on Windows yields incorrect bounds for text PSwing components

Closed this issue · 13 comments

mro commented

Originally reported on Google Code with ID 191

What steps will reproduce the problem?
1. Run PSwingExample1 on Windows
2. Continuously zoom until the "This is a growable TextArea." text exceeds the rightmost
bounds of the blue boundary.

What is the expected output? What do you see instead?

The PSwing text shouldn't exceed its bounds.  In other applications, this causes the
edge of some PSwing components to fall behind other components, clipping it so that
the rightmost part of the PSwing is hidden.

Note that the problem disappears when commenting out line 474 of PSwing:
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);

This line was presumably added to make sure that PSwings on Mac do not render with
ellipses "...".  However, when we added that workaround we did not know it would cause
incorrect layout for text PSwings on Windows (and possibly Linux?)

In my working copy, I have applied the change to detect whether the OS is Mac, and
to disable fractional metrics if and only if the OS is mac:

        //Disable Fractional Metrics on Mac OS because when FRACTIONAL_METRICS are
enabled on Mac OS, spurious ellipses
        // are renderer on PSwing text components. Disabling this property on Windows
causes incorrect rendering of 
        // adjacent text PSwing nodes.
        if (System.getProperty("os.name").toLowerCase().indexOf("mac") >= 0) {
            g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
        }

What do others think of this solution?  Could leaving fractional metrics enabled in
Windows and Linux cause any other buggy behavior?  It would also be nice to confirm
why this workaround was added in the first place.

Reported by reids%colorado.edu@gtempaccount.com on 2010-09-08 14:51:25

mro commented
The solution you gave seems to be the way to go about it. 

Best case scenario is to have the fractional metrics enabled across the board and this
gets us far closer to that. Even though it's obviously going against the very nature
of cross platform Java code, working is working.

Only gotcha there I think is that it would disable it for all mac platforms. Are we
sure that there are no mac machines for which fractional metrics doesn't introduce
an ellipsis?

Reported by allain.lalonde on 2010-09-08 19:07:20

mro commented

Reported by heuermh on 2010-12-22 02:06:00

  • Labels added: Milestone-1.3.1
mro commented
Per

http://developer.apple.com/library/mac/documentation/Java/Reference/Java_PropertiesRef/Articles/JavaSystemProperties.html

There are some system properties on OSX that might affect how text is rendered and
how this rendering hint is applied:

apple.awt.graphics.EnableQ2DX

    Determines whether hardware acceleration is used to speed up rendering of simple
primitives like images, lines, rects, and simple characters. In addition to using this
flag, you need to enable Quartz 2D acceleration in the Quartz Debug application, included
with the Xcode Developer Tools for Mac OS X.

    This is strictly a developer option. Java applications intended for use on Mac
OS X should not rely on the presence of Quartz 2D acceleration.

    The default value is false.

apple.awt.graphics.UseQuartz

    Determines whether Apple’s Quartz renderer is used instead of Sun’s 2D renderer.

    The default value is true for J2SE 5.0 and false for Java SE 6.


Thus the OS check might not be sufficient.

See also Issue 117 which documents my frustration with Piccolo2D text rendering in
general.

Reported by heuermh on 2011-03-02 16:34:00

mro commented
Consider also OpenJDK builds on Mac OSX

http://code.google.com/p/openjdk-osx-build/

Reported by heuermh on 2011-03-02 18:00:21

mro commented
Here's a summary of this issue to date:

While the default for all platforms seems to be FRACTIONAL_METRICS_ON ("fm_on"), Piccolo2D
explicitly sets FRACTIONAL_METRICS_OFF ("fm_off") for painting of PSwing nodes. As
I understand it, this decision has been a part of the PSwing class for a long while
now and the primary motivation for doing this is to avoid rendering of ellipses on
Mac OS X platforms (by using "fm_off", we prevent Mac OS from rendering ellipses for
some text renderings that, due to fractional metrics calculations can't fully render
within their bounds.)

After running several tests, however, it seems that painting w/ "fm_off" causes more
unpleasant behavior across systems than using the default of "fm_on". On all systems,
using "fm_off" causes noticeable jittering while zooming. On Ubuntu/Java4, ellipses
are actually rendered in this mode and not in "fm_on". And on Windows 7, using Java4,
ellipses are rendered regardless of the setting.

I tested on a subset of {Win7, Snow Leopard, Ubuntu10} x {Java4, Java6} x {FRACTIONAL_METRICS_ON,
FRACTIONALMETRICS_OFF} and the outcome images will come soon attached with tell-tale
filenames:

                                   | "fm_off"                                | "fm_on"

Windows7
    Java4:                         jittering; ellipsed                   no jitter;
ellipsed
    Java6:                         jittering                                  slight
jittering
Ubuntu10
   Java4:                          jittering; ellipsed                   slight jittering
   Java6 (openjdk):          jittering; slight artifacts         no jitter; noticeable
artifacts
Mac/Snow
   Java6:                           jittering                                 slight
jittering; ellipsed

It appears impossible to avoid ellipse-rendering using RenderingHints. Also, using
the default rendering hint "fm_on" yields much better behavior (little or no jittering)
otherwise.

It seems clients can avoid ellipses by explicitly setting preferred sizes on their
components, so there is a workaround.

With this data, I believe the *correct* route is to use the default "fm_on" rendering
hints (which is default on all systems I tested on), which also resolves this issue.

I don't believe we can do this, however, in 1.3.* releases as clients may already rely
on this behavior. 1.3.* clients can workaround this issue by overriding paint() behavior
(not ideal, I know.)

Looking for P2D developers to comment. My vote is to move this ticket to 2.0 with the
plan of removing our use "fm_off" in 2.0.

Reported by atdixon on 2011-03-27 21:23:02

mro commented
Attaching Windows 7 outcomes -- {Java4, Java6} x {"fm_on", "fm_off"}

Reported by atdixon on 2011-03-27 21:24:17


- _Attachment: Win7.Java6.FracMetricsOn.PNG
![Win7.Java6.FracMetricsOn.PNG](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-6/Win7.Java6.FracMetricsOn.PNG)_ - _Attachment: Win7.Java6.FracMetricsOff.PNG
![Win7.Java6.FracMetricsOff.PNG](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-6/Win7.Java6.FracMetricsOff.PNG)_ - _Attachment: Win7.Java4.FracMetricsOn.PNG
![Win7.Java4.FracMetricsOn.PNG](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-6/Win7.Java4.FracMetricsOn.PNG)_ - _Attachment: Win7.Java4.FracMetricsOff.PNG
![Win7.Java4.FracMetricsOff.PNG](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-6/Win7.Java4.FracMetricsOff.PNG)_
mro commented
Attaching Ubuntu outcomes -- {Java4, Java6 (openjdk)} x {"fm_on", "fm_off"}

Reported by atdixon on 2011-03-27 21:26:08


- _Attachment: Ubuntu.OpenJdk6.FracMetricsOff.png
![Ubuntu.OpenJdk6.FracMetricsOff.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-8/Ubuntu.OpenJdk6.FracMetricsOff.png)_ - _Attachment: Ubuntu.Java6.FracMetricsOn.png
![Ubuntu.Java6.FracMetricsOn.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-8/Ubuntu.Java6.FracMetricsOn.png)_ - _Attachment: Ubuntu.Java4.FracMetricsOn.png
![Ubuntu.Java4.FracMetricsOn.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-8/Ubuntu.Java4.FracMetricsOn.png)_ - _Attachment: Ubuntu.Java4.FracMetricsOff.WhileZooming.png
![Ubuntu.Java4.FracMetricsOff.WhileZooming.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-8/Ubuntu.Java4.FracMetricsOff.WhileZooming.png)_ - _Attachment: Ubuntu.Java4.FracMetricsOff.png
![Ubuntu.Java4.FracMetricsOff.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-8/Ubuntu.Java4.FracMetricsOff.png)_
mro commented
Attaching Mac OS X (Snow L.) -- {Java6} x {"fm_on", "fm_off"}

Reported by atdixon on 2011-03-27 21:27:24


- _Attachment: MacOsX.Java6.FracMetricsOn.png
![MacOsX.Java6.FracMetricsOn.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-9/MacOsX.Java6.FracMetricsOn.png)_ - _Attachment: MacOsX.Java6.FracMetricsOff.png
![MacOsX.Java6.FracMetricsOff.png](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-191/comment-9/MacOsX.Java6.FracMetricsOff.png)_
mro commented
Speaking for PhET...

+1 for the proposal to move this ticket to 2.0.  Also OK to default to "fm_on", as
long as we have some way to globally change to "fm_off" in client code.

Also of note is that we have recently experienced the Mac OS ellipsis problem with
Arabic characters at font size > 14, with both "fm_on" and "fm_off" scenarios.

Reported by cmalley@pixelzoom.com on 2011-03-29 00:12:34

mro commented
Are you able to workaround ellipses by explicitly setting preferred bounds on the component
(giving it larger width)?

Reported by atdixon on 2011-03-29 03:18:03

mro commented

Reported by atdixon on 2011-03-29 03:18:22

  • Labels added: Milestone-2.0
  • Labels removed: Milestone-1.3.1
mro commented
Yes, I am able to work around ellipses in a component by explicitly increasing its preferred
width.

Reported by cmalley@pixelzoom.com on 2011-03-30 19:17:04

mro commented

Reported by heuermh on 2013-11-26 21:11:16

  • Labels added: Milestone-2.1
  • Labels removed: Milestone-2.0