home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / books / progem / vdigrph.9 < prev    next >
Text File  |  1986-11-01  |  25KB  |  526 lines

  1.      Permission to reprint or excerpt is granted only if the following
  2.      line appears at the top of the article:
  3.  
  4.       ANTIC PUBLISHING INC., COPYRIGHT 1986.  REPRINTED BY PERMISSION.
  5.  
  6.  
  7.  
  8.      PROFESSIONAL GEM  by Tim Oren
  9.      Column #9 - VDI Graphics: Lines and Solids
  10.  
  11.  
  12.          This issue of ST PRO GEM is the first in a series of two which
  13.      will  explore  the  fundamentals  of VDI graphics output.  In this
  14.      installment,  we  will  take  a  look at the commands necessary to
  15.      output simple graphics such as lines,  squares and circles as well
  16.      as  more complex figures such as polygons.   The following episode
  17.      will  take a first look at graphics text output,  with an emphasis
  18.      on  ways  to  optimize its drawing speed.   It will  also  include
  19.      another  installment  of ONLINE Feedback.   As usual,  there is  a
  20.      download  with  this column.   You should find it under  the  name
  21.      GEMCL9.C in DL3 of ATARI16 (PCS-58).
  22.  
  23.           A BIT OF HISTORY.  One  of  the reasons that the VDI  can  be
  24.      confusing is that drawing anything at all, even a simple line, can
  25.      involve setting around four different VDI parameters before making
  26.      the draw call! (Given the state of the GEM documents, just FINDING
  27.      them can be fun!)  Looking backwards a bit sheds some light on why
  28.      the VDI is structured this way, and also gives us a framework  for
  29.      organizing a discussion of graphics output.
  30.  
  31.           The GEM VDI closely follows the so-called GKS standard, which
  32.      defines  capabilities  and calling sequences  for  a  standardized
  33.      graphic  input/output system.   GKS is itself an evolution from an
  34.      early system called "Core".   Both of these standards were born in
  35.      the  days  when  pen plotters,  vectored  graphics  displays,  and
  36.      minicomputers  were  the  latest items.   So,  if you  wonder  why
  37.      setting  the drawing pen color is a separate command,  just  think
  38.      back  a  few  years when it actually meant  what  it  says!   (The
  39.      cynical   may   choose   instead  to  ponder   the   benefits   of
  40.      standardization.)
  41.  
  42.           When  doing  VDI  output,  it helps if you pretend  that  the
  43.      display screen really is a plotter or some other separate  device,
  44.      which  has  its own internal parameters which you can set  up  and
  45.      read  back.   The class of VDI commands called Attribute Functions
  46.      let  you set the parameters.   Output Functions cause the "device"
  47.      to  actually  draw  someone once it is  configured.   The  Inquire
  48.      Functions let you read back the parameters if necessary.
  49.  
  50.           There  are two parameters which are relevant no  matter  what
  51.      type of object you are trying to draw.   They are the writing mode
  52.      and  the clipping rectangle.   The writing mode is similar to that
  53.      discussed in the column on raster operations.   It determines what
  54.      effect the figure you are drawing will have on data already on the
  55.      screen.  The writing mode is set with the call:
  56.  
  57.                vswr_mode(vdi_handle, mode);
  58.  
  59.          Vdi_handle,  here  and  below,  is the  handle  obtained  from
  60.      graf_handle at the beginning of the program.  Mode is a word which
  61.      may be one of:
  62.  
  63.                1 - Replace Mode,
  64.                2 - Transparent Mode,
  65.                3 - XOR mode,
  66.                4 - Reverse Transparent Mode.
  67.  
  68.           In  replace mode,  whatever is on the screen is  overwritten.
  69.      If  you are writing characters,  this means the background of each
  70.      character cell will be erased.
  71.  
  72.           In  transparent  mode,  only  the pixels directly  under  the
  73.      "positive"  part  of the image,  that is,  where 1-bits are  being
  74.      written, will be changed.  When writing characters, the background
  75.      of the cell will be left intact.
  76.  
  77.           In XOR mode,  an exclusive or is performed between the screen
  78.      contents and what is being written.   The effect is to reverse the
  79.      image under areas where a 1-bit occurs.
  80.  
  81.           Reverse transparent is like transparent,  but with a "reverse
  82.      color  scheme".   That  is,  only  places where a 0-bit is  to  be
  83.      put   are  changed  to  the  current  writing  color.    When  you
  84.      write  characters in reverse transparent (over white),  the effect
  85.      is reverse video.
  86.  
  87.           The  other  common parameter is the clipping  rectangle.   It
  88.      defines the area on the screen where the VDI is permitted to draw.
  89.      Any output which would fall outside of this area is ignored; it is
  90.      effectively a null operation.   The clip rectangle is set with the
  91.      call:
  92.  
  93.                vs_clip(vdi_handle, flag, pxy);
  94.  
  95.         Pxy is a four-word array.   Pxy[0] and pxy[1] are the X  and  Y
  96.      screen coordinates,  respectively,  of one corner of your clipping
  97.      rectangle.    Pxy[2]  and  pxy[3]  are  the  coordinates  of   the
  98.      diagonally opposite corner of the rectangle.   (When working  with
  99.      the  AES,  use  of  a  GRECT to define  the  clip  is  often  more
  100.      convenient.  The routine set_clip() in the download does this.)
  101.  
  102.           Flag is set to TRUE if clipping is to be used.  If you set it
  103.      to  FALSE,  the  entire  screen is assumed to be fair  game.
  104.  
  105.           Normally,  you should walk the rectangle list for the current
  106.      window to obtain your clipping rectangles.  (See ST PRO GEM #2 for
  107.      more details.)  However, turning off the clip speeds up all output
  108.      operations,  particularly text.  You may do this ONLY when you are
  109.      absolutely certain that the figure you are drawing will not extend
  110.      out of the top-most window, or out of a dialog.
  111.  
  112.           THE LINE FORMS ON THE LEFT.  The VDI line drawing  operations
  113.      include polyline,  arc,  elliptical arc,  and  rounded  rectangle.
  114.      I'll first look at the Attribute Functions for line drawing,  then
  115.      go through the drawing primitives themselves.
  116.  
  117.           The  most  common used line attributes are color  and  width.
  118.      The color is set with:
  119.  
  120.                vsl_color(vdi_handle, color);
  121.  
  122.         where color is one of the standard VDI color  indices,  ranging
  123.      from  zero to 15.   (As discussed in column #6,  the  color  which
  124.      actually appears will depend on the pallette setting of your ST.)
  125.  
  126.           The  line width may only be set to ODD positive  values,  for
  127.      reasons  of  symmetry.   If you try to set an even value,  the VDI
  128.      will take the next lower odd value.  The call is:
  129.  
  130.                vsl_width(vdi_handle, width);
  131.  
  132.           The  two  less  used line parameters are the  end  style  and
  133.      pattern.   With  the  end style you can cause the output  line  to
  134.      have rounded ends or arrowhead ends.  The call is:
  135.  
  136.                vsl_ends(vdi_handle, begin_style, end_style);
  137.  
  138.         Begin_style  and end_style are each words which  may  have  the
  139.      values zero for square ends (the default),  one for arrowed  ends,
  140.      or  two  for  rounded ends.   They determine the  styles  for  the
  141.      starting and finishing ends of the line, respectively.
  142.  
  143.           The line pattern attribute can select dotted or dashed  lines
  144.      as  well  as more complicated patterns.   Before  continuing,  you
  145.      should  note one warning:  VDI line output DOES NOT compensate for
  146.      pixel aspect ratio.  That is, the dashes on a line will look twice
  147.      as long drawn vertically on a medium-res ST screen as they do when
  148.      drawn horizontally.  The command for setting the pattern is:
  149.  
  150.                vsl_type(vdi_handle, style);
  151.  
  152.         Style  is  a word with a value between 1  and  7.   The  styles
  153.      selected are:
  154.  
  155.                1 - Solid (the default)
  156.                2 - Long Dash
  157.                3 - Dot
  158.                4 - Dash, Dot
  159.                5 - Dash
  160.                6 - Dash, Dot, Dot
  161.                7 - (User defined style)
  162.  
  163.         The  user  defined  style is determined  by  a  16-bit  pattern
  164.      supplied  by the application.   A one bit in the pattern  turns  a
  165.      pixel on, a zero bit leaves it off.  The pattern is cycled through
  166.      repeatedly,  using the high bit first.  To use a custom style, you
  167.      must make the call:
  168.  
  169.                vsl_udsty(vdi_handle, pattern);
  170.  
  171.        before doing vsl_type().
  172.  
  173.           As  I  mentioned  above,   the  line  type  Output  Functions
  174.      available are polyline,  circular and ellliptical arc, and rounded
  175.      rectangle.   Each  has  its own calling sequence.   The call for a
  176.      polyline is:
  177.  
  178.                v_pline(vdi_handle, points, pxy);
  179.  
  180.        Points tells how many vertices will appear on the polyline.  For
  181.      instance,  a  straight  line has two vertices:  the  end  and  the
  182.      beginning.   A closed square would have five,  with the first  and
  183.      last  identical.    (There  is  no  requirement  that  the  figure
  184.      described be closed.)
  185.  
  186.           The pxy array contains the X and Y raster coordinates for the
  187.      vertices,  with a total of 2 * points entries.   Pxy[0] and pxy[1]
  188.      are the first X-Y pair, and so on.
  189.  
  190.           If you happen to be using the XOR drawing mode, remember that
  191.      drawing  twice  at  a point is equivalent to no  drawing  at  all.
  192.      Therefore,  for  a figure to appear closed in XOR mode,  the final
  193.      stroke  should actually stop one pixel short of the origin of  the
  194.      figure.
  195.  
  196.           You  may  notice  that  in the GEM  VDI  manual  the  rounded
  197.      rectangle  and arc commands are referred to as  GDPs  (Generalized
  198.      Drawing Primitives).  This denotation is historical in nature, and
  199.      has  no effect unless you are writing your own VDI bindings.
  200.  
  201.           The  rounded rectangle is nice to use for customized  buttons
  202.      in  windows and dialogs.   It gives a "softer" look to the  screen
  203.      than the standard square objects.  The drawing command is:
  204.  
  205.                v_rbox(vdi_handle, pxy);
  206.  
  207.         Pxy  is  a  four word array  giving  opposite  corners  of  the
  208.      rectangle,  just as for the vs_clip() call.   The corner  rounding
  209.      occurs  within  the  confines of  this  rectangle.   Nothing  will
  210.      protrude  unless  you specify a line thickness greater  than  one.
  211.      The  corner rounding is approximately circular;  there is no  user
  212.      control over the degree or shape of rounding.
  213.  
  214.           Both the arc and elliptical arc commands use a curious method
  215.      of  specifying  angles.   The units are tenths of degrees,  so  an
  216.      entire  circle is 3600 units.   The count starts at ninety degrees
  217.      right of vertical, and proceeds counterclockwise.  This means that
  218.      "3 o'clock" is 0 units,  "noon" is 900 units,  "9 o'clock" is 1800
  219.      units, and 2700 units is at "half-past".  3600 units take you back
  220.      to "3 o'clock".
  221.  
  222.           The command for drawing a circular arc is:
  223.  
  224.                v_arc(vdi_handle, x, y, radius, begin, end);
  225.  
  226.         X  and y specify the raster coordinates of the  center  of  the
  227.      circle.   Radius specifies the distance from center to all  points
  228.      on the arc.   Begin and end are angles given in units as described
  229.      above,  both with values between 0 and 3600.   The drawing of  the
  230.      arc  ALWAYS  proceeds  counterclockwise,   in  the  direction   of
  231.      increasing arc number.   So values of 0 and 900 for begin and  end
  232.      would  draw  a  quarter circle from  "three  o'clock"  to  "noon".
  233.      Reversing  the values would draw the other three quarters  of  the
  234.      circle.
  235.  
  236.           A  v_arc()  command  which specifies a  "full  turn"  is  the
  237.      fastest  way to draw a complete circle on the screen.   Be warned,
  238.      however,  that  the circle drawing algorithm used in the VDI seems
  239.      to  have  some  serious  shortcomings at  small  radii!   You  can
  240.      experiment  with  the  CIRCLE primitive in  ST  Logo,  which  uses
  241.      v_arc(), to see what I mean.
  242.  
  243.           Notice  that if you want an arc to strike one or more  given
  244.      points on the screen,  then you are in for some trigonometry.   If
  245.      your  math  is  a  bit  rusty,  I highly  recommend  the  book  "A
  246.      Programmer's  Geometry",  by  Bowyer  and Woodwark,  published  by
  247.      Butterworths (London, Boston, Toronto).
  248.  
  249.           Finally, the elliptical arc is generated with:
  250.  
  251.                v_ellarc(vdi_handle, x, y, xrad, yrad, begin, end);
  252.  
  253.       X,  y,  begin, and end are just as before.  Xrad and yrad give the
  254.      horizontal and vertical radii of the defining ellipse.  This means
  255.      that  the distance of the arc from center will be yrad  pixels  at
  256.      "noon"  and  "half-past",  and it will be xrad pixels at "3 and  9
  257.      o'clock".  Again, the arc is always drawn counterclockwise.
  258.  
  259.           There  are  a  number  of approaches  to  keeping  the  VDI's
  260.      attributes "in sync" with the actual output operations.   Probably
  261.      the  LEAST efficient is to use the Inquire Functions to  determine
  262.      the  current  attributes.   For  this  reason,  I have  omitted  a
  263.      discussion of these calls from this column.
  264.  
  265.           Another  idea  is  to keep a local copy  of  all  significant
  266.      attributes, use a test-before-set method to minimize the number of
  267.      Attribute  Functions which need to be called.   This puts a burden
  268.      on  the programmer to be sure that the local  attribute  variables
  269.      are correctly maintained.   Failure to do so may result in obscure
  270.      drawing  bugs.   If  your  application employs  user  defined  AES
  271.      objects, you must be very careful because GEM might call your draw
  272.      code  in the middle of a VDI operation (particularly if  the  user
  273.      defined objects are in the menu).
  274.  
  275.           Always  setting  the attributes is a simplistic  method,  but
  276.      often   proves  most  effective.    The  routines  pl_perim()  and
  277.      rr_perim()  in the download exhibit this  approach.   Modification
  278.      for  other  primitives  is straightforward.   This style  is  most
  279.      useful  when  drawing  operations  are  scattered  throughout  the
  280.      program,  so that keeping track of the current attribute status is
  281.      difficult.  Although inherently inefficient, the difference is not
  282.      very  noticable if the drawing operation requested is itself  time
  283.      consuming.
  284.  
  285.           In  many  applications,  such  as data graphing  programs  or
  286.      "Draw"  packages,  the output operations are centralized,  forming
  287.      the primary functionality of the code.   In this case,  it is both
  288.      easy  and  efficient  to keep track of  attribute  status  between
  289.      successive drawing operations.
  290.  
  291.           SOLIDS.  There are a wider variety of VDI calls  for  drawing
  292.      solid figures.  They include rectangle or bar, disk, pie, ellipse,
  293.      elliptical  pie,  filled rounded rectangle,  and filled  polygonal
  294.      area.   Of course,  filled figure calls also have their own set of
  295.      attributes which you will need to set.
  296.  
  297.           The  fill color index determines what pen color will be  used
  298.      to draw the solid.  It is set with:
  299.  
  300.                vsf_color(vdi_handle, color);
  301.  
  302.           Color is just the same as for line drawing.   A solid may  or
  303.      may not have a visible border.  This is determined with the call:
  304.  
  305.                vsf_perimeter(vdi_handle, vis);
  306.  
  307.         Vis is a Boolean.   If it is true,  the figure will be given  a
  308.      solid one pixel outline in the current fill color index.   This is
  309.      often  useful  to improve the appearance of solids  drawn  with  a
  310.      dithered fill pattern.  If vis is false, then no outline is drawn.
  311.  
  312.           There are two parameters which together determine the pattern
  313.      used  to  fill your figure.   They are called interior  style  and
  314.      interior  index.   The style determines the general type of  fill,
  315.      and the index is used to select a particular pattern if necessary.
  316.      The style is set with the command:
  317.  
  318.                vsf_interior(vdi_handle, style);
  319.  
  320.        where style is a value from zero through four.   Zero selects  a
  321.      hollow  style:  the  fill is performed in  color  zero,  which  is
  322.      usually  white.   Style one selects a solid fill with the  current
  323.      fill  color.   A style of two is called "pattern" and a  three  is
  324.      called "hatch", which are terms somewhat suggestive of the options
  325.      which can then be selected using the interior index.   Style  four
  326.      selects the user defined pattern, which is described below.
  327.  
  328.           The  interior  index is only significant for styles  two  and
  329.      three. To set it, use:
  330.  
  331.                vsf_style(vdi_handle, index);
  332.  
  333.         (Be careful here: it is very easy to confuse this call with the
  334.      one  above  due  to the unfortunate choice of  name.)   The  index
  335.      selects the actual drawing pattern.  The GEM VDI manual shows fill
  336.      patterns corresponding to index values from 1 to 24 under style 2,
  337.      and  from  1 to 12 under style 3.   However,  some  of  these  are
  338.      implemented  differently on the ST.   Rather than try to  describe
  339.      them all here, I would suggest that you experiment.  You can do so
  340.      easily  in  ST Logo by opening the Graphics  Settings  dialog  and
  341.      playing with the style and index values there.
  342.  
  343.           The user defined style gives you some interesting options for
  344.      multi-color fills.  It is set with:
  345.  
  346.                vsf_udpat(vdi_handle, pattern, planes);
  347.  
  348.          Planes  determines the number of color planes in  the  pattern
  349.      which  you  supply.   It  is  set to one  if  you  are  setting  a
  350.      monochrome  pattern.   (Remember,  monochrome is  not  necessarily
  351.      black).   It may be set to higher values on color systems: two for
  352.      ST medium-res mode, or four for low-res mode.  If you use a number
  353.      lower than four under low-res, the other planes are zero filled.
  354.  
  355.           The  pattern  parameter  is  an array of  words  which  is  a
  356.      multiple  of  16 words long.  The pattern determined is 16  by  16
  357.      pixels,  with each word forming one row of the pattern.   The rows
  358.      are  arranged top to bottom,  with the most significant bit to the
  359.      left.   If  you  have selected a multi-plane pattern,  the  entire
  360.      first plane is stored, then the second, and so on.
  361.  
  362.             Note that to use a multi-plane pattern, you set the writing
  363.      mode  to replace using vswr_mode().   Since the each plane can  be
  364.      different,  you can produce multi-colored patterns.   If you use a
  365.      writing   color  other  than  black,   some  of  the  planes   may
  366.      "disappear".
  367.  
  368.           Most  of  the  solids Output Functions  have  analogous  line
  369.      drawing commands.   The polyline command corresponds to the filled
  370.      area primitive.  The filled area routine is:
  371.  
  372.                v_fillarea(vdi_handle, count, pxy);
  373.  
  374.          Count  and pxy are just the same as  for  v_pline().   If  the
  375.      polygon  defined  by pxy is not closed,  then the VDI  will  force
  376.      closure  with  a straight line from the last to the  first  point.
  377.      The  polygon may  be concave or self-intersecting.   If  perimeter
  378.      show is on, the area will be outlined.
  379.  
  380.           One  note of caution is necessary for both  v_fillarea()  and
  381.      v_pline().   There is a limit on the number of points which may be
  382.      stored in pxy[].   This limit occurs because the contents of pxy[]
  383.      are copied to the intin[] binding array before the VDI is  called.
  384.      You  can  determine  the maximum number of  vertices  by  checking
  385.      intout[14] after using the extended inquire function vq_extnd().
  386.  
  387.           For  reasons unknown to this writer,  there are TWO different
  388.      filled rectangle commands in the VDI.  The first is
  389.  
  390.                vr_recfl(vdi_handle, pxy);
  391.  
  392.          Pxy is a four word array defining two opposite corners of  the
  393.      rectangle,  just  as  in  vs_clip().   Vr_recfl()  uses  the  fill
  394.      attribute settings, except that it NEVER draws a perimeter.
  395.  
  396.           The other rectangle routine is v_bar(), with exactly the same
  397.      arguments  as  vr_recfl().    The  only  difference  is  that  the
  398.      perimeter  setting  IS  respected.   These two  routines  are  the
  399.      fastest way to produce a solid rectangle using the VDI.   They may
  400.      be  used in XOR mode with a BLACK fill color to quickly invert  an
  401.      area  of  the screen.   You can improve the speed even further  by
  402.      turning off the clip (if possible), and byte aligning the left and
  403.      right edges of the rectangle.
  404.  
  405.           Separate commands are provided for solid circle and  ellipse.
  406.      The circle call is:
  407.  
  408.                v_circle(vdi_handle, x, y, radius);
  409.  
  410.         and the ellipse command is:
  411.  
  412.                v_ellipse(vdi_handle, x, y, xrad, yrad);
  413.  
  414.          All of the parameters are identical to those given  above  for
  415.      v_arc()  and v_ellarc().   The solid analogue of an arc is a  "pie
  416.      slice".  The VDI pie commands are:
  417.  
  418.                v_pieslice(vdi_handle, x, y, radius, begin, end);
  419.  
  420.        for a slice from a circular pie, and
  421.  
  422.                v_ellpie(vdi_handle, x, y, xrad, yrad, begin, end);
  423.  
  424.         for a slice from a "squashed" pie.   Again,  the parameters are
  425.      identical  to  those in v_arc() and  v_ellarc().   The  units  and
  426.      drawing  order  of angles are also the  same.   The  final  solids
  427.      Output Function is:
  428.  
  429.                v_rfbox(vdi_handle, pxy);
  430.  
  431.      which draws a filled rounded rectangle.   The  pxy  array  defines
  432.      two opposite corners of the bounding box, as shown for vs_clip().
  433.  
  434.           The  issues involved in correctly setting the VDI  attributes
  435.      for a fill operation are identical to those in drawing lines.  For
  436.      those  who  want to employ the "always set" method,  I have  again
  437.      included  two  skeleton  routines in the download,  which  can  be
  438.      modified as desired.
  439.  
  440.  
  441.           TO  BE  CONTINUED.   This  concludes  the  first  part of our
  442.      expedition  through  basic VDI operations.   The next  issue  will
  443.      tackle  the  problems of drawing  bit mapped text at a  reasonable
  444.      speed.   This first  pass will  not attempt to tackle alternate or
  445.      proportional  fonts,  or  alternate font sizes.   Instead,  I will
  446.      concentrate on techniques for squeezing greater performance out of
  447.      the standard  monospaced system fonts.
  448.  
  449.  
  450.  
  451.  
  452. >>>>>>>>>>>>>>>> Routines to set clip to a GRECT <<<<<<<<<<<<<<<<
  453.  
  454.         VOID
  455. grect_to_array(area, array)     /* convert x,y,w,h to upr lt x,y and    */
  456.         GRECT   *area;          /*                    lwr rt x,y        */
  457.         WORD    *array;
  458.         {
  459.         *array++ = area->g_x;
  460.         *array++ = area->g_y;
  461.         *array++ = area->g_x + area->g_w - 1;
  462.         *array = area->g_y + area->g_h - 1;
  463.         }
  464.  
  465.         VOID
  466. set_clip(clip_flag, s_area)     /* set clip to specified area           */
  467.         WORD    clip_flag;
  468.         GRECT   *s_area;
  469.         {
  470.         WORD    pxy[4];
  471.  
  472.         grect_to_array(s_area, pxy);
  473.         vs_clip(vdi_handle, clip_flag, pxy);
  474.         }
  475.  
  476.  
  477. >>>>>>>>>> Routines to set attributes before output <<<<<<<<<<<<
  478.  
  479.         VOID
  480. rr_perim(mode, color, type, width, pxy)      /* Draw a rounded    */
  481.         WORD    mode, color, width, *pxy;    /* rectangle outline */
  482.         {
  483.         vswr_mode(vdi_handle, mode);
  484.         vsl_color(vdi_handle, color);
  485.         vsl_type(vdi_handle, type);
  486.         vsl_width(vdi_handle, width);
  487.         v_rbox(vdi_handle, pxy);
  488.         vswr_mode(vdi_handle, MD_REPLACE);
  489.         }
  490.  
  491.         VOID
  492. pl_perim(mode, type, color, width, npts, pxy)     /* Draw a polygonal */
  493.                                                   /* figure           */
  494.         WORD    mode, type, color, width, npts, *pxy;
  495.         {
  496.         vswr_mode(vdi_handle, mode);
  497.         vsl_type(vdi_handle, type);
  498.         vsl_color(vdi_handle, color);
  499.         vsl_width(vdi_handle, width);
  500.         v_pline(vdi_handle, npts, pxy);
  501.         }
  502.  
  503.         VOID                  /* Draw a filled polygonal area */
  504. pl_fill(mode, perim, color, interior, style, npts, pxy)
  505.         WORD    mode, perim, color, interior, style, npts, *pxy;
  506.         {
  507.         vswr_mode(vdi_handle, mode);
  508.         vsf_color(vdi_handle, color);
  509.         vsf_style(vdi_handle, style);
  510.         vsf_interior(vdi_handle, interior);
  511.         vsf_perimeter(vdi_handle, perim);
  512.         v_fillarea(vdi_handle, npts, pxy);
  513.         }
  514.  
  515.         VOID                  /* Draw a filled rectangle    */
  516. rect_fill(mode, perim, color, interior, style, pxy)
  517.         WORD    mode, perim, color, style, interior, *pxy;
  518.         {
  519.         vswr_mode(vdi_handle, mode);
  520.         vsf_color(vdi_handle, color);
  521.         vsf_style(vdi_handle, style);
  522.         vsf_interior(vdi_handle, interior);
  523.         vsf_perimeter(vdi_handle, perim);
  524.         vr_recfl(vdi_handle, pxy);
  525.         }
  526.