2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "GraphicsContextCG.h"
32 #include <wtf/Assertions.h>
33 #include <wtf/RetainPtr.h>
34 #include <ApplicationServices/ApplicationServices.h>
38 Color::Color(CGColorRef color)
46 size_t numComponents = CGColorGetNumberOfComponents(color);
47 const CGFloat* components = CGColorGetComponents(color);
54 switch (numComponents) {
56 r = g = b = components[0];
69 m_color = makeRGBA(r * 255, g * 255, b * 255, a * 255);
73 static inline CGColorSpaceRef cachedCGColorSpace(ColorSpace colorSpace)
76 case ColorSpaceDeviceRGB:
77 return deviceRGBColorSpaceRef();
79 return sRGBColorSpaceRef();
80 case ColorSpaceLinearRGB:
81 return linearRGBColorSpaceRef();
84 return deviceRGBColorSpaceRef();
87 static CGColorRef leakCGColor(const Color& color, ColorSpace colorSpace)
89 CGFloat components[4];
90 color.getRGBA(components[0], components[1], components[2], components[3]);
91 return CGColorCreate(cachedCGColorSpace(colorSpace), components);
94 template<ColorSpace colorSpace> static CGColorRef cachedCGColor(const Color& color)
96 switch (color.rgb()) {
97 case Color::transparent: {
98 static CGColorRef transparentCGColor = leakCGColor(color, colorSpace);
99 return transparentCGColor;
102 static CGColorRef blackCGColor = leakCGColor(color, colorSpace);
106 static CGColorRef whiteCGColor = leakCGColor(color, colorSpace);
113 const size_t cacheSize = 32;
114 static RGBA32 cachedRGBAValues[cacheSize];
115 static RetainPtr<CGColorRef>* cachedCGColors = new RetainPtr<CGColorRef>[cacheSize];
117 for (size_t i = 0; i < cacheSize; ++i) {
118 if (cachedRGBAValues[i] == color.rgb())
119 return cachedCGColors[i].get();
122 CGColorRef newCGColor = leakCGColor(color, colorSpace);
124 static size_t cursor;
125 cachedRGBAValues[cursor] = color.rgb();
126 cachedCGColors[cursor].adoptCF(newCGColor);
127 if (++cursor == cacheSize)
133 CGColorRef cachedCGColor(const Color& color, ColorSpace colorSpace)
135 switch (colorSpace) {
136 case ColorSpaceDeviceRGB:
137 return cachedCGColor<ColorSpaceDeviceRGB>(color);
139 return cachedCGColor<ColorSpaceSRGB>(color);
140 case ColorSpaceLinearRGB:
141 return cachedCGColor<ColorSpaceLinearRGB>(color);
143 ASSERT_NOT_REACHED();
144 return cachedCGColor(color, ColorSpaceDeviceRGB);