comparison mac/dw.m @ 909:c092eab43ae3

Experimental change to pixmap rendering. Switch from using NSImage to NSBitmapImageRef to store the image. This is closer to the core backing store used to display images. Using this I was able to avoid using lockFocus on the images and instead set the graphics context manually allowing us to draw directly on the backing image. However NSBitmapImageRef is a more simple format and didn't work with the flipped Y axis... so... I had to perform some voodoo to get the flipping to work with the graphics context. Not sure it is 100% right.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 20 Apr 2011 14:09:00 +0000
parents 5596e3830ae3
children 329f2ca62f1b
comparison
equal deleted inserted replaced
908:850b2e6cfeab 909:c092eab43ae3
416 NSValue *bi = (NSValue *)param; 416 NSValue *bi = (NSValue *)param;
417 DWBitBlt *bltinfo = (DWBitBlt *)[bi pointerValue]; 417 DWBitBlt *bltinfo = (DWBitBlt *)[bi pointerValue];
418 id bltdest = bltinfo->dest; 418 id bltdest = bltinfo->dest;
419 id bltsrc = bltinfo->src; 419 id bltsrc = bltinfo->src;
420 420
421 if([bltdest isMemberOfClass:[NSImage class]]) 421 if([bltdest isMemberOfClass:[NSBitmapImageRep class]])
422 { 422 {
423 [bltdest lockFocus]; 423 [NSGraphicsContext saveGraphicsState];
424 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
425 graphicsContextWithBitmapImageRep:bltdest]];
426 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
427 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
428 [[NSDictionary alloc] initWithObjectsAndKeys:bltdest, NSGraphicsContextDestinationAttributeName, nil];
424 } 429 }
425 else 430 else
426 { 431 {
427 if([bltdest lockFocusIfCanDraw] == NO) 432 if([bltdest lockFocusIfCanDraw] == NO)
428 { 433 {
429 return; 434 return;
430 } 435 }
431 _DWLastDrawable = bltinfo->dest; 436 _DWLastDrawable = bltinfo->dest;
432 } 437 }
433 if([bltsrc isMemberOfClass:[NSImage class]]) 438 if([bltsrc isMemberOfClass:[NSBitmapImageRep class]])
434 { 439 {
435 NSImage *image = bltsrc; 440 NSImage *image = [[NSImage alloc] initWithCGImage:[(NSBitmapImageRep *)bltsrc CGImage] size:NSZeroSize];
441 // make a new transform:
442 NSAffineTransform *t = [NSAffineTransform transform];
443
444 // by scaling Y negatively, we effectively flip the image:
445 [t scaleXBy:1.0 yBy:-1.0];
446
447 // but we also have to translate it back by its height:
448 [t translateXBy:0.0 yBy:-bltinfo->height];
449
450 // apply the transform:
451 [t concat];
436 [image drawAtPoint:NSMakePoint(bltinfo->xdest, bltinfo->ydest) fromRect:NSMakeRect(bltinfo->xsrc, bltinfo->ysrc, bltinfo->width, bltinfo->height) 452 [image drawAtPoint:NSMakePoint(bltinfo->xdest, bltinfo->ydest) fromRect:NSMakeRect(bltinfo->xsrc, bltinfo->ysrc, bltinfo->width, bltinfo->height)
437 operation:NSCompositeCopy fraction:1.0]; 453 operation:NSCompositeCopy fraction:1.0];
438 [bltsrc release]; 454 [bltsrc release];
439 } 455 [image release];
440 [bltdest unlockFocus]; 456 }
457 if([bltdest isMemberOfClass:[NSBitmapImageRep class]])
458 {
459 [NSGraphicsContext restoreGraphicsState];
460 }
461 else
462 {
463 [bltdest unlockFocus];
464 }
441 free(bltinfo); 465 free(bltinfo);
442 } 466 }
443 -(void)doFlush:(id)param 467 -(void)doFlush:(id)param
444 { 468 {
445 if(_DWLastDrawable) 469 if(_DWLastDrawable)
4352 DW_MUTEX_LOCK; 4376 DW_MUTEX_LOCK;
4353 id image = handle; 4377 id image = handle;
4354 if(pixmap) 4378 if(pixmap)
4355 { 4379 {
4356 image = (id)pixmap->image; 4380 image = (id)pixmap->image;
4357 [image lockFocus]; 4381 [NSGraphicsContext saveGraphicsState];
4382 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4383 graphicsContextWithBitmapImageRep:image]];
4384 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4385 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
4358 } 4386 }
4359 else 4387 else
4360 { 4388 {
4361 if([image lockFocusIfCanDraw] == NO) 4389 if([image lockFocusIfCanDraw] == NO)
4362 { 4390 {
4370 NSColor *color = pthread_getspecific(_dw_fg_color_key); 4398 NSColor *color = pthread_getspecific(_dw_fg_color_key);
4371 [color set]; 4399 [color set];
4372 4400
4373 [aPath moveToPoint:NSMakePoint(x, y)]; 4401 [aPath moveToPoint:NSMakePoint(x, y)];
4374 [aPath stroke]; 4402 [aPath stroke];
4375 [image unlockFocus]; 4403 if(pixmap)
4404 {
4405 [NSGraphicsContext restoreGraphicsState];
4406 }
4407 else
4408 {
4409 [image unlockFocus];
4410 }
4376 DW_MUTEX_UNLOCK; 4411 DW_MUTEX_UNLOCK;
4377 } 4412 }
4378 4413
4379 /* Draw a line on a window (preferably a render window). 4414 /* Draw a line on a window (preferably a render window).
4380 * Parameters: 4415 * Parameters:
4391 DW_MUTEX_LOCK; 4426 DW_MUTEX_LOCK;
4392 id image = handle; 4427 id image = handle;
4393 if(pixmap) 4428 if(pixmap)
4394 { 4429 {
4395 image = (id)pixmap->image; 4430 image = (id)pixmap->image;
4396 [image lockFocus]; 4431 [NSGraphicsContext saveGraphicsState];
4432 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4433 graphicsContextWithBitmapImageRep:image]];
4434 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4435 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
4397 } 4436 }
4398 else 4437 else
4399 { 4438 {
4400 if([image lockFocusIfCanDraw] == NO) 4439 if([image lockFocusIfCanDraw] == NO)
4401 { 4440 {
4411 4450
4412 [aPath moveToPoint:NSMakePoint(x1, y1)]; 4451 [aPath moveToPoint:NSMakePoint(x1, y1)];
4413 [aPath lineToPoint:NSMakePoint(x2, y2)]; 4452 [aPath lineToPoint:NSMakePoint(x2, y2)];
4414 [aPath stroke]; 4453 [aPath stroke];
4415 4454
4416 [image unlockFocus]; 4455 if(pixmap)
4456 {
4457 [NSGraphicsContext restoreGraphicsState];
4458 }
4459 else
4460 {
4461 [image unlockFocus];
4462 }
4417 DW_MUTEX_UNLOCK; 4463 DW_MUTEX_UNLOCK;
4418 } 4464 }
4419 4465
4420 /* Draw text on a window (preferably a render window). 4466 /* Draw text on a window (preferably a render window).
4421 * Parameters: 4467 * Parameters:
4466 if([render isMemberOfClass:[DWRender class]]) 4512 if([render isMemberOfClass:[DWRender class]])
4467 { 4513 {
4468 font = [render font]; 4514 font = [render font];
4469 } 4515 }
4470 image = (id)pixmap->image; 4516 image = (id)pixmap->image;
4471 [image lockFocus]; 4517 [NSGraphicsContext saveGraphicsState];
4518 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4519 graphicsContextWithBitmapImageRep:image]];
4520 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4521 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
4472 NSColor *fgcolor = pthread_getspecific(_dw_fg_color_key); 4522 NSColor *fgcolor = pthread_getspecific(_dw_fg_color_key);
4473 NSColor *bgcolor = pthread_getspecific(_dw_bg_color_key); 4523 NSColor *bgcolor = pthread_getspecific(_dw_bg_color_key);
4474 NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:fgcolor, NSForegroundColorAttributeName, nil]; 4524 NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:fgcolor, NSForegroundColorAttributeName, nil];
4475 if(bgcolor) 4525 if(bgcolor)
4476 { 4526 {
4479 if(font) 4529 if(font)
4480 { 4530 {
4481 [dict setValue:font forKey:NSFontAttributeName]; 4531 [dict setValue:font forKey:NSFontAttributeName];
4482 } 4532 }
4483 [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict]; 4533 [nstr drawAtPoint:NSMakePoint(x, y) withAttributes:dict];
4484 [image unlockFocus]; 4534 [NSGraphicsContext restoreGraphicsState];
4485 [dict release]; 4535 [dict release];
4486 } 4536 }
4487 DW_MUTEX_UNLOCK; 4537 DW_MUTEX_UNLOCK;
4488 } 4538 }
4489 4539
4542 id image = handle; 4592 id image = handle;
4543 int z; 4593 int z;
4544 if(pixmap) 4594 if(pixmap)
4545 { 4595 {
4546 image = (id)pixmap->image; 4596 image = (id)pixmap->image;
4547 [image lockFocus]; 4597 [NSGraphicsContext saveGraphicsState];
4598 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4599 graphicsContextWithBitmapImageRep:image]];
4600 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4601 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
4548 } 4602 }
4549 else 4603 else
4550 { 4604 {
4551 if([image lockFocusIfCanDraw] == NO) 4605 if([image lockFocusIfCanDraw] == NO)
4552 { 4606 {
4569 if(fill) 4623 if(fill)
4570 { 4624 {
4571 [aPath fill]; 4625 [aPath fill];
4572 } 4626 }
4573 [aPath stroke]; 4627 [aPath stroke];
4574 [image unlockFocus]; 4628 if(pixmap)
4629 {
4630 [NSGraphicsContext restoreGraphicsState];
4631 }
4632 else
4633 {
4634 [image unlockFocus];
4635 }
4575 DW_MUTEX_UNLOCK; 4636 DW_MUTEX_UNLOCK;
4576 } 4637 }
4577 4638
4578 /* Draw a rectangle on a window (preferably a render window). 4639 /* Draw a rectangle on a window (preferably a render window).
4579 * Parameters: 4640 * Parameters:
4591 DW_MUTEX_LOCK; 4652 DW_MUTEX_LOCK;
4592 id image = handle; 4653 id image = handle;
4593 if(pixmap) 4654 if(pixmap)
4594 { 4655 {
4595 image = (id)pixmap->image; 4656 image = (id)pixmap->image;
4596 [image lockFocus]; 4657 [NSGraphicsContext saveGraphicsState];
4658 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4659 graphicsContextWithBitmapImageRep:image]];
4660 [NSGraphicsContext setCurrentContext:[NSGraphicsContext
4661 graphicsContextWithGraphicsPort:[[NSGraphicsContext currentContext] graphicsPort] flipped:YES]];
4597 } 4662 }
4598 else 4663 else
4599 { 4664 {
4600 if([image lockFocusIfCanDraw] == NO) 4665 if([image lockFocusIfCanDraw] == NO)
4601 { 4666 {
4615 [aPath lineToPoint:NSMakePoint(x + width, y)]; 4680 [aPath lineToPoint:NSMakePoint(x + width, y)];
4616 [aPath closePath]; 4681 [aPath closePath];
4617 if(fill) 4682 if(fill)
4618 [aPath fill]; 4683 [aPath fill];
4619 [aPath stroke]; 4684 [aPath stroke];
4620 [image unlockFocus]; 4685 if(pixmap)
4686 {
4687 [NSGraphicsContext restoreGraphicsState];
4688 }
4689 else
4690 {
4691 [image unlockFocus];
4692 }
4621 DW_MUTEX_UNLOCK; 4693 DW_MUTEX_UNLOCK;
4622 } 4694 }
4623 4695
4624 /* 4696 /*
4625 * Create a tree object to be packed. 4697 * Create a tree object to be packed.
5726 * Returns: 5798 * Returns:
5727 * A handle to a pixmap or NULL on failure. 5799 * A handle to a pixmap or NULL on failure.
5728 */ 5800 */
5729 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) 5801 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
5730 { 5802 {
5731 NSSize size = { (float)width, (float)height };
5732 HPIXMAP pixmap; 5803 HPIXMAP pixmap;
5733 5804
5734 if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) 5805 if(!(pixmap = calloc(1,sizeof(struct _hpixmap))))
5735 return NULL; 5806 return NULL;
5736 pixmap->width = width; 5807 pixmap->width = width;
5737 pixmap->height = height; 5808 pixmap->height = height;
5738 pixmap->handle = handle; 5809 pixmap->handle = handle;
5739 NSImage *image = pixmap->image = [[NSImage alloc] initWithSize:size]; 5810 id image = pixmap->image = [[NSBitmapImageRep alloc]
5740 [image setFlipped:YES]; 5811 initWithBitmapDataPlanes:NULL
5812 pixelsWide:width
5813 pixelsHigh:height
5814 bitsPerSample:8
5815 samplesPerPixel:4
5816 hasAlpha:YES
5817 isPlanar:NO
5818 colorSpaceName:@"NSCalibratedRGBColorSpace"
5819 bytesPerRow:0
5820 bitsPerPixel:0];
5821 [image retain];
5741 return pixmap; 5822 return pixmap;
5742 } 5823 }
5743 5824
5744 /* 5825 /*
5745 * Creates a pixmap from a file. 5826 * Creates a pixmap from a file.
5756 HPIXMAP pixmap; 5837 HPIXMAP pixmap;
5757 5838
5758 if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) 5839 if(!(pixmap = calloc(1,sizeof(struct _hpixmap))))
5759 return NULL; 5840 return NULL;
5760 NSString *nstr = [ NSString stringWithUTF8String:filename ]; 5841 NSString *nstr = [ NSString stringWithUTF8String:filename ];
5761 NSImage *image = [[NSImage alloc] initWithContentsOfFile:nstr]; 5842 NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr];
5762 if(!image) 5843 if(!image)
5763 { 5844 {
5764 nstr = [nstr stringByAppendingString:@".png"]; 5845 nstr = [nstr stringByAppendingString:@".png"];
5765 image = [[NSImage alloc] initWithContentsOfFile:nstr]; 5846 image = [[NSBitmapImageRep alloc] initWithContentsOfFile:nstr];
5766 } 5847 }
5767 NSSize size = [image size]; 5848 NSSize size = [image size];
5768 pixmap->width = size.width; 5849 pixmap->width = size.width;
5769 pixmap->height = size.height; 5850 pixmap->height = size.height;
5770 pixmap->image = image; 5851 pixmap->image = image;
5771 pixmap->handle = handle; 5852 pixmap->handle = handle;
5772 [image setFlipped:YES];
5773 return pixmap; 5853 return pixmap;
5774 } 5854 }
5775 5855
5776 /* 5856 /*
5777 * Creates a pixmap from memory. 5857 * Creates a pixmap from memory.
5788 HPIXMAP pixmap; 5868 HPIXMAP pixmap;
5789 5869
5790 if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) 5870 if(!(pixmap = calloc(1,sizeof(struct _hpixmap))))
5791 return NULL; 5871 return NULL;
5792 NSData *thisdata = [NSData dataWithBytes:data length:len]; 5872 NSData *thisdata = [NSData dataWithBytes:data length:len];
5793 NSImage *image = [[NSImage alloc] initWithData:thisdata]; 5873 NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithData:thisdata];
5794 NSSize size = [image size]; 5874 NSSize size = [image size];
5795 pixmap->width = size.width; 5875 pixmap->width = size.width;
5796 pixmap->height = size.height; 5876 pixmap->height = size.height;
5797 pixmap->image = image; 5877 pixmap->image = image;
5798 pixmap->handle = handle; 5878 pixmap->handle = handle;
5799 [image setFlipped:YES];
5800 return pixmap; 5879 return pixmap;
5801 } 5880 }
5802 5881
5803 /* 5882 /*
5804 * Sets the transparent color for a pixmap 5883 * Sets the transparent color for a pixmap
5830 return NULL; 5909 return NULL;
5831 5910
5832 NSBundle *bundle = [NSBundle mainBundle]; 5911 NSBundle *bundle = [NSBundle mainBundle];
5833 NSString *respath = [bundle resourcePath]; 5912 NSString *respath = [bundle resourcePath];
5834 NSString *filepath = [respath stringByAppendingFormat:@"/%u.png", resid]; 5913 NSString *filepath = [respath stringByAppendingFormat:@"/%u.png", resid];
5835 NSImage *image = [[NSImage alloc] initWithContentsOfFile:filepath]; 5914 NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithContentsOfFile:filepath];
5836 NSSize size = [image size]; 5915 NSSize size = [image size];
5837 pixmap->width = size.width; 5916 pixmap->width = size.width;
5838 pixmap->height = size.height; 5917 pixmap->height = size.height;
5839 pixmap->image = image; 5918 pixmap->image = image;
5840 pixmap->handle = handle; 5919 pixmap->handle = handle;
5841 [image setFlipped:YES];
5842 return pixmap; 5920 return pixmap;
5843 } 5921 }
5844 5922
5845 /* 5923 /*
5846 * Destroys an allocated pixmap. 5924 * Destroys an allocated pixmap.
5848 * pixmap: Handle to a pixmap returned by 5926 * pixmap: Handle to a pixmap returned by
5849 * dw_pixmap_new.. 5927 * dw_pixmap_new..
5850 */ 5928 */
5851 void API dw_pixmap_destroy(HPIXMAP pixmap) 5929 void API dw_pixmap_destroy(HPIXMAP pixmap)
5852 { 5930 {
5853 NSImage *image = (NSImage *)pixmap->image; 5931 NSBitmapImageRep *image = (NSBitmapImageRep *)pixmap->image;
5854 [image dealloc]; 5932 [image release];
5855 free(pixmap); 5933 free(pixmap);
5856 } 5934 }
5857 5935
5858 /* 5936 /*
5859 * Copies from one item to another. 5937 * Copies from one item to another.