/**
  * The Td operator.
  *
  * @param x The x coordinate.
  * @param y The y coordinate.
  * @throws IOException If there is an error writing to the stream.
  */
 public void moveTextPositionByAmount(float x, float y) throws IOException {
   if (!inTextMode) {
     throw new IOException("Error: must call beginText() before moveTextPositionByAmount");
   }
   appendRawCommands(formatDecimal.format(x));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(y));
   appendRawCommands(SPACE);
   appendRawCommands(MOVE_TEXT_POSITION);
 }
 /**
  * This will draw a string at the current location on the screen.
  *
  * @param text The text to draw.
  * @throws IOException If an io exception occurs.
  */
 public void drawString(String text) throws IOException {
   if (!inTextMode) {
     throw new IOException("Error: must call beginText() before drawString");
   }
   COSString string = new COSString(text);
   ByteArrayOutputStream buffer = new ByteArrayOutputStream();
   string.writePDF(buffer);
   appendRawCommands(new String(buffer.toByteArray(), "ISO-8859-1"));
   appendRawCommands(SPACE);
   appendRawCommands(SHOW_TEXT);
 }
 /**
  * Draw a rectangle on the page using the current non stroking color.
  *
  * @param x The lower left x coordinate.
  * @param y The lower left y coordinate.
  * @param width The width of the rectangle.
  * @param height The height of the rectangle.
  * @throws IOException If there is an error while drawing on the screen.
  */
 public void fillRect(float x, float y, float width, float height) throws IOException {
   appendRawCommands(formatDecimal.format(x));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(y));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(width));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(height));
   appendRawCommands(SPACE);
   appendRawCommands(APPEND_RECTANGLE);
   appendRawCommands(FILL);
 }
 /**
  * Set the color components of current non stroking colorspace.
  *
  * @param components The components to set for the current color.
  * @throws IOException If there is an error while writing to the stream.
  */
 public void setNonStrokingColor(float[] components) throws IOException {
   for (int i = 0; i < components.length; i++) {
     appendRawCommands(formatDecimal.format(components[i]));
     appendRawCommands(SPACE);
   }
   if (currentNonStrokingColorSpace instanceof PDSeparation
       || currentNonStrokingColorSpace instanceof PDPattern
       || currentNonStrokingColorSpace instanceof PDDeviceN
       || currentNonStrokingColorSpace instanceof PDICCBased) {
     appendRawCommands(SET_NON_STROKING_COLOR_COMPLEX);
   } else {
     appendRawCommands(SET_NON_STROKING_COLOR_SIMPLE);
   }
 }
 /**
  * Set the non stroking color, specified as CMYK, 0-255.
  *
  * @param c The cyan value.
  * @param m The magenta value.
  * @param y The yellow value.
  * @param k The black value.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setNonStrokingColor(int c, int m, int y, int k) throws IOException {
   appendRawCommands(formatDecimal.format(c / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(m / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(y / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(k / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(K_NON_STROKING);
 }
 /**
  * Set the non stroking color, specified as CMYK, 0.0-1.0.
  *
  * @param c The cyan value.
  * @param m The magenta value.
  * @param y The yellow value.
  * @param k The black value.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setNonStrokingColor(double c, double m, double y, double k) throws IOException {
   appendRawCommands(formatDecimal.format(c));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(m));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(y));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(k));
   appendRawCommands(SPACE);
   appendRawCommands(K_NON_STROKING);
 }
 /**
  * Begin some text operations.
  *
  * @throws IOException If there is an error writing to the stream or if you attempt to nest
  *     beginText calls.
  */
 public void beginText() throws IOException {
   if (inTextMode) {
     throw new IOException("Error: Nested beginText() calls are not allowed.");
   }
   appendRawCommands(BEGIN_TEXT);
   inTextMode = true;
 }
 /**
  * End some text operations.
  *
  * @throws IOException If there is an error writing to the stream or if you attempt to nest
  *     endText calls.
  */
 public void endText() throws IOException {
   if (!inTextMode) {
     throw new IOException("Error: You must call beginText() before calling endText.");
   }
   appendRawCommands(END_TEXT);
   inTextMode = false;
 }
  private void writeColorSpace(PDColorSpace colorSpace) throws IOException {
    COSName key = null;
    if (colorSpace instanceof PDDeviceGray
        || colorSpace instanceof PDDeviceRGB
        || colorSpace instanceof PDDeviceCMYK) {
      key = COSName.getPDFName(colorSpace.getName());
    } else {
      COSDictionary colorSpaces =
          (COSDictionary) resources.getCOSDictionary().getDictionaryObject(COSName.COLORSPACE);
      if (colorSpaces == null) {
        colorSpaces = new COSDictionary();
        resources.getCOSDictionary().setItem(COSName.COLORSPACE, colorSpaces);
      }
      key = colorSpaces.getKeyForValue(colorSpace.getCOSObject());

      if (key == null) {
        int counter = 0;
        String csName = "CS";
        while (colorSpaces.containsValue(csName + counter)) {
          counter++;
        }
        key = COSName.getPDFName(csName + counter);
        colorSpaces.setItem(key, colorSpace);
      }
    }
    key.writePDF(output);
    appendRawCommands(SPACE);
  }
 /**
  * Set the non stroking color, specified as RGB, 0-255.
  *
  * @param r The red value.
  * @param g The green value.
  * @param b The blue value.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setNonStrokingColor(int r, int g, int b) throws IOException {
   appendRawCommands(formatDecimal.format(r / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(g / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(b / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(RG_NON_STROKING);
 }
  private boolean markupMatch(Color color, PDPageContentStream contentStream, Match markingMatch)
      throws IOException {
    final List<PDRectangle> textBoundingBoxes = getTextBoundingBoxes(markingMatch.positions);

    if (textBoundingBoxes.size() > 0) {
      contentStream.appendRawCommands("/highlights gs\n");
      contentStream.setNonStrokingColor(color);
      for (PDRectangle textBoundingBox : textBoundingBoxes) {
        contentStream.fillRect(
            textBoundingBox.getLowerLeftX(),
            textBoundingBox.getLowerLeftY(),
            Math.max(
                Math.abs(textBoundingBox.getUpperRightX() - textBoundingBox.getLowerLeftX()), 10),
            10);
      }
      return true;
    }
    return false;
  }
 /**
  * Set the font to draw text with.
  *
  * @param font The font to use.
  * @param fontSize The font size to draw the text.
  * @throws IOException If there is an error writing the font information.
  */
 public void setFont(PDFont font, float fontSize) throws IOException {
   String fontMapping = (String) fontMappings.get(font);
   if (fontMapping == null) {
     fontMapping = MapUtil.getNextUniqueKey(fonts, "F");
     fontMappings.put(font, fontMapping);
     fonts.put(fontMapping, font);
   }
   appendRawCommands("/");
   appendRawCommands(fontMapping);
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(fontSize));
   appendRawCommands(SPACE);
   appendRawCommands(SET_FONT);
 }
 /**
  * Draw a line on the page using the current non stroking color and the current line width.
  *
  * @param xStart The start x coordinate.
  * @param yStart The start y coordinate.
  * @param xEnd The end x coordinate.
  * @param yEnd The end y coordinate.
  * @throws IOException If there is an error while drawing on the screen.
  */
 public void drawLine(float xStart, float yStart, float xEnd, float yEnd) throws IOException {
   // moveTo
   appendRawCommands(formatDecimal.format(xStart));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(yStart));
   appendRawCommands(SPACE);
   appendRawCommands(MOVE_TO);
   // lineTo
   appendRawCommands(formatDecimal.format(xEnd));
   appendRawCommands(SPACE);
   appendRawCommands(formatDecimal.format(yEnd));
   appendRawCommands(SPACE);
   appendRawCommands(LINE_TO);
   // stroke
   appendRawCommands(STROKE);
 }
 /**
  * Set the non stroking color, specified as Grayscale 0.0-1.0.
  *
  * @param g The gray value.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setNonStrokingColor(double g) throws IOException {
   appendRawCommands(formatDecimal.format(g));
   appendRawCommands(SPACE);
   appendRawCommands(G_NON_STROKING);
 }
  /**
   * Draw an xobject(form or image) at the x,y coordinates and a certain width and height.
   *
   * @param xobject The xobject to draw.
   * @param x The x-coordinate to draw the image.
   * @param y The y-coordinate to draw the image.
   * @param width The width of the image to draw.
   * @param height The height of the image to draw.
   * @throws IOException If there is an error writing to the stream.
   */
  public void drawXObject(PDXObject xobject, float x, float y, float width, float height)
      throws IOException {
    String xObjectPrefix = null;
    if (xobject instanceof PDXObjectImage) {
      xObjectPrefix = "Im";
    } else {
      xObjectPrefix = "Form";
    }

    String objMapping = (String) xobjectMappings.get(xobject);
    if (objMapping == null) {
      objMapping = MapUtil.getNextUniqueKey(xobjects, xObjectPrefix);
      xobjectMappings.put(xobject, objMapping);
      xobjects.put(objMapping, xobject);
    }
    appendRawCommands(SAVE_GRAPHICS_STATE);
    appendRawCommands(formatDecimal.format(width));
    appendRawCommands(SPACE);
    appendRawCommands(formatDecimal.format(0));
    appendRawCommands(SPACE);
    appendRawCommands(formatDecimal.format(0));
    appendRawCommands(SPACE);
    appendRawCommands(formatDecimal.format(height));
    appendRawCommands(SPACE);
    appendRawCommands(formatDecimal.format(x));
    appendRawCommands(SPACE);
    appendRawCommands(formatDecimal.format(y));
    appendRawCommands(SPACE);
    appendRawCommands(CONCATENATE_MATRIX);
    appendRawCommands(SPACE);
    appendRawCommands("/");
    appendRawCommands(objMapping);
    appendRawCommands(SPACE);
    appendRawCommands(XOBJECT_DO);
    appendRawCommands(SPACE);
    appendRawCommands(RESTORE_GRAPHICS_STATE);
  }
 /**
  * Set the stroking color space. This will add the colorspace to the PDResources if necessary.
  *
  * @param colorSpace The colorspace to write.
  * @throws IOException If there is an error writing the colorspace.
  */
 public void setNonStrokingColorSpace(PDColorSpace colorSpace) throws IOException {
   currentNonStrokingColorSpace = colorSpace;
   writeColorSpace(colorSpace);
   appendRawCommands(SET_NON_STROKING_COLORSPACE);
 }
 /**
  * Set linewidth to the given value.
  *
  * @param lineWidth The width which is used for drwaing.
  * @throws IOException If there is an error while drawing on the screen.
  */
 public void setLineWidth(float lineWidth) throws IOException {
   appendRawCommands(formatDecimal.format(lineWidth));
   appendRawCommands(SPACE);
   appendRawCommands(LINE_WIDTH);
 }
 /**
  * This will append raw commands to the content stream.
  *
  * @param commands The commands to append to the stream.
  * @throws IOException If an error occurs while writing to the stream.
  */
 public void appendRawCommands(String commands) throws IOException {
   appendRawCommands(commands.getBytes("ISO-8859-1"));
 }
 /**
  * Set the stroking color, specified as grayscale, 0-255.
  *
  * @param g The gray value.
  * @throws IOException If an IO error occurs while writing to the stream.
  */
 public void setStrokingColor(int g) throws IOException {
   appendRawCommands(formatDecimal.format(g / 255d));
   appendRawCommands(SPACE);
   appendRawCommands(G_STROKING);
 }