1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.gnu.jfiglet.core;
22
23 /***
24 * Layout of a FIGFont.
25 *
26 * @version $Id: FIGFontLayout.java,v 1.3 2004/04/27 20:09:28 sbrunot Exp $
27 *
28 * @author <a href="mailto:sebastien.brunot@club-internet.fr">
29 * Sebastien Brunot</a>
30 *
31 */
32 public class FIGFontLayout
33 {
34
35
36
37
38 /***
39 * Horizontal layout mode "Full size".
40 * Represents each FIGcharacter occupying the full width of its arrangement
41 * of sub-characters as designed.
42 */
43 public static final int HORIZONTAL_LAYOUT_MODE_FULL_SIZE = 0;
44
45 /***
46 * Horizontal layout mode "Fitting only".
47 * Moves FIGcharacters closer together until they touch.
48 * Typographers use the term "kerning" for this phenomenon
49 * when applied to the horizontal axis, but fitting also
50 * includes this as a vertical behavior, for which there is
51 * apparently no established typographical term.
52 */
53 public static final int HORIZONTAL_LAYOUT_MODE_FITTING_ONLY = 1;
54
55 /***
56 * Horizontal layout mode "smushing"
57 * Moves FIGcharacters one step closer after they touch, so that
58 * they partially occupy the same space. A FIGdriver must decide
59 * what sub-character to display at each junction. There are two
60 * ways of making these decisions: by controlled smushing or by
61 * universal smushing.
62 *
63 * Controlled smushing uses a set of "smushing rules" selected by
64 * the designer of a FIGfont.
65 * Each rule is a comparison of the two sub-characters which must
66 * be joined to yield what to display at the junction.
67 * Controlled smushing will not always allow smushing to occur,
68 * because the compared sub-characters may not correspond to any
69 * active rule. Wherever smushing cannot occur, fitting occurs
70 * instead.
71 *
72 * Universal smushing simply overrides the sub-character from the
73 * earlier FIGcharacter with the sub-character from the later
74 * FIGcharacter. This produces an "overlapping" effect with some
75 * FIGfonts, wherin the latter FIGcharacter may appear to be "in
76 * front".
77 *
78 * A FIGfont which does not specify any smushing rules for a
79 * particular axis indicates that universal smushing is to occur
80 * when smushing is requested. Therefore, it is not possible for
81 * a FIGfont designer to "forbid" smushing. However there are
82 * ways to ensure that smushing does not cause a FIGfont to be
83 * illegible when smushed. This is especially important for
84 * smaller FIGfonts.
85 */
86 public static final int HORIZONTAL_LAYOUT_MODE_SMUSHING = 2;
87
88 /***
89 * Vertical layout modes
90 */
91 public static final int VERTICAL_LAYOUT_MODE_FULL_SIZE = 3;
92 public static final int VERTICAL_LAYOUT_MODE_FITTING_ONLY = 4;
93 public static final int VERTICAL_LAYOUT_MODE_SMUSHING = 5;
94
95 private static final int OLD_LAYOUT_FULL_WIDTH = -1;
96 private static final int OLD_LAYOUT_HORIZONTAL_FITTING = 0;
97
98 private static final int FULL_LAYOUT_HORIZONTAL_FITTING = 64;
99 private static final int FULL_LAYOUT_HORIZONTAL_SMUSHING = 128;
100 private static final int FULL_LAYOUT_VERTICAL_FITTING = 8192;
101 private static final int FULL_LAYOUT_VERTICAL_SMUSHING = 16384;
102
103 /***
104 * Smushing rules
105 */
106 private static final int SMUSHING_RULE_UNIVERSAL = 0;
107 public static final int HORIZONTAL_SMUSHING_RULE_EQUALS_CHARACTER = 1;
108 public static final int HORIZONTAL_SMUSHING_RULE_UNDERSCORE = 2;
109 public static final int HORIZONTAL_SMUSHING_RULE_HIERARCHY = 4;
110 public static final int HORIZONTAL_SMUSHING_RULE_OPPOSITE_PAIR = 8;
111 public static final int HORIZONTAL_SMUSHING_RULE_BIG_X = 16;
112 public static final int HORIZONTAL_SMUSHING_RULE_HARDBLANK = 32;
113 public static final int VERTICAL_SMUSHING_RULE_EQUALS_CHARACTER = 256;
114 public static final int VERTICAL_SMUSHING_RULE_UNDERSCORE = 512;
115 public static final int VERTICAL_SMUSHING_RULE_HIERARCHY = 1024;
116 public static final int VERTICAL_SMUSHING_RULE_HORIZONTAL_LINE = 2048;
117 public static final int VERTICAL_SMUSHING_RULE_VERTICAL_LINE = 4096;
118
119
120
121
122
123 private int horizontalMode = HORIZONTAL_LAYOUT_MODE_FITTING_ONLY;
124 private int verticalMode = VERTICAL_LAYOUT_MODE_FULL_SIZE;
125 private int horizontalSmushingModes = SMUSHING_RULE_UNIVERSAL;
126 private int verticalSmushingModes = SMUSHING_RULE_UNIVERSAL;
127
128
129
130
131
132 /***
133 * @TODO : DOCUMENT ME !
134 */
135 public FIGFontLayout(
136 int theOldLayoutSpecification,
137 Integer theFullLayoutSpecification)
138 {
139
140 if ((theOldLayoutSpecification < -1)
141 || (theOldLayoutSpecification > 63))
142 {
143 throw new IllegalArgumentException("the old layout specification must be an integer between -1 and 63 included");
144 }
145
146
147 if (theFullLayoutSpecification != null)
148 {
149
150 if ((theFullLayoutSpecification.intValue() < 0)
151 || (theFullLayoutSpecification.intValue() > 32767))
152 {
153 throw new IllegalArgumentException("the full layout specification must be an integer between 0 and 32767 included");
154 }
155 }
156
157 if (theOldLayoutSpecification == OLD_LAYOUT_FULL_WIDTH)
158 {
159
160 this.horizontalMode = HORIZONTAL_LAYOUT_MODE_FULL_SIZE;
161
162
163
164 if (theFullLayoutSpecification != null)
165 {
166 if (((theFullLayoutSpecification.intValue()
167 & FULL_LAYOUT_HORIZONTAL_FITTING)
168 == FULL_LAYOUT_HORIZONTAL_FITTING)
169 || ((theFullLayoutSpecification.intValue()
170 & FULL_LAYOUT_HORIZONTAL_SMUSHING)
171 == FULL_LAYOUT_HORIZONTAL_SMUSHING))
172 {
173 throw new IllegalArgumentException("Old and full layout specifications are unconsistent");
174 }
175 }
176 }
177 else if (
178 theOldLayoutSpecification == OLD_LAYOUT_HORIZONTAL_FITTING)
179 {
180
181
182
183
184
185
186
187
188
189 if (theFullLayoutSpecification != null)
190 {
191 if (((theFullLayoutSpecification.intValue()
192 & FULL_LAYOUT_HORIZONTAL_FITTING)
193 == FULL_LAYOUT_HORIZONTAL_FITTING)
194 && ((theFullLayoutSpecification.intValue()
195 & FULL_LAYOUT_HORIZONTAL_SMUSHING)
196 == 0))
197 {
198
199 this.horizontalMode =
200 HORIZONTAL_LAYOUT_MODE_FITTING_ONLY;
201 }
202 else if (
203 ((theFullLayoutSpecification.intValue()
204 & FULL_LAYOUT_HORIZONTAL_FITTING)
205 == 0)
206 && ((theFullLayoutSpecification.intValue()
207 & FULL_LAYOUT_HORIZONTAL_SMUSHING)
208 == FULL_LAYOUT_HORIZONTAL_SMUSHING))
209 {
210
211 this.horizontalMode = HORIZONTAL_LAYOUT_MODE_SMUSHING;
212 }
213 else
214 {
215 throw new IllegalArgumentException("The old and full layout specifications are unconsistent");
216 }
217 }
218 else
219 {
220
221 this.horizontalMode = HORIZONTAL_LAYOUT_MODE_FITTING_ONLY;
222 }
223 }
224 else
225 {
226
227 this.horizontalMode = HORIZONTAL_LAYOUT_MODE_SMUSHING;
228 this.horizontalSmushingModes = theOldLayoutSpecification;
229
230 }
231
232 if (theFullLayoutSpecification != null)
233 {
234 if ((theFullLayoutSpecification.intValue()
235 & FULL_LAYOUT_VERTICAL_FITTING)
236 == FULL_LAYOUT_VERTICAL_FITTING)
237 {
238
239 this.verticalMode = VERTICAL_LAYOUT_MODE_FITTING_ONLY;
240 }
241 else if (
242 (theFullLayoutSpecification.intValue()
243 & FULL_LAYOUT_VERTICAL_SMUSHING)
244 == FULL_LAYOUT_VERTICAL_SMUSHING)
245 {
246
247 this.verticalMode = VERTICAL_LAYOUT_MODE_SMUSHING;
248 this.verticalSmushingModes =
249 theFullLayoutSpecification.intValue();
250 }
251 }
252 }
253
254
255
256
257
258 /***
259 * @TODO : DOCUMENT ME !
260 */
261 public int getHorizontalMode()
262 {
263 return this.horizontalMode;
264 }
265
266 /***
267 * @TODO : DOCUMENT ME !
268 */
269 public int getVerticalMode()
270 {
271 return this.verticalMode;
272 }
273
274 /***
275 * @TODO : DOCUMENT ME !
276 */
277 public boolean hasHorizontalSmushingRule(int theSmushingRule)
278 {
279 return (
280 (this.horizontalSmushingModes & theSmushingRule)
281 == theSmushingRule);
282 }
283
284 /***
285 * @TODO : DOCUMENT ME !
286 */
287 public boolean hasVerticalSmushingRule(int theSmushingRule)
288 {
289 return (
290 (this.verticalSmushingModes & theSmushingRule)
291 == theSmushingRule);
292 }
293
294 }