Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2014 by Tizra Inc.
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is 'iText, a free JAVA-PDF library'.
*
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
* the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie.
* All Rights Reserved.
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
* are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved.
*
* Contributor(s): all the names of the contributors are added in the source code
* where applicable.
*
* Alternatively, the contents of this file may be used under the terms of the
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
* provisions of LGPL are applicable instead of those above. If you wish to
* allow use of your version of this file only under the terms of the LGPL
* License and not to allow others to use your version of this file under
* the MPL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the LGPL.
* If you do not delete the provisions above, a recipient may use your version
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MPL as stated above or under the terms of the GNU
* Library General Public License as published by the Free Software Foundation;
* either version 2 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
* details.
*/
package com.lowagie.text.pdf.parser;
import com.lowagie.text.error_messages.MessageLocalization;
import com.lowagie.text.pdf.CMapAwareDocumentFont;
import com.lowagie.text.pdf.PRIndirectReference;
import com.lowagie.text.pdf.PdfArray;
import com.lowagie.text.pdf.PdfDictionary;
import com.lowagie.text.pdf.PdfIndirectReference;
import com.lowagie.text.pdf.PdfLiteral;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfNumber;
import com.lowagie.text.pdf.PdfObject;
import com.lowagie.text.pdf.PdfString;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
/**
* @author dgd
*/
public class PdfContentStreamHandler {
/**
* A content operator implementation (TJ).
*/
static class ShowTextArray implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "TJ";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfArray array = (PdfArray) operands.get(0);
float tj = 0;
for (Iterator> i = array.listIterator(); i.hasNext();) {
Object entryObj = i.next();
if (entryObj instanceof PdfString) {
handler.displayPdfString((PdfString) entryObj);
tj = 0;
} else {
tj = ((PdfNumber) entryObj).floatValue();
handler.applyTextAdjust(tj);
}
}
}
}
/**
* A content operator implementation (BT).
*/
static class BeginText implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "BT";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
handler.textMatrix = new Matrix();
handler.textLineMatrix = handler.textMatrix;
}
}
/**
* A content operator implementation (ET).
*/
static class EndText implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "ET";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
handler.textMatrix = null;
handler.textLineMatrix = null;
}
}
/**
* A content operator implementation (cm).
*/
static class ModifyCurrentTransformationMatrix implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "cm";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
float a = ((PdfNumber) operands.get(0)).floatValue();
float b = ((PdfNumber) operands.get(1)).floatValue();
float c = ((PdfNumber) operands.get(2)).floatValue();
float d = ((PdfNumber) operands.get(3)).floatValue();
float e = ((PdfNumber) operands.get(4)).floatValue();
float f = ((PdfNumber) operands.get(5)).floatValue();
Matrix matrix = new Matrix(a, b, c, d, e, f);
GraphicsState gs = handler.gsStack.peek();
gs.ctm = gs.ctm.multiply(matrix);
}
}
/**
* A content operator implementation (').
*/
static class MoveNextLineAndShowText implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "'";
}
private final PdfContentStreamHandler.TextMoveNextLine textMoveNextLine;
private final PdfContentStreamHandler.ShowText showText;
public MoveNextLineAndShowText(
PdfContentStreamHandler.TextMoveNextLine textMoveNextLine,
PdfContentStreamHandler.ShowText showText) {
this.textMoveNextLine = textMoveNextLine;
this.showText = showText;
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
textMoveNextLine.invoke(new ArrayList(0), handler,
resources);
showText.invoke(operands, handler, resources);
}
}
/**
* A content operator implementation (").
*/
static class MoveNextLineAndShowTextWithSpacing implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "\"";
}
private final PdfContentStreamHandler.SetTextWordSpacing setTextWordSpacing;
private final PdfContentStreamHandler.SetTextCharacterSpacing setTextCharacterSpacing;
private final MoveNextLineAndShowText moveNextLineAndShowText;
public MoveNextLineAndShowTextWithSpacing(
PdfContentStreamHandler.SetTextWordSpacing setTextWordSpacing,
PdfContentStreamHandler.SetTextCharacterSpacing setTextCharacterSpacing,
MoveNextLineAndShowText moveNextLineAndShowText) {
this.setTextWordSpacing = setTextWordSpacing;
this.setTextCharacterSpacing = setTextCharacterSpacing;
this.moveNextLineAndShowText = moveNextLineAndShowText;
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber aw = (PdfNumber) operands.get(0);
PdfNumber ac = (PdfNumber) operands.get(1);
PdfString string = (PdfString) operands.get(2);
ArrayList twOperands = new ArrayList(1);
twOperands.add(0, aw);
setTextWordSpacing.invoke(twOperands, handler, resources);
ArrayList tcOperands = new ArrayList(1);
tcOperands.add(0, ac);
setTextCharacterSpacing.invoke(tcOperands, handler, resources);
ArrayList tickOperands = new ArrayList(1);
tickOperands.add(0, string);
moveNextLineAndShowText.invoke(tickOperands, handler, resources);
}
}
/**
* A content operator implementation (Q).
*/
static class PopGraphicsState implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Q";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
handler.gsStack.pop();
}
}
/**
* A content operator implementation (gs).
*/
static class ProcessGraphicsStateResource implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "gs";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfName dictionaryName = (PdfName) operands.get(0);
PdfDictionary extGState = resources.getAsDict(PdfName.EXTGSTATE);
if (extGState == null) {
throw new IllegalArgumentException(
MessageLocalization
.getComposedMessage(
"resources.do.not.contain.extgstate.entry.unable.to.process.operator.1",
getOperatorName()));
}
PdfDictionary gsDic = extGState.getAsDict(dictionaryName);
if (gsDic == null) {
throw new IllegalArgumentException(
MessageLocalization.getComposedMessage(
"1.is.an.unknown.graphics.state.dictionary",
dictionaryName));
}
// at this point, all we care about is the FONT entry in the GS
// dictionary
PdfArray fontParameter = gsDic.getAsArray(PdfName.FONT);
if (fontParameter != null) {
CMapAwareDocumentFont font = new CMapAwareDocumentFont(
(PRIndirectReference) fontParameter.getPdfObject(0));
float size = fontParameter.getAsNumber(1).floatValue();
handler.gs().font = font;
handler.gs().fontSize = size;
}
}
}
/**
* A content operator implementation (q).
*/
static class PushGraphicsState implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "q";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
GraphicsState gs = handler.gsStack.peek();
GraphicsState copy = new GraphicsState(gs);
handler.gsStack.push(copy);
}
}
/**
* A content operator implementation (Tc).
*/
static class SetTextCharacterSpacing implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tc";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber charSpace = (PdfNumber) operands.get(0);
handler.gs().characterSpacing = charSpace.floatValue();
}
}
/**
* A content operator implementation (Tf).
*/
static class SetTextFont implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tf";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfName fontResourceName = (PdfName) operands.get(0);
float size = ((PdfNumber) operands.get(1)).floatValue();
PdfDictionary fontsDictionary = resources.getAsDict(PdfName.FONT);
CMapAwareDocumentFont font = new CMapAwareDocumentFont(
(PRIndirectReference) fontsDictionary.get(fontResourceName));
handler.gs().font = font;
handler.gs().fontSize = size;
}
}
/**
* A content operator implementation (Tm).
*/
static class TextSetTextMatrix implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tm";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
float a = ((PdfNumber) operands.get(0)).floatValue();
float b = ((PdfNumber) operands.get(1)).floatValue();
float c = ((PdfNumber) operands.get(2)).floatValue();
float d = ((PdfNumber) operands.get(3)).floatValue();
float e = ((PdfNumber) operands.get(4)).floatValue();
float f = ((PdfNumber) operands.get(5)).floatValue();
handler.textLineMatrix = new Matrix(a, b, c, d, e, f);
handler.textMatrix = handler.textLineMatrix;
}
}
/**
* A content operator implementation (TD).
*/
static class TextMoveStartNextLineWithLeading implements ContentOperator {
private final PdfContentStreamHandler.TextMoveStartNextLine moveStartNextLine;
private final PdfContentStreamHandler.SetTextLeading setTextLeading;
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "TD";
}
public TextMoveStartNextLineWithLeading(
PdfContentStreamHandler.TextMoveStartNextLine moveStartNextLine,
PdfContentStreamHandler.SetTextLeading setTextLeading) {
this.moveStartNextLine = moveStartNextLine;
this.setTextLeading = setTextLeading;
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
float ty = ((PdfNumber) operands.get(1)).floatValue();
ArrayList tlOperands = new ArrayList(1);
tlOperands.add(0, new PdfNumber(-ty));
setTextLeading.invoke(tlOperands, handler, resources);
moveStartNextLine.invoke(operands, handler, resources);
}
}
/**
* A content operator implementation (Tj).
*/
static class ShowText implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tj";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfString string = (PdfString) operands.get(0);
handler.displayPdfString(string);
}
}
/**
* A content operator implementation (T*).
*/
static class TextMoveNextLine implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "T*";
}
private final TextMoveStartNextLine moveStartNextLine;
public TextMoveNextLine(TextMoveStartNextLine moveStartNextLine) {
this.moveStartNextLine = moveStartNextLine;
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
ArrayList tdoperands = new ArrayList(2);
tdoperands.add(0, new PdfNumber(0));
tdoperands.add(1, new PdfNumber(-handler.gs().leading));
moveStartNextLine.invoke(tdoperands, handler, resources);
}
}
/**
* A content operator implementation (Td).
*/
static class TextMoveStartNextLine implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Td";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
float tx = ((PdfNumber) operands.get(0)).floatValue();
float ty = ((PdfNumber) operands.get(1)).floatValue();
Matrix translationMatrix = new Matrix(tx, ty);
handler.textMatrix = translationMatrix
.multiply(handler.textLineMatrix);
handler.textLineMatrix = handler.textMatrix;
}
}
/**
* A content operator implementation (Tr).
*/
static class SetTextRenderMode implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tr";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber render = (PdfNumber) operands.get(0);
handler.gs().renderMode = render.intValue();
}
}
/**
* A content operator implementation (Ts).
*/
static class SetTextRise implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Ts";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber rise = (PdfNumber) operands.get(0);
handler.gs().rise = rise.floatValue();
}
}
/**
* A content operator implementation (TL).
*/
static class SetTextLeading implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "TL";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber leading = (PdfNumber) operands.get(0);
handler.gs().leading = leading.floatValue();
}
}
/**
* A content operator implementation (Tz).
*/
static class SetTextHorizontalScaling implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tz";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber scale = (PdfNumber) operands.get(0);
handler.gs().horizontalScaling = scale.floatValue();
}
}
/**
* A content operator implementation (Tw).
*/
static class SetTextWordSpacing implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "Tw";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfNumber wordSpace = (PdfNumber) operands.get(0);
handler.gs().wordSpacing = wordSpace.floatValue();
}
}
Stack> textFragmentStreams = new Stack>();
Stack contextNames = new Stack();
Collection textFragments = new ArrayList();
/** A map with all supported operators operators (PDF syntax). */
public Map operators;
/** Stack keeping track of the graphics state. */
public Stack gsStack;
/** Text matrix. */
public Matrix textMatrix;
/** Text line matrix. */
public Matrix textLineMatrix;
boolean useContainerMarkup;
/**
* detail parser for text within a marked section. used by TextAssembler
*/
TextAssembler renderListener;
/**
* @param renderListener
*
*/
public PdfContentStreamHandler(TextAssembler renderListener) {
this.renderListener = renderListener;
installDefaultOperators();
reset();
}
/**
* Registers a content operator that will be called when the specified
* operator string is encountered during content processing. Each operator
* may be registered only once (it is not legal to have multiple operators
* with the same operatorString)
*
* @param operator
* the operator that will receive notification when the operator
* is encountered
*
* @since 2.1.7
*/
public void registerContentOperator(ContentOperator operator) {
String operatorString = operator.getOperatorName();
if (operators.containsKey(operatorString)) {
throw new IllegalArgumentException(
MessageLocalization.getComposedMessage(
"operator.1.already.registered", operatorString));
}
operators.put(operatorString, operator);
}
/**
* A content operator implementation (BMC).
*/
private static class BeginMarked implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "BMC";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
PdfName name = (PdfName) operands.get(0);
String realName = name.toString().substring(1);
if ("Artifact".equals(realName)) {
handler.pushContext(null);
} else {
handler.pushContext(realName);
}
}
}
/**
* A content operator implementation (BDC).
*/
private static class BeginMarkedDict implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "BDC";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
String tagName = ((PdfName) operands.get(0)).toString()
.substring(1).toLowerCase();
if ("artifact".equals(tagName) || "placedpdf".equals(tagName)
|| handler.contextNames.peek() == null) {
tagName = null;
} else if ("l".equals(tagName)) {
tagName = "ul";
}
PdfDictionary attrs = getBDCDictionary(operands, resources);
if (attrs != null) {
PdfString alternateText = attrs.getAsString(PdfName.E);
if (alternateText != null) {
handler.pushContext(tagName);
handler.textFragments.add(new FinalText(alternateText
.toString()));
handler.popContext();
handler.pushContext(null);
return;
}
}
handler.pushContext(tagName);
}
/**
* @param operands
* @param resources
* @return
*/
private PdfDictionary getBDCDictionary(ArrayList operands,
PdfDictionary resources) {
PdfObject o = operands.get(1);
if (o.isName()) {
PdfDictionary properties = resources
.getAsDict(PdfName.PROPERTIES);
PdfIndirectReference ir = properties
.getAsIndirectObject((PdfName) o);
if (ir != null) {
o = ir.getIndRef();
} else {
o = properties.getAsDict((PdfName) o);
}
}
PdfDictionary attrs = (PdfDictionary) o;
return attrs;
}
}
/**
* A content operator implementation (EMC).
*/
private static class EndMarked implements ContentOperator {
/**
* @see com.lowagie.text.pdf.parser.ContentOperator#getOperatorName()
*/
@Override
public String getOperatorName() {
return "EMC";
}
@Override
public void invoke(ArrayList operands,
PdfContentStreamHandler handler, PdfDictionary resources) {
handler.popContext();
}
}
/**
* Loads all the supported graphics and text state operators in a map.
*/
protected void installDefaultOperators() {
operators = new HashMap();
registerContentOperator(new PdfContentStreamHandler.PushGraphicsState());
registerContentOperator(new PdfContentStreamHandler.PopGraphicsState());
registerContentOperator(new PdfContentStreamHandler.ModifyCurrentTransformationMatrix());
registerContentOperator(new PdfContentStreamHandler.ProcessGraphicsStateResource());
PdfContentStreamHandler.SetTextCharacterSpacing tcOperator = new PdfContentStreamHandler.SetTextCharacterSpacing();
registerContentOperator(tcOperator);
PdfContentStreamHandler.SetTextWordSpacing twOperator = new PdfContentStreamHandler.SetTextWordSpacing();
registerContentOperator(twOperator);
registerContentOperator(new PdfContentStreamHandler.SetTextHorizontalScaling());
PdfContentStreamHandler.SetTextLeading tlOperator = new PdfContentStreamHandler.SetTextLeading();
registerContentOperator(tlOperator);
registerContentOperator(new PdfContentStreamHandler.SetTextFont());
registerContentOperator(new PdfContentStreamHandler.SetTextRenderMode());
registerContentOperator(new PdfContentStreamHandler.SetTextRise());
registerContentOperator(new PdfContentStreamHandler.BeginText());
registerContentOperator(new PdfContentStreamHandler.EndText());
PdfContentStreamHandler.TextMoveStartNextLine tdOperator = new PdfContentStreamHandler.TextMoveStartNextLine();
registerContentOperator(tdOperator);
registerContentOperator(new PdfContentStreamHandler.TextMoveStartNextLineWithLeading(
tdOperator, tlOperator));
registerContentOperator(new PdfContentStreamHandler.TextSetTextMatrix());
PdfContentStreamHandler.TextMoveNextLine tstarOperator = new PdfContentStreamHandler.TextMoveNextLine(
tdOperator);
registerContentOperator(tstarOperator);
PdfContentStreamHandler.ShowText tjOperator = new PdfContentStreamHandler.ShowText();
registerContentOperator(new PdfContentStreamHandler.ShowText());
PdfContentStreamHandler.MoveNextLineAndShowText tickOperator = new PdfContentStreamHandler.MoveNextLineAndShowText(
tstarOperator, tjOperator);
registerContentOperator(tickOperator);
registerContentOperator(new PdfContentStreamHandler.MoveNextLineAndShowTextWithSpacing(
twOperator, tcOperator, tickOperator));
registerContentOperator(new PdfContentStreamHandler.ShowTextArray());
// marked sections
registerContentOperator(new BeginMarked());
registerContentOperator(new BeginMarkedDict());
registerContentOperator(new EndMarked());
}
/**
* Get the operator to process a command with a given name
*
* @param operatorName
* name of the operator that we might need to call
*
* @return the operator or null if none present
*/
public ContentOperator lookupOperator(String operatorName) {
return operators.get(operatorName);
}
/**
* Invokes an operator.
*
* @param operator
* the PDF Syntax of the operator
* @param operands
* a list with operands
* @param resources
* Pdf Resources found in the file containing the stream.
*/
public void invokeOperator(PdfLiteral operator,
ArrayList operands, PdfDictionary resources) {
String operatorName = operator.toString();
ContentOperator op = lookupOperator(operatorName);
if (op == null) {
// System.out.println("Skipping operator " + operator);
return;
}
// System.err.println(operator);
// System.err.println(operands);
op.invoke(operands, this, resources);
}
void popContext() {
String contextName = contextNames.pop();
Collection newBuffer = textFragmentStreams.pop();
// put together set of unparsed text fragments
renderListener.reset();
for (TextAssemblyBuffer fragment : textFragments) {
fragment.accumulate(renderListener, contextName);
}
FinalText contextResult = renderListener.endParsingContext(contextName);
if (contextResult != null && contextResult.getText().length() > 0) {
newBuffer.add(contextResult);
}
textFragments = newBuffer;
}
void pushContext(String newContextName) {
contextNames.push(newContextName);
textFragmentStreams.push(textFragments);
textFragments = new ArrayList();
}
/**
* Returns the current graphics state.
*
* @return the graphics state
*/
GraphicsState gs() {
return gsStack.peek();
}
/**
*
*/
public void reset() {
if (gsStack == null || gsStack.isEmpty()) {
gsStack = new Stack();
}
gsStack.add(new GraphicsState());
textMatrix = null;
textLineMatrix = null;
}
/**
* Returns the current text matrix.
*
* @return the text matrix
* @since 2.1.5
*/
protected Matrix getCurrentTextMatrix() {
return textMatrix;
}
/**
* Returns the current line matrix.
*
* @return the line matrix
* @since 2.1.5
*/
protected Matrix getCurrentTextLineMatrix() {
return textLineMatrix;
}
/**
* Adjusts the text matrix for the specified adjustment value (see TJ
* operator in the PDF spec for information)
*
* @param tj
* the text adjustment
*/
void applyTextAdjust(float tj) {
float adjustBy = -tj / 1000f * gs().fontSize * gs().horizontalScaling;
textMatrix = new Matrix(adjustBy, 0).multiply(textMatrix);
}
/**
* Decodes a PdfString (which will contain glyph ids encoded in the font's
* encoding) based on the active font, and determine the unicode equivalent
*
* @param in
* the String that needs to be encoded
*
* @return the encoded String
* @since 2.1.7
*/
protected String decode(PdfString in) {
byte[] bytes = in.getBytes();
return getCurrentFont().decode(bytes, 0, bytes.length);
}
/**
* @return current font in processing state
*/
public CMapAwareDocumentFont getCurrentFont() {
return gs().font;
}
/**
* Displays text.
*
* @param string
* the text to display
*/
void displayPdfString(PdfString string) {
String unicode = decode(string);
ParsedText renderInfo = new ParsedText(unicode, gs(), textMatrix);
if (contextNames.peek() != null) {
textFragments.add(renderInfo);
}
textMatrix = new Matrix(renderInfo.getUnscaledWidth(gs()), 0)
.multiply(textMatrix);
}
/**
* @return
*/
public String getResultantText() {
if (contextNames.size() > 0) {
throw new RuntimeException(
"can't get text with unprocessed stack items");
}
StringBuffer res = new StringBuffer();
for (TextAssemblyBuffer fragment : textFragments) {
res.append(fragment.getText());
}
return res.toString();
}
}