28 var _redComponent = 0,
33 var _hueComponent = 0,
34 _saturationComponent = 1,
35 _brightnessComponent = 2;
87 if (arguments.length < 3)
89 var slices = arguments[0],
92 for (var i = 0; i < slices.length; ++i)
94 var slice = slices[i];
96 imageSlices.push(slice ?
CPImageInBundle(slice[0], CGSizeMake(slice[1], slice[2]), slice[3]) : nil);
99 if (imageSlices.length === 3)
104 else if (arguments.length === 3 || arguments.length === 4)
106 return [
CPColor colorWithPatternImage:
CPImageInBundle(arguments[0], CGSizeMake(arguments[1], arguments[2]), arguments[3])];
144 + (
CPColor)colorWithRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
146 return [[
CPColor alloc] _initWithRGBA:[MAX(0.0, MIN(1.0, red)), MAX(0.0, MIN(1.0, green)), MAX(0.0, MIN(1.0, blue)), MAX(0.0, MIN(1.0, alpha))]];
164 + (
CPColor)colorWithCalibratedRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
179 + (
CPColor)colorWithWhite:(
float)white alpha:(
float)alpha
181 return [[
CPColor alloc] _initWithRGBA:[white, white, white, alpha]];
195 + (
CPColor)colorWithCalibratedWhite:(
float)white alpha:(
float)alpha
209 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness
214 + (
CPColor)colorWithHue:(
float)hue saturation:(
float)saturation brightness:(
float)brightness alpha:(
float)alpha
216 if (saturation === 0.0)
220 p = (brightness * (100 - saturation)) / 10000,
221 q = (brightness * (6000 - saturation * f)) / 600000,
222 t = (brightness * (6000 - saturation * (60 -f))) / 600000,
223 b = brightness / 100.0;
225 switch (FLOOR(hue / 60))
248 var rgba = hexToRGB(hex);
249 return rgba ? [[
CPColor alloc] _initWithRGBA: rgba] : null;
256 + (
CPColor)colorWithSRGBRed:(
float)red green:(
float)green blue:(
float)blue alpha:(
float)alpha
268 if (!cachedBlackColor)
269 cachedBlackColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0]];
271 return cachedBlackColor;
279 if (!cachedBlueColor)
280 cachedBlueColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 1.0, 1.0]];
282 return cachedBlueColor;
290 if (!cachedDarkGrayColor)
293 return cachedDarkGrayColor;
301 if (!cachedGrayColor)
304 return cachedGrayColor;
312 if (!cachedGreenColor)
313 cachedGreenColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 0.0, 1.0]];
315 return cachedGreenColor;
323 if (!cachedLightGrayColor)
326 return cachedLightGrayColor;
335 cachedRedColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 0.0, 1.0]];
337 return cachedRedColor;
345 if (!cachedWhiteColor)
346 cachedWhiteColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 1.0, 1.0]];
348 return cachedWhiteColor;
356 if (!cachedYellowColor)
357 cachedYellowColor = [[
CPColor alloc] _initWithRGBA:[1.0, 1.0, 0.0, 1.0]];
359 return cachedYellowColor;
367 if (!cachedBrownColor)
368 cachedBrownColor = [[
CPColor alloc] _initWithRGBA:[0.6, 0.4, 0.2, 1.0]];
370 return cachedBrownColor;
378 if (!cachedCyanColor)
379 cachedCyanColor = [[
CPColor alloc] _initWithRGBA:[0.0, 1.0, 1.0, 1.0]];
381 return cachedCyanColor;
389 if (!cachedMagentaColor)
390 cachedMagentaColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.0, 1.0, 1.0]];
392 return cachedMagentaColor;
400 if (!cachedOrangeColor)
401 cachedOrangeColor = [[
CPColor alloc] _initWithRGBA:[1.0, 0.5, 0.0, 1.0]];
403 return cachedOrangeColor;
411 if (!cachedPurpleColor)
412 cachedPurpleColor = [[
CPColor alloc] _initWithRGBA:[0.5, 0.0, 0.5, 1.0]];
414 return cachedPurpleColor;
423 if (!cachedShadowColor)
424 cachedShadowColor = [[
CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0 / 3.0]];
426 return cachedShadowColor;
435 if (!cachedClearColor)
438 return cachedClearColor;
443 return [[
CPColor alloc] _initWithRGBA:[0.22, 0.46, 0.84, 1.0]];
448 return [[
CPColor alloc] _initWithRGBA:[0.83, 0.83, 0.83, 1.0]];
473 - (id)_initWithCSSString:(
CPString)aString
480 var startingIndex = aString.indexOf(
"("),
481 parts = aString.substring(startingIndex + 1).split(
',');
484 parseInt(parts[0], 10) / 255.0,
485 parseInt(parts[1], 10) / 255.0,
486 parseInt(parts[2], 10) / 255.0,
487 parts[3] ? parseFloat(parts[3], 10) : 1.0
492 [
self _initCSSStringFromComponents];
498 - (id)_initWithRGBA:(
CPArray)components
504 _components = components;
506 [
self _initCSSStringFromComponents];
512 - (void)_initCSSStringFromComponents
516 _cssString = (hasAlpha ?
"rgba(" :
"rgb(") +
517 parseInt(_components[0] * 255.0) + ", " +
518 parseInt(_components[1] * 255.0) + ", " +
519 parseInt(_components[2] * 255.0) +
520 (hasAlpha ? (", " + _components[3]) : "") + ")";
524 - (id)_initWithPatternImage:(
CPImage)anImage
530 _patternImage = anImage;
531 _cssString =
"url(\"" + [_patternImage filename] + "\")";
532 _components = [0.0, 0.0, 0.0, 1.0];
543 return _patternImage;
549 - (float)alphaComponent
551 return _components[3];
557 - (float)blueComponent
559 return _components[2];
565 - (float)greenComponent
567 return _components[1];
573 - (float)redComponent
575 return _components[0];
601 - (
CPColor)colorWithAlphaComponent:(
float)anAlphaComponent
603 var components = _components.slice();
605 components[components.length - 1] = anAlphaComponent;
607 return [[[
self class] alloc] _initWithRGBA:components];
613 - (
CPColor)colorUsingColorSpaceName:(
id)aColorSpaceName
630 var red = ROUND(_components[_redComponent] * 255.0),
631 green = ROUND(_components[_greenComponent] * 255.0),
632 blue = ROUND(_components[_blueComponent] * 255.0);
634 var max = MAX(red, green, blue),
635 min = MIN(red, green, blue),
638 var brightness = max / 255.0,
639 saturation = (max != 0) ? delta / max : 0;
649 var rr = (max - red) / delta,
650 gr = (max - green) / delta,
651 br = (max - blue) / delta;
655 else if (green == max)
667 ROUND(saturation * 100.0),
668 ROUND(brightness * 100.0)
691 return rgbToHex([
self redComponent], [
self greenComponent], [
self blueComponent]);
702 if (![aColor isKindOfClass:
CPColor])
705 if (_patternImage || [aColor patternImage])
711 return ROUND([
self redComponent] * 255.0) == ROUND([aColor redComponent] * 255.0) &&
712 ROUND([
self greenComponent] * 255.0) == ROUND([aColor greenComponent] * 255.0) &&
713 ROUND([
self blueComponent] * 255.0) == ROUND([aColor blueComponent] * 255.0) &&
723 return description +
" " + [
self cssString];
725 description +=
" {\n";
727 if ([patternImage isThreePartImage] || [patternImage isNinePartImage])
731 if ([patternImage isThreePartImage])
732 description +=
" orientation: " + ([
patternImage isVertical] ?
"vertical" :
"horizontal") +
",\n";
734 description +=
" patternImage (" + slices.
length +
" part): [\n";
736 for (var i = 0; i < slices.length; ++i)
738 var imgDescription = [slices[i] description];
740 description += imgDescription.replace(/^/mg,
" ") +
",\n";
743 description = description.substr(0, description.length - 2) +
"\n ]\n}";
794 var CPColorComponentsKey =
@"CPColorComponentsKey",
795 CPColorPatternImageKey =
@"CPColorPatternImageKey";
806 if ([aCoder containsValueForKey:CPColorPatternImageKey])
807 return [
self _initWithPatternImage:[aCoder decodeObjectForKey:CPColorPatternImageKey]];
809 return [
self _initWithRGBA:[aCoder decodeObjectForKey:CPColorComponentsKey]];
819 [aCoder encodeObject:_patternImage forKey:CPColorPatternImageKey];
821 [aCoder encodeObject:_components forKey:CPColorComponentsKey];
828 var hexCharacters =
"0123456789ABCDEF";
834 var hexToRGB =
function(hex)
837 hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
842 hex = hex.toUpperCase();
844 for (var i = 0; i < hex.length; i++)
845 if (hexCharacters.indexOf(hex.charAt(i)) == -1)
848 var red = (hexCharacters.indexOf(hex.charAt(0)) * 16 + hexCharacters.indexOf(hex.charAt(1))) / 255.0,
849 green = (hexCharacters.indexOf(hex.charAt(2)) * 16 + hexCharacters.indexOf(hex.charAt(3))) / 255.0,
850 blue = (hexCharacters.indexOf(hex.charAt(4)) * 16 + hexCharacters.indexOf(hex.charAt(5))) / 255.0;
852 return [red, green, blue, 1.0];
855 var rgbToHex =
function(r,g,b)
857 return byteToHex(r) + byteToHex(g) + byteToHex(b);
860 var byteToHex =
function(n)
865 n = FLOOR(MIN(255, MAX(0, 256 * n)));
867 return hexCharacters.charAt((n - n % 16) / 16) +
868 hexCharacters.charAt(n % 16);