mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-19 01:04:20 +00:00
Updated gradient rendering on OSX to use newer APIs.
This commit is contained in:
parent
cd2f7d6ffb
commit
8eb2fef209
2 changed files with 49 additions and 71 deletions
|
|
@ -77,7 +77,6 @@ private:
|
|||
const CGFloat flipHeight;
|
||||
float targetScale;
|
||||
CGColorSpaceRef rgbColourSpace, greyColourSpace;
|
||||
CGFunctionCallbacks gradientCallbacks;
|
||||
mutable Rectangle<int> lastClipRect;
|
||||
mutable bool lastClipRectIsValid;
|
||||
|
||||
|
|
@ -87,24 +86,17 @@ private:
|
|||
SavedState (const SavedState&);
|
||||
~SavedState();
|
||||
|
||||
void setFill (const FillType& newFill);
|
||||
CGShadingRef getShading (CoreGraphicsContext& owner);
|
||||
|
||||
static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData);
|
||||
void setFill (const FillType&);
|
||||
|
||||
FillType fillType;
|
||||
Font font;
|
||||
CGFontRef fontRef;
|
||||
CGAffineTransform fontTransform;
|
||||
|
||||
private:
|
||||
CGShadingRef shading;
|
||||
HeapBlock <PixelARGB> gradientLookupTable;
|
||||
int numGradientLookupEntries;
|
||||
CGGradientRef gradient;
|
||||
};
|
||||
|
||||
ScopedPointer <SavedState> state;
|
||||
OwnedArray <SavedState> stateStack;
|
||||
ScopedPointer<SavedState> state;
|
||||
OwnedArray<SavedState> stateStack;
|
||||
|
||||
void drawGradient();
|
||||
void createPath (const Path&) const;
|
||||
|
|
|
|||
|
|
@ -178,9 +178,6 @@ CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, const float h, const f
|
|||
CGContextSetBlendMode (context, kCGBlendModeNormal);
|
||||
rgbColourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
greyColourSpace = CGColorSpaceCreateDeviceGray();
|
||||
gradientCallbacks.version = 0;
|
||||
gradientCallbacks.evaluate = SavedState::gradientCallback;
|
||||
gradientCallbacks.releaseInfo = 0;
|
||||
setFont (Font());
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +248,7 @@ bool CoreGraphicsContext::clipToRectangleListWithoutTest (const RectangleList<in
|
|||
else
|
||||
{
|
||||
const size_t numRects = (size_t) clipRegion.getNumRectangles();
|
||||
HeapBlock <CGRect> rects (numRects);
|
||||
HeapBlock<CGRect> rects (numRects);
|
||||
|
||||
int i = 0;
|
||||
for (const Rectangle<int>* r = clipRegion.begin(), * const e = clipRegion.end(); r != e; ++r)
|
||||
|
|
@ -519,7 +516,7 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
|
|||
while (x > clip.origin.x) x -= iw;
|
||||
while (y > clip.origin.y) y -= ih;
|
||||
|
||||
const int right = (int) (clip.origin.x + clip.size.width);
|
||||
const int right = (int) (clip.origin.x + clip.size.width);
|
||||
const int bottom = (int) (clip.origin.y + clip.size.height);
|
||||
|
||||
while (y < bottom)
|
||||
|
|
@ -600,7 +597,7 @@ void CoreGraphicsContext::setFont (const Font& newFont)
|
|||
state->fontRef = 0;
|
||||
state->font = newFont;
|
||||
|
||||
if (OSXTypeface* osxTypeface = dynamic_cast <OSXTypeface*> (state->font.getTypeface()))
|
||||
if (OSXTypeface* osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
|
||||
{
|
||||
state->fontRef = osxTypeface->fontRef;
|
||||
CGContextSetFont (context, state->fontRef);
|
||||
|
|
@ -678,89 +675,78 @@ bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Re
|
|||
}
|
||||
|
||||
CoreGraphicsContext::SavedState::SavedState()
|
||||
: font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity),
|
||||
shading (0), numGradientLookupEntries (0)
|
||||
: font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity), gradient (0)
|
||||
{
|
||||
}
|
||||
|
||||
CoreGraphicsContext::SavedState::SavedState (const SavedState& other)
|
||||
: fillType (other.fillType), font (other.font), fontRef (other.fontRef),
|
||||
fontTransform (other.fontTransform), shading (0),
|
||||
gradientLookupTable ((size_t) other.numGradientLookupEntries),
|
||||
numGradientLookupEntries (other.numGradientLookupEntries)
|
||||
fontTransform (other.fontTransform), gradient (other.gradient)
|
||||
{
|
||||
memcpy (gradientLookupTable, other.gradientLookupTable, sizeof (PixelARGB) * (size_t) numGradientLookupEntries);
|
||||
if (gradient != 0)
|
||||
CGGradientRetain (gradient);
|
||||
}
|
||||
|
||||
CoreGraphicsContext::SavedState::~SavedState()
|
||||
{
|
||||
if (shading != 0)
|
||||
CGShadingRelease (shading);
|
||||
if (gradient != 0)
|
||||
CGGradientRelease (gradient);
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::SavedState::setFill (const FillType& newFill)
|
||||
{
|
||||
fillType = newFill;
|
||||
|
||||
if (fillType.isGradient() && shading != 0)
|
||||
if (gradient != 0)
|
||||
{
|
||||
CGShadingRelease (shading);
|
||||
shading = 0;
|
||||
CGGradientRelease (gradient);
|
||||
gradient = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CGShadingRef CoreGraphicsContext::SavedState::getShading (CoreGraphicsContext& owner)
|
||||
static CGGradientRef createGradient (const ColourGradient& g, CGColorSpaceRef colourSpace)
|
||||
{
|
||||
if (shading == 0)
|
||||
const int numColours = g.getNumColours();
|
||||
CGFloat* const data = (CGFloat*) alloca (numColours * 5 * sizeof (CGFloat));
|
||||
CGFloat* const locations = data;
|
||||
CGFloat* const components = data + numColours;
|
||||
CGFloat* comps = components;
|
||||
|
||||
for (int i = 0; i < numColours; ++i)
|
||||
{
|
||||
ColourGradient& g = *(fillType.gradient);
|
||||
numGradientLookupEntries = g.createLookupTable (fillType.transform, gradientLookupTable) - 1;
|
||||
|
||||
CGFunctionRef function = CGFunctionCreate (this, 1, 0, 4, 0, &(owner.gradientCallbacks));
|
||||
CGPoint p1 (convertToCGPoint (g.point1));
|
||||
|
||||
if (g.isRadial)
|
||||
{
|
||||
shading = CGShadingCreateRadial (owner.rgbColourSpace, p1, 0,
|
||||
p1, g.point1.getDistanceFrom (g.point2),
|
||||
function, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
shading = CGShadingCreateAxial (owner.rgbColourSpace, p1,
|
||||
convertToCGPoint (g.point2),
|
||||
function, true, true);
|
||||
}
|
||||
|
||||
CGFunctionRelease (function);
|
||||
const Colour colour (g.getColour (i));
|
||||
*comps++ = colour.getFloatRed();
|
||||
*comps++ = colour.getFloatGreen();
|
||||
*comps++ = colour.getFloatBlue();
|
||||
*comps++ = colour.getFloatAlpha();
|
||||
locations[i] = g.getColourPosition (i);
|
||||
}
|
||||
|
||||
return shading;
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::SavedState::gradientCallback (void* info, const CGFloat* inData, CGFloat* outData)
|
||||
{
|
||||
const SavedState* const s = static_cast <const SavedState*> (info);
|
||||
|
||||
const int index = roundToInt (s->numGradientLookupEntries * inData[0]);
|
||||
PixelARGB colour (s->gradientLookupTable [jlimit (0, s->numGradientLookupEntries, index)]);
|
||||
colour.unpremultiply();
|
||||
|
||||
outData[0] = colour.getRed() / 255.0f;
|
||||
outData[1] = colour.getGreen() / 255.0f;
|
||||
outData[2] = colour.getBlue() / 255.0f;
|
||||
outData[3] = colour.getAlpha() / 255.0f;
|
||||
return CGGradientCreateWithColorComponents (colourSpace, components, locations, numColours);
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::drawGradient()
|
||||
{
|
||||
flip();
|
||||
applyTransform (state->fillType.transform);
|
||||
|
||||
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));
|
||||
|
||||
const 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);
|
||||
|
||||
if (state->gradient == 0)
|
||||
state->gradient = createGradient (g, rgbColourSpace);
|
||||
|
||||
if (g.isRadial)
|
||||
CGContextDrawRadialGradient (context, state->gradient, p1, 0, p1, g.point1.getDistanceFrom (g.point2),
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
else
|
||||
CGContextDrawLinearGradient (context, state->gradient, p1, p2,
|
||||
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
}
|
||||
|
||||
void CoreGraphicsContext::createPath (const Path& path) const
|
||||
|
|
@ -917,7 +903,7 @@ CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef
|
|||
|
||||
CGContextRef juce_getImageContext (const Image& image)
|
||||
{
|
||||
if (CoreGraphicsImage* const cgi = dynamic_cast <CoreGraphicsImage*> (image.getPixelData()))
|
||||
if (CoreGraphicsImage* const cgi = dynamic_cast<CoreGraphicsImage*> (image.getPixelData()))
|
||||
return cgi->context;
|
||||
|
||||
jassertfalse;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue