28 namespace X11 = ROOT::MacOSX::X11;
29 namespace Util = ROOT::MacOSX::Util;
30 namespace Quartz = ROOT::Quartz;
37 - (
id) initWithW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
39 if (
self = [super
init]) {
43 if (![
self resizeW : width
H : height scaleFactor : scaleFactor]) {
53 - (BOOL) resizeW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
55 assert(width > 0 &&
"resizeW:H:, Pixmap width must be positive");
56 assert(height > 0 &&
"resizeW:H:, Pixmap height must be positive");
60 std::vector<unsigned char> memory;
66 memory.resize(scaledW * scaledH * 4);
67 }
catch (
const std::bad_alloc &) {
68 NSLog(
@"QuartzPixmap: -resizeW:H:, memory allocation failed");
72 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
73 if (!colorSpace.Get()) {
74 NSLog(
@"QuartzPixmap: -resizeW:H:, CGColorSpaceCreateDeviceRGB failed");
78 Util::CFScopeGuard<CGContextRef> ctx(CGBitmapContextCreateWithData(&memory[0], scaledW, scaledH, 8,
79 scaledW * 4, colorSpace.Get(),
80 kCGImageAlphaPremultipliedLast,
NULL, 0));
82 NSLog(
@"QuartzPixmap: -resizeW:H:, CGBitmapContextCreateWithData failed");
105 return [
self createImageFromPixmap : X11::Rectangle(0, 0, fWidth, fHeight)];
116 assert(cropArea.fX >= 0 &&
"createImageFromPixmap:, cropArea.fX is negative");
117 assert(cropArea.fY >= 0 &&
"createImageFromPixmap:, cropArea.fY is negative");
118 assert(cropArea.fWidth <=
fWidth &&
"createImageFromPixmap:, bad cropArea.fWidth");
119 assert(cropArea.fHeight <=
fHeight &&
"createImageFromPixmap:, bad cropArea.fHeight");
125 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(
nullptr, &
fData[0],
126 scaledW * scaledH * 4,
nullptr));
127 if (!provider.Get()) {
128 NSLog(
@"QuartzPixmap: -pixmapToImage, CGDataProviderCreateWithData failed");
133 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
134 if (!colorSpace.Get()) {
135 NSLog(
@"QuartzPixmap: -pixmapToImage, CGColorSpaceCreateDeviceRGB failed");
143 kCGImageAlphaPremultipliedLast, provider.Get(), 0,
144 false, kCGRenderingIntentDefault);
164 assert(
fContext.
Get() != 0 &&
"fContext, called for bad pixmap");
172 assert(
fContext.
Get() != 0 &&
"fWidth, called for bad pixmap");
180 assert(
fContext.
Get() != 0 &&
"fHeight, called for bad pixmap");
186 - (
void) copyImage : (
QuartzImage *) srcImage area : (X11::Rectangle) area
187 withMask : (
QuartzImage *) mask clipOrigin : (X11::Point) clipXY toPoint : (X11::Point) dstPoint
189 using namespace ROOT::MacOSX::X11;
192 assert(srcImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage parameter is nil");
193 assert(srcImage.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage.fImage is nil");
196 NSLog(
@"QuartzPixmap: -copyImage:srcImage:area:withMask:clipOrigin"
197 ":toPoint, srcRect and copyRect do not intersect");
201 CGImageRef subImage = 0;
202 bool needSubImage =
false;
203 if (area.fX || area.fY || area.fWidth != srcImage.
fWidth || area.fHeight != srcImage.
fHeight) {
207 NSLog(
@"QuartzPixmap: -copyImage:area:withMask:clipOrigin:toPoint:, subimage creation failed");
211 subImage = srcImage.
fImage;
217 assert(mask.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
218 assert(CGImageIsMask(mask.
fImage) &&
"copyImage:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
221 const CGRect clipRect = CGRectMake(clipXY.fX, clipXY.fY, mask.
fWidth, mask.
fHeight);
227 const CGRect imageRect = CGRectMake(dstPoint.fX, dstPoint.fY, area.fWidth, area.fHeight);
228 CGContextDrawImage(
fContext.
Get(), imageRect, subImage);
231 CGImageRelease(subImage);
238 using namespace ROOT::MacOSX::X11;
240 assert(srcPixmap != nil &&
241 "copyPixmap:area:withMask:clipOrigin:toPoint, srcPixmap parameter is nil");
244 NSLog(
@"QuartzPixmap: -copyPixmap:area:withMask:clipOrigin:"
245 "toPoint, srcRect and copyRect do not intersect");
256 assert(mask.
fImage != nil &&
257 "copyPixmap:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
258 assert(CGImageIsMask(mask.
fImage) &&
259 "copyPixmap:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
262 const CGRect clipRect = CGRectMake(clipXY.
fX, clipXY.
fY, mask.
fWidth, mask.
fHeight);
268 const CGRect imageRect = CGRectMake(dstPoint.
fX, dstPoint.
fY, area.
fWidth, area.
fHeight);
269 CGContextDrawImage(
fContext.
Get(), imageRect, image.Get());
277 "copy:area:widthMask:clipOrigin:toPoint, empty area to copy");
280 [
self copyImage : (QuartzImage *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
281 }
else if ([src isKindOfClass : [
QuartzPixmap class]]) {
282 [
self copyPixmap : (QuartzPixmap *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
284 assert(0 &&
"Can copy only from pixmap or image");
288 - (
unsigned char *) readColorBits : (X11::
Rectangle) area
290 assert(area.
fWidth && area.
fHeight &&
"readColorBits:, empty area to copy");
293 NSLog(
@"QuartzPixmap: readColorBits:intoBuffer:, src and copy area do not intersect");
298 unsigned char *buffer = 0;
300 buffer =
new unsigned char[area.fWidth * area.fHeight * 4]();
301 }
catch (
const std::bad_alloc &) {
302 NSLog(
@"QuartzImage: -readColorBits:, memory allocation failed");
306 Util::NSScopeGuard<QuartzPixmap> scaledPixmap;
311 if (!scaledPixmap.Get()) {
312 NSLog(
@"QuartzImage: -readColorBits:, can not create scaled pixmap");
316 [scaledPixmap.Get() copy : self area : X11::Rectangle(0, 0, fWidth, fHeight)
317 withMask : nil clipOrigin : X11::Point() toPoint : X11::Point()];
320 unsigned char *dstPixel = buffer;
325 : &scaledPixmap.Get()->fData[0] + area.
fY *
fWidth * 4;
327 const unsigned char *srcPixel = line + area.
fX * 4;
329 for (
unsigned i = 0; i < area.
fHeight; ++i) {
330 for (
unsigned j = 0; j < area.
fWidth; ++j, srcPixel += 4, dstPixel += 4) {
331 dstPixel[0] = srcPixel[0];
332 dstPixel[1] = srcPixel[1];
333 dstPixel[2] = srcPixel[2];
334 dstPixel[3] = srcPixel[3];
338 srcPixel = line + area.
fX * 4;
351 - (
void) putPixel : (const
unsigned char *) rgb X : (
unsigned) x Y : (
unsigned) y
354 assert(rgb != 0 &&
"putPixel:X:Y:, rgb parameter is null");
355 assert(x < fWidth && "putPixel:X:Y:, x parameter is >=
self.
fWidth");
356 assert(y < fHeight && "putPixel:
X:
Y:, y parameter is >=
self.
fHeight");
358 unsigned char * const data = &fData[0];
359 if (fScaleFactor > 1) {
360 //Ooops, and what should I do now???
361 const unsigned scaledW = fWidth * fScaleFactor;
362 unsigned char *dst = data + y * fScaleFactor * scaledW * 4 + x * fScaleFactor * 4;
364 for (unsigned i = 0; i < 2; ++i, dst += 4) {
374 for (unsigned i = 0; i < 2; ++i, dst += 4) {
381 unsigned char *dst = data + y * fWidth * 4 + x * 4;
390 //______________________________________________________________________________
391 - (void) addPixel : (const unsigned char *) rgb
393 //Primitive version of XAddPixel.
394 assert(rgb != 0 && "addPixel:, rgb parameter is
null");
396 for (unsigned i = 0; i < fHeight; ++i) {
397 for (unsigned j = 0; j < fWidth; ++j) {
398 fData[i * fWidth * 4 + j * 4] = rgb[0];
399 fData[i * fWidth * 4 + j * 4 + 1] = rgb[1];
400 fData[i * fWidth * 4 + j * 4 + 2] = rgb[2];
401 fData[i * fWidth * 4 + j * 4 + 3] = rgb[3];
408 @implementation QuartzImage
410 @synthesize fIsStippleMask;
413 //______________________________________________________________________________
414 - (id) initWithW : (unsigned) width H : (unsigned) height data : (unsigned char *) data
416 assert(width != 0 && "initWithW:
H:
data:, width parameter is 0
");
417 assert(height != 0 && "initWithW:
H:data:, height parameter is 0
");
418 assert(data != 0 && "initWithW:
H:data:, data parameter is
null");
420 if (self = [super init]) {
421 Util::NSScopeGuard<QuartzImage> selfGuard(self);
423 //This w * h * 4 is ONLY for TGCocoa::CreatePixmapFromData.
424 //If needed something else, I'll make this code more generic.
426 fImageData.resize(width * height * 4);
427 } catch (const std::bad_alloc &) {
428 NSLog(@"QuartzImage: -initWithW:
H:data:, memory allocation failed
");
432 std::copy(data, data + width * height * 4, &fImageData[0]);
435 const Util::CFScopeGuard<CGDataProviderRef>
436 provider(CGDataProviderCreateWithData(nullptr, &fImageData[0], width * height * 4, nullptr));
437 if (!provider.Get()) {
438 NSLog(@"QuartzImage: -initWithW:
H:data: CGDataProviderCreateWithData failed
");
442 //RGB - this is only for TGCocoa::CreatePixmapFromData.
443 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
444 if (!colorSpace.Get()) {
445 NSLog(@"QuartzImage: -initWithW:
H:data: CGColorSpaceCreateDeviceRGB failed
");
449 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
450 //all values hardcoded for TGCocoa::CreatePixmapFromData.
451 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(),
452 kCGImageAlphaLast, provider.Get(), 0, false,
453 kCGRenderingIntentDefault));
456 NSLog(@"QuartzImage: -initWithW:
H:data: CGImageCreate failed
");
469 //______________________________________________________________________________
470 - (id) initMaskWithW : (unsigned) width H : (unsigned) height bitmapMask : (unsigned char *) mask
472 assert(width != 0 && "initMaskWithW:
H:bitmapMask:, width parameter is zero
");
473 assert(height != 0 && "initMaskWithW:
H:bitmapMask:, height parameter is zero
");
474 assert(mask != 0 && "initMaskWithW:
H:bitmapMask:, mask parameter is
null");
476 if (self = [super init]) {
477 Util::NSScopeGuard<QuartzImage> selfGuard(self);
480 fImageData.resize(width * height);
481 } catch (const std::bad_alloc &) {
482 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, memory allocation failed
");
486 std::copy(mask, mask + width * height, &fImageData[0]);
488 fIsStippleMask = YES;
489 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
490 width * height, nullptr));
491 if (!provider.Get()) {
492 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask: CGDataProviderCreateWithData failed
");
496 //0 -> decode, false -> shouldInterpolate.
497 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
499 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, CGImageMaskCreate failed
");
512 //______________________________________________________________________________
513 - (id) initMaskWithW : (unsigned) width H : (unsigned) height
515 //Two-step initialization.
517 assert(width != 0 && "initMaskWithW:
H:, width parameter is zero
");
518 assert(height != 0 && "initMaskWithW:H:, height parameter is zero
");
520 if (self = [super init]) {
521 Util::NSScopeGuard<QuartzImage> selfGuard(self);
524 fImageData.resize(width * height);
525 } catch (const std::bad_alloc &) {
526 NSLog(@"QuartzImage: -initMaskWithW:H:, memory allocation failed
");
530 fIsStippleMask = YES;
531 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
532 width * height, nullptr));
533 if (!provider.Get()) {
534 NSLog(@"QuartzImage: -initMaskWithW:H: CGDataProviderCreateWithData failed
");
538 //0 -> decode, false -> shouldInterpolate.
539 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
541 NSLog(@"QuartzImage: -initMaskWithW:H:, CGImageMaskCreate failed
");
554 //______________________________________________________________________________
555 - (id) initFromPixmap : (QuartzPixmap *) pixmap
557 //Two-step initialization.
558 assert(pixmap != nil && "initFromPixmap:, pixmap parameter is nil
");
559 assert(pixmap.fWidth != 0 && "initFromPixmap:, pixmap width is zero
");
560 assert(pixmap.fHeight != 0 && "initFromPixmap:, pixmap height is zero
");
562 return [self initWithW : pixmap.fWidth H : pixmap.fHeight data : pixmap.fData];
565 //______________________________________________________________________________
566 - (id) initFromImage : (QuartzImage *) image
568 assert(image != nil && "initFromImage:, image parameter is nil
");
569 assert(image.fWidth != 0 && "initFromImage:, image width is 0
");
570 assert(image.fHeight != 0 && "initFromImage:, image height is 0
");
571 assert(image.fIsStippleMask == NO && "initFromImage:, image is
a stipple mask, not implemented
");
573 return [self initWithW : image.fWidth H : image.fHeight data : &image->fImageData[0]];
576 //______________________________________________________________________________
577 - (id) initFromImageFlipped : (QuartzImage *) image
579 assert(image != nil && "initFromImageFlipped:, image parameter is nil
");
580 assert(image.fWidth != 0 && "initFromImageFlipped:, image width is 0
");
581 assert(image.fHeight != 0 && "initFromImageFlipped:, image height is 0
");
583 const unsigned bpp = image.fIsStippleMask ? 1 : 4;
585 if (self = [super init]) {
586 const unsigned width = image.fWidth;
587 const unsigned height = image.fHeight;
589 Util::NSScopeGuard<QuartzImage> selfGuard(self);
592 fImageData.resize(width * height * bpp);
593 } catch (const std::bad_alloc &) {
594 NSLog(@"QuartzImage: -initFromImageFlipped:, memory allocation failed
");
598 const unsigned lineSize = bpp * width;
599 const unsigned char * const src = &image->fImageData[0];
600 unsigned char * const dst = &fImageData[0];
601 for (unsigned i = 0; i < height; ++i) {
602 const unsigned char *sourceLine = src + lineSize * (height - 1 - i);
603 unsigned char *dstLine = dst + i * lineSize;
604 std::copy(sourceLine, sourceLine + lineSize, dstLine);
608 fIsStippleMask = YES;
609 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
610 width * height, nullptr));
611 if (!provider.Get()) {
612 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateWithData failed
");
616 //0 -> decode, false -> shouldInterpolate.
617 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
619 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageMaskCreate failed
");
624 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
625 width * height * 4, nullptr));
626 if (!provider.Get()) {
627 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateWithData failed
");
631 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
632 if (!colorSpace.Get()) {
633 NSLog(@"QuartzImage: -initFromImageFlipped:, CGColorSpaceCreateDeviceRGB failed
");
637 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
638 //all values hardcoded for TGCocoa::CreatePixmapFromData.
639 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(), kCGImageAlphaLast,
640 provider.Get(), 0, false, kCGRenderingIntentDefault));
642 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageCreate failed
");
656 //______________________________________________________________________________
657 - (BOOL) isRectInside : (X11::Rectangle) area
659 if (area.fX < 0 || (unsigned)area.fX >= fWidth)
661 if (area.fY < 0 || (unsigned)area.fY >= fHeight)
663 if (area.fWidth > fWidth || !area.fWidth)
665 if (area.fHeight > fHeight || !area.fHeight)
671 //______________________________________________________________________________
672 - (unsigned char *) readColorBits : (X11::Rectangle) area
674 assert([self isRectInside : area] == YES && "readColorBits: bad area parameter
");
675 //Image, bitmap - they all must be converted to ARGB (bitmap) or BGRA (image) (for libAfterImage).
676 //Raw pointer - we pass the ownership.
677 unsigned char *buffer = 0;
680 buffer = new unsigned char[area.fWidth * area.fHeight * 4]();
681 } catch (const std::bad_alloc &) {
682 NSLog(@"QuartzImage: -readColorBits:, memory allocation failed
");
686 unsigned char *dstPixel = buffer;
687 if (CGImageIsMask(fImage.Get())) {
688 //fImageData has 1 byte per pixel.
689 const unsigned char *line = &fImageData[0] + area.fY * fWidth;
690 const unsigned char *srcPixel = line + area.fX;
692 for (unsigned i = 0; i < area.fHeight; ++i) {
693 for (unsigned j = 0; j < area.fWidth; ++j, ++srcPixel, dstPixel += 4) {
695 dstPixel[0] = 255;//can be 1 or anything different from 0.
699 srcPixel = line + area.fX;
703 //fImageData has 4 bytes per pixel.
704 const unsigned char *line = &fImageData[0] + area.fY * fWidth * 4;
705 const unsigned char *srcPixel = line + area.fX * 4;
707 for (unsigned i = 0; i < area.fHeight; ++i) {
708 for (unsigned j = 0; j < area.fWidth; ++j, srcPixel += 4, dstPixel += 4) {
709 dstPixel[0] = srcPixel[2];
710 dstPixel[1] = srcPixel[1];
711 dstPixel[2] = srcPixel[0];
712 dstPixel[3] = srcPixel[3];
716 srcPixel = line + area.fX * 4;
725 //______________________________________________________________________________
731 //______________________________________________________________________________
732 - (BOOL) fIsOpenGLWidget
737 //______________________________________________________________________________
743 //______________________________________________________________________________
749 //______________________________________________________________________________
750 - (CGImageRef) fImage
761 //______________________________________________________________________________
762 CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
766 const CGRect subImageRect = CGRectMake(area.fX, area.fY, area.fHeight, area.fWidth);
767 return CGImageCreateWithImageInRect(image.fImage, subImageRect);
772 //Now, close your eyes and open them at the end of this block. :)
773 //Sure, this can be done easy, but I hate to convert between negative signed integers and
774 //unsigned integers and the other way, so I have this implementation (integers will be always
775 //positive and they obviously fit into unsigned integers).
777 typedef std::pair<int, unsigned> range_type;
779 //______________________________________________________________________________
780 bool FindOverlapSameSigns(const range_type &left, const range_type &right, range_type &intersection)
782 //"Same
" means both xs are non-negative, or both are negative.
784 const unsigned dX(right.first - left.first);//diff fits into the positive range of int.
786 if (dX >= left.second)
788 //Find an intersection.
789 intersection.first = right.first;
790 intersection.second = std::min(right.second, left.second - dX);//left.second is always > dX.
795 //______________________________________________________________________________
796 bool FindOverlapDifferentSigns(const range_type &left, const range_type &right, range_type &intersection)
798 //x2 - x1 can overflow.
799 //Left.x is negative, right.x is non-negative (0 included).
800 const unsigned signedMinAbs(std::numeric_limits<unsigned>::max() / 2 + 1);
802 if (left.first == std::numeric_limits<int>::min()) {//hehehe
803 if (left.second <= signedMinAbs)
806 if (left.second - signedMinAbs <= unsigned(right.first))
809 intersection.first = right.first;
810 intersection.second = std::min(right.second, left.second - signedMinAbs - unsigned(right.first));
812 const unsigned leftXAbs(-left.first);//-left.first can't overflow.
813 if (leftXAbs >= left.second)
816 if (left.second - leftXAbs <= unsigned(right.first))
819 intersection.first = right.first;
820 intersection.second = std::min(right.second, left.second - leftXAbs - unsigned(right.first));
826 //______________________________________________________________________________
827 bool FindOverlap(const range_type &range1, const range_type &range2, range_type &intersection)
832 if (range1.first < range2.first) {
841 return right.first < 0 ? FindOverlapSameSigns(left, right, intersection) :
842 FindOverlapDifferentSigns(left, right, intersection);
844 return FindOverlapSameSigns(left, right, intersection);
849 //______________________________________________________________________________
850 bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)
852 //Find rects intersection.
853 range_type xIntersection;
854 if (!FindOverlap(range_type(srcRect.fX, srcRect.fWidth),
855 range_type(cropArea.fX, cropArea.fWidth), xIntersection))
858 range_type yIntersection;
859 if (!FindOverlap(range_type(srcRect.fY, srcRect.fHeight),
860 range_type(cropArea.fY, cropArea.fHeight), yIntersection))
863 cropArea.fX = xIntersection.first;
864 cropArea.fWidth = xIntersection.second;
866 cropArea.fY = yIntersection.first;
867 cropArea.fHeight = yIntersection.second;
872 //______________________________________________________________________________
873 bool AdjustCropArea(QuartzImage *srcImage, Rectangle &cropArea)
875 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
878 return AdjustCropArea(X11::Rectangle(0, 0, srcImage.fWidth, srcImage.fHeight), cropArea);
881 //______________________________________________________________________________
882 bool AdjustCropArea(QuartzImage *srcImage, NSRect &cropArea)
884 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
885 assert(srcImage.fImage != 0 && "AdjustCropArea, srcImage.
fImage is
null");
887 const Rectangle srcRect(0, 0, srcImage.fWidth, srcImage.fHeight);
888 Rectangle dstRect(int(cropArea.origin.x), int(cropArea.origin.y),
889 unsigned(cropArea.size.width), unsigned(cropArea.size.height));
891 if (AdjustCropArea(srcRect, dstRect)) {
892 cropArea.origin.x = dstRect.fX;
893 cropArea.origin.y = dstRect.fY;
894 cropArea.size.width = dstRect.fWidth;
895 cropArea.size.height = dstRect.fHeight;
903 //______________________________________________________________________________
904 bool AdjustCropArea(QuartzPixmap *srcPixmap, X11::Rectangle &cropArea)
906 assert(srcPixmap != nil && "AdjustCropArea, srcPixmap parameter is nil
");
908 return AdjustCropArea(X11::Rectangle(0, 0, srcPixmap.fWidth, srcPixmap.fHeight), cropArea);
911 //______________________________________________________________________________
912 bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
914 //Test if a bit (i,j) is set in a bitmap (w, h).
916 //Code in ROOT's GUI suggests, that byte is octet.
919 assert(i < w && "TestBitmapBit, i parameter is >= w
");
921 const unsigned bytesPerLine = (w + 7) / 8;
922 const unsigned char *line = bitmap + j * bytesPerLine;
923 const unsigned char byteValue = line[i / 8];
925 return byteValue & (1 << (i % 8));
928 //______________________________________________________________________________
929 void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height,
930 ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth,
931 unsigned char *imageData)
935 assert(height != 0 && "FillPixmapBuffer, height parameter is 0
");
936 assert(imageData != 0 && "FillPixmapBuffer, imageData parameter is
null");
939 unsigned char foregroundColor[4] = {};
940 PixelToRGB(foregroundPixel, foregroundColor);
941 unsigned char backgroundColor[4] = {};
942 PixelToRGB(backgroundPixel, backgroundColor);
944 for (unsigned j = 0; j < height; ++j) {
945 const unsigned line = j * width * 4;
946 for (unsigned i = 0; i < width; ++i) {
947 const unsigned pixel = line + i * 4;
949 if (TestBitmapBit(bitmap, width, i, j)) {
951 imageData[pixel] = foregroundColor[0];
952 imageData[pixel + 1] = foregroundColor[1];
953 imageData[pixel + 2] = foregroundColor[2];
955 imageData[pixel] = backgroundColor[0];
956 imageData[pixel + 1] = backgroundColor[1];
957 imageData[pixel + 2] = backgroundColor[2];
960 imageData[pixel + 3] = 255;
964 for (unsigned j = 0; j < height; ++j) {
965 const unsigned line = j * width;
966 for (unsigned i = 0; i < width; ++i) {
967 const unsigned pixel = line + i;
968 if (TestBitmapBit(bitmap, width, i, j))
969 imageData[pixel] = 0;
971 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)
bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
CGImageRef createImageFromPixmap()
int LocalYROOTToCocoa(NSView< X11Window > *parentView, CGFloat yROOT)
ROOT::MacOSX::Util::CFScopeGuard< CGContextRef > fContext
typedef void((*Func_t)())