0

I already can add line using contentStream with methods:

setLineWidth(h) - set line thickness

setLineDashPattern(pattern, period) - pattern create needed space and dots e.g new float[]{0.075,2}

setLineCapStyle(2) - set all dots as rectangle

moveTo(x,y) - set start point

lineTo(x,y) - set end point

stroke() - print line

but now for me need create a gradient from center of dot to edge of dot

Could anybody give me advice how to add gradient?

Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
dmmax
  • 63
  • 6
  • Sounds like a single radial shading. Please have a look at the CreateGradientShadingPDF.java example in the source code. – Tilman Hausherr Mar 06 '19 at 20:16
  • @TilmanHausherr thank you for answer. I tried it but I'm not sure that this approach will help. I upload example code on git: https://github.com/dmmax/pdfbox-dotted-pattern So..you can see my current dot pattern (implement in method 'printDottedPattern') In resource folder exists image small_dot. I should to create same dot using PDFBox – dmmax Mar 07 '19 at 05:39

1 Answers1

2

This is based on the CreateGradientShadingPDF.java example in the source code. The two circles have an identical position but the second one is empty. In the function, c0 is white and c1 is black.

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);

// type 2 (exponential) function with attributes
COSDictionary fdict = new COSDictionary();
fdict.setInt(COSName.FUNCTION_TYPE, 2);
COSArray domain = new COSArray();
domain.add(COSInteger.get(0));
domain.add(COSInteger.get(1));
COSArray c0 = new COSArray();
c0.add(COSFloat.get("1"));
c0.add(COSFloat.get("1"));
c0.add(COSFloat.get("1"));
COSArray c1 = new COSArray();
c1.add(COSFloat.get("0"));
c1.add(COSFloat.get("0"));
c1.add(COSFloat.get("0"));
fdict.setItem(COSName.DOMAIN, domain);
fdict.setItem(COSName.C0, c0);
fdict.setItem(COSName.C1, c1);
fdict.setInt(COSName.N, 1);
PDFunctionType2 func = new PDFunctionType2(fdict);

// radial shading with attributes
PDShadingType3 radialShading = new PDShadingType3(new COSDictionary());
radialShading.setColorSpace(PDDeviceRGB.INSTANCE);
radialShading.setShadingType(PDShading.SHADING_TYPE3);
COSArray coords2 = new COSArray();
coords2.add(COSInteger.get(100));
coords2.add(COSInteger.get(400));
coords2.add(COSInteger.get(50)); // radius1
coords2.add(COSInteger.get(100));
coords2.add(COSInteger.get(400));
coords2.add(COSInteger.get(0)); // radius2
radialShading.setCoords(coords2);
radialShading.setFunction(func);

// invoke shading from content stream
// compress parameter is set to false so that you can see the stream in a text editor
try (PDPageContentStream contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, false))
{
    contentStream.shadingFill(radialShading);
}

More background on radial shading can be found in the PDF 32000 specification.

Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
  • Thank you! Yes, this approach is work fine but when I use it, size of file will too large. In repository I added implementation: github.com/dmmax/pdfbox-dotted-pattern Do you know another options how to add gradient dots? – dmmax Mar 07 '19 at 13:20
  • No, that's the way it is done, see the PDF specification. You can reuse the shading object and do a transform if you want to have several dots. I haven't tested your code and you haven't shared the result PDF so I don't know what you mean with "too large". – Tilman Hausherr Mar 07 '19 at 18:04
  • Too large is size of file about 1.4 mb for 5 dotted pattern. One dotted pattern is square (400x15). You can see implementation result in pdf (https://github.com/dmmax/pdfbox-dotted-pattern/blob/master/print.pdf). If I implement dotted pattern for 20 times then size of file will be more than 6 mb. – dmmax Mar 08 '19 at 04:26
  • You did the thing I wanted you to avoid. You have 8800 different shadings. Instead of reusing the one and doing a `transform()` in your page content stream. – Tilman Hausherr Mar 08 '19 at 06:22
  • 2
    A more advanced solution would be to create a pattern, and in this pattern have the shading. Then use this pattern "color" to create a shape that looks like a line. That of course requires some fine tuning. See the CreatePatternsPDF example in the source code download. – Tilman Hausherr Mar 08 '19 at 06:30
  • Sorry for the long answer, was in vacation. Thank you, I checked your solution and it works fine! – dmmax Mar 30 '19 at 04:50