diff options
Diffstat (limited to 'WebCore/platform/graphics/cg/ColorCG.cpp')
-rw-r--r-- | WebCore/platform/graphics/cg/ColorCG.cpp | 93 |
1 files changed, 68 insertions, 25 deletions
diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp index 6f05c38..c9b05da 100644 --- a/WebCore/platform/graphics/cg/ColorCG.cpp +++ b/WebCore/platform/graphics/cg/ColorCG.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,6 +28,7 @@ #if PLATFORM(CG) +#include "GraphicsContextCG.h" #include <wtf/Assertions.h> #include <wtf/RetainPtr.h> #include <ApplicationServices/ApplicationServices.h> @@ -69,37 +70,79 @@ Color::Color(CGColorRef color) m_valid = true; } -#if OS(WINDOWS) +static inline CGColorSpaceRef cachedCGColorSpace(ColorSpace colorSpace) +{ + switch (colorSpace) { + case ColorSpaceDeviceRGB: + return deviceRGBColorSpaceRef(); + case ColorSpaceSRGB: + return sRGBColorSpaceRef(); + case ColorSpaceLinearRGB: + return linearRGBColorSpaceRef(); + } + ASSERT_NOT_REACHED(); + return deviceRGBColorSpaceRef(); +} -CGColorRef createCGColor(const Color& c) +static CGColorRef leakCGColor(const Color& color, ColorSpace colorSpace) { - CGColorRef color = NULL; -#ifdef OBSOLETE_COLORSYNC_API - CMProfileRef prof = NULL; - CMGetSystemProfile(&prof); - RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(prof)); -#else - ColorSyncProfileRef prof = ColorSyncProfileCreateWithDisplayID(0); - RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(const_cast<void*>(reinterpret_cast<const void*>(prof)))); -#endif - - if (rgbSpace) { - CGFloat components[4] = { static_cast<CGFloat>(c.red()) / 255, static_cast<CGFloat>(c.green()) / 255, - static_cast<CGFloat>(c.blue()) / 255, static_cast<CGFloat>(c.alpha()) / 255 }; - color = CGColorCreate(rgbSpace.get(), components); + CGFloat components[4]; + color.getRGBA(components[0], components[1], components[2], components[3]); + return CGColorCreate(cachedCGColorSpace(colorSpace), components); +} + +template<ColorSpace colorSpace> static CGColorRef cachedCGColor(const Color& color) +{ + switch (color.rgb()) { + case Color::transparent: { + static CGColorRef transparentCGColor = leakCGColor(color, colorSpace); + return transparentCGColor; + } + case Color::black: { + static CGColorRef blackCGColor = leakCGColor(color, colorSpace); + return blackCGColor; + } + case Color::white: { + static CGColorRef whiteCGColor = leakCGColor(color, colorSpace); + return whiteCGColor; + } } -#ifdef OBSOLETE_COLORSYNC_API - CMCloseProfile(prof); -#else - if (prof) - CFRelease(prof); -#endif + ASSERT(color.rgb()); - return color; + const size_t cacheSize = 32; + static RGBA32 cachedRGBAValues[cacheSize]; + static RetainPtr<CGColorRef>* cachedCGColors = new RetainPtr<CGColorRef>[cacheSize]; + + for (size_t i = 0; i < cacheSize; ++i) { + if (cachedRGBAValues[i] == color.rgb()) + return cachedCGColors[i].get(); + } + + CGColorRef newCGColor = leakCGColor(color, colorSpace); + + static size_t cursor; + cachedRGBAValues[cursor] = color.rgb(); + cachedCGColors[cursor].adoptCF(newCGColor); + if (++cursor == cacheSize) + cursor = 0; + + return newCGColor; } -#endif // OS(WINDOWS) +CGColorRef cachedCGColor(const Color& color, ColorSpace colorSpace) +{ + switch (colorSpace) { + case ColorSpaceDeviceRGB: + return cachedCGColor<ColorSpaceDeviceRGB>(color); + case ColorSpaceSRGB: + return cachedCGColor<ColorSpaceSRGB>(color); + case ColorSpaceLinearRGB: + return cachedCGColor<ColorSpaceLinearRGB>(color); + } + ASSERT_NOT_REACHED(); + return cachedCGColor(color, ColorSpaceDeviceRGB); +} } |