示例#1
0
  /**
   * 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);
      }
    }
  }
示例#2
0
  /**
   * 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(
            fontSize * horizontalScaling,
            0, // 0
            0,
            fontSize, // 0
            0,
            textState.getRise()); // 1

    // 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);

      // get glyph's position vector if this is vertical text
      // 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));
    }
  }