[hg] main-silver: #65158 - I18N - IDE does not handle arabic tex...

  • From: Miloslav Metelka < >
  • To: ,
  • Subject: [hg] main-silver: #65158 - I18N - IDE does not handle arabic tex...
  • Date: Thu, 24 Jan 2013 12:17:20 -0800

changeset 82a545b61c94 in main-silver ((none))
details: http://hg.netbeans.org/main-silver/rev/82a545b61c94
description:
        #65158 - I18N - IDE does not handle arabic text properly.

diffstat:

 
editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewFactory.java
 |  107 ++++++---
 
editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewUtils.java
   |   20 +-
 2 files changed, 84 insertions(+), 43 deletions(-)

diffs (215 lines):

diff --git 
a/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewFactory.java
 
b/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewFactory.java
--- 
a/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewFactory.java
+++ 
b/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewFactory.java
@@ -103,6 +103,11 @@
     // 
-J-Dorg.netbeans.modules.editor.lib2.view.HighlightsViewFactory.level=FINE
     private static final Logger LOG = 
Logger.getLogger(HighlightsViewFactory.class.getName());
     
+    private static final int UNKNOWN_CHAR_TYPE = 0;
+    private static final int LTR_CHAR_TYPE = 1;
+    private static final int RTL_CHAR_TYPE = 2;
+    private static final int TAB_CHAR_TYPE = 3;
+    
     private final DocumentView docView;
 
     private final HighlightingManager highlightingManager;
@@ -123,14 +128,25 @@
     
     private int lineEndOffset;
     
-    /** Line index where tabs and highlights were last updated. */
-    private int hlLineIndex;
-
     private HighlightsReader highlightsReader;
     
     private Font defaultFont;
     
-    private int nextTabOffset;
+    /**
+     * Offset where either '\t' occurs or where boundary between LTR and RTL 
text is located.
+     */
+    private int nextTabOrRTLOffset;
+
+    /**
+     * Char type below nextTabOrRTLOffset (updated in createView() so it's 
actual
+     * from created view's startOffset till nextTabOrRTLOffset.
+     */
+    private int charType;
+    
+    /**
+     * Char type of character right at nextTabOrRTLOffset.
+     */
+    private int nextCharType;
     
     private boolean createViews;
     
@@ -180,7 +196,7 @@
         lineIndex = lineElementRoot.getElementIndex(startOffset);
         lineEndOffset = lineElementRoot.getElement(lineIndex).getEndOffset();
         defaultFont = textComponent().getFont();
