Logo ROOT   6.16/01
Reference Guide
QuartzFillArea.mm
Go to the documentation of this file.
1// @(#)root/graf2d:$Id$
2// Author: Olivier Couet, 23/01/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <algorithm>
13#include <cassert>
14#include <vector>
15
16#include "QuartzFillArea.h"
17#include "TColorGradient.h"
18#include "QuartzLine.h"
19#include "CocoaUtils.h"
20#include "TVirtualX.h"
21#include "RStipples.h"
22#include "TError.h"
23#include "TROOT.h"
24
25namespace ROOT {
26namespace Quartz {
27
28namespace Util = MacOSX::Util;
29
30namespace {
31
32const CGSize shadowOffset = CGSizeMake(10., 10.);
33const CGFloat shadowBlur = 5.;
34
35//ROOT has TColorGradient, TLinearGradient and TRadialGradient -
36//they all specify parameters in NDC. But for rendering with
37//Quartz I need more specific parameters, I calculate them here.
38
39// GradientFactory deals with CGFloat being either float or double.
40template<class SRC, class DST>
41struct GradientFactory {
42 static CGGradientRef CreateGradient(CGColorSpaceRef colorSpace,
43 const TColorGradient *extendedColor)
44 {
45 assert(colorSpace != nullptr &&
46 "GradientFactory::CreateGradient, parameter 'colorSpace' is null");
47 assert(extendedColor != nullptr &&
48 "GradientFactory::CreateGradient, parameter 'extendedColor' is null");
49 const SRC *compStart = extendedColor->GetColors();
50 const SRC *compEnd = compStart + extendedColor->GetNumberOfSteps() * 4;
51 const std::vector<DST> convertedComponents(compStart, compEnd);
52 const SRC *posStart = extendedColor->GetColorPositions();
53 const SRC *posEnd = posStart + extendedColor->GetNumberOfSteps();
54 const std::vector<DST> convertedPositions(posStart, posEnd);
55
56 return CGGradientCreateWithColorComponents(colorSpace,
57 &convertedComponents[0],
58 &convertedPositions[0],
59 extendedColor->GetNumberOfSteps());
60 }
61};
62
63template<class DST>
64struct GradientFactory<DST, DST> {
65 static CGGradientRef CreateGradient(CGColorSpaceRef colorSpace,
66 const TColorGradient *extendedColor)
67 {
68 assert(colorSpace != nullptr &&
69 "GradientFactory::CreateGradient, parameter 'colorSpace' is null");
70 assert(extendedColor != nullptr &&
71 "GradientFactory::CreateGradient, parameter 'extendedColor' is null");
72 const DST *comps = extendedColor->GetColors();
73 const DST *pos = extendedColor->GetColorPositions();
74 return CGGradientCreateWithColorComponents(colorSpace, comps, pos,
75 extendedColor->GetNumberOfSteps());
76 }
77};
78
79struct GradientParameters {
80 //
81 CGPoint fStartPoint;
82 CGPoint fEndPoint;
83
84 //Only for radial gradient fill:
85 CGFloat fStartRadius;
86 CGFloat fEndRadius;
87
88 //For the 'simple' radial gradient we use
89 //only fStartPoint (it's a center actually)
90 //and fStartRadius.
91
92 //Something else:...
93
94 GradientParameters()
96 {
97 }
98
99 GradientParameters(const CGPoint &start, const CGPoint &end)
100 : fStartPoint(start), fEndPoint(end), fStartRadius(0.), fEndRadius(0.)
101 {
102 }
103
104
105 GradientParameters(const CGPoint &start, const CGPoint &end,
106 CGFloat startRadius, CGFloat endRadius)
107 : fStartPoint(start), fEndPoint(end), fStartRadius(startRadius), fEndRadius(endRadius)
108 {
109 }
110
111};
112
113//______________________________________________________________________________
114CGRect FindBoundingBox(Int_t nPoints, const TPoint *xy)
115{
116 //When calculating gradient parameters for TColorGradient::kObjectBoundingMode
117 //we need a bounding rect for a polygon.
118 assert(nPoints > 2 && "FindBoundingBox, invalid number of points in a polygon");
119 assert(xy != nullptr && "FindBoundingBox, parameter 'xy' is null");
120
121 CGPoint bottomLeft = {};
122 bottomLeft.x = xy[0].fX;
123 bottomLeft.y = xy[0].fY;
124
125 CGPoint topRight = bottomLeft;
126
127 for (Int_t i = 1; i < nPoints; ++i) {
128 bottomLeft.x = std::min(bottomLeft.x, CGFloat(xy[i].fX));
129 bottomLeft.y = std::min(bottomLeft.y, CGFloat(xy[i].fY));
130 //
131 topRight.x = std::max(topRight.x, CGFloat(xy[i].fX));
132 topRight.y = std::max(topRight.y, CGFloat(xy[i].fY));
133 }
134
135 return CGRectMake(bottomLeft.x, bottomLeft.y,
136 topRight.x - bottomLeft.x,
137 topRight.y - bottomLeft.y);
138}
139
140//______________________________________________________________________________
141template<class GradientType>
142bool CalculateGradientStartEnd(const GradientType *grad,
143 const CGSize &sizeOfDrawable,
144 Int_t n, const TPoint *polygon,
145 GradientParameters &params)
146{
147 assert(grad != nullptr &&
148 "CalculateGradientStartEnd, parameter 'grad' is null");
149 assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
150 "CalculateGradientStartEnd, invalid destination drawable size");
151 assert(n > 2 &&
152 "CalculateGradientStartEnd, parameter 'n' is not a valid number of points");
153 assert(polygon != nullptr &&
154 "CalculateGradientStartEnd, parameter 'polygon' is null");
155
156 const TColorGradient::ECoordinateMode mode = grad->GetCoordinateMode();
157
158 CGPoint start = CGPointMake(grad->GetStart().fX, grad->GetStart().fY);
159 CGPoint end = CGPointMake(grad->GetEnd().fX, grad->GetEnd().fY);
160
161 const CGRect &bbox = FindBoundingBox(n, polygon);
162
163 if (!bbox.size.width || !bbox.size.height)
164 return false;//Invalid polygon actually.
165
167 //With Quartz we always work with something similar to 'kPadMode',
168 //so convert start and end into this space.
169 start.x = bbox.size.width * start.x + bbox.origin.x;
170 end.x = bbox.size.width * end.x + bbox.origin.x;
171
172 start.y = bbox.size.height * start.y + bbox.origin.y;
173 end.y = bbox.size.height * end.y + bbox.origin.y;
174 } else {
175 start.x *= sizeOfDrawable.width;
176 start.y *= sizeOfDrawable.height;
177 end.x *= sizeOfDrawable.width;
178 end.y *= sizeOfDrawable.height;
179 }
180
181 params.fStartPoint = start;
182 params.fEndPoint = end;
183
184 return true;
185}
186
187//______________________________________________________________________________
188bool CalculateGradientRadiuses(const TRadialGradient *grad,
189 const CGSize &sizeOfDrawable,
190 Int_t n, const TPoint *polygon,
191 GradientParameters &params)
192{
193 assert(grad != nullptr && "CalculateGradientRadiuses, parameter 'grad' is null");
194 assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
195 "CalculateGradientRadiuses, invalid destination drawable size");
197 "CalculateGradientRadiuses, extended radial gradient expected");
198 assert(n > 2 && "CalculateGradientRadiuses, parameter 'n' is not a valid number of points");
199 assert(polygon != nullptr &&
200 "CalculateGradientRadiuses, parameter 'polygon' is null");
201
202
203 const CGRect &bbox = FindBoundingBox(n, polygon);
204 if (!bbox.size.width || !bbox.size.height)
205 return false;//Invalid polygon actually.
206
207 CGFloat startRadius = grad->GetR1();
208 CGFloat endRadius = grad->GetR2();
209
211 const CGFloat scale = std::max(bbox.size.width, bbox.size.height);
212
213 startRadius *= scale;
214 endRadius *= scale;
215 } else {
216 const CGFloat scale = std::max(sizeOfDrawable.width, sizeOfDrawable.height);
217
218 startRadius *= scale;
219 endRadius *= scale;
220 }
221
222 params.fStartRadius = startRadius;
223 params.fEndRadius = endRadius;
224
225 return true;
226}
227
228//______________________________________________________________________________
229bool CalculateSimpleRadialGradientParameters(const TRadialGradient *grad,
230 const CGSize &sizeOfDrawable,
231 Int_t n, const TPoint *polygon,
232 GradientParameters &params)
233{
234 assert(grad != nullptr &&
235 "CalculateSimpleRadialGradientParameters, parameter 'grad' is null");
236 assert(grad->GetGradientType() == TRadialGradient::kSimple &&
237 "CalculateSimpleRadialGradientParameters, invalid gradient type");
238 assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
239 "CCalculateSimpleRadialGradientParameters, invalid destination drawable size");
240 assert(n > 2 &&
241 "CalculateSimpleRadialGradientParameters, parameter 'n' is not a valid number of points");
242 assert(polygon != nullptr &&
243 "CalculateSimpleRadialGradientParameters, parameter 'polygon' is null");
244
245
246 const CGRect &bbox = FindBoundingBox(n, polygon);
247 if (!bbox.size.width || !bbox.size.height)
248 return false;//Invalid polygon actually.
249
250
251 CGFloat radius = grad->GetRadius();
252 CGPoint center = CGPointMake(grad->GetCenter().fX, grad->GetCenter().fY);
253
255 radius *= std::max(bbox.size.width, bbox.size.height);
256 center.x = bbox.size.width * center.x + bbox.origin.x;
257 center.y = bbox.size.height * center.y + bbox.origin.y;
258 } else {
259 radius *= std::max(sizeOfDrawable.width, sizeOfDrawable.height);
260 center.x *= sizeOfDrawable.width;
261 center.y *= sizeOfDrawable.height;
262 }
263
264 params.fStartPoint = center;
265 params.fStartRadius = radius;
266
267 return true;
268}
269
270//______________________________________________________________________________
271bool CalculateGradientParameters(const TColorGradient *extendedColor,
272 const CGSize &sizeOfDrawable,
273 Int_t n, const TPoint *polygon,
274 GradientParameters &params)
275{
276 assert(extendedColor != nullptr &&
277 "CalculateGradientParameters, parameter 'extendedColor' is null");
278 assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
279 "CalculateGradientParameters, invalid destination drawable size");
280 assert(n > 2 && "CalculateGradientParameters, parameter 'n' is not a valid number of points");
281 assert(polygon != nullptr &&
282 "CalculateGradientParameters, parameter 'polygon' is null");
283
284 if (const TLinearGradient * const gl = dynamic_cast<const TLinearGradient *>(extendedColor))
285 return CalculateGradientStartEnd(gl, sizeOfDrawable, n, polygon, params);
286 else if (const TRadialGradient * const gr = dynamic_cast<const TRadialGradient *>(extendedColor)) {
287 if (gr->GetGradientType() == TRadialGradient::kSimple) {
288 return CalculateSimpleRadialGradientParameters(gr, sizeOfDrawable, n, polygon, params);
289 } else {
290 if (CalculateGradientStartEnd(gr, sizeOfDrawable, n, polygon, params))
291 return CalculateGradientRadiuses(gr, sizeOfDrawable, n, polygon, params);
292 return false;
293 }
294 }
295
296 assert(0 && "CalculateGradientParamters, unknown gradient type");
297
298 return false;
299}
300
301}//Unnamed namespace.
302
303//______________________________________________________________________________
304Bool_t SetFillColor(CGContextRef ctx, Color_t colorIndex)
305{
306 assert(ctx != nullptr && "SetFillColor, ctx parameter is null");
307
308 const TColor *color = gROOT->GetColor(colorIndex);
309
310 //TGX11 selected color 0 (which is white).
311 if (!color)
312 color = gROOT->GetColor(kWhite);
313 //???
314 if (!color)
315 return kFALSE;
316
317 const CGFloat alpha = color->GetAlpha();
318
319 Float_t rgb[3] = {};
320 color->GetRGB(rgb[0], rgb[1], rgb[2]);
321 CGContextSetRGBFillColor(ctx, rgb[0], rgb[1], rgb[2], alpha);
322
323 return kTRUE;
324}
325
326//______________________________________________________________________________
327void DrawPattern(void *data, CGContextRef ctx)
328{
329 assert(data != nullptr && "DrawPattern, data parameter is null");
330 assert(ctx != nullptr && "DrawPattern, ctx parameter is null");
331
332 //Draw a stencil pattern from gStipples
333 const unsigned stencilIndex = *static_cast<unsigned *>(data);
334
335 for (int i = 30, y = 0; i >= 0; i -= 2, ++y) {
336 int x = 0;
337 for (int j = 0; j < 8; ++j, ++x) {
338 if (gStipples[stencilIndex][i] & (1 << j))
339 CGContextFillRect(ctx, CGRectMake(x, y, 1, 1));
340 }
341
342 for (int j = 0; j < 8; ++j, ++x) {
343 if (gStipples[stencilIndex][i + 1] & (1 << j))
344 CGContextFillRect(ctx, CGRectMake(x, y, 1, 1));
345 }
346 }
347}
348
349//______________________________________________________________________________
350bool SetFillPattern(CGContextRef ctx, const unsigned *patternIndex)
351{
352 assert(ctx != nullptr && "SetFillPattern, ctx parameter is null");
353 assert(patternIndex != nullptr && "SetFillPattern, patternIndex parameter is null");
354
355 const TColor *fillColor = gROOT->GetColor(gVirtualX->GetFillColor());
356 if (!fillColor)
357 fillColor = gROOT->GetColor(kWhite);
358
359 if (!fillColor)
360 return false;
361
362 CGFloat rgba[] = {fillColor->GetRed(), fillColor->GetGreen(), fillColor->GetBlue(), fillColor->GetAlpha()};
363
364
365 const Util::CFScopeGuard<CGColorSpaceRef> baseSpace(CGColorSpaceCreateDeviceRGB());
366 if (!baseSpace.Get())
367 return false;
368
369 const Util::CFScopeGuard<CGColorSpaceRef> patternSpace(CGColorSpaceCreatePattern (baseSpace.Get()));
370 if (!patternSpace.Get())
371 return false;
372
373 CGContextSetFillColorSpace(ctx, patternSpace.Get());
374
375 CGPatternCallbacks callbacks = {0, &DrawPattern, 0};
376 const Util::CFScopeGuard<CGPatternRef> pattern(CGPatternCreate((void*)patternIndex,
377 CGRectMake(0, 0, 16, 16),
378 CGAffineTransformIdentity, 16, 16,
379 kCGPatternTilingConstantSpacing,
380 false, &callbacks));
381
382 if (!pattern.Get())
383 return false;
384
385 CGContextSetFillPattern(ctx, pattern.Get(), rgba);
386
387 return true;
388}
389
390//______________________________________________________________________________
391bool SetFillAreaParameters(CGContextRef ctx, unsigned *patternIndex)
392{
393 assert(ctx != nullptr && "SetFillAreaParameters, ctx parameter is null");
394
395 const unsigned fillStyle = gVirtualX->GetFillStyle() / 1000;
396
397 //2 is hollow, 1 is solid and 3 is a hatch, !solid and !hatch - this is from O.C.'s code.
398 if (fillStyle == 2 || (fillStyle != 1 && fillStyle != 3)) {
399 if (!SetLineColor(ctx, gVirtualX->GetFillColor())) {
400 ::Error("SetFillAreaParameters", "Line color for index %d was not found", int(gVirtualX->GetLineColor()));
401 return false;
402 }
403 } else if (fillStyle == 1) {
404 //Solid fill.
405 if (!SetFillColor(ctx, gVirtualX->GetFillColor())) {
406 ::Error("SetFillAreaParameters", "Fill color for index %d was not found", int(gVirtualX->GetFillColor()));
407 return false;
408 }
409 } else {
410 assert(patternIndex != nullptr && "SetFillAreaParameters, pattern index in null");
411
412 *patternIndex = gVirtualX->GetFillStyle() % 1000;
413 //ROOT has 26 fixed patterns.
414 if (*patternIndex > 25)
415 *patternIndex = 2;
416
417 if (!SetFillPattern(ctx, patternIndex)) {
418 ::Error("SetFillAreaParameters", "SetFillPattern failed");
419 return false;
420 }
421 }
422
423 return true;
424}
425
426//______________________________________________________________________________
427void DrawBox(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2, bool hollow)
428{
429 // Draw a box
430
431 if (x1 > x2)
432 std::swap(x1, x2);
433 if (y1 > y2)
434 std::swap(y1, y2);
435
436 if (hollow)
437 CGContextStrokeRect(ctx, CGRectMake(x1, y1, x2 - x1, y2 - y1));
438 else
439 CGContextFillRect(ctx, CGRectMake(x1, y1, x2 - x1, y2 - y1));
440}
441
442//______________________________________________________________________________
443void DrawFillArea(CGContextRef ctx, Int_t n, TPoint *xy, Bool_t shadow)
444{
445 // Draw a filled area through all points.
446 // n : number of points
447 // xy : list of points
448
449 assert(ctx != nullptr && "DrawFillArea, ctx parameter is null");
450 assert(xy != nullptr && "DrawFillArea, xy parameter is null");
451
452 CGContextBeginPath(ctx);
453
454 CGContextMoveToPoint(ctx, xy[0].fX, xy[0].fY);
455 for (Int_t i = 1; i < n; ++i)
456 CGContextAddLineToPoint(ctx, xy[i].fX, xy[i].fY);
457
458 CGContextClosePath(ctx);
459
460 const unsigned fillStyle = gVirtualX->GetFillStyle() / 1000;
461
462 //2 is hollow, 1 is solid and 3 is a hatch, !solid and !hatch - this is from O.C.'s code.
463 if (fillStyle == 2 || (fillStyle != 1 && fillStyle != 3)) {
464 CGContextStrokePath(ctx);
465 } else if (fillStyle == 1) {
466 if (shadow)
467 CGContextSetShadow(ctx, shadowOffset, shadowBlur);
468
469 CGContextFillPath(ctx);
470 } else {
471 if (shadow)
472 CGContextSetShadow(ctx, shadowOffset, shadowBlur);
473
474 CGContextFillPath(ctx);
475 }
476}
477
478//______________________________________________________________________________
479void DrawPolygonWithGradientFill(CGContextRef ctx, const TColorGradient *extendedColor, const CGSize &sizeOfDrawable,
480 Int_t nPoints, const TPoint *xy, Bool_t drawShadow)
481{
483
484 assert(ctx != nullptr && "DrawPolygonWithGradientFill, ctx parameter is null");
485 assert(nPoints != 0 && "DrawPolygonWithGradientFill, nPoints parameter is 0");
486 assert(xy != nullptr && "DrawPolygonWithGradientFill, xy parameter is null");
487 assert(extendedColor != nullptr &&
488 "DrawPolygonWithGradientFill, extendedColor parameter is null");
489
490 if (!sizeOfDrawable.width || !sizeOfDrawable.height)
491 return;
492
493 const CFScopeGuard<CGMutablePathRef> path(CGPathCreateMutable());
494 if (!path.Get()) {
495 ::Error("DrawPolygonWithGradientFill", "CGPathCreateMutable failed");
496 return;
497 }
498
499 //Create a gradient.
500 const CFScopeGuard<CGColorSpaceRef> baseSpace(CGColorSpaceCreateDeviceRGB());
501 if (!baseSpace.Get()) {
502 ::Error("DrawPolygonWithGradientFill", "CGColorSpaceCreateDeviceRGB failed");
503 return;
504 }
505
506 typedef GradientFactory<Double_t, CGFloat> Factory;
507 const CFScopeGuard<CGGradientRef> gradient(Factory::CreateGradient(baseSpace.Get(), extendedColor));
508 if (!gradient.Get()) {
509 ::Error("DrawPolygonWithGradientFill", "CGGradientCreateWithColorComponents failed");
510 return;
511 }
512
513
514 CGPathMoveToPoint(path.Get(), nullptr, xy[0].fX, xy[0].fY);
515 for (Int_t i = 1; i < nPoints; ++i)
516 CGPathAddLineToPoint(path.Get(), nullptr, xy[i].fX, xy[i].fY);
517
518 CGPathCloseSubpath(path.Get());
519
520 if (drawShadow) {
521 //To have shadow and gradient at the same time,
522 //I first have to fill polygon, and after that
523 //draw gradient (since gradient fills the whole area
524 //with clip path and generates no shadow).
525 CGContextSetRGBFillColor(ctx, 1., 1., 1., 0.5);
526 CGContextBeginPath(ctx);
527 CGContextAddPath(ctx, path.Get());
528 CGContextSetShadow(ctx, shadowOffset, shadowBlur);
529 CGContextFillPath(ctx);
530 }
531
532 CGContextBeginPath(ctx);
533 CGContextAddPath(ctx, path.Get());
534 CGContextClip(ctx);
535
536 GradientParameters params;
537 if (!CalculateGradientParameters(extendedColor, sizeOfDrawable, nPoints, xy, params))
538 return;
539
540 const TRadialGradient * const gr = dynamic_cast<const TRadialGradient *>(extendedColor);
541 if (gr && (params.fStartRadius || params.fEndRadius)) {
542 if (gr->GetGradientType() == TRadialGradient::kSimple) {
543 CGContextDrawRadialGradient(ctx, gradient.Get(), params.fStartPoint, 0.,
544 params.fStartPoint, params.fStartRadius,
545 kCGGradientDrawsAfterEndLocation |
546 kCGGradientDrawsBeforeStartLocation);
547 } else {
548 CGContextDrawRadialGradient(ctx, gradient.Get(), params.fStartPoint, params.fStartRadius,
549 params.fEndPoint, params.fEndRadius,
550 kCGGradientDrawsAfterEndLocation |
551 kCGGradientDrawsBeforeStartLocation);
552 }
553 } else {
554 CGContextDrawLinearGradient(ctx, gradient.Get(),
555 params.fStartPoint, params.fEndPoint,
556 kCGGradientDrawsAfterEndLocation |
557 kCGGradientDrawsBeforeStartLocation);
558 }
559}
560
561}//namespace Quartz
562}//namespace ROOT
CGFloat fStartRadius
CGPoint fStartPoint
CGFloat fEndRadius
CGPoint fEndPoint
const unsigned char gStipples[26][32]
Definition: RStipples.h:26
static const double x2[5]
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
short Color_t
Definition: RtypesCore.h:79
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
@ kWhite
Definition: Rtypes.h:62
void Error(const char *location, const char *msgfmt,...)
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
#define gROOT
Definition: TROOT.h:410
#define gVirtualX
Definition: TVirtualX.h:345
TColorGradient extends basic TColor.
const Double_t * GetColors() const
Get colors.
SizeType_t GetNumberOfSteps() const
Get number of steps.
ECoordinateMode GetCoordinateMode() const
Get coordinate mode.
const Double_t * GetColorPositions() const
Get color positions.
The color creation and management class.
Definition: TColor.h:19
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:50
Float_t GetRed() const
Definition: TColor.h:56
Float_t GetAlpha() const
Definition: TColor.h:62
Float_t GetBlue() const
Definition: TColor.h:58
Float_t GetGreen() const
Definition: TColor.h:57
Define a linear color gradient.
Definition: TPoint.h:31
Define a radial color gradient.
Double_t GetR1() const
Double_t GetRadius() const
Get radius.
Double_t GetR2() const
Get R2.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
TGraphErrors * gr
Definition: legend1.C:25
void DrawFillArea(CGContextRef ctx, Int_t n, TPoint *xy, Bool_t drawShadow)
void DrawBox(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2, bool hollow)
Bool_t SetLineColor(CGContextRef ctx, Color_t colorIndex)
Definition: QuartzLine.mm:29
void DrawPattern(void *data, CGContextRef ctx)
Bool_t SetFillColor(CGContextRef ctx, Color_t colorIndex)
Bool_t SetFillAreaParameters(CGContextRef ctx, unsigned *patternIndex)
void DrawPolygonWithGradientFill(CGContextRef ctx, const TColorGradient *extendedColor, const CGSize &sizeOfDrawable, Int_t nPoints, const TPoint *xy, Bool_t drawShadow)
bool SetFillPattern(CGContextRef ctx, const unsigned *patternIndex)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:12929