You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-users@xmlgraphics.apache.org by Massimo <ma...@snai.it> on 2013/07/08 11:10:41 UTC

SVG pixel size

Hi all.
I am producing a PNG file and I'm using an xsl with SVG element like this:

<fo:instream-foreign-object>
  <svg:svg xmlns:svg="http://www.w3.org/2000/svg" width="100%"
height="100%">
    <svg:line x1="15" y1="15" x2="25" y2="15"/>
    <svg:line x1="15" y1="16" x2="25" y2="16"/>
  </svg:svg>
</fo:instream-foreign-object>

I need to draw 1 pixel thin lines.
I set the target resolution to 203dpi and I noticed that the pixel of the
lines is scaled (bigger) according the resolution (~3px thin).

Is there any way to control the svg pixel size via program or configuration
leaving  the resolution to 203dpi?

Thanks.




--
View this message in context: http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853.html
Sent from the FOP - Users mailing list archive at Nabble.com.

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


Re: SVG pixel size

Posted by Massimo <ma...@snai.it>.
Hi all.
Thanks for your answers.

Finally I found a solution that worked for me.

Cheers, Massimo.



--
View this message in context: http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853p38896.html
Sent from the FOP - Users mailing list archive at Nabble.com.

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


Re: SVG pixel size

Posted by Luis Bernardo <lm...@gmail.com>.
Correct. And since FOP is still in the past and uses 72 instead of 96:

2.125 / 72 * 96 = 2.833 (pixels, which become dots when sent to the printer)

On 7/9/13 5:46 PM, Sergiu Dumitriu wrote:
> So, a pixel is a fixed length that doesn't scale down with the DPI, it
> should always be 1/96 inches. At 204 DPI that would translate into 2.125
> dots.
>
>
> On 07/09/2013 09:33 AM, Luis Bernardo wrote:
>> Lets look at the default case, that creates a 100x100 pixel image. The
>> default target dpi is 72, so 100/72 = 1.388888.
>>
>> If you set the target dpi to 204, then the image needs to be 283x283
>> pixels because 204*1.38888 = 283.3333. Then a 1 pixel line needs to be
>> 2.83 pixels to keep the scaling correct. Since you cannot have 2.83
>> pixel thickness in the monitor, it defaults to 3 pixels.
>>
>> Is your goal to print (to paper) a line of a certain thickness? Then you
>> need to talk about dimensions (say, mm) not pixels.
>>
>>
>>
>> On Tue, Jul 9, 2013 at 1:35 PM, Massimo <massimo.iasevoli@snai.it
>> <ma...@snai.it>> wrote:
>>
>>      Thanks for the answer.
>>
>>      I try to better explain the problem with an attached java example.
>>
>>      If you run the main method you should get two png image
>>      . svgDefImage.png that contain a 1px thin line generated with
>>      default target
>>      resolution
>>      . svg204Image.png that contain a 3px thin line generated with 204dpi
>>      target
>>      resolution
>>
>>      According to the svg tag, both files should contain 1px thin lines.
>>
>>      All images is generated with the same attached fo file.
>>
>>      Notice that I use a custom Java2D renderer.
>>
>>      I forgot to mention that I am using the fop trunk version.
>>
>>      Thanks.
>>      Massimo.
>>
>>      SVGTest.java
>>      <http://apache-fop.1065347.n5.nabble.com/file/n38858/SVGTest.java>
>>      svgpixelsize.fo <http://svgpixelsize.fo>
>>      <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgpixelsize.fo>
>>      svgDefImage.png
>>      <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgDefImage.png>
>>      svg204Image.png
>>      <http://apache-fop.1065347.n5.nabble.com/file/n38858/svg204Image.png>
>>
>


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


Re: SVG pixel size

Posted by Sergiu Dumitriu <se...@gmail.com>.
The problem is that the "pixel" is a very wrong/misleading unit.

Initially (HTML3) there was no CSS, and no units, so there were just
unit-less length: <table border=4> would create a table with a 4 pixels
wide border [1]. Back then (early-mid 90s), almost all monitors were low
resolution, and it was so obvious what a pixel was that it wasn't even
defined.

