Tilman,

It turns out to be a trivial piece of code to get patterns to render properly 
when generating SVG.  I had to add a class, 'eqSVGGraphics' to superclass the 
SVGGraphics2D module, and then override the fill(Shape s) method.

I've attached my eqSVGGraphics.java module to show you what I did.

However, to do this, I needed to have the PDFBox TilingPaint module be public, 
and be able to access the 'paint' attribute of that class.

I've modified and locally built a download of PDFBox 3.0.2 source for this.  
How do I get that mod back into PDFBox?

I'll try your test case with the gradient as well.

Rich Stafford
Chief Scientist
eQuorum Corporation
***
Tilman,

The TIlingPaint object has attributes of a TexturePaint and a PatternMatrix.  

In my case, the TexturePaint has a BufferedImage, and four attributes: sx, sy 
(values 0.2439,0.2439) and tx, ty (values 0.0,0.0).

The PatternMatrix is just an identity matrix.

I can get the Rectangle2D for the shape to be painted.

 From all of that, what would be the coordinate increments to draw the image 
across the shape?

Is there an example in the PDFBox code that draws a pattern when outputting to 
renderImageWithDpi()?

Rich
***
Tilman,

Yes, this is the same project from last year.  I suspended it in the interim 
for other priorities.

It's still a goal for us, SVG is a much better, scalable representation of many 
PDF documents.  We are getting really close to having it be a good solution.

I'm going to experiment with doing the pattern across the range block of the 
shape.  Hopefully that will handle this issue.

Rich

At 08:03 AM 6/24/2024, Tilman Hausherr wrote:
>Hi,
>
>TexturePaint is used for patterns, i.e. rectangles that repeat itself. 
>GetImage() returns a single pattern image. You can test this by saving that 
>BufferedImage with ImageIO.write() and look what's in it.
>
>About your problem: the cause is either a bug in Batik, or a missing 
>implementation there, or that it's impossible (does SVG have a concept about 
>patterns?), or the cause is an old bug in renderPageToGraphics(), that it 
>fails when there is some sort of transformation. I don't remember what ticket 
>number it is, but it's many years old, and we haven't been able to fix it.
>
>Tilman
>
>On 24.06.2024 13:39, Rich Stafford wrote:
>>I am still working on getting the hatched object in a PDF to render when 
>>generating SVG, using the SVGGraphics2D output, called from the PDFBox 
>>PDFRenderer.renderPageToGraphics() method.
>>
>>I have subclassed SVGGraphics2D class, specifically the fill(Shape s) method. 
>> For my PDF hatch data, this method is being called with a PDFBox TilingPaint 
>>object.  This class is 'private', but for testing, I've modified it to 
>>'public' to be able to access from my module.
>>
>>The TilingPaint object has an AWT 'Paint' member, which is an AWT 
>>'TexturePaint' object.  I am able to use it's 'getImage()' method to access a 
>>BufferedImage object.
>>
>>My question is, what is contained in that BufferedImage object?  Does it 
>>contain the same rendered view of the hatched PDF data as I can see when I 
>>generate a full raster view using PDFRenderer.renderImageWithDPI() method?
>>
>>Rich
>>***
>>At 02:01 AM 6/18/2024, Andreas Lehmkühler wrote:
>>>Hi,
>>>
>>>Am 18.06.24 um 01:10 schrieb Rich Stafford:
>>>>I have a simplified PDF case that renders (using PDFBox) differently 
>>>>between JPG and SVG output modes.
>>>PDFBox doesn't have a SVG output mode. I guess you are using some code/tool 
>>>from the Apache XMLGraphics project so that you might ask them for help.
>>>
>>>https://xmlgraphics.apache.org/
>>>
>>>Andreas
>>>
>>>>This PDF has a simple line element, and a lime colored rectangle that is 
>>>>filled with some lime color horizontal lines and shows the black line 
>>>>behind it.
>>>>When rendering to JPG, it matches the input PDF.
>>>>When rendered to SVG, the rectangle is filled with opaque black.
>>>>I am using PDFBox 3.0.2, and Batik 1.17.
>>>>The following link is to an open share of a file 't2.zip.  In this zip is:
>>>>   t2.pdf       the PDF being rendered
>>>>   t2.jpg               the rendered JPG file
>>>>   t2.svg       the rendered SVG file
>>>>https://drive.google.com/file/d/1qbuM6O-yNdbr8Ip32q6jp0Z9demfSZBe/view?usp=sharing
>>>>Any help or advice would be appreciated!
>>>>Rich Stafford
>>>>Chief Scientist
>>>>eQuorum Corporation
>>>>
>>>>---------------------------------------------------------------------
>>>>To unsubscribe, e-mail:users-unsubscr...@pdfbox.apache.org
>>>>For additional commands, e-mail:users-h...@pdfbox.apache.org
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail:users-unsubscr...@pdfbox.apache.org
>>>For additional commands, e-mail:users-h...@pdfbox.apache.org
/**
 *  eqSVGGraphics2D.java - Module to extend SVGGraphcs2D to handle fill using 
raster based patterns coming from PdfBox
 *
 *  
 * history:
 *       03-23 Jan 2023 ras - I20220623, initial entry
 *       03-24 Jun 2024 ras - I20240170, mod for TexturePaint handling
 *  
 * Copyright 2023-2024, eQuorum Corporation 
 */
package com.ims.utils;

import java.awt.Paint;
import java.awt.Shape;
import java.awt.TexturePaint;

import org.apache.batik.svggen.DOMGroupManager;
import org.apache.batik.svggen.SVGGeneratorContext;
import org.apache.batik.svggen.SVGGraphics2D;
import org.w3c.dom.Element;
import org.apache.pdfbox.rendering.*;
public class eqSVGGraphics2D extends SVGGraphics2D
{
    public eqSVGGraphics2D(SVGGeneratorContext generatorCtx,
                        boolean textAsShapes)
        {
                super(generatorCtx, textAsShapes);
        }

    /**
     * Method to fill a shape with either a solid fill, or a raster pattern
     * 
     */
    @Override
    public void fill(Shape s) 
    {
        // see if there is an image or texture associated with the shape
                Paint oPaint = this.gc.getPaint();
                if ( oPaint instanceof TexturePaint )
                {       // yes, coming from PDFBox, or some such pattern handler
                        // get the Image data and draw it
                        TexturePaint oTexture = (TexturePaint) oPaint;
                        this.setPaint( oTexture );
                }
                else
                if ( oPaint instanceof TilingPaint )
                {       // is an instance of PDFBox TilingPaint, get the 
texture component
                        // and set it as the current paint method
                        TilingPaint      oTiling  = (TilingPaint) oPaint;
                        TexturePaint oTexture = (TexturePaint) oTiling.paint;
                        this.setPaint( oTexture );
                }

                // draw the shape component
        Element svgShape = shapeConverter.toSVG(s);
        if (svgShape != null ) 
        {       // and then fill the shape
            domGroupManager.addElement(svgShape, DOMGroupManager.FILL);
        }
    }
}

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

Reply via email to