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

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

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

revision 1.5 by rabbit78, Thu Aug 25 19:25:22 2005 UTC revision 1.6 by rabbit78, Tue Sep 13 23:14:11 2005 UTC
# Line 44  import java.awt.FontMetrics; Line 44  import java.awt.FontMetrics;
44  import java.awt.Graphics;  import java.awt.Graphics;
45  import java.awt.Rectangle;  import java.awt.Rectangle;
46  import java.awt.Shape;  import java.awt.Shape;
47    import java.text.BreakIterator;
48    
49    import javax.swing.SwingConstants;
50    import javax.swing.event.DocumentEvent;
51    import javax.swing.text.Position.Bias;
52    
53  /**  /**
54   * Renders a run of styled text. This {@link View} subclass paints the   * Renders a run of styled text. This {@link View} subclass paints the
# Line 52  import java.awt.Shape; Line 57  import java.awt.Shape;
57   *   *
58   * @author Roman Kennke (roman@kennke.org)   * @author Roman Kennke (roman@kennke.org)
59   */   */
60  public class GlyphView  public class GlyphView extends View implements TabableView, Cloneable
   extends View  
   implements TabableView, Cloneable  
61  {  {
62    
63    /**    /**
# Line 71  public class GlyphView Line 74  public class GlyphView
74      }      }
75    
76      /**      /**
77         * Returns the ascent of the font that is used by this glyph painter.
78         *
79         * @param v the glyph view
80         *
81         * @return the ascent of the font that is used by this glyph painter
82         */
83        public abstract float getAscent(GlyphView v);
84    
85        /**
86         * Returns the descent of the font that is used by this glyph painter.
87         *
88         * @param v the glyph view
89         *
90         * @return the descent of the font that is used by this glyph painter
91         */
92        public abstract float getDescent(GlyphView v);
93    
94        /**
95       * Returns the full height of the rendered text.       * Returns the full height of the rendered text.
96       *       *
97       * @return the full height of the rendered text       * @return the full height of the rendered text
98       */       */
99      public abstract float getHeight(GlyphView view);      public abstract float getHeight(GlyphView view);
100        
101        /**
102         * Determines the model offset, so that the text between <code>p0</code>
103         * and this offset fits within the span starting at <code>x</code> with
104         * the length of <code>len</code>.
105         *
106         * @param v the glyph view
107         * @param p0 the starting offset in the model
108         * @param x the start location in the view
109         * @param len the length of the span in the view
110         */
111        public abstract int getBoundedPosition(GlyphView v, int p0, float x,
112                                               float len);
113    
114      /**      /**
115       * Paints the glyphs.       * Paints the glyphs.
116       *       *
# Line 97  public class GlyphView Line 131  public class GlyphView
131       * @param view the glyph view       * @param view the glyph view
132       * @param pos the position of the character in the model       * @param pos the position of the character in the model
133       * @param a the area that is occupied by the view       * @param a the area that is occupied by the view
134       * @param bias either {@link Position.Bias.Forward} or       * @param b either {@link Position.Bias#Forward} or
135       *        {@link Position.Bias.Backward} depending on the preferred       *        {@link Position.Bias#Backward} depending on the preferred
136       *        direction bias. If <code>null</code> this defaults to       *        direction bias. If <code>null</code> this defaults to
137       *        <code>Position.Bias.Forward</code>       *        <code>Position.Bias.Forward</code>
138       *       *
# Line 114  public class GlyphView Line 148  public class GlyphView
148        throws BadLocationException;        throws BadLocationException;
149    
150      /**      /**
151         * Maps a visual position into a document location.
152         *
153         * @param v the glyph view
154         * @param x the X coordinate of the visual position
155         * @param y the Y coordinate of the visual position
156         * @param a the allocated region
157         * @param biasRet filled with the bias of the model location on method exit
158         *
159         * @return the model location that represents the specified view location
160         */
161        public abstract int viewToModel(GlyphView v, float x, float y, Shape a,
162                                        Position.Bias[] biasRet);
163    
164        /**
165       * Determine the span of the glyphs from location <code>p0</code> to       * Determine the span of the glyphs from location <code>p0</code> to
166       * location <code>p1</code>. If <code>te</code> is not <code>null</code>,       * location <code>p1</code>. If <code>te</code> is not <code>null</code>,
167       * then TABs are expanded using this <code>TabExpander</code>.       * then TABs are expanded using this <code>TabExpander</code>.
# Line 122  public class GlyphView Line 170  public class GlyphView
170       *       *
171       * @param view the glyph view       * @param view the glyph view
172       * @param p0 the starting location in the document model       * @param p0 the starting location in the document model
173       * @param p0 the end location in the document model       * @param p1 the end location in the document model
174       * @param te the tab expander to use       * @param te the tab expander to use
175       * @param x the location at which the view is located       * @param x the location at which the view is located
176       *       *
# Line 132  public class GlyphView Line 180  public class GlyphView
180      public abstract float getSpan(GlyphView view, int p0, int p1,      public abstract float getSpan(GlyphView view, int p0, int p1,
181                                    TabExpander te, float x);                                    TabExpander te, float x);
182    
183    
184        /**
185         * Returns the model location that should be used to place a caret when
186         * moving the caret through the document.
187         *
188         * @param v the glyph view
189         * @param pos the current model location
190         * @param b the bias for <code>p</code>
191         * @param a the allocated region for the glyph view
192         * @param direction the direction from the current position; Must be one of
193         *        {@link SwingConstants#EAST}, {@link SwingConstants#WEST},
194         *        {@link SwingConstants#NORTH} or {@link SwingConstants#SOUTH}
195         * @param biasRet filled with the bias of the resulting location when method
196         *        returns
197         *
198         * @return the location within the document that should be used to place the
199         *         caret when moving the caret around the document
200         *
201         * @throws BadLocationException if <code>pos</code> is an invalid model
202         *         location
203         * @throws IllegalArgumentException if <code>d</code> is invalid
204         */
205        public int getNextVisualPositionFrom(GlyphView v, int pos, Position.Bias b,
206                                             Shape a, int direction,
207                                             Position.Bias[] biasRet)
208          throws BadLocationException
209    
210        {
211          int result = pos;
212          switch (direction)
213          {
214            case SwingConstants.EAST:
215              result = pos + 1;
216              break;
217            case SwingConstants.WEST:
218              result = pos - 1;
219              break;
220            case SwingConstants.NORTH:
221            case SwingConstants.SOUTH:
222            default:
223              // This should be handled in enclosing view, since the glyph view
224              // does not layout vertically.
225              break;
226          }
227          return result;
228        }
229    
230        /**
231         * Returns a painter that can be used to render the specified glyph view.
232         * If this glyph painter is stateful, then it should return a new instance.
233         * However, if this painter is stateless it should return itself. The
234         * default behaviour is to return itself.
235         *
236         * @param v the glyph view for which to create a painter
237         * @param p0 the start offset of the rendered area
238         * @param p1 the end offset of the rendered area
239         *
240         * @return a painter that can be used to render the specified glyph view
241         */
242        public GlyphPainter getPainter(GlyphView v, int p0, int p1)
243        {
244          return this;
245        }
246    }    }
247    
248    /**    /**
# Line 173  public class GlyphView Line 284  public class GlyphView
284        if (parent instanceof TabExpander)        if (parent instanceof TabExpander)
285          tabEx = (TabExpander) parent;          tabEx = (TabExpander) parent;
286    
287        // FIXME: Set character attributes like font-family, font-size, colors.        // Fill the background of the text run.
288        Color foreground = view.getForeground();        Color background = view.getBackground();
289        g.setColor(foreground);        g.setColor(background);
290        Utilities.drawTabbedText(txt, bounds.x, bounds.y, g, tabEx,        int width = Utilities.getTabbedTextWidth(txt, g.getFontMetrics(),
291                                 txt.offset);                                                 bounds.x, tabEx, txt.offset);
292          g.fillRect(bounds.x, bounds.y, width, height);
293    
294          // Draw the actual text.
295          g.setColor(view.getForeground());
296          g.setFont(view.getFont());
297          if (view.isSuperscript())
298            // TODO: Adjust font for superscripting.
299            Utilities.drawTabbedText(txt, bounds.x, bounds.y - height / 2, g, tabEx,
300                                       txt.offset);
301          else if (view.isSubscript())
302            // TODO: Adjust font for subscripting.
303            Utilities.drawTabbedText(txt, bounds.x, bounds.y + height / 2, g, tabEx,
304                                     txt.offset);
305          else
306            Utilities.drawTabbedText(txt, bounds.x, bounds.y, g, tabEx,
307                                     txt.offset);
308    
309          if (view.isStikeThrough())
310            {
311              int strikeHeight = (int) (getAscent(view) / 2);
312              g.drawLine(bounds.x, bounds.y + strikeHeight, bounds.height + width,
313                         bounds.y + strikeHeight);
314            }
315          if (view.isUnderline())
316            {
317              int lineHeight = (int) getAscent(view);
318              g.drawLine(bounds.x, bounds.y + lineHeight, bounds.height + width,
319                         bounds.y + lineHeight);
320            }
321      }      }
322    
323      /**      /**
# Line 188  public class GlyphView Line 328  public class GlyphView
328       * @param view the glyph view       * @param view the glyph view
329       * @param pos the position of the character in the model       * @param pos the position of the character in the model
330       * @param a the area that is occupied by the view       * @param a the area that is occupied by the view
331       * @param bias either {@link Position.Bias.Forward} or       * @param b either {@link Position.Bias#Forward} or
332       *        {@link Position.Bias.Backward} depending on the preferred       *        {@link Position.Bias#Backward} depending on the preferred
333       *        direction bias. If <code>null</code> this defaults to       *        direction bias. If <code>null</code> this defaults to
334       *        <code>Position.Bias.Forward</code>       *        <code>Position.Bias.Forward</code>
335       *       *
# Line 225  public class GlyphView Line 365  public class GlyphView
365       *       *
366       * @param view the glyph view       * @param view the glyph view
367       * @param p0 the starting location in the document model       * @param p0 the starting location in the document model
368       * @param p0 the end location in the document model       * @param p1 the end location in the document model
369       * @param te the tab expander to use       * @param te the tab expander to use
370       * @param x the location at which the view is located       * @param x the location at which the view is located
371       *       *
# Line 242  public class GlyphView Line 382  public class GlyphView
382        int span = Utilities.getTabbedTextWidth(txt, fm, (int) x, te, p0);        int span = Utilities.getTabbedTextWidth(txt, fm, (int) x, te, p0);
383        return span;        return span;
384      }      }
385    
386        /**
387         * Returns the ascent of the text run that is rendered by this
388         * <code>GlyphPainter</code>.
389         *
390         * @param v the glyph view
391         *
392         * @return the ascent of the text run that is rendered by this
393         *         <code>GlyphPainter</code>
394         *
395         * @see FontMetrics#getAscent()
396         */
397        public float getAscent(GlyphView v)
398        {
399          Font font = v.getFont();
400          FontMetrics fm = v.getContainer().getFontMetrics(font);
401          return fm.getAscent();
402        }
403    
404        /**
405         * Returns the descent of the text run that is rendered by this
406         * <code>GlyphPainter</code>.
407         *
408         * @param v the glyph view
409         *
410         * @return the descent of the text run that is rendered by this
411         *         <code>GlyphPainter</code>
412         *
413         * @see FontMetrics#getDescent()
414         */
415        public float getDescent(GlyphView v)
416        {
417          Font font = v.getFont();
418          FontMetrics fm = v.getContainer().getFontMetrics(font);
419          return fm.getDescent();
420        }
421    
422        /**
423         * Determines the model offset, so that the text between <code>p0</code>
424         * and this offset fits within the span starting at <code>x</code> with
425         * the length of <code>len</code>.
426         *
427         * @param v the glyph view
428         * @param p0 the starting offset in the model
429         * @param x the start location in the view
430         * @param len the length of the span in the view
431         */
432        public int getBoundedPosition(GlyphView v, int p0, float x, float len)
433        {
434          // TODO: Implement this properly.
435          throw new AssertionError("Not yet implemented.");
436        }
437    
438        /**
439         * Maps a visual position into a document location.
440         *
441         * @param v the glyph view
442         * @param x the X coordinate of the visual position
443         * @param y the Y coordinate of the visual position
444         * @param a the allocated region
445         * @param biasRet filled with the bias of the model location on method exit
446         *
447         * @return the model location that represents the specified view location
448         */
449        public int viewToModel(GlyphView v, float x, float y, Shape a, Bias[] biasRet)
450        {
451          // TODO: Implement this properly.
452          throw new AssertionError("Not yet implemented.");
453        }
454    }    }
455    
456    /**    /**
# Line 250  public class GlyphView Line 459  public class GlyphView
459    GlyphPainter glyphPainter;    GlyphPainter glyphPainter;
460    
461    /**    /**
462       * The start offset within the document for this view.
463       */
464      int startOffset;
465    
466      /**
467       * The end offset within the document for this view.
468       */
469      int endOffset;
470    
471      /**
472     * Creates a new <code>GlyphView</code> for the given <code>Element</code>.     * Creates a new <code>GlyphView</code> for the given <code>Element</code>.
473     *     *
474     * @param element the element that is rendered by this GlyphView     * @param element the element that is rendered by this GlyphView
# Line 257  public class GlyphView Line 476  public class GlyphView
476    public GlyphView(Element element)    public GlyphView(Element element)
477    {    {
478      super(element);      super(element);
479        startOffset = element.getStartOffset();
480        endOffset = element.getEndOffset();
481    }    }
482    
483    /**    /**
# Line 319  public class GlyphView Line 540  public class GlyphView
540     */     */
541    public float getPreferredSpan(int axis)    public float getPreferredSpan(int axis)
542    {    {
543      Element el = getElement();      float span = 0;
544      checkPainter();      checkPainter();
545      GlyphPainter painter = getGlyphPainter();      GlyphPainter painter = getGlyphPainter();
546      TabExpander tabEx = null;      if (axis == X_AXIS)
547      View parent = getParent();        {
548      if (parent instanceof TabExpander)          Element el = getElement();
549        tabEx = (TabExpander) parent;          TabExpander tabEx = null;
550      // FIXME: Figure out how to determine the x parameter.          View parent = getParent();
551      float span = painter.getSpan(this, el.getStartOffset(), el.getEndOffset(),          if (parent instanceof TabExpander)
552                                   tabEx, 0.F);            tabEx = (TabExpander) parent;
553            // TODO: Figure out how to determine the x parameter.
554            span = painter.getSpan(this, getStartOffset(), getEndOffset(),
555                                   tabEx, 0.F);
556          }
557        else
558          span = painter.getHeight(this);
559      return span;      return span;
560    }    }
561    
# Line 372  public class GlyphView Line 599  public class GlyphView
599     */     */
600    public int viewToModel(float x, float y, Shape a, Position.Bias[] b)    public int viewToModel(float x, float y, Shape a, Position.Bias[] b)
601    {    {
602      // FIXME: not implemented      checkPainter();
603      return 0;      GlyphPainter painter = getGlyphPainter();
604        return painter.viewToModel(this, x, y, a, b);
605    }    }
606    
607    /**    /**
# Line 448  public class GlyphView Line 676  public class GlyphView
676    }    }
677    
678    /**    /**
679       * Returns the start offset in the document model of the portion
680       * of text that this view is responsible for.
681       *
682       * @return the start offset in the document model of the portion
683       *         of text that this view is responsible for
684       */
685      public int getStartOffset()
686      {
687        return startOffset;
688      }
689    
690      /**
691     * Returns the end offset in the document model of the portion     * Returns the end offset in the document model of the portion
692     * of text that this view is responsible for.     * of text that this view is responsible for.
693     *     *
694     * @return the end offset in the document model of the portion     * @return the end offset in the document model of the portion
695     *         of text that this view is responsible for     *         of text that this view is responsible for
696     */     */
697    public int getEndIndex()    public int getEndOffset()
698    {    {
699      return getElement().getEndOffset();      return endOffset;
700    }    }
701    
702    /**    /**
# Line 518  public class GlyphView Line 758  public class GlyphView
758      AttributeSet atts = el.getAttributes();      AttributeSet atts = el.getAttributes();
759      return StyleConstants.getForeground(atts);      return StyleConstants.getForeground(atts);
760    }    }
761    
762      /**
763       * Returns the background color which should be used to paint the text.
764       * This is fetched from the associated element's text attributes using
765       * {@link StyleConstants#getBackground}.
766       *
767       * @return the background color which should be used to paint the text
768       */
769      public Color getBackground()
770      {
771        Element el = getElement();
772        AttributeSet atts = el.getAttributes();
773        return StyleConstants.getBackground(atts);
774      }
775    
776      /**
777       * Determines whether the text should be rendered strike-through or not. This
778       * is determined using the method
779       * {@link StyleConstants#isStrikeThrough(AttributeSet)} on the element of
780       * this view.
781       *
782       * @return whether the text should be rendered strike-through or not
783       */
784      public boolean isStikeThrough()
785      {
786        Element el = getElement();
787        AttributeSet atts = el.getAttributes();
788        return StyleConstants.isStrikeThrough(atts);
789      }
790    
791      /**
792       * Determines whether the text should be rendered as subscript or not. This
793       * is determined using the method
794       * {@link StyleConstants#isSubscript(AttributeSet)} on the element of
795       * this view.
796       *
797       * @return whether the text should be rendered as subscript or not
798       */
799      public boolean isSubscript()
800      {
801        Element el = getElement();
802        AttributeSet atts = el.getAttributes();
803        return StyleConstants.isSubscript(atts);
804      }
805    
806      /**
807       * Determines whether the text should be rendered as superscript or not. This
808       * is determined using the method
809       * {@link StyleConstants#isSuperscript(AttributeSet)} on the element of
810       * this view.
811       *
812       * @return whether the text should be rendered as superscript or not
813       */
814      public boolean isSuperscript()
815      {
816        Element el = getElement();
817        AttributeSet atts = el.getAttributes();
818        return StyleConstants.isSuperscript(atts);
819      }
820    
821      /**
822       * Determines whether the text should be rendered as underlined or not. This
823       * is determined using the method
824       * {@link StyleConstants#isUnderline(AttributeSet)} on the element of
825       * this view.
826       *
827       * @return whether the text should be rendered as underlined or not
828       */
829      public boolean isUnderline()
830      {
831        Element el = getElement();
832        AttributeSet atts = el.getAttributes();
833        return StyleConstants.isUnderline(atts);
834      }
835    
836      /**
837       * Creates and returns a shallow clone of this GlyphView. This is used by
838       * the {@link #createFragment} and {@link #breakView} methods.
839       *
840       * @return a shallow clone of this GlyphView
841       */
842      protected final Object clone()
843      {
844        try
845          {
846            return super.clone();
847          }
848        catch (CloneNotSupportedException ex)
849          {
850            AssertionError err = new AssertionError("CloneNotSupportedException "
851                                                    + "must not be thrown here");
852            err.initCause(ex);
853            throw err;
854          }
855      }
856    
857      /**
858       * Tries to break the view near the specified view span <code>len</code>.
859       * The glyph view can only be broken in the X direction. For Y direction it
860       * returns itself.
861       *
862       * @param axis the axis for breaking, may be {@link View#X_AXIS} or
863       *        {@link View#Y_AXIS}
864       * @param p0 the model location where the fragment should start
865       * @param pos the view position along the axis where the fragment starts
866       * @param len the desired length of the fragment view
867       *
868       * @return the fragment view, or <code>this</code> if breaking was not
869       *         possible
870       */
871      public View breakView(int axis, int p0, float pos, float len)
872      {
873        if (axis == Y_AXIS)
874          return this;
875    
876        checkPainter();
877        GlyphPainter painter = getGlyphPainter();
878        int breakLocation = painter.getBoundedPosition(this, p0, pos, len);
879        // Try to find a suitable line break.
880        BreakIterator lineBreaker = BreakIterator.getLineInstance();
881        Segment txt = new Segment();
882        try
883          {
884            getDocument().getText(getStartOffset(), getEndOffset(), txt);
885          }
886        catch (BadLocationException ex)
887          {
888            AssertionError err = new AssertionError("BadLocationException must not "
889                                                    + "be thrown here.");
890            err.initCause(ex);
891            throw err;
892          }
893        lineBreaker.setText(txt);
894        int goodBreakLocation = lineBreaker.previous();
895        if (goodBreakLocation != BreakIterator.DONE)
896          breakLocation = goodBreakLocation;
897    
898        GlyphView brokenView = (GlyphView) clone();
899        brokenView.startOffset = p0;
900        brokenView.endOffset = breakLocation;
901        return brokenView;
902      }
903    
904      public int getBreakWeight(int axis, float pos, float len)
905      {
906        // FIXME: Implement me.
907        throw new AssertionError("Not yet implemented.");
908      }
909    
910      public void changedUpdate(DocumentEvent e, Shape a, ViewFactory vf)
911      {
912        // FIXME: Implement me.
913        throw new AssertionError("Not yet implemented.");
914      }
915    
916      public void insertUpdate(DocumentEvent e, Shape a, ViewFactory vf)
917      {
918        // FIXME: Implement me.
919        throw new AssertionError("Not yet implemented.");
920      }
921    
922      public void removeUpdate(DocumentEvent e, Shape a, ViewFactory vf)
923      {
924        // FIXME: Implement me.
925        throw new AssertionError("Not yet implemented.");
926      }
927    
928      public View createFragment(int p0, int p1)
929      {
930        // FIXME: Implement me.
931        throw new AssertionError("Not yet implemented.");
932      }
933    
934      /**
935       * Returns the alignment of this view along the specified axis. For the Y
936       * axis this is <code>(height - descent) / height</code> for the used font,
937       * so that it is aligned along the baseline.
938       * For the X axis the superclass is called.
939       */
940      public float getAlignment(int axis)
941      {
942        float align;
943        if (axis == Y_AXIS)
944          {
945            checkPainter();
946            GlyphPainter painter = getGlyphPainter();
947            float height = painter.getHeight(this);
948            float descent = painter.getDescent(this);
949            align = (height - descent) / height;
950          }
951        else
952          align = super.getAlignment(axis);
953    
954        return align;
955      }
956    
957      /**
958       * Returns the model location that should be used to place a caret when
959       * moving the caret through the document.
960       *
961       * @param pos the current model location
962       * @param bias the bias for <code>p</code>
963       * @param a the allocated region for the glyph view
964       * @param direction the direction from the current position; Must be one of
965       *        {@link SwingConstants#EAST}, {@link SwingConstants#WEST},
966       *        {@link SwingConstants#NORTH} or {@link SwingConstants#SOUTH}
967       * @param biasRet filled with the bias of the resulting location when method
968       *        returns
969       *
970       * @return the location within the document that should be used to place the
971       *         caret when moving the caret around the document
972       *
973       * @throws BadLocationException if <code>pos</code> is an invalid model
974       *         location
975       * @throws IllegalArgumentException if <code>d</code> is invalid
976       */
977      public int getNextVisualPositionFrom(int pos, Position.Bias bias, Shape a,
978                                           int direction, Position.Bias[] biasRet)
979        throws BadLocationException
980      {
981        checkPainter();
982        GlyphPainter painter = getGlyphPainter();
983        return painter.getNextVisualPositionFrom(this, pos, bias, a, direction,
984                                                 biasRet);
985      }
986  }  }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

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