CSS1 defined [2] the pixel not as a screen unit, but as a an angle:

"The suggested reference pixel is the visual angle of one pixel on a
device with a pixel density of 90dpi and a distance from the reader of
an arm's length. For a nominal arm's length of 28 inches, the visual
angle is about 0.0227 degrees."

That means that a pixel isn't a display pixel, or a dot, regardless of
the DPI. Would it make sense for a 2400DPI printer to print lines 1/2400
in? Would that even be visible? One pixel is always a dot at 90DPI,
according to CSS1.


CSS2 defines the pixel both as a fixed length [3] and as an angle [4]:

"1px is equal to 0.75pt", and "the points used by CSS are equal to
1/72nd of 1in." => 1px = 1/96in

"The reference pixel is the visual angle of one pixel on a device with a
pixel density of 96dpi and a distance from the reader of an arm's
length. For a nominal arm's length of 28 inches, the visual angle is
therefore about 0.0213 degrees. For reading at arm's length, 1px thus
corresponds to about 0.26 mm (1/96 inch)."

This is a change from the 1/90, since there are far more monitors at
96DPI than at 90DPI, so it makes no sense to define it that way.


CSS3 removes the pt from the pixel definition, and goes straight to [5]:

"1px is equal to 1/96th of 1in"

And it keeps the visual angle definition for the "reference pixel".

So, a pixel is a fixed length that doesn't scale down with the DPI, it
should always be 1/96 inches. At 204 DPI that would translate into 2.125
dots.

[1] http://www.w3.org/TR/REC-html32.html#table
[2] http://www.w3.org/TR/1999/REC-CSS1-19990111#length-units
[3] http://www.w3.org/TR/CSS21/syndata.html#x39
[4] http://www.w3.org/TR/CSS21/syndata.html#x40
[5] http://www.w3.org/TR/css3-values/#absolute-lengths

On 07/09/2013 09:33 AM, Luis Bernardo wrote:
> Lets look at the default case, that creates a 100x100 pixel image. The
> default target dpi is 72, so 100/72 = 1.388888.
> 
> If you set the target dpi to 204, then the image needs to be 283x283
> pixels because 204*1.38888 = 283.3333. Then a 1 pixel line needs to be
> 2.83 pixels to keep the scaling correct. Since you cannot have 2.83
> pixel thickness in the monitor, it defaults to 3 pixels.
> 
> Is your goal to print (to paper) a line of a certain thickness? Then you
> need to talk about dimensions (say, mm) not pixels.
> 
> 
> 
> On Tue, Jul 9, 2013 at 1:35 PM, Massimo <massimo.iasevoli@snai.it
> <ma...@snai.it>> wrote:
> 
>     Thanks for the answer.
> 
>     I try to better explain the problem with an attached java example.
> 
>     If you run the main method you should get two png image
>     . svgDefImage.png that contain a 1px thin line generated with
>     default target
>     resolution
>     . svg204Image.png that contain a 3px thin line generated with 204dpi
>     target
>     resolution
> 
>     According to the svg tag, both files should contain 1px thin lines.
> 
>     All images is generated with the same attached fo file.
> 
>     Notice that I use a custom Java2D renderer.
> 
>     I forgot to mention that I am using the fop trunk version.
> 
>     Thanks.
>     Massimo.
> 
>     SVGTest.java
>     <http://apache-fop.1065347.n5.nabble.com/file/n38858/SVGTest.java>
>     svgpixelsize.fo <http://svgpixelsize.fo>
>     <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgpixelsize.fo>
>     svgDefImage.png
>     <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgDefImage.png>
>     svg204Image.png
>     <http://apache-fop.1065347.n5.nabble.com/file/n38858/svg204Image.png>
> 


-- 
Sergiu Dumitriu
http://purl.org/net/sergiu

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


Re: SVG pixel size

Posted by Luis Bernardo <lm...@gmail.com>.
Lets look at the default case, that creates a 100x100 pixel image. The
default target dpi is 72, so 100/72 = 1.388888.

If you set the target dpi to 204, then the image needs to be 283x283 pixels
because 204*1.38888 = 283.3333. Then a 1 pixel line needs to be 2.83 pixels
to keep the scaling correct. Since you cannot have 2.83 pixel thickness in
the monitor, it defaults to 3 pixels.

