use of com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState in project PdfBox-Android by TomRoush.
the class PageDrawer method setStroke.
// set stroke based on the current CTM and the current stroke
private void setStroke() {
PDGraphicsState state = getGraphicsState();
// apply the CTM
float lineWidth = transformWidth(state.getLineWidth());
// minimum line width as used by Adobe Reader
if (lineWidth < 0.25) {
lineWidth = 0.25f;
}
PDLineDashPattern dashPattern = state.getLineDashPattern();
float phaseStart = dashPattern.getPhase();
float[] dashArray = getDashArray(dashPattern);
phaseStart = transformWidth(phaseStart);
// avoid also infinite and NaN values (PDFBOX-3360)
if (dashArray.length == 0 || Float.isInfinite(phaseStart) || Float.isNaN(phaseStart)) {
dashArray = null;
} else {
for (int i = 0; i < dashArray.length; ++i) {
if (Float.isInfinite(dashArray[i]) || Float.isNaN(dashArray[i])) {
dashArray = null;
break;
}
}
}
paint.setStrokeWidth(lineWidth);
paint.setStrokeCap(state.getLineCap());
paint.setStrokeJoin(state.getLineJoin());
if (dashArray != null) {
paint.setPathEffect(new DashPathEffect(dashArray, phaseStart));
}
}
use of com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState in project PdfBox-Android by TomRoush.
the class PageDrawer method showType3Glyph.
@Override
protected void showType3Glyph(Matrix textRenderingMatrix, PDType3Font font, int code, String unicode, Vector displacement) throws IOException {
PDGraphicsState state = getGraphicsState();
RenderingMode renderingMode = state.getTextState().getRenderingMode();
if (!RenderingMode.NEITHER.equals(renderingMode)) {
super.showType3Glyph(textRenderingMatrix, font, code, unicode, displacement);
}
}
use of com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method showText.
/**
* Process text from the PDF Stream. You should override this method if you want to
* perform an action when encoded text is being processed.
*
* @param string the encoded text
* @throws IOException if there is an error processing the string
*/
protected void showText(byte[] string) throws IOException {
PDGraphicsState state = getGraphicsState();
PDTextState textState = state.getTextState();
// get the current font
PDFont font = textState.getFont();
if (font == null) {
Log.w("PdfBox-Android", "No current font, will use default");
font = PDType1Font.HELVETICA;
}
float fontSize = textState.getFontSize();
float horizontalScaling = textState.getHorizontalScaling() / 100f;
float charSpacing = textState.getCharacterSpacing();
// put the text state parameters into matrix form
Matrix parameters = new Matrix(// 0
fontSize * horizontalScaling, // 0
0, // 0
0, // 0
fontSize, 0, // 1
textState.getRise());
// read the stream until it is empty
InputStream in = new ByteArrayInputStream(string);
while (in.available() > 0) {
// decode a character
int before = in.available();
int code = font.readCode(in);
int codeLength = before - in.available();
String unicode = font.toUnicode(code);
// Word spacing shall be applied to every occurrence of the single-byte character code
// 32 in a string when using a simple font or a composite font that defines code 32 as
// a single-byte code.
float wordSpacing = 0;
if (codeLength == 1 && code == 32) {
wordSpacing += textState.getWordSpacing();
}
// text rendering matrix (text space -> device space)
Matrix ctm = state.getCurrentTransformationMatrix();
Matrix textRenderingMatrix = parameters.multiply(textMatrix).multiply(ctm);
// changes to vertical text should be tested with PDFBOX-2294 and PDFBOX-1422
if (font.isVertical()) {
// position vector, in text space
Vector v = font.getPositionVector(code);
// apply the position vector to the horizontal origin to get the vertical origin
textRenderingMatrix.translate(v);
}
// get glyph's horizontal and vertical displacements, in text space
Vector w = font.getDisplacement(code);
// process the decoded glyph
saveGraphicsState();
Matrix textMatrixOld = textMatrix;
Matrix textLineMatrixOld = textLineMatrix;
showGlyph(textRenderingMatrix, font, code, unicode, w);
textMatrix = textMatrixOld;
textLineMatrix = textLineMatrixOld;
restoreGraphicsState();
// calculate the combined displacements
float tx;
float ty;
if (font.isVertical()) {
tx = 0;
ty = w.getY() * fontSize + charSpacing + wordSpacing;
} else {
tx = (w.getX() * fontSize + charSpacing + wordSpacing) * horizontalScaling;
ty = 0;
}
// update the text matrix
textMatrix.concatenate(Matrix.getTranslateInstance(tx, ty));
}
}
use of com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processType3Stream.
/**
* Processes a Type 3 character stream.
*
* @param charProc Type 3 character procedure
* @param textRenderingMatrix the Text Rendering Matrix
* @throws IOException if there is an error reading or parsing the character content stream.
*/
protected void processType3Stream(PDType3CharProc charProc, Matrix textRenderingMatrix) throws IOException {
if (currentPage == null) {
throw new IllegalStateException("No current page, call " + "#processChildStream(PDContentStream, PDPage) instead");
}
PDResources parent = pushResources(charProc);
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
// replace the CTM with the TRM
getGraphicsState().setCurrentTransformationMatrix(textRenderingMatrix);
// transform the CTM using the stream's matrix (this is the FontMatrix)
getGraphicsState().getCurrentTransformationMatrix().concatenate(charProc.getMatrix());
// note: we don't clip to the BBox as it is often wrong, see PDFBOX-1917
// save text matrices (Type 3 stream may contain BT/ET, see PDFBOX-2137)
Matrix textMatrixOld = textMatrix;
textMatrix = new Matrix();
Matrix textLineMatrixOld = textLineMatrix;
textLineMatrix = new Matrix();
processStreamOperators(charProc);
// restore text matrices
textMatrix = textMatrixOld;
textLineMatrix = textLineMatrixOld;
restoreGraphicsStack(savedStack);
popResources(parent);
}
use of com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState in project PdfBox-Android by TomRoush.
the class PDFStreamEngine method processStream.
/**
* Process a content stream.
*
* @param contentStream the content stream
* @throws IOException if there is an exception while processing the stream
*/
private void processStream(PDContentStream contentStream) throws IOException {
PDResources parent = pushResources(contentStream);
Deque<PDGraphicsState> savedStack = saveGraphicsStack();
Matrix parentMatrix = initialMatrix;
// transform the CTM using the stream's matrix
getGraphicsState().getCurrentTransformationMatrix().concatenate(contentStream.getMatrix());
// the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form
initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clone();
// clip to bounding box
PDRectangle bbox = contentStream.getBBox();
clipToRect(bbox);
processStreamOperators(contentStream);
initialMatrix = parentMatrix;
restoreGraphicsStack(savedStack);
popResources(parent);
}
Aggregations