| /* |
| |
| Copyright 2001-2003 The Apache Software Foundation |
| |
| 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.apache.batik.apps.rasterizer; |
| |
| import java.awt.Color; |
| import java.awt.geom.Rectangle2D; |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.apache.batik.transcoder.Transcoder; |
| import org.apache.batik.transcoder.TranscoderInput; |
| import org.apache.batik.transcoder.TranscoderOutput; |
| import org.apache.batik.transcoder.image.ImageTranscoder; |
| import org.apache.batik.transcoder.image.JPEGTranscoder; |
| import org.apache.batik.transcoder.image.PNGTranscoder; |
| |
| /** |
| * This application can be used to convert SVG images to raster images. |
| * <br /> |
| * Possible result raster image formats are PNG, JPEG, TIFF, and PDF. |
| * The Batik Transcoder API is used to execute the conversion. FOP is |
| * needed to be able to transcode to the PDF format<br /> |
| * |
| * The source has to be list of files or URL (set by the <tt>setSources</tt> |
| * method). <br /> |
| * |
| * The destination can be:<br /><ul> |
| * <li><b>unspecified</b>. In that case, only file sources can be converted and |
| * a file in the same directory as the source will be created.</li> |
| * <li><b>a directory</b>, set by the <tt>setDst</tt> method. In that case, |
| * the output files are created in that destination directory</li> |
| * <li><b>a file</b>. In case there is a <i>single |
| * source</i>, the destination can be a single named file |
| * (set with the <tt>setDst</tt> method.</li>)<br /> |
| * </ul> |
| * |
| * <hr /> |
| * |
| * There are a number of options which control the way the image is |
| * converted to the destination format:<br /><ul> |
| * <li>destinationType: controls the type of conversion which should be done. |
| * see the {@link DestinationType} documentation.</li> |
| * <li>width/height: they control the desired width and height, in user space, |
| * for the output image.</li> |
| * <li>maxWidth/maxHeight: control the maximum width and height, |
| * in user space, of the output image.</li> |
| * <li>area: controls the specific sub-area of the image which should be |
| * rendered.</li> |
| * <li>backgroundColor: controls the color which is used to fill the |
| * background before rendering the image</li> |
| * <li>quality: relevant only for JPEG destinations, this controls the |
| * encoding quality.</li> |
| * <li>indexed: relevant only for PNG, controls the number of bits |
| * used in writting of a palletized files.</li> |
| * <li>mediaType: controls the CSS media, or list of media, for which the |
| * image should be rendered.</li> |
| * <li>alternate: controls the alternate CSS stylesheet to activate, |
| * if any.</li> |
| * <li>language: controls the user language with which the SVG document |
| * should be converted.</li> |
| * <li>userStylesheet: defines the user stylesheet to apply to SVG documents |
| * in addition to other stylesheets referenced by or embedded in the |
| * SVG documents.</li> |
| * <li>pixelUnitToMillimeter: defines the size of a pixel in millimeters |
| * to use when processing the SVG documents.</li> |
| * </ul> |
| * |
| * @version $Id$ |
| * @author <a href="mailto:Henri.Ruini@nokia.com">Henri Ruini</a> |
| * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a> |
| */ |
| public class SVGConverter { |
| // |
| // Error codes reported by the SVGConverter |
| // |
| |
| // |
| // Reported when no source file has been specified. |
| // |
| public static final String ERROR_NO_SOURCES_SPECIFIED |
| = "SVGConverter.error.no.sources.specified"; |
| |
| // |
| // Reported when there is more than one valid input source |
| // and no output directory has been set and the source is |
| // not a file. |
| // |
| public static final String ERROR_CANNOT_COMPUTE_DESTINATION |
| = "SVGConverter.error.cannot.compute.destination"; |
| |
| // |
| // Reported when the dst is a file and there are multiple |
| // sources. |
| // |
| public static final String ERROR_CANNOT_USE_DST_FILE |
| = "SVGConverter.error.cannot.use.dst.file"; |
| |
| // |
| // Reported when the <tt>Transcoder</tt> for the requested |
| // <tt>destinationType</tt> cannot be found. |
| // |
| public static final String ERROR_CANNOT_ACCESS_TRANSCODER |
| = "SVGConverter.error.cannot.access.transcoder"; |
| |
| // |
| // Reported when the source is found to be the same as |
| // the destination. Note that it is not guaranteed that |
| // this error condition will always be detected. |
| // |
| public static final String ERROR_SOURCE_SAME_AS_DESTINATION |
| = "SVGConverter.error.source.same.as.destination"; |
| |
| // |
| // Reported when one of the sources cannot be read. |
| // |
| public static final String ERROR_CANNOT_READ_SOURCE |
| = "SVGConverter.error.cannot.read.source"; |
| |
| // |
| // Reported when an error happens while opening a source |
| // file. |
| // |
| public static final String ERROR_CANNOT_OPEN_SOURCE |
| = "SVGConverter.error.cannot.open.source"; |
| |
| // |
| // Reported if the output is not writeable. This may |
| // happen if the output file already exists and does not |
| // have write permission. |
| // |
| public static final String ERROR_OUTPUT_NOT_WRITEABLE |
| = "SVGConverter.error.output.not.writeable"; |
| |
| // |
| // Reported when an error happens while trying to open |
| // the output file for writing. |
| // |
| public static final String ERROR_CANNOT_OPEN_OUTPUT_FILE |
| = "SVGConverter.error.cannot.open.output.file"; |
| |
| // |
| // Reported when the converter was not able to create |
| // the destination directory for the files. |
| // |
| public static final String ERROR_UNABLE_TO_CREATE_OUTPUT_DIR |
| = "SVGConverter.error.unable.to.create.output.dir"; |
| |
| // |
| // Reported when an error occurs while convertion the |
| // source file. |
| // |
| public static final String ERROR_WHILE_RASTERIZING_FILE |
| = "SVGConverter.error.while.rasterizing.file"; |
| |
| // |
| // Class variables and constants |
| // |
| |
| /** SVG file extension */ |
| protected static final String SVG_EXTENSION = ".svg"; |
| |
| /** Default quality value. A value of -1 means disabled. */ |
| protected static final float DEFAULT_QUALITY |
| = -1f; |
| |
| /** Maximum quality value */ |
| protected static final float MAXIMUM_QUALITY |
| = .99F; |
| |
| /** Default result type */ |
| protected static final DestinationType DEFAULT_RESULT_TYPE |
| = DestinationType.PNG; |
| |
| /** Default width */ |
| protected static final float DEFAULT_WIDTH = -1; |
| |
| /** Default height */ |
| protected static final float DEFAULT_HEIGHT = -1; |
| |
| /** Result type */ |
| protected DestinationType destinationType = DEFAULT_RESULT_TYPE; |
| |
| /** Output image height. */ |
| protected float height = DEFAULT_HEIGHT; |
| |
| /** Output image width. */ |
| protected float width = DEFAULT_WIDTH; |
| |
| /** Maximum output image height. */ |
| protected float maxHeight = DEFAULT_HEIGHT; |
| |
| /** Maximum output image width. */ |
| protected float maxWidth = DEFAULT_WIDTH; |
| |
| /** Output image quality. */ |
| protected float quality = DEFAULT_QUALITY; |
| |
| /** Should output Image be indexed . */ |
| protected int indexed = -1; |
| |
| /** Output AOI area. */ |
| protected Rectangle2D area = null; |
| |
| /** Language */ |
| protected String language = null; |
| |
| /** User stylesheet */ |
| protected String userStylesheet = null; |
| |
| /** Millimeters Per Pixel */ |
| protected float pixelUnitToMillimeter = -1f; |
| |
| /** Validation flag */ |
| protected boolean validate = false; |
| |
| /** Execute the 'onload' scripts flag */ |
| protected boolean executeOnload = false; |
| |
| /** Set of allowed script types. */ |
| protected String allowedScriptTypes = null; |
| |
| /** Controls whether scripts can only have the same origin as |
| the document which references them. */ |
| protected boolean constrainScriptOrigin = true; |
| |
| /** Controls whether scripts should be run securely or not */ |
| protected boolean securityOff = false; |
| |
| /** Sources files or URLs */ |
| protected Vector sources = null; |
| |
| /** |
| * Destination image path. Can be a file (for single source) or |
| * a directory |
| */ |
| protected File dst; |
| |
| /** Background color for the output images. */ |
| protected Color backgroundColor = null; |
| |
| /** Media type for which the SVG image should be rendered */ |
| protected String mediaType = null; |
| |
| /** Default value for the font-family when it is unspecified */ |
| protected String defaultFontFamily = null; |
| |
| /** Alternate stylesheet for which should be applied to the SVG */ |
| protected String alternateStylesheet = null; |
| |
| /** Contents of <tt>fileset</tt> elements. */ |
| protected Vector files = new Vector(); |
| |
| /** |
| * Controls some aspects of the converter's operation, |
| * such as whether or not it should proceed in some |
| * error situations. See {@link SVGConverterController} |
| */ |
| protected SVGConverterController controller; |
| |
| // |
| // Default constructor |
| // |
| public SVGConverter(){ |
| this(new DefaultSVGConverterController()); |
| } |
| |
| // |
| // Constructor |
| // |
| public SVGConverter(SVGConverterController controller){ |
| if (controller == null){ |
| throw new IllegalArgumentException(); |
| } |
| |
| this.controller = controller; |
| } |
| |
| // |
| // Property get/set methods |
| // |
| |
| /** |
| * Sets the <tt>destinationType</tt> attribute value. |
| * Should not be null. |
| */ |
| public void setDestinationType(DestinationType destinationType) { |
| if(destinationType == null){ |
| throw new IllegalArgumentException(); |
| } |
| this.destinationType = destinationType; |
| } |
| |
| public DestinationType getDestinationType(){ |
| return destinationType; |
| } |
| |
| /** |
| * In less than or equal to zero, the height is not |
| * constrained on the output image. The height is in |
| * user space. |
| */ |
| public void setHeight(float height) { |
| this.height = height; |
| } |
| |
| public float getHeight(){ |
| return height; |
| } |
| |
| /** |
| * In less than or equal to zero, the width is not |
| * constrained on the output image. The width is in |
| * user space. |
| */ |
| public void setWidth(float width) { |
| this.width = width; |
| } |
| |
| public float getWidth(){ |
| return width; |
| } |
| |
| /** |
| * If less than or equal to zero, the maximum height |
| * does not have any effect on the output image. |
| * The maximum height is in user space. |
| */ |
| public void setMaxHeight(float height) { |
| this.maxHeight = height; |
| } |
| |
| public float getMaxHeight(){ |
| return maxHeight; |
| } |
| |
| /** |
| * If less than or equal to zero, the maximum width |
| * does not have any effect on the output image. |
| * The maximum width is in user space. |
| */ |
| public void setMaxWidth(float width) { |
| this.maxWidth = width; |
| } |
| |
| public float getMaxWidth(){ |
| return maxWidth; |
| } |
| |
| /** |
| * Sets the JPEG encoding quality. The value should be strictly |
| * less than 1. If the value is less than zero, then the maximum |
| * encoding quality is used. |
| */ |
| public void setQuality(float quality) throws IllegalArgumentException { |
| if(quality >= 1){ |
| throw new IllegalArgumentException(); |
| } |
| |
| this.quality = quality; |
| } |
| |
| public float getQuality(){ |
| return quality; |
| } |
| |
| /** |
| * Tells the PNG encoder to reduce the image to 256 colors, so the |
| * PNG file is indexed. |
| */ |
| public void setIndexed(int bits) throws IllegalArgumentException { |
| this.indexed = bits; |
| } |
| |
| public int getIndexed(){ |
| return indexed; |
| } |
| |
| /** |
| * Sets the user language. If the value is null, then the default (see |
| * {@link org.apache.batik.bridge.UserAgent#getLanguages}) |
| * is used. |
| */ |
| public void setLanguage(String language){ |
| this.language = language; |
| } |
| |
| public String getLanguage(){ |
| return language; |
| } |
| |
| /** |
| * Sets the user stylesheet. May be null. |
| */ |
| public void setUserStylesheet(String userStylesheet){ |
| this.userStylesheet = userStylesheet; |
| } |
| |
| public String getUserStylesheet(){ |
| return userStylesheet; |
| } |
| |
| /** |
| * Sets the millimeters per pixel constant. A negative |
| * value will cause the default value |
| * (see {@link org.apache.batik.bridge.UserAgent#getPixelUnitToMillimeter}) |
| * to be used. |
| */ |
| public void setPixelUnitToMillimeter(float pixelUnitToMillimeter){ |
| this.pixelUnitToMillimeter = pixelUnitToMillimeter; |
| } |
| |
| public float getPixelUnitToMillimeter(){ |
| return pixelUnitToMillimeter; |
| } |
| |
| /** |
| * Sets the <tt>area</tt> as a Rectangle. This value can |
| * be null in which case the whole image will be rendered. If the |
| * area is not null, then only the portion of the image it |
| * defines will be rendered. |
| */ |
| public void setArea(Rectangle2D area){ |
| this.area = area; |
| } |
| |
| public Rectangle2D getArea(){ |
| return area; |
| } |
| |
| /** |
| * Sets the list of individual SVG sources. The strings |
| * can be either URLs or file names. Note that invalid |
| * sources (e.g., read-protected files or invalid URLs) |
| * will cause <tt>SVGConverterExceptions</tt> to be |
| * thrown during the transcoding process (see {@link #execute}); |
| */ |
| public void setSources(String[] sources) { |
| if(sources == null){ |
| this.sources = null; |
| } |
| else{ |
| this.sources = new Vector(); |
| for (int i=0; i<sources.length; i++){ |
| if (sources[i] != null){ |
| this.sources.addElement(sources[i]); |
| } |
| } |
| |
| if (this.sources.size() == 0){ |
| this.sources = null; |
| } |
| } |
| } |
| |
| public Vector getSources(){ |
| return sources; |
| } |
| |
| /** |
| * When converting a single source, dst can be a file. |
| * Othewise, it should be a directory. |
| */ |
| public void setDst(File dst) { |
| this.dst = dst; |
| } |
| |
| public File getDst(){ |
| return dst; |
| } |
| |
| /** |
| * Sets the <tt>backgroundColor</tt> value. This can be |
| * null in which case no color will be used to fill the |
| * background before rendering this SVG image. |
| */ |
| public void setBackgroundColor(Color backgroundColor){ |
| this.backgroundColor = backgroundColor; |
| } |
| |
| public Color getBackgroundColor(){ |
| return backgroundColor; |
| } |
| |
| /** |
| * Sets the <tt>mediaType</tt> value. This value controls |
| * the CSS media for which the image should be rendered. It |
| * can be null, in which case no specific media selectors will |
| * apply. If it is not null, it can contain space separated values |
| * of the medias for which the image should be rendered. For example, |
| * "screen", "print" or "scree projection" are valid values. |
| */ |
| public void setMediaType(String mediaType){ |
| this.mediaType = mediaType; |
| } |
| |
| public String getMediaType(){ |
| return mediaType; |
| } |
| |
| /** |
| * Sets the <tt>defaultFontFamily</tt> value. This value controls |
| * the default value for the font-family CSS property when that |
| * property is unspecified. |
| */ |
| public void setDefaultFontFamily(String defaultFontFamily) { |
| this.defaultFontFamily = defaultFontFamily; |
| } |
| |
| public String getDefaultFontFamily() { |
| return defaultFontFamily; |
| } |
| |
| /** |
| * Sets the <tt>alternateStyleSheet</tt> value. This value |
| * controls the CSS alternate stylesheet to select in the |
| * rendered SVG file(s). It may be null, in which case no alternate |
| * stylesheet will be selected. |
| */ |
| public void setAlternateStylesheet(String alternateStylesheet){ |
| this.alternateStylesheet = alternateStylesheet; |
| } |
| |
| public String getAlternateStylesheet(){ |
| return alternateStylesheet; |
| } |
| |
| /** |
| * Defines whether or not input sources should be validated in |
| * the conversion process |
| */ |
| public void setValidate(boolean validate){ |
| this.validate = validate; |
| } |
| |
| public boolean getValidate(){ |
| return validate; |
| } |
| |
| /** |
| * Sets whether or not scripts attached to the DOM using 'onload' |
| * event attribute must be executed before rasterizing. |
| * |
| * @param b true means scripts will be executed |
| */ |
| public void setExecuteOnload(boolean b){ |
| this.executeOnload = b; |
| } |
| |
| /** |
| * Returns true if the scripts attached to the DOM using 'onload' |
| * event attribute is going to be executed before rasterizing, |
| * false otherwise. |
| */ |
| public boolean getExecuteOnload(){ |
| return executeOnload; |
| } |
| |
| /** |
| * Sets the set of allowed script types (i.e., the set of possible |
| * values for the type attribute in the <script> element), |
| * as a comma separated list of allowed values. |
| */ |
| public void setAllowedScriptTypes(String allowedScriptTypes){ |
| this.allowedScriptTypes = allowedScriptTypes; |
| } |
| |
| /** |
| * Returns the list of allowed script types. |
| * |
| * @see #setAllowedScriptTypes |
| */ |
| public String getAllowedScriptTypes(){ |
| return allowedScriptTypes; |
| } |
| |
| /** |
| * Sets whether scripts should only be loaded from the same |
| * location as the documents referencing them. |
| */ |
| public void setConstrainScriptOrigin(boolean constrainScriptOrigin){ |
| this.constrainScriptOrigin = constrainScriptOrigin; |
| } |
| |
| /** |
| * Returns whether scripts can only be loaded from the same |
| * origin as the documents referencing them. |
| */ |
| public boolean getConstrainScriptOrigin(){ |
| return constrainScriptOrigin; |
| } |
| |
| /** |
| * Sets whether or not scripts should be run securely |
| */ |
| public void setSecurityOff(boolean securityOff){ |
| this.securityOff = securityOff; |
| } |
| |
| /** |
| * Returns whether or not scripts will be run securely |
| */ |
| public boolean getSecurityOff(){ |
| return securityOff; |
| } |
| |
| /** |
| * Returns true if f is a File. <code>f</code> is found to be a file if |
| * it exists and is a file. If it does not exist, it is declared |
| * to be a file if it has the same extension as the DestinationType. |
| */ |
| protected boolean isFile(File f){ |
| if (f.exists()){ |
| return f.isFile(); |
| } else { |
| if (f.toString().toLowerCase().endsWith(destinationType.getExtension())){ |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Starts the conversion process. |
| * @throws SVGConverterException thrown if parameters are not set correctly. |
| */ |
| public void execute() throws SVGConverterException { |
| // Compute the set of SVGConverterSource from the source properties |
| // (srcDir and srcFile); |
| // This throws an exception if there is not at least one src file. |
| Vector sources = computeSources(); |
| |
| // Compute the destination files from dest |
| Vector dstFiles = null; |
| if(sources.size() == 1 && dst != null && isFile(dst)){ |
| dstFiles = new Vector(); |
| dstFiles.addElement(dst); |
| } |
| else{ |
| dstFiles = computeDstFiles(sources); |
| } |
| |
| // Now, get the transcoder to use for the operation |
| Transcoder transcoder = destinationType.getTranscoder(); |
| if(transcoder == null) { |
| throw new SVGConverterException(ERROR_CANNOT_ACCESS_TRANSCODER, |
| new Object[]{destinationType.toString()}, |
| true /* fatal error */); |
| } |
| |
| // Now, compute the set of transcoding hints to use |
| Map hints = computeTranscodingHints(); |
| transcoder.setTranscodingHints(hints); |
| |
| // Notify listener that task has been computed |
| if(!controller.proceedWithComputedTask(transcoder, |
| hints, |
| sources, |
| dstFiles)){ |
| return; |
| } |
| |
| // Convert files one by one |
| for(int i = 0 ; i < sources.size() ; i++) { |
| // Get the file from the vector. |
| SVGConverterSource currentFile |
| = (SVGConverterSource)sources.elementAt(i); |
| File outputFile = (File)dstFiles.elementAt(i); |
| |
| createOutputDir(outputFile); |
| transcode(currentFile, outputFile, transcoder); |
| } |
| } |
| |
| /** |
| * Populates a vector with destination files names |
| * computed from the names of the files in the sources vector |
| * and the value of the dst property |
| */ |
| protected Vector computeDstFiles(Vector sources) |
| throws SVGConverterException { |
| Vector dstFiles = new Vector(); |
| if (dst != null) { |
| if (dst.exists() && dst.isFile()) { |
| throw new SVGConverterException(ERROR_CANNOT_USE_DST_FILE); |
| } |
| |
| // |
| // Either dst exist and is a directory or dst does not |
| // exist and we may fail later on in createOutputDir |
| // |
| int n = sources.size(); |
| for(int i=0; i<n; i++){ |
| SVGConverterSource src = (SVGConverterSource)sources.elementAt(i); |
| // Generate output filename from input filename. |
| File outputName = new File(dst.getPath(), |
| getDestinationFile(src.getName())); |
| dstFiles.addElement(outputName); |
| |
| } |
| } else { |
| // |
| // No destination directory has been specified. |
| // Try and create files in the same directory as the |
| // sources. This only work if sources are files. |
| // |
| int n = sources.size(); |
| for(int i=0; i<n; i++){ |
| SVGConverterSource src = (SVGConverterSource)sources.elementAt(i); |
| if (!(src instanceof SVGConverterFileSource)) { |
| throw new SVGConverterException(ERROR_CANNOT_COMPUTE_DESTINATION, |
| new Object[]{src}); |
| } |
| |
| // Generate output filename from input filename. |
| SVGConverterFileSource fs = (SVGConverterFileSource)src; |
| File outputName = new File(fs.getFile().getParent(), |
| getDestinationFile(src.getName())); |
| dstFiles.addElement(outputName); |
| } |
| |
| } |
| |
| return dstFiles; |
| } |
| |
| /** |
| * Populates a vector with the set of SVG files from the |
| * srcDir if it is not null and with the sources (files or URLs) |
| * if any. |
| */ |
| protected Vector computeSources() throws SVGConverterException{ |
| Vector sources = new Vector(); |
| |
| // Check that at least one source has been specified. |
| if (this.sources == null){ |
| throw new SVGConverterException(ERROR_NO_SOURCES_SPECIFIED); |
| } |
| |
| int n = this.sources.size(); |
| for (int i=0; i<n; i++){ |
| String sourceString = (String)(this.sources.elementAt(i)); |
| File file = new File(sourceString); |
| if (file.exists()) { |
| sources.addElement(new SVGConverterFileSource(file)); |
| } else { |
| String[] fileNRef = getFileNRef(sourceString); |
| file = new File(fileNRef[0]); |
| if (file.exists()){ |
| sources.addElement(new SVGConverterFileSource(file, fileNRef[1])); |
| } else{ |
| sources.addElement(new SVGConverterURLSource(sourceString)); |
| } |
| } |
| } |
| |
| return sources; |
| } |
| |
| public String[] getFileNRef(String fileName){ |
| int n = fileName.lastIndexOf("#"); |
| String[] result = {fileName, ""}; |
| if (n > -1){ |
| result[0] = fileName.substring(0, n); |
| if (n+1 < fileName.length()){ |
| result[1] = fileName.substring(n+1); |
| } |
| } |
| |
| return result; |
| } |
| |
| // ----------------------------------------------------------------------- |
| // Internal methods |
| // ----------------------------------------------------------------------- |
| |
| /** |
| * Computes the set of transcoding hints to use for the operation |
| */ |
| protected Map computeTranscodingHints(){ |
| HashMap map = new HashMap(); |
| |
| // Set AOI. ---------------------------------------------------------- |
| if (area != null) { |
| map.put(ImageTranscoder.KEY_AOI, area); |
| } |
| |
| // Set image quality. ------------------------------------------------ |
| if (quality > 0) { |
| map.put(JPEGTranscoder.KEY_QUALITY, new Float(this.quality)); |
| } |
| |
| // Set image indexed. ------------------------------------------------ |
| if (indexed != -1) { |
| map.put(PNGTranscoder.KEY_INDEXED, new Integer(indexed)); |
| } |
| |
| // Set image background color ----------------------------------------- |
| if (backgroundColor != null){ |
| map.put(ImageTranscoder.KEY_BACKGROUND_COLOR, backgroundColor); |
| } |
| |
| // Set image height and width. ---------------------------------------- |
| if (height > 0) { |
| map.put(ImageTranscoder.KEY_HEIGHT, new Float(this.height)); |
| } |
| if (width > 0){ |
| map.put(ImageTranscoder.KEY_WIDTH, new Float(this.width)); |
| } |
| |
| // Set maximum height and width --------------------------------------- |
| if (maxHeight > 0) { |
| map.put(ImageTranscoder.KEY_MAX_HEIGHT, new Float(this.maxHeight)); |
| } |
| if (maxWidth > 0){ |
| map.put(ImageTranscoder.KEY_MAX_WIDTH, new Float(this.maxWidth)); |
| } |
| |
| // Set CSS Media |
| if (mediaType != null){ |
| map.put(ImageTranscoder.KEY_MEDIA, mediaType); |
| } |
| |
| // Set default font-family |
| if (defaultFontFamily != null) { |
| map.put(ImageTranscoder.KEY_DEFAULT_FONT_FAMILY, defaultFontFamily); |
| } |
| |
| // Set alternateStylesheet |
| if (alternateStylesheet != null){ |
| map.put(ImageTranscoder.KEY_ALTERNATE_STYLESHEET, alternateStylesheet); |
| } |
| |
| // Set user stylesheet |
| if (userStylesheet != null){ |
| map.put(ImageTranscoder.KEY_USER_STYLESHEET_URI, userStylesheet); |
| } |
| |
| // Set the user language |
| if (language != null){ |
| map.put(ImageTranscoder.KEY_LANGUAGE, language); |
| } |
| |
| // Sets the millimeters per pixel |
| if (pixelUnitToMillimeter > 0){ |
| map.put(ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER, |
| new Float(pixelUnitToMillimeter)); |
| } |
| |
| // Set validation |
| if (validate){ |
| map.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, |
| new Boolean(validate)); |
| } |
| |
| // Set onload |
| if (executeOnload) { |
| map.put(ImageTranscoder.KEY_EXECUTE_ONLOAD, new Boolean(executeOnload)); |
| } |
| |
| // Set allowed scripts |
| if (allowedScriptTypes != null) { |
| map.put(ImageTranscoder.KEY_ALLOWED_SCRIPT_TYPES, allowedScriptTypes); |
| } |
| |
| // Set constrain script origin |
| if (!constrainScriptOrigin) { |
| map.put(ImageTranscoder.KEY_CONSTRAIN_SCRIPT_ORIGIN, |
| new Boolean(constrainScriptOrigin)); |
| } |
| |
| return map; |
| } |
| |
| /** |
| * Converts the input image to the result image. |
| * with the given transcoder. If a failure happens, the |
| * controller is notified and decides whether to proceed |
| * or not. If it decides to proceed, the converter will |
| * continue processing other files. Otherwise, it will |
| * throw an exception. |
| */ |
| protected void transcode(SVGConverterSource inputFile, |
| File outputFile, |
| Transcoder transcoder) |
| throws SVGConverterException { |
| TranscoderInput input = null; |
| TranscoderOutput output = null; |
| OutputStream outputStream = null; |
| |
| if (!controller.proceedWithSourceTranscoding(inputFile, |
| outputFile)){ |
| return; |
| } |
| |
| try { |
| if (inputFile.isSameAs(outputFile.getPath())) { |
| throw new SVGConverterException(ERROR_SOURCE_SAME_AS_DESTINATION, |
| true /* fatal error */); |
| } |
| |
| // Compute transcoder input. |
| if (!inputFile.isReadable()) { |
| throw new SVGConverterException(ERROR_CANNOT_READ_SOURCE, |
| new Object[]{inputFile.getName()}); |
| } |
| |
| try { |
| InputStream in = inputFile.openStream(); |
| in.close(); |
| } catch(IOException ioe) { |
| throw new SVGConverterException(ERROR_CANNOT_OPEN_SOURCE, |
| new Object[] {inputFile.getName(), |
| ioe.toString()}); |
| } |
| |
| input = new TranscoderInput(inputFile.getURI()); |
| |
| // Compute transcoder output. |
| if (!isWriteable(outputFile)) { |
| throw new SVGConverterException(ERROR_OUTPUT_NOT_WRITEABLE, |
| new Object[] {outputFile.getName()}); |
| } |
| try { |
| outputStream = new FileOutputStream(outputFile); |
| } catch(FileNotFoundException fnfe) { |
| throw new SVGConverterException(ERROR_CANNOT_OPEN_OUTPUT_FILE, |
| new Object[] {outputFile.getName()}); |
| } |
| |
| output = new TranscoderOutput(outputStream); |
| } catch(SVGConverterException e){ |
| boolean proceed = controller.proceedOnSourceTranscodingFailure |
| (inputFile, outputFile, e.getErrorCode()); |
| if (proceed){ |
| return; |
| } else { |
| throw e; |
| } |
| } |
| |
| // Transcode now |
| boolean success = false; |
| try { |
| transcoder.transcode(input, output); |
| success = true; |
| } catch(Exception te) { |
| te.printStackTrace(); |
| try { |
| outputStream.flush(); |
| outputStream.close(); |
| } catch(IOException ioe) {} |
| |
| // Report error to the controller. If controller decides |
| // to stop, throw an exception |
| boolean proceed = controller.proceedOnSourceTranscodingFailure |
| (inputFile, outputFile, ERROR_WHILE_RASTERIZING_FILE); |
| |
| if (!proceed){ |
| throw new SVGConverterException(ERROR_WHILE_RASTERIZING_FILE, |
| new Object[] {outputFile.getName(), |
| te.getMessage()}); |
| } |
| } |
| |
| // Close streams and clean up. |
| try { |
| outputStream.flush(); |
| outputStream.close(); |
| } catch(IOException ioe) { |
| return; |
| } |
| |
| if (success){ |
| controller.onSourceTranscodingSuccess(inputFile, outputFile); |
| } |
| } |
| |
| /** |
| * Get the name of the result image file. |
| * |
| * <P>This method modifies the result filename, it changes the existing |
| * suffix to correspong the result file type. It also adds the suffix |
| * if the file doesn't have one.</P> |
| * |
| * @param file Result file name as a String object. |
| * |
| * @return Name of the file. The directory of the file is not returned. |
| * The returned string is empty if the parameter is not a file. |
| */ |
| protected String getDestinationFile(String file) { |
| int suffixStart; // Location of the first char of |
| // the suffix in a String. |
| String oldName; // Existing filename. |
| String newSuffix = destinationType.getExtension(); |
| // New suffix. |
| |
| oldName = file; |
| // Find the first char of the suffix. |
| suffixStart = oldName.lastIndexOf("."); |
| String dest = null; |
| if (suffixStart != -1) { |
| // Replace existing suffix. |
| dest = new String(oldName.substring(0, suffixStart) + newSuffix); |
| } else { |
| // Add new suffix. |
| dest = new String(oldName + newSuffix); |
| } |
| |
| return dest; |
| } |
| |
| /** |
| * Creates directories for output files if needed. |
| * |
| * @param output Output file with path. |
| * |
| * @throws SVGConverterException Output directory doesn't exist and it can't be created. |
| */ |
| protected void createOutputDir(File output) |
| throws SVGConverterException { |
| |
| File outputDir; // Output directory object. |
| boolean success = true; // false if the output directory |
| // doesn't exist and it can't be created |
| // true otherwise |
| |
| |
| // Create object from output directory. |
| String parentDir = output.getParent(); |
| if (parentDir != null){ |
| outputDir = new File(output.getParent()); |
| if (outputDir.exists() == false) { |
| // Output directory doesn't exist, so create it. |
| success = outputDir.mkdirs(); |
| } else { |
| if (outputDir.isDirectory() == false) { |
| // File, which have a same name as the output directory, exists. |
| // Create output directory. |
| success = outputDir.mkdirs(); |
| } |
| } |
| } |
| |
| if (!success) { |
| throw new SVGConverterException(ERROR_UNABLE_TO_CREATE_OUTPUT_DIR); |
| } |
| } |
| |
| /** |
| * Checks if the application is allowed to write to the file. |
| * |
| * @param file File to be checked. |
| * |
| * @return <tt>true</tt> if the file is writeable and <tt>false</tt> otherwise. |
| */ |
| protected boolean isWriteable(File file) { |
| if (file.exists()) { |
| // Check the existing file. |
| if (!file.canWrite()) { |
| return false; |
| } |
| } else { |
| // Check the file that doesn't exist yet. |
| // Create a new file. The file is writeable if |
| // the creation succeeds. |
| try { |
| file.createNewFile(); |
| } catch(IOException ioe) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| // ----------------------------------------------------------------------- |
| // Inner classes |
| // ----------------------------------------------------------------------- |
| |
| /** |
| * Convenience class to filter svg files |
| */ |
| public static class SVGFileFilter implements FileFilter { |
| public static final String SVG_EXTENSION = ".svg"; |
| |
| public boolean accept(File file){ |
| if (file != null && file.getName().toLowerCase().endsWith(SVG_EXTENSION)){ |
| return true; |
| } |
| |
| return false; |
| } |
| } |
| |
| } |
| |