Is your goal to print (to paper) a line of a certain thickness? Then you
need to talk about dimensions (say, mm) not pixels.



On Tue, Jul 9, 2013 at 1:35 PM, Massimo <ma...@snai.it> wrote:

> Thanks for the answer.
>
> I try to better explain the problem with an attached java example.
>
> If you run the main method you should get two png image
> . svgDefImage.png that contain a 1px thin line generated with default
> target
> resolution
> . svg204Image.png that contain a 3px thin line generated with 204dpi target
> resolution
>
> According to the svg tag, both files should contain 1px thin lines.
>
> All images is generated with the same attached fo file.
>
> Notice that I use a custom Java2D renderer.
>
> I forgot to mention that I am using the fop trunk version.
>
> Thanks.
> Massimo.
>
> SVGTest.java
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/SVGTest.java>
> svgpixelsize.fo
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgpixelsize.fo>
> svgDefImage.png
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgDefImage.png>
> svg204Image.png
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svg204Image.png>
>
>
>
> --
> View this message in context:
> http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853p38858.html
> Sent from the FOP - Users mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>
>

Re: SVG pixel size

Posted by Sergiu Dumitriu <se...@gmail.com>.
On 07/09/2013 01:43 PM, Vincent Hennebert wrote:
> On 09/07/13 18:51, Sergiu Dumitriu wrote:
>> On 07/09/2013 12:26 PM, Vincent Hennebert wrote:
>>> Hi Massimo,
>>>
>>> the easiest is to have the source resolution match the target
>>> resolution. That way, one pixel in your source will become 1 pixel in
>>> the output.
>>>
>>> That said, if you want a real one-pixel line and not something
>>> anti-aliased you have to ensure that the coordinates will match output
>>> pixels. Start by setting the font-size on the outer block to 0, in order
>>> to avoid that the baseline ends up somewhere in between two pixels.
>>> Then, for some reason, you have to set the y pixels to half values. For
>>> example, 1.5px. I haven’t investigated why.
>>
>> Because the stroked line width is split evenly around the imaginary line
>> defined by the coordinates. If it goes through 1.5, then 0.5px will be
>> above and 0.5px will be below it, which means that it actually fills in
>> a solid stripe between 1.0 and 2.0, which is exactly a pixel without any
>> antialiassing.
> 
> I was looking in the SVG Recommendation for something similar to the
> description in the javadoc of Graphics2D:
> http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Graphics2D.html
>   “The JDK(tm) 1.1 rendering model is based on a pixelization model that
>   specifies that coordinates are infinitely thin, lying between the
>   pixels. Drawing operations are performed using a one-pixel wide pen
>   that fills the pixel below and to the right of the anchor point on the
>   path.”
> 
> I couldn’t find anything though. Do you happen to have any pointers?

Couldn't find anything after a quick scan of the specification, but it
makes sense since SVG is "scalable". Unlike Java graphics, which is
clearly targeting interactive displays (screens), and most coordinates
are integers, SVG is defined as scalable, device- and
resolution-independent graphics. It works on an abstract mathematical
canvas, and coordinates are abstract points, with zero width, around
which paint is applied with a real width.

The pixel (px) doesn't make that much sense defined as a screen dot,
since one of the main targets of SVG is print, and a possible usecase is
for SVG to be implemented as a standard printer language, alongside PCL
and EPS, and printers don't have pixels (that's the purpose of SVG Print).

Another aspect is that units correspond to pixels only in the initial
coordinate system, but that one isn't fixed. The actual coordinate
system can be either explicitly or automatically changed, so in the end
a pixel length can be equal to 10 device pixels, or 0.024 device pixels.
Should everything be shifted by 0.5 device pixels so that they align nicely?

