! display_range.MBS
! Display a range of Hershey glyphs at (0,0) in a local coordinate system.

local drawing module display_range(
int    range_number;
string range_name*128;
int    start;
int    stop;
int    box_radius;
int    toplevel;         ! 0 = false = not top level; 1 = true = top level
int    box_visibility;   ! 0 = plain = invisible (no boxes); 1 = boxed = visible
int    verbosity);

int    onesplace;
float  onesplace_float;
float  start_float;
float  x, y;
int    glyph_number;
int    glyph_csys_number;
string shortname*8;
int    numpairs;
int    pairs(300);
int    rc;
string range_label*128;

string homedir*132;
string prefix*132;

! crop/plot size
float  edge_left, edge_right, edge_top, edge_bottom;

int    very_large_glyph_range;

constant int toplevel_false = 0;
constant int toplevel_true  = 1;

beginmodule

   if verbosity >= 9 then
      lst_lin("display_range: range " + str(range_number,1,0) +
                           ", start " + str(start,1,0) + 
                           ", stop " + str(stop,1,0));
   endif;

   start_float := start;

   ! At present, there are three "radii" of glyphs: 10, 25, and 50.
   ! These radii are used to space the glyphs.
   ! It is necessary also to adjust the size of the crop marks
   ! (if at top level) and the size of the plotted area (also,
   ! if at top level) to accomodate these sizes.
   ! for simplicity, cropmark and plot ranges of radii 10 and 25
   ! the same, and make an exception only for ranges of radius 50
   ! (there are only two such ranges: No. 80 (very large grouping
   ! symbols) and No. 185 (large pointing hands).
   
   if box_radius = 50 then
      very_large_glyph_range := 1;
   else
      very_large_glyph_range := 0;
   endif;

   ! if the box isn't visible, display the glyphs closer together
   if box_visibility = 0 then
      box_radius := trunc(box_radius/3);
   endif;

   if toplevel = toplevel_true then
      ! Draw four crop marks so that the image generated from
      ! this will crop to a known size.

      ! Determine the edges; these numbers are empirical
      if box_visibility = 0 then
         if very_large_glyph_range = 0 then
            edge_left   :=  -45;
            edge_right  :=  435;
            edge_top    :=   60;
            edge_bottom := -240;
         else
            edge_left   :=  -45;
            edge_right  :=  550;
            edge_top    :=   60;
            edge_bottom := -240;
         endif;
      else
         if very_large_glyph_range = 0 then
            edge_left   :=  -45;
            edge_right  :=  675;
            edge_top    :=  120;
            edge_bottom := -360;
         else
            edge_left   :=  -45;
            edge_right  := 1200;
            edge_top    :=  120;
            edge_bottom := -360;
         endif;
      endif;

      poi_free(#10,vec(edge_left,  edge_top));     ! upper left
      poi_free(#11,vec(edge_right, edge_top));     ! upper right
      poi_free(#12,vec(edge_right, edge_bottom));  ! lower right
      poi_free(#13,vec(edge_left,  edge_bottom));  ! lower left
   endif;


   ! This should work, but doesn't - it works for 507,
   ! but fails for 508 and 509.
   ! There seems to be a bug in trunc() for VARKON 1.17D
   ! No such bug is listed in the 1.18A release notes, but
   ! a bug whereby abs() failed on expressions is.
   !onesplace := trunc(frac(start_float/10.0) * 10.0);
   ! So instead kludge it with strings:
   onesplace_float := frac(start_float/10.0) * 10.0;
   onesplace       := ival(substr(str(onesplace_float,1,0),1,1));

   ! Hershey glyph numbers tend to start with 1
   if onesplace = 0 then
      x := 9 * ((box_radius * 2) + 20);
   else
      x := (onesplace - 1) * ((box_radius * 2) + 20);
   endif;
   y := 0;  ! redundant, yes

   glyph_csys_number := 1;
   for glyph_number := start to stop do

      ! create a local coordinate system for the glyph
      csys_1p(#40,"glyph",vec(x,y):blank=1);

      ! rely upon show_one_glyph() not to show nonexistent glyphs
      part(#41,show_one_glyph(glyph_number, toplevel_false, box_visibility,
                              verbosity), 
               refc(40,glyph_csys_number));

      if glyph_number/10 - trunc(glyph_number/10) = 0 then
         x := 0;
         y := y - (box_radius * 2) - 20;
      else
         x := x + (box_radius * 2) + 20;
      endif;

      glyph_csys_number := glyph_csys_number + 1;
   endfor;

   ! label the range, again in the local coordinate system
   ! if the descriptive boxes are invisible, just use the range number
   set(tsize=6);
   if box_visibility = 1 then
      range_label := "Range " + str(range_number,1,0) + ": " + range_name;
   else
      range_label := str(range_number,1,0) + ":";
   endif;
   text(#50,vec((box_radius * 10) + (4 * 20) - textl(range_label)/2, 
                box_radius + 10),
                0,range_label);

   ! plot it automatically
   if toplevel = toplevel_true then
      homedir := get_environment("HOME");
      if box_visibility = 0 then
         prefix := "range-";
      else                 
         prefix := "rangeboxed-";
      endif;
      plot_win(
         vec(edge_left-1, edge_bottom-1), vec(edge_right+1, edge_top+1),
         homedir + "/hershey_plots/" + prefix + str(range_number,1,0) +".PLT",
         vec(0,0));
   endif;

   ! Aside: Though the code above (and in display_glyph(), and, though
   !        redundantly, in display_table()) avoids the situation
   !        whereby we plot when not at the top level of invocation,
   !        were this the case it would fail.
   !        VARKON's plot_win() function plots relative to the
   !        model, not the currently active coordinate system.


endmodule

! Copyright 2003, 2004 by David M. MacMillan

! This work is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 2 of the License, or
! (at your option) any later version.

! NOTICE OF DISCLAIMER OF WARRANTY AND LIABILITY:

! This work is distributed WITHOUT ANY WARRANTY;
! without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
! See the GNU General Public License for more details.

! In no event will the author(s), editor(s), or publisher(s) of this work
! be liable to you or to any other party for damages,
! including but not limited to any general, special, incidental
! or consequential damages arising out of your use of or inability to use this
! work or the information contained in it, even if you have been advised
! of the possibility of such damages.

! In no event will the author(s), editor(s), or publisher(s) of this work
! be liable to you or to any other party for any injury, death,
! disfigurement, or other personal damage arising out of your use of
! or inability to use this work or the information
! contained in it, even if you have been advised of the
! possibility of such injury, death, disfigurement, or other
! personal damage.

! You should have received a copy of the GNU General Public License
! along with this work; if not, write to the
! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
! Boston, MA  02111-1307, USA.

