On Roman's advice, I changed the 2 methods to use binary searching
rather than sequential searching.  This is now committed.

2005-09-27  Anthony Balkissoon  <[EMAIL PROTECTED]>

        * javax/swing/text/Utilities.java:
        (getRowEnd): New method.
        (getRowStart): New method.

--Tony

On Mon, 2005-09-26 at 16:34 -0400, Anthony Balkissoon wrote:
> I implemented getRowStart and getRowEnd in javax.swing.text.Utilities.
> This is RFC because of the issue raised in the large comment in each of
> this methods (namely, performance).  Some comments would be appreciated.
> 
> 
> 2005-09-26  Anthony Balkissoon  <[EMAIL PROTECTED]>
> 
>       * javax/swing/text/Utilities.java:
>       (getRowEnd): New method.
>       (getRowStart): New method.
> 
> --Tony
> _______________________________________________
> Classpath-patches mailing list
> [email protected]
> http://lists.gnu.org/mailman/listinfo/classpath-patches
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v
retrieving revision 1.11
diff -u -r1.11 Utilities.java
--- javax/swing/text/Utilities.java	22 Sep 2005 20:17:08 -0000	1.11
+++ javax/swing/text/Utilities.java	27 Sep 2005 16:39:55 -0000
@@ -394,4 +394,95 @@
     wb.setText(text);
     return wb.following(offs);
   }
+  
+  /**
+   * Get the model position of the end of the row that contains the 
+   * specified model position.  Return null if the given JTextComponent
+   * does not have a size.
+   * @param c the JTextComponent
+   * @param offs the model position
+   * @return the model position of the end of the row containing the given 
+   * offset
+   * @throws BadLocationException if the offset is invalid
+   */
+  public static final int getRowEnd(JTextComponent c, int offs)
+      throws BadLocationException
+  {
+    Element root = c.getDocument().getDefaultRootElement();
+    Element rowElement = root.getElement(root.getElementIndex(offs));
+    String text = c.getText(rowElement.getStartOffset(),
+                            rowElement.getEndOffset());
+    if (text == null)
+      return -1;
+
+    // Do a binary search for the smallest position X > offs
+    // such that that character at positino X is not on the same
+    // line as the character at position offs
+    int high = offs + ((text.length() - 1 - offs) / 2);
+    int low = offs;
+    int oldHigh = text.length();
+    while (true)
+      {
+        if (c.modelToView(high).y != c.modelToView(offs).y)
+          {
+            oldHigh = high;
+            high = low + ((high + 1 - low) / 2);
+            if (oldHigh == high)
+              return high - 1;
+          }
+        else
+          {
+            low = high;
+            high += ((oldHigh - high) / 2);
+            if (low == high)
+              return low;
+          }
+      }
+  }
+      
+  /**
+   * Get the model position of the start of the row that contains the specified
+   * model position. Return null if the given JTextComponent does not have a
+   * size.
+   * 
+   * @param c the JTextComponent
+   * @param offs the model position
+   * @return the model position of the start of the row containing the given
+   *         offset
+   * @throws BadLocationException if the offset is invalid
+   */
+  public static final int getRowStart(JTextComponent c, int offs)
+      throws BadLocationException
+  {
+    Element root = c.getDocument().getDefaultRootElement();
+    Element rowElement = root.getElement(root.getElementIndex(offs));
+    String text = c.getText(rowElement.getStartOffset(),
+                            rowElement.getEndOffset());
+    if (text == null)
+      return -1;
+
+    // Do a binary search for the greatest position X < offs
+    // such that the character at position X is not on the same
+    // row as the character at position offs
+    int high = offs;
+    int low = 0;
+    int oldLow = 0;
+    while (true)
+      {
+        if (c.modelToView(low).y != c.modelToView(offs).y)
+          {
+            oldLow = low;
+            low = high - ((high + 1 - low) / 2);
+            if (oldLow == low)
+              return low + 1;
+          }
+        else
+          {
+            high = low;
+            low -= ((low - oldLow) / 2);
+            if (low == high)
+              return low;
+          }
+      }
+  }
 }
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to