19 #include <Cocoa/Cocoa.h> 83 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
84 "Execute, gVirtualX is either null or not of TGCocoa type");
94 assert(segments != 0 &&
"DrawSegments, segments parameter is null");
95 assert(nSegments > 0 &&
"DrawSegments, nSegments <= 0");
97 fSegments.assign(segments, segments + nSegments);
103 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
104 "Execute, gVirtualX is either null or not of TGCocoa type");
119 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
120 "Execute, gVirtualX is either null or not of TGCocoa type");
144 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
145 "Execute, gVirtualX is either null or not of TGCocoa type");
154 const std::string &
text)
164 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
165 "Execute, gVirtualX is either null or not of TGCocoa type");
175 fRectangle(rectangle)
182 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
183 "Execute, gVirtualX is either null or not of TGCocoa type");
195 assert(points != 0 &&
"FillPolygon, points parameter is null");
196 assert(nPoints > 0 &&
"FillPolygon, nPoints <= 0");
198 fPolygon.assign(points, points + nPoints);
204 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
205 "Execute, gVirtualX is either null or not of TGCocoa type");
214 fRectangle(rectangle)
221 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
222 "Execute, gVirtualX is either null or not of TGCocoa type");
234 assert(view != nil &&
"UpdateWindow, view parameter is nil");
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()];
256 assert(dynamic_cast<TGCocoa *>(
gVirtualX) != 0 &&
257 "Execute, gVirtualX is either null or not of TGCocoa type");
284 assert(ctx != 0 &&
"Execute, ctx parameter is null");
286 CGContextSetRGBStrokeColor(ctx, 0., 0., 0., 1.);
287 CGContextSetLineWidth(ctx, 1.);
310 assert(ctx != 0 &&
"Execute, ctx parameter is null");
312 CGContextSetRGBStrokeColor(ctx, 0., 0., 0., 1.);
313 CGContextSetLineWidth(ctx, 1.);
315 CGContextBeginPath(ctx);
318 CGContextStrokePath(ctx);
330 ClearXOROperations();
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::unique_ptr<DrawSegments> cmd(
new DrawSegments(wid, gc, segments, nSegments));
356 fCommands.push_back(cmd.get());
358 }
catch (
const std::exception &) {
372 std::unique_ptr<ClearArea> cmd(
new ClearArea(wid, r));
373 fCommands.push_back(cmd.get());
375 }
catch (
const std::exception &) {
392 std::unique_ptr<CopyArea> cmd(
new CopyArea(src, dst, gc, area,
Point(dstX, dstY)));
393 fCommands.push_back(cmd.get());
395 }
catch (
const std::exception &) {
406 len = std::strlen(text);
407 const std::string substr(text, len);
408 std::unique_ptr<DrawString> cmd(
new DrawString(wid, gc,
Point(x, y), substr));
409 fCommands.push_back(cmd.get());
411 }
catch (
const std::exception &) {
426 std::unique_ptr<FillRectangle> cmd(
new FillRectangle(wid, gc, r));
427 fCommands.push_back(cmd.get());
429 }
catch (
const std::exception &) {
444 std::unique_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::unique_ptr<FillPolygon> cmd(
new FillPolygon(wid, gc, polygon, nPoints));
461 fCommands.push_back(cmd.get());
463 }
catch (
const std::exception &) {
471 assert(view != nil &&
"AddUpdateWindow, view parameter is nil");
474 std::unique_ptr<UpdateWindow> cmd(
new UpdateWindow(view));
475 fCommands.push_back(cmd.get());
477 }
catch (
const std::exception &) {
486 std::unique_ptr<DeletePixmap> cmd(
new DeletePixmap(pixmapID));
487 fCommands.push_back(cmd.get());
489 }
catch (
const std::exception &) {
499 fXorOps.push_back(cmd.get());
501 }
catch (
const std::exception &) {
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];
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());
577 withMask : nil clipOrigin :
Point() toPoint :
Point()];
584 }
catch (
const std::exception &) {
595 CGContextFlush(currContext);
603 assert(impl != 0 &&
"FlushXOROps, impl parameter is null");
611 NSObject<X11Drawable> *drawable = impl->
GetDrawable(fXorOps[0]->
fID);
613 assert([drawable isKindOfClass : [
QuartzView class]] &&
614 "FlushXOROps, drawable must be of type QuartzView");
618 if ([view lockFocusIfCanDraw]) {
619 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
620 assert(nsContext != nil &&
"FlushXOROps, currentContext is nil");
621 CGContextRef currContext = (CGContextRef)[nsContext graphicsPort];
622 assert(currContext != 0 &&
"FlushXOROps, graphicsPort is null");
626 CGContextSetAllowsAntialiasing(currContext,
false);
634 withMask : nil clipOrigin :
Point() toPoint :
Point()];
638 for (
size_type i = 0,
e = fXorOps.size(); i <
e; ++i) {
640 fXorOps[i]->Execute(currContext);
647 CGContextFlush(currContext);
649 CGContextSetAllowsAntialiasing(currContext,
true);
652 ClearXOROperations();
658 for (
size_type i = 0; i < fCommands.size(); ++i) {
659 if (fCommands[i] && fCommands[i]->
HasOperand(drawable)) {
665 for (
size_type i = 0; i < fXorOps.size(); ++i) {
666 if (fXorOps[i] && fXorOps[i]->
HasOperand(drawable)) {
676 for (
size_type i = 0; i < fCommands.size(); ++i) {
677 if (fCommands[i] && fCommands[i]->
HasOperand(wid) &&
678 fCommands[i]->IsGraphicsCommand())
689 for (
size_type i = 0; i < fCommands.size(); ++i) {
690 if (fXorOps[i] && fXorOps[i]->
HasOperand(wid)) {
700 for (
size_type i = 0,
e = fCommands.size(); i <
e; ++i)
709 for (
size_type i = 0,
e = fXorOps.size(); i <
e; ++i)
720 bool RectsOverlap(
const NSRect &r1,
const NSRect &r2)
722 if (r2.origin.x >= r1.origin.x + r1.size.width)
724 if (r2.origin.x + r2.size.width <= r1.origin.x)
726 if (r2.origin.y >= r1.origin.y + r1.size.height)
728 if (r2.origin.y + r2.size.height <= r1.origin.y)
752 assert(view != nil &&
"ClipOverlaps, view parameter is nil");
754 typedef std::vector<QuartzView *>::reverse_iterator reverse_iterator;
755 typedef std::vector<CGRect>::iterator rect_iterator;
757 fRectsToClip.clear();
758 fClippedRegion.clear();
766 fViewBranch.push_back(
v);
769 if (fViewBranch.size())
770 fViewBranch.pop_back();
778 const NSRect frame2 = view.frame;
780 for (reverse_iterator it = fViewBranch.rbegin(), eIt = fViewBranch.rend(); it != eIt; ++it) {
782 bool doCheck =
false;
784 if (ancestorView == sibling) {
789 }
else if (!doCheck || sibling.fMapState !=
kIsViewable) {
793 frame1 = sibling.frame;
795 if (!frame1.size.width || !frame1.size.height)
798 frame1.origin = [sibling.fParentView convertPoint : frame1.origin
802 if (RectsOverlap(frame2, frame1)) {
804 clipRect.
fX1 = frame1.origin.x;
805 clipRect.
fX2 = clipRect.
fX1 + frame1.size.width;
806 clipRect.
fY1 = frame1.origin.y;
807 clipRect.
fY2 = clipRect.
fY1 + frame1.size.height;
808 fRectsToClip.push_back(clipRect);
819 frame1 = child.frame;
821 if (!frame1.size.width || !frame1.size.height)
825 frame1.origin = [view convertPoint : frame1.origin toView : view.
fParentView];
827 if (RectsOverlap(frame2, frame1)) {
828 clipRect.
fX1 = frame1.origin.x;
829 clipRect.
fX2 = clipRect.
fX1 + frame1.size.width;
830 clipRect.
fY1 = frame1.origin.y;
831 clipRect.
fY2 = clipRect.
fY1 + frame1.size.height;
832 fRectsToClip.push_back(clipRect);
836 if (fRectsToClip.size()) {
840 WidgetRect rect(frame2.origin.x, frame2.origin.y, frame2.origin.x + frame2.size.width,
841 frame2.origin.y + frame2.size.height);
843 BuildClipRegion(rect);
848 rect_iterator recIt = fClippedRegion.begin(), eIt = fClippedRegion.end();
849 for (; recIt != eIt; ++recIt) {
850 if (!recIt->size.width && !recIt->size.height) {
852 assert(fClippedRegion.size() == 1 &&
"ClipOverlaps, internal logic error");
855 recIt->origin = NSPointToCGPoint([view.
fParentView convertPoint :
856 NSPointFromCGPoint(recIt->origin) toView : view]);
864 typedef std::vector<int>::iterator int_iterator;
867 int_iterator BinarySearchLeft(int_iterator
first, int_iterator last,
int value)
872 const int_iterator it = std::lower_bound(first, last, value);
873 assert(it != last && (it == first || *it == value) &&
"internal logic error");
876 return it == first && *it != value ? last : it;
880 int_iterator BinarySearchRight(int_iterator first, int_iterator last,
int value)
885 const int_iterator it = std::lower_bound(first, last, value);
886 assert((it == last || *it == value) &&
"internal logic error");
915 typedef std::vector<WidgetRect>::const_iterator rect_const_iterator;
917 assert(fRectsToClip.size() != 0 &&
"BuildClipRegion, nothing to clip");
919 fClippedRegion.clear();
924 rect_const_iterator recIt = fRectsToClip.begin(), endIt = fRectsToClip.end();
925 for (; recIt != endIt; ++recIt) {
926 if (recIt->fX1 <= rect.
fX1 && recIt->fX2 >= rect.
fX2 &&
927 recIt->fY1 <= rect.
fY1 && recIt->fY2 >= rect.
fY2) {
929 fClippedRegion.push_back(CGRectMake(0., 0., 0., 0.));
933 if (recIt->fX1 > rect.
fX1)
934 fXBounds.push_back(recIt->fX1);
936 if (recIt->fX2 < rect.
fX2)
937 fXBounds.push_back(recIt->fX2);
939 if (recIt->fY1 > rect.
fY1)
940 fYBounds.push_back(recIt->fY1);
942 if (recIt->fY2 < rect.
fY2)
943 fYBounds.push_back(recIt->fY2);
946 std::sort(fXBounds.begin(), fXBounds.end());
947 std::sort(fYBounds.begin(), fYBounds.end());
950 const int_iterator xBoundsEnd = std::unique(fXBounds.begin(), fXBounds.end());
951 const int_iterator yBoundsEnd = std::unique(fYBounds.begin(), fYBounds.end());
957 fGrid.assign(nXBands * nYBands,
false);
960 recIt = fRectsToClip.begin(), endIt = fRectsToClip.end();
961 for (; recIt != endIt; ++recIt) {
962 const int_iterator left = BinarySearchLeft(fXBounds.begin(), xBoundsEnd, recIt->fX1);
963 const size_type firstXBand = left == xBoundsEnd ? 0 : left - fXBounds.begin() + 1;
965 const int_iterator right = BinarySearchRight(fXBounds.begin(), xBoundsEnd, recIt->fX2);
966 const size_type lastXBand = right - fXBounds.begin() + 1;
968 const int_iterator bottom = BinarySearchLeft(fYBounds.begin(), yBoundsEnd, recIt->fY1);
969 const size_type firstYBand = bottom == yBoundsEnd ? 0 : bottom - fYBounds.begin() + 1;
971 const int_iterator top = BinarySearchRight(fYBounds.begin(), yBoundsEnd, recIt->fY2);
972 const size_type lastYBand = top - fYBounds.begin() + 1;
974 for (
size_type i = firstYBand; i < lastYBand; ++i) {
976 for (
size_type j = firstXBand; j < lastXBand; ++j)
977 fGrid[baseIndex + j] =
true;
985 for (
size_type i = 0; i < nYBands; ++i) {
987 for (
size_type j = 0; j < nXBands; ++j) {
988 if (!fGrid[baseIndex + j]) {
989 newRect.origin.x = j ? fXBounds[j - 1] : rect.
fX1;
990 newRect.origin.y = i ? fYBounds[i - 1] : rect.
fY1;
992 newRect.size.width = (j == nXBands - 1 ? rect.
fX2 : fXBounds[j]) - newRect.origin.x;
993 newRect.size.height = (i == nYBands - 1 ? rect.
fY2 : fYBounds[i]) - newRect.origin.y;
995 fClippedRegion.push_back(newRect);
1000 if (!fClippedRegion.size())
1001 fClippedRegion.push_back(CGRectMake(0., 0., 0., 0.));
DrawRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle)
void RemoveOperationsForDrawable(Drawable_t wid)
virtual void Execute() const =0
DrawLine(Drawable_t wid, const GCValues_t &gc, const Point &p1, const Point &p2)
void DrawSegmentsAux(Drawable_t wid, const GCValues_t &gcVals, const Segment_t *segments, Int_t nSegments)
Namespace for new ROOT classes and functions.
FillRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle)
DrawLineXor(Window_t windowID, const Point &p1, const Point &p2)
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
bool HasOperand(Drawable_t drawable) const
void DrawRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
virtual bool IsGraphicsCommand() const
DrawBoxXor(Window_t windowID, const Point &p1, const Point &p2)
QuartzImage * fShapeCombineMask
void RemoveXORGraphicsOperationsForWindow(Window_t wid)
NSObject< X11Window > * GetWindow(Window_t windowID) const
void BuildClipRegion(const WidgetRect &rect)
QuartzPixmap * fBackBuffer
void AddDrawLineXor(Window_t windowID, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
DrawString(Drawable_t wid, const GCValues_t &gc, const Point &point, const std::string &text)
void ClearAreaAux(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
static const double x2[5]
DeletePixmap(Pixmap_t pixmap)
void AddFillRectangle(Drawable_t wid, const GCValues_t &gc, 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)
static double p2(double t, double a, double b, double c)
void AddDrawString(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *text, Int_t len)
QuartzWindow * fQuartzWindow
DrawSegments(Drawable_t wid, const GCValues_t &gc, const Segment_t *segments, Int_t nSegments)
void FillRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
std::vector< Segment_t > fSegments
void AddDrawLine(Drawable_t wid, const GCValues_t &gc, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
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 Flush(Details::CocoaPrivate *impl)
void DrawStringAux(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *s, Int_t len)
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
const Rectangle_t fRectangle
CopyArea(Drawable_t src, Drawable_t dst, const GCValues_t &gc, const Rectangle_t &area, const Point &dstPoint)
void AddDrawSegments(Drawable_t wid, const GCValues_t &gc, const Segment_t *segments, Int_t nSegments)
virtual bool HasOperand(Drawable_t drawable) const
FillPolygon(Drawable_t wid, const GCValues_t &gc, const Point_t *points, Int_t nPoints)
static double p1(double t, double a, double b)
void RemoveGraphicsOperationsForWindow(Window_t wid)
lv DrawLine(0.33, 0.0, 0.33, 1.0)
std::vector< Command * >::size_type size_type
void ClipOverlaps(QuartzView *view)
static const double x1[5]
ClearArea(Window_t wid, const Rectangle_t &area)
void FlushXOROps(Details::CocoaPrivate *impl)
void AddClearArea(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
void ClearXOROperations()
std::vector< Point_t > fPolygon
void AddFillPolygon(Drawable_t wid, const GCValues_t &gc, const Point_t *polygon, Int_t nPoints)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
void ClipToShapeMask(NSView< X11Window > *view, CGContextRef ctx)
UpdateWindow(QuartzView *view)
void AddDrawRectangle(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D. ...
void AddDeletePixmap(Pixmap_t pixmap)
void AddCopyArea(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 AddUpdateWindow(QuartzView *view)
void AddDrawBoxXor(Window_t windowID, Int_t x1, Int_t y1, Int_t x2, Int_t y2)