/******************************************************************************* * Copyright 2010 Simon Mieth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.kabeja.svg.generators; import java.util.Map; import org.kabeja.common.DraftEntity; import org.kabeja.entities.Ellipse; import org.kabeja.math.Point3D; import org.kabeja.math.TransformContext; import org.kabeja.svg.SVGConstants; import org.kabeja.svg.SVGPathBoundaryGenerator; import org.kabeja.svg.SVGUtils; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; public class SVGEllipseGenerator extends AbstractSVGSAXGenerator implements SVGPathBoundaryGenerator { public void toSAX(ContentHandler handler, Map svgContext, DraftEntity entity, TransformContext transformContext) throws SAXException { Ellipse ellipse = (Ellipse) entity; AttributesImpl attr = new AttributesImpl(); super.setCommonAttributes(attr, svgContext, ellipse); if ((ellipse.getStartParameter() == Ellipse.DEFAULT_START_PARAMETER) && (ellipse.getEndParameter() == Ellipse.DEFAULT_END_PARAMETER)) { SVGUtils.addAttribute(attr, "cx", SVGUtils.formatNumberAttribute(ellipse.getCenterPoint().getX())); SVGUtils.addAttribute(attr, "cy", SVGUtils.formatNumberAttribute(ellipse.getCenterPoint().getY())); double major = ellipse.getHalfMajorAxisLength(); double minor = ellipse.getRatio() * major; SVGUtils.addAttribute(attr, "rx", SVGUtils.formatNumberAttribute(major)); SVGUtils.addAttribute(attr, "ry", SVGUtils.formatNumberAttribute(minor)); // chek for rotation double angle = ellipse.getRotationAngle(); if (angle != 0.0) { StringBuffer buf = new StringBuffer(); buf.append("rotate("); buf.append(SVGUtils.formatNumberAttribute(Math.toDegrees(angle))); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute( ellipse.getCenterPoint().getX())); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute( ellipse.getCenterPoint().getY())); buf.append(')'); SVGUtils.addAttribute(attr, "transform", buf.toString()); } // SVGUtils.addAttribute(attr, "fill", "none"); SVGUtils.emptyElement(handler, SVGConstants.SVG_ELLIPSE, attr); } else { SVGUtils.addAttribute(attr, "d", getSVGPath(ellipse)); SVGUtils.emptyElement(handler, SVGConstants.SVG_PATH, attr); } } public String getSVGPath(DraftEntity entity) { Ellipse ellipse = (Ellipse) entity; StringBuffer buf = new StringBuffer(); Point3D start = ellipse.getPointAt(ellipse.getStartParameter()); Point3D end = ellipse.getPointAt(ellipse.getEndParameter()); buf.append("M "); buf.append(SVGUtils.formatNumberAttribute(start.getX())); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute(start.getY())); // get the angle between x-axis and major-axis double major = ellipse.getMajorAxisDirection().getLength(); double angle = ellipse.getRotationAngle(); buf.append(" A "); buf.append(SVGUtils.formatNumberAttribute(major)); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute(major * ellipse.getRatio())); buf.append(' '); // rotation value of the ellipse buf.append(SVGUtils.formatNumberAttribute(Math.toDegrees(angle))); if ((ellipse.getStartParameter() == Ellipse.DEFAULT_START_PARAMETER) && (ellipse.getEndParameter() == Ellipse.DEFAULT_END_PARAMETER)) { // drawing a full ellipse -> from start point to half // and then back // the large-arc flag and the sweep-flag always 1 buf.append(" 1 1 "); buf.append(SVGUtils.formatNumberAttribute(end.getX())); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute(end.getY())); buf.append(" A "); buf.append(SVGUtils.formatNumberAttribute(major)); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute( major * ellipse.getRatio())); buf.append(' '); // rotation value of the ellipse buf.append(SVGUtils.formatNumberAttribute(Math.toDegrees(angle))); buf.append(" 1 1 "); buf.append(SVGUtils.formatNumberAttribute(start.getX())); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute(start.getY())); // buf.append(" z "); } else { //TODO check the correct flags // buf.append(' '); // the large-arc flag if ((ellipse.getEndParameter() - ellipse.getStartParameter()) >= Math.PI) { buf.append(1); } else { buf.append(0); } buf.append(' '); // the sweep-flag always 1 buf.append(" 1 "); buf.append(SVGUtils.formatNumberAttribute(end.getX())); buf.append(' '); buf.append(SVGUtils.formatNumberAttribute(end.getY())); } return buf.toString(); } }