blob: 643dcb70228a009b2e81d9c43db4358a48dbf20f [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.fop.afp;
import java.awt.Point;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.util.AbstractPaintingState;
/**
* This keeps information about the current painting state when writing to an AFP datastream.
*/
public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
implements Cloneable {
private static final long serialVersionUID = 8206711712452344473L;
private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
/** the portrait rotation */
private int portraitRotation = 0;
/** the landscape rotation */
private int landscapeRotation = 270;
/** color image support */
private boolean colorImages = false;
/** true if certain image formats may be embedded unchanged in their native format. */
private boolean nativeImagesSupported = false;
/** true if CMYK images (requires IOCA FS45 suppport on the target platform) may be generated */
private boolean cmykImagesSupported;
/** default value for image depth */
private int bitsPerPixel = 8;
/** the output resolution */
private int resolution = 240; // 240 dpi
/** the current page */
private transient AFPPagePaintingState pagePaintingState = new AFPPagePaintingState();
// /** reference orientation */
// private int orientation = 0;
/** a unit converter */
private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
/**
* Sets the rotation to be used for portrait pages, valid values are 0
* (default), 90, 180, 270.
*
* @param rotation
* The rotation in degrees.
*/
public void setPortraitRotation(int rotation) {
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
portraitRotation = rotation;
} else {
throw new IllegalArgumentException(
"The portrait rotation must be one"
+ " of the values 0, 90, 180, 270");
}
}
/**
* Returns the rotation to be used for portrait pages
*
* @return the rotation to be used for portrait pages
*/
protected int getPortraitRotation() {
return this.portraitRotation;
}
/**
* Sets the rotation to be used for landscape pages, valid values are 0, 90,
* 180, 270 (default).
*
* @param rotation
* The rotation in degrees.
*/
public void setLandscapeRotation(int rotation) {
if (rotation == 0 || rotation == 90 || rotation == 180
|| rotation == 270) {
landscapeRotation = rotation;
} else {
throw new IllegalArgumentException(
"The landscape rotation must be one"
+ " of the values 0, 90, 180, 270");
}
}
/**
* Returns the landscape rotation
*
* @return the landscape rotation
*/
protected int getLandscapeRotation() {
return this.landscapeRotation;
}
/**
* Sets the number of bits used per pixel
*
* @param bitsPerPixel
* number of bits per pixel
*/
public void setBitsPerPixel(int bitsPerPixel) {
switch (bitsPerPixel) {
case 1:
case 4:
case 8:
this.bitsPerPixel = bitsPerPixel;
break;
default:
log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
this.bitsPerPixel = 8;
break;
}
}
/**
* Returns the number of bits per pixel
*
* @return the number of bits per pixel
*/
public int getBitsPerPixel() {
return this.bitsPerPixel;
}
/**
* Sets whether images are color or not
*
* @param colorImages
* color image output
*/
public void setColorImages(boolean colorImages) {
this.colorImages = colorImages;
}
/**
* Returns true if color images are to be used
*
* @return true if color images are to be used
*/
public boolean isColorImages() {
return this.colorImages;
}
/**
* Sets whether images are natively supported or not in the AFP environment
*
* @param nativeImagesSupported true if images are natively supported in this AFP environment
*/
public void setNativeImagesSupported(boolean nativeImagesSupported) {
this.nativeImagesSupported = nativeImagesSupported;
}
/**
* Returns true if images are supported natively in this AFP environment
*
* @return true if images are supported natively in this AFP environment
*/
public boolean isNativeImagesSupported() {
return this.nativeImagesSupported;
}
/**
* Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
* for wider compatibility. When disabled, any CMYK image is converted to the selected
* color format.
* @param value true to enabled CMYK images
*/
public void setCMYKImagesSupported(boolean value) {
this.cmykImagesSupported = value;
}
/**
* Indicates whether CMYK images (IOCA FS45) are enabled.
* @return true if IOCA FS45 is enabled
*/
public boolean isCMYKImagesSupported() {
return this.cmykImagesSupported;
}
/**
* Sets the output/device resolution
*
* @param resolution
* the output resolution (dpi)
*/
public void setResolution(int resolution) {
if (log.isDebugEnabled()) {
log.debug("renderer-resolution set to: " + resolution + "dpi");
}
this.resolution = resolution;
}
/**
* Returns the output/device resolution.
*
* @return the resolution in dpi
*/
public int getResolution() {
return this.resolution;
}
/** {@inheritDoc} */
protected AbstractData instantiateData() {
return new AFPData();
}
/** {@inheritDoc} */
protected AbstractPaintingState instantiate() {
return new AFPPaintingState();
}
/**
* Returns the painting state of the current page
*
* @return the painting state of the current page
*/
protected AFPPagePaintingState getPagePaintingState() {
return this.pagePaintingState;
}
/**
* Gets the current page fonts
*
* @return the current page fonts
*/
public AFPPageFonts getPageFonts() {
return pagePaintingState.getFonts();
}
/**
* Sets the page width
*
* @param pageWidth the page width
*/
public void setPageWidth(int pageWidth) {
pagePaintingState.setWidth(pageWidth);
}
/**
* Returns the page width
*
* @return the page width
*/
public int getPageWidth() {
return pagePaintingState.getWidth();
}
/**
* Sets the page height
*
* @param pageHeight the page height
*/
public void setPageHeight(int pageHeight) {
pagePaintingState.setHeight(pageHeight);
}
/**
* Returns the page height
*
* @return the page height
*/
public int getPageHeight() {
return pagePaintingState.getHeight();
}
/**
* Returns the page rotation
*
* @return the page rotation
*/
public int getPageRotation() {
return pagePaintingState.getOrientation();
}
/**
* Sets the uri of the current image
*
* @param uri the uri of the current image
*/
public void setImageUri(String uri) {
((AFPData)getData()).imageUri = uri;
}
/**
* Gets the uri of the current image
*
* @return the uri of the current image
*/
public String getImageUri() {
return ((AFPData)getData()).imageUri;
}
/**
* Returns the currently derived rotation
*
* @return the currently derived rotation
*/
public int getRotation() {
return getData().getDerivedRotation();
}
/**
* Returns the unit converter
*
* @return the unit converter
*/
public AFPUnitConverter getUnitConverter() {
return this.unitConv;
}
/**
* Returns a point on the current page, taking the current painting state into account.
*
* @param x the X-coordinate
* @param y the Y-coordinate
* @return a point on the current page
*/
public Point getPoint(int x, int y) {
Point p = new Point();
int rotation = getRotation();
switch (rotation) {
case 90:
p.x = y;
p.y = getPageWidth() - x;
break;
case 180:
p.x = getPageWidth() - x;
p.y = getPageHeight() - y;
break;
case 270:
p.x = getPageHeight() - y;
p.y = x;
break;
default:
p.x = x;
p.y = y;
break;
}
return p;
}
/** {@inheritDoc} */
public Object clone() {
AFPPaintingState paintingState = (AFPPaintingState)super.clone();
paintingState.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
paintingState.portraitRotation = this.portraitRotation;
paintingState.landscapeRotation = this.landscapeRotation;
paintingState.bitsPerPixel = this.bitsPerPixel;
paintingState.colorImages = this.colorImages;
paintingState.resolution = this.resolution;
return paintingState;
}
/** {@inheritDoc} */
public String toString() {
return "AFPPaintingState{" + "portraitRotation=" + portraitRotation
+ ", landscapeRotation=" + landscapeRotation
+ ", colorImages=" + colorImages
+ ", bitsPerPixel=" + bitsPerPixel
+ ", resolution=" + resolution
+ ", pageState=" + pagePaintingState
+ super.toString()
+ "}";
}
/**
* Page level state data
*/
private class AFPPagePaintingState implements Cloneable {
/** page width */
private int width = 0;
/** page height */
private int height = 0;
/** page fonts */
private AFPPageFonts fonts = new AFPPageFonts();
/** page font count */
private int fontCount = 0;
/** page orientation */
private int orientation = 0;
/**
* Returns the page width
*
* @return the page width
*/
protected int getWidth() {
return width;
}
/**
* Sets the page width
*
* @param width the page width
*/
protected void setWidth(int width) {
this.width = width;
}
/**
* Returns the page height
*
* @return the page height
*/
protected int getHeight() {
return height;
}
/**
* Sets the page height
*
* @param height the page height
*/
protected void setHeight(int height) {
this.height = height;
}
/**
* Returns the page fonts
*
* @return the page fonts
*/
protected AFPPageFonts getFonts() {
return fonts;
}
/**
* Sets the current page fonts
*
* @param fonts the current page fonts
*/
protected void setFonts(AFPPageFonts fonts) {
this.fonts = fonts;
}
/**
* Increments and returns the current page font count
*
* @return increment and return the current page font count
*/
protected int incrementFontCount() {
return ++fontCount;
}
/**
* Returns the current page orientation
*
* @return the current page orientation
*/
protected int getOrientation() {
return orientation;
}
/**
* Sets the current page orientation
*
* @param orientation the current page orientation
*/
protected void setOrientation(int orientation) {
this.orientation = orientation;
}
/** {@inheritDoc} */
public Object clone() {
AFPPagePaintingState state = new AFPPagePaintingState();
state.width = this.width;
state.height = this.height;
state.orientation = this.orientation;
state.fonts = new AFPPageFonts(this.fonts);
state.fontCount = this.fontCount;
return state;
}
/** {@inheritDoc} */
public String toString() {
return "AFPPagePaintingState{width=" + width
+ ", height=" + height
+ ", orientation=" + orientation
+ ", fonts=" + fonts
+ ", fontCount=" + fontCount
+ "}";
}
}
/**
* Block level state data
*/
private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData {
private static final long serialVersionUID = -1789481244175275686L;
/** The current fill status */
private boolean filled = false;
private String imageUri = null;
/** {@inheritDoc} */
public Object clone() {
AFPData obj = (AFPData)super.clone();
obj.filled = this.filled;
obj.imageUri = this.imageUri;
return obj;
}
/** {@inheritDoc} */
public String toString() {
return "AFPData{" + super.toString()
+ ", filled=" + filled
+ ", imageUri=" + imageUri
+ "}";
}
/** {@inheritDoc} */
protected AbstractData instantiate() {
return new AFPData();
}
}
}