Created
February 17, 2015 15:27
-
-
Save beschulz/36cca0c38302bcd05618 to your computer and use it in GitHub Desktop.
juce_use_CGContextDrawXYZGradient_on_osx_10_5_plus.diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h | |
index bf26ce8..41a8571 100644 | |
--- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h | |
+++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h | |
@@ -77,7 +77,9 @@ private: | |
const CGFloat flipHeight; | |
float targetScale; | |
CGColorSpaceRef rgbColourSpace, greyColourSpace; | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
CGFunctionCallbacks gradientCallbacks; | |
+ #endif | |
mutable Rectangle<int> lastClipRect; | |
mutable bool lastClipRectIsValid; | |
@@ -88,9 +90,12 @@ private: | |
~SavedState(); | |
void setFill (const FillType& newFill); | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
CGShadingRef getShading (CoreGraphicsContext& owner); | |
- | |
static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData); | |
+ #else | |
+ CGGradientRef getGradient(CGColorSpaceRef colourSpace); | |
+ #endif | |
FillType fillType; | |
Font font; | |
@@ -98,9 +103,13 @@ private: | |
CGAffineTransform fontTransform; | |
private: | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
CGShadingRef shading; | |
HeapBlock <PixelARGB> gradientLookupTable; | |
int numGradientLookupEntries; | |
+ #else | |
+ CGGradientRef gradient; | |
+ #endif | |
}; | |
ScopedPointer <SavedState> state; | |
diff --git a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm | |
index 309a02a..c968295 100644 | |
--- a/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm | |
+++ b/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm | |
@@ -178,9 +178,11 @@ CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, const float h, const f | |
CGContextSetBlendMode (context, kCGBlendModeNormal); | |
rgbColourSpace = CGColorSpaceCreateDeviceRGB(); | |
greyColourSpace = CGColorSpaceCreateDeviceGray(); | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
gradientCallbacks.version = 0; | |
gradientCallbacks.evaluate = SavedState::gradientCallback; | |
gradientCallbacks.releaseInfo = 0; | |
+ #endif | |
setFont (Font()); | |
} | |
@@ -679,36 +681,62 @@ bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Re | |
CoreGraphicsContext::SavedState::SavedState() | |
: font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity), | |
- shading (0), numGradientLookupEntries (0) | |
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
+ shading (0), | |
+ numGradientLookupEntries (0) | |
+#else | |
+ gradient(0) | |
+#endif | |
{ | |
} | |
CoreGraphicsContext::SavedState::SavedState (const SavedState& other) | |
: fillType (other.fillType), font (other.font), fontRef (other.fontRef), | |
- fontTransform (other.fontTransform), shading (0), | |
+ fontTransform (other.fontTransform), | |
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
+ shading (0), | |
gradientLookupTable ((size_t) other.numGradientLookupEntries), | |
numGradientLookupEntries (other.numGradientLookupEntries) | |
+#else | |
+ gradient(0) | |
+#endif | |
{ | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
memcpy (gradientLookupTable, other.gradientLookupTable, sizeof (PixelARGB) * (size_t) numGradientLookupEntries); | |
+ #endif | |
} | |
CoreGraphicsContext::SavedState::~SavedState() | |
{ | |
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
if (shading != 0) | |
CGShadingRelease (shading); | |
+#else | |
+ if (gradient != 0) | |
+ CGGradientRelease(gradient); | |
+#endif | |
} | |
void CoreGraphicsContext::SavedState::setFill (const FillType& newFill) | |
{ | |
fillType = newFill; | |
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
if (fillType.isGradient() && shading != 0) | |
{ | |
CGShadingRelease (shading); | |
shading = 0; | |
} | |
+#else | |
+ if (fillType.isGradient() && gradient != 0) | |
+ { | |
+ CGGradientRelease (gradient); | |
+ gradient = 0; | |
+ } | |
+#endif | |
} | |
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
CGShadingRef CoreGraphicsContext::SavedState::getShading (CoreGraphicsContext& owner) | |
{ | |
if (shading == 0) | |
@@ -752,15 +780,76 @@ void CoreGraphicsContext::SavedState::gradientCallback (void* info, const CGFloa | |
outData[3] = colour.getAlpha() / 255.0f; | |
} | |
+#else | |
+ | |
+CGGradientRef CoreGraphicsContext::SavedState::getGradient(CGColorSpaceRef colourSpace) | |
+{ | |
+ if(gradient == 0) | |
+ { | |
+ ColourGradient& g = *(fillType.gradient); | |
+ | |
+ //CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); | |
+ | |
+ CGFloat* components = new CGFloat[g.getNumColours() * 4]; | |
+ CGFloat* locations = new CGFloat[g.getNumColours()]; | |
+ | |
+ for(int i=0; i!=g.getNumColours(); ++i) | |
+ { | |
+ Colour colour = g.getColour(i); | |
+ components[i * 4 + 0] = colour.getFloatRed(); | |
+ components[i * 4 + 1] = colour.getFloatGreen(); | |
+ components[i * 4 + 2] = colour.getFloatBlue(); | |
+ components[i * 4 + 3] = colour.getFloatAlpha(); | |
+ locations[i] = g.getColourPosition(i); | |
+ } | |
+ | |
+ gradient = CGGradientCreateWithColorComponents(colourSpace, components, locations, g.getNumColours()); | |
+ //CGColorSpaceRelease(colourSpace); | |
+ delete[] components; | |
+ delete[] locations; | |
+ } | |
+ | |
+ return gradient; | |
+} | |
+#endif | |
+ | |
void CoreGraphicsContext::drawGradient() | |
{ | |
flip(); | |
applyTransform (state->fillType.transform); | |
+ CGContextSetAlpha (context, state->fillType.getOpacity()); | |
+ #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |
CGContextSetInterpolationQuality (context, kCGInterpolationDefault); // (This is required for 10.4, where there's a crash if | |
// you draw a gradient with high quality interp enabled). | |
- CGContextSetAlpha (context, state->fillType.getOpacity()); | |
CGContextDrawShading (context, state->getShading (*this)); | |
+ #else | |
+ ColourGradient& g = *(state->fillType.gradient); | |
+ CGPoint p1 (convertToCGPoint (g.point1)); | |
+ CGPoint p2 (convertToCGPoint (g.point2)); | |
+ | |
+ state->fillType.transform.transformPoints(p1.x, p1.y, p2.x, p2.y); | |
+ | |
+ CGGradientRef gradient = state->getGradient(rgbColourSpace); | |
+ | |
+ if (g.isRadial) | |
+ { | |
+ CGFloat dx = p2.x-p1.x; | |
+ CGFloat dy = p2.y-p1.y; | |
+ CGFloat r = sqrt(dx*dx+dy*dy); | |
+ | |
+ CGContextDrawRadialGradient(context, gradient, | |
+ p1, 0, p1, r, | |
+ kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation | |
+ ); | |
+ } | |
+ else | |
+ { | |
+ CGContextDrawLinearGradient(context, gradient, | |
+ p1, p2, | |
+ kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); | |
+ } | |
+ #endif | |
} | |
void CoreGraphicsContext::createPath (const Path& path) const |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This patch modifies the CoreGraphicsContext of Juce to use CGGradient instead of CGShading for drawing gradients. The code that uses CGGradient is only enabled, if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 (because CGGradient did not exist back then).
This patch was necessary, because the SavedState object that is passed to CGFunctionCreate was already released when a page based CoreGraphics context starts to draw the gradients (indirectly via CGContextEndPage). Apparently drawing of gradients is deferred on page based Graphics Contexts (like CGPDFContextCreateWithURL).
Further Info:
http://www.juce.com/forum/topic/render-juce-screenshots-pdf-osx#comment-310182
https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGFunction/index.html#//apple_ref/c/func/CGFunctionCreate
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CGShading/index.html