Make semi-transparent background colors work in browsers that don't support RGBA.

Closes #569.
This commit is contained in:
Ross Boucher
2010-03-23 14:26:32 -07:00
parent 4175b762c3
commit 0cf86318ce
2 changed files with 64 additions and 86 deletions
+15 -61
View File
@@ -437,51 +437,16 @@ var cachedBlackColor,
if (self)
{
_components = components;
if (!CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0 && window.Base64 && window.CRC32)
{
var bytes = [0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x8,0x3,0x0,0x0,0x0,0x28,0xcb,0x34,0xbb,0x0,0x0,0x3,0x0,0x50,0x4c,0x54,0x45,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x17,0x89,0x99,0x55,0x0,0x0,0x0,0x1,0x74,0x52,0x4e,0x53,0x0,0x40,0xe6,0xd8,0x66,0x0,0x0,0x0,0x10,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x60,0x0,0x0,0x0,0x0,0xff,0xff,0x3,0x0,0x0,0x2,0x0,0x1,0x24,0x7f,0x24,0xf1,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82,0xff];
var r_off = 41;
var g_off = 42;
var b_off = 43;
var a_off = 821;
var plte_crc_off = 809;
var trns_crc_off = 822;
var plte_type_off = 37;
var trns_type_off = 817;
bytes[r_off] = Math.round(_components[0]*255);
bytes[g_off] = Math.round(_components[1]*255);
bytes[b_off] = Math.round(_components[2]*255);
bytes[a_off] = Math.round(_components[3]*255);
// calculate new CRCs
var new_plte_crc = integerToBytes(CRC32.getCRC(bytes, plte_type_off, 4+768), 4);
var new_trns_crc = integerToBytes(CRC32.getCRC(bytes, trns_type_off, 4+1), 4);
// overwrite old CRCs with new ones
for (var i = 0; i < 4; i++)
{
bytes[plte_crc_off+i] = new_plte_crc[i];
bytes[trns_crc_off+i] = new_trns_crc[i];
}
// Base64 encode, strip whitespace and build data URL
var base64image = Base64.encode(bytes); //.replace(/[\s]/g, "");
_cssString = "url(\"data:image/png;base64," + base64image + "\")";
}
else
{
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
}
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
}
return self;
}
@@ -494,6 +459,7 @@ var cachedBlackColor,
{
_patternImage = anImage;
_cssString = "url(\"" + [_patternImage filename] + "\")";
_components = [];
}
return self;
@@ -512,7 +478,7 @@ var cachedBlackColor,
*/
- (float)alphaComponent
{
return _components[3];
return _components[3] || 0.0;
}
/*!
@@ -520,7 +486,7 @@ var cachedBlackColor,
*/
- (float)blueComponent
{
return _components[2];
return _components[2] || 0.0;
}
/*!
@@ -528,7 +494,7 @@ var cachedBlackColor,
*/
- (float)greenComponent
{
return _components[1];
return _components[1] || 0.0;
}
/*!
@@ -536,7 +502,7 @@ var cachedBlackColor,
*/
- (float)redComponent
{
return _components[0];
return _components[0] || 0.0;
}
/*!
@@ -736,7 +702,7 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
var hexCharacters = "0123456789ABCDEF";
// HACK: prevent these from becoming globals. workaround for obj-j "function foo(){}" behavior
var hexToRGB, integerToBytes, rgbToHex, byteToHex;
var hexToRGB, rgbToHex, byteToHex;
/*!
Used for the CPColor \c +colorWithHexString: implementation
@@ -764,18 +730,6 @@ function hexToRGB(hex)
return [red, green, blue, 1.0];
}
function integerToBytes(integer, length) {
if (!length)
length = (integer == 0) ? 1 : Math.round((Math.log(integer)/Math.log(2))/8+0.5);
var bytes = new Array(length);
for (var i = length-1; i >= 0; i--) {
bytes[i] = integer & 255;
integer = integer >> 8
}
return bytes;
}
function rgbToHex(r,g,b) {
return byteToHex(r) + byteToHex(g) + byteToHex(b);
}
+49 -25
View File
@@ -1199,7 +1199,7 @@ var CPViewFlags = { },
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
{
if (anAlphaValue == 1.0)
if (anAlphaValue === 1.0)
try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
else
_DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
@@ -1317,56 +1317,72 @@ var CPViewFlags = { },
{
if (_backgroundColor == aColor)
return;
_backgroundColor = aColor;
#if PLATFORM(DOM)
var patternImage = [_backgroundColor patternImage],
colorExists = _backgroundColor && [_backgroundColor alphaComponent] > 0.0,
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
amount = 0;
if ([patternImage isThreePartImage])
{
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3 - _DOMImageParts.length;
}
else if ([patternImage isNinePartImage])
{
_backgroundType = BackgroundNinePartImage;
amount = 9 - _DOMImageParts.length;
amount = 9 - _DOMImageParts.length;
}
else
{
_backgroundType = BackgroundTrivialColor;
amount = 0 - _DOMImageParts.length;
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
}
if (amount > 0)
{
while (amount--)
{
var DOMElement = DOMElementPrototype.cloneNode(false);
DOMElement.style.zIndex = -1000;
_DOMImageParts.push(DOMElement);
_DOMElement.appendChild(DOMElement);
}
}
else
{
amount = -amount;
while (amount--)
_DOMElement.removeChild(_DOMImageParts.pop());
}
if (_backgroundType == BackgroundTrivialColor)
// Opera doesn't like DOM properties set to nil.
// https://trac.280north.com/ticket/7
_DOMElement.style.background = _backgroundColor ? [_backgroundColor cssString] : "";
if (_backgroundType === BackgroundTrivialColor)
{
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
if (colorNeedsDOMElement)
{
_DOMElement.style.background = "";
_DOMImageParts[0].style.background = [_backgroundColor cssString];
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
_DOMImageParts[0].style.filter = "alpha(opacity=" + [_backgroundColor alphaComponent] * 100 + ")";
else
_DOMImageParts[0].style.opacity = [_backgroundColor alphaComponent];
var size = [self bounds].size;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, size.height);
}
else
_DOMElement.style.background = colorCSS;
}
else
{
var slices = [patternImage imageSlices],
@@ -1377,23 +1393,31 @@ var CPViewFlags = { },
{
var image = slices[count],
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
if (!supportsRGBA)
{
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
try { _DOMImageParts[count].style.removeAttribute("filter") } catch (anException) { }
else
_DOMImageParts[count].style.opacity = 1.0;
}
}
if (_backgroundType == BackgroundNinePartImage)
{
var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
@@ -1407,7 +1431,7 @@ var CPViewFlags = { },
else if (_backgroundType == BackgroundVerticalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
@@ -1415,7 +1439,7 @@ var CPViewFlags = { },
else if (_backgroundType == BackgroundHorizontalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);