37- (
id) initWithW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
39 if (self = [super init]) {
44 if (![self resizeW : width
H : height scaleFactor : scaleFactor]) {
54- (BOOL) resizeW : (
unsigned) width H : (
unsigned) height scaleFactor : (CGFloat) scaleFactor
56 assert(width > 0 &&
"resizeW:H:, Pixmap width must be positive");
57 assert(height > 0 &&
"resizeW:H:, Pixmap height must be positive");
61 std::vector<unsigned char> memory;
67 memory.resize(scaledW * scaledH * 4);
68 }
catch (
const std::bad_alloc &) {
69 NSLog(
@"QuartzPixmap: -resizeW:H:, memory allocation failed");
74 if (!colorSpace.
Get()) {
75 NSLog(
@"QuartzPixmap: -resizeW:H:, CGColorSpaceCreateDeviceRGB failed");
80 scaledW * 4, colorSpace.
Get(),
81 kCGImageAlphaPremultipliedLast, NULL, 0));
83 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");
126 scaledW * scaledH * 4,
nullptr));
127 if (!provider.
Get()) {
128 NSLog(
@"QuartzPixmap: -pixmapToImage, CGDataProviderCreateWithData failed");
134 if (!colorSpace.
Get()) {
135 NSLog(
@"QuartzPixmap: -pixmapToImage, CGColorSpaceCreateDeviceRGB failed");
143 kCGImageAlphaPremultipliedLast, provider.
Get(), 0,
144 false, kCGRenderingIntentDefault);
170 assert(
fContext.Get() != 0 &&
"fContext, called for bad pixmap");
178 assert(
fContext.Get() != 0 &&
"fWidth, called for bad pixmap");
186 assert(
fContext.Get() != 0 &&
"fHeight, called for bad pixmap");
216- (void) setDirectDraw : (BOOL) mode
228- (void) copyImage : (
QuartzImage *) srcImage area : (
X11::Rectangle) area
229 withMask : (
QuartzImage *) mask clipOrigin : (
X11::Point) clipXY toPoint : (
X11::Point) dstPoint
234 assert(srcImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage parameter is nil");
235 assert(srcImage.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint:, srcImage.fImage is nil");
238 NSLog(
@"QuartzPixmap: -copyImage:srcImage:area:withMask:clipOrigin"
239 ":toPoint, srcRect and copyRect do not intersect");
243 CGImageRef subImage = 0;
244 bool needSubImage =
false;
245 if (area.fX || area.fY || area.fWidth != srcImage.
fWidth || area.fHeight != srcImage.
fHeight) {
249 NSLog(
@"QuartzPixmap: -copyImage:area:withMask:clipOrigin:toPoint:, subimage creation failed");
253 subImage = srcImage.
fImage;
256 const Quartz::CGStateGuard stateGuard(
fContext);
259 assert(mask.
fImage != nil &&
"copyImage:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
260 assert(CGImageIsMask(mask.
fImage) &&
"copyImage:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
263 const CGRect clipRect = CGRectMake(clipXY.fX, clipXY.fY, mask.
fWidth, mask.
fHeight);
269 const CGRect imageRect = CGRectMake(dstPoint.fX, dstPoint.fY, area.fWidth, area.fHeight);
270 CGContextDrawImage(
fContext.Get(), imageRect, subImage);
273 CGImageRelease(subImage);
278 withMask : (
QuartzImage *)mask clipOrigin : (
X11::Point) clipXY toPoint : (
X11::Point) dstPoint
280 using namespace ROOT::MacOSX::X11;
282 assert(srcPixmap != nil &&
283 "copyPixmap:area:withMask:clipOrigin:toPoint, srcPixmap parameter is nil");
286 NSLog(
@"QuartzPixmap: -copyPixmap:area:withMask:clipOrigin:"
287 "toPoint, srcRect and copyRect do not intersect");
295 const Quartz::CGStateGuard stateGuard(
fContext);
298 assert(mask.
fImage != nil &&
299 "copyPixmap:area:withMask:clipOrigin:toPoint, mask is not nil, but mask.fImage is nil");
300 assert(CGImageIsMask(mask.
fImage) &&
301 "copyPixmap:area:withMask:clipOrigin:toPoint, mask.fImage is not a mask");
304 const CGRect clipRect = CGRectMake(clipXY.fX, clipXY.fY, mask.
fWidth, mask.
fHeight);
310 const CGRect imageRect = CGRectMake(dstPoint.fX, dstPoint.fY, area.
fWidth, area.
fHeight);
311 CGContextDrawImage(
fContext.Get(), imageRect, image.Get());
316 withMask : (
QuartzImage *)mask clipOrigin : (
X11::Point) origin toPoint : (
X11::Point) dstPoint
319 "copy:area:widthMask:clipOrigin:toPoint, empty area to copy");
322 [
self copyImage : (QuartzImage *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
323 }
else if ([src isKindOfClass : [
QuartzPixmap class]]) {
324 [
self copyPixmap : (QuartzPixmap *)src area : area withMask : mask clipOrigin : origin toPoint : dstPoint];
326 assert(0 &&
"Can copy only from pixmap or image");
332 assert(area.
fWidth && area.
fHeight &&
"readColorBits:, empty area to copy");
335 NSLog(
@"QuartzPixmap: readColorBits:intoBuffer:, src and copy area do not intersect");
340 unsigned char *buffer = 0;
342 buffer =
new unsigned char[
area.
fWidth * area.fHeight * 4]();
343 }
catch (
const std::bad_alloc &) {
344 NSLog(
@"QuartzImage: -readColorBits:, memory allocation failed");
353 if (!scaledPixmap.
Get()) {
354 NSLog(
@"QuartzImage: -readColorBits:, can not create scaled pixmap");
358 [
scaledPixmap.
Get() copy :
self area : X11::Rectangle(0, 0, fWidth, fHeight)
359 withMask : nil clipOrigin : X11::Point() toPoint : X11::Point()];
362 unsigned char *dstPixel = buffer;
367 : &scaledPixmap.
Get()->fData[0] + area.
fY *
fWidth * 4;
369 const unsigned char *srcPixel =
line + area.
fX * 4;
371 for (
unsigned i = 0; i < area.
fHeight; ++i) {
372 for (
unsigned j = 0; j < area.
fWidth; ++j, srcPixel += 4, dstPixel += 4) {
373 dstPixel[0] = srcPixel[0];
374 dstPixel[1] = srcPixel[1];
375 dstPixel[2] = srcPixel[2];
376 dstPixel[3] = srcPixel[3];
380 srcPixel =
line + area.
fX * 4;
393- (void) putPixel : (const
unsigned char *) rgb X : (
unsigned) x Y : (
unsigned) y
396 assert(rgb != 0 &&
"putPixel:X:Y:, rgb parameter is null");
398 assert(y < fHeight && "putPixel:
X:Y:,
y parameter is >= self.fHeight
");
400 unsigned char * const data = &fData[0];
401 if (fScaleFactor > 1) {
402 //Ooops, and what should I do now???
403 const unsigned scaledW = fWidth * fScaleFactor;
404 unsigned char *dst = data + unsigned(y * fScaleFactor * scaledW * 4) + unsigned(x * fScaleFactor * 4);
406 for (unsigned i = 0; i < 2; ++i, dst += 4) {
416 for (unsigned i = 0; i < 2; ++i, dst += 4) {
423 unsigned char *dst = data + y * fWidth * 4 + x * 4;
432//______________________________________________________________________________
433- (void) addPixel : (const unsigned char *) rgb
435 //Primitive version of XAddPixel.
436 assert(rgb != 0 && "addPixel:, rgb parameter is null
");
438 for (unsigned i = 0; i < fHeight; ++i) {
439 for (unsigned j = 0; j < fWidth; ++j) {
440 fData[i * fWidth * 4 + j * 4] = rgb[0];
441 fData[i * fWidth * 4 + j * 4 + 1] = rgb[1];
442 fData[i * fWidth * 4 + j * 4 + 2] = rgb[2];
443 fData[i * fWidth * 4 + j * 4 + 3] = rgb[3];
451@implementation QuartzImage
453@synthesize fIsStippleMask;
456//______________________________________________________________________________
457- (id) initWithW : (unsigned) width H : (unsigned) height data : (unsigned char *) data
459 assert(width != 0 && "initWithW:
H:data:, width parameter is 0
");
460 assert(height != 0 && "initWithW:
H:data:, height parameter is 0
");
461 assert(data != 0 && "initWithW:
H:data:, data parameter is null
");
463 if (self = [super init]) {
464 Util::NSScopeGuard<QuartzImage> selfGuard(self);
466 //This w * h * 4 is ONLY for TGCocoa::CreatePixmapFromData.
467 //If needed something else, I'll make this code more generic.
469 fImageData.resize(width * height * 4);
470 } catch (const std::bad_alloc &) {
471 NSLog(@"QuartzImage: -initWithW:
H:data:, memory allocation failed
");
475 std::copy(data, data + width * height * 4, &fImageData[0]);
478 const Util::CFScopeGuard<CGDataProviderRef>
479 provider(CGDataProviderCreateWithData(nullptr, &fImageData[0], width * height * 4, nullptr));
480 if (!provider.Get()) {
481 NSLog(@"QuartzImage: -initWithW:
H:data: CGDataProviderCreateWithData failed
");
485 //RGB - this is only for TGCocoa::CreatePixmapFromData.
486 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
487 if (!colorSpace.Get()) {
488 NSLog(@"QuartzImage: -initWithW:
H:data: CGColorSpaceCreateDeviceRGB failed
");
492 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
493 //all values hardcoded for TGCocoa::CreatePixmapFromData.
494 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(),
495 kCGImageAlphaLast, provider.Get(), 0, false,
496 kCGRenderingIntentDefault));
499 NSLog(@"QuartzImage: -initWithW:
H:data: CGImageCreate failed
");
512//______________________________________________________________________________
513- (id) initMaskWithW : (unsigned) width H : (unsigned) height bitmapMask : (unsigned char *) mask
515 assert(width != 0 && "initMaskWithW:
H:bitmapMask:, width parameter is zero
");
516 assert(height != 0 && "initMaskWithW:
H:bitmapMask:, height parameter is zero
");
517 assert(mask != 0 && "initMaskWithW:
H:bitmapMask:, mask parameter is null
");
519 if (self = [super init]) {
520 Util::NSScopeGuard<QuartzImage> selfGuard(self);
523 fImageData.resize(width * height);
524 } catch (const std::bad_alloc &) {
525 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, memory allocation failed
");
529 std::copy(mask, mask + width * height, &fImageData[0]);
531 fIsStippleMask = YES;
532 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
533 width * height, nullptr));
534 if (!provider.Get()) {
535 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask: CGDataProviderCreateWithData failed
");
539 //0 -> decode, false -> shouldInterpolate.
540 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
542 NSLog(@"QuartzImage: -initMaskWithW:
H:bitmapMask:, CGImageMaskCreate failed
");
555//______________________________________________________________________________
556- (id) initMaskWithW : (unsigned) width H : (unsigned) height
558 //Two-step initialization.
560 assert(width != 0 && "initMaskWithW:
H:, width parameter is zero
");
561 assert(height != 0 && "initMaskWithW:
H:, height parameter is zero
");
563 if (self = [super init]) {
564 Util::NSScopeGuard<QuartzImage> selfGuard(self);
567 fImageData.resize(width * height);
568 } catch (const std::bad_alloc &) {
569 NSLog(@"QuartzImage: -initMaskWithW:
H:, memory allocation failed
");
573 fIsStippleMask = YES;
574 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
575 width * height, nullptr));
576 if (!provider.Get()) {
577 NSLog(@"QuartzImage: -initMaskWithW:
H: CGDataProviderCreateWithData failed
");
581 //0 -> decode, false -> shouldInterpolate.
582 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
584 NSLog(@"QuartzImage: -initMaskWithW:
H:, CGImageMaskCreate failed
");
597//______________________________________________________________________________
598- (id) initFromPixmap : (QuartzPixmap *) pixmap
600 //Two-step initialization.
601 assert(pixmap != nil && "initFromPixmap:, pixmap parameter is nil
");
602 assert(pixmap.fWidth != 0 && "initFromPixmap:, pixmap width is zero
");
603 assert(pixmap.fHeight != 0 && "initFromPixmap:, pixmap height is zero
");
605 return [self initWithW : pixmap.fWidth H : pixmap.fHeight data : pixmap.fData];
608//______________________________________________________________________________
609- (id) initFromImage : (QuartzImage *) image
611 assert(image != nil && "initFromImage:, image parameter is nil
");
612 assert(image.fWidth != 0 && "initFromImage:, image width is 0
");
613 assert(image.fHeight != 0 && "initFromImage:, image height is 0
");
614 assert(image.fIsStippleMask == NO && "initFromImage:, image is
a stipple mask, not implemented
");
616 return [self initWithW : image.fWidth H : image.fHeight data : &image->fImageData[0]];
619//______________________________________________________________________________
620- (id) initFromImageFlipped : (QuartzImage *) image
622 assert(image != nil && "initFromImageFlipped:, image parameter is nil
");
623 assert(image.fWidth != 0 && "initFromImageFlipped:, image width is 0
");
624 assert(image.fHeight != 0 && "initFromImageFlipped:, image height is 0
");
626 const unsigned bpp = image.fIsStippleMask ? 1 : 4;
628 if (self = [super init]) {
629 const unsigned width = image.fWidth;
630 const unsigned height = image.fHeight;
632 Util::NSScopeGuard<QuartzImage> selfGuard(self);
635 fImageData.resize(width * height * bpp);
636 } catch (const std::bad_alloc &) {
637 NSLog(@"QuartzImage: -initFromImageFlipped:, memory allocation failed
");
641 const unsigned lineSize = bpp * width;
642 const unsigned char * const src = &image->fImageData[0];
643 unsigned char * const dst = &fImageData[0];
644 for (unsigned i = 0; i < height; ++i) {
645 const unsigned char *sourceLine = src + lineSize * (height - 1 - i);
646 unsigned char *dstLine = dst + i * lineSize;
647 std::copy(sourceLine, sourceLine + lineSize, dstLine);
651 fIsStippleMask = YES;
652 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
653 width * height, nullptr));
654 if (!provider.Get()) {
655 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateWithData failed
");
659 //0 -> decode, false -> shouldInterpolate.
660 fImage.Reset(CGImageMaskCreate(width, height, 8, 8, width, provider.Get(), 0, false));
662 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageMaskCreate failed
");
667 const Util::CFScopeGuard<CGDataProviderRef> provider(CGDataProviderCreateWithData(nullptr, &fImageData[0],
668 width * height * 4, nullptr));
669 if (!provider.Get()) {
670 NSLog(@"QuartzImage: -initFromImageFlipped:, CGDataProviderCreateWithData failed
");
674 const Util::CFScopeGuard<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
675 if (!colorSpace.Get()) {
676 NSLog(@"QuartzImage: -initFromImageFlipped:, CGColorSpaceCreateDeviceRGB failed
");
680 //8 bits per component, 32 bits per pixel, 4 bytes per pixel, kCGImageAlphaLast:
681 //all values hardcoded for TGCocoa::CreatePixmapFromData.
682 fImage.Reset(CGImageCreate(width, height, 8, 32, width * 4, colorSpace.Get(), kCGImageAlphaLast,
683 provider.Get(), 0, false, kCGRenderingIntentDefault));
685 NSLog(@"QuartzImage: -initFromImageFlipped:, CGImageCreate failed
");
699//______________________________________________________________________________
700- (BOOL) isRectInside : (X11::Rectangle) area
702 if (area.fX < 0 || (unsigned)area.fX >= fWidth)
704 if (area.fY < 0 || (unsigned)area.fY >= fHeight)
706 if (area.fWidth > fWidth || !area.fWidth)
708 if (area.fHeight > fHeight || !area.fHeight)
714//______________________________________________________________________________
715- (unsigned char *) readColorBits : (X11::Rectangle) area
717 assert([self isRectInside : area] == YES && "readColorBits: bad area parameter
");
718 //Image, bitmap - they all must be converted to ARGB (bitmap) or BGRA (image) (for libAfterImage).
719 //Raw pointer - we pass the ownership.
720 unsigned char *buffer = 0;
723 buffer = new unsigned char[area.fWidth * area.fHeight * 4]();
724 } catch (const std::bad_alloc &) {
725 NSLog(@"QuartzImage: -readColorBits:, memory allocation failed
");
729 unsigned char *dstPixel = buffer;
730 if (CGImageIsMask(fImage.Get())) {
731 //fImageData has 1 byte per pixel.
732 const unsigned char *line = &fImageData[0] + area.fY * fWidth;
733 const unsigned char *srcPixel = line + area.fX;
735 for (unsigned i = 0; i < area.fHeight; ++i) {
736 for (unsigned j = 0; j < area.fWidth; ++j, ++srcPixel, dstPixel += 4) {
738 dstPixel[0] = 255;//can be 1 or anything different from 0.
742 srcPixel = line + area.fX;
746 //fImageData has 4 bytes per pixel.
747 const unsigned char *line = &fImageData[0] + area.fY * fWidth * 4;
748 const unsigned char *srcPixel = line + area.fX * 4;
750 for (unsigned i = 0; i < area.fHeight; ++i) {
751 for (unsigned j = 0; j < area.fWidth; ++j, srcPixel += 4, dstPixel += 4) {
752 dstPixel[0] = srcPixel[2];
753 dstPixel[1] = srcPixel[1];
754 dstPixel[2] = srcPixel[0];
755 dstPixel[3] = srcPixel[3];
759 srcPixel = line + area.fX * 4;
768//______________________________________________________________________________
774//______________________________________________________________________________
775- (BOOL) fIsOpenGLWidget
780//______________________________________________________________________________
781- (CGFloat) fScaleFactor
783 // TODO: this is to be understood yet ...
787//______________________________________________________________________________
793//______________________________________________________________________________
799//______________________________________________________________________________
800- (TAttLine *) attLine
805//______________________________________________________________________________
806- (TAttFill *) attFill
811//______________________________________________________________________________
812- (TAttMarker *) attMarker
817//______________________________________________________________________________
818- (TAttText *) attText
823//______________________________________________________________________________
835//______________________________________________________________________________
836CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
840 const CGRect subImageRect = CGRectMake(area.fX, area.fY, area.fHeight, area.fWidth);
841 return CGImageCreateWithImageInRect(image.fImage, subImageRect);
846//Now, close your eyes and open them at the end of this block. :)
847//Sure, this can be done easy, but I hate to convert between negative signed integers and
848//unsigned integers and the other way, so I have this implementation (integers will be always
849//positive and they obviously fit into unsigned integers).
851typedef std::pair<int, unsigned> range_type;
853//______________________________________________________________________________
854bool FindOverlapSameSigns(const range_type &left, const range_type &right, range_type &intersection)
856 //"Same
" means both xs are non-negative, or both are negative.
858 const unsigned dX(right.first - left.first);//diff fits into the positive range of int.
860 if (dX >= left.second)
862 //Find an intersection.
863 intersection.first = right.first;
864 intersection.second = std::min(right.second, left.second - dX);//left.second is always > dX.
869//______________________________________________________________________________
870bool FindOverlapDifferentSigns(const range_type &left, const range_type &right, range_type &intersection)
872 //x2 - x1 can overflow.
873 //Left.x is negative, right.x is non-negative (0 included).
874 const unsigned signedMinAbs(std::numeric_limits<unsigned>::max() / 2 + 1);
876 if (left.first == std::numeric_limits<int>::min()) {//hehehe
877 if (left.second <= signedMinAbs)
880 if (left.second - signedMinAbs <= unsigned(right.first))
883 intersection.first = right.first;
884 intersection.second = std::min(right.second, left.second - signedMinAbs - unsigned(right.first));
886 const unsigned leftXAbs(-left.first);//-left.first can't overflow.
887 if (leftXAbs >= left.second)
890 if (left.second - leftXAbs <= unsigned(right.first))
893 intersection.first = right.first;
894 intersection.second = std::min(right.second, left.second - leftXAbs - unsigned(right.first));
900//______________________________________________________________________________
901bool FindOverlap(const range_type &range1, const range_type &range2, range_type &intersection)
906 if (range1.first < range2.first) {
915 return right.first < 0 ? FindOverlapSameSigns(left, right, intersection) :
916 FindOverlapDifferentSigns(left, right, intersection);
918 return FindOverlapSameSigns(left, right, intersection);
923//______________________________________________________________________________
924bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)
926 //Find rects intersection.
927 range_type xIntersection;
928 if (!FindOverlap(range_type(srcRect.fX, srcRect.fWidth),
929 range_type(cropArea.fX, cropArea.fWidth), xIntersection))
932 range_type yIntersection;
933 if (!FindOverlap(range_type(srcRect.fY, srcRect.fHeight),
934 range_type(cropArea.fY, cropArea.fHeight), yIntersection))
937 cropArea.fX = xIntersection.first;
938 cropArea.fWidth = xIntersection.second;
940 cropArea.fY = yIntersection.first;
941 cropArea.fHeight = yIntersection.second;
946//______________________________________________________________________________
947bool AdjustCropArea(QuartzImage *srcImage, Rectangle &cropArea)
949 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
952 return AdjustCropArea(X11::Rectangle(0, 0, srcImage.fWidth, srcImage.fHeight), cropArea);
955//______________________________________________________________________________
956bool AdjustCropArea(QuartzImage *srcImage, NSRect &cropArea)
958 assert(srcImage != nil && "AdjustCropArea, srcImage parameter is nil
");
961 const Rectangle srcRect(0, 0, srcImage.fWidth, srcImage.fHeight);
962 Rectangle dstRect(int(cropArea.origin.x), int(cropArea.origin.y),
963 unsigned(cropArea.size.width), unsigned(cropArea.size.height));
965 if (AdjustCropArea(srcRect, dstRect)) {
966 cropArea.origin.x = dstRect.fX;
967 cropArea.origin.y = dstRect.fY;
968 cropArea.size.width = dstRect.fWidth;
969 cropArea.size.height = dstRect.fHeight;
977//______________________________________________________________________________
978bool AdjustCropArea(QuartzPixmap *srcPixmap, X11::Rectangle &cropArea)
980 assert(srcPixmap != nil && "AdjustCropArea, srcPixmap parameter is nil
");
982 return AdjustCropArea(X11::Rectangle(0, 0, srcPixmap.fWidth, srcPixmap.fHeight), cropArea);
985//______________________________________________________________________________
986bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
988 //Test if a bit (i,j) is set in a bitmap (w, h).
990 //Code in ROOT's GUI suggests, that byte is octet.
991 assert(bitmap != 0 && "TestBitmapBit, bitmap parameter is null
");
995 const unsigned bytesPerLine = (w + 7) / 8;
996 const unsigned char *line = bitmap + j * bytesPerLine;
997 const unsigned char byteValue = line[i / 8];
999 return byteValue & (1 << (i % 8));
1002//______________________________________________________________________________
1003void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height,
1004 ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth,
1005 unsigned char *imageData)
1013 unsigned char foregroundColor[4] = {};
1014 PixelToRGB(foregroundPixel, foregroundColor);
1015 unsigned char backgroundColor[4] = {};
1016 PixelToRGB(backgroundPixel, backgroundColor);
1018 for (unsigned j = 0; j < height; ++j) {
1019 const unsigned line = j * width * 4;
1020 for (unsigned i = 0; i < width; ++i) {
1021 const unsigned pixel = line + i * 4;
1023 if (TestBitmapBit(bitmap, width, i, j)) {
1025 imageData[pixel] = foregroundColor[0];
1026 imageData[pixel + 1] = foregroundColor[1];
1027 imageData[pixel + 2] = foregroundColor[2];
1029 imageData[pixel] = backgroundColor[0];
1030 imageData[pixel + 1] = backgroundColor[1];
1031 imageData[pixel + 2] = backgroundColor[2];
1034 imageData[pixel + 3] = 255;
1038 for (unsigned j = 0; j < height; ++j) {
1039 const unsigned line = j * width;
1040 for (unsigned i = 0; i < width; ++i) {
1041 const unsigned pixel = line + i;
1042 if (TestBitmapBit(bitmap, width, i, j))
1043 imageData[pixel] = 0;
1045 imageData[pixel] = 255;//mask out pixel.
DerivedType * Get() const
void Reset(NSObject *object)
ROOT::MacOSX::Util::CFScopeGuard< CGImageRef > fImage
TAttLine fAttLine
current line attributes
TAttText fAttText
current text attribute
TAttFill fAttFill
current fill attributes
std::vector< unsigned char > fData
TAttMarker fAttMarker
current marker attribute
ROOT::MacOSX::Util::CFScopeGuard< CGContextRef > fContext
CGImageRef createImageFromPixmap()
bool TestBitmapBit(const unsigned char *bitmap, unsigned w, unsigned i, unsigned j)
void FillPixmapBuffer(const unsigned char *bitmap, unsigned width, unsigned height, ULong_t foregroundPixel, ULong_t backgroundPixel, unsigned depth, unsigned char *imageData)
CGImageRef CreateSubImage(QuartzImage *image, const Rectangle &area)
int LocalYROOTToCocoa(NSView< X11Window > *parentView, CGFloat yROOT)
bool AdjustCropArea(const Rectangle &srcRect, Rectangle &cropArea)