blob: 8f7ee383bb30d9bafbf6258c04d806f3eaebdda1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.xmlgraphics.ps;
import java.awt.Dimension;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.image.RenderedImage;
import java.io.IOException;
/**
* Abstract helper class for generating PostScript forms.
*/
public class ImageFormGenerator extends FormGenerator {
//Mode 1 (RenderedImage)
private RenderedImage image;
//Mode 2 (ImageEncoder)
private ImageEncoder encoder;
private ColorSpace colorSpace;
private int bitsPerComponent = 8;
private boolean invertImage;
private Dimension pixelDimensions;
/**
* Main constructor.
* @param formName the form's name
* @param title the form's title or null
* @param dimensions the form's dimensions in units (usually points)
* @param image the image
* @param invertImage true if the image shall be inverted
*/
public ImageFormGenerator(String formName, String title,
Dimension2D dimensions,
RenderedImage image, boolean invertImage) {
super(formName, title, dimensions);
this.image = image;
this.encoder = ImageEncodingHelper.createRenderedImageEncoder(image);
this.invertImage = invertImage;
this.pixelDimensions = new Dimension(image.getWidth(), image.getHeight());
}
/**
* Main constructor.
* @param formName the form's name
* @param title the form's title or null
* @param dimensions the form's dimensions in units (usually points)
* @param dimensionsPx the form's dimensions in pixels
* @param encoder the image encoder
* @param colorSpace the target color space
* @param bitsPerComponent the bits per component
* @param invertImage true if the image shall be inverted
*/
public ImageFormGenerator(String formName, String title,
Dimension2D dimensions, Dimension dimensionsPx,
ImageEncoder encoder,
ColorSpace colorSpace, int bitsPerComponent, boolean invertImage) {
super(formName, title, dimensions);
this.pixelDimensions = dimensionsPx;
this.encoder = encoder;
this.colorSpace = colorSpace;
this.bitsPerComponent = bitsPerComponent;
this.invertImage = invertImage;
}
/**
* Main constructor.
* @param formName the form's name
* @param title the form's title or null
* @param dimensions the form's dimensions in units (usually points)
* @param dimensionsPx the form's dimensions in pixels
* @param encoder the image encoder
* @param colorSpace the target color space
* @param invertImage true if the image shall be inverted
*/
public ImageFormGenerator(String formName, String title,
Dimension2D dimensions, Dimension dimensionsPx,
ImageEncoder encoder,
ColorSpace colorSpace, boolean invertImage) {
this(formName, title, dimensions, dimensionsPx, encoder, colorSpace, 8, invertImage);
}
/**
* Returns the name of the data segment associated with this image form.
* @return the data segment name
*/
protected String getDataName() {
return getFormName() + ":Data";
}
private String getAdditionalFilters(PSGenerator gen) {
String implicitFilter = encoder.getImplicitFilter();
if (implicitFilter != null) {
return "/ASCII85Decode filter " + implicitFilter + " filter";
} else {
if (gen.getPSLevel() >= 3) {
return "/ASCII85Decode filter";
} else {
return "/ASCII85Decode filter /RunLengthDecode filter";
}
}
}
/** {@inheritDoc} */
protected void generatePaintProc(PSGenerator gen) throws IOException {
if (gen.getPSLevel() == 2) {
gen.writeln(" userdict /i 0 put"); //rewind image data
} else {
gen.writeln(" " + getDataName() + " 0 setfileposition"); //rewind image data
}
String dataSource;
if (gen.getPSLevel() == 2) {
dataSource = "{ " + getDataName() + " i get /i i 1 add store } bind";
} else {
dataSource = getDataName();
if (gen.getPSLevel() >= 3) {
String implicitFilter = encoder.getImplicitFilter();
if (implicitFilter == null) {
dataSource += " /FlateDecode filter";
}
}
}
AffineTransform at = new AffineTransform();
at.scale(getDimensions().getWidth(), getDimensions().getHeight());
gen.concatMatrix(at);
PSDictionary imageDict = new PSDictionary();
imageDict.put("/DataSource", dataSource);
if (this.image != null) {
PSImageUtils.writeImageCommand(this.image, imageDict, gen);
} else {
imageDict.put("/BitsPerComponent", Integer.toString(this.bitsPerComponent));
PSImageUtils.writeImageCommand(imageDict,
this.pixelDimensions, this.colorSpace, this.invertImage,
gen);
}
}
/** {@inheritDoc} */
protected void generateAdditionalDataStream(PSGenerator gen) throws IOException {
gen.writeln("/" + getDataName() + " currentfile");
gen.writeln(getAdditionalFilters(gen));
if (gen.getPSLevel() == 2) {
//Creates a data array from the inline file
gen.writeln("{ /temp exch def ["
+ " { temp 16384 string readstring not {exit } if } loop ] } exec");
} else {
gen.writeln("/ReusableStreamDecode filter");
}
PSImageUtils.compressAndWriteBitmap(encoder, gen);
gen.writeln("def");
}
}