/*
 * 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: PCLRenderingUtil.java 1756387 2016-08-15 14:15:27Z ssteiner $ */

package org.apache.fop.render.pcl;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

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

import org.apache.xmlgraphics.util.UnitConv;

import org.apache.fop.apps.FOUserAgent;

Utility class for handling all sorts of peripheral tasks around PCL generation.
/** * Utility class for handling all sorts of peripheral tasks around PCL generation. */
public class PCLRenderingUtil {
logging instance
/** logging instance */
private static Log log = LogFactory.getLog(PCLRenderingUtil.class); private FOUserAgent userAgent;
Controls whether appearance is more important than speed. "SPEED" can cause some FO feature to be ignored (like the advanced borders).
/** * Controls whether appearance is more important than speed. "SPEED" can cause some FO feature * to be ignored (like the advanced borders). */
private PCLRenderingMode renderingMode = PCLRenderingMode.SPEED;
Controls the dithering quality when rendering gray or color images.
/** Controls the dithering quality when rendering gray or color images. */
private float ditheringQuality = 0.5f; private boolean useColor; private boolean optimizeResources;
Controls whether the generation of PJL commands gets disabled.
/** * Controls whether the generation of PJL commands gets disabled. */
private boolean disabledPJL;
Controls whether all text should be painted as text. This is a fallback setting in case the mixture of native and bitmapped text does not provide the necessary quality.
/** * Controls whether all text should be painted as text. This is a fallback setting in case the mixture of native and * bitmapped text does not provide the necessary quality. */
private boolean allTextAsBitmaps; PCLRenderingUtil(FOUserAgent userAgent) { this.userAgent = userAgent; initialize(); } private void initialize() { }
Returns the user agent.
Returns:the user agent
/** * Returns the user agent. * @return the user agent */
public FOUserAgent getUserAgent() { return this.userAgent; }
Configures the renderer to trade speed for quality if desired. One example here is the way that borders are rendered.
Params:
/** * Configures the renderer to trade speed for quality if desired. One example here is the way * that borders are rendered. * @param mode one of the {@link PCLRenderingMode}.* constants */
public void setRenderingMode(PCLRenderingMode mode) { this.renderingMode = mode; this.ditheringQuality = mode.getDefaultDitheringQuality(); }
Returns the selected rendering mode.
Returns:the rendering mode
/** * Returns the selected rendering mode. * @return the rendering mode */
public PCLRenderingMode getRenderingMode() { return this.renderingMode; }
Returns the dithering quality to be used when encoding gray or color images.
Returns:the quality (0.0f..1.0f)
/** * Returns the dithering quality to be used when encoding gray or color images. * @return the quality (0.0f..1.0f) */
public float getDitheringQuality() { return this.ditheringQuality; }
Controls whether PJL commands shall be generated by the PCL renderer.
Params:
  • disable – true to disable PJL commands
/** * Controls whether PJL commands shall be generated by the PCL renderer. * @param disable true to disable PJL commands */
public void setPJLDisabled(boolean disable) { this.disabledPJL = disable; }
Indicates whether PJL generation is disabled.
Returns:true if PJL generation is disabled.
/** * Indicates whether PJL generation is disabled. * @return true if PJL generation is disabled. */
public boolean isPJLDisabled() { return this.disabledPJL; }
Controls whether all text should be generated as bitmaps or only text for which there's no native font.
Params:
  • allTextAsBitmaps – true if all text should be painted as bitmaps
/** * Controls whether all text should be generated as bitmaps or only text for which there's no native font. * @param allTextAsBitmaps true if all text should be painted as bitmaps */
public void setAllTextAsBitmaps(boolean allTextAsBitmaps) { this.allTextAsBitmaps = allTextAsBitmaps; }
Indicates whether all text shall be painted as bitmaps.
Returns:true if all text shall be painted as bitmaps
/** * Indicates whether all text shall be painted as bitmaps. * @return true if all text shall be painted as bitmaps */
public boolean isAllTextAsBitmaps() { return this.allTextAsBitmaps; } public void setColorEnabled(boolean useColor) { this.useColor = useColor; } public boolean isColorEnabled() { return useColor; }
Determines the print direction based on the given transformation matrix. This method only detects right angles (0, 90, 180, 270). If any other angle is determined, 0 is returned.
Params:
  • transform – the transformation matrix
Returns:the angle in degrees of the print direction.
/** * Determines the print direction based on the given transformation matrix. This method * only detects right angles (0, 90, 180, 270). If any other angle is determined, 0 is * returned. * @param transform the transformation matrix * @return the angle in degrees of the print direction. */
public static int determinePrintDirection(AffineTransform transform) { int newDir; if (transform.getScaleX() == 0 && transform.getScaleY() == 0 && transform.getShearX() == 1 && transform.getShearY() == -1) { newDir = 90; } else if (transform.getScaleX() == -1 && transform.getScaleY() == -1 && transform.getShearX() == 0 && transform.getShearY() == 0) { newDir = 180; } else if (transform.getScaleX() == 0 && transform.getScaleY() == 0 && transform.getShearX() == -1 && transform.getShearY() == 1) { newDir = 270; } else { newDir = 0; } return newDir; }
Returns a coordinate in PCL's coordinate system when given a coordinate in the user coordinate system.
Params:
  • x – the X coordinate
  • y – the Y coordinate
  • transform – the currently valid transformation matrix
  • pageDefinition – the currently valid page definition
  • printDirection – the currently valid print direction
Returns:the transformed point
/** * Returns a coordinate in PCL's coordinate system when given a coordinate in the user * coordinate system. * @param x the X coordinate * @param y the Y coordinate * @param transform the currently valid transformation matrix * @param pageDefinition the currently valid page definition * @param printDirection the currently valid print direction * @return the transformed point */
public static Point2D transformedPoint(int x, int y, AffineTransform transform, PCLPageDefinition pageDefinition, int printDirection) { if (log.isTraceEnabled()) { log.trace("Current transform: " + transform); } Point2D.Float orgPoint = new Point2D.Float(x, y); Point2D.Float transPoint = new Point2D.Float(); transform.transform(orgPoint, transPoint); //At this point we have the absolute position in FOP's coordinate system //Now get PCL coordinates taking the current print direction and the logical page //into account. Dimension pageSize = pageDefinition.getPhysicalPageSize(); Rectangle logRect = pageDefinition.getLogicalPageRect(); switch (printDirection) { case 0: transPoint.x -= logRect.x; transPoint.y -= logRect.y; break; case 90: float ty = transPoint.x; transPoint.x = pageSize.height - transPoint.y; transPoint.y = ty; transPoint.x -= logRect.y; transPoint.y -= logRect.x; break; case 180: transPoint.x = pageSize.width - transPoint.x; transPoint.y = pageSize.height - transPoint.y; transPoint.x -= pageSize.width - logRect.x - logRect.width; transPoint.y -= pageSize.height - logRect.y - logRect.height; //The next line is odd and is probably necessary due to the default value of the //Text Length command: "1/2 inch less than maximum text length" //I wonder why this isn't necessary for the 90 degree rotation. *shrug* transPoint.y -= UnitConv.in2mpt(0.5); break; case 270: float tx = transPoint.y; transPoint.y = pageSize.width - transPoint.x; transPoint.x = tx; transPoint.x -= pageSize.height - logRect.y - logRect.height; transPoint.y -= pageSize.width - logRect.x - logRect.width; break; default: throw new IllegalStateException("Illegal print direction: " + printDirection); } return transPoint; } public boolean isOptimizeResources() { return optimizeResources; } public void setOptimizeResources(boolean b) { optimizeResources = b; } }