Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TImageDump.cxx
Go to the documentation of this file.
1 // @(#)root/postscript:$Id$
2 // Author: Valeriy Onuchin
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 /** \class TImageDump
13 \ingroup PS
14 
15 \brief Save canvas as an image (GIF, JPEG, PNG, XPM, TIFF etc.).
16 
17 Example:
18 ~~~ {.cpp}
19  $ root -b
20  root [0] .x hsimple.C
21  root [1] c1->Print("c1.gif");
22 ~~~
23 TImageDump can be used in any mode (batch, interactive) as follows
24 ~~~ {.cpp}
25  TCanvas *c1;
26  TImageDump *imgdump = new TImageDump("test.png");
27  c1->Paint();
28  imgdump->Close();
29 ~~~
30 */
31 
32 #include "TImageDump.h"
33 #include "TImage.h"
34 #include "TMath.h"
35 #include "TPoint.h"
36 #include "TColor.h"
37 #include "TVirtualPad.h"
38 #include "TEnv.h"
39 #include "TROOT.h"
40 #include "TSystem.h"
41 #include "TText.h"
42 #include "RStipples.h"
43 #include "TList.h"
44 #include "TStyle.h"
45 #include "TObjString.h"
46 #include "TObjArray.h"
47 
48 
49 ClassImp(TImageDump);
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Default constructor
53 
54 TImageDump::TImageDump() : TVirtualPS()
55 {
56  fStream = 0;
57  fImage = 0;
58  gVirtualPS = this;
59  fType = 0;
60  SetTitle("IMG");
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Initialize batch image interface
65 ///
66 /// fname : image file name
67 ///
68 /// The possible workstation types are:
69 /// - 111 - Portrait
70 /// - 112 - Landscape
71 /// - 114 - preview, keep in memory (do not write on delete)
72 
73 TImageDump::TImageDump(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
74 {
75  Open(fname, wtype);
76  gVirtualPS = this;
77  SetTitle("IMG");
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Open a image file
82 
83 void TImageDump::Open(const char *fname, Int_t type)
84 {
85  fStream = 0;
86  fImage = TImage::Create();
87  fType = type;
88  SetName(fname);
89 }
90 
91 ////////////////////////////////////////////////////////////////////////////////
92 /// destructor
93 
94 TImageDump::~TImageDump()
95 {
96  Close();
97 
98  delete fImage;
99  fImage = 0;
100 
101  gVirtualPS = 0;
102 }
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Close a image file
106 
107 void TImageDump::Close(Option_t *)
108 {
109  // if fType == 114 - do not write image
110  if (!fImage || (fType == 114)) {
111  return;
112  }
113 
114  //if (fType == 112) fImage->Flip(90);
115  fImage->WriteImage(GetName());
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Draw a Box
120 
121 void TImageDump::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
122 {
123  if (!gPad || !fImage) {
124  return;
125  }
126 
127  fImage->BeginPaint();
128 
129  static Double_t x[4], y[4];
130  Int_t ix1 = x1 < x2 ? XtoPixel(x1) : XtoPixel(x2);
131  Int_t ix2 = x1 < x2 ? XtoPixel(x2) : XtoPixel(x1);
132  Int_t iy1 = y1 < y2 ? YtoPixel(y1) : YtoPixel(y2);
133  Int_t iy2 = y1 < y2 ? YtoPixel(y2) : YtoPixel(y1);
134 
135  if (ix1<0 || ix2 <0 || iy1 < 0 || iy2 <0) return; // box is not visible
136 
137  if (TMath::Abs(ix2-ix1) < 1) ix2 = ix1+1;
138  if (TMath::Abs(iy1-iy2) < 1) iy1 = iy2+1;
139 
140  Int_t fillis = fFillStyle/1000;
141  Int_t fillsi = fFillStyle%1000;
142 
143  TColor *col = gROOT->GetColor(fFillColor);
144  if (!col) { // no color, set it white
145  fFillColor = 10;
146  col = gROOT->GetColor(fFillColor);
147  if (!col) return;
148  }
149 
150  TColor *linecol = gROOT->GetColor(fLineColor);
151  if (!linecol) { // no color, set it to black
152  fLineColor = 1;
153  linecol = gROOT->GetColor(fLineColor);
154  }
155 
156  if ((fillis == 3) || (fillis == 2)) {
157  if (fillsi > 99) {
158  x[0] = x1; y[0] = y1;
159  x[1] = x2; y[1] = y1;
160  x[2] = x2; y[2] = y2;
161  x[3] = x1; y[3] = y2;
162  return;
163  }
164  if ((fillsi > 0) && (fillsi < 26)) {
165  x[0] = x1; y[0] = y1;
166  x[1] = x2; y[1] = y1;
167  x[2] = x2; y[2] = y2;
168  x[3] = x1; y[3] = y2;
169  DrawPS(-4, &x[0], &y[0]);
170  }
171  if (fillsi == -3) {
172  // fill style = -3 ... which is NEVER used now
173  }
174  }
175 
176  if (fillis == 1) {
177  fImage->DrawBox(ix1, iy1, ix2, iy2, col->AsHexString(), 1, TVirtualX::kFilled);
178  }
179 
180  if (fillis == 0) {
181  if (fLineWidth<=0) return;
182  fImage->DrawBox(ix1, iy1, ix2, iy2, linecol->AsHexString(), fLineWidth, TVirtualX::kHollow);
183  }
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Draw a Frame around a box
188 ///
189 /// - mode = -1 the box looks as it is behind the screen
190 /// - mode = 1 the box looks as it is in front of the screen
191 /// border is the border size in already pre-computed dark is the
192 /// color for the dark part of the frame light is the color for the light
193 /// part of the frame
194 
195 void TImageDump::DrawFrame(Double_t x1, Double_t y1, Double_t x2, Double_t y2,
196  Int_t mode, Int_t bordersize, Int_t dark, Int_t light)
197 {
198  if (!gPad || !fImage) {
199  return;
200  }
201 
202  fImage->BeginPaint();
203 
204  bordersize = bordersize < 1 ? 1 : bordersize;
205 
206  TColor *col;
207  TColor *lo = gROOT->GetColor(dark);
208  if (!lo) {
209  lo = gROOT->GetColor(10);
210  }
211  TColor *hi = gROOT->GetColor(light);
212  if (!hi) {
213  hi = gROOT->GetColor(10);
214  }
215 
216  Short_t pxl,pyl,pxt,pyt,px1,py1,px2,py2;
217 
218  px1 = XtoPixel(x1); py1 = YtoPixel(y1);
219  px2 = XtoPixel(x2); py2 = YtoPixel(y2);
220  if (px1 < px2) {pxl = px1; pxt = px2;}
221  else {pxl = px2; pxt = px1;}
222  if (py1 > py2) {pyl = py1; pyt = py2;}
223  else {pyl = py2; pyt = py1;}
224 
225  if (bordersize == 1) {
226  col = gROOT->GetColor(fLineColor);
227  if (!col) {
228  fLineColor = 1;
229  col = gROOT->GetColor(fLineColor);
230  if (!col) return;
231  }
232  fImage->DrawBox(pxl, pyl, pxt, pyt-1, col->AsHexString(), TVirtualX::kFilled);
233  return;
234  }
235 
236  if (!fImage->IsValid()) {
237  col = gROOT->GetColor(light);
238  if (!col) {
239  col = gROOT->GetColor(10);
240  if (!col) return;
241  }
242  fImage->DrawBox(pxl, pyl, pxt, pyt, // force image creation and resizing
243  "#ffffffff", 1, TVirtualX::kFilled);
244  }
245 
246  TPoint frame[6];
247 
248  frame[0].fX = pxl; frame[0].fY = pyl;
249  frame[1].fX = pxl + bordersize; frame[1].fY = pyl - bordersize;
250  frame[2].fX = pxl + bordersize; frame[2].fY = pyt + bordersize;
251  frame[3].fX = pxt - bordersize; frame[3].fY = pyt + bordersize;;
252  frame[4].fX = pxt; frame[4].fY = pyt;
253  frame[5].fX = pxl; frame[5].fY = pyt;
254 
255  if (mode == -1) col = lo;
256  else col = hi;
257 
258  fImage->DrawFillArea(6, frame, col->AsHexString());
259 
260  frame[0].fX = pxl; frame[0].fY = pyl;
261  frame[1].fX = pxl + bordersize; frame[1].fY = pyl - bordersize;
262  frame[2].fX = pxt - bordersize; frame[2].fY = frame[1].fY;
263  frame[3].fX = frame[2].fX; frame[3].fY = pyt + bordersize;
264  frame[4].fX = pxt; frame[4].fY = pyt;
265  frame[5].fX = pxt; frame[5].fY = pyl;
266 
267  if (mode == -1) col = hi;
268  else col = lo;
269 
270  fImage->DrawFillArea(6, frame, col->AsHexString());
271 }
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 /// not used
275 
276 void TImageDump::DrawPolyMarker(Int_t, Float_t *, Float_t *)
277 {
278  if (!gPad || !fImage) {
279  return;
280  }
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 /// draw polymarker
285 
286 void TImageDump::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
287 {
288  if (!gPad || !fImage) {
289  return;
290  }
291 
292  fImage->BeginPaint();
293 
294  Int_t ms = TMath::Abs(fMarkerStyle);
295  static TPoint pt[20];
296 
297  if (ms > 7 && ms <= 19) ms = 20;
298  if (ms == 4) ms = 24;
299 
300  // Define the marker size
301  const Int_t kBASEMARKER = 8;
302  Double_t msize = fMarkerSize * kBASEMARKER * gStyle->GetImageScaling();
303  if (ms == 6) msize *= 0.2;
304  if (ms == 7) msize *= 0.3;
305  Double_t m = msize;
306  Double_t m2 = m/2;
307  Double_t m3 = m/3;
308  Double_t m6 = m/6;
309  Double_t m4 = m/4;
310  Double_t m8 = m/8;
311  Double_t m0 = m*0.1;
312 
313  TColor *col = gROOT->GetColor(fMarkerColor);
314  if (!col) { // no color
315  fMarkerColor = 1;
316  col = gROOT->GetColor(fMarkerColor);
317  if (!col) return;
318  }
319  if (col->GetAlpha()<1.) {
320  if (ms==8) ms = 108;
321  if (ms==20) ms = 120;
322  }
323 
324  // Draw the marker according to the type
325  Short_t ix,iy;
326  for (Int_t i=0;i<n;i++) {
327  ix = XtoPixel(xw[i]);
328  iy = YtoPixel(yw[i]);
329 
330  switch (ms) {
331  // Dots (.) big, medium and small
332  case 7:
333  fImage->PutPixel((UInt_t)ix-1, (UInt_t)iy-1, col->AsHexString());
334  fImage->PutPixel((UInt_t)ix-1, (UInt_t)iy+1, col->AsHexString());
335  fImage->PutPixel((UInt_t)ix+1, (UInt_t)iy+1, col->AsHexString());
336  fImage->PutPixel((UInt_t)ix+1, (UInt_t)iy-1, col->AsHexString());
337  case 6:
338  fImage->PutPixel((UInt_t)ix, (UInt_t)iy-1, col->AsHexString());
339  fImage->PutPixel((UInt_t)ix, (UInt_t)iy+1, col->AsHexString());
340  fImage->PutPixel((UInt_t)ix-1, (UInt_t)iy, col->AsHexString());
341  fImage->PutPixel((UInt_t)ix+1, (UInt_t)iy, col->AsHexString());
342  case 1:
343  fImage->PutPixel((UInt_t)ix, (UInt_t)iy, col->AsHexString());
344  break;
345  // Plus (+)
346  case 2:
347  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy), UInt_t(ix+m2), UInt_t(iy), col->AsHexString());
348  fImage->DrawLine(UInt_t(ix), UInt_t(iy-m2), UInt_t(ix), UInt_t(iy+m2), col->AsHexString());
349  break;
350  // X shape (X)
351  case 5:
352  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy-m2), UInt_t(ix+m2), UInt_t(iy+m2), col->AsHexString());
353  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy+m2), UInt_t(ix+m2), UInt_t(iy-m2), col->AsHexString());
354  break;
355  // Asterisk shape (*)
356  case 3:
357  case 31:
358  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy), UInt_t(ix+m2), UInt_t(iy), col->AsHexString());
359  fImage->DrawLine(UInt_t(ix), UInt_t(iy-m2), UInt_t(ix), UInt_t(iy+m2), col->AsHexString());
360  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy-m2), UInt_t(ix+m2), UInt_t(iy+m2), col->AsHexString());
361  fImage->DrawLine(UInt_t(ix-m2), UInt_t(iy+m2), UInt_t(ix+m2), UInt_t(iy-m2), col->AsHexString());
362  break;
363  // Circle
364  case 4:
365  case 24:
366  fImage->DrawCircle(ix, iy, Int_t(msize/2), col->AsHexString(), 1);
367  break;
368  // Circle
369  case 8:
370  case 20:
371  fImage->DrawCircle(ix, iy, Int_t(msize/2), col->AsHexString(), -1);
372  break;
373  case 108:
374  case 120:
375  for (int idx=Int_t(msize/2); idx>0; idx--) fImage->DrawCircle(ix, iy, idx, col->AsHexString(), 1);
376  fImage->PutPixel((UInt_t)ix, (UInt_t)iy, col->AsHexString());
377  break;
378  // Square
379  case 21:
380  fImage->FillRectangle(col->AsHexString(), UInt_t(ix-m2), UInt_t(iy-m2), UInt_t(m), UInt_t(m));
381  break;
382  case 25:
383  fImage->DrawRectangle(UInt_t(ix-m2), UInt_t(iy-m2), UInt_t(m), UInt_t(m), col->AsHexString());
384  break;
385  // Down triangle
386  case 23:
387  case 32:
388  pt[0].fX = Short_t(ix-m2); pt[0].fY = Short_t(iy-m2);
389  pt[1].fX = Short_t(ix+m2); pt[1].fY = Short_t(iy-m2);
390  pt[2].fX = Short_t(ix); pt[2].fY = Short_t(iy+m2);
391  pt[3].fX = Short_t(ix-m2); pt[3].fY = Short_t(iy-m2);
392  ms == 32 ? fImage->DrawPolyLine(4, pt, col->AsHexString()) :
393  fImage->FillPolygon(3, pt, col->AsHexString());
394  break;
395  // Up triangle
396  case 22:
397  case 26:
398  pt[0].fX = Short_t(ix); pt[0].fY = Short_t(iy-m2);
399  pt[1].fX = Short_t(ix+m2); pt[1].fY = Short_t(iy+m2);
400  pt[2].fX = Short_t(ix-m2); pt[2].fY = Short_t(iy+m2);
401  pt[3].fX = Short_t(ix); pt[3].fY = Short_t(iy-m2);
402  ms == 26 ? fImage->DrawPolyLine(4, pt, col->AsHexString()) :
403  fImage->FillPolygon(3, pt, col->AsHexString());
404  break;
405  case 27:
406  case 33:
407  pt[0].fX = Short_t(ix); pt[0].fY = Short_t(iy-m2);
408  pt[1].fX = Short_t(ix+m3); pt[1].fY = Short_t(iy);
409  pt[2].fX = Short_t(ix); pt[2].fY = Short_t(iy+m2);
410  pt[3].fX = Short_t(ix-m3); pt[3].fY = Short_t(iy);
411  pt[4].fX = Short_t(ix); pt[4].fY = Short_t(iy-m2);
412  ms == 27 ? fImage->DrawPolyLine(5, pt, col->AsHexString()) :
413  fImage->FillPolygon(4, pt, col->AsHexString());
414  break;
415  case 28:
416  case 34:
417  pt[0].fX = Short_t(ix-m6); pt[0].fY = Short_t(iy-m6);
418  pt[1].fX = Short_t(ix-m6); pt[1].fY = Short_t(iy-m2);
419  pt[2].fX = Short_t(ix+m6); pt[2].fY = Short_t(iy-m2);
420  pt[3].fX = Short_t(ix+m6); pt[3].fY = Short_t(iy-m6);
421  pt[4].fX = Short_t(ix+m2); pt[4].fY = Short_t(iy-m6);
422  pt[5].fX = Short_t(ix+m2); pt[5].fY = Short_t(iy+m6);
423  pt[6].fX = Short_t(ix+m6); pt[6].fY = Short_t(iy+m6);
424  pt[7].fX = Short_t(ix+m6); pt[7].fY = Short_t(iy+m2);
425  pt[8].fX = Short_t(ix-m6); pt[8].fY = Short_t(iy+m2);
426  pt[9].fX = Short_t(ix-m6); pt[9].fY = Short_t(iy+m6);
427  pt[10].fX = Short_t(ix-m2); pt[10].fY = Short_t(iy+m6);
428  pt[11].fX = Short_t(ix-m2); pt[11].fY = Short_t(iy-m6);
429  pt[12].fX = Short_t(ix-m6); pt[12].fY = Short_t(iy-m6);
430  ms == 28 ? fImage->DrawPolyLine(13, pt, col->AsHexString()) :
431  fImage->FillPolygon(12, pt, col->AsHexString());
432  break;
433  case 29:
434  case 30:
435  pt[0].fX = Short_t(ix); pt[0].fY = Short_t(iy+m2);
436  pt[1].fX = Short_t(ix+0.112255*m); pt[1].fY = Short_t(iy+0.15451*m);
437  pt[2].fX = Short_t(ix+0.47552*m); pt[2].fY = Short_t(iy+0.15451*m);
438  pt[3].fX = Short_t(ix+0.181635*m); pt[3].fY = Short_t(iy-0.05902*m);
439  pt[4].fX = Short_t(ix+0.29389*m); pt[4].fY = Short_t(iy-0.40451*m);
440  pt[5].fX = Short_t(ix); pt[5].fY = Short_t(iy-0.19098*m);
441  pt[6].fX = Short_t(ix-0.29389*m); pt[6].fY = Short_t(iy-0.40451*m);
442  pt[7].fX = Short_t(ix-0.181635*m); pt[7].fY = Short_t(iy-0.05902*m);
443  pt[8].fX = Short_t(ix-0.47552*m); pt[8].fY = Short_t(iy+0.15451*m);
444  pt[9].fX = Short_t(ix-0.112255*m); pt[9].fY = Short_t(iy+0.15451*m);
445  pt[10].fX = Short_t(ix); pt[10].fY = Short_t(iy+m2);
446  ms == 30 ? fImage->DrawPolyLine(11, pt, col->AsHexString()) :
447  fImage->DrawFillArea(10, pt, col->AsHexString());
448  break;
449  case 35:
450  pt[0].fX = Short_t(ix-m2); pt[0].fY = Short_t(iy );
451  pt[1].fX = Short_t(ix ); pt[1].fY = Short_t(iy-m2);
452  pt[2].fX = Short_t(ix+m2); pt[2].fY = Short_t(iy );
453  pt[3].fX = Short_t(ix ); pt[3].fY = Short_t(iy+m2);
454  pt[4].fX = Short_t(ix-m2); pt[4].fY = Short_t(iy );
455  pt[5].fX = Short_t(ix+m2); pt[5].fY = Short_t(iy );
456  pt[6].fX = Short_t(ix ); pt[6].fY = Short_t(iy+m2);
457  pt[7].fX = Short_t(ix ); pt[7].fY = Short_t(iy-m2);
458  fImage->DrawPolyLine(8, pt, col->AsHexString()) ;
459  break;
460  case 36:
461  pt[0].fX = Short_t(ix-m2); pt[0].fY = Short_t(iy-m2);
462  pt[1].fX = Short_t(ix+m2); pt[1].fY = Short_t(iy-m2);
463  pt[2].fX = Short_t(ix+m2); pt[2].fY = Short_t(iy+m2);
464  pt[3].fX = Short_t(ix-m2); pt[3].fY = Short_t(iy+m2);
465  pt[4].fX = Short_t(ix-m2); pt[4].fY = Short_t(iy-m2);
466  pt[5].fX = Short_t(ix+m2); pt[5].fY = Short_t(iy+m2);
467  pt[6].fX = Short_t(ix-m2); pt[6].fY = Short_t(iy+m2);
468  pt[7].fX = Short_t(ix+m2); pt[7].fY = Short_t(iy-m2);
469  fImage->DrawPolyLine(8, pt, col->AsHexString()) ;
470  break;
471  case 37:
472  case 39:
473  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy );
474  pt[1].fX = Short_t(ix-m4); pt[1].fY = Short_t(iy-m2);
475  pt[2].fX = Short_t(ix-m2); pt[2].fY = Short_t(iy );
476  pt[3].fX = Short_t(ix+m2); pt[3].fY = Short_t(iy );
477  pt[4].fX = Short_t(ix+m4); pt[4].fY = Short_t(iy-m2);
478  pt[5].fX = Short_t(ix-m4); pt[5].fY = Short_t(iy+m2);
479  pt[6].fX = Short_t(ix+m4); pt[6].fY = Short_t(iy+m2);
480  pt[7].fX = Short_t(ix ); pt[7].fY = Short_t(iy );
481  ms == 37 ? fImage->DrawPolyLine(8, pt, col->AsHexString()) :
482  fImage->DrawFillArea(7, pt, col->AsHexString());
483  break;
484  case 38:
485  pt[0].fX = Short_t(ix-m2); pt[0].fY = Short_t(iy );
486  pt[1].fX = Short_t(ix-m2); pt[1].fY = Short_t(iy-m4);
487  pt[2].fX = Short_t(ix-m4); pt[2].fY = Short_t(iy-m2);
488  pt[3].fX = Short_t(ix+m4); pt[3].fY = Short_t(iy-m2);
489  pt[4].fX = Short_t(ix+m2); pt[4].fY = Short_t(iy-m4);
490  pt[5].fX = Short_t(ix+m2); pt[5].fY = Short_t(iy+m4);
491  pt[6].fX = Short_t(ix+m4); pt[6].fY = Short_t(iy+m2);
492  pt[7].fX = Short_t(ix-m4); pt[7].fY = Short_t(iy+m2);
493  pt[8].fX = Short_t(ix-m2); pt[8].fY = Short_t(iy+m4);
494  pt[9].fX = Short_t(ix-m2); pt[9].fY = Short_t(iy );
495  pt[10].fX = Short_t(ix+m2); pt[10].fY = Short_t(iy );
496  pt[11].fX = Short_t(ix ); pt[11].fY = Short_t(iy );
497  pt[12].fX = Short_t(ix ); pt[12].fY = Short_t(iy-m2);
498  pt[13].fX = Short_t(ix ); pt[13].fY = Short_t(iy+m2);
499  pt[14].fX = Short_t(ix ); pt[14].fY = Short_t(iy );
500  fImage->DrawPolyLine(15, pt, col->AsHexString()) ;
501  break;
502  case 40:
503  case 41:
504  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy );
505  pt[1].fX = Short_t(ix+m4); pt[1].fY = Short_t(iy+m2);
506  pt[2].fX = Short_t(ix+m2); pt[2].fY = Short_t(iy+m4);
507  pt[3].fX = Short_t(ix ); pt[3].fY = Short_t(iy );
508  pt[4].fX = Short_t(ix+m2); pt[4].fY = Short_t(iy-m4);
509  pt[5].fX = Short_t(ix+m4); pt[5].fY = Short_t(iy-m2);
510  pt[6].fX = Short_t(ix ); pt[6].fY = Short_t(iy );
511  pt[7].fX = Short_t(ix-m4); pt[7].fY = Short_t(iy-m2);
512  pt[8].fX = Short_t(ix-m2); pt[8].fY = Short_t(iy-m4);
513  pt[9].fX = Short_t(ix ); pt[9].fY = Short_t(iy );
514  pt[10].fX = Short_t(ix-m2); pt[10].fY = Short_t(iy+m4);
515  pt[11].fX = Short_t(ix-m4); pt[11].fY = Short_t(iy+m2);
516  pt[12].fX = Short_t(ix ); pt[12].fY = Short_t(iy );
517  ms == 40 ? fImage->DrawPolyLine(13, pt, col->AsHexString()) :
518  fImage->DrawFillArea(12, pt, col->AsHexString());
519  break;
520  case 42:
521  case 43:
522  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy+m2);
523  pt[1].fX = Short_t(ix-m8); pt[1].fY = Short_t(iy+m8);
524  pt[2].fX = Short_t(ix-m2); pt[2].fY = Short_t(iy );
525  pt[3].fX = Short_t(ix-m8); pt[3].fY = Short_t(iy-m8);
526  pt[4].fX = Short_t(ix ); pt[4].fY = Short_t(iy-m2);
527  pt[5].fX = Short_t(ix+m8); pt[5].fY = Short_t(iy-m8);
528  pt[6].fX = Short_t(ix+m2); pt[6].fY = Short_t(iy );
529  pt[7].fX = Short_t(ix+m8); pt[7].fY = Short_t(iy+m8);
530  pt[8].fX = Short_t(ix ); pt[8].fY = Short_t(iy+m2);
531  ms == 42 ? fImage->DrawPolyLine(9, pt, col->AsHexString()) :
532  fImage->DrawFillArea(8, pt, col->AsHexString());
533  break;
534  case 44:
535  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy );
536  pt[1].fX = Short_t(ix+m4); pt[1].fY = Short_t(iy+m2);
537  pt[2].fX = Short_t(ix-m4); pt[2].fY = Short_t(iy+m2);
538  pt[3].fX = Short_t(ix+m4); pt[3].fY = Short_t(iy-m2);
539  pt[4].fX = Short_t(ix-m4); pt[4].fY = Short_t(iy-m2);
540  pt[5].fX = Short_t(ix ); pt[5].fY = Short_t(iy );
541  pt[6].fX = Short_t(ix+m2); pt[6].fY = Short_t(iy+m4);
542  pt[7].fX = Short_t(ix+m2); pt[7].fY = Short_t(iy-m4);
543  pt[8].fX = Short_t(ix-m2); pt[8].fY = Short_t(iy+m4);
544  pt[9].fX = Short_t(ix-m2); pt[9].fY = Short_t(iy-m4);
545  pt[10].fX = Short_t(ix ); pt[10].fY = Short_t(iy );
546  fImage->DrawPolyLine(11, pt, col->AsHexString()) ;
547  break;
548  case 45:
549  pt[0].fX = Short_t(ix+m0); pt[0].fY = Short_t(iy+m0);
550  pt[1].fX = Short_t(ix+m4); pt[1].fY = Short_t(iy+m2);
551  pt[2].fX = Short_t(ix-m4); pt[2].fY = Short_t(iy+m2);
552  pt[3].fX = Short_t(ix-m0); pt[3].fY = Short_t(iy+m0);
553  pt[4].fX = Short_t(ix-m2); pt[4].fY = Short_t(iy+m4);
554  pt[5].fX = Short_t(ix-m2); pt[5].fY = Short_t(iy-m4);
555  pt[6].fX = Short_t(ix-m0); pt[6].fY = Short_t(iy-m0);
556  pt[7].fX = Short_t(ix-m4); pt[7].fY = Short_t(iy-m2);
557  pt[8].fX = Short_t(ix+m4); pt[8].fY = Short_t(iy-m2);
558  pt[9].fX = Short_t(ix+m0); pt[9].fY = Short_t(iy-m0);
559  pt[10].fX = Short_t(ix+m2); pt[10].fY = Short_t(iy-m4);
560  pt[11].fX = Short_t(ix+m2); pt[11].fY = Short_t(iy+m4);
561  pt[12].fX = Short_t(ix+m0); pt[12].fY = Short_t(iy+m0);
562  fImage->DrawFillArea(13, pt, col->AsHexString());
563  break;
564  case 46:
565  case 47:
566  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy+m4);
567  pt[1].fX = Short_t(ix-m4); pt[1].fY = Short_t(iy+m2);
568  pt[2].fX = Short_t(ix-m2); pt[2].fY = Short_t(iy+m4);
569  pt[3].fX = Short_t(ix-m4); pt[3].fY = Short_t(iy );
570  pt[4].fX = Short_t(ix-m2); pt[4].fY = Short_t(iy-m4);
571  pt[5].fX = Short_t(ix-m4); pt[5].fY = Short_t(iy-m2);
572  pt[6].fX = Short_t(ix ); pt[6].fY = Short_t(iy-m4);
573  pt[7].fX = Short_t(ix+m4); pt[7].fY = Short_t(iy-m2);
574  pt[8].fX = Short_t(ix+m2); pt[8].fY = Short_t(iy-m4);
575  pt[9].fX = Short_t(ix+m4); pt[9].fY = Short_t(iy );
576  pt[10].fX = Short_t(ix+m2); pt[10].fY = Short_t(iy+m4);
577  pt[11].fX = Short_t(ix+m4); pt[11].fY = Short_t(iy+m2);
578  pt[12].fX = Short_t(ix ); pt[12].fY = Short_t(iy+m4);
579  ms == 46 ? fImage->DrawPolyLine(13, pt, col->AsHexString()) :
580  fImage->DrawFillArea(12, pt, col->AsHexString());
581  break;
582  case 48:
583  pt[0].fX = Short_t(ix ); pt[0].fY = Short_t(iy+m4*1.005);
584  pt[1].fX = Short_t(ix-m4); pt[1].fY = Short_t(iy+m2);
585  pt[2].fX = Short_t(ix-m2); pt[2].fY = Short_t(iy+m4);
586  pt[3].fX = Short_t(ix-m4); pt[3].fY = Short_t(iy );
587  pt[4].fX = Short_t(ix-m2); pt[4].fY = Short_t(iy-m4);
588  pt[5].fX = Short_t(ix-m4); pt[5].fY = Short_t(iy-m2);
589  pt[6].fX = Short_t(ix ); pt[6].fY = Short_t(iy-m4);
590  pt[7].fX = Short_t(ix+m4); pt[7].fY = Short_t(iy-m2);
591  pt[8].fX = Short_t(ix+m2); pt[8].fY = Short_t(iy-m4);
592  pt[9].fX = Short_t(ix+m4); pt[9].fY = Short_t(iy );
593  pt[10].fX = Short_t(ix+m2); pt[10].fY = Short_t(iy+m4);
594  pt[11].fX = Short_t(ix+m4); pt[11].fY = Short_t(iy+m2);
595  pt[12].fX = Short_t(ix ); pt[12].fY = Short_t(iy+m4*0.995);
596  pt[13].fX = Short_t(ix+m4*0.995); pt[13].fY = Short_t(iy );
597  pt[14].fX = Short_t(ix ); pt[14].fY = Short_t(iy-m4*0.995);
598  pt[15].fX = Short_t(ix-m4*0.995); pt[15].fY = Short_t(iy );
599  pt[16].fX = Short_t(ix ); pt[16].fY = Short_t(iy+m4*0.995);
600  fImage->DrawFillArea(17, pt, col->AsHexString());
601  break;
602  case 49:
603  pt[0].fX = Short_t(ix-m6); pt[0].fY = Short_t(iy-m6*1.005);
604  pt[1].fX = Short_t(ix-m6); pt[1].fY = Short_t(iy-m2);
605  pt[2].fX = Short_t(ix+m6); pt[2].fY = Short_t(iy-m2);
606  pt[3].fX = Short_t(ix+m6); pt[3].fY = Short_t(iy-m6);
607  pt[4].fX = Short_t(ix+m2); pt[4].fY = Short_t(iy-m6);
608  pt[5].fX = Short_t(ix+m2); pt[5].fY = Short_t(iy+m6);
609  pt[6].fX = Short_t(ix+m6); pt[6].fY = Short_t(iy+m6);
610  pt[7].fX = Short_t(ix+m6); pt[7].fY = Short_t(iy+m2);
611  pt[8].fX = Short_t(ix-m6); pt[8].fY = Short_t(iy+m2);
612  pt[9].fX = Short_t(ix-m6); pt[9].fY = Short_t(iy+m6);
613  pt[10].fX = Short_t(ix-m2); pt[10].fY = Short_t(iy+m6);
614  pt[11].fX = Short_t(ix-m2); pt[11].fY = Short_t(iy-m6);
615  pt[12].fX = Short_t(ix-m6); pt[12].fY = Short_t(iy-m6*0.995);
616  pt[13].fX = Short_t(ix-m6); pt[13].fY = Short_t(iy+m6);
617  pt[14].fX = Short_t(ix+m6); pt[14].fY = Short_t(iy+m6);
618  pt[15].fX = Short_t(ix+m6); pt[15].fY = Short_t(iy-m6);
619  pt[16].fX = Short_t(ix-m6); pt[16].fY = Short_t(iy-m6*1.005);
620  fImage->DrawFillArea(17, pt, col->AsHexString());
621  break;
622  default:
623  fImage->PutPixel(UInt_t(ix), UInt_t(iy), col->AsHexString());
624  break;
625  }
626  }
627 }
628 
629 ////////////////////////////////////////////////////////////////////////////////
630 /// This function defines a path with xw and yw and draw it according the
631 /// value of nn:
632 ///
633 /// - If nn > 0 a line is drawn.
634 /// - If nn < 0 a closed polygon is drawn.
635 
636 void TImageDump::DrawPS(Int_t nn, Double_t *x, Double_t *y)
637 {
638  if (!gPad || !fImage || !nn) {
639  return;
640  }
641 
642  fImage->BeginPaint();
643 
644  TColor *col = 0;
645  Int_t fais = 0 , fasi = 0;
646  Bool_t line = nn > 1;
647  UInt_t n = TMath::Abs(nn);
648 
649  fais = fFillStyle/1000;
650  fasi = fFillStyle%1000;
651 
652  Short_t px1, py1, px2, py2;
653  static const UInt_t gCachePtSize = 200;
654  static TPoint gPointCache[gCachePtSize];
655  Bool_t del = kTRUE;
656 
657 
658  // SetLineStyle
659  Int_t ndashes = 0;
660  char *dash = 0;
661  static char dashList[10];
662  Int_t dashLength = 0;
663  Int_t dashSize = 0;
664 
665  if (line) {
666  if (fLineWidth<=0) return;
667  // dash lines
668  if (fLineStyle > 1) {
669  TString st = gStyle->GetLineStyleString(fLineStyle);
670  TObjArray *tokens = st.Tokenize(" ");
671  ndashes = tokens->GetEntries();
672  dash = new char[ndashes];
673 
674  for (int j = 0; j < ndashes; j++) {
675  Int_t it;
676  sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
677  dash[j] = (char)(it/4);
678  }
679 
680  dashSize = TMath::Min((int)sizeof(dashList), ndashes);
681  dashLength = 0;
682  for (int i = 0; i < dashSize; i++ ) {
683  dashList[i] = dash[i];
684  dashLength += dashList[i];
685  }
686  delete tokens;
687  delete [] dash;
688  }
689 
690  // SetLineColor
691  col = gROOT->GetColor(fLineColor);
692  if (!col) { // no color, make it black
693  fLineColor = 1;
694  col = gROOT->GetColor(fLineColor);
695  if (!col) return;
696  }
697  }
698 
699  if (n == 1) { // point
700  col = gROOT->GetColor(fFillColor);
701  if (!col) { // no color, make it black
702  fFillColor = 1;
703  col = gROOT->GetColor(fFillColor);
704  if (!col) return;
705  }
706  px1 = XtoPixel(x[0]); py1 = YtoPixel(y[0]);
707  fImage->PutPixel(px1, py1, col->AsHexString());
708  return;
709  }
710 
711  if (n == 2) { // line
712  px1 = XtoPixel(x[0]); py1 = YtoPixel(y[0]);
713  px2 = XtoPixel(x[1]); py2 = YtoPixel(y[1]);
714 
715  // SetLineColor
716  col = gROOT->GetColor(fLineColor);
717  if (!col) { // no color, make it black
718  fLineColor = 1;
719  col = gROOT->GetColor(fLineColor);
720  if (!col) return;
721  }
722  if (fLineStyle < 2) {
723  fImage->DrawLine(px1, py1, px2, py2, col->AsHexString(), fLineWidth);
724  } else {
725  fImage->DrawDashLine(px1, py1, px2, py2, dashSize, (const char*)dashList,
726  col->AsHexString(), fLineWidth);
727  }
728  return;
729  }
730 
731  if (!line && ((fais == 3) || (fais == 2)) && (fasi > 100) ) {
732  return;
733  }
734 
735  TPoint *pt = 0;
736  if (n+1 < gCachePtSize) {
737  pt = (TPoint*)&gPointCache;
738  del = kFALSE;
739  } else {
740  pt = new TPoint[n+1];
741  del = kTRUE;
742  }
743 
744  TColor *fcol = gROOT->GetColor(fFillColor);
745  if (!fcol) { // no color, set it white
746  fFillColor = 10;
747  fcol = gROOT->GetColor(fFillColor);
748  }
749 
750  TColor *lcol = gROOT->GetColor(fLineColor);
751  if (!lcol) { // no color, make it black
752  fLineColor = 1;
753  lcol = gROOT->GetColor(fLineColor);
754  }
755 
756  for (UInt_t i = 0; i < n; i++) {
757  pt[i].fX = XtoPixel(x[i]);
758  pt[i].fY = YtoPixel(y[i]);
759  }
760  pt[n].fX = pt[0].fX;
761  pt[n].fY = pt[0].fY;
762 
763  const char *stipple = (fais == 3) && (fasi > 0) && (fasi < 26) ? (const char*)gStipples[fasi] : 0;
764 
765  // filled polygon
766  if (!line && fFillStyle && (fFillStyle != 4000)) {
767  if (!fcol) return;
768 
769  if (n < 5) { // convex
770  fImage->FillPolygon(n, pt, fcol->AsHexString(), stipple);
771  } else { // non-convex fill area
772  fImage->DrawFillArea(n, pt, fcol->AsHexString(), stipple);
773  }
774  }
775 
776  // hollow polygon or polyline is drawn
777  if (line || !fFillStyle || (fFillStyle == 4000)) {
778  if (!lcol) return;
779  if (!line) {
780  fImage->DrawPolyLine(n+1, pt, fcol->AsHexString(), 1);
781  } else {
782  if (fLineStyle < 2) { // solid
783  fImage->DrawPolyLine(n, pt, lcol->AsHexString(), fLineWidth);
784  } else { // dashed
785  DrawDashPolyLine(n, pt, dashSize, (const char*)dashList,
786  lcol->AsHexString(), fLineWidth);
787  }
788  }
789  }
790  if (del) delete [] pt;
791 }
792 
793 ////////////////////////////////////////////////////////////////////////////////
794 /// not used
795 
796 void TImageDump::DrawPS(Int_t, Float_t *, Float_t *)
797 {
798  if (!gPad || !fImage) {
799  return;
800  }
801 }
802 
803 ////////////////////////////////////////////////////////////////////////////////
804 /// draw dashed polyline
805 
806 void TImageDump::DrawDashPolyLine(Int_t nn, TPoint *xy, UInt_t nDash,
807  const char* pDash, const char* col, UInt_t thick)
808 {
809  Int_t x0 = xy[0].GetX();
810  Int_t y0 = xy[0].GetY();
811  Int_t x = 0;
812  Int_t y = 0;
813 
814  for (Int_t i = 1; i < nn; i++) {
815  x = xy[i].GetX();
816  y = xy[i].GetY();
817 
818  fImage->DrawDashLine(x0, y0, x, y, nDash, pDash, col, thick);
819 
820  x0 = x;
821  y0 = y;
822  }
823 }
824 
825 ////////////////////////////////////////////////////////////////////////////////
826 /// new page
827 
828 void TImageDump::NewPage()
829 {
830  if (gPad && fImage) {
831  UInt_t w = UInt_t(gPad->GetWw()*gPad->GetWNDC()) * gStyle->GetImageScaling();
832  UInt_t h = UInt_t(gPad->GetWh()*gPad->GetHNDC()) * gStyle->GetImageScaling();
833  fImage->DrawRectangle(0, 0, w, h, "#ffffffff");
834  }
835  return;
836 }
837 
838 ////////////////////////////////////////////////////////////////////////////////
839 /// Draw text
840 ///
841 /// - x: x position of the text
842 /// - y: y position of the text
843 
844 void TImageDump::Text(Double_t x, Double_t y, const char *chars)
845 {
846  if (!gPad || !fImage) {
847  return;
848  }
849 
850  fImage->BeginPaint();
851 
852  TText t(x, y, chars);
853  t.SetTextSize(fTextSize*gStyle->GetImageScaling());
854  t.SetTextFont(fTextFont);
855  t.SetTextAlign(fTextAlign);
856  t.SetTextAngle(fTextAngle);
857  t.SetTextColor(fTextColor);
858  fImage->DrawText(&t, XtoPixel(x), YtoPixel(y));
859 }
860 
861 ////////////////////////////////////////////////////////////////////////////////
862 /// Draw text
863 ///
864 /// - x: x position of the text
865 /// - y: y position of the text
866 
867 void TImageDump::Text(Double_t x, Double_t y, const wchar_t *chars)
868 {
869  if (!gPad || !fImage) {
870  return;
871  }
872 
873  fImage->BeginPaint();
874 
875  TText t(x, y, chars);
876  t.SetTextSize(fTextSize*gStyle->GetImageScaling());
877  t.SetTextFont(fTextFont);
878  t.SetTextAlign(fTextAlign);
879  t.SetTextAngle(fTextAngle);
880  t.SetTextColor(fTextColor);
881  fImage->DrawText(&t, XtoPixel(x), YtoPixel(y));
882 }
883 
884 
885 ////////////////////////// CellArray code ////////////////////////////////////
886 static UInt_t *gCellArrayColors = 0;
887 static Int_t gCellArrayN = 0;
888 static Int_t gCellArrayW = 0;
889 static Int_t gCellArrayH = 0;
890 static Int_t gCellArrayX1 = 0;
891 static Int_t gCellArrayX2 = 0;
892 static Int_t gCellArrayY1 = 0;
893 static Int_t gCellArrayY2 = 0;
894 static Int_t gCellArrayIdx = 0;
895 
896 ////////////////////////////////////////////////////////////////////////////////
897 ///cell array begin
898 
899 void TImageDump::CellArrayBegin(Int_t w, Int_t h, Double_t x1, Double_t x2,
900  Double_t y1, Double_t y2)
901 {
902  if (!gPad || !fImage || (w <= 0) || (h <= 0)) {
903  return;
904  }
905 
906  if (gCellArrayColors) {
907  delete [] gCellArrayColors;
908  }
909 
910  fImage->BeginPaint();
911 
912  gCellArrayN = w * h;
913  gCellArrayW = w;
914  gCellArrayH = h;
915  gCellArrayColors = new UInt_t[gCellArrayN];
916 
917  gCellArrayX1 = x1 < x2 ? XtoPixel(x1) : XtoPixel(x2);
918  gCellArrayX2 = x1 > x2 ? XtoPixel(x2) : XtoPixel(x1);
919  gCellArrayY1 = y1 < y2 ? YtoPixel(y1) : YtoPixel(y2);
920  gCellArrayY2 = y1 < y2 ? YtoPixel(y2) : YtoPixel(y1);
921 
922  gCellArrayIdx = 0;
923 }
924 
925 ////////////////////////////////////////////////////////////////////////////////
926 /// Cell array fill
927 
928 void TImageDump::CellArrayFill(Int_t r, Int_t g, Int_t b)
929 {
930  if (gCellArrayIdx >= gCellArrayN) return;
931 
932  fImage->BeginPaint();
933 
934  gCellArrayColors[gCellArrayIdx] = ((r & 0xFF) << 16) + ((g & 0xFF) << 8) + (b & 0xFF);
935  gCellArrayIdx++;
936 }
937 
938 ////////////////////////////////////////////////////////////////////////////////
939 /// Cell array end
940 
941 void TImageDump::CellArrayEnd()
942 {
943  if (!fImage || !gCellArrayColors || !gCellArrayW || !gCellArrayH) {
944  return;
945  }
946 
947  fImage->BeginPaint();
948 
949  fImage->DrawCellArray(gCellArrayX1, gCellArrayX2, gCellArrayY1, gCellArrayY2,
950  gCellArrayW, gCellArrayH, gCellArrayColors);
951 
952  delete [] gCellArrayColors;
953  gCellArrayColors = 0;
954  gCellArrayN = 0;
955  gCellArrayW = 0;
956  gCellArrayH = 0;
957  gCellArrayX1 = 0;
958  gCellArrayX2 = 0;
959  gCellArrayY1 = 0;
960  gCellArrayY2 = 0;
961  gCellArrayIdx = 0;
962 }
963 
964 ////////////////////////////////////////////////////////////////////////////////
965 /// Set color with its R G B components
966 ///
967 /// - r: % of red in [0,1]
968 /// - g: % of green in [0,1]
969 /// - b: % of blue in [0,1]
970 
971 void TImageDump::SetColor(Float_t /*r*/, Float_t /*g*/, Float_t /*b*/)
972 {
973 }
974 
975 ////////////////////////////////////////////////////////////////////////////////
976 /// x to pixel
977 
978 Int_t TImageDump::XtoPixel(Double_t x)
979 {
980  return gPad->XtoAbsPixel(x)*gStyle->GetImageScaling();
981 }
982 
983 ////////////////////////////////////////////////////////////////////////////////
984 /// y to pixel
985 
986 Int_t TImageDump::YtoPixel(Double_t y)
987 {
988  return gPad->YtoAbsPixel(y)*gStyle->GetImageScaling();
989 }