Re: Rounding to device pixels (was: Designs that zoom)

Ben Curtis wrote:
> On Mar 4, 2005, at 5:15 AM, Mikko Rantalainen wrote:
>> css_box.bottom_right_corner_x = round(left) + round(width)
>> instead of
>> css_box.bottom_right_corner_x = round(left + width)
> 
> This seems like something reasonable to have in the standard, if it is 
> not already. But before we go there, will it address another rounding 
> issue that is much less apparent: the line-height of text?
> 
> Say in my UA for a particular layout, 1em = 10.72px (because I've been 
> reading all those cool graphic designers' websites about setting 
> font-size on the body to 67%), and my line-height is  1.75em = 18.76px.
> 
> How tall is a paragraph that renders over 5 lines?
> 
> 	round(5 * 18.76px) = round(93.8px) = 94px
> -or-
> 	5 * round(18.76px) = 5 * 19px = 95px

I'd would prefer exact position by default. As a general rule one 
should compute line's starting height as a float or fixed point 
number, and same for line's height. And only round to integer just 
before rendering.

However, I agree that in some special cases the "incorrect" rounding 
is indeed desirable.

How about adding a yet another new property:

name: dimension-rounding:
value: exact | equal
initial: exact // ?? doesn't match current UA behavior
applies to: a box with any dimension
inherited: no
media: visual
computed value: exact | equal

Where 'exact' would result to mathematically correct rounding 
behavior (and as a result two boxes that have, for example,  "width: 
50%" may be rendered with different widths if available width isn't 
dividable by 2). The value 'equal', on the other hand, would result 
to rounding (always towards zero?) box's top and left coordinates 
individually from width and height which will result every box to 
have the same size when identical input is given but gaps may occur 
in some cases because of rounding errors. [1]

To put it another way: 'exact' computes the "correct" location, and 
'equal' computes the "what most people want" location.

Perhaps an additional value 'auto' should be allowed where UA is 
expected to follow rule "do what I mean". This is what currently 
existing implementations do, after all. And mostly undefined...

The rationale for this rule is to give style authors a possibility 
to select which model they want to follow while keeping the rounding 
rule as simple as possible in the same time.


[1] In some cases different behavior for side-by-side boxes is required:

case 1) I have two elements with style "display: inline-block; 
width: 50%;" and I want them to have combined width of one row 
exactly. If the available width is 123 device pixels and previous 
box stops at device pixel position 14.8 then horizontal coordinates 
for both boxes are:
device.left1 = round(14.8) = 15
device.right1= round(14.8 + 0.5 * 123) = 76
device.left2 = round(14.8 + 0.5 * 123) = 76 // the same as above
device.right2 = round(14.8 + 0.5 * 123 + 0.5*123) = 138
line width = round(14.8 + 123) = 138 // same as above

Note that first element has width of 61 device pixels and the 
seconds one has width of 62 device pixels even though both have 
"width: 50%" set. Combined width of both elements is exactly the 
width of the the available space.

If, on the other hand, all coordinates are rounded first (the 
'equal' width) we get
device.left1 = round(14.8) = 15
device.right1= 15 + round(0.5 * 123) = 77
device.left2 = 15 + round(0.5 * 123) = 77
device.right2 = 15 + round(0.5 * 123) + round(0.5 * 123) = 140
line width = round(14.8) + round(123) = 138
So the two elements didn't take expected space, instead they took 
2px too much.

case 2) Line-spacing; If I have multiple lines of text that has the 
same text-size I expect rows to be evenly distributed. As in Ben's 
example above if we compute with fractional line height we get the 
result that on some line the space between lines must be one pixel 
more than between the others (assuming that text cannot be rendered 
in fractional positions). Setting dimension-rounding: equal would help.

Other examples can be found for both use cases in both vertical and 
horizontal orientation so this cannot be fixed just by defining 
different rounding rules for both. It might be sensible define 
rounding rules for text(/inline elements?) individually from block 
elements.


Possible problems:

Should this property set rounding rules for the element OR for the 
childs? (I think for the element.)

When two consecutive elements have different values (one has 'equal' 
and another has 'exact') how should rendering proceed? (There's no 
problem if 'exact' follows after 'equal' element because it starts 
from integer position. In other case, I think that the renderer 
should be allowed to round the 'exact' coordinate as usual - just 
round the left and width individually - and not mind of a possible 
single pixel gap.)


What do you think? Without this kind of property CSS cannot be used 
to get pixel perfect AND fluid layouts. Most of the time something 
is always one pixel too small or one pixel too big when one tries to 
use percentages or em-unit for anything.

-- 
Mikko

Received on Monday, 7 March 2005 16:33:44 UTC