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.
--
Mark de Does, Magdalenastraat 6, 3512 NH Utrecht, the Netherlands,
http://maps.google.nl/?q=52.08692,5.1271,
e:m...@mdedoes.xs4all.nl t: 030 2314150
On 04-03-2025 08:13, Andreas Lehmkühler wrote:
Hi,
I don't understand your issue.
AFAIKT there is no api using a PDPageContentStream as parameter, so
that you shouldn't be bound to use any of our classes. Your proposal
to introduce an interface indicates that you are reimplementing the
whole class. Why is a change on our side necessary?
Maybe it is just me, but I didn't get your point. Can you give as some
sample code how you are using that content stream of yours?
Andreas
Am 28.02.25 um 14:22 schrieb Mark de Does:
In one of my projects, I convert (a subset of) SVG to PDF, using PdfBox.
In SVG, the contents of the main <svg> element, the <marker>,
<symbol> and <pattern> definitions have the same syntax and
structure. With PdfBox 2, I use a PDPageContentStream to record the
content of all three. With PdfBox 3, that no longer works because I
must use a PDPatternContentStream to record a pattern. Because the
different kinds of content stream do not share a visible (public)
ancestor, I cannot use the same code to record SVG content to a
content stream.
This morning, I captured the public methods of
PDAbstractContentStream in an interface and declared
PDAbstractContentStream to implement that interface. I adapted my
code to use the interface and everything works fine. (As expected).
Before I make a PR, I need some guidance.
* Do you think introducing an interface is overkill? Simply making
PDAbstractContentStream public would achieve the same thing for me.
(The class, not the constructor)
* I chose the name PDContentStream for the interface. Later on, I
discovered that is an infortunate name: A different interface with
that name already exists. What would be a better name?
* I moved the JavaDoc comments from the abstract class to the
interface. You agree? Or shall I also leave them in place?
* On which branch must I base my PR? (I see that the trunk already has
a 4.0 version number)
Thanks and Greetings.. Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@pdfbox.apache.org
For additional commands, e-mail: users-h...@pdfbox.apache.org