19#include <Cocoa/Cocoa.h>
85 "Execute, gVirtualX is either null or not of TGCocoa type");
95 assert(segments != 0 &&
"DrawSegments, segments parameter is null");
96 assert(nSegments > 0 &&
"DrawSegments, nSegments <= 0");
98 fSegments.assign(segments, segments + nSegments);
105 "Execute, gVirtualX is either null or not of TGCocoa type");
121 "Execute, gVirtualX is either null or not of TGCocoa type");
146 "Execute, gVirtualX is either null or not of TGCocoa type");
155 const std::string &
text)
166 "Execute, gVirtualX is either null or not of TGCocoa type");
176 fRectangle(rectangle)
184 "Execute, gVirtualX is either null or not of TGCocoa type");
196 assert(
points != 0 &&
"FillPolygon, points parameter is null");
197 assert(nPoints > 0 &&
"FillPolygon, nPoints <= 0");
206 "Execute, gVirtualX is either null or not of TGCocoa type");
215 fRectangle(rectangle)
223 "Execute, gVirtualX is either null or not of TGCocoa type");
235 assert(view != nil &&
"UpdateWindow, view parameter is nil");
241 assert(
fView.
fContext != 0 &&
"Execute, view.fContext is null");
244 [
fView copy : pixmap area :
Rectangle(0, 0, pixmap.fWidth, pixmap.fHeight)
245 withMask : nil clipOrigin :
Point() toPoint :
Point()];
258 "Execute, gVirtualX is either null or not of TGCocoa type");
285 assert(ctx != 0 &&
"Execute, ctx parameter is null");
287 CGContextSetRGBStrokeColor(ctx, 0., 0., 0., 1.);
288 CGContextSetLineWidth(ctx, 1.);
334 }
catch (
const std::exception &) {
343 assert(segments != 0 &&
"AddDrawSegments, segments parameter is null");
344 assert(nSegments > 0 &&
"AddDrawSegments, nSegments <= 0");
347 std::unique_ptr<DrawSegments> cmd(
new DrawSegments(wid, gc, segments, nSegments));
350 }
catch (
const std::exception &) {
364 std::unique_ptr<ClearArea> cmd(
new ClearArea(wid,
r));
367 }
catch (
const std::exception &) {
384 std::unique_ptr<CopyArea> cmd(
new CopyArea(src, dst, gc, area,
Point(dstX, dstY)));
387 }
catch (
const std::exception &) {
398 len = std::strlen(
text);
399 const std::string substr(
text, len);
403 }
catch (
const std::exception &) {
418 std::unique_ptr<FillRectangle> cmd(
new FillRectangle(wid, gc,
r));
421 }
catch (
const std::exception &) {
436 std::unique_ptr<DrawRectangle> cmd(
new DrawRectangle(wid, gc,
r));
439 }
catch (
const std::exception &) {
448 assert(polygon != 0 &&
"AddFillPolygon, polygon parameter is null");
449 assert(nPoints > 0 &&
"AddFillPolygon, nPoints <= 0");
452 std::unique_ptr<FillPolygon> cmd(
new FillPolygon(wid, gc, polygon, nPoints));
455 }
catch (
const std::exception &) {
463 assert(view != nil &&
"AddUpdateWindow, view parameter is nil");
466 std::unique_ptr<UpdateWindow> cmd(
new UpdateWindow(view));
469 }
catch (
const std::exception &) {
478 std::unique_ptr<DeletePixmap> cmd(
new DeletePixmap(pixmapID));
481 }
catch (
const std::exception &) {
493 }
catch (
const std::exception &) {
505 }
catch (
const std::exception &) {
513 assert(impl != 0 &&
"Flush, impl parameter is null");
529 if (drawable.fIsPixmap) {
536 if (prevView != view)
542 if ([view lockFocusIfCanDraw]) {
543 NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
544 assert(nsContext != nil &&
"Flush, currentContext is nil");
546 assert(currContext != 0 &&
"Flush, graphicsPort is null");
549 if (prevContext && prevContext != currContext)
550 CGContextFlush(prevContext);
551 prevContext = currContext;
569 withMask : nil clipOrigin :
Point() toPoint :
Point()];
576 }
catch (
const std::exception &) {
587 CGContextFlush(currContext);
602 assert(impl != 0 &&
"FlushXOROps, impl parameter is null");
610 assert([drawable isKindOfClass : [
QuartzView class]] &&
611 "FlushXOROps, drawable must be of type QuartzView");
614 auto crosshairWindow = [window findCrosshairWindow];
615 if (!crosshairWindow) {
616 ::Warning(
"FlushXOROps",
"No CrosshairWindow found to draw into");
621 for (
auto *candidateOp :
fXorOps) {
623 NSLog(
@"XOR mode supports DrawLine only, unexpected operation was found");
633 auto rootToNs = [](
Point rp) {
634 return NSPoint{CGFloat(rp.fX), CGFloat(rp.fY)};
637 NSPoint cross[] = {rootToNs(line1->
start()), rootToNs(line1->
end()),
638 rootToNs(line2->
start()), rootToNs(line2->
end())};
640 for (
auto &point : cross) {
642 point = [view convertPoint : point toView : nil];
650 [cv setNeedsDisplay : YES];
720bool 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;
778 const NSRect frame2 = view.frame;
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;
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;
840 WidgetRect rect(frame2.origin.x, frame2.origin.y, frame2.origin.x + frame2.size.width,
841 frame2.origin.y + frame2.size.height);
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]);
864typedef std::vector<int>::iterator int_iterator;
867int_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;
880int_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");
925 for (; recIt != endIt; ++recIt) {
926 if (recIt->fX1 <= rect.
fX1 && recIt->fX2 >= rect.
fX2 &&
927 recIt->fY1 <= rect.
fY1 && recIt->fY2 >= rect.
fY2) {
933 if (recIt->fX1 > rect.
fX1)
936 if (recIt->fX2 < rect.
fX2)
939 if (recIt->fY1 > rect.
fY1)
942 if (recIt->fY2 < rect.
fY2)
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);
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);
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);
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]) {
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;
Handle_t Pixmap_t
Pixmap handle.
Handle_t Drawable_t
Drawable handle.
Handle_t Window_t
Window handle.
static const double x2[5]
static const double x1[5]
include TDocParser_001 C image html pict1_TDocParser_001 png width
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
NSObject< X11Drawable > * GetDrawable(Drawable_t drawableD) const
NSObject< X11Window > * GetWindow(Window_t windowID) const
ClearArea(Window_t wid, const Rectangle_t &area)
void RemoveXORGraphicsOperationsForWindow(Window_t wid)
void AddDrawBoxXor(Window_t windowID, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
std::vector< WidgetRect > fRectsToClip
std::vector< CGRect > fClippedRegion
std::vector< Command * > fXorOps
std::vector< bool > fGrid
void AddDrawLineXor(Window_t windowID, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
void Flush(Details::CocoaPrivate *impl)
void AddDrawSegments(Drawable_t wid, const GCValues_t &gc, const Segment_t *segments, Int_t nSegments)
void AddFillPolygon(Drawable_t wid, const GCValues_t &gc, const Point_t *polygon, Int_t nPoints)
void FlushXOROps(Details::CocoaPrivate *impl)
void ClipOverlaps(QuartzView *view)
std::vector< QuartzView * > fViewBranch
void RemoveGraphicsOperationsForWindow(Window_t wid)
void AddClearArea(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
std::vector< int > fYBounds
void AddDrawRectangle(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
void ClearXOROperations()
void AddDrawLine(Drawable_t wid, const GCValues_t &gc, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
void RemoveOperationsForDrawable(Drawable_t wid)
std::vector< Command * >::size_type size_type
void AddDrawString(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *text, Int_t len)
void AddDeletePixmap(Pixmap_t pixmap)
std::vector< Command * > fCommands
std::vector< int > fXBounds
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 BuildClipRegion(const WidgetRect &rect)
void AddFillRectangle(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, UInt_t w, UInt_t h)
virtual bool IsGraphicsCommand() const
virtual void Execute() const =0
virtual bool HasOperand(Drawable_t drawable) const
bool HasOperand(Drawable_t drawable) const
CopyArea(Drawable_t src, Drawable_t dst, const GCValues_t &gc, const Rectangle_t &area, const Point &dstPoint)
DeletePixmap(Pixmap_t pixmap)
DrawBoxXor(Window_t windowID, const Point &p1, const Point &p2)
DrawLineXor(Window_t windowID, const Point &p1, const Point &p2)
DrawLine(Drawable_t wid, const GCValues_t &gc, const Point &p1, const Point &p2)
DrawRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle)
std::vector< Segment_t > fSegments
DrawSegments(Drawable_t wid, const GCValues_t &gc, const Segment_t *segments, Int_t nSegments)
DrawString(Drawable_t wid, const GCValues_t &gc, const Point &point, const std::string &text)
std::vector< Point_t > fPolygon
FillPolygon(Drawable_t wid, const GCValues_t &gc, const Point_t *points, Int_t nPoints)
const Rectangle_t fRectangle
FillRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle)
UpdateWindow(QuartzView *view)
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D.
void DrawLineAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x1, Int_t y1, Int_t x2, Int_t y2)
void FillRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
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 DrawRectangleAux(Drawable_t wid, const GCValues_t &gcVals, Int_t x, Int_t y, UInt_t w, UInt_t h)
void DrawStringAux(Drawable_t wid, const GCValues_t &gc, Int_t x, Int_t y, const char *s, Int_t len)
void ClearAreaAux(Window_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h)
void DrawSegmentsAux(Drawable_t wid, const GCValues_t &gcVals, const Segment_t *segments, Int_t nSegments)
QuartzPixmap * fBackBuffer
QuartzWindow * fQuartzWindow
QuartzWindow * fQuartzWindow
QuartzImage * fShapeCombineMask
void ClipToShapeMask(NSView< X11Window > *view, CGContextRef ctx)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Graphics context structure.
Pixmap_t fClipMask
bitmap clipping; other calls for rects
Point structure (maps to the X11 XPoint structure)
Rectangle structure (maps to the X11 XRectangle structure)
Used for drawing line segments (maps to the X11 XSegments structure)