Skip to content

Commit f3fdb3d

Browse files
authored
Merge pull request #1664 from GillesDuvert/exact_plot_positioning_in_all_cases
Exact plot positioning in all cases
2 parents eaecbdc + bd58fae commit f3fdb3d

22 files changed

+1189
-987
lines changed

src/basic_pro.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -2355,7 +2355,12 @@ static DWORD launch_cmd(BOOL hide, BOOL nowait,
23552355
SizeT nParam = e->NParam(1);
23562356
if (nParam == 1) return;
23572357
DDoubleGDL* p0 = e->GetParAs<DDoubleGDL>(0);
2358-
2358+
2359+
static int GDL_DOW = e->KeywordIx("GDL_DOW");
2360+
bool hasDow = e->WriteableKeywordPresent(GDL_DOW); //insure the output variable exist and is of 'good' type
2361+
static int GDL_ICAP = e->KeywordIx("GDL_ICAP");
2362+
bool hasIcap = e->WriteableKeywordPresent(GDL_ICAP); //insure the output variable exist and is of 'good' type
2363+
23592364
// checking output (if present and global); exiting if nothing to do
23602365
bool global[6];
23612366
{
@@ -2374,6 +2379,11 @@ static DWORD launch_cmd(BOOL hide, BOOL nowait,
23742379
BaseGDL*** ret;
23752380
ret = (BaseGDL***) malloc((nParam - 1) * sizeof (BaseGDL**));
23762381
GDLGuard<BaseGDL**, void, void> retGuard(ret, free);
2382+
2383+
DLongGDL* retdow;
2384+
DLongGDL* reticap;
2385+
if (hasDow) retdow=new DLongGDL(dimension(nEl));
2386+
if (hasIcap) reticap=new DLongGDL(dimension(nEl));
23772387

23782388
for (int i = nParam - 2; i >= 0; i--) {
23792389
if (global[i]) {
@@ -2416,7 +2426,12 @@ static DWORD launch_cmd(BOOL hide, BOOL nowait,
24162426

24172427
// seconds
24182428
if (global[6 - 1]) (*static_cast<DDoubleGDL*> (*ret[6 - 1]))[i] = Second;
2429+
2430+
if (hasDow) (*retdow)[i]= dow;
2431+
if (hasIcap) (*reticap)[i]= icap;
24192432
}
2433+
if (hasDow) e->SetKW(GDL_DOW,retdow);
2434+
if (hasIcap) e->SetKW(GDL_ICAP,reticap);
24202435
// now guarded. s. a.
24212436
// free((void *)ret);
24222437
}

src/calendar.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ using namespace std;
9595
F = JD - Z;
9696
// note that IDL dow is false before Sun dec 31 12:00:00 -4714, (type: a=[-2,-1]& PRINT, FORMAT='(C())',a)
9797
// ...and ... we are not!
98-
if ((DLong)Z > 0) dow = ((DLong)Z) % 7; else dow = ((DLong)Z+1099) % 7; //just translate axis...
98+
if ((DLong)Z+1 > 0) dow = ((DLong)Z+1) % 7; else dow = ((DLong)Z+1099) % 7; //just translate axis...
9999

100100
if (Z < 2299161) A = (DLong)Z;
101101
else {

src/deviceps.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,11 @@ class DevicePS: public GraphicsDevice
138138
actStream->plstream::wind(0, 1, 0, 1);
139139

140140
actStream->ssub(1, 1);
141-
actStream->adv(0); //this is for us (counters)
142141
float fudge=17780./float(XPageSize*scale*PS_RESOL)*12700./float(YPageSize*scale*PS_RESOL);
143142
fudge=1.46*sqrt(fudge); //best value (experimental) to get same results as IDL with varying CHARSIZE
144143
actStream->SetPageDPMM(fudge);
145144
actStream->DefaultCharSize();
145+
actStream->adv(0); //this is for us (counters) //needs DefaultCharSize
146146
// clear();
147147
}
148148

src/devicesvg.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ class DeviceSVG : public GraphicsDevice
7676
actStream->plstream::wind(0, 1, 0, 1);
7777

7878
actStream->ssub(1, 1);
79-
actStream->adv(0); //this is for us (counters)
8079
actStream->SetPageDPMM();
8180
actStream->DefaultCharSize();
81+
actStream->adv(0); //this is for us (counters) //needs DefaultCharSize
8282
}
8383

8484
public:

src/devicez.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ class DeviceZ: public GraphicsDevice
111111
actStream->plstream::wind(0, 1, 0, 1);
112112

113113
actStream->ssub(1, 1);
114-
actStream->adv(0); //this is for us (counters)
115114
actStream->SetPageDPMM();
116115
actStream->DefaultCharSize();
116+
actStream->adv(0); //this is for us (counters) //needs DefaultCharSize
117117
}
118118

119119
public:

src/gdlgstream.cpp

+70-29
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#include "graphicsdevice.hpp"
2323
#include "gdlgstream.hpp"
2424
#include "initsysvar.hpp"
25+
#ifndef MAX
26+
#define MAX(a,b) ((a) < (b) ? (b) : (a))
27+
#endif
2528

2629
using namespace std;
2730

@@ -380,8 +383,9 @@ void GDLGStream::SetCharSize(DLong ichx, DLong chy) {
380383
gdlDefaultCharInitialized=1;
381384
}
382385

383-
void GDLGStream::NextPlot( bool erase )
384-
{
386+
void GDLGStream::NextPlot( bool erase ) {
387+
// restore charsize to default for newpage at beginning since adv() uses charsize to get box position.
388+
if (!erase) sizeChar(1.0);
385389
DLongGDL* pMulti = SysVar::GetPMulti();
386390

387391
DLong nx = (*pMulti)[ 1];
@@ -446,8 +450,7 @@ void GDLGStream::NextPlot( bool erase )
446450
--(*pMulti)[0];
447451
}
448452
}
449-
// restore charsize to default for newpage
450-
sizeChar(1.0);
453+
451454
}
452455

453456
void GDLGStream::NoSub()
@@ -505,7 +508,7 @@ void GDLGStream::GetGeometry( long& xSize, long& ySize)
505508
// - ... a look-up table instead of the long switch/case blocks ...
506509

507510
size_t len = strlen(in);
508-
if (stringLength) *stringLength=0;
511+
if (stringLength!=NULL) *stringLength=0;
509512
// skip conversion if the string is empty
510513
if (len == 0) return "";
511514

@@ -694,12 +697,12 @@ void GDLGStream::GetGeometry( long& xSize, long& ySize)
694697
}
695698
else
696699
{
697-
if (stringLength) *stringLength+=base*fact[curr_lev%7];
700+
if (stringLength!=NULL) *stringLength+=base*fact[curr_lev%7];
698701
curr_pos++;
699702
// handling IDL exclamation mark escape '!!'
700703
if (in[i] == '!') {
701704
i++;
702-
if (stringLength) *stringLength+=base*fact[curr_lev%7];
705+
if (stringLength!=NULL) *stringLength+=base*fact[curr_lev%7];
703706
}
704707
// handling plplot number sign escape '##'
705708
if
@@ -1029,12 +1032,12 @@ void GDLGStream::GetGeometry( long& xSize, long& ySize)
10291032
activeFontCodeNum = curr_fnt;
10301033
//if gdlGetStringLength function is available, use it to give back a better value ("X" and "I" do not have the same width in hershey format!)
10311034
#if PLPLOT_PRIVATE_NOT_HIDDEN
1032-
if (stringLength) *stringLength=gdlGetStringLength(out)/this->mmCharLength();
1035+
if (stringLength!=NULL) *stringLength=gdlGetStringLength(out)/this->mmCharLength();
10331036
#endif
10341037
return out;
10351038
retrn:
10361039
activeFontCodeNum = curr_fnt;
1037-
if (stringLength) *stringLength=0;
1040+
if (stringLength!=NULL) *stringLength=0;
10381041
cout << "ERROR: GDLGStream::TranslateFormatCodes(\"" << in << "\") = \"" << out << "\"" << endl;
10391042
return "";
10401043
}
@@ -1052,7 +1055,7 @@ void GDLGStream::setLineSpacing(PLFLT newSpacing)
10521055
}
10531056
PLFLT GDLGStream::getSymbolSize(){return theCurrentSymSize;}
10541057
void GDLGStream::mtex( const char *side, PLFLT disp, PLFLT posit, PLFLT just,
1055-
const char *text)
1058+
const char *text, double *stringCharLength, double *stringCharHeight)
10561059
{
10571060
//plot does not handle !C
10581061
size_t len = strlen(text);
@@ -1061,15 +1064,17 @@ void GDLGStream::mtex( const char *side, PLFLT disp, PLFLT posit, PLFLT just,
10611064
simple=false;
10621065
}
10631066
if (simple) {
1064-
plstream::mtex(side,disp,posit,just,TranslateFormatCodes(text).c_str());
1067+
plstream::mtex(side,disp,posit,just,TranslateFormatCodes(text,stringCharLength).c_str());
1068+
if (stringCharHeight!=NULL) *stringCharHeight = 1;
10651069
return;
10661070
}
10671071
//complicated:
1072+
if (stringCharHeight != NULL) *stringCharHeight = 0;
10681073
double d=0;
10691074
std::string s(text);
10701075
std::string newline="!C";
1071-
long pos = 0, oldpos=0;
1072-
PLFLT ydisp=(1.0+nLineSpacing()/nCharHeight());
1076+
size_t pos = 0, oldpos=0;
1077+
PLFLT yadd=nLineSpacing()/nCharHeight();
10731078
std::vector<long> positions;
10741079
while (pos != string::npos) {
10751080
pos = s.find(newline, oldpos);
@@ -1081,11 +1086,19 @@ void GDLGStream::mtex( const char *side, PLFLT disp, PLFLT posit, PLFLT just,
10811086
for (std::vector<long>::iterator it = positions.begin(); it != positions.end();) {
10821087
oldpos=(*it++);
10831088
pos=(*(it++));
1084-
long l=pos-oldpos;
1089+
size_t l=pos-oldpos;
10851090
if (l<0) l=string::npos;
10861091
// std::cerr<<pos<<":"<<l<<" "<<s.substr(oldpos,l)<<std::endl;
1087-
plstream::mtex(side,disp,posit,just,TranslateFormatCodes(s.substr(oldpos,l).c_str()).c_str());
1088-
disp+=ydisp;
1092+
plstream::mtex(side,disp,posit,just,TranslateFormatCodes(s.substr(oldpos,l).c_str(),&d).c_str());
1093+
if (strstr(side,"b")!=NULL) { //bottom increments 1 line
1094+
disp += yadd;
1095+
} else if (strstr(side,"t")!=NULL) {//top decrements 1 line
1096+
disp -= yadd;
1097+
} else {//left decrements position in Y : change posit not disp unless parallel
1098+
if (strstr(side,"v")!=NULL) posit-=nLineSpacing()/boxnYSize() ; else disp -= yadd;
1099+
}
1100+
if (stringCharLength!=NULL) *stringCharLength = std::max<double>(*stringCharLength, d);
1101+
if (stringCharHeight!=NULL) *stringCharHeight += 1;
10891102
}
10901103
}
10911104

@@ -1106,8 +1119,8 @@ void GDLGStream::ptex( PLFLT x, PLFLT y, PLFLT dx, PLFLT dy, PLFLT just,
11061119
double d=0;
11071120
std::string s(text);
11081121
std::string newline="!C";
1109-
long pos = 0, oldpos=0;
1110-
PLFLT ydisp=(1.0+nLineSpacing()/nCharHeight())*wCharHeight();
1122+
size_t pos = 0, oldpos=0;
1123+
PLFLT ydisp=(nLineSpacing()/nCharHeight())*wCharHeight();
11111124
std::vector<long> positions;
11121125
while (pos != string::npos) {
11131126
pos = s.find(newline, oldpos);
@@ -1119,7 +1132,7 @@ void GDLGStream::ptex( PLFLT x, PLFLT y, PLFLT dx, PLFLT dy, PLFLT just,
11191132
for (std::vector<long>::iterator it = positions.begin(); it != positions.end();) {
11201133
oldpos=(*it++);
11211134
pos=(*(it++));
1122-
long l=pos-oldpos;
1135+
size_t l=pos-oldpos;
11231136
if (l<0) l=string::npos;
11241137
// std::cerr<<pos<<":"<<l<<" "<<s.substr(oldpos,l)<<std::endl;
11251138
plstream::ptex(x,y,dx,dy,just,TranslateFormatCodes(s.substr(oldpos,l).c_str(),&d).c_str()) ;
@@ -1326,7 +1339,7 @@ void GDLGStream::adv(PLINT page)
13261339
if (thePage.curPage > thePage.nbPages) thePage.curPage=1;
13271340
if (GDL_DEBUG_PLSTREAM) fprintf(stderr,"adv() now at page %d\n",thePage.curPage);
13281341
PLFLT sxmin,symin,sxmax,symax,szmin,szmax;
1329-
getSubpageRegion(sxmin,symin,sxmax,symax,&szmin,&szmax);
1342+
getSubpageRegion(&sxmin,&symin,&sxmax,&symax,&szmin,&szmax);
13301343
//SET ALL REGION TAGS
13311344
unsigned regionTag=SysVar::X()->Desc()->TagIndex("REGION");
13321345
(*static_cast<DFloatGDL*>(SysVar::X()->GetTag(regionTag, 0)))[0]=sxmin;
@@ -1339,19 +1352,47 @@ void GDLGStream::adv(PLINT page)
13391352
(*static_cast<DFloatGDL*>(SysVar::Z()->GetTag(regionTag, 0)))[1]=szmax;
13401353
}
13411354

1342-
void GDLGStream::getSubpageRegion(PLFLT &sxmin, PLFLT &symin, PLFLT &sxmax, PLFLT &symax, PLFLT *szmin, PLFLT *szmax){
1355+
void GDLGStream::getSubpageRegion(PLFLT *sxmin, PLFLT *symin, PLFLT *sxmax, PLFLT *symax, PLFLT *szmin, PLFLT *szmax) {
1356+
//here we must take into account the contents of ![X|Y|Z].OMARGIN
1357+
unsigned int omarginTag = SysVar::X()->Desc()->TagIndex("OMARGIN");
1358+
DFloat xstart = (*static_cast<DFloatGDL*> (SysVar::X()->GetTag(omarginTag, 0)))[0];
1359+
xstart=MAX(xstart,0);
1360+
DFloat xend = (*static_cast<DFloatGDL*> (SysVar::X()->GetTag(omarginTag, 0)))[1];
1361+
xend=MAX(xend,0);
1362+
omarginTag = SysVar::Y()->Desc()->TagIndex("OMARGIN");
1363+
DFloat ystart = (*static_cast<DFloatGDL*> (SysVar::Y()->GetTag(omarginTag, 0)))[0];
1364+
ystart=MAX(ystart,0);
1365+
DFloat yend = (*static_cast<DFloatGDL*> (SysVar::Y()->GetTag(omarginTag, 0)))[1];
1366+
yend=MAX(yend,0);
1367+
// Z OMARGIN to BE CHECKED and code must be written.
1368+
// omarginTag = SysVar::Z()->Desc()->TagIndex("OMARGIN");
1369+
// DFloat zstart = (*static_cast<DFloatGDL*> (SysVar::Z()->GetTag(omarginTag, 0)))[0];
1370+
// DFloat zend = (*static_cast<DFloatGDL*> (SysVar::Z()->GetTag(omarginTag, 0)))[1];
1371+
DFloat xNormedPageSize=1-(xend+xstart)*theCurrentChar.ndsx;
1372+
DFloat yNormedPageSize=1-(yend+ystart)*theCurrentChar.nspacing;
1373+
if (xNormedPageSize < 0 || xNormedPageSize > 1 || yNormedPageSize < 0 || yNormedPageSize > 1) {
1374+
Message("Data coordinate system not established.");
1375+
if (xNormedPageSize < 0) xNormedPageSize=0;
1376+
if (yNormedPageSize < 0) yNormedPageSize=0;
1377+
if (xNormedPageSize > 1) xNormedPageSize=1;
1378+
if (yNormedPageSize > 1) yNormedPageSize=1;
1379+
}
1380+
DFloat zNormedPageSize=1; //zend-zstart??;
1381+
DFloat xNormedOffset=xstart*theCurrentChar.ndsx;
1382+
DFloat yNormedOffset=yend*theCurrentChar.nspacing;
1383+
//check silly values: normed must be >0 and < 1
13431384
int p=thePage.curPage-1;
1344-
PLFLT width=1.0/thePage.nx;
1345-
PLFLT height=1.0/thePage.ny;
1346-
PLFLT profund=1.0/thePage.nz;
1385+
PLFLT width=xNormedPageSize/thePage.nx;
1386+
PLFLT height=yNormedPageSize/thePage.ny;
1387+
PLFLT profund=zNormedPageSize/thePage.nz;
13471388
int k= p / (thePage.nx*thePage.ny);
13481389
int l= p - k*(thePage.nx*thePage.ny);
13491390
int j= l /thePage.nx ;
1350-
int i= (l - j*thePage.nx);
1351-
sxmin=i*width;
1352-
sxmax=sxmin+width;
1353-
symax=1-(j*height);
1354-
symin=symax-height;
1391+
int i= (l - j*thePage.nx);
1392+
*sxmin=i*width+xNormedOffset;
1393+
*sxmax=*sxmin+width;
1394+
*symax=1-(j*height+yNormedOffset);
1395+
*symin=*symax-height;
13551396
if (szmin != NULL) {
13561397
*szmin=k*profund;
13571398
*szmax=*szmin+profund;

src/gdlgstream.hpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -625,9 +625,7 @@ class GDLGStream: public plstream
625625
void setLineSpacing( PLFLT spacing );
626626
PLFLT getSymbolSize();
627627
void mtex( const char *side, PLFLT disp, PLFLT pos, PLFLT just,
628-
const char *text);
629-
void mtex3( const char *side, PLFLT disp, PLFLT pos, PLFLT just,
630-
const char *text);
628+
const char *text, double *stringCharLength=NULL, double *stringCharHeight=NULL);
631629
void ptex( PLFLT x, PLFLT y, PLFLT dx, PLFLT dy, PLFLT just,
632630
const char *text, double *stringCharLength=NULL );
633631
void setVariableCharacterSize( PLFLT charwidthpixel, PLFLT scale, PLFLT lineSpacingpixel, PLFLT xpxcm, PLFLT ypxcm);
@@ -641,7 +639,7 @@ class GDLGStream: public plstream
641639
void wind( PLFLT xmin, PLFLT xmax, bool xLog, PLFLT ymin, PLFLT ymax, bool yLog );
642640
void ssub( PLINT nx, PLINT ny, PLINT nz=1);
643641
void adv(PLINT page);
644-
void getSubpageRegion(PLFLT &sxmin, PLFLT &symin, PLFLT &sxmax, PLFLT &symax, PLFLT *zmin=NULL, PLFLT *zmax=NULL);
642+
void getSubpageRegion(PLFLT *sxmin, PLFLT *symin, PLFLT *sxmax, PLFLT *symax, PLFLT *zmin=NULL, PLFLT *zmax=NULL);
645643
void SetPageDPMM(float setPsCharFudge=1.0, float setPsSymFudge=1.0);
646644
void syncPageInfo();
647645
void updateBoxDeviceCoords();

src/gdlwxstream.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ GDLWXStream::GDLWXStream( int width, int height )
9393
plstream::wind(0,1,0,1);
9494

9595
ssub(1,1);
96-
adv(0); //this is for us (counters)
9796
SetPageDPMM();
9897
DefaultCharSize();
98+
adv(0); //this is for us (counters) //needs DefaultCharSize
9999
clear();
100100
}
101101

src/gdlxstream.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ class GDLXStream: public GDLGStream
7474
plstream::wind(0, 1, 0, 1);
7575

7676
ssub(1, 1);
77-
adv(0); //this is for us (counters)
7877
SetPageDPMM();
7978
DefaultCharSize();
79+
adv(0); //this is for us (counters) //needs DefaultCharSize
8080
clear();
8181
}
8282

src/libinit.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,8 @@ void LibInit()
982982

983983
new DLibFunRetNew(lib::t_pdf,string("T_PDF"),2);
984984

985-
new DLibPro(lib::caldat, string("CALDAT"), 7);
985+
const string caldatKey[]={"GDL_DOW","GDL_ICAP",KLISTEND};
986+
new DLibPro(lib::caldat, string("CALDAT"), 7, caldatKey);
986987
new DLibFunRetNew(lib::julday, string("JULDAY"), 6);
987988

988989
// SA: the HYBRID key is used in imsl_zerosys.pro to switch to the modif. brent algo.

0 commit comments

Comments
 (0)