Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostScript shape,size and position improvements. #1638

Merged
Merged
69 changes: 41 additions & 28 deletions src/deviceps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,9 @@
// for the offsets to be taken into account by spage(), works with plplot >= 5.9.9)
PLINT XSIZE=ceil(XPageSize*DPICM);
PLINT YSIZE=ceil(YPageSize*DPICM);
PLINT XOFF=encapsulated?0:ceil(XOffset*DPICM);
PLINT YOFF=encapsulated?0:ceil(YOffset*DPICM);
PLINT XOFF=ceil(XOffset*DPICM);
PLINT YOFF=ceil(YOffset*DPICM);

// as setting the offsets and sizes with plPlot is (extremely) tricky, and some of these setting
// are hardcoded into plplot (like EPS header, and offsets in older versions of plplot)
// here we play only with the aspect ratio

// plot orientation
//std::cout << "orientation : " << orient_portrait<< '\n';
if (orient_portrait) { //X size will be OK, Y size must be scaled
actStream->setopt( "portrait",NULL);
actStream->sdidev( PL_NOTSET, PlplotInternalPageRatioXoverY, PL_NOTSET, PL_NOTSET ); //only OK if page ratio is 540x720
actStream->spage(PS_DPI, PS_DPI, XSIZE, YSIZE, YOFF, XOFF);
} else {
actStream->spage(PS_DPI, PS_DPI, YSIZE, XSIZE, YOFF-XSIZE, XOFF); //invert axes, displace as does IDL..
actStream->sdiori(2);
}

// no pause on destruction
actStream->spause( false);

Expand All @@ -112,10 +97,36 @@
// default: black+white (IDL behaviour)
//? force TTF fonts as scaling of hershey fonts will not be good
short text=(SysVar::GetPFont()>=0)?1:0;
string what="hrshsym=1,text="+i2s(text)+",color="+i2s(color);
string what="hrshsym=1,text="+i2s(text)+",color="+i2s(color)+",epsf="+i2s(encapsulated);
actStream->setopt( "drvopt",what.c_str());
actStream->scolbg(255,255,255); // start with a white background

// setting the offsets and sizes with plPlot is (extremely) tricky as some of these setting
// are hardcoded into plplot (like EPS header, and offsets in older versions of plplot)
// here we play only with the aspect ratio, and, I must confess, this has been largely based on trial and error.
// plot orientation
PLFLT xovery = float(XSIZE) / float(YSIZE);
//Only by using the -a option can we really fix the aspect ratio. use plsdidev (revious version) did absolutely nothing
//to keep characters etc aspect ok we need to make the 'good' size larger or smaller by truc*PlplotInternalPageRatioXoverY and displace by half this value
actStream->setopt("a", i2s(xovery).c_str()); //this will compress the X or Y axis by xovery, but does not change the position of the axis center. So some difficulty to find the good offsets as
//they depend on the axis compression, the half axis size . the following should do.
xovery/=PlplotInternalPageRatioXoverY; //normalize
if (orient_portrait) { //X size will be OK, Y size must be scaled
actStream->setopt("portrait", NULL);
if (xovery <= 1) { //expand Y (will be compressed by the -a setopt)
actStream->spage(PS_DPI, PS_DPI, XSIZE, YSIZE/xovery, YOFF -YSIZE/2/xovery + YSIZE/2, XOFF);
} else { //expand X
actStream->spage(PS_DPI, PS_DPI, XSIZE*xovery, YSIZE, YOFF , -XSIZE/2*xovery + XSIZE/2 + XOFF);
}
} else { //landscape: XOFF and YOFF are X and Y but XSIZE and YSIZE are exchanged wrt previous case, and YOFF is replaced by YOFF-XSIZE.
if (xovery <= 1) {
actStream->spage(PS_DPI, PS_DPI, YSIZE, XSIZE/xovery, YOFF-XSIZE -XSIZE/2/xovery + XSIZE/2 , XOFF);
} else {
actStream->spage(PS_DPI, PS_DPI, YSIZE*xovery, XSIZE, YOFF-XSIZE, -YSIZE/2*xovery + YSIZE/2 + XOFF);

Check warning on line 125 in src/deviceps.hpp

View check run for this annotation

Codecov / codecov/patch

src/deviceps.hpp#L125

Added line #L125 was not covered by tests
}
actStream->sdiori(2);
}

actStream->Init();

// need to be called initially. permit to fix things
Expand All @@ -128,14 +139,16 @@

