28namespace Util = MacOSX::Util;
 
   32const CGSize shadowOffset = CGSizeMake(10., 10.);
 
   33const CGFloat shadowBlur = 5.;
 
   40template<
class SRC, 
class DST>
 
   41struct GradientFactory {
 
   42   static CGGradientRef CreateGradient(CGColorSpaceRef colorSpace,
 
   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();
 
   51      const std::vector<DST> convertedComponents(compStart, compEnd);
 
   54      const std::vector<DST> convertedPositions(posStart, posEnd);
 
   56      return CGGradientCreateWithColorComponents(colorSpace,
 
   57                                                 &convertedComponents[0],
 
   58                                                 &convertedPositions[0],
 
   64struct GradientFactory<DST, DST> {
 
   65   static CGGradientRef CreateGradient(CGColorSpaceRef colorSpace,
 
   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();
 
   74      return CGGradientCreateWithColorComponents(colorSpace, comps, pos,
 
   79struct GradientParameters {
 
   99   GradientParameters(
const CGPoint &start, 
const CGPoint &end)
 
  105   GradientParameters(
const CGPoint &start, 
const CGPoint &end,
 
  106                      CGFloat startRadius, CGFloat endRadius)
 
  118   assert(nPoints > 2 && 
"FindBoundingBox, invalid number of points in a polygon");
 
  119   assert(
xy != 
nullptr && 
"FindBoundingBox, parameter 'xy' is null");
 
  121   CGPoint bottomLeft = {};
 
  122   bottomLeft.x = 
xy[0].
fX;
 
  123   bottomLeft.y = 
xy[0].
fY;
 
  125   CGPoint topRight = bottomLeft;
 
  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));
 
  131      topRight.x = std::max(topRight.x, CGFloat(
xy[i].fX));
 
  132      topRight.y = std::max(topRight.y, CGFloat(
xy[i].fY));
 
  135   return CGRectMake(bottomLeft.x, bottomLeft.y,
 
  136                     topRight.x - bottomLeft.x,
 
  137                     topRight.y - bottomLeft.y);
 
  141template<
class GradientType>
 
  142bool CalculateGradientStartEnd(
const GradientType *grad,
 
  143                               const CGSize &sizeOfDrawable,
 
  145                               GradientParameters ¶ms)
 
  147   assert(grad != 
nullptr &&
 
  148          "CalculateGradientStartEnd, parameter 'grad' is null");
 
  149   assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
 
  150          "CalculateGradientStartEnd, invalid destination drawable size");
 
  152          "CalculateGradientStartEnd, parameter 'n' is not a valid number of points");
 
  153   assert(polygon != 
nullptr &&
 
  154          "CalculateGradientStartEnd, parameter 'polygon' is null");
 
  158   CGPoint 
start = CGPointMake(grad->GetStart().fX, grad->GetStart().fY);
 
  159   CGPoint 
end = CGPointMake(grad->GetEnd().fX, grad->GetEnd().fY);
 
  161   const CGRect &bbox = FindBoundingBox(
n, polygon);
 
  163   if (!bbox.size.width || !bbox.size.height)
 
  169      start.x = bbox.size.width * 
start.x + bbox.origin.x;
 
  170      end.x = bbox.size.width * 
end.x + bbox.origin.x;
 
  172      start.y = bbox.size.height * 
start.y + bbox.origin.y;
 
  173      end.y = bbox.size.height * 
end.y + bbox.origin.y;
 
  175      start.x *= sizeOfDrawable.width;
 
  176      start.y *= sizeOfDrawable.height;
 
  177      end.x *= sizeOfDrawable.width;
 
  178      end.y *= sizeOfDrawable.height;
 
  181   params.fStartPoint = 
start;
 
  182   params.fEndPoint = 
end;
 
  189                               const CGSize &sizeOfDrawable,
 
  191                               GradientParameters ¶ms)
 
  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");
 
  203   const CGRect &bbox = FindBoundingBox(
n, polygon);
 
  204   if (!bbox.size.width || !bbox.size.height)
 
  207   CGFloat startRadius = grad->
GetR1();
 
  208   CGFloat endRadius = grad->
GetR2();
 
  211      const CGFloat scale = std::max(bbox.size.width, bbox.size.height);
 
  213      startRadius *= scale;
 
  216      const CGFloat scale = std::max(sizeOfDrawable.width, sizeOfDrawable.height);
 
  218      startRadius *= scale;
 
  222   params.fStartRadius = startRadius;
 
  223   params.fEndRadius = endRadius;
 
  229bool CalculateSimpleRadialGradientParameters(
const TRadialGradient *grad,
 
  230                                             const CGSize &sizeOfDrawable,
 
  232                                             GradientParameters ¶ms)
 
  234   assert(grad != 
nullptr &&
 
  235          "CalculateSimpleRadialGradientParameters, parameter 'grad' is null");
 
  237          "CalculateSimpleRadialGradientParameters, invalid gradient type");
 
  238   assert(sizeOfDrawable.width > 0. && sizeOfDrawable.height > 0. &&
 
  239          "CCalculateSimpleRadialGradientParameters, invalid destination drawable size");
 
  241          "CalculateSimpleRadialGradientParameters, parameter 'n' is not a valid number of points");
 
  242   assert(polygon != 
nullptr &&
 
  243          "CalculateSimpleRadialGradientParameters, parameter 'polygon' is null");
 
  246   const CGRect &bbox = FindBoundingBox(
n, polygon);
 
  247   if (!bbox.size.width || !bbox.size.height)
 
  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;
 
  259      radius *= std::max(sizeOfDrawable.width, sizeOfDrawable.height);
 
  260      center.x *= sizeOfDrawable.width;
 
  261      center.y *= sizeOfDrawable.height;
 
  264   params.fStartPoint = center;
 
  265   params.fStartRadius = radius;
 
  271bool CalculateGradientParameters(
const TColorGradient *extendedColor,
 
  272                                 const CGSize &sizeOfDrawable,
 
  274                                 GradientParameters ¶ms)
 
  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");
 
  285      return CalculateGradientStartEnd(gl, sizeOfDrawable, 
n, polygon, params);
 
  288         return CalculateSimpleRadialGradientParameters(
gr, sizeOfDrawable, 
n, polygon, params);
 
  290         if (CalculateGradientStartEnd(
gr, sizeOfDrawable, 
n, polygon, params))
 
  291            return CalculateGradientRadiuses(
gr, sizeOfDrawable, 
n, polygon, params);
 
  296   assert(0 && 
"CalculateGradientParamters, unknown gradient type");
 
  306   assert(ctx != 
nullptr && 
"SetFillColor, ctx parameter is null");
 
  317   const CGFloat alpha = color->
