Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TVirtualPS.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Rene Brun 05/09/99
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 TVirtualPS
13 \ingroup Base
14 \ingroup PS
15 
16 TVirtualPS is an abstract interface to Postscript, PDF, SVG. TeX etc... drivers
17 */
18 
19 #include "Riostream.h"
20 #include "TVirtualPS.h"
21 
22 TVirtualPS *gVirtualPS = 0;
23 
24 const Int_t kMaxBuffer = 250;
25 
26 ClassImp(TVirtualPS);
27 
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// VirtualPS default constructor.
31 
32 TVirtualPS::TVirtualPS()
33 {
34  fStream = 0;
35  fNByte = 0;
36  fSizBuffer = kMaxBuffer;
37  fBuffer = new char[fSizBuffer+1];
38  fLenBuffer = 0;
39  fPrinted = kFALSE;
40  fImplicitCREsc = 0;
41 }
42 
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// VirtualPS constructor.
46 
47 TVirtualPS::TVirtualPS(const char *name, Int_t)
48  : TNamed(name,"Postscript interface")
49 {
50  fStream = 0;
51  fNByte = 0;
52  fSizBuffer = kMaxBuffer;
53  fBuffer = new char[fSizBuffer+1];
54  fLenBuffer = 0;
55  fPrinted = kFALSE;
56  fImplicitCREsc = 0;
57 }
58 
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// VirtualPS destructor
62 
63 TVirtualPS::~TVirtualPS()
64 {
65  if (fBuffer) delete [] fBuffer;
66 }
67 
68 
69 ////////////////////////////////////////////////////////////////////////////////
70 /// Output the string str in the output buffer
71 
72 void TVirtualPS::PrintStr(const char *str)
73 {
74  if (!str || !str[0])
75  return;
76  Int_t len = strlen(str);
77  while (len) {
78  if (str[0] == '@') {
79  if (fLenBuffer) {
80  fStream->write(fBuffer, fLenBuffer);
81  fNByte += fLenBuffer;
82  fLenBuffer = 0;
83  fStream->write("\n", 1);
84  fNByte++;
85  fPrinted = kTRUE;
86  }
87  len--;
88  str++;
89  } else {
90  Int_t lenText = len;
91  if (str[len-1] == '@') lenText--;
92  PrintFast(lenText, str);
93  len -= lenText;
94  str += lenText;
95  }
96  }
97 }
98 
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Fast version of Print
102 
103 void TVirtualPS::PrintFast(Int_t len, const char *str)
104 {
105  if (!len || !str) return;
106  while ((len + fLenBuffer) > kMaxBuffer) {
107  Int_t nWrite = kMaxBuffer;
108  if (fImplicitCREsc) {
109  if (fLenBuffer > 0) nWrite = fLenBuffer;
110  } else {
111  if ((len + fLenBuffer) > nWrite) {
112  // Search for the nearest preceding space to break a line, if there is no instruction to escape the <end-of-line>.
113  while ((nWrite >= fLenBuffer) && (str[nWrite - fLenBuffer] != ' ')) nWrite--;
114  if (nWrite < fLenBuffer) {
115  while ((nWrite >= 0) && (fBuffer[nWrite] != ' ')) nWrite--;
116  }
117  if (nWrite <= 0) {
118  // Cannot find a convenient place to break a line, so we just break at this location.
119  nWrite = kMaxBuffer;
120  }
121  }
122  }
123  if (nWrite >= fLenBuffer) {
124  if (fLenBuffer > 0) {
125  fStream->write(fBuffer, fLenBuffer);
126  fNByte += fLenBuffer;
127  nWrite -= fLenBuffer;
128  fLenBuffer = 0;
129  }
130  if (nWrite > 0) {
131  fStream->write(str, nWrite);
132  len -= nWrite;
133  str += nWrite;
134  fNByte += nWrite;
135  }
136  } else {
137  if (nWrite > 0) {
138  fStream->write(fBuffer, nWrite);
139  fNByte += nWrite;
140  memmove(fBuffer, fBuffer + nWrite, fLenBuffer - nWrite); // not strcpy because source and destination overlap
141  fBuffer[fLenBuffer - nWrite] = 0; // not sure if this is needed, but just in case
142  fLenBuffer -= nWrite;
143  }
144  }
145  if (fImplicitCREsc) {
146  // Write escape characters (if any) before an end-of-line is enforced.
147  // For example, in PostScript the <new line> character must be escaped inside strings.
148  Int_t crlen = strlen(fImplicitCREsc);
149  fStream->write(fImplicitCREsc, crlen);
150  fNByte += crlen;
151  }
152  fStream->write("\n",1);
153  fNByte++;
154  }
155  if (len > 0) {
156  strlcpy(fBuffer + fLenBuffer, str, len+1);
157  fLenBuffer += len;
158  fBuffer[fLenBuffer] = 0;
159  }
160  fPrinted = kTRUE;
161 }
162 
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// Write one Integer to the file
166 ///
167 /// n: Integer to be written in the file.
168 /// space: If TRUE, a space in written before the integer.
169 
170 void TVirtualPS::WriteInteger(Int_t n, Bool_t space )
171 {
172  char str[15];
173  if (space) {
174  snprintf(str,15," %d", n);
175  } else {
176  snprintf(str,15,"%d", n);
177  }
178  PrintStr(str);
179 }
180 
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Write a Real number to the file
184 
185 void TVirtualPS::WriteReal(Float_t z, Bool_t space)
186 {
187  char str[15];
188  if (space) {
189  snprintf(str,15," %g", z);
190  } else {
191  snprintf(str,15,"%g", z);
192  }
193  PrintStr(str);
194 }
195 
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Print a raw
199 
200 void TVirtualPS::PrintRaw(Int_t len, const char *str)
201 {
202  fNByte += len;
203  if ((len + fLenBuffer) > kMaxBuffer - 1) {
204  fStream->write(fBuffer, fLenBuffer);
205  while(len > kMaxBuffer-1) {
206  fStream->write(str,kMaxBuffer);
207  len -= kMaxBuffer;
208  str += kMaxBuffer;
209  }
210  memcpy(fBuffer, str, len);
211  fLenBuffer = len;
212  } else {
213  memcpy(fBuffer + fLenBuffer, str, len);
214  fLenBuffer += len;
215  }
216  fPrinted = kTRUE;
217 }