Source code: com/anotherbigidea/flash/movie/Text.java
1 /****************************************************************
2 * Copyright (c) 2001, David N. Main, All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the
6 * following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 *
17 * 3. The name of the author may not be used to endorse or
18 * promote products derived from this software without specific
19 * prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ****************************************************************/
34 package com.anotherbigidea.flash.movie;
35
36 import java.io.*;
37 import java.util.*;
38 import com.anotherbigidea.flash.interfaces.*;
39 import com.anotherbigidea.flash.writers.*;
40 import com.anotherbigidea.flash.readers.*;
41 import com.anotherbigidea.flash.structs.*;
42 import com.anotherbigidea.flash.SWFConstants;
43
44 /**
45 * A Text Symbol.
46 */
47 public class Text extends Symbol
48 {
49 /**
50 * A set of contiguous characters in one font, size and color.
51 */
52 public static class Row
53 {
54 protected Font.Chars chars;
55 protected double x;
56 protected double y;
57 protected boolean hasX;
58 protected boolean hasY;
59 protected Color color;
60
61 public Font.Chars getChars() { return chars; }
62 public double getX() { return x; }
63 public double getY() { return y; }
64 public Color getColor() { return color; }
65 public boolean hasX() { return hasX; }
66 public boolean hasY() { return hasY; }
67
68 /**
69 * @param chars the characters to display
70 * @param color may be AlphaColor.
71 * @param x new X position for text - only valid if hasX is true
72 * @param y new Y position for text - only valid if hasY is true
73 */
74 public Row( Font.Chars chars, Color color, double x, double y, boolean hasX, boolean hasY )
75 {
76 this.chars = chars;
77 this.color = color;
78 this.x = x;
79 this.y = y;
80 this.hasX = hasX;
81 this.hasY = hasY;
82 }
83
84 protected void write( SWFText text, boolean changeColor, boolean changeFont )
85 throws IOException
86 {
87 if( changeFont )
88 {
89 Font font = chars.getFont();
90 int fontid = font.getId();
91
92 text.font( fontid, (int)(chars.getSize() * SWFConstants.TWIPS) );
93 }
94
95 if( changeColor ) text.color( color );
96 if( hasX ) text.setX( (int)(x * SWFConstants.TWIPS));
97 if( hasY ) text.setY( (int)(y * SWFConstants.TWIPS));
98
99 text.text( chars.indices, chars.advances );
100 }
101 }
102
103 protected boolean hasAlpha;
104 protected Transform matrix;
105 protected ArrayList rows = new ArrayList();
106
107 /**
108 * Create a Text Symbol which is transformed by the given matrix
109 * @param matrix if null then an identity transform is assumed
110 */
111 public Text( Transform matrix )
112 {
113 if( matrix == null ) matrix = new Transform();
114 this.matrix = matrix;
115 }
116
117 /**
118 * Access the list of Row instances.
119 */
120 public ArrayList getRows() { return rows; }
121
122 /**
123 * Get the transformation matrix applied to the text
124 */
125 public Transform getTransform() { return matrix; }
126
127 public void setTransform( Transform matrix ) { this.matrix = matrix; }
128
129 /**
130 * Add a contiguous set of characters that have the same font, size, color
131 * and vertical position.
132 *
133 * @param chars the characters to display)
134 * @param may be AlphaColor.
135 * @param x new X position for text - only valid if hasX is true
136 * @param y new Y position for text - only valid if hasY is true
137 *
138 * @return the new X position after writing the chars
139 */
140 public Row row( Font.Chars chars, Color color,
141 double x, double y, boolean hasX, boolean hasY )
142 {
143 Row row = new Row( chars, color, x, y, hasX, hasY );
144
145 rows.add( row );
146
147 return row;
148 }
149
150 protected int defineSymbol( Movie movie,
151 SWFTagTypes timelineWriter,
152 SWFTagTypes definitionWriter )
153 throws IOException
154 {
155 Font currentFont = null;
156 double currentSize = 0.0;
157 Color currentColor = null;
158 boolean hasAlpha = false;
159 double currentX = 0.0;
160 double currentY = 0.0;
161 double minX = 0.0;
162 double minY = 0.0;
163 double maxX = 0.0;
164 double maxY = 0.0;
165
166 //--make sure that all fonts are defined and figure out the alpha
167 for( Iterator it = rows.iterator(); it.hasNext(); )
168 {
169 Object obj = it.next();
170
171 if( obj instanceof Text.Row )
172 {
173 Text.Row row = (Text.Row)obj;
174
175 if( row.color != null
176 && (row.color instanceof AlphaColor) ) hasAlpha = true;
177
178 Font font = row.chars.getFont();
179 double size = row.chars.getSize();
180
181 if( currentFont == null || font != currentFont )
182 {
183 font.define( true, movie, definitionWriter );
184 }
185
186 currentFont = font;
187
188 if( row.hasX ) currentX = row.x;
189 if( row.hasY ) currentY = row.y;
190
191 double leftEdge = currentX - row.chars.getLeftMargin();
192 double rightEdge = currentX + row.chars.getTotalAdvance()
193 + row.chars.getRightMargin();
194 double topEdge = currentY - row.chars.getAscent();
195 double bottomEdge = currentY + row.chars.getDescent();
196
197 if( leftEdge < minX ) minX = leftEdge;
198 if( rightEdge > maxX ) maxX = rightEdge;
199 if( topEdge < minY ) minY = topEdge;
200 if( bottomEdge > maxY ) maxY = bottomEdge;
201
202 currentX += row.chars.getTotalAdvance();
203 }
204 }
205
206 int id = getNextId( movie );
207 Rect bounds = new Rect( (int)(minX * SWFConstants.TWIPS),
208 (int)(minY * SWFConstants.TWIPS),
209 (int)(maxX * SWFConstants.TWIPS),
210 (int)(maxY * SWFConstants.TWIPS));
211
212 SWFText text = hasAlpha ?
213 definitionWriter.tagDefineText2( id, bounds, matrix ) :
214 definitionWriter.tagDefineText( id, bounds, matrix );
215
216 currentFont = null;
217 currentSize = 0.0;
218 currentColor = null;
219
220 for( Iterator it = rows.iterator(); it.hasNext(); )
221 {
222 Object obj = it.next();
223
224 if( obj instanceof Text.Row )
225 {
226 Text.Row row = (Text.Row)obj;
227
228 Font font = row.chars.getFont();
229 double size = row.chars.getSize();
230 Color color = row.color;
231
232 boolean changeFont = currentFont == null ||
233 font != currentFont ||
234 size != currentSize;
235
236 boolean changeColor = currentColor == null ||
237 ( color!=null && !color.equals( currentColor) );
238
239 row.write( text, changeColor, changeFont );
240
241 if( color != null ) currentColor = color;
242 }
243 }
244
245 text.done();
246
247 return id;
248 }
249 }