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.Image;
  44 import java.awt.Graphics2D;
  45 import java.awt.geom.Rectangle2D;
  46 
  47 /**
  48  * The <code>ImageGraphicAttribute</code> class is an implementation of
  49  * {@link GraphicAttribute} which draws images in
  50  * a {@link TextLayout}.
  51  * @see GraphicAttribute
  52  */
  53 
  54 public final class ImageGraphicAttribute extends GraphicAttribute {
  55 
  56     private Image fImage;
  57     private float fImageWidth, fImageHeight;
  58     private float fOriginX, fOriginY;
  59 
  60     /**
  61      * Constucts an <code>ImageGraphicAttribute</code> from the specified
  62      * {@link Image}.  The origin is at (0,&nbsp;0).
  63      * @param image the <code>Image</code> rendered by this
  64      * <code>ImageGraphicAttribute</code>.
  65      * This object keeps a reference to <code>image</code>.
  66      * @param alignment one of the alignments from this
  67      * <code>ImageGraphicAttribute</code>
  68      */
  69     public ImageGraphicAttribute(Image image, int alignment) {
  70 
  71         this(image, alignment, 0, 0);
  72     }
  73 
  74     /**
  75      * Constructs an <code>ImageGraphicAttribute</code> from the specified
  76      * <code>Image</code>. The point
  77      * (<code>originX</code>,&nbsp;<code>originY</code>) in the
  78      * <code>Image</code> appears at the origin of the
  79      * <code>ImageGraphicAttribute</code> within the text.
  80      * @param image the <code>Image</code> rendered by this
  81      * <code>ImageGraphicAttribute</code>.
  82      * This object keeps a reference to <code>image</code>.
  83      * @param alignment one of the alignments from this
  84      * <code>ImageGraphicAttribute</code>
  85      * @param originX the X coordinate of the point within
  86      * the <code>Image</code> that appears at the origin of the
  87      * <code>ImageGraphicAttribute</code> in the text line.
  88      * @param originY the Y coordinate of the point within
  89      * the <code>Image</code> that appears at the origin of the
  90      * <code>ImageGraphicAttribute</code> in the text line.
  91      */
  92     public ImageGraphicAttribute(Image image,
  93                                  int alignment,
  94                                  float originX,
  95                                  float originY) {
  96 
  97         super(alignment);
  98 
  99         // Can't clone image
 100         // fImage = (Image) image.clone();
 101         fImage = image;
 102 
 103         fImageWidth = image.getWidth(null);
 104         fImageHeight = image.getHeight(null);
 105 
 106         // ensure origin is in Image?
 107         fOriginX = originX;
 108         fOriginY = originY;
 109     }
 110 
 111     /**
 112      * Returns the ascent of this <code>ImageGraphicAttribute</code>.  The
 113      * ascent of an <code>ImageGraphicAttribute</code> is the distance
 114      * from the top of the image to the origin.
 115      * @return the ascent of this <code>ImageGraphicAttribute</code>.
 116      */
 117     public float getAscent() {
 118 
 119         return Math.max(0, fOriginY);
 120     }
 121 
 122     /**
 123      * Returns the descent of this <code>ImageGraphicAttribute</code>.
 124      * The descent of an <code>ImageGraphicAttribute</code> is the
 125      * distance from the origin to the bottom of the image.
 126      * @return the descent of this <code>ImageGraphicAttribute</code>.
 127      */
 128     public float getDescent() {
 129 
 130         return Math.max(0, fImageHeight-fOriginY);
 131     }
 132 
 133     /**
 134      * Returns the advance of this <code>ImageGraphicAttribute</code>.
 135      * The advance of an <code>ImageGraphicAttribute</code> is the
 136      * distance from the origin to the right edge of the image.
 137      * @return the advance of this <code>ImageGraphicAttribute</code>.
 138      */
 139     public float getAdvance() {
 140 
 141         return Math.max(0, fImageWidth-fOriginX);
 142     }
 143 
 144     /**
 145      * Returns a {@link Rectangle2D} that encloses all of the
 146      * bits rendered by this <code>ImageGraphicAttribute</code>, relative
 147      * to the rendering position.  A graphic can be rendered beyond its
 148      * origin, ascent, descent, or advance;  but if it is, this
 149      * method's implementation must indicate where the graphic is rendered.
 150      * @return a <code>Rectangle2D</code> that encloses all of the bits
 151      * rendered by this <code>ImageGraphicAttribute</code>.
 152      */
 153     public Rectangle2D getBounds() {
 154 
 155         return new Rectangle2D.Float(
 156                         -fOriginX, -fOriginY, fImageWidth, fImageHeight);
 157     }
 158 
 159     /**
 160      * {@inheritDoc}
 161      */
 162     public void draw(Graphics2D graphics, float x, float y) {
 163 
 164         graphics.drawImage(fImage, (int) (x-fOriginX), (int) (y-fOriginY), null);
 165     }
 166 
 167     /**
 168      * Returns a hashcode for this <code>ImageGraphicAttribute</code>.
 169      * @return  a hash code value for this object.
 170      */
 171     public int hashCode() {
 172 
 173         return fImage.hashCode();
 174     }
 175 
 176     /**
 177      * Compares this <code>ImageGraphicAttribute</code> to the specified
 178      * {@link Object}.
 179      * @param rhs the <code>Object</code> to compare for equality
 180      * @return <code>true</code> if this
 181      * <code>ImageGraphicAttribute</code> equals <code>rhs</code>;
 182      * <code>false</code> otherwise.
 183      */
 184     public boolean equals(Object rhs) {
 185 
 186         try {
 187             return equals((ImageGraphicAttribute) rhs);
 188         }
 189         catch(ClassCastException e) {
 190             return false;
 191         }
 192     }
 193 
 194     /**
 195      * Compares this <code>ImageGraphicAttribute</code> to the specified
 196      * <code>ImageGraphicAttribute</code>.
 197      * @param rhs the <code>ImageGraphicAttribute</code> to compare for
 198      * equality
 199      * @return <code>true</code> if this
 200      * <code>ImageGraphicAttribute</code> equals <code>rhs</code>;
 201      * <code>false</code> otherwise.
 202      */
 203     public boolean equals(ImageGraphicAttribute rhs) {
 204 
 205         if (rhs == null) {
 206             return false;
 207         }
 208 
 209         if (this == rhs) {
 210             return true;
 211         }
 212 
 213         if (fOriginX != rhs.fOriginX || fOriginY != rhs.fOriginY) {
 214             return false;
 215         }
 216 
 217         if (getAlignment() != rhs.getAlignment()) {
 218             return false;
 219         }
 220 
 221         if (!fImage.equals(rhs.fImage)) {
 222             return false;
 223         }
 224 
 225         return true;
 226     }
 227 }