com.googlecode.blaisemath.graphics.svg.SVGGraphic Maven / Gradle / Ivy
package com.googlecode.blaisemath.graphics.svg;
/*
* #%L
* BlaiseSVG
* --
* Copyright (C) 2014 - 2017 Elisha Peterson
* --
* 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.
* #L%
*/
import static com.google.common.base.Preconditions.checkNotNull;
import com.googlecode.blaisemath.graphics.core.Graphic;
import com.googlecode.blaisemath.graphics.core.GraphicComposite;
import com.googlecode.blaisemath.graphics.core.GraphicUtils;
import com.googlecode.blaisemath.graphics.swing.JGraphicComponent;
import com.googlecode.blaisemath.graphics.swing.PanAndZoomHandler;
import com.googlecode.blaisemath.svg.SVGElement;
import com.googlecode.blaisemath.svg.SVGRoot;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
/**
* Uses an {@link SVGElement} as a primitive to be rendered on a {@link JGraphicComponent}.
* Allows setting bounding boxes, so that the SVG element can be scaled or moved on the canvas.
*
* @author elisha
*/
public class SVGGraphic extends GraphicComposite {
/** Source SVG element to be drawn */
private SVGElement element;
/** Describes where on the canvas the element will be drawn */
private Rectangle2D graphicBounds;
/** The graphic object that will be rendered */
private Graphic primitiveElement;
/**
* Create a new instance for the provided SVG.
* @param element SVG to draw
* @return graphic
*/
public static SVGGraphic create(SVGElement element) {
checkNotNull(element);
SVGGraphic res = new SVGGraphic();
res.setElement(element);
return res;
}
private void updateGraphics() {
Graphic nue = SVGElementGraphicConverter.getInstance()
.convert(element);
if (primitiveElement == null) {
addGraphic(nue);
} else {
replaceGraphics(Collections.singleton(primitiveElement), Collections.singleton(nue));
}
primitiveElement = nue;
if (element instanceof SVGRoot) {
int wid = ((SVGRoot) element).getWidth();
int ht = ((SVGRoot) element).getHeight();
this.graphicBounds = new Rectangle2D.Double(0, 0, wid, ht);
}
}
//
//
// PROPERTY PATTERNS
//
public SVGElement getElement() {
return element;
}
public void setElement(SVGElement el) {
Object old = this.element;
if (old != el) {
this.element = el;
updateGraphics();
}
}
public Rectangle2D getGraphicBounds() {
return graphicBounds;
}
public void setGraphicBounds(Rectangle2D graphicBounds) {
this.graphicBounds = graphicBounds;
fireGraphicChanged();
}
//
/** Generate transform used to scale/translate the SVG */
private AffineTransform transform() {
if (graphicBounds == null || !(element instanceof SVGRoot)) {
return null;
}
Rectangle2D viewBox = ((SVGRoot) element).getViewBoxAsRectangle();
return viewBox == null ? null : PanAndZoomHandler.scaleRectTransform(graphicBounds, viewBox);
}
/** Inverse transform */
private AffineTransform inverseTransform() {
if (graphicBounds == null || !(element instanceof SVGRoot)) {
return null;
}
Rectangle2D viewBox = ((SVGRoot) element).getViewBoxAsRectangle();
return viewBox == null ? null : PanAndZoomHandler.scaleRectTransform(viewBox, graphicBounds);
}
@Override
public Rectangle2D boundingBox() {
AffineTransform tx = transform();
Rectangle2D norm = GraphicUtils.boundingBox(entries);
return tx == null ? norm : tx.createTransformedShape(norm).getBounds2D();
}
@Override
public boolean contains(Point2D point) {
AffineTransform tx = inverseTransform();
return tx == null ? super.contains(point)
: super.contains(tx.transform(point, null));
}
@Override
public boolean intersects(Rectangle2D box) {
AffineTransform tx = inverseTransform();
return tx == null ? super.intersects(box)
: super.intersects(tx.createTransformedShape(box).getBounds2D());
}
@Override
public void renderTo(Graphics2D canvas) {
AffineTransform tx = transform();
if (graphicBounds != null) {
canvas.setColor(Color.red);
canvas.draw(graphicBounds);
}
if (tx == null) {
super.renderTo(canvas);
} else {
AffineTransform original = canvas.getTransform();
canvas.transform(transform());
super.renderTo(canvas);
canvas.setTransform(original);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy