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