OK, I see you are looking for a common handle for all classes to simplify your code.

I don't like to introduce an interface just to provide such a handle.

IMHO there is an easier solution. We can make the class PDAbstractContentStream public, so that you can use it as superclass. As long as the construction remains package private it is impossible to extend that class outside the package. As the class is still abstract, it is impossible as well to create an instance of the class itself.

That change should be a non breaking change.

Or did I miss something?


Am 04.03.25 um 09:08 schrieb Mark de Does:
With PDFBox 2, It was possible to construct a PDPageContentStream that issues (drawing) instructions to one of the following:

  * A PDPage (root <svg> in SVG terms)
  * A PDAppearanceStream (<symbol> in SVG terms)
  * A PDTilingPatten (<pattern> in SVG terms)

In PDFBox 3, it is no longer possible to construct a PDPageContentStream that issues (drawing) instructions to a PDTilingPattern. Which would mean I can no longer use the same code to convert different pieces from an SVG input to PDF through PDFBox. (With 60+ instruction primitives, circumventing the limitation with a wrapper class would be tedious.)

Now, the three content stream classes that draw on PDPage,PDAppearanceStream,PDTilingPattern all inherit from PDAbstractContentStream. But PDAbstractContentStream is a package local class. Probably to prevent people from subclassing it. (Do not worry Andreas, I am not mad, I do not want to subclass PDAbstractContentStream). Luckily, in PDAbstractContentStream, the 60+ methods to issue (drawing) instructions to the stream are public.

Without making PDAbstractContentStream a public class, the methods to issue (drawing) instructions to a content stream can be captured in a public interface. Consuming code, like mine, can be written in terms of the interface. The nice thing about this is that the actual implementations are unchanged. That means that you open extra possibilities while maintaining full binary compatibility.

So let me give an example. Suppose I want to draw a diagonal line on a page and on a pattern. I might do the following:

PDPageContentStream pgContentStream=new PDPageContentStream(document,page,PDPageContentStream.AppendMode.APPEND,true,true );
pgContentStream.moveTo( 0f, 0f);
pgContentStream.lineTo( 1f, 1f);

PDPatternContentStreamptContentStream=new PDPatternContentStream(tilingPattern );
ptContentStream.moveTo( 0f, 0f);
ptContentStream.lineTo( 1f, 1f);

Now with the interface, I can use the same code to draw on the page and on the pattern. E.G.

private void drawDiagonal(PDContentOutputStream outStream ) { outStream.moveTo( 0f, 0f);
outStrean.lineTo( 1f, 1f);
}

PDPageContentStream pgContentStream=new PDPageContentStream(document,page,PDPageContentStream.AppendMode.APPEND,true,true );
drawDiagonal( pgContentStream);

PDPatternContentStreamptContentStream=new PDPatternContentStream(tilingPattern );
drawDiagonal( ptContentStream);

With code that is more elaborate than drawing a simple diagonal, that is quite an advantage.



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@pdfbox.apache.org
For additional commands, e-mail: users-h...@pdfbox.apache.org

Reply via email to