1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.pdfwriter; 18 19 import java.io.IOException; 20 import java.io.OutputStream; 21 22 import java.util.Iterator; 23 import java.util.List; 24 import java.util.Map; 25 26 import org.apache.pdfbox.cos.COSArray; 27 import org.apache.pdfbox.cos.COSBase; 28 import org.apache.pdfbox.cos.COSBoolean; 29 import org.apache.pdfbox.cos.COSDictionary; 30 import org.apache.pdfbox.cos.COSFloat; 31 import org.apache.pdfbox.cos.COSInteger; 32 import org.apache.pdfbox.cos.COSName; 33 import org.apache.pdfbox.cos.COSString; 34 35 import org.apache.pdfbox.util.ImageParameters; 36 import org.apache.pdfbox.util.PDFOperator; 37 38 /** 39 * A class that will take a list of tokens and write out a stream with them. 40 * 41 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> 42 * @version $Revision: 1.8 $ 43 */ 44 public class ContentStreamWriter 45 { 46 private OutputStream output; 47 /** 48 * space character. 49 */ 50 public static final byte[] SPACE = new byte[] { 32 }; 51 52 /** 53 * standard line separator on this platform. 54 */ 55 public static final byte[] EOL = System.getProperty("line.separator").getBytes(); 56 57 /** 58 * This will create a new content stream writer. 59 * 60 * @param out The stream to write the data to. 61 */ 62 public ContentStreamWriter( OutputStream out ) 63 { 64 output = out; 65 } 66 67 /** 68 * This will write out the list of tokens to the stream. 69 * 70 * @param tokens The tokens to write to the stream. 71 * @param start The start index into the list of tokens. 72 * @param end The end index into the list of tokens. 73 * @throws IOException If there is an error writing to the stream. 74 */ 75 public void writeTokens( List tokens, int start, int end ) throws IOException 76 { 77 for( int i=start; i<end; i++ ) 78 { 79 Object o = tokens.get( i ); 80 writeObject( o ); 81 //write a space between each object. 82 output.write( 32 ); 83 } 84 output.flush(); 85 } 86 87 private void writeObject( Object o ) throws IOException 88 { 89 if( o instanceof COSString ) 90 { 91 ((COSString)o).writePDF( output ); 92 } 93 else if( o instanceof COSFloat ) 94 { 95 ((COSFloat)o).writePDF( output ); 96 } 97 else if( o instanceof COSInteger ) 98 { 99 ((COSInteger)o).writePDF( output ); 100 } 101 else if( o instanceof COSBoolean ) 102 { 103 ((COSBoolean)o).writePDF( output ); 104 } 105 else if( o instanceof COSName ) 106 { 107 ((COSName)o).writePDF( output ); 108 } 109 else if( o instanceof COSArray ) 110 { 111 COSArray array = (COSArray)o; 112 output.write(COSWriter.ARRAY_OPEN); 113 for( int i=0; i<array.size(); i++ ) 114 { 115 writeObject( array.get( i ) ); 116 output.write( SPACE ); 117 } 118 119 output.write( COSWriter.ARRAY_CLOSE ); 120 } 121 else if( o instanceof COSDictionary ) 122 { 123 COSDictionary obj = (COSDictionary)o; 124 output.write( COSWriter.DICT_OPEN ); 125 for (Map.Entry<COSName, COSBase> entry : obj.entrySet()) 126 { 127 if (entry.getValue() != null) 128 { 129 writeObject( entry.getKey() ); 130 output.write( SPACE ); 131 writeObject( entry.getValue() ); 132 output.write( SPACE ); 133 } 134 } 135 output.write( COSWriter.DICT_CLOSE ); 136 output.write( SPACE ); 137 } 138 else if( o instanceof PDFOperator ) 139 { 140 PDFOperator op = (PDFOperator)o; 141 if( op.getOperation().equals( "BI" ) ) 142 { 143 output.write( "BI".getBytes() ); 144 ImageParameters params = op.getImageParameters(); 145 COSDictionary dic = params.getDictionary(); 146 for( COSName key : dic.keySet() ) 147 { 148 Object value = dic.getDictionaryObject( key ); 149 key.writePDF( output ); 150 output.write( SPACE ); 151 writeObject( value ); 152 output.write( EOL ); 153 } 154 output.write( "ID".getBytes() ); 155 output.write( EOL ); 156 output.write( op.getImageData() ); 157 } 158 else 159 { 160 output.write( op.getOperation().getBytes() ); 161 output.write( EOL ); 162 } 163 } 164 else 165 { 166 throw new IOException( "Error:Unknown type in content stream:" + o ); 167 } 168 } 169 170 /** 171 * This will write out the list of tokens to the stream. 172 * 173 * @param tokens The tokens to write to the stream. 174 * @throws IOException If there is an error writing to the stream. 175 */ 176 public void writeTokens( List tokens ) throws IOException 177 { 178 writeTokens( tokens, 0, tokens.size() ); 179 } 180 }