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, Bool_t absCoord = kFALSE);
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>
51
52template<typename T>
53void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, Bool_t absCoord, unsigned nPoints, const T *xs, const T *ys);
54
55template<class T>
56void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, Bool_t double_buffer, 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
92
93////////////////////////////////////////////////////////////////////////////////
94/// Delegate to gVirtualX.
95
97{
98 return gVirtualX->GetTextMagnitude();
99}
100
101////////////////////////////////////////////////////////////////////////////////
102/// Create a gVirtualX Pixmap.
103
105{
106 return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
107}
108
109////////////////////////////////////////////////////////////////////////////////
110/// Resize a gVirtualX Pixmap.
111
113{
114 return gVirtualX->ResizePixmap(device, w, h);
115}
116
117
118////////////////////////////////////////////////////////////////////////////////
119/// Returns true when cocoa backend is used
120
122{
123 return gVirtualX->InheritsFrom("TGCocoa");
124}
125
126////////////////////////////////////////////////////////////////////////////////
127/// Returns true if transparent colors are supported
128
130{
131 return gVirtualX->InheritsFrom("TGQuartz");
132}
133
134////////////////////////////////////////////////////////////////////////////////
135/// Clear the current gVirtualX window - calling gVirtualX->ClearWindowW
136
138{
139 if (fWinContext)
140 gVirtualX->ClearWindowW(fWinContext);
141}
142
143////////////////////////////////////////////////////////////////////////////////
144/// Clear specified window - calling gVirtualX->ClearWindowW
145
147{
148 auto ctxt = gVirtualX->GetWindowContext(device);
149 if (ctxt)
150 gVirtualX->ClearWindowW(ctxt);
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Copy a gVirtualX pixmap.
155
157{
158 gVirtualX->CopyPixmapW(fWinContext, device, px, py);
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Close the current gVirtualX pixmap.
163
165{
166 gVirtualX->SelectWindow(device);
167 gVirtualX->ClosePixmap();
169}
170
171////////////////////////////////////////////////////////////////////////////////
172/// Select the window in which the graphics will go.
173
175{
176 gVirtualX->SelectWindow(device);
177 fWinContext = gVirtualX->GetWindowContext(device);
178}
179
180////////////////////////////////////////////////////////////////////////////////
181/// Call low-level update of selected drawable, redirect to gVirtualX.
182
184{
185 gVirtualX->UpdateWindowW(fWinContext, mode);
186}
187
188////////////////////////////////////////////////////////////////////////////////
189/// Set drawing mode for specified device
190
192{
193 gVirtualX->SetDrawModeW(gVirtualX->GetWindowContext(device), (TVirtualX::EDrawMode) mode);
194}
195
196////////////////////////////////////////////////////////////////////////////////
197/// Set double buffer mode for specified device
198
200{
201 // important flag - when disabled canvas pixmap used directly
202 // so one need to use absolute coordinates
204
205 gVirtualX->SetDoubleBuffer(device, mode);
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Return true if TTF font can be used
210
212{
213 return gVirtualX->HasTTFonts();
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Draw image on the gVirtualX window
218
220{
221 Window_t wid = (Window_t)gVirtualX->GetWindowID(fPad->GetPixmapID());
222 // use old API to draw image on gVirtualX window
223 img->PaintImage(wid, x, y, 0, 0, 0, 0, flags ? "" : "opaque");
224}
225
226////////////////////////////////////////////////////////////////////////////////
227///Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
228
229void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
230 Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
231{
232}
233
234////////////////////////////////////////////////////////////////////////////////
235/// Set fill attributes
236
238{
240
242
243 gVirtualX->SetAttFill(fWinContext, fill);
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Set line attributes
248
255
256////////////////////////////////////////////////////////////////////////////////
257/// Set marker attributes
258
265
266////////////////////////////////////////////////////////////////////////////////
267/// Set text attributes
268
270{
272
273 // TODO: in ROOT7 move text size handling directly to correspondent PS engine
274 // One not need to recalculate text size many time back and forth
275
276 if (!fPad)
277 Fatal("SetAttText", "Pad not specified");
278
280 attm.SetTextSize(att.GetTextSizePixels(*fPad));
281
282 gVirtualX->SetAttText(fWinContext, attm);
283}
284
285////////////////////////////////////////////////////////////////////////////////
286/// Paint a simple line.
287
289{
290 if (fAttLine.GetLineWidth() <= 0)
291 return;
292
293 const Int_t px1 = fDoubleBuffer ? gPad->XtoPixel(x1) : gPad->XtoAbsPixel(x1);
294 const Int_t px2 = fDoubleBuffer ? gPad->XtoPixel(x2) : gPad->XtoAbsPixel(x2);
295 const Int_t py1 = fDoubleBuffer ? gPad->YtoPixel(y1) : gPad->YtoAbsPixel(y1);
296 const Int_t py2 = fDoubleBuffer ? gPad->YtoPixel(y2) : gPad->YtoAbsPixel(y2);
297 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
298}
299
300
301////////////////////////////////////////////////////////////////////////////////
302/// Paint a simple line in normalized coordinates.
303
305{
306 if (fAttLine.GetLineWidth() <= 0)
307 return;
308
309 const Int_t px1 = fDoubleBuffer ? gPad->UtoPixel(u1) : gPad->UtoAbsPixel(u1);
310 const Int_t py1 = fDoubleBuffer ? gPad->VtoPixel(v1) : gPad->VtoAbsPixel(v1);
311 const Int_t px2 = fDoubleBuffer ? gPad->UtoPixel(u2) : gPad->UtoAbsPixel(u2);
312 const Int_t py2 = fDoubleBuffer ? gPad->VtoPixel(v2) : gPad->VtoAbsPixel(v2);
313 gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2);
314}
315
316
317////////////////////////////////////////////////////////////////////////////////
318/// Paint a simple box.
319
321{
323 return;
324
326 return;
327
328 Int_t px1 = fDoubleBuffer ? gPad->XtoPixel(x1) : gPad->XtoAbsPixel(x1);
329 Int_t px2 = fDoubleBuffer ? gPad->XtoPixel(x2) : gPad->XtoAbsPixel(x2);
330 Int_t py1 = fDoubleBuffer ? gPad->YtoPixel(y1) : gPad->YtoAbsPixel(y1);
331 Int_t py2 = fDoubleBuffer ? gPad->YtoPixel(y2) : gPad->YtoAbsPixel(y2);
332
333 // Box width must be at least one pixel (WTF is this code???)
334 if (TMath::Abs(px2 - px1) < 1)
335 px2 = px1 + 1;
336 if (TMath::Abs(py1 - py2) < 1)
337 py1 = py2 + 1;
338
339 gVirtualX->DrawBoxW(fWinContext, px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Paint filled area.
344
346{
347 if (nPoints < 3) {
348 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
349 return;
350 }
351
352 // if fully transparent, add first point to draw line
354}
355
356
357////////////////////////////////////////////////////////////////////////////////
358/// Paint filled area.
359
361{
362 if (nPoints < 3) {
363 ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
364 return;
365 }
366
367 // if fully transparent, add first point to draw line
369}
370
371////////////////////////////////////////////////////////////////////////////////
372/// Paint Polyline.
373
375{
376 if (fAttLine.GetLineWidth() <= 0)
377 return;
378
379 if (n < 2) {
380 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
381 return;
382 }
383
385}
386
387
388////////////////////////////////////////////////////////////////////////////////
389/// Paint polyline.
390
392{
393 if (fAttLine.GetLineWidth() <= 0)
394 return;
395
396 if (n < 2) {
397 ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
398 return;
399 }
400
402}
403
404
405////////////////////////////////////////////////////////////////////////////////
406/// Paint polyline in normalized coordinates.
407
409{
410 if (fAttLine.GetLineWidth() <= 0)
411 return;
412
413 if (n < 2) {
414 ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
415 return;
416 }
417
418 std::vector<TPoint> xy(n);
419
420 for (Int_t i = 0; i < n; ++i) {
421 xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
422 xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
423 }
424
425 gVirtualX->DrawPolyLineW(fWinContext, n, &xy[0]);
426}
427
428////////////////////////////////////////////////////////////////////////////////
429/// Paint N segments on the pad
430
432{
433 if (fAttLine.GetLineWidth() <= 0)
434 return;
435
436 if (n < 1) {
437 ::Error("TPadPainter::DrawSegments", "invalid number of segments %d", n);
438 return;
439 }
440
441 std::vector<TPoint> xy(n*2);
442 Int_t cnt = 0;
443 for (Int_t i = 0; i < n*2; ++i) {
444 if ((i % 2 == 0) && (x[i] == x[i+1]) && (y[i] == y[i+1])) {
445 // exclude empty segment
446 i++;
447 continue;
448 }
449
450 xy[cnt].fX = (SCoord_t)gPad->XtoPixel(x[i]);
451 xy[cnt].fY = (SCoord_t)gPad->YtoPixel(y[i]);
452 cnt++;
453 }
454
455 if (cnt > 1)
456 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
457}
458
459////////////////////////////////////////////////////////////////////////////////
460/// Paint N segments in normalized coordinates on the pad
461
463{
464 if (fAttLine.GetLineWidth() <= 0)
465 return;
466
467 if (n < 1) {
468 ::Error("TPadPainter::DrawSegmentsNDC", "invalid number of segments %d", n);
469 return;
470 }
471
472 std::vector<TPoint> xy(n*2);
473 Int_t cnt = 0;
474 for (Int_t i = 0; i < n*2; ++i) {
475 if ((i % 2 == 0) && (u[i] == u[i+1]) && (v[i] == v[i+1])) {
476 // exclude empty segment
477 i++;
478 continue;
479 }
480
481 xy[cnt].fX = (SCoord_t)gPad->UtoPixel(u[i]);
482 xy[cnt].fY = (SCoord_t)gPad->VtoPixel(v[i]);
483 cnt++;
484 }
485
486 if (cnt > 1)
487 gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]);
488}
489
490
491
492////////////////////////////////////////////////////////////////////////////////
493/// Paint polymarker.
494
496{
497 if (n < 1) {
498 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
499 return;
500 }
501
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Paint polymarker.
507
509{
510 if (n < 1) {
511 ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
512 return;
513 }
514
516}
517
518////////////////////////////////////////////////////////////////////////////////
519/// Paint TTF glyps on virtualx device
520
525
526////////////////////////////////////////////////////////////////////////////////
527/// Save the image displayed in the canvas pointed by "pad" into a binary file.
528
529void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
530{
531 if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
532 pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
533
534 TCanvas * const canvas = pad->GetCanvas();
535 //Force TCanvas::CopyPixmaps.
536 canvas->Flush();
537
538 const UInt_t w = canvas->GetWw();
539 const UInt_t h = canvas->GetWh();
540
541 const std::unique_ptr<unsigned char[]>
542 pixelData(gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h));
543
544 if (pixelData.get()) {
545 const std::unique_ptr<TImage> image(TImage::Create());
546 if (image.get()) {
547 image->DrawRectangle(0, 0, w, h);
548 if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
549 //Ohhh.
550 if (sizeof(UInt_t) == 4) {
551 //For sure the data returned from TGCocoa::GetColorBits,
552 //it's 4 * w * h bytes with what TASImage considers to be argb.
553 std::copy(pixelData.get(), pixelData.get() + 4 * w * h, argb);
554 } else {
555 //A bit paranoid, don't you think so?
556 //Will Quartz/TASImage work at all on such a fancy platform? ;)
557 const unsigned shift = std::numeric_limits<unsigned char>::digits;
558 //
559 unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
560 const unsigned char *srcPixel = pixelData.get();
561 for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
562 //Looks fishy but should work, trust me :)
563 *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
564 (srcPixel[2] << 2 * shift) &
565 (srcPixel[3] << 3 * shift);
566 }
567 }
568
569 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
570 //Success.
571 return;
572 }
573 }
574 }
575 }
576
577 if (type == TImage::kGif) {
578 Int_t wid = (pad == pad->GetCanvas()) ? pad->GetCanvasID() : pad->GetPixmapID();
579 auto ctxt = gVirtualX->GetWindowContext(wid);
580 // TODO: if fail, one can use TImage functionality instead
581 gVirtualX->WriteGIFW(ctxt, fileName);
582 } else {
583 const std::unique_ptr<TImage> img(TImage::Create());
584 if (img.get()) {
585 img->FromPad(pad);
586 img->WriteImage(fileName, (TImage::EImageFileTypes)type);
587 }
588 }
589}
590
591
592//Aux. private functions.
593namespace {
594
595////////////////////////////////////////////////////////////////////////////////
596///I'm using 'pad' pointer to get rid of this damned gPad.
597///Unfortunately, TPadPainter itself still has to use it.
598///But at least this code does not have to be fixed.
599
600template<typename T>
601void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
602 std::vector<TPoint> &dst, Bool_t absCoord)
603{
604 if (!nPoints)
605 return;
606
607 dst.resize(nPoints);
608
609 if (absCoord) {
610 for (unsigned i = 0; i < nPoints; ++i) {
611 dst[i].fX = (SCoord_t) pad->XtoAbsPixel(x[i]);
612 dst[i].fY = (SCoord_t) pad->YtoAbsPixel(y[i]);
613 }
614 } else {
615 for (unsigned i = 0; i < nPoints; ++i) {
616 dst[i].fX = (SCoord_t) pad->XtoPixel(x[i]);
617 dst[i].fY = (SCoord_t) pad->YtoPixel(y[i]);
618 }
619 }
620}
621
622////////////////////////////////////////////////////////////////////////////////
623
624inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
625 SCoord_t yMax, SCoord_t yLast)
626{
627 const auto firstPointX = points.back().fX;
628 const auto firstPointY = points.back().fY;
629
630 if (nMerged == 2) {
631 points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
632 } else if (nMerged == 3) {
633 yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
634 points.push_back(TPoint(firstPointX, yMin));
635 points.push_back(TPoint(firstPointX, yLast));
636 } else {
637 points.push_back(TPoint(firstPointX, yMin));
638 points.push_back(TPoint(firstPointX, yMax));
639 points.push_back(TPoint(firstPointX, yLast));
640 }
641}
642
643////////////////////////////////////////////////////////////////////////////////
644///Indices below are _valid_.
645
646inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
647 SCoord_t xMax, SCoord_t xLast, size_type first)
648{
649 const TPoint &firstPoint = dst[first];//This point is never updated.
650
651 if (nMerged == 2) {
652 dst[first + 1].fX = xLast;
653 dst[first + 1].fY = firstPoint.fY;
654 } else if (nMerged == 3) {
655 dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
656 dst[first + 1].fY = firstPoint.fY;
657 dst[first + 2].fX = xLast;
658 dst[first + 2].fY = firstPoint.fY;
659 } else {
660 dst[first + 1].fX = xMin;
661 dst[first + 1].fY = firstPoint.fY;
662 dst[first + 2].fX = xMax;
663 dst[first + 2].fY = firstPoint.fY;
664 dst[first + 3].fX = xLast;
665 dst[first + 3].fY = firstPoint.fY;
666 nMerged = 4;//Adjust the shift.
667 }
668
669 return nMerged;
670}
671
672////////////////////////////////////////////////////////////////////////////////
673/// I'm using 'pad' pointer to get rid of this damned gPad.
674/// Unfortunately, TPadPainter itself still has to use it.
675/// But at least this code does not have to be fixed.
676
677template<typename T>
678void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
679 std::vector<TPoint> &dst)
680{
681 //The "first" pass along X axis.
683 SCoord_t yMin = 0, yMax = 0, yLast = 0;
684 unsigned nMerged = 0;
685
686 //The first pass along X.
687 for (unsigned i = 0; i < nPoints;) {
688 currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
689 currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
690
691 yMin = currentPoint.fY;
692 yMax = yMin;
693
694 dst.push_back(currentPoint);
695 bool merged = false;
696 nMerged = 1;
697
698 for (unsigned j = i + 1; j < nPoints; ++j) {
699 const SCoord_t newX = pad->XtoPixel(x[j]);
700
701 if (newX == currentPoint.fX) {
702 yLast = pad->YtoPixel(y[j]);
703 yMin = TMath::Min(yMin, yLast);
704 yMax = TMath::Max(yMax, yLast);//We continue.
705 ++nMerged;
706 } else {
707 if (nMerged > 1)
708 MergePointsX(dst, nMerged, yMin, yMax, yLast);
709 merged = true;
710 break;
711 }
712 }
713
714 if (!merged && nMerged > 1)
715 MergePointsX(dst, nMerged, yMin, yMax, yLast);
716
717 i += nMerged;
718 }
719}
720
721////////////////////////////////////////////////////////////////////////////////
722/// This pass is a bit more complicated, since we have to 'compact' in-place.
723
724void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
725{
726 size_type i = 0;
727 for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
728 //i is always less than j, so i is always valid here.
729 const TPoint &currentPoint = dst[i];
730
731 SCoord_t xMin = currentPoint.fX;
732 SCoord_t xMax = xMin;
733 SCoord_t xLast = 0;
734
735 bool merged = false;
736 size_type nMerged = 1;
737
738 for (; j < nPoints; ++j) {
739 const TPoint &nextPoint = dst[j];
740
741 if (nextPoint.fY == currentPoint.fY) {
742 xLast = nextPoint.fX;
743 xMin = TMath::Min(xMin, xLast);
744 xMax = TMath::Max(xMax, xLast);
745 ++nMerged;//and we continue ...
746 } else {
747 if (nMerged > 1)
748 nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
749 merged = true;
750 break;
751 }
752 }
753
754 if (!merged && nMerged > 1)
755 nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
756
757 i += nMerged;
758
759 if (j < nPoints) {
760 dst[i] = dst[j];
761 ++j;
762 } else
763 break;
764 }
765
766 dst.resize(i);
767}
768
769////////////////////////////////////////////////////////////////////////////////
770/// This is a quite simple algorithm, using the fact, that after conversion many
771/// subsequent vertices can have the same 'x' or 'y' coordinate and this part of
772/// a polygon will look like a line on the screen.
773
774template<typename T>
775void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
776 const T *y, std::vector<TPoint> &dst)
777{
778 //I'm using 'pad' pointer to get rid of this damned gPad.
779 //Unfortunately, TPadPainter itself still has to use it.
780 //But at least this code does not have to be fixed.
781
782 if (!nPoints)
783 return;
784
785 dst.clear();
786 dst.reserve(threshold);
787
789
790 if (dst.size() < threshold)
791 return;
792
794}
795
796////////////////////////////////////////////////////////////////////////////////
797
798template<class T>
800{
801 std::vector<TPoint> xy;
802
803 const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
804 pad->GetWh() * pad->GetAbsHNDC())) * 2;
805
806 if (threshold <= 0) {
807 //Ooops, pad is invisible or something really bad and stupid happened.
808 ::Error("DrawFillAreaAux", "invalid pad's geometry");
809 return;
810 }
811
812 if (nPoints < threshold)
814 else
816
817 //We close the 'polygon' so it can be rendered as a polyline by gVirtualX.
818 if (add_first_point)
819 xy.push_back(xy.front());
820
821 if (xy.size() > 2)
822 gVirtualX->DrawFillAreaW(cont, xy.size(), xy.data());
823}
824
825////////////////////////////////////////////////////////////////////////////////
826
827template <typename T>
828void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, Bool_t absCoord, unsigned nPoints, const T *xs, const T *ys)
829{
830 std::vector<TPoint> xy;
831
832 const UInt_t threshold = TMath::Min(pad->GetPadWidth(), pad->GetPadHeight()) * 2;
833
834 if (threshold == 0) {//Ooops, pad is invisible or something really bad and stupid happened.
835 ::Error("DrawPolyLineAux", "invalid pad's geometry");
836 return;
837 }
838
839 if (absCoord || (nPoints < threshold))
841 else
843
844 if (xy.size() > 1)
845 gVirtualX->DrawPolyLineW(cont, xy.size(), &xy[0]);
846}
847
848////////////////////////////////////////////////////////////////////////////////
849
850template<class T>
851void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, Bool_t double_buffer, unsigned nPoints, const T *xs, const T *ys)
852{
853 std::vector<TPoint> xy(nPoints);
854
855 for (unsigned i = 0; i < nPoints; ++i) {
856 xy[i].fX = (SCoord_t) (double_buffer ? pad->XtoPixel(xs[i]) : pad->XtoAbsPixel(xs[i]));
857 xy[i].fY = (SCoord_t) (double_buffer ? pad->YtoPixel(ys[i]) : pad->YtoAbsPixel(ys[i]));
858 }
859
860 gVirtualX->DrawPolyMarkerW(cont, nPoints, &xy[0]);
861}
862
863}
Handle_t WinContext_t
Window drawing context.
Definition GuiTypes.h:30
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
#define h(i)
Definition RSha256.hxx:106
double * dst
char * device
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
short SCoord_t
Screen coordinates (short)
Definition RtypesCore.h:101
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
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:267
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize wid
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
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 y1
#define gROOT
Definition TROOT.h:417
#define gPad
#define gVirtualX
Definition TVirtualX.h:379
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:22
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:1154
An abstract interface to image processing library.
Definition TImage.h:29
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.
WinContext_t fWinContext
TVirtualPad * fPad
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 DrawTTFglyphs(Int_t x, Int_t y, TTFhandle &ttf, ETextMode mode) override
Paint TTF glyps on virtualx device.
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 transparent colors are supported.
void ClearWindow(Int_t device) override
Clear specified window - calling gVirtualX->ClearWindowW.
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.
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.
Bool_t HasTTFonts() const override
Return true if TTF font can be used.
void SetDrawMode(Int_t device, Int_t mode) override
Set drawing mode for specified device.
void ClearDrawable() override
Clear the current gVirtualX window - calling gVirtualX->ClearWindowW.
void DestroyDrawable(Int_t device) override
Close the current gVirtualX pixmap.
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 DrawImage(TImage *img, Int_t x, Int_t y, Int_t flags=0) override
Draw image on the gVirtualX window.
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
Dynamic handle to work with freetype 2 library.
Definition TTFhandle.h:21
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual Int_t GetPixmapID() 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: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