Re: [cssom] Serializing non-opaque colors, background-position keywords

On 1/28/15 5:10 AM, Simon Pieters wrote:
> How should color: rgba(5, 7, 10, 0.9) be serialized? Gecko round-trips
> alpha as 0.9 but Blink makes it 0.901961. I think Gecko faithfully
> round-trips two decimals for colors.

Yes.

Specifically, Gecko's internal storage for the case above is a 32-bit 
integer, 8 bits each for RGBA.  Which means the 0.9 gets coverted to an 
integer in the range [0,255], by multiplying it by 255 and then 
rounding.  This produces 230 in this case.  I assume Blink does the 
same, since 230 / 255 == 0.901960784314...

In any case, when converting the integer back to a float, Gecko does the 
following (code at 
<http://hg.mozilla.org/mozilla-central/file/9b6b80222e66/layout/style/nsStyleUtil.cpp#l567> 
but reproduced below as pseudo-code with more extensive comments):

   // Produce a float with at most two digits after the decimal point,
   // modulo representability issues.
   rounded = round(alpha * 100.0 / 255.0) / 100.0;
   if (round(rounded * 255) == alpha) {
     // We have a float which would give us the observed alpha value;
     // use it.
     return rounded;
   }
   // Produce a float with at most three digits after the decimal
   // point.  More precision that that is pointless, because there are
   // only 256 possible values of "alpha" anyway, so the 1000 values we
   // can produce here cover all of them.
   return round(alpha * 1000.0 / 255.0) / 1000.0;

This faithfully round-trips two decimals, preserves about 1/4 of 
three-decimal values, and rounds off all values with more precision to 
three decimal places (and in fact only to the subset of 
three-decimal-place values that are multiples of 1/255).

> Should we specify Gecko's behavior
> of rounding to a "nicer" number?

We feel pretty strongly that this behavior is much better for authors in 
typical situations.  The spec obviously doesn't require browsers to 
store alpha as an 8-bit integer, but it could require that if they do so 
they must use an algorithm like the above when serializing the 
(already-rounded, just in different units) value.

> Similarly for 'opacity' (although that is represented with higher
> precision I think).

I'd think opacity is typically represented as an actual float... though 
of course technically CSS requires representation as an 
infinite-precision decimal or something.

> How should background-position: 0% top be serialized? For element.style,
> Gecko round-trips keywords, Blink converts to percentages.

Interstingly, the devtools in Blink show "0% top" in this case, so 
either they're not using the actual parsed CSS data structures or the 
latter are in fact storing the keyword and just converting to 0% at 
serialization time...

-Boris

Received on Wednesday, 28 January 2015 17:55:17 UTC