KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > parser > UnitProcessor


1 /*
2
3    Copyright 1999-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17 */

18
19 package org.apache.batik.parser;
20
21 import org.w3c.dom.Element JavaDoc;
22 import org.w3c.dom.svg.SVGLength;
23
24 /**
25  * This class provides methods to convert SVG length and coordinate to
26  * float in user units.
27  *
28  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
29  * @author <a HREF="mailto:tkormann@apache.org">Thierry Kormann</a>
30  * @version $Id: UnitProcessor.java,v 1.5 2005/03/27 08:58:35 cam Exp $
31  */

32 public abstract class UnitProcessor {
33
34     /**
35      * This constant represents horizontal lengths.
36      */

37     public final static short HORIZONTAL_LENGTH = 2;
38
39     /**
40      * This constant represents vertical lengths.
41      */

42     public final static short VERTICAL_LENGTH = 1;
43
44     /**
45      * This constant represents other lengths.
46      */

47     public final static short OTHER_LENGTH = 0;
48
49     /**
50      * No instance of this class is required.
51      */

52     protected UnitProcessor() { }
53
54
55     /**
56      * Returns the specified value with the specified direction in
57      * objectBoundingBox units.
58      *
59      * @param s the value
60      * @param attr the attribute name that represents the value
61      * @param d the direction of the value
62      * @param ctx the context used to resolve relative value
63      */

64     public static float svgToObjectBoundingBox(String JavaDoc s,
65                                                String JavaDoc attr,
66                                                short d,
67                                                Context ctx)
68         throws ParseException {
69         LengthParser lengthParser = new LengthParser();
70         UnitResolver ur = new UnitResolver();
71         lengthParser.setLengthHandler(ur);
72         lengthParser.parse(s);
73         return svgToObjectBoundingBox(ur.value, ur.unit, d, ctx);
74     }
75
76     /**
77      * Returns the specified value with the specified direction in
78      * objectBoundingBox units.
79      *
80      * @param value the value
81      * @param type the type of the value
82      * @param d the direction of the value
83      * @param ctx the context used to resolve relative value
84      */

85     public static float svgToObjectBoundingBox(float value,
86                                                short type,
87                                                short d,
88                                                Context ctx) {
89         switch (type) {
90         case SVGLength.SVG_LENGTHTYPE_NUMBER:
91             // as is
92
return value;
93         case SVGLength.SVG_LENGTHTYPE_PERCENTAGE:
94             // If a percentage value is used, it is converted to a
95
// 'bounding box' space coordinate by division by 100
96
return value / 100f;
97         case SVGLength.SVG_LENGTHTYPE_PX:
98         case SVGLength.SVG_LENGTHTYPE_MM:
99         case SVGLength.SVG_LENGTHTYPE_CM:
100         case SVGLength.SVG_LENGTHTYPE_IN:
101         case SVGLength.SVG_LENGTHTYPE_PT:
102         case SVGLength.SVG_LENGTHTYPE_PC:
103         case SVGLength.SVG_LENGTHTYPE_EMS:
104         case SVGLength.SVG_LENGTHTYPE_EXS:
105             // <!> FIXME: resolve units in userSpace but consider them
106
// in the objectBoundingBox coordinate system
107
return svgToUserSpace(value, type, d, ctx);
108         default:
109             throw new Error JavaDoc(); // can't be reached
110
}
111     }
112
113     /////////////////////////////////////////////////////////////////////////
114
// SVG methods - userSpace
115
/////////////////////////////////////////////////////////////////////////
116

117
118     /**
119      * Returns the specified coordinate with the specified direction
120      * in user units.
121      *
122      * @param s the 'other' coordinate
123      * @param attr the attribute name that represents the length
124      * @param d the direction of the coordinate
125      * @param ctx the context used to resolve relative value
126      */

127     public static float svgToUserSpace(String JavaDoc s,
128                                        String JavaDoc attr,
129                                        short d,
130                                        Context ctx) throws ParseException {
131         LengthParser lengthParser = new LengthParser();
132         UnitResolver ur = new UnitResolver();
133         lengthParser.setLengthHandler(ur);
134         lengthParser.parse(s);
135         return svgToUserSpace(ur.value, ur.unit, d, ctx);
136     }
137
138     /**
139      * Converts the specified value of the specified type and
140      * direction to user units.
141      *
142      * @param v the value to convert
143      * @param type the type of the value
144      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
145      * @param ctx the context used to resolve relative value
146      */

147     public static float svgToUserSpace(float v,
148                                        short type,
149                                        short d,
150                                        Context ctx) {
151         switch (type) {
152         case SVGLength.SVG_LENGTHTYPE_NUMBER:
153         case SVGLength.SVG_LENGTHTYPE_PX:
154             return v;
155         case SVGLength.SVG_LENGTHTYPE_MM:
156             return (v / ctx.getPixelUnitToMillimeter());
157         case SVGLength.SVG_LENGTHTYPE_CM:
158             return (v * 10f / ctx.getPixelUnitToMillimeter());
159         case SVGLength.SVG_LENGTHTYPE_IN:
160             return (v * 25.4f / ctx.getPixelUnitToMillimeter());
161         case SVGLength.SVG_LENGTHTYPE_PT:
162             return (v * 25.4f / (72f * ctx.getPixelUnitToMillimeter()));
163         case SVGLength.SVG_LENGTHTYPE_PC:
164             return (v * 25.4f / (6f * ctx.getPixelUnitToMillimeter()));
165         case SVGLength.SVG_LENGTHTYPE_EMS:
166             return emsToPixels(v, d, ctx);
167         case SVGLength.SVG_LENGTHTYPE_EXS:
168             return exsToPixels(v, d, ctx);
169         case SVGLength.SVG_LENGTHTYPE_PERCENTAGE:
170             return percentagesToPixels(v, d, ctx);
171         default:
172             throw new Error JavaDoc(); // can't be reached
173
}
174     }
175
176     /**
177      * Converts the specified value of the specified type and
178      * direction to SVG units.
179      *
180      * @param v the value to convert
181      * @param type the type of the value
182      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
183      * @param ctx the context used to resolve relative value
184      */

185     public static float userSpaceToSVG(float v,
186                                        short type,
187                                        short d,
188                                        Context ctx) {
189         switch (type) {
190         case SVGLength.SVG_LENGTHTYPE_NUMBER:
191         case SVGLength.SVG_LENGTHTYPE_PX:
192             return v;
193         case SVGLength.SVG_LENGTHTYPE_MM:
194             return (v * ctx.getPixelUnitToMillimeter());
195         case SVGLength.SVG_LENGTHTYPE_CM:
196             return (v * ctx.getPixelUnitToMillimeter() / 10f);
197         case SVGLength.SVG_LENGTHTYPE_IN:
198             return (v * ctx.getPixelUnitToMillimeter() / 25.4f);
199         case SVGLength.SVG_LENGTHTYPE_PT:
200             return (v * (72f * ctx.getPixelUnitToMillimeter()) / 25.4f);
201         case SVGLength.SVG_LENGTHTYPE_PC:
202             return (v * (6f * ctx.getPixelUnitToMillimeter()) / 25.4f);
203         case SVGLength.SVG_LENGTHTYPE_EMS:
204             return pixelsToEms(v, d, ctx);
205         case SVGLength.SVG_LENGTHTYPE_EXS:
206             return pixelsToExs(v, d, ctx);
207         case SVGLength.SVG_LENGTHTYPE_PERCENTAGE:
208             return pixelsToPercentages(v, d, ctx);
209         default:
210             throw new Error JavaDoc(); // can't be reached
211
}
212     }
213
214     /////////////////////////////////////////////////////////////////////////
215
// Utilities methods for relative length
216
/////////////////////////////////////////////////////////////////////////
217

218     /**
219      * Converts percentages to user units.
220      *
221      * @param v the percentage to convert
222      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
223      * @param ctx the context
224      */

225     protected static float percentagesToPixels(float v, short d, Context ctx) {
226         if (d == HORIZONTAL_LENGTH) {
227             float w = ctx.getViewportWidth();
228             return w * v / 100f;
229         } else if (d == VERTICAL_LENGTH) {
230             float h = ctx.getViewportHeight();
231             return h * v / 100f;
232         } else {
233             double w = ctx.getViewportWidth();
234             double h = ctx.getViewportHeight();
235             double vpp = Math.sqrt(w * w + h * h) / Math.sqrt(2);
236             return (float)(vpp * v / 100d);
237         }
238     }
239
240     /**
241      * Converts user units to percentages relative to the viewport.
242      *
243      * @param v the value to convert
244      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
245      * @param ctx the context
246      */

247     protected static float pixelsToPercentages(float v, short d, Context ctx) {
248         if (d == HORIZONTAL_LENGTH) {
249             float w = ctx.getViewportWidth();
250             return v * 100f / w;
251         } else if (d == VERTICAL_LENGTH) {
252             float h = ctx.getViewportHeight();
253             return v * 100f / h;
254         } else {
255             double w = ctx.getViewportWidth();
256             double h = ctx.getViewportHeight();
257             double vpp = Math.sqrt(w * w + h * h) / Math.sqrt(2);
258             return (float)(v * 100d / vpp);
259         }
260     }
261
262     /**
263      * Converts user units to ems units.
264      *
265      * @param v the value to convert
266      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
267      * @param ctx the context
268      */

269     protected static float pixelsToEms(float v, short d, Context ctx) {
270         return v / ctx.getFontSize();
271     }
272
273     /**
274      * Converts ems units to user units.
275      *
276      * @param v the value to convert
277      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
278      * @param ctx the context
279      */

280     protected static float emsToPixels(float v, short d, Context ctx) {
281         return v * ctx.getFontSize();
282     }
283
284     /**
285      * Converts user units to exs units.
286      *
287      * @param v the value to convert
288      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
289      * @param ctx the context
290      */

291     protected static float pixelsToExs(float v, short d, Context ctx) {
292         float xh = ctx.getXHeight();
293         return v / xh / ctx.getFontSize();
294     }
295
296     /**
297      * Converts exs units to user units.
298      *
299      * @param v the value to convert
300      * @param d HORIZONTAL_LENGTH, VERTICAL_LENGTH, or OTHER_LENGTH
301      * @param ctx the context
302      */

303     protected static float exsToPixels(float v, short d, Context ctx) {
304         float xh = ctx.getXHeight();
305         return v * xh * ctx.getFontSize();
306     }
307
308
309     /**
310      * A LengthHandler that convert units.
311      */

312     public static class UnitResolver implements LengthHandler {
313
314         /**
315          * The length value.
316          */

317         public float value;
318
319         /**
320          * The length type.
321          */

322         public short unit = SVGLength.SVG_LENGTHTYPE_NUMBER;
323
324         /**
325          * Implements {@link LengthHandler#startLength()}.
326          */

327         public void startLength() throws ParseException {
328         }
329
330         /**
331          * Implements {@link LengthHandler#lengthValue(float)}.
332          */

333         public void lengthValue(float v) throws ParseException {
334             this.value = v;
335         }
336
337         /**
338          * Implements {@link LengthHandler#em()}.
339          */

340         public void em() throws ParseException {
341             this.unit = SVGLength.SVG_LENGTHTYPE_EMS;
342         }
343
344         /**
345          * Implements {@link LengthHandler#ex()}.
346          */

347         public void ex() throws ParseException {
348             this.unit = SVGLength.SVG_LENGTHTYPE_EXS;
349         }
350
351         /**
352          * Implements {@link LengthHandler#in()}.
353          */

354         public void in() throws ParseException {
355             this.unit = SVGLength.SVG_LENGTHTYPE_IN;
356         }
357
358         /**
359          * Implements {@link LengthHandler#cm()}.
360          */

361         public void cm() throws ParseException {
362             this.unit = SVGLength.SVG_LENGTHTYPE_CM;
363         }
364
365         /**
366          * Implements {@link LengthHandler#mm()}.
367          */

368         public void mm() throws ParseException {
369             this.unit = SVGLength.SVG_LENGTHTYPE_MM;
370         }
371
372         /**
373          * Implements {@link LengthHandler#pc()}.
374          */

375         public void pc() throws ParseException {
376             this.unit = SVGLength.SVG_LENGTHTYPE_PC;
377         }
378
379         /**
380          * Implements {@link LengthHandler#pt()}.
381          */

382         public void pt() throws ParseException {
383             this.unit = SVGLength.SVG_LENGTHTYPE_PT;
384         }
385
386         /**
387          * Implements {@link LengthHandler#px()}.
388          */

389         public void px() throws ParseException {
390             this.unit = SVGLength.SVG_LENGTHTYPE_PX;
391         }
392
393         /**
394          * Implements {@link LengthHandler#percentage()}.
395          */

396         public void percentage() throws ParseException {
397             this.unit = SVGLength.SVG_LENGTHTYPE_PERCENTAGE;
398         }
399
400         /**
401          * Implements {@link LengthHandler#endLength()}.
402          */

403         public void endLength() throws ParseException {
404         }
405     }
406
407     /**
408      * Holds the informations needed to compute the units.
409      */

410     public interface Context {
411
412         /**
413          * Returns the element.
414          */

415         Element JavaDoc getElement();
416
417         /**
418          * Returns the size of a px CSS unit in millimeters.
419          */

420         float getPixelUnitToMillimeter();
421
422         /**
423          * Returns the size of a px CSS unit in millimeters.
424          * This will be removed after next release.
425          * @see #getPixelUnitToMillimeter()
426          */

427         float getPixelToMM();
428
429         /**
430          * Returns the font-size value.
431          */

432         float getFontSize();
433
434         /**
435          * Returns the x-height value.
436          */

437         float getXHeight();
438
439         /**
440          * Returns the viewport width used to compute units.
441          */

442         float getViewportWidth();
443
444         /**
445          * Returns the viewport height used to compute units.
446          */

447         float getViewportHeight();
448     }
449 }
450
Popular Tags