/*
 * 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: AFPPaintingState.java 1617052 2014-08-10 06:55:01Z gadams $ */

package org.apache.fop.afp;

import java.awt.Point;
import java.io.IOException;
import java.io.ObjectInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.java2d.color.ColorConverter;
import org.apache.xmlgraphics.java2d.color.DefaultColorConverter;

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.
/** * This keeps information about the current painting state when writing to an * AFP datastream. */
public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState { private static final long serialVersionUID = 8206711712452344473L; private static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
the portrait rotation
/** the portrait rotation */
private int portraitRotation;
the landscape rotation
/** the landscape rotation */
private int landscapeRotation = 270;
color image support
/** color image support */
private boolean colorImages;
dithering quality setting (0.0f..1.0f)
/** dithering quality setting (0.0f..1.0f) */
private float ditheringQuality;
image encoding quality setting (0.0f..1.0f)
/** image encoding quality setting (0.0f..1.0f) */
private float bitmapEncodingQuality;
color image handler
/** color image handler */
private transient ColorConverter colorConverter;
true if certain image formats may be embedded unchanged in their native format.
/** * true if certain image formats may be embedded unchanged in their native * format. */
private boolean nativeImagesSupported; private boolean canEmbedJpeg;
true if CMYK images (requires IOCA FS45 suppport on the target platform) may be generated
/** * true if CMYK images (requires IOCA FS45 suppport on the target platform) * may be generated */
private boolean cmykImagesSupported;
default value for image depth
/** default value for image depth */
private int bitsPerPixel = 8;
the output resolution
/** the output resolution */
private int resolution = 240; // 240 dpi
A configurable value to correct the line width so that the output matches the expected. Different devices may need different values.
/** * A configurable value to correct the line width so that the output matches the expected. Different * devices may need different values. */
private float lineWidthCorrection = AFPConstants.LINE_WIDTH_CORRECTION;
determines whether GOCA is enabled or disabled
/** determines whether GOCA is enabled or disabled */
private boolean gocaEnabled = true;
determines whether to stroke text in GOCA mode or to use text operators where possible
/** determines whether to stroke text in GOCA mode or to use text operators where possible */
private boolean strokeGocaText;
use page segment with F11 and F45 images
/** use page segment with F11 and F45 images*/
private boolean pSeg;
use FS45 images
/** use FS45 images*/
private boolean fs45;
the current page
/** the current page */
private transient AFPPagePaintingState pagePaintingState; // /** reference orientation */ // private int orientation = 0;
a unit converter
/** a unit converter */
private final transient AFPUnitConverter unitConv; public AFPPaintingState() { colorConverter = GrayScaleColorConverter.getInstance(); pagePaintingState = new AFPPagePaintingState(); unitConv = new AFPUnitConverter(this); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); }
Sets the rotation to be used for portrait pages, valid values are 0 (default), 90, 180, 270.
Params:
  • rotation – The rotation in degrees.
/** * 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
Returns:the rotation to be used for portrait pages
/** * 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).
Params:
  • rotation – The rotation in degrees.
/** * 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
Returns:the landscape rotation
/** * Returns the landscape rotation * * @return the landscape rotation */
protected int getLandscapeRotation() { return this.landscapeRotation; }
Sets the number of bits used per pixel
Params:
  • bitsPerPixel – number of bits per pixel
/** * 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
Returns:the number of bits per pixel
/** * 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 and instantiates a ColorHandler
Params:
  • colorImages – color image output
/** * Sets whether images are color or not and instantiates a ColorHandler * * @param colorImages * color image output */
public void setColorImages(boolean colorImages) { this.colorImages = colorImages; if (colorImages) { this.colorConverter = DefaultColorConverter.getInstance(); } }
Returns true if color images are to be used
Returns:true if color images are to be used
/** * Returns true if color images are to be used * * @return true if color images are to be used */
public boolean isColorImages() { return this.colorImages; }
Used to convert color in respect of the colorImages flag
Returns:the color converter
/** * Used to convert color in respect of the colorImages flag * * @return the color converter */
public ColorConverter getColorConverter() { return this.colorConverter; }
Sets whether images are natively supported or not in the AFP environment
Params:
  • nativeImagesSupported – true if images are natively supported in this AFP environment
/** * 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
Returns:true if images are supported natively in this AFP environment
/** * 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; }
Set whether or not JPEG images can be embedded within an AFP document.
Params:
  • canEmbed – true if the JPEG image can be embedded
/** * Set whether or not JPEG images can be embedded within an AFP document. * * @param canEmbed true if the JPEG image can be embedded */
public void setCanEmbedJpeg(boolean canEmbed) { canEmbedJpeg = canEmbed; }
Returns true if JPEGs can be embedded in an AFP document.
Returns:true if JPEG embedding is allowed
/** * Returns true if JPEGs can be embedded in an AFP document. * * @return true if JPEG embedding is allowed */
public boolean canEmbedJpeg() { return canEmbedJpeg; }
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.
Params:
  • value – true to enabled CMYK images
