Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do browsers handle rgb(percentage); for strange numbers

This is related to CSS color codes:

For hexcode we can represent 16,777,216 colors from #000000 to #FFFFFF

According to W3C Specs, Valid RGB percentages fit in a range from (0.0% to 100.0%) essentially giving you 1,003,003,001 color combinations. (1001^3)

According to the specs:

Values outside the device gamut should be clipped or mapped into the gamut when the gamut is known: the red, green, and blue values must be changed to fall within the range supported by the device. Users agents may perform higher quality mapping of colors from one gamut to another. For a typical CRT monitor, whose device gamut is the same as sRGB, the four rules below are equivalent:

I'm doubtful if browsers actually can render all these values. (but if they do please tell me and ignore the rest of this post)

Im assuming there's some mapping from rgb(percentage) to hex. (but again Im not really sure how this works)

Ideally I'd like to find out the function rgb(percentage)->HEX

If I had to guess it would probably be one of these 3.

1) Round to the nearest HEX

2) CEIL to the nearest HEX

3) FLOOR to the nearest HEX

Problem is I need to be accurate on the mapping and I have no idea where to search. There's no way my eyes can differentiate color at that level, but maybe there's some clever way to test each of these 3.

It might also be browser dependent. Can this be tested?

EDIT:

Firefox seems to round from empirical testing.

EDIT:

I'm looking through Firefox's source code right now,

nsColor.h
// A color is a 32 bit unsigned integer with four components: R, G, B
// and A.
typedef PRUint32 nscolor;

It seems Fiefox only has room for 255 values for each R,G and B. Hinting that rounding might be the answer, but maybe somethings being done with the alpha channel.

like image 875
Ray Avatar asked Oct 13 '11 19:10

Ray


People also ask

What does RGB 255 255 255 mean?

RGB Colors. All colors on a computer are made up by combining the light from three colors (red, blue, and green). Black is [0,0,0], and White is [255, 255, 255]; Gray is any [x,x,x] where all the numbers are the same.

How does the RGB color format work?

RGB is called an additive color system because the combinations of red, green, and blue light create the colors that we perceive by stimulating the different types of cone cells simultaneously. As shown above, the combinations of red, green, and blue light will cause us to perceive different colors.

What do the RGB numbers mean?

The first and second digits represent the red level; the third and fourth digits represent the green level; the fifth and sixth digits represent the blue level. In order to actually display the colors for all possible values, the computer display system must have 24 bits to describe the color in each pixel.


1 Answers

I think I found a solution for Firefox anyways, thought you might like a follow up:

Looking through the source code I found a file:

nsCSSParser.cpp

For each rgb percentages it does the following:

  1. It takes the percentage component multiplies it by 255.0f
  2. Stores it in a float
  3. Passes it into a function NSToIntRound
  4. The result of NSToIntRound is stored into an 8 bit integer datatype, before it is combined with the other 2 components and an alpha channel

Looking for more detail on NSToIntRound:

nsCoord.h
inline PRInt32 NSToIntRound(float aValue)
{
  return NS_lroundf(aValue);
}

NSToIntRound is a wrapper function for NS_lroundf

nsMathUtils.h
inline NS_HIDDEN_(PRInt32) NS_lroundf(float x)
{
    return x >= 0.0f ? PRInt32(x + 0.5f) : PRInt32(x - 0.5f);
}

This function is actually very clever, took me a while to decipher (I don't really have a good C++ background).

Assuming x is positive

It adds 0.5f to x and then casts to an integer

If the fractional part of x was less than 0.5, adding 0.5 won't change the integer and the fractional part is truncated,

Otherwise the integer value is bumped by 1 and the fractional part is truncated.

  1. So each component's percentage is first multiplied by 255.0f
  2. Then Rounded and cast into a 32bit Integer
  3. And then Cast again into an 8 bit Integer

I agree with most of you that say this appears to be a browser dependent issue, so I will do some further research on other browsers.

Thanks a bunch!

like image 185
Ray Avatar answered Sep 26 '22 17:09

Ray