001/* =================================================== 002 * JFreeSVG : an SVG library for the Java(tm) platform 003 * =================================================== 004 * 005 * (C)opyright 2013-2021, by Object Refinery Limited. All rights reserved. 006 * 007 * Project Info: http://www.jfree.org/jfreesvg/index.html 008 * 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation, either version 3 of the License, or 012 * (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 021 * 022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 023 * Other names may be trademarks of their respective owners.] 024 * 025 * If you do not wish to be bound by the terms of the GPL, an alternative 026 * commercial license can be purchased. For details, please see visit the 027 * JFreeSVG home page: 028 * 029 * http://www.jfree.org/jfreesvg 030 * 031 */ 032 033package org.jfree.graphics2d; 034 035import java.awt.Polygon; 036import java.awt.Shape; 037import java.awt.geom.Arc2D; 038import java.awt.geom.Ellipse2D; 039import java.awt.geom.GeneralPath; 040import java.awt.geom.Line2D; 041import java.awt.geom.Path2D; 042import java.awt.geom.Rectangle2D; 043import java.awt.geom.RoundRectangle2D; 044import java.awt.image.BufferedImage; 045import java.awt.image.ColorModel; 046import java.awt.image.RenderedImage; 047import java.awt.image.WritableRaster; 048import java.util.Hashtable; 049 050/** 051 * A collection of static utility methods for shapes and images. 052 */ 053public final class GraphicsUtils { 054 055 private GraphicsUtils() { 056 // no need to instantiate this 057 } 058 059 /** 060 * Returns a shape that is (more or less) equivalent to the supplied shape. 061 * For some known shape implementations ({@code Line2D}, 062 * {@code Rectangle2D}, {@code RoundRectangle2D}, {@code Arc2D}, 063 * {@code Ellipse2D}, and {@code Polygon}) the copy will be an instance of 064 * that class. For other shapes, a {@code Path2D} containing the outline 065 * of the shape is returned. 066 * 067 * @param shape the shape ({@code null} not permitted). 068 * 069 * @return A copy of the shape or shape outline (never {@code null}). 070 */ 071 public static Shape copyOf(Shape shape) { 072 Args.nullNotPermitted(shape, "shape"); 073 if (shape instanceof Line2D) { 074 Line2D l = (Line2D) shape; 075 return new Line2D.Double(l.getX1(), l.getY1(), l.getX2(), l.getY2()); 076 } 077 if (shape instanceof Rectangle2D) { 078 Rectangle2D r = (Rectangle2D) shape; 079 return new Rectangle2D.Double(r.getX(), r.getY(), r.getWidth(), 080 r.getHeight()); 081 } 082 if (shape instanceof RoundRectangle2D) { 083 RoundRectangle2D rr = (RoundRectangle2D) shape; 084 return new RoundRectangle2D.Double(rr.getX(), rr.getY(), 085 rr.getWidth(), rr.getHeight(), rr.getArcWidth(), 086 rr.getArcHeight()); 087 } 088 if (shape instanceof Arc2D) { 089 Arc2D arc = (Arc2D) shape; 090 return new Arc2D.Double(arc.getX(), arc.getY(), arc.getWidth(), 091 arc.getHeight(), arc.getAngleStart(), arc.getAngleExtent(), 092 arc.getArcType()); 093 } 094 if (shape instanceof Ellipse2D) { 095 Ellipse2D ell = (Ellipse2D) shape; 096 return new Ellipse2D.Double(ell.getX(), ell.getY(), ell.getWidth(), 097 ell.getHeight()); 098 } 099 if (shape instanceof Polygon) { 100 Polygon p = (Polygon) shape; 101 return new Polygon(p.xpoints, p.ypoints, p.npoints); 102 } 103 return new Path2D.Double(shape); 104 } 105 106 /** 107 * Creates a polygon from the specified {@code x} and {@code y} coordinate 108 * arrays. 109 * 110 * @param xPoints the x-points. 111 * @param yPoints the y-points. 112 * @param nPoints the number of points to use for the polyline. 113 * @param close closed? 114 * 115 * @return A polygon. 116 */ 117 public static GeneralPath createPolygon(int[] xPoints, int[] yPoints, 118 int nPoints, boolean close) { 119 GeneralPath p = new GeneralPath(); 120 p.moveTo(xPoints[0], yPoints[0]); 121 for (int i = 1; i < nPoints; i++) { 122 p.lineTo(xPoints[i], yPoints[i]); 123 } 124 if (close) { 125 p.closePath(); 126 } 127 return p; 128 } 129 130 /** 131 * Converts a rendered image to a {@code BufferedImage}. This utility 132 * method has come from a forum post by Jim Moore at: 133 * <p> 134 * <a href="http://www.jguru.com/faq/view.jsp?EID=114602"> 135 * http://www.jguru.com/faq/view.jsp?EID=114602</a> 136 * 137 * @param img the rendered image. 138 * 139 * @return A buffered image. 140 */ 141 public static BufferedImage convertRenderedImage(RenderedImage img) { 142 if (img instanceof BufferedImage) { 143 return (BufferedImage) img; 144 } 145 ColorModel cm = img.getColorModel(); 146 int width = img.getWidth(); 147 int height = img.getHeight(); 148 WritableRaster raster = cm.createCompatibleWritableRaster(width, height); 149 boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); 150 Hashtable properties = new Hashtable(); 151 String[] keys = img.getPropertyNames(); 152 if (keys != null) { 153 for (int i = 0; i < keys.length; i++) { 154 properties.put(keys[i], img.getProperty(keys[i])); 155 } 156 } 157 BufferedImage result = new BufferedImage(cm, raster, 158 isAlphaPremultiplied, properties); 159 img.copyData(raster); 160 return result; 161 } 162}