java.lang.Object
org.apache.pdfbox.pdmodel.interactive.annotation.handlers.CloudyBorder

class CloudyBorder extends Object
Generates annotation appearances with a cloudy border.

Dashed stroke styles are not recommended with cloudy borders. The result would not look good because some parts of the arcs are traced twice by the stroked path. Actually Acrobat Reader's line style dialog does not allow to choose a dashed and a cloudy style at the same time.

  • Field Details

    • ANGLE_180_DEG

      private static final double ANGLE_180_DEG
      See Also:
    • ANGLE_90_DEG

      private static final double ANGLE_90_DEG
      See Also:
    • ANGLE_34_DEG

      private static final double ANGLE_34_DEG
    • ANGLE_30_DEG

      private static final double ANGLE_30_DEG
    • ANGLE_12_DEG

      private static final double ANGLE_12_DEG
    • output

      private final PDAppearanceContentStream output
    • annotRect

      private final PDRectangle annotRect
    • intensity

      private final double intensity
    • lineWidth

      private final double lineWidth
    • rectWithDiff

      private PDRectangle rectWithDiff
    • outputStarted

      private boolean outputStarted
    • bboxMinX

      private double bboxMinX
    • bboxMinY

      private double bboxMinY
    • bboxMaxX

      private double bboxMaxX
    • bboxMaxY

      private double bboxMaxY
  • Constructor Details

    • CloudyBorder

      CloudyBorder(PDAppearanceContentStream stream, double intensity, double lineWidth, PDRectangle rect)
      Creates a new CloudyBorder that writes to the specified content stream.
      Parameters:
      stream - content stream
      intensity - intensity of cloudy effect (entry I); typically 1.0 or 2.0
      lineWidth - line width for annotation border (entry W)
      rect - annotation rectangle (entry Rect)
  • Method Details

    • createCloudyRectangle

      void createCloudyRectangle(PDRectangle rd) throws IOException
      Creates a cloudy border for a rectangular annotation. The rectangle is specified by the RD entry and the Rect entry that was passed in to the constructor.

      This can be used for Square and FreeText annotations. However, this does not produce the text and the callout line for FreeTexts.

      Parameters:
      rd - entry RD, or null if the entry does not exist
      Throws:
      IOException - If there is an error writing to the stream.
    • createCloudyPolygon

      void createCloudyPolygon(float[][] path) throws IOException
      Creates a cloudy border for a Polygon annotation.
      Parameters:
      path - polygon path
      Throws:
      IOException - If there is an error writing to the stream.
    • createCloudyEllipse

      void createCloudyEllipse(PDRectangle rd) throws IOException
      Creates a cloudy border for a Circle annotation. The ellipse is specified by the RD entry and the Rect entry that was passed in to the constructor.
      Parameters:
      rd - entry RD, or null if the entry does not exist
      Throws:
      IOException - If there is an error writing to the stream.
    • getBBox

      PDRectangle getBBox()
      Returns the BBox entry (bounding box) for the appearance stream form XObject.
      Returns:
      Bounding box for appearance stream form XObject.
    • getRectangle

      PDRectangle getRectangle()
      Returns the updated Rect entry for the annotation. The rectangle completely contains the cloudy border.
      Returns:
      Annotation Rect.
    • getMatrix

      AffineTransform getMatrix()
      Returns the Matrix entry for the appearance stream form XObject.
      Returns:
      Matrix for appearance stream form XObject.
    • getRectDifference

      PDRectangle getRectDifference()
      Returns the updated RD entry for Square and Circle annotations.
      Returns:
      Annotation RD value.
    • cosine

      private static double cosine(double dx, double hypot)
    • sine

      private static double sine(double dy, double hypot)
    • cloudyRectangleImpl

      private void cloudyRectangleImpl(double left, double bottom, double right, double top, boolean isEllipse) throws IOException
      Cloudy rectangle implementation is based on converting the rectangle to a polygon.
      Throws:
      IOException
    • cloudyPolygonImpl

      private void cloudyPolygonImpl(Point2D.Double[] vertices, boolean isEllipse) throws IOException
      Cloudy polygon implementation.
      Parameters:
      vertices - polygon vertices; first and last point must be equal
      isEllipse - specifies if the polygon represents an ellipse
      Throws:
      IOException
    • computeParamsPolygon

      private int computeParamsPolygon(double advInterm, double advCorner, double k, double r, double length, double[] array)
      Computes parameters for a cloudy polygon: n, alpha, and dx.
    • addCornerCurl

      private void addCornerCurl(double anglePrev, double angleCur, double radius, double cx, double cy, double alpha, double alphaPrev, boolean addMoveTo) throws IOException
      Creates a corner curl for polygons and ellipses.
      Throws:
      IOException
    • addFirstIntermediateCurl

      private void addFirstIntermediateCurl(double angleCur, double r, double alpha, double cx, double cy) throws IOException
      Generates the first intermediate curl for a cloudy polygon.
      Throws:
      IOException
    • getIntermediateCurlTemplate

      private Point2D.Double[] getIntermediateCurlTemplate(double angleCur, double r) throws IOException
      Returns a template for intermediate curls in a cloudy polygon.
      Throws:
      IOException
    • outputCurlTemplate

      private void outputCurlTemplate(Point2D.Double[] template, double x, double y) throws IOException
      Writes the curl template points to the output and applies translation (x, y).
      Throws:
      IOException
    • applyRectDiff

      private PDRectangle applyRectDiff(PDRectangle rd, double min)
    • reversePolygon

      private void reversePolygon(Point2D.Double[] points)
    • getPositivePolygon

      private void getPositivePolygon(Point2D.Double[] points)
      Makes a polygon whose direction is the same as the positive angle direction in the coordinate system. The polygon must not intersect itself.
    • getPolygonDirection

      private double getPolygonDirection(Point2D.Double[] points)
      Returns the direction of the specified polygon. A positive value indicates that the polygon's direction is the same as the direction of positive angles in the coordinate system. A negative value indicates the opposite direction. The polygon must not intersect itself. A 2-point polygon is not acceptable. This is based on the "shoelace formula".
    • getArc

      private void getArc(double startAng, double endAng, double rx, double ry, double cx, double cy, ArrayList<Point2D.Double> out, boolean addMoveTo) throws IOException
      Creates one or more Bézier curves that represent an elliptical arc. Angles are in radians. The arc will always proceed in the positive angle direction. If the argument `out` is null, this writes the results to the instance variable `output`.
      Throws:
      IOException
    • getArcSegment

      private void getArcSegment(double startAng, double endAng, double cx, double cy, double rx, double ry, ArrayList<Point2D.Double> out, boolean addMoveTo) throws IOException
      Creates a single Bézier curve that represents a section of an elliptical arc. The sweep angle of the section must not be larger than 90 degrees. If argument `out` is null, this writes the results to the instance variable `output`.
      Throws:
      IOException
    • flattenEllipse

      private static Point2D.Double[] flattenEllipse(double left, double bottom, double right, double top)
      Flattens an ellipse into a polygon.
    • cloudyEllipseImpl

      private void cloudyEllipseImpl(double leftOrig, double bottomOrig, double rightOrig, double topOrig) throws IOException
      Cloudy ellipse implementation.
      Throws:
      IOException
    • computeParamsEllipse

      private double computeParamsEllipse(Point2D.Double pt, Point2D.Double ptNext, double r, double curlAdv)
      Computes the alpha parameter for an ellipse curl.
    • removeZeroLengthSegments

      private Point2D.Double[] removeZeroLengthSegments(Point2D.Double[] polygon)
    • drawBasicEllipse

      private void drawBasicEllipse(double left, double bottom, double right, double top) throws IOException
      Draws an ellipse without a cloudy border effect.
      Throws:
      IOException
    • beginOutput

      private void beginOutput(double x, double y) throws IOException
      Throws:
      IOException
    • updateBBox

      private void updateBBox(double x, double y)
    • moveTo

      private void moveTo(Point2D.Double p) throws IOException
      Throws:
      IOException
    • moveTo

      private void moveTo(double x, double y) throws IOException
      Throws:
      IOException
    • lineTo

      private void lineTo(Point2D.Double p) throws IOException
      Throws:
      IOException
    • lineTo

      private void lineTo(double x, double y) throws IOException
      Throws:
      IOException
    • curveTo

      private void curveTo(double ax, double ay, double bx, double by, double cx, double cy) throws IOException
      Throws:
      IOException
    • finish

      private void finish() throws IOException
      Throws:
      IOException
    • getEllipseCloudRadius

      private double getEllipseCloudRadius()
    • getPolygonCloudRadius

      private double getPolygonCloudRadius()