34 assert(info != 0 &&
"ROOT_QuartzImage_GetBytePointer, info parameter is null");
48 std::copy((
char *)info + position, (
char *)info + position + count, (
char*)buffer);
54 namespace X11 = ROOT::MacOSX::X11;
55 namespace Util = ROOT::MacOSX::Util;
56 namespace Quartz = ROOT::Quartz;
67 - (
id) initWithW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
69 if (
self = [super
init]) {
73 if (![
self resizeW : width H : height scaleFactor : scaleFactor]) {
83 - (BOOL) resizeW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
85 assert(width > 0 &&
"resizeW:H:, Pixmap width must be positive");
86 assert(height > 0 &&
"resizeW:H:, Pixmap height must be positive");
90 std::vector<unsigned char> memory;
96 memory.resize(scaledW * scaledH * 4);
97 }
catch (
const std::bad_alloc &) {
98 NSLog(
@"QuartzPixmap: -resizeW:H:, memory allocation failed");
103 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
104 if (!colorSpace.Get()) {
105 NSLog(
@"QuartzPixmap: -resizeW:H:, CGColorSpaceCreateDeviceRGB failed");
109 Util::CFScopeGuard<CGContextRef> ctx(CGBitmapContextCreateWithData(&memory[0], scaledW, scaledH, 8,
110 scaledW * 4, colorSpace.Get(),
111 kCGImageAlphaPremultipliedLast,
NULL, 0));
113 NSLog(
@"QuartzPixmap: -resizeW:H:, CGBitmapContextCreateWithData failed");
119 if (fScaleFactor > 1)
137 return [
self createImageFromPixmap : X11::Rectangle(0, 0, fWidth, fHeight)];
149 assert(cropArea.fX >= 0 &&
"createImageFromPixmap:, cropArea.fX is negative");
150 assert(cropArea.fY >= 0 &&
"createImageFromPixmap:, cropArea.fY is negative");
151 assert(cropArea.fWidth <=
fWidth &&
"createImageFromPixmap:, bad cropArea.fWidth");
152 assert(cropArea.fHeight <=
fHeight &&
"createImageFromPixmap:, bad cropArea.fHeight");
163 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateDirect(&
fData[0],
164 scaledW * scaledH * 4, &providerCallbacks));
165 if (!provider.Get()) {
166 NSLog(
@"QuartzPixmap: -pixmapToImage, CGDataProviderCreateDirect failed");
171 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
172 if (!colorSpace.Get()) {
173 NSLog(
@"QuartzPixmap: -pixmapToImage, CGColorSpaceCreateDeviceRGB failed");
179 CGImageRef
image = CGImageCreate(cropArea.fWidth * fScaleFactor, cropArea.fHeight * fScaleFactor,
180 8, 32,
fWidth * 4 * fScaleFactor, colorSpace.Get(),
181 kCGImageAlphaPremultipliedLast, provider.Get(), 0,
182 false, kCGRenderingIntentDefault);
224 - (
void) copyImage : (
QuartzImage *) srcImage area : (X11::Rectangle) area
225 withMask : (
QuartzImage *) mask clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
227 using namespace ROOT::MacOSX::X11;
230 assert(srcImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage parameter is nil");
231 assert(srcImage.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage.fImage is nil");
234 NSLog(
@"QuartzPixmap: -copyImage:srcImage:area:withMask:clipOrigin"
235 ":toPoint, srcRect and copyRect do not intersect");
239 CGImageRef subImage = 0;
240 bool needSubImage =
false;
241 if (area.fX || area.fY || area.fWidth != srcImage.
fWidth || area.fHeight != srcImage.
fHeight) {
245 NSLog(
@"QuartzPixmap: -copyImage:area:withMask:clipOrigin:toPoint:, subimage creation failed");
249 subImage = srcImage.
fImage;
255 assert(mask.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
256 assert(CGImageIsMask(mask.
fImage) &&
"copyImage:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
259 const CGRect clipRect = CGRectMake(clipXY.fX, clipXY.fY, mask.
fWidth, mask.
fHeight);
265 const CGRect imageRect = CGRectMake(dstPoint.fX, dstPoint.fY, area.fWidth, area.fHeight);
266 CGContextDrawImage(
fContext.
Get(), imageRect, subImage);
269 CGImageRelease(subImage);
273 - (
void) copyPixmap : (
QuartzPixmap *) srcPixmap area : (X11::Rectangle) area
274 withMask : (
QuartzImage *)mask clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
276 using namespace ROOT::MacOSX::X11;
278 assert(srcPixmap != nil &&
279 "copyPixmap:area:withMask:clipOrigin:toPoint, srcPixmap parameter is nil");
282 NSLog(
@"QuartzPixmap: -copyPixmap:area:withMask:clipOrigin:"
283 "toPoint, srcRect and copyRect do not intersect");
295 "copyPixmap:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
297 "copyPixmap:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
300 const CGRect clipRect = CGRectMake(clipXY.fX, clipXY.fY, mask.
fWidth, mask.
fHeight);
306 const CGRect imageRect = CGRectMake(dstPoint.fX, dstPoint.fY, area.fWidth, area.fHeight);
314 assert(area.fWidth && area.fHeight &&
315 "copy:area:widthMask:clipOrigin:toPoint, empty area to copy");
318 [
self copyImage : (QuartzImage *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
319 }
else if ([src isKindOfClass : [
QuartzPixmap class]]) {
320 [
self copyPixmap : (QuartzPixmap *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
322 assert(0 &&
"Can copy only from pixmap or image");
326 - (
unsigned char *) readColorBits : (X11::Rectangle) area
328 assert(area.fWidth && area.fHeight &&
"readColorBits:, empty area to copy");
331 NSLog(
@"QuartzPixmap: readColorBits:intoBuffer:, src and copy area do not intersect");
336 unsigned char *
buffer = 0;
338 buffer =
new unsigned char[area.fWidth * area.fHeight * 4]();
339 }
catch (
const std::bad_alloc &) {
340 NSLog(
@"QuartzImage: -readColorBits:, memory allocation failed");
344 Util::NSScopeGuard<QuartzPixmap> scaledPixmap;
349 if (!scaledPixmap.Get()) {
350 NSLog(
@"QuartzImage: -readColorBits:, can not create scaled pixmap");
354 [scaledPixmap.Get() copy : self area : X11::Rectangle(0, 0, fWidth, fHeight)
355 withMask : nil clipOrigin : X11::Point() toPoint : X11::Point()];
358 unsigned char *dstPixel =
buffer;
363 : &scaledPixmap.Get()->fData[0] + area.fY *
fWidth * 4;
365 const unsigned char *srcPixel = line + area.fX * 4;
367 for (
unsigned i = 0; i < area.fHeight; ++i) {
368 for (
unsigned j = 0; j < area.fWidth; ++j, srcPixel += 4, dstPixel += 4) {
369 dstPixel[0] = srcPixel[0];
370 dstPixel[1] = srcPixel[1];
371 dstPixel[2] = srcPixel[2];
372 dstPixel[3] = srcPixel[3];
376 srcPixel = line + area.fX * 4;
389 - (
void) putPixel : (const
unsigned char *) rgb X : (
unsigned) x Y : (
unsigned) y
392 assert(rgb != 0 &&
"putPixel:X:Y:, rgb parameter is null");
393 assert(x < fWidth && "putPixel:X:Y:, x parameter is >=
self.
fWidth");
394 assert(y < fHeight && "putPixel:
X:
Y:, y parameter is >=
self.
fHeight");
396 unsigned char * const data = &fData[0];
397 if (fScaleFactor > 1) {
398 //Ooops, and what should I do now???
399 const unsigned scaledW = fWidth * fScaleFactor;
400 unsigned char *dst = data + y * fScaleFactor * scaledW * 4 + x * fScaleFactor * 4;
402 for (unsigned i = 0; i < 2; ++i, dst += 4) {
412 for (unsigned i = 0; i < 2; ++i, dst += 4) {
419 unsigned char *dst = data + y * fWidth * 4 + x * 4;
428 //______________________________________________________________________________
429 - (void) addPixel : (const unsigned char *) rgb
431 //Primitive version of XAddPixel.
432 assert(rgb != 0 && "addPixel:, rgb parameter is
null");
434 for (unsigned i = 0; i < fHeight; ++i) {
435 for (unsigned j = 0; j < fWidth; ++j) {
436 fData[i * fWidth * 4 + j * 4] = rgb[0];
437 fData[i * fWidth * 4 + j * 4 + 1] = rgb[1];
438 fData[i * fWidth * 4 + j * 4 + 2] = rgb[2];
439 fData[i * fWidth * 4 + j * 4 + 3] = rgb[3];
446 @implementation QuartzImage
448 @synthesize fIsStippleMask;
451 //TODO: all these "ctors
" were added at different times, not from the beginnning.
452 //Refactor them to reduce code duplication, where possible.
454 //______________________________________________________________________________
455 - (id) initWithW : (unsigned) width H : (unsigned) height data : (unsigned char *) data
457 assert(width != 0 && "initWithW:
H:data:, width parameter is 0
");
458 assert(height != 0 && "initWithW:
H:data:, height parameter is 0
");
459 assert(data != 0 && "initWithW:
H:data:, data parameter is
null");
461 if (self = [super init]) {
462 Util::NSScopeGuard<QuartzImage> selfGuard(self);
464 //This w * h * 4 is ONLY for TGCocoa::CreatePixmapFromData.
465 //If needed something else, I'll make this code more generic.
467 fImageData.resize(width * height * 4);
468 } catch (const std::bad_alloc &) {
469 NSLog(@"QuartzImage: -initWithW:
H:data:, memory allocation failed
");
473 std::copy(data, data + width * height * 4, &fImageData[0]);
476 const CGDataProviderDirectCallbacks providerCallbacks = {0, ROOT_QuartzImage_GetBytePointer,
477 ROOT_QuartzImage_ReleaseBytePointer,
478 ROOT_QuartzImage_GetBytesAtPosition, 0};
480 const Util::CFScopeGuard<CGDataProviderRef>
481 provider(CGDataProviderCreateDirect(&fImageData[0], width * height * 4, &providerCallbacks));
482 if (!provider.Get()) {
483 NSLog(@"QuartzImage: -initWithW:
H:data: CGDataProviderCreateDirect failed
");
487 //RGB - this is only for TGCocoa::CreatePixmapFromData.
488 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
489 if (!colorSpace.Get()) {
490 NSLog(@"QuartzImage: -initWithW:
H:data: CGColorSpaceCreateDeviceRGB failed
");
494 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
495 //all values hardcoded for TGCocoa::CreatePixmapFromData.
496 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(),
497 kCGImageAlphaLast, provider.Get(), 0, false,
498 kCGRenderingIntentDefault));
501 NSLog(@"QuartzImage: -initWithW:
H:data: CGImageCreate failed
");
514 //______________________________________________________________________________
515 - (id) initMaskWithW : (unsigned) width H : (unsigned) height bitmapMask : (unsigned char *) mask
517 assert(width != 0 && "initMaskWithW:
H:bitmapMask:, width parameter is zero
");
518 assert(height != 0 && "initMaskWithW:
H:bitmapMask:, height parameter is zero
");
519 assert(mask != 0 && "initMaskWithW:
H:bitmapMask:, mask parameter is
null");
521 if (self = [super init]) {
522 Util::NSScopeGuard<QuartzImage> selfGuard(self);
525 fImageData.resize(width * height);
526 } catch (const std::bad_alloc &) {
527 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, memory allocation failed
");
531 std::copy(mask, mask + width * height, &fImageData[0]);
533 fIsStippleMask = YES;
534 const CGDataProviderDirectCallbacks providerCallbacks = {0, ROOT_QuartzImage_GetBytePointer,
535 ROOT_QuartzImage_ReleaseBytePointer,
536 ROOT_QuartzImage_GetBytesAtPosition, 0};
539 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateDirect(&fImageData[0],
540 width * height, &providerCallbacks));
541 if (!provider.Get()) {
542 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask: CGDataProviderCreateDirect failed
");
546 //0 -> decode, false -> shouldInterpolate.
547 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
549 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, CGImageMaskCreate failed
");
562 //______________________________________________________________________________
563 - (id) initMaskWithW : (unsigned) width H : (unsigned) height
565 //Two-step initialization.
567 assert(width != 0 && "initMaskWithW:
H:, width parameter is zero
");
568 assert(height != 0 && "initMaskWithW:H:, height parameter is zero
");
570 if (self = [super init]) {
571 Util::NSScopeGuard<QuartzImage> selfGuard(self);
574 fImageData.resize(width * height);
575 } catch (const std::bad_alloc &) {
576 NSLog(@"QuartzImage: -initMaskWithW:H:, memory allocation failed
");
580 fIsStippleMask = YES;
581 const CGDataProviderDirectCallbacks providerCallbacks = {0, ROOT_QuartzImage_GetBytePointer,
582 ROOT_QuartzImage_ReleaseBytePointer,
583 ROOT_QuartzImage_GetBytesAtPosition, 0};
585 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateDirect(&fImageData[0],
586 width * height, &providerCallbacks));
587 if (!provider.Get()) {
588 NSLog(@"QuartzImage: -initMaskWithW:H: CGDataProviderCreateDirect failed
");
592 //0 -> decode, false -> shouldInterpolate.
593 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
595 NSLog(@"QuartzImage: -initMaskWithW:H:, CGImageMaskCreate failed
");
608 //______________________________________________________________________________
609 - (id) initFromPixmap : (QuartzPixmap *) pixmap
611 //Two-step initialization.
612 assert(pixmap != nil && "initFromPixmap:, pixmap parameter is nil
");
613 assert(pixmap.fWidth != 0 && "initFromPixmap:, pixmap width is zero
");
614 assert(pixmap.fHeight != 0 && "initFromPixmap:, pixmap height is zero
");
616 return [self initWithW : pixmap.fWidth H : pixmap.fHeight data : pixmap.fData];
619 //______________________________________________________________________________
620 - (id) initFromImage : (QuartzImage *) image
622 assert(image != nil && "initFromImage:,
image parameter is nil
");
623 assert(image.fWidth != 0 && "initFromImage:,
image width is 0
");
624 assert(image.fHeight != 0 && "initFromImage:,
image height is 0
");
625 assert(image.fIsStippleMask == NO && "initFromImage:,
image is
a stipple mask, not implemented
");
627 return [self initWithW : image.fWidth H : image.fHeight data : &image->fImageData[0]];
630 //______________________________________________________________________________
631 - (id) initFromImageFlipped : (QuartzImage *) image
633 assert(image != nil && "initFromImageFlipped:,
image parameter is nil
");
634 assert(image.fWidth != 0 && "initFromImageFlipped:,
image width is 0
");
635 assert(image.fHeight != 0 && "initFromImageFlipped:,
image height is 0
");
637 const unsigned bpp = image.fIsStippleMask ? 1 : 4;
639 if (self = [super init]) {
640 const unsigned width = image.fWidth;
641 const unsigned height = image.fHeight;
643 Util::NSScopeGuard<QuartzImage> selfGuard(self);
646 fImageData.resize(width * height * bpp);
647 } catch (const std::bad_alloc &) {
648 NSLog(@"QuartzImage: -initFromImageFlipped:, memory allocation failed
");
652 const unsigned lineSize = bpp * width;
653 const unsigned char * const src = &image->fImageData[0];
654 unsigned char * const dst = &fImageData[0];
655 for (unsigned i = 0; i < height; ++i) {
656 const unsigned char *sourceLine = src + lineSize * (height - 1 - i);
657 unsigned char *dstLine = dst + i * lineSize;
658 std::copy(sourceLine, sourceLine + lineSize, dstLine);
661 const CGDataProviderDirectCallbacks providerCallbacks = {0, ROOT_QuartzImage_GetBytePointer,
662 ROOT_QuartzImage_ReleaseBytePointer,
663 ROOT_QuartzImage_GetBytesAtPosition, 0};
666 fIsStippleMask = YES;
667 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateDirect(&fImageData[0],
668 width * height, &providerCallbacks));
669 if (!provider.Get()) {
670 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateDirect failed
");
674 //0 -> decode, false -> shouldInterpolate.
675 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
677 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageMaskCreate failed
");
682 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateDirect(&fImageData[0],
683 width * height * 4, &providerCallbacks));
684 if (!provider.Get()) {
685 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateDirect failed
");
689 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
690 if (!colorSpace.Get()) {
691 NSLog(@"QuartzImage: -initFromImageFlipped:, CGColorSpaceCreateDeviceRGB failed
");
695 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
696 //all values hardcoded for TGCocoa::CreatePixmapFromData.
697 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(), kCGImageAlphaLast,
698 provider.Get(), 0, false, kCGRenderingIntentDefault));
700 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageCreate failed
");
714 //______________________________________________________________________________
715 - (BOOL) isRectInside : (X11::Rectangle) area
717 if (area.fX < 0 || (unsigned)area.fX >= fWidth)
719 if (area.fY < 0 || (unsigned)area.fY >= fHeight)
721 if (area.fWidth > fWidth || !area.fWidth)
723 if (area.fHeight > fHeight || !area.fHeight)
729 //______________________________________________________________________________
730 - (unsigned char *) readColorBits : (X11::Rectangle) area
732 assert([self isRectInside : area] == YES && "readColorBits: bad area parameter
");
733 //Image, bitmap - they all must be converted to ARGB (bitmap) or BGRA (image) (for libAfterImage).
734 //Raw pointer - we pass the ownership.
735 unsigned char *buffer = 0;
738 buffer = new unsigned char[area.fWidth * area.fHeight * 4]();
739 } catch (const std::bad_alloc &) {
740 NSLog(@"QuartzImage: -readColorBits:, memory allocation failed
");
744 unsigned char *dstPixel = buffer;
745 if (CGImageIsMask(fImage.Get())) {
746 //fImageData has 1 byte per pixel.
747 const unsigned char *line = &fImageData[0] + area.fY * fWidth;
748 const unsigned char *srcPixel = line + area.fX;
750 for (unsigned i = 0; i < area.fHeight; ++i) {
751 for (unsigned j = 0; j < area.fWidth; ++j, ++srcPixel, dstPixel += 4) {
753 dstPixel[0] = 255;//can be 1 or anything different from 0.
757 srcPixel = line + area.fX;
761 //fImageData has 4 bytes per pixel.
762 const unsigned char *line = &fImageData[0] + area.fY * fWidth * 4;
763 const unsigned char *srcPixel = line + area.fX * 4;
765 for (unsigned i = 0; i < area.fHeight; ++i) {
766 for (unsigned j = 0; j < area.fWidth; ++j, srcPixel += 4, dstPixel += 4) {
767 dstPixel[0] = srcPixel[2];
768 dstPixel[1] = srcPixel[1];
769 dstPixel[2] = srcPixel[0];
770 dstPixel[3] = srcPixel[3];
774 srcPixel = line + area.fX * 4;
783 //______________________________________________________________________________
789 //______________________________________________________________________________
790 - (BOOL) fIsOpenGLWidget
795 //______________________________________________________________________________
801 //______________________________________________________________________________
807 //______________________________________________________________________________
808 - (CGImageRef) fImage
819 //______________________________________________________________________________
820 CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
824 const CGRect subImageRect = CGRectMake(area.fX, area.fY, area.fHeight, area.fWidth);
825 return CGImageCreateWithImageInRect(image.fImage, subImageRect);
830 //Now, close your eyes and open them at the end of this block. :)
831 //Sure, this can be done easy, but I hate to convert between negative signed integers and
832 //unsigned integers and the other way, so I have this implementation (integers will be always
833 //positive and they obviously fit into unsigned integers).
835 typedef std::pair<int, unsigned> range_type;
837 //______________________________________________________________________________
838 bool FindOverlapSameSigns(const range_type &left, const range_type &right, range_type &intersection)
840 //"Same
" means both xs are non-negative, or both are negative.
842 const unsigned dX(right.first - left.first);//diff fits into the positive range of int.
844 if (dX >= left.second)
846 //Find an intersection.
847 intersection.first = right.first;
848 intersection.second = std::min(right.second, left.second - dX);//left.second is always > dX.
853 //______________________________________________________________________________
854 bool FindOverlapDifferentSigns(const range_type &left, const range_type &right, range_type &intersection)
856 //x2 - x1 can overflow.
857 //Left.x is negative, right.x is non-negative (0 included).
858 const unsigned signedMinAbs(std::numeric_limits<unsigned>::max() / 2 + 1);
860 if (left.first == std::numeric_limits<int>::min()) {//hehehe
861 if (left.second <= signedMinAbs)
864 if (left.second - signedMinAbs <= unsigned(right.first))
867 intersection.first = right.first;
868 intersection.second = std::min(right.second, left.second - signedMinAbs - unsigned(right.first));
870 const unsigned leftXAbs(-left.first);//-left.first can't overflow.
871 if (leftXAbs >= left.second)
874 if (left.second - leftXAbs <= unsigned(right.first))
877 intersection.first = right.first;
878 intersection.second = std::min(right.second, left.second - leftXAbs - unsigned(right.first));
884 //______________________________________________________________________________
885 bool FindOverlap(const range_type &range1, const range_type &range2, range_type &intersection)
890 if (range1.first < range2.first) {
899 return right.first < 0 ? FindOverlapSameSigns(left, right, intersection) :
900 FindOverlapDifferentSigns(left, right, intersection);
902 return FindOverlapSameSigns(left, right, intersection);
907 //______________________________________________________________________________
908 bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)
910 //Find rects intersection.
911 range_type xIntersection;
912 if (!FindOverlap(range_type(srcRect.fX, srcRect.fWidth),
913 range_type(cropArea.fX, cropArea.fWidth), xIntersection))
916 range_type yIntersection;
917 if (!FindOverlap(range_type(srcRect.fY, srcRect.fHeight),
918 range_type(cropArea.fY, cropArea.fHeight), yIntersection))
921 cropArea.fX = xIntersection.first;
922 cropArea.fWidth = xIntersection.second;
924 cropArea.fY = yIntersection.first;
925 cropArea.fHeight = yIntersection.second;
930 //______________________________________________________________________________
931 bool AdjustCropArea(QuartzImage *srcImage, Rectangle &cropArea)
933 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
936 return AdjustCropArea(X11::Rectangle(0, 0, srcImage.fWidth, srcImage.fHeight), cropArea);
939 //______________________________________________________________________________
940 bool AdjustCropArea(QuartzImage *srcImage, NSRect &cropArea)
942 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
943 assert(srcImage.fImage != 0 && "AdjustCropArea, srcImage.
fImage is
null");
945 const Rectangle srcRect(0, 0, srcImage.fWidth, srcImage.fHeight);
946 Rectangle dstRect(int(cropArea.origin.x), int(cropArea.origin.y),
947 unsigned(cropArea.size.width), unsigned(cropArea.size.height));
949 if (AdjustCropArea(srcRect, dstRect)) {
950 cropArea.origin.x = dstRect.fX;
951 cropArea.origin.y = dstRect.fY;
952 cropArea.size.width = dstRect.fWidth;
953 cropArea.size.height = dstRect.fHeight;
961 //______________________________________________________________________________
962 bool AdjustCropArea(QuartzPixmap *srcPixmap, X11::Rectangle &cropArea)
964 assert(srcPixmap != nil && "AdjustCropArea, srcPixmap parameter is nil
");
966 return AdjustCropArea(X11::Rectangle(0, 0, srcPixmap.fWidth, srcPixmap.fHeight), cropArea);
969 //______________________________________________________________________________
970 bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
972 //Test if a bit (i,j) is set in a bitmap (w, h).
974 //Code in ROOT's GUI suggests, that byte is octet.
977 assert(i < w && "TestBitmapBit, i parameter is >=
w");
979 const unsigned bytesPerLine = (w + 7) / 8;
980 const unsigned char *line = bitmap + j * bytesPerLine;
981 const unsigned char byteValue = line[i / 8];
983 return byteValue & (1 << (i % 8));
986 //______________________________________________________________________________
987 void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height,
988 ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth,
989 unsigned char *imageData)
993 assert(height != 0 && "FillPixmapBuffer, height parameter is 0
");
994 assert(imageData != 0 && "FillPixmapBuffer, imageData parameter is
null");
997 unsigned char foregroundColor[4] = {};
998 PixelToRGB(foregroundPixel, foregroundColor);
999 unsigned char backgroundColor[4] = {};
1000 PixelToRGB(backgroundPixel, backgroundColor);
1002 for (unsigned j = 0; j < height; ++j) {
1003 const unsigned line = j * width * 4;
1004 for (unsigned i = 0; i < width; ++i) {
1005 const unsigned pixel = line + i * 4;
1007 if (TestBitmapBit(bitmap, width, i, j)) {
1009 imageData[pixel] = foregroundColor[0];
1010 imageData[pixel + 1] = foregroundColor[1];
1011 imageData[pixel + 2] = foregroundColor[2];
1013 imageData[pixel] = backgroundColor[0];
1014 imageData[pixel + 1] = backgroundColor[1];
1015 imageData[pixel + 2] = backgroundColor[2];
1018 imageData[pixel + 3] = 255;
1022 for (unsigned j = 0; j < height; ++j) {
1023 const unsigned line = j * width;
1024 for (unsigned i = 0; i < width; ++i) {
1025 const unsigned pixel = line + i;
1026 if (TestBitmapBit(bitmap, width, i, j))
1027 imageData[pixel] = 0;
1029 imageData[pixel] = 255;//mask out pixel.
ROOT::MacOSX::Util::CFScopeGuard< CGImageRef > fImage
bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)
void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height, ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth, unsigned char *imageData)
const void * ROOT_QuartzImage_GetBytePointer(void *info)
bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
CGImageRef createImageFromPixmap()
std::size_t ROOT_QuartzImage_GetBytesAtPosition(void *info, void *buffer, off_t position, std::size_t count)
int LocalYROOTToCocoa(NSView< X11Window > *parentView, CGFloat yROOT)
ROOT::MacOSX::Util::CFScopeGuard< CGContextRef > fContext
typedef void((*Func_t)())
const char Int_t const char * image
void ROOT_QuartzImage_ReleaseBytePointer(void *, const void *)