/[classpath]/classpath/javax/swing/text/Utilities.java
ViewVC logotype

Diff of /classpath/javax/swing/text/Utilities.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4.2.7 by gnu_andrew, Tue Sep 20 18:46:35 2005 UTC revision 1.4.2.8 by gnu_andrew, Wed Nov 2 00:44:04 2005 UTC
# Line 40  package javax.swing.text; Line 40  package javax.swing.text;
40    
41  import java.awt.FontMetrics;  import java.awt.FontMetrics;
42  import java.awt.Graphics;  import java.awt.Graphics;
43    import java.text.BreakIterator;
44    
45  /**  /**
46   * A set of utilities to deal with text. This is used by several other classes   * A set of utilities to deal with text. This is used by several other classes
# Line 231  public class Utilities Line 232  public class Utilities
232      // At the end of the for loop, this holds the requested model location      // At the end of the for loop, this holds the requested model location
233      int pos;      int pos;
234      int currentX = x0;      int currentX = x0;
235      for (pos = p0; pos < s.getEndIndex(); pos++)  
236        for (pos = p0; pos < s.count; pos++)
237        {        {
238          char nextChar = s.array[pos];          char nextChar = s.array[s.offset+pos];
239          if (nextChar != '\n')          if (nextChar == 0)
240              {
241                if (! round)
242                  pos--;
243                break;
244              }
245            if (nextChar != '\t')
246            currentX += fm.charWidth(nextChar);            currentX += fm.charWidth(nextChar);
247          else          else
248            {            {
# Line 243  public class Utilities Line 251  public class Utilities
251              else              else
252                currentX = (int) te.nextTabStop(currentX, pos);                currentX = (int) te.nextTabStop(currentX, pos);
253            }            }
254          if (currentX >= x)          if (currentX > x)
255            {            {
256              if (! round)              if (! round)
257                pos--;                pos--;
# Line 280  public class Utilities Line 288  public class Utilities
288    {    {
289      return getTabbedTextOffset(s, fm, x0, x, te, p0, true);      return getTabbedTextOffset(s, fm, x0, x, te, p0, true);
290    }    }
291      
292      /**
293       * Finds the start of the next word for the given offset.
294       *
295       * @param c
296       *          the text component
297       * @param offs
298       *          the offset in the document
299       * @return the location in the model of the start of the next word.
300       * @throws BadLocationException
301       *           if the offset is invalid.
302       */
303      public static final int getNextWord(JTextComponent c, int offs)
304          throws BadLocationException
305      {
306        if (offs < 0 || offs > (c.getText().length() - 1))
307          throw new BadLocationException("invalid offset specified", offs);
308        String text = c.getText();
309        BreakIterator wb = BreakIterator.getWordInstance();
310        wb.setText(text);
311        int last = wb.following(offs);
312        int current = wb.next();
313        while (current != BreakIterator.DONE)
314          {
315            for (int i = last; i < current; i++)
316              {
317                // FIXME: Should use isLetter(int) and text.codePointAt(int)
318                // instead, but isLetter(int) isn't implemented yet
319                if (Character.isLetter(text.charAt(i)))
320                  return last;
321              }
322            last = current;
323            current = wb.next();
324          }
325        return BreakIterator.DONE;
326      }
327    
328      /**
329       * Finds the start of the previous word for the given offset.
330       *
331       * @param c
332       *          the text component
333       * @param offs
334       *          the offset in the document
335       * @return the location in the model of the start of the previous word.
336       * @throws BadLocationException
337       *           if the offset is invalid.
338       */
339      public static final int getPreviousWord(JTextComponent c, int offs)
340          throws BadLocationException
341      {
342        if (offs < 0 || offs > (c.getText().length() - 1))
343          throw new BadLocationException("invalid offset specified", offs);
344        String text = c.getText();
345        BreakIterator wb = BreakIterator.getWordInstance();
346        wb.setText(text);
347        int last = wb.preceding(offs);
348        int current = wb.previous();
349    
350        while (current != BreakIterator.DONE)
351          {
352            for (int i = last; i < offs; i++)
353              {
354                // FIXME: Should use isLetter(int) and text.codePointAt(int)
355                // instead, but isLetter(int) isn't implemented yet
356                if (Character.isLetter(text.charAt(i)))
357                  return last;
358              }
359            last = current;
360            current = wb.previous();
361          }
362        return 0;
363      }
364      
365      /**
366       * Finds the start of a word for the given location.
367       * @param c the text component
368       * @param offs the offset location
369       * @return the location of the word beginning
370       * @throws BadLocationException if the offset location is invalid
371       */
372      public static final int getWordStart(JTextComponent c, int offs)
373          throws BadLocationException
374      {
375        if (offs < 0 || offs >= c.getText().length())
376          throw new BadLocationException("invalid offset specified", offs);
377        
378        String text = c.getText();
379        BreakIterator wb = BreakIterator.getWordInstance();
380        wb.setText(text);
381        if (wb.isBoundary(offs))
382          return offs;
383        return wb.preceding(offs);
384      }
385      
386      /**
387       * Finds the end of a word for the given location.
388       * @param c the text component
389       * @param offs the offset location
390       * @return the location of the word end
391       * @throws BadLocationException if the offset location is invalid
392       */
393      public static final int getWordEnd(JTextComponent c, int offs)
394          throws BadLocationException
395      {
396        if (offs < 0 || offs >= c.getText().length())
397          throw new BadLocationException("invalid offset specified", offs);
398        
399        String text = c.getText();
400        BreakIterator wb = BreakIterator.getWordInstance();
401        wb.setText(text);
402        return wb.following(offs);
403      }
404      
405      /**
406       * Get the model position of the end of the row that contains the
407       * specified model position.  Return null if the given JTextComponent
408       * does not have a size.
409       * @param c the JTextComponent
410       * @param offs the model position
411       * @return the model position of the end of the row containing the given
412       * offset
413       * @throws BadLocationException if the offset is invalid
414       */
415      public static final int getRowEnd(JTextComponent c, int offs)
416          throws BadLocationException
417      {
418        String text = c.getText();
419        if (text == null)
420          return -1;
421    
422        // Do a binary search for the smallest position X > offs
423        // such that that character at positino X is not on the same
424        // line as the character at position offs
425        int high = offs + ((text.length() - 1 - offs) / 2);
426        int low = offs;
427        int oldHigh = text.length() + 1;
428        while (true)
429          {
430            if (c.modelToView(high).y != c.modelToView(offs).y)
431              {
432                oldHigh = high;
433                high = low + ((high + 1 - low) / 2);
434                if (oldHigh == high)
435                  return high - 1;
436              }
437            else
438              {
439                low = high;
440                high += ((oldHigh - high) / 2);
441                if (low == high)
442                  return low;
443              }
444          }
445      }
446          
447      /**
448       * Get the model position of the start of the row that contains the specified
449       * model position. Return null if the given JTextComponent does not have a
450       * size.
451       *
452       * @param c the JTextComponent
453       * @param offs the model position
454       * @return the model position of the start of the row containing the given
455       *         offset
456       * @throws BadLocationException if the offset is invalid
457       */
458      public static final int getRowStart(JTextComponent c, int offs)
459          throws BadLocationException
460      {
461        String text = c.getText();
462        if (text == null)
463          return -1;
464    
465        // Do a binary search for the greatest position X < offs
466        // such that the character at position X is not on the same
467        // row as the character at position offs
468        int high = offs;
469        int low = 0;
470        int oldLow = 0;
471        while (true)
472          {
473            if (c.modelToView(low).y != c.modelToView(offs).y)
474              {
475                oldLow = low;
476                low = high - ((high + 1 - low) / 2);
477                if (oldLow == low)
478                  return low + 1;
479              }
480            else
481              {
482                high = low;
483                low -= ((low - oldLow) / 2);
484                if (low == high)
485                  return low;
486              }
487          }
488      }
489      
490      /**
491       * Determine where to break the text in the given Segment, attempting to find
492       * a word boundary.
493       * @param s the Segment that holds the text
494       * @param metrics the font metrics used for calculating the break point
495       * @param x0 starting view location representing the start of the text
496       * @param x the target view location
497       * @param e the TabExpander used for expanding tabs (if this is null tabs
498       * are expanded to 1 space)
499       * @param startOffset the offset in the Document of the start of the text
500       * @return the offset at which we should break the text
501       */
502      public static final int getBreakLocation(Segment s, FontMetrics metrics,
503                                               int x0, int x, TabExpander e,
504                                               int startOffset)
505      {
506        int mark = Utilities.getTabbedTextOffset(s, metrics, x0, x, e, startOffset);
507        BreakIterator breaker = BreakIterator.getWordInstance();
508        breaker.setText(s.toString());
509        
510        // If mark is equal to the end of the string, just use that position
511        if (mark == s.count)
512          return mark;
513        
514        // Try to find a word boundary previous to the mark at which we
515        // can break the text
516        int preceding = breaker.preceding(mark + 1);
517        
518        if (preceding != 0)
519          return preceding;
520        else
521          // If preceding is 0 we couldn't find a suitable word-boundary so
522          // just break it on the character boundary
523          return mark;
524      }
525  }  }

Legend:
Removed from v.1.4.2.7  
changed lines
  Added in v.1.4.2.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26