#ifdef WIN32
#pragma optimize("",off)
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include "Riostream.h"
#include "Byteswap.h"
#include "TROOT.h"
#include "TColor.h"
#include "TVirtualPad.h"
#include "TPoints.h"
#include "TPostScript.h"
#include "TStyle.h"
#include "TMath.h"
#include "TText.h"
#include "TSystem.h"
#include "TEnv.h"
#include "../../../graf2d/mathtext/inc/fontembed.h"
const Float_t kScale = 0.93376068;
Int_t TPostScript::fgLineJoin = 0;
ClassImp(TPostScript)
TPostScript::TPostScript() : TVirtualPS()
{
fStream = 0;
fType = 0;
gVirtualPS = this;
fBlue = 0.;
fBoundingBox = kFALSE;
fClear = kFALSE;
fClip = 0;
fClipStatus = kFALSE;
fCurrentColor = 0;
fDXC = 0.;
fDYC = 0.;
fFX = 0.;
fFY = 0.;
fGreen = 0.;
fIXzone = 0;
fIYzone = 0;
fLastCellBlue = 0;
fLastCellGreen = 0;
fLastCellRed = 0;
fLineJoin = 0;
fLineScale = 0.;
fMarkerSizeCur = 0.;
fMaxLines = 0;
fMaxsize = 0;
fMode = 0;
fNBSameColorCell = 0;
fNXzone = 0;
fNYzone = 0;
fNbCellLine = 0;
fNbCellW = 0;
fNbinCT = 0;
fNpages = 0;
fRange = kFALSE;
fRed = 0.;
fSave = 0;
fX1v = 0.;
fX1w = 0.;
fX2v = 0.;
fX2w = 0.;
fXC = 0.;
fXVP1 = 0.;
fXVP2 = 0.;
fXVS1 = 0.;
fXVS2 = 0.;
fXsize = 0.;
fY1v = 0.;
fY1w = 0.;
fY2v = 0.;
fY2w = 0.;
fYC = 0.;
fYVP1 = 0.;
fYVP2 = 0.;
fYVS1 = 0.;
fYVS2 = 0.;
fYsize = 0.;
fZone = kFALSE;
fFileName = "";
fFontEmbed = kFALSE;
for (Int_t i=0; i<32; i++) fPatterns[i]=0;
SetTitle("PS");
}
TPostScript::TPostScript(const char *fname, Int_t wtype)
:TVirtualPS(fname, wtype)
{
fStream = 0;
SetTitle("PS");
Open(fname, wtype);
}
void TPostScript::Open(const char *fname, Int_t wtype)
{
if (fStream) {
Warning("Open", "postscript file already open");
return;
}
fMarkerSizeCur = 0;
fCurrentColor = 0;
fRed = -1;
fGreen = -1;
fBlue = -1;
fLenBuffer = 0;
fClip = 0;
fType = abs(wtype);
fClear = kTRUE;
fZone = kFALSE;
fSave = 0;
fFontEmbed = kFALSE;
SetLineScale(gStyle->GetLineScalePS());
gStyle->GetPaperSize(fXsize, fYsize);
fMode = fType%10;
Float_t xrange, yrange;
if (gPad) {
Double_t ww = gPad->GetWw();
Double_t wh = gPad->GetWh();
if (fType == 113) {
ww *= gPad->GetWNDC();
wh *= gPad->GetHNDC();
}
Double_t ratio = wh/ww;
if (fType == 112) {
xrange = fYsize;
yrange = xrange*ratio;
if (yrange > fXsize) { yrange = fXsize; xrange = yrange/ratio;}
} else {
xrange = fXsize;
yrange = fXsize*ratio;
if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
}
fXsize = xrange; fYsize = yrange;
}
fFileName = fname;
fStream = new std::ofstream(fFileName.Data(),std::ios::out);
if (fStream == 0 || gSystem->AccessPathName(fFileName.Data(),kWritePermission)) {
printf("ERROR in TPostScript::Open: Cannot open file:%s\n",fFileName.Data());
return;
}
gVirtualPS = this;
for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
if( fType == 113) {
fBoundingBox = kFALSE;
PrintStr("%!PS-Adobe-2.0 EPSF-2.0@");
} else {
fBoundingBox = kTRUE;
PrintStr("%!PS-Adobe-2.0@");
Initialize();
}
fClipStatus = kFALSE;
fRange = kFALSE;
Range(fXsize, fYsize);
fPrinted = kFALSE;
if (fType == 113) NewPage();
}
TPostScript::~TPostScript()
{
Close();
}
void TPostScript::Close(Option_t *)
{
if (!gVirtualPS) return;
if (!fStream) return;
if (gPad) gPad->Update();
if( fMode != 3) {
SaveRestore(-1);
if( fPrinted ) { PrintStr("showpage@"); SaveRestore(-1);}
PrintStr("@");
PrintStr("%%Trailer@");
PrintStr("%%Pages: ");
WriteInteger(fNpages);
PrintStr("@");
while (fSave > 0) { SaveRestore(-1); }
} else {
PrintStr("@");
while (fSave > 0) { SaveRestore(-1); }
PrintStr("showpage@");
PrintStr("end@");
}
PrintStr("@");
PrintStr("%%EOF@");
fFontEmbed = kFALSE;
if (fStream) { fStream->close(); delete fStream; fStream = 0;}
gVirtualPS = 0;
}
void TPostScript::On()
{
if (!fType) {
Error("On", "no postscript file open");
Off();
return;
}
gVirtualPS = this;
}
void TPostScript::Off()
{
gVirtualPS = 0;
}
void TPostScript::CellArrayBegin(Int_t W, Int_t , Double_t x1, Double_t x2,
Double_t y1, Double_t y2)
{
Int_t ix1 = XtoPS(x1);
Int_t iy1 = YtoPS(y1);
Float_t wt = (288/2.54)*gPad->GetAbsWNDC()*
fXsize*((x2 - x1)/(gPad->GetX2()-gPad->GetX1()));
Float_t ht = (288/2.54)*gPad->GetAbsHNDC()*
fYsize*((y2 - y1)/(gPad->GetY2()-gPad->GetY1()));
fLastCellRed = 300;
fLastCellGreen = 300;
fLastCellBlue = 300;
fNBSameColorCell = 0;
fNbinCT = 0;
fNbCellW = W;
fNbCellLine = 0;
fMaxLines = 40000/(3*fNbCellW);
PrintStr("@/WT"); WriteReal(wt) ; PrintStr(" def");
PrintStr(" /HT"); WriteReal(ht) ; PrintStr(" def");
PrintStr(" /XS"); WriteInteger(ix1) ; PrintStr(" def");
PrintStr(" /YY"); WriteInteger(iy1) ; PrintStr(" def");
PrintStr(" /NX"); WriteInteger(W) ; PrintStr(" def");
PrintStr(" /NY"); WriteInteger(fMaxLines); PrintStr(" def");
PrintStr(" /DrawCell ");
PrintStr( "{WT HT XX YY bf");
PrintStr( " /NBBD NBBD 1 add def");
PrintStr( " NBBD NBB eq {exit} if");
PrintStr( " /XX WT XX add def");
PrintStr( " IX NX eq ");
PrintStr( "{/YY YY HT sub def");
PrintStr( " /XX XS def");
PrintStr( " /IX 0 def} if");
PrintStr( " /IX IX 1 add def} def");
PrintStr(" /DrawCT ");
PrintStr( "{/NBB NX NY mul def");
PrintStr( " /XX XS def");
PrintStr( " /IX 1 def");
PrintStr( " /NBBD 0 def");
PrintStr( " /RC 0 def /GC 1 def /BC 2 def");
PrintStr( " 1 1 NBB ");
PrintStr( "{/NB CT RC get def");
PrintStr( " NB 301 ge ");
PrintStr( "{/NBL NB 300 sub def");
PrintStr( " 1 1 NBL ");
PrintStr( "{DrawCell}");
PrintStr( " for");
PrintStr( " /RC RC 1 add def");
PrintStr( " /GC RC 1 add def");
PrintStr( " /BC RC 2 add def}");
PrintStr( "{CT RC get 255 div CT GC get 255 div CT BC get 255 div setrgbcolor");
PrintStr( " DrawCell");
PrintStr( " /RC RC 3 add def");
PrintStr( " /GC GC 3 add def");
PrintStr( " /BC BC 3 add def} ifelse NBBD NBB eq {exit} if} for");
PrintStr( " /YY YY HT sub def clear} def");
PrintStr(" /CT [");
}
void TPostScript::CellArrayFill(Int_t r, Int_t g, Int_t b)
{
if (fLastCellRed == r && fLastCellGreen == g && fLastCellBlue == b) {
fNBSameColorCell++;
} else {
if (fNBSameColorCell != 0 ) {
WriteInteger(fNBSameColorCell+300);
fNBSameColorCell = 0;
}
WriteInteger(r);
WriteInteger(g);
WriteInteger(b);
fLastCellRed = r;
fLastCellGreen = g;
fLastCellBlue = b;
}
fNbinCT++;
if (fNbinCT == fNbCellW) {
fNbCellLine++;
fNbinCT = 0;
}
if (fNbCellLine == fMaxLines) {
if (fNBSameColorCell != 0) WriteInteger(fNBSameColorCell+300);
PrintStr("] def DrawCT /CT [");
fNbCellLine = 0;
fLastCellRed = 300;
fLastCellGreen = 300;
fLastCellBlue = 300;
fNBSameColorCell = 0;
fNbinCT = 0;
}
}
void TPostScript::CellArrayEnd()
{
if (fNBSameColorCell != 0 ) WriteInteger(fNBSameColorCell+300);
PrintStr("] def /NY");
WriteInteger(fNbCellLine);
PrintStr(" def DrawCT ");
}
void TPostScript::DefineMarkers()
{
PrintStr("/mp {newpath /y exch def /x exch def} def@");
PrintStr("/side {[w .77 mul w .23 mul] .385 w mul sd w 0 l currentpoint t -144 r} def@");
PrintStr("/mr {mp x y w2 0 360 arc} def /m24 {mr s} def /m20 {mr f} def@");
PrintStr("/mb {mp x y w2 add m w2 neg 0 d 0 w neg d w 0 d 0 w d cl} def@");
PrintStr("/mt {mp x y w2 add m w2 neg w neg d w 0 d cl} def@");
PrintStr("/m21 {mb f} def /m25 {mb s} def /m22 {mt f} def /m26{mt s} def@");
PrintStr("/m23 {mp x y w2 sub m w2 w d w neg 0 d cl f} def@");
PrintStr("/m27 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl s} def@");
PrintStr("/m28 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
PrintStr(" 0 w3 neg d w3 neg 0 d cl s } def@");
PrintStr("/m29 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
PrintStr(" 4 {side} repeat cl fill gr} def@");
PrintStr("/m30 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
PrintStr(" 4 {side} repeat cl s gr} def@");
PrintStr("/m31 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d");
PrintStr(" x w2 sub y w2 add m w w neg d x w2 sub y w2");
PrintStr(" sub m w w d s} def@");
PrintStr("/m32 {mp x y w2 sub m w2 w d w neg 0 d cl s} def@");
PrintStr("/m33 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl f} def@");
PrintStr("/m34 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
PrintStr(" 0 w3 neg d w3 neg 0 d cl f } def@");
PrintStr("/m2 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d s} def@");
PrintStr("/m5 {mp x w2 sub y w2 sub m w w d x w2 sub y w2 add m w w neg d s} def@");
}
void TPostScript::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
static Double_t x[4], y[4];
Int_t ix1 = XtoPS(x1);
Int_t ix2 = XtoPS(x2);
Int_t iy1 = YtoPS(y1);
Int_t iy2 = YtoPS(y2);
Int_t fillis = fFillStyle/1000;
Int_t fillsi = fFillStyle%1000;
if (fillis == 3 || fillis == 2) {
if (fillsi > 99) {
x[0] = x1; y[0] = y1;
x[1] = x2; y[1] = y1;
x[2] = x2; y[2] = y2;
x[3] = x1; y[3] = y2;
return;
}
if (fillsi > 0 && fillsi < 26) {
x[0] = x1; y[0] = y1;
x[1] = x2; y[1] = y1;
x[2] = x2; y[2] = y2;
x[3] = x1; y[3] = y2;
DrawPS(-4, &x[0], &y[0]);
}
if (fillsi == -3) {
SetColor(5);
WriteInteger(ix2 - ix1);
WriteInteger(iy2 - iy1);
WriteInteger(ix1);
WriteInteger(iy1);
PrintFast(3," bf");
}
}
if (fillis == 1) {
SetColor(fFillColor);
WriteInteger(ix2 - ix1);
WriteInteger(iy2 - iy1);
WriteInteger(ix1);
WriteInteger(iy1);
PrintFast(3," bf");
}
if (fillis == 0) {
SetColor(fLineColor);
WriteInteger(ix2 - ix1);
WriteInteger(iy2 - iy1);
WriteInteger(ix1);
WriteInteger(iy1);
PrintFast(3," bl");
}
}
void TPostScript::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt,
Int_t mode, Int_t border, Int_t dark, Int_t light)
{
static Int_t xps[7], yps[7];
Int_t i, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
if (mode == -1) SetColor(dark);
else SetColor(light);
Int_t bordPS = 4*border;
xps[0] = XtoPS(xl); yps[0] = YtoPS(yl);
xps[1] = xps[0] + bordPS; yps[1] = yps[0] + bordPS;
xps[2] = xps[1]; yps[2] = YtoPS(yt) - bordPS;
xps[3] = XtoPS(xt) - bordPS; yps[3] = yps[2];
xps[4] = XtoPS(xt); yps[4] = YtoPS(yt);
xps[5] = xps[0]; yps[5] = yps[4];
xps[6] = xps[0]; yps[6] = yps[0];
ixd0 = xps[0];
iyd0 = yps[0];
WriteInteger(ixd0);
WriteInteger(iyd0);
PrintFast(2," m");
idx = 0;
idy = 0;
for (i=1;i<7;i++) {
ixdi = xps[i];
iydi = yps[i];
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
continue;
}
if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0; }
if( !idx ) { idx = ix; continue;}
if( ix*idx > 0 ) idx += ix;
else { MovePS(idx,0); idx = ix; }
continue;
}
if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( !idy) { idy = iy; continue;}
if( iy*idy > 0 ) idy += iy;
else { MovePS(0,idy); idy = iy; }
}
}
if( idx ) MovePS(idx,0);
if( idy ) MovePS(0,idy);
PrintFast(2," f");
if (mode == -1) SetColor(light);
else SetColor(dark);
xps[0] = XtoPS(xl); yps[0] = YtoPS(yl);
xps[1] = xps[0] + bordPS; yps[1] = yps[0] + bordPS;
xps[2] = XtoPS(xt) - bordPS; yps[2] = yps[1];
xps[3] = xps[2]; yps[3] = YtoPS(yt) - bordPS;
xps[4] = XtoPS(xt); yps[4] = YtoPS(yt);
xps[5] = xps[4]; yps[5] = yps[0];
xps[6] = xps[0]; yps[6] = yps[0];
ixd0 = xps[0];
iyd0 = yps[0];
WriteInteger(ixd0);
WriteInteger(iyd0);
PrintFast(2," m");
idx = 0;
idy = 0;
for (i=1;i<7;i++) {
ixdi = xps[i];
iydi = yps[i];
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
continue;
}
if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0; }
if( !idx ) { idx = ix; continue;}
if( ix*idx > 0 ) idx += ix;
else { MovePS(idx,0); idx = ix; }
continue;
}
if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( !idy) { idy = iy; continue;}
if( iy*idy > 0 ) idy += iy;
else { MovePS(0,idy); idy = iy; }
}
}
if( idx ) MovePS(idx,0);
if( idy ) MovePS(0,idy);
PrintFast(2," f");
}
void TPostScript::DrawPolyLine(Int_t nn, TPoints *xy)
{
Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
if (nn > 0) {
n = nn;
SetLineStyle(fLineStyle);
SetLineWidth(fLineWidth);
SetColor(Int_t(fLineColor));
} else {
n = -nn;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fLineColor));
}
ixd0 = XtoPS(xy[0].GetX());
iyd0 = YtoPS(xy[0].GetY());
WriteInteger(ixd0);
WriteInteger(iyd0);
if( n <= 1) {
if( n == 0) goto END;
PrintFast(2," m");
goto END;
}
PrintFast(2," m");
idx = 0;
idy = 0;
for (i=1;i<n;i++) {
ixdi = XtoPS(xy[i].GetX());
iydi = YtoPS(xy[i].GetY());
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
continue;
}
if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0; }
if( !idx ) { idx = ix; continue;}
if( ix*idx > 0 ) idx += ix;
else { MovePS(idx,0); idx = ix; }
continue;
}
if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( !idy) { idy = iy; continue;}
if( iy*idy > 0 ) idy += iy;
else { MovePS(0,idy); idy = iy; }
}
}
if( idx ) MovePS(idx,0);
if( idy ) MovePS(0,idy);
if (nn > 0 ) {
if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
PrintFast(2," s");
} else {
PrintFast(2," f");
}
END:
if (nn < 0) {
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
}
void TPostScript::DrawPolyLineNDC(Int_t nn, TPoints *xy)
{
Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
if (nn > 0) {
n = nn;
SetLineStyle(fLineStyle);
SetLineWidth(fLineWidth);
SetColor(Int_t(fLineColor));
} else {
n = -nn;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fLineColor));
}
ixd0 = UtoPS(xy[0].GetX());
iyd0 = VtoPS(xy[0].GetY());
WriteInteger(ixd0);
WriteInteger(iyd0);
if( n <= 1) {
if( n == 0) goto END;
PrintFast(2," m");
goto END;
}
PrintFast(2," m");
idx = 0;
idy = 0;
for (i=1;i<n;i++) {
ixdi = UtoPS(xy[i].GetX());
iydi = VtoPS(xy[i].GetY());
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
continue;
}
if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0; }
if( !idx ) { idx = ix; continue;}
if( ix*idx > 0 ) idx += ix;
else { MovePS(idx,0); idx = ix; }
continue;
}
if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( !idy) { idy = iy; continue;}
if( iy*idy > 0 ) idy += iy;
else { MovePS(0,idy); idy = iy; }
}
}
if( idx ) MovePS(idx,0);
if( idy ) MovePS(0,idy);
if (nn > 0 ) {
if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
PrintFast(2," s");
} else {
PrintFast(2," f");
}
END:
if (nn < 0) {
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
}
void TPostScript::DrawPolyMarker(Int_t n, Float_t *x, Float_t *y)
{
Int_t i, np, markerstyle;
Float_t markersize;
static char chtemp[10];
if (!fMarkerSize) return;
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fMarkerColor));
markerstyle = abs(fMarkerStyle);
if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
if (markerstyle == 1) strlcpy(chtemp, " m20",10);
if (markerstyle == 2) strlcpy(chtemp, " m2",10);
if (markerstyle == 3) strlcpy(chtemp, " m31",10);
if (markerstyle == 4) strlcpy(chtemp, " m24",10);
if (markerstyle == 5) strlcpy(chtemp, " m5",10);
if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
if (markerstyle == 1) {
markersize = 2.;
} else if (markerstyle == 6) {
markersize = 4.;
} else if (markerstyle == 7) {
markersize = 8.;
} else {
Float_t symbolsize = fMarkerSize;
const Int_t kBASEMARKER = 8;
Float_t sbase = symbolsize*kBASEMARKER;
Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
markersize = this->UtoPS(s2x) - this->UtoPS(0);
}
if (fMarkerSizeCur != markersize) {
fMarkerSizeCur = markersize;
PrintFast(3," /w");
WriteInteger(Int_t(markersize+0.5));
PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
}
WriteInteger(XtoPS(x[0]));
WriteInteger(YtoPS(y[0]));
if (n == 1) {
PrintStr(chtemp);
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
return;
}
np = 1;
for (i=1;i<n;i++) {
WriteInteger(XtoPS(x[i]));
WriteInteger(YtoPS(y[i]));
np++;
if (np == 100 || i == n-1) {
WriteInteger(np);
PrintFast(2," {");
PrintStr(chtemp);
PrintFast(3,"} R");
np = 0;
}
}
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
void TPostScript::DrawPolyMarker(Int_t n, Double_t *x, Double_t *y)
{
Int_t i, np, markerstyle;
Float_t markersize;
static char chtemp[10];
if (!fMarkerSize) return;
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fMarkerColor));
markerstyle = abs(fMarkerStyle);
if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
if (markerstyle == 1) strlcpy(chtemp, " m20",10);
if (markerstyle == 2) strlcpy(chtemp, " m2",10);
if (markerstyle == 3) strlcpy(chtemp, " m31",10);
if (markerstyle == 4) strlcpy(chtemp, " m24",10);
if (markerstyle == 5) strlcpy(chtemp, " m5",10);
if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
if (markerstyle == 1) {
markersize = 2.;
} else if (markerstyle == 6) {
markersize = 4.;
} else if (markerstyle == 7) {
markersize = 8.;
} else {
Float_t symbolsize = fMarkerSize;
const Int_t kBASEMARKER = 8;
Float_t sbase = symbolsize*kBASEMARKER;
Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
markersize = this->UtoPS(s2x) - this->UtoPS(0);
}
if (fMarkerSizeCur != markersize) {
fMarkerSizeCur = markersize;
PrintFast(3," /w");
WriteInteger(Int_t(markersize+0.5));
PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
}
WriteInteger(XtoPS(x[0]));
WriteInteger(YtoPS(y[0]));
if (n == 1) {
PrintStr(chtemp);
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
return;
}
np = 1;
for (i=1;i<n;i++) {
WriteInteger(XtoPS(x[i]));
WriteInteger(YtoPS(y[i]));
np++;
if (np == 100 || i == n-1) {
WriteInteger(np);
PrintFast(2," {");
PrintStr(chtemp);
PrintFast(3,"} R");
np = 0;
}
}
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
void TPostScript::DrawPS(Int_t nn, Float_t *xw, Float_t *yw)
{
static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
180, 90,135, 45,150, 30,120, 60,
180, 90,135, 45,150, 30,120, 60};
Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
fais = fasi = n = 0;
Int_t jxd0 = XtoPS(xw[0]);
Int_t jyd0 = YtoPS(yw[0]);
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
if (nn > 0) {
n = nn;
SetLineStyle(fLineStyle);
SetLineWidth(fLineWidth);
SetColor(Int_t(fLineColor));
}
if (nn < 0) {
n = -nn;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fFillColor));
fais = fFillStyle/1000;
fasi = fFillStyle%1000;
if (fais == 3 || fais == 2) {
if (fasi > 100 && fasi <125) {
DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
goto END;
}
if (fasi > 0 && fasi < 26) {
SetFillPatterns(fasi, Int_t(fFillColor));
}
}
}
ixd0 = jxd0;
iyd0 = jyd0;
WriteInteger(ixd0);
WriteInteger(iyd0);
if( n <= 1) {
if( n == 0) goto END;
PrintFast(2," m");
goto END;
}
PrintFast(2," m");
idx = idy = 0;
for (i=1;i<n;i++) {
ixdi = XtoPS(xw[i]);
iydi = YtoPS(yw[i]);
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
} else if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0;}
if( !idx ) { idx = ix;}
else if( TMath::Sign(ix,idx) == ix ) idx += ix;
else { MovePS(idx,0); idx = ix;}
} else if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0;}
if( !idy) { idy = iy;}
else if( TMath::Sign(iy,idy) == iy) idy += iy;
else { MovePS(0,idy); idy = iy;}
}
}
if (idx) MovePS(idx,0);
if (idy) MovePS(0,idy);
if (nn > 0 ) {
if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
PrintFast(2," s");
} else {
if (fais == 0) {PrintFast(5," cl s"); goto END;}
if (fais == 3 || fais == 2) {
if (fasi > 0 && fasi < 26) {
PrintFast(3," FA");
fRed = -1;
fGreen = -1;
fBlue = -1;
}
goto END;
}
PrintFast(2," f");
}
END:
if (nn < 0) {
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
}
void TPostScript::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
{
static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
180, 90,135, 45,150, 30,120, 60,
180, 90,135, 45,150, 30,120, 60};
Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
fais = fasi = n = 0;
Int_t jxd0 = XtoPS(xw[0]);
Int_t jyd0 = YtoPS(yw[0]);
Style_t linestylesav = fLineStyle;
Width_t linewidthsav = fLineWidth;
if (nn > 0) {
n = nn;
SetLineStyle(fLineStyle);
SetLineWidth(fLineWidth);
SetColor(Int_t(fLineColor));
}
if (nn < 0) {
n = -nn;
SetLineStyle(1);
SetLineWidth(1);
SetColor(Int_t(fFillColor));
fais = fFillStyle/1000;
fasi = fFillStyle%1000;
if (fais == 3 || fais == 2) {
if (fasi > 100 && fasi <125) {
DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
goto END;
}
if (fasi > 0 && fasi < 26) {
SetFillPatterns(fasi, Int_t(fFillColor));
}
}
}
ixd0 = jxd0;
iyd0 = jyd0;
WriteInteger(ixd0);
WriteInteger(iyd0);
if( n <= 1) {
if( n == 0) goto END;
PrintFast(2," m");
goto END;
}
PrintFast(2," m");
idx = idy = 0;
for (i=1;i<n;i++) {
ixdi = XtoPS(xw[i]);
iydi = YtoPS(yw[i]);
ix = ixdi - ixd0;
iy = iydi - iyd0;
ixd0 = ixdi;
iyd0 = iydi;
if( ix && iy) {
if( idx ) { MovePS(idx,0); idx = 0; }
if( idy ) { MovePS(0,idy); idy = 0; }
MovePS(ix,iy);
} else if ( ix ) {
if( idy ) { MovePS(0,idy); idy = 0;}
if( !idx ) { idx = ix;}
else if( TMath::Sign(ix,idx) == ix ) idx += ix;
else { MovePS(idx,0); idx = ix;}
} else if( iy ) {
if( idx ) { MovePS(idx,0); idx = 0;}
if( !idy) { idy = iy;}
else if( TMath::Sign(iy,idy) == iy) idy += iy;
else { MovePS(0,idy); idy = iy;}
}
}
if (idx) MovePS(idx,0);
if (idy) MovePS(0,idy);
if (nn > 0 ) {
if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
PrintFast(2," s");
} else {
if (fais == 0) {PrintFast(5," cl s"); goto END;}
if (fais == 3 || fais == 2) {
if (fasi > 0 && fasi < 26) {
PrintFast(3," FA");
fRed = -1;
fGreen = -1;
fBlue = -1;
}
goto END;
}
PrintFast(2," f");
}
END:
if (nn < 0) {
SetLineStyle(linestylesav);
SetLineWidth(linewidthsav);
}
}
void TPostScript::DrawHatch(Float_t, Float_t, Int_t, Float_t *, Float_t *)
{
Warning("DrawHatch", "hatch fill style not yet implemented");
}
void TPostScript::DrawHatch(Float_t, Float_t, Int_t, Double_t *, Double_t *)
{
Warning("DrawHatch", "hatch fill style not yet implemented");
}
Bool_t TPostScript::FontEmbedType1(const char *filename)
{
std::ifstream font_file(filename, std::ios::binary);
font_file.seekg(0, std::ios::end);
const size_t font_file_length = font_file.tellg();
font_file.seekg(0, std::ios::beg);
std::vector<unsigned char> font_data(font_file_length, '\0');
font_file.read(reinterpret_cast<char *>(&font_data[0]),
font_file_length);
std::string font_name;
std::string postscript_string =
mathtext::font_embed_postscript_t::font_embed_type_1(
font_name, font_data);
if (!postscript_string.empty()) {
PrintRaw(postscript_string.size(), postscript_string.data());
PrintStr("@");
return true;
}
return false;
}
Bool_t TPostScript::FontEmbedType2(const char *filename)
{
std::ifstream font_file(filename, std::ios::binary);
font_file.seekg(0, std::ios::end);
const size_t font_file_length = font_file.tellg();
font_file.seekg(0, std::ios::beg);
std::vector<unsigned char> font_data(font_file_length, '\0');
font_file.read(reinterpret_cast<char *>(&font_data[0]),
font_file_length);
std::string font_name;
std::string postscript_string =
mathtext::font_embed_postscript_t::font_embed_type_2(
font_name, font_data);
if (!postscript_string.empty()) {
PrintRaw(postscript_string.size(), postscript_string.data());
PrintStr("@");
return true;
}
return false;
}
Bool_t TPostScript::FontEmbedType42(const char *filename)
{
std::ifstream font_file(filename, std::ios::binary);
font_file.seekg(0, std::ios::end);
const size_t font_file_length = font_file.tellg();
font_file.seekg(0, std::ios::beg);
std::vector<unsigned char> font_data(font_file_length, '\0');
font_file.read(reinterpret_cast<char *>(&font_data[0]),
font_file_length);
std::string font_name;
std::string postscript_string =
mathtext::font_embed_postscript_t::font_embed_type_42(
font_name, font_data);
if (!postscript_string.empty()) {
PrintRaw(postscript_string.size(), postscript_string.data());
PrintStr("@");
return true;
}
fprintf(stderr, "%s:%d:\n", __FILE__, __LINE__);
return false;
}
void TPostScript::FontEmbed(void)
{
static const char *fonttable[32][2] = {
{ "Root.TTFont.0", "FreeSansBold.otf" },
{ "Root.TTFont.1", "FreeSerifItalic.otf" },
{ "Root.TTFont.2", "FreeSerifBold.otf" },
{ "Root.TTFont.3", "FreeSerifBoldItalic.otf" },
{ "Root.TTFont.4", "FreeSans.otf" },
{ "Root.TTFont.5", "FreeSansOblique.otf" },
{ "Root.TTFont.6", "FreeSansBold.otf" },
{ "Root.TTFont.7", "FreeSansBoldOblique.otf" },
{ "Root.TTFont.8", "FreeMono.otf" },
{ "Root.TTFont.9", "FreeMonoOblique.otf" },
{ "Root.TTFont.10", "FreeMonoBold.otf" },
{ "Root.TTFont.11", "FreeMonoBoldOblique.otf" },
{ "Root.TTFont.12", "symbol.ttf" },
{ "Root.TTFont.13", "FreeSerif.otf" },
{ "Root.TTFont.14", "wingding.ttf" },
{ "Root.TTFont.15", "symbol.ttf" },
{ "Root.TTFont.STIXGen", "STIXGeneral.otf" },
{ "Root.TTFont.STIXGenIt", "STIXGeneralItalic.otf" },
{ "Root.TTFont.STIXGenBd", "STIXGeneralBol.otf" },
{ "Root.TTFont.STIXGenBdIt", "STIXGeneralBolIta.otf" },
{ "Root.TTFont.STIXSiz1Sym", "STIXSiz1Sym.otf" },
{ "Root.TTFont.STIXSiz1SymBd", "STIXSiz1SymBol.otf" },
{ "Root.TTFont.STIXSiz2Sym", "STIXSiz2Sym.otf" },
{ "Root.TTFont.STIXSiz2SymBd", "STIXSiz2SymBol.otf" },
{ "Root.TTFont.STIXSiz3Sym", "STIXSiz3Sym.otf" },
{ "Root.TTFont.STIXSiz3SymBd", "STIXSiz3SymBol.otf" },
{ "Root.TTFont.STIXSiz4Sym", "STIXSiz4Sym.otf" },
{ "Root.TTFont.STIXSiz4SymBd", "STIXSiz4SymBol.otf" },
{ "Root.TTFont.STIXSiz5Sym", "STIXSiz5Sym.otf" },
{ "Root.TTFont.ME", "DroidSansFallback.ttf" },
{ "Root.TTFont.CJKMing", "DroidSansFallback.ttf" },
{ "Root.TTFont.CJKCothic", "DroidSansFallback.ttf" }
};
PrintStr("%%IncludeResource: ProcSet (FontSetInit)@");
const char *ttpath = gEnv->GetValue("Root.TTFontPath",
#ifdef TTFFONTDIR
TTFFONTDIR
#else // TTFFONTDIR
"$(ROOTSYS)/fonts"
#endif // TTFFONTDIR
);
for (Int_t fontid = 1; fontid < 30; fontid++) {
if (fontid != 15) {
const char *filename = gEnv->GetValue(
fonttable[fontid][0], fonttable[fontid][1]);
char *ttfont = gSystem->Which(ttpath, filename,
kReadPermission);
if(!ttfont) {
Error("TPostScript::FontEmbed",
"font %d (filename `%s') not found in path",
fontid, filename);
} else {
if (FontEmbedType2(ttfont)) {
} else if(FontEmbedType1(ttfont)) {
} else if(FontEmbedType42(ttfont)) {
} else {
Error("TPostScript::FontEmbed",
"failed to embed font %d (filename `%s')",
fontid, filename);
}
delete [] ttfont;
}
}
}
PrintStr("%%IncludeResource: font Times-Roman@");
PrintStr("%%IncludeResource: font Times-Italic@");
PrintStr("%%IncludeResource: font Times-Bold@");
PrintStr("%%IncludeResource: font Times-BoldItalic@");
PrintStr("%%IncludeResource: font Helvetica@");
PrintStr("%%IncludeResource: font Helvetica-Oblique@");
PrintStr("%%IncludeResource: font Helvetica-Bold@");
PrintStr("%%IncludeResource: font Helvetica-BoldOblique@");
PrintStr("%%IncludeResource: font Courier@");
PrintStr("%%IncludeResource: font Courier-Oblique@");
PrintStr("%%IncludeResource: font Courier-Bold@");
PrintStr("%%IncludeResource: font Courier-BoldOblique@");
PrintStr("%%IncludeResource: font Symbol@");
PrintStr("%%IncludeResource: font ZapfDingbats@");
fFontEmbed = kTRUE;
}
void TPostScript::FontEncode()
{
PrintStr("/reEncode ");
PrintStr("{exch findfont");
PrintStr(" dup length dict begin");
PrintStr(" {1 index /FID eq ");
PrintStr(" {pop pop}");
PrintStr(" {def} ifelse");
PrintStr(" } forall");
PrintStr(" /Encoding exch def");
PrintStr(" currentdict end");
PrintStr(" dup /FontName get exch");
PrintStr(" definefont pop");
PrintStr(" } def");
PrintStr(" [/Times-Bold /Times-Italic /Times-BoldItalic /Helvetica");
PrintStr(" /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique");
PrintStr(" /Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique");
PrintStr(" /Times-Roman /AvantGarde-Book /AvantGarde-BookOblique");
PrintStr(" /AvantGarde-Demi /AvantGarde-DemiOblique /Bookman-Demi");
PrintStr(" /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic");
PrintStr(" /Helvetica-Narrow /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique");
PrintStr(" /Helvetica-Narrow-Oblique /NewCenturySchlbk-Roman /NewCenturySchlbk-Bold");
PrintStr(" /NewCenturySchlbk-BoldItalic /NewCenturySchlbk-Italic");
PrintStr(" /Palatino-Bold /Palatino-BoldItalic /Palatino-Italic /Palatino-Roman");
PrintStr(" ] {ISOLatin1Encoding reEncode } forall");
}
void TPostScript::Initialize()
{
Double_t rpxmin, rpymin, width, heigth;
rpxmin = rpymin = width = heigth = 0;
Int_t format;
fNpages=1;
for (Int_t i=0;i<32;i++) fPatterns[i]=0;
Int_t atype = abs(fType);
fMode = atype%10;
if( fMode <= 0 || fMode > 5) {
Error("Initialize", "invalid file type %d", fMode);
return;
}
fNXzone = (atype%1000)/100;
fNYzone = (atype%100)/10;
if( fNXzone <= 0 ) fNXzone = 1;
if( fNYzone <= 0 ) fNYzone = 1;
fIXzone = 1;
fIYzone = 1;
format = atype/1000;
if( format == 0 ) format = 4;
if( format == 99 ) format = 0;
PrintStr("%%Title: ");
const char *pstitle = gStyle->GetTitlePS();
if (gPad && !strlen(pstitle)) pstitle = gPad->GetMother()->GetTitle();
if (strlen(GetName())<=80) PrintStr(GetName());
if(!strlen(pstitle) && fMode != 3) {;
PrintFast(2," (");
if ( format <= 99 ) {;
PrintFast(2," A");
WriteInteger(format);
PrintFast(1,")");
}
else {
if ( format == 100 ) PrintFast(8," Letter)");
if ( format == 200 ) PrintFast(7," Legal)");
if ( format == 300 ) PrintFast(8," Ledger)");
}
PrintStr("@");
PrintStr("%%Pages: (atend)@");
}
else {
if (!strchr(pstitle,'\n')) {
PrintFast(2,": ");
PrintStr(pstitle);
}
PrintStr("@");
}
PrintFast(24,"%%Creator: ROOT Version ");
PrintStr(gROOT->GetVersion());
PrintStr("@");
PrintFast(16,"%%CreationDate: ");
TDatime t;
PrintStr(t.AsString());
PrintStr("@");
if ( fMode == 1 || fMode == 4) PrintStr("%%Orientation: Portrait@");
if ( fMode == 2 || fMode == 5) PrintStr("%%Orientation: Landscape@");
PrintStr("%%EndComments@");
PrintStr("%%BeginProlog@");
if( fMode == 3)PrintStr("80 dict begin@");
PrintStr("/s {stroke} def /l {lineto} def /m {moveto} def /t {translate} def@");
PrintStr("/r {rotate} def /rl {roll} def /R {repeat} def@");
PrintStr("/d {rlineto} def /rm {rmoveto} def /gr {grestore} def /f {eofill} def@");
if (gStyle->GetColorModelPS()) {
PrintStr("/c {setcmykcolor} def /black {0 0 0 1 setcmykcolor} def /sd {setdash} def@");
} else {
PrintStr("/c {setrgbcolor} def /black {0 setgray} def /sd {setdash} def@");
}
PrintStr("/cl {closepath} def /sf {scalefont setfont} def /lw {setlinewidth} def@");
PrintStr("/box {m dup 0 exch d exch 0 d 0 exch neg d cl} def@");
PrintStr("/NC{systemdict begin initclip end}def/C{NC box clip newpath}def@");
PrintStr("/bl {box s} def /bf {gsave box gsave f grestore 1 lw [] 0 sd s grestore} def /Y { 0 exch d} def /X { 0 d} def @");
PrintStr("/K {{pop pop 0 moveto} exch kshow} bind def@");
PrintStr("/ita {/ang 15 def gsave [1 0 ang dup sin exch cos div 1 0 0] concat} def @");
DefineMarkers();
FontEncode();
if (fMode == 1) {
rpxmin = 0.7;
rpymin = TMath::Sqrt(2.)*rpxmin;
switch (format) {
case 100 :
width = (8.5*2.54)-2.*rpxmin;
heigth = (11.*2.54)-2.*rpymin;
break;
case 200 :
width = (8.5*2.54)-2.*rpxmin;
heigth = (14.*2.54)-2.*rpymin;
break;
case 300 :
width = (11.*2.54)-2.*rpxmin;
heigth = (17.*2.54)-2.*rpymin;
break;
default :
width = 21.0-2.*rpxmin;
heigth = 29.7-2.*rpymin;
};
}
if (fMode == 2) {
rpymin = 0.7;
rpxmin = TMath::Sqrt(2.)*rpymin;
switch (format) {
case 100 :
width = (11.*2.54)-2.*rpxmin;
heigth = (8.5*2.54)-2.*rpymin;
case 200 :
width = (14.*2.54)-2.*rpxmin;
heigth = (8.5*2.54)-2.*rpymin;
case 300 :
width = (17.*2.54)-2.*rpxmin;
heigth = (11.*2.54)-2.*rpymin;
default :
width = 29.7-2.*rpxmin;
heigth = 21-2.*rpymin;
};
}
if (fMode == 3) {
width = 20;
heigth = 20;
format = 4;
fNXzone = 1;
fNYzone = 1;
}
if (fMode == 4) {
rpxmin = 0.7;
rpymin = 3.4;
switch (format) {
case 100 :
width = (8.5*2.54)-2.*rpxmin;
heigth = (11.*2.54)-2.*rpymin;
case 200 :
width = (8.5*2.54)-2.*rpxmin;
heigth = (14.*2.54)-2.*rpymin;
case 300 :
width = (11.*2.54)-2.*rpxmin;
heigth = (17.*2.54)-2.*rpymin;
default :
width = (21.0-2*rpxmin);
heigth = (29.7-2.*rpymin);
};
}
if (fMode == 5) {
rpxmin = 3.4;
rpymin = 0.7;
switch (format) {
case 100 :
width = (11.*2.54)-2.*rpxmin;
heigth = (8.5*2.54)-2.*rpymin;
case 200 :
width = (14.*2.54)-2.*rpxmin;
heigth = (8.5*2.54)-2.*rpymin;
case 300 :
width = (17.*2.54)-2.*rpxmin;
heigth = (11.*2.54)-2.*rpymin;
default :
width = (29.7-2*rpxmin);
heigth = (21-2.*rpymin);
};
}
Double_t value = 0;
if (format < 100) value = 21*TMath::Power(TMath::Sqrt(2.), 4-format);
else if (format == 100) value = 8.5*2.54;
else if (format == 200) value = 8.5*2.54;
else if (format == 300) value = 11.*2.54;
if (format >= 100) format = 4;
Double_t sizex = width/Double_t(fNXzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
Double_t sizey = heigth/Double_t(fNYzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
Int_t npx = 4*CMtoPS(sizex);
Int_t npy = 4*CMtoPS(sizey);
if (sizex > sizey) fMaxsize = CMtoPS(sizex);
else fMaxsize = CMtoPS(sizey);
if (fMode != 3) {
PrintFast(33,"/Zone {/iy exch def /ix exch def ");
PrintFast(10," ix 1 sub ");
WriteInteger(npx);
PrintFast(5," mul ");
WriteReal(Float_t(fNYzone));
PrintFast(8," iy sub ");
WriteInteger(npy);
PrintStr(" mul t} def@");
} else {
PrintStr("@");
}
PrintStr("%%EndProlog@");
PrintStr("%%BeginSetup@");
PrintStr("%%EndSetup@");
PrintFast(8,"newpath ");
SaveRestore(1);
if (fMode == 1 || fMode == 4) {
WriteInteger(CMtoPS(rpxmin));
WriteInteger(CMtoPS(rpymin));
PrintFast(2," t");
}
if (fMode == 2 || fMode == 5) {
PrintFast(7," 90 r 0");
WriteInteger(CMtoPS(-value));
PrintFast(3," t ");
WriteInteger(CMtoPS(rpxmin));
WriteInteger(CMtoPS(rpymin));
PrintFast(2," t");
}
PrintFast(15," .25 .25 scale ");
if (fMode != 3) {
SaveRestore(1);
PrintStr("@");
PrintStr("%%Page: 1 1@");
SaveRestore(1);
}
Int_t nh = strlen(gStyle->GetHeaderPS());
if (nh) {
PrintFast(nh,gStyle->GetHeaderPS());
if (fMode != 3) SaveRestore(1);
}
}
void TPostScript::MovePS(Int_t ix, Int_t iy)
{
if (ix != 0 && iy != 0) {
WriteInteger(ix);
WriteInteger(iy);
PrintFast(2," d");
} else if (ix != 0) {
WriteInteger(ix);
PrintFast(2," X");
} else if (iy != 0) {
WriteInteger(iy);
PrintFast(2," Y");
}
}
void TPostScript::NewPage()
{
if (gPad) {
Double_t ww = gPad->GetWw();
Double_t wh = gPad->GetWh();
fYsize = fXsize*wh/ww;
} else fYsize = 27;
if(fType == 113 && !fBoundingBox) {
Bool_t psave = fPrinted;
PrintStr("@%%BoundingBox: ");
Double_t xlow=0, ylow=0, xup=1, yup=1;
if (gPad) {
xlow = gPad->GetAbsXlowNDC();
xup = xlow + gPad->GetAbsWNDC();
ylow = gPad->GetAbsYlowNDC();
yup = ylow + gPad->GetAbsHNDC();
}
WriteInteger(CMtoPS(fXsize*xlow));
WriteInteger(CMtoPS(fYsize*ylow));
WriteInteger(CMtoPS(fXsize*xup));
WriteInteger(CMtoPS(fYsize*yup));
PrintStr("@");
Initialize();
fBoundingBox = kTRUE;
fPrinted = psave;
}
if (fPrinted) {
if (fSave) SaveRestore(-1);
fClear = kTRUE;
fPrinted = kFALSE;
}
Zone();
}
void TPostScript::Range(Float_t xsize, Float_t ysize)
{
Float_t xps=0, yps=0, xncm=0, yncm=0, dxwn=0, dywn=0, xwkwn=0, ywkwn=0, xymax=0;
fXsize = xsize;
fYsize = ysize;
if( fType != 113) { xps = fXsize; yps = fYsize; }
else { xps = xsize; yps = ysize; }
if( xsize <= xps && ysize < yps) {
if ( xps > yps ) xymax = xps;
else xymax = yps;
xncm = xsize/xymax;
yncm = ysize/xymax;
dxwn = ((xps/xymax)-xncm)/2;
dywn = ((yps/xymax)-yncm)/2;
} else {
if (xps/yps < 1) xwkwn = xps/yps;
else xwkwn = 1;
if (yps/xps < 1) ywkwn = yps/xps;
else ywkwn = 1;
if (xsize < ysize) {
xncm = ywkwn*xsize/ysize;
yncm = ywkwn;
dxwn = (xwkwn-xncm)/2;
dywn = 0;
if( dxwn < 0) {
xncm = xwkwn;
dxwn = 0;
yncm = xwkwn*ysize/xsize;
dywn = (ywkwn-yncm)/2;
}
} else {
xncm = xwkwn;
yncm = xwkwn*ysize/xsize;
dxwn = 0;
dywn = (ywkwn-yncm)/2;
if( dywn < 0) {
yncm = ywkwn;
dywn = 0;
xncm = ywkwn*xsize/ysize;
dxwn = (xwkwn-xncm)/2;
}
}
}
fXVP1 = dxwn;
fXVP2 = xncm+dxwn;
fYVP1 = dywn;
fYVP2 = yncm+dywn;
fRange = kTRUE;
}
void TPostScript::SaveRestore(Int_t flag)
{
if (flag == 1) { PrintFast(7," gsave "); fSave++; }
else { PrintFast(4," gr "); fSave--; }
}
void TPostScript::SetFillColor( Color_t cindex )
{
fFillColor = cindex;
if (gStyle->GetFillColor() <= 0) cindex = 0;
SetColor(Int_t(cindex));
}
void TPostScript::SetFillPatterns(Int_t ipat, Int_t color)
{
char cdef[28];
char cpat[5];
snprintf(cpat,5," P%2.2d", ipat);
if (fPatterns[ipat] == 0) {
fLineWidth = -1;
PrintFast(5," 1 lw");
PrintStr(" << /PatternType 1 /PaintType 2 /TilingType 1");
switch (ipat) {
case 1 :
PrintStr(" /BBox [ 0 0 98 4 ]");
PrintStr(" /XStep 98 /YStep 4");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [1] 0 sd 2 4 m 99 4 l s 1 3 m 98 3 l s");
PrintStr(" 2 2 m 99 2 l s 1 1 m 98 1 l s");
PrintStr(" gr end } >> [ 4.0 0 0 4.0 0 0 ]");
break;
case 2 :
PrintStr(" /BBox [ 0 0 96 4 ]");
PrintStr(" /XStep 96 /YStep 4");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [1 3] 0 sd 2 4 m 98 4 l s 0 3 m 96 3 l s");
PrintStr(" 2 2 m 98 2 l s 0 1 m 96 1 l s");
PrintStr(" gr end } >> [ 3.0 0 0 3.0 0 0 ]");
break;
case 3 :
PrintStr(" /BBox [ 0 0 96 16 ]");
PrintStr(" /XStep 96 /YStep 16");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [1 3] 0 sd 2 13 m 98 13 l s 0 9 m 96 9 l s");
PrintStr(" 2 5 m 98 5 l s 0 1 m 96 1 l s");
PrintStr(" gr end } >> [ 2.0 0 0 2.0 0 0 ]");
break;
case 4 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 0 m 100 100 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 5 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 100 m 100 0 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 6 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 50 0 m 50 100 l s");
PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
break;
case 7 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 50 m 100 50 l s");
PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
break;
case 8 :
PrintStr(" /BBox [ 0 0 101 101 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 0 m 0 30 l 30 0 l f 0 70 m 0 100 l 30 100 l f");
PrintStr(" 70 100 m 100 100 l 100 70 l f 70 0 m 100 0 l");
PrintStr(" 100 30 l f 50 20 m 20 50 l 50 80 l 80 50 l f");
PrintStr(" 50 80 m 30 100 l s 20 50 m 0 30 l s 50 20 m");
PrintStr(" 70 0 l s 80 50 m 100 70 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 9 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 50 m 50 50 50 180 360 arc");
PrintStr(" 0 50 m 0 100 50 270 360 arc");
PrintStr(" 50 100 m 100 100 50 180 270 arc s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 10 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 50 m 100 50 l 1 1 m 100 1 l");
PrintStr(" 0 0 m 0 50 l 100 0 m 100 50 l");
PrintStr(" 50 50 m 50 100 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 11 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 0 m 0 20 l 50 0 m 50 20 l");
PrintStr(" 100 0 m 100 20 l 0 80 m 0 100 l");
PrintStr(" 50 80 m 50 100 l 100 80 m 100 100 l");
PrintStr(" 25 30 m 25 70 l 75 30 m 75 70 l");
PrintStr(" 0 100 m 20 85 l 50 100 m 30 85 l");
PrintStr(" 50 100 m 70 85 l 100 100 m 80 85 l");
PrintStr(" 0 0 m 20 15 l 50 0 m 30 15 l");
PrintStr(" 50 0 m 70 15 l 100 0 m 80 15 l");
PrintStr(" 5 35 m 45 65 l 5 65 m 45 35 l");
PrintStr(" 55 35 m 95 65 l 55 65 m 95 35 l s");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
break;
case 12 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 80 m 0 100 20 270 360 arc");
PrintStr(" 30 100 m 50 100 20 180 360 arc");
PrintStr(" 80 100 m 100 100 20 180 270 arc");
PrintStr(" 20 0 m 0 0 20 0 90 arc");
PrintStr(" 70 0 m 50 0 20 0 180 arc");
PrintStr(" 100 20 m 100 0 20 90 180 arc");
PrintStr(" 45 50 m 25 50 20 0 360 arc");
PrintStr(" 95 50 m 75 50 20 0 360 arc s");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
break;
case 13 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 0 m 100 100 l 0 100 m 100 0 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 14 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 80 /YStep 80");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 20 m 100 20 l 20 0 m 20 100 l");
PrintStr(" 0 80 m 100 80 l 80 0 m 80 100 l");
PrintStr(" 20 40 m 60 40 l 60 20 m 60 60 l");
PrintStr(" 40 40 m 40 80 l 40 60 m 80 60 l s");
PrintStr(" gr end } >> [ 0.60 0 0 0.60 0 0 ]");
break;
case 15 :
PrintStr(" /BBox [ 0 0 60 60 ]");
PrintStr(" /XStep 60 /YStep 60");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 55 m 0 60 5 270 360 arc");
PrintStr(" 25 60 m 30 60 5 180 360 arc");
PrintStr(" 55 60 m 60 60 5 180 270 arc");
PrintStr(" 20 30 m 15 30 5 0 360 arc");
PrintStr(" 50 30 m 45 30 5 0 360");
PrintStr(" arc 5 0 m 0 0 5 0 90 arc");
PrintStr(" 35 0 m 30 0 5 0 180 arc");
PrintStr(" 60 5 m 60 0 5 90 180 arc s");
PrintStr(" gr end } >> [ 0.41 0 0 0.41 0 0 ]");
break;
case 16 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 50 50 m 25 50 25 0 180 arc s");
PrintStr(" 50 50 m 75 50 25 180 360 arc s");
PrintStr(" gr end } >> [ 0.4 0 0 0.2 0 0 ]");
break;
case 17 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [24] 0 setdash 0 0 m 100 100 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 18 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [24] 0 setdash 0 100 m 100 0 l s");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 19 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 90 50 m 50 50 40 0 360 arc");
PrintStr(" 0 50 m 0 100 50 270 360 arc");
PrintStr(" 50 0 m 0 0 50 0 90 arc");
PrintStr(" 100 50 m 100 0 50 90 180 arc");
PrintStr(" 50 100 m 100 100 50 180 270 arc s");
PrintStr(" gr end } >> [ 0.47 0 0 0.47 0 0 ]");
break;
case 20 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 50 50 m 50 75 25 270 450 arc s");
PrintStr(" 50 50 m 50 25 25 90 270 arc s");
PrintStr(" gr end } >> [ 0.2 0 0 0.4 0 0 ]");
break;
case 21 :
PrintStr(" /BBox [ 0 0 101 101 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 1 1 m 25 1 l 25 25 l 50 25 l 50 50 l");
PrintStr(" 75 50 l 75 75 l 100 75 l 100 100 l");
PrintStr(" 50 1 m 75 1 l 75 25 l 100 25 l 100 50 l");
PrintStr(" 0 50 m 25 50 l 25 75 l 50 75 l 50 100 l s");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
break;
case 22 :
PrintStr(" /BBox [ 0 0 101 101 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 1 100 m 25 100 l 25 75 l 50 75 l 50 50 l");
PrintStr(" 75 50 l 75 25 l 100 25 l 100 1 l");
PrintStr(" 50 100 m 75 100 l 75 75 l 100 75 l 100 50 l");
PrintStr(" 0 50 m 25 50 l 25 25 l 50 25 l 50 1 l s");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
break;
case 23 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" [1 7] 0 sd 0 8 50 { dup dup m 2 mul 0 l s } for");
PrintStr(" 0 8 50 { dup dup 2 mul 100 m 50 add exch 50");
PrintStr(" add l s } for 100 0 m 100 100 l 50 50 l f");
PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
break;
case 24 :
PrintStr(" /BBox [ 0 0 100 100 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 100 100 m 100 36 l 88 36 l 88 88 l f");
PrintStr(" 100 0 m 100 12 l 56 12 l 50 0 l f");
PrintStr(" 0 0 m 48 0 l 48 48 l 50 48 l 56 60 l");
PrintStr(" 36 60 l 36 12 l 0 12 l f [1 7] 0 sd");
PrintStr(" 61 8 87 { dup dup dup 12 exch m 88 exch l s");
PrintStr(" 16 exch 4 sub m 88 exch 4 sub l s } for");
PrintStr(" 13 8 35 { dup dup dup 0 exch m 36 exch l s");
PrintStr(" 4 exch 4 sub m 36 exch 4 sub l s } for");
PrintStr(" 37 8 59 { dup dup dup 12 exch m 36 exch l s");
PrintStr(" 16 exch 4 sub m 36 exch 4 sub l s } for");
PrintStr(" 13 8 60 { dup dup dup 56 exch m 100 exch l s");
PrintStr(" 60 exch 4 sub m 100 exch 4 sub l s } for");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
break;
case 25 :
PrintStr(" /BBox [ 0 0 101 101 ]");
PrintStr(" /XStep 100 /YStep 100");
PrintStr(" /PaintProc { begin gsave");
PrintStr(" 0 0 m 30 30 l 70 30 l 70 70 l 100 100 l 100 0 l");
PrintStr(" f 30 30 m 30 70 l 70 70 l f");
PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
};
snprintf(cdef,28," makepattern /%s exch def",&cpat[1]);
PrintStr(cdef);
fPatterns[ipat] = 1;
}
if (fPatterns[26] == 0) {
if (gStyle->GetColorModelPS()) {
PrintStr(" /cs {[/Pattern /DeviceCMYK] setcolorspace} def");
PrintStr(" /FA {f [/DeviceCMYK] setcolorspace} def");
} else {
PrintStr(" /cs {[/Pattern /DeviceRGB] setcolorspace} def");
PrintStr(" /FA {f [/DeviceRGB] setcolorspace} def");
}
fPatterns[26] = 1;
}
PrintFast(3," cs");
TColor *col = gROOT->GetColor(color);
if (col) {
Double_t colRed = col->GetRed();
Double_t colGreen = col->GetGreen();
Double_t colBlue = col->GetBlue();
if (gStyle->GetColorModelPS()) {
Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
if (colBlack==1) {
WriteReal(0);
WriteReal(0);
WriteReal(0);
WriteReal(colBlack);
} else {
Double_t colCyan = (1-colRed-colBlack)/(1-colBlack);
Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
Double_t colYellow = (1-colBlue-colBlack)/(1-colBlack);
WriteReal(colCyan);
WriteReal(colMagenta);
WriteReal(colYellow);
WriteReal(colBlack);
}
} else {
WriteReal(colRed);
WriteReal(colGreen);
WriteReal(colBlue);
}
}
PrintFast(4,cpat);
PrintFast(9," setcolor");
}
void TPostScript::SetLineColor( Color_t cindex )
{
fLineColor = cindex;
SetColor(Int_t(cindex));
}
void TPostScript::SetLineJoin( Int_t linejoin )
{
/*
<img src="gif/linejoin.gif">
*/
//End_Html
fgLineJoin = linejoin;
}
void TPostScript::SetLineStyle(Style_t linestyle)
{
if ( linestyle == fLineStyle) return;
fLineStyle = linestyle;
const char *st = gStyle->GetLineStyleString(linestyle);
PrintFast(1,"[");
Int_t nch = strlen(st);
PrintFast(nch,st);
PrintFast(6,"] 0 sd");
}
void TPostScript::SetLineWidth(Width_t linewidth)
{
if ( linewidth == fLineWidth) return;
fLineWidth = linewidth;
WriteInteger(Int_t(fLineScale*fLineWidth));
PrintFast(3," lw");
}
void TPostScript::SetMarkerColor( Color_t cindex )
{
fMarkerColor = cindex;
SetColor(Int_t(cindex));
}
void TPostScript::SetColor(Int_t color)
{
if (color < 0) color = 0;
fCurrentColor = color;
TColor *col = gROOT->GetColor(color);
if (col)
SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
else
SetColor(1., 1., 1.);
}
void TPostScript::SetColor(Float_t r, Float_t g, Float_t b)
{
if (r == fRed && g == fGreen && b == fBlue) return;
fRed = r;
fGreen = g;
fBlue = b;
if (fRed <= 0 && fGreen <= 0 && fBlue <= 0 ) {
PrintFast(6," black");
} else {
if (gStyle->GetColorModelPS()) {
Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
Double_t colCyan = (1-fRed-colBlack)/(1-colBlack);
Double_t colMagenta = (1-fGreen-colBlack)/(1-colBlack);
Double_t colYellow = (1-fBlue-colBlack)/(1-colBlack);
WriteReal(colCyan);
WriteReal(colMagenta);
WriteReal(colYellow);
WriteReal(colBlack);
} else {
WriteReal(fRed);
WriteReal(fGreen);
WriteReal(fBlue);
}
PrintFast(2," c");
}
}
void TPostScript::SetTextColor( Color_t cindex )
{
fTextColor = cindex;
SetColor( Int_t(cindex) );
}
void TPostScript::Text(Double_t xx, Double_t yy, const char *chars)
{
static const char *psfont[31][2] = {
{ "Root.PSFont.1", "/Times-Italic" },
{ "Root.PSFont.2", "/Times-Bold" },
{ "Root.PSFont.3", "/Times-BoldItalic" },
{ "Root.PSFont.4", "/Helvetica" },
{ "Root.PSFont.5", "/Helvetica-Oblique" },
{ "Root.PSFont.6", "/Helvetica-Bold" },
{ "Root.PSFont.7", "/Helvetica-BoldOblique" },
{ "Root.PSFont.8", "/Courrier" },
{ "Root.PSFont.9", "/Courrier-Oblique" },
{ "Root.PSFont.10", "/Courrier-Bold" },
{ "Root.PSFont.11", "/Courrier-BoldOblique" },
{ "Root.PSFont.12", "/Symbol" },
{ "Root.PSFont.13", "/Times-Roman" },
{ "Root.PSFont.14", "/ZapfDingbats" },
{ "Root.PSFont.15", "/Symbol" },
{ "Root.PSFont.STIXGen", "/STIXGeneral" },
{ "Root.PSFont.STIXGenIt", "/STIXGeneral-Italic" },
{ "Root.PSFont.STIXGenBd", "/STIXGeneral-Bold" },
{ "Root.PSFont.STIXGenBdIt", "/STIXGeneral-BoldItalic" },
{ "Root.PSFont.STIXSiz1Sym", "/STIXSize1Symbols" },
{ "Root.PSFont.STIXSiz1SymBd", "/STIXSize1Symbols-Bold" },
{ "Root.PSFont.STIXSiz2Sym", "/STIXSize2Symbols" },
{ "Root.PSFont.STIXSiz2SymBd", "/STIXSize2Symbols-Bold" },
{ "Root.PSFont.STIXSiz3Sym", "/STIXSize3Symbols" },
{ "Root.PSFont.STIXSiz3SymBd", "/STIXSize3Symbols-Bold" },
{ "Root.PSFont.STIXSiz4Sym", "/STIXSize4Symbols" },
{ "Root.PSFont.STIXSiz4SymBd", "/STIXSize4Symbols-Bold" },
{ "Root.PSFont.STIXSiz5Sym", "/STIXSize5Symbols" },
{ "Root.PSFont.ME", "/DroidSansFallback" },
{ "Root.PSFont.CJKMing", "/DroidSansFallback" },
{ "Root.PSFont.CJKGothic", "/DroidSansFallback" }
};
const Double_t kDEGRAD = TMath::Pi()/180.;
Double_t x = xx;
Double_t y = yy;
if (!gPad) return;
Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
Float_t tsize, ftsize;
if (wh < hh) {
tsize = fTextSize*wh;
Int_t sizeTTF = (Int_t)(tsize*kScale+0.5);
ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
} else {
tsize = fTextSize*hh;
Int_t sizeTTF = (Int_t)(tsize*kScale+0.5);
ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
}
Double_t fontsize = 4*(72*(ftsize)/2.54);
if( fontsize <= 0) return;
Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
Int_t font = abs(fTextFont)/10;
if( font > 31 || font < 1) font = 1;
SetColor(Int_t(fTextColor));
Int_t txalh = fTextAlign/10;
if (txalh <1) txalh = 1; if (txalh > 3) txalh = 3;
Int_t txalv = fTextAlign%10;
if (txalv <1) txalv = 1; if (txalv > 3) txalv = 3;
if (txalv == 3) {
y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
} else if (txalv == 2) {
y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
}
UInt_t w = 0, w0 = 0;
Bool_t kerning;
const Float_t scale = 16.0;
TText saveAttText;
saveAttText.TAttText::operator=(*this);
const Int_t len=strlen(chars);
Int_t *charWidthsCumul = 0;
TText t;
t.SetTextSize(fTextSize * scale);
t.SetTextFont(fTextFont);
t.GetTextAdvance(w, chars);
t.GetTextAdvance(w0, chars, kFALSE);
t.TAttText::Modify();
if (w0-w != 0) kerning = kTRUE;
else kerning = kFALSE;
if (kerning) {
charWidthsCumul = new Int_t[len];
for (Int_t i = len - 1;i >= 0;i--) {
UInt_t ww = 0;
t.GetTextAdvance(ww, chars + i);
Double_t wwl = (gPad->AbsPixeltoX(ww)-gPad->AbsPixeltoX(0));
charWidthsCumul[i] = (Int_t)((XtoPS(wwl) - XtoPS(0)) / scale);
}
}
saveAttText.TAttText::Modify();
Double_t charsLength = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
Int_t psCharsLength = (Int_t)((XtoPS(charsLength)-XtoPS(0)) / scale);
Int_t psangle = Int_t(0.5 + fTextAngle);
PrintStr("@");
SaveRestore(1);
Int_t xc1 = XtoPS(gPad->GetX1());
Int_t xc2 = XtoPS(gPad->GetX2());
Int_t yc1 = YtoPS(gPad->GetY1());
Int_t yc2 = YtoPS(gPad->GetY2());
WriteInteger(xc2 - xc1);
WriteInteger(yc2 - yc1);
WriteInteger(xc1);
WriteInteger(yc1);
PrintStr(" C");
Double_t vx = (x - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1());
Double_t cmx = fXsize*(gPad->GetAbsXlowNDC()+vx*gPad->GetAbsWNDC());
WriteReal((288.*cmx)/2.54);
Double_t vy = (y - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1());
Double_t cmy = fYsize*(gPad->GetAbsYlowNDC()+vy*gPad->GetAbsHNDC());
WriteReal((288.*cmy)/2.54);
PrintStr(Form(" t %d r ", psangle));
if(txalh == 2) PrintStr(Form(" %d 0 t ", -psCharsLength/2));
if(txalh == 3) PrintStr(Form(" %d 0 t ", -psCharsLength));
PrintStr(gEnv->GetValue(psfont[font-1][0], psfont[font-1][1]));
if (font != 15) {
PrintStr(Form(" findfont %g sf 0 0 m ",fontsize));
} else {
PrintStr(Form(" findfont %g sf 0 0 m ita ",fontsize));
}
if (kerning) {
PrintStr("@");
for (Int_t i = len-1; i >= 1; i--) {
WriteInteger(charWidthsCumul[0] - charWidthsCumul[i]);
}
delete [] charWidthsCumul;
PrintStr("@");
}
PrintStr("(");
const char *crsave = fImplicitCREsc;
fImplicitCREsc = "\\";
char str[8];
for (Int_t i=0; i<len;i++) {
if (chars[i]!='\n') {
if (chars[i]=='(' || chars[i]==')' || chars[i]=='\\') {
snprintf(str,8,"\\%c",chars[i]);
PrintStr(str);
} else if ((chars[i]=='-') && (font != 12)) {
PrintStr("\\255");
} else {
snprintf(str,8,"%c",chars[i]);
PrintFast(1,str);
}
}
}
PrintStr(")");
fImplicitCREsc = crsave;
if (kerning) {
if (font != 15) PrintStr(" K NC");
else PrintStr(" K gr NC");
} else {
if (font != 15) PrintStr(" show NC");
else PrintStr(" show gr NC");
}
SaveRestore(-1);
}
void TPostScript::Text(Double_t xx, Double_t yy, const wchar_t *chars)
{
static const char *psfont[31][2] = {
{ "Root.PSFont.1", "/FreeSerifItalic" },
{ "Root.PSFont.2", "/FreeSerifBold" },
{ "Root.PSFont.3", "/FreeSerifBoldItalic" },
{ "Root.PSFont.4", "/FreeSans" },
{ "Root.PSFont.5", "/FreeSansOblique" },
{ "Root.PSFont.6", "/FreeSansBold" },
{ "Root.PSFont.7", "/FreeSansBoldOblique" },
{ "Root.PSFont.8", "/FreeMono" },
{ "Root.PSFont.9", "/FreeMonoOblique" },
{ "Root.PSFont.10", "/FreeMonoBold" },
{ "Root.PSFont.11", "/FreeMonoBoldOblique" },
{ "Root.PSFont.12", "/SymbolMT" },
{ "Root.PSFont.13", "/FreeSerif" },
{ "Root.PSFont.14", "/Wingdings-Regular" },
{ "Root.PSFont.15", "/SymbolMT" },
{ "Root.PSFont.STIXGen", "/STIXGeneral" },
{ "Root.PSFont.STIXGenIt", "/STIXGeneral-Italic" },
{ "Root.PSFont.STIXGenBd", "/STIXGeneral-Bold" },
{ "Root.PSFont.STIXGenBdIt", "/STIXGeneral-BoldItalic" },
{ "Root.PSFont.STIXSiz1Sym", "/STIXSize1Symbols" },
{ "Root.PSFont.STIXSiz1SymBd", "/STIXSize1Symbols-Bold" },
{ "Root.PSFont.STIXSiz2Sym", "/STIXSize2Symbols" },
{ "Root.PSFont.STIXSiz2SymBd", "/STIXSize2Symbols-Bold" },
{ "Root.PSFont.STIXSiz3Sym", "/STIXSize3Symbols" },
{ "Root.PSFont.STIXSiz3SymBd", "/STIXSize3Symbols-Bold" },
{ "Root.PSFont.STIXSiz4Sym", "/STIXSize4Symbols" },
{ "Root.PSFont.STIXSiz4SymBd", "/STIXSize4Symbols-Bold" },
{ "Root.PSFont.STIXSiz5Sym", "/STIXSize5Symbols" },
{ "Root.PSFont.ME", "/DroidSansFallback" },
{ "Root.PSFont.CJKMing", "/DroidSansFallback" },
{ "Root.PSFont.CJKGothic", "/DroidSansFallback" }
};
Int_t len = wcslen(chars);
if (len<=0) return;
const Double_t kDEGRAD = TMath::Pi()/180.;
Double_t x = xx;
Double_t y = yy;
if (!gPad) return;
if (!fFontEmbed) {
if (fStream) {
PrintStr("@");
fStream->close(); delete fStream; fStream = 0;
}
TString tmpname = Form("%s_tmp_%d",fFileName.Data(),gSystem->GetPid());
if (gSystem->Rename( fFileName.Data() , tmpname.Data())) {
Error("Text", "Cannot open temporary file: %s\n", tmpname.Data());
return;
}
fStream = new std::ofstream(fFileName.Data(),std::ios::out);
if (fStream == 0 || gSystem->AccessPathName(fFileName.Data(),kWritePermission)) {
Error("Text", "Cannot open file: %s\n", fFileName.Data());
return;
}
FILE *sg = fopen(tmpname.Data(),"r");
if (sg == 0) {
Error("Text", "Cannot open file: %s\n", tmpname.Data());
return;
}
char line[255];
while (fgets(line,255,sg)) {
if (strstr(line,"EndComments")) PrintStr("%%DocumentNeededResources: ProcSet (FontSetInit)@");
fStream->write(line,strlen(line));
if (!fFontEmbed && strstr(line,"m5")) {
FontEmbed();
PrintStr("@");
}
}
fclose(sg);
if (gSystem->Unlink(tmpname.Data())) return;
}
Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
Float_t tsize, ftsize;
if (wh < hh) {
tsize = fTextSize*wh;
Int_t sizeTTF = (Int_t)(tsize*kScale+0.5);
ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
} else {
tsize = fTextSize*hh;
Int_t sizeTTF = (Int_t)(tsize*kScale+0.5);
ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
}
Double_t fontsize = 4*(72*(ftsize)/2.54);
if( fontsize <= 0) return;
Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
Int_t font = abs(fTextFont)/10;
if( font > 29 || font < 1) font = 1;
SetColor(Int_t(fTextColor));
Int_t txalh = fTextAlign/10;
if (txalh <1) txalh = 1; if (txalh > 3) txalh = 3;
Int_t txalv = fTextAlign%10;
if (txalv <1) txalv = 1; if (txalv > 3) txalv = 3;
if (txalv == 3) {
y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
} else if (txalv == 2) {
y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
}
UInt_t w = 0, h = 0;
TText t;
t.SetTextSize(fTextSize);
t.SetTextFont(fTextFont);
t.GetTextExtent(w, h, chars);
Double_t charsLength = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
Int_t psCharsLength = XtoPS(charsLength)-XtoPS(0);
Int_t psangle = Int_t(0.5 + fTextAngle);
PrintStr("@");
SaveRestore(1);
Int_t xc1 = XtoPS(gPad->GetX1());
Int_t xc2 = XtoPS(gPad->GetX2());
Int_t yc1 = YtoPS(gPad->GetY1());
Int_t yc2 = YtoPS(gPad->GetY2());
WriteInteger(xc2 - xc1);
WriteInteger(yc2 - yc1);
WriteInteger(xc1);
WriteInteger(yc1);
PrintStr(" C");
WriteInteger(XtoPS(x));
WriteInteger(YtoPS(y));
PrintStr(Form(" t %d r ", psangle));
if(txalh == 2) PrintStr(Form(" %d 0 t ", -psCharsLength/2));
if(txalh == 3) PrintStr(Form(" %d 0 t ", -psCharsLength));
PrintStr(gEnv->GetValue(psfont[font-1][0], psfont[font-1][1]));
PrintStr(Form(" findfont %g sf 0 0 m ",fontsize));
PrintStr("@");
if (len > 1) PrintStr(Form("%d ", len));
for(Int_t i = 0; i < len; i++) {
#include "AdobeGlyphList.h"
const wchar_t *lower = std::lower_bound(
adobe_glyph_ucs, adobe_glyph_ucs + nadobe_glyph,
chars[i]);
if(lower < adobe_glyph_ucs + nadobe_glyph &&
*lower == chars[i]) {
const unsigned long index =
lower - adobe_glyph_ucs;
PrintStr(Form("/%s ", adobe_glyph_name[index]));
}
else if((unsigned int)chars[i] < 0xffff) {
PrintStr(Form("/uni%04X ",
(unsigned int)chars[i]));
}
else {
PrintStr(Form("/u%04X ",
(unsigned int)chars[i]));
}
}
if(len > 1) {
PrintStr("{glyphshow} repeat ");
}
else {
PrintStr("glyphshow ");
}
PrintStr("NC");
SaveRestore(-1);
}
void TPostScript::TextNDC(Double_t u, Double_t v, const char *chars)
{
Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
Text(x, y, chars);
}
void TPostScript::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
{
Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
Text(x, y, chars);
}
Int_t TPostScript::UtoPS(Double_t u)
{
Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
return Int_t(0.5 + 288*cm/2.54);
}
Int_t TPostScript::VtoPS(Double_t v)
{
Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
return Int_t(0.5 + 288*cm/2.54);
}
Int_t TPostScript::XtoPS(Double_t x)
{
Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
return UtoPS(u);
}
Int_t TPostScript::YtoPS(Double_t y)
{
Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
return VtoPS(v);
}
void TPostScript::Zone()
{
if( !fClear )return;
fClear = kFALSE;
fZone = kTRUE;
if( fIYzone > fNYzone) {
fIYzone=1;
if( fMode != 3) {
PrintStr("@showpage");
SaveRestore(-1);
fNpages++;
PrintStr("@%%Page:");
WriteInteger(fNpages);
WriteInteger(fNpages);
PrintStr("@");
} else {
PrintFast(9," showpage");
SaveRestore(-1);
}
}
if( fMode != 3) {
if( fIXzone != 1 || fIYzone != 1) SaveRestore(-1);
SaveRestore(1);
PrintStr("@");
WriteInteger(fIXzone);
WriteInteger(fIYzone);
PrintFast(5," Zone");
PrintStr("@");
fIXzone++;
if( fIXzone > fNXzone) { fIXzone=1; fIYzone++; }
}
SaveRestore(1);
if (fgLineJoin) {
WriteInteger(fgLineJoin);
PrintFast(12," setlinejoin");
}
PrintFast(6," 0 0 t");
fRed = -1;
fGreen = -1;
fBlue = -1;
fPrinted = kFALSE;
fLineColor = -1;
fLineStyle = -1;
fLineWidth = -1;
fFillColor = -1;
fFillStyle = -1;
fMarkerSizeCur = -1;
}