]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added internal-link functionality
authorJordan Naftolin <jordan@apache.org>
Wed, 21 Jun 2000 01:40:56 +0000 (01:40 +0000)
committerJordan Naftolin <jordan@apache.org>
Wed, 21 Jun 2000 01:40:56 +0000 (01:40 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@193417 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/layout/LinkSet.java
src/org/apache/fop/layout/Page.java
src/org/apache/fop/pdf/PDFDocument.java

index 32172bc7d92ab1068a00194a4719eea627ff39f2..67155d0f039eff268b861a461d5d9a0cafd7a925 100644 (file)
@@ -75,7 +75,7 @@ import org.apache.fop.fo.properties.TextAlignLast; // for enumerated
 public class LinkSet {
 
     /** the destination of the links */
-    String externalDestination;
+    String destination;
 
     /** the set of rectangles */
     Vector rects = new Vector();
@@ -89,14 +89,21 @@ public class LinkSet {
     protected int startIndent;
     protected int endIndent;
 
+    private int linkType;
+
     private Area area;
 
+    public final static int 
+        INTERNAL = 0,  // represents internal link
+        EXTERNAL = 1;  // represents external link    
+
     // property required for alignment adjustments
     int contentRectangleWidth = 0;
 
-    public LinkSet(String externalDest, Area area) {
-       this.externalDestination = externalDest;
+    public LinkSet(String destination, Area area, int linkType) {
+       this.destination = destination;
        this.area = area;
+        this.linkType = linkType;
     }
     
     public void addRect(Rectangle r, LineArea lineArea) {
@@ -170,7 +177,7 @@ public class LinkSet {
     }
 
     public String getDest() {
-       return this.externalDestination;
+       return this.destination;
     }
 
     public Vector getRects() {
@@ -188,4 +195,8 @@ public class LinkSet {
     public Area getArea() {
        return area;
     }
+
+    public int getLinkType(){
+        return linkType;
+    }
 }
index 18db9fa64c2d07d7a6ef7e6ed7804cec635c705a..304a1b409df5b524115c54087a1800d453563283 100644 (file)
@@ -75,6 +75,8 @@ public class Page {
 
     protected Vector linkSets = new Vector();
 
+    private Vector idList = new Vector();
+
     Page(AreaTree areaTree, int height, int width) {
        this.areaTree = areaTree;
        this.height = height;
@@ -153,4 +155,12 @@ public class Page {
     public boolean hasLinks() {
        return (!this.linkSets.isEmpty());
     }
+
+    public void addToIDList(String id){
+        idList.addElement(id);
+    }
+
+    public Vector getIDList(){
+        return idList;
+    }
 }
index 72710eeb23a3e0752a8ab7daf4e2864d27fe48be..bf577d966e0e10e748905e7d3960fafc57d8f05d 100644 (file)
@@ -1,35 +1,35 @@
 /*-- $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.
+    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
@@ -57,15 +57,19 @@ package org.apache.fop.pdf;
 // referenced and I'd rather not do it
 import org.apache.fop.image.FopImage;
 
+import org.apache.fop.layout.LinkSet;
 import org.apache.fop.datatypes.ColorSpace;
 
+import org.apache.fop.datatypes.IDReferences;
+import org.apache.fop.layout.Page;
 // Java
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Vector;
 import java.util.Hashtable;
+import java.util.Enumeration;
 import java.awt.Rectangle;
-                                                          
+
 /**
  * class representing a PDF document. 
  *
@@ -81,870 +85,901 @@ import java.awt.Rectangle;
  */
 public class PDFDocument {
 
-       /** the version of PDF supported */
-       protected static final String pdfVersion = "1.3";
-
-       /** the current character position */
-       protected int position = 0;
-
-       /** the character position of each object */
-       protected Vector location = new Vector();
-
-       /** the counter for object numbering */
-       protected int objectcount = 0;
-               
-       /** the objects themselves */
-       protected Vector objects = new Vector();
-
-       /** character position of xref table */
-       protected int xref;
-
-       /** the /Root object */
-       protected PDFRoot root;
-
-       /** the /Info object */
-       protected PDFInfo info;
-
-       /** the /Resources object */
-       protected PDFResources resources;
-
-       /** the colorspace (0=RGB, 1=CMYK) **/
-       //protected int colorspace = 0;
-       protected ColorSpace colorspace = new ColorSpace(ColorSpace.DEVICE_RGB);
-       
-       /** the counter for Pattern name numbering (e.g. 'Pattern1')*/
-       protected int patternCount = 0;
-       
-       /** the counter for Shading name numbering */
-       protected int shadingCount = 0;
-       
-       /** the counter for XObject numbering */
-       protected int xObjectCount = 0;
-
-       /** the XObjects */
-       protected Vector xObjects = new Vector();
-
-       /** the XObjects Map. 
-       Should be modified (works only for image subtype) */
-       protected Hashtable xObjectsMap = new Hashtable();
-
-       /**
-        * creates an empty PDF document
-        */
-       public PDFDocument() {
-
-               /* create the /Root, /Info and /Resources objects */
-               this.root = makeRoot();
-               this.info = makeInfo();
-               this.resources = makeResources();
-       }
-       
-       /**
-        * set the producer of the document
-        *
-        * @param producer string indicating application producing the PDF
-        */
-       public void setProducer(String producer) {
-       this.info.setProducer(producer);
-       }
-
-       /**
-        * make /Root object as next object
-        *
-        * @return the created /Root object
-        */
-       protected PDFRoot makeRoot() {
-
-       /* create a PDFRoot with the next object number and add to
-          list of objects */
-       PDFRoot pdfRoot = new PDFRoot(++this.objectcount);
-       this.objects.addElement(pdfRoot);
-
-       /* create a new /Pages object to be root of Pages hierarchy
-          and add to list of objects */
-       PDFPages rootPages = new PDFPages(++this.objectcount);
-       this.objects.addElement(rootPages);
-       
-       /* inform the /Root object of the /Pages root */
-       pdfRoot.setRootPages(rootPages);
-       return pdfRoot;
-       }
-
-       /**
-        * make an /Info object
-        *
-        * @param producer string indicating application producing the PDF
-        * @return the created /Info object
-        */
-       protected PDFInfo makeInfo() {
-
-       /* create a PDFInfo with the next object number and add to
-          list of objects */
-       PDFInfo pdfInfo = new PDFInfo(++this.objectcount);
-       this.objects.addElement(pdfInfo);
-       return pdfInfo;
-       }
-
-       /**
-        * make a /Resources object
-        *
-        * @return the created /Resources object
-        */
-       private PDFResources makeResources() {
-
-       /* create a PDFResources with the next object number and add
-          to list of objects */
-       PDFResources pdfResources = new PDFResources(++this.objectcount);
-       this.objects.addElement(pdfResources);
-       return pdfResources;
-       }
-       
-       /**
-        * Make a Type 0 sampled function
-        * 
-        * @param theDomain Vector objects of Double objects.
-        * This is the domain of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theRange Vector objects of Double objects.
-        * This is the Range of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theSize A Vector object of Integer objects.
-        * This is the number of samples in each input dimension.
-        * I can't imagine there being more or less than two input dimensions,
-        * so maybe this should be an array of length 2.
-        * 
-        * See page 265 of the PDF 1.3 Spec.
-        * @param theBitsPerSample An int specifying the number of bits user to represent each sample value.
-        * Limited to 1,2,4,8,12,16,24 or 32.
-        * See page 265 of the 1.3 PDF Spec.
-        * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited
-        * to 1 (one) or 3, which means linear or cubic-spline interpolation.
-        * 
-        * This attribute is optional.
-        * 
-        * See page 265 in the PDF 1.3 spec.
-        * @param theEncode Vector objects of Double objects.
-        * This is the linear mapping of input values intop the domain
-        * of the function's sample table. Default is hard to represent in
-        * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
-        * This attribute is optional.
-        * 
-        * See page 265 in the PDF 1.3 spec.
-        * @param theDecode Vector objects of Double objects.
-        * This is a linear mapping of sample values into the range.
-        * The default is just the range.
-        * 
-        * This attribute is optional.
-        * Read about it on page 265 of the PDF 1.3 spec.
-        * @param theFunctionDataStream The sample values that specify the function are provided in a stream.
-        * 
-        * This is optional, but is almost always used.
-        * 
-        * Page 265 of the PDF 1.3 spec has more.
-        * @param theFilter This is a vector of String objects which are the various filters that
-        * have are to be applied to the stream to make sense of it. Order matters,
-        * so watch out.
-        * 
-        * This is not documented in the Function section of the PDF 1.3 spec,
-        * it was deduced from samples that this is sometimes used, even if we may never
-        * use it in FOP. It is added for completeness sake.
-        * @param theNumber The object number of this PDF object.
-        * @param theFunctionType This is the type of function (0,2,3, or 4).
-        * It should be 0 as this is the constructor for sampled functions.
-        */
-       public PDFFunction makeFunction(int theFunctionType,
-                       Vector theDomain, Vector theRange,
-                       Vector theSize,int theBitsPerSample,
-                       int theOrder,Vector theEncode,Vector theDecode,
-                       StringBuffer theFunctionDataStream, Vector theFilter)
-       {//Type 0 function
-               PDFFunction function = new PDFFunction(
-                       ++this.objectcount, theFunctionType,
-                       theDomain, theRange,    theSize,
-                       theBitsPerSample,       theOrder,
-                       theEncode, theDecode,
-                       theFunctionDataStream,  theFilter);
-
-               this.objects.addElement(function);
-               return(function);
-       }
-       
-       /**
-        * make a type Exponential interpolation function
-        * (for shading usually)
-        * 
-        * @param theDomain Vector objects of Double objects.
-        * This is the domain of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theRange Vector of Doubles that is the Range of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theCZero This is a vector of Double objects which defines the function result
-        * when x=0.
-        * 
-        * This attribute is optional.
-        * It's described on page 268 of the PDF 1.3 spec.
-        * @param theCOne This is a vector of Double objects which defines the function result
-        * when x=1.
-        * 
-        * This attribute is optional.
-        * It's described on page 268 of the PDF 1.3 spec.
-        * @param theInterpolationExponentN This is the inerpolation exponent.
-        * 
-        * This attribute is required.
-        * PDF Spec page 268
-        * @param theFunctionType The type of the function, which should be 2.
-        */
-       public PDFFunction makeFunction(int theFunctionType,
-               Vector theDomain, Vector theRange,
-               Vector theCZero, Vector theCOne,
-               double theInterpolationExponentN)
-       
-       {//type 2
-               PDFFunction function = new PDFFunction(
-               ++this.objectcount,
-               theFunctionType,
-               theDomain, theRange,
-               theCZero, theCOne,
-               theInterpolationExponentN);
-               
-               this.objects.addElement(function);
-               return(function);
-       }
-
-       /**
-        * Make a Type 3 Stitching function
-        * 
-        * @param theDomain Vector objects of Double objects.
-        * This is the domain of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theRange Vector objects of Double objects.
-        * This is the Range of the function.
-        * See page 264 of the PDF 1.3 Spec.
-        * @param theFunctions A Vector of the PDFFunction objects that the stitching function stitches.
-        * 
-        * This attributed is required.
-        * It is described on page 269 of the PDF spec.
-        * @param theBounds This is a vector of Doubles representing the numbers that,
-        * in conjunction with Domain define the intervals to which each function from
-        * the 'functions' object applies. It must be in order of increasing magnitude,
-        * and each must be within Domain.
-        * 
-        * It basically sets how much of the gradient each function handles.
-        * 
-        * This attributed is required.
-        * It's described on page 269 of the PDF 1.3 spec.
-        * @param theEncode Vector objects of Double objects.
-        * This is the linear mapping of input values intop the domain
-        * of the function's sample table. Default is hard to represent in
-        * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
-        * This attribute is required.
-        * 
-        * See page 270 in the PDF 1.3 spec.
-        * @param theFunctionType This is the function type. It should be 3,
-        * for a stitching function.
-        */
-       public PDFFunction makeFunction(int theFunctionType,
-               Vector theDomain, Vector theRange,
-               Vector theFunctions, Vector theBounds,
-               Vector theEncode)
-       {//Type 3
-               
-               PDFFunction function = new PDFFunction(
-                       ++this.objectcount,
-                       theFunctionType,
-                       theDomain, theRange,
-                       theFunctions, theBounds,
-                       theEncode);                     
-               
-               this.objects.addElement(function);
-               return(function);       
-       }
-       
-       /**
-        * make a postscript calculator function
-        * 
-        * @param theNumber
-        * @param theFunctionType
-        * @param theDomain
-        * @param theRange
-        * @param theFunctionDataStream
-        */
-       public PDFFunction makeFunction(int theNumber, int theFunctionType,
-                       Vector theDomain, Vector theRange,
-                       StringBuffer theFunctionDataStream)
-       { //Type 4
-               PDFFunction function = new PDFFunction(
-                       ++this.objectcount,
-                       theFunctionType,
-                       theDomain, theRange,
-                       theFunctionDataStream);
-
-               this.objects.addElement(function);
-               return(function);       
-
-       }
-       
-       /**
-        * make a function based shading object
-        * 
-        * @param theShadingType The type of shading object, which should be 1 for function
-        * based shading.
-        * @param theColorSpace The colorspace is 'DeviceRGB' or something similar.
-        * @param theBackground An array of color components appropriate to the
-        * colorspace key specifying a single color value.
-        * This key is used by the f operator buy ignored by the sh operator.
-        * @param theBBox Vector of double's representing a rectangle
-        * in the coordinate space that is current at the
-        * time of shading is imaged. Temporary clipping
-        * boundary.
-        * @param theAntiAlias Whether or not to anti-alias.
-        * @param theDomain Optional vector of Doubles specifying the domain.
-        * @param theMatrix Vector of Doubles specifying the matrix.
-        * If it's a pattern, then the matrix maps it to pattern space.
-        * If it's a shading, then it maps it to current user space.
-        * It's optional, the default is the identity matrix
-        * @param theFunction The PDF Function that maps an (x,y) location to a color
-        */
-       public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
-               Vector theBackground, Vector theBBox, boolean theAntiAlias,
-               Vector theDomain, Vector theMatrix, PDFFunction theFunction)
-       {       //make Shading of Type 1
-               String theShadingName = new String("Sh"+(++this.shadingCount));
-       
-               PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
-                       theShadingType, theColorSpace, theBackground, theBBox,
-                       theAntiAlias, theDomain, theMatrix, theFunction);
-               this.objects.addElement(shading);
-               
-               //add this shading to resources
-               this.resources.addShading(shading);
-
-               return(shading);
-       }
-       
-   /**
-       * Make an axial or radial shading object.
-       * 
-                * @param theShadingType 2 or 3 for axial or radial shading
-                * @param theColorSpace "DeviceRGB" or similar.
-                * @param theBackground theBackground An array of color components appropriate to the
-                * colorspace key specifying a single color value.
-                * This key is used by the f operator buy ignored by the sh operator.
-                * @param theBBox Vector of double's representing a rectangle
-                * in the coordinate space that is current at the
-                * time of shading is imaged. Temporary clipping
-                * boundary.
-                * @param theAntiAlias Default is false
-                * @param theCoords Vector of four (type 2) or 6 (type 3) Double
-                * @param theDomain Vector of Doubles specifying the domain
-                * @param theFunction the Stitching (PDFfunction type 3) function, even if it's stitching a single function
-                * @param theExtend Vector of Booleans of whether to extend teh start and end colors past the start and end points
-                * The default is [false, false]
-       */
-   public PDFShading makeShading(int theShadingType,
-       ColorSpace theColorSpace, Vector theBackground,
-       Vector theBBox, boolean theAntiAlias,
-               Vector theCoords, Vector theDomain,
-               PDFFunction theFunction, Vector theExtend)
-       { //make Shading of Type 2 or 3
-               String theShadingName = new String("Sh"+(++this.shadingCount));
-               
-               PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
-                       theShadingType, theColorSpace,
-                       theBackground, theBBox, theAntiAlias,
-                       theCoords, theDomain,theFunction,theExtend);
-
-               this.resources.addShading(shading);
-               
-               this.objects.addElement(shading);
-               return(shading);
-       }
-       
-       /**
-        * Make a free-form gouraud shaded triangle mesh, coons patch mesh, or tensor patch mesh 
-        * shading object
-        * 
-        * @param theShadingType 4, 6, or 7 depending on whether it's
-        * Free-form gouraud-shaded triangle meshes, coons patch meshes, 
-        * or tensor product patch meshes, respectively.
-        * @param theColorSpace "DeviceRGB" or similar.
-        * @param theBackground theBackground An array of color components appropriate to the
-        * colorspace key specifying a single color value.
-        * This key is used by the f operator buy ignored by the sh operator.
-        * @param theBBox Vector of double's representing a rectangle
-        * in the coordinate space that is current at the
-        * time of shading is imaged. Temporary clipping
-        * boundary.
-        * @param theAntiAlias Default is false
-        * @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32.
-        * @param theBitsPerComponent 1,2,4,8,12, and 16
-        * @param theBitsPerFlag 2,4,8.
-        * @param theDecode Vector of Doubles see PDF 1.3 spec pages 303 to 312.
-        * @param theFunction the PDFFunction
-        */
-       public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
-               Vector theBackground, Vector theBBox, boolean theAntiAlias,
-               int theBitsPerCoordinate, int theBitsPerComponent,
-               int theBitsPerFlag, Vector theDecode, PDFFunction theFunction)
-       { //make Shading of type 4,6 or 7
-               String theShadingName = new String("Sh"+(++this.shadingCount));
-               
-               PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
-                       theShadingType, theColorSpace,
-                       theBackground, theBBox, theAntiAlias,
-                       theBitsPerCoordinate,theBitsPerComponent,
-                       theBitsPerFlag, theDecode, theFunction);
-
-               this.resources.addShading(shading);
-               
-               this.objects.addElement(shading);
-               return(shading);
-       }
-       
-       /**
-        * make a Lattice-Form Gouraud mesh shading object
-        * 
-        * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh
-        * without spaces. "Shading1" or "Sh1" are good examples.
-        * @param theColorSpace "DeviceRGB" or similar.
-        * @param theBackground theBackground An array of color components appropriate to the
-        * colorspace key specifying a single color value.
-        * This key is used by the f operator buy ignored by the sh operator.
-        * @param theBBox Vector of double's representing a rectangle
-        * in the coordinate space that is current at the
-        * time of shading is imaged. Temporary clipping
-        * boundary.
-        * @param theAntiAlias Default is false
-        * @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32
-        * @param theBitsPerComponent 1,2,4,8,12,24,32
-        * @param theDecode Vector of Doubles. See page 305 in PDF 1.3 spec.
-        * @param theVerticesPerRow number of vertices in each "row" of the lattice.
-        * @param theFunction The PDFFunction that's mapped on to this shape
-        */
-       public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
-               Vector theBackground, Vector theBBox, boolean theAntiAlias,
-               int theBitsPerCoordinate, int theBitsPerComponent,
-               Vector theDecode, int theVerticesPerRow, PDFFunction theFunction)
-       { //make shading of Type 5
-               String theShadingName = new String("Sh"+(++this.shadingCount));
-               
-               PDFShading shading= new PDFShading(++this.objectcount,
-                       theShadingName, theShadingType, theColorSpace,
-                       theBackground, theBBox, theAntiAlias,
-                       theBitsPerCoordinate, theBitsPerComponent,
-                       theDecode, theVerticesPerRow, theFunction);
-
-               this.resources.addShading(shading);
-               
-               this.objects.addElement(shading);
-               
-               return(shading);
-       }
-       
-       /**
-        * Make a tiling pattern
-        * 
-        * @param thePatternType the type of pattern, which is 1 for tiling. 
-        * @param theResources the resources associated with this pattern
-        * @param thePaintType 1 or 2, colored or uncolored.
-        * @param theTilingType 1, 2, or 3, constant spacing, no distortion, or faster tiling
-        * @param theBBox Vector of Doubles: The pattern cell bounding box
-        * @param theXStep horizontal spacing
-        * @param theYStep vertical spacing
-        * @param theMatrix Optional Vector of Doubles transformation matrix
-        * @param theXUID Optional vector of Integers that uniquely identify the pattern
-        * @param thePatternDataStream The stream of pattern data to be tiled.
-        */
-       public PDFPattern makePattern(
-                       int thePatternType, //1
-                       PDFResources theResources, 
-                       int thePaintType, int theTilingType,
-                       Vector theBBox, double theXStep, double theYStep,
-                       Vector theMatrix, Vector theXUID, StringBuffer thePatternDataStream)
-       {
-               String thePatternName = new String("Pa"+(++this.patternCount));
-               //int theNumber, String thePatternName,
-                       //PDFResources theResources
-                       PDFPattern pattern = new PDFPattern(++this.objectcount,
-                       thePatternName,
-                       theResources, 1,
-                       thePaintType, theTilingType,
-                       theBBox, theXStep, theYStep,
-                       theMatrix, theXUID, thePatternDataStream);
-                       
-                       this.resources.addPattern(pattern);
-                       this.objects.addElement(pattern);
-                       
-                       return(pattern);
-       }
-       
-       /**
-        * Make a smooth shading pattern
-        * 
-        * @param thePatternType the type of the pattern, which is 2, smooth shading
-        * @param theShading the PDF Shading object that comprises this pattern
-        * @param theXUID optional:the extended unique Identifier if used.
-        * @param theExtGState optional: the extended graphics state, if used.
-        * @param theMatrix Optional:Vector of Doubles that specify the matrix.
-        */
-       public PDFPattern makePattern(int thePatternType,
-               PDFShading theShading, Vector theXUID,
-               StringBuffer theExtGState,Vector theMatrix)
-       {
-               String thePatternName = new String("Pa"+(++this.patternCount));
-
-               PDFPattern pattern = new PDFPattern(++this.objectcount,
-               thePatternName, 2, theShading, theXUID,
-               theExtGState, theMatrix);
-               
-               this.resources.addPattern(pattern);
-               this.objects.addElement(pattern);
-               
-               return(pattern);
-       }
-
-       public int getColorSpace()
-       {
-               return(this.colorspace.getColorSpace());
-       }
-       
-       public void setColorSpace(int theColorspace)
-       {
-               this.colorspace.setColorSpace(theColorspace);
-               return;
-       }
-       
-       public PDFPattern createGradient(boolean radial,
-                                                                       ColorSpace theColorspace,
-                                                                       Vector theColors,
-                                                                       Vector theBounds,
-                                                                       Vector theCoords)
-       {
-               PDFShading myShad;
-               PDFFunction myfunky;
-               PDFFunction myfunc;
-               Vector theCzero;
-               Vector theCone;
-               PDFPattern myPattern;
-               ColorSpace theColorSpace;
-               double interpolation = (double) 1.000;
-               Vector theFunctions = new Vector();
-
-         int currentPosition;
-         int lastPosition = theColors.size()-2;
-         
-         
-         //if 5 elements, the penultimate element is 3.
-         //do not go beyond that, because you always need
-         //to have a next color when creating the function.
-
-         for(currentPosition=0;
-               currentPosition < lastPosition;
-               currentPosition++)
-         {//for every consecutive color pair
-               PDFColor currentColor = 
-                               (PDFColor)theColors.elementAt(currentPosition);
-               PDFColor nextColor = 
-                               (PDFColor)theColors.elementAt(currentPosition+1);
-                       //colorspace must be consistant
-                       if (this.colorspace.getColorSpace() != currentColor.getColorSpace())
-                               currentColor.setColorSpace(this.colorspace.getColorSpace());
-                       
-                       if (this.colorspace.getColorSpace() != nextColor.getColorSpace())
-                               nextColor.setColorSpace(this.colorspace.getColorSpace());
-                                               
-                       theCzero = currentColor.getVector();
-                       theCone = nextColor.getVector();
-                       
-                       myfunc = this.makeFunction(
-                               2, null, null,
-                               theCzero, theCone,
-                               interpolation);
-                       
-                       theFunctions.addElement(myfunc);
-               
-               }//end of for every consecutive color pair
-               
-               myfunky = this.makeFunction(3,
-                       null, null,
-                       theFunctions, theBounds,
-                       null);
-                       
-               if(radial)
-               {
-                       if(theCoords.size() ==6)
-                       {
-                               myShad = this.makeShading(
-                               3, this.colorspace,
-                               null, null, false,
-                               theCoords, null, myfunky, null);
-                       }
-                       else
-                       { //if the center x, center y, and radius specifiy
-                       //the gradient, then assume the same center x, center y,
-                       //and radius of zero for the other necessary component
-                               Vector newCoords = new Vector();
-                               newCoords.addElement(theCoords.elementAt(0));
-                               newCoords.addElement(theCoords.elementAt(1));
-                               newCoords.addElement(theCoords.elementAt(2));
-                               newCoords.addElement(theCoords.elementAt(0));
-                               newCoords.addElement(theCoords.elementAt(1));
-                               newCoords.addElement(new Double(0.0));
-
-                               myShad = this.makeShading(
-                               3, this.colorspace,
-                               null, null, false,
-                               newCoords, null, myfunky, null);
-                               
-                       }
-               }
-               else
-               {
-               myShad = this.makeShading(
-                       2, this.colorspace,
-                       null, null, false,
-                       theCoords, null, myfunky, null);
-                       
-               }
-               
-               myPattern = this.makePattern(
-               2, myShad, null, null, null);
-               
-               return(myPattern);
-       }
-
-
-       /**
-        * make a Type1 /Font object
-        * 
-        * @param fontname internal name to use for this font (eg "F1")
-        * @param basefont name of the base font (eg "Helvetica")
-        * @param encoding character encoding scheme used by the font
-        * @return the created /Font object
-        */
-       public PDFFont makeFont(String fontname, String basefont,
-                               String encoding) {
-
-       /* create a PDFFont with the next object number and add to the
-          list of objects */
-       PDFFont font = new PDFFont(++this.objectcount, fontname,
-                                  basefont, encoding);
-       this.objects.addElement(font);
-       return font;
-       }
-
-       public int addImage(FopImage img) {
-       // check if already created
-       String url = img.getURL();
-       PDFXObject xObject = (PDFXObject) this.xObjectsMap.get(url);
-       if (xObject != null) return xObject.getXNumber();
-       // else, create a new one
-       xObject = new PDFXObject(++this.objectcount,
-                                               ++this.xObjectCount, img);
-       this.objects.addElement(xObject);
-       this.xObjects.addElement(xObject);
-       this.xObjectsMap.put(url, xObject);
-       return xObjectCount;
-       }
-
-       /**
-        * make a /Page object
-        *
-        * @param resources resources object to use
-        * @param contents stream object with content
-        * @param pagewidth width of the page in points
-        * @param pageheight height of the page in points
-        *
-        * @return the created /Page object
-        */
-       public PDFPage makePage(PDFResources resources,
-                               PDFStream contents,
-                               int pagewidth,
-                               int pageheight)  {
-
-       /* create a PDFPage with the next object number, the given
-          resources, contents and dimensions */
-       PDFPage page = new PDFPage(++this.objectcount, resources,
-                                  contents,
-                                  pagewidth, pageheight);
-
-       /* add it to the list of objects */
-       this.objects.addElement(page);
-
-       /* add the page to the Root */
-       this.root.addPage(page);
-
-       return page;
-       }
-
-       /**
-        * make a link object
-        *
-        * @param rect the clickable rectangle
-        * @param destination the destination file
-        * 
-        * @return the PDFLink object created
-        */
-       public PDFLink makeLink(Rectangle rect, String destination) {
+    /** the version of PDF supported */
+    protected static final String pdfVersion = "1.3";
+
+    /** the current character position */
+    protected int position = 0;
+
+    /** the character position of each object */
+    protected Vector location = new Vector();
+
+    /** the counter for object numbering */
+    protected int objectcount = 0;
+
+    /** the objects themselves */
+    protected Vector objects = new Vector();
+
+    /** character position of xref table */
+    protected int xref;
+
+    /** the /Root object */
+    protected PDFRoot root;
+
+    /** the /Info object */
+    protected PDFInfo info;
+
+    /** the /Resources object */
+    protected PDFResources resources;
+
+    /** the documents idReferences */
+    protected IDReferences idReferences;
+
+    /** the colorspace (0=RGB, 1=CMYK) **/
+    //protected int colorspace = 0;
+    protected ColorSpace colorspace = new ColorSpace(ColorSpace.DEVICE_RGB);
+
+    /** the counter for Pattern name numbering (e.g. 'Pattern1')*/
+    protected int patternCount = 0;
+
+    /** the counter for Shading name numbering */
+    protected int shadingCount = 0;
+
+    /** the counter for XObject numbering */
+    protected int xObjectCount = 0;
+
+    /** the XObjects */
+    protected Vector xObjects = new Vector();
+
+    /** the XObjects Map. 
+    Should be modified (works only for image subtype) */
+    protected Hashtable xObjectsMap = new Hashtable();
+
+    /**
+     * creates an empty PDF document
+     */
+    public PDFDocument() {
+
+        /* create the /Root, /Info and /Resources objects */
+        this.root = makeRoot();
+        this.info = makeInfo();
+        this.resources = makeResources();
+    }
+
+    /**
+     * set the producer of the document
+     *
+     * @param producer string indicating application producing the PDF
+     */
+    public void setProducer(String producer) {
+        this.info.setProducer(producer);
+    }
+
+    /**
+     * make /Root object as next object
+     *
+     * @return the created /Root object
+     */
+    protected PDFRoot makeRoot() {
+
+        /* create a PDFRoot with the next object number and add to
+           list of objects */
+        PDFRoot pdfRoot = new PDFRoot(++this.objectcount);
+        this.objects.addElement(pdfRoot);
+
+        /* create a new /Pages object to be root of Pages hierarchy
+           and add to list of objects */
+        PDFPages rootPages = new PDFPages(++this.objectcount);
+        this.objects.addElement(rootPages);
+
+        /* inform the /Root object of the /Pages root */
+        pdfRoot.setRootPages(rootPages);
+        return pdfRoot;
+    }
+
+    /**
+     * make an /Info object
+     *
+     * @param producer string indicating application producing the PDF
+     * @return the created /Info object
+     */
+    protected PDFInfo makeInfo() {
+
+        /* create a PDFInfo with the next object number and add to
+           list of objects */
+        PDFInfo pdfInfo = new PDFInfo(++this.objectcount);
+        this.objects.addElement(pdfInfo);
+        return pdfInfo;
+    }
+
+    /**
+     * make a /Resources object
+     *
+     * @return the created /Resources object
+     */
+    private PDFResources makeResources() {
+
+        /* create a PDFResources with the next object number and add
+           to list of objects */
+        PDFResources pdfResources = new PDFResources(++this.objectcount);
+        this.objects.addElement(pdfResources);
+        return pdfResources;
+    }
+
+    /**
+     * Make a Type 0 sampled function
+     * 
+     * @param theDomain Vector objects of Double objects.
+     * This is the domain of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theRange Vector objects of Double objects.
+     * This is the Range of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theSize A Vector object of Integer objects.
+     * This is the number of samples in each input dimension.
+     * I can't imagine there being more or less than two input dimensions,
+     * so maybe this should be an array of length 2.
+     * 
+     * See page 265 of the PDF 1.3 Spec.
+     * @param theBitsPerSample An int specifying the number of bits user to represent each sample value.
+     * Limited to 1,2,4,8,12,16,24 or 32.
+     * See page 265 of the 1.3 PDF Spec.
+     * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited
+     * to 1 (one) or 3, which means linear or cubic-spline interpolation.
+     * 
+     * This attribute is optional.
+     * 
+     * See page 265 in the PDF 1.3 spec.
+     * @param theEncode Vector objects of Double objects.
+     * This is the linear mapping of input values intop the domain
+     * of the function's sample table. Default is hard to represent in
+     * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
+     * This attribute is optional.
+     * 
+     * See page 265 in the PDF 1.3 spec.
+     * @param theDecode Vector objects of Double objects.
+     * This is a linear mapping of sample values into the range.
+     * The default is just the range.
+     * 
+     * This attribute is optional.
+     * Read about it on page 265 of the PDF 1.3 spec.
+     * @param theFunctionDataStream The sample values that specify the function are provided in a stream.
+     * 
+     * This is optional, but is almost always used.
+     * 
+     * Page 265 of the PDF 1.3 spec has more.
+     * @param theFilter This is a vector of String objects which are the various filters that
+     * have are to be applied to the stream to make sense of it. Order matters,
+     * so watch out.
+     * 
+     * This is not documented in the Function section of the PDF 1.3 spec,
+     * it was deduced from samples that this is sometimes used, even if we may never
+     * use it in FOP. It is added for completeness sake.
+     * @param theNumber The object number of this PDF object.
+     * @param theFunctionType This is the type of function (0,2,3, or 4).
+     * It should be 0 as this is the constructor for sampled functions.
+     */
+    public PDFFunction makeFunction(int theFunctionType,
+    Vector theDomain, Vector theRange,
+    Vector theSize,int theBitsPerSample,
+    int theOrder,Vector theEncode,Vector theDecode,
+    StringBuffer theFunctionDataStream, Vector theFilter)
+    {//Type 0 function
+        PDFFunction function = new PDFFunction(
+        ++this.objectcount, theFunctionType,
+        theDomain, theRange,    theSize,
+        theBitsPerSample,   theOrder,
+        theEncode, theDecode,
+        theFunctionDataStream,  theFilter);
+
+        this.objects.addElement(function);
+        return(function);
+    }
+
+    /**
+     * make a type Exponential interpolation function
+     * (for shading usually)
+     * 
+     * @param theDomain Vector objects of Double objects.
+     * This is the domain of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theRange Vector of Doubles that is the Range of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theCZero This is a vector of Double objects which defines the function result
+     * when x=0.
+     * 
+     * This attribute is optional.
+     * It's described on page 268 of the PDF 1.3 spec.
+     * @param theCOne This is a vector of Double objects which defines the function result
+     * when x=1.
+     * 
+     * This attribute is optional.
+     * It's described on page 268 of the PDF 1.3 spec.
+     * @param theInterpolationExponentN This is the inerpolation exponent.
+     * 
+     * This attribute is required.
+     * PDF Spec page 268
+     * @param theFunctionType The type of the function, which should be 2.
+     */
+    public PDFFunction makeFunction(int theFunctionType,
+    Vector theDomain, Vector theRange,
+    Vector theCZero, Vector theCOne,
+    double theInterpolationExponentN)
+
+    {//type 2
+        PDFFunction function = new PDFFunction(
+        ++this.objectcount,
+        theFunctionType,
+        theDomain, theRange,
+        theCZero, theCOne,
+        theInterpolationExponentN);
+
+        this.objects.addElement(function);
+        return(function);
+    }
+
+    /**
+     * Make a Type 3 Stitching function
+     * 
+     * @param theDomain Vector objects of Double objects.
+     * This is the domain of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theRange Vector objects of Double objects.
+     * This is the Range of the function.
+     * See page 264 of the PDF 1.3 Spec.
+     * @param theFunctions A Vector of the PDFFunction objects that the stitching function stitches.
+     * 
+     * This attributed is required.
+     * It is described on page 269 of the PDF spec.
+     * @param theBounds This is a vector of Doubles representing the numbers that,
+     * in conjunction with Domain define the intervals to which each function from
+     * the 'functions' object applies. It must be in order of increasing magnitude,
+     * and each must be within Domain.
+     * 
+     * It basically sets how much of the gradient each function handles.
+     * 
+     * This attributed is required.
+     * It's described on page 269 of the PDF 1.3 spec.
+     * @param theEncode Vector objects of Double objects.
+     * This is the linear mapping of input values intop the domain
+     * of the function's sample table. Default is hard to represent in
+     * ascii, but basically [0 (Size0 1) 0 (Size1 1)...].
+     * This attribute is required.
+     * 
+     * See page 270 in the PDF 1.3 spec.
+     * @param theFunctionType This is the function type. It should be 3,
+     * for a stitching function.
+     */
+    public PDFFunction makeFunction(int theFunctionType,
+    Vector theDomain, Vector theRange,
+    Vector theFunctions, Vector theBounds,
+    Vector theEncode)
+    {//Type 3
+
+        PDFFunction function = new PDFFunction(
+        ++this.objectcount,
+        theFunctionType,
+        theDomain, theRange,
+        theFunctions, theBounds,
+        theEncode);         
+
+        this.objects.addElement(function);
+        return(function);   
+    }
+
+    /**
+     * make a postscript calculator function
+     * 
+     * @param theNumber
+     * @param theFunctionType
+     * @param theDomain
+     * @param theRange
+     * @param theFunctionDataStream
+     */
+    public PDFFunction makeFunction(int theNumber, int theFunctionType,
+    Vector theDomain, Vector theRange,
+    StringBuffer theFunctionDataStream)
+    { //Type 4
+        PDFFunction function = new PDFFunction(
+        ++this.objectcount,
+        theFunctionType,
+        theDomain, theRange,
+        theFunctionDataStream);
+
+        this.objects.addElement(function);
+        return(function);   
+
+    }
+
+    /**
+     * make a function based shading object
+     * 
+     * @param theShadingType The type of shading object, which should be 1 for function
+     * based shading.
+     * @param theColorSpace The colorspace is 'DeviceRGB' or something similar.
+     * @param theBackground An array of color components appropriate to the
+     * colorspace key specifying a single color value.
+     * This key is used by the f operator buy ignored by the sh operator.
+     * @param theBBox Vector of double's representing a rectangle
+     * in the coordinate space that is current at the
+     * time of shading is imaged. Temporary clipping
+     * boundary.
+     * @param theAntiAlias Whether or not to anti-alias.
+     * @param theDomain Optional vector of Doubles specifying the domain.
+     * @param theMatrix Vector of Doubles specifying the matrix.
+     * If it's a pattern, then the matrix maps it to pattern space.
+     * If it's a shading, then it maps it to current user space.
+     * It's optional, the default is the identity matrix
+     * @param theFunction The PDF Function that maps an (x,y) location to a color
+     */
+    public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
+    Vector theBackground, Vector theBBox, boolean theAntiAlias,
+    Vector theDomain, Vector theMatrix, PDFFunction theFunction)
+    {   //make Shading of Type 1
+        String theShadingName = new String("Sh"+(++this.shadingCount));
+
+        PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
+        theShadingType, theColorSpace, theBackground, theBBox,
+        theAntiAlias, theDomain, theMatrix, theFunction);
+        this.objects.addElement(shading);
+
+        //add this shading to resources
+        this.resources.addShading(shading);
+
+        return(shading);
+    }
+
+    /**
+     * Make an axial or radial shading object.
+     * 
+          * @param theShadingType 2 or 3 for axial or radial shading
+          * @param theColorSpace "DeviceRGB" or similar.
+          * @param theBackground theBackground An array of color components appropriate to the
+          * colorspace key specifying a single color value.
+          * This key is used by the f operator buy ignored by the sh operator.
+          * @param theBBox Vector of double's representing a rectangle
+          * in the coordinate space that is current at the
+          * time of shading is imaged. Temporary clipping
+          * boundary.
+          * @param theAntiAlias Default is false
+          * @param theCoords Vector of four (type 2) or 6 (type 3) Double
+          * @param theDomain Vector of Doubles specifying the domain
+          * @param theFunction the Stitching (PDFfunction type 3) function, even if it's stitching a single function
+          * @param theExtend Vector of Booleans of whether to extend teh start and end colors past the start and end points
+          * The default is [false, false]
+     */
+    public PDFShading makeShading(int theShadingType,
+    ColorSpace theColorSpace, Vector theBackground,
+    Vector theBBox, boolean theAntiAlias,
+    Vector theCoords, Vector theDomain,
+    PDFFunction theFunction, Vector theExtend)
+    { //make Shading of Type 2 or 3
+        String theShadingName = new String("Sh"+(++this.shadingCount));
+
+        PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
+        theShadingType, theColorSpace,
+        theBackground, theBBox, theAntiAlias,
+        theCoords, theDomain,theFunction,theExtend);
+
+        this.resources.addShading(shading);
+
+        this.objects.addElement(shading);
+        return(shading);
+    }
+
+    /**
+     * Make a free-form gouraud shaded triangle mesh, coons patch mesh, or tensor patch mesh 
+     * shading object
+     * 
+     * @param theShadingType 4, 6, or 7 depending on whether it's
+     * Free-form gouraud-shaded triangle meshes, coons patch meshes, 
+     * or tensor product patch meshes, respectively.
+     * @param theColorSpace "DeviceRGB" or similar.
+     * @param theBackground theBackground An array of color components appropriate to the
+     * colorspace key specifying a single color value.
+     * This key is used by the f operator buy ignored by the sh operator.
+     * @param theBBox Vector of double's representing a rectangle
+     * in the coordinate space that is current at the
+     * time of shading is imaged. Temporary clipping
+     * boundary.
+     * @param theAntiAlias Default is false
+     * @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32.
+     * @param theBitsPerComponent 1,2,4,8,12, and 16
+     * @param theBitsPerFlag 2,4,8.
+     * @param theDecode Vector of Doubles see PDF 1.3 spec pages 303 to 312.
+     * @param theFunction the PDFFunction
+     */
+    public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
+    Vector theBackground, Vector theBBox, boolean theAntiAlias,
+    int theBitsPerCoordinate, int theBitsPerComponent,
+    int theBitsPerFlag, Vector theDecode, PDFFunction theFunction)
+    { //make Shading of type 4,6 or 7
+        String theShadingName = new String("Sh"+(++this.shadingCount));
+
+        PDFShading shading = new PDFShading(++this.objectcount, theShadingName,
+        theShadingType, theColorSpace,
+        theBackground, theBBox, theAntiAlias,
+        theBitsPerCoordinate,theBitsPerComponent,
+        theBitsPerFlag, theDecode, theFunction);
+
+        this.resources.addShading(shading);
+
+        this.objects.addElement(shading);
+        return(shading);
+    }
+
+    /**
+     * make a Lattice-Form Gouraud mesh shading object
+     * 
+     * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh
+     * without spaces. "Shading1" or "Sh1" are good examples.
+     * @param theColorSpace "DeviceRGB" or similar.
+     * @param theBackground theBackground An array of color components appropriate to the
+     * colorspace key specifying a single color value.
+     * This key is used by the f operator buy ignored by the sh operator.
+     * @param theBBox Vector of double's representing a rectangle
+     * in the coordinate space that is current at the
+     * time of shading is imaged. Temporary clipping
+     * boundary.
+     * @param theAntiAlias Default is false
+     * @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32
+     * @param theBitsPerComponent 1,2,4,8,12,24,32
+     * @param theDecode Vector of Doubles. See page 305 in PDF 1.3 spec.
+     * @param theVerticesPerRow number of vertices in each "row" of the lattice.
+     * @param theFunction The PDFFunction that's mapped on to this shape
+     */
+    public PDFShading makeShading(int theShadingType, ColorSpace theColorSpace,
+    Vector theBackground, Vector theBBox, boolean theAntiAlias,
+    int theBitsPerCoordinate, int theBitsPerComponent,
+    Vector theDecode, int theVerticesPerRow, PDFFunction theFunction)
+    { //make shading of Type 5
+        String theShadingName = new String("Sh"+(++this.shadingCount));
+
+        PDFShading shading= new PDFShading(++this.objectcount,
+        theShadingName, theShadingType, theColorSpace,
+        theBackground, theBBox, theAntiAlias,
+        theBitsPerCoordinate, theBitsPerComponent,
+        theDecode, theVerticesPerRow, theFunction);
+
+        this.resources.addShading(shading);
+
+        this.objects.addElement(shading);
+
+        return(shading);
+    }
+
+    /**
+     * Make a tiling pattern
+     * 
+     * @param thePatternType the type of pattern, which is 1 for tiling. 
+     * @param theResources the resources associated with this pattern
+     * @param thePaintType 1 or 2, colored or uncolored.
+     * @param theTilingType 1, 2, or 3, constant spacing, no distortion, or faster tiling
+     * @param theBBox Vector of Doubles: The pattern cell bounding box
+     * @param theXStep horizontal spacing
+     * @param theYStep vertical spacing
+     * @param theMatrix Optional Vector of Doubles transformation matrix
+     * @param theXUID Optional vector of Integers that uniquely identify the pattern
+     * @param thePatternDataStream The stream of pattern data to be tiled.
+     */
+    public PDFPattern makePattern(
+    int thePatternType, //1
+    PDFResources theResources, 
+    int thePaintType, int theTilingType,
+    Vector theBBox, double theXStep, double theYStep,
+    Vector theMatrix, Vector theXUID, StringBuffer thePatternDataStream)
+    {
+        String thePatternName = new String("Pa"+(++this.patternCount));
+        //int theNumber, String thePatternName,
+        //PDFResources theResources
+        PDFPattern pattern = new PDFPattern(++this.objectcount,
+        thePatternName,
+        theResources, 1,
+        thePaintType, theTilingType,
+        theBBox, theXStep, theYStep,
+        theMatrix, theXUID, thePatternDataStream);
+
+        this.resources.addPattern(pattern);
+        this.objects.addElement(pattern);
+
+        return(pattern);
+    }
+
+    /**
+     * Make a smooth shading pattern
+     * 
+     * @param thePatternType the type of the pattern, which is 2, smooth shading
+     * @param theShading the PDF Shading object that comprises this pattern
+     * @param theXUID optional:the extended unique Identifier if used.
+     * @param theExtGState optional: the extended graphics state, if used.
+     * @param theMatrix Optional:Vector of Doubles that specify the matrix.
+     */
+    public PDFPattern makePattern(int thePatternType,
+    PDFShading theShading, Vector theXUID,
+    StringBuffer theExtGState,Vector theMatrix)
+    {
+        String thePatternName = new String("Pa"+(++this.patternCount));
+
+        PDFPattern pattern = new PDFPattern(++this.objectcount,
+        thePatternName, 2, theShading, theXUID,
+        theExtGState, theMatrix);
+
+        this.resources.addPattern(pattern);
+        this.objects.addElement(pattern);
+
+        return(pattern);
+    }
+
+    public int getColorSpace()
+    {
+        return(this.colorspace.getColorSpace());
+    }
+
+    public void setColorSpace(int theColorspace)
+    {
+        this.colorspace.setColorSpace(theColorspace);
+        return;
+    }
+
+    public PDFPattern createGradient(boolean radial,
+    ColorSpace theColorspace,
+    Vector theColors,
+    Vector theBounds,
+    Vector theCoords)
+    {
+        PDFShading myShad;
+        PDFFunction myfunky;
+        PDFFunction myfunc;
+        Vector theCzero;
+        Vector theCone;
+        PDFPattern myPattern;
+        ColorSpace theColorSpace;
+        double interpolation = (double) 1.000;
+        Vector theFunctions = new Vector();
+
+        int currentPosition;
+        int lastPosition = theColors.size()-2;
+
+
+        //if 5 elements, the penultimate element is 3.
+        //do not go beyond that, because you always need
+        //to have a next color when creating the function.
+
+        for ( currentPosition=0;
+        currentPosition < lastPosition;
+        currentPosition++ ) {//for every consecutive color pair
+            PDFColor currentColor = 
+            (PDFColor)theColors.elementAt(currentPosition);
+            PDFColor nextColor = 
+            (PDFColor)theColors.elementAt(currentPosition+1);
+            //colorspace must be consistant
+            if ( this.colorspace.getColorSpace() != currentColor.getColorSpace() )
+                currentColor.setColorSpace(this.colorspace.getColorSpace());
+
+            if ( this.colorspace.getColorSpace() != nextColor.getColorSpace() )
+                nextColor.setColorSpace(this.colorspace.getColorSpace());
+
+            theCzero = currentColor.getVector();
+            theCone = nextColor.getVector();
+
+            myfunc = this.makeFunction(
+            2, null, null,
+            theCzero, theCone,
+            interpolation);
+
+            theFunctions.addElement(myfunc);
+
+        }//end of for every consecutive color pair
+
+        myfunky = this.makeFunction(3,
+        null, null,
+        theFunctions, theBounds,
+        null);
+
+        if ( radial ) {
+            if ( theCoords.size() ==6 ) {
+                myShad = this.makeShading(
+                3, this.colorspace,
+                null, null, false,
+                theCoords, null, myfunky, null);
+            }
+            else { //if the center x, center y, and radius specifiy
+                //the gradient, then assume the same center x, center y,
+                //and radius of zero for the other necessary component
+                Vector newCoords = new Vector();
+                newCoords.addElement(theCoords.elementAt(0));
+                newCoords.addElement(theCoords.elementAt(1));
+                newCoords.addElement(theCoords.elementAt(2));
+                newCoords.addElement(theCoords.elementAt(0));
+                newCoords.addElement(theCoords.elementAt(1));
+                newCoords.addElement(new Double(0.0));
+
+                myShad = this.makeShading(
+                3, this.colorspace,
+                null, null, false,
+                newCoords, null, myfunky, null);
+
+            }
+        }
+        else {
+            myShad = this.makeShading(
+            2, this.colorspace,
+            null, null, false,
+            theCoords, null, myfunky, null);
+
+        }
+
+        myPattern = this.makePattern(
+        2, myShad, null, null, null);
+
+        return(myPattern);
+    }
+
+
+    /**
+     * make a Type1 /Font object
+     * 
+     * @param fontname internal name to use for this font (eg "F1")
+     * @param basefont name of the base font (eg "Helvetica")
+     * @param encoding character encoding scheme used by the font
+     * @return the created /Font object
+     */
+    public PDFFont makeFont(String fontname, String basefont,
+    String encoding) {
+
+        /* create a PDFFont with the next object number and add to the
+           list of objects */
+        PDFFont font = new PDFFont(++this.objectcount, fontname,
+        basefont, encoding);
+        this.objects.addElement(font);
+        return font;
+    }
+
+    public int addImage(FopImage img) {
+        // check if already created
+        String url = img.getURL();
+        PDFXObject xObject = (PDFXObject) this.xObjectsMap.get(url);
+        if ( xObject != null ) return xObject.getXNumber();
+        // else, create a new one
+        xObject = new PDFXObject(++this.objectcount,
+        ++this.xObjectCount, img);
+        this.objects.addElement(xObject);
+        this.xObjects.addElement(xObject);
+        this.xObjectsMap.put(url, xObject);
+        return xObjectCount;
+    }
+
+    /**
+     * make a /Page object
+     *
+     * @param resources resources object to use
+     * @param contents stream object with content
+     * @param pagewidth width of the page in points
+     * @param pageheight height of the page in points
+     *
+     * @return the created /Page object
+     */
+    public PDFPage makePage(PDFResources resources,
+    PDFStream contents,
+    int pagewidth,
+    int pageheight,
+    Page currentPage)  {
+
+        /* create a PDFPage with the next object number, the given
+           resources, contents and dimensions */
+        PDFPage page = new PDFPage(++this.objectcount, resources,
+        contents,
+        pagewidth, pageheight);
+
+        Enumeration enum=currentPage.getIDList().elements();        
+        while ( enum.hasMoreElements() ) {
+            String id=enum.nextElement().toString();                                    
+            idReferences.setInternalGoToPageReference(id,page.referencePDF());
+        }
+
+        /* add it to the list of objects */
+        this.objects.addElement(page);
+
+        /* add the page to the Root */
+        this.root.addPage(page);
+
+        return page;
+    }
+
+    /**
+     * make a link object
+     * 
+     * @param rect   the clickable rectangle
+     * @param destination  the destination file
+     * @param linkType the link type
+     * @return the PDFLink object created
+     */
+    public PDFLink makeLink(Rectangle rect, String destination, int linkType) {
 
         PDFLink linkObject;
         PDFAction action;
 
         PDFLink link = new PDFLink(++this.objectcount, rect);
         this.objects.addElement(link);               
-        
-        //check destination
-        if ( destination.endsWith(".pdf") ) //FileSpec
-        {                        
-            PDFFileSpec fileSpec = new PDFFileSpec(++this.objectcount,destination);
-            this.objects.addElement(fileSpec);
-            action = new PDFGoToRemote(++this.objectcount,fileSpec);
-            this.objects.addElement(action);
-            link.setAction(action);                    
+
+        if ( linkType == LinkSet.EXTERNAL ) {
+            //check destination
+            if ( destination.endsWith(".pdf") ) { //FileSpec
+                PDFFileSpec fileSpec = new PDFFileSpec(++this.objectcount,destination);
+                this.objects.addElement(fileSpec);
+                action = new PDFGoToRemote(++this.objectcount,fileSpec);
+                this.objects.addElement(action);
+                link.setAction(action);                    
+            }
+            else { //URI
+                PDFUri uri = new PDFUri(destination);    
+                link.setAction(uri);    
+            }
         }
-        else //URI
-        {            
-            PDFUri uri = new PDFUri(destination);    
-            link.setAction(uri);    
+        else { // linkType is internal            
+            String goToReference;
+            PDFInternalLink internalLink;            
+
+            if ( idReferences.doesIDExist(destination) ) {
+                if ( idReferences.doesGoToReferenceExist(destination) ) {
+                    goToReference = idReferences.getInternalLinkGotToReference(destination);
+                }
+                else { //assign Internal Link GoTo object
+                    goToReference = idReferences.createInternalLinkGoTo(destination,++this.objectcount);                    
+                    this.objects.addElement(idReferences.getPDFGoTo(destination));
+                }
+            }
+            else { //id was not found, so create it
+                idReferences.createNewId(destination);
+                idReferences.addToIdValidationList(destination);
+                goToReference = idReferences.createInternalLinkGoTo(destination,++this.objectcount);
+                this.objects.addElement(idReferences.getPDFGoTo(destination));
+            }
+            internalLink = new PDFInternalLink(goToReference);
+            link.setAction(internalLink);
         }
-             
         return link;
     }
 
-       /**
-        * make a stream object
-        *
-        * @return the stream object created
-        */
-       public PDFStream makeStream() {
-       
-       /* create a PDFStream with the next object number and add it
-
-          to the list of objects */
-       PDFStream obj = new PDFStream(++this.objectcount);
-       this.objects.addElement(obj);
-       return obj;
-       }
-       
-       /**
-        * make an annotation list object
-        *
-        * @return the annotation list object created
-        */
-       public PDFAnnotList makeAnnotList() {
-       
-       /* create a PDFAnnotList with the next object number and add it
-          to the list of objects */
-       PDFAnnotList obj = new PDFAnnotList(++this.objectcount);
-       this.objects.addElement(obj);
-       return obj;
-       }
-
-       /**
-        * get the /Resources object for the document
-        *
-        * @return the /Resources object
-        */
-       public PDFResources getResources() {
-       return this.resources;
-       }
-
-       /**
-        * write the entire document out
-        *
-        * @param writer the PrinterWriter to output the document to
-        */
-       public void output(PrintWriter writer) throws IOException {
-
-       /* output the header and increment the character position by
-          the header's length */
-       this.position += outputHeader(writer);
-
-       this.resources.setXObjects(xObjects);
-
-       /* loop through the object numbers */
-       for (int i=1; i <= this.objectcount; i++) {
-
-               /* add the position of this object to the list of object
-                  locations */
-               this.location.addElement(new Integer(this.position));
-
-               /* retrieve the object with the current number */
-               PDFObject object = (PDFObject)this.objects.elementAt(i-1);
-
-               /* output the object and increment the character position
-                  by the object's length */
-               this.position += object.output(writer);
-       }
-
-       /* output the xref table and increment the character position
-          by the table's length */
-       this.position += outputXref(writer);
-
-       /* output the trailer and flush the Writer */
-       outputTrailer(writer);
-       writer.flush();
-       }
-
-       /**
-        * write the PDF header
-        *
-        * @param writer the PrintWriter to write the header to
-        * @return the number of characters written
-        */
-       protected int outputHeader(PrintWriter writer) throws IOException {
-       String pdf = "%PDF-" + this.pdfVersion + "\n";
-       writer.write(pdf);
-       return pdf.length();
-       }
-
-       /**
-        * write the trailer
-        *
-        * @param writer the PrintWriter to write the trailer to
-        */
-       protected void outputTrailer(PrintWriter writer) throws IOException {
-
-       /* construct the trailer */
-       String pdf = "trailer\n<<\n/Size " + (this.objectcount+1)
-               + "\n/Root " + this.root.number + " " + this.root.generation
-               + " R\n/Info " + this.info.number + " " 
-               + this.info.generation + " R\n>>\nstartxref\n" + this.xref 
-               + "\n%%EOF\n";
-
-       /* write the trailer */
-       writer.write(pdf);
-       }
-
-       /**
-        * write the xref table
-        *
-        * @param writer the PrintWriter to write the xref table to
-        * @return the number of characters written
-        */
-       private int outputXref(PrintWriter writer) throws IOException {
-
-       /* remember position of xref table */
-       this.xref = this.position;
-
-       /* construct initial part of xref */
-       StringBuffer pdf = new StringBuffer("xref\n0 " + (this.objectcount+1) 
-               + "\n0000000000 65535 f \n");
-
-       /* loop through object numbers */
-       for (int i=1; i < this.objectcount+1; i++) {
-
-               /* contruct xref entry for object */
-               String padding = "0000000000";
-               String x = this.location.elementAt(i-1).toString();
-               String loc = padding.substring(x.length()) + x;
-
-               /* append to xref table */
-               pdf = pdf.append(loc + " 00000 n \n");
-       }
-
-       /* write the xref table and return the character length */
-       writer.write(pdf.toString());
-       return pdf.length();
-       }
-}
+    
+    /**
+     * make a stream object
+     *
+     * @return the stream object created
+     */
+    public PDFStream makeStream() {
+
+        /* create a PDFStream with the next object number and add it
+    
+           to the list of objects */
+        PDFStream obj = new PDFStream(++this.objectcount);
+        this.objects.addElement(obj);
+        return obj;
+    }
+
+    /**
+     * make an annotation list object
+     *
+     * @return the annotation list object created
+     */
+    public PDFAnnotList makeAnnotList() {
+
+        /* create a PDFAnnotList with the next object number and add it
+           to the list of objects */
+        PDFAnnotList obj = new PDFAnnotList(++this.objectcount);
+        this.objects.addElement(obj);
+        return obj;
+    }
+
+    /**
+     * get the /Resources object for the document
+     *
+     * @return the /Resources object
+     */
+    public PDFResources getResources() {
+        return this.resources;
+    }
+
+    /**
+     * write the entire document out
+     *
+     * @param writer the PrinterWriter to output the document to
+     */
+    public void output(PrintWriter writer) throws IOException {
+
+        /* output the header and increment the character position by
+           the header's length */
+        this.position += outputHeader(writer);
+
+        this.resources.setXObjects(xObjects);
+
+        /* loop through the object numbers */
+        for ( int i=1; i <= this.objectcount; i++ ) {
+
+            /* add the position of this object to the list of object
+               locations */
+            this.location.addElement(new Integer(this.position));
+
+            /* retrieve the object with the current number */
+            PDFObject object = (PDFObject)this.objects.elementAt(i-1);
+
+            /* output the object and increment the character position
+               by the object's length */
+            this.position += object.output(writer);
+        }
+
+        /* output the xref table and increment the character position
+           by the table's length */
+        this.position += outputXref(writer);
+
+        /* output the trailer and flush the Writer */
+        outputTrailer(writer);
+        writer.flush();
+    }
+
+    /**
+     * write the PDF header
+     *
+     * @param writer the PrintWriter to write the header to
+     * @return the number of characters written
+     */
+    protected int outputHeader(PrintWriter writer) throws IOException {
+        String pdf = "%PDF-" + this.pdfVersion + "\n";
+        writer.write(pdf);
+        return pdf.length();
+    }
+
+    /**
+     * write the trailer
+     *
+     * @param writer the PrintWriter to write the trailer to
+     */
+    protected void outputTrailer(PrintWriter writer) throws IOException {
+
+        /* construct the trailer */
+        String pdf = "trailer\n<<\n/Size " + (this.objectcount+1)
+        + "\n/Root " + this.root.number + " " + this.root.generation
+        + " R\n/Info " + this.info.number + " " 
+        + this.info.generation + " R\n>>\nstartxref\n" + this.xref 
+        + "\n%%EOF\n";
+
+        /* write the trailer */
+        writer.write(pdf);
+    }
+
+    /**
+     * write the xref table
+     *
+     * @param writer the PrintWriter to write the xref table to
+     * @return the number of characters written
+     */
+    private int outputXref(PrintWriter writer) throws IOException {
+
+        /* remember position of xref table */
+        this.xref = this.position;
+
+        /* construct initial part of xref */
+        StringBuffer pdf = new StringBuffer("xref\n0 " + (this.objectcount+1) 
+        + "\n0000000000 65535 f \n");
+
+        /* loop through object numbers */
+        for ( int i=1; i < this.objectcount+1; i++ ) {
+
+            /* contruct xref entry for object */
+            String padding = "0000000000";
+            String x = this.location.elementAt(i-1).toString();
+            String loc = padding.substring(x.length()) + x;
+
+            /* append to xref table */
+            pdf = pdf.append(loc + " 00000 n \n");
+        }
+
+        /* write the xref table and return the character length */
+        writer.write(pdf.toString());
+        return pdf.length();
+    }    
+
+    public void setIDReferences(IDReferences idReferences){
+        this.idReferences= idReferences;
+    }
+}
\ No newline at end of file