GetAlpha();
 
  320   color->
GetRGB(rgb[0], rgb[1], rgb[2]);
 
  321   CGContextSetRGBFillColor(ctx, rgb[0], rgb[1], rgb[2], alpha);
 
  329   assert(
data != 
nullptr && 
"DrawPattern, data parameter is null");
 
  330   assert(ctx != 
nullptr && 
"DrawPattern, ctx parameter is null");
 
  333   const unsigned stencilIndex = *
static_cast<unsigned *
>(
data);
 
  335   for (
int i = 30, 
y = 0; i >= 0; i -= 2, ++
y) {
 
  337      for (
int j = 0; j < 8; ++j, ++
x) {
 
  338         if (
gStipples[stencilIndex][i] & (1 << j))
 
  339            CGContextFillRect(ctx, CGRectMake(
x, 
y, 1, 1));
 
  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));
 
  352   assert(ctx != 
nullptr && 
"SetFillPattern, ctx parameter is null");
 
  353   assert(patternIndex != 
nullptr && 
"SetFillPattern, patternIndex parameter is null");
 
  366   if (!baseSpace.
Get())
 
  370   if (!patternSpace.
Get())
 
  373   CGContextSetFillColorSpace(ctx, patternSpace.
Get());
 
  375   CGPatternCallbacks callbacks = {0, &
DrawPattern, 0};
 
  377                                                  CGRectMake(0, 0, 16, 16),
 
  378                                                  CGAffineTransformIdentity, 16, 16,
 
  379                                                  kCGPatternTilingConstantSpacing,
 
  385   CGContextSetFillPattern(ctx, pattern.
Get(), rgba);
 
  393   assert(ctx != 
nullptr && 
"SetFillAreaParameters, ctx parameter is null");
 
  395   const unsigned fillStyle = 
gVirtualX->GetFillStyle() / 1000;
 
  398   if (fillStyle == 2 || (fillStyle != 1 && fillStyle != 3)) {
 
  400         ::Error(
"SetFillAreaParameters", 
"Line color for index %d was not found", 
int(
gVirtualX->GetLineColor()));
 
  403   } 
