W3C home > Mailing lists > Public > www-svg@w3.org > April 2003

Re: [SVG] optimizeSpeed misbehavior pixel rendering at 100% zoom level in Adobe

From: Thomas E Deweese <thomas.deweese@kodak.com>
Date: Wed, 30 Apr 2003 08:08:04 -0400
Message-ID: <16047.48292.885099.899072@frog.rl.kodak.com>
To: "Fred P." <fprog26@hotmail.com>
Cc: thomas.deweese@kodak.com, www-svg@w3.org

>>>>> "FP" == Fred P <fprog26@hotmail.com> writes:

FP> What about this line not being drawn properly!!!

FP> (101,101)-(109,109)

>>  (101.5,101.5) -> (109.5,109.5) [pixel center->pixel center] is
>> rendered "correctly".  In your given example the path has a bunch
>> of stuff hanging off the 'top' of the pixel the Adobe rasterizer
>> probably moves that to the 'wrong' pixel to ensure when drawn as a
>> whole you don't get 'drop outs (these are very complex issues and
>> usually fixing this particular 'broken' output would simply move
>> the problem to other cases - it is much better to give the
>> rasterizer something that makes sense to start with).

FP> So, basically, they have a fix that broke different thing instead.

    At the level you are dealing with the vector data simply doesn't
provide enough information in all cases to make it clear what the
author's intent is.  A 'Good property' of a renderer is that any two
lines that begin/end at the same point, in float space, should meet in
pixel space - this is generally true even if the lines are not drawn
"together".  This in practice can be very difficult to achieve
especially given that you are generally filling regions not "drawing
lines".  I don't know the internal details of the Adobe Renderer but
my guess is if you didn't see the problem in this case you would have
seen the problem in other cases.

FP> Maybe you can tell me simply what's wrong in my logic?

    Part of it is that your 'logical view' is still a bit simplified
(you were missing the bits off the top and left of the first pixel).
the following SVG is a good harness for understanding the lines you
are really drawing:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN"
      "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"
   >

   <defs>
      <symbol id="grid" viewbox="0 0 11 11">
         <g stroke="#000" fill="none" stroke-width="0.05">
            <line x1="0" y1="0" x2="10" y2="0"/>
            <line x1="0" y1="1" x2="10" y2="1"/>
            <line x1="0" y1="2" x2="10" y2="2"/>
            <line x1="0" y1="3" x2="10" y2="3"/>
            <line x1="0" y1="4" x2="10" y2="4"/>
            <line x1="0" y1="5" x2="10" y2="5"/>
            <line x1="0" y1="6" x2="10" y2="6"/>
            <line x1="0" y1="7" x2="10" y2="7"/>
            <line x1="0" y1="8" x2="10" y2="8"/>
            <line x1="0" y1="9" x2="10" y2="9"/>
            <line x1="0" y1="10" x2="10" y2="10"/>

            <line y1="0" x1="0" y2="10" x2="0"/>
            <line y1="0" x1="1" y2="10" x2="1"/>
            <line y1="0" x1="2" y2="10" x2="2"/>
            <line y1="0" x1="3" y2="10" x2="3"/>
            <line y1="0" x1="4" y2="10" x2="4"/>
            <line y1="0" x1="5" y2="10" x2="5"/>
            <line y1="0" x1="6" y2="10" x2="6"/>
            <line y1="0" x1="7" y2="10" x2="7"/>
            <line y1="0" x1="8" y2="10" x2="8"/>
            <line y1="0" x1="9" y2="10" x2="9"/>
            <line y1="0" x1="10" y2="10" x2="10"/>
         </g>
      </symbol>
   </defs>

 <g transform="scale(20)">
   <use x="0.025" y="0.025" width="10" height="10" xlink:href="#grid"/>
   <path stroke-width="1" d="M2 2 L 8 8" 
         fill="none" stroke="#00F" stroke-opacity="0.5"/>
 </g>

 <g transform="translate(210,0) scale(20)">
   <use x="0.025" y="0.025" width="10" height="10" xlink:href="#grid"/>
   <path stroke-width="1" d="M2.5 2.5 L 8.5 8.5" 
         fill="none" stroke="#00F" stroke-opacity="0.5"/>
 </g>

</svg>

BTW those ascii pictures are a lot of work generally I just use SVG
for these things as above.


FP> Logical view of a line (101.5, 101.5)-(104.5, 104.5)
FP> i.e. Desired line drawn.
FP> 
FP> (101.5, 101.5)
FP>   [x][x][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [x][x][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [x][x][B][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [x][x][x][B]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP> 
FP>   [ ][ ][ ][ ]  [B][x][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [x][B][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [x][x][B][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [x][x][x][B]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP> 
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [B][x][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][B][x][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][x][B][x]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][x][x][B]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP> 
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [B][x][x][x]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][B][x][x]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][x][B][x]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [x][x][x][B]  (104.5, 104.5)
FP> 
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [-][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][-][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]
FP>   [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]  [ ][ ][ ][ ]

          101.5        102.5          103.5         104.5        105.5???  

      Why did you draw out to 105.5?

FP> As far as I can understand, I can accept the transform(0.5,0.5)
FP> work around.  I'm amused by the fact that it give 4 pixels line
FP> instead of 5 pixels, even though I wanted a 4 pixel diagonal line.

    Why would 101.5,101.5 -> 104.5,104.5 give a 5 pixel line?  The
logical drawing you showed goes from 101.5,101.5->105.5,105.5 (if I
counted correctly).  You might argue that it should give a 3 pixel
line.

FP> Why does the top pixel get drawn correctly and not the bottom is
FP> not drawn?

    It is drawn correctly (assuming you are talking about the 104.5
thing still).

FP> How come the little top-right-right pixel doesn't appear anymore?

    Probably because you don't have the extra coverage hanging off the
top and left of the first pixel.  Without looking at Adobe's code I
can't give you definite answers but they may be trying to maintain
total pixel coverage (important for perceived visual weight -
especially for fonts).

FP> Seems you solved my problem using the workaround, you have my
FP> gratitude, but I still don't get it.

FP> For me it still doesn't make sense.

FP> When you tell me the middle point the (.5, .5) offset makes sense,
FP> but if we take your word then (101.5,101.5)-(104.5, 104.5) should
FP> really be (101,101)-(105,105) unless you are taking the 'floor'
FP> rounding value, but (101.6,101.6)-(104.6, 104.6) is still
FP> (101,101)-(104,104).  Weirdly.

    We are doing total coverage of a pixel.  I also suspect that they
always try and fill the pixel that contains the start point and end
points.  This helps ensure that you don't get drop outs. A basic
problem is that for aliased drawing you can't always do a 'perfect'
job for all cases.

FP> Thanks again for the trick.

    It's not a trick it's a matter of getting the areas to be filled
to lie directly on top of the pixels they are supposed to fill.  Try
plugging your unshifted hand into my grid and I think you will see
what I mean.
Received on Wednesday, 30 April 2003 08:09:04 GMT

This archive was generated by hypermail 2.3.1 : Friday, 8 March 2013 15:54:24 GMT