JDK-8186558 : javax.swing.text.Utilities.getTabbedTextOffset returns incorrect value at end of text when fractional metrics are enabled
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • Submitted: 2017-08-19
  • Updated: 2021-06-16
  • Resolved: 2021-06-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
I am filing this bug report at the request of Phil Race.

There is a problem in the method javax.swing.text.Utilities.getTabbedTextOffset. This problem may or may not be visible at this time as it depends on fractional metrics being enabled. I am not aware of any legitimate way to enable fractional metrics currently.

The implementation of this method has two steps. It first uses a loop to identify a candidate position. It then corrects the position, if needed. The need for the correction is environment dependent. For example, the correction is needed if fractional metrics are enabled.

The correction is implemented inside the for loop, in a conditional that exits the loop. The problem is that when the candidate position is at the end of the text, this conditional is never executed; instead, the loop terminates normally. Therefore, if the correction was needed, the result is incorrect (the position exceeds the width of the text display).

Solution: the corrrection code should be after the loop, not inside the loop.



REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
It is possible to double check the result of this method and correct it using information obtained by the modelToView() method.


Comments
Please read comments for details.
16-06-2021

related issues: JDK-8199441: Wrong caret position in multiline text components on Windows with a screen resolution higher than 100% JDK-8232243: Wrong caret position in JTextPane on Windows with a screen resolution > 100% getTabbedTextOffset(Segment s, FontMetrics metrics, float x0, float x, TabExpander e, int startOffset, boolean round) was added by JDK-8142966: Wrong cursor position in text components on HiDPI display.
16-06-2021

This bug is not OS specific, so I removed os_x / x86 from OS and CPU fields.
15-06-2021

Wrote a test program [FMIssue.java attached] to exercise the part of code inside javax.swing.text.Utilities.getTabbedTextOffset mentioned in reported issue. Debugged and stepped through this code with Fractional metrics enabled and saw that it was working as intended and could not find the problem reported. The test program attached renders two strings, upper one without and below one with Fractional Metrics enabled and it uses getTabbedTextOffset to calculate the position at which to render the caret. The latest version of this program contains code by the bug reporter to change color in the middle of the letter. If the color changes in middle of the letter we are good. The program was run with highDPI settings on windows and retina display on macOS with JDK 8 and latest JDK. For latest JDK color transitions happen correctly in the middle of the letter. With JDK8 we found the color didn't change in middle of the letter for some of the letters for both the strings, thus not proving to us that Fractional Metrics has a part to play in this. Also, JDK8 contains only int verion of getTabbedTextOffset: public static int getTabbedTextOffset(Segment s, FontMetrics metrics, int x0, int x, TabExpander e, int startOffset, boolean round) But, going forward the newer JDKs have the float version of getTabbedTextOffset and int version is deprecated in latest JDK: public static int getTabbedTextOffset(Segment s, FontMetrics metrics, float x0, float x, TabExpander e, int startOffset, boolean round) This could be the reason why latest JDK shows correct color transitions(in middle of the letter) , while JDK8 does not due to int version of getTabbedTextOffset. Backporting to enable float version of getTabbedTextOffset in JDK8 has lot of overhead and won't be done in this point in time.
24-05-2021

You can ask the questions here: http://mail.openjdk.java.net/pipermail/swing-dev/2017-August/007691.html
31-08-2017

unable to reproduce with existing descriptions. Request a test case with positive and negative scenario.
30-08-2017