00001 00002 c 00003 c Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993, 00004 c by Steve McMillan, Drexel University, Philadelphia, PA. 00005 c 00006 c All rights reserved. 00007 c 00008 c Redistribution and use in source and binary forms are permitted 00009 c provided that the above copyright notice and this paragraph are 00010 c duplicated in all such forms and that any documentation, 00011 c advertising materials, and other materials related to such 00012 c distribution and use acknowledge that the software was developed 00013 c by the author named above. 00014 c 00015 c THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 00016 c IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 00017 c WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00018 c 00019 00020 c------------------------------------------------------------------------ 00021 c 00022 c Box creation and resizing. 00023 c 00024 c Contents: setup 00025 c newbox 00026 c offbox 00027 c popbox 00028 c setaspects 00029 c fitbox 00030 c 00031 c------------------------------------------------------------------------ 00032 00033 00034 block data init box params 00035 save 00036 c 00037 common /last aspect/ aspect0 00038 common /compress frames/ icompress 00039 c 00040 data aspect0/1./icompress/0/ 00041 c 00042 end 00043 00044 00045 subroutine setup(device,id) 00046 save 00047 c 00048 c Set up graphics and frame parameters. 00049 c 00050 character*(*) device,id 00051 common /plot sizes/ xsize,ysize 00052 common /draw params/ roff,soff,aspect1,xlen,ylen,hs,hn,hp, 00053 & idevset,jbox,iorig 00054 c 00055 common /initial/ roff0,soff0,hn0,hs0,hp0 00056 common /last aspect/ aspect0 00057 common /dev init/ init 00058 c 00059 character*80 dev 00060 common /plot device/ dev,aspect,idev 00061 character*80 colormapfile 00062 common /mcdraw_colormap_file/ colormapfile 00063 c 00064 common /prompt/ iprompt 00065 integer curr_win 00066 c 00067 if (idevset.eq.0.and.init.eq.0) then 00068 c 00069 c Establish some defaults and initialize the system. 00070 c 00071 if (iprompt.eq.1) then 00072 if (id(1:1).ne.' ') then 00073 write(6,'(a,a,a)')'Graphics setup triggered by "', 00074 $ id,'" command' 00075 else 00076 if (device(1:1).eq.' ') then 00077 write(6,'(a)')'Initializing graphics with "de"' 00078 else 00079 write(6,'(a,a,a)') 00080 $ 'Initializing graphics with "de ', 00081 $ device,'"' 00082 end if 00083 end if 00084 write(6,'(a)')'Prior settings will be overridden' 00085 end if 00086 c 00087 call options('-x 0.5 -b 255') 00088 call mcinita(device) 00089 call setpln 00090 call sethts(hs,hn) 00091 call nobounds 00092 idevset = 1 00093 colormapfile = 'default' 00094 00095 else 00096 c 00097 c Choose a new device. 00098 c 00099 c NOTE: Context switching must be performed here if we want 00100 c different windows/devices to be independent. 00101 c 00102 idevold = idev 00103 icurrwin = curr_win() 00104 call save_context(idev,icurrwin) 00105 c 00106 call dev selecta(device) 00107 colormapfile = 'default' 00108 c 00109 icurrwin = curr_win() 00110 call load_context(idev,icurrwin) 00111 c 00112 idevset = 1 00113 c 00114 if (idevold.eq.17.and.idev.ne.idevold 00115 $ .and.num_win(17).gt.0) then 00116 c 00117 c Shouldn't be necessary to close X windows if we can 00118 c get input from them... 00119 c 00120 c if (iprompt.ne.0) write(6,*) 00121 c $ '(Iconifying inactive X-windows.)' 00122 c call iconify_all 00123 end if 00124 end if 00125 c 00126 call getstatus(idum,idum,ic, iw) 00127 c 00128 c The aspect ratio will have been set to the ratio for the 00129 c specified device. Reset it here if aspect1 has been set. 00130 c 00131 if (aspect1.gt.0.) aspect = aspect1 00132 c 00133 call setaspects(aspect,ax,ay) 00134 c 00135 c On return from setaspects, aspect will be the specified value or 00136 c the device default, and ax and ay will be set accordingly. 00137 c 00138 if (iorig.eq.0) then 00139 c 00140 c Initial setup of basic graphics parameters. 00141 c 00142 c The initial definitions of roff0 and soff0 are in terms 00143 c of the device dimensions. Because of the possibility of 00144 c horizontal y-labels, roff0 is somewhat larger than soff0. 00145 c 00146 roff0 = xsize*roff0 00147 soff0 = ysize*soff0 00148 c 00149 c NOTE: The height settings in effect at the first frame 00150 c initialization become the default. 00151 c 00152 hs0 = hs 00153 hn0 = hn 00154 hp0 = hp 00155 c 00156 iorig = 1 00157 c 00158 end if 00159 c 00160 c Establish the new offset of the box within the frame, 00161 c and other plot parameters. 00162 c 00163 if (jbox.eq.0) then 00164 scale = 1. 00165 roff = roff0 00166 soff = soff0 00167 hs = hs0 00168 hn = hn0 00169 hp = hp0 00170 else 00171 scale = .5 00172 roff = roff0 / 1.5 00173 soff = soff0 / 1.25 00174 ss = sqrt(scale) 00175 hs = hs0 * ss 00176 hn = hn0 * ss 00177 hp = hp0 * ss 00178 end if 00179 c 00180 call sethts(hs,hn) 00181 c 00182 c Choose xlen and ylen, maintaining the correct aspect ratio, 00183 c and fitting into the space available. 00184 c 00185 call fitbox(roff,soff,aspect,scale,xlen,ylen,xextra,yextra) 00186 c 00187 c Establish the offset of the frame. Note that the subdivision 00188 c splits the display into four equal pieces, unless the "compress" 00189 c flag has been sent (via common) to fitbox, and xextra and yextra 00190 c are nonzero. 00191 c 00192 call setorigin(0.,0.) 00193 if (jbox.eq.2.or.jbox.eq.4) call plot(.5*xsize-xextra,0.,-3) 00194 if (jbox.eq.1.or.jbox.eq.2) call plot(0.,.5*ysize-yextra,-3) 00195 c 00196 c Offset the box within the frame. 00197 c 00198 call plot(roff,soff,-3) 00199 call setlhe(-roff) 00200 call setbot(-soff) 00201 c 00202 c Save the current value of the aspect ratio. 00203 c 00204 aspect0 = aspect 00205 c 00206 end 00207 00208 00209 subroutine newbox(input,nin,ierbox,*) 00210 save 00211 c 00212 c Choose a new output area. 00213 c The input arguments from mcdraw are in input(1:nin). 00214 c 00215 character*(*) input 00216 dimension ierbox(0:4) 00217 c 00218 common /plot sizes/ xsize,ysize 00219 common /draw params/ roff,soff,aspect1,xlen,ylen,hs,hn,hp, 00220 & idevset,jbox,iorig 00221 c 00222 common /initial/ roff0,soff0,hn0,hs0,hp0 00223 common /last aspect/ aspect0 00224 c 00225 data inew/0/ 00226 c 00227 jboxo = jbox 00228 idel = 1 00229 c 00230 if (nin.lt.2.or.input(2:2).eq.' '.or.input(2:3).eq.'- ' 00231 & .or.input(2:3).eq.'-0') then 00232 jbox = 0 00233 idel = 0 00234 else 00235 read(input(2:nin),'(i5)',iostat=io)jbox 00236 if (io.ne.0) then 00237 write(6,'(a,a,a)') 00238 $ 'Error reading argument "',input(2:nin),'"' 00239 go to 1001 00240 end if 00241 end if 00242 c 00243 if (jbox.lt.0) then 00244 jbox = -jbox 00245 idel = 0 00246 end if 00247 c 00248 if (jbox.eq.5) then 00249 jbox = 0 00250 idel = 0 00251 end if 00252 c 00253 jbox = max(0,min(4,jbox)) 00254 c 00255 if (aspect1.gt.0.) aspect = aspect1 00256 call setaspects(aspect,ax,ay) 00257 c 00258 if (inew.eq.0.or.aspect.ne.aspect0.or.jbox.ne.jboxo) then 00259 c 00260 inew = 1 00261 c 00262 if (idevset.eq.0) then 00263 jb = jbox 00264 jbox = jboxo 00265 call setup(' ','newbox') 00266 jbox = jb 00267 aspect = aspect1 00268 call setaspects(aspect,ax,ay) 00269 end if 00270 c 00271 if (aspect.ne.aspect0.or.jbox*jboxo.eq.0) then 00272 c 00273 c Change plot size or shape. Note that "=x" has the 00274 c effect of reinitializing the offsets and heights to 00275 c the default, or scaled default, values. 00276 c 00277 if (jbox.eq.0) then 00278 scale = 1. 00279 roff = roff0 00280 soff = soff0 00281 hs = hs0 00282 hn = hn0 00283 hp = hp0 00284 else 00285 scale = .5 00286 roff = roff0 / 1.5 00287 soff = soff0 / 1.25 00288 ss = sqrt(scale) 00289 hs = hs0 * ss 00290 hn = hn0 * ss 00291 hp = hp0 * ss 00292 end if 00293 c 00294 end if 00295 c 00296 call sethts(hs,hn) 00297 c 00298 end if 00299 c 00300 c Choose xlen and ylen, maintaining the correct aspect ratio, 00301 c and fitting into the space available. 00302 c 00303 call fitbox(roff,soff,aspect,scale,xlen,ylen, 00304 & xextra,yextra) 00305 c 00306 c Reposition the bottom-left corner of the current frame. 00307 c Note that the subdivision splits the display into four 00308 c equal pieces unless the "compress" flag has been sent 00309 c (via common) to fitbox, and xextra and yextra are nonzero. 00310 c 00311 call setorigin(0.,0.) 00312 if (jbox.eq.2.or.jbox.eq.4) 00313 & call plot(.5*xsize-xextra,0.,-3) 00314 if (jbox.eq.1.or.jbox.eq.2) 00315 & call plot(0.,.5*ysize-yextra,-3) 00316 c 00317 c The old box will only be erased if both idel and ierbox are 00318 c set, or if a shape change has occurred. 00319 c 00320 if (idel.eq.1.and.(ierbox(jbox).eq.1 00321 & .or.aspect.ne.aspect0)) then 00322 if (jbox.eq.0) then 00323 call clear 00324 else 00325 c 00326 c Clear any unused space. 00327 c 00328 if (jbox.eq.1) then 00329 call erase(0.,.5*xsize-xextra,0.,.5*ysize+yextra) 00330 else if (jbox.eq.2) then 00331 call erase(0.,.5*xsize+xextra,0.,.5*ysize+yextra) 00332 else if (jbox.eq.3) then 00333 call erase(0.,.5*xsize-xextra,0.,.5*ysize-yextra) 00334 else 00335 call erase(0.,.5*xsize+xextra,0.,.5*ysize-yextra) 00336 end if 00337 c 00338 end if 00339 end if 00340 c 00341 do k=0,4 00342 ierbox(k) = 1 00343 end do 00344 ierbox(jbox) = 0 00345 c 00346 c Establish the offset of the box within the frame. 00347 c 00348 call plot(roff,soff,-3) 00349 call setlhe(-roff) 00350 call setbot(-soff) 00351 c 00352 c Save the last-used aspect ratio. 00353 c 00354 aspect0 = aspect 00355 c 00356 return 00357 1001 return 1 00358 c 00359 end 00360 00361 00362 subroutine offbox(input,nin,ierbox,xbox,ybox,bscale,nbox,*) 00363 save 00364 c 00365 c Choose a new output area with arbitrary (absolute) offset and size. 00366 c 00367 character*(*) input 00368 dimension ierbox(0:4) 00369 dimension xbox(1),ybox(1),bscale(1) 00370 c 00371 common /plot sizes/ xsize,ysize 00372 common /draw params/ roff,soff,aspect1,xlen,ylen,hs,hn,hp, 00373 & idevset,jbox,iorig 00374 c 00375 common /initial/ roff0,soff0,hn0,hs0,hp0 00376 c 00377 character*40 arg(4) 00378 c 00379 if (nin.le.0) go to 99999 00380 iflag = 0 00381 c 00382 call gettokens(input(1:nin),arg,narg) 00383 if (narg.lt.2) go to 99999 00384 c 00385 call readrq(input(1:nin),narg, 00386 & x,y,scale,xiflag,*99999) 00387 c 00388 if (narg.lt.3) scale = 1. 00389 if (narg.lt.4) xiflag = 0. 00390 c 00391 iflag = nint(xiflag) 00392 c 00393 c Apply some checks (don't restrict y to be less than ysize, note). 00394 c 00395 if (x.lt.0..or.x.gt.xsize.or.y.lt.0. 00396 & .or.scale.le.0..or.scale.gt.1.) go to 99999 00397 ioff = 0 00398 go to 1 00399 c 00400 entry offbox1(x1,y1,scale1,iflag1,ierbox,*) 00401 c 00402 x = x1 00403 y = y1 00404 scale = scale1 00405 iflag = iflag1 00406 ioff = 1 00407 c 00408 c Undo any standard subdivisions. 00409 c 00410 1 if (jbox.ne.0) call newbox('=-0',3,ierbox,*99999) 00411 c 00412 c Set the new origin (absolute units). 00413 c 00414 call setorigin(x,y) 00415 c 00416 c Set up the new box parameters. 00417 c 00418 aspect = aspect1 00419 call setaspects(aspect,ax,ay) 00420 c 00421 c Establish a fictitious "offset" for the box, even though (x,y) 00422 c as specified refers to the botom-left corner of the box itself. 00423 c 00424 c (Note that setup has already been called, so roff0 and soff0 are 00425 c in "standard" units, rather than relative to the display size.) 00426 c 00427 ss = sqrt(scale) 00428 c 00429 roff = ax*ss*roff0 00430 soff = ay*ss*soff0 00431 c 00432 call setlhe(-roff) 00433 call setbot(-soff) 00434 c 00435 hn = ss*hn0 00436 hs = ss*hs0 00437 hp = ss*hp0 00438 call sethts(hs,hn) 00439 c 00440 c Choose xlen and ylen, maintaining the correct aspect ratio, 00441 c and fitting into the space available. 00442 c 00443 call fitbox(roff,soff,aspect,scale,xlen,ylen,xextra,yextra) 00444 c 00445 c Clear the appropriate region of the screen, if requested. 00446 c Note that, in this case, the erased area follows the box, 00447 c as opposed to being a fixed quadrant of the screen. 00448 c 00449 if (iflag.ne.0) call erase(-1.1*roff,1.1*xlen,-1.1*soff,1.1*ylen) 00450 c 00451 if (ioff.eq.0) then 00452 c 00453 c Save everything on the stack. 00454 c 00455 nbox = nbox + 1 00456 xbox(nbox) = x 00457 ybox(nbox) = y 00458 bscale(nbox) = scale 00459 end if 00460 c 00461 return 00462 99999 return 1 00463 c 00464 end 00465 00466 00467 subroutine popbox(input,nin,ierbox,xbox,ybox,bscale,nbox,*) 00468 save 00469 c 00470 c Pop a previous output area from the box stack. 00471 c 00472 character*(*) input 00473 dimension xbox(1),ybox(1),bscale(1) 00474 character*40 arg(4) 00475 c 00476 common /initial/ roff0,soff0,hn0,hs0,hp0 00477 c 00478 c Count the number of arguments. 00479 c 00480 call gettokens(input(1:nin),arg,narg) 00481 c 00482 if (narg.gt.0) call readiq(input(1:nin),narg, 00483 & ipop,iflag,idum,idum,*99999) 00484 if (narg.lt.1) ipop = 1 00485 if (narg.lt.2) iflag = 0 00486 c 00487 if (ipop.gt.nbox) then 00488 write(6,*)'Box stack underflow' 00489 go to 99999 00490 end if 00491 c 00492 nbox = nbox - ipop 00493 if (nbox.gt.0) then 00494 call offbox1(xbox(nbox),ybox(nbox),bscale(nbox),iflag, 00495 & ierbox,*99999) 00496 else 00497 call offbox1(roff0,soff0,1.,iflag,ierbox,*99999) 00498 end if 00499 c 00500 return 00501 99999 return 1 00502 c 00503 end 00504 00505 00506 subroutine setaspects(aspect,ax,ay) 00507 c 00508 c Standard interpretation of the aspect ratio. 00509 c On return, aspect is the specified aspect ratio, or the 00510 c device default, ax is the reduction factor in the x- 00511 c direction, ay is the reduction factor in the y-direction. 00512 c 00513 character*80 device 00514 common /plot device/ device,devaspect,idev 00515 c 00516 c Use the device aspect ratio if none is specified. 00517 c 00518 if (aspect.le.0.) aspect = devaspect 00519 c 00520 if (aspect.le.devaspect) then 00521 ax = 1. 00522 ay = aspect 00523 else 00524 ax = devaspect/aspect 00525 ay = 1. 00526 end if 00527 c 00528 end 00529 00530 00531 subroutine fitbox(roff,soff,aspect,scale,xlen,ylen, 00532 & xextra,yextra) 00533 c 00534 c Ensure that the box has the correct aspect ratio and will 00535 c fit in the space available. The "excess" space at the 00536 c right or top is returned in xextra or yextra. 00537 c 00538 c Reduce roff and soff, if necessary, to fit the plot in. 00539 c 00540 common /plot sizes/ xsize,ysize 00541 common /compress frames/ icompress 00542 c 00543 parameter (WHITESPACE = 0.7, OFFTOL = 0.4) 00544 c 00545 c Allow for offset of box, and (scaled) spacing at right. 00546 c 00547 dx = scale*(xsize - WHITESPACE) 00548 if (roff.gt.OFFTOL*dx) roff = OFFTOL*dx 00549 xlen = dx - roff 00550 c 00551 c Choose ylen to get the correct aspect ratio. 00552 c 00553 ylen = xlen*aspect 00554 c 00555 c Make sure that the y-axis will fit, by shrinking the entire 00556 c plot if necessary. 00557 c 00558 dy = scale*(ysize - WHITESPACE*min(aspect,1.)) 00559 if (soff.gt.OFFTOL*dy) soff = OFFTOL*dy 00560 ylmax = dy - soff 00561 c 00562 xextra = 0. 00563 yextra = 0. 00564 if (icompress.ne.0) yextra = max(0., ylmax - ylen) 00565 c 00566 if (ylen.gt.ylmax) then 00567 xlen0 = xlen 00568 xlen = xlen*ylmax/ylen 00569 ylen = ylmax 00570 if (icompress.ne.0) xextra = xlen0 - xlen 00571 end if 00572 c 00573 end