> According to that model, there would be no need to specify coordinates
> in 0.5 to have full lines.
> 
> SVG seems to do the same as PDF however:
>   “stroking a path entails painting all points whose perpendicular
>   distance from the path in user space is less than or equal to half the
>   line width.”
> 
> That makes sense I guess.
> 
> 
>> If it were to pass through 2.0, then it would end up as a solid stripe
>> between 1.5 and 2.5, which means that half of the first pixel and half
>> of the second pixel must be stroked, and since half pixels can't be
>> drawn, antialiassing is used.
>>
>> I usually shift the viewbox by 0.5px to get rid of this problem and use
>> integer coordinates in the rest of the SVG.
> 
> 
> Thanks,
> Vincent
> 
> ---------------------------------------------------------------------


-- 
Sergiu Dumitriu
http://purl.org/net/sergiu

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


Re: SVG pixel size

Posted by Vincent Hennebert <vh...@gmail.com>.
On 09/07/13 18:51, Sergiu Dumitriu wrote:
> On 07/09/2013 12:26 PM, Vincent Hennebert wrote:
>> Hi Massimo,
>>
>> the easiest is to have the source resolution match the target
>> resolution. That way, one pixel in your source will become 1 pixel in
>> the output.
>>
>> That said, if you want a real one-pixel line and not something
>> anti-aliased you have to ensure that the coordinates will match output
>> pixels. Start by setting the font-size on the outer block to 0, in order
>> to avoid that the baseline ends up somewhere in between two pixels.
>> Then, for some reason, you have to set the y pixels to half values. For
>> example, 1.5px. I haven’t investigated why.
> 
> Because the stroked line width is split evenly around the imaginary line
> defined by the coordinates. If it goes through 1.5, then 0.5px will be
> above and 0.5px will be below it, which means that it actually fills in
> a solid stripe between 1.0 and 2.0, which is exactly a pixel without any
> antialiassing.

I was looking in the SVG Recommendation for something similar to the
description in the javadoc of Graphics2D:
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Graphics2D.html
  “The JDK(tm) 1.1 rendering model is based on a pixelization model that
  specifies that coordinates are infinitely thin, lying between the
  pixels. Drawing operations are performed using a one-pixel wide pen
  that fills the pixel below and to the right of the anchor point on the
  path.”

I couldn’t find anything though. Do you happen to have any pointers?

According to that model, there would be no need to specify coordinates
in 0.5 to have full lines.

SVG seems to do the same as PDF however:
  “stroking a path entails painting all points whose perpendicular
  distance from the path in user space is less than or equal to half the
  line width.”

That makes sense I guess.


> If it were to pass through 2.0, then it would end up as a solid stripe
> between 1.5 and 2.5, which means that half of the first pixel and half
> of the second pixel must be stroked, and since half pixels can't be
> drawn, antialiassing is used.
> 
> I usually shift the viewbox by 0.5px to get rid of this problem and use
> integer coordinates in the rest of the SVG.


Thanks,
Vincent

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


Re: SVG pixel size

Posted by Sergiu Dumitriu <se...@gmail.com>.
On 07/09/2013 12:26 PM, Vincent Hennebert wrote:
> Hi Massimo,
> 
> the easiest is to have the source resolution match the target
> resolution. That way, one pixel in your source will become 1 pixel in
> the output.
> 
> That said, if you want a real one-pixel line and not something
> anti-aliased you have to ensure that the coordinates will match output
> pixels. Start by setting the font-size on the outer block to 0, in order
> to avoid that the baseline ends up somewhere in between two pixels.
> Then, for some reason, you have to set the y pixels to half values. For
> example, 1.5px. I haven’t investigated why.

Because the stroked line width is split evenly around the imaginary line
defined by the coordinates. If it goes through 1.5, then 0.5px will be
above and 0.5px will be below it, which means that it actually fills in
a solid stripe between 1.0 and 2.0, which is exactly a pixel without any
antialiassing.

If it were to pass through 2.0, then it would end up as a solid stripe
between 1.5 and 2.5, which means that half of the first pixel and half
of the second pixel must be stroked, and since half pixels can't be
drawn, antialiassing is used.

I usually shift the viewbox by 0.5px to get rid of this problem and use
integer coordinates in the rest of the SVG.
-- 
Sergiu Dumitriu
http://purl.org/net/sergiu

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


Re: SVG pixel size

Posted by Vincent Hennebert <vh...@gmail.com>.
Hi Massimo,

