Logo ROOT   6.10/09
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 
25 namespace ROOT {
26 namespace Quartz {
27 
28 namespace Util = MacOSX::Util;
29 
30 namespace {
31 
32 const CGSize shadowOffset = CGSizeMake(10., 10.);
33 const 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.
40 template<class SRC, class DST>
41 struct 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 
63 template<class DST>
64 struct 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 
79 struct 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()
95  : fStartPoint(), fEndPoint(), fStartRadius(0.), fEndRadius(0.)
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 //______________________________________________________________________________
114 CGRect 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 //______________________________________________________________________________
141 template<class GradientType>
142 bool 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 //______________________________________________________________________________
188 bool 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");
196  assert(grad->GetGradientType() == TRadialGradient::kExtended &&
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 //______________________________________________________________________________
229 bool 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 //______________________________________________________________________________
271 bool 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 //______________________________________________________________________________
304 Bool_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 //______________________________________________________________________________
327 void 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 //______________________________________________________________________________
350 bool 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 //______________________________________________________________________________
391 bool 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 //______________________________________________________________________________
427 void 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 //______________________________________________________________________________
443 void 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 //______________________________________________________________________________
479 void 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)) {
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
Double_t GetRadius() const
Get radius.
Double_t GetR1() const
Float_t GetRed() const
Definition: TColor.h:56
Bool_t SetFillAreaParameters(CGContextRef ctx, unsigned *patternIndex)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
const Point & GetCenter() const
Get center.
float Float_t
Definition: RtypesCore.h:53
const Double_t * GetColorPositions() const
Get color positions.
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
ECoordinateMode GetCoordinateMode() const
Get coordinate mode.
Float_t GetAlpha() const
Definition: TColor.h:62
Bool_t SetFillColor(CGContextRef ctx, Color_t colorIndex)
SizeType_t GetNumberOfSteps() const
Get number of steps.
SCoord_t fX
Definition: TPoint.h:35
#define gROOT
Definition: TROOT.h:375
SCoord_t fY
Definition: TPoint.h:36
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Define a radial color gradient.
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
Definition: TColor.h:50
Float_t GetBlue() const
Definition: TColor.h:58
bool SetFillPattern(CGContextRef ctx, const unsigned *patternIndex)
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
Float_t GetGreen() const
Definition: TColor.h:57
Double_t GetR2() const
Get R2.
CGFloat fStartRadius
void DrawPattern(void *data, CGContextRef ctx)
short Color_t
Definition: RtypesCore.h:79
Definition: TPoint.h:31
Definition: Rtypes.h:55
void DrawFillArea(CGContextRef ctx, Int_t n, TPoint *xy, Bool_t drawShadow)
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
Bool_t SetLineColor(CGContextRef ctx, Color_t colorIndex)
Definition: QuartzLine.mm:29
CGFloat fEndRadius
void DrawPolygonWithGradientFill(CGContextRef ctx, const TColorGradient *extendedColor, const CGSize &sizeOfDrawable, Int_t nPoints, const TPoint *xy, Bool_t drawShadow)
const unsigned char gStipples[26][32]
Definition: RStipples.h:26
TGraphErrors * gr
Definition: legend1.C:25
#define gVirtualX
Definition: TVirtualX.h:350
const Bool_t kFALSE
Definition: RtypesCore.h:92
Define a linear color gradient.
static const double x1[5]
Double_t y[n]
Definition: legend1.C:17
The color creation and management class.
Definition: TColor.h:19
CGPoint fStartPoint
EGradientType GetGradientType() const
Get gradient type.
void DrawBox(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2, bool hollow)
const Double_t * GetColors() const
Get colors.
TColorGradient extends basic TColor.
const Bool_t kTRUE
Definition: RtypesCore.h:91
const Int_t n
Definition: legend1.C:16
CGPoint fEndPoint
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.