Search in sources :

Example 1 with PDTextState

use of org.apache.pdfbox.pdmodel.graphics.state.PDTextState in project pdfbox by apache.

the class PreflightContentStream method validateText.

/**
 * Process the validation of a Text operand contains in a ContentStream This validation checks that :
 * <UL>
 * <li>The font isn't missing if the Rendering Mode isn't 3
 * <li>The font metrics are consistent
 * <li>All character used in the text are defined in the font program.
 * </UL>
 *
 * @param string
 * @throws IOException
 */
public void validateText(byte[] string) throws IOException {
    // TextSize accessible through the TextState
    PDTextState textState = getGraphicsState().getTextState();
    final RenderingMode renderingMode = textState.getRenderingMode();
    final PDFont font = textState.getFont();
    if (font == null) {
        // Unable to decode the Text without Font
        registerError("Text operator can't be processed without a Font", ERROR_FONTS_UNKNOWN_FONT_REF);
        return;
    }
    FontContainer<?> fontContainer = context.getFontContainer(font.getCOSObject());
    if (renderingMode == RenderingMode.NEITHER && (fontContainer == null || !fontContainer.isEmbeddedFont())) {
        // font not embedded and rendering mode is 3. Valid case and nothing to check
        return;
    } else if (fontContainer == null) {
        // Font Must be embedded if the RenderingMode isn't 3
        if (font.getName() == null) {
            registerError("invalid font dictionary", ERROR_FONTS_UNKNOWN_FONT_REF);
        } else {
            registerError("font '" + font.getName() + "' is missing", ERROR_FONTS_UNKNOWN_FONT_REF);
        }
        return;
    } else if (!fontContainer.isValid() && !fontContainer.errorsAleadyMerged()) {
        context.addValidationErrors(fontContainer.getAllErrors());
        fontContainer.setErrorsAlreadyMerged(true);
        return;
    }
    if (!fontContainer.isValid() && fontContainer.errorsAleadyMerged()) {
        // font already computed
        return;
    }
    InputStream in = new ByteArrayInputStream(string);
    while (in.available() > 0) {
        try {
            int code = font.readCode(in);
            fontContainer.checkGlyphWidth(code);
        } catch (IOException e) {
            registerError("Encoding can't interpret the character code", ERROR_FONTS_ENCODING_ERROR, e);
            return;
        } catch (GlyphException e) {
            if (renderingMode != RenderingMode.NEITHER) {
                registerError(e.getMessage(), e.getErrorCode(), e);
                return;
            }
        }
    }
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) RenderingMode(org.apache.pdfbox.pdmodel.graphics.state.RenderingMode) ByteArrayInputStream(java.io.ByteArrayInputStream) GlyphException(org.apache.pdfbox.preflight.font.util.GlyphException) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) PDTextState(org.apache.pdfbox.pdmodel.graphics.state.PDTextState) IOException(java.io.IOException)

Example 2 with PDTextState

use of org.apache.pdfbox.pdmodel.graphics.state.PDTextState in project pdfbox by apache.

the class PDFStreamEngine method showTextStrings.

/**
 * Called when a string of text with spacing adjustments is to be shown.
 *
 * @param array array of encoded text strings and adjustments
 * @throws IOException if there was an error showing the text
 */
public void showTextStrings(COSArray array) throws IOException {
    PDTextState textState = getGraphicsState().getTextState();
    float fontSize = textState.getFontSize();
    float horizontalScaling = textState.getHorizontalScaling() / 100f;
    PDFont font = textState.getFont();
    boolean isVertical = false;
    if (font != null) {
        isVertical = font.isVertical();
    }
    for (COSBase obj : array) {
        if (obj instanceof COSNumber) {
            float tj = ((COSNumber) obj).floatValue();
            // calculate the combined displacements
            float tx, ty;
            if (isVertical) {
                tx = 0;
                ty = -tj / 1000 * fontSize;
            } else {
                tx = -tj / 1000 * fontSize * horizontalScaling;
                ty = 0;
            }
            applyTextAdjustment(tx, ty);
        } else if (obj instanceof COSString) {
            byte[] string = ((COSString) obj).getBytes();
            showText(string);
        } else {
            throw new IOException("Unknown type in array for TJ operation:" + obj);
        }
    }
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) COSNumber(org.apache.pdfbox.cos.COSNumber) COSBase(org.apache.pdfbox.cos.COSBase) PDTextState(org.apache.pdfbox.pdmodel.graphics.state.PDTextState) IOException(java.io.IOException) COSString(org.apache.pdfbox.cos.COSString)

Example 3 with PDTextState

use of org.apache.pdfbox.pdmodel.graphics.state.PDTextState in project pdfbox by apache.

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.warn("No current font, will use default");
        font = PDFontFactory.createDefaultFont();
    }
    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, 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));
    }
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) Matrix(org.apache.pdfbox.util.Matrix) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) PDTextState(org.apache.pdfbox.pdmodel.graphics.state.PDTextState) COSString(org.apache.pdfbox.cos.COSString) Vector(org.apache.pdfbox.util.Vector) PDGraphicsState(org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState)

Aggregations

PDFont (org.apache.pdfbox.pdmodel.font.PDFont)3 PDTextState (org.apache.pdfbox.pdmodel.graphics.state.PDTextState)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 COSString (org.apache.pdfbox.cos.COSString)2 COSBase (org.apache.pdfbox.cos.COSBase)1 COSNumber (org.apache.pdfbox.cos.COSNumber)1 PDGraphicsState (org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState)1 RenderingMode (org.apache.pdfbox.pdmodel.graphics.state.RenderingMode)1 GlyphException (org.apache.pdfbox.preflight.font.util.GlyphException)1 Matrix (org.apache.pdfbox.util.Matrix)1 Vector (org.apache.pdfbox.util.Vector)1