Mercurial > dwindows
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. |