KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > animation > renderer > AbstractTextRenderer


1 /*
2  * Copyright (c) 2001-2004 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.animation.renderer;
32
33 import java.awt.Color JavaDoc;
34 import java.awt.Font JavaDoc;
35 import java.awt.Graphics2D JavaDoc;
36 import java.awt.Shape JavaDoc;
37 import java.awt.font.FontRenderContext JavaDoc;
38 import java.awt.font.GlyphVector JavaDoc;
39 import java.awt.geom.Rectangle2D JavaDoc;
40
41 import com.jgoodies.animation.*;
42
43 /**
44  * An abstract superclass that helps implementing typographic animation renderers.
45  *
46  * @author Karsten Lentzsch
47  * @version $Revision: 1.3 $
48  */

49 public abstract class AbstractTextRenderer implements AnimationRenderer {
50
51     private String JavaDoc text;
52     private Font JavaDoc font;
53     private Color JavaDoc color;
54     private HeightMode heightMode = HeightMode.CAPITAL_ASCENT;
55
56     // Cached data -------------------------------------------
57
protected GlyphVector JavaDoc cachedGlyphVector;
58     protected Shape JavaDoc[] cachedGlyphShapes;
59     protected float cachedTextWidth;
60     protected float cachedTextAscent;
61     protected float cachedTextHeight;
62     protected float capitalMAscent = -1f; // Ascent of a capital M
63
private boolean cacheValid = false;
64
65     
66     // Instance Creation ******************************************************
67

68     AbstractTextRenderer(String JavaDoc text) {
69         this(text, null);
70     }
71
72     AbstractTextRenderer(String JavaDoc text, Font JavaDoc font) {
73         this.text = text == null ? "Karsten Lentzsch" : text;
74         this.font = font == null ? createDefaultFont() : font;
75     }
76
77     /**
78      * Creates and returns a default font object.
79      *
80      * @return a default font object
81      */

82     private static Font JavaDoc createDefaultFont() {
83         return new Font JavaDoc("dialog", Font.BOLD, 12);
84     }
85     
86     
87     // Accessors **************************************************************
88

89     public Color JavaDoc getColor() {
90         return color;
91     }
92     
93     public Font JavaDoc getFont() {
94         return font;
95     }
96     
97     public String JavaDoc getText() {
98         return text;
99     }
100     
101     public HeightMode getHeightMode() {
102         return heightMode;
103     }
104
105     public void setColor(Color JavaDoc color) {
106         this.color = color;
107     }
108     
109     public void setHeightMode(HeightMode heightMode) {
110         this.heightMode = heightMode;
111     }
112
113     /**
114      * Sets the renderer's font.
115      *
116      * @param newFont the font to be set
117      */

118     public void setFont(Font JavaDoc newFont) {
119         if (newFont == null)
120             throw new NullPointerException JavaDoc("The font must not be null.");
121
122         if (newFont.equals(font))
123             return;
124
125         font = newFont;
126         invalidateCache();
127     }
128
129     /**
130      * Sets the renderer's text.
131      *
132      * @param newText the text to be set
133      */

134     public void setText(String JavaDoc newText) {
135         if (newText == null)
136             throw new NullPointerException JavaDoc("The text must not be null.");
137
138         if (newText.equals(text))
139             return;
140
141         text = newText;
142         invalidateCache();
143     }
144
145     /**
146      * Computes and answers the text ascent using the current height mode.
147      *
148      * @return the ascent adjusted using the current height mode
149      * @see #getHeightMode()
150      */

151     protected float getAdjustedAscent() {
152         if (heightMode == HeightMode.CAPITAL_ASCENT)
153             return capitalMAscent;
154         else if (heightMode == HeightMode.TEXT_ASCENT)
155             return cachedTextAscent;
156         else
157             return cachedTextHeight;
158     }
159
160     /**
161      * Computes and answers the text descent using the current height mode.
162      *
163      * @return the descent adjusted to the current height mode
164      * @see #getHeightMode()
165      */

166     protected float getAdjustedDescent() {
167         if (heightMode == HeightMode.CAPITAL_ASCENT)
168             return 0;
169         else if (heightMode == HeightMode.TEXT_ASCENT)
170             return 0;
171         else
172             return cachedTextHeight - cachedTextAscent;
173     }
174
175     // Caching ****************************************************************
176

177     protected boolean isCacheValid() {
178         return cacheValid;
179     }
180
181     protected void setCacheValid(boolean b) {
182         cacheValid = b;
183     }
184
185     protected void ensureValidCache(Graphics2D JavaDoc g2) {
186         if (!isCacheValid())
187             validateCache(g2);
188     }
189
190     /**
191      * Validates the cache, here: creates a <code>GlyphVector</code>
192      * and computes and stores its size information.
193      *
194      * @param g2 the Graphics object used to get the font render context
195      */

196     protected void validateCache(Graphics2D JavaDoc g2) {
197         FontRenderContext JavaDoc frc = g2.getFontRenderContext();
198
199         ensureCapitalMAscentComputed(frc);
200
201         cachedGlyphVector = font.createGlyphVector(frc, text);
202         Rectangle2D JavaDoc bounds = cachedGlyphVector.getVisualBounds();
203         cachedTextWidth = (float) bounds.getWidth();
204         cachedTextAscent = (float) - bounds.getY();
205         cachedTextHeight = (float) bounds.getHeight();
206
207         int glyphCount = cachedGlyphVector.getNumGlyphs();
208         cachedGlyphShapes = new Shape JavaDoc[glyphCount];
209         for (int i = 0; i < glyphCount; i++) {
210             cachedGlyphShapes[i] = cachedGlyphVector.getGlyphOutline(i);
211         }
212         setCacheValid(true);
213
214         /* Debug lines
215         System.out.println("Text = " + text);
216         System.out.println("GV visual bounds = " + glyphVector.getVisualBounds());
217         */

218     }
219
220     /**
221      * Ensures that the ascent of a capital M has been computed.
222      *
223      * @param frc the font render context used to create the glyph vector
224      */

225     private void ensureCapitalMAscentComputed(FontRenderContext JavaDoc frc) {
226         if (capitalMAscent > 0)
227             return;
228         GlyphVector JavaDoc mGlyphVector = font.createGlyphVector(frc, "M");
229         capitalMAscent = (float) - mGlyphVector.getVisualBounds().getY();
230     }
231
232     /**
233      * Invalidates the cache.
234      */

235     protected void invalidateCache() {
236         setCacheValid(false);
237         cachedGlyphVector = null;
238         cachedGlyphShapes = null;
239     }
240
241 }
Popular Tags