actStream->ssub(1, 1);
actStream->adv(0); //this is for us (counters)
actStream->SetPageDPMM();
float fudge=17780./float(XPageSize*scale*PS_RESOL)*12700./float(YPageSize*scale*PS_RESOL);
fudge=1.46*sqrt(fudge); //best value (experimental) to get same results as IDL with varying CHARSIZE
actStream->SetPageDPMM(fudge);
actStream->DefaultCharSize();
// clear();
}

public:
DevicePS(): GraphicsDevice(), fileName( "gdl.ps"), actStream( NULL),
XPageSize(17.78), YPageSize(12.7), XOffset(1.905),YOffset(12.7), //IDL default for offests: 54 pts /X and 360 pts/Y
XPageSize(17.78), YPageSize(12.7), XOffset(1.905),YOffset(12.7), //IDL default for offsets: 54 pts /X and 360 pts/Y
color(0), decomposed( 0), encapsulated(false), scale(1.), orient_portrait(true), bitsPerPix(8)
{
name = "PS";
Expand Down Expand Up @@ -263,21 +276,21 @@
// no need to update !D
orient_portrait = true;
// nb: IDL defaults to:
// SetXPageSize(7 * in2cm);
// SetYPageSize(5 * in2cm);
// SetXOffset(.75 * in2cm);
// SetYOffset(5 * in2cm);
SetXPageSize(7 * in2cm);
SetYPageSize(5 * in2cm);
SetXOffset(.75 * in2cm);
SetYOffset(5 * in2cm);
return true;
}

bool SetLandscape()
{
// no need to update !D
orient_portrait = false;
// SetXPageSize(9.5 * in2cm);
// SetYPageSize(7.0 * in2cm);
// SetXOffset(.75 * in2cm);
// SetYOffset(10.25 * in2cm);
SetXPageSize(9.5 * in2cm);
SetYPageSize(7.0 * in2cm);
SetXOffset(.75 * in2cm);
SetYOffset(10.25 * in2cm);
return true;
}

Expand Down
54 changes: 16 additions & 38 deletions src/gdlgstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,8 @@

using namespace std;

// bool GDLGStream::plstreamInitCalled = false;

// void PLPlotAbortHandler(const char *c)
// {
// cout << "PLPlot abort handler: " << c << endl;
// }
//
// int PLPlotExitHandler(const char *c)
// {
// cout << "PLPlot exit handler: " << c << endl;
// return 0;
// }
//
// void GDLGStream::SetErrorHandlers()
// {
// plsexit( PLPlotExitHandler);
// plsabort( PLPlotAbortHandler);
// }
static float psCharFudge=1; //to compensate the wrong size of fonts in PS using Hershey
static float psSymFudge=1; //to compensate the wrong size of symbols in PS

void GDLGStream::Thick(DFloat thick)
{
Expand Down Expand Up @@ -194,10 +178,12 @@
}
#undef WHITEB

void GDLGStream::SetPageDPMM() {
void GDLGStream::SetPageDPMM(float setPsCharFudge, float setPsSymFudge) {
//This is supposed to be called each time DPI is changed, which happens only at creation of a new device.
// contrary to the page size, that may change for intercative devices that can be resized.
if (GDL_DEBUG_PLSTREAM) fprintf(stderr, "SetPageDPMM()\n");
psCharFudge=setPsCharFudge;
psSymFudge=setPsSymFudge;
PLINT level;
plstream::glevel(level);
if (level <= 1) return;
Expand Down Expand Up @@ -332,8 +318,10 @@
DStructDesc* s = d->Desc();
int X_CH_SIZE = s->TagIndex("X_CH_SIZE");
int Y_CH_SIZE = s->TagIndex("Y_CH_SIZE");
DLong chx = (*static_cast<DLongGDL*> (d->GetTag(X_CH_SIZE, 0)))[0];
DLong chy = (*static_cast<DLongGDL*> (d->GetTag(Y_CH_SIZE, 0)))[0];
DLong ichx = (*static_cast<DLongGDL*> (d->GetTag(X_CH_SIZE, 0)))[0];
DLong ichy = (*static_cast<DLongGDL*> (d->GetTag(Y_CH_SIZE, 0)))[0];
PLFLT chx=ichx; //needed as floats for subsequent computations!
PLFLT chy=ichy;
int FLAGS = s->TagIndex("FLAGS");
DLong flags = (*static_cast<DLongGDL*> (d->GetTag(FLAGS, 0)))[0];
if (flags & 0x1) {
Expand All @@ -346,7 +334,8 @@
setFixedCharacterSize(chx, 1.0, chy);
}
}
void GDLGStream::SetCharSize(DLong chx, DLong chy) {
void GDLGStream::SetCharSize(DLong ichx, DLong chy) {
PLFLT chx=ichx;

Check warning on line 338 in src/gdlgstream.cpp

View check run for this annotation

Codecov / codecov/patch

src/gdlgstream.cpp#L337-L338

Added lines #L337 - L338 were not covered by tests
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"GDLGStream::SetCharSize()\n");
DStructGDL* d = SysVar::D();
DStructDesc* s = d->Desc();
Expand Down Expand Up @@ -483,16 +472,8 @@

//since the page sizes for PS and EPS images are processed by GDL after plplot finishes
//its work, gpage will not output correct sizes
DString name = (*static_cast<DStringGDL*>(
SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("NAME"), 0)
))[0];
if (name == "PS") {
xSize = (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("X_SIZE"), 0)))[0];
ySize = (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("Y_SIZE"), 0)))[0];
} else {
xSize = xleng;
ySize = yleng;
}
if (xSize<1.0||ySize<1) //plplot gives back crazy values! z-buffer for example!
{
PLFLT xmin,xmax,ymin,ymax;
Expand Down Expand Up @@ -1062,7 +1043,7 @@
{
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"setSymbolScale(%f)\n",scale);
// plstream::ssym(0.0, scale);
theCurrentSymSize=scale;
theCurrentSymSize=scale*psSymFudge;
}

