You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by Tim Heuer <He...@landcareresearch.co.nz> on 2011/02/11 00:17:06 UTC

Units in SVG - PDF

Hi List,

I came across a problem with the SVG rendering onto a PDF:

The units seem to be wrong or I am doing a mistake.

When I let Batik parse my SVG image:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="126pt" height="25pt" viewBox="0 0 126 25" version="1.1">
<g id="surface2">
<rect x="0" y="0" width="126" height="25" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(81.176471%,85.098039%,69.411765%);fill-opacity:1;" d="M 5.5 5.5 L 34.5 5.5 L 34.5 19.5 L 5.5 19.5 Z M 5.5 5.5 "/>
...
</g>
</svg>


My Java code is as follows:

                        PdfContentByte dc = context.getDirectContent();
                        URI uri = URI.create(iconItem);
                        URL url = uri.toURL();
                        SVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
                              UserAgent userAgent = new UserAgentAdapter();
                            DocumentLoader loader = new DocumentLoader(userAgent);
                            BridgeContext ctx = new BridgeContext(userAgent, loader);
                          ctx.setDynamicState(BridgeContext.DYNAMIC);
                          SVGDocument svgDoc = factory.createSVGDocument(null, url.openStream());
                          GVTBuilder builder = new GVTBuilder();
                          GraphicsNode graphics = builder.build(ctx, svgDoc);
                              String svgWidthString = svgDoc.getDocumentElement().getAttribute("width");
                              String svgHeightString = svgDoc.getDocumentElement().getAttribute("height");
                              float svgWidth = Float.valueOf(svgWidthString.substring(0, svgWidthString.length() - 2));
                              float svgHeight = Float.valueOf(svgHeightString.substring(0, svgHeightString.length() - 2));
                        PdfTemplate map = dc.createTemplate(svgWidth*1.25f, svgHeight*1.25f);
                              //PdfTemplate map = dc.createTemplate(svgWidth, svgHeight);
                        Graphics2D g2d = map.createGraphics(svgWidth*1.25f, svgHeight*1.25f);
                        graphics.paint(g2d);
                        g2d.dispose();
                        System.out.println("w="+ svgWidth +" h="+ svgHeight +" maxW="+ maxIconWidth +" maxH="+ maxIconHeight);
                        //...
                        Image image = Image.getInstance(map);
PdfPCell cell = new PdfPCell(...);
cell.add(image);

I looked up the SVG specifications and found that pt is 1.25 pixels. However, this renders wrongly on the PDF. The image becomes too big and is cut off. When I enter 1.5f instead of 1.25f above, it seems more correct but still a bit out.

I don't want to hack together a number that will just happen to look right, because it is the wrong approach. Is there some kind of trickiness with the units between SVG and PDF (using iText)?

Help is much appreciated. I am working on the legends' rendering in SVG in the MapFish print module and will submit the source back to the project, so I think they would appreciate your input too.

Kind regards,
Tim

________________________________
Please consider the environment before printing this email
Warning: This electronic message together with any attachments is confidential. If you receive it in error: (i) you must not read, use, disclose, copy or retain it; (ii) please contact the sender immediately by reply email and then delete the emails.
The views expressed in this email may not be those of Landcare Research New Zealand Limited. http://www.landcareresearch.co.nz

Re: Units in SVG - PDF

Posted by Chris Lilley <ch...@w3.org>.
On Saturday, February 12, 2011, 2:08:38 AM, jonathan wrote:

jw> H Chris & Tim.

jw>   I think that the confusion comes from an example in the spec,
jw> section 7.10 Units.  Without context, the reader might pick out the 1pt == 1.25px...

Thanks for the helpful pointer. I agree that this example could be taken as a general statement, and I will make sure it is reworded to clarify that this is one particular example.

jw> my 2 cents

