Changeset 6002 in josm for trunk/src/com/kitfox/svg/SVGElement.java
- Timestamp:
- 2013-06-11T01:01:28+02:00 (13 years ago)
- File:
-
- 1 edited
-
trunk/src/com/kitfox/svg/SVGElement.java (modified) (40 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/kitfox/svg/SVGElement.java
r4256 r6002 1 1 /* 2 * SVGElement.java 2 * SVG Salamander 3 * Copyright (c) 2004, Mark McKay 4 * All rights reserved. 3 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: 4 9 * 5 * The Salamander Project - 2D and 3D graphics libraries in Java 6 * Copyright (C) 2004 Mark McKay 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. 7 17 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other 23 * projects can be found at http://www.kitfox.com 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 24 33 * 25 34 * Created on January 26, 2004, 1:59 AM 26 35 */ 27 28 36 package com.kitfox.svg; 29 37 30 import java.util.*; 31 import java.util.regex.*; 32 import java.net.*; 33 import java.awt.geom.*; 34 35 import org.xml.sax.*; 36 import com.kitfox.svg.pathcmd.*; 37 import com.kitfox.svg.xml.*; 38 import com.kitfox.svg.pathcmd.Arc; 39 import com.kitfox.svg.pathcmd.BuildHistory; 40 import com.kitfox.svg.pathcmd.Cubic; 41 import com.kitfox.svg.pathcmd.CubicSmooth; 42 import com.kitfox.svg.pathcmd.Horizontal; 43 import com.kitfox.svg.pathcmd.LineTo; 44 import com.kitfox.svg.pathcmd.MoveTo; 45 import com.kitfox.svg.pathcmd.PathCommand; 46 import com.kitfox.svg.pathcmd.Quadratic; 47 import com.kitfox.svg.pathcmd.QuadraticSmooth; 48 import com.kitfox.svg.pathcmd.Terminal; 49 import com.kitfox.svg.pathcmd.Vertical; 50 import com.kitfox.svg.xml.StyleAttribute; 51 import com.kitfox.svg.xml.StyleSheet; 52 import com.kitfox.svg.xml.XMLParseUtil; 53 import java.awt.geom.AffineTransform; 54 import java.awt.geom.GeneralPath; 38 55 import java.io.Serializable; 56 import java.net.URI; 57 import java.util.ArrayList; 58 import java.util.Collections; 59 import java.util.HashMap; 60 import java.util.HashSet; 61 import java.util.Iterator; 62 import java.util.LinkedList; 63 import java.util.List; 64 import java.util.Set; 65 import java.util.regex.Matcher; 66 import java.util.regex.Pattern; 67 import org.xml.sax.Attributes; 68 import org.xml.sax.SAXException; 69 39 70 40 71 /** … … 44 75 abstract public class SVGElement implements Serializable 45 76 { 77 46 78 public static final long serialVersionUID = 0; 47 48 79 public static final String SVG_NS = "http://www.w3.org/2000/svg"; 49 50 80 protected SVGElement parent = null; 51 52 81 protected final ArrayList children = new ArrayList(); 53 54 82 protected String id = null; 55 83 /** 56 * CSS class. Used for applying style sheet information.84 * CSS class. Used for applying style sheet information. 57 85 */ 58 86 protected String cssClass = null; 59 60 87 /** 61 88 * Styles defined for this elemnt via the <b>style</b> attribute. 62 89 */ 63 90 protected final HashMap inlineStyles = new HashMap(); 64 65 /** 66 * Presentation attributes set for this element. Ie, any attribute other 91 /** 92 * Presentation attributes set for this element. Ie, any attribute other 67 93 * than the <b>style</b> attribute. 68 94 */ 69 95 protected final HashMap presAttribs = new HashMap(); 70 71 96 /** 72 97 * A list of presentation attributes to not include in the presentation … … 74 99 */ 75 100 protected static final Set ignorePresAttrib; 101 76 102 static 77 103 { … … 81 107 // set.add("style"); 82 108 // set.add("xml:base"); 83 109 84 110 ignorePresAttrib = Collections.unmodifiableSet(set); 85 111 } 86 87 /** 88 * This element may override the URI we resolve against with an 89 * xml:base attribute. If so, a copy is placed here. Otherwise, we defer 90 * to our parent for the reolution base 112 /** 113 * This element may override the URI we resolve against with an xml:base 114 * attribute. If so, a copy is placed here. Otherwise, we defer to our 115 * parent for the reolution base 91 116 */ 92 117 protected URI xmlBase = null; 93 94 118 /** 95 119 * The diagram this element belongs to 96 120 */ 97 121 protected SVGDiagram diagram; 98 /**99 * Link to the universe we reside in100 */101 // protected SVGUniverse universe;102 103 122 boolean dirty = true; 104 123 105 // public static final Matcher adobeId = Pattern.compile("(.*)_1_").matcher(""); 106 // static final String fpNumRe = "[-+]?((\\d+)|(\\d*\\.\\d+))([-+]?[eE]\\d+)?"; 107 108 /** Creates a new instance of SVGElement */ 124 /** 125 * Creates a new instance of SVGElement 126 */ 109 127 public SVGElement() 110 128 { 111 129 this(null, null, null); 112 130 } 113 131 114 132 public SVGElement(String id, SVGElement parent) 115 133 { 116 134 this(id, null, parent); 117 135 } 118 136 119 137 public SVGElement(String id, String cssClass, SVGElement parent) 120 138 { … … 123 141 this.parent = parent; 124 142 } 125 143 144 abstract public String getTagName(); 145 126 146 public SVGElement getParent() 127 147 { 128 148 return parent; 129 149 } 130 150 131 151 void setParent(SVGElement parent) 132 152 { 133 153 this.parent = parent; 134 154 } 135 155 136 156 /** 137 157 * @return an ordered list of nodes from the root of the tree to this node … … 139 159 public List getPath(List retVec) 140 160 { 141 if (retVec == null) retVec = new ArrayList(); 142 161 if (retVec == null) 162 { 163 retVec = new ArrayList(); 164 } 165 143 166 if (parent != null) 144 167 { … … 146 169 } 147 170 retVec.add(this); 148 171 149 172 return retVec; 150 173 } 151 152 /** 153 * @param retVec - A list to add all children to. If null, a new list is174 175 /** 176 * @param retVec - A list to add all children to. If null, a new list is 154 177 * created and children of this group are added. 155 178 * … … 158 181 public List getChildren(List retVec) 159 182 { 160 if (retVec == null) retVec = new ArrayList(); 161 183 if (retVec == null) 184 { 185 retVec = new ArrayList(); 186 } 187 162 188 retVec.addAll(children); 163 189 164 190 return retVec; 165 191 } 166 192 167 193 /** 168 194 * @param id - Id of svg element to return … … 173 199 for (Iterator it = children.iterator(); it.hasNext();) 174 200 { 175 SVGElement ele = (SVGElement)it.next(); 201 SVGElement ele = (SVGElement) it.next(); 176 202 String eleId = ele.getId(); 177 if (eleId != null && eleId.equals(id)) return ele; 178 } 179 203 if (eleId != null && eleId.equals(id)) 204 { 205 return ele; 206 } 207 } 208 180 209 return null; 181 210 } 182 183 /** 184 * Searches children for given element. If found, returns index of child.211 212 /** 213 * Searches children for given element. If found, returns index of child. 185 214 * Otherwise returns -1. 186 215 */ … … 189 218 return children.indexOf(child); 190 219 } 191 220 192 221 /** 193 222 * Swaps 2 elements in children. 223 * 194 224 * @i index of first 195 225 * @j index of second … … 203 233 return; 204 234 } 205 235 206 236 Object temp = children.get(i); 207 237 children.set(i, children.get(j)); … … 209 239 build(); 210 240 } 211 212 /** 213 * Called during SAX load process to notify that this tag has begun the process 214 * of being loaded 241 242 /** 243 * Called during SAX load process to notify that this tag has begun the 244 * process of being loaded 245 * 215 246 * @param attrs - Attributes of this tag 216 * @param helper - An object passed to all SVG elements involved in this build217 * process to aid in sharing information. 247 * @param helper - An object passed to all SVG elements involved in this 248 * build process to aid in sharing information. 218 249 */ 219 250 public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException … … 222 253 this.parent = parent; 223 254 this.diagram = helper.diagram; 224 255 225 256 this.id = attrs.getValue("id"); 226 257 if (this.id != null && !this.id.equals("")) … … 228 259 diagram.setElement(this.id, this); 229 260 } 230 261 231 262 String className = attrs.getValue("class"); 232 263 this.cssClass = (className == null || className.equals("")) ? null : className; 233 264 //docRoot = helper.docRoot; 234 265 //universe = helper.universe; 235 266 236 267 //Parse style string, if any 237 268 String style = attrs.getValue("style"); … … 240 271 HashMap map = XMLParseUtil.parseStyle(style, inlineStyles); 241 272 } 242 273 243 274 String base = attrs.getValue("xml:base"); 244 275 if (base != null && !base.equals("")) … … 247 278 { 248 279 xmlBase = new URI(base); 249 } 250 catch (Exception e) 280 } catch (Exception e) 251 281 { 252 282 throw new SAXException(e); 253 283 } 254 284 } 255 285 256 286 //Place all other attributes into the presentation attribute list 257 287 int numAttrs = attrs.getLength(); … … 259 289 { 260 290 String name = attrs.getQName(i); 261 if (ignorePresAttrib.contains(name)) continue; 291 if (ignorePresAttrib.contains(name)) 292 { 293 continue; 294 } 262 295 String value = attrs.getValue(i); 263 296 264 297 presAttribs.put(name, new StyleAttribute(name, value)); 265 298 } 266 299 } 267 300 268 301 /** 269 302 * @return a set of Strings that corespond to CSS attributes on this element … … 273 306 return inlineStyles.keySet(); 274 307 } 275 308 276 309 /** 277 310 * @return a set of Strings that corespond to XML attributes on this element … … 281 314 return presAttribs.keySet(); 282 315 } 283 316 284 317 /** 285 318 * Called after the start element but before the end element to indicate … … 292 325 child.setDiagram(diagram); 293 326 } 294 295 pr ivatevoid setDiagram(SVGDiagram diagram)327 328 protected void setDiagram(SVGDiagram diagram) 296 329 { 297 330 this.diagram = diagram; … … 299 332 for (Iterator it = children.iterator(); it.hasNext();) 300 333 { 301 SVGElement ele = (SVGElement)it.next(); 334 SVGElement ele = (SVGElement) it.next(); 302 335 ele.setDiagram(diagram); 303 336 } 304 337 } 305 338 306 339 public void removeChild(SVGElement child) throws SVGElementException 307 340 { … … 310 343 throw new SVGElementException(this, "Element does not contain child " + child); 311 344 } 312 345 313 346 children.remove(child); 314 347 } 315 348 316 349 /** 317 350 * Called during load process to add text scanned within a tag … … 320 353 { 321 354 } 322 323 /** 324 * Called to indicate that this tag and the tags it contains have been completely325 * processed, and that it should finish any load processes. 355 356 /** 357 * Called to indicate that this tag and the tags it contains have been 358 * completely processed, and that it should finish any load processes. 326 359 */ 327 360 public void loaderEndElement(SVGLoaderHelper helper) throws SVGParseException 328 361 { 329 try 330 { 331 build(); 332 } 333 catch (SVGException se) 334 { 335 throw new SVGParseException(se); 336 } 337 } 338 339 /** 340 * Called by internal processes to rebuild the geometry of this node 341 * fromit's presentation attributes, style attributes and animated tracks.362 // try 363 // { 364 // build(); 365 // } 366 // catch (SVGException se) 367 // { 368 // throw new SVGParseException(se); 369 // } 370 } 371 372 /** 373 * Called by internal processes to rebuild the geometry of this node from 374 * it's presentation attributes, style attributes and animated tracks. 342 375 */ 343 376 protected void build() throws SVGException 344 377 { 345 378 StyleAttribute sty = new StyleAttribute(); 346 379 347 380 if (getPres(sty.setName("id"))) 348 381 { … … 355 388 } 356 389 } 357 if (getPres(sty.setName("class"))) cssClass = sty.getStringValue(); 358 if (getPres(sty.setName("xml:base"))) xmlBase = sty.getURIValue(); 359 } 360 390 if (getPres(sty.setName("class"))) 391 { 392 cssClass = sty.getStringValue(); 393 } 394 if (getPres(sty.setName("xml:base"))) 395 { 396 xmlBase = sty.getURIValue(); 397 } 398 399 //Build children 400 for (int i = 0; i < children.size(); ++i) 401 { 402 SVGElement ele = (SVGElement) children.get(i); 403 ele.build(); 404 } 405 } 406 361 407 public URI getXMLBase() 362 408 { 363 return xmlBase != null ? xmlBase :364 (parent != null ? parent.getXMLBase() : diagram.getXMLBase()); 365 } 366 367 /** 368 * @return the id assigned to this node. Null if no id explicitly set.409 return xmlBase != null ? xmlBase 410 : (parent != null ? parent.getXMLBase() : diagram.getXMLBase()); 411 } 412 413 /** 414 * @return the id assigned to this node. Null if no id explicitly set. 369 415 */ 370 416 public String getId() 371 417 { 372 return id; 373 } 374 375 418 return id; 419 } 376 420 LinkedList contexts = new LinkedList(); 377 378 /** 379 * Hack to allow nodes to temporarily change their parents. The Use tag will421 422 /** 423 * Hack to allow nodes to temporarily change their parents. The Use tag will 380 424 * need this so it can alter the attributes that a particular node uses. 381 425 */ … … 387 431 protected SVGElement popParentContext() 388 432 { 389 return (SVGElement)contexts.removeLast(); 390 } 391 433 return (SVGElement) contexts.removeLast(); 434 } 435 392 436 protected SVGElement getParentContext() 393 437 { 394 return contexts.isEmpty() ? null : (SVGElement)contexts.getLast(); 395 } 396 438 return contexts.isEmpty() ? null : (SVGElement) contexts.getLast(); 439 } 440 441 public SVGRoot getRoot() 442 { 443 return parent == null ? null : parent.getRoot(); 444 } 445 397 446 /* 398 447 * Returns the named style attribute. Checks for inline styles first, then … … 408 457 return getStyle(attrib, true); 409 458 } 410 411 /** 412 * Copies the current style into the passed style attribute. Checks for 413 * inline styles first, then internal and extranal style sheets, and 414 * finally checks for presentation attributes. Recursively checks parents. 415 * @param attrib - Attribute to write style data to. Must have it's name 416 * set to the name of the style being queried. 417 * @param recursive - If true and this object does not contain the 418 * named style attribute, checks attributes of parents abck to root until 419 * one found. 459 460 /** 461 * Copies the current style into the passed style attribute. Checks for 462 * inline styles first, then internal and extranal style sheets, and finally 463 * checks for presentation attributes. Recursively checks parents. 464 * 465 * @param attrib - Attribute to write style data to. Must have it's name set 466 * to the name of the style being queried. 467 * @param recursive - If true and this object does not contain the named 468 * style attribute, checks attributes of parents back to root until one 469 * found. 420 470 */ 421 471 public boolean getStyle(StyleAttribute attrib, boolean recursive) throws SVGException 422 472 { 423 473 String styName = attrib.getName(); 424 474 425 475 //Check for local inline styles 426 476 StyleAttribute styAttr = (StyleAttribute)inlineStyles.get(styName); 427 477 428 478 attrib.setStringValue(styAttr == null ? "" : styAttr.getStringValue()); 429 479 430 480 //Return if we've found a non animated style 431 if (styAttr != null) return true;432 433 434 435 //Implement style sheet lookup later 436 481 if (styAttr != null) 482 { 483 return true; 484 } 485 486 437 487 //Check for presentation attribute 438 488 StyleAttribute presAttr = (StyleAttribute)presAttribs.get(styName); 439 489 440 490 attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue()); 441 491 442 492 //Return if we've found a presentation attribute instead 443 if (presAttr != null) return true; 444 445 493 if (presAttr != null) 494 { 495 return true; 496 } 497 498 //Check for style sheet 499 SVGRoot root = getRoot(); 500 if (root != null) 501 { 502 StyleSheet ss = root.getStyleSheet(); 503 if (ss != null) 504 { 505 return ss.getStyle(attrib, getTagName(), cssClass); 506 } 507 } 508 446 509 //If we're recursive, check parents 447 510 if (recursive) 448 511 { 449 512 SVGElement parentContext = getParentContext(); 450 if (parentContext != null) return parentContext.getStyle(attrib, true); 451 if (parent != null) return parent.getStyle(attrib, true); 452 } 453 513 if (parentContext != null) 514 { 515 return parentContext.getStyle(attrib, true); 516 } 517 if (parent != null) 518 { 519 return parent.getStyle(attrib, true); 520 } 521 } 522 454 523 //Unsuccessful reading style attribute 455 524 return false; 456 525 } 457 458 /** 459 * @return the raw style value of this attribute. Does not take the460 * presentation value or animation into consideration. Used by animations461 * todetermine the base to animate from.526 527 /** 528 * @return the raw style value of this attribute. Does not take the 529 * presentation value or animation into consideration. Used by animations to 530 * determine the base to animate from. 462 531 */ 463 532 public StyleAttribute getStyleAbsolute(String styName) 464 533 { 465 534 //Check for local inline styles 466 return (StyleAttribute)inlineStyles.get(styName); 467 } 468 535 return (StyleAttribute) inlineStyles.get(styName); 536 } 537 469 538 /** 470 539 * Copies the presentation attribute into the passed one. 540 * 471 541 * @return - True if attribute was read successfully 472 542 */ … … 474 544 { 475 545 String presName = attrib.getName(); 476 546 477 547 //Make sure we have a coresponding presentation attribute 478 StyleAttribute presAttr = (StyleAttribute)presAttribs.get(presName); 479 548 StyleAttribute presAttr = (StyleAttribute) presAttribs.get(presName); 549 480 550 //Copy presentation value directly 481 551 attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue()); 482 552 483 553 //Return if we found presentation attribute 484 if (presAttr != null) return true; 485 554 if (presAttr != null) 555 { 556 return true; 557 } 558 486 559 return false; 487 560 } 488 489 /** 490 * @return the raw presentation value of this attribute. Ignores any491 * modifications applied by style attributes or animation. Used by561 562 /** 563 * @return the raw presentation value of this attribute. Ignores any 564 * modifications applied by style attributes or animation. Used by 492 565 * animations to determine the starting point to animate from 493 566 */ … … 495 568 { 496 569 //Check for local inline styles 497 return (StyleAttribute)presAttribs.get(styName); 498 } 499 570 return (StyleAttribute) presAttribs.get(styName); 571 } 572 500 573 static protected AffineTransform parseTransform(String val) throws SVGException 501 574 { 502 575 final Matcher matchExpression = Pattern.compile("\\w+\\([^)]*\\)").matcher(""); 503 576 504 577 AffineTransform retXform = new AffineTransform(); 505 578 506 579 matchExpression.reset(val); 507 580 while (matchExpression.find()) … … 509 582 retXform.concatenate(parseSingleTransform(matchExpression.group())); 510 583 } 511 584 512 585 return retXform; 513 586 } 514 587 515 588 static public AffineTransform parseSingleTransform(String val) throws SVGException 516 589 { 517 590 final Matcher matchWord = Pattern.compile("[-.\\w]+").matcher(""); 518 591 519 592 AffineTransform retXform = new AffineTransform(); 520 593 521 594 matchWord.reset(val); 522 595 if (!matchWord.find()) … … 525 598 return retXform; 526 599 } 527 600 528 601 String function = matchWord.group().toLowerCase(); 529 602 530 603 LinkedList termList = new LinkedList(); 531 604 while (matchWord.find()) … … 533 606 termList.add(matchWord.group()); 534 607 } 535 536 608 609 537 610 double[] terms = new double[termList.size()]; 538 611 Iterator it = termList.iterator(); … … 540 613 while (it.hasNext()) 541 614 { 542 terms[count++] = XMLParseUtil.parseDouble((String)it.next()); 543 } 544 615 terms[count++] = XMLParseUtil.parseDouble((String) it.next()); 616 } 617 545 618 //Calculate transformation 546 619 if (function.equals("matrix")) 547 620 { 548 621 retXform.setTransform(terms[0], terms[1], terms[2], terms[3], terms[4], terms[5]); 549 } 550 else if (function.equals("translate")) 551 { 552 retXform.setToTranslation(terms[0], terms[1]); 553 } 554 else if (function.equals("scale")) 622 } else if (function.equals("translate")) 623 { 624 if (terms.length == 1) 625 { 626 retXform.setToTranslation(terms[0], 0); 627 } else 628 { 629 retXform.setToTranslation(terms[0], terms[1]); 630 } 631 } else if (function.equals("scale")) 555 632 { 556 633 if (terms.length > 1) 634 { 557 635 retXform.setToScale(terms[0], terms[1]); 558 else 636 } else 637 { 559 638 retXform.setToScale(terms[0], terms[0]); 560 } 561 else if (function.equals("rotate")) 639 } 640 } else if (function.equals("rotate")) 562 641 { 563 642 if (terms.length > 2) 643 { 564 644 retXform.setToRotation(Math.toRadians(terms[0]), terms[1], terms[2]); 565 else 645 } else 646 { 566 647 retXform.setToRotation(Math.toRadians(terms[0])); 567 } 568 else if (function.equals("skewx")) 648 } 649 } else if (function.equals("skewx")) 569 650 { 570 651 retXform.setToShear(Math.toRadians(terms[0]), 0.0); 571 } 572 else if (function.equals("skewy")) 652 } else if (function.equals("skewy")) 573 653 { 574 654 retXform.setToShear(0.0, Math.toRadians(terms[0])); 575 } 576 else 655 } else 577 656 { 578 657 throw new SVGException("Unknown transform type"); 579 658 } 580 659 581 660 return retXform; 582 661 } 583 662 584 663 static protected float nextFloat(LinkedList l) 585 664 { 586 String s = (String)l.removeFirst(); 665 String s = (String) l.removeFirst(); 587 666 return Float.parseFloat(s); 588 667 } 589 668 590 669 static protected PathCommand[] parsePathList(String list) 591 670 { 592 671 final Matcher matchPathCmd = Pattern.compile("([MmLlHhVvAaQqTtCcSsZz])|([-+]?((\\d*\\.\\d+)|(\\d+))([eE][-+]?\\d+)?)").matcher(list); 593 672 594 673 //Tokenize 595 674 LinkedList tokens = new LinkedList(); … … 598 677 tokens.addLast(matchPathCmd.group()); 599 678 } 600 601 679 680 602 681 boolean defaultRelative = false; 603 682 LinkedList cmdList = new LinkedList(); … … 605 684 while (tokens.size() != 0) 606 685 { 607 String curToken = (String)tokens.removeFirst(); 686 String curToken = (String) tokens.removeFirst(); 608 687 char initChar = curToken.charAt(0); 609 if ((initChar >= 'A' && initChar <='Z') || (initChar >= 'a' && initChar <='z')) 688 if ((initChar >= 'A' && initChar <= 'Z') || (initChar >= 'a' && initChar <= 'z')) 610 689 { 611 690 curCmd = initChar; 612 } 613 else 691 } else 614 692 { 615 693 tokens.addFirst(curToken); 616 694 } 617 695 618 696 PathCommand cmd = null; 619 697 620 698 switch (curCmd) 621 699 { … … 648 726 case 'A': 649 727 cmd = new Arc(false, nextFloat(tokens), nextFloat(tokens), 650 nextFloat(tokens),651 nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,652 nextFloat(tokens), nextFloat(tokens));728 nextFloat(tokens), 729 nextFloat(tokens) == 1f, nextFloat(tokens) == 1f, 730 nextFloat(tokens), nextFloat(tokens)); 653 731 break; 654 732 case 'a': 655 733 cmd = new Arc(true, nextFloat(tokens), nextFloat(tokens), 656 nextFloat(tokens),657 nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,658 nextFloat(tokens), nextFloat(tokens));734 nextFloat(tokens), 735 nextFloat(tokens) == 1f, nextFloat(tokens) == 1f, 736 nextFloat(tokens), nextFloat(tokens)); 659 737 break; 660 738 case 'Q': 661 739 cmd = new Quadratic(false, nextFloat(tokens), nextFloat(tokens), 662 nextFloat(tokens), nextFloat(tokens));740 nextFloat(tokens), nextFloat(tokens)); 663 741 break; 664 742 case 'q': 665 743 cmd = new Quadratic(true, nextFloat(tokens), nextFloat(tokens), 666 nextFloat(tokens), nextFloat(tokens));744 nextFloat(tokens), nextFloat(tokens)); 667 745 break; 668 746 case 'T': … … 674 752 case 'C': 675 753 cmd = new Cubic(false, nextFloat(tokens), nextFloat(tokens), 676 nextFloat(tokens), nextFloat(tokens),677 nextFloat(tokens), nextFloat(tokens));754 nextFloat(tokens), nextFloat(tokens), 755 nextFloat(tokens), nextFloat(tokens)); 678 756 break; 679 757 case 'c': 680 758 cmd = new Cubic(true, nextFloat(tokens), nextFloat(tokens), 681 nextFloat(tokens), nextFloat(tokens),682 nextFloat(tokens), nextFloat(tokens));759 nextFloat(tokens), nextFloat(tokens), 760 nextFloat(tokens), nextFloat(tokens)); 683 761 break; 684 762 case 'S': 685 763 cmd = new CubicSmooth(false, nextFloat(tokens), nextFloat(tokens), 686 nextFloat(tokens), nextFloat(tokens));764 nextFloat(tokens), nextFloat(tokens)); 687 765 break; 688 766 case 's': 689 767 cmd = new CubicSmooth(true, nextFloat(tokens), nextFloat(tokens), 690 nextFloat(tokens), nextFloat(tokens));768 nextFloat(tokens), nextFloat(tokens)); 691 769 break; 692 770 case 'Z': … … 697 775 throw new RuntimeException("Invalid path element"); 698 776 } 699 777 700 778 cmdList.add(cmd); 701 779 defaultRelative = cmd.isRelative; 702 780 } 703 781 704 782 PathCommand[] retArr = new PathCommand[cmdList.size()]; 705 783 cmdList.toArray(retArr); 706 784 return retArr; 707 785 } 708 786 709 787 static protected GeneralPath buildPath(String text, int windingRule) 710 788 { 711 789 PathCommand[] commands = parsePathList(text); 712 790 713 791 int numKnots = 2; 714 792 for (int i = 0; i < commands.length; i++) … … 716 794 numKnots += commands[i].getNumKnotsAdded(); 717 795 } 718 719 796 797 720 798 GeneralPath path = new GeneralPath(windingRule, numKnots); 721 799 722 800 BuildHistory hist = new BuildHistory(); 723 801 724 802 for (int i = 0; i < commands.length; i++) 725 803 { … … 727 805 cmd.appendPath(path, hist); 728 806 } 729 807 730 808 return path; 731 809 } 732 733 734 735 /** 736 * Updates all attributes in this diagram associated with a time event. 737 * Ie, all attributes with track information. 810 811 /** 812 * Updates all attributes in this diagram associated with a time event. Ie, 813 * all attributes with track information. 814 * 738 815 * @return - true if this node has changed state as a result of the time 739 816 * update … … 748 825 public SVGElement getChild(int i) 749 826 { 750 return (SVGElement)children.get(i); 751 } 752 827 return (SVGElement) children.get(i); 828 } 829 830 public double lerp(double t0, double t1, double alpha) 831 { 832 return (1 - alpha) * t0 + alpha * t1; 833 } 753 834 }
Note:
See TracChangeset
for help on using the changeset viewer.
