Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

box.f

Go to the documentation of this file.
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

Generated at Sun Feb 24 09:56:55 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001