jw> --- clip
jw>   
jw> The other absolute unit identifiers from CSS (i.e., pt,        
jw> pc, cm, mm, in) are all defined as an appropriate multiple        
jw> of one px unit (which, according to the previous         item, is
jw> defined to be equal to one user unit), based on         what the
jw> SVG user agent determines is the size of a px unit (possibly
jw> passed from the parent processor         or environment at
jw> initialization time). For example,         suppose that the user
jw> agent can determine from its         environment that "1px"
jw> corresponds to "0.2822222mm" (i.e.,         90dpi). 

This sentence in particular could mislead:

jw> Then, for all processing of SVG content:
 



-- 
 Chris Lilley   Technical Director, Interaction Domain                 
 W3C Graphics Activity Lead, Fonts Activity Lead
 Co-Chair, W3C Hypertext CG
 Member, CSS, WebFonts, SVG Working Groups


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


Re: Units in SVG - PDF

Posted by jonathan wood <jo...@gmail.com>.
H Chris & Tim.

  I think that the confusion comes from an example in the spec, section 7.10
Units.  Without context, the reader might pick out the 1pt == 1.25px...

my 2 cents

--- clip

   -

   The other absolute unit identifiers from CSS (i.e., pt, pc, cm, mm, in)
   are all defined as an appropriate multiple of one *px* unit (which,
   according to the previous item, is defined to be equal to one user unit),
   based on what the SVG user agent determines is the size of a *px* unit
   (possibly passed from the parent processor or environment at initialization
   time). For example, suppose that the user agent can determine from its
   environment that "1px" corresponds to "0.2822222mm" (i.e., 90dpi). Then, for
   all processing of SVG content:
   - "1pt" equals "1.25px" (and therefore 1.25 user units)
      - "1pc" equals "15px" (and therefore 15 user units)
      - "1mm" would be "3.543307px" (3.543307 user units)
      - "1cm" equals "35.43307px" (and therefore 35.43307 user units)
      - "1in" equals "90px" (and therefore 90 user units)

-- clip

On Fri, Feb 11, 2011 at 1:18 PM, Chris Lilley <ch...@w3.org> wrote:

> On Friday, February 11, 2011, 12:17:06 AM, Tim wrote:
>
> TH> I looked up the SVG specifications and found that pt is 1.25
> TH> pixels. However, this renders wrongly on the PDF. The image
> TH> becomes too big and is cut off. When I enter 1.5f instead of 1.25f
> TH> above, it seems more correct  but still a bit out.
>
> Tim, could you give me a pointer to exactly where you read that definition?
>
>
> --
>  Chris Lilley   Technical Director, Interaction Domain
>  W3C Graphics Activity Lead, Fonts Activity Lead
>  Co-Chair, W3C Hypertext CG
>  Member, CSS, WebFonts, SVG Working Groups
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
>
>

Re: Units in SVG - PDF

Posted by Chris Lilley <ch...@w3.org>.
On Friday, February 11, 2011, 12:17:06 AM, Tim wrote:
 
TH> I looked up the SVG specifications and found that pt is 1.25
TH> pixels. However, this renders wrongly on the PDF. The image
TH> becomes too big and is cut off. When I enter 1.5f instead of 1.25f
TH> above, it seems more correct  but still a bit out.

Tim, could you give me a pointer to exactly where you read that definition?
 

-- 
 Chris Lilley   Technical Director, Interaction Domain                 
 W3C Graphics Activity Lead, Fonts Activity Lead
 Co-Chair, W3C Hypertext CG
 Member, CSS, WebFonts, SVG Working Groups


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


RE: Units in SVG - PDF

Posted by Tim Heuer <He...@landcareresearch.co.nz>.
Hi Thomas, Jeremias, Jonathan and Chris,

First of all, thanks for all the support!

See comments below.

From: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
Sent: Sunday, 13 February 2011 10:28 a.m.
To: batik-users@xmlgraphics.apache.org
Cc: batik-users@xmlgraphics.apache.org
Subject: Re: Units in SVG - PDF

Hi Tim,

Tim Heuer <He...@landcareresearch.co.nz> wrote on 02/10/2011 06:17:06 PM:

> The units seem to be wrong or I am doing a mistake.
[...]