-        hlLineIndex = lineIndex - 1; // Make it different for 
updateTabsAndHighlights()
+        nextTabOrRTLOffset = -1;
         if (createViews) {
             highlightsReader = new HighlightsReader(highlightsContainer, 
startOffset, endOffset);
             highlightsReader.readUntil(endOffset);
@@ -200,7 +216,7 @@
         assert (startOffset < limitOffset) : "startOffset=" + startOffset + 
" >= limitOffset=" + limitOffset; // NOI18N
         // Possibly update lineEndOffset since updateHighlight() will read 
till it
         updateLineEndOffset(startOffset);
-        updateTabsAndHighlights(startOffset);
+        updateTabsAndHighlightsAndRTL(startOffset);
         HighlightsList hList = highlightsReader.highlightsList();
         if (hList.startOffset() < startOffset) {
             hList.skip(startOffset);
@@ -209,30 +225,17 @@
             AttributeSet attrs = hList.cutSingleChar();
             return new NewlineView(attrs);
         } else { // Regular view with possible highlight(s) or tab view
-            if (startOffset == nextTabOffset) { // Create TabView
-                int tabsEndOffset;
-                for (tabsEndOffset = nextTabOffset + 1; tabsEndOffset < 
lineEndOffset - 1; tabsEndOffset++) {
-                    if (docText.charAt(tabsEndOffset) != '\t') {
-                        break;
+            if (charType == TAB_CHAR_TYPE) {
+                int tabsEndOffset = nextTabOrRTLOffset; 
+                AttributeSet attrs;
+                if (limitOffset > tabsEndOffset) {
+                    limitOffset = tabsEndOffset;
                     }
-                }
-                AttributeSet attrs;
-                if (limitOffset < tabsEndOffset) {
                     attrs = hList.cut(limitOffset);
-                    nextTabOffset = limitOffset;
-                } else {
-                    attrs = hList.cut(tabsEndOffset);
-                    limitOffset = tabsEndOffset;
-                    for (nextTabOffset = tabsEndOffset; nextTabOffset < 
lineEndOffset - 1; nextTabOffset++) {
-                        if (docText.charAt(nextTabOffset) == '\t') {
-                            break;
-                        }
-                    }
-                }
                 return new TabView(limitOffset - startOffset, attrs);
 
-            } else { // Create regular view
-                limitOffset = Math.min(limitOffset, Math.min(nextTabOffset, 
lineEndOffset - 1));
+            } else { // Create regular view with either LTR or RTL text
+                limitOffset = Math.min(limitOffset, nextTabOrRTLOffset); // 
nextTabOrRTLOffset < lineEndOffset 
                 int wsEndOffset = limitOffset;
                 if (limitOffset - startOffset > SPLIT_TEXT_LAYOUT_LENGTH - 
MODIFICATION_TOLERANCE) {
                     if (nextOrigViewOffset <= limitOffset &&
@@ -280,6 +283,46 @@
         }
     }
 
+    private void updateTabsAndHighlightsAndRTL(int offset) {
+        if (offset >= nextTabOrRTLOffset) { // Update nextTabOrRTLOffset
+            // Determine situation right at offset
+            if (nextCharType == UNKNOWN_CHAR_TYPE || offset > 
nextTabOrRTLOffset) {
+                char ch = docText.charAt(offset);
+                charType = getCharType(ch);
+            } else { // Reuse nextCharType
+                charType = nextCharType;
+            }
+
+            for (nextTabOrRTLOffset = offset + 1; nextTabOrRTLOffset < 
lineEndOffset - 1; nextTabOrRTLOffset++) {
+                char ch = docText.charAt(nextTabOrRTLOffset);
+                nextCharType = getCharType(ch);
+                if (charType == RTL_CHAR_TYPE && Character.isWhitespace(ch)) 
{
+                    nextCharType = RTL_CHAR_TYPE; // RTL followed by WS -> 
retain RTL
+                }
+                if (nextCharType != charType) {
+                    break;
+                }
+            }
+        }
+    }
+    
+    private int getCharType(char ch) {
+        if (ch == '\t') {
+            return TAB_CHAR_TYPE;
+        } else {
+            byte dir = Character.getDirectionality(ch);
+            switch (dir) {
+                case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
+                case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
+                case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
+                case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
+                    return RTL_CHAR_TYPE;
+                default:
+                    return LTR_CHAR_TYPE;
+            }
+        }
+    }
+    
     @Override
     public int viewEndOffset(int startOffset, int limitOffset, boolean 
forcedLimit) {
         updateLineEndOffset(startOffset);
@@ -303,18 +346,6 @@
         }
     }
 
-    private void updateTabsAndHighlights(int offset) {
-        if (hlLineIndex != lineIndex) {
-            hlLineIndex = lineIndex;
-            // Update nextTabOffset to point to nearest '\t'
-            for (nextTabOffset = offset; nextTabOffset < lineEndOffset - 1; 
nextTabOffset++) {
-                if (docText.charAt(nextTabOffset) == '\t') {
-                    break;
-                }
-            }
-        }
-    }
-
     @Override
     public void finishCreation() {
         highlightsReader = null;
diff --git 
a/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewUtils.java
 
b/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewUtils.java
--- 
a/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewUtils.java
+++ 
b/editor.lib2/src/org/netbeans/modules/editor/lib2/view/HighlightsViewUtils.java
@@ -183,14 +183,18 @@
         switch (direction) {
             case View.EAST:
                 if (offset == -1) { // Entering view from the left.
-                    retOffset = viewStartOffset;
+                    // Assuming TextLayout only holds RTL or LTR text 
(HighlightsViewFactory should ensure)
+                    retOffset = textLayout.isLeftToRight()
+                            ? viewStartOffset
+                            : viewStartOffset + viewLength - 1;
                 } else { // Regular offset
                     int index = offset - viewStartOffset;
                     if (index >= 0 && index <= viewLength) {
                         currentHit = TextHitInfo.afterOffset(index);
                         nextHit = textLayout.getNextRightHit(currentHit);
-                        if (nextHit != null) {
-                            retOffset = viewStartOffset + 
nextHit.getInsertionIndex();
+                        int insertionIndex;
+                        if (nextHit != null && (insertionIndex = 
nextHit.getInsertionIndex()) != viewLength) {
+                            retOffset = viewStartOffset + insertionIndex;
                         } // Leave retOffset == -1
                     } // Leave retOffset == -1
                 }
@@ -198,14 +202,20 @@
 
             case View.WEST:
                 if (offset == -1) { // Entering view from the right
-                    retOffset = viewStartOffset + viewLength - 1;
+                    retOffset = textLayout.isLeftToRight()
+                            ? viewStartOffset + viewLength - 1
+                            : viewStartOffset;
                 } else { // Regular offset
                     int index = offset - viewStartOffset;
                     if (index >= 0 && index <= viewLength) {
                         currentHit = TextHitInfo.afterOffset(index);
                         nextHit = textLayout.getNextLeftHit(currentHit);
                         if (nextHit != null) {
-                            retOffset = viewStartOffset + 
nextHit.getInsertionIndex();
+                            int insertionIndex = nextHit.getInsertionIndex();
+                            // Handle RTL
+                            if (textLayout.isLeftToRight() || insertionIndex 
!= viewLength) {
+                                retOffset = viewStartOffset + insertionIndex;
+                            }
                         } // Leave retOffset == -1
                     } // Leave retOffset == -1
                 }

[hg] main-silver: #65158 - I18N - IDE does not handle arabic tex...

Miloslav Metelka 01/24/2013

Project Features

About this Project

Editor was started in November 2009, is owned by Martin Ryzl, and has 147 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20131025.e7cbc9d). © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close