I work with PDFBox now, and I'm trying to draw a polygon with a big border stroke using the fillAndStroke() method in PDPageContentStream. Actually it works with a stroke in center mode (half inside and half outside the polygon).
How can I specify the stroke type inside or outside the polygon like I can do in JavaFX with this kind of code.
Thank you for your help.
// Create a polygon
Polygon polygon = new Polygon();
polygon.getPoints().addAll(
50.0, 150.0, // Point 1 (x, y)
150.0, 50.0, // Point 2 (x, y)
250.0, 150.0, // Point 3 (x, y)
150.0, 250.0 // Point 4 (x, y)
);
polygon.setFill(Color.LIGHTBLUE);
polygon.setStroke(Color.BLACK);
polygon.setStrokeWidth(3);
// Here we specify the stroke type to inside
polygon.setStrokeType(StrokeType.INSIDE);
I search help in documentation without success, currently I use the PDFBox version: 2.0.25.
The methods the PDFBox class PDPageContentStream
offers correspond to the operations defined by the PDF standard for content streams. Consequentially, the docs you are looking for are the ISO 32000 parts.
Unfortunately, you'll find there that PDF does not have anything like the StrokeType
options of JavaFX. Nonetheless, you can emulate the effect using clip paths, e.g. as follows:
This is the mode PDF always uses. Thus, no clip paths are necessary:
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.closeAndFillAndStroke();
(DrawPolygons method drawPolygonCenterStroke
)
To emulate this we set a clip path along the polygon border.
canvas.saveGraphicsState();
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.closePath();
canvas.clip();
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.closeAndFillAndStroke();
canvas.restoreGraphicsState();
(DrawPolygons method drawPolygonInsideStroke
)
To emulate this we first fill the inside of the full polygon, then set the clip path to include the rest of the page except the polygon, and finally stroke the polygon border.
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.fill();
canvas.saveGraphicsState();
canvas.addRect(0, 0, 300, 300);
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.closePath();
canvas.clipEvenOdd();
canvas.moveTo(50, 150);
canvas.lineTo(150, 50);
canvas.lineTo(250, 150);
canvas.lineTo(150, 250);
canvas.closeAndStroke();
canvas.restoreGraphicsState();
(DrawPolygons method drawPolygonOutsideStroke
)
Obviously in the inside and outside cases half the stroke line is cut off. Thus, to achieve a certain stroke width, you have to set the line width to twice that value.