1 /*
   2  * Copyright (c) 1998, 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 
  26 /*
  27  * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
  28  * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
  29  *
  30  * The original version of this source code and documentation is
  31  * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
  32  * of IBM. These materials are provided under terms of a License
  33  * Agreement between Taligent and Sun. This technology is protected
  34  * by multiple US and International patents.
  35  *
  36  * This notice and attribution to Taligent may not be removed.
  37  * Taligent is a registered trademark of Taligent, Inc.
  38  *
  39  */
  40 
  41 package java.awt.font;
  42 
  43 import java.awt.Graphics2D;
  44 import java.awt.Font;
  45 import java.awt.Shape;
  46 import java.awt.geom.AffineTransform;
  47 import java.awt.geom.Rectangle2D;
  48 
  49 /**
  50  * This class is used with the CHAR_REPLACEMENT attribute.
  51  * <p>
  52  * The <code>GraphicAttribute</code> class represents a graphic embedded
  53  * in text. Clients subclass this class to implement their own char
  54  * replacement graphics.  Clients wishing to embed shapes and images in
  55  * text need not subclass this class.  Instead, clients can use the
  56  * {@link ShapeGraphicAttribute} and {@link ImageGraphicAttribute}
  57  * classes.
  58  * <p>
  59  * Subclasses must ensure that their objects are immutable once they
  60  * are constructed.  Mutating a <code>GraphicAttribute</code> that
  61  * is used in a {@link TextLayout} results in undefined behavior from the
  62  * <code>TextLayout</code>.
  63  */
  64 public abstract class GraphicAttribute {
  65 
  66     private int fAlignment;
  67 
  68     /**
  69      * Aligns top of graphic to top of line.
  70      */
  71     public static final int TOP_ALIGNMENT = -1;
  72 
  73     /**
  74      * Aligns bottom of graphic to bottom of line.
  75      */
  76     public static final int BOTTOM_ALIGNMENT = -2;
  77 
  78     /**
  79      * Aligns origin of graphic to roman baseline of line.
  80      */
  81     public static final int ROMAN_BASELINE = Font.ROMAN_BASELINE;
  82 
  83     /**
  84      * Aligns origin of graphic to center baseline of line.
  85      */
  86     public static final int CENTER_BASELINE = Font.CENTER_BASELINE;
  87 
  88     /**
  89      * Aligns origin of graphic to hanging baseline of line.
  90      */
  91     public static final int HANGING_BASELINE = Font.HANGING_BASELINE;
  92 
  93     /**
  94      * Constructs a <code>GraphicAttribute</code>.
  95      * Subclasses use this to define the alignment of the graphic.
  96      * @param alignment an int representing one of the
  97      * <code>GraphicAttribute</code> alignment fields
  98      * @throws IllegalArgumentException if alignment is not one of the
  99      * five defined values.
 100      */
 101     protected GraphicAttribute(int alignment) {
 102         if (alignment < BOTTOM_ALIGNMENT || alignment > HANGING_BASELINE) {
 103           throw new IllegalArgumentException("bad alignment");
 104         }
 105         fAlignment = alignment;
 106     }
 107 
 108     /**
 109      * Returns the ascent of this <code>GraphicAttribute</code>.  A
 110      * graphic can be rendered above its ascent.
 111      * @return the ascent of this <code>GraphicAttribute</code>.
 112      * @see #getBounds()
 113      */
 114     public abstract float getAscent();
 115 
 116 
 117     /**
 118      * Returns the descent of this <code>GraphicAttribute</code>.  A
 119      * graphic can be rendered below its descent.
 120      * @return the descent of this <code>GraphicAttribute</code>.
 121      * @see #getBounds()
 122      */
 123     public abstract float getDescent();
 124 
 125     /**
 126      * Returns the advance of this <code>GraphicAttribute</code>.  The
 127      * <code>GraphicAttribute</code> object's advance is the distance
 128      * from the point at which the graphic is rendered and the point where
 129      * the next character or graphic is rendered.  A graphic can be
 130      * rendered beyond its advance
 131      * @return the advance of this <code>GraphicAttribute</code>.
 132      * @see #getBounds()
 133      */
 134     public abstract float getAdvance();
 135 
 136     /**
 137      * Returns a {@link Rectangle2D} that encloses all of the
 138      * bits drawn by this <code>GraphicAttribute</code> relative to the
 139      * rendering position.
 140      * A graphic may be rendered beyond its origin, ascent, descent,
 141      * or advance;  but if it is, this method's implementation must
 142      * indicate where the graphic is rendered.
 143      * Default bounds is the rectangle (0, -ascent, advance, ascent+descent).
 144      * @return a <code>Rectangle2D</code> that encloses all of the bits
 145      * rendered by this <code>GraphicAttribute</code>.
 146      */
 147     public Rectangle2D getBounds() {
 148         float ascent = getAscent();
 149         return new Rectangle2D.Float(0, -ascent,
 150                                         getAdvance(), ascent+getDescent());
 151     }
 152 
 153     /**
 154      * Return a {@link java.awt.Shape} that represents the region that
 155      * this <code>GraphicAttribute</code> renders.  This is used when a
 156      * {@link TextLayout} is requested to return the outline of the text.
 157      * The (untransformed) shape must not extend outside the rectangular
 158      * bounds returned by <code>getBounds</code>.
 159      * The default implementation returns the rectangle returned by
 160      * {@link #getBounds}, transformed by the provided {@link AffineTransform}
 161      * if present.
 162      * @param tx an optional {@link AffineTransform} to apply to the
 163      *   outline of this <code>GraphicAttribute</code>. This can be null.
 164      * @return a <code>Shape</code> representing this graphic attribute,
 165      *   suitable for stroking or filling.
 166      * @since 1.6
 167      */
 168     public Shape getOutline(AffineTransform tx) {
 169         Shape b = getBounds();
 170         if (tx != null) {
 171             b = tx.createTransformedShape(b);
 172         }
 173         return b;
 174     }
 175 
 176     /**
 177      * Renders this <code>GraphicAttribute</code> at the specified
 178      * location.
 179      * @param graphics the {@link Graphics2D} into which to render the
 180      * graphic
 181      * @param x the user-space X coordinate where the graphic is rendered
 182      * @param y the user-space Y coordinate where the graphic is rendered
 183      */
 184     public abstract void draw(Graphics2D graphics, float x, float y);
 185 
 186     /**
 187      * Returns the alignment of this <code>GraphicAttribute</code>.
 188      * Alignment can be to a particular baseline, or to the absolute top
 189      * or bottom of a line.
 190      * @return the alignment of this <code>GraphicAttribute</code>.
 191      */
 192     public final int getAlignment() {
 193 
 194         return fAlignment;
 195     }
 196 
 197     /**
 198      * Returns the justification information for this
 199      * <code>GraphicAttribute</code>.  Subclasses
 200      * can override this method to provide different justification
 201      * information.
 202      * @return a {@link GlyphJustificationInfo} object that contains the
 203      * justification information for this <code>GraphicAttribute</code>.
 204      */
 205     public GlyphJustificationInfo getJustificationInfo() {
 206 
 207         // should we cache this?
 208         float advance = getAdvance();
 209 
 210         return new GlyphJustificationInfo(
 211                                      advance,   // weight
 212                                      false,     // growAbsorb
 213                                      2,         // growPriority
 214                                      advance/3, // growLeftLimit
 215                                      advance/3, // growRightLimit
 216                                      false,     // shrinkAbsorb
 217                                      1,         // shrinkPriority
 218                                      0,         // shrinkLeftLimit
 219                                      0);        // shrinkRightLimit
 220     }
 221 }