the easiest is to have the source resolution match the target
resolution. That way, one pixel in your source will become 1 pixel in
the output.

That said, if you want a real one-pixel line and not something
anti-aliased you have to ensure that the coordinates will match output
pixels. Start by setting the font-size on the outer block to 0, in order
to avoid that the baseline ends up somewhere in between two pixels.
Then, for some reason, you have to set the y pixels to half values. For
example, 1.5px. I haven’t investigated why.

HTH,
Vincent


On 09/07/13 14:35, Massimo wrote:
> Thanks for the answer.
> 
> I try to better explain the problem with an attached java example.
> 
> If you run the main method you should get two png image
> . svgDefImage.png that contain a 1px thin line generated with default target
> resolution
> . svg204Image.png that contain a 3px thin line generated with 204dpi target
> resolution
> 
> According to the svg tag, both files should contain 1px thin lines.
> 
> All images is generated with the same attached fo file.
> 
> Notice that I use a custom Java2D renderer.
> 
> I forgot to mention that I am using the fop trunk version.
> 
> Thanks.
> Massimo.
> 
> SVGTest.java
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/SVGTest.java>  
> svgpixelsize.fo
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgpixelsize.fo>  
> svgDefImage.png
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svgDefImage.png>  
> svg204Image.png
> <http://apache-fop.1065347.n5.nabble.com/file/n38858/svg204Image.png>  
> 
> 
> 
> --
> View this message in context: http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853p38858.html
> Sent from the FOP - Users mailing list archive at Nabble.com.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
> 

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


Re: SVG pixel size

Posted by Massimo <ma...@snai.it>.
Thanks for the answer.

I try to better explain the problem with an attached java example.

If you run the main method you should get two png image
. svgDefImage.png that contain a 1px thin line generated with default target
resolution
. svg204Image.png that contain a 3px thin line generated with 204dpi target
resolution

According to the svg tag, both files should contain 1px thin lines.

All images is generated with the same attached fo file.

Notice that I use a custom Java2D renderer.

I forgot to mention that I am using the fop trunk version.

Thanks.
Massimo.

SVGTest.java
<http://apache-fop.1065347.n5.nabble.com/file/n38858/SVGTest.java>  
svgpixelsize.fo
<http://apache-fop.1065347.n5.nabble.com/file/n38858/svgpixelsize.fo>  
svgDefImage.png
<http://apache-fop.1065347.n5.nabble.com/file/n38858/svgDefImage.png>  
svg204Image.png
<http://apache-fop.1065347.n5.nabble.com/file/n38858/svg204Image.png>  



--
View this message in context: http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853p38858.html
Sent from the FOP - Users mailing list archive at Nabble.com.

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


Re: SVG pixel size

Posted by Luis Bernardo <lm...@gmail.com>.
Pixel is only for monitors. If you want a 1 pixel line you don't need to 
care about dpi. That only matters if you want to print. When you print a 
pixel becomes a dot.

Attached is an example with a 1 pixel thick line. Of course, the 
thickness you see in the monitor depends on the zoom you use. If you 
open the image with Gimp and zoom in to 1600% you will see that the line 
thickness corresponds, on the left scale, to 1 pixel.

Maybe you can clarify your question?

On 7/8/13 10:10 AM, Massimo wrote:
> Hi all.
> I am producing a PNG file and I'm using an xsl with SVG element like this:
>
> <fo:instream-foreign-object>
>    <svg:svg xmlns:svg="http://www.w3.org/2000/svg" width="100%"
> height="100%">
>      <svg:line x1="15" y1="15" x2="25" y2="15"/>
>      <svg:line x1="15" y1="16" x2="25" y2="16"/>
>    </svg:svg>
> </fo:instream-foreign-object>
>
> I need to draw 1 pixel thin lines.
> I set the target resolution to 203dpi and I noticed that the pixel of the
> lines is scaled (bigger) according the resolution (~3px thin).
>
> Is there any way to control the svg pixel size via program or configuration
> leaving  the resolution to 203dpi?
>
> Thanks.
>
>
>
>
> --
> View this message in context: http://apache-fop.1065347.n5.nabble.com/SVG-pixel-size-tp38853.html
> Sent from the FOP - Users mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org
>