void GDLGStream::setLineSpacing(PLFLT newSpacing)
Expand Down Expand Up @@ -1147,15 +1128,12 @@
}
}

#define FUDGE_VARCHARSIZE sqrt(2)
//This defines the character size for SCALABLE character devices (POSTSCRIPT, SVG))
//The dimension of "average" character (given by X_CH_SIZE) is to be a physical (mm) size.
//this implies to have a correct value for DPI AND that the plplot driver is correctly written.
void GDLGStream::setVariableCharacterSize( PLFLT charwidthpixel, PLFLT scale , PLFLT lineSpacingpixel, PLFLT xpxcm, PLFLT ypxcm)
{
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"setVariableCharacterSize()\n");
xpxcm/=FUDGE_VARCHARSIZE;
ypxcm/=FUDGE_VARCHARSIZE; //go figure why this is needed, but indeed it is needed!
//tried by comparison of outputs of
// "set_plot,'ps' & !P.multi=[0,2,2]&a=dist(5)&for i=1,4 do begin&s=i*0.7& plot,a,psym=6,syms=s,chars=s,xtit="XXXX" $
// & xyouts,indgen(25),a,"M",ali=0.5,chars=s & end & !p.multi=0 & plots,[0.001,0.001,0.999,0.999,0.001],$
Expand Down Expand Up @@ -1188,7 +1166,7 @@
// if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"re-check character width=%f, ratio is %f\n",em, ratio);
//#endif
}
setLineSpacing(lineSpacingpixel/ydpi*INCHToMM); //this one is NOT related to characters idiosyncrasies.
setLineSpacing(lineSpacingpixel/ydpi*INCHToMM); //this one is NOT related to characters idiosyncrasies.
gdlDefaultCharInitialized=0; //reset Default
CurrentCharSize(scale);
}
Expand Down Expand Up @@ -1230,9 +1208,9 @@

void GDLGStream::sizeChar( PLFLT scale )
{
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"SizeChar(%f)\n",scale);
plstream::schr(theDefaultChar.mmsx, scale); //must FORCE a new size.
CurrentCharSize(scale);
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"SizeChar(%f)\n",scale);
plstream::schr(theDefaultChar.mmsx, scale*psCharFudge); //must FORCE a new size.
CurrentCharSize(scale*psCharFudge);
}

bool GDLGStream::vpor(PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax )
Expand Down
4 changes: 2 additions & 2 deletions src/gdlgstream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static const float ALLCHARACTERSFORSTRINGLENGTHTEST_NCHARS = 36;
const double INCHToMM = 25.4 ;
const double INCHToCM = 2.54 ;
const double CM_IN_MM = 10.00000000 ;
const double DEFAULT_FONT_ASPECT_RATIO = 1.2; // Height / Width
const double DEFAULT_FONT_ASPECT_RATIO = 1.3; // Height / Width
using namespace std;
static std::string internalFontCodes[] = {
"#fn", // !0 : unused
Expand Down Expand Up @@ -642,7 +642,7 @@ class GDLGStream: public plstream
void ssub( PLINT nx, PLINT ny, PLINT nz=1);
void adv(PLINT page);
void getSubpageRegion(PLFLT &sxmin, PLFLT &symin, PLFLT &sxmax, PLFLT &symax, PLFLT *zmin=NULL, PLFLT *zmax=NULL);
void SetPageDPMM();
void SetPageDPMM(float setPsCharFudge=1.0, float setPsSymFudge=1.0);
void syncPageInfo();
void updateBoxDeviceCoords();

Expand Down
Loading
Loading