/** * 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.
Returns:true if IOCA FS45 is enabled
/** * Indicates whether CMYK images (IOCA FS45) are enabled. * * @return true if IOCA FS45 is enabled */
public boolean isCMYKImagesSupported() { return this.cmykImagesSupported; }
Gets the dithering quality setting to use when converting images to monochrome images.
Returns:the dithering quality (a value between 0.0f and 1.0f)
/** * Gets the dithering quality setting to use when converting images to monochrome images. * @return the dithering quality (a value between 0.0f and 1.0f) */
public float getDitheringQuality() { return this.ditheringQuality; }
Sets the dithering quality setting to use when converting images to monochrome images.
Params:
  • quality – Defines the desired quality level for the conversion. Valid values: a value between 0.0f (fastest) and 1.0f (best)
/** * Sets the dithering quality setting to use when converting images to monochrome images. * @param quality Defines the desired quality level for the conversion. * Valid values: a value between 0.0f (fastest) and 1.0f (best) */
public void setDitheringQuality(float quality) { quality = Math.max(quality, 0.0f); quality = Math.min(quality, 1.0f); this.ditheringQuality = quality; }
Gets the image encoding quality setting to use when encoding bitmap images.
Returns:the encoding quality (a value between 0.0f and 1.0f, 1.0 meaning loss-less)
/** * Gets the image encoding quality setting to use when encoding bitmap images. * @return the encoding quality (a value between 0.0f and 1.0f, 1.0 meaning loss-less) */
public float getBitmapEncodingQuality() { return this.bitmapEncodingQuality; }
Sets the image encoding quality setting to use when encoding bitmap images.
Params:
  • quality – Defines the desired quality level for the conversion. Valid values: a value between 0.0f (lowest) and 1.0f (best, loss-less)
/** * Sets the image encoding quality setting to use when encoding bitmap images. * @param quality Defines the desired quality level for the conversion. * Valid values: a value between 0.0f (lowest) and 1.0f (best, loss-less) */
public void setBitmapEncodingQuality(float quality) { quality = Math.max(quality, 0.0f); quality = Math.min(quality, 1.0f); this.bitmapEncodingQuality = quality; }
Sets the output/device resolution
Params:
  • resolution – the output resolution (dpi)
/** * 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; }
Sets the line width correction
Params:
  • correction – the line width multiplying factor correction
/** * Sets the line width correction * * @param correction the line width multiplying factor correction */
public void setLineWidthCorrection(float correction) { if (log.isDebugEnabled()) { log.debug("line width correction set to: " + correction); } this.lineWidthCorrection = correction; }
Returns the output/device resolution.
Returns:the resolution in dpi
/** * Returns the output/device resolution. * * @return the resolution in dpi */
public int getResolution() { return this.resolution; }
Returns the line width correction.
Returns:the correction
/** * Returns the line width correction. * @return the correction */
public float getLineWidthCorrection() { return this.lineWidthCorrection; }
Controls whether GOCA is enabled or disabled.
Params:
  • enabled – true if GOCA is enabled, false if it is disabled
/** * Controls whether GOCA is enabled or disabled. * @param enabled true if GOCA is enabled, false if it is disabled */
public void setGOCAEnabled(boolean enabled) { this.gocaEnabled = enabled; }
Indicates whether GOCA is enabled or disabled.
Returns:true if GOCA is enabled, false if GOCA is disabled
/** * Indicates whether GOCA is enabled or disabled. * @return true if GOCA is enabled, false if GOCA is disabled */
public boolean isGOCAEnabled() { return this.gocaEnabled; }
Controls whether to stroke text in GOCA mode or to use text operators where possible.
Params:
  • stroke – true to stroke, false to paint with text operators where possible
/** * Controls whether to stroke text in GOCA mode or to use text operators where possible. * @param stroke true to stroke, false to paint with text operators where possible */
public void setStrokeGOCAText(boolean stroke) { this.strokeGocaText = stroke; }
Indicates whether to stroke text in GOCA mode or to use text operators where possible.
Returns:true to stroke, false to paint with text operators where possible
/** * Indicates whether to stroke text in GOCA mode or to use text operators where possible. * @return true to stroke, false to paint with text operators where possible */
public boolean isStrokeGOCAText() { return this.strokeGocaText; }
Whether FS11 and SF45 non-inline images should be wrapped in a page segment
Returns:true iff images should be wrapped
/** * Whether FS11 and SF45 non-inline images should be wrapped in a page segment * @return true iff images should be wrapped */
public boolean getWrapPSeg() { return pSeg; }
Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment
Params:
  • pSeg – true iff images should be wrapped
/** * Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment * @param pSeg true iff images should be wrapped */
public void setWrapPSeg(boolean pSeg) { this.pSeg = pSeg; }
gets whether images should be FS45
Returns:true iff images should be FS45
/** * gets whether images should be FS45 * @return true iff images should be FS45 */
public boolean getFS45() { return fs45; }
sets whether images should be FS45
Params:
  • fs45 – true iff images should be FS45
