<Swing Dev> [9] Review request for 8156217 Selected text is shifted on HiDPI display

Semyon Sadetsky semyon.sadetsky at oracle.com
Tue Sep 20 11:41:09 UTC 2016


Yet another question: Why the floating point API doesn't work for JTextPane?

Also it doesn't work for JTextArea, JTextField and JTextPane if i18n is on.

--Semyon


On 12.09.2016 15:19, Alexandr Scherbatiy wrote:
>
> Hello,
>
> Could you review the updated fix:
>   all changes: http://cr.openjdk.java.net/~alexsch/8156217/webrev.07/all
>   public API changes: 
> http://cr.openjdk.java.net/~alexsch/8156217/webrev.07/public-api
>
>   - @since 9 tag is added to new methods.
>
>   Thanks,
>   Alexandr.
>
> On 9/10/2016 2:36 AM, Philip Race wrote:
>> -     * Returns the tab size set for the document, defaulting to 8.
>> -     *
>> -     * @implSpec This implementation calls {@link #getTabSize() 
>> getTabSize()}.
>> -     *
>> -     * @return the tab size
>> -     */
>> -    protected float getFractionalTabSize() {
>> -        return getTabSize();
>> -    }
>> -
>>
>>
>> It seems this was added only in 9.
>> Since I think I remember that asking a question about it.
>> I note it has no @since. Moot if you are really removing it but
>> what has it to do with the rest of this change ?
>>
>> -phil.
>>
>> On 9/9/16, 11:51 AM, Alexandr Scherbatiy wrote:
>>>
>>> Hello,
>>>
>>> Could you review the updated fix:
>>>  all changes: http://cr.openjdk.java.net/~alexsch/8156217/webrev.06/all
>>>  public API changes: 
>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.06/public-api
>>>
>>>  - reflection is used to detect do methods with floating point API 
>>> need to be called.
>>>
>>> Thanks,
>>> Alexandr.
>>>
>>> On 9/1/2016 9:17 PM, Semyon Sadetsky wrote:
>>>>
>>>>
>>>>
>>>> On 9/1/2016 8:26 PM, Alexandr Scherbatiy wrote:
>>>>> On 9/1/2016 7:27 PM, Alexandr Scherbatiy wrote:
>>>>>> On 9/1/2016 6:49 PM, Semyon Sadetsky wrote:
>>>>>>>
>>>>>>> Alexander, did you consider possibility to check if method is 
>>>>>>> really over-riden then to use the old API?
>>>>>>>
>>>>>>   Could you give a sample how it can be done?
>>>>>   I think it is possible to use a reflection to found the latest 
>>>>> overridden method which uses int coordinates and check does it has 
>>>>> a corresponding overridden method with floating point arguments. 
>>>>> But I doubt that it is a good solution.
>>>> yes. You could use:
>>>> useFloatingPointAPI = 
>>>> PlainView.class.equals(getClass().getMethod("drawUnselectedText", 
>>>> ...).getDeclaringClass());
>>>>
>>>> Otherwise, with high probability your new API will never be used.
>>>>
>>>> --Semyon
>>>>>
>>>>>   Thanks,
>>>>>   Alexandr.
>>>>>>
>>>>>>   Thanks,
>>>>>>   Alexandr.
>>>>>>
>>>>>>> --Semyon
>>>>>>>
>>>>>>> On 9/1/2016 3:07 PM, Alexandr Scherbatiy wrote:
>>>>>>>> On 9/1/2016 11:31 AM, Semyon Sadetsky wrote:
>>>>>>>>>
>>>>>>>>> Hi Alexander,
>>>>>>>>>
>>>>>>>>> It is a good style to add a note recommending what to use 
>>>>>>>>> instead of the method which is being deprecated.
>>>>>>>>>
>>>>>>>>    Could you review the updated public API there "replaced by" 
>>>>>>>> notes are added to the deprecated methods:
>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/public-api.02
>>>>>>>>>
>>>>>>>>> I did not get for what the useFloatingPointAPI property was 
>>>>>>>>> introduced and moreover is set to false by default. If the old 
>>>>>>>>> API is used then it doesn't matter which value it has because 
>>>>>>>>> the float values will receive ints. And for the new API I 
>>>>>>>>> would expect everything having the float precision, and it is 
>>>>>>>>> unclear what may be the reason to switch it off back to 
>>>>>>>>> integer. Especially if
>>>>>>>>>
>>>>>>>>> " This allows to draw text properly using graphics with scaled 
>>>>>>>>> transform."
>>>>>>>>>
>>>>>>>>> so an improper mode is the default?
>>>>>>>>>
>>>>>>>>   This is has been discussed below. For example new 
>>>>>>>> drawSelectedText(Graphics2D g, float x, float y, int p0, int 
>>>>>>>> p1) with floating point coordinates is added to the PlainView 
>>>>>>>> which has the same method with int coordinates. Suppose someone 
>>>>>>>> has a custom password component which uses and old methods with 
>>>>>>>> int coordinates.
>>>>>>>> --------
>>>>>>>>  public class CustomPasswordField extends FieldView {
>>>>>>>>
>>>>>>>>      @Override
>>>>>>>>      protected int drawSelectedText(Graphics g, int x, int y, 
>>>>>>>> int p0, int p1) throws BadLocationException {
>>>>>>>>          // draw echo chars
>>>>>>>>      }
>>>>>>>>  }
>>>>>>>> --------
>>>>>>>>
>>>>>>>> If we start to call drawSelectedText() with floating point 
>>>>>>>> values the customization of old components will not be used and 
>>>>>>>> the CustomPasswordField from the example starts to show real 
>>>>>>>> text instead of echo chars. This is incompatible change with 
>>>>>>>> previous JDK releases.
>>>>>>>>
>>>>>>>> The solution is to switch to new floating point API only when 
>>>>>>>> it is known that a component properly overrides new methods 
>>>>>>>> with floating point arguments. After that the 
>>>>>>>> PlainView.useFloatingPointAPI flag can be set to true.
>>>>>>>>
>>>>>>>> For example, BasicPasswordFieldUI sets the 
>>>>>>>> PasswordView.useFloatingPointAPI  flag to true because it is 
>>>>>>>> sure that drawSelectedText() methods with floating point 
>>>>>>>> arguments is overridden. So Swing standard text components are 
>>>>>>>> switched to use new floating point API.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Alexandr.
>>>>>>>>
>>>>>>>>> --Semyon
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 19.08.2016 11:03, Alexandr Scherbatiy wrote:
>>>>>>>>>> On 8/19/2016 2:25 AM, Philip Race wrote:
>>>>>>>>>>> OK .. I do not know enough about how modelToView is used by 
>>>>>>>>>>> Swing
>>>>>>>>>>> to know what is really needed here. Someone with a bit more 
>>>>>>>>>>> Swing
>>>>>>>>>>> background needs to chime in. I was encouraged that the 
>>>>>>>>>>> *API* surface
>>>>>>>>>>> of the changes was much smaller than it had seemed from the 
>>>>>>>>>>> webrev
>>>>>>>>>>> but maybe that is because you did not include everything. 
>>>>>>>>>>> For example
>>>>>>>>>>> although they are just subclassing the method overrides in 
>>>>>>>>>>> PasswordView
>>>>>>>>>>> since that is a public class would become part of the spec 
>>>>>>>>>>> .. would they not  ?
>>>>>>>>>>> Just like the "int" counterparts today :-
>>>>>>>>>>> https://docs.oracle.com/javase/8/docs/api/javax/swing/text/PasswordView.html
>>>>>>>>>>>
>>>>>>>>>>> Put another way I was looking for what the content of the 
>>>>>>>>>>> CCC would be.
>>>>>>>>>>    Here is the updated version of the public API change which 
>>>>>>>>>> includes overridden deprecated methods:
>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/public-api.01
>>>>>>>>>>
>>>>>>>>>>   Thanks,
>>>>>>>>>>   Alexandr.
>>>>>>>>>>>
>>>>>>>>>>> -phil.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 8/15/16, 11:48 AM, Alexander Scherbatiy wrote:
>>>>>>>>>>>> On 15/08/16 21:43, Phil Race wrote:
>>>>>>>>>>>>> Why is the caret support added in here ? Same for the 
>>>>>>>>>>>>> modelToView
>>>>>>>>>>>>> That will just hold this up as the reasoning behind 
>>>>>>>>>>>>> needing those changes is not something
>>>>>>>>>>>>> I have yet been able to convince myself about - even after 
>>>>>>>>>>>>> reading your last email.
>>>>>>>>>>>>
>>>>>>>>>>>>   The main change for the Caret public API (methods 
>>>>>>>>>>>> Caret.getMagicCaretPosition2D()/setMagicCaretPosition2D(Point2D 
>>>>>>>>>>>> p)) is not included in the current fix. I only moved the 
>>>>>>>>>>>> new methods JTextComponent.modelToView2D(int 
>>>>>>>>>>>> pos)/viewToModel2D(Point2D pt) from the fix for the Caret 
>>>>>>>>>>>> to this fix. These methods are used not only for caret but 
>>>>>>>>>>>> in other cases like mouse handling, text dragging and others.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Alexandr.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> -phil.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 08/15/2016 04:13 AM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   Hello,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   Could you review the updated fix?
>>>>>>>>>>>>>>     webrev which contains only change in public API: 
>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/public-api
>>>>>>>>>>>>>>     webrev with contains all changes: 
>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.05/all
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   - methods with int coordinates are deprecated
>>>>>>>>>>>>>>   - public 
>>>>>>>>>>>>>> isUseFloatingPointAPI()/setUseFloatingPointAPI() methods 
>>>>>>>>>>>>>> are added to the PlainView and WrappedPlainView classes
>>>>>>>>>>>>>>   - JTextComponent.modelToView2D(int 
>>>>>>>>>>>>>> pos)/viewToModel2D(Point2D pt) public methods from fix 
>>>>>>>>>>>>>> JDK-8163124 Add floating point API support to 
>>>>>>>>>>>>>> javax.swing.text.Caret
>>>>>>>>>>>>>>     are added
>>>>>>>>>>>>>>   - some @implSpec descriptions are removed from the new 
>>>>>>>>>>>>>> text drawing methods with floating point arguments
>>>>>>>>>>>>>>   - Built-in L&Fs are updated to use floating point API 
>>>>>>>>>>>>>> in standard Java text components
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 7/28/2016 5:38 PM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> See comments inline.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 7/26/2016 11:57 PM, Phil Race wrote:
>>>>>>>>>>>>>>>> I have a lot of doubts about this as well as trouble 
>>>>>>>>>>>>>>>> getting my head around all of it.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Given that apps need to 'buy in' to the floating point 
>>>>>>>>>>>>>>>> I am not sure what we are gaining
>>>>>>>>>>>>>>>> but I need to make sure I understand the problem.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> It affects only the  methods that the 3rd party code 
>>>>>>>>>>>>>>>> can over-ride
>>>>>>>>>>>>>>>> in subclasses and that are called by the JDK internal 
>>>>>>>>>>>>>>>> code.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> There are just two protected methods that matter :-
>>>>>>>>>>>>>>>> PlainView.drawSelectedText(..)
>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>> PlainView.drawUnselectedText(..)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The hidpi precison matters since they are drawing a 
>>>>>>>>>>>>>>>> sub-range of the text.
>>>>>>>>>>>>>>>> Is there any other method that matters / is used in 
>>>>>>>>>>>>>>>> this way ?
>>>>>>>>>>>>>>>   I have found the following methods which relate to 
>>>>>>>>>>>>>>> text drawing, can be overridden and could have floating 
>>>>>>>>>>>>>>> point coordinates:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> javax.swing.text.PlainView.drawLine(...)
>>>>>>>>>>>>>>> javax.swing.text.PlainView.lineToRect(...)
>>>>>>>>>>>>>>> javax.swing.text.PasswordView.drawEchoCharacter(...)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> javax.swing.plaf.TextUI.modelToView(...)
>>>>>>>>>>>>>>> javax.swing.plaf.TextUI.viewToModel(...)
>>>>>>>>>>>>>>> javax.swing.plaf.TextUI.getToolTipText(...)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> There is also a method which relates to a caret position 
>>>>>>>>>>>>>>> in a text:
>>>>>>>>>>>>>>> javax.swing.text.DefaultCaret.setMagicCaretPosition(Point p)
>>>>>>>>>>>>>>> This requires additional investigation because 
>>>>>>>>>>>>>>> DefaultCaret extends Rectangle and so its coordinates 
>>>>>>>>>>>>>>> can't be float.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Since 3rd party code is not over-riding these they will 
>>>>>>>>>>>>>>>> get the JDK
>>>>>>>>>>>>>>>> super-class version, thus losing any customisation they 
>>>>>>>>>>>>>>>> might have done
>>>>>>>>>>>>>>>> in the no-longer-called int version.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Assuming that is correct, what customisation would be 
>>>>>>>>>>>>>>>> lost and how much does it matter?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The example is javax.swing.text.PasswordView class which 
>>>>>>>>>>>>>>> overrides drawSelectedText(...)/drawUnselectedText(...) 
>>>>>>>>>>>>>>> methods and draws echo chars instead of text.
>>>>>>>>>>>>>>> The similar can be done in a custom component:
>>>>>>>>>>>>>>> --------
>>>>>>>>>>>>>>>  public class CustomPasswordField extends FieldView {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>      @Override
>>>>>>>>>>>>>>>      protected int drawSelectedText(Graphics g, int x, 
>>>>>>>>>>>>>>> int y, int p0, int p1) throws BadLocationException {
>>>>>>>>>>>>>>>          // draw echo chars
>>>>>>>>>>>>>>>      }
>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>> --------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Switching to support new methods with floating point 
>>>>>>>>>>>>>>> coordinates will lead that real text will be shown for 
>>>>>>>>>>>>>>> old applications in password fields.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> My prefernce is to deprecate the int versions and 
>>>>>>>>>>>>>>>> always call the float versions
>>>>>>>>>>>>>>>> rather than the opt-in approach.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Actually my real preference would be to come up with 
>>>>>>>>>>>>>>>> something that does
>>>>>>>>>>>>>>>> not involve drawing the text in chunks like this.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> ie Swing should use AttributedCharacterIterator ..  it 
>>>>>>>>>>>>>>>> looks like the code to
>>>>>>>>>>>>>>>> do this might already be there !
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 106 private float drawElement(int lineIndex, Element 
>>>>>>>>>>>>>>>> elem, Graphics g,
>>>>>>>>>>>>>>>> 107 float x, float y, boolean fractionalCharBounds)
>>>>>>>>>>>>>>>> 108 throws BadLocationException
>>>>>>>>>>>>>>>> 109 {
>>>>>>>>>>>>>>>>   110         int p0 = elem.getStartOffset();
>>>>>>>>>>>>>>>>   111         int p1 = elem.getEndOffset();
>>>>>>>>>>>>>>>>   112         p1 = Math.min(getDocument().getLength(), p1);
>>>>>>>>>>>>>>>>   113
>>>>>>>>>>>>>>>>   114         if (lineIndex == 0) {
>>>>>>>>>>>>>>>>   115             x += firstLineOffset;
>>>>>>>>>>>>>>>>   116         }
>>>>>>>>>>>>>>>>   117         AttributeSet attr = elem.getAttributes();
>>>>>>>>>>>>>>>>   118         if (Utilities.isComposedTextAttributeDefined(attr)) {
>>>>>>>>>>>>>>>>   119             g.setColor(unselected);
>>>>>>>>>>>>>>>>   120             x = Utilities.drawComposedText(this, attr, g, x, y,
>>>>>>>>>>>>>>>>   121                                         p0-elem.getStartOffset(),
>>>>>>>>>>>>>>>>   122                                         p1-elem.getStartOffset());
>>>>>>>>>>>>>>>>   123         } else {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> In fact what *that* illustrates is that applications 
>>>>>>>>>>>>>>>> already cannot expect
>>>>>>>>>>>>>>>> their over-ridden methods to be called, so this fix is 
>>>>>>>>>>>>>>>> trying to fix something
>>>>>>>>>>>>>>>> that can't be fixed.
>>>>>>>>>>>>>>> The javadoc for the "protected PlainView.drawLine(...)" 
>>>>>>>>>>>>>>> method is:
>>>>>>>>>>>>>>> ---------
>>>>>>>>>>>>>>>     /**
>>>>>>>>>>>>>>>      * Renders a line of text, suppressing whitespace at 
>>>>>>>>>>>>>>> the end
>>>>>>>>>>>>>>>      * and expanding any tabs.  This is implemented to 
>>>>>>>>>>>>>>> make calls
>>>>>>>>>>>>>>>      * to the methods {@code drawUnselectedText} and
>>>>>>>>>>>>>>>      * {@code drawSelectedText} so that the way selected and
>>>>>>>>>>>>>>>      * unselected text are rendered can be customized.
>>>>>>>>>>>>>>> ---------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  Applications can rely on this behaviour and stopping to 
>>>>>>>>>>>>>>> call the drawSelectedText(...)/drawUnselectedText(...) 
>>>>>>>>>>>>>>> methods with int coordinates will be incompatible change.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> So why can't we do that ? Just deprecate those int 
>>>>>>>>>>>>>>>> methods, don't add
>>>>>>>>>>>>>>>> the float methods and use ACI ..
>>>>>>>>>>>>>>>   New float methods allow to easily migrate on new API 
>>>>>>>>>>>>>>> for applications without significant changes.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> BTW getTabSize() is supposed to be a character count 
>>>>>>>>>>>>>>>> isn't it ? Not a pixel
>>>>>>>>>>>>>>>> count. So why does it need a float version.
>>>>>>>>>>>>>>>   Could you review the updated fix:
>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.04
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     - methods with int coordinates which can be 
>>>>>>>>>>>>>>> overridden are deprecated
>>>>>>>>>>>>>>>     - getFractionalTabSize() method is removed
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -phil
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 06/30/2016 08:50 AM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>>> On 6/28/2016 8:14 PM, Alan Snyder wrote:
>>>>>>>>>>>>>>>>>> Suppose an application is only partially fixed to 
>>>>>>>>>>>>>>>>>> use/override the floating point methods. Perhaps it 
>>>>>>>>>>>>>>>>>> uses a library that has not been fixed.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Is there a more fine grained way to detect programmer 
>>>>>>>>>>>>>>>>>> awareness or lack of awareness of the new methods?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   Here is a slightly updated version which adds public 
>>>>>>>>>>>>>>>>> isUseFloatingPointAPI()/setUseFloatingPointAPI() 
>>>>>>>>>>>>>>>>> methods to the PlainView and WrappedPlainView classes:
>>>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.02
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   Using the floating point API is disabled by default 
>>>>>>>>>>>>>>>>> and enabled for standard Swing text component classes. 
>>>>>>>>>>>>>>>>> This has advantage that selection will work for text 
>>>>>>>>>>>>>>>>> component in users applications on HiDPI display.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   But it still has the same problem. Applications 
>>>>>>>>>>>>>>>>> which use custom View classes needs to updated them to 
>>>>>>>>>>>>>>>>> implement corresponding text drawing methods with 
>>>>>>>>>>>>>>>>> floating point arguments and enable the floating point 
>>>>>>>>>>>>>>>>> API usage.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>   Alan
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Jun 28, 2016, at 9:59 AM, Alexandr Scherbatiy 
>>>>>>>>>>>>>>>>>>> <alexandr.scherbatiy at oracle.com 
>>>>>>>>>>>>>>>>>>> <mailto:alexandr.scherbatiy at oracle.com>> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   Hello,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   I tried to merge this fix with the 8132119 Provide 
>>>>>>>>>>>>>>>>>>> public API for text related methods in SwingUtilities2
>>>>>>>>>>>>>>>>>>>   and found a flow in the used algorithm.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  For each method that uses integer coordinates the 
>>>>>>>>>>>>>>>>>>> fix adds a pair with floating point arguments.
>>>>>>>>>>>>>>>>>>>  The fix 8156217 uses only methods with floating 
>>>>>>>>>>>>>>>>>>> point values to correctly handle a selected text.
>>>>>>>>>>>>>>>>>>>  This leads that overridden method with integer 
>>>>>>>>>>>>>>>>>>> arguments in user code is not called anymore.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>  I think that this can be handled in the following way:
>>>>>>>>>>>>>>>>>>>  - Add a property that enables to use methods with 
>>>>>>>>>>>>>>>>>>> floating point arguments in Swing.
>>>>>>>>>>>>>>>>>>>    By default it is false and all work as before. 
>>>>>>>>>>>>>>>>>>> The issue with selected text is reproduced.
>>>>>>>>>>>>>>>>>>>    An application with enabled property does not 
>>>>>>>>>>>>>>>>>>> have issue with the selected text but a user should 
>>>>>>>>>>>>>>>>>>> override
>>>>>>>>>>>>>>>>>>>    all methods with floating point values if he uses 
>>>>>>>>>>>>>>>>>>> corresponding methods with integer values.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   Here is a proposed solution where new public 
>>>>>>>>>>>>>>>>>>> system property "javax.swing.floatingPoints.enabled" 
>>>>>>>>>>>>>>>>>>> is added:
>>>>>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.01
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> - Fix the enhancement JDK-8157461 Glyph image 
>>>>>>>>>>>>>>>>>>> rendering for HiDPI displays
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On 6/16/2016 6:07 PM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>> On 6/16/2016 4:47 PM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I tried to look deeper in the code and it seems 
>>>>>>>>>>>>>>>>>>>>> there is a rounding issue when float values are 
>>>>>>>>>>>>>>>>>>>>> summed up.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Suppose a transform with scale 1.5 is used and the 
>>>>>>>>>>>>>>>>>>>>> 'a' char advance is 10 in a dev space.
>>>>>>>>>>>>>>>>>>>>> The 'a' char has advance 10 / 1.5 = 
>>>>>>>>>>>>>>>>>>>>> 6.666666666666667 as double value and 6.6666665 
>>>>>>>>>>>>>>>>>>>>> when it is cast to float in user space.
>>>>>>>>>>>>>>>>>>>>> The width of a string which consists of 15 'a' 
>>>>>>>>>>>>>>>>>>>>> chars is 15 * 6.6666665 = 100.000000.
>>>>>>>>>>>>>>>>>>>>> But the same width calculated as sum of each glyph 
>>>>>>>>>>>>>>>>>>>>> advance in StandardGlyphVector.initPositions() 
>>>>>>>>>>>>>>>>>>>>> method is 99.999992.
>>>>>>>>>>>>>>>>>>>>> --------------
>>>>>>>>>>>>>>>>>>>>>        double scale = 1.5;
>>>>>>>>>>>>>>>>>>>>>         float advance = (float) (10 / scale);
>>>>>>>>>>>>>>>>>>>>>         int N = 15;
>>>>>>>>>>>>>>>>>>>>> System.out.printf("%d * %f = %f\n", N, advance, N 
>>>>>>>>>>>>>>>>>>>>> * advance);
>>>>>>>>>>>>>>>>>>>>>         float sum = 0;
>>>>>>>>>>>>>>>>>>>>>         for (int i = 0; i < N; i++) {
>>>>>>>>>>>>>>>>>>>>>             sum += advance;
>>>>>>>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>>>>>>> System.out.printf("sum: %f\n", sum);
>>>>>>>>>>>>>>>>>>>>> --------------
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Because of this a string drawn from float position 
>>>>>>>>>>>>>>>>>>>>> 99.999998 is shifted one pixel left which affects 
>>>>>>>>>>>>>>>>>>>>> the text selection code in Swing:
>>>>>>>>>>>>>>>>>>>>> ------------------------
>>>>>>>>>>>>>>>>>>>>>         g.scale(1.5, 1.5);
>>>>>>>>>>>>>>>>>>>>>         String TEXT = "aaaaaaaaaaaaaaaa";
>>>>>>>>>>>>>>>>>>>>>         Rectangle2D rect = 
>>>>>>>>>>>>>>>>>>>>> font.getStringBounds(TEXT, 0, index, 
>>>>>>>>>>>>>>>>>>>>> g.getFontMetrics().getFontRenderContext());
>>>>>>>>>>>>>>>>>>>>>         float selectedTextPosition = (float) 
>>>>>>>>>>>>>>>>>>>>> rect.getWidth(); //   99.999992
>>>>>>>>>>>>>>>>>>>>>         g.drawString(TEXT.substring(0, index), x, 
>>>>>>>>>>>>>>>>>>>>> y); // non-selected text
>>>>>>>>>>>>>>>>>>>>>         g.drawString(TEXT.substring(index, 
>>>>>>>>>>>>>>>>>>>>> TEXT.length()), x + selectedTextPosition, y); // 
>>>>>>>>>>>>>>>>>>>>> selected text is shifted to one pixel left
>>>>>>>>>>>>>>>>>>>>> ------------------------
>>>>>>>>>>>>>>>>>>>>    The last step is how coordinates are scaled in 
>>>>>>>>>>>>>>>>>>>> Graphics2D.drawString() method.
>>>>>>>>>>>>>>>>>>>>    If the graphics has scale 1.5 and zero translate 
>>>>>>>>>>>>>>>>>>>> the transformed coordinates are:
>>>>>>>>>>>>>>>>>>>>     (99.999992 + 0) * 1.5 = 149.999985
>>>>>>>>>>>>>>>>>>>>     (100.000000 + 0) * 1.5 = 150.000000
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   Both of them are rounded to the same value.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>   If the translate is set to integer 1 value:
>>>>>>>>>>>>>>>>>>>>     (99.999992 + 1) * 1.5 = 151.499989  // shifted 
>>>>>>>>>>>>>>>>>>>> to one pixel left
>>>>>>>>>>>>>>>>>>>>     (100.000000 + 1) * 1.5 = 151.500000
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  A position 99.999992 in user space is rounded to 
>>>>>>>>>>>>>>>>>>>> 151 in dev space.
>>>>>>>>>>>>>>>>>>>>  A position 100.000000 in user space is rounded to 
>>>>>>>>>>>>>>>>>>>> 152 in dev space.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>  And this difference can depend on the translate 
>>>>>>>>>>>>>>>>>>>> even it has integer value in user space because it 
>>>>>>>>>>>>>>>>>>>> is multiplied on the graphics scale.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>> Alexandr.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>> Alexandr.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On 6/2/2016 11:41 PM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>>>> On 5/31/2016 10:40 PM, Phil Race wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> I applied this and it is *much* better but there 
>>>>>>>>>>>>>>>>>>>>>>> still seem to be some tiny quirks.
>>>>>>>>>>>>>>>>>>>>>>> When I drag the mouse to select text down and 
>>>>>>>>>>>>>>>>>>>>>>> then up again, as I pass the
>>>>>>>>>>>>>>>>>>>>>>> original mouse click point vertically, repaint 
>>>>>>>>>>>>>>>>>>>>>>> seem to jiggle vertically by a pixel.
>>>>>>>>>>>>>>>>>>>>>>> Perhaps a rounding issue in the repaint code's 
>>>>>>>>>>>>>>>>>>>>>>> calculation of the location of
>>>>>>>>>>>>>>>>>>>>>>> the target y. I think I may see the same in 
>>>>>>>>>>>>>>>>>>>>>>> left/right dragging along a line too.
>>>>>>>>>>>>>>>>>>>>>>> So I think this is repaint and not text related. 
>>>>>>>>>>>>>>>>>>>>>>> Can you take a look.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>     I am able to reproduce this only using a 
>>>>>>>>>>>>>>>>>>>>>> floating point scale.
>>>>>>>>>>>>>>>>>>>>>>     It looks like 2d issue. I used a test which 
>>>>>>>>>>>>>>>>>>>>>> draws a text in two pieces. The second piece of 
>>>>>>>>>>>>>>>>>>>>>> the text is shifted from the first piece by the 
>>>>>>>>>>>>>>>>>>>>>> floating point size of the the first piece of the 
>>>>>>>>>>>>>>>>>>>>>> text.
>>>>>>>>>>>>>>>>>>>>>>   -----------
>>>>>>>>>>>>>>>>>>>>>>     Rectangle2D rect = font.getStringBounds(TEXT, 
>>>>>>>>>>>>>>>>>>>>>> 0, index, 
>>>>>>>>>>>>>>>>>>>>>> g.getFontMetrics().getFontRenderContext());
>>>>>>>>>>>>>>>>>>>>>>     float selectedTextPosition = (float) 
>>>>>>>>>>>>>>>>>>>>>> rect.getWidth();
>>>>>>>>>>>>>>>>>>>>>> g.drawString(TEXT.substring(0, index), x, y);
>>>>>>>>>>>>>>>>>>>>>> g.drawString(TEXT.substring(index, 
>>>>>>>>>>>>>>>>>>>>>> TEXT.length()), x + selectedTextPosition, y);
>>>>>>>>>>>>>>>>>>>>>>   -----------
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   The second piece of the text can be shifted in 
>>>>>>>>>>>>>>>>>>>>>> the 2 cases:
>>>>>>>>>>>>>>>>>>>>>>   a) graphics scale is 1.5 and translation is 1.
>>>>>>>>>>>>>>>>>>>>>>   b) graphics scale is 2.25 without applied 
>>>>>>>>>>>>>>>>>>>>>> translation
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   I have filed an issue on it:
>>>>>>>>>>>>>>>>>>>>>>     JDK-8158370 Text drawn from float pointing 
>>>>>>>>>>>>>>>>>>>>>> position and with float pointing scale is shifted
>>>>>>>>>>>>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8158370
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>   Thanks,
>>>>>>>>>>>>>>>>>>>>>>   Alexandr.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> -phil.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On 05/06/2016 12:31 PM, Alexandr Scherbatiy wrote:
>>>>>>>>>>>>>>>>>>>>>>>> Hello,
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Could you review the fix:
>>>>>>>>>>>>>>>>>>>>>>>>   bug: 
>>>>>>>>>>>>>>>>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8156217
>>>>>>>>>>>>>>>>>>>>>>>>   webrev: 
>>>>>>>>>>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~alexsch/8156217/webrev.00 
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   This is the second part of the fix related to 
>>>>>>>>>>>>>>>>>>>>>>>> the fact that char width can be fractional in 
>>>>>>>>>>>>>>>>>>>>>>>> user space.
>>>>>>>>>>>>>>>>>>>>>>>> http://mail.openjdk.java.net/pipermail/swing-dev/2016-May/005814.html 
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>   The Font.getStringBounds(...) method is used 
>>>>>>>>>>>>>>>>>>>>>>>> for the fractional string width calculation by 
>>>>>>>>>>>>>>>>>>>>>>>> Swing in user space.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>  Thanks,
>>>>>>>>>>>>>>>>>>>>>>>>  Alexandr.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/swing-dev/attachments/20160920/e1100479/attachment.html>


More information about the swing-dev mailing list