else if (fillStyle == 1) {
 
  406         ::Error(
"SetFillAreaParameters", 
"Fill color for index %d was not found", 
int(
gVirtualX->GetFillColor()));
 
  410      assert(patternIndex != 
nullptr && 
"SetFillAreaParameters, pattern index in null");
 
  412      *patternIndex = 
gVirtualX->GetFillStyle() % 1000;
 
  414      if (*patternIndex > 25)
 
  418         ::Error(
"SetFillAreaParameters", 
"SetFillPattern failed");
 
  437      CGContextStrokeRect(ctx, CGRectMake(
x1, 
y1, 
x2 - 
x1, 
y2 - 
y1));
 
  439      CGContextFillRect(ctx, CGRectMake(
x1, 
y1, 
x2 - 
x1, 
y2 - 
y1));
 
  449   assert(ctx != 
nullptr && 
"DrawFillArea, ctx parameter is null");
 
  450   assert(
xy != 
nullptr && 
"DrawFillArea, xy parameter is null");
 
  452   CGContextBeginPath(ctx);
 
  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);
 
  458   CGContextClosePath(ctx);
 
  460   const unsigned fillStyle = 
gVirtualX->GetFillStyle() / 1000;
 
  463   if (fillStyle == 2 || (fillStyle != 1 && fillStyle != 3)) {
 
  464      CGContextStrokePath(ctx);
 
  465   } 
else if (fillStyle == 1) {
 
  467         CGContextSetShadow(ctx, shadowOffset, shadowBlur);
 
  469      CGContextFillPath(ctx);
 
  472         CGContextSetShadow(ctx, shadowOffset, shadowBlur);
 
  474      CGContextFillPath(ctx);
 
  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");
 
  490   if (!sizeOfDrawable.width || !sizeOfDrawable.height)
 
  493   const CFScopeGuard<CGMutablePathRef> path(CGPathCreateMutable());
 
  495      ::Error(
"DrawPolygonWithGradientFill", 
"CGPathCreateMutable failed");
 
  500   const CFScopeGuard<CGColorSpaceRef> baseSpace(CGColorSpaceCreateDeviceRGB());
 
  501   if (!baseSpace.Get()) {
 
  502      ::Error(
"DrawPolygonWithGradientFill", 
"CGColorSpaceCreateDeviceRGB failed");
 
  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");
 
  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);
 
  518   CGPathCloseSubpath(path.Get());
 
  525      CGContextSetRGBFillColor(ctx, 1., 1., 1., 0.5);
 
  526      CGContextBeginPath(ctx);
 
  527      CGContextAddPath(ctx, path.Get());
 
  528      CGContextSetShadow(ctx, shadowOffset, shadowBlur);
 
  529      CGContextFillPath(ctx);
 
  532   CGContextBeginPath(ctx);
 
  533   CGContextAddPath(ctx, path.Get());
 
  536   GradientParameters params;
 
  537   if (!CalculateGradientParameters(extendedColor, sizeOfDrawable, nPoints, 
xy, params))
 
  541   if (
gr && (params.fStartRadius || params.fEndRadius)) {
 
  543         CGContextDrawRadialGradient(ctx, gradient.Get(), params.fStartPoint, 0.,
 
  544                                     params.fStartPoint, params.fStartRadius,
 
  545                                     kCGGradientDrawsAfterEndLocation |
 
  546                                     kCGGradientDrawsBeforeStartLocation);
 
  548         CGContextDrawRadialGradient(ctx, gradient.Get(), params.fStartPoint, params.fStartRadius,
 
  549                                     params.fEndPoint, params.fEndRadius,
 
  550                                     kCGGradientDrawsAfterEndLocation |
 
  551                                     kCGGradientDrawsBeforeStartLocation);
 
  554      CGContextDrawLinearGradient(ctx, gradient.Get(),
 
  555                                  params.fStartPoint, params.fEndPoint,
 
  556                                  kCGGradientDrawsAfterEndLocation |
 
  557                                  kCGGradientDrawsBeforeStartLocation);
 
const unsigned char gStipples[26][32]
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t DrawFillArea
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint xy
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t TPoint TPoint const char y1
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.
virtual void GetRGB(Float_t &r, Float_t &g, Float_t &b) const
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Define a linear color gradient.
Define a radial color gradient.
Double_t GetRadius() const
Get radius.
Double_t GetR2() const
Get R2.
const Point & GetCenter() const
Get center.
EGradientType GetGradientType() const
Get gradient type.
void DrawBox(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2, bool hollow)
void DrawPattern(void *data, CGContextRef ctx)
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)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.