Hi,
this fixes another bunch of problems with WrappedPlainView. There were all kinds
of oddities which I have described in PR26676[0] and these are now fixed.

Included is a fix to Utilities.getTabbedTextOffset() which makes this method a
bit more eager to break text. I changed a comparison from > to >= and now lines
are not only broken when a character exceeds a certain x coordinate but even
when it lies exactly on it. This has the effect that lines will not end exactly
on the right edge of a textfield/textarea any more.

IMHO this is how the JDK does things.

ChangeLog:

2006-04-02  Robert Schuster  <[EMAIL PROTECTED]>

        PR #26676
        * javax/swing/text/Utilities.java:
        (getTabbedTextOffset): Added check to decrement pos not below zero,
        changed '>' comparison to '>='.
        * javax/swing/text/WrappedPlainView.java:
        (lineHeight): New field.
        (calculateBreakPosition): Throw InternalError in catch block, removed
        unneeded brackets, use specific version of
        Utilities.getTabbedTextOffset.
        (paint): Set various properties neccessary for drawing.
        (WrappedLine.paint): Removed code to set field of outer class.
        (WrappedLine.modelToView): Removed unneeded expression from
        if-statement.
        (WrappedLine.viewToModel): Initialize end with endOffset - 1, removed
        -1 from return statement, copy only a subset into the Segment, removed
        special handling of mark value - just return it, simplified
        incrementation of currLineStart.
        (WrappedLine.insertUpdate): Recalculate numLines, report preference
        change to parent view.
        (WrappedLine.removeUpdate): Dito.


cya
Robert

[0] - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26676
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v
retrieving revision 1.28
diff -u -r1.28 Utilities.java
--- javax/swing/text/Utilities.java	1 Apr 2006 15:22:07 -0000	1.28
+++ javax/swing/text/Utilities.java	1 Apr 2006 22:44:03 -0000
@@ -238,14 +238,14 @@
     // At the end of the for loop, this holds the requested model location
     int pos;
     int currentX = x0;
-
+    
     for (pos = 0; pos < s.count; pos++)
       {
         char nextChar = s.array[s.offset+pos];
         
         if (nextChar == 0)
           {
-            if (! round)
+            if (! round && pos > 0)
               pos--;
             break;
           }
@@ -259,14 +259,13 @@
               currentX = (int) te.nextTabStop(currentX, pos);
           }
         
-        if (currentX > x)
+        if (currentX >= x)
           {
-            if (! round)
+            if (! round && pos > 0)
               pos--;
             break;
           }
       }
-    
     return pos + p0;
   }
 
Index: javax/swing/text/WrappedPlainView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/WrappedPlainView.java,v
retrieving revision 1.14
diff -u -r1.14 WrappedPlainView.java
--- javax/swing/text/WrappedPlainView.java	1 Apr 2006 15:22:07 -0000	1.14
+++ javax/swing/text/WrappedPlainView.java	1 Apr 2006 22:44:03 -0000
@@ -81,6 +81,9 @@
   /** The end of the selected text **/
   int selectionEnd;
   
+  /** The height of the line (used while painting) **/
+  int lineHeight;
+  
   /**
    * The instance returned by [EMAIL PROTECTED] #getLineBuffer()}.
    */
@@ -274,6 +277,7 @@
     Container c = getContainer();
     Rectangle alloc = new Rectangle(0, 0, getWidth(), getHeight());
     updateMetrics();
+    
     try
       {
         getDocument().getText(p0, p1 - p0, getLineBuffer());
@@ -281,18 +285,16 @@
     catch (BadLocationException ble)
       {
         // this shouldn't happen
+        throw new InternalError("Invalid offsets p0: " + p0 + " - p1: " + p1);
       }
     // FIXME: Should we account for the insets of the container?
     if (wordWrap)
-      return p0
-             + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
+      return p0 + Utilities.getBreakLocation(lineBuffer, metrics, alloc.x,
                                           alloc.x + alloc.width, this, 0);
     else
-      {
-      return p0
-             + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
-                                             alloc.x + alloc.width, this, 0);
-      }
+      return p0 + Utilities.getTabbedTextOffset(lineBuffer, metrics, alloc.x,
+                                             alloc.x + alloc.width, this, 0,
+                                             true);
   }
   
   void updateMetrics()