/** * sets whether images should be FS45 * @param fs45 true iff images should be FS45 */
public void setFS45(boolean fs45) { this.fs45 = fs45; }
{@inheritDoc}
/** {@inheritDoc} */
@Override protected AbstractData instantiateData() { return new AFPData(); }
{@inheritDoc}
/** {@inheritDoc} */
@Override protected AbstractPaintingState instantiate() { return new AFPPaintingState(); }
Returns the painting state of the current page
Returns:the painting state of the current page
/** * 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
Returns:the current page fonts
/** * Gets the current page fonts * * @return the current page fonts */
public AFPPageFonts getPageFonts() { return pagePaintingState.getFonts(); }
Sets the page width
Params:
  • pageWidth – the page width
/** * Sets the page width * * @param pageWidth * the page width */
public void setPageWidth(int pageWidth) { pagePaintingState.setWidth(pageWidth); }
Returns the page width
Returns:the page width
/** * Returns the page width * * @return the page width */
public int getPageWidth() { return pagePaintingState.getWidth(); }
Sets the page height
Params:
  • pageHeight – the page height
/** * Sets the page height * * @param pageHeight * the page height */
public void setPageHeight(int pageHeight) { pagePaintingState.setHeight(pageHeight); }
Returns the page height
Returns:the page height
/** * Returns the page height * * @return the page height */
public int getPageHeight() { return pagePaintingState.getHeight(); }
Returns the page rotation
Returns:the page rotation
/** * Returns the page rotation * * @return the page rotation */
public int getPageRotation() { return pagePaintingState.getOrientation(); }
Sets the uri of the current image
Params:
  • uri – the uri of the current image
/** * 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
Returns:the uri of the current image
/** * 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
Returns:the currently derived rotation
/** * Returns the currently derived rotation * * @return the currently derived rotation */
public int getRotation() { return getData().getDerivedRotation(); }
Returns the unit converter
Returns:the unit converter
/** * 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.
Params:
  • x – the X-coordinate
  • y – the Y-coordinate
Returns:a point on the current page
/** * 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}
/** {@inheritDoc} */
@Override 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.colorConverter = this.colorConverter; paintingState.resolution = this.resolution; return paintingState; }
{@inheritDoc}
/** {@inheritDoc} */
@Override public String toString() { return "AFPPaintingState{" + "portraitRotation=" + portraitRotation + ", landscapeRotation=" + landscapeRotation + ", colorImages=" + colorImages + ", bitsPerPixel=" + bitsPerPixel + ", resolution=" + resolution + ", pageState=" + pagePaintingState + super.toString() + "}"; }
Page level state data
/** * Page level state data */
private class AFPPagePaintingState implements Cloneable {
page width
/** page width */
private int width;
page height
/** page height */
private int height;
page fonts
/** page fonts */
private AFPPageFonts fonts = new AFPPageFonts();
page font count
/** page font count */
private int fontCount;
page orientation
/** page orientation */
private int orientation;
Returns the page width
Returns:the page width
/** * Returns the page width * * @return the page width */
protected int getWidth() { return width; }
Sets the page width
Params:
  • width – the page width
/** * Sets the page width * * @param width * the page width */
protected void setWidth(int width) { this.width = width; }
Returns the page height
Returns:the page height
/** * Returns the page height * * @return the page height */
protected int getHeight() { return height; }
Sets the page height
Params:
  • height – the page height
/** * Sets the page height * * @param height * the page height */
protected void setHeight(int height) { this.height = height; }
Returns the page fonts
Returns:the page fonts
/** * Returns the page fonts * * @return the page fonts */
protected AFPPageFonts getFonts() { return fonts; }
Sets the current page fonts
Params:
  • fonts – the current page 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
Returns:increment and return the current page font count
/** * 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
Returns:the current page orientation
/** * Returns the current page orientation * * @return the current page orientation */
protected int getOrientation() { return orientation; }
Sets the current page orientation
Params:
  • orientation – the current page orientation
/** * Sets the current page orientation * * @param orientation * the current page orientation */
protected void setOrientation(int orientation) { this.orientation = orientation; }
{@inheritDoc}
/** {@inheritDoc} */
@Override 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}
/** {@inheritDoc} */
@Override public String toString() { return "AFPPagePaintingState{width=" + width + ", height=" + height + ", orientation=" + orientation + ", fonts=" + fonts + ", fontCount=" + fontCount + "}"; } }
Block level state data
/** * Block level state data */
// @SuppressFBWarnings("SE_INNER_CLASS") private class AFPData extends org.apache.fop.util.AbstractPaintingState.AbstractData { private static final long serialVersionUID = -1789481244175275686L;
The current fill status
/** The current fill status */
private boolean filled; private String imageUri;
{@inheritDoc}
/** {@inheritDoc} */
@Override public Object clone() { AFPData obj = (AFPData) super.clone(); obj.filled = this.filled; obj.imageUri = this.imageUri; return obj; }
{@inheritDoc}
/** {@inheritDoc} */
@Override public String toString() { return "AFPData{" + super.toString() + ", filled=" + filled + ", imageUri=" + imageUri + "}"; }
{@inheritDoc}
/** {@inheritDoc} */
@Override protected AbstractData instantiate() { return new AFPData(); } } }