From 989ed10627c5d1f489317a56895cd29e63d38826 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Mon, 15 May 2000 13:00:21 +0000 Subject: [PATCH] This is to use colors instead of numbers, the first step in supporting gradientsand shadings. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193347 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/pdf/PDFColor.java | 69 +- src/org/apache/fop/pdf/PDFFunction.java | 79 +-- src/org/apache/fop/pdf/PDFNumber.java | 125 ++++ src/org/apache/fop/pdf/PDFPathPaint.java | 6 +- src/org/apache/fop/pdf/PDFPattern.java | 49 +- src/org/apache/fop/pdf/PDFShading.java | 44 +- .../apache/fop/render/pdf/PDFRenderer.java | 644 +++++++++--------- 7 files changed, 499 insertions(+), 517 deletions(-) create mode 100644 src/org/apache/fop/pdf/PDFNumber.java diff --git a/src/org/apache/fop/pdf/PDFColor.java b/src/org/apache/fop/pdf/PDFColor.java index 3e47d4fa0..73c07d464 100644 --- a/src/org/apache/fop/pdf/PDFColor.java +++ b/src/org/apache/fop/pdf/PDFColor.java @@ -69,7 +69,8 @@ public class PDFColor extends PDFPathPaint { protected double magenta= -1.0; protected double yellow = -1.0; protected double black = -1.0; - + + private PDFNumber pdfNumber = new PDFNumber(); public PDFColor(org.apache.fop.datatypes.ColorType theColor) { @@ -202,25 +203,22 @@ public class PDFColor extends PDFPathPaint { double tempDouble; - //if the color was constructed in a different colorspace, - //then we need to convert it. - if(this.colorSpace.getColorSpace()==ColorSpace.DEVICE_RGB) {//colorspace is RGB //output RGB if(fillNotStroke) { //fill - p.append(this.doubleOut(this.red)+" " - +this.doubleOut(this.green)+" " - +this.doubleOut(this.blue)+" " + p.append(pdfNumber.doubleOut(this.red)+" " + +pdfNumber.doubleOut(this.green)+" " + +pdfNumber.doubleOut(this.blue)+" " +" rg \n"); } else {//stroke/border - p.append(this.doubleOut(this.red)+" " - +this.doubleOut(this.green)+" " - +this.doubleOut(this.blue)+" " + p.append(pdfNumber.doubleOut(this.red)+" " + +pdfNumber.doubleOut(this.green)+" " + +pdfNumber.doubleOut(this.blue)+" " +" RG \n"); } }//end of output RGB @@ -229,17 +227,17 @@ public class PDFColor extends PDFPathPaint { if(fillNotStroke) { //fill - p.append(this.doubleOut(this.cyan) + " " - + this.doubleOut(this.magenta) + " " - + this.doubleOut(this.yellow) + " " - + this.doubleOut(this.black) + " k \n"); + p.append(pdfNumber.doubleOut(this.cyan) + " " + + pdfNumber.doubleOut(this.magenta) + " " + + pdfNumber.doubleOut(this.yellow) + " " + + pdfNumber.doubleOut(this.black) + " k \n"); } else { //fill - p.append(this.doubleOut(this.cyan) + " " - + this.doubleOut(this.magenta) + " " - + this.doubleOut(this.yellow) + " " - + this.doubleOut(this.black) + " K \n"); + p.append(pdfNumber.doubleOut(this.cyan) + " " + + pdfNumber.doubleOut(this.magenta) + " " + + pdfNumber.doubleOut(this.yellow) + " " + + pdfNumber.doubleOut(this.black) + " K \n"); } }//end of if CMYK @@ -248,11 +246,11 @@ public class PDFColor extends PDFPathPaint { if(fillNotStroke) { - p.append(this.doubleOut(this.black) + " g \n"); + p.append(pdfNumber.doubleOut(this.black) + " g \n"); } else { - p.append(this.doubleOut(this.black) + " G \n"); + p.append(pdfNumber.doubleOut(this.black) + " G \n"); } } @@ -261,37 +259,6 @@ public class PDFColor extends PDFPathPaint { - public String doubleOut(double doubleDown) - { - - StringBuffer p = new StringBuffer(); - double trouble = doubleDown % 1; - - if(trouble > 0.950) - { - p.append((int)doubleDown+1); - } - else if (trouble < 0.050) - { - p.append((int)doubleDown); - } - else - { - String doubleString = new String(doubleDown+""); - int decimal = doubleString.indexOf("."); - p.append(doubleString.substring(0, decimal)); - - if ((doubleString.length() - decimal) > 6) - { - p.append(doubleString.substring(decimal,decimal+6)); - } - else - { - p.append(doubleString.substring(decimal)); - } - } - return(p.toString()); - } protected void convertCMYKtoRGB() { diff --git a/src/org/apache/fop/pdf/PDFFunction.java b/src/org/apache/fop/pdf/PDFFunction.java index 0e4b44222..a7f974df7 100644 --- a/src/org/apache/fop/pdf/PDFFunction.java +++ b/src/org/apache/fop/pdf/PDFFunction.java @@ -142,6 +142,7 @@ public class PDFFunction extends PDFObject { /* *************************TYPE 4************************** */ //See 'data' above. + private PDFNumber pdfNumber = new PDFNumber(); /** * create an complete Function object of Type 0, A Sampled function. @@ -360,50 +361,6 @@ public class PDFFunction extends PDFObject { } - /** - * This converts an Object of type double to a prettily printed - * floating point number that PDF won't choke on. If a number's - * value is close to an integer, it's printed as an integer. - * Excess digits after the decimal place are trimmed (no rounding). - * Always print 0 in front of the decimal point of a number - * that is between 0 and 1. - * Note: Negative values are untested, as I assume they don't - * come up. Should work anyway. - * - * @param doubleDown Cool name, eh? - * @return String representation of Double that PDF won't choke on. - */ - public String doubleOut(Double doubleDown) - { - StringBuffer p = new StringBuffer(); - double trouble = doubleDown.doubleValue() % 1; - if(trouble > 0.950) - { - p.append(doubleDown.intValue()+1); - } - else if (trouble < 0.050) - { - p.append(doubleDown.intValue()); - } - else - { - String doubleString = new String(doubleDown+""); - int decimal = doubleString.indexOf("."); - p.append(doubleString.substring(0, decimal)); - - if ((doubleString.length() - decimal) > 6) - { - p.append(doubleString.substring(decimal,decimal+6)); - } - else - { - p.append(doubleString.substring(decimal)); - } - } - return(p.toString()); - } - - /** * represent as PDF. Whatever the FunctionType is, the correct @@ -434,7 +391,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } @@ -453,7 +410,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.size.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.size.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -465,7 +422,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.encode.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.encode.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -498,7 +455,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.range.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.range.elementAt(tempInt)) +" "); } @@ -512,7 +469,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.decode.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.decode.elementAt(tempInt)) +" "); } @@ -565,7 +522,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } @@ -584,7 +541,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.range.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.range.elementAt(tempInt)) +" "); } @@ -600,7 +557,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.cZero.size(); for(tempInt = 0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.cZero.elementAt(tempInt))+" "); } p.append("] \n"); @@ -613,7 +570,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.cOne.size(); for(tempInt = 0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.cOne.elementAt(tempInt))+" "); } p.append("] \n"); @@ -621,7 +578,7 @@ public class PDFFunction extends PDFObject { //N: The interpolation Exponent p.append("/N " - +this.doubleOut( + +pdfNumber.doubleOut( new Double(this.interpolationExponentN)) +" \n"); @@ -637,7 +594,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -654,7 +611,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.range.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.range.elementAt(tempInt)) +" "); } @@ -682,7 +639,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.encode.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.encode.elementAt(tempInt)) +" "); } @@ -709,7 +666,7 @@ public class PDFFunction extends PDFObject { vectorSize= this.bounds.size(); for(tempInt = 0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.bounds.elementAt(tempInt))+" "); } @@ -724,7 +681,7 @@ public class PDFFunction extends PDFObject { // of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ] String functionsFraction = - this.doubleOut(new Double( + pdfNumber.doubleOut(new Double( 1.0 / ((double)numberOfFunctions))); for(tempInt =0;tempInt+1 < numberOfFunctions; tempInt++) @@ -751,7 +708,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } @@ -769,7 +726,7 @@ public class PDFFunction extends PDFObject { vectorSize = this.range.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.range.elementAt(tempInt)) +" "); } diff --git a/src/org/apache/fop/pdf/PDFNumber.java b/src/org/apache/fop/pdf/PDFNumber.java new file mode 100644 index 000000000..6dc9cbdba --- /dev/null +++ b/src/org/apache/fop/pdf/PDFNumber.java @@ -0,0 +1,125 @@ +/*-- $Id$ -- + + ============================================================================ + The Apache Software License, Version 1.1 + ============================================================================ + + Copyright (C) 1999 The Apache Software Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without modifica- + tion, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. The end-user documentation included with the redistribution, if any, must + include the following acknowledgment: "This product includes software + developed by the Apache Software Foundation (http://www.apache.org/)." + Alternately, this acknowledgment may appear in the software itself, if + and wherever such third-party acknowledgments normally appear. + + 4. The names "FOP" and "Apache Software Foundation" must not be used to + endorse or promote products derived from this software without prior + written permission. For written permission, please contact + apache@apache.org. + + 5. Products derived from this software may not be called "Apache", nor may + "Apache" appear in their name, without prior written permission of the + Apache Software Foundation. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + This software consists of voluntary contributions made by many individuals + on behalf of the Apache Software Foundation and was originally created by + James Tauber . For more information on the Apache + Software Foundation, please see . + + */ + +package org.apache.fop.pdf; + +public class PDFNumber { + + + public PDFNumber() + { + + //How can I allow people to use the method, without allowing construction? + + } + + public String doubleOut(Double doubleDown) + { + StringBuffer p = new StringBuffer(); + double trouble = doubleDown.doubleValue() % 1; + if(trouble > 0.950) + { + p.append(doubleDown.intValue()+1); + } + else if (trouble < 0.050) + { + p.append(doubleDown.intValue()); + } + else + { + String doubleString = new String(doubleDown+""); + int decimal = doubleString.indexOf("."); + p.append(doubleString.substring(0, decimal)); + + if ((doubleString.length() - decimal) > 6) + { + p.append(doubleString.substring(decimal,decimal+6)); + } + else + { + p.append(doubleString.substring(decimal)); + } + } + return(p.toString()); + } + + public String doubleOut(double doubleDown) + { + + StringBuffer p = new StringBuffer(); + double trouble = doubleDown % 1; + + if(trouble > 0.950) + { + p.append((int)doubleDown+1); + } + else if (trouble < 0.050) + { + p.append((int)doubleDown); + } + else + { + String doubleString = new String(doubleDown+""); + int decimal = doubleString.indexOf("."); + p.append(doubleString.substring(0, decimal)); + + if ((doubleString.length() - decimal) > 6) + { + p.append(doubleString.substring(decimal,decimal+6)); + } + else + { + p.append(doubleString.substring(decimal)); + } + } + return(p.toString()); + } +} diff --git a/src/org/apache/fop/pdf/PDFPathPaint.java b/src/org/apache/fop/pdf/PDFPathPaint.java index 702e20b17..fd9c3eed8 100644 --- a/src/org/apache/fop/pdf/PDFPathPaint.java +++ b/src/org/apache/fop/pdf/PDFPathPaint.java @@ -67,8 +67,10 @@ public abstract class PDFPathPaint extends PDFObject //do nothing } - abstract String getColorSpaceOut(boolean fillNotStroke); - + public String getColorSpaceOut(boolean fillNotStroke) + { + return(""); + } public void setColorSpace(int theColorSpace) { diff --git a/src/org/apache/fop/pdf/PDFPattern.java b/src/org/apache/fop/pdf/PDFPattern.java index 097c43d0a..ecfa39f98 100644 --- a/src/org/apache/fop/pdf/PDFPattern.java +++ b/src/org/apache/fop/pdf/PDFPattern.java @@ -68,7 +68,8 @@ import org.apache.fop.datatypes.ColorSpace; * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range. */ public class PDFPattern extends PDFPathPaint { - + private PDFNumber pdfNumber = new PDFNumber(); + /** * The resources associated with this pattern */ @@ -216,7 +217,6 @@ public class PDFPattern extends PDFPathPaint { return (this.patternName); } - public String getColorSpaceOut(boolean fillNotStroke) { if(fillNotStroke) @@ -228,41 +228,6 @@ public class PDFPattern extends PDFPathPaint { return("/Pattern CS /"+this.getName()+" SCN \n"); } } - /** - * Output a Double prettily as a string - * - * @param doubleDown The Double to output. - * @return String representation of value passed. - */ - public String doubleOut(Double doubleDown) - { - StringBuffer p = new StringBuffer(); - double trouble = doubleDown.doubleValue() % 1; - if(trouble > 0.950) - { - p.append(doubleDown.intValue()+1); - } - else if (trouble < 0.050) - { - p.append(doubleDown.intValue()); - } - else - { - String doubleString = new String(doubleDown+""); - int decimal = doubleString.indexOf("."); - p.append(doubleString.substring(0, decimal)); - - if ((doubleString.length() - decimal) > 6) - { - p.append(doubleString.substring(decimal,decimal+6)); - } - else - { - p.append(doubleString.substring(decimal)); - } - } - return(p.toString()); - } /** @@ -304,12 +269,12 @@ public class PDFPattern extends PDFPathPaint { for (tempInt =0; tempInt < vectorSize; tempInt++) { p.append( - this.doubleOut((Double)this.bBox.elementAt(tempInt))); + pdfNumber.doubleOut((Double)this.bBox.elementAt(tempInt))); } p.append("] \n"); } - p.append("/XStep "+this.doubleOut(new Double(this.xStep))+" \n"); - p.append("/YStep "+this.doubleOut(new Double(this.yStep))+" \n"); + p.append("/XStep "+pdfNumber.doubleOut(new Double(this.xStep))+" \n"); + p.append("/YStep "+pdfNumber.doubleOut(new Double(this.yStep))+" \n"); if(this.matrix != null) { @@ -317,7 +282,7 @@ public class PDFPattern extends PDFPathPaint { p.append("/Matrix [ "); for (tempInt =0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.matrix.elementAt(tempInt))); } p.append("] \n"); @@ -370,7 +335,7 @@ public class PDFPattern extends PDFPathPaint { p.append("/Matrix [ "); for (tempInt =0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.matrix.elementAt(tempInt))); } p.append("] \n"); diff --git a/src/org/apache/fop/pdf/PDFShading.java b/src/org/apache/fop/pdf/PDFShading.java index da682fb73..948b92798 100644 --- a/src/org/apache/fop/pdf/PDFShading.java +++ b/src/org/apache/fop/pdf/PDFShading.java @@ -160,6 +160,8 @@ public class PDFShading extends PDFObject { */ protected int verticesPerRow = 0; + private PDFNumber pdfNumber = new PDFNumber(); + /** * Constructor for type function based shading * @@ -336,36 +338,6 @@ public class PDFShading extends PDFObject { return (this.shadingName); } - public String doubleOut(Double doubleDown) - { - StringBuffer p = new StringBuffer(); - double trouble = doubleDown.doubleValue() % 1; - if(trouble > 0.950) - { - p.append(doubleDown.intValue()+1); - } - else if (trouble < 0.050) - { - p.append(doubleDown.intValue()); - } - else - { - String doubleString = new String(doubleDown+""); - int decimal = doubleString.indexOf("."); - p.append(doubleString.substring(0, decimal)); - - if ((doubleString.length() - decimal) > 6) - { - p.append(doubleString.substring(decimal,decimal+6)); - } - else - { - p.append(doubleString.substring(decimal)); - } - } - return(p.toString()); - } - /** * represent as PDF. Whatever the shadingType is, the correct * representation spits out. The sets of required and optional @@ -395,7 +367,7 @@ public class PDFShading extends PDFObject { vectorSize = this.background.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.background.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -407,7 +379,7 @@ public class PDFShading extends PDFObject { vectorSize = this.bBox.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.bBox.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -427,7 +399,7 @@ public class PDFShading extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -443,7 +415,7 @@ public class PDFShading extends PDFObject { vectorSize = this.matrix.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.matrix.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -465,7 +437,7 @@ public class PDFShading extends PDFObject { vectorSize = this.coords.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.coords.elementAt(tempInt)) +" "); } p.append("] \n"); @@ -478,7 +450,7 @@ public class PDFShading extends PDFObject { vectorSize = this.domain.size(); for(tempInt=0; tempInt < vectorSize; tempInt++) { - p.append(this.doubleOut( + p.append(pdfNumber.doubleOut( (Double)this.domain.elementAt(tempInt)) +" "); } p.append("] \n"); diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index 0bf33a6e0..d4fca07c3 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -1,49 +1,49 @@ /*-- $Id$ -- ============================================================================ - The Apache Software License, Version 1.1 + The Apache Software License, Version 1.1 ============================================================================ - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. + Copyright (C) 1999 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. + include the following acknowledgment: "This product includes software + developed by the Apache Software Foundation (http://www.apache.org/)." + Alternately, this acknowledgment may appear in the software itself, if + and wherever such third-party acknowledgments normally appear. 4. The names "FOP" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. + endorse or promote products derived from this software without prior + written permission. For written permission, please contact + apache@apache.org. 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. + "Apache" appear in their name, without prior written permission of the + Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by + This software consists of voluntary contributions made by many individuals + on behalf of the Apache Software Foundation and was originally created by James Tauber . For more information on the Apache Software Foundation, please see . @@ -73,262 +73,261 @@ import java.util.Vector; */ public class PDFRenderer implements Renderer { - /** the PDF Document being created */ - protected PDFDocument pdfDoc; + /** the PDF Document being created */ + protected PDFDocument pdfDoc; - /** the /Resources object of the PDF document being created */ - protected PDFResources pdfResources; + /** the /Resources object of the PDF document being created */ + protected PDFResources pdfResources; - /** the current stream to add PDF commands to */ - PDFStream currentStream; + /** the current stream to add PDF commands to */ + PDFStream currentStream; - /** the current annotation list to add annotations to */ - PDFAnnotList currentAnnotList; + /** the current annotation list to add annotations to */ + PDFAnnotList currentAnnotList; - /** the current page to add annotations to */ - PDFPage currentPage; + /** the current page to add annotations to */ + PDFPage currentPage; - /** the current (internal) font name */ - protected String currentFontName; + /** the current (internal) font name */ + protected String currentFontName; - /** the current font size in millipoints */ - protected int currentFontSize; + /** the current font size in millipoints */ + protected int currentFontSize; - /** the current colour's red component */ - protected float currentRed = 0; + /** the current color/gradient for borders, letters, etc. */ + protected PDFPathPaint currentStroke = null; + + /** the current color/gradient to fill shapes with */ + protected PDFPathPaint currentFill = null; + + /** the current colour's red component */ + protected float currentRed = 0; - /** the current colour's green component */ - protected float currentGreen = 0; + /** the current colour's green component */ + protected float currentGreen = 0; - /** the current colour's blue component */ - protected float currentBlue = 0; + /** the current colour's blue component */ + protected float currentBlue = 0; - /** the current vertical position in millipoints from bottom */ - protected int currentYPosition = 0; + /** the current vertical position in millipoints from bottom */ + protected int currentYPosition = 0; - /** the current horizontal position in millipoints from left */ - protected int currentXPosition = 0; + /** the current horizontal position in millipoints from left */ + protected int currentXPosition = 0; - /** the horizontal position of the current area container */ - private int currentAreaContainerXPosition = 0; + /** the horizontal position of the current area container */ + private int currentAreaContainerXPosition = 0; - /** - * create the PDF renderer - */ - public PDFRenderer() { + /** + * create the PDF renderer + */ + public PDFRenderer() { this.pdfDoc = new PDFDocument(); - } - - /** - * set the PDF document's producer - * - * @param producer string indicating application producing PDF - */ - public void setProducer(String producer) { + } + + /** + * set the PDF document's producer + * + * @param producer string indicating application producing PDF + */ + public void setProducer(String producer) { this.pdfDoc.setProducer(producer); - } - - /** - * render the areas into PDF - * - * @param areaTree the laid-out area tree - * @param writer the PrintWriter to write the PDF with - */ - public void render(AreaTree areaTree, PrintWriter writer) + } + + /** + * render the areas into PDF + * + * @param areaTree the laid-out area tree + * @param writer the PrintWriter to write the PDF with + */ + public void render(AreaTree areaTree, PrintWriter writer) throws IOException { System.err.println("rendering areas to PDF"); this.pdfResources = this.pdfDoc.getResources(); Enumeration e = areaTree.getPages().elements(); while (e.hasMoreElements()) { - this.renderPage((Page) e.nextElement()); + this.renderPage((Page) e.nextElement()); } System.err.println("writing out PDF"); this.pdfDoc.output(writer); - } - - /** - * add a line to the current stream - * - * @param x1 the start x location in millipoints - * @param y1 the start y location in millipoints - * @param x2 the end x location in millipoints - * @param y2 the end y location in millipoints - * @param th the thickness in millipoints - * @param r the red component - * @param g the green component - * @param b the blue component - */ - protected void addLine(int x1, int y1, int x2, int y2, int th, - float r, float g, float b) { - currentStream.add(r + " " + g + " " + b + " RG\n" + } + + /** + * add a line to the current stream + * + * @param x1 the start x location in millipoints + * @param y1 the start y location in millipoints + * @param x2 the end x location in millipoints + * @param y2 the end y location in millipoints + * @param th the thickness in millipoints + * @param stroke the stroke color/gradient + */ + protected void addLine(int x1, int y1, int x2, int y2, int th, + PDFPathPaint stroke) { + + currentStream.add(stroke.getColorSpaceOut(false) + (x1/1000f) + " " + (y1/1000f) + " m " + (x2/1000f) + " " + (y2/1000f) + " l " + (th/1000f) + " w S\n" + "0 0 0 RG\n"); - } - - /** - * add a rectangle to the current stream - * - * @param x the x position of left edge in millipoints - * @param y the y position of top edge in millipoints - * @param w the width in millipoints - * @param h the height in millipoints - * @param r the red component - * @param g the green component - * @param b the blue component - */ - protected void addRect(int x, int y, int w, int h, - float r, float g, float b) { - currentStream.add(r + " " + g + " " + b + " RG\n" + } + + /** + * add a rectangle to the current stream + * + * @param x the x position of left edge in millipoints + * @param y the y position of top edge in millipoints + * @param w the width in millipoints + * @param h the height in millipoints + * @param stroke the stroke color/gradient + */ + protected void addRect(int x, int y, int w, int h, + PDFPathPaint stroke) { + currentStream.add(stroke.getColorSpaceOut(false) + (x/1000f) + " " + (y/1000f) + " " + (w/1000f) + " " + (h/1000f) + " re S\n" + "0 0 0 RG\n"); - } - - /** - * add a filled rectangle to the current stream - * - * @param x the x position of left edge in millipoints - * @param y the y position of top edge in millipoints - * @param w the width in millipoints - * @param h the height in millipoints - * @param r the red component of edges - * @param g the green component of edges - * @param b the blue component of edges - * @param fr the red component of the fill - * @param fg the green component of the fill - * @param fb the blue component of the fill - */ - protected void addRect(int x, int y, int w, int h, - float r, float g, float b, - float fr, float fg, float fb) { - currentStream.add(fr + " " + fg + " " + fb + " rg\n" - + r + " " + g + " " + b + " RG\n" + } + + /** + * add a filled rectangle to the current stream + * + * @param x the x position of left edge in millipoints + * @param y the y position of top edge in millipoints + * @param w the width in millipoints + * @param h the height in millipoints + * @param fill the fill color/gradient + * @param stroke the stroke color/gradient + */ + protected void addRect(int x, int y, int w, int h, + PDFPathPaint stroke, + PDFPathPaint fill) { + currentStream.add(fill.getColorSpaceOut(true) + + stroke.getColorSpaceOut(false) + (x/1000f) + " " + (y/1000f) + " " + (w/1000f) + " " + (h/1000f) + " re S\n" + (x/1000f) + " " + (y/1000f) + " " + (w/1000f) + " " + (h/1000f) + " re f\n" + "0 0 0 RG 0 0 0 rg\n"); - } - - /** - * render area container to PDF - * - * @param area the area container to render - */ - public void renderAreaContainer(AreaContainer area) { - - int saveY = this.currentYPosition; - int saveX = this.currentAreaContainerXPosition; - - if (area.getPosition() == Position.ABSOLUTE) { - // Y position is computed assuming positive Y axis, adjust for negative postscript one - this.currentYPosition = area.getYPosition() - 2 * area.getPaddingTop() - 2 * area.borderWidthTop; + } + + /** + * render area container to PDF + * + * @param area the area container to render + */ + public void renderAreaContainer(AreaContainer area) { + + int saveY = this.currentYPosition; + int saveX = this.currentAreaContainerXPosition; + + if (area.getPosition() == Position.ABSOLUTE) { + // Y position is computed assuming positive Y axis, adjust for negative postscript one + this.currentYPosition = area.getYPosition() - 2 * area.getPaddingTop() - 2 * area.borderWidthTop; this.currentAreaContainerXPosition = area.getXPosition(); - } else if (area.getPosition() == Position.RELATIVE) { + } else if (area.getPosition() == Position.RELATIVE) { this.currentYPosition -= area.getYPosition(); - this.currentAreaContainerXPosition += area.getXPosition(); - } else if (area.getPosition() == Position.STATIC) { + this.currentAreaContainerXPosition += area.getXPosition(); + } else if (area.getPosition() == Position.STATIC) { this.currentYPosition -= area.getPaddingTop() + area.borderWidthTop; - this.currentAreaContainerXPosition += area.getPaddingLeft() + area.borderWidthLeft; - } + this.currentAreaContainerXPosition += area.getPaddingLeft() + area.borderWidthLeft; + } - doFrame(area); - + doFrame(area); + Enumeration e = area.getChildren().elements(); while (e.hasMoreElements()) { - Box b = (Box) e.nextElement(); - b.render(this); + Box b = (Box) e.nextElement(); + b.render(this); + } + if (area.getPosition() != Position.STATIC) { + this.currentYPosition = saveY; + this.currentAreaContainerXPosition = saveX; + } else + this.currentYPosition -= area.getHeight(); } - if (area.getPosition() != Position.STATIC) { - this.currentYPosition = saveY; - this.currentAreaContainerXPosition = saveX; - } else - this.currentYPosition -= area.getHeight(); - } - - private void doFrame(Area area) { - int w, h; + + private void doFrame(Area area) { + int w, h; int rx = this.currentAreaContainerXPosition; w = area.getContentWidth(); - if (area instanceof BlockArea) + if (area instanceof BlockArea) rx += ((BlockArea)area).getStartIndent(); - h = area.getContentHeight(); + h = area.getContentHeight(); int ry = this.currentYPosition; ColorType bg = area.getBackgroundColor(); - - rx = rx - area.getPaddingLeft(); - ry = ry + area.getPaddingTop(); - w = w + area.getPaddingLeft() + area.getPaddingRight(); - h = h + area.getPaddingTop() + area.getPaddingBottom(); - + + rx = rx - area.getPaddingLeft(); + ry = ry + area.getPaddingTop(); + w = w + area.getPaddingLeft() + area.getPaddingRight(); + h = h + area.getPaddingTop() + area.getPaddingBottom(); + // I'm not sure I should have to check for bg being null // but I do if ((bg != null) && (bg.alpha() == 0)) { - this.addRect(rx, ry, w, -h, - bg.red(), bg.green(), bg.blue(), - bg.red(), bg.green(), bg.blue()); + this.addRect(rx, ry, w, -h, + new PDFColor(bg), + new PDFColor(bg)); } - - rx = rx - area.borderWidthLeft; - ry = ry + area.borderWidthTop; - w = w + area.borderWidthLeft + area.borderWidthRight; - h = h + area.borderWidthTop + area.borderWidthBottom; - - if (area.borderWidthTop != 0) - addLine(rx, ry, rx + w, ry, - area.borderWidthTop, - area.borderColorTop.red(), area.borderColorTop.green(), area.borderColorTop.blue()); - if (area.borderWidthLeft != 0) - addLine(rx, ry, rx, ry - h, - area.borderWidthLeft, - area.borderColorLeft.red(), area.borderColorLeft.green(), area.borderColorLeft.blue()); - if (area.borderWidthRight != 0) - addLine(rx + w, ry, rx + w, ry - h, - area.borderWidthRight, - area.borderColorRight.red(), area.borderColorRight.green(), area.borderColorRight.blue()); - if (area.borderWidthBottom != 0) - addLine(rx, ry - h, rx + w, ry - h, - area.borderWidthBottom, - area.borderColorBottom.red(), area.borderColorBottom.green(), area.borderColorBottom.blue()); - - } + + rx = rx - area.borderWidthLeft; + ry = ry + area.borderWidthTop; + w = w + area.borderWidthLeft + area.borderWidthRight; + h = h + area.borderWidthTop + area.borderWidthBottom; + + if (area.borderWidthTop != 0) + addLine(rx, ry, rx + w, ry, + area.borderWidthTop, + new PDFColor(area.borderColorTop)); + if (area.borderWidthLeft != 0) + addLine(rx, ry, rx, ry - h, + area.borderWidthLeft, + new PDFColor(area.borderColorLeft)); + if (area.borderWidthRight != 0) + addLine(rx + w, ry, rx + w, ry - h, + area.borderWidthRight, + new PDFColor(area.borderColorRight)); + if (area.borderWidthBottom != 0) + addLine(rx, ry - h, rx + w, ry - h, + area.borderWidthBottom, + new PDFColor(area.borderColorBottom)); + + } - /** - * render block area to PDF - * - * @param area the block area to render - */ - public void renderBlockArea(BlockArea area) { - doFrame(area); + /** + * render block area to PDF + * + * @param area the block area to render + */ + public void renderBlockArea(BlockArea area) { + doFrame(area); Enumeration e = area.getChildren().elements(); while (e.hasMoreElements()) { - Box b = (Box) e.nextElement(); - b.render(this); + Box b = (Box) e.nextElement(); + b.render(this); + } } - } - - /** - * render display space to PDF - * - * @param space the display space to render - */ - public void renderDisplaySpace(DisplaySpace space) { + + /** + * render display space to PDF + * + * @param space the display space to render + */ + public void renderDisplaySpace(DisplaySpace space) { int d = space.getSize(); this.currentYPosition -= d; - } - - /** - * render image area to PDF - * - * @param area the image area to render - */ - public void renderImageArea(ImageArea area) { + } + + /** + * render image area to PDF + * + * @param area the image area to render + */ + public void renderImageArea(ImageArea area) { // adapted from contribution by BoBoGi int x = this.currentAreaContainerXPosition + - area.getXOffset(); + area.getXOffset(); int y = this.currentYPosition; int w = area.getContentWidth(); int h = area.getHeight(); @@ -344,14 +343,14 @@ public class PDFRenderer implements Renderer { ((x + img.getX())/1000f) + " " + (((y - h) - img.getY())/1000f) + " cm\n" + "/Im" + xObjectNum + " Do\nQ\nBT\n"); - } - - /** - * render SVG area to PDF - * - * @param area the SVG area to render - */ - public void renderSVGArea(SVGArea area) { + } + + /** + * render SVG area to PDF + * + * @param area the SVG area to render + */ + public void renderSVGArea(SVGArea area) { int x = this.currentAreaContainerXPosition; int y = this.currentYPosition; int w = area.getContentWidth(); @@ -359,20 +358,20 @@ public class PDFRenderer implements Renderer { this.currentYPosition -= h; Enumeration e = area.getChildren().elements(); while (e.hasMoreElements()) { - Object o = e.nextElement(); - if (o instanceof RectGraphic) { + Object o = e.nextElement(); + if (o instanceof RectGraphic) { int rx = ((RectGraphic)o).x; int ry = ((RectGraphic)o).y; int rw = ((RectGraphic)o).width; int rh = ((RectGraphic)o).height; - addRect(x+rx,y-ry,rw,-rh,0,0,0); - } else if (o instanceof LineGraphic) { + addRect(x+rx,y-ry,rw,-rh,new PDFColor(0,0,0)); + } else if (o instanceof LineGraphic) { int x1 = ((LineGraphic)o).x1; int y1 = ((LineGraphic)o).y1; int x2 = ((LineGraphic)o).x2; int y2 = ((LineGraphic)o).y2; - addLine(x+x1,y-y1,x+x2,y-y2,0,0,0,0); - } else if (o instanceof TextGraphic) { + addLine(x+x1,y-y1,x+x2,y-y2,0,new PDFColor(0,0,0)); + } else if (o instanceof TextGraphic) { int tx = ((TextGraphic)o).x; int ty = ((TextGraphic)o).y; String s = ((TextGraphic)o).s; @@ -380,41 +379,39 @@ public class PDFRenderer implements Renderer { + ((x+tx)/1000f) + " " + ((y-ty)/1000f) + " Tm " + "(" + s + ") Tj\n"); - } + } + } } - } - - /** - * render inline area to PDF - * - * @param area inline area to render - */ - public void renderInlineArea(InlineArea area) { + + /** + * render inline area to PDF + * + * @param area inline area to render + */ + public void renderInlineArea(InlineArea area) { char ch; StringBuffer pdf = new StringBuffer(); String name = area.getFontState().getFontName(); int size = area.getFontState().getFontSize(); - - float red = area.getRed(); - float green = area.getGreen(); - float blue = area.getBlue(); + + PDFColor theAreaColor = new PDFColor( + (double)area.getRed(), + (double)area.getGreen(), + (double)area.getBlue() ); if ((!name.equals(this.currentFontName)) - || (size != this.currentFontSize)) { - this.currentFontName = name; - this.currentFontSize = size; - pdf = pdf.append("/" + name + " " + (size/1000) + " Tf\n"); + || (size != this.currentFontSize)) { + this.currentFontName = name; + this.currentFontSize = size; + pdf = pdf.append("/" + name + " " + (size/1000) + " Tf\n"); } - if ((red != this.currentRed) - || (green != this.currentGreen) - || (blue != this.currentBlue)) { - this.currentRed = red; - this.currentGreen = green; - this.currentBlue = blue; - pdf = pdf.append(red + " " + green + " " + blue + " rg\n"); - } + //if (theAreaColor.isEquivalent(this.currentFill)) { + this.currentFill = theAreaColor; + + pdf = pdf.append(this.currentFill.getColorSpaceOut(true)); + //} int rx = this.currentXPosition; int bl = this.currentYPosition; @@ -427,43 +424,43 @@ public class PDFRenderer implements Renderer { int l = s.length(); for (int i=0; i < l; i++) { - ch = s.charAt(i); - if (ch > 127) { + ch = s.charAt(i); + if (ch > 127) { pdf = pdf.append("\\"); pdf = pdf.append(Integer.toOctalString((int)ch)); - } else { + } else { switch (ch) { case '(' : pdf = pdf.append("\\("); break; case ')' : pdf = pdf.append("\\)"); break; case '\\' : pdf = pdf.append("\\\\"); break; default : pdf = pdf.append(ch); break; } - } + } } pdf = pdf.append(") Tj\n"); currentStream.add(pdf.toString()); this.currentXPosition += area.getContentWidth(); - } - - /** - * render inline space to PDF - * - * @param space space to render - */ - public void renderInlineSpace(InlineSpace space) { + } + + /** + * render inline space to PDF + * + * @param space space to render + */ + public void renderInlineSpace(InlineSpace space) { this.currentXPosition += space.getSize(); - } - - /** - * render line area to PDF - * - * @param area area to render - */ - public void renderLineArea(LineArea area) { + } + + /** + * render line area to PDF + * + * @param area area to render + */ + public void renderLineArea(LineArea area) { int rx = this.currentAreaContainerXPosition - + area.getStartIndent(); + + area.getStartIndent(); int ry = this.currentYPosition; int w = area.getContentWidth(); int h = area.getHeight(); @@ -475,21 +472,21 @@ public class PDFRenderer implements Renderer { Enumeration e = area.getChildren().elements(); while (e.hasMoreElements()) { - Box b = (Box) e.nextElement(); - b.render(this); + Box b = (Box) e.nextElement(); + b.render(this); } this.currentYPosition = ry-h; - } - - /** - * render page into PDF - * - * @param page page to render - */ - public void renderPage(Page page) { + } + + /** + * render page into PDF + * + * @param page page to render + */ + public void renderPage(Page page) { AreaContainer body, before, after; - + currentStream = this.pdfDoc.makeStream(); body = page.getBody(); before = page.getBefore(); @@ -502,69 +499,66 @@ public class PDFRenderer implements Renderer { renderAreaContainer(body); if (before != null) { - renderAreaContainer(before); + renderAreaContainer(before); } if (after != null) { - renderAreaContainer(after); + renderAreaContainer(after); } currentStream.add("ET\n"); currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream, - page.getWidth()/1000, - page.getHeight()/1000); + page.getWidth()/1000, + page.getHeight()/1000); if (page.hasLinks()) { - currentAnnotList = this.pdfDoc.makeAnnotList(); - currentPage.setAnnotList(currentAnnotList); + currentAnnotList = this.pdfDoc.makeAnnotList(); + currentPage.setAnnotList(currentAnnotList); - Enumeration e = page.getLinkSets().elements(); - while (e.hasMoreElements()) { + Enumeration e = page.getLinkSets().elements(); + while (e.hasMoreElements()) { LinkSet linkSet = (LinkSet) e.nextElement(); linkSet.align(); String dest = linkSet.getDest(); Enumeration f = linkSet.getRects().elements(); while (f.hasMoreElements()) { - LinkedRectangle lrect = (LinkedRectangle) f.nextElement(); - currentAnnotList.addLink( - this.pdfDoc.makeLink(lrect.getRectangle(), dest)); + LinkedRectangle lrect = (LinkedRectangle) f.nextElement(); + currentAnnotList.addLink( + this.pdfDoc.makeLink(lrect.getRectangle(), dest)); + } } - } } else { - // just to be on the safe side - currentAnnotList = null; + // just to be on the safe side + currentAnnotList = null; + } } - } - - /** - * render rule area into PDF - * - * @param area area to render - */ - public void renderRuleArea(RuleArea area) { + + /** + * render rule area into PDF + * + * @param area area to render + */ + public void renderRuleArea(RuleArea area) { int rx = this.currentAreaContainerXPosition - + area.getStartIndent(); + + area.getStartIndent(); int ry = this.currentYPosition; int w = area.getContentWidth(); int h = area.getHeight(); int th = area.getRuleThickness(); - float r = area.getRed(); - float g = area.getGreen(); - float b = area.getBlue(); - addLine(rx, ry, rx+w, ry, th, r, g, b); - } - - /** - * set up the font info - * - * @param fontInfo font info to set up - */ - public void setupFontInfo(FontInfo fontInfo) { + addLine(rx, ry, rx+w, ry, th, new PDFColor(area.getRed(), area.getGreen(),area.getBlue())); + } + + /** + * set up the font info + * + * @param fontInfo font info to set up + */ + public void setupFontInfo(FontInfo fontInfo) { FontSetup.setup(fontInfo); FontSetup.addToResources(this.pdfDoc, fontInfo); - } + } } -- 2.39.5