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