Source code: com/anotherbigidea/flash/movie/FontLoader.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 * Font loading utilities
46 */
47 public class FontLoader extends SWFTagTypesImpl
48 {
49 protected FontDefinition fontDef;
50
51 public FontLoader()
52 {
53 super( null );
54 }
55
56 /**
57 * Load the first font from the given Flash movie
58 *
59 * @return null if no font was found
60 */
61 public static FontDefinition loadFont( String filename )
62 throws IOException
63 {
64 FileInputStream in = new FileInputStream( filename );
65
66 FontDefinition def = loadFont(in);
67
68 in.close();
69
70 return def;
71 }
72
73 /**
74 * Load the first font from the given Flash movie
75 *
76 * @return null if no font was found
77 */
78 public static FontDefinition loadFont( InputStream flashMovie )
79 throws IOException
80 {
81 FontLoader fontloader = new FontLoader();
82 SWFTags swfparser = new TagParser( fontloader );
83 SWFReader swfreader = new SWFReader( swfparser, flashMovie );
84
85 swfreader.readFile();
86
87 return fontloader.fontDef;
88 }
89
90 /**
91 * SWFTagTypes Interface
92 */
93 public SWFVectors tagDefineFont2( int id, int flags, String name, int numGlyphs,
94 int ascent, int descent, int leading,
95 int[] codes, int[] advances, Rect[] bounds,
96 int[] kernCodes1, int[] kernCodes2,
97 int[] kernAdjustments ) throws IOException
98 {
99 if( fontDef != null ) return null; //only load first font
100
101 double twips = (double)SWFConstants.TWIPS;
102
103 fontDef = new FontDefinition( name,
104 ((double)ascent)/twips,
105 ((double)descent)/twips,
106 ((double)leading)/twips,
107 (flags & SWFConstants.FONT2_UNICODE ) != 0,
108 (flags & SWFConstants.FONT2_SHIFTJIS ) != 0,
109 (flags & SWFConstants.FONT2_ANSI ) != 0,
110 (flags & SWFConstants.FONT2_ITALIC ) != 0,
111 (flags & SWFConstants.FONT2_BOLD ) != 0,
112 (flags & SWFConstants.FONT2_HAS_LAYOUT) != 0 );
113
114 if( kernCodes1 != null && kernCodes1.length > 0 )
115 {
116 //System.out.println( "Number of Kernings --> " + kernCodes1.length );
117
118 ArrayList kerns = fontDef.getKerningPairList();
119
120 for( int i = 0; i < kernCodes1.length; i++ )
121 {
122 FontDefinition.KerningPair pair =
123 new FontDefinition.KerningPair(
124 kernCodes1[i],
125 kernCodes2[i],
126 ((double)kernAdjustments[i])/twips );
127
128 kerns.add( pair );
129 }
130 }
131
132 return new VectorImpl( codes, advances, bounds );
133 }
134
135 protected class VectorImpl implements SWFVectors
136 {
137 protected int[] codes;
138 protected int[] advances;
139 protected Rect[] bounds;
140 protected int i;
141 protected Shape shape;
142 protected int currx;
143 protected int curry;
144 protected double twips = (double)SWFConstants.TWIPS;
145
146 protected VectorImpl( int[] codes, int[] advances, Rect[] bounds )
147 {
148 this.codes = codes;
149 this.advances = advances;
150 this.bounds = bounds;
151 i = 0;
152
153 shape = new Shape();
154 }
155
156 public void done()
157 {
158 //System.out.println( "------------" );
159 double advance = (advances == null) ? 0.0 : ((double)advances[i])/twips;
160 int code = codes[i];
161
162 Rect rect = bounds[i];
163 shape.minX = ((double)rect.getMinX())/twips;
164 shape.minY = ((double)rect.getMinY())/twips;
165 shape.maxX = ((double)rect.getMaxX())/twips;
166 shape.maxY = ((double)rect.getMaxY())/twips;
167
168 FontDefinition.Glyph g = new FontDefinition.Glyph( shape, advance, code );
169
170 fontDef.getGlyphList().add( g );
171
172 i++;
173
174 if( i < codes.length ) shape = new Shape();
175
176 currx = curry = 0;
177 }
178
179 public void line( int dx, int dy )
180 {
181 currx += dx;
182 curry += dy;
183
184 shape.line( currx/twips, curry/twips );
185
186 //System.out.println( "L: " + dx + " " + dy + " " + currx + " " + curry );
187 }
188
189 public void curve( int cx, int cy, int dx, int dy )
190 {
191 cx += currx;
192 cy += curry;
193 dx += cx;
194 dy += cy;
195
196 currx = dx;
197 curry = dy;
198
199 shape.curve( dx/twips, dy/twips, cx/twips, cy/twips );
200
201 //System.out.println( "C: " + cx + " " + cy + " " + dx + " " + dy +
202 // " " + (cx/twips) + " " + (cy/twips) +
203 // " " + (dx/twips) + " " + (dy/twips) );
204
205 }
206
207 public void move( int x, int y )
208 {
209 currx = x;
210 curry = y;
211
212 shape.move( x/twips, y/twips );
213
214 //System.out.println( "M: " + x + " " + y + " " + (x/twips) + " " + (y/twips) );
215 }
216 }
217 }