Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGLPadUtils.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Timur Pocheptsov 06/05/2009
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2009, 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 "Riostream.h"
13 #include <stdexcept>
14 #include <cassert>
15 
16 #include "TVirtualPad.h"
17 #include "TVirtualX.h"
18 #include "RStipples.h"
19 #include "TColor.h"
20 #include "TROOT.h"
21 #include "TMath.h"
22 
23 #include "TGLPadUtils.h"
24 #include "TGLIncludes.h"
25 
26 namespace Rgl {
27 namespace Pad {
28 
29 const UInt_t PolygonStippleSet::fgBitSwap[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
30 
31 
32 /*
33 Temporary fix.
34 */
35 #ifndef GL_VERSION_1_2
36 const GLenum lineWidthPNAME = GLenum(0xB22);
37 const GLenum pointSizePNAME = GLenum(0xB12);
38 #else
39 const GLenum lineWidthPNAME = GLenum(GL_SMOOTH_LINE_WIDTH_RANGE);//Cast for real enums and macros.
40 const GLenum pointSizePNAME = GLenum(GL_SMOOTH_POINT_SIZE_RANGE);
41 #endif
42 
43 /*
44 Auxiliary class to converts ROOT's polygon stipples from
45 RStipples.h into GL's stipples and hold them in a fStipples array.
46 */
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 PolygonStippleSet::PolygonStippleSet()
51 {
52  /*
53  I have to assume, that gStipple has two chars in a line.
54  There in no way to calculate line length and there are no corresponding constants in RStipple.h.
55  So, these numbers are hardcode here.
56  Ordering in RStipples completely different from OpenGL.
57  In OpenGL, if I have, say, 16x2 pattern, GLbytes will be:
58 
59  [3][4]
60  [1][2]
61 
62  and bits inside them
63 
64  [7 6 5 4 3 2 1 0][7 6 5 4 3 2 1 0]
65  [7 6 5 4 3 2 1 0][7 6 5 4 3 2 1 0].
66 
67  But for X11 this will be:
68 
69  [2][1]
70  [4][3]
71 
72  [0 1 2 3 4 5 6 7][0 1 2 3 4 5 6 7]
73  [0 1 2 3 4 5 6 7][0 1 2 3 4 5 6 7]
74 
75  So, line 0x7, 0xE from X11 must be
76  converted into 0x70, 0xE0 for OpenGL.
77 
78  As OpenGL expects 32x32 pattern, I have to twice each line.
79  */
80 
81  /*If somebody will seriously change gStipples declaration,
82  so, that sizeof gStipples becomes "wrong", change this!*/
83  const UInt_t numOfStipples = sizeof gStipples / sizeof gStipples[0];
84  fStipples.resize(kStippleSize * numOfStipples);
85 
86  for (UInt_t i = 0; i < numOfStipples; ++i) {
87  const UInt_t baseInd = i * kStippleSize;
88 
89  for (Int_t j = 15, j1 = 0; j >= 0; --j, ++j1) {//ROOT uses 16x16 stipples.
90  const UInt_t rowShift = j1 * kRowSize;
91 
92  for (Int_t k = 1, k1 = 0; k >= 0; --k, ++k1) {//Two chars form a line.
93  const UChar_t pixel = SwapBits(gStipples[i][j * 2 + k]);
94  const UInt_t ind = baseInd + rowShift + k1;
95 
96  fStipples[ind] = pixel;
97  fStipples[ind + 2] = pixel;
98  fStipples[ind + 64] = pixel;
99  fStipples[ind + 66] = pixel;
100  }
101  }
102  }
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 
107 UInt_t PolygonStippleSet::SwapBits(UInt_t b)
108 {
109 #ifdef WIN32
110  b = ~b & 0xff;
111 #endif
112  b &= k16Bits;
113 
114  const UInt_t low = fgBitSwap[b & kLow4] << 4;
115  const UInt_t up = fgBitSwap[(b & kUp4) >> 4];
116 
117  return low | up;
118 }
119 
120 /*
121 Class to manipulate fill parameters.
122 */
123 ////////////////////////////////////////////////////////////////////////////////
124 ///Polygon stipple, if required.
125 
126 FillAttribSet::FillAttribSet(const PolygonStippleSet &set, Bool_t ignoreStipple)
127  : fStipple(0), fAlpha(1.)
128 {
129  const UInt_t style = gVirtualX->GetFillStyle() / 1000;
130 
131  if (!ignoreStipple) {
132  if (style == 3) {
133  const UInt_t fasi = gVirtualX->GetFillStyle() % 1000;
134  fStipple = (fasi >= 1 && fasi <=25) ? fasi : 2;
135  glPolygonStipple(&set.fStipples[fStipple * PolygonStippleSet::kStippleSize]);
136  glEnable(GL_POLYGON_STIPPLE);
137  }
138  }
139 
140  // Color and transparency
141  Float_t rgba[] = {0.f, 0.f, 0.f, 1.f};
142  ExtractRGBA(gVirtualX->GetFillColor(), rgba);
143  fAlpha = rgba[3];
144  if (fAlpha<1.) {
145  glEnable(GL_BLEND);
146  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
147  }
148  glColor4fv(rgba);
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 
153 FillAttribSet::~FillAttribSet()
154 {
155  if (fStipple)
156  glDisable(GL_POLYGON_STIPPLE);
157 
158  if (fAlpha<1.)
159  glDisable(GL_BLEND);
160 }
161 
162 /*
163 "ROOT like" line stipples.
164 */
165 
166 const UShort_t gLineStipples[] = {0xffff, 0xffff, 0x3333, 0x5555,
167  0xf040, 0xf4f4, 0xf111, 0xf0f0,
168  0xff11, 0x3fff, 0x08ff};
169 
170 const UInt_t gMaxStipple = sizeof gLineStipples / sizeof gLineStipples[0];
171 
172 /*
173 Set/unset line attributes.
174 */
175 ////////////////////////////////////////////////////////////////////////////////
176 ///Set up line parameters.
177 ///Smooth.
178 
179 LineAttribSet::LineAttribSet(Bool_t smooth, UInt_t stipple, Double_t maxWidth, Bool_t setWidth)
180  : fSmooth(smooth), fStipple(stipple), fSetWidth(setWidth), fAlpha(0.8)
181 {
182  if (fSmooth) {
183  glEnable(GL_BLEND);
184  glEnable(GL_LINE_SMOOTH);
185  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
186  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
187  }
188 
189  //Stipple.
190  if (fStipple > 1) {
191  if (fStipple >= gMaxStipple)
192  fStipple = 1;
193  else {
194  glEnable(GL_LINE_STIPPLE);
195  glLineStipple(fStipple == 10 ? 2 : 1, gLineStipples[fStipple]);
196  }
197  }
198 
199  //Color and transparency
200  Float_t rgba[] = {0.f, 0.f, 0.f, 0.8f};
201  ExtractRGBA(gVirtualX->GetLineColor(), rgba);
202  fAlpha = rgba[3];
203  if (fAlpha<0.8) {
204  glEnable(GL_BLEND);
205  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
206  }
207  glColor4fv(rgba);
208 
209  //Width.
210  if (fSetWidth) {
211  const Width_t w = gVirtualX->GetLineWidth();
212  glLineWidth(w > maxWidth ? maxWidth : !w ? 1.f : w);
213  }
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 
218 LineAttribSet::~LineAttribSet()
219 {
220  if (fSmooth || fAlpha<0.8) {
221  glDisable(GL_LINE_SMOOTH);
222  glDisable(GL_BLEND);
223  }
224 
225  if (fStipple > 1)
226  glDisable(GL_LINE_STIPPLE);
227 
228  if (fSetWidth)
229  glLineWidth(1.f);
230 }
231 
232 /*
233 Auxiliary class to draw markers in a gl-pad.
234 */
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// Simple 1-pixel dots.
238 
239 void MarkerPainter::DrawDot(UInt_t n, const TPoint *xy)const
240 {
241  glBegin(GL_POINTS);
242 
243  for (UInt_t i = 0; i < n; ++i)
244  glVertex2d(xy[i].fX, xy[i].fY);
245 
246  glEnd();
247 }
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// + sign. 1 pixel width lines.
251 
252 void MarkerPainter::DrawPlus(UInt_t n, const TPoint *xy)const
253 {
254  const Double_t im = 4 * gVirtualX->GetMarkerSize() + 0.5;
255  glBegin(GL_LINES);
256 
257  for (UInt_t i = 0; i < n; ++i) {
258  const Double_t x = xy[i].fX;
259  const Double_t y = xy[i].fY;
260  glVertex2d(-im + x, y);
261  glVertex2d(im + x, y);
262  glVertex2d(x, -im + y);
263  glVertex2d(x, im + y);
264  }
265 
266  glEnd();
267 }
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// * marker.
271 
272 void MarkerPainter::DrawStar(UInt_t n, const TPoint *xy)const
273 {
274  SCoord_t im = SCoord_t(4 * gVirtualX->GetMarkerSize() + 0.5);
275  fStar[0].fX = -im; fStar[0].fY = 0;
276  fStar[1].fX = im; fStar[1].fY = 0;
277  fStar[2].fX = 0 ; fStar[2].fY = -im;
278  fStar[3].fX = 0 ; fStar[3].fY = im;
279  im = SCoord_t(0.707*Float_t(im) + 0.5);
280  fStar[4].fX = -im; fStar[4].fY = -im;
281  fStar[5].fX = im; fStar[5].fY = im;
282  fStar[6].fX = -im; fStar[6].fY = im;
283  fStar[7].fX = im; fStar[7].fY = -im;
284 
285  glBegin(GL_LINES);
286 
287  for (UInt_t i = 0; i < n; ++i) {
288  const Double_t x = xy[i].fX;
289  const Double_t y = xy[i].fY;
290 
291  glVertex2d(fStar[0].fX + x, fStar[0].fY + y);
292  glVertex2d(fStar[1].fX + x, fStar[1].fY + y);
293  glVertex2d(fStar[2].fX + x, fStar[2].fY + y);
294  glVertex2d(fStar[3].fX + x, fStar[3].fY + y);
295  glVertex2d(fStar[4].fX + x, fStar[4].fY + y);
296  glVertex2d(fStar[5].fX + x, fStar[5].fY + y);
297  glVertex2d(fStar[6].fX + x, fStar[6].fY + y);
298  glVertex2d(fStar[7].fX + x, fStar[7].fY + y);
299  }
300 
301  glEnd();
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 
306 void MarkerPainter::DrawX(UInt_t n, const TPoint *xy)const
307 {
308  const Double_t im = 0.707 * (4 * gVirtualX->GetMarkerSize() + 0.5) + 0.5;
309 
310  glBegin(GL_LINES);
311 
312  for (UInt_t i = 0; i < n; ++i) {
313  const Double_t x = xy[i].fX;
314  const Double_t y = xy[i].fY;
315 
316  glVertex2d(-im + x, -im + y);
317  glVertex2d(im + x, im + y);
318  glVertex2d(-im + x, im + y);
319  glVertex2d(im + x, -im + y);
320  }
321 
322  glEnd();
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 
327 void MarkerPainter::DrawFullDotSmall(UInt_t n, const TPoint *xy)const
328 {
329  glBegin(GL_LINES);
330 
331  for (UInt_t i = 0; i < n; ++i) {
332  const Double_t x = xy[i].fX;
333  const Double_t y = xy[i].fY;
334 
335  glVertex2d(-1. + x, y);
336  glVertex2d(x + 1., y);
337  glVertex2d(x, -1. + y);
338  glVertex2d(x, 1. + y);
339  }
340 
341  glEnd();
342 }
343 
344 ////////////////////////////////////////////////////////////////////////////////
345 
346 void MarkerPainter::DrawFullDotMedium(UInt_t n, const TPoint *xy)const
347 {
348  for (UInt_t i = 0; i < n; ++i)
349  glRectd(xy[i].fX - 1, xy[i].fY - 1, xy[i].fX + 1, xy[i].fY + 1);
350 }
351 
352 namespace {
353 //Auxilary function for MarkerPainter. Define near the end of this source file.
354 void CalculateCircle(std::vector<TPoint> &circle, Double_t r, UInt_t pts);
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 
359 void MarkerPainter::DrawCircle(UInt_t n, const TPoint *xy)const
360 {
361  Double_t r = 4 * gVirtualX->GetMarkerSize() + 0.5;
362  if (r > 100.)
363  r = 100.;//as in TGX11.
364 
365  fCircle.clear();
366  CalculateCircle(fCircle, r, r < 100. ? kSmallCirclePts : kLargeCirclePts);
367 
368  for (UInt_t i = 0; i < n; ++i) {
369  const Double_t x = xy[i].fX;
370  const Double_t y = xy[i].fY;
371 
372  glBegin(GL_LINE_LOOP);
373  for (UInt_t j = 0, e = fCircle.size(); j < e; ++j)
374  glVertex2d(fCircle[j].fX + x, fCircle[j].fY + y);
375  glEnd();
376  }
377 }
378 
379 ////////////////////////////////////////////////////////////////////////////////
380 
381 void MarkerPainter::DrawFullDotLarge(UInt_t n, const TPoint *xy)const
382 {
383  fCircle.clear();
384  fCircle.push_back(TPoint(0, 0));
385 
386  Double_t r = 4 * gVirtualX->GetMarkerSize() + 0.5;
387  if (r > 100.)
388  r = 100;//as in TGX11.
389 
390  CalculateCircle(fCircle, r, r < 100 ? kSmallCirclePts : kLargeCirclePts);
391 
392  for (UInt_t i = 0; i < n; ++i) {
393  const Double_t x = xy[i].fX;
394  const Double_t y = xy[i].fY;
395 
396  glBegin(GL_TRIANGLE_FAN);
397  for (UInt_t j = 0, e = fCircle.size(); j < e; ++j)
398  glVertex2d(fCircle[j].fX + x, fCircle[j].fY + y);
399  glEnd();
400  }
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////
404 
405 void MarkerPainter::DrawFullSquare(UInt_t n, const TPoint *xy)const
406 {
407  const Double_t im = 4 * gVirtualX->GetMarkerSize() + 0.5;
408  for (UInt_t i = 0; i < n; ++i)
409  glRectd(xy[i].fX - im, xy[i].fY - im, xy[i].fX + im, xy[i].fY + im);
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 
414 void MarkerPainter::DrawFullTrianlgeUp(UInt_t n, const TPoint *xy)const
415 {
416  const Double_t im = 4 * gVirtualX->GetMarkerSize() + 0.5;
417  for (UInt_t i = 0; i < n; ++i) {
418  const Double_t x = xy[i].fX;
419  const Double_t y = xy[i].fY;
420  glBegin(GL_POLYGON);
421  glVertex2d(x - im, y - im);
422  glVertex2d(x + im, y - im);
423  glVertex2d(x, im + y);
424  glEnd();
425  }
426 }
427 
428 ////////////////////////////////////////////////////////////////////////////////
429 
430 void MarkerPainter::DrawFullTrianlgeDown(UInt_t n, const TPoint *xy)const
431 {
432  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
433 
434  for (UInt_t i = 0; i < n; ++i) {
435  const Double_t x = xy[i].fX;
436  const Double_t y = xy[i].fY;
437  glBegin(GL_POLYGON);
438  glVertex2d(x - im, y + im);
439  glVertex2d(x, y - im);
440  glVertex2d(im + x, y + im);
441  glEnd();
442  }
443 }
444 
445 ////////////////////////////////////////////////////////////////////////////////
446 
447 void MarkerPainter::DrawDiamond(UInt_t n, const TPoint *xy)const
448 {
449  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
450  const Int_t imx = Int_t(2.66 * gVirtualX->GetMarkerSize() + 0.5);
451 
452  for (UInt_t i = 0; i < n; ++i) {
453  const Double_t x = xy[i].fX;
454  const Double_t y = xy[i].fY;
455 
456  glBegin(GL_LINE_LOOP);
457  glVertex2d(x - imx, y);
458  glVertex2d(x, y - im);
459  glVertex2d(x + imx, y);
460  glVertex2d(x, y + im);
461  glEnd();
462  }
463 }
464 
465 ////////////////////////////////////////////////////////////////////////////////
466 
467 void MarkerPainter::DrawFullDiamond(UInt_t n, const TPoint *xy)const
468 {
469  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
470  const Int_t imx = Int_t(2.66 * gVirtualX->GetMarkerSize() + 0.5);
471 
472  for (UInt_t i = 0; i < n; ++i) {
473  const Double_t x = xy[i].fX;
474  const Double_t y = xy[i].fY;
475 
476  glBegin(GL_POLYGON);
477  glVertex2d(x - imx, y);
478  glVertex2d(x, y - im);
479  glVertex2d(x + imx, y);
480  glVertex2d(x, y + im);
481  glEnd();
482  }
483 }
484 
485 ////////////////////////////////////////////////////////////////////////////////
486 
487 void MarkerPainter::DrawOpenTrianlgeDown(UInt_t n, const TPoint *xy)const
488 {
489  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
490 
491  for (UInt_t i = 0; i < n; ++i) {
492  const Double_t x = xy[i].fX;
493  const Double_t y = xy[i].fY;
494  glBegin(GL_LINE_LOOP);
495  glVertex2d(x - im, y + im);
496  glVertex2d(x, y - im);
497  glVertex2d(im + x, y + im);
498  glEnd();
499  }
500 }
501 
502 ////////////////////////////////////////////////////////////////////////////////
503 
504 void MarkerPainter::DrawOpenCross(UInt_t n, const TPoint *xy)const
505 {
506  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
507  const Int_t imx = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
508 
509  for (UInt_t i = 0; i < n; ++i) {
510  const Double_t x = xy[i].fX;
511  const Double_t y = xy[i].fY;
512 
513  glBegin(GL_LINE_LOOP);
514  glVertex2d(x - im, y - imx);
515  glVertex2d(x - imx, y - imx);
516  glVertex2d(x - imx, y - im);
517  glVertex2d(x + imx, y - im);
518  glVertex2d(x + imx, y - imx);
519  glVertex2d(x + im, y - imx);
520  glVertex2d(x + im, y + imx);
521  glVertex2d(x + imx, y + imx);
522  glVertex2d(x + imx, y + im);
523  glVertex2d(x - imx, y + im);
524  glVertex2d(x - imx, y + imx);
525  glVertex2d(x - im, y + imx);
526  glEnd();
527  }
528 }
529 
530 ////////////////////////////////////////////////////////////////////////////////
531 
532 void MarkerPainter::DrawFullCross(UInt_t n, const TPoint *xy)const
533 {
534  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
535  const Int_t imx = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
536 
537  for (UInt_t i = 0; i < n; ++i) {
538  const Double_t x = xy[i].fX;
539  const Double_t y = xy[i].fY;
540 
541  glBegin(GL_POLYGON);
542  glVertex2d(x - im, y - imx);
543  glVertex2d(x - im, y + imx);
544  glVertex2d(x + im, y + imx);
545  glVertex2d(x + im, y - imx);
546  glEnd();
547  glBegin(GL_POLYGON);
548  glVertex2d(x - imx, y + imx);
549  glVertex2d(x - imx, y + im);
550  glVertex2d(x + imx, y + im);
551  glVertex2d(x + imx, y + imx);
552  glEnd();
553  glEnd();
554  glBegin(GL_POLYGON);
555  glVertex2d(x - imx, y - imx);
556  glVertex2d(x - imx, y - im);
557  glVertex2d(x + imx, y - im);
558  glVertex2d(x + imx, y - imx);
559  glEnd();
560  }
561 }
562 
563 ////////////////////////////////////////////////////////////////////////////////
564 /// Full star pentagone
565 
566 void MarkerPainter::DrawFullStar(UInt_t n, const TPoint *xy)const
567 {
568  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
569  const Int_t im1 = Int_t(0.66 * gVirtualX->GetMarkerSize() + 0.5);
570  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
571  const Int_t im3 = Int_t(2.66 * gVirtualX->GetMarkerSize() + 0.5);
572  const Int_t im4 = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
573 
574  for (UInt_t i = 0; i < n; ++i) {
575  const Double_t x = xy[i].fX;
576  const Double_t y = xy[i].fY;
577 
578  glBegin(GL_TRIANGLES);
579  glVertex2d(x - im, y - im4);//0
580  glVertex2d(x - im2, y + im1);//1
581  glVertex2d(x - im4, y - im4);//9
582 
583  glVertex2d(x - im2, y + im1);//1
584  glVertex2d(x - im3, y + im);//2
585  glVertex2d(x, y + im2);//3
586 
587  glVertex2d(x, y + im2);//3
588  glVertex2d(x + im3, y + im);//4
589  glVertex2d(x + im2, y + im1);//5
590 
591  glVertex2d(x + im2, y + im1);//5
592  glVertex2d(x + im, y - im4);//6
593  glVertex2d(x + im4, y - im4);//7
594 
595  glVertex2d(x + im4, y - im4);//7
596  glVertex2d(x, y - im);//8
597  glVertex2d(x - im4, y - im4);//9
598 
599  glVertex2d(x - im4, y - im4);//9
600  glVertex2d(x - im2, y + im1);//1
601  glVertex2d(x, y + im2);//3
602 
603  glVertex2d(x - im4, y - im4);//9
604  glVertex2d(x, y + im2);//3
605  glVertex2d(x + im2, y + im1);//5
606 
607  glVertex2d(x - im4, y - im4);//9
608  glVertex2d(x + im2, y + im1);//5
609  glVertex2d(x + im4, y - im4);//7
610 
611  glEnd();
612 
613  }
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Full star pentagone
618 
619 void MarkerPainter::DrawOpenStar(UInt_t n, const TPoint *xy)const
620 {
621  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
622  const Int_t im1 = Int_t(0.66 * gVirtualX->GetMarkerSize() + 0.5);
623  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
624  const Int_t im3 = Int_t(2.66 * gVirtualX->GetMarkerSize() + 0.5);
625  const Int_t im4 = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
626 
627  for (UInt_t i = 0; i < n; ++i) {
628  const Double_t x = xy[i].fX;
629  const Double_t y = xy[i].fY;
630 
631  glBegin(GL_LINE_LOOP);
632  glVertex2d(x - im, y - im4);
633  glVertex2d(x - im2, y + im1);
634  glVertex2d(x - im3, y + im);
635  glVertex2d(x, y + im2);
636  glVertex2d(x + im3, y + im);
637  glVertex2d(x + im2, y + im1);
638  glVertex2d(x + im, y - im4);
639  glVertex2d(x + im4, y - im4);
640  glVertex2d(x, y - im);
641  glVertex2d(x - im4, y - im4);
642  glEnd();
643  }
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 
648 void MarkerPainter::DrawOpenSquareDiagonal(UInt_t n, const TPoint *xy)const
649 {
650  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
651 
652  for (unsigned i = 0; i < n; ++i) {
653  const Double_t x = xy[i].fX;
654  const Double_t y = xy[i].fY;
655 
656  glBegin(GL_LINE_LOOP);
657  glVertex2d(x - im, y - im);
658  glVertex2d(x + im, y - im);
659  glVertex2d(x + im, y + im);
660  glVertex2d(x - im, y + im);
661  glVertex2d(x - im, y - im);
662  glVertex2d(x + im, y + im);
663  glVertex2d(x - im, y + im);
664  glVertex2d(x + im, y - im);
665  glEnd();
666  }
667 }
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 
671 void MarkerPainter::DrawOpenDiamondCross(UInt_t n, const TPoint *xy)const
672 {
673  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
674 
675  for (unsigned i = 0; i < n; ++i) {
676  const Double_t x = xy[i].fX;
677  const Double_t y = xy[i].fY;
678 
679  glBegin(GL_LINE_LOOP);
680  glVertex2d(x - im, y );
681  glVertex2d(x , y - im);
682  glVertex2d(x + im, y );
683  glVertex2d(x , y + im);
684  glVertex2d(x - im, y );
685  glVertex2d(x + im, y );
686  glVertex2d(x , y + im);
687  glVertex2d(x , y - im);
688  glEnd();
689  }
690 }
691 
692 ////////////////////////////////////////////////////////////////////////////////
693 
694 void MarkerPainter::DrawOpenThreeTriangles(UInt_t n, const TPoint *xy)const
695 {
696  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
697  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
698 
699  for (unsigned i = 0; i < n; ++i) {
700  const Double_t x = xy[i].fX;
701  const Double_t y = xy[i].fY;
702 
703  glBegin(GL_LINE_LOOP);
704  glVertex2d(x , y );
705  glVertex2d(x -im2, y + im);
706  glVertex2d(x - im, y );
707  glVertex2d(x , y );
708  glVertex2d(x -im2, y - im);
709  glVertex2d(x +im2, y - im);
710  glVertex2d(x , y );
711  glVertex2d(x + im, y );
712  glVertex2d(x +im2, y + im);
713  glVertex2d(x , y );
714  glEnd();
715  }
716 }
717 
718 ////////////////////////////////////////////////////////////////////////////////
719 
720 void MarkerPainter::DrawOctagonCross(UInt_t n, const TPoint *xy)const
721 {
722  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
723  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
724 
725  for (unsigned i = 0; i < n; ++i) {
726  const Double_t x = xy[i].fX;
727  const Double_t y = xy[i].fY;
728 
729  glBegin(GL_LINE_LOOP);
730  glVertex2d(x-im, y );
731  glVertex2d(x-im, y-im2);
732  glVertex2d(x-im2, y-im);
733  glVertex2d(x+im2, y-im);
734  glVertex2d(x+im, y-im2);
735  glVertex2d(x+im, y+im2);
736  glVertex2d(x+im2, y+im);
737  glVertex2d(x-im2, y+im);
738  glVertex2d(x-im, y+im2);
739  glVertex2d(x-im, y );
740  glVertex2d(x+im, y );
741  glVertex2d(x , y );
742  glVertex2d(x , y-im);
743  glVertex2d(x , y+im);
744  glVertex2d(x , y);
745  glEnd();
746  }
747 }
748 
749 ////////////////////////////////////////////////////////////////////////////////
750 
751 void MarkerPainter::DrawFullThreeTriangles(UInt_t n, const TPoint *xy)const
752 {
753  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
754  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
755 
756  for (unsigned i = 0; i < n; ++i) {
757  const Double_t x = xy[i].fX;
758  const Double_t y = xy[i].fY;
759 
760  glBegin(GL_POLYGON);
761  glVertex2d(x , y );
762  glVertex2d(x -im2, y + im);
763  glVertex2d(x - im, y );
764  glVertex2d(x , y );
765  glVertex2d(x -im2, y - im);
766  glVertex2d(x +im2, y - im);
767  glVertex2d(x , y );
768  glVertex2d(x + im, y );
769  glVertex2d(x +im2, y + im);
770  glVertex2d(x , y );
771  glEnd();
772  }
773 }
774 
775 ////////////////////////////////////////////////////////////////////////////////
776 
777 void MarkerPainter::DrawOpenFourTrianglesX(UInt_t n, const TPoint *xy)const
778 {
779  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
780  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
781 
782  for (unsigned i = 0; i < n; ++i) {
783  const Double_t x = xy[i].fX;
784  const Double_t y = xy[i].fY;
785 
786  glBegin(GL_LINE_LOOP);
787  glVertex2d(x , y );
788  glVertex2d(x+im2, y+im);
789  glVertex2d(x+im , y+im2);
790  glVertex2d(x , y );
791  glVertex2d(x+im , y-im2);
792  glVertex2d(x+im2, y-im);
793  glVertex2d(x , y );
794  glVertex2d(x-im2, y-im);
795  glVertex2d(x-im , y-im2);
796  glVertex2d(x , y );
797  glVertex2d(x-im , y+im2);
798  glVertex2d(x-im2, y+im);
799  glVertex2d(x , y );
800  glEnd();
801  }
802 }
803 
804 ////////////////////////////////////////////////////////////////////////////////
805 
806 void MarkerPainter::DrawFullFourTrianglesX(UInt_t n, const TPoint *xy)const
807 {
808  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
809  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
810 
811  for (unsigned i = 0; i < n; ++i) {
812  const Double_t x = xy[i].fX;
813  const Double_t y = xy[i].fY;
814 
815  glBegin(GL_POLYGON);
816  glVertex2d(x , y );
817  glVertex2d(x+im2, y+im);
818  glVertex2d(x+im , y+im2);
819  glVertex2d(x , y );
820  glVertex2d(x+im , y-im2);
821  glVertex2d(x+im2, y-im);
822  glVertex2d(x , y );
823  glVertex2d(x-im2, y-im);
824  glVertex2d(x-im , y-im2);
825  glVertex2d(x , y );
826  glVertex2d(x-im , y+im2);
827  glVertex2d(x-im2, y+im);
828  glVertex2d(x , y );
829  glEnd();
830  }
831 }
832 
833 ////////////////////////////////////////////////////////////////////////////////
834 
835 void MarkerPainter::DrawOpenDoubleDiamond(UInt_t n, const TPoint *xy)const
836 {
837  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
838  const Int_t im4 = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
839 
840  for (unsigned i = 0; i < n; ++i) {
841  const Double_t x = xy[i].fX;
842  const Double_t y = xy[i].fY;
843 
844  glBegin(GL_LINE_LOOP);
845  glVertex2d(x , y+im );
846  glVertex2d(x-im4, y+im4);
847  glVertex2d(x-im , y );
848  glVertex2d(x-im4, y-im4);
849  glVertex2d(x , y-im );
850  glVertex2d(x+im4, y-im4);
851  glVertex2d(x+im , y );
852  glVertex2d(x+im4, y+im4);
853  glVertex2d(x , y+im );
854  glEnd();
855  }
856 }
857 
858 ////////////////////////////////////////////////////////////////////////////////
859 
860 void MarkerPainter::DrawFullDoubleDiamond(UInt_t n, const TPoint *xy)const
861 {
862  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
863  const Int_t im4 = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
864 
865  for (unsigned i = 0; i < n; ++i) {
866  const Double_t x = xy[i].fX;
867  const Double_t y = xy[i].fY;
868 
869  glBegin(GL_POLYGON);
870  glVertex2d(x, y+im );
871  glVertex2d(x-im4, y+im4);
872  glVertex2d(x, y);
873  glEnd();
874  glBegin(GL_POLYGON);
875  glVertex2d(x-im4, y+im4);
876  glVertex2d(x-im, y);
877  glVertex2d(x, y );
878  glEnd();
879  glBegin(GL_POLYGON);
880  glVertex2d(x-im, y);
881  glVertex2d(x-im4, y-im4);
882  glVertex2d(x, y );
883  glEnd();
884  glBegin(GL_POLYGON);
885  glVertex2d(x-im4, y-im4);
886  glVertex2d(x, y-im);
887  glVertex2d(x, y );
888  glEnd();
889  glBegin(GL_POLYGON);
890  glVertex2d(x, y-im);
891  glVertex2d(x+im4, y-im4);
892  glVertex2d(x, y );
893  glEnd();
894  glBegin(GL_POLYGON);
895  glVertex2d(x+im4, y-im4);
896  glVertex2d(x+im, y);
897  glVertex2d(x, y );
898  glEnd();
899  glBegin(GL_POLYGON);
900  glVertex2d(x+im, y);
901  glVertex2d(x+im4, y+im4);
902  glVertex2d(x, y );
903  glEnd();
904  glBegin(GL_POLYGON);
905  glVertex2d(x+im4, y+im4);
906  glVertex2d(x, y+im);
907  glVertex2d(x, y );
908  glEnd();
909  }
910 }
911 
912 ////////////////////////////////////////////////////////////////////////////////
913 
914 void MarkerPainter::DrawOpenFourTrianglesPlus(UInt_t n, const TPoint *xy)const
915 {
916  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
917  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
918 
919  for (unsigned i = 0; i < n; ++i) {
920  const Double_t x = xy[i].fX;
921  const Double_t y = xy[i].fY;
922 
923  glBegin(GL_LINE_LOOP);
924  glVertex2d(x , y );
925  glVertex2d(x+im2, y+im);
926  glVertex2d(x-im2, y+im);
927  glVertex2d(x+im2, y-im);
928  glVertex2d(x-im2, y-im);
929  glVertex2d(x , y );
930  glVertex2d(x+im, y+im2);
931  glVertex2d(x+im, y-im2);
932  glVertex2d(x-im, y+im2);
933  glVertex2d(x-im, y-im2);
934  glVertex2d(x , y );
935  glEnd();
936  }
937 }
938 
939 ////////////////////////////////////////////////////////////////////////////////
940 
941 void MarkerPainter::DrawFullFourTrianglesPlus(UInt_t n, const TPoint *xy)const
942 {
943  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
944  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
945 
946  for (unsigned i = 0; i < n; ++i) {
947  const Double_t x = xy[i].fX;
948  const Double_t y = xy[i].fY;
949 
950  glBegin(GL_POLYGON);
951  glVertex2d(x , y );
952  glVertex2d(x+im2, y+im);
953  glVertex2d(x-im2, y+im);
954  glVertex2d(x+im2, y-im);
955  glVertex2d(x-im2, y-im);
956  glVertex2d(x , y );
957  glVertex2d(x+im, y+im2);
958  glVertex2d(x+im, y-im2);
959  glVertex2d(x-im, y+im2);
960  glVertex2d(x-im, y-im2);
961  glVertex2d(x , y );
962  glEnd();
963  }
964 }
965 
966 ////////////////////////////////////////////////////////////////////////////////
967 
968 void MarkerPainter::DrawOpenCrossX(UInt_t n, const TPoint *xy)const
969 {
970  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
971  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
972 
973  for (unsigned i = 0; i < n; ++i) {
974  const Double_t x = xy[i].fX;
975  const Double_t y = xy[i].fY;
976 
977  glBegin(GL_LINE_LOOP);
978  glVertex2d(x , y +im2);
979  glVertex2d(x -im2, y + im);
980  glVertex2d(x - im, y +im2);
981  glVertex2d(x -im2, y );
982  glVertex2d(x - im, y -im2);
983  glVertex2d(x -im2, y - im);
984  glVertex2d(x , y -im2);
985  glVertex2d(x +im2, y - im);
986  glVertex2d(x + im, y -im2);
987  glVertex2d(x +im2, y );
988  glVertex2d(x + im, y +im2);
989  glVertex2d(x +im2, y + im);
990  glVertex2d(x , y +im2);
991  glEnd();
992  }
993 }
994 
995 ////////////////////////////////////////////////////////////////////////////////
996 
997 void MarkerPainter::DrawFullCrossX(UInt_t n, const TPoint *xy)const
998 {
999  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
1000  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
1001 
1002  for (unsigned i = 0; i < n; ++i) {
1003  const Double_t x = xy[i].fX;
1004  const Double_t y = xy[i].fY;
1005 
1006  glBegin(GL_POLYGON);
1007  glVertex2d(x , y +im2);
1008  glVertex2d(x -im2, y +im);
1009  glVertex2d(x -im , y +im2);
1010  glVertex2d(x -im2, y );
1011  glVertex2d(x , y );
1012  glEnd();
1013  glBegin(GL_POLYGON);
1014  glVertex2d(x -im2, y);
1015  glVertex2d(x -im, y -im2);
1016  glVertex2d(x -im2, y -im);
1017  glVertex2d(x , y-im2);
1018  glVertex2d(x , y );
1019  glEnd();
1020  glBegin(GL_POLYGON);
1021  glVertex2d(x , y -im2);
1022  glVertex2d(x +im2, y -im);
1023  glVertex2d(x +im , y -im2);
1024  glVertex2d(x +im2, y);
1025  glVertex2d(x , y );
1026  glEnd();
1027  glBegin(GL_POLYGON);
1028  glVertex2d(x +im2, y);
1029  glVertex2d(x +im , y +im2);
1030  glVertex2d(x +im2, y +im);
1031  glVertex2d(x , y +im2);
1032  glVertex2d(x , y );
1033  glEnd(); }
1034 }
1035 
1036 ////////////////////////////////////////////////////////////////////////////////
1037 
1038 void MarkerPainter::DrawFourSquaresX(UInt_t n, const TPoint *xy)const
1039 {
1040  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
1041  const Int_t im2 = Int_t(2.00 * gVirtualX->GetMarkerSize() + 0.5);
1042 
1043  for (unsigned i = 0; i < n; ++i) {
1044  const Double_t x = xy[i].fX;
1045  const Double_t y = xy[i].fY;
1046 
1047  glBegin(GL_POLYGON);
1048  glVertex2d(x, y+im2);
1049  glVertex2d(x-im2 , y+im);
1050  glVertex2d(x-im, y+im2);
1051  glVertex2d(x-im2 , y);
1052  glEnd();
1053  glBegin(GL_POLYGON);
1054  glVertex2d(x-im2, y);
1055  glVertex2d(x-im , y-im2);
1056  glVertex2d(x-im2, y-im);
1057  glVertex2d(x, y-im2);
1058  glEnd();
1059  glBegin(GL_POLYGON);
1060  glVertex2d(x, y-im2);
1061  glVertex2d(x+im2 , y-im);
1062  glVertex2d(x+im, y-im2);
1063  glVertex2d(x+im2, y);
1064  glEnd();
1065  glBegin(GL_POLYGON);
1066  glVertex2d(x+im2, y);
1067  glVertex2d(x+im , y+im2);
1068  glVertex2d(x+im2, y+im);
1069  glVertex2d(x, y+im2);
1070  glEnd();
1071  }
1072 }
1073 
1074 ////////////////////////////////////////////////////////////////////////////////
1075 
1076 void MarkerPainter::DrawFourSquaresPlus(UInt_t n, const TPoint *xy)const
1077 {
1078  const Int_t im = Int_t(4 * gVirtualX->GetMarkerSize() + 0.5);
1079  const Int_t im2 = Int_t(1.33 * gVirtualX->GetMarkerSize() + 0.5);
1080 
1081  for (unsigned i = 0; i < n; ++i) {
1082  const Double_t x = xy[i].fX;
1083  const Double_t y = xy[i].fY;
1084 
1085  glBegin(GL_POLYGON);
1086  glVertex2d(x+im2, y+im2);
1087  glVertex2d(x+im2, y+im);
1088  glVertex2d(x-im2, y+im);
1089  glVertex2d(x-im2, y+im2);
1090  glEnd();
1091  glBegin(GL_POLYGON);
1092  glVertex2d(x-im2, y+im2);
1093  glVertex2d(x-im, y+im2);
1094  glVertex2d(x-im, y-im2);
1095  glVertex2d(x-im2, y-im2);
1096  glEnd();
1097  glBegin(GL_POLYGON);
1098  glVertex2d(x-im2, y-im2);
1099  glVertex2d(x-im2, y-im);
1100  glVertex2d(x+im2, y-im);
1101  glVertex2d(x+im2, y-im2);
1102  glEnd();
1103  glBegin(GL_POLYGON);
1104  glVertex2d(x+im2, y-im2);
1105  glVertex2d(x+im, y-im2);
1106  glVertex2d(x+im, y+im2);
1107  glVertex2d(x+im2, y+im2);
1108  glEnd();
1109  }
1110 }
1111 
1112 /*
1113 Small RAII class for GLU tesselator.
1114 */
1115 #ifndef CALLBACK
1116 #define CALLBACK
1117 #endif
1118 
1119 extern "C" {
1120 #if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
1121  typedef GLvoid (*tess_t)(...);
1122 #elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__) || defined (__APPLE__)
1123  typedef GLvoid (*tess_t)();
1124 #elif defined ( WIN32)
1125  typedef GLvoid (CALLBACK *tess_t)( );
1126 #else
1127  #error "Error - need to define type tess_t for this platform/compiler"
1128 #endif
1129 }
1130 
1131 ////////////////////////////////////////////////////////////////////////////////
1132 
1133 void Begin(Int_t type)
1134 {
1135  Tesselation_t *dump = Tesselator::GetDump();
1136  if (!dump)
1137  return;
1138 
1139  dump->push_back(MeshPatch_t(type));
1140 }
1141 
1142 ////////////////////////////////////////////////////////////////////////////////
1143 
1144 void Vertex(const Double_t *v)
1145 {
1146  Tesselation_t *dump = Tesselator::GetDump();
1147  if (!dump)
1148  return;
1149 
1150  std::vector<Double_t> & vs = dump->back().fPatch;
1151  vs.push_back(v[0]);
1152  vs.push_back(v[1]);
1153  vs.push_back(v[2]);
1154 }
1155 
1156 ////////////////////////////////////////////////////////////////////////////////
1157 
1158 void End()
1159 {
1160 }
1161 
1162 Tesselation_t *Tesselator::fVs = 0;
1163 
1164 ////////////////////////////////////////////////////////////////////////////////
1165 
1166 Tesselator::Tesselator(Bool_t dump)
1167  : fTess(0)
1168 {
1169  GLUtesselator *tess = gluNewTess();
1170  if (!tess)
1171  throw std::runtime_error("tesselator creation failed");
1172 
1173 #if defined(__GNUC__) && __GNUC__ >= 8
1174 #pragma GCC diagnostic push
1175 #pragma GCC diagnostic ignored "-Wcast-function-type"
1176 #endif
1177 
1178  if (!dump) {
1179  gluTessCallback(tess, (GLenum)GLU_BEGIN, (tess_t) glBegin);
1180  gluTessCallback(tess, (GLenum)GLU_END, (tess_t) glEnd);
1181  gluTessCallback(tess, (GLenum)GLU_VERTEX, (tess_t) glVertex3dv);
1182  } else {
1183  gluTessCallback(tess, (GLenum)GLU_BEGIN, (tess_t) Begin);
1184  gluTessCallback(tess, (GLenum)GLU_END, (tess_t) End);
1185  gluTessCallback(tess, (GLenum)GLU_VERTEX, (tess_t) Vertex);
1186  }
1187 
1188 #if defined(__GNUC__) && __GNUC__ >= 8
1189 #pragma GCC diagnostic pop
1190 #endif
1191 
1192  gluTessProperty(tess, GLU_TESS_TOLERANCE, 1e-10);
1193  fTess = tess;
1194 }
1195 
1196 ////////////////////////////////////////////////////////////////////////////////
1197 
1198 Tesselator::~Tesselator()
1199 {
1200  gluDeleteTess((GLUtesselator *)fTess);
1201 }
1202 
1203 /*
1204 In future, this should be an interface to per-pad FBO.
1205 Currently, in only save sizes and coordinates (?)
1206 */
1207 ////////////////////////////////////////////////////////////////////////////////
1208 
1209 OffScreenDevice::OffScreenDevice(UInt_t w, UInt_t h, UInt_t x, UInt_t y, Bool_t top)
1210  : fW(w), fH(h), fX(x), fY(y), fTop(top)
1211 {
1212 }
1213 
1214 ////////////////////////////////////////////////////////////////////////////////
1215 
1216 GLLimits::GLLimits()
1217  : fMaxLineWidth(0.),
1218  fMaxPointSize(0.)
1219 {
1220 }
1221 
1222 ////////////////////////////////////////////////////////////////////////////////
1223 
1224 Double_t GLLimits::GetMaxLineWidth()const
1225 {
1226  if (!fMaxLineWidth) {
1227  Double_t lp[2] = {};
1228  glGetDoublev(lineWidthPNAME, lp);//lineWidthPNAME is defined at the top of this file.
1229  fMaxLineWidth = lp[1];
1230  }
1231 
1232  return fMaxLineWidth;
1233 }
1234 
1235 ////////////////////////////////////////////////////////////////////////////////
1236 
1237 Double_t GLLimits::GetMaxPointSize()const
1238 {
1239  if (!fMaxPointSize) {
1240  Double_t lp[2] = {};
1241  glGetDoublev(pointSizePNAME, lp);//pointSizePNAME is defined at the top of this file.
1242  fMaxPointSize = lp[1];
1243  }
1244 
1245  return fMaxLineWidth;
1246 }
1247 
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 
1251 void ExtractRGBA(Color_t colorIndex, Float_t *rgba)
1252 {
1253  const TColor *color = gROOT->GetColor(colorIndex);
1254  if (color) {
1255  color->GetRGB(rgba[0], rgba[1], rgba[2]);
1256  rgba[3] = color->GetAlpha();
1257  }
1258 }
1259 
1260 ////////////////////////////////////////////////////////////////////////////////
1261 
1262 template<class ValueType>
1263 BoundingRect<ValueType> FindBoundingRect(Int_t nPoints, const ValueType *xs, const ValueType *ys)
1264 {
1265  assert(nPoints > 0 && "FindBoundingRect, invalind number of points");
1266  assert(xs != nullptr && "FindBoundingRect, parameter 'xs' is null");
1267  assert(ys != nullptr && "FindBoundingRect, parameter 'ys' is null");
1268 
1269  ValueType xMin = xs[0], xMax = xMin;
1270  ValueType yMin = ys[0], yMax = yMin;
1271 
1272  for (Int_t i = 1; i < nPoints; ++i) {
1273  xMin = TMath::Min(xMin, xs[i]);
1274  xMax = TMath::Max(xMax, xs[i]);
1275 
1276  yMin = TMath::Min(yMin, ys[i]);
1277  yMax = TMath::Max(yMax, ys[i]);
1278  }
1279 
1280  BoundingRect<ValueType> box = {};
1281  box.fXMin = xMin;
1282  box.fXMax = xMax;
1283  box.fWidth = xMax - xMin;
1284 
1285  box.fYMin = yMin;
1286  box.fYMax = yMax;
1287  box.fHeight = yMax - yMin;
1288 
1289  return box;
1290 }
1291 
1292 template BoundingRect<Double_t> FindBoundingRect(Int_t nPoints, const Double_t *xs, const Double_t *ys);
1293 template BoundingRect<Float_t> FindBoundingRect(Int_t nPoints, const Float_t *xs, const Float_t *ys);
1294 template BoundingRect<Long_t> FindBoundingRect(Int_t nPoints, const Long_t *xs, const Long_t *ys);
1295 template BoundingRect<Int_t> FindBoundingRect(Int_t nPoints, const Int_t *xs, const Int_t *ys);
1296 template BoundingRect<SCoord_t> FindBoundingRect(Int_t nPoints, const SCoord_t *xs, const SCoord_t *ys);
1297 
1298 
1299 
1300 namespace {
1301 
1302 ////////////////////////////////////////////////////////////////////////////////
1303 
1304 void CalculateCircle(std::vector<TPoint> &circle, Double_t r, UInt_t pts)
1305 {
1306  const Double_t delta = TMath::TwoPi() / pts;
1307  const UInt_t first = circle.size();
1308  Double_t angle = 0.;
1309  circle.resize(circle.size() + pts + 1);
1310 
1311  for (UInt_t i = 0; i < pts; ++i, angle += delta) {
1312  circle[first + i].fX = SCoord_t(r * TMath::Cos(angle));
1313  circle[first + i].fY = SCoord_t(r * TMath::Sin(angle));
1314  }
1315 
1316  circle.back().fX = circle[first].fX;
1317  circle.back().fY = circle[first].fY;
1318 }
1319 
1320 }//anonymous namespace
1321 
1322 }//namespace Pad
1323 }//namespace Rgl