Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TPadPainter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Olivier Couet, Timur Pocheptsov (vertex merge) 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 <algorithm>
13#include <limits>
14#include <memory>
15#include <vector>
16
17#include "TPadPainter.h"
18#include "TVirtualX.h"
19#include "TCanvas.h"
20#include "TPoint.h"
21#include "TError.h"
22#include "TImage.h"
23#include "TROOT.h"
24#include "TMath.h"
25#include "TPad.h"
26
27namespace {
28
29//Typedef is fine, but let's pretend we look cool and modern:
30using size_type = std::vector<TPoint>::size_type;
31
32template<typename T>
33void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys,
34 std::vector<TPoint> &dst);
35inline
36void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
38
39inline
40size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
41 SCoord_t xMax, SCoord_t xLast, size_type first);
42
43template<typename T>
44void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
45 std::vector<TPoint> &dst);
46
47void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst);
48
49template<class T>
50void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys);
51
52template<typename T>
53void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys);
54
55template<class T>
56void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys);
57
58
59}
60
61
62/** \class TPadPainter
63\ingroup gpad
64
65Implement TVirtualPadPainter which abstracts painting operations.
66*/
67
68////////////////////////////////////////////////////////////////////////////////
69///Empty ctor. We need it only because of explicit copy ctor.
70
74
75/*
76Line/fill/etc. attributes can be set inside TPad, but not only where:
77many of them are set by base sub-objects of 2d primitives
78(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
79call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
80it will be mess - at any moment I do not know, where to take line attribute - from
81gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
82*/
83
84
85////////////////////////////////////////////////////////////////////////////////
86/// Delegate to gVirtualX.
87
89{
90 return gVirtualX->GetLineColor();
91}
92
93
94////////////////////////////////////////////////////////////////////////////////
95/// Delegate to gVirtualX.
96
98{
99 return gVirtualX->GetLineStyle();
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Delegate to gVirtualX.
105
107{
108 return gVirtualX->GetLineWidth();
109}
110
111
112////////////////////////////////////////////////////////////////////////////////
113/// Delegate to gVirtualX.
114
116{
117 gVirtualX->SetLineColor(lcolor);
118}
119
120
121////////////////////////////////////////////////////////////////////////////////
122/// Delegate to gVirtualX.
123
125{
126 gVirtualX->SetLineStyle(lstyle);
127}
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Delegate to gVirtualX.
132
134{
135 gVirtualX->SetLineWidth(lwidth);
136}
137
138
139////////////////////////////////////////////////////////////////////////////////
140/// Delegate to gVirtualX.
141
143{
144 return gVirtualX->GetFillColor();
145}
146
147
148////////////////////////////////////////////////////////////////////////////////
149/// Delegate to gVirtualX.
150
152{
153 return gVirtualX->GetFillStyle();
154}
155
156
157////////////////////////////////////////////////////////////////////////////////
158/// Delegate to gVirtualX.
159
161{
162 //IsTransparent is implemented as inline function in TAttFill.
163 return gVirtualX->IsTransparent();
164}
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// Delegate to gVirtualX.
169
171{
172 gVirtualX->SetFillColor(fcolor);
173}
174
175
176////////////////////////////////////////////////////////////////////////////////
177/// Delegate to gVirtualX.
178
180{
181 gVirtualX->SetFillStyle(fstyle);
182}
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Delegate to gVirtualX.
187
189{
190 gVirtualX->SetOpacity(percent);
191}
192
193
194////////////////////////////////////////////////////////////////////////////////
195/// Delegate to gVirtualX.
196
198{
199 return gVirtualX->GetTextAlign();
200}
201
202
203////////////////////////////////////////////////////////////////////////////////
204/// Delegate to gVirtualX.
205
207{
208 return gVirtualX->GetTextAngle();
209}
210
211
212////////////////////////////////////////////////////////////////////////////////
213/// Delegate to gVirtualX.
214
216{
217 return gVirtualX->GetTextColor();
218}
219
220
221////////////////////////////////////////////////////////////////////////////////
222/// Delegate to gVirtualX.
223
225{
226 return gVirtualX->GetTextFont();
227}
228
229
230////////////////////////////////////////////////////////////////////////////////
231/// Delegate to gVirtualX.
232
234{
235 return gVirtualX->GetTextSize();
236}
237
238
239////////////////////////////////////////////////////////////////////////////////
240/// Delegate to gVirtualX.
241
243{
244 return gVirtualX->GetTextMagnitude();
245}
246
247
248////////////////////////////////////////////////////////////////////////////////
249/// Delegate to gVirtualX.
250
252{
253 gVirtualX->SetTextAlign(align);
254}
255
256
257////////////////////////////////////////////////////////////////////////////////
258/// Delegate to gVirtualX.
259
261{
262 gVirtualX->SetTextAngle(tangle);
263}
264
265
266////////////////////////////////////////////////////////////////////////////////
267/// Delegate to gVirtualX.
268
270{
271 gVirtualX->SetTextColor(tcolor);
272}
273
274
275////////////////////////////////////////////////////////////////////////////////
276/// Delegate to gVirtualX.
277
279{
280 gVirtualX->SetTextFont(tfont);
281}
282
283
284////////////////////////////////////////////////////////////////////////////////
285/// Delegate to gVirtualX.
286
288{
289 gVirtualX->SetTextSize(tsize);
290}
291
292
293////////////////////////////////////////////////////////////////////////////////
294/// Delegate to gVirtualX.
295
297{
298 gVirtualX->SetTextSizePixels(npixels);
299}
300
301
302////////////////////////////////////////////////////////////////////////////////
303/// Create a gVirtualX Pixmap.
304
306{
307 return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
308}
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Clear the current gVirtualX window.
313
315{
316 gVirtualX->ClearWindow();
317}
318
319
320////////////////////////////////////////////////////////////////////////////////
321/// Copy a gVirtualX pixmap.
322
324{
325 gVirtualX->CopyPixmap(device, px, py);
326}
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// Close the current gVirtualX pixmap.
331
333{
334 gVirtualX->SelectWindow(device);
335 gVirtualX->ClosePixmap();
336}
337
338
339////////////////////////////////////////////////////////////////////////////////
340/// Select the window in which the graphics will go.
341
343{
344 gVirtualX->SelectWindow(device);
345}
346
347////////////////////////////////////////////////////////////////////////////////
348///Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
349
350void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
351 Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
352{
353}
354
355
356////////////////////////////////////////////////////////////////////////////////
357/// Paint a simple line.
358
360{
361 if (GetLineWidth()<=0) return;
362
363 const Int_t px1 = gPad->XtoPixel(x1);
364 const Int_t px2 = gPad->XtoPixel(x2);
365 const Int_t py1 = gPad->YtoPixel(y1);
366 const Int_t py2 = gPad->YtoPixel(y2);
367 gVirtualX->DrawLine(px1, py1, px2, py2);
368}
369
370
371////////////////////////////////////////////////////////////////////////////////
372/// Paint a simple line in normalized coordinates.
373
375{
376 if (GetLineWidth()<=0) return;
377
378 const Int_t px1 = gPad->UtoPixel(u1);
379 const Int_t py1 = gPad->VtoPixel(v1);
380 const Int_t px2 = gPad->UtoPixel(u2);
381 const Int_t py2 = gPad->VtoPixel(v2);
382 gVirtualX->DrawLine(px1, py1, px2, py2);
383}
384
385
386////////////////////////////////////////////////////////////////////////////////
387/// Paint a simple box.
388
390{
391 if (GetLineWidth()<=0 && mode == TVirtualPadPainter::kHollow) return;
392
393 Int_t px1 = gPad->XtoPixel(x1);
394 Int_t px2 = gPad->XtoPixel(x2);
395 Int_t py1 = gPad->YtoPixel(y1);
396 Int_t py2 = gPad->YtoPixel(y2);
397
398 // Box width must be at least one pixel (WTF is this code???)
399 if (TMath::Abs(px2 - px1) < 1)
400 px2 = px1 + 1;
401 if (TMath::Abs(py1 - py2) < 1)
402 py1 = py2 + 1;
403
404 gVirtualX->DrawBox(px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
405}
406
407////////////////////////////////////////////////////////////////////////////////
408/// Paint filled area.
409
411{
412 if (nPoints < 3) {
413 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
414 return;
415 }
416
418}
419
420
421////////////////////////////////////////////////////////////////////////////////
422/// Paint filled area.
423
425{
426 if (nPoints < 3) {
427 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
428 return;
429 }
430
432}
433
434////////////////////////////////////////////////////////////////////////////////
435/// Paint Polyline.
436
438{
439 if (GetLineWidth()<=0) return;
440
441 if (n < 2) {
442 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
443 return;
444 }
445
447}
448
449
450////////////////////////////////////////////////////////////////////////////////
451/// Paint polyline.
452
454{
455 if (GetLineWidth()<=0) return;
456
457 if (n < 2) {
458 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
459 return;
460 }
461
463}
464
465
466////////////////////////////////////////////////////////////////////////////////
467/// Paint polyline in normalized coordinates.
468
470{
471 if (GetLineWidth()<=0) return;
472
473 if (n < 2) {
474 ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
475 return;
476 }
477
478 std::vector<TPoint> xy(n);
479
480 for (Int_t i = 0; i < n; ++i) {
481 xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
482 xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
483 }
484
485 gVirtualX->DrawPolyLine(n, &xy[0]);
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// Paint N segments on the pad
490
492{
493 if (GetLineWidth() <= 0)
494 return;
495
496 if (n < 1) {
497 ::Error("TPadPainter::DrawSegments", "invalid number of segments %d", n);
498 return;
499 }
500
501 std::vector<TPoint> xy(n*2);
502 Int_t cnt = 0;
503 for (Int_t i = 0; i < n*2; ++i) {
504 if ((i % 2 == 0) && (x[i] == x[i+1]) && (y[i] == y[i+1])) {
505 // exclude empty segment
506 i++;
507 continue;
508 }
509
510 xy[cnt].fX = (SCoord_t)gPad->XtoPixel(x[i]);
511 xy[cnt].fY = (SCoord_t)gPad->YtoPixel(y[i]);
512 cnt++;
513 }
514
515 if (cnt > 1)
516 gVirtualX->DrawLinesSegments(cnt/2, &xy[0]);
517}
518
519////////////////////////////////////////////////////////////////////////////////
520/// Paint N segments in normalized coordinates on the pad
521
523{
524 if (GetLineWidth() <= 0)
525 return;
526
527 if (n < 1) {
528 ::Error("TPadPainter::DrawSegmentsNDC", "invalid number of segments %d", n);
529 return;
530 }
531
532 std::vector<TPoint> xy(n*2);
533 Int_t cnt = 0;
534 for (Int_t i = 0; i < n*2; ++i) {
535 if ((i % 2 == 0) && (u[i] == u[i+1]) && (v[i] == v[i+1])) {
536 // exclude empty segment
537 i++;
538 continue;
539 }
540
541 xy[cnt].fX = (SCoord_t)gPad->UtoPixel(u[i]);
542 xy[cnt].fY = (SCoord_t)gPad->VtoPixel(v[i]);
543 cnt++;
544 }
545
546 if (cnt > 1)
547 gVirtualX->DrawLinesSegments(cnt/2, &xy[0]);
548}
549
550
551
552////////////////////////////////////////////////////////////////////////////////
553/// Paint polymarker.
554
556{
557 if (n < 1) {
558 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
559 return;
560 }
561
563}
564
565
566////////////////////////////////////////////////////////////////////////////////
567/// Paint polymarker.
568
570{
571 if (n < 1) {
572 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
573 return;
574 }
575
577}
578
579
580////////////////////////////////////////////////////////////////////////////////
581/// Paint text.
582
584{
585 const Int_t px = gPad->XtoPixel(x);
586 const Int_t py = gPad->YtoPixel(y);
587 const Double_t angle = GetTextAngle();
588 const Double_t mgn = GetTextMagnitude();
589 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
590}
591
592
593////////////////////////////////////////////////////////////////////////////////
594/// Special version working with wchar_t and required by TMathText.
595
597{
598 const Int_t px = gPad->XtoPixel(x);
599 const Int_t py = gPad->YtoPixel(y);
600 const Double_t angle = GetTextAngle();
601 const Double_t mgn = GetTextMagnitude();
602 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
603}
604
605
606////////////////////////////////////////////////////////////////////////////////
607/// Paint text in normalized coordinates.
608
610{
611 const Int_t px = gPad->UtoPixel(u);
612 const Int_t py = gPad->VtoPixel(v);
613 const Double_t angle = GetTextAngle();
614 const Double_t mgn = GetTextMagnitude();
615 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
616}
617
618
619////////////////////////////////////////////////////////////////////////////////
620/// Save the image displayed in the canvas pointed by "pad" into a binary file.
621
622void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
623{
624 if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
625 pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
626
627 TCanvas * const canvas = pad->GetCanvas();
628 //Force TCanvas::CopyPixmaps.
629 canvas->Flush();
630
631 const UInt_t w = canvas->GetWw();
632 const UInt_t h = canvas->GetWh();
633
634 const std::unique_ptr<unsigned char[]>
635 pixelData(gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h));
636
637 if (pixelData.get()) {
638 const std::unique_ptr<TImage> image(TImage::Create());
639 if (image.get()) {
640 image->DrawRectangle(0, 0, w, h);
641 if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
642 //Ohhh.
643 if (sizeof(UInt_t) == 4) {
644 //For sure the data returned from TGCocoa::GetColorBits,
645 //it's 4 * w * h bytes with what TASImage considers to be argb.
646 std::copy(pixelData.get(), pixelData.get() + 4 * w * h, argb);
647 } else {
648 //A bit paranoid, don't you think so?
649 //Will Quartz/TASImage work at all on such a fancy platform? ;)
650 const unsigned shift = std::numeric_limits<unsigned char>::digits;
651 //
652 unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
653 const unsigned char *srcPixel = pixelData.get();
654 for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
655 //Looks fishy but should work, trust me :)
656 *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
657 (srcPixel[2] << 2 * shift) &
658 (srcPixel[3] << 3 * shift);
659 }
660 }
661
662 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
663 //Success.
664 return;
665 }
666 }
667 }
668 }
669
670 if (type == TImage::kGif) {
671 gVirtualX->WriteGIF((char*)fileName);
672 } else {
673 const std::unique_ptr<TImage> img(TImage::Create());
674 if (img.get()) {
675 img->FromPad(pad);
676 img->WriteImage(fileName, (TImage::EImageFileTypes)type);
677 }
678 }
679}
680
681
682////////////////////////////////////////////////////////////////////////////////
683/// Paint text in normalized coordinates.
684
686{
687 const Int_t px = gPad->UtoPixel(u);
688 const Int_t py = gPad->VtoPixel(v);
689 const Double_t angle = GetTextAngle();
690 const Double_t mgn = GetTextMagnitude();
691 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
692}
693
694//Aux. private functions.
695namespace {
696
697////////////////////////////////////////////////////////////////////////////////
698///I'm using 'pad' pointer to get rid of this damned gPad.
699///Unfortunately, TPadPainter itself still has to use it.
700///But at least this code does not have to be fixed.
701
702template<typename T>
703void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
704 std::vector<TPoint> &dst)
705{
706 if (!nPoints)
707 return;
708
709 dst.resize(nPoints);
710
711 for (unsigned i = 0; i < nPoints; ++i) {
712 dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]);
713 dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]);
714 }
715}
716
717////////////////////////////////////////////////////////////////////////////////
718
719inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
721{
722 const auto firstPointX = points.back().fX;
723 const auto firstPointY = points.back().fY;
724
725 if (nMerged == 2) {
726 points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
727 } else if (nMerged == 3) {
728 yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
729 points.push_back(TPoint(firstPointX, yMin));
730 points.push_back(TPoint(firstPointX, yLast));
731 } else {
732 points.push_back(TPoint(firstPointX, yMin));
733 points.push_back(TPoint(firstPointX, yMax));
734 points.push_back(TPoint(firstPointX, yLast));
735 }
736}
737
738////////////////////////////////////////////////////////////////////////////////
739///Indices below are _valid_.
740
741inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
742 SCoord_t xMax, SCoord_t xLast, size_type first)
743{
744 const TPoint &firstPoint = dst[first];//This point is never updated.
745
746 if (nMerged == 2) {
747 dst[first + 1].fX = xLast;
748 dst[first + 1].fY = firstPoint.fY;
749 } else if (nMerged == 3) {
750 dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
751 dst[first + 1].fY = firstPoint.fY;
752 dst[first + 2].fX = xLast;
753 dst[first + 2].fY = firstPoint.fY;
754 } else {
755 dst[first + 1].fX = xMin;
756 dst[first + 1].fY = firstPoint.fY;
757 dst[first + 2].fX = xMax;
758 dst[first + 2].fY = firstPoint.fY;
759 dst[first + 3].fX = xLast;
760 dst[first + 3].fY = firstPoint.fY;
761 nMerged = 4;//Adjust the shift.
762 }
763
764 return nMerged;
765}
766
767////////////////////////////////////////////////////////////////////////////////
768/// I'm using 'pad' pointer to get rid of this damned gPad.
769/// Unfortunately, TPadPainter itself still has to use it.
770/// But at least this code does not have to be fixed.
771
772template<typename T>
773void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
774 std::vector<TPoint> &dst)
775{
776 //The "first" pass along X axis.
778 SCoord_t yMin = 0, yMax = 0, yLast = 0;
779 unsigned nMerged = 0;
780
781 //The first pass along X.
782 for (unsigned i = 0; i < nPoints;) {
783 currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
784 currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
785
786 yMin = currentPoint.fY;
787 yMax = yMin;
788
789 dst.push_back(currentPoint);
790 bool merged = false;
791 nMerged = 1;
792
793 for (unsigned j = i + 1; j < nPoints; ++j) {
794 const SCoord_t newX = pad->XtoPixel(x[j]);
795
796 if (newX == currentPoint.fX) {
797 yLast = pad->YtoPixel(y[j]);
799 yMax = TMath::Max(yMax, yLast);//We continue.
800 ++nMerged;
801 } else {
802 if (nMerged > 1)
804 merged = true;
805 break;
806 }
807 }
808
809 if (!merged && nMerged > 1)
811
812 i += nMerged;
813 }
814}
815
816////////////////////////////////////////////////////////////////////////////////
817/// This pass is a bit more complicated, since we have to 'compact' in-place.
818
819void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
820{
821 size_type i = 0;
822 for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
823 //i is always less than j, so i is always valid here.
824 const TPoint &currentPoint = dst[i];
825
828 SCoord_t xLast = 0;
829
830 bool merged = false;
831 size_type nMerged = 1;
832
833 for (; j < nPoints; ++j) {
834 const TPoint &nextPoint = dst[j];
835
836 if (nextPoint.fY == currentPoint.fY) {
837 xLast = nextPoint.fX;
840 ++nMerged;//and we continue ...
841 } else {
842 if (nMerged > 1)
844 merged = true;
845 break;
846 }
847 }
848
849 if (!merged && nMerged > 1)
851
852 i += nMerged;
853
854 if (j < nPoints) {
855 dst[i] = dst[j];
856 ++j;
857 } else
858 break;
859 }
860
861 dst.resize(i);
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// This is a quite simple algorithm, using the fact, that after conversion many
866/// subsequent vertices can have the same 'x' or 'y' coordinate and this part of
867/// a polygon will look like a line on the screen.
868
869template<typename T>
870void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
871 const T *y, std::vector<TPoint> &dst)
872{
873 //I'm using 'pad' pointer to get rid of this damned gPad.
874 //Unfortunately, TPadPainter itself still has to use it.
875 //But at least this code does not have to be fixed.
876
877 if (!nPoints)
878 return;
879
880 dst.clear();
881 dst.reserve(threshold);
882
884
885 if (dst.size() < threshold)
886 return;
887
889}
890
891////////////////////////////////////////////////////////////////////////////////
892
893template<class T>
894void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys)
895{
896 std::vector<TPoint> xy;
897
898 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
899 pad->GetWh() * pad->GetAbsHNDC())) * 2;
900
901 if (threshold <= 0) {
902 //Ooops, pad is invisible or something really bad and stupid happened.
903 ::Error("DrawFillAreaAux", "invalid pad's geometry");
904 return;
905 }
906
907 if (nPoints < threshold)
909 else
911
912 //We close the 'polygon' and it'll be rendered as a polyline by gVirtualX.
913 if (!gVirtualX->GetFillStyle())
914 xy.push_back(xy.front());
915
916 if (xy.size() > 2)
917 gVirtualX->DrawFillArea(xy.size(), &xy[0]);
918}
919
920////////////////////////////////////////////////////////////////////////////////
921
922template<typename T>
923void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
924{
925 std::vector<TPoint> xy;
926
927 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
928 pad->GetWh() * pad->GetAbsHNDC())) * 2;
929
930 if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened.
931 ::Error("DrawPolyLineAux", "invalid pad's geometry");
932 return;
933 }
934
935 if (nPoints < (unsigned)threshold)
937 else
939
940 if (xy.size() > 1)
941 gVirtualX->DrawPolyLine(xy.size(), &xy[0]);
942
943}
944
945////////////////////////////////////////////////////////////////////////////////
946
947template<class T>
948void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
949{
950 std::vector<TPoint> xy(nPoints);
951
952 for (unsigned i = 0; i < nPoints; ++i) {
953 xy[i].fX = (SCoord_t)pad->XtoPixel(xs[i]);
954 xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]);
955 }
956
957 gVirtualX->DrawPolyMarker(nPoints, &xy[0]);
958}
959
960}
#define h(i)
Definition RSha256.hxx:106
short Style_t
Style number (short)
Definition RtypesCore.h:96
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Width_t
Line width (short)
Definition RtypesCore.h:98
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Font_t
Font number (short)
Definition RtypesCore.h:95
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
short SCoord_t
Screen coordinates (short)
Definition RtypesCore.h:100
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
Option_t Option_t mgn
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint angle
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 TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
Option_t Option_t TPoint TPoint percent
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:414
#define gPad
#define gVirtualX
Definition TVirtualX.h:338
The Canvas class.
Definition TCanvas.h:23
Int_t GetCanvasID() const override
Definition TCanvas.h:157
UInt_t GetWw() const override
Definition TCanvas.h:163
UInt_t GetWh() const override
Definition TCanvas.h:164
void Flush()
Flush canvas buffers.
Definition TCanvas.cxx:1143
EImageFileTypes
Definition TImage.h:36
@ kGif
Definition TImage.h:48
static TImage * Create()
Create an image.
Definition TImage.cxx:34
TPadPainter()
Empty ctor. We need it only because of explicit copy ctor.
void DrawFillArea(Int_t n, const Double_t *x, const Double_t *y) override
Paint filled area.
Color_t GetFillColor() const override
Delegate to gVirtualX.
void DrawPixels(const unsigned char *pixelData, UInt_t width, UInt_t height, Int_t dstX, Int_t dstY, Bool_t enableAlphaBlending) override
Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
Float_t GetTextAngle() const override
Delegate to gVirtualX.
void CopyDrawable(Int_t device, Int_t px, Int_t py) override
Copy a gVirtualX pixmap.
void SetFillColor(Color_t fcolor) override
Delegate to gVirtualX.
Float_t GetTextSize() const override
Delegate to gVirtualX.
Style_t GetFillStyle() const override
Delegate to gVirtualX.
void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) override
Paint Polyline.
void DrawSegments(Int_t n, const Double_t *x, const Double_t *y) override
Paint N segments on the pad.
Short_t GetTextAlign() const override
Delegate to gVirtualX.
Style_t GetLineStyle() const override
Delegate to gVirtualX.
Bool_t IsTransparent() const override
Delegate to gVirtualX.
Float_t GetTextMagnitude() const override
Delegate to gVirtualX.
Color_t GetTextColor() const override
Delegate to gVirtualX.
Int_t CreateDrawable(UInt_t w, UInt_t h) override
Create a gVirtualX Pixmap.
void SetTextSize(Float_t tsize) override
Delegate to gVirtualX.
void SetTextAlign(Short_t align) override
Delegate to gVirtualX.
void SetFillStyle(Style_t fstyle) override
Delegate to gVirtualX.
void DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) override
Paint polymarker.
void SetOpacity(Int_t percent) override
Delegate to gVirtualX.
void SetTextAngle(Float_t tangle) override
Delegate to gVirtualX.
void DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode) override
Paint text in normalized coordinates.
void SetTextFont(Font_t tfont) override
Delegate to gVirtualX.
void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const override
Save the image displayed in the canvas pointed by "pad" into a binary file.
void DrawSegmentsNDC(Int_t n, const Double_t *u, const Double_t *v) override
Paint N segments in normalized coordinates on the pad.
void SetLineStyle(Style_t lstyle) override
Delegate to gVirtualX.
Font_t GetTextFont() const override
Delegate to gVirtualX.
void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) override
Paint polyline in normalized coordinates.
void ClearDrawable() override
Clear the current gVirtualX window.
void DestroyDrawable(Int_t device) override
Close the current gVirtualX pixmap.
Width_t GetLineWidth() const override
Delegate to gVirtualX.
void SetTextColor(Color_t tcolor) override
Delegate to gVirtualX.
void SetLineWidth(Width_t lwidth) override
Delegate to gVirtualX.
void SetTextSizePixels(Int_t npixels) override
Delegate to gVirtualX.
void SelectDrawable(Int_t device) override
Select the window in which the graphics will go.
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode) override
Paint a simple box.
void SetLineColor(Color_t lcolor) override
Delegate to gVirtualX.
Color_t GetLineColor() const override
Delegate to gVirtualX.
void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Paint a simple line.
void DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) override
Paint a simple line in normalized coordinates.
void DrawText(Double_t x, Double_t y, const char *text, ETextMode mode) override
Paint text.
SCoord_t fY
Definition TPoint.h:36
SCoord_t fX
Definition TPoint.h:35
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122