From 6025b6016517c6d898d8957d1d7e03ba71431912 Mon Sep 17 00:00:00 2001 From: tknall Date: Fri, 1 Dec 2006 12:20:24 +0000 Subject: Initial import of release 2.2. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@4 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../org/pdfbox/pdmodel/font/Type3StreamParser.java | 607 +++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 src/main/java/org/pdfbox/pdmodel/font/Type3StreamParser.java (limited to 'src/main/java/org/pdfbox/pdmodel/font/Type3StreamParser.java') diff --git a/src/main/java/org/pdfbox/pdmodel/font/Type3StreamParser.java b/src/main/java/org/pdfbox/pdmodel/font/Type3StreamParser.java new file mode 100644 index 0000000..a2adc1f --- /dev/null +++ b/src/main/java/org/pdfbox/pdmodel/font/Type3StreamParser.java @@ -0,0 +1,607 @@ +/** + * Copyright (c) 2003-2004, www.pdfbox.org + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, 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. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS 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 REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, 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. + * + * http://www.pdfbox.org + * + */ +package org.pdfbox.pdmodel.font; + +import java.awt.Image; + +import java.io.IOException; + +import java.util.List; + +import org.pdfbox.cos.COSNumber; +import org.pdfbox.cos.COSStream; + +import org.pdfbox.pdmodel.graphics.xobject.PDInlinedImage; + +import org.pdfbox.util.BoundingBox; +import org.pdfbox.util.ImageParameters; +import org.pdfbox.util.PDFOperator; +import org.pdfbox.util.PDFStreamEngine; + +/** + * This class will handle creating an image for a type 3 glyph. + * + * @author Ben Litchfield (ben@csh.rit.edu) + * @version $Revision: 1.8 $ + */ +public class Type3StreamParser extends PDFStreamEngine +{ + private PDInlinedImage image = null; + private BoundingBox box = null; + + + /** + * This will parse a type3 stream and create an image from it. + * + * @param type3Stream The stream containing the operators to draw the image. + * + * @return The image that was created. + * + * @throws IOException If there is an error processing the stream. + */ + public Image createImage( COSStream type3Stream ) throws IOException + { + processStream( null, null, type3Stream ); + return image.createImage(); + } + + /** + * This is used to handle an operation. + * + * @param operator The operation to perform. + * @param arguments The list of arguments. + * + * @throws IOException If there is an error processing the operation. + */ + protected void processOperator( PDFOperator operator, List arguments ) throws IOException + { + super.processOperator( operator, arguments ); + String operation = operator.getOperation(); + /** + if( operation.equals( "b" ) ) + { + //Close, fill, and stroke path using nonzero winding number rule + } + else if( operation.equals( "B" ) ) + { + //Fill and stroke path using nonzero winding number rule + } + else if( operation.equals( "b*" ) ) + { + //Close, fill, and stroke path using even-odd rule + } + else if( operation.equals( "B*" ) ) + { + //Fill and stroke path using even-odd rule + } + else if( operation.equals( "BDC" ) ) + { + //(PDF 1.2) Begin marked-content sequence with property list + } + else **/if( operation.equals( "BI" ) ) + { + ImageParameters params = operator.getImageParameters(); + image = new PDInlinedImage(); + image.setImageParameters( params ); + image.setImageData( operator.getImageData() ); + //begin inline image object + }/** + else if( operation.equals( "BMC" ) ) + { + //(PDF 1.2) Begin marked-content sequence + } + else if( operation.equals( "BT" ) ) + { + log.debug( "" ); + textMatrix = new Matrix(); + textLineMatrix = new Matrix(); + } + else if( operation.equals( "BX" ) ) + { + //(PDF 1.1) Begin compatibility section + } + else if( operation.equals( "c" ) ) + { + //Append curved segment to path (three control points) + } + else if( operation.equals( "cm" ) ) + { + } + else if( operation.equals( "cs" ) ) + { + } + else if( operation.equals( "CS" ) ) + { + } + else if( operation.equals( "d" ) ) + { + //Set the line dash pattern in the graphics state + } + else */if( operation.equals( "d0" ) ) + { + //set glyph with for a type3 font + //COSNumber horizontalWidth = (COSNumber)arguments.get( 0 ); + //COSNumber verticalWidth = (COSNumber)arguments.get( 1 ); + //width = horizontalWidth.intValue(); + //height = verticalWidth.intValue(); + } + else if( operation.equals( "d1" ) ) + { + //set glyph with and bounding box for type 3 font + //COSNumber horizontalWidth = (COSNumber)arguments.get( 0 ); + //COSNumber verticalWidth = (COSNumber)arguments.get( 1 ); + COSNumber llx = (COSNumber)arguments.get( 2 ); + COSNumber lly = (COSNumber)arguments.get( 3 ); + COSNumber urx = (COSNumber)arguments.get( 4 ); + COSNumber ury = (COSNumber)arguments.get( 5 ); + + //width = horizontalWidth.intValue(); + //height = verticalWidth.intValue(); + box = new BoundingBox(); + box.setLowerLeftX( llx.floatValue() ); + box.setLowerLeftY( lly.floatValue() ); + box.setUpperRightX( urx.floatValue() ); + box.setUpperRightY( ury.floatValue() ); + }/* + else if( operation.equals( "Do" ) ) + { + //invoke named object. + } + else if( operation.equals( "DP" ) ) + { + //(PDF 1.2) De.ne marked-content point with property list + } + else if( operation.equals( "EI" ) ) + { + //end inline image object + } + else if( operation.equals( "EMC" ) ) + { + //End inline image object + } + else if( operation.equals( "ET" ) ) + { + log.debug( "" ); + textMatrix = null; + textLineMatrix = null; + } + else if( operation.equals( "EX" ) ) + { + //(PDF 1.1) End compatibility section + } + else if( operation.equals( "f" ) ) + { + //Fill the path, using the nonzero winding number rule to determine the region to .ll + } + else if( operation.equals( "F" ) ) + { + } + else if( operation.equals( "f*" ) ) + { + //Fill path using even-odd rule + } + else if( operation.equals( "g" ) ) + { + } + else if( operation.equals( "G" ) ) + { + } + else if( operation.equals( "gs" ) ) + { + } + else if( operation.equals( "h" ) ) + { + //close subpath + } + else if( operation.equals( "i" ) ) + { + //set flatness tolerance, not sure what this does + } + else if( operation.equals( "ID" ) ) + { + //begin inline image data + } + else if( operation.equals( "j" ) ) + { + //Set the line join style in the graphics state + //System.out.println( "" ); + } + else if( operation.equals( "J" ) ) + { + //Set the line cap style in the graphics state + //System.out.println( "" ); + } + else if( operation.equals( "k" ) ) + { + //Set CMYK color for nonstroking operations + } + else if( operation.equals( "K" ) ) + { + //Set CMYK color for stroking operations + } + else if( operation.equals( "l" ) ) + { + //append straight line segment from the current point to the point. + COSNumber x = (COSNumber)arguments.get( 0 ); + COSNumber y = (COSNumber)arguments.get( 1 ); + linePath.lineTo( x.floatValue(), pageSize.getHeight()-y.floatValue() ); + } + else if( operation.equals( "m" ) ) + { + COSNumber x = (COSNumber)arguments.get( 0 ); + COSNumber y = (COSNumber)arguments.get( 1 ); + linePath.reset(); + linePath.moveTo( x.floatValue(), pageSize.getHeight()-y.floatValue() ); + //System.out.println( "" ); + } + else if( operation.equals( "M" ) ) + { + //System.out.println( "" ); + } + else if( operation.equals( "MP" ) ) + { + //(PDF 1.2) Define marked-content point + } + else if( operation.equals( "n" ) ) + { + //End path without .lling or stroking + //System.out.println( "" ); + } + else if( operation.equals( "q" ) ) + { + //save graphics state + if( log.isDebugEnabled() ) + { + log.debug( "<" + operation + "> - save state" ); + } + graphicsStack.push(graphicsState.clone()); + } + else if( operation.equals( "Q" ) ) + { + //restore graphics state + if( log.isDebugEnabled() ) + { + log.debug( "<" + operation + "> - restore state" ); + } + graphicsState = (PDGraphicsState)graphicsStack.pop(); + } + else if( operation.equals( "re" ) ) + { + } + else if( operation.equals( "rg" ) ) + { + //Set RGB color for nonstroking operations + } + else if( operation.equals( "RG" ) ) + { + //Set RGB color for stroking operations + } + else if( operation.equals( "ri" ) ) + { + //Set color rendering intent + } + else if( operation.equals( "s" ) ) + { + //Close and stroke path + } + else if( operation.equals( "S" ) ) + { + graphics.draw( linePath ); + } + else if( operation.equals( "sc" ) ) + { + //set color for nonstroking operations + //System.out.println( "" ); + } + else if( operation.equals( "SC" ) ) + { + //set color for stroking operations + //System.out.println( "" ); + } + else if( operation.equals( "scn" ) ) + { + //set color for nonstroking operations special + } + else if( operation.equals( "SCN" ) ) + { + //set color for stroking operations special + } + else if( operation.equals( "sh" ) ) + { + //(PDF 1.3) Paint area de.ned by shading pattern + } + else if( operation.equals( "T*" ) ) + { + if (log.isDebugEnabled()) + { + log.debug(""); + } + //move to start of next text line + if( graphicsState.getTextState().getLeading() == 0 ) + { + graphicsState.getTextState().setLeading( -.01f ); + } + Matrix td = new Matrix(); + td.setValue( 2, 1, -1 * graphicsState.getTextState().getLeading() * textMatrix.getValue(1,1)); + textLineMatrix = textLineMatrix.multiply( td ); + textMatrix = textLineMatrix.copy(); + } + else if( operation.equals( "Tc" ) ) + { + //set character spacing + COSNumber characterSpacing = (COSNumber)arguments.get( 0 ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + graphicsState.getTextState().setCharacterSpacing( characterSpacing.floatValue() ); + } + else if( operation.equals( "Td" ) ) + { + COSNumber x = (COSNumber)arguments.get( 0 ); + COSNumber y = (COSNumber)arguments.get( 1 ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + Matrix td = new Matrix(); + td.setValue( 2, 0, x.floatValue() * textMatrix.getValue(0,0) ); + td.setValue( 2, 1, y.floatValue() * textMatrix.getValue(1,1) ); + //log.debug( "textLineMatrix before " + textLineMatrix ); + textLineMatrix = textLineMatrix.multiply( td ); + //log.debug( "textLineMatrix after " + textLineMatrix ); + textMatrix = textLineMatrix.copy(); + } + else if( operation.equals( "TD" ) ) + { + //move text position and set leading + COSNumber x = (COSNumber)arguments.get( 0 ); + COSNumber y = (COSNumber)arguments.get( 1 ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + graphicsState.getTextState().setLeading( -1 * y.floatValue() ); + Matrix td = new Matrix(); + td.setValue( 2, 0, x.floatValue() * textMatrix.getValue(0,0) ); + td.setValue( 2, 1, y.floatValue() * textMatrix.getValue(1,1) ); + //log.debug( "textLineMatrix before " + textLineMatrix ); + textLineMatrix = textLineMatrix.multiply( td ); + //log.debug( "textLineMatrix after " + textLineMatrix ); + textMatrix = textLineMatrix.copy(); + } + else if( operation.equals( "Tf" ) ) + { + //set font and size + COSName fontName = (COSName)arguments.get( 0 ); + graphicsState.getTextState().setFontSize( ((COSNumber)arguments.get( 1 ) ).floatValue() ); + + if (log.isDebugEnabled()) + { + log.debug(""); + } + + //old way + //graphicsState.getTextState().getFont() = (COSObject)stream.getDictionaryObject( fontName ); + //if( graphicsState.getTextState().getFont() == null ) + //{ + // graphicsState.getTextState().getFont() = (COSObject)graphicsState.getTextState().getFont() + // Dictionary.getItem( fontName ); + //} + graphicsState.getTextState().setFont( (PDFont)fonts.get( fontName.getName() ) ); + if( graphicsState.getTextState().getFont() == null ) + { + throw new IOException( "Error: Could not find font(" + fontName + ") in map=" + fonts ); + } + //log.debug( "Font Resource=" + fontResource ); + //log.debug( "Current Font=" + graphicsState.getTextState().getFont() ); + //log.debug( "graphicsState.getTextState().getFontSize()=" + graphicsState.getTextState().getFontSize() ); + } + else if( operation.equals( "Tj" ) ) + { + COSString string = (COSString)arguments.get( 0 ); + TextPosition pos = showString( string.getBytes() ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + } + else if( operation.equals( "TJ" ) ) + { + Matrix td = new Matrix(); + + COSArray array = (COSArray)arguments.get( 0 ); + for( int i=0; i" ); + } + td.setValue( 2, 0, value ); + textMatrix = textMatrix.multiply( td ); + } + else if( next instanceof COSString ) + { + TextPosition pos = showString( ((COSString)next).getBytes() ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + } + else + { + throw new IOException( "Unknown type in array for TJ operation:" + next ); + } + } + } + else if( operation.equals( "TL" ) ) + { + COSNumber leading = (COSNumber)arguments.get( 0 ); + graphicsState.getTextState().setLeading( leading.floatValue() ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + } + else if( operation.equals( "Tm" ) ) + { + //Set text matrix and text line matrix + COSNumber a = (COSNumber)arguments.get( 0 ); + COSNumber b = (COSNumber)arguments.get( 1 ); + COSNumber c = (COSNumber)arguments.get( 2 ); + COSNumber d = (COSNumber)arguments.get( 3 ); + COSNumber e = (COSNumber)arguments.get( 4 ); + COSNumber f = (COSNumber)arguments.get( 5 ); + + if (log.isDebugEnabled()) + { + log.debug(""); + } + + textMatrix = new Matrix(); + textMatrix.setValue( 0, 0, a.floatValue() ); + textMatrix.setValue( 0, 1, b.floatValue() ); + textMatrix.setValue( 1, 0, c.floatValue() ); + textMatrix.setValue( 1, 1, d.floatValue() ); + textMatrix.setValue( 2, 0, e.floatValue() ); + textMatrix.setValue( 2, 1, f.floatValue() ); + textLineMatrix = textMatrix.copy(); + } + else if( operation.equals( "Tr" ) ) + { + //Set text rendering mode + //System.out.println( "" ); + } + else if( operation.equals( "Ts" ) ) + { + //Set text rise + //System.out.println( "" ); + } + else if( operation.equals( "Tw" ) ) + { + //set word spacing + COSNumber wordSpacing = (COSNumber)arguments.get( 0 ); + if (log.isDebugEnabled()) + { + log.debug(""); + } + graphicsState.getTextState().setWordSpacing( wordSpacing.floatValue() ); + } + else if( operation.equals( "Tz" ) ) + { + //Set horizontal text scaling + } + else if( operation.equals( "v" ) ) + { + //Append curved segment to path (initial point replicated) + } + else if( operation.equals( "w" ) ) + { + //Set the line width in the graphics state + //System.out.println( "" ); + } + else if( operation.equals( "W" ) ) + { + //Set clipping path using nonzero winding number rule + //System.out.println( "" ); + } + else if( operation.equals( "W*" ) ) + { + //Set clipping path using even-odd rule + } + else if( operation.equals( "y" ) ) + { + //Append curved segment to path (final point replicated) + } + else if( operation.equals( "'" ) ) + { + // Move to start of next text line, and show text + // + COSString string = (COSString)arguments.get( 0 ); + if (log.isDebugEnabled()) + { + log.debug("<' string=\"" + string.getString() + "\">"); + } + + Matrix td = new Matrix(); + td.setValue( 2, 1, -1 * graphicsState.getTextState().getLeading() * textMatrix.getValue(1,1)); + textLineMatrix = textLineMatrix.multiply( td ); + textMatrix = textLineMatrix.copy(); + + showString( string.getBytes() ); + } + else if( operation.equals( "\"" ) ) + { + //Set word and character spacing, move to next line, and show text + // + COSNumber wordSpacing = (COSNumber)arguments.get( 0 ); + COSNumber characterSpacing = (COSNumber)arguments.get( 1 ); + COSString string = (COSString)arguments.get( 2 ); + + if (log.isDebugEnabled()) + { + log.debug("<\" wordSpacing=\"" + wordSpacing + + "\", characterSpacing=\"" + characterSpacing + + "\", string=\"" + string.getString() + "\">"); + } + + graphicsState.getTextState().setCharacterSpacing( characterSpacing.floatValue() ); + graphicsState.getTextState().setWordSpacing( wordSpacing.floatValue() ); + + Matrix td = new Matrix(); + td.setValue( 2, 1, -1 * graphicsState.getTextState().getLeading() * textMatrix.getValue(1,1)); + textLineMatrix = textLineMatrix.multiply( td ); + textMatrix = textLineMatrix.copy(); + + showString( string.getBytes() ); + }*/ + } + + +} \ No newline at end of file -- cgit v1.2.3