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>
51
52template<typename T>
53void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys);
54
55template<class T>
56void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, 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
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
185
186
187////////////////////////////////////////////////////////////////////////////////
188/// Delegate to gVirtualX.
189
191{
192 gVirtualX->SetOpacity(percent);
193}
194
195
196////////////////////////////////////////////////////////////////////////////////
197/// Delegate to gVirtualX.
198
200{
201 return gVirtualX->GetTextAlign();
202}
203
204
205////////////////////////////////////////////////////////////////////////////////
206/// Delegate to gVirtualX.
207
209{
210 return gVirtualX->GetTextAngle();
211}
212
213
214////////////////////////////////////////////////////////////////////////////////
215/// Delegate to gVirtualX.
216
218{
219 return gVirtualX->GetTextColor();
220}
221
222
223////////////////////////////////////////////////////////////////////////////////
224/// Delegate to gVirtualX.
225
227{
228 return gVirtualX->GetTextFont();
229}
230
231
232////////////////////////////////////////////////////////////////////////////////
233/// Delegate to gVirtualX.
234
236{
237 return gVirtualX->GetTextSize();
238}
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// Delegate to gVirtualX.
243
245{
246 return gVirtualX->GetTextMagnitude();
247}
248
249
250////////////////////////////////////////////////////////////////////////////////
251/// Delegate to gVirtualX.
252
254{
255 gVirtualX->SetTextAlign(align);
256}
257
258
259////////////////////////////////////////////////////////////////////////////////
260/// Delegate to gVirtualX.
261
263{
264 gVirtualX->SetTextAngle(tangle);
265}
266
267
268////////////////////////////////////////////////////////////////////////////////
269/// Delegate to gVirtualX.
270
272{
273 gVirtualX->SetTextColor(tcolor);
274}
275
276
277////////////////////////////////////////////////////////////////////////////////
278/// Delegate to gVirtualX.
279
281{
282 gVirtualX->SetTextFont(tfont);
283}
284
285
286////////////////////////////////////////////////////////////////////////////////
287/// Delegate to gVirtualX.
288
290{
291 gVirtualX->SetTextSize(tsize);
292}
293
294
295////////////////////////////////////////////////////////////////////////////////
296/// Delegate to gVirtualX.
297
299{
300 gVirtualX->SetTextSizePixels(npixels);
301}
302
303
304////////////////////////////////////////////////////////////////////////////////
305/// Delegate to gVirtualX.
306
308{
309 return gVirtualX->GetMarkerColor();
310}
311
312
313////////////////////////////////////////////////////////////////////////////////
314/// Delegate to gVirtualX.
315
317{
318 return gVirtualX->GetMarkerStyle();
319}
320
321
322////////////////////////////////////////////////////////////////////////////////
323/// Delegate to gVirtualX.
324
326{
327 return gVirtualX->GetMarkerSize();
328}
329
330
331////////////////////////////////////////////////////////////////////////////////
332/// Delegate to gVirtualX.
333
335{
336 gVirtualX->SetMarkerColor(mcolor);
337}
338
339
340////////////////////////////////////////////////////////////////////////////////
341/// Delegate to gVirtualX.
342
344{
345 gVirtualX->SetMarkerStyle(mstyle);
346}
347
348
349////////////////////////////////////////////////////////////////////////////////
350/// Delegate to gVirtualX.
351
353{
354 gVirtualX->SetMarkerSize(msize);
355}
356
357
358////////////////////////////////////////////////////////////////////////////////
359/// Create a gVirtualX Pixmap.
360
362{
363 return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Resize a gVirtualX Pixmap.
368
370{
371 return gVirtualX->ResizePixmap(device, w, h);
372}
373
374
375////////////////////////////////////////////////////////////////////////////////
376/// Returns true when cocoa backend is used
377
379{
380 return gVirtualX->InheritsFrom("TGCocoa");
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Returns true if trasnparent colors are supported
385
387{
388 return gVirtualX->InheritsFrom("TGQuartz");
389}
390
391////////////////////////////////////////////////////////////////////////////////
392/// Clear the current gVirtualX window.
393
395{
396 gVirtualX->ClearWindowW(fWinContext);
397}
398
399////////////////////////////////////////////////////////////////////////////////
400/// Copy a gVirtualX pixmap.
401
403{
404 gVirtualX->CopyPixmap(device, px, py);
405}
406
407
408////////////////////////////////////////////////////////////////////////////////
409/// Close the current gVirtualX pixmap.
410
412{
413 gVirtualX->SelectWindow(device);
414 gVirtualX->ClosePixmap();
416}
417
418
419////////////////////////////////////////////////////////////////////////////////
420/// Select the window in which the graphics will go.
421
423{
424 gVirtualX->SelectWindow(device);
425 fWinContext = gVirtualX->GetWindowContext(device);
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Call low-level update of selected drawable, redirect to gVirtualX.
430
432{
433 gVirtualX->UpdateWindowW(fWinContext, mode);
434}
435
436////////////////////////////////////////////////////////////////////////////////
437/// Set drawing mode for specified device
438
440{
441 gVirtualX->SetDrawModeW(gVirtualX->GetWindowContext(device), (TVirtualX::EDrawMode) mode);
442}
443
444////////////////////////////////////////////////////////////////////////////////
445///Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
446
447void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
448 Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
449{
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Set fill attributes
454
456{
457 fSetFillStyle = att.GetFillStyle();
458 gVirtualX->SetAttFill(fWinContext, att);
459}
460
461////////////////////////////////////////////////////////////////////////////////
462/// Set line attributes
463
465{
466 fSetLineWidth = att.GetLineWidth();
467 gVirtualX->SetAttLine(fWinContext, att);
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// Set marker attributes
472
474{
475 gVirtualX->SetAttMarker(fWinContext, att);
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Set text attributes
480
482{
483 gVirtualX->SetAttText(fWinContext, att);
484}
485
486////////////////////////////////////////////////////////////////////////////////
487/// Paint a simple line.
488
490{
491 if (fSetLineWidth <= 0)
492 return;
493
494 const Int_t px1 = gPad->XtoPixel(x1);
495 const Int_t px2 = gPad->XtoPixel(x2);
496 const Int_t py1 = gPad->YtoPixel(y1);
497 const Int_t py2 = gPad->YtoPixel(y2);
498 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
499}
500
501
502////////////////////////////////////////////////////////////////////////////////
503/// Paint a simple line in normalized coordinates.
504
506{
507 if (fSetLineWidth <= 0)
508 return;
509
510 const Int_t px1 = gPad->UtoPixel(u1);
511 const Int_t py1 = gPad->VtoPixel(v1);
512 const Int_t px2 = gPad->UtoPixel(u2);
513 const Int_t py2 = gPad->VtoPixel(v2);
514 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
515}
516
517
518////////////////////////////////////////////////////////////////////////////////
519/// Paint a simple box.
520
522{
524 return;
525
526 Int_t px1 = gPad->XtoPixel(x1);
527 Int_t px2 = gPad->XtoPixel(x2);
528 Int_t py1 = gPad->YtoPixel(y1);
529 Int_t py2 = gPad->YtoPixel(y2);
530
531 // Box width must be at least one pixel (WTF is this code???)
532 if (TMath::Abs(px2 - px1) < 1)
533 px2 = px1 + 1;
534 if (TMath::Abs(py1 - py2) < 1)
535 py1 = py2 + 1;
536
537 gVirtualX->DrawBoxW(fWinContext, px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
538}
539
540////////////////////////////////////////////////////////////////////////////////
541/// Paint filled area.
542
544{
545 if (nPoints < 3) {
546 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
547 return;
548 }
549
551}
552
553
554////////////////////////////////////////////////////////////////////////////////
555/// Paint filled area.
556
558{
559 if (nPoints < 3) {
560 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
561 return;
562 }
563
565}
566
567////////////////////////////////////////////////////////////////////////////////
568/// Paint Polyline.
569
571{
572 if (fSetLineWidth <= 0)
573 return;
574
575 if (n < 2) {
576 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
577 return;
578 }
579
581}
582
583
584////////////////////////////////////////////////////////////////////////////////
585/// Paint polyline.
586
588{
589 if (fSetLineWidth <= 0)
590 return;
591
592 if (n < 2) {
593 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
594 return;
595 }
596
598}
599
600
601////////////////////////////////////////////////////////////////////////////////
602/// Paint polyline in normalized coordinates.
603
605{
606 if (fSetLineWidth <= 0)
607 return;
608
609 if (n < 2) {
610 ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
611 return;
612 }
613
614 std::vector<TPoint> xy(n);
615
616 for (Int_t i = 0; i < n; ++i) {
617 xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
618 xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
619 }
620
621 gVirtualX->DrawPolyLineW(fWinContext, n, &xy[0]);
622}
623
624////////////////////////////////////////////////////////////////////////////////
625/// Paint N segments on the pad
626
628{
629 if (fSetLineWidth <= 0)
630 return;
631
632 if (n < 1) {
633 ::Error("TPadPainter::DrawSegments", "invalid number of segments %d", n);
634 return;
635 }
636
637 std::vector<TPoint> xy(n*2);
638 Int_t cnt = 0;
639 for (Int_t i = 0; i < n*2; ++i) {
640 if ((i % 2 == 0) && (x[i] == x[i+1]) && (y[i] == y[i+1])) {
641 // exclude empty segment
642 i++;
643 continue;
644 }
645
646 xy[cnt].fX = (SCoord_t)gPad->XtoPixel(x[i]);
647 xy[cnt].fY = (SCoord_t)gPad->YtoPixel(y[i]);
648 cnt++;
649 }
650
651 if (cnt > 1)
652 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
653}
654
655////////////////////////////////////////////////////////////////////////////////
656/// Paint N segments in normalized coordinates on the pad
657
659{
660 if (fSetLineWidth <= 0)
661 return;
662
663 if (n < 1) {
664 ::Error("TPadPainter::DrawSegmentsNDC", "invalid number of segments %d", n);
665 return;
666 }
667
668 std::vector<TPoint> xy(n*2);
669 Int_t cnt = 0;
670 for (Int_t i = 0; i < n*2; ++i) {
671 if ((i % 2 == 0) && (u[i] == u[i+1]) && (v[i] == v[i+1])) {
672 // exclude empty segment
673 i++;
674 continue;
675 }
676
677 xy[cnt].fX = (SCoord_t)gPad->UtoPixel(u[i]);
678 xy[cnt].fY = (SCoord_t)gPad->VtoPixel(v[i]);
679 cnt++;
680 }
681
682 if (cnt > 1)
683 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
684}
685
686
687
688////////////////////////////////////////////////////////////////////////////////
689/// Paint polymarker.
690
692{
693 if (n < 1) {
694 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
695 return;
696 }
697
699}
700
701
702////////////////////////////////////////////////////////////////////////////////
703/// Paint polymarker.
704
706{
707 if (n < 1) {
708 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
709 return;
710 }
711
713}
714
715
716////////////////////////////////////////////////////////////////////////////////
717/// Paint text.
718
720{
721 const Int_t px = gPad->XtoPixel(x);
722 const Int_t py = gPad->YtoPixel(y);
723 const Double_t angle = GetTextAngle();
724 const Double_t mgn = GetTextMagnitude();
726}
727
728
729////////////////////////////////////////////////////////////////////////////////
730/// Special version working with wchar_t and required by TMathText.
731
733{
734 const Int_t px = gPad->XtoPixel(x);
735 const Int_t py = gPad->YtoPixel(y);
736 const Double_t angle = GetTextAngle();
737 const Double_t mgn = GetTextMagnitude();
739}
740
741
742////////////////////////////////////////////////////////////////////////////////
743/// Paint text in normalized coordinates.
744
746{
747 const Int_t px = gPad->UtoPixel(u);
748 const Int_t py = gPad->VtoPixel(v);
749 const Double_t angle = GetTextAngle();
750 const Double_t mgn = GetTextMagnitude();
752}
753
754
755////////////////////////////////////////////////////////////////////////////////
756/// Save the image displayed in the canvas pointed by "pad" into a binary file.
757
758void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
759{
760 if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
761 pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
762
763 TCanvas * const canvas = pad->GetCanvas();
764 //Force TCanvas::CopyPixmaps.
765 canvas->Flush();
766
767 const UInt_t w = canvas->GetWw();
768 const UInt_t h = canvas->GetWh();
769
770 const std::unique_ptr<unsigned char[]>
771 pixelData(gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h));
772
773 if (pixelData.get()) {
774 const std::unique_ptr<TImage> image(TImage::Create());
775 if (image.get()) {
776 image->DrawRectangle(0, 0, w, h);
777 if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
778 //Ohhh.
779 if (sizeof(UInt_t) == 4) {
780 //For sure the data returned from TGCocoa::GetColorBits,
781 //it's 4 * w * h bytes with what TASImage considers to be argb.
782 std::copy(pixelData.get(), pixelData.get() + 4 * w * h, argb);
783 } else {
784 //A bit paranoid, don't you think so?
785 //Will Quartz/TASImage work at all on such a fancy platform? ;)
786 const unsigned shift = std::numeric_limits<unsigned char>::digits;
787 //
788 unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
789 const unsigned char *srcPixel = pixelData.get();
790 for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
791 //Looks fishy but should work, trust me :)
792 *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
793 (srcPixel[2] << 2 * shift) &
794 (srcPixel[3] << 3 * shift);
795 }
796 }
797
798 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
799 //Success.
800 return;
801 }
802 }
803 }
804 }
805
806 if (type == TImage::kGif) {
807 gVirtualX->WriteGIF((char*)fileName);
808 } else {
809 const std::unique_ptr<TImage> img(TImage::Create());
810 if (img.get()) {
811 img->FromPad(pad);
812 img->WriteImage(fileName, (TImage::EImageFileTypes)type);
813 }
814 }
815}
816
817
818////////////////////////////////////////////////////////////////////////////////
819/// Paint text in normalized coordinates.
820
822{
823 const Int_t px = gPad->UtoPixel(u);
824 const Int_t py = gPad->VtoPixel(v);
825 const Double_t angle = GetTextAngle();
826 const Double_t mgn = GetTextMagnitude();
828}
829
830//Aux. private functions.
831namespace {
832
833////////////////////////////////////////////////////////////////////////////////
834///I'm using 'pad' pointer to get rid of this damned gPad.
835///Unfortunately, TPadPainter itself still has to use it.
836///But at least this code does not have to be fixed.
837
838template<typename T>
839void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
840 std::vector<TPoint> &dst)
841{
842 if (!nPoints)
843 return;
844
845 dst.resize(nPoints);
846
847 for (unsigned i = 0; i < nPoints; ++i) {
848 dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]);
849 dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]);
850 }
851}
852
853////////////////////////////////////////////////////////////////////////////////
854
855inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
857{
858 const auto firstPointX = points.back().fX;
859 const auto firstPointY = points.back().fY;
860
861 if (nMerged == 2) {
862 points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
863 } else if (nMerged == 3) {
864 yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
865 points.push_back(TPoint(firstPointX, yMin));
866 points.push_back(TPoint(firstPointX, yLast));
867 } else {
868 points.push_back(TPoint(firstPointX, yMin));
869 points.push_back(TPoint(firstPointX, yMax));
870 points.push_back(TPoint(firstPointX, yLast));
871 }
872}
873
874////////////////////////////////////////////////////////////////////////////////
875///Indices below are _valid_.
876
877inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
878 SCoord_t xMax, SCoord_t xLast, size_type first)
879{
880 const TPoint &firstPoint = dst[first];//This point is never updated.
881
882 if (nMerged == 2) {
883 dst[first + 1].fX = xLast;
884 dst[first + 1].fY = firstPoint.fY;
885 } else if (nMerged == 3) {
886 dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
887 dst[first + 1].fY = firstPoint.fY;
888 dst[first + 2].fX = xLast;
889 dst[first + 2].fY = firstPoint.fY;
890 } else {
891 dst[first + 1].fX = xMin;
892 dst[first + 1].fY = firstPoint.fY;
893 dst[first + 2].fX = xMax;
894 dst[first + 2].fY = firstPoint.fY;
895 dst[first + 3].fX = xLast;
896 dst[first + 3].fY = firstPoint.fY;
897 nMerged = 4;//Adjust the shift.
898 }
899
900 return nMerged;
901}
902
903////////////////////////////////////////////////////////////////////////////////
904/// I'm using 'pad' pointer to get rid of this damned gPad.
905/// Unfortunately, TPadPainter itself still has to use it.
906/// But at least this code does not have to be fixed.
907
908template<typename T>
909void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
910 std::vector<TPoint> &dst)
911{
912 //The "first" pass along X axis.
914 SCoord_t yMin = 0, yMax = 0, yLast = 0;
915 unsigned nMerged = 0;
916
917 //The first pass along X.
918 for (unsigned i = 0; i < nPoints;) {
919 currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
920 currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
921
922 yMin = currentPoint.fY;
923 yMax = yMin;
924
925 dst.push_back(currentPoint);
926 bool merged = false;
927 nMerged = 1;
928
929 for (unsigned j = i + 1; j < nPoints; ++j) {
930 const SCoord_t newX = pad->XtoPixel(x[j]);
931
932 if (newX == currentPoint.fX) {
933 yLast = pad->YtoPixel(y[j]);
935 yMax = TMath::Max(yMax, yLast);//We continue.
936 ++nMerged;
937 } else {
938 if (nMerged > 1)
940 merged = true;
941 break;
942 }
943 }
944
945 if (!merged && nMerged > 1)
947
948 i += nMerged;
949 }
950}
951
952////////////////////////////////////////////////////////////////////////////////
953/// This pass is a bit more complicated, since we have to 'compact' in-place.
954
955void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
956{
957 size_type i = 0;
958 for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
959 //i is always less than j, so i is always valid here.
960 const TPoint &currentPoint = dst[i];
961
964 SCoord_t xLast = 0;
965
966 bool merged = false;
967 size_type nMerged = 1;
968
969 for (; j < nPoints; ++j) {
970 const TPoint &nextPoint = dst[j];
971
972 if (nextPoint.fY == currentPoint.fY) {
973 xLast = nextPoint.fX;
976 ++nMerged;//and we continue ...
977 } else {
978 if (nMerged > 1)
980 merged = true;
981 break;
982 }
983 }
984
985 if (!merged && nMerged > 1)
987
988 i += nMerged;
989
990 if (j < nPoints) {
991 dst[i] = dst[j];
992 ++j;
993 } else
994 break;
995 }
996
997 dst.resize(i);
998}
999
1000////////////////////////////////////////////////////////////////////////////////
1001/// This is a quite simple algorithm, using the fact, that after conversion many
1002/// subsequent vertices can have the same 'x' or 'y' coordinate and this part of
1003/// a polygon will look like a line on the screen.
1004
1005template<typename T>
1006void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
1007 const T *y, std::vector<TPoint> &dst)
1008{
1009 //I'm using 'pad' pointer to get rid of this damned gPad.
1010 //Unfortunately, TPadPainter itself still has to use it.
1011 //But at least this code does not have to be fixed.
1012
1013 if (!nPoints)
1014 return;
1015
1016 dst.clear();
1017 dst.reserve(threshold);
1018
1020
1021 if (dst.size() < threshold)
1022 return;
1023
1025}
1026
1027////////////////////////////////////////////////////////////////////////////////
1028
1029template<class T>
1031{
1032 std::vector<TPoint> xy;
1033
1034 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
1035 pad->GetWh() * pad->GetAbsHNDC())) * 2;
1036
1037 if (threshold <= 0) {
1038 //Ooops, pad is invisible or something really bad and stupid happened.
1039 ::Error("DrawFillAreaAux", "invalid pad's geometry");
1040 return;
1041 }
1042
1043 if (nPoints < threshold)
1045 else
1047
1048 //We close the 'polygon' and it'll be rendered as a polyline by gVirtualX.
1049 if (close_path)
1050 xy.push_back(xy.front());
1051
1052 if (xy.size() > 2)
1053 gVirtualX->DrawFillAreaW(cont, xy.size(), &xy[0]);
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057
1058template<typename T>
1059void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys)
1060{
1061 std::vector<TPoint> xy;
1062
1063 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
1064 pad->GetWh() * pad->GetAbsHNDC())) * 2;
1065
1066 if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened.
1067 ::Error("DrawPolyLineAux", "invalid pad's geometry");
1068 return;
1069 }
1070
1071 if (nPoints < (unsigned)threshold)
1073 else
1075
1076 if (xy.size() > 1)
1077 gVirtualX->DrawPolyLineW(cont, xy.size(), &xy[0]);
1078
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082
1083template<class T>
1084void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys)
1085{
1086 std::vector<TPoint> xy(nPoints);
1087
1088 for (unsigned i = 0; i < nPoints; ++i) {
1089 xy[i].fX = (SCoord_t)pad->XtoPixel(xs[i]);
1090 xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]);
1091 }
1092
1093 gVirtualX->DrawPolyMarkerW(cont, nPoints, &xy[0]);
1094}
1095
1096}
Handle_t WinContext_t
Window drawing context.
Definition GuiTypes.h:30
#define h(i)
Definition RSha256.hxx:106
short Style_t
Style number (short)
Definition RtypesCore.h:96
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
float Size_t
Attribute size (float)
Definition RtypesCore.h:103
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:365
Fill Area Attributes class.
Definition TAttFill.h:21
Line Attributes class.
Definition TAttLine.h:21
Marker Attributes class.
Definition TAttMarker.h:21
Text Attributes class.
Definition TAttText.h:21
The Canvas class.
Definition TCanvas.h:23
Int_t GetCanvasID() const override
Definition TCanvas.h:159
UInt_t GetWw() const override
Definition TCanvas.h:165
UInt_t GetWh() const override
Definition TCanvas.h:166
void Flush()
Flush canvas buffers.
Definition TCanvas.cxx:1141
EImageFileTypes
Definition TImage.h:36
@ kGif
Definition TImage.h:48
static TImage * Create()
Create an image.
Definition TImage.cxx:34
void DrawSegments(Int_t n, Double_t *x, Double_t *y) override
Paint N segments on the pad.
Size_t GetMarkerSize() const override
Delegate to gVirtualX.
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.
void SetAttText(const TAttText &att) override
Set text attributes.
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.
Style_t GetMarkerStyle() const override
Delegate to gVirtualX.
Float_t GetTextAngle() const override
Delegate to gVirtualX.
void UpdateDrawable(Int_t mode) override
Call low-level update of selected drawable, redirect 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.
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
Style_t fSetFillStyle
remember set fill style to optimize painting
Definition TPadPainter.h:30
Int_t fSetLineWidth
remember set width to optimize some painting
Definition TPadPainter.h:29
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.
Int_t ResizeDrawable(Int_t device, UInt_t w, UInt_t h) override
Resize a gVirtualX Pixmap.
Float_t GetTextMagnitude() const override
Delegate to gVirtualX.
void SetMarkerColor(Color_t mcolor) override
Delegate to gVirtualX.
Bool_t IsSupportAlpha() const override
Returns true if trasnparent colors are supported.
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 SetMarkerSize(Size_t msize) override
Delegate to gVirtualX.
void SetAttFill(const TAttFill &att) override
Set fill attributes.
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.
Bool_t IsCocoa() const override
Returns true when cocoa backend is used.
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 SetMarkerStyle(Style_t mstyle) override
Delegate to gVirtualX.
void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) override
Paint polyline in normalized coordinates.
void SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void ClearDrawable() override
Clear the current gVirtualX window.
void DestroyDrawable(Int_t device) override
Close the current gVirtualX pixmap.
WinContext_t fWinContext
Definition TPadPainter.h:28
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 DrawSegmentsNDC(Int_t n, Double_t *u, Double_t *v) override
Paint N segments in normalized coordinates on the pad.
void SetAttLine(const TAttLine &att) override
Set line attributes.
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.
Color_t GetMarkerColor() const override
Delegate to gVirtualX.
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