diff options
Diffstat (limited to 'src/java/org/apache/fop/render')
11 files changed, 493 insertions, 49 deletions
diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java index 235e051f9..8d562e465 100644 --- a/src/java/org/apache/fop/render/intermediate/IFParser.java +++ b/src/java/org/apache/fop/render/intermediate/IFParser.java @@ -523,7 +523,7 @@ public class IFParser implements IFConstants { establishForeignAttributes(foreignAttributes); documentHandler.startPage(index, name, pageMasterName, new Dimension(width, height)); - documentHandler.getContext().setPageNumber(Integer.parseInt(name)); + documentHandler.getContext().setPageNumber(index + 1); resetForeignAttributes(); } diff --git a/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java b/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java index cb23f7191..9ec0b779b 100644 --- a/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java +++ b/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java @@ -27,7 +27,8 @@ public enum Java2DRendererOption implements RendererConfigOption { RENDERING_MODE("rendering", PCLRenderingMode.class), TEXT_RENDERING("text-rendering", Boolean.class), - DISABLE_PJL("disable-pjl", Boolean.class); + DISABLE_PJL("disable-pjl", Boolean.class), + MODE_COLOR("color", Boolean.class); private final String name; diff --git a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java index 1991295bd..66655a721 100644 --- a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java +++ b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java @@ -274,7 +274,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler try { Rectangle printArea = this.currentPageDefinition.getLogicalPageRect(); gen.setCursorPos(0, 0); - gen.paintBitmap(this.currentImage, printArea.getSize(), true); + gen.paintBitmap(this.currentImage, printArea.getSize(), true, pclUtil); } catch (IOException ioe) { throw new IFException("I/O error while encoding page image", ioe); } finally { diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java index 67d37fbb5..589779ad9 100644 --- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java +++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java @@ -21,12 +21,19 @@ package org.apache.fop.render.pcl; import java.awt.Color; import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; +import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; import java.awt.image.IndexColorModel; import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; +import java.awt.image.SinglePixelPackedSampleModel; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -380,7 +387,7 @@ public class PCLGenerator { * @param col the fill color * @throws IOException In case of an I/O error */ - protected void fillRect(int w, int h, Color col) throws IOException { + protected void fillRect(int w, int h, Color col, boolean colorEnabled) throws IOException { if ((w == 0) || (h == 0)) { return; } @@ -399,12 +406,19 @@ public class PCLGenerator { writeCommand("*c" + lineshade + "G"); writeCommand("*c2P"); //Shaded fill } else { - defineGrayscalePattern(col, 32, DitherUtil.DITHER_MATRIX_4X4); + if (colorEnabled) { + selectColor(col); + writeCommand("*c" + formatDouble4(w / 100.0) + "h" + + formatDouble4(h / 100.0) + "V"); + writeCommand("*c0P"); //Solid fill + } else { + defineGrayscalePattern(col, 32, DitherUtil.DITHER_MATRIX_4X4); - writeCommand("*c" + formatDouble4(w / 100.0) + "h" - + formatDouble4(h / 100.0) + "V"); - writeCommand("*c32G"); - writeCommand("*c4P"); //User-defined pattern + writeCommand("*c" + formatDouble4(w / 100.0) + "h" + + formatDouble4(h / 100.0) + "V"); + writeCommand("*c32G"); + writeCommand("*c4P"); //User-defined pattern + } } // Reset pattern transparency mode. setPatternTransparencyMode(true); @@ -530,6 +544,13 @@ public class PCLGenerator { } } + public void selectColor(Color col) throws IOException { + writeCommand("*v6W"); + writeBytes(new byte[]{0, 1, 1, 8, 8, 8}); + writeCommand(String.format("*v%da%db%dc0I", col.getRed(), col.getGreen(), col.getBlue())); + writeCommand("*v0S"); + } + /** * Select the current pattern * @param patternID the pattern ID (<ESC>*c#G command) @@ -696,13 +717,15 @@ public class PCLGenerator { * @param sourceTransparency true if the background should not be erased * @throws IOException In case of an I/O error */ - public void paintBitmap(RenderedImage img, Dimension targetDim, boolean sourceTransparency) - throws IOException { + public void paintBitmap(RenderedImage img, Dimension targetDim, boolean sourceTransparency, + PCLRenderingUtil pclUtil) throws IOException { + final boolean printerSupportsColor = pclUtil.isColorEnabled(); + boolean monochrome = isMonochromeImage(img); double targetHResolution = img.getWidth() / UnitConv.mpt2in(targetDim.width); double targetVResolution = img.getHeight() / UnitConv.mpt2in(targetDim.height); double targetResolution = Math.max(targetHResolution, targetVResolution); int resolution = (int)Math.round(targetResolution); - int effResolution = calculatePCLResolution(resolution, true); + int effResolution = calculatePCLResolution(resolution, !(printerSupportsColor && !monochrome)); Dimension orgDim = new Dimension(img.getWidth(), img.getHeight()); Dimension effDim; if (targetResolution == effResolution) { @@ -713,27 +736,30 @@ public class PCLGenerator { (int)Math.ceil(UnitConv.mpt2px(targetDim.height, effResolution))); } boolean scaled = !orgDim.equals(effDim); - - boolean monochrome = isMonochromeImage(img); if (!monochrome) { - //Transparency mask disabled. Doesn't work reliably - /* - final boolean transparencyDisabled = true; - RenderedImage mask = (transparencyDisabled ? null : getMask(img, effDim)); - if (mask != null) { - pushCursorPos(); - selectCurrentPattern(0, 1); //Solid white - setTransparencyMode(true, true); - paintMonochromeBitmap(mask, effResolution); - popCursorPos(); - } - */ + if (printerSupportsColor) { + selectCurrentPattern(0, 0); //Solid black + renderImageAsColor(img, effResolution); + } else { + //Transparency mask disabled. Doesn't work reliably + /* + final boolean transparencyDisabled = true; + RenderedImage mask = (transparencyDisabled ? null : getMask(img, effDim)); + if (mask != null) { + pushCursorPos(); + selectCurrentPattern(0, 1); //Solid white + setTransparencyMode(true, true); + paintMonochromeBitmap(mask, effResolution); + popCursorPos(); + } + */ - RenderedImage red = BitmapImageUtil.convertToMonochrome( - img, effDim, this.ditheringQuality); - selectCurrentPattern(0, 0); //Solid black - setTransparencyMode(sourceTransparency /*|| mask != null*/, true); - paintMonochromeBitmap(red, effResolution); + RenderedImage red = BitmapImageUtil.convertToMonochrome( + img, effDim, this.ditheringQuality); + selectCurrentPattern(0, 0); //Solid black + setTransparencyMode(sourceTransparency /*|| mask != null*/, true); + paintMonochromeBitmap(red, effResolution); + } } else { RenderedImage effImg = img; if (scaled) { @@ -755,6 +781,90 @@ public class PCLGenerator { return (int)greyVal; } + private void renderImageAsColor(RenderedImage imgOrg, int dpi) throws IOException { + BufferedImage img = new BufferedImage(imgOrg.getWidth(), imgOrg.getHeight(), BufferedImage.TYPE_INT_RGB); + Graphics2D g = img.createGraphics(); + g.setColor(Color.WHITE); + g.fillRect(0, 0, imgOrg.getWidth(), imgOrg.getHeight()); + g.drawImage((Image) imgOrg, 0, 0, null); + + if (!isValidPCLResolution(dpi)) { + throw new IllegalArgumentException("Invalid PCL resolution: " + dpi); + } + int w = img.getWidth(); + ColorModel cm = img.getColorModel(); + if (cm instanceof DirectColorModel) { + writeCommand("*v6W"); // ImagingMode + out.write(new byte[]{0, 3, 0, 8, 8, 8}); + } else { + IndexColorModel icm = (IndexColorModel)cm; + writeCommand("*v6W"); // ImagingMode + out.write(new byte[]{0, 1, (byte)icm.getMapSize(), 8, 8, 8}); + + byte[] reds = new byte[256]; + byte[] greens = new byte[256]; + byte[] blues = new byte[256]; + + icm.getReds(reds); + icm.getGreens(greens); + icm.getBlues(blues); + for (int i = 0; i < icm.getMapSize(); i++) { + writeCommand("*v" + (reds[i] & 0xFF) + "A"); //ColorComponentOne + writeCommand("*v" + (greens[i] & 0xFF) + "B"); //ColorComponentTwo + writeCommand("*v" + (blues[i] & 0xFF) + "C"); //ColorComponentThree + writeCommand("*v" + i + "I"); //AssignColorIndex + } + } + setRasterGraphicsResolution(dpi); + writeCommand("*r0f" + img.getHeight() + "t" + (w) + "S"); + writeCommand("*r1A"); + + Raster raster = img.getData(); + + ColorEncoder encoder = new ColorEncoder(img); + // Transfer graphics data + if (cm.getTransferType() == DataBuffer.TYPE_BYTE) { + DataBufferByte dataBuffer = (DataBufferByte)raster.getDataBuffer(); + if (img.getSampleModel() instanceof MultiPixelPackedSampleModel && dataBuffer.getNumBanks() == 1) { + byte[] buf = dataBuffer.getData(); + MultiPixelPackedSampleModel sampleModel = (MultiPixelPackedSampleModel)img.getSampleModel(); + int scanlineStride = sampleModel.getScanlineStride(); + int idx = 0; + for (int y = 0, maxy = img.getHeight(); y < maxy; y++) { + for (int x = 0; x < scanlineStride; x++) { + encoder.add8Bits(buf[idx]); + idx++; + } + encoder.endLine(); + } + } else { + throw new IOException("Unsupported image"); + } + } else if (cm.getTransferType() == DataBuffer.TYPE_INT) { + DataBufferInt dataBuffer = (DataBufferInt)raster.getDataBuffer(); + if (img.getSampleModel() instanceof SinglePixelPackedSampleModel && dataBuffer.getNumBanks() == 1) { + int[] buf = dataBuffer.getData(); + SinglePixelPackedSampleModel sampleModel = (SinglePixelPackedSampleModel)img.getSampleModel(); + int scanlineStride = sampleModel.getScanlineStride(); + int idx = 0; + for (int y = 0, maxy = img.getHeight(); y < maxy; y++) { + for (int x = 0; x < scanlineStride; x++) { + encoder.add8Bits((byte)(buf[idx] >> 16)); + encoder.add8Bits((byte)(buf[idx] >> 8)); + encoder.add8Bits((byte)(buf[idx] >> 0)); + idx++; + } + encoder.endLine(); + } + } else { + throw new IOException("Unsupported image"); + } + } else { + throw new IOException("Unsupported image"); + } + // End raster graphics + writeCommand("*rB"); + } /** * Paint a bitmap at the current cursor position. The bitmap must be a monochrome * (1-bit) bitmap image. @@ -921,4 +1031,236 @@ public class PCLGenerator { } + private class ColorEncoder { + private int imgw; + private int bytewidth; + private byte ib; //current image bits + + private int currentIndex; + private int len; + private int shiftBit = 0x80; + private int whiteLines; + final byte[] zeros; + final byte[] buff1; + final byte[] buff2; + final byte[] encodedRun; + final byte[] encodedTagged; + final byte[] encodedDelta; + byte[] seed; + byte[] current; + int compression; + int seedLen; + + public ColorEncoder(RenderedImage img) { + imgw = img.getWidth(); + bytewidth = imgw * 3 + 1; + + zeros = new byte[bytewidth]; + buff1 = new byte[bytewidth]; + buff2 = new byte[bytewidth]; + encodedRun = new byte[bytewidth]; + encodedTagged = new byte[bytewidth]; + encodedDelta = new byte[bytewidth]; + + seed = buff1; + current = buff2; + + seedLen = 0; + compression = (-1); + System.arraycopy(zeros, 0, seed, 0, zeros.length); + + } + + private int runCompression(byte[] buff, int len) { + int bytes = 0; + + try { + for (int i = 0; i < len;) { + int sameCount; + byte seed = current[i++]; + + for (sameCount = 1; i < len && current[i] == seed; i++) { + sameCount++; + } + + for (; sameCount > 256; sameCount -= 256) { + buff[bytes++] = (byte)255; + buff[bytes++] = seed; + } + if (sameCount > 0) { + buff[bytes++] = (byte)(sameCount - 1); + buff[bytes++] = seed; + } + + } + } catch (ArrayIndexOutOfBoundsException e) { + return len + 1; + } + return bytes; + } + + private int deltaCompression(byte[] seed, byte[] buff, int len) { + int bytes = 0; + + try { + for (int i = 0; i < len;) { + int sameCount; + int diffCount; + + for (sameCount = 0; i < len && current[i] == seed[i]; i++) { + sameCount++; + } + for (diffCount = 0; i < len && current[i] != seed[i]; i++) { + diffCount++; + } + + for (; diffCount != 0;) { + int diffToWrite = (diffCount > 8) ? 8 : diffCount; + int sameToWrite = (sameCount > 31) ? 31 : sameCount; + + buff[bytes++] = (byte)(((diffToWrite - 1) << 5) | sameToWrite); + sameCount -= sameToWrite; + if (sameToWrite == 31) { + for (; sameCount >= 255; sameCount -= 255) { + buff[bytes++] = (byte)255; + } + buff[bytes++] = (byte)sameCount; + sameCount = 0; + } + + System.arraycopy(current, i - diffCount, buff, bytes, diffToWrite); + bytes += diffToWrite; + + diffCount -= diffToWrite; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + return len + 1; + } + return bytes; + } + + private int tiffCompression(byte[] encodedTagged, int len) { + int literalCount = 0; + int bytes = 0; + + try { + for (int from = 0; from < len;) { + int repeatLength; + int repeatValue = current[from]; + + for (repeatLength = 1; repeatLength < 128 + && from + repeatLength < len + && current[from + repeatLength] == repeatValue;) { + repeatLength++; + } + + if (literalCount == 128 || (repeatLength > 2 && literalCount > 0)) { + encodedTagged[bytes++] = (byte)(literalCount - 1); + System.arraycopy(current, from - literalCount, encodedTagged, bytes, literalCount); + bytes += literalCount; + literalCount = 0; + } + if (repeatLength > 2) { + encodedTagged[bytes++] = (byte)(1 - repeatLength); + encodedTagged[bytes++] = current[from]; + from += repeatLength; + } else { + literalCount++; + from++; + } + } + if (literalCount > 0) { + encodedTagged[bytes++] = (byte)(literalCount - 1); + System.arraycopy(current, (3 * len) - literalCount, encodedTagged, bytes, literalCount); + bytes += literalCount; + } + } catch (ArrayIndexOutOfBoundsException e) { + return len + 1; + } + return bytes; + } + + public void addBit(boolean bit) { + //Set image bit for black + if (bit) { + ib |= shiftBit; + } + shiftBit >>= 1; + if (shiftBit == 0) { + add8Bits(ib); + shiftBit = 0x80; + ib = 0; + } + } + + public void add8Bits(byte b) { + current[currentIndex++] = b; + if (b != 0) { + len = currentIndex; + } + } + + public void endLine() throws IOException { + if (len == 0) { + whiteLines++; + } else { + if (whiteLines > 0) { + writeCommand("*b" + whiteLines + "Y"); + whiteLines = 0; + } + + int unencodedCount = len; + int runCount = runCompression(encodedRun, len); + int tiffCount = tiffCompression(encodedTagged, len); + int deltaCount = deltaCompression(seed, encodedDelta, Math.max(len, seedLen)); + + int bestCount = Math.min(unencodedCount, Math.min(runCount, Math.min(tiffCount, deltaCount))); + int bestCompression; + + if (bestCount == unencodedCount) { + bestCompression = 0; + } else if (bestCount == runCount) { + bestCompression = 1; + } else if (bestCount == tiffCount) { + bestCompression = 2; + } else { + bestCompression = 3; + } + + if (compression != bestCompression) { + compression = bestCompression; + writeCommand("*b" + compression + "M"); + } + + if (bestCompression == 0) { + writeCommand("*b" + unencodedCount + "W"); + out.write(current, 0, unencodedCount); + } else if (bestCompression == 1) { + writeCommand("*b" + runCount + "W"); + out.write(encodedRun, 0, runCount); + } else if (bestCompression == 2) { + writeCommand("*b" + tiffCount + "W"); + out.write(encodedTagged, 0, tiffCount); + } else if (bestCompression == 3) { + writeCommand("*b" + deltaCount + "W"); + out.write(encodedDelta, 0, deltaCount); + } + + if (current == buff1) { + seed = buff1; + current = buff2; + } else { + seed = buff2; + current = buff1; + } + seedLen = len; + } + shiftBit = 0x80; + ib = 0; + len = 0; + currentIndex = 0; + } + } + } diff --git a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java index 014bc47a1..66336955e 100644 --- a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java @@ -139,7 +139,7 @@ public class PCLImageHandlerGraphics2D implements ImageHandler { } gen.paintBitmap(imgRend.getRenderedImage(), new Dimension(pos.width, pos.height), - pclContext.isSourceTransparencyEnabled()); + pclContext.isSourceTransparencyEnabled(), pclContext.getPCLUtil()); } } diff --git a/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java index ebfb1829a..aabb9c5ac 100644 --- a/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java +++ b/src/java/org/apache/fop/render/pcl/PCLImageHandlerRenderedImage.java @@ -66,7 +66,7 @@ public class PCLImageHandlerRenderedImage implements ImageHandler { Point2D transPoint = pclContext.transformedPoint(pos.x, pos.y); gen.setCursorPos(transPoint.getX(), transPoint.getY()); gen.paintBitmap(ri, new Dimension(pos.width, pos.height), - pclContext.isSourceTransparencyEnabled()); + pclContext.isSourceTransparencyEnabled(), pclContext.getPCLUtil()); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/pcl/PCLPainter.java b/src/java/org/apache/fop/render/pcl/PCLPainter.java index 69465a7fd..65e996d08 100644 --- a/src/java/org/apache/fop/render/pcl/PCLPainter.java +++ b/src/java/org/apache/fop/render/pcl/PCLPainter.java @@ -211,7 +211,7 @@ public class PCLPainter extends AbstractIFPainter<PCLDocumentHandler> implements } try { setCursorPos(rect.x, rect.y); - gen.fillRect(rect.width, rect.height, fillColor); + gen.fillRect(rect.width, rect.height, fillColor, getPCLUtil().isColorEnabled()); } catch (IOException ioe) { throw new IFException("I/O error in fillRect()", ioe); } @@ -410,7 +410,11 @@ public class PCLPainter extends AbstractIFPainter<PCLDocumentHandler> implements Color textColor = state.getTextColor(); if (textColor != null) { gen.setTransparencyMode(true, false); - gen.selectGrayscale(textColor); + if (getDocumentHandler().getPCLUtil().isColorEnabled()) { + gen.selectColor(textColor); + } else { + gen.selectGrayscale(textColor); + } } gen.setTransparencyMode(true, true); @@ -492,7 +496,11 @@ public class PCLPainter extends AbstractIFPainter<PCLDocumentHandler> implements Color textColor = state.getTextColor(); if (textColor != null) { gen.setTransparencyMode(true, false); - gen.selectGrayscale(textColor); + if (getDocumentHandler().getPCLUtil().isColorEnabled()) { + gen.selectColor(textColor); + } else { + gen.selectGrayscale(textColor); + } } if (x != -1 && y != -1) { diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java index 29fccc2c8..05e72b00e 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java +++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java @@ -32,6 +32,7 @@ import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser; import org.apache.fop.render.RendererConfig; import static org.apache.fop.render.pcl.Java2DRendererOption.DISABLE_PJL; +import static org.apache.fop.render.pcl.Java2DRendererOption.MODE_COLOR; import static org.apache.fop.render.pcl.Java2DRendererOption.RENDERING_MODE; import static org.apache.fop.render.pcl.Java2DRendererOption.TEXT_RENDERING; @@ -65,6 +66,10 @@ public final class PCLRendererConfig implements RendererConfig { return getParam(DISABLE_PJL, Boolean.class); } + public Boolean isColorEnabled() { + return getParam(MODE_COLOR, Boolean.class); + } + private <T> T getParam(Java2DRendererOption option, Class<T> type) { assert option.getType().equals(type); return type.cast(params.get(option)); @@ -90,6 +95,12 @@ public final class PCLRendererConfig implements RendererConfig { private void configure(Configuration cfg, PCLRendererConfig config) throws FOPException { if (cfg != null) { + Configuration imagesCfg = cfg.getChild("images"); + String imageMode = imagesCfg.getAttribute("mode", null); + if ("color".equalsIgnoreCase(imageMode)) { + config.setParam(MODE_COLOR, true); + } + String rendering = cfg.getChild(RENDERING_MODE.getName()).getValue(null); if (rendering != null) { try { diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java index 33376655f..7a92b7408 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java +++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java @@ -67,7 +67,9 @@ public class PCLRendererConfigurator extends PrintRendererConfigurator { if (config.isTextRendering() != null) { pclUtil.setAllTextAsBitmaps(config.isTextRendering()); } - + if (config.isColorEnabled() != null) { + pclUtil.setColorEnabled(config.isColorEnabled()); + } } @Override diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java b/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java index 32693764f..674605bde 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderingUtil.java @@ -50,12 +50,7 @@ public class PCLRenderingUtil { /** Controls the dithering quality when rendering gray or color images. */ private float ditheringQuality = 0.5f; - /** - * Controls whether an RGB canvas is used when converting Java2D graphics to bitmaps. - * This can be used to work around problems with Apache Batik, for example, but setting - * this to true will increase memory consumption. - */ - private boolean useColorCanvas; + private boolean useColor; /** * Controls whether the generation of PJL commands gets disabled. @@ -142,12 +137,12 @@ public class PCLRenderingUtil { return this.allTextAsBitmaps; } - /** - * Indicates whether a color canvas is used when creating bitmap images. - * @return true if a color canvas is used. - */ - public boolean isColorCanvasEnabled() { - return this.useColorCanvas; + public void setColorEnabled(boolean useColor) { + this.useColor = useColor; + } + + public boolean isColorEnabled() { + return useColor; } /** diff --git a/src/java/org/apache/fop/render/ps/Gradient.java b/src/java/org/apache/fop/render/ps/Gradient.java new file mode 100644 index 000000000..558f3b952 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/Gradient.java @@ -0,0 +1,85 @@ +/* + * 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.render.ps; + +import java.util.List; + +import org.apache.fop.render.gradient.Function; +import org.apache.fop.render.gradient.Function.SubFunctionRenderer; +import org.apache.fop.render.gradient.GradientMaker.DoubleFormatter; +import org.apache.fop.render.gradient.Pattern; +import org.apache.fop.render.gradient.Shading; + +/** + * Helper class to draw gradients in PostScript. + */ +public final class Gradient { + + private Gradient() { } + + public static String outputPattern(Pattern pattern, DoubleFormatter doubleFormatter) { + StringBuilder p = new StringBuilder(64); + p.append("/Pattern setcolorspace\n"); + p.append("<< \n/Type /Pattern \n"); + + p.append("/PatternType " + pattern.getPatternType() + " \n"); + + if (pattern.getShading() != null) { + p.append("/Shading "); + outputShading(p, pattern.getShading(), doubleFormatter); + p.append(" \n"); + } + p.append(">> \n"); + List<Double> matrix = pattern.getMatrix(); + if (matrix == null) { + p.append("matrix "); + } else { + p.append("[ "); + for (double m : pattern.getMatrix()) { + p.append(doubleFormatter.formatDouble(m)); + p.append(" "); + } + p.append("] "); + } + p.append("makepattern setcolor\n"); + + return p.toString(); + } + + private static void outputShading(StringBuilder out, Shading shading, final DoubleFormatter doubleFormatter) { + final Function function = shading.getFunction(); + Shading.FunctionRenderer functionRenderer = new Shading.FunctionRenderer() { + + public void outputFunction(StringBuilder out) { + SubFunctionRenderer subFunctionRenderer = new Function.SubFunctionRenderer() { + + public void outputFunction(StringBuilder out, int functionIndex) { + Function subFunction = function.getFunctions().get(functionIndex); + assert subFunction.getFunctions().isEmpty(); + subFunction.output(out, doubleFormatter, null); + } + }; + function.output(out, doubleFormatter, subFunctionRenderer); + } + }; + shading.output(out, doubleFormatter, functionRenderer); + } + +} |