Home » openjdk-7 » javax » swing » text » [javadoc | source]

    1   /*
    2    * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package javax.swing.text;
   26   
   27   import java.awt;
   28   
   29   /**
   30    * A class to perform rendering of the glyphs.
   31    * This can be implemented to be stateless, or
   32    * to hold some information as a cache to
   33    * facilitate faster rendering and model/view
   34    * translation.  At a minimum, the GlyphPainter
   35    * allows a View implementation to perform its
   36    * duties independent of a particular version
   37    * of JVM and selection of capabilities (i.e.
   38    * shaping for i18n, etc).
   39    * <p>
   40    * This implementation is intended for operation
   41    * under the JDK1.1 API of the Java Platform.
   42    * Since the JDK is backward compatible with
   43    * JDK1.1 API, this class will also function on
   44    * Java 2.  The JDK introduces improved
   45    * API for rendering text however, so the GlyphPainter2
   46    * is recommended for the DK.
   47    *
   48    * @author  Timothy Prinzing
   49    * @see GlyphView
   50    */
   51   class GlyphPainter1 extends GlyphView.GlyphPainter {
   52   
   53       /**
   54        * Determine the span the glyphs given a start location
   55        * (for tab expansion).
   56        */
   57       public float getSpan(GlyphView v, int p0, int p1,
   58                            TabExpander e, float x) {
   59           sync(v);
   60           Segment text = v.getText(p0, p1);
   61           int[] justificationData = getJustificationData(v);
   62           int width = Utilities.getTabbedTextWidth(v, text, metrics, (int) x, e, p0,
   63                                                    justificationData);
   64           SegmentCache.releaseSharedSegment(text);
   65           return width;
   66       }
   67   
   68       public float getHeight(GlyphView v) {
   69           sync(v);
   70           return metrics.getHeight();
   71       }
   72   
   73       /**
   74        * Fetches the ascent above the baseline for the glyphs
   75        * corresponding to the given range in the model.
   76        */
   77       public float getAscent(GlyphView v) {
   78           sync(v);
   79           return metrics.getAscent();
   80       }
   81   
   82       /**
   83        * Fetches the descent below the baseline for the glyphs
   84        * corresponding to the given range in the model.
   85        */
   86       public float getDescent(GlyphView v) {
   87           sync(v);
   88           return metrics.getDescent();
   89       }
   90   
   91       /**
   92        * Paints the glyphs representing the given range.
   93        */
   94       public void paint(GlyphView v, Graphics g, Shape a, int p0, int p1) {
   95           sync(v);
   96           Segment text;
   97           TabExpander expander = v.getTabExpander();
   98           Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
   99   
  100           // determine the x coordinate to render the glyphs
  101           int x = alloc.x;
  102           int p = v.getStartOffset();
  103           int[] justificationData = getJustificationData(v);
  104           if (p != p0) {
  105               text = v.getText(p, p0);
  106               int width = Utilities.getTabbedTextWidth(v, text, metrics, x, expander, p,
  107                                                        justificationData);
  108               x += width;
  109               SegmentCache.releaseSharedSegment(text);
  110           }
  111   
  112           // determine the y coordinate to render the glyphs
  113           int y = alloc.y + metrics.getHeight() - metrics.getDescent();
  114   
  115           // render the glyphs
  116           text = v.getText(p0, p1);
  117           g.setFont(metrics.getFont());
  118   
  119           Utilities.drawTabbedText(v, text, x, y, g, expander,p0,
  120                                    justificationData);
  121           SegmentCache.releaseSharedSegment(text);
  122       }
  123   
  124       public Shape modelToView(GlyphView v, int pos, Position.Bias bias,
  125                                Shape a) throws BadLocationException {
  126   
  127           sync(v);
  128           Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
  129           int p0 = v.getStartOffset();
  130           int p1 = v.getEndOffset();
  131           TabExpander expander = v.getTabExpander();
  132           Segment text;
  133   
  134           if(pos == p1) {
  135               // The caller of this is left to right and borders a right to
  136               // left view, return our end location.
  137               return new Rectangle(alloc.x + alloc.width, alloc.y, 0,
  138                                    metrics.getHeight());
  139           }
  140           if ((pos >= p0) && (pos <= p1)) {
  141               // determine range to the left of the position
  142               text = v.getText(p0, pos);
  143               int[] justificationData = getJustificationData(v);
  144               int width = Utilities.getTabbedTextWidth(v, text, metrics, alloc.x, expander, p0,
  145                                                        justificationData);
  146               SegmentCache.releaseSharedSegment(text);
  147               return new Rectangle(alloc.x + width, alloc.y, 0, metrics.getHeight());
  148           }
  149           throw new BadLocationException("modelToView - can't convert", p1);
  150       }
  151   
  152       /**
  153        * Provides a mapping from the view coordinate space to the logical
  154        * coordinate space of the model.
  155        *
  156        * @param v the view containing the view coordinates
  157        * @param x the X coordinate
  158        * @param y the Y coordinate
  159        * @param a the allocated region to render into
  160        * @param biasReturn always returns <code>Position.Bias.Forward</code>
  161        *   as the zero-th element of this array
  162        * @return the location within the model that best represents the
  163        *  given point in the view
  164        * @see View#viewToModel
  165        */
  166       public int viewToModel(GlyphView v, float x, float y, Shape a,
  167                              Position.Bias[] biasReturn) {
  168   
  169           sync(v);
  170           Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
  171           int p0 = v.getStartOffset();
  172           int p1 = v.getEndOffset();
  173           TabExpander expander = v.getTabExpander();
  174           Segment text = v.getText(p0, p1);
  175           int[] justificationData = getJustificationData(v);
  176           int offs = Utilities.getTabbedTextOffset(v, text, metrics,
  177                                                    alloc.x, (int) x, expander, p0,
  178                                                    justificationData);
  179           SegmentCache.releaseSharedSegment(text);
  180           int retValue = p0 + offs;
  181           if(retValue == p1) {
  182               // No need to return backward bias as GlyphPainter1 is used for
  183               // ltr text only.
  184               retValue--;
  185           }
  186           biasReturn[0] = Position.Bias.Forward;
  187           return retValue;
  188       }
  189   
  190       /**
  191        * Determines the best location (in the model) to break
  192        * the given view.
  193        * This method attempts to break on a whitespace
  194        * location.  If a whitespace location can't be found, the
  195        * nearest character location is returned.
  196        *
  197        * @param v the view
  198        * @param p0 the location in the model where the
  199        *  fragment should start its representation >= 0
  200        * @param pos the graphic location along the axis that the
  201        *  broken view would occupy >= 0; this may be useful for
  202        *  things like tab calculations
  203        * @param len specifies the distance into the view
  204        *  where a potential break is desired >= 0
  205        * @return the model location desired for a break
  206        * @see View#breakView
  207        */
  208       public int getBoundedPosition(GlyphView v, int p0, float x, float len) {
  209           sync(v);
  210           TabExpander expander = v.getTabExpander();
  211           Segment s = v.getText(p0, v.getEndOffset());
  212           int[] justificationData = getJustificationData(v);
  213           int index = Utilities.getTabbedTextOffset(v, s, metrics, (int)x, (int)(x+len),
  214                                                     expander, p0, false,
  215                                                     justificationData);
  216           SegmentCache.releaseSharedSegment(s);
  217           int p1 = p0 + index;
  218           return p1;
  219       }
  220   
  221       void sync(GlyphView v) {
  222           Font f = v.getFont();
  223           if ((metrics == null) || (! f.equals(metrics.getFont()))) {
  224               // fetch a new FontMetrics
  225               Container c = v.getContainer();
  226               metrics = (c != null) ? c.getFontMetrics(f) :
  227                   Toolkit.getDefaultToolkit().getFontMetrics(f);
  228           }
  229       }
  230   
  231   
  232   
  233       /**
  234        * @return justificationData from the ParagraphRow this GlyphView
  235        * is in or {@code null} if no justification is needed
  236        */
  237       private int[] getJustificationData(GlyphView v) {
  238           View parent = v.getParent();
  239           int [] ret = null;
  240           if (parent instanceof ParagraphView.Row) {
  241               ParagraphView.Row row = ((ParagraphView.Row) parent);
  242               ret = row.justificationData;
  243           }
  244           return ret;
  245       }
  246   
  247       // --- variables ---------------------------------------------
  248   
  249       FontMetrics metrics;
  250   }

Home » openjdk-7 » javax » swing » text » [javadoc | source]