source: josm/trunk/src/com/kitfox/svg/MissingGlyph.java@ 17333

Last change on this file since 17333 was 14328, checked in by Don-vip, 6 years ago

see #14319, see #16838 - update to svgSalamander 1.1.2

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1/*
2 * SVG Salamander
3 * Copyright (c) 2004, Mark McKay
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * - Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
32 * projects can be found at http://www.kitfox.com
33 *
34 * Created on February 20, 2004, 10:00 PM
35 */
36package com.kitfox.svg;
37
38import com.kitfox.svg.pathcmd.BuildHistory;
39import com.kitfox.svg.pathcmd.PathCommand;
40import com.kitfox.svg.xml.StyleAttribute;
41import java.awt.Graphics2D;
42import java.awt.Shape;
43import java.awt.geom.AffineTransform;
44import java.awt.geom.GeneralPath;
45import java.awt.geom.Rectangle2D;
46import java.util.Iterator;
47
48/**
49 * Implements an embedded font.
50 *
51 * SVG specification: http://www.w3.org/TR/SVG/fonts.html
52 *
53 * @author Mark McKay
54 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
55 */
56public class MissingGlyph extends ShapeElement
57{
58 public static final String TAG_NAME = "missingglyph";
59
60 //We may define a path
61 private Shape path = null;
62 //Alternately, we may have child graphical elements
63 private float horizAdvX = -1; //Inherits font's value if not set
64 private float vertOriginX = -1; //Inherits font's value if not set
65 private float vertOriginY = -1; //Inherits font's value if not set
66 private float vertAdvY = -1; //Inherits font's value if not set
67
68 /**
69 * Creates a new instance of Font
70 */
71 public MissingGlyph()
72 {
73 }
74
75 @Override
76 public String getTagName()
77 {
78 return TAG_NAME;
79 }
80
81 /**
82 * Called after the start element but before the end element to indicate
83 * each child tag that has been processed
84 */
85 @Override
86 public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException
87 {
88 super.loaderAddChild(helper, child);
89 }
90
91 @Override
92 protected void build() throws SVGException
93 {
94 super.build();
95
96 StyleAttribute sty = new StyleAttribute();
97
98 String commandList = "";
99 if (getPres(sty.setName("d")))
100 {
101 commandList = sty.getStringValue();
102 }
103
104
105 //If glyph path was specified, calculate it
106 if (commandList != null)
107 {
108 String fillRule = getStyle(sty.setName("fill-rule")) ? sty.getStringValue() : "nonzero";
109
110 PathCommand[] commands = parsePathList(commandList);
111
112 GeneralPath buildPath = new GeneralPath(
113 fillRule.equals("evenodd") ? GeneralPath.WIND_EVEN_ODD : GeneralPath.WIND_NON_ZERO,
114 commands.length);
115
116 BuildHistory hist = new BuildHistory();
117
118 for (int i = 0; i < commands.length; i++)
119 {
120 PathCommand cmd = commands[i];
121 cmd.appendPath(buildPath, hist);
122 }
123
124 //Reflect glyph path to put it in user coordinate system
125 AffineTransform at = new AffineTransform();
126 at.scale(1, -1);
127 path = at.createTransformedShape(buildPath);
128 }
129
130
131 //Read glyph spacing info
132 if (getPres(sty.setName("horiz-adv-x")))
133 {
134 horizAdvX = sty.getFloatValue();
135 }
136
137 if (getPres(sty.setName("vert-origin-x")))
138 {
139 vertOriginX = sty.getFloatValue();
140 }
141
142 if (getPres(sty.setName("vert-origin-y")))
143 {
144 vertOriginY = sty.getFloatValue();
145 }
146
147 if (getPres(sty.setName("vert-adv-y")))
148 {
149 vertAdvY = sty.getFloatValue();
150 }
151 }
152
153 public Shape getPath()
154 {
155 return path;
156 }
157
158 @Override
159 public void render(Graphics2D g) throws SVGException
160 {
161 //Do not push or pop stack
162
163 if (path != null)
164 {
165 renderShape(g, path);
166 }
167
168 Iterator<SVGElement> it = children.iterator();
169 while (it.hasNext())
170 {
171 SVGElement ele = it.next();
172 if (ele instanceof RenderableElement)
173 {
174 ((RenderableElement) ele).render(g);
175 }
176 }
177
178 //Do not push or pop stack
179 }
180
181 public float getHorizAdvX()
182 {
183 if (horizAdvX == -1)
184 {
185 horizAdvX = ((Font) parent).getHorizAdvX();
186 }
187 return horizAdvX;
188 }
189
190 public float getVertOriginX()
191 {
192 if (vertOriginX == -1)
193 {
194 vertOriginX = getHorizAdvX() / 2;
195 }
196 return vertOriginX;
197 }
198
199 public float getVertOriginY()
200 {
201 if (vertOriginY == -1)
202 {
203 vertOriginY = ((Font) parent).getFontFace().getAscent();
204 }
205 return vertOriginY;
206 }
207
208 public float getVertAdvY()
209 {
210 if (vertAdvY == -1)
211 {
212 vertAdvY = ((Font) parent).getFontFace().getUnitsPerEm();
213 }
214 return vertAdvY;
215
216 }
217
218 @Override
219 public Shape getShape()
220 {
221 if (path != null)
222 {
223 return shapeToParent(path);
224 }
225 return null;
226 }
227
228 @Override
229 public Rectangle2D getBoundingBox() throws SVGException
230 {
231 if (path != null)
232 {
233 return boundsToParent(includeStrokeInBounds(path.getBounds2D()));
234 }
235 return null;
236 }
237
238 /**
239 * Updates all attributes in this diagram associated with a time event. Ie,
240 * all attributes with track information.
241 *
242 * @return - true if this node has changed state as a result of the time
243 * update
244 */
245 @Override
246 public boolean updateTime(double curTime) throws SVGException
247 {
248 //Fonts can't change
249 return false;
250 }
251
252 /**
253 * @param path the path to set
254 */
255 public void setPath(Shape path)
256 {
257 this.path = path;
258 }
259
260 /**
261 * @param horizAdvX the horizAdvX to set
262 */
263 public void setHorizAdvX(float horizAdvX)
264 {
265 this.horizAdvX = horizAdvX;
266 }
267
268 /**
269 * @param vertOriginX the vertOriginX to set
270 */
271 public void setVertOriginX(float vertOriginX)
272 {
273 this.vertOriginX = vertOriginX;
274 }
275
276 /**
277 * @param vertOriginY the vertOriginY to set
278 */
279 public void setVertOriginY(float vertOriginY)
280 {
281 this.vertOriginY = vertOriginY;
282 }
283
284 /**
285 * @param vertAdvY the vertAdvY to set
286 */
287 public void setVertAdvY(float vertAdvY)
288 {
289 this.vertAdvY = vertAdvY;
290 }
291}
Note: See TracBrowser for help on using the repository browser.