Source code: com/anotherbigidea/flash/movie/FontDefinition.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 Font Definition that can referenced by Font symbols.
46 * If read in from an existing Flash movie the font definition may only contain
47 * a subset of the glyphs in the font.
48 *
49 * To use a system font set the hasMetrics flag to false.
50 */
51 public class FontDefinition
52 {
53 /**
54 * A Glyph within the font.
55 */
56 public static class Glyph
57 {
58 protected int code;
59 protected double advance;
60 protected Shape shape;
61
62 public Shape getShape() { return shape; }
63 public int getCode() { return code; }
64 public double getAdvance() { return advance; }
65
66 public void setShape( Shape shape ) { this.shape = shape; }
67 public void setCode( int code ) { this.code = code; }
68 public void setAdvance( double advance ) { this.advance = advance; }
69
70 public Glyph( Shape shape, double advance, int code )
71 {
72 this.shape = shape;
73 this.advance = advance;
74 this.code = code;
75 }
76 }
77
78 /**
79 * A Kerning Pair is an adjustment to the advance between two particular glyphs.
80 */
81 public static class KerningPair
82 {
83 protected int code1, code2;
84 protected double adjustment;
85
86 public int getCode1() { return code1; }
87 public int getCode2() { return code2; }
88 public double getAdjustment() { return adjustment; }
89
90 public void setCode1( int code ) { code1 = code; }
91 public void setCode2( int code ) { code2 = code; }
92 public void setAdjustment( double offset ) { adjustment = offset; }
93
94 public KerningPair( int code1, int code2, double adjustment )
95 {
96 this.code1 = code1;
97 this.code2 = code2;
98 this.adjustment = adjustment;
99 }
100 }
101
102 protected String name;
103 protected double ascent;
104 protected double descent;
105 protected double leading;
106
107 protected boolean isUnicode;
108 protected boolean isShiftJIS;
109 protected boolean isAnsi;
110 protected boolean isItalic;
111 protected boolean isBold;
112 protected boolean hasMetrics;
113
114 protected ArrayList glyphs = new ArrayList();
115 protected ArrayList kerning = new ArrayList();
116
117 protected HashMap glyphLookup;
118 protected HashMap kernLookup;
119
120 public String getName() { return name; }
121 public double getAscent() { return ascent; }
122 public double getDescent() { return descent; }
123 public double getLeading() { return leading; }
124
125 public boolean isUnicode() { return isUnicode; }
126 public boolean isShiftJIS() { return isShiftJIS; }
127 public boolean isAnsi() { return isAnsi; }
128 public boolean isItalic() { return isItalic; }
129 public boolean isBold() { return isBold; }
130 public boolean hasMetrics() { return hasMetrics; }
131
132 /**
133 * Get the List of Glyph objects
134 */
135 public ArrayList getGlyphList() { return glyphs; }
136
137 /**
138 * Get the List of KerningPair objects
139 */
140 public ArrayList getKerningPairList() { return kerning; }
141
142 public void setName( String name ) { this.name = name; }
143 public void setAscent ( double ascent ) { this.ascent = ascent; }
144 public void setDescent( double descent ) { this.descent = descent; }
145 public void setLeading( double leading ) { this.leading = leading; }
146
147 public void setFontFlags( boolean isUnicode, boolean isShiftJIS, boolean isAnsi,
148 boolean isItalic, boolean isBold, boolean hasMetrics )
149 {
150 this.isUnicode = isUnicode;
151 this.isShiftJIS = isShiftJIS;
152 this.isAnsi = isAnsi;
153 this.isItalic = isItalic;
154 this.isBold = isBold;
155 this.hasMetrics = hasMetrics;
156 }
157
158 public FontDefinition(){}
159
160 public FontDefinition( String name, double ascent, double descent, double leading,
161 boolean isUnicode, boolean isShiftJIS, boolean isAnsi,
162 boolean isItalic, boolean isBold, boolean hasMetrics )
163 {
164 this.name = name;
165 this.ascent = ascent;
166 this.descent = descent;
167 this.leading = leading;
168
169 this.isUnicode = isUnicode;
170 this.isShiftJIS = isShiftJIS;
171 this.isAnsi = isAnsi;
172 this.isItalic = isItalic;
173 this.isBold = isBold;
174 this.hasMetrics = hasMetrics;
175 }
176
177 /**
178 * Look up a glyph by code
179 * @return null if the code has no glyph
180 */
181 public Glyph getGlyph( int code )
182 {
183 if( glyphLookup == null )
184 {
185 glyphLookup = new HashMap();
186
187 for( Iterator it = glyphs.iterator(); it.hasNext(); )
188 {
189 Glyph g = (Glyph)it.next();
190
191 glyphLookup.put( new Integer( g.code ), g );
192 }
193 }
194
195 Glyph g = (Glyph)glyphLookup.get( new Integer( code ) );
196
197 return g;
198 }
199
200 /**
201 * Get the kerning adjustment required between the two given codes
202 */
203 public double getKerningOffset( int code1, int code2 )
204 {
205 if( kernLookup == null )
206 {
207 kernLookup = new HashMap();
208
209 for( Iterator it = kerning.iterator(); it.hasNext(); )
210 {
211 KerningPair pair = (KerningPair)it.next();
212 Integer i1 = new Integer( pair.code1 );
213 Integer i2 = new Integer( pair.code2 );
214
215 HashMap kerns = (HashMap)kernLookup.get( i1 );
216
217 if( kerns == null )
218 {
219 kerns = new HashMap();
220 kernLookup.put( i1, kerns );
221 }
222
223 kerns.put( i2, pair );
224 }
225 }
226
227 Integer i1 = new Integer( code1 );
228 Integer i2 = new Integer( code2 );
229
230 HashMap kerns = (HashMap)kernLookup.get( i1 );
231 if( kerns == null ) return 0.0;
232
233 KerningPair pair = (KerningPair)kerns.get( i2 );
234 if( pair == null ) return 0.0;
235
236 return pair.adjustment;
237 }
238 }