mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-11 23:54:18 +00:00
More graphics updates, including fixes for CoreGraphics on PPC macs. Fix for keypress recursion in AU plugins, and fix for tabs in the CodeEditorComponent
This commit is contained in:
parent
01f109e857
commit
95fcc168d8
7 changed files with 271 additions and 594 deletions
|
|
@ -1359,8 +1359,14 @@ private:
|
|||
{
|
||||
// If we have an unused keypress, move the key-focus to a host window
|
||||
// and re-inject the event..
|
||||
[[hostWindow parentWindow] makeKeyWindow];
|
||||
[NSApp postEvent: [NSApp currentEvent] atStart: YES];
|
||||
static NSTimeInterval lastEventTime = 0; // check we're not recursively sending the same event
|
||||
|
||||
if (lastEventTime != [[NSApp currentEvent] timestamp])
|
||||
{
|
||||
lastEventTime = [[NSApp currentEvent] timestamp];
|
||||
[[hostWindow parentWindow] makeKeyWindow];
|
||||
[NSApp postEvent: [NSApp currentEvent] atStart: YES];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -730,7 +730,7 @@ public:
|
|||
the rest of the codebase.
|
||||
*/
|
||||
|
||||
#define USE_COREGRAPHICS_RENDERING 0
|
||||
#define USE_COREGRAPHICS_RENDERING 1
|
||||
|
||||
#if JUCE_IPHONE
|
||||
#import <Foundation/Foundation.h>
|
||||
|
|
@ -44829,8 +44829,11 @@ void CodeEditorComponent::insertTextAtCaret (const String& newText)
|
|||
|
||||
void CodeEditorComponent::insertTabAtCaret()
|
||||
{
|
||||
if (CharacterFunctions::isWhitespace (caretPos.getCharacter()))
|
||||
if (CharacterFunctions::isWhitespace (caretPos.getCharacter())
|
||||
&& caretPos.getLineNumber() == caretPos.movedBy (1).getLineNumber())
|
||||
{
|
||||
moveCaretTo (document.findWordBreakAfter (caretPos), false);
|
||||
}
|
||||
|
||||
if (useSpacesForTabs)
|
||||
{
|
||||
|
|
@ -261310,6 +261313,7 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri
|
|||
class CoreGraphicsImage : public Image
|
||||
{
|
||||
public:
|
||||
|
||||
CoreGraphicsImage (const PixelFormat format,
|
||||
const int imageWidth,
|
||||
const int imageHeight,
|
||||
|
|
@ -261320,9 +261324,7 @@ public:
|
|||
: CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
|
||||
colourSpace,
|
||||
format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault);
|
||||
colourSpace, getCGImageFlags (*this));
|
||||
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
}
|
||||
|
|
@ -261334,7 +261336,62 @@ public:
|
|||
|
||||
LowLevelGraphicsContext* createLowLevelContext();
|
||||
|
||||
static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace, getCGImageFlags (juceImage), provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static NSImage* createNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im setSize: NSMakeSize (image.getWidth(), image.getHeight())];
|
||||
[im lockFocus];
|
||||
|
||||
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef imageRef = createImage (image, false, colourSpace);
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
|
||||
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextDrawImage (cg, CGRectMake (0, 0, image.getWidth(), image.getHeight()), imageRef);
|
||||
|
||||
CGImageRelease (imageRef);
|
||||
[im unlockFocus];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
CGContextRef context;
|
||||
|
||||
private:
|
||||
static CGBitmapInfo getCGImageFlags (const Image& image) throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big) : kCGBitmapByteOrderDefault;
|
||||
#else
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
|
||||
|
|
@ -261423,7 +261480,7 @@ public:
|
|||
if (! transform.isSingularity())
|
||||
{
|
||||
Image* singleChannelImage = createAlphaChannelImage (sourceImage);
|
||||
CGImageRef image = createImage (*singleChannelImage, true);
|
||||
CGImageRef image = CoreGraphicsImage::createImage (*singleChannelImage, true, greyColourSpace);
|
||||
|
||||
flip();
|
||||
AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
|
||||
|
|
@ -261589,7 +261646,7 @@ public:
|
|||
void drawImage (const Image& sourceImage, const Rectangle& srcClip,
|
||||
const AffineTransform& transform, const bool fillEntireClipAsTiles)
|
||||
{
|
||||
CGImageRef fullImage = createImage (sourceImage, false);
|
||||
CGImageRef fullImage = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace);
|
||||
CGImageRef image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClip.getX(), sourceImage.getHeight() - srcClip.getBottom(),
|
||||
srcClip.getWidth(), srcClip.getHeight()));
|
||||
CGImageRelease (fullImage);
|
||||
|
|
@ -261887,35 +261944,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace,
|
||||
(juceImage.hasAlphaChannel() && ! forAlpha)
|
||||
? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault,
|
||||
provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static Image* createAlphaChannelImage (const Image& im) throw()
|
||||
{
|
||||
if (im.getFormat() == Image::SingleChannel)
|
||||
|
|
@ -263519,38 +263547,9 @@ void juce_glViewport (const int w, const int h)
|
|||
|
||||
#if JUCE_MAC
|
||||
|
||||
static NSImage* juceImageToNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
const Image::BitmapData srcData (image, 0, 0, image.getWidth(), image.getHeight());
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: srcData.width
|
||||
pixelsHigh: srcData.height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
|
||||
hasAlpha: image.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: srcData.lineStride
|
||||
bitsPerPixel: srcData.pixelStride * 8];
|
||||
|
||||
unsigned char* newData = [rep bitmapData];
|
||||
memcpy (newData, srcData.data, srcData.lineStride * srcData.height);
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im addRepresentation: rep];
|
||||
[rep release];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
|
||||
{
|
||||
NSImage* im = juceImageToNSImage (image);
|
||||
NSImage* im = CoreGraphicsImage::createNSImage (image);
|
||||
NSCursor* c = [[NSCursor alloc] initWithImage: im
|
||||
hotSpot: NSMakePoint (hotspotX, hotspotY)];
|
||||
[im release];
|
||||
|
|
@ -265759,6 +265758,7 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri
|
|||
class CoreGraphicsImage : public Image
|
||||
{
|
||||
public:
|
||||
|
||||
CoreGraphicsImage (const PixelFormat format,
|
||||
const int imageWidth,
|
||||
const int imageHeight,
|
||||
|
|
@ -265769,9 +265769,7 @@ public:
|
|||
: CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
|
||||
colourSpace,
|
||||
format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault);
|
||||
colourSpace, getCGImageFlags (*this));
|
||||
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
}
|
||||
|
|
@ -265783,7 +265781,62 @@ public:
|
|||
|
||||
LowLevelGraphicsContext* createLowLevelContext();
|
||||
|
||||
static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace, getCGImageFlags (juceImage), provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static NSImage* createNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im setSize: NSMakeSize (image.getWidth(), image.getHeight())];
|
||||
[im lockFocus];
|
||||
|
||||
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef imageRef = createImage (image, false, colourSpace);
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
|
||||
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextDrawImage (cg, CGRectMake (0, 0, image.getWidth(), image.getHeight()), imageRef);
|
||||
|
||||
CGImageRelease (imageRef);
|
||||
[im unlockFocus];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
CGContextRef context;
|
||||
|
||||
private:
|
||||
static CGBitmapInfo getCGImageFlags (const Image& image) throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big) : kCGBitmapByteOrderDefault;
|
||||
#else
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
|
||||
|
|
@ -265872,7 +265925,7 @@ public:
|
|||
if (! transform.isSingularity())
|
||||
{
|
||||
Image* singleChannelImage = createAlphaChannelImage (sourceImage);
|
||||
CGImageRef image = createImage (*singleChannelImage, true);
|
||||
CGImageRef image = CoreGraphicsImage::createImage (*singleChannelImage, true, greyColourSpace);
|
||||
|
||||
flip();
|
||||
AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
|
||||
|
|
@ -266038,7 +266091,7 @@ public:
|
|||
void drawImage (const Image& sourceImage, const Rectangle& srcClip,
|
||||
const AffineTransform& transform, const bool fillEntireClipAsTiles)
|
||||
{
|
||||
CGImageRef fullImage = createImage (sourceImage, false);
|
||||
CGImageRef fullImage = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace);
|
||||
CGImageRef image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClip.getX(), sourceImage.getHeight() - srcClip.getBottom(),
|
||||
srcClip.getWidth(), srcClip.getHeight()));
|
||||
CGImageRelease (fullImage);
|
||||
|
|
@ -266336,35 +266389,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace,
|
||||
(juceImage.hasAlphaChannel() && ! forAlpha)
|
||||
? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault,
|
||||
provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static Image* createAlphaChannelImage (const Image& im) throw()
|
||||
{
|
||||
if (im.getFormat() == Image::SingleChannel)
|
||||
|
|
@ -266928,122 +266952,6 @@ END_JUCE_NAMESPACE
|
|||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
class JuceNSImage
|
||||
{
|
||||
public:
|
||||
JuceNSImage (const int width, const int height, const bool hasAlpha)
|
||||
: juceImage (hasAlpha ? Image::ARGB : Image::RGB,
|
||||
width, height, hasAlpha),
|
||||
srcData (juceImage, 0, 0, width, height)
|
||||
{
|
||||
imageRep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: (unsigned char**) &(srcData.data)
|
||||
pixelsWide: width
|
||||
pixelsHigh: height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: srcData.pixelStride
|
||||
hasAlpha: hasAlpha
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0
|
||||
bytesPerRow: srcData.lineStride
|
||||
bitsPerPixel: 8 * srcData.pixelStride ];
|
||||
}
|
||||
|
||||
~JuceNSImage()
|
||||
{
|
||||
[imageRep release];
|
||||
}
|
||||
|
||||
Image& getJuceImage() throw() { return juceImage; }
|
||||
|
||||
void draw (const float x, const float y,
|
||||
const RectangleList& clip,
|
||||
const int originX, const int originY) const
|
||||
{
|
||||
// Our data is BGRA and the damned image rep only takes RGBA, so
|
||||
// we need to byte-swap the active areas if there's an alpha channel...
|
||||
if (juceImage.hasAlphaChannel())
|
||||
{
|
||||
RectangleList::Iterator iter (clip);
|
||||
while (iter.next())
|
||||
{
|
||||
const Rectangle* const r = iter.getRectangle();
|
||||
|
||||
swapRGBOrder (r->getX() + originX,
|
||||
r->getY() + originY,
|
||||
r->getWidth(),
|
||||
r->getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
NSPoint p;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
[imageRep drawAtPoint: p];
|
||||
}
|
||||
|
||||
void drawNSImage (NSImage* imageToDraw)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:
|
||||
[NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
|
||||
|
||||
[imageToDraw drawAtPoint: NSZeroPoint
|
||||
fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
|
||||
operation: NSCompositeSourceOver
|
||||
fraction: 1.0f];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
if (juceImage.hasAlphaChannel())
|
||||
swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
}
|
||||
|
||||
private:
|
||||
Image juceImage;
|
||||
NSBitmapImageRep* imageRep;
|
||||
const Image::BitmapData srcData;
|
||||
|
||||
void swapRGBOrder (const int x, const int y, const int w, int h) const
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
jassert (srcData.pixelStride == 4);
|
||||
#endif
|
||||
jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
|
||||
.contains (Rectangle (x, y, w, h)));
|
||||
|
||||
uint8* start = srcData.getPixelPointer (x, y);
|
||||
|
||||
while (--h >= 0)
|
||||
{
|
||||
uint8* p = start;
|
||||
start += srcData.lineStride;
|
||||
|
||||
for (int i = w; --i >= 0;)
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
const uint8 oldp3 = p[3];
|
||||
const uint8 oldp1 = p[1];
|
||||
p[3] = p[0];
|
||||
p[0] = oldp1;
|
||||
p[1] = p[2];
|
||||
p[2] = oldp3;
|
||||
#else
|
||||
const uint8 oldp0 = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = oldp0;
|
||||
#endif
|
||||
|
||||
p += srcData.pixelStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ComponentPeer* currentlyFocusedPeer = 0;
|
||||
static VoidArray keysCurrentlyDown;
|
||||
|
||||
|
|
@ -267801,28 +267709,26 @@ void NSViewComponentPeer::drawRect (NSRect r)
|
|||
if (r.size.width < 1.0f || r.size.height < 1.0f)
|
||||
return;
|
||||
|
||||
#if USE_COREGRAPHICS_RENDERING
|
||||
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
if (! component->isOpaque())
|
||||
CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
|
||||
|
||||
#if USE_COREGRAPHICS_RENDERING
|
||||
CoreGraphicsContext context (cg, [view frame].size.height);
|
||||
|
||||
insideDrawRect = true;
|
||||
handlePaint (context);
|
||||
insideDrawRect = false;
|
||||
#else
|
||||
const float y = [view frame].size.height - (r.origin.y + r.size.height);
|
||||
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
|
||||
(int) (r.size.width + 0.5f),
|
||||
(int) (r.size.height + 0.5f),
|
||||
! getComponent()->isOpaque());
|
||||
|
||||
JuceNSImage temp ((int) (r.size.width + 0.5f),
|
||||
(int) (r.size.height + 0.5f),
|
||||
! getComponent()->isOpaque());
|
||||
|
||||
LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
|
||||
const int originX = -roundFloatToInt (r.origin.x);
|
||||
const int originY = -roundFloatToInt (y);
|
||||
context.setOrigin (originX, originY);
|
||||
LowLevelGraphicsSoftwareRenderer context (temp);
|
||||
context.setOrigin (-roundFloatToInt (r.origin.x),
|
||||
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));
|
||||
|
||||
const NSRect* rects = 0;
|
||||
NSInteger numRects = 0;
|
||||
|
|
@ -267843,7 +267749,11 @@ void NSViewComponentPeer::drawRect (NSRect r)
|
|||
handlePaint (context);
|
||||
insideDrawRect = false;
|
||||
|
||||
temp.draw (r.origin.x, r.origin.y, clip, originX, originY);
|
||||
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
|
||||
CGImageRelease (image);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -267930,22 +267840,25 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
|
|||
return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo);
|
||||
}
|
||||
|
||||
static Image* NSImageToJuceImage (NSImage* image)
|
||||
{
|
||||
JuceNSImage juceIm ((int) [image size].width,
|
||||
(int) [image size].height,
|
||||
true);
|
||||
|
||||
juceIm.drawNSImage (image);
|
||||
return juceIm.getJuceImage().createCopy();
|
||||
}
|
||||
|
||||
Image* juce_createIconForFile (const File& file)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
|
||||
return NSImageToJuceImage (im);
|
||||
NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
|
||||
|
||||
CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, (int) [image size].width, (int) [image size].height, true);
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: result->context flipped: false]];
|
||||
|
||||
[image drawAtPoint: NSMakePoint (0, 0)
|
||||
fromRect: NSMakeRect (0, 0, [image size].width, [image size].height)
|
||||
operation: NSCompositeSourceOver fraction: 1.0f];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const int KeyPress::spaceKey = ' ';
|
||||
|
|
@ -268012,38 +267925,9 @@ const int KeyPress::rewindKey = 0x30003;
|
|||
|
||||
#if JUCE_MAC
|
||||
|
||||
static NSImage* juceImageToNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
const Image::BitmapData srcData (image, 0, 0, image.getWidth(), image.getHeight());
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: srcData.width
|
||||
pixelsHigh: srcData.height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
|
||||
hasAlpha: image.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: srcData.lineStride
|
||||
bitsPerPixel: srcData.pixelStride * 8];
|
||||
|
||||
unsigned char* newData = [rep bitmapData];
|
||||
memcpy (newData, srcData.data, srcData.lineStride * srcData.height);
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im addRepresentation: rep];
|
||||
[rep release];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
|
||||
{
|
||||
NSImage* im = juceImageToNSImage (image);
|
||||
NSImage* im = CoreGraphicsImage::createNSImage (image);
|
||||
NSCursor* c = [[NSCursor alloc] initWithImage: im
|
||||
hotSpot: NSMakePoint (hotspotX, hotspotY)];
|
||||
[im release];
|
||||
|
|
@ -273104,63 +272988,12 @@ public:
|
|||
[session removeOutput: imageOutput];
|
||||
}
|
||||
|
||||
static void drawNSBitmapIntoJuceImage (Image& dest, NSBitmapImageRep* source)
|
||||
void callListeners (CIImage* frame, int w, int h)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
const Image::BitmapData destData (dest, 0, 0, dest.getWidth(), dest.getHeight(), true);
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: (unsigned char**) &(destData.data)
|
||||
pixelsWide: destData.width
|
||||
pixelsHigh: destData.height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: destData.pixelStride
|
||||
hasAlpha: dest.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: destData.lineStride
|
||||
bitsPerPixel: destData.pixelStride * 8];
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithBitmapImageRep: rep]];
|
||||
|
||||
[source drawAtPoint: NSZeroPoint];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
uint8* start = destData.data;
|
||||
for (int h = dest.getHeight(); --h >= 0;)
|
||||
{
|
||||
uint8* p = start;
|
||||
start += destData.lineStride;
|
||||
|
||||
for (int i = dest.getWidth(); --i >= 0;)
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
const uint8 oldp3 = p[3];
|
||||
const uint8 oldp1 = p[1];
|
||||
p[3] = p[0];
|
||||
p[0] = oldp1;
|
||||
p[1] = p[2];
|
||||
p[2] = oldp3;
|
||||
#else
|
||||
const uint8 oldp0 = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = oldp0;
|
||||
#endif
|
||||
|
||||
p += destData.pixelStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callListeners (NSBitmapImageRep* bitmap)
|
||||
{
|
||||
Image image (Image::ARGB, [bitmap size].width, [bitmap size].height, false);
|
||||
drawNSBitmapIntoJuceImage (image, bitmap);
|
||||
CoreGraphicsImage image (Image::ARGB, w, h, false);
|
||||
CIContext* cic = [CIContext contextWithCGContext: image.context options: nil];
|
||||
[cic drawImage: frame inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)];
|
||||
CGContextFlush (image.context);
|
||||
|
||||
const ScopedLock sl (listenerLock);
|
||||
|
||||
|
|
@ -273210,10 +273043,10 @@ END_JUCE_NAMESPACE
|
|||
fromConnection: (QTCaptureConnection*) connection
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
CIImage* image = [CIImage imageWithCVImageBuffer: videoFrame];
|
||||
NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCIImage: image] autorelease];
|
||||
|
||||
internal->callListeners (bitmap);
|
||||
internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame],
|
||||
CVPixelBufferGetWidth (videoFrame),
|
||||
CVPixelBufferGetHeight (videoFrame));
|
||||
}
|
||||
|
||||
- (void) captureOutput: (QTCaptureFileOutput*) captureOutput
|
||||
|
|
|
|||
|
|
@ -618,8 +618,11 @@ void CodeEditorComponent::insertTextAtCaret (const String& newText)
|
|||
|
||||
void CodeEditorComponent::insertTabAtCaret()
|
||||
{
|
||||
if (CharacterFunctions::isWhitespace (caretPos.getCharacter()))
|
||||
if (CharacterFunctions::isWhitespace (caretPos.getCharacter())
|
||||
&& caretPos.getLineNumber() == caretPos.movedBy (1).getLineNumber())
|
||||
{
|
||||
moveCaretTo (document.findWordBreakAfter (caretPos), false);
|
||||
}
|
||||
|
||||
if (useSpacesForTabs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -145,63 +145,12 @@ public:
|
|||
[session removeOutput: imageOutput];
|
||||
}
|
||||
|
||||
static void drawNSBitmapIntoJuceImage (Image& dest, NSBitmapImageRep* source)
|
||||
void callListeners (CIImage* frame, int w, int h)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
const Image::BitmapData destData (dest, 0, 0, dest.getWidth(), dest.getHeight(), true);
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: (unsigned char**) &(destData.data)
|
||||
pixelsWide: destData.width
|
||||
pixelsHigh: destData.height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: destData.pixelStride
|
||||
hasAlpha: dest.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: destData.lineStride
|
||||
bitsPerPixel: destData.pixelStride * 8];
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithBitmapImageRep: rep]];
|
||||
|
||||
[source drawAtPoint: NSZeroPoint];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
uint8* start = destData.data;
|
||||
for (int h = dest.getHeight(); --h >= 0;)
|
||||
{
|
||||
uint8* p = start;
|
||||
start += destData.lineStride;
|
||||
|
||||
for (int i = dest.getWidth(); --i >= 0;)
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
const uint8 oldp3 = p[3];
|
||||
const uint8 oldp1 = p[1];
|
||||
p[3] = p[0];
|
||||
p[0] = oldp1;
|
||||
p[1] = p[2];
|
||||
p[2] = oldp3;
|
||||
#else
|
||||
const uint8 oldp0 = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = oldp0;
|
||||
#endif
|
||||
|
||||
p += destData.pixelStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callListeners (NSBitmapImageRep* bitmap)
|
||||
{
|
||||
Image image (Image::ARGB, [bitmap size].width, [bitmap size].height, false);
|
||||
drawNSBitmapIntoJuceImage (image, bitmap);
|
||||
CoreGraphicsImage image (Image::ARGB, w, h, false);
|
||||
CIContext* cic = [CIContext contextWithCGContext: image.context options: nil];
|
||||
[cic drawImage: frame inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)];
|
||||
CGContextFlush (image.context);
|
||||
|
||||
const ScopedLock sl (listenerLock);
|
||||
|
||||
|
|
@ -251,10 +200,10 @@ END_JUCE_NAMESPACE
|
|||
fromConnection: (QTCaptureConnection*) connection
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
CIImage* image = [CIImage imageWithCVImageBuffer: videoFrame];
|
||||
NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCIImage: image] autorelease];
|
||||
|
||||
internal->callListeners (bitmap);
|
||||
internal->callListeners ([CIImage imageWithCVImageBuffer: videoFrame],
|
||||
CVPixelBufferGetWidth (videoFrame),
|
||||
CVPixelBufferGetHeight (videoFrame));
|
||||
}
|
||||
|
||||
- (void) captureOutput: (QTCaptureFileOutput*) captureOutput
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
class CoreGraphicsImage : public Image
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
CoreGraphicsImage (const PixelFormat format,
|
||||
const int imageWidth,
|
||||
const int imageHeight,
|
||||
|
|
@ -41,9 +42,7 @@ public:
|
|||
: CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
context = CGBitmapContextCreate (imageData, imageWidth, imageHeight, 8, lineStride,
|
||||
colourSpace,
|
||||
format == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault);
|
||||
colourSpace, getCGImageFlags (*this));
|
||||
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
}
|
||||
|
|
@ -55,7 +54,64 @@ public:
|
|||
|
||||
LowLevelGraphicsContext* createLowLevelContext();
|
||||
|
||||
//==============================================================================
|
||||
static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace, getCGImageFlags (juceImage), provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static NSImage* createNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im setSize: NSMakeSize (image.getWidth(), image.getHeight())];
|
||||
[im lockFocus];
|
||||
|
||||
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef imageRef = createImage (image, false, colourSpace);
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
|
||||
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGContextDrawImage (cg, CGRectMake (0, 0, image.getWidth(), image.getHeight()), imageRef);
|
||||
|
||||
CGImageRelease (imageRef);
|
||||
[im unlockFocus];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
CGContextRef context;
|
||||
|
||||
private:
|
||||
static CGBitmapInfo getCGImageFlags (const Image& image) throw()
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big) : kCGBitmapByteOrderDefault;
|
||||
#else
|
||||
return image.getFormat() == Image::ARGB ? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little) : kCGBitmapByteOrderDefault;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
Image* Image::createNativeImage (const PixelFormat format, const int imageWidth, const int imageHeight, const bool clearImage)
|
||||
|
|
@ -146,7 +202,7 @@ public:
|
|||
if (! transform.isSingularity())
|
||||
{
|
||||
Image* singleChannelImage = createAlphaChannelImage (sourceImage);
|
||||
CGImageRef image = createImage (*singleChannelImage, true);
|
||||
CGImageRef image = CoreGraphicsImage::createImage (*singleChannelImage, true, greyColourSpace);
|
||||
|
||||
flip();
|
||||
AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform));
|
||||
|
|
@ -315,7 +371,7 @@ public:
|
|||
void drawImage (const Image& sourceImage, const Rectangle& srcClip,
|
||||
const AffineTransform& transform, const bool fillEntireClipAsTiles)
|
||||
{
|
||||
CGImageRef fullImage = createImage (sourceImage, false);
|
||||
CGImageRef fullImage = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace);
|
||||
CGImageRef image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClip.getX(), sourceImage.getHeight() - srcClip.getBottom(),
|
||||
srcClip.getWidth(), srcClip.getHeight()));
|
||||
CGImageRelease (fullImage);
|
||||
|
|
@ -614,35 +670,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
CGImageRef createImage (const Image& juceImage, const bool forAlpha) const throw()
|
||||
{
|
||||
const CoreGraphicsImage* nativeImage = dynamic_cast <const CoreGraphicsImage*> (&juceImage);
|
||||
|
||||
if (nativeImage != 0 && (juceImage.getFormat() == Image::SingleChannel || ! forAlpha))
|
||||
{
|
||||
return CGBitmapContextCreateImage (nativeImage->context);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.pixelStride, 0);
|
||||
CGColorSpaceRef colourSpace = forAlpha ? greyColourSpace : rgbColourSpace;
|
||||
|
||||
CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height,
|
||||
8, srcData.pixelStride * 8, srcData.lineStride,
|
||||
colourSpace,
|
||||
(juceImage.hasAlphaChannel() && ! forAlpha)
|
||||
? (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little)
|
||||
: kCGBitmapByteOrderDefault,
|
||||
provider,
|
||||
0, true, kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (provider);
|
||||
return imageRef;
|
||||
}
|
||||
}
|
||||
|
||||
static Image* createAlphaChannelImage (const Image& im) throw()
|
||||
{
|
||||
if (im.getFormat() == Image::SingleChannel)
|
||||
|
|
|
|||
|
|
@ -29,40 +29,11 @@
|
|||
|
||||
#if JUCE_MAC
|
||||
|
||||
//==============================================================================
|
||||
static NSImage* juceImageToNSImage (const Image& image)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
const Image::BitmapData srcData (image, 0, 0, image.getWidth(), image.getHeight());
|
||||
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: NULL
|
||||
pixelsWide: srcData.width
|
||||
pixelsHigh: srcData.height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: image.hasAlphaChannel() ? 4 : 3
|
||||
hasAlpha: image.hasAlphaChannel()
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: (NSBitmapFormat) 0
|
||||
bytesPerRow: srcData.lineStride
|
||||
bitsPerPixel: srcData.pixelStride * 8];
|
||||
|
||||
unsigned char* newData = [rep bitmapData];
|
||||
memcpy (newData, srcData.data, srcData.lineStride * srcData.height);
|
||||
|
||||
NSImage* im = [[NSImage alloc] init];
|
||||
[im addRepresentation: rep];
|
||||
[rep release];
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) throw()
|
||||
{
|
||||
NSImage* im = juceImageToNSImage (image);
|
||||
NSImage* im = CoreGraphicsImage::createNSImage (image);
|
||||
NSCursor* c = [[NSCursor alloc] initWithImage: im
|
||||
hotSpot: NSMakePoint (hotspotX, hotspotY)];
|
||||
[im release];
|
||||
|
|
|
|||
|
|
@ -555,123 +555,6 @@ END_JUCE_NAMESPACE
|
|||
//==============================================================================
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
//==============================================================================
|
||||
class JuceNSImage
|
||||
{
|
||||
public:
|
||||
JuceNSImage (const int width, const int height, const bool hasAlpha)
|
||||
: juceImage (hasAlpha ? Image::ARGB : Image::RGB,
|
||||
width, height, hasAlpha),
|
||||
srcData (juceImage, 0, 0, width, height)
|
||||
{
|
||||
imageRep = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes: (unsigned char**) &(srcData.data)
|
||||
pixelsWide: width
|
||||
pixelsHigh: height
|
||||
bitsPerSample: 8
|
||||
samplesPerPixel: srcData.pixelStride
|
||||
hasAlpha: hasAlpha
|
||||
isPlanar: NO
|
||||
colorSpaceName: NSCalibratedRGBColorSpace
|
||||
bitmapFormat: /*NSAlphaFirstBitmapFormat*/ (NSBitmapFormat) 0
|
||||
bytesPerRow: srcData.lineStride
|
||||
bitsPerPixel: 8 * srcData.pixelStride ];
|
||||
}
|
||||
|
||||
~JuceNSImage()
|
||||
{
|
||||
[imageRep release];
|
||||
}
|
||||
|
||||
Image& getJuceImage() throw() { return juceImage; }
|
||||
|
||||
void draw (const float x, const float y,
|
||||
const RectangleList& clip,
|
||||
const int originX, const int originY) const
|
||||
{
|
||||
// Our data is BGRA and the damned image rep only takes RGBA, so
|
||||
// we need to byte-swap the active areas if there's an alpha channel...
|
||||
if (juceImage.hasAlphaChannel())
|
||||
{
|
||||
RectangleList::Iterator iter (clip);
|
||||
while (iter.next())
|
||||
{
|
||||
const Rectangle* const r = iter.getRectangle();
|
||||
|
||||
swapRGBOrder (r->getX() + originX,
|
||||
r->getY() + originY,
|
||||
r->getWidth(),
|
||||
r->getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
NSPoint p;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
[imageRep drawAtPoint: p];
|
||||
}
|
||||
|
||||
void drawNSImage (NSImage* imageToDraw)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:
|
||||
[NSGraphicsContext graphicsContextWithBitmapImageRep: imageRep]];
|
||||
|
||||
[imageToDraw drawAtPoint: NSZeroPoint
|
||||
fromRect: NSMakeRect (0, 0, [imageToDraw size].width, [imageToDraw size].height)
|
||||
operation: NSCompositeSourceOver
|
||||
fraction: 1.0f];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
if (juceImage.hasAlphaChannel())
|
||||
swapRGBOrder (0, 0, juceImage.getWidth(), juceImage.getHeight());
|
||||
}
|
||||
|
||||
private:
|
||||
Image juceImage;
|
||||
NSBitmapImageRep* imageRep;
|
||||
const Image::BitmapData srcData;
|
||||
|
||||
void swapRGBOrder (const int x, const int y, const int w, int h) const
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
jassert (srcData.pixelStride == 4);
|
||||
#endif
|
||||
jassert (Rectangle (0, 0, juceImage.getWidth(), juceImage.getHeight())
|
||||
.contains (Rectangle (x, y, w, h)));
|
||||
|
||||
uint8* start = srcData.getPixelPointer (x, y);
|
||||
|
||||
while (--h >= 0)
|
||||
{
|
||||
uint8* p = start;
|
||||
start += srcData.lineStride;
|
||||
|
||||
for (int i = w; --i >= 0;)
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
const uint8 oldp3 = p[3];
|
||||
const uint8 oldp1 = p[1];
|
||||
p[3] = p[0];
|
||||
p[0] = oldp1;
|
||||
p[1] = p[2];
|
||||
p[2] = oldp3;
|
||||
#else
|
||||
const uint8 oldp0 = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = oldp0;
|
||||
#endif
|
||||
|
||||
p += srcData.pixelStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
static ComponentPeer* currentlyFocusedPeer = 0;
|
||||
static VoidArray keysCurrentlyDown;
|
||||
|
|
@ -1435,28 +1318,26 @@ void NSViewComponentPeer::drawRect (NSRect r)
|
|||
if (r.size.width < 1.0f || r.size.height < 1.0f)
|
||||
return;
|
||||
|
||||
#if USE_COREGRAPHICS_RENDERING
|
||||
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
if (! component->isOpaque())
|
||||
CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
|
||||
|
||||
#if USE_COREGRAPHICS_RENDERING
|
||||
CoreGraphicsContext context (cg, [view frame].size.height);
|
||||
|
||||
insideDrawRect = true;
|
||||
handlePaint (context);
|
||||
insideDrawRect = false;
|
||||
#else
|
||||
const float y = [view frame].size.height - (r.origin.y + r.size.height);
|
||||
Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB,
|
||||
(int) (r.size.width + 0.5f),
|
||||
(int) (r.size.height + 0.5f),
|
||||
! getComponent()->isOpaque());
|
||||
|
||||
JuceNSImage temp ((int) (r.size.width + 0.5f),
|
||||
(int) (r.size.height + 0.5f),
|
||||
! getComponent()->isOpaque());
|
||||
|
||||
LowLevelGraphicsSoftwareRenderer context (temp.getJuceImage());
|
||||
const int originX = -roundFloatToInt (r.origin.x);
|
||||
const int originY = -roundFloatToInt (y);
|
||||
context.setOrigin (originX, originY);
|
||||
LowLevelGraphicsSoftwareRenderer context (temp);
|
||||
context.setOrigin (-roundFloatToInt (r.origin.x),
|
||||
-roundFloatToInt ([view frame].size.height - (r.origin.y + r.size.height)));
|
||||
|
||||
const NSRect* rects = 0;
|
||||
NSInteger numRects = 0;
|
||||
|
|
@ -1477,7 +1358,11 @@ void NSViewComponentPeer::drawRect (NSRect r)
|
|||
handlePaint (context);
|
||||
insideDrawRect = false;
|
||||
|
||||
temp.draw (r.origin.x, r.origin.y, clip, originX, originY);
|
||||
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||
CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace);
|
||||
CGColorSpaceRelease (colourSpace);
|
||||
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image);
|
||||
CGImageRelease (image);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1567,22 +1452,25 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
static Image* NSImageToJuceImage (NSImage* image)
|
||||
{
|
||||
JuceNSImage juceIm ((int) [image size].width,
|
||||
(int) [image size].height,
|
||||
true);
|
||||
|
||||
juceIm.drawNSImage (image);
|
||||
return juceIm.getJuceImage().createCopy();
|
||||
}
|
||||
|
||||
Image* juce_createIconForFile (const File& file)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSImage* im = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
|
||||
return NSImageToJuceImage (im);
|
||||
NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (file.getFullPathName())];
|
||||
|
||||
CoreGraphicsImage* result = new CoreGraphicsImage (Image::ARGB, (int) [image size].width, (int) [image size].height, true);
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: result->context flipped: false]];
|
||||
|
||||
[image drawAtPoint: NSMakePoint (0, 0)
|
||||
fromRect: NSMakeRect (0, 0, [image size].width, [image size].height)
|
||||
operation: NSCompositeSourceOver fraction: 1.0f];
|
||||
|
||||
[[NSGraphicsContext currentContext] flushGraphics];
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue