Well, the way its done now, it has massive overhead (just repaint to little controls, calls paint for the whole GUI)
Why not split up the drawRect calls directly in the JuceNSViewClass
static void drawRect (id self, SEL, NSRect r)
{
if (NSViewComponentPeer* p = getOwner (self))
{
const NSRect* rects;
NSInteger count;
[self getRectsBeingDrawn:&rects count:&count];
for (int i = 0; i < count; i++)
{
NSRect rc = rects[i];
p->drawRect (rc);
};
};
}
and then intersect the clip-context for every drawRect call in NSViewComponentPeer (inside save/restorrGraphicsState scope)
its applied before the transforms, so i think it should be okay (?)
BTW: the clipping could be optional, if only one rect is provided
void drawRect (NSRect r)
{
if (r.size.width < 1.0f || r.size.height < 1.0f)
return;
CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
[NSGraphicsContext saveGraphicsState]; // New, don't forget to restore NSGraphicsContext down below
CGContextClipToRect(cg, NSRectToCGRect(r)); // new
if (! component.isOpaque())
CGContextClearRect (cg, CGContextGetClipBoundingBox (cg));
float displayScale = 1.0f;
#if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
NSScreen* screen = [[view window] screen];
if ([screen respondsToSelector: @selector (backingScaleFactor)])
displayScale = (float) screen.backingScaleFactor;
#endif
#if USE_COREGRAPHICS_RENDERING
if (usingCoreGraphics)
{
CoreGraphicsContext context (cg, (float) [view frame].size.height, displayScale);
insideDrawRect = true;
handlePaint (context);
insideDrawRect = false;
}
else
#endif
{
const Point<int> offset (-roundToInt (r.origin.x),
-roundToInt ([view frame].size.height - (r.origin.y + r.size.height)));
const int clipW = (int) (r.size.width + 0.5f);
const int clipH = (int) (r.size.height + 0.5f);
RectangleList<int> clip;
getClipRects (clip, offset, clipW, clipH);
if (! clip.isEmpty())
{
Image temp (component.isOpaque() ? Image::RGB : Image::ARGB,
roundToInt (clipW * displayScale),
roundToInt (clipH * displayScale),
! component.isOpaque());
{
const int intScale = roundToInt (displayScale);
if (intScale != 1)
clip.scaleAll (intScale);
ScopedPointer<LowLevelGraphicsContext> context (component.getLookAndFeel()
.createGraphicsContext (temp, offset * intScale, clip));
if (intScale != 1)
context->addTransform (AffineTransform::scale (displayScale));
insideDrawRect = true;
handlePaint (*context);
insideDrawRect = false;
}
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef image = juce_createCoreGraphicsImage (temp, colourSpace, false);
CGColorSpaceRelease (colourSpace);
CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, clipW, clipH), image);
CGImageRelease (image);
}
}
[NSGraphicsContext restoreGraphicsState]; // new
}
Edit: use of NSRectToCGRect
Edit: looks like it works here, very well (in a app wich also uses transformations)