Created attachment 16838 [details] Patch to add support for a 'deviceDPI' other than 72. This patch manipulates the transforms in the PDFGraphics2D so that if people want to query the 'device DPI' (as Batik does when rendering images/filters/etc). They can get a number other than 72DPI (the default PDF DPI). It works by adding a scaling transform to the PDFGraphics2D, and a reciprical 'hidden' transform to the PDFGraphicsState. Thus if code asks the Graphics2D for it's Transform (which should be the mapping to the 'device' coordinate system) they will see the scaled coordinate system (likely making it appear that the device is say 150 or 300 DPI). But the 'hidden' transform will then map everything back to the PDF default 72DPI. The only issue I am aware of is that currently the PDFGraphics2D doesn't call preparePainting in _every_ method. So in particular some methods like 'clip' could take place before a page has been started. I think this is likely an oversite in the PDFGraphics2D implementation. However in the mean time I've added a call to preparePainting in the PDFTranscoder after all the configuration is done so that the needed transforms are present immediately.
I've got a question on this one: How does the setDeviceDPI() relate to the resolution setting in the user agent? So far I was able to set a different resolution on the user agent to get PDFs with higher resolution on-the-fly images. I'm not sure but it seems that this isn't working properly anymore. Can't tell when this went lost. And AFAICS setDeviceDPI() is not called by the Transcoder. Is that by design? I'm a bit lost. Concerning preparePainting(), we may need to add additional calls where necessary. I've added this method to support multi-page PDFs from PDFDocumentGraphics2D. I'm using it in a JPS StreamPrintService where you don't know beforehand if the next page will be produced or not. A call to nextPage() finishes the current page and a new one can only be set up when painting begins. So for single page SVGs from the Transcoder, your change is fine, but we may need to add additional calls where needed. I'll have a look when I start moving the transcoders as I will publish my JPS StreamPrintService at that time.
(In reply to comment #2) > I've got a question on this one: How does the setDeviceDPI() relate to the > resolution setting in the user agent? So far I was able to set a different > resolution on the user agent to get PDFs with higher resolution on-the-fly > images. This working depends heavily on the way the SVG is constructed, also it can have some very unexpected (read harmful) results. The pixel per mm setting is used to map 'real world' units (like in, mm, pt, px - yes px is a "real world" unit in SVG because it's defined == to pt) to user space units. So in the default case let's say we have the User Agent setup so 1pt == 1 user space unit (1in = 72 user space units), and you have a 'good' outermost SVG element: <svg width="8in" height="10in" viewBox="0 0 576 720 xmlns="..."> In this case your width and height establish a 'device' image size of 8*72x10*72 (576x720) user space units. Since the viewBox is the same size there will be no scaling. Now if you were to set the mapping to say 144 user space units to the inch. Then the device image size would be 8*144x10*144 (1152x1440) user space units. However the viewBox would scale this back down to 576x720. The PDF transcoder adds a 'hidden' scale from the PDF page size to the 1152x1440 page size (much as my code does). So far everything looks good, but the problem is that when someone says <text font-size="12pt"/> this gets mapped to 24 userspace units instead of 12 userspace units. > I'm not sure but it seems that this isn't working properly anymore. > Can't tell when this went lost. And AFAICS setDeviceDPI() is not called by the > Transcoder. Is that by design? I'm a bit lost. You are right that it isn't currently called. The problem is that it should really be exposed as a new rendering hint. In my patch I didn't change the 'default' DPI but it should really be set to 150 or 300 dpi. > Concerning preparePainting(), we may need to add additional calls where > necessary. I've added this method to support multi-page PDFs from > PDFDocumentGraphics2D. I'm using it in a JPS StreamPrintService where > you don't know beforehand if the next page will be produced or not. > A call to nextPage() finishes the current page and a new one can > only be set up when painting begins. So for single page SVGs from > the Transcoder, your change is fine, but we may need to add additional > calls where needed. I'll have a look when I start moving the > transcoders as I will publish my JPS StreamPrintService at that time. I strongly suspected that the missing calls were an oversite, but before making such extensive changes I wanted to make sure.
Thanks, Thomas, for explaining it to me. After some time playing around with different settings (and fixing my buggy test code) I finally figured out how this works. I agree that your approach is much better than my earlier one. I hope you agree with my default setting of 300dpi. The patch is applied now: http://svn.apache.org/viewcvs?rev=332304&view=rev I'm now going to look at doing the same for our PDFSVGHandler. I'll leave the issue open for a short while as a reminder for myself.
resetting P2 open bugs to P3 pending further review
change status from ASSIGNED to NEW for consistency