JDK-5101869 : REGRESSION: Arabic Text Does Not Repaint Correctly After Being Selected
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-09-14
  • Updated: 2019-12-17
  • Resolved: 2019-12-17
Related Reports
Relates :  
Relates :  
Relates :  
Description
Name: jl125535			Date: 09/14/2004


FULL PRODUCT VERSION :
java version "1.5.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
NVIDIA GeForce4 MX 440 with AGP8X video card

A DESCRIPTION OF THE PROBLEM :
When Arabic text is used in a JTextPane or JTextArea it originally displays correctly.  However when the users selects a range of text by dragging on a single line from right of screen to left of screen and back the text which becomes unselected while dragging back to the right does not repaint and a white space is left instead.

This seems to occur in many situations where the arabic text becomes unselected but not all (noteably when dragging from left to right and back it does repaint correctly).

Also note that the problem occurs in JTextPane when using text/plain or text/html and also in JTextArea.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Place a file with Arabic text in it at C:\test.html and then run the example source code (it is also possible to reproduce by typing in Arabic text but this is generally simpler).  I'll send the actual file I'm testing with via email as it will be corrupted if sent via a web form.

Create a selection by dragging from right to left and then reduce the size of the selection by dragging back to the right.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The text should have repainted correctly.
ACTUAL -
The text that became unselected was not repainted and was left white.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
No error message was printed.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.io.*;
import java.net.*;

public class ArabicRefresh {

    public static void main(String[] args) throws Exception {
    	JFrame frame = new JFrame();
    	JTextPane area = new JTextPane();
    	area.setContentType("text/html");
    	area.setPage(new File("C:\\test.html").toURL());
    	frame.getContentPane().add(new JScrollPane(area));
    	frame.pack();
    	frame.show();
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No workaround found.

Release Regression From : 1.4.2
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Incident Review ID: 310605) 
======================================================================

Comments
EVALUATION will work on this bug for the next update release ###@###.### 2004-09-20 The same problem is reproducible with RightToLeft text. After the fix for 4532590 [JTextPane jTextPane.setHighlighter(null) doesn't disable highlighter.] http://sa.sfbay.sun.com/swing/tiger/4532590/src/share/classes/javax/swing/text/GlyphView.java.sdiff.html We stared to paint selected part of GlyphView separately from unselected. For i18n and RTL text GlyphView is using TextLaout to paint. TextLayout does not support partial painting and thus GlyphPainter2 clipping the region. To find out clipping boundaries TextLayout.getCaretInfo is used. to get clip from position 0 to n we use region from TextLayout.getCaretInfo([0,after]) - TextLayout.getCaretInfo([n,before]) (see GlyphPainter2.paint) --- TextLayoutTest.java --- import java.text.*; import java.awt.*; import java.awt.font.*; class TextLayoutTest { public static void main(String[] args) { Font font = new Font("Dialog", Font.PLAIN, 14); FontRenderContext frc = new FontRenderContext(null, false, false); String testString = " abc "; AttributedString aString = new AttributedString(testString); aString.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL); aString.addAttribute(TextAttribute.FONT, font); TextLayout layout = new TextLayout(aString.getIterator() , frc); TextHitInfo hit; System.out.println("isLeftToRight " + layout.isLeftToRight() + " advance " + layout.getAdvance() + " bounds " + layout.getBounds()); for (int pos = 0; pos < testString.length(); pos ++) { System.out.println("pos " + pos + " before offset = " + (layout.getCaretInfo(TextHitInfo.beforeOffset(pos)))[0] + " after offset = " + (layout.getCaretInfo(TextHitInfo.afterOffset(pos)))[0]); } } } ------- pos 0 before offset = 32.0 after offset = 32.0 pos 1 before offset = 28.0 after offset = 4.0 pos 2 before offset = 12.0 after offset = 12.0 pos 3 before offset = 21.0 after offset = 21.0 pos 4 before offset = 28.0 after offset = 4.0 pos 5 before offset = 0.0 after offset = 0.0 Selection "c " is [3 - 5] which translated to [21 - 0]. It has nothing to do with actual visual range for "c " We end up clipping wrong region and not painting the end of string. Reassigning to ###@###.### for further investigation. ###@###.### 2004-10-01 ================ I think I know what the problem is. "abc abc abc abc" is unidirectional. Substring of it "abc abc abc " is not unidirectional anymore (when direction is right to left) Breaking unidirectional raw into two raws creats multi-directional raws. One way to address that could be breaking elements to left-to-right, right-to-left and neutral pieces (now we break only to ltr and rtl pieces). This way any part of unidirectional piece going to be unidirectional. The drawback going to be much more elments under bidiRoot. ###@###.### 2004-11-08 17:50:32 GMT
08-11-2004

WORK AROUND one could use a hack to get the old behavior back ------ import javax.swing.*; import java.io.*; import java.net.*; import javax.swing.text.*; public class Test { public static void main(String[] args) throws Exception { JFrame frame = new JFrame(); JTextPane area = new JTextPane(); area.setCaret(new MyCaret()); area.setContentType("text/html"); area.setPage(new File("test.html").toURL()); frame.getContentPane().add(new JScrollPane(area)); frame.setSize(500,500); frame.show(); } static class MyCaret extends DefaultCaret { protected Highlighter.HighlightPainter getSelectionPainter() { return highlightPainter; } } static class MyHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter { MyHighlightPainter() { super(null); } } static LayeredHighlighter.LayerPainter highlightPainter = new MyHighlightPainter(); } ----- Using custom HighlightPainter turns off new code path ###@###.### 2004-09-20
20-09-2004