--- /dev/null
+/*
+ * Copyright 2005 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.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.apps;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+// commons logging
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Provides FOP specific URI resolution.
+ * This is the default URIResolver {@link FOUserAgent} will use unless overidden.
+ * @see javax.xml.transform.URIResolver
+ */
+public class FOURIResolver
+ implements javax.xml.transform.URIResolver
+{
+ private Log log = LogFactory.getLog("FOP");
+
+ /**
+ * Called by the processor through {@link FOUserAgent} when it encounters an uri in an external-graphic element.
+ * (see also {@link javax.xml.transform.URIResolver#resolve(String, String)}
+ * This resolver will allow URLs without a scheme, i.e. it assumes 'file:' as the default
+ * scheme. It also allows relative URLs with scheme, e.g. file:../../abc.jpg which is
+ * not strictly RFC compliant as long as the scheme is the same as the scheme of the
+ * base URL. If the base URL is null a 'file:' URL referencing the current directory is used as
+ * the base URL.
+ * If the method is successful it will return a Source of type
+ * {@link javax.xml.transform.stream.StreamSource} with its SystemID set to the resolved
+ * URL used to open the underlying InputStream.
+ *
+ * @param href An href attribute, which may be relative or absolute.
+ * @param base The base URI against which the first argument will be made absolute if the absolute URI is required.
+ * @return A {@link javax.xml.transform.Source} object, or null if the href cannot be resolved.
+ * @throws TransformerException Never thrown by this implementation.
+ * @see javax.xml.transform.URIResolver#resolve(String, String)
+ */
+ public Source resolve(String href, String base)
+ throws javax.xml.transform.TransformerException
+ {
+ URL absoluteURL = null;
+ URL baseURL = toBaseURL(base);
+ if (baseURL == null) {
+ // We don't have a valid baseURL just use the URL as given
+ try {
+ absoluteURL = new URL(href);
+ } catch (MalformedURLException mue) {
+ try {
+ // the above failed, we give it another go in case
+ // the href contains only a path then file: is assumed
+ absoluteURL = new URL("file:" + href);
+ } catch (MalformedURLException mfue) {
+ log.error("Error with URL '" + href + "': " + mue.getMessage(), mue);
+ return null;
+ }
+ }
+ } else {
+ try {
+ /*
+ This piece of code is based on the following statement in RFC2396 section 5.2:
+
+ 3) If the scheme component is defined, indicating that the reference
+ starts with a scheme name, then the reference is interpreted as an
+ absolute URI and we are done. Otherwise, the reference URI's
+ scheme is inherited from the base URI's scheme component.
+
+ Due to a loophole in prior specifications [RFC1630], some parsers
+ allow the scheme name to be present in a relative URI if it is the
+ same as the base URI scheme. Unfortunately, this can conflict
+ with the correct parsing of non-hierarchical URI. For backwards
+ compatibility, an implementation may work around such references
+ by removing the scheme if it matches that of the base URI and the
+ scheme is known to always use the <hier_part> syntax.
+
+ The URL class does not implement this work around, so we do.
+ */
+
+ String scheme = baseURL.getProtocol() + ":";
+ if (href.startsWith(scheme)) {
+ href = href.substring(scheme.length());
+ }
+ absoluteURL = new URL(baseURL, href);
+ } catch (MalformedURLException mfue) {
+ log.error("Error with URL '" + href + "': " + mfue.getMessage(), mfue);
+ return null;
+ }
+ }
+ try {
+ return new StreamSource(absoluteURL.openStream(), absoluteURL.toExternalForm());
+ } catch (java.io.IOException ioe) {
+ log.error("Error with opening URL '" + href + "': " + ioe.getMessage(), ioe);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the base URL as a java.net.URL.
+ * If the base URL is not set a default URL pointing to the
+ * current directory is returned.
+ * @param baseURL the base URL
+ * @returns the base URL as java.net.URL
+ */
+ private URL toBaseURL(String baseURL)
+ {
+ try {
+ return new URL(baseURL == null
+ ? new java.io.File("").toURL().toExternalForm()
+ : baseURL);
+ } catch (MalformedURLException mfue) {
+ log.error("Error with base URL: " + mfue.getMessage(), mfue);
+ }
+ return null;
+ }
+
+}
// Java
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamSource;
// avalon configuration
import org.apache.avalon.framework.configuration.Configuration;
private XMLHandlerRegistry xmlHandlers = new XMLHandlerRegistry();
private String baseURL;
+
+ /** A user settable URI Resolver */
+ private URIResolver uriResolver = null;
+ /** Our default resolver if none is set */
+ private URIResolver foURIResolver = new FOURIResolver();
+
private PDFEncryptionParams pdfEncryptionParams;
private float px2mm = DEFAULT_PX2MM;
private Map rendererOptions = new java.util.HashMap();
* @return the base URL
*/
public String getBaseURL() {
- if ((this.baseURL == null) || (this.baseURL.trim().equals(""))) {
- return "file:.";
- } else {
- return this.baseURL;
- }
+ return this.baseURL;
+ }
+
+ /**
+ * Sets the URI Resolver.
+ * @param uriResolver the new URI resolver
+ */
+ public void setURIResolver(URIResolver uriResolver) {
+ this.uriResolver = uriResolver;
+ }
+
+ /**
+ * Returns the URI Resolver.
+ * @return the URI Resolver
+ */
+ public URIResolver getURIResolver() {
+ return this.uriResolver != null ? this.uriResolver : this.foURIResolver;
}
/**
/**
- * Get an input stream for a reference. Subclass FOUserAgent and override this method to
- * do custom URI to InputStream resolution.
+ * Get a stream source for a reference. Subclass FOUserAgent and override this method to
+ * do custom URI to {@link javax.xml.transform.stream.StreamSource} resolution.
+ * Alternatively set your own {@link javax.xml.transform.URIResolver} on the FOUserAgent.
* Temporary solution until the API is better.
* @param uri URI to access
- * @return InputStream for accessing the resource.
+ * @return StreamSource for accessing the resource.
* @throws IOException in case of an I/O problem
*/
- public InputStream getStream(String uri) throws IOException {
- //The default implementation does noting. Subclass FOUserAgent to add custom behaviour.
+ public StreamSource getStream(String uri) throws IOException {
+ Source source = null;
+ try {
+ source = getURIResolver().resolve(uri, getBaseURL());
+ } catch (TransformerException te) {
+ log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
+ }
+ if (source != null) {
+ if (source instanceof StreamSource) {
+ return (StreamSource)source;
+ } else {
+ log.error("Attempt to resolve URI returned unknown source");
+ }
+ }
return null;
}
* Gets the output File.
* @return the output File
*/
- public File getOutputFile(){
+ public File getOutputFile() {
return outputFile;
}
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
/* if width and height are zero, get the bounds of the content. */
try {
- String baseDir = getUserAgent().getBaseURL();
- if (baseDir != null) {
- ((SVGOMDocument)doc).setURLObject(new URL(baseDir));
+ URL baseURL = new URL(getUserAgent().getBaseURL() == null
+ ? new java.io.File("").toURL().toExternalForm()
+ : getUserAgent().getBaseURL());
+ if (baseURL != null) {
+ ((SVGOMDocument)doc).setURLObject(baseURL);
}
} catch (Exception e) {
getLogger().error("Could not set base URL for svg", e);
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
* Load the bitmap.
* This laods the bitmap data from the bitmap image.
*
- * @param ua the user agent
* @return true if it was loaded successfully
*/
protected boolean loadBitmap() {
int hpos = 22; // offset positioning for w and height in bmp files
int[] headermap = new int[54];
int filepos = 0;
- byte palette[] = null;
+ byte[] palette = null;
try {
boolean eof = false;
while ((!eof) && (filepos < 54)) {
if (input == -1) {
eof = true;
} else if (count2 >= 0) {
- palette[countr * 3 + count2] =
- (byte)(input & 0xFF);
+ palette[countr * 3 + count2] = (byte)(input & 0xFF);
}
count2--;
filepos++;
int count = 0;
inputStream.skip((long)(imagestart - filepos));
while ((input = inputStream.read()) != -1) {
- temp[count++] = input;
+ if (count >= temp.length) {
+ log.warn("Data longer than expected while loading image");
+ break;
+ } else {
+ temp[count++] = input;
+ }
}
inputStream.close();
inputStream = null;
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
// Java
import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
-import java.net.MalformedURLException;
import java.lang.reflect.Constructor;
+import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
+import javax.xml.transform.stream.StreamSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
* Create FopImage objects (with a configuration file - not yet implemented).
* @author Eric SCHAEFFER
*/
-public class ImageFactory {
+public final class ImageFactory {
/**
* logging instance
*/
protected static Log log = LogFactory.getLog(FopImage.class);
-
+
private static ImageFactory factory = new ImageFactory();
+ private HashMap imageMimeTypes = new HashMap();
+
private ImageCache cache = new ContextImageCache(true);
private ImageFactory() {
+ /* @todo The mappings set up below of image mime types to implementing
+ * classes should be made externally configurable
+ */
+ ImageProvider jaiImage = new ImageProvider("JAIImage", "org.apache.fop.image.JAIImage");
+ ImageProvider jimiImage = new ImageProvider("JIMIImage", "org.apache.fop.image.JimiImage");
+ ImageProvider imageIoImage = new ImageProvider(
+ "ImageIOImage", "org.apache.fop.image.ImageIoImage");
+ ImageProvider gifImage = new ImageProvider("GIFImage", "org.apache.fop.image.GifImage");
+ ImageProvider jpegImage = new ImageProvider("JPEGImage", "org.apache.fop.image.JpegImage");
+ ImageProvider bmpImage = new ImageProvider("BMPImage", "org.apache.fop.image.BmpImage");
+ ImageProvider epsImage = new ImageProvider("EPSImage", "org.apache.fop.image.EPSImage");
+ ImageProvider pngImage = new ImageProvider("PNGImage", "org.apache.fop.image.PNGImage");
+ ImageProvider tiffImage = new ImageProvider("TIFFImage", "org.apache.fop.image.TIFFImage");
+ ImageProvider xmlImage = new ImageProvider("XMLImage", "org.apache.fop.image.XMLImage");
+
+ ImageMimeType imt = new ImageMimeType("image/gif");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(jaiImage);
+ imt.addProvider(imageIoImage);
+ imt.addProvider(jimiImage);
+ imt.addProvider(gifImage);
+
+ imt = new ImageMimeType("image/jpeg");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(jpegImage);
+
+ imt = new ImageMimeType("image/bmp");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(bmpImage);
+
+ imt = new ImageMimeType("image/eps");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(epsImage);
+
+ imt = new ImageMimeType("image/png");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(pngImage);
+
+ imt = new ImageMimeType("image/tga");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(jaiImage);
+ imt.addProvider(imageIoImage);
+ imt.addProvider(jimiImage);
+
+ imt = new ImageMimeType("image/tiff");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(tiffImage);
+
+ imt = new ImageMimeType("image/svg+xml");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(xmlImage);
+
+ imt = new ImageMimeType("text/xml");
+ imageMimeTypes.put(imt.getMimeType(), imt);
+ imt.addProvider(xmlImage);
+
}
/**
* @param ua the user agent context
* @return the fop image instance
*/
- public static FopImage loadImage(String href, FOUserAgent ua) {
+ public FopImage loadImage(String href, FOUserAgent ua) {
- InputStream in = openStream(href, ua);
-
- if (in == null) {
+ StreamSource source = openStream(href, ua);
+ if (source == null) {
return null;
}
- // If not, check image type
+ InputStream in = source.getInputStream();
+ //Make sure the InputStream is decorated with a BufferedInputStream
+ if (!(in instanceof java.io.BufferedInputStream)) {
+ in = new java.io.BufferedInputStream(in);
+ }
+
+ // Check image type
FopImage.ImageInfo imgInfo = null;
try {
- imgInfo = ImageReaderFactory.make(
- href, in, ua);
+ imgInfo = ImageReaderFactory.make(source.getSystemId(), in, ua);
} catch (Exception e) {
log.error("Error while recovering image information ("
+ href + ") : " + e.getMessage(), e);
}
// Associate mime-type to FopImage class
String imgMimeType = imgInfo.mimeType;
- String imgClassName = getImageClassName(imgMimeType);
- if (imgClassName == null) {
+ Class imageClass = getImageClass(imgMimeType);
+ if (imageClass == null) {
log.error("Unsupported image type ("
+ href + "): " + imgMimeType);
return null;
// load the right image class
// return new <FopImage implementing class>
Object imageInstance = null;
- Class imageClass = null;
try {
- imageClass = Class.forName(imgClassName);
Class[] imageConstructorParameters = new Class[1];
imageConstructorParameters[0] = org.apache.fop.image.FopImage.ImageInfo.class;
- Constructor imageConstructor =
- imageClass.getDeclaredConstructor(
- imageConstructorParameters);
+ Constructor imageConstructor = imageClass.getDeclaredConstructor(
+ imageConstructorParameters);
Object[] initArgs = new Object[1];
initArgs[0] = imgInfo;
imageInstance = imageConstructor.newInstance(initArgs);
- } catch (ClassNotFoundException cnfe) {
- log.error("Class " + imgClassName + " not found. Check that Jimi/JAI is in classpath");
- return null;
} catch (java.lang.reflect.InvocationTargetException ex) {
Throwable t = ex.getTargetException();
String msg;
return null;
} catch (InstantiationException ie) {
log.error("Error creating FopImage object ("
- + href + "): Could not instantiate " + imgClassName + " instance");
+ + href + "): Could not instantiate " + imageClass.getName() + " instance");
return null;
} catch (Exception ex) {
log.error("Error creating FopImage object ("
}
/**
- * Create an FopImage objects.
+ * Create a StreamSource objects.
* @param href image URL as a String
* @param ua user agent
- * @return a new FopImage object
+ * @return a new StreamSource object
*/
- protected static InputStream openStream(String href, FOUserAgent ua) {
+ protected StreamSource openStream(String href, FOUserAgent ua) {
- // Get the absolute URL
- URL absoluteURL = null;
- InputStream in = null;
+ StreamSource in = null;
try {
in = ua.getStream(href);
+ href + "): " + ioe.getMessage(), ioe);
return null;
}
- if (in == null) {
- try {
- // try url as complete first, this can cause
- // a problem with relative uri's if there is an
- // image relative to where fop is run and relative
- // to the base dir of the document
- try {
- absoluteURL = new URL(href);
- } catch (MalformedURLException mue) {
- // if the href contains only a path then file is assumed
- absoluteURL = new URL("file:" + href);
- }
- in = absoluteURL.openStream();
- } catch (MalformedURLException mfue) {
- log.error("Error with image URL: " + mfue.getMessage(), mfue);
- return null;
- } catch (Exception e) {
- // maybe relative
- if (ua.getBaseURL() == null) {
- log.error("Error with image URL: " + e.getMessage()
- + " and no base URL is specified", e);
- return null;
- }
- try {
- absoluteURL = new URL(ua.getBaseURL() + absoluteURL.getFile());
- } catch (MalformedURLException e_context) {
- // pb context url
- log.error("Invalid Image URL - error on relative URL: "
- + e_context.getMessage(), e_context);
- return null;
- }
- }
- } /* if (in == null) */
-
- try {
- if (in == null && absoluteURL != null) {
- in = absoluteURL.openStream();
- }
- if (in == null) {
- log.error("Could not resolve URI for image: " + href);
- return null;
- }
+ return in;
+ }
- //Make sure the InputStream is decorated with a BufferedInputStream
- if (in instanceof java.io.BufferedInputStream) {
- return in;
- } else {
- return new java.io.BufferedInputStream(in);
- }
- } catch (Exception e) {
- log.error("Error while opening stream for ("
- + href + "): " + e.getMessage(), e);
+ private Class getImageClass(String imgMimeType) {
+ ImageMimeType imt = (ImageMimeType)imageMimeTypes.get(imgMimeType);
+ if (imt == null) {
return null;
}
- }
-
- private static String getImageClassName(String imgMimeType) {
- String imgClassName = null;
- if ("image/gif".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.GifImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/jpeg".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.JpegImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/bmp".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.BmpImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/eps".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.EPSImage";
- } else if ("image/png".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.PNGImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/tga".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.JimiImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/tiff".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.TIFFImage";
- // imgClassName = "org.apache.fop.image.JAIImage";
- } else if ("image/svg+xml".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.XMLImage";
- } else if ("text/xml".equals(imgMimeType)) {
- imgClassName = "org.apache.fop.image.XMLImage";
- }
- return imgClassName;
+ return imt.getFirstImplementingClass();
}
}
class BasicImageCache implements ImageCache {
private Set invalid = Collections.synchronizedSet(new java.util.HashSet());
- private Map contextStore = Collections.synchronizedMap(new java.util.HashMap());
+ //private Map contextStore = Collections.synchronizedMap(new java.util.HashMap());
public FopImage getImage(String url, FOUserAgent context) {
if (invalid.contains(url)) {
}
+/**
+ * Encapsulates a class of type FopImage by holding its class name.
+ * This allows dynamic loading of the class at runtime.
+ */
+class ImageProvider {
+
+ private String name = null;
+
+ private String className = null;
+
+ private boolean checked = false;
+
+ private Class clazz = null;
+
+ /**
+ * Creates an ImageProvider with a given name and implementing class.
+ * The class name should refer to a class of type {@link FopImage}.
+ * However, this is not checked on construction.
+ * @param name The name of the provider
+ * @param className The full class name of the class implementing this provider
+ */
+ public ImageProvider(String name, String className) {
+ setName(name);
+ setClassName(className);
+ }
+
+ /**
+ * Returns the provider name.
+ * @return The provider name
+ */
+ public String getName() {
+ return name;
+ }
+
+ private void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the implementing class name.
+ * @return The implementing class name
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ private void setClassName(String className) {
+ this.className = className;
+ }
+
+ /**
+ * Returns the implementing class as a {@link Class} object.
+ * @return The implementing class or null if it couldn't be loaded.
+ */
+ public Class getImplementingClass() {
+ if (!checked) {
+ try {
+ clazz = Class.forName(getClassName());
+ } catch (ClassNotFoundException cnfe) {
+ //nop
+ }
+ checked = true;
+ }
+ return clazz;
+ }
+}
+
+/**
+ * Holds a mime type for a particular image format plus a list of
+ * {@link ImageProvider} objects which support the particular image format.
+ */
+class ImageMimeType {
+
+ private String mimeType = null;
+
+ private List providers = null;
+
+ /**
+ * Constructor for a particular mime type.
+ * @param mimeType The mime type
+ */
+ public ImageMimeType(String mimeType) {
+ setMimeType(mimeType);
+ }
+
+ /**
+ * Returns the mime type.
+ * @return The mime type
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ private void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ /**
+ * Returns the class from the first available provider.
+ * @return The first available class or null if none can be found
+ */
+ public Class getFirstImplementingClass() {
+ if (providers == null) {
+ return null;
+ }
+ for (Iterator it = providers.iterator(); it.hasNext();) {
+ ImageProvider ip = (ImageProvider)it.next();
+ Class clazz = ip.getImplementingClass();
+ if (clazz != null) {
+ return clazz;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds a new provider.
+ * The provider is added to the end of the current provider list.
+ * @param The new provider to add
+ */
+ public void addProvider(ImageProvider provider) {
+ if (providers == null) {
+ providers = new ArrayList(4); // Assume we only have a few providers
+ }
+ if (!providers.contains(provider)) {
+ providers.add(provider);
+ }
+ }
+}
+
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
if (!valid || image != null) {
return image;
}
- image = ImageFactory.loadImage(url, userAgent);
+ image = ImageFactory.getInstance().loadImage(url, userAgent);
if (image == null) {
cache.invalidateImage(url, userAgent);
valid = false;
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 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.
public class BMPReader implements ImageReader {
/** Length of the BMP header */
- protected static final int BMP_SIG_LENGTH = 26;
+ protected static final int BMP_SIG_LENGTH = 46;
+
+ /** offset to width */
+ private static final int WIDTH_OFFSET = 18;
+ /** offset to height */
+ private static final int HEIGHT_OFFSET = 18;
+ /** offset to horizontal res */
+ private static final int HRES_OFFSET = 38;
+ /** offset to vertical res */
+ private static final int VRES_OFFSET = 42;
/** @see org.apache.fop.image.analyser.ImageReader */
public FopImage.ImageInfo verifySignature(String uri, InputStream bis,
info.mimeType = getMimeType();
// little endian notation
- int byte1 = header[18] & 0xff;
- int byte2 = header[19] & 0xff;
- int byte3 = header[20] & 0xff;
- int byte4 = header[21] & 0xff;
+ int byte1 = header[WIDTH_OFFSET] & 0xff;
+ int byte2 = header[WIDTH_OFFSET + 1] & 0xff;
+ int byte3 = header[WIDTH_OFFSET + 2] & 0xff;
+ int byte4 = header[WIDTH_OFFSET + 3] & 0xff;
long l = (long) ((byte4 << 24) | (byte3 << 16)
| (byte2 << 8) | byte1);
info.width = (int) (l & 0xffffffff);
- byte1 = header[22] & 0xff;
- byte2 = header[23] & 0xff;
- byte3 = header[24] & 0xff;
- byte4 = header[25] & 0xff;
+ byte1 = header[HEIGHT_OFFSET] & 0xff;
+ byte2 = header[HEIGHT_OFFSET + 1] & 0xff;
+ byte3 = header[HEIGHT_OFFSET + 2] & 0xff;
+ byte4 = header[HEIGHT_OFFSET + 3] & 0xff;
l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
info.height = (int) (l & 0xffffffff);
+
+ byte1 = header[HRES_OFFSET] & 0xff;
+ byte2 = header[HRES_OFFSET + 1] & 0xff;
+ byte3 = header[HRES_OFFSET + 2] & 0xff;
+ byte4 = header[HRES_OFFSET + 3] & 0xff;
+ l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
+ if (l > 0) {
+ info.dpiHorizontal = l / 39.37d;
+ }
+
+ byte1 = header[VRES_OFFSET] & 0xff;
+ byte2 = header[VRES_OFFSET + 1] & 0xff;
+ byte3 = header[VRES_OFFSET + 2] & 0xff;
+ byte4 = header[VRES_OFFSET + 3] & 0xff;
+ l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1);
+ if (l > 0) {
+ info.dpiVertical = l / 39.37d;
+ }
+
return info;
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>BMP external-graphic 300dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg300dpi.bmp"/>EOG
+ </fo:block>
+ <fo:block>BMP external-graphic 72dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg72dpi.bmp"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="46091" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+ <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+ <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+ <eval expected="192043" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>EPS external-graphic</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/barcode.eps"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="136000" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="136000" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="43000" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="43000" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>GIF external-graphic</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg72dpi.gif"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="192000" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="192000" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="192000" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="192000" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>JPEG external-graphic 300dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg300dpi.jpg"/>EOG
+ </fo:block>
+ <fo:block>JPEG external-graphic 72dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg72dpi.jpg"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>PNG external-graphic 300dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg300dpi.png"/>EOG
+ </fo:block>
+ <fo:block>PNG external-graphic 72dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg72dpi.png"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ <!-- Due to unit computations there is a little difference to the expected 192000 -->
+ <eval expected="191975" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+ <eval expected="191975" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+ <eval expected="191975" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+ <eval expected="191975" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>SVG external-graphic</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/img.svg"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="100000" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="100000" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="100000" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="100000" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>TIFF external-graphic 300dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg300dpi.tif"/>EOG
+ </fo:block>
+ <fo:block>TIFF external-graphic 72dpi</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg72dpi.tif"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+ <eval expected="192000" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks URI references to external-graphics.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="210mm" page-height="297mm">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal" white-space-collapse="true">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>plain external-graphic (relative URI)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="../../resources/images/bgimg300dpi.jpg"/>EOG
+ </fo:block>
+ <fo:block>plain external-graphic (relative URI with scheme)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="file:../../resources/images/bgimg300dpi.jpg"/>EOG
+ </fo:block>
+ <!-- Commented out until portable solution found
+ <fo:block>plain external-graphic (absolute URI)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="/home/mm/fop-trunk/test/resources/images/bgimg300dpi.jpg"/>EOG
+ </fo:block>
+ <fo:block>plain external-graphic (absolute URI with scheme)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="file:/home/mm/fop-trunk/test/resources/images/bgimg300dpi.jpg"/>EOG
+ </fo:block>
+ -->
+ <fo:block>plain external-graphic (relative URI using url(...) function)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="url(../../resources/images/bgimg300dpi.jpg)"/>EOG
+ </fo:block>
+ <fo:block>plain external-graphic (absolute HTTP URI)</fo:block>
+ <fo:block>
+ <fo:external-graphic src="http://xml.apache.org/fop/images/logo.jpg"/>EOG
+ </fo:block>
+ <fo:block>EOF</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[2]/lineArea/viewport/@bpda"/>
+ <eval expected="46080" xpath="//flow/block[4]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[4]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[4]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[4]/lineArea/viewport/@bpda"/>
+ <eval expected="46080" xpath="//flow/block[6]/lineArea/viewport/@ipd"/>
+ <eval expected="46080" xpath="//flow/block[6]/lineArea/viewport/@ipda"/>
+ <eval expected="46080" xpath="//flow/block[6]/lineArea/viewport/@bpd"/>
+ <eval expected="46080" xpath="//flow/block[6]/lineArea/viewport/@bpda"/>
+ <eval expected="120000" xpath="//flow/block[8]/lineArea/viewport/@ipd"/>
+ <eval expected="120000" xpath="//flow/block[8]/lineArea/viewport/@ipda"/>
+ <eval expected="65000" xpath="//flow/block[8]/lineArea/viewport/@bpd"/>
+ <eval expected="65000" xpath="//flow/block[8]/lineArea/viewport/@bpda"/>
+ </checks>
+</testcase>
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 136 43
+%%HiResBoundingBox: 0 0 135.6548 42.525
+%%Creator: Barcode4J (http://barcode4j.krysalis.org)
+%%CreationDate: 2005-08-15T10:58:35
+%%LanguageLevel: 1
+%%EndComments
+%%BeginProlog
+%%BeginProcSet: barcode4j-procset 1.0
+/rf {
+newpath
+4 -2 roll moveto
+dup neg 0 exch rlineto
+exch 0 rlineto
+0 neg exch rlineto
+closepath fill
+} def
+/ct {
+moveto dup stringwidth
+2 div neg exch 2 div neg exch
+rmoveto show
+} def
+/jt {
+4 -1 roll dup stringwidth pop
+5 -2 roll 1 index sub
+3 -1 roll sub
+2 index length
+1 sub div
+0 4 -1 roll 4 -1 roll 5 -1 roll
+moveto ashow
+} def
+%%EndProcSet: barcode4j-procset 1.0
+%%EndProlog
+9.3555 42.525 0.9356 38.525 rf
+11.2266 42.525 0.9356 38.525 rf
+14.0332 42.525 1.8711 34.525 rf
+17.7755 42.525 0.9356 34.525 rf
+20.5821 42.525 0.9356 34.525 rf
+22.4532 42.525 2.8066 34.525 rf
+26.1954 42.525 0.9356 34.525 rf
+29.9376 42.525 1.8711 34.525 rf
+32.7442 42.525 1.8711 34.525 rf
+37.422 42.525 0.9356 34.525 rf
+41.1642 42.525 0.9356 34.525 rf
+43.9709 42.525 0.9356 34.525 rf
+48.6486 42.525 0.9356 34.525 rf
+50.5197 42.525 0.9356 34.525 rf
+/Helvetica findfont 7.999999999999999 scalefont setfont
+(4) 3.2744 0.5644 ct
+/Helvetica findfont 7.999999999999999 scalefont setfont
+(194586) 13.0977 50.5197 0.5644 jt
+52.3908 42.525 0.9356 38.525 rf
+54.2619 42.525 0.9356 38.525 rf
+56.133 42.525 0.9356 34.525 rf
+59.8752 42.525 0.9356 34.525 rf
+62.6818 42.525 2.8066 34.525 rf
+67.3596 42.525 0.9356 34.525 rf
+69.2307 42.525 0.9356 34.525 rf
+72.0373 42.525 2.8066 34.525 rf
+75.7795 42.525 0.9356 34.525 rf
+78.5862 42.525 2.8066 34.525 rf
+82.3284 42.525 2.8066 34.525 rf
+87.0061 42.525 0.9356 34.525 rf
+88.8772 42.525 0.9356 34.525 rf
+90.7483 42.525 0.9356 34.525 rf
+/Helvetica findfont 7.999999999999999 scalefont setfont
+(705506) 57.0685 94.4905 0.5644 jt
+95.4261 42.525 0.9356 38.525 rf
+97.2972 42.525 0.9356 38.525 rf
+107.5882 34.525 0.9356 30.525 rf
+109.4593 34.525 1.8711 30.525 rf
+114.1371 34.525 1.8711 30.525 rf
+116.9437 34.525 0.9356 30.525 rf
+118.8148 34.525 0.9356 30.525 rf
+120.6859 34.525 0.9356 30.525 rf
+124.4281 34.525 1.8711 30.525 rf
+/Helvetica findfont 7.999999999999999 scalefont setfont
+(04) 116.9437 35.0894 ct
+%%EOF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
+<!--
+ Copyright 2005 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.
+-->
+<!-- $Id: font-size-absolute.xml 230445 2005-08-05 11:30:05Z cbowditch $ -->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <g style="fill:red; stroke:#000000">
+ <rect x="0" y="0" width="15" height="15"/>
+ <rect x="5" y="5" width="15" height="15"/>
+ </g>
+</svg>