>                               UserAgent userAgent = new UserAgentAdapter();

        Since the correct relationship between 'px' and real world units
is dependent on the rendering context the UserAgent has a method that
allows you do specify this relationship, this is the default in the
UserAgentAdapter we provide.

    /**
     * Returns the size of a px CSS unit in millimeters.
     */
    public float getPixelUnitToMillimeter() {
        return 0.26458333333333333333333333333333f; // 96dpi
    }

This seems to do the trick! However, I found that this works as well and seems slightly cleaner to me:

float svgFactor = (float) Toolkit.getDefaultToolkit().getScreenResolution() / 72f; // Might need to get 72 from somewhere else?

> I looked up the SVG specifications and found that pt is 1.25 pixels.
> However, this renders wrongly on the PDF. The image becomes too big
> and is cut off. When I enter 1.5f instead of 1.25f above, it seems
> more correct but still a bit out.

        So given that we use the above figure 1.333 would be correct.
But I suggest you use the above method to work out the relationship
between pt and px.

> I don’t want to hack together a number that will just happen to look
> right, because it is the wrong approach. Is there some kind of
> trickiness with the units between SVG and PDF (using iText)?

        I'll just second Jeremias' suggestion that FOP/Batik already
includes a PDF renderer that has code so it generates better output
from Batik (as mentioned "simple: SVG text will stay text in the output
and Gradients generally do not get rasterized).

> Help is much appreciated. I am working on the legends’ rendering in
> SVG in the MapFish print module and will submit the source back to
> the project, so I think they would appreciate your input too.

        Hope that helps.

Thomas DeWeese | CDG Advanced Development |
Eastman Kodak Company | 343 State Street | Rochester, NY 14650-0128 |
Thomas.DeWeese@Kodak.com<ma...@Kodak.com> | 585 724-0294 |
www.kodak.com<http://www.kodak.com/>

________________________________
Please consider the environment before printing this email
Warning: This electronic message together with any attachments is confidential. If you receive it in error: (i) you must not read, use, disclose, copy or retain it; (ii) please contact the sender immediately by reply email and then delete the emails.
The views expressed in this email may not be those of Landcare Research New Zealand Limited. http://www.landcareresearch.co.nz

Re: Units in SVG - PDF

Posted by th...@kodak.com.
Hi Tim,

Tim Heuer <He...@landcareresearch.co.nz> wrote on 02/10/2011 06:17:06 PM:

> The units seem to be wrong or I am doing a mistake.
[...]

>                               UserAgent userAgent = new 
UserAgentAdapter();

        Since the correct relationship between 'px' and real world units
is dependent on the rendering context the UserAgent has a method that
allows you do specify this relationship, this is the default in the
UserAgentAdapter we provide.

    /**
     * Returns the size of a px CSS unit in millimeters.
     */
    public float getPixelUnitToMillimeter() {
        return 0.26458333333333333333333333333333f; // 96dpi
    }

> I looked up the SVG specifications and found that pt is 1.25 pixels.
> However, this renders wrongly on the PDF. The image becomes too big 
> and is cut off. When I enter 1.5f instead of 1.25f above, it seems 
> more correct but still a bit out.

        So given that we use the above figure 1.333 would be correct.
But I suggest you use the above method to work out the relationship
between pt and px.

> I don’t want to hack together a number that will just happen to look
> right, because it is the wrong approach. Is there some kind of 
> trickiness with the units between SVG and PDF (using iText)?

        I'll just second Jeremias' suggestion that FOP/Batik already 
includes a PDF renderer that has code so it generates better output
from Batik (as mentioned "simple: SVG text will stay text in the output
and Gradients generally do not get rasterized).

> Help is much appreciated. I am working on the legends’ rendering in 
> SVG in the MapFish print module and will submit the source back to 
> the project, so I think they would appreciate your input too.

        Hope that helps.
Thomas DeWeese | CDG Advanced Development | 
Eastman Kodak Company | 343 State Street | Rochester, NY 14650-0128 | 
Thomas.DeWeese@Kodak.com | 585 724-0294 | 
www.kodak.com 