@@ -385,9 +387,19 @@
   public void paint(Graphics g, Shape a)
   {
     JTextComponent comp = (JTextComponent)getContainer();
+    // Ensure metrics are up-to-date.
+    updateMetrics();
+    
     selectionStart = comp.getSelectionStart();
     selectionEnd = comp.getSelectionEnd();
-    updateMetrics();
+
+    selectedColor = comp.getSelectedTextColor();
+    unselectedColor = comp.getForeground();
+    disabledColor = comp.getDisabledTextColor();
+    selectedColor = comp.getSelectedTextColor();
+    lineHeight = metrics.getHeight();
+    g.setFont(comp.getFont());
+
     super.paint(g, a);
   }
   
@@ -420,21 +432,7 @@
      */
     public void paint(Graphics g, Shape s)
     {
-      // Ensure metrics are up-to-date.
-      updateMetrics();
-      JTextComponent textComponent = (JTextComponent) getContainer();
-
-      g.setFont(textComponent.getFont());
-      selectedColor = textComponent.getSelectedTextColor();
-      unselectedColor = textComponent.getForeground();
-      disabledColor = textComponent.getDisabledTextColor();
-
-      // FIXME: this is a hack, for some reason textComponent.getSelectedColor
-      // was returning black, which is not visible against a black background
-      selectedColor = Color.WHITE;
-      
       Rectangle rect = s.getBounds();
-      int lineHeight = metrics.getHeight();
 
       int end = getEndOffset();
       int currStart = getStartOffset();
@@ -532,7 +530,7 @@
           // If pos is between currLineStart and currLineEnd then just find
           // the width of the text from currLineStart to pos and add that
           // to rect.x
-          if (pos >= currLineStart && pos < currLineEnd || pos == end - 1)
+          if (pos >= currLineStart && pos < currLineEnd)
             {             
               try
                 {
@@ -576,12 +574,16 @@
       Segment s = getLineBuffer();
       Rectangle rect = a.getBounds();
       int currLineStart = getStartOffset();
-      int end = getEndOffset();
+      
+      // WrappedLine does not represent the last possible offset in a line.
+      // So we should never return that offset. Behavior observed in the RI.
+      int end = getEndOffset() - 1;
+      
       int lineHeight = metrics.getHeight();
       if (y < rect.y)
         return currLineStart;
       if (y > rect.y + rect.height)
-        return end - 1;
+        return end;
       
       // Note: rect.x and rect.width do not represent the width of painted
       // text but the area where text *may* be painted. This means the width
@@ -596,32 +598,24 @@
             {
               try
                 {
-                  getDocument().getText(currLineStart, end - currLineStart, s);
+                  getDocument().getText(currLineStart, currLineEnd - currLineStart, s);
                 }
               catch (BadLocationException ble)
                 {
                   // Shouldn't happen
                 }
               
-              int mark = Utilities.getTabbedTextOffset(s, metrics, rect.x,
+              return Utilities.getTabbedTextOffset(s, metrics, rect.x,
                                                    (int) x,
                                                    WrappedPlainView.this,
                                                    currLineStart);
-              
-              // WrappedPlainView does not represent the last possible offset
-              // in the document. Se we should never return that offset.
-              // Behavior observed in the RI.
-              return (mark == end) ? end - 1 : mark;
             }
           // Increment rect.y so we're checking the next logical line
           rect.y += lineHeight;
           
           // Increment currLineStart to the model position of the start
           // of the next logical line
-          if (currLineEnd == currLineStart)
-            currLineStart = end;
-          else
-            currLineStart = currLineEnd;
+          currLineStart = currLineEnd;
         }
     }    
     
@@ -655,6 +649,11 @@
      */
     public void insertUpdate (DocumentEvent changes, Shape a, ViewFactory f)
     {
+      int oldNumLines = numLines;
+      determineNumLines();
+      if (oldNumLines != numLines)
+        getParent().preferenceChanged(this, false, true);
+      
       updateDamage((Rectangle)a); 
     }
     
@@ -668,6 +667,11 @@
      */
     public void removeUpdate (DocumentEvent changes, Shape a, ViewFactory f)
     {
+      int oldNumLines = numLines;
+      determineNumLines();
+      if (oldNumLines != numLines)
+        getParent().preferenceChanged(this, false, true);
+      
       updateDamage((Rectangle)a); 
     }
   }

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to