Make GBImageView not slow

This commit is contained in:
Lior Halphon 2022-02-19 22:13:07 +02:00
parent 4c6bc91ded
commit 3c6a46830d
2 changed files with 60 additions and 42 deletions

View File

@ -1389,28 +1389,21 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale
{
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef) data);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width,
height,
8,
32,
4 * width,
colorSpaceRef,
bitmapInfo,
provider,
NULL,
true,
renderingIntent);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
NSImage *ret = [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(width * scale, height * scale)];
CGImageRelease(iref);
NSImage *ret = [[NSImage alloc] initWithSize:NSMakeSize(width * scale, height * scale)];
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:width
pixelsHigh:height
bitsPerSample:8
samplesPerPixel:3
hasAlpha:false
isPlanar:false
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:0
bytesPerRow:4 * width
bitsPerPixel:32];
memcpy(rep.bitmapData, data.bytes, data.length);
[ret addRepresentation:rep];
return ret;
}

View File

@ -10,18 +10,18 @@
}
@end
@implementation GBImageView
{
NSTrackingArea *trackingArea;
}
@interface GBGridView : NSView
@end
@implementation GBGridView
- (void)drawRect:(NSRect)dirtyRect
{
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
[super drawRect:dirtyRect];
CGFloat y_ratio = self.frame.size.height / self.image.size.height;
CGFloat x_ratio = self.frame.size.width / self.image.size.width;
for (GBImageViewGridConfiguration *conf in self.verticalGrids) {
GBImageView *parent = (GBImageView *)self.superview;
CGFloat y_ratio = parent.frame.size.height / parent.image.size.height;
CGFloat x_ratio = parent.frame.size.width / parent.image.size.width;
for (GBImageViewGridConfiguration *conf in parent.verticalGrids) {
[conf.color set];
for (CGFloat y = conf.size * y_ratio; y < self.frame.size.height; y += conf.size * y_ratio) {
NSBezierPath *line = [NSBezierPath bezierPath];
@ -32,7 +32,7 @@
}
}
for (GBImageViewGridConfiguration *conf in self.horizontalGrids) {
for (GBImageViewGridConfiguration *conf in parent.horizontalGrids) {
[conf.color set];
for (CGFloat x = conf.size * x_ratio; x < self.frame.size.width; x += conf.size * x_ratio) {
NSBezierPath *line = [NSBezierPath bezierPath];
@ -43,11 +43,11 @@
}
}
if (self.displayScrollRect) {
if (parent.displayScrollRect) {
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectInfinite];
for (unsigned x = 0; x < 2; x++) {
for (unsigned y = 0; y < 2; y++) {
NSRect rect = self.scrollRect;
NSRect rect = parent.scrollRect;
rect.origin.x *= x_ratio;
rect.origin.y *= y_ratio;
rect.size.width *= x_ratio;
@ -56,7 +56,7 @@
rect.origin.x -= self.frame.size.width * x;
rect.origin.y += self.frame.size.height * y;
NSBezierPath *subpath = [NSBezierPath bezierPathWithRect:rect];
[path appendBezierPath:subpath];
@ -72,36 +72,61 @@
[path stroke];
}
}
@end
@implementation GBImageView
{
NSTrackingArea *_trackingArea;
GBGridView *_gridView;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
self.wantsLayer = true;
_gridView = [[GBGridView alloc] initWithFrame:self.bounds];
_gridView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[self addSubview:_gridView];
return self;
}
- (void)setImage:(NSImage *)image
{
[super setImage:image];
for (CALayer *layer in self.layer.sublayers) {
layer.magnificationFilter = kCAFilterNearest;
}
}
- (void)setHorizontalGrids:(NSArray *)horizontalGrids
{
self->_horizontalGrids = horizontalGrids;
[self setNeedsDisplay];
[_gridView setNeedsDisplay:true];
}
- (void)setVerticalGrids:(NSArray *)verticalGrids
{
self->_verticalGrids = verticalGrids;
[self setNeedsDisplay];
[_gridView setNeedsDisplay:true];
}
- (void)setDisplayScrollRect:(bool)displayScrollRect
{
self->_displayScrollRect = displayScrollRect;
[self setNeedsDisplay];
[_gridView setNeedsDisplay:true];
}
- (void)updateTrackingAreas
{
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
if (_trackingArea != nil) {
[self removeTrackingArea:_trackingArea];
}
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
_trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingMouseMoved
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
[self addTrackingArea:_trackingArea];
}
- (void)mouseExited:(NSEvent *)theEvent