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,
37 SCoord_t yMax, SCoord_t yLast);
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
62
63/** \class TPadPainter
64\ingroup gpad
65
66Implement TVirtualPadPainter which abstracts painting operations.
67*/
68
69////////////////////////////////////////////////////////////////////////////////
70///Empty ctor. We need it only because of explicit copy ctor.
71
73{
74}
75
76/*
77Line/fill/etc. attributes can be set inside TPad, but not only where:
78many of them are set by base sub-objects of 2d primitives
79(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
80call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
81it will be mess - at any moment I do not know, where to take line attribute - from
82gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
83*/
84
85
86////////////////////////////////////////////////////////////////////////////////
87/// Delegate to gVirtualX.
88
90{
91 return gVirtualX->GetLineColor();
92}
93
94
95////////////////////////////////////////////////////////////////////////////////
96/// Delegate to gVirtualX.
97
99{
100 return gVirtualX->GetLineStyle();
101}
102
103
104////////////////////////////////////////////////////////////////////////////////
105/// Delegate to gVirtualX.
106
108{
109 return gVirtualX->GetLineWidth();
110}
111
112
113////////////////////////////////////////////////////////////////////////////////
114/// Delegate to gVirtualX.
115
117{
118 gVirtualX->SetLineColor(lcolor);
119}
120
121
122////////////////////////////////////////////////////////////////////////////////
123/// Delegate to gVirtualX.
124
126{
127 gVirtualX->SetLineStyle(lstyle);
128}
129
130
131////////////////////////////////////////////////////////////////////////////////
132/// Delegate to gVirtualX.
133
135{
136 gVirtualX->SetLineWidth(lwidth);
137}
138
139
140////////////////////////////////////////////////////////////////////////////////
141/// Delegate to gVirtualX.
142
144{
145 return gVirtualX->GetFillColor();
146}
147
148
149////////////////////////////////////////////////////////////////////////////////
150/// Delegate to gVirtualX.
151
153{
154 return gVirtualX->GetFillStyle();
155}
156
157
158////////////////////////////////////////////////////////////////////////////////
159/// Delegate to gVirtualX.
160
162{
163 //IsTransparent is implemented as inline function in TAttFill.
164 return gVirtualX->IsTransparent();
165}
166
167
168////////////////////////////////////////////////////////////////////////////////
169/// Delegate to gVirtualX.
170
172{
173 gVirtualX->SetFillColor(fcolor);
174}
175
176
177////////////////////////////////////////////////////////////////////////////////
178/// Delegate to gVirtualX.
179
181{
182 gVirtualX->SetFillStyle(fstyle);
183}
184
185
186////////////////////////////////////////////////////////////////////////////////
187/// Delegate to gVirtualX.
188
190{
191 gVirtualX->SetOpacity(percent);
192}
193
194
195////////////////////////////////////////////////////////////////////////////////
196/// Delegate to gVirtualX.
197
199{
200 return gVirtualX->GetTextAlign();
201}
202
203
204////////////////////////////////////////////////////////////////////////////////
205/// Delegate to gVirtualX.
206
208{
209 return gVirtualX->GetTextAngle();
210}
211
212
213////////////////////////////////////////////////////////////////////////////////
214/// Delegate to gVirtualX.
215
217{
218 return gVirtualX->GetTextColor();
219}
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Delegate to gVirtualX.
224
226{
227 return gVirtualX->GetTextFont();
228}
229
230
231////////////////////////////////////////////////////////////////////////////////
232/// Delegate to gVirtualX.
233
235{
236 return gVirtualX->GetTextSize();
237}
238
239
240////////////////////////////////////////////////////////////////////////////////
241/// Delegate to gVirtualX.
242
244{
245 return gVirtualX->GetTextMagnitude();
246}
247
248
249////////////////////////////////////////////////////////////////////////////////
250/// Delegate to gVirtualX.
251
253{
254 gVirtualX->SetTextAlign(align);
255}
256
257
258////////////////////////////////////////////////////////////////////////////////
259/// Delegate to gVirtualX.
260
262{
263 gVirtualX->SetTextAngle(tangle);
264}
265
266
267////////////////////////////////////////////////////////////////////////////////
268/// Delegate to gVirtualX.
269
271{
272 gVirtualX->SetTextColor(tcolor);
273}
274
275
276////////////////////////////////////////////////////////////////////////////////
277/// Delegate to gVirtualX.
278
280{
281 gVirtualX->SetTextFont(tfont);
282}
283
284
285////////////////////////////////////////////////////////////////////////////////
286/// Delegate to gVirtualX.
287
289{
290 gVirtualX->SetTextSize(tsize);
291}
292
293
294////////////////////////////////////////////////////////////////////////////////
295/// Delegate to gVirtualX.
296
298{
299 gVirtualX->SetTextSizePixels(npixels);
300}
301
302
303////////////////////////////////////////////////////////////////////////////////
304/// Create a gVirtualX Pixmap.
305
307{
308 return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
309}
310
311
312////////////////////////////////////////////////////////////////////////////////
313/// Clear the current gVirtualX window.
314
316{
317 gVirtualX->ClearWindow();
318}
319
320
321////////////////////////////////////////////////////////////////////////////////
322/// Copy a gVirtualX pixmap.
323
325{
326 gVirtualX->CopyPixmap(device, px, py);
327}
328
329
330////////////////////////////////////////////////////////////////////////////////
331/// Close the current gVirtualX pixmap.
332
334{
335 gVirtualX->SelectWindow(device);
336 gVirtualX->ClosePixmap();
337}
338
339
340////////////////////////////////////////////////////////////////////////////////
341/// Select the window in which the graphics will go.
342
344{
345 gVirtualX->SelectWindow(device);
346}
347
348////////////////////////////////////////////////////////////////////////////////
349///Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
350
351void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
352 Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
353{
354}
355
356
357////////////////////////////////////////////////////////////////////////////////
358/// Paint a simple line.
359
361{
362 if (GetLineWidth()<=0) return;
363
364 const Int_t px1 = gPad->XtoPixel(x1);
365 const Int_t px2 = gPad->XtoPixel(x2);
366 const Int_t py1 = gPad->YtoPixel(y1);
367 const Int_t py2 = gPad->YtoPixel(y2);
368 gVirtualX->DrawLine(px1, py1, px2, py2);
369}
370
371
372////////////////////////////////////////////////////////////////////////////////
373/// Paint a simple line in normalized coordinates.
374
376{
377 if (GetLineWidth()<=0) return;
378
379 const Int_t px1 = gPad->UtoPixel(u1);
380 const Int_t py1 = gPad->VtoPixel(v1);
381 const Int_t px2 = gPad->UtoPixel(u2);
382 const Int_t py2 = gPad->VtoPixel(v2);
383 gVirtualX->DrawLine(px1, py1, px2, py2);
384}
385
386
387////////////////////////////////////////////////////////////////////////////////
388/// Paint a simple box.
389
391{
392 if (GetLineWidth()<=0 && mode == TVirtualPadPainter::kHollow) return;
393
394 Int_t px1 = gPad->XtoPixel(x1);
395 Int_t px2 = gPad->XtoPixel(x2);
396 Int_t py1 = gPad->YtoPixel(y1);
397 Int_t py2 = gPad->YtoPixel(y2);
398
399 // Box width must be at least one pixel (WTF is this code???)
400 if (TMath::Abs(px2 - px1) < 1)
401 px2 = px1 + 1;
402 if (TMath::Abs(py1 - py2) < 1)
403 py1 = py2 + 1;
404
405 gVirtualX->DrawBox(px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
406}
407
408////////////////////////////////////////////////////////////////////////////////
409/// Paint filled area.
410
411void TPadPainter::DrawFillArea(Int_t nPoints, const Double_t *xs, const Double_t *ys)
412{
413 if (nPoints < 3) {
414 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
415 return;
416 }
417
418 DrawFillAreaAux(gPad, nPoints, xs, ys);
419}
420
421
422////////////////////////////////////////////////////////////////////////////////
423/// Paint filled area.
424
425void TPadPainter::DrawFillArea(Int_t nPoints, const Float_t *xs, const Float_t *ys)
426{
427 if (nPoints < 3) {
428 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
429 return;
430 }
431
432 DrawFillAreaAux(gPad, nPoints, xs, ys);
433}
434
435////////////////////////////////////////////////////////////////////////////////
436/// Paint Polyline.
437
439{
440 if (GetLineWidth()<=0) return;
441
442 if (n < 2) {
443 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
444 return;
445 }
446
447 DrawPolyLineAux(gPad, n, xs, ys);
448}
449
450
451////////////////////////////////////////////////////////////////////////////////
452/// Paint polyline.
453
455{
456 if (GetLineWidth()<=0) return;
457
458 if (n < 2) {
459 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
460 return;
461 }
462
463 DrawPolyLineAux(gPad, n, xs, ys);
464}
465
466
467////////////////////////////////////////////////////////////////////////////////
468/// Paint polyline in normalized coordinates.
469
471{
472 if (GetLineWidth()<=0) return;
473
474 if (n < 2) {
475 ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
476 return;
477 }
478
479 std::vector<TPoint> xy(n);
480
481 for (Int_t i = 0; i < n; ++i) {
482 xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
483 xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
484 }
485
486 gVirtualX->DrawPolyLine(n, &xy[0]);
487}
488
489
490////////////////////////////////////////////////////////////////////////////////
491/// Paint polymarker.
492
494{
495 if (n < 1) {
496 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
497 return;
498 }
499
500 DrawPolyMarkerAux(gPad, n, x, y);
501}
502
503
504////////////////////////////////////////////////////////////////////////////////
505/// Paint polymarker.
506
508{
509 if (n < 1) {
510 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
511 return;
512 }
513
514 DrawPolyMarkerAux(gPad, n, x, y);
515}
516
517
518////////////////////////////////////////////////////////////////////////////////
519/// Paint text.
520
522{
523 const Int_t px = gPad->XtoPixel(x);
524 const Int_t py = gPad->YtoPixel(y);
525 const Double_t angle = GetTextAngle();
526 const Double_t mgn = GetTextMagnitude();
527 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
528}
529
530
531////////////////////////////////////////////////////////////////////////////////
532/// Special version working with wchar_t and required by TMathText.
533
535{
536 const Int_t px = gPad->XtoPixel(x);
537 const Int_t py = gPad->YtoPixel(y);
538 const Double_t angle = GetTextAngle();
539 const Double_t mgn = GetTextMagnitude();
540 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
541}
542
543
544////////////////////////////////////////////////////////////////////////////////
545/// Paint text in normalized coordinates.
546
548{
549 const Int_t px = gPad->UtoPixel(u);
550 const Int_t py = gPad->VtoPixel(v);
551 const Double_t angle = GetTextAngle();
552 const Double_t mgn = GetTextMagnitude();
553 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
554}
555
556
557////////////////////////////////////////////////////////////////////////////////
558/// Save the image displayed in the canvas pointed by "pad" into a binary file.
559
560void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
561{
562 if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
563 pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
564
565 TCanvas * const canvas = pad->GetCanvas();
566 //Force TCanvas::CopyPixmaps.
567 canvas->Flush();
568
569 const UInt_t w = canvas->GetWw();
570 const UInt_t h = canvas->GetWh();
571
572 const std::unique_ptr<unsigned char[]>
573 pixelData(gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h));
574
575 if (pixelData.get()) {
576 const std::unique_ptr<TImage> image(TImage::Create());
577 if (image.get()) {
578 image->DrawRectangle(0, 0, w, h);
579 if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
580 //Ohhh.
581 if (sizeof(UInt_t) == 4) {
582 //For sure the data returned from TGCocoa::GetColorBits,
583 //it's 4 * w * h bytes with what TASImage considers to be argb.
584 std::copy(pixelData.get(), pixelData.get() + 4 * w * h, argb);
585 } else {
586 //A bit paranoid, don't you think so?
587 //Will Quartz/TASImage work at all on such a fancy platform? ;)
588 const unsigned shift = std::numeric_limits<unsigned char>::digits;
589 //
590 unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
591 const unsigned char *srcPixel = pixelData.get();
592 for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
593 //Looks fishy but should work, trust me :)
594 *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
595 (srcPixel[2] << 2 * shift) &
596 (srcPixel[3] << 3 * shift);
597 }
598 }
599
600 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
601 //Success.
602 return;
603 }
604 }
605 }
606 }
607
608 if (type == TImage::kGif) {
609 gVirtualX->WriteGIF((char*)fileName);
610 } else {
611 const std::unique_ptr<TImage> img(TImage::Create());
612 if (img.get()) {
613 img->FromPad(pad);
614 img->WriteImage(fileName, (TImage::EImageFileTypes)type);
615 }
616 }
617}
618
619
620////////////////////////////////////////////////////////////////////////////////
621/// Paint text in normalized coordinates.
622
624{
625 const Int_t px = gPad->UtoPixel(u);
626 const Int_t py = gPad->VtoPixel(v);
627 const Double_t angle = GetTextAngle();
628 const Double_t mgn = GetTextMagnitude();
629 gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
630}
631
632//Aux. private functions.
633namespace {
634
635////////////////////////////////////////////////////////////////////////////////
636///I'm using 'pad' pointer to get rid of this damned gPad.
637///Unfortunately, TPadPainter itself still has to use it.
638///But at least this code does not have to be fixed.
639
640template<typename T>
641void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
642 std::vector<TPoint> &dst)
643{
644 if (!nPoints)
645 return;
646
647 dst.resize(nPoints);
648
649 for (unsigned i = 0; i < nPoints; ++i) {
650 dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]);
651 dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]);
652 }
653}
654
655////////////////////////////////////////////////////////////////////////////////
656
657inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
658 SCoord_t yMax, SCoord_t yLast)
659{
660 const auto firstPointX = points.back().fX;
661 const auto firstPointY = points.back().fY;
662
663 if (nMerged == 2) {
664 points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
665 } else if (nMerged == 3) {
666 yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
667 points.push_back(TPoint(firstPointX, yMin));
668 points.push_back(TPoint(firstPointX, yLast));
669 } else {
670 points.push_back(TPoint(firstPointX, yMin));
671 points.push_back(TPoint(firstPointX, yMax));
672 points.push_back(TPoint(firstPointX, yLast));
673 }
674}
675
676////////////////////////////////////////////////////////////////////////////////
677///Indices below are _valid_.
678
679inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
680 SCoord_t xMax, SCoord_t xLast, size_type first)
681{
682 const TPoint &firstPoint = dst[first];//This point is never updated.
683
684 if (nMerged == 2) {
685 dst[first + 1].fX = xLast;
686 dst[first + 1].fY = firstPoint.fY;
687 } else if (nMerged == 3) {
688 dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
689 dst[first + 1].fY = firstPoint.fY;
690 dst[first + 2].fX = xLast;
691 dst[first + 2].fY = firstPoint.fY;
692 } else {
693 dst[first + 1].fX = xMin;
694 dst[first + 1].fY = firstPoint.fY;
695 dst[first + 2].fX = xMax;
696 dst[first + 2].fY = firstPoint.fY;
697 dst[first + 3].fX = xLast;
698 dst[first + 3].fY = firstPoint.fY;
699 nMerged = 4;//Adjust the shift.
700 }
701
702 return nMerged;
703}
704
705////////////////////////////////////////////////////////////////////////////////
706/// I'm using 'pad' pointer to get rid of this damned gPad.
707/// Unfortunately, TPadPainter itself still has to use it.
708/// But at least this code does not have to be fixed.
709
710template<typename T>
711void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
712 std::vector<TPoint> &dst)
713{
714 //The "first" pass along X axis.
715 TPoint currentPoint;
716 SCoord_t yMin = 0, yMax = 0, yLast = 0;
717 unsigned nMerged = 0;
718
719 //The first pass along X.
720 for (unsigned i = 0; i < nPoints;) {
721 currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
722 currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
723
724 yMin = currentPoint.fY;
725 yMax = yMin;
726
727 dst.push_back(currentPoint);
728 bool merged = false;
729 nMerged = 1;
730
731 for (unsigned j = i + 1; j < nPoints; ++j) {
732 const SCoord_t newX = pad->XtoPixel(x[j]);
733
734 if (newX == currentPoint.fX) {
735 yLast = pad->YtoPixel(y[j]);
736 yMin = TMath::Min(yMin, yLast);
737 yMax = TMath::Max(yMax, yLast);//We continue.
738 ++nMerged;
739 } else {
740 if (nMerged > 1)
741 MergePointsX(dst, nMerged, yMin, yMax, yLast);
742 merged = true;
743 break;
744 }
745 }
746
747 if (!merged && nMerged > 1)
748 MergePointsX(dst, nMerged, yMin, yMax, yLast);
749
750 i += nMerged;
751 }
752}
753
754////////////////////////////////////////////////////////////////////////////////
755/// This pass is a bit more complicated, since we have to 'compact' in-place.
756
757void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
758{
759 size_type i = 0;
760 for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
761 //i is always less than j, so i is always valid here.
762 const TPoint &currentPoint = dst[i];
763
764 SCoord_t xMin = currentPoint.fX;
765 SCoord_t xMax = xMin;
766 SCoord_t xLast = 0;
767
768 bool merged = false;
769 size_type nMerged = 1;
770
771 for (; j < nPoints; ++j) {
772 const TPoint &nextPoint = dst[j];
773
774 if (nextPoint.fY == currentPoint.fY) {
775 xLast = nextPoint.fX;
776 xMin = TMath::Min(xMin, xLast);
777 xMax = TMath::Max(xMax, xLast);
778 ++nMerged;//and we continue ...
779 } else {
780 if (nMerged > 1)
781 nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
782 merged = true;
783 break;
784 }
785 }
786
787 if (!merged && nMerged > 1)
788 nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
789
790 i += nMerged;
791
792 if (j < nPoints) {
793 dst[i] = dst[j];
794 ++j;
795 } else
796 break;
797 }
798
799 dst.resize(i);
800}
801
802////////////////////////////////////////////////////////////////////////////////
803/// This is a quite simple algorithm, using the fact, that after conversion many
804/// subsequent vertices can have the same 'x' or 'y' coordinate and this part of
805/// a polygon will look like a line on the screen.
806
807template<typename T>
808void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
809 const T *y, std::vector<TPoint> &dst)
810{
811 //I'm using 'pad' pointer to get rid of this damned gPad.
812 //Unfortunately, TPadPainter itself still has to use it.
813 //But at least this code does not have to be fixed.
814
815 if (!nPoints)
816 return;
817
818 dst.clear();
819 dst.reserve(threshold);
820
821 ConvertPointsAndMergePassX(pad, nPoints, x, y, dst);
822
823 if (dst.size() < threshold)
824 return;
825
826 ConvertPointsAndMergeInplacePassY(dst);
827}
828
829////////////////////////////////////////////////////////////////////////////////
830
831template<class T>
832void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys)
833{
834 std::vector<TPoint> xy;
835
836 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
837 pad->GetWh() * pad->GetAbsHNDC())) * 2;
838
839 if (threshold <= 0) {
840 //Ooops, pad is invisible or something really bad and stupid happened.
841 ::Error("DrawFillAreaAux", "invalid pad's geometry");
842 return;
843 }
844
845 if (nPoints < threshold)
846 ConvertPoints(gPad, nPoints, xs, ys, xy);
847 else
848 ConvertPointsAndMerge(gPad, threshold, nPoints, xs, ys, xy);
849
850 //We close the 'polygon' and it'll be rendered as a polyline by gVirtualX.
851 if (!gVirtualX->GetFillStyle())
852 xy.push_back(xy.front());
853
854 if (xy.size() > 2)
855 gVirtualX->DrawFillArea(xy.size(), &xy[0]);
856}
857
858////////////////////////////////////////////////////////////////////////////////
859
860template<typename T>
861void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
862{
863 std::vector<TPoint> xy;
864
865 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
866 pad->GetWh() * pad->GetAbsHNDC())) * 2;
867
868 if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened.
869 ::Error("DrawPolyLineAux", "invalid pad's geometry");
870 return;
871 }
872
873 if (nPoints < (unsigned)threshold)
874 ConvertPoints(pad, nPoints, xs, ys, xy);
875 else
876 ConvertPointsAndMerge(pad, threshold, nPoints, xs, ys, xy);
877
878 if (xy.size() > 1)
879 gVirtualX->DrawPolyLine(xy.size(), &xy[0]);
880
881}
882
883////////////////////////////////////////////////////////////////////////////////
884
885template<class T>
886void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
887{
888 std::vector<TPoint> xy(nPoints);
889
890 for (unsigned i = 0; i < nPoints; ++i) {
891 xy[i].fX = (SCoord_t)pad->XtoPixel(xs[i]);
892 xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]);
893 }
894
895 gVirtualX->DrawPolyMarker(nPoints, &xy[0]);
896}
897
898}
#define h(i)
Definition RSha256.hxx:106
short Style_t
Definition RtypesCore.h:89
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:92
short Width_t
Definition RtypesCore.h:91
float Float_t
Definition RtypesCore.h:57
short Font_t
Definition RtypesCore.h:88
short Short_t
Definition RtypesCore.h:39
short SCoord_t
Definition RtypesCore.h:93
#define ClassImp(name)
Definition Rtypes.h:377
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
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:406
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
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:35
Implement TVirtualPadPainter which abstracts painting operations.
Definition TPadPainter.h:26
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.
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 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
virtual Int_t YtoPixel(Double_t y) const =0
virtual UInt_t GetWh() const =0
virtual Double_t GetAbsWNDC() const =0
virtual Double_t GetAbsHNDC() const =0
virtual Int_t XtoPixel(Double_t x) const =0
virtual UInt_t GetWw() const =0
virtual TCanvas * GetCanvas() const =0
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:250
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123