Re: Units in SVG - PDF

Posted by Jeremias Maerki <de...@jeremias-maerki.ch>.
Tim, you might want to test the PDF transcoder that is bundled with
Apache Batik. Or to get the latest version of the PDF transcoder, just
put the latest Apache FOP in the classpath instead of pdf-transcoder.jar.
That has the benefit that you don't have to care much about the scaling
problem and you get text as text (and not text converted to shapes) and
nice-looking gradients among other things.

On 11.02.2011 00:17:06 Tim Heuer wrote:
> Hi List,
> 
> I came across a problem with the SVG rendering onto a PDF:
> 
> The units seem to be wrong or I am doing a mistake.
> 
> When I let Batik parse my SVG image:
> <?xml version="1.0" encoding="UTF-8"?>
> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="126pt" height="25pt" viewBox="0 0 126 25" version="1.1">
> <g id="surface2">
> <rect x="0" y="0" width="126" height="25" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
> <path style=" stroke:none;fill-rule:evenodd;fill:rgb(81.176471%,85.098039%,69.411765%);fill-opacity:1;" d="M 5.5 5.5 L 34.5 5.5 L 34.5 19.5 L 5.5 19.5 Z M 5.5 5.5 "/>
> ...
> </g>
> </svg>
> 
> 
> My Java code is as follows:
> 
>                         PdfContentByte dc = context.getDirectContent();
>                         URI uri = URI.create(iconItem);
>                         URL url = uri.toURL();
>                         SVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
>                               UserAgent userAgent = new UserAgentAdapter();
>                             DocumentLoader loader = new DocumentLoader(userAgent);
>                             BridgeContext ctx = new BridgeContext(userAgent, loader);
>                           ctx.setDynamicState(BridgeContext.DYNAMIC);
>                           SVGDocument svgDoc = factory.createSVGDocument(null, url.openStream());
>                           GVTBuilder builder = new GVTBuilder();
>                           GraphicsNode graphics = builder.build(ctx, svgDoc);
>                               String svgWidthString = svgDoc.getDocumentElement().getAttribute("width");
>                               String svgHeightString = svgDoc.getDocumentElement().getAttribute("height");
>                               float svgWidth = Float.valueOf(svgWidthString.substring(0, svgWidthString.length() - 2));
>                               float svgHeight = Float.valueOf(svgHeightString.substring(0, svgHeightString.length() - 2));
>                         PdfTemplate map = dc.createTemplate(svgWidth*1.25f, svgHeight*1.25f);
>                               //PdfTemplate map = dc.createTemplate(svgWidth, svgHeight);
>                         Graphics2D g2d = map.createGraphics(svgWidth*1.25f, svgHeight*1.25f);
>                         graphics.paint(g2d);
>                         g2d.dispose();
>                         System.out.println("w="+ svgWidth +" h="+ svgHeight +" maxW="+ maxIconWidth +" maxH="+ maxIconHeight);
>                         //...
>                         Image image = Image.getInstance(map);
> PdfPCell cell = new PdfPCell(...);
> cell.add(image);
> 
> I looked up the SVG specifications and found that pt is 1.25 pixels. However, this renders wrongly on the PDF. The image becomes too big and is cut off. When I enter 1.5f instead of 1.25f above, it seems more correct but still a bit out.
> 
> I don't want to hack together a number that will just happen to look right, because it is the wrong approach. Is there some kind of trickiness with the units between SVG and PDF (using iText)?
> 
> Help is much appreciated. I am working on the legends' rendering in SVG in the MapFish print module and will submit the source back to the project, so I think they would appreciate your input too.
> 
> Kind regards,
> Tim
> 
> ________________________________
> Please consider the environment before printing this email
> Warning: This electronic message together with any attachments is confidential. If you receive it in error: (i) you must not read, use, disclose, copy or retain it; (ii) please contact the sender immediately by reply email and then delete the emails.
> The views expressed in this email may not be those of Landcare Research New Zealand Limited. http://www.landcareresearch.co.nz




Jeremias Maerki


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org