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
76
77/*
78Line/fill/etc. attributes can be set inside TPad, but not only where:
79many of them are set by base sub-objects of 2d primitives
80(2d primitives usually inherit TAttLine or TAttFill etc.). And these sub-objects
81call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
82it will be mess - at any moment I do not know, where to take line attribute - from
83gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
84*/
85
86
87////////////////////////////////////////////////////////////////////////////////
88/// Delegate to gVirtualX.
89
94
95////////////////////////////////////////////////////////////////////////////////
96/// Delegate to gVirtualX.
97
99{
100 return gVirtualX->GetTextMagnitude();
101}
102
103////////////////////////////////////////////////////////////////////////////////
104/// Create a gVirtualX Pixmap.
105
107{
108 return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Resize a gVirtualX Pixmap.
113
115{
116 return gVirtualX->ResizePixmap(device, w, h);
117}
118
119
120////////////////////////////////////////////////////////////////////////////////
121/// Returns true when cocoa backend is used
122
124{
125 return gVirtualX->InheritsFrom("TGCocoa");
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Returns true if trasnparent colors are supported
130
132{
133 return gVirtualX->InheritsFrom("TGQuartz");
134}
135
136////////////////////////////////////////////////////////////////////////////////
137/// Clear the current gVirtualX window.
138
140{
141 gVirtualX->ClearWindowW(fWinContext);
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Copy a gVirtualX pixmap.
146
148{
149 gVirtualX->CopyPixmapW(fWinContext, device, px, py);
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// Close the current gVirtualX pixmap.
154
156{
157 gVirtualX->SelectWindow(device);
158 gVirtualX->ClosePixmap();
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Select the window in which the graphics will go.
164
166{
167 gVirtualX->SelectWindow(device);
168 fWinContext = gVirtualX->GetWindowContext(device);
169}
170
171////////////////////////////////////////////////////////////////////////////////
172/// Call low-level update of selected drawable, redirect to gVirtualX.
173
175{
176 gVirtualX->UpdateWindowW(fWinContext, mode);
177}
178
179////////////////////////////////////////////////////////////////////////////////
180/// Set drawing mode for specified device
181
183{
184 gVirtualX->SetDrawModeW(gVirtualX->GetWindowContext(device), (TVirtualX::EDrawMode) mode);
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Set double buffer mode for specified device
189
191{
192 // important flag - when disabled canvas pixmap used directly
193 // so one need to use absolute coordinates
195
196 gVirtualX->SetDoubleBuffer(device, mode);
197}
198
199////////////////////////////////////////////////////////////////////////////////
200///Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
201
202void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
203 Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
204{
205}
206
207////////////////////////////////////////////////////////////////////////////////
208/// Set fill attributes
209
211{
213
215
216 gVirtualX->SetAttFill(fWinContext, fill);
217}
218
219////////////////////////////////////////////////////////////////////////////////
220/// Set line attributes
221
228
229////////////////////////////////////////////////////////////////////////////////
230/// Set marker attributes
231
238
239////////////////////////////////////////////////////////////////////////////////
240/// Set text attributes
241
248
249////////////////////////////////////////////////////////////////////////////////
250/// Paint a simple line.
251
253{
254 if (fAttLine.GetLineWidth() <= 0)
255 return;
256
257 const Int_t px1 = fDoubleBuffer ? gPad->XtoPixel(x1) : gPad->XtoAbsPixel(x1);
258 const Int_t px2 = fDoubleBuffer ? gPad->XtoPixel(x2) : gPad->XtoAbsPixel(x2);
259 const Int_t py1 = fDoubleBuffer ? gPad->YtoPixel(y1) : gPad->YtoAbsPixel(y1);
260 const Int_t py2 = fDoubleBuffer ? gPad->YtoPixel(y2) : gPad->YtoAbsPixel(y2);
261 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
262}
263
264
265////////////////////////////////////////////////////////////////////////////////
266/// Paint a simple line in normalized coordinates.
267
269{
270 if (fAttLine.GetLineWidth() <= 0)
271 return;
272
273 const Int_t px1 = fDoubleBuffer ? gPad->UtoPixel(u1) : gPad->UtoAbsPixel(u1);
274 const Int_t py1 = fDoubleBuffer ? gPad->VtoPixel(v1) : gPad->VtoAbsPixel(v1);
275 const Int_t px2 = fDoubleBuffer ? gPad->UtoPixel(u2) : gPad->UtoAbsPixel(u2);
276 const Int_t py2 = fDoubleBuffer ? gPad->VtoPixel(v2) : gPad->VtoAbsPixel(v2);
277 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
278}
279
280
281////////////////////////////////////////////////////////////////////////////////
282/// Paint a simple box.
283
285{
287 return;
288
290 return;
291
292 Int_t px1 = fDoubleBuffer ? gPad->XtoPixel(x1) : gPad->XtoAbsPixel(x1);
293 Int_t px2 = fDoubleBuffer ? gPad->XtoPixel(x2) : gPad->XtoAbsPixel(x2);
294 Int_t py1 = fDoubleBuffer ? gPad->YtoPixel(y1) : gPad->YtoAbsPixel(y1);
295 Int_t py2 = fDoubleBuffer ? gPad->YtoPixel(y2) : gPad->YtoAbsPixel(y2);
296
297 // Box width must be at least one pixel (WTF is this code???)
298 if (TMath::Abs(px2 - px1) < 1)
299 px2 = px1 + 1;
300 if (TMath::Abs(py1 - py2) < 1)
301 py1 = py2 + 1;
302
303 gVirtualX->DrawBoxW(fWinContext, px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// Paint filled area.
308
310{
311 if (nPoints < 3) {
312 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
313 return;
314 }
315
316 // if fully transparent, add first point to draw line
318}
319
320
321////////////////////////////////////////////////////////////////////////////////
322/// Paint filled area.
323
325{
326 if (nPoints < 3) {
327 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
328 return;
329 }
330
331 // if fully transparent, add first point to draw line
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Paint Polyline.
337
339{
340 if (fAttLine.GetLineWidth() <= 0)
341 return;
342
343 if (n < 2) {
344 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
345 return;
346 }
347
349}
350
351
352////////////////////////////////////////////////////////////////////////////////
353/// Paint polyline.
354
356{
357 if (fAttLine.GetLineWidth() <= 0)
358 return;
359
360 if (n < 2) {
361 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
362 return;
363 }
364
366}
367
368
369////////////////////////////////////////////////////////////////////////////////
370/// Paint polyline in normalized coordinates.
371
373{
374 if (fAttLine.GetLineWidth() <= 0)
375 return;
376
377 if (n < 2) {
378 ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
379 return;
380 }
381
382 std::vector<TPoint> xy(n);
383
384 for (Int_t i = 0; i < n; ++i) {
385 xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
386 xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
387 }
388
389 gVirtualX->DrawPolyLineW(fWinContext, n, &xy[0]);
390}
391
392////////////////////////////////////////////////////////////////////////////////
393/// Paint N segments on the pad
394
396{
397 if (fAttLine.GetLineWidth() <= 0)
398 return;
399
400 if (n < 1) {
401 ::Error("TPadPainter::DrawSegments", "invalid number of segments %d", n);
402 return;
403 }
404
405 std::vector<TPoint> xy(n*2);
406 Int_t cnt = 0;
407 for (Int_t i = 0; i < n*2; ++i) {
408 if ((i % 2 == 0) && (x[i] == x[i+1]) && (y[i] == y[i+1])) {
409 // exclude empty segment
410 i++;
411 continue;
412 }
413
414 xy[cnt].fX = (SCoord_t)gPad->XtoPixel(x[i]);
415 xy[cnt].fY = (SCoord_t)gPad->YtoPixel(y[i]);
416 cnt++;
417 }
418
419 if (cnt > 1)
420 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
421}
422
423////////////////////////////////////////////////////////////////////////////////
424/// Paint N segments in normalized coordinates on the pad
425
427{
428 if (fAttLine.GetLineWidth() <= 0)
429 return;
430
431 if (n < 1) {
432 ::Error("TPadPainter::DrawSegmentsNDC", "invalid number of segments %d", n);
433 return;
434 }
435
436 std::vector<TPoint> xy(n*2);
437 Int_t cnt = 0;
438 for (Int_t i = 0; i < n*2; ++i) {
439 if ((i % 2 == 0) && (u[i] == u[i+1]) && (v[i] == v[i+1])) {
440 // exclude empty segment
441 i++;
442 continue;
443 }
444
445 xy[cnt].fX = (SCoord_t)gPad->UtoPixel(u[i]);
446 xy[cnt].fY = (SCoord_t)gPad->VtoPixel(v[i]);
447 cnt++;
448 }
449
450 if (cnt > 1)
451 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
452}
453
454
455
456////////////////////////////////////////////////////////////////////////////////
457/// Paint polymarker.
458
460{
461 if (n < 1) {
462 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
463 return;
464 }
465
467}
468
469
470////////////////////////////////////////////////////////////////////////////////
471/// Paint polymarker.
472
474{
475 if (n < 1) {
476 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
477 return;
478 }
479
481}
482
483
484////////////////////////////////////////////////////////////////////////////////
485/// Paint text.
486
488{
489 const Int_t px = gPad->XtoPixel(x);
490 const Int_t py = gPad->YtoPixel(y);
491 const Double_t angle = GetTextAngle();
492 const Double_t mgn = GetTextMagnitude();
494}
495
496
497////////////////////////////////////////////////////////////////////////////////
498/// Special version working with wchar_t and required by TMathText.
499
501{
502 const Int_t px = gPad->XtoPixel(x);
503 const Int_t py = gPad->YtoPixel(y);
504 const Double_t angle = GetTextAngle();
505 const Double_t mgn = GetTextMagnitude();
507}
508
509
510////////////////////////////////////////////////////////////////////////////////
511/// Paint text in normalized coordinates.
512
514{
515 const Int_t px = gPad->UtoPixel(u);
516 const Int_t py = gPad->VtoPixel(v);
517 const Double_t angle = GetTextAngle();
518 const Double_t mgn = GetTextMagnitude();
520}
521
522
523////////////////////////////////////////////////////////////////////////////////
524/// Save the image displayed in the canvas pointed by "pad" into a binary file.
525
526void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
527{
528 if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
529 pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
530
531 TCanvas * const canvas = pad->GetCanvas();
532 //Force TCanvas::CopyPixmaps.
533 canvas->Flush();
534
535 const UInt_t w = canvas->GetWw();
536 const UInt_t h = canvas->GetWh();
537
538 const std::unique_ptr<unsigned char[]>
539 pixelData(gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h));
540
541 if (pixelData.get()) {
542 const std::unique_ptr<TImage> image(TImage::Create());
543 if (image.get()) {
544 image->DrawRectangle(0, 0, w, h);
545 if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
546 //Ohhh.
547 if (sizeof(UInt_t) == 4) {
548 //For sure the data returned from TGCocoa::GetColorBits,
549 //it's 4 * w * h bytes with what TASImage considers to be argb.
550 std::copy(pixelData.get(), pixelData.get() + 4 * w * h, argb);
551 } else {
552 //A bit paranoid, don't you think so?
553 //Will Quartz/TASImage work at all on such a fancy platform? ;)
554 const unsigned shift = std::numeric_limits<unsigned char>::digits;
555 //
556 unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
557 const unsigned char *srcPixel = pixelData.get();
558 for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
559 //Looks fishy but should work, trust me :)
560 *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
561 (srcPixel[2] << 2 * shift) &
562 (srcPixel[3] << 3 * shift);
563 }
564 }
565
566 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
567 //Success.
568 return;
569 }
570 }
571 }
572 }
573
574 if (type == TImage::kGif) {
575 Int_t wid = (pad == pad->GetCanvas()) ? pad->GetCanvasID() : pad->GetPixmapID();
576 auto ctxt = gVirtualX->GetWindowContext(wid);
577 // TODO: if fail, one can use TImage functionality instead
578 gVirtualX->WriteGIFW(ctxt, fileName);
579 } else {
580 const std::unique_ptr<TImage> img(TImage::Create());
581 if (img.get()) {
582 img->FromPad(pad);
583 img->WriteImage(fileName, (TImage::EImageFileTypes)type);
584 }
585 }
586}
587
588
589////////////////////////////////////////////////////////////////////////////////
590/// Paint text in normalized coordinates.
591
593{
594 const Int_t px = gPad->UtoPixel(u);
595 const Int_t py = gPad->VtoPixel(v);
596 const Double_t angle = GetTextAngle();
597 const Double_t mgn = GetTextMagnitude();
599}
600
601//Aux. private functions.
602namespace {
603
604////////////////////////////////////////////////////////////////////////////////
605///I'm using 'pad' pointer to get rid of this damned gPad.
606///Unfortunately, TPadPainter itself still has to use it.
607///But at least this code does not have to be fixed.
608
609template<typename T>
610void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
611 std::vector<TPoint> &dst)
612{
613 if (!nPoints)
614 return;
615
616 dst.resize(nPoints);
617
618 for (unsigned i = 0; i < nPoints; ++i) {
619 dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]);
620 dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]);
621 }
622}
623
624////////////////////////////////////////////////////////////////////////////////
625
626inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
628{
629 const auto firstPointX = points.back().fX;
630 const auto firstPointY = points.back().fY;
631
632 if (nMerged == 2) {
633 points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
634 } else if (nMerged == 3) {
635 yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
636 points.push_back(TPoint(firstPointX, yMin));
637 points.push_back(TPoint(firstPointX, yLast));
638 } else {
639 points.push_back(TPoint(firstPointX, yMin));
640 points.push_back(TPoint(firstPointX, yMax));
641 points.push_back(TPoint(firstPointX, yLast));
642 }
643}
644
645////////////////////////////////////////////////////////////////////////////////
646///Indices below are _valid_.
647
648inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
649 SCoord_t xMax, SCoord_t xLast, size_type first)
650{
651 const TPoint &firstPoint = dst[first];//This point is never updated.
652
653 if (nMerged == 2) {
654 dst[first + 1].fX = xLast;
655 dst[first + 1].fY = firstPoint.fY;
656 } else if (nMerged == 3) {
657 dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
658 dst[first + 1].fY = firstPoint.fY;
659 dst[first + 2].fX = xLast;
660 dst[first + 2].fY = firstPoint.fY;
661 } else {
662 dst[first + 1].fX = xMin;
663 dst[first + 1].fY = firstPoint.fY;
664 dst[first + 2].fX = xMax;
665 dst[first + 2].fY = firstPoint.fY;
666 dst[first + 3].fX = xLast;
667 dst[first + 3].fY = firstPoint.fY;
668 nMerged = 4;//Adjust the shift.
669 }
670
671 return nMerged;
672}
673
674////////////////////////////////////////////////////////////////////////////////
675/// I'm using 'pad' pointer to get rid of this damned gPad.
676/// Unfortunately, TPadPainter itself still has to use it.
677/// But at least this code does not have to be fixed.
678
679template<typename T>
680void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
681 std::vector<TPoint> &dst)
682{
683 //The "first" pass along X axis.
685 SCoord_t yMin = 0, yMax = 0, yLast = 0;
686 unsigned nMerged = 0;
687
688 //The first pass along X.
689 for (unsigned i = 0; i < nPoints;) {
690 currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
691 currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
692
693 yMin = currentPoint.fY;
694 yMax = yMin;
695
696 dst.push_back(currentPoint);
697 bool merged = false;
698 nMerged = 1;
699
700 for (unsigned j = i + 1; j < nPoints; ++j) {
701 const SCoord_t newX = pad->XtoPixel(x[j]);
702
703 if (newX == currentPoint.fX) {
704 yLast = pad->YtoPixel(y[j]);
706 yMax = TMath::Max(yMax, yLast);//We continue.
707 ++nMerged;
708 } else {
709 if (nMerged > 1)
711 merged = true;
712 break;
713 }
714 }
715
716 if (!merged && nMerged > 1)
718
719 i += nMerged;
720 }
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// This pass is a bit more complicated, since we have to 'compact' in-place.
725
726void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
727{
728 size_type i = 0;
729 for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
730 //i is always less than j, so i is always valid here.
731 const TPoint &currentPoint = dst[i];
732
735 SCoord_t xLast = 0;
736
737 bool merged = false;
738 size_type nMerged = 1;
739
740 for (; j < nPoints; ++j) {
741 const TPoint &nextPoint = dst[j];
742
743 if (nextPoint.fY == currentPoint.fY) {
744 xLast = nextPoint.fX;
747 ++nMerged;//and we continue ...
748 } else {
749 if (nMerged > 1)
751 merged = true;
752 break;
753 }
754 }
755
756 if (!merged && nMerged > 1)
758
759 i += nMerged;
760
761 if (j < nPoints) {
762 dst[i] = dst[j];
763 ++j;
764 } else
765 break;
766 }
767
768 dst.resize(i);
769}
770
771////////////////////////////////////////////////////////////////////////////////
772/// This is a quite simple algorithm, using the fact, that after conversion many
773/// subsequent vertices can have the same 'x' or 'y' coordinate and this part of
774/// a polygon will look like a line on the screen.
775
776template<typename T>
777void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
778 const T *y, std::vector<TPoint> &dst)
779{
780 //I'm using 'pad' pointer to get rid of this damned gPad.
781 //Unfortunately, TPadPainter itself still has to use it.
782 //But at least this code does not have to be fixed.
783
784 if (!nPoints)
785 return;
786
787 dst.clear();
788 dst.reserve(threshold);
789
791
792 if (dst.size() < threshold)
793 return;
794
796}
797
798////////////////////////////////////////////////////////////////////////////////
799
800template<class T>
802{
803 std::vector<TPoint> xy;
804
805 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
806 pad->GetWh() * pad->GetAbsHNDC())) * 2;
807
808 if (threshold <= 0) {
809 //Ooops, pad is invisible or something really bad and stupid happened.
810 ::Error("DrawFillAreaAux", "invalid pad's geometry");
811 return;
812 }
813
814 if (nPoints < threshold)
816 else
818
819 //We close the 'polygon' so it can be rendered as a polyline by gVirtualX.
820 if (add_first_point)
821 xy.push_back(xy.front());
822
823 if (xy.size() > 2)
824 gVirtualX->DrawFillAreaW(cont, xy.size(), xy.data());
825}
826
827////////////////////////////////////////////////////////////////////////////////
828
829template<typename T>
830void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys)
831{
832 std::vector<TPoint> xy;
833
834 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
835 pad->GetWh() * pad->GetAbsHNDC())) * 2;
836
837 if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened.
838 ::Error("DrawPolyLineAux", "invalid pad's geometry");
839 return;
840 }
841
842 if (nPoints < (unsigned)threshold)
844 else
846
847 if (xy.size() > 1)
848 gVirtualX->DrawPolyLineW(cont, xy.size(), &xy[0]);
849
850}
851
852////////////////////////////////////////////////////////////////////////////////
853
854template<class T>
855void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys)
856{
857 std::vector<TPoint> xy(nPoints);
858
859 for (unsigned i = 0; i < nPoints; ++i) {
860 xy[i].fX = (SCoord_t)pad->XtoPixel(xs[i]);
861 xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]);
862 }
863
864 gVirtualX->DrawPolyMarkerW(cont, nPoints, &xy[0]);
865}
866
867}
Handle_t WinContext_t
Window drawing context.
Definition GuiTypes.h:30
#define h(i)
Definition RSha256.hxx:106
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
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
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 TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize wid
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:426
#define gPad
#define gVirtualX
Definition TVirtualX.h:368
Fill Area Attributes class.
Definition TAttFill.h:21
Line Attributes class.
Definition TAttLine.h:21
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
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:161
UInt_t GetWw() const override
Definition TCanvas.h:167
UInt_t GetWh() const override
Definition TCanvas.h:168
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 SetAttFill(const TAttFill &att) override
Set fill attributes.
void SetAttText(const TAttText &att) override
Set text attributes.
TAttLine fAttLine
current line attributes
Bool_t fFullyTransparent
if transformed fill attributes fully transparent
void SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void SetAttLine(const TAttLine &att) override
Set line attributes.
Float_t GetTextAngle() const override
TAttFill GetAttFillInternal(Bool_t with_transparency)
Returns fill attributes after modification Checks for special fill styles 4000 .
void DrawSegments(Int_t n, Double_t *x, Double_t *y) override
Paint N segments on the pad.
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.
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.
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 SetAttMarker(const TAttMarker &att) override
Set marker attributes.
void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) override
Paint Polyline.
Int_t fDoubleBuffer
Definition TPadPainter.h:27
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.
Bool_t IsSupportAlpha() const override
Returns true if trasnparent colors are supported.
Int_t CreateDrawable(UInt_t w, UInt_t h) override
Create a gVirtualX Pixmap.
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 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 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 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:26
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 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.
void SetDoubleBuffer(Int_t device, Int_t mode) override
Set double buffer mode for specified device.
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