19 #include <Cocoa/Cocoa.h>
81 void DrawLine::Execute()
const
84 "Execute, gVirtualX is either null or not of TGCocoa type");
86 vx->
DrawLineAux(fID, fGC, fP1.fX, fP1.fY, fP2.fX, fP2.fY);
94 assert(segments != 0 &&
"DrawSegments, segments parameter is null");
95 assert(nSegments > 0 &&
"DrawSegments, nSegments <= 0");
97 fSegments.assign(segments, segments + nSegments);
101 void DrawSegments::Execute()
const
104 "Execute, gVirtualX is either null or not of TGCocoa type");
117 void ClearArea::Execute()
const
120 "Execute, gVirtualX is either null or not of TGCocoa type");
122 vx->
ClearAreaAux(fID, fArea.fX, fArea.fY, fArea.fWidth, fArea.fHeight);
136 bool CopyArea::HasOperand(
Drawable_t drawable)
const
138 return fID == drawable || fSrc == drawable || fGC.fClipMask == drawable;
142 void CopyArea::Execute()
const
145 "Execute, gVirtualX is either null or not of TGCocoa type");
148 vx->
CopyAreaAux(fSrc, fID, fGC, fArea.fX, fArea.fY, fArea.fWidth,
149 fArea.fHeight, fDstPoint.fX, fDstPoint.fY);
154 const std::string &text)
162 void DrawString::Execute()
const
165 "Execute, gVirtualX is either null or not of TGCocoa type");
168 vx->
DrawStringAux(fID, fGC, fPoint.fX, fPoint.fY, fText.c_str(), fText.length());
175 fRectangle(rectangle)
180 void FillRectangle::Execute()
const
183 "Execute, gVirtualX is either null or not of TGCocoa type");
187 fRectangle.fWidth, fRectangle.fHeight);
195 assert(points != 0 &&
"FillPolygon, points parameter is null");
196 assert(nPoints > 0 &&
"FillPolygon, nPoints <= 0");
198 fPolygon.assign(points, points + nPoints);
202 void FillPolygon::Execute()
const
205 "Execute, gVirtualX is either null or not of TGCocoa type");
214 fRectangle(rectangle)
219 void DrawRectangle::Execute()
const
222 "Execute, gVirtualX is either null or not of TGCocoa type");
226 fRectangle.fWidth, fRectangle.fHeight);
234 assert(view != nil &&
"UpdateWindow, view parameter is nil");
238 void UpdateWindow::Execute()
const
240 assert(fView.fContext != 0 &&
"Execute, view.fContext is null");
243 [fView copy : pixmap area : Rectangle(0, 0, pixmap.fWidth, pixmap.fHeight)
244 withMask : nil clipOrigin : Point() toPoint : Point()];
248 DeletePixmap::DeletePixmap(
Pixmap_t pixmap)
254 void DeletePixmap::Execute()
const
257 "Execute, gVirtualX is either null or not of TGCocoa type");
263 DrawBoxXor::DrawBoxXor(
Window_t windowID,
const Point &p1,
const Point &p2)
275 void DrawBoxXor::Execute()
const
281 void DrawBoxXor::Execute(CGContextRef ctx)
const
284 assert(ctx != 0 &&
"Execute, ctx parameter is null");
286 CGContextSetRGBStrokeColor(ctx, 0., 0., 0., 1.);
287 CGContextSetLineWidth(ctx, 1.);
289 CGContextStrokeRect(ctx, CGRectMake(fP1.fX, fP1.fY, fP2.fX - fP1.fX, fP2.fY - fP1.fY));
293 DrawLineXor::DrawLineXor(
Window_t windowID,
const Point &p1,
const Point &p2)
301 void DrawLineXor::Execute()
const
307 void DrawLineXor::Execute(CGContextRef ctx)
const
310 assert(ctx != 0 &&
"Execute, ctx parameter is null");
312 CGContextSetRGBStrokeColor(ctx, 0., 0., 0., 1.);
313 CGContextSetLineWidth(ctx, 1.);
315 CGContextBeginPath(ctx);
316 CGContextMoveToPoint(ctx, fP1.fX, fP1.fY);
317 CGContextAddLineToPoint(ctx, fP2.fX, fP2.fY);
318 CGContextStrokePath(ctx);
322 CommandBuffer::CommandBuffer()
327 CommandBuffer::~CommandBuffer()
330 ClearXOROperations();
339 std::auto_ptr<DrawLine> cmd(
new DrawLine(wid, gc, Point(x1, y1), Point(x2, y2)));
340 fCommands.push_back(cmd.get());
342 }
catch (
const std::exception &) {
351 assert(segments != 0 &&
"AddDrawSegments, segments parameter is null");
352 assert(nSegments > 0 &&
"AddDrawSegments, nSegments <= 0");
355 std::auto_ptr<DrawSegments> cmd(
new DrawSegments(wid, gc, segments, nSegments));
356 fCommands.push_back(cmd.get());
358 }
catch (
const std::exception &) {
372 std::auto_ptr<ClearArea> cmd(
new ClearArea(wid, r));
373 fCommands.push_back(cmd.get());
375 }
catch (
const std::exception &) {
392 std::auto_ptr<CopyArea> cmd(
new CopyArea(src, dst, gc, area, Point(dstX, dstY)));
393 fCommands.push_back(cmd.get());
395 }
catch (
const std::exception &) {
402 const char *text,
Int_t len)
406 len = std::strlen(text);
407 const std::string substr(text, len);
408 std::auto_ptr<DrawString> cmd(
new DrawString(wid, gc, Point(x, y), substr));
409 fCommands.push_back(cmd.get());
411 }
catch (
const std::exception &) {
426 std::auto_ptr<FillRectangle> cmd(
new FillRectangle(wid, gc, r));
427 fCommands.push_back(cmd.get());
429 }
catch (
const std::exception &) {
444 std::auto_ptr<DrawRectangle> cmd(
new DrawRectangle(wid, gc, r));
445 fCommands.push_back(cmd.get());
447 }
catch (
const std::exception &) {
456 assert(polygon != 0 &&
"AddFillPolygon, polygon parameter is null");
457 assert(nPoints > 0 &&
"AddFillPolygon, nPoints <= 0");
460 std::auto_ptr<FillPolygon> cmd(
new FillPolygon(wid, gc, polygon, nPoints));
461 fCommands.push_back(cmd.get());
463 }
catch (
const std::exception &) {
469 void CommandBuffer::AddUpdateWindow(
QuartzView *view)
471 assert(view != nil &&
"AddUpdateWindow, view parameter is nil");
474 std::auto_ptr<UpdateWindow> cmd(
new UpdateWindow(view));
475 fCommands.push_back(cmd.get());
477 }
catch (
const std::exception &) {
483 void CommandBuffer::AddDeletePixmap(
Pixmap_t pixmapID)
486 std::auto_ptr<DeletePixmap> cmd(
new DeletePixmap(pixmapID));
487 fCommands.push_back(cmd.get());
489 }
catch (
const std::exception &) {
498 std::auto_ptr<DrawBoxXor> cmd(
new DrawBoxXor(windowID, Point(x1, y1), Point(x2, y2)));
499 fXorOps.push_back(cmd.get());
501 }
catch (
const std::exception &) {
510 std::auto_ptr<DrawLineXor> cmd(
new DrawLineXor(windowID, Point(x1, y1), Point(x2, y2)));
511 fXorOps.push_back(cmd.get());
513 }
catch (
const std::exception &) {
521 assert(impl != 0 &&
"Flush, impl parameter is null");
527 CGContextRef prevContext = 0;
528 CGContextRef currContext = 0;
531 for (size_type i = 0, e = fCommands.size(); i < e; ++i) {
532 const Command *cmd = fCommands[i];
536 NSObject<X11Drawable> *drawable = impl->
GetDrawable(cmd->fID);
537 if (drawable.fIsPixmap) {
544 if (prevView != view)
550 if ([view lockFocusIfCanDraw]) {
551 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
552 assert(nsContext != nil &&
"Flush, currentContext is nil");
553 currContext = (CGContextRef)[nsContext graphicsPort];
554 assert(currContext != 0 &&
"Flush, graphicsPort is null");
557 if (prevContext && prevContext != currContext)
558 CGContextFlush(prevContext);
559 prevContext = currContext;
564 if (fClippedRegion.size())
565 CGContextClipToRects(currContext, &fClippedRegion[0], fClippedRegion.size());
576 [view copy : view.fBackBuffer area : copyArea
577 withMask : nil clipOrigin : Point() toPoint : Point()];
584 }
catch (
const std::exception &) {
595 CGContextFlush(currContext);
603 assert(impl != 0 &&
"FlushXOROps, impl parameter is null");
612 NSObject<X11Drawable> *drawable = impl->
GetDrawable(fXorOps[0]->fID);
615 "FlushXOROps, drawable must be of type QuartzView");
619 if ([view lockFocusIfCanDraw]) {
620 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
621 assert(nsContext != nil &&
"FlushXOROps, currentContext is nil");
622 CGContextRef currContext = (CGContextRef)[nsContext graphicsPort];
623 assert(currContext != 0 &&
"FlushXOROps, graphicsPort is null");
627 CGContextSetAllowsAntialiasing(currContext,
false);
634 [view copy : view.fBackBuffer area : copyArea
635 withMask : nil clipOrigin : Point() toPoint : Point()];
639 for (size_type i = 0, e = fXorOps.size(); i < e; ++i) {
641 fXorOps[i]->Execute(currContext);
648 CGContextFlush(currContext);
650 CGContextSetAllowsAntialiasing(currContext,
true);
653 ClearXOROperations();
657 void CommandBuffer::RemoveOperationsForDrawable(
Drawable_t drawable)
659 for (size_type i = 0; i < fCommands.size(); ++i) {
660 if (fCommands[i] && fCommands[i]->HasOperand(drawable)) {
666 for (size_type i = 0; i < fXorOps.size(); ++i) {
667 if (fXorOps[i] && fXorOps[i]->HasOperand(drawable)) {
675 void CommandBuffer::RemoveGraphicsOperationsForWindow(
Window_t wid)
677 for (size_type i = 0; i < fCommands.size(); ++i) {
678 if (fCommands[i] && fCommands[i]->HasOperand(wid) &&
679 fCommands[i]->IsGraphicsCommand())
688 void CommandBuffer::RemoveXORGraphicsOperationsForWindow(
Window_t wid)
690 for (size_type i = 0; i < fCommands.size(); ++i) {
691 if (fXorOps[i] && fXorOps[i]->HasOperand(wid)) {
699 void CommandBuffer::ClearCommands()
701 for (size_type i = 0, e = fCommands.size(); i < e; ++i)
708 void CommandBuffer::ClearXOROperations()
710 for (size_type i = 0, e = fXorOps.size(); i < e; ++i)
721 bool RectsOverlap(
const NSRect &r1,
const NSRect &r2)
723 if (r2.origin.x >= r1.origin.x + r1.size.width)
725 if (r2.origin.x + r2.size.width <= r1.origin.x)
727 if (r2.origin.y >= r1.origin.y + r1.size.height)
729 if (r2.origin.y + r2.size.height <= r1.origin.y)
738 void CommandBuffer::ClipOverlaps(
QuartzView *view)
753 assert(view != nil &&
"ClipOverlaps, view parameter is nil");
755 typedef std::vector<QuartzView *>::reverse_iterator reverse_iterator;
756 typedef std::vector<CGRect>::iterator rect_iterator;
758 fRectsToClip.clear();
759 fClippedRegion.clear();
767 fViewBranch.push_back(
v);
770 if (fViewBranch.size())
771 fViewBranch.pop_back();
779 const NSRect frame2 = view.frame;
781 for (reverse_iterator it = fViewBranch.rbegin(), eIt = fViewBranch.rend(); it != eIt; ++it) {
783 bool doCheck =
false;
785 if (ancestorView == sibling) {
790 }
else if (!doCheck || sibling.fMapState !=
kIsViewable) {
794 frame1 = sibling.frame;
796 if (!frame1.size.width || !frame1.size.height)
799 frame1.origin = [sibling.fParentView convertPoint : frame1.origin
800 toView : view.fParentView];
803 if (RectsOverlap(frame2, frame1)) {
805 clipRect.fX1 = frame1.origin.x;
806 clipRect.fX2 = clipRect.fX1 + frame1.size.width;
807 clipRect.fY1 = frame1.origin.y;
808 clipRect.fY2 = clipRect.fY1 + frame1.size.height;
809 fRectsToClip.push_back(clipRect);
820 frame1 = child.frame;
822 if (!frame1.size.width || !frame1.size.height)
826 frame1.origin = [view convertPoint : frame1.origin toView : view.fParentView];
828 if (RectsOverlap(frame2, frame1)) {
829 clipRect.fX1 = frame1.origin.x;
830 clipRect.fX2 = clipRect.fX1 + frame1.size.width;
831 clipRect.fY1 = frame1.origin.y;
832 clipRect.fY2 = clipRect.fY1 + frame1.size.height;
833 fRectsToClip.push_back(clipRect);
837 if (fRectsToClip.size()) {
841 WidgetRect rect(frame2.origin.x, frame2.origin.y, frame2.origin.x + frame2.size.width,
842 frame2.origin.y + frame2.size.height);
844 BuildClipRegion(rect);
849 rect_iterator recIt = fClippedRegion.begin(), eIt = fClippedRegion.end();
850 for (; recIt != eIt; ++recIt) {
851 if (!recIt->size.width && !recIt->size.height) {
853 assert(fClippedRegion.size() == 1 &&
"ClipOverlaps, internal logic error");
856 recIt->origin = NSPointToCGPoint([view.
fParentView convertPoint :
857 NSPointFromCGPoint(recIt->origin) toView : view]);
865 typedef std::vector<int>::iterator int_iterator;
868 int_iterator BinarySearchLeft(int_iterator first, int_iterator last,
int value)
873 const int_iterator it = std::lower_bound(first, last, value);
874 assert(it != last && (it == first || *it == value) &&
"internal logic error");
877 return it == first && *it != value ? last : it;
881 int_iterator BinarySearchRight(int_iterator first, int_iterator last,
int value)
886 const int_iterator it = std::lower_bound(first, last, value);
887 assert((it == last || *it == value) &&
"internal logic error");
895 void CommandBuffer::BuildClipRegion(
const WidgetRect &rect)
916 typedef std::vector<WidgetRect>::const_iterator rect_const_iterator;
917 typedef std::vector<bool>::size_type size_type;
919 assert(fRectsToClip.size() != 0 &&
"BuildClipRegion, nothing to clip");
921 fClippedRegion.clear();
926 rect_const_iterator recIt = fRectsToClip.begin(), endIt = fRectsToClip.end();
927 for (; recIt != endIt; ++recIt) {
928 if (recIt->fX1 <= rect.fX1 && recIt->fX2 >= rect.fX2 &&
929 recIt->fY1 <= rect.fY1 && recIt->fY2 >= rect.fY2) {
931 fClippedRegion.push_back(CGRectMake(0., 0., 0., 0.));
935 if (recIt->fX1 > rect.fX1)
936 fXBounds.push_back(recIt->fX1);
938 if (recIt->fX2 < rect.fX2)
939 fXBounds.push_back(recIt->fX2);
941 if (recIt->fY1 > rect.fY1)
942 fYBounds.push_back(recIt->fY1);
944 if (recIt->fY2 < rect.fY2)
945 fYBounds.push_back(recIt->fY2);
948 std::sort(fXBounds.begin(), fXBounds.end());
949 std::sort(fYBounds.begin(), fYBounds.end());
952 const int_iterator xBoundsEnd = std::unique(fXBounds.begin(), fXBounds.end());
953 const int_iterator yBoundsEnd = std::unique(fYBounds.begin(), fYBounds.end());
956 const size_type nXBands = size_type(xBoundsEnd - fXBounds.begin()) + 1;
957 const size_type nYBands = size_type(yBoundsEnd - fYBounds.begin()) + 1;
959 fGrid.assign(nXBands * nYBands,
false);
962 recIt = fRectsToClip.begin(), endIt = fRectsToClip.end();
963 for (; recIt != endIt; ++recIt) {
964 const int_iterator left = BinarySearchLeft(fXBounds.begin(), xBoundsEnd, recIt->fX1);
965 const size_type firstXBand = left == xBoundsEnd ? 0 : left - fXBounds.begin() + 1;
967 const int_iterator right = BinarySearchRight(fXBounds.begin(), xBoundsEnd, recIt->fX2);
968 const size_type lastXBand = right - fXBounds.begin() + 1;
970 const int_iterator bottom = BinarySearchLeft(fYBounds.begin(), yBoundsEnd, recIt->fY1);
971 const size_type firstYBand = bottom == yBoundsEnd ? 0 : bottom - fYBounds.begin() + 1;
973 const int_iterator top = BinarySearchRight(fYBounds.begin(), yBoundsEnd, recIt->fY2);
974 const size_type lastYBand = top - fYBounds.begin() + 1;
976 for (size_type i = firstYBand; i < lastYBand; ++i) {
977 const size_type baseIndex = i * nXBands;
978 for (size_type j = firstXBand; j < lastXBand; ++j)
979 fGrid[baseIndex + j] = true;
987 for (size_type i = 0; i < nYBands; ++i) {
988 const size_type baseIndex = i * nXBands;
989 for (size_type j = 0; j < nXBands; ++j) {
990 if (!fGrid[baseIndex + j]) {
991 newRect.origin.x = j ? fXBounds[j - 1] : rect.fX1;
992 newRect.origin.y = i ? fYBounds[i - 1] : rect.fY1;
994 newRect.size.width = (j == nXBands - 1 ? rect.fX2 : fXBounds[j]) - newRect.origin.x;
995 newRect.size.height = (i == nYBands - 1 ? rect.fY2 : fYBounds[i]) - newRect.origin.y;
997 fClippedRegion.push_back(newRect);
1002 if (!fClippedRegion.size())
1003 fClippedRegion.push_back(CGRectMake(0., 0., 0., 0.));
virtual void Execute() const =0
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
void DrawSegmentsAux(Drawable_t wid, const GCValues_t &gcVals, const Segment_t *segments, Int_t nSegments)
Namespace for new ROOT classes and functions.
void DrawRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
void swap(ROOT::THist< DIMENSIONS, PRECISION > &a, ROOT::THist< DIMENSIONS, PRECISION > &b) noexcept
Swap two histograms.
QuartzImage * fShapeCombineMask
QuartzPixmap * fBackBuffer
void ClearAreaAux(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
void DrawLineAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
QuartzWindow * fQuartzWindow
void FillRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
if(pyself &&pyself!=Py_None)
void CopyAreaAux(Drawable_t src, Drawable_t dst, const GCValues_t &gc, Int_t srcX, Int_t srcY, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY)
void DrawStringAux(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *s, Int_t len)
lv DrawLine(0.33, 0.0, 0.33, 1.0)
virtual bool HasOperand(Drawable_t drawable) const
NSObject< X11Window > * GetWindow(Window_t windowID) const
void ClipToShapeMask(NSView< X11Window > *view, CGContextRef ctx)
virtual bool IsGraphicsCommand() const
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D. ...