rts-plotutils.c

     
   1  //! @file rts-plotutils.c
   2  //! @author J. Marcel van der Veer
   3  //!
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
   8  //!
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Gnuplot's libplot interface. 
  25  
  26  // This file contains the Algol68G interface to libplot. Note that Algol68G is not
  27  // a binding for libplot. When GNU plotutils are not installed then the routines in
  28  // this file will give a runtime error when called. You can also choose to not
  29  // define them in "prelude.c". 
  30  
  31  #include "a68g.h"
  32  #include "a68g-genie.h"
  33  #include "a68g-numbers.h"
  34  #include "a68g-prelude.h"
  35  
  36  #if defined (HAVE_GNU_PLOTUTILS)
  37  
  38  // This part contains names for 24-bit colours recognised by libplot.
  39  // The table below is based on the "rgb.txt" file distributed with X11R6. 
  40  
  41  struct COLOUR_INFO
  42  {
  43    char *name;
  44    int red, green, blue;
  45  };
  46  
  47  typedef struct COLOUR_INFO colour_info;
  48  
  49  #define COLOUR_MAX 65535
  50  #define COLOUR_NAMES 668
  51  
  52  const colour_info A68_COLOURS[COLOUR_NAMES + 1] = {
  53    {"aliceblue", 0xf0, 0xf8, 0xff},
  54    {"aluminium", 0xaa, 0xac, 0xb7},
  55    {"aluminum", 0xaa, 0xac, 0xb7},
  56    {"antiquewhite", 0xfa, 0xeb, 0xd7},
  57    {"antiquewhite1", 0xff, 0xef, 0xdb},
  58    {"antiquewhite2", 0xee, 0xdf, 0xcc},
  59    {"antiquewhite3", 0xcd, 0xc0, 0xb0},
  60    {"antiquewhite4", 0x8b, 0x83, 0x78},
  61    {"aquamarine", 0x7f, 0xff, 0xd4},
  62    {"aquamarine1", 0x7f, 0xff, 0xd4},
  63    {"aquamarine2", 0x76, 0xee, 0xc6},
  64    {"aquamarine3", 0x66, 0xcd, 0xaa},
  65    {"aquamarine4", 0x45, 0x8b, 0x74},
  66    {"azure", 0xf0, 0xff, 0xff},
  67    {"azure1", 0xf0, 0xff, 0xff},
  68    {"azure2", 0xe0, 0xee, 0xee},
  69    {"azure3", 0xc1, 0xcd, 0xcd},
  70    {"azure4", 0x83, 0x8b, 0x8b},
  71    {"beige", 0xf5, 0xf5, 0xdc},
  72    {"bisque", 0xff, 0xe4, 0xc4},
  73    {"bisque1", 0xff, 0xe4, 0xc4},
  74    {"bisque2", 0xee, 0xd5, 0xb7},
  75    {"bisque3", 0xcd, 0xb7, 0x9e},
  76    {"bisque4", 0x8b, 0x7d, 0x6b},
  77    {"black", 0x00, 0x00, 0x00},
  78    {"blanchedalmond", 0xff, 0xeb, 0xcd},
  79    {"blue", 0x00, 0x00, 0xff},
  80    {"blue1", 0x00, 0x00, 0xff},
  81    {"blue2", 0x00, 0x00, 0xee},
  82    {"blue3", 0x00, 0x00, 0xcd},
  83    {"blue4", 0x00, 0x00, 0x8b},
  84    {"blueviolet", 0x8a, 0x2b, 0xe2},
  85    {"bondi1", 0x02, 0x48, 0x8f},
  86    {"brown", 0xa5, 0x2a, 0x2a},
  87    {"brown1", 0xff, 0x40, 0x40},
  88    {"brown2", 0xee, 0x3b, 0x3b},
  89    {"brown3", 0xcd, 0x33, 0x33},
  90    {"brown4", 0x8b, 0x23, 0x23},
  91    {"burlywood", 0xde, 0xb8, 0x87},
  92    {"burlywood1", 0xff, 0xd3, 0x9b},
  93    {"burlywood2", 0xee, 0xc5, 0x91},
  94    {"burlywood3", 0xcd, 0xaa, 0x7d},
  95    {"burlywood4", 0x8b, 0x73, 0x55},
  96    {"cadetblue", 0x5f, 0x9e, 0xa0},
  97    {"cadetblue1", 0x98, 0xf5, 0xff},
  98    {"cadetblue2", 0x8e, 0xe5, 0xee},
  99    {"cadetblue3", 0x7a, 0xc5, 0xcd},
 100    {"cadetblue4", 0x53, 0x86, 0x8b},
 101    {"chartreuse", 0x7f, 0xff, 0x00},
 102    {"chartreuse1", 0x7f, 0xff, 0x00},
 103    {"chartreuse2", 0x76, 0xee, 0x00},
 104    {"chartreuse3", 0x66, 0xcd, 0x00},
 105    {"chartreuse4", 0x45, 0x8b, 0x00},
 106    {"chocolate", 0xd2, 0x69, 0x1e},
 107    {"chocolate1", 0xff, 0x7f, 0x24},
 108    {"chocolate2", 0xee, 0x76, 0x21},
 109    {"chocolate3", 0xcd, 0x66, 0x1d},
 110    {"chocolate4", 0x8b, 0x45, 0x13},
 111    {"coral", 0xff, 0x7f, 0x50},
 112    {"coral1", 0xff, 0x72, 0x56},
 113    {"coral2", 0xee, 0x6a, 0x50},
 114    {"coral3", 0xcd, 0x5b, 0x45},
 115    {"coral4", 0x8b, 0x3e, 0x2f},
 116    {"cornflowerblue", 0x64, 0x95, 0xed},
 117    {"cornsilk", 0xff, 0xf8, 0xdc},
 118    {"cornsilk1", 0xff, 0xf8, 0xdc},
 119    {"cornsilk2", 0xee, 0xe8, 0xcd},
 120    {"cornsilk3", 0xcd, 0xc8, 0xb1},
 121    {"cornsilk4", 0x8b, 0x88, 0x78},
 122    {"cyan", 0x00, 0xff, 0xff},
 123    {"cyan1", 0x00, 0xff, 0xff},
 124    {"cyan2", 0x00, 0xee, 0xee},
 125    {"cyan3", 0x00, 0xcd, 0xcd},
 126    {"cyan4", 0x00, 0x8b, 0x8b},
 127    {"darkblue", 0x00, 0x00, 0x8b},
 128    {"darkcyan", 0x00, 0x8b, 0x8b},
 129    {"darkgoldenrod", 0xb8, 0x86, 0x0b},
 130    {"darkgoldenrod1", 0xff, 0xb9, 0x0f},
 131    {"darkgoldenrod2", 0xee, 0xad, 0x0e},
 132    {"darkgoldenrod3", 0xcd, 0x95, 0x0c},
 133    {"darkgoldenrod4", 0x8b, 0x65, 0x08},
 134    {"darkgray", 0xa9, 0xa9, 0xa9},
 135    {"darkgreen", 0x00, 0x64, 0x00},
 136    {"darkgrey", 0xa9, 0xa9, 0xa9},
 137    {"darkkhaki", 0xbd, 0xb7, 0x6b},
 138    {"darkmagenta", 0x8b, 0x00, 0x8b},
 139    {"darkolivegreen", 0x55, 0x6b, 0x2f},
 140    {"darkolivegreen1", 0xca, 0xff, 0x70},
 141    {"darkolivegreen2", 0xbc, 0xee, 0x68},
 142    {"darkolivegreen3", 0xa2, 0xcd, 0x5a},
 143    {"darkolivegreen4", 0x6e, 0x8b, 0x3d},
 144    {"darkorange", 0xff, 0x8c, 0x00},
 145    {"darkorange1", 0xff, 0x7f, 0x00},
 146    {"darkorange2", 0xee, 0x76, 0x00},
 147    {"darkorange3", 0xcd, 0x66, 0x00},
 148    {"darkorange4", 0x8b, 0x45, 0x00},
 149    {"darkorchid", 0x99, 0x32, 0xcc},
 150    {"darkorchid1", 0xbf, 0x3e, 0xff},
 151    {"darkorchid2", 0xb2, 0x3a, 0xee},
 152    {"darkorchid3", 0x9a, 0x32, 0xcd},
 153    {"darkorchid4", 0x68, 0x22, 0x8b},
 154    {"darkred", 0x8b, 0x00, 0x00},
 155    {"darksalmon", 0xe9, 0x96, 0x7a},
 156    {"darkseagreen", 0x8f, 0xbc, 0x8f},
 157    {"darkseagreen1", 0xc1, 0xff, 0xc1},
 158    {"darkseagreen2", 0xb4, 0xee, 0xb4},
 159    {"darkseagreen3", 0x9b, 0xcd, 0x9b},
 160    {"darkseagreen4", 0x69, 0x8b, 0x69},
 161    {"darkslateblue", 0x48, 0x3d, 0x8b},
 162    {"darkslategray", 0x2f, 0x4f, 0x4f},
 163    {"darkslategray1", 0x97, 0xff, 0xff},
 164    {"darkslategray2", 0x8d, 0xee, 0xee},
 165    {"darkslategray3", 0x79, 0xcd, 0xcd},
 166    {"darkslategray4", 0x52, 0x8b, 0x8b},
 167    {"darkslategrey", 0x2f, 0x4f, 0x4f},
 168    {"darkslategrey1", 0x97, 0xff, 0xff},
 169    {"darkslategrey2", 0x8d, 0xee, 0xee},
 170    {"darkslategrey3", 0x79, 0xcd, 0xcd},
 171    {"darkslategrey4", 0x52, 0x8b, 0x8b},
 172    {"darkturquoise", 0x00, 0xce, 0xd1},
 173    {"darkviolet", 0x94, 0x00, 0xd3},
 174    {"deeppink", 0xff, 0x14, 0x93},
 175    {"deeppink1", 0xff, 0x14, 0x93},
 176    {"deeppink2", 0xee, 0x12, 0x89},
 177    {"deeppink3", 0xcd, 0x10, 0x76},
 178    {"deeppink4", 0x8b, 0x0a, 0x50},
 179    {"deepskyblue", 0x00, 0xbf, 0xff},
 180    {"deepskyblue1", 0x00, 0xbf, 0xff},
 181    {"deepskyblue2", 0x00, 0xb2, 0xee},
 182    {"deepskyblue3", 0x00, 0x9a, 0xcd},
 183    {"deepskyblue4", 0x00, 0x68, 0x8b},
 184    {"dimgray", 0x69, 0x69, 0x69},
 185    {"dimgrey", 0x69, 0x69, 0x69},
 186    {"dodgerblue", 0x1e, 0x90, 0xff},
 187    {"dodgerblue1", 0x1e, 0x90, 0xff},
 188    {"dodgerblue2", 0x1c, 0x86, 0xee},
 189    {"dodgerblue3", 0x18, 0x74, 0xcd},
 190    {"dodgerblue4", 0x10, 0x4e, 0x8b},
 191    {"firebrick", 0xb2, 0x22, 0x22},
 192    {"firebrick1", 0xff, 0x30, 0x30},
 193    {"firebrick2", 0xee, 0x2c, 0x2c},
 194    {"firebrick3", 0xcd, 0x26, 0x26},
 195    {"firebrick4", 0x8b, 0x1a, 0x1a},
 196    {"floralwhite", 0xff, 0xfa, 0xf0},
 197    {"forestgreen", 0x22, 0x8b, 0x22},
 198    {"gainsboro", 0xdc, 0xdc, 0xdc},
 199    {"ghostwhite", 0xf8, 0xf8, 0xff},
 200    {"gold", 0xff, 0xd7, 0x00},
 201    {"gold1", 0xff, 0xd7, 0x00},
 202    {"gold2", 0xee, 0xc9, 0x00},
 203    {"gold3", 0xcd, 0xad, 0x00},
 204    {"gold4", 0x8b, 0x75, 0x00},
 205    {"goldenrod", 0xda, 0xa5, 0x20},
 206    {"goldenrod1", 0xff, 0xc1, 0x25},
 207    {"goldenrod2", 0xee, 0xb4, 0x22},
 208    {"goldenrod3", 0xcd, 0x9b, 0x1d},
 209    {"goldenrod4", 0x8b, 0x69, 0x14},
 210    {"gray", 0xbe, 0xbe, 0xbe},
 211    {"gray0", 0x00, 0x00, 0x00},
 212    {"gray1", 0x03, 0x03, 0x03},
 213    {"gray2", 0x05, 0x05, 0x05},
 214    {"gray3", 0x08, 0x08, 0x08},
 215    {"gray4", 0x0a, 0x0a, 0x0a},
 216    {"gray5", 0x0d, 0x0d, 0x0d},
 217    {"gray6", 0x0f, 0x0f, 0x0f},
 218    {"gray7", 0x12, 0x12, 0x12},
 219    {"gray8", 0x14, 0x14, 0x14},
 220    {"gray9", 0x17, 0x17, 0x17},
 221    {"gray10", 0x1a, 0x1a, 0x1a},
 222    {"gray11", 0x1c, 0x1c, 0x1c},
 223    {"gray12", 0x1f, 0x1f, 0x1f},
 224    {"gray13", 0x21, 0x21, 0x21},
 225    {"gray14", 0x24, 0x24, 0x24},
 226    {"gray15", 0x26, 0x26, 0x26},
 227    {"gray16", 0x29, 0x29, 0x29},
 228    {"gray17", 0x2b, 0x2b, 0x2b},
 229    {"gray18", 0x2e, 0x2e, 0x2e},
 230    {"gray19", 0x30, 0x30, 0x30},
 231    {"gray20", 0x33, 0x33, 0x33},
 232    {"gray21", 0x36, 0x36, 0x36},
 233    {"gray22", 0x38, 0x38, 0x38},
 234    {"gray23", 0x3b, 0x3b, 0x3b},
 235    {"gray24", 0x3d, 0x3d, 0x3d},
 236    {"gray25", 0x40, 0x40, 0x40},
 237    {"gray26", 0x42, 0x42, 0x42},
 238    {"gray27", 0x45, 0x45, 0x45},
 239    {"gray28", 0x47, 0x47, 0x47},
 240    {"gray29", 0x4a, 0x4a, 0x4a},
 241    {"gray30", 0x4d, 0x4d, 0x4d},
 242    {"gray31", 0x4f, 0x4f, 0x4f},
 243    {"gray32", 0x52, 0x52, 0x52},
 244    {"gray33", 0x54, 0x54, 0x54},
 245    {"gray34", 0x57, 0x57, 0x57},
 246    {"gray35", 0x59, 0x59, 0x59},
 247    {"gray36", 0x5c, 0x5c, 0x5c},
 248    {"gray37", 0x5e, 0x5e, 0x5e},
 249    {"gray38", 0x61, 0x61, 0x61},
 250    {"gray39", 0x63, 0x63, 0x63},
 251    {"gray40", 0x66, 0x66, 0x66},
 252    {"gray41", 0x69, 0x69, 0x69},
 253    {"gray42", 0x6b, 0x6b, 0x6b},
 254    {"gray43", 0x6e, 0x6e, 0x6e},
 255    {"gray44", 0x70, 0x70, 0x70},
 256    {"gray45", 0x73, 0x73, 0x73},
 257    {"gray46", 0x75, 0x75, 0x75},
 258    {"gray47", 0x78, 0x78, 0x78},
 259    {"gray48", 0x7a, 0x7a, 0x7a},
 260    {"gray49", 0x7d, 0x7d, 0x7d},
 261    {"gray50", 0x7f, 0x7f, 0x7f},
 262    {"gray51", 0x82, 0x82, 0x82},
 263    {"gray52", 0x85, 0x85, 0x85},
 264    {"gray53", 0x87, 0x87, 0x87},
 265    {"gray54", 0x8a, 0x8a, 0x8a},
 266    {"gray55", 0x8c, 0x8c, 0x8c},
 267    {"gray56", 0x8f, 0x8f, 0x8f},
 268    {"gray57", 0x91, 0x91, 0x91},
 269    {"gray58", 0x94, 0x94, 0x94},
 270    {"gray59", 0x96, 0x96, 0x96},
 271    {"gray60", 0x99, 0x99, 0x99},
 272    {"gray61", 0x9c, 0x9c, 0x9c},
 273    {"gray62", 0x9e, 0x9e, 0x9e},
 274    {"gray63", 0xa1, 0xa1, 0xa1},
 275    {"gray64", 0xa3, 0xa3, 0xa3},
 276    {"gray65", 0xa6, 0xa6, 0xa6},
 277    {"gray66", 0xa8, 0xa8, 0xa8},
 278    {"gray67", 0xab, 0xab, 0xab},
 279    {"gray68", 0xad, 0xad, 0xad},
 280    {"gray69", 0xb0, 0xb0, 0xb0},
 281    {"gray70", 0xb3, 0xb3, 0xb3},
 282    {"gray71", 0xb5, 0xb5, 0xb5},
 283    {"gray72", 0xb8, 0xb8, 0xb8},
 284    {"gray73", 0xba, 0xba, 0xba},
 285    {"gray74", 0xbd, 0xbd, 0xbd},
 286    {"gray75", 0xbf, 0xbf, 0xbf},
 287    {"gray76", 0xc2, 0xc2, 0xc2},
 288    {"gray77", 0xc4, 0xc4, 0xc4},
 289    {"gray78", 0xc7, 0xc7, 0xc7},
 290    {"gray79", 0xc9, 0xc9, 0xc9},
 291    {"gray80", 0xcc, 0xcc, 0xcc},
 292    {"gray81", 0xcf, 0xcf, 0xcf},
 293    {"gray82", 0xd1, 0xd1, 0xd1},
 294    {"gray83", 0xd4, 0xd4, 0xd4},
 295    {"gray84", 0xd6, 0xd6, 0xd6},
 296    {"gray85", 0xd9, 0xd9, 0xd9},
 297    {"gray86", 0xdb, 0xdb, 0xdb},
 298    {"gray87", 0xde, 0xde, 0xde},
 299    {"gray88", 0xe0, 0xe0, 0xe0},
 300    {"gray89", 0xe3, 0xe3, 0xe3},
 301    {"gray90", 0xe5, 0xe5, 0xe5},
 302    {"gray91", 0xe8, 0xe8, 0xe8},
 303    {"gray92", 0xeb, 0xeb, 0xeb},
 304    {"gray93", 0xed, 0xed, 0xed},
 305    {"gray94", 0xf0, 0xf0, 0xf0},
 306    {"gray95", 0xf2, 0xf2, 0xf2},
 307    {"gray96", 0xf5, 0xf5, 0xf5},
 308    {"gray97", 0xf7, 0xf7, 0xf7},
 309    {"gray98", 0xfa, 0xfa, 0xfa},
 310    {"gray99", 0xfc, 0xfc, 0xfc},
 311    {"gray100", 0xff, 0xff, 0xff},
 312    {"green", 0x00, 0xff, 0x00},
 313    {"green1", 0x00, 0xff, 0x00},
 314    {"green2", 0x00, 0xee, 0x00},
 315    {"green3", 0x00, 0xcd, 0x00},
 316    {"green4", 0x00, 0x8b, 0x00},
 317    {"greenyellow", 0xad, 0xff, 0x2f},
 318    {"grey", 0xbe, 0xbe, 0xbe},
 319    {"grey0", 0x00, 0x00, 0x00},
 320    {"grey1", 0x03, 0x03, 0x03},
 321    {"grey2", 0x05, 0x05, 0x05},
 322    {"grey3", 0x08, 0x08, 0x08},
 323    {"grey4", 0x0a, 0x0a, 0x0a},
 324    {"grey5", 0x0d, 0x0d, 0x0d},
 325    {"grey6", 0x0f, 0x0f, 0x0f},
 326    {"grey7", 0x12, 0x12, 0x12},
 327    {"grey8", 0x14, 0x14, 0x14},
 328    {"grey9", 0x17, 0x17, 0x17},
 329    {"grey10", 0x1a, 0x1a, 0x1a},
 330    {"grey11", 0x1c, 0x1c, 0x1c},
 331    {"grey12", 0x1f, 0x1f, 0x1f},
 332    {"grey13", 0x21, 0x21, 0x21},
 333    {"grey14", 0x24, 0x24, 0x24},
 334    {"grey15", 0x26, 0x26, 0x26},
 335    {"grey16", 0x29, 0x29, 0x29},
 336    {"grey17", 0x2b, 0x2b, 0x2b},
 337    {"grey18", 0x2e, 0x2e, 0x2e},
 338    {"grey19", 0x30, 0x30, 0x30},
 339    {"grey20", 0x33, 0x33, 0x33},
 340    {"grey21", 0x36, 0x36, 0x36},
 341    {"grey22", 0x38, 0x38, 0x38},
 342    {"grey23", 0x3b, 0x3b, 0x3b},
 343    {"grey24", 0x3d, 0x3d, 0x3d},
 344    {"grey25", 0x40, 0x40, 0x40},
 345    {"grey26", 0x42, 0x42, 0x42},
 346    {"grey27", 0x45, 0x45, 0x45},
 347    {"grey28", 0x47, 0x47, 0x47},
 348    {"grey29", 0x4a, 0x4a, 0x4a},
 349    {"grey30", 0x4d, 0x4d, 0x4d},
 350    {"grey31", 0x4f, 0x4f, 0x4f},
 351    {"grey32", 0x52, 0x52, 0x52},
 352    {"grey33", 0x54, 0x54, 0x54},
 353    {"grey34", 0x57, 0x57, 0x57},
 354    {"grey35", 0x59, 0x59, 0x59},
 355    {"grey36", 0x5c, 0x5c, 0x5c},
 356    {"grey37", 0x5e, 0x5e, 0x5e},
 357    {"grey38", 0x61, 0x61, 0x61},
 358    {"grey39", 0x63, 0x63, 0x63},
 359    {"grey40", 0x66, 0x66, 0x66},
 360    {"grey41", 0x69, 0x69, 0x69},
 361    {"grey42", 0x6b, 0x6b, 0x6b},
 362    {"grey43", 0x6e, 0x6e, 0x6e},
 363    {"grey44", 0x70, 0x70, 0x70},
 364    {"grey45", 0x73, 0x73, 0x73},
 365    {"grey46", 0x75, 0x75, 0x75},
 366    {"grey47", 0x78, 0x78, 0x78},
 367    {"grey48", 0x7a, 0x7a, 0x7a},
 368    {"grey49", 0x7d, 0x7d, 0x7d},
 369    {"grey50", 0x7f, 0x7f, 0x7f},
 370    {"grey51", 0x82, 0x82, 0x82},
 371    {"grey52", 0x85, 0x85, 0x85},
 372    {"grey53", 0x87, 0x87, 0x87},
 373    {"grey54", 0x8a, 0x8a, 0x8a},
 374    {"grey55", 0x8c, 0x8c, 0x8c},
 375    {"grey56", 0x8f, 0x8f, 0x8f},
 376    {"grey57", 0x91, 0x91, 0x91},
 377    {"grey58", 0x94, 0x94, 0x94},
 378    {"grey59", 0x96, 0x96, 0x96},
 379    {"grey60", 0x99, 0x99, 0x99},
 380    {"grey61", 0x9c, 0x9c, 0x9c},
 381    {"grey62", 0x9e, 0x9e, 0x9e},
 382    {"grey63", 0xa1, 0xa1, 0xa1},
 383    {"grey64", 0xa3, 0xa3, 0xa3},
 384    {"grey65", 0xa6, 0xa6, 0xa6},
 385    {"grey66", 0xa8, 0xa8, 0xa8},
 386    {"grey67", 0xab, 0xab, 0xab},
 387    {"grey68", 0xad, 0xad, 0xad},
 388    {"grey69", 0xb0, 0xb0, 0xb0},
 389    {"grey70", 0xb3, 0xb3, 0xb3},
 390    {"grey71", 0xb5, 0xb5, 0xb5},
 391    {"grey72", 0xb8, 0xb8, 0xb8},
 392    {"grey73", 0xba, 0xba, 0xba},
 393    {"grey74", 0xbd, 0xbd, 0xbd},
 394    {"grey75", 0xbf, 0xbf, 0xbf},
 395    {"grey76", 0xc2, 0xc2, 0xc2},
 396    {"grey77", 0xc4, 0xc4, 0xc4},
 397    {"grey78", 0xc7, 0xc7, 0xc7},
 398    {"grey79", 0xc9, 0xc9, 0xc9},
 399    {"grey80", 0xcc, 0xcc, 0xcc},
 400    {"grey81", 0xcf, 0xcf, 0xcf},
 401    {"grey82", 0xd1, 0xd1, 0xd1},
 402    {"grey83", 0xd4, 0xd4, 0xd4},
 403    {"grey84", 0xd6, 0xd6, 0xd6},
 404    {"grey85", 0xd9, 0xd9, 0xd9},
 405    {"grey86", 0xdb, 0xdb, 0xdb},
 406    {"grey87", 0xde, 0xde, 0xde},
 407    {"grey88", 0xe0, 0xe0, 0xe0},
 408    {"grey89", 0xe3, 0xe3, 0xe3},
 409    {"grey90", 0xe5, 0xe5, 0xe5},
 410    {"grey91", 0xe8, 0xe8, 0xe8},
 411    {"grey92", 0xeb, 0xeb, 0xeb},
 412    {"grey93", 0xed, 0xed, 0xed},
 413    {"grey94", 0xf0, 0xf0, 0xf0},
 414    {"grey95", 0xf2, 0xf2, 0xf2},
 415    {"grey96", 0xf5, 0xf5, 0xf5},
 416    {"grey97", 0xf7, 0xf7, 0xf7},
 417    {"grey98", 0xfa, 0xfa, 0xfa},
 418    {"grey99", 0xfc, 0xfc, 0xfc},
 419    {"grey100", 0xff, 0xff, 0xff},
 420    {"honeydew", 0xf0, 0xff, 0xf0},
 421    {"honeydew1", 0xf0, 0xff, 0xf0},
 422    {"honeydew2", 0xe0, 0xee, 0xe0},
 423    {"honeydew3", 0xc1, 0xcd, 0xc1},
 424    {"honeydew4", 0x83, 0x8b, 0x83},
 425    {"hotpink", 0xff, 0x69, 0xb4},
 426    {"hotpink1", 0xff, 0x6e, 0xb4},
 427    {"hotpink2", 0xee, 0x6a, 0xa7},
 428    {"hotpink3", 0xcd, 0x60, 0x90},
 429    {"hotpink4", 0x8b, 0x3a, 0x62},
 430    {"indianred", 0xcd, 0x5c, 0x5c},
 431    {"indianred1", 0xff, 0x6a, 0x6a},
 432    {"indianred2", 0xee, 0x63, 0x63},
 433    {"indianred3", 0xcd, 0x55, 0x55},
 434    {"indianred4", 0x8b, 0x3a, 0x3a},
 435    {"ivory", 0xff, 0xff, 0xf0},
 436    {"ivory1", 0xff, 0xff, 0xf0},
 437    {"ivory2", 0xee, 0xee, 0xe0},
 438    {"ivory3", 0xcd, 0xcd, 0xc1},
 439    {"ivory4", 0x8b, 0x8b, 0x83},
 440    {"khaki", 0xf0, 0xe6, 0x8c},
 441    {"khaki1", 0xff, 0xf6, 0x8f},
 442    {"khaki2", 0xee, 0xe6, 0x85},
 443    {"khaki3", 0xcd, 0xc6, 0x73},
 444    {"khaki4", 0x8b, 0x86, 0x4e},
 445    {"lavender", 0xe6, 0xe6, 0xfa},
 446    {"lavenderblush", 0xff, 0xf0, 0xf5},
 447    {"lavenderblush1", 0xff, 0xf0, 0xf5},
 448    {"lavenderblush2", 0xee, 0xe0, 0xe5},
 449    {"lavenderblush3", 0xcd, 0xc1, 0xc5},
 450    {"lavenderblush4", 0x8b, 0x83, 0x86},
 451    {"lawngreen", 0x7c, 0xfc, 0x00},
 452    {"lemonchiffon", 0xff, 0xfa, 0xcd},
 453    {"lemonchiffon1", 0xff, 0xfa, 0xcd},
 454    {"lemonchiffon2", 0xee, 0xe9, 0xbf},
 455    {"lemonchiffon3", 0xcd, 0xc9, 0xa5},
 456    {"lemonchiffon4", 0x8b, 0x89, 0x70},
 457    {"lightblue", 0xad, 0xd8, 0xe6},
 458    {"lightblue1", 0xbf, 0xef, 0xff},
 459    {"lightblue2", 0xb2, 0xdf, 0xee},
 460    {"lightblue3", 0x9a, 0xc0, 0xcd},
 461    {"lightblue4", 0x68, 0x83, 0x8b},
 462    {"lightcoral", 0xf0, 0x80, 0x80},
 463    {"lightcyan", 0xe0, 0xff, 0xff},
 464    {"lightcyan1", 0xe0, 0xff, 0xff},
 465    {"lightcyan2", 0xd1, 0xee, 0xee},
 466    {"lightcyan3", 0xb4, 0xcd, 0xcd},
 467    {"lightcyan4", 0x7a, 0x8b, 0x8b},
 468    {"lightgoldenrod", 0xee, 0xdd, 0x82},
 469    {"lightgoldenrod1", 0xff, 0xec, 0x8b},
 470    {"lightgoldenrod2", 0xee, 0xdc, 0x82},
 471    {"lightgoldenrod3", 0xcd, 0xbe, 0x70},
 472    {"lightgoldenrod4", 0x8b, 0x81, 0x4c},
 473    {"lightgoldenrodyellow", 0xfa, 0xfa, 0xd2},
 474    {"lightgray", 0xd3, 0xd3, 0xd3},
 475    {"lightgreen", 0x90, 0xee, 0x90},
 476    {"lightgrey", 0xd3, 0xd3, 0xd3},
 477    {"lightpink", 0xff, 0xb6, 0xc1},
 478    {"lightpink1", 0xff, 0xae, 0xb9},
 479    {"lightpink2", 0xee, 0xa2, 0xad},
 480    {"lightpink3", 0xcd, 0x8c, 0x95},
 481    {"lightpink4", 0x8b, 0x5f, 0x65},
 482    {"lightsalmon", 0xff, 0xa0, 0x7a},
 483    {"lightsalmon1", 0xff, 0xa0, 0x7a},
 484    {"lightsalmon2", 0xee, 0x95, 0x72},
 485    {"lightsalmon3", 0xcd, 0x81, 0x62},
 486    {"lightsalmon4", 0x8b, 0x57, 0x42},
 487    {"lightseagreen", 0x20, 0xb2, 0xaa},
 488    {"lightskyblue", 0x87, 0xce, 0xfa},
 489    {"lightskyblue1", 0xb0, 0xe2, 0xff},
 490    {"lightskyblue2", 0xa4, 0xd3, 0xee},
 491    {"lightskyblue3", 0x8d, 0xb6, 0xcd},
 492    {"lightskyblue4", 0x60, 0x7b, 0x8b},
 493    {"lightslateblue", 0x84, 0x70, 0xff},
 494    {"lightslategray", 0x77, 0x88, 0x99},
 495    {"lightslategrey", 0x77, 0x88, 0x99},
 496    {"lightsteelblue", 0xb0, 0xc4, 0xde},
 497    {"lightsteelblue1", 0xca, 0xe1, 0xff},
 498    {"lightsteelblue2", 0xbc, 0xd2, 0xee},
 499    {"lightsteelblue3", 0xa2, 0xb5, 0xcd},
 500    {"lightsteelblue4", 0x6e, 0x7b, 0x8b},
 501    {"lightyellow", 0xff, 0xff, 0xe0},
 502    {"lightyellow1", 0xff, 0xff, 0xe0},
 503    {"lightyellow2", 0xee, 0xee, 0xd1},
 504    {"lightyellow3", 0xcd, 0xcd, 0xb4},
 505    {"lightyellow4", 0x8b, 0x8b, 0x7a},
 506    {"limegreen", 0x32, 0xcd, 0x32},
 507    {"linen", 0xfa, 0xf0, 0xe6},
 508    {"magenta", 0xff, 0x00, 0xff},
 509    {"magenta1", 0xff, 0x00, 0xff},
 510    {"magenta2", 0xee, 0x00, 0xee},
 511    {"magenta3", 0xcd, 0x00, 0xcd},
 512    {"magenta4", 0x8b, 0x00, 0x8b},
 513    {"maroon", 0xb0, 0x30, 0x60},
 514    {"maroon1", 0xff, 0x34, 0xb3},
 515    {"maroon2", 0xee, 0x30, 0xa7},
 516    {"maroon3", 0xcd, 0x29, 0x90},
 517    {"maroon4", 0x8b, 0x1c, 0x62},
 518    {"mediumaquamarine", 0x66, 0xcd, 0xaa},
 519    {"mediumblue", 0x00, 0x00, 0xcd},
 520    {"mediumorchid", 0xba, 0x55, 0xd3},
 521    {"mediumorchid1", 0xe0, 0x66, 0xff},
 522    {"mediumorchid2", 0xd1, 0x5f, 0xee},
 523    {"mediumorchid3", 0xb4, 0x52, 0xcd},
 524    {"mediumorchid4", 0x7a, 0x37, 0x8b},
 525    {"mediumpurple", 0x93, 0x70, 0xdb},
 526    {"mediumpurple1", 0xab, 0x82, 0xff},
 527    {"mediumpurple2", 0x9f, 0x79, 0xee},
 528    {"mediumpurple3", 0x89, 0x68, 0xcd},
 529    {"mediumpurple4", 0x5d, 0x47, 0x8b},
 530    {"mediumseagreen", 0x3c, 0xb3, 0x71},
 531    {"mediumslateblue", 0x7b, 0x68, 0xee},
 532    {"mediumspringgreen", 0x00, 0xfa, 0x9a},
 533    {"mediumturquoise", 0x48, 0xd1, 0xcc},
 534    {"mediumvioletred", 0xc7, 0x15, 0x85},
 535    {"midnightblue", 0x19, 0x19, 0x70},
 536    {"mintcream", 0xf5, 0xff, 0xfa},
 537    {"mistyrose", 0xff, 0xe4, 0xe1},
 538    {"mistyrose1", 0xff, 0xe4, 0xe1},
 539    {"mistyrose2", 0xee, 0xd5, 0xd2},
 540    {"mistyrose3", 0xcd, 0xb7, 0xb5},
 541    {"mistyrose4", 0x8b, 0x7d, 0x7b},
 542    {"moccasin", 0xff, 0xe4, 0xb5},
 543    {"navajowhite", 0xff, 0xde, 0xad},
 544    {"navajowhite1", 0xff, 0xde, 0xad},
 545    {"navajowhite2", 0xee, 0xcf, 0xa1},
 546    {"navajowhite3", 0xcd, 0xb3, 0x8b},
 547    {"navajowhite4", 0x8b, 0x79, 0x5e},
 548    {"navy", 0x00, 0x00, 0x80},
 549    {"navyblue", 0x00, 0x00, 0x80},
 550    {"oldlace", 0xfd, 0xf5, 0xe6},
 551    {"olivedrab", 0x6b, 0x8e, 0x23},
 552    {"olivedrab1", 0xc0, 0xff, 0x3e},
 553    {"olivedrab2", 0xb3, 0xee, 0x3a},
 554    {"olivedrab3", 0x9a, 0xcd, 0x32},
 555    {"olivedrab4", 0x69, 0x8b, 0x22},
 556    {"orange", 0xff, 0xa5, 0x00},
 557    {"orange1", 0xff, 0xa5, 0x00},
 558    {"orange2", 0xee, 0x9a, 0x00},
 559    {"orange3", 0xcd, 0x85, 0x00},
 560    {"orange4", 0x8b, 0x5a, 0x00},
 561    {"orangered", 0xff, 0x45, 0x00},
 562    {"orangered1", 0xff, 0x45, 0x00},
 563    {"orangered2", 0xee, 0x40, 0x00},
 564    {"orangered3", 0xcd, 0x37, 0x00},
 565    {"orangered4", 0x8b, 0x25, 0x00},
 566    {"orchid", 0xda, 0x70, 0xd6},
 567    {"orchid1", 0xff, 0x83, 0xfa},
 568    {"orchid2", 0xee, 0x7a, 0xe9},
 569    {"orchid3", 0xcd, 0x69, 0xc9},
 570    {"orchid4", 0x8b, 0x47, 0x89},
 571    {"palegoldenrod", 0xee, 0xe8, 0xaa},
 572    {"palegreen", 0x98, 0xfb, 0x98},
 573    {"palegreen1", 0x9a, 0xff, 0x9a},
 574    {"palegreen2", 0x90, 0xee, 0x90},
 575    {"palegreen3", 0x7c, 0xcd, 0x7c},
 576    {"palegreen4", 0x54, 0x8b, 0x54},
 577    {"paleturquoise", 0xaf, 0xee, 0xee},
 578    {"paleturquoise1", 0xbb, 0xff, 0xff},
 579    {"paleturquoise2", 0xae, 0xee, 0xee},
 580    {"paleturquoise3", 0x96, 0xcd, 0xcd},
 581    {"paleturquoise4", 0x66, 0x8b, 0x8b},
 582    {"palevioletred", 0xdb, 0x70, 0x93},
 583    {"palevioletred1", 0xff, 0x82, 0xab},
 584    {"palevioletred2", 0xee, 0x79, 0x9f},
 585    {"palevioletred3", 0xcd, 0x68, 0x89},
 586    {"palevioletred4", 0x8b, 0x47, 0x5d},
 587    {"papayawhip", 0xff, 0xef, 0xd5},
 588    {"peachpuff", 0xff, 0xda, 0xb9},
 589    {"peachpuff1", 0xff, 0xda, 0xb9},
 590    {"peachpuff2", 0xee, 0xcb, 0xad},
 591    {"peachpuff3", 0xcd, 0xaf, 0x95},
 592    {"peachpuff4", 0x8b, 0x77, 0x65},
 593    {"peru", 0xcd, 0x85, 0x3f},
 594    {"pink", 0xff, 0xc0, 0xcb},
 595    {"pink1", 0xff, 0xb5, 0xc5},
 596    {"pink2", 0xee, 0xa9, 0xb8},
 597    {"pink3", 0xcd, 0x91, 0x9e},
 598    {"pink4", 0x8b, 0x63, 0x6c},
 599    {"plum", 0xdd, 0xa0, 0xdd},
 600    {"plum1", 0xff, 0xbb, 0xff},
 601    {"plum2", 0xee, 0xae, 0xee},
 602    {"plum3", 0xcd, 0x96, 0xcd},
 603    {"plum4", 0x8b, 0x66, 0x8b},
 604    {"powderblue", 0xb0, 0xe0, 0xe6},
 605    {"purple", 0xa0, 0x20, 0xf0},
 606    {"purple1", 0x9b, 0x30, 0xff},
 607    {"purple2", 0x91, 0x2c, 0xee},
 608    {"purple3", 0x7d, 0x26, 0xcd},
 609    {"purple4", 0x55, 0x1a, 0x8b},
 610    {"red", 0xff, 0x00, 0x00},
 611    {"red1", 0xff, 0x00, 0x00},
 612    {"red2", 0xee, 0x00, 0x00},
 613    {"red3", 0xcd, 0x00, 0x00},
 614    {"red4", 0x8b, 0x00, 0x00},
 615    {"rosybrown", 0xbc, 0x8f, 0x8f},
 616    {"rosybrown1", 0xff, 0xc1, 0xc1},
 617    {"rosybrown2", 0xee, 0xb4, 0xb4},
 618    {"rosybrown3", 0xcd, 0x9b, 0x9b},
 619    {"rosybrown4", 0x8b, 0x69, 0x69},
 620    {"royalblue", 0x41, 0x69, 0xe1},
 621    {"royalblue1", 0x48, 0x76, 0xff},
 622    {"royalblue2", 0x43, 0x6e, 0xee},
 623    {"royalblue3", 0x3a, 0x5f, 0xcd},
 624    {"royalblue4", 0x27, 0x40, 0x8b},
 625    {"saddlebrown", 0x8b, 0x45, 0x13},
 626    {"salmon", 0xfa, 0x80, 0x72},
 627    {"salmon1", 0xff, 0x8c, 0x69},
 628    {"salmon2", 0xee, 0x82, 0x62},
 629    {"salmon3", 0xcd, 0x70, 0x54},
 630    {"salmon4", 0x8b, 0x4c, 0x39},
 631    {"sandybrown", 0xf4, 0xa4, 0x60},
 632    {"seagreen", 0x2e, 0x8b, 0x57},
 633    {"seagreen1", 0x54, 0xff, 0x9f},
 634    {"seagreen2", 0x4e, 0xee, 0x94},
 635    {"seagreen3", 0x43, 0xcd, 0x80},
 636    {"seagreen4", 0x2e, 0x8b, 0x57},
 637    {"seashell", 0xff, 0xf5, 0xee},
 638    {"seashell1", 0xff, 0xf5, 0xee},
 639    {"seashell2", 0xee, 0xe5, 0xde},
 640    {"seashell3", 0xcd, 0xc5, 0xbf},
 641    {"seashell4", 0x8b, 0x86, 0x82},
 642    {"sienna", 0xa0, 0x52, 0x2d},
 643    {"sienna1", 0xff, 0x82, 0x47},
 644    {"sienna2", 0xee, 0x79, 0x42},
 645    {"sienna3", 0xcd, 0x68, 0x39},
 646    {"sienna4", 0x8b, 0x47, 0x26},
 647    {"skyblue", 0x87, 0xce, 0xeb},
 648    {"skyblue1", 0x87, 0xce, 0xff},
 649    {"skyblue2", 0x7e, 0xc0, 0xee},
 650    {"skyblue3", 0x6c, 0xa6, 0xcd},
 651    {"skyblue4", 0x4a, 0x70, 0x8b},
 652    {"slateblue", 0x6a, 0x5a, 0xcd},
 653    {"slateblue1", 0x83, 0x6f, 0xff},
 654    {"slateblue2", 0x7a, 0x67, 0xee},
 655    {"slateblue3", 0x69, 0x59, 0xcd},
 656    {"slateblue4", 0x47, 0x3c, 0x8b},
 657    {"slategray", 0x70, 0x80, 0x90},
 658    {"slategray1", 0xc6, 0xe2, 0xff},
 659    {"slategray2", 0xb9, 0xd3, 0xee},
 660    {"slategray3", 0x9f, 0xb6, 0xcd},
 661    {"slategray4", 0x6c, 0x7b, 0x8b},
 662    {"slategrey", 0x70, 0x80, 0x90},
 663    {"slategrey1", 0xc6, 0xe2, 0xff},
 664    {"slategrey2", 0xb9, 0xd3, 0xee},
 665    {"slategrey3", 0x9f, 0xb6, 0xcd},
 666    {"slategrey4", 0x6c, 0x7b, 0x8b},
 667    {"snow", 0xff, 0xfa, 0xfa},
 668    {"snow1", 0xff, 0xfa, 0xfa},
 669    {"snow2", 0xee, 0xe9, 0xe9},
 670    {"snow3", 0xcd, 0xc9, 0xc9},
 671    {"snow4", 0x8b, 0x89, 0x89},
 672    {"springgreen", 0x00, 0xff, 0x7f},
 673    {"springgreen1", 0x00, 0xff, 0x7f},
 674    {"springgreen2", 0x00, 0xee, 0x76},
 675    {"springgreen3", 0x00, 0xcd, 0x66},
 676    {"springgreen4", 0x00, 0x8b, 0x45},
 677    {"steelblue", 0x46, 0x82, 0xb4},
 678    {"steelblue1", 0x63, 0xb8, 0xff},
 679    {"steelblue2", 0x5c, 0xac, 0xee},
 680    {"steelblue3", 0x4f, 0x94, 0xcd},
 681    {"steelblue4", 0x36, 0x64, 0x8b},
 682    {"tan", 0xd2, 0xb4, 0x8c},
 683    {"tan1", 0xff, 0xa5, 0x4f},
 684    {"tan2", 0xee, 0x9a, 0x49},
 685    {"tan3", 0xcd, 0x85, 0x3f},
 686    {"tan4", 0x8b, 0x5a, 0x2b},
 687    {"thistle", 0xd8, 0xbf, 0xd8},
 688    {"thistle1", 0xff, 0xe1, 0xff},
 689    {"thistle2", 0xee, 0xd2, 0xee},
 690    {"thistle3", 0xcd, 0xb5, 0xcd},
 691    {"thistle4", 0x8b, 0x7b, 0x8b},
 692    {"tomato", 0xff, 0x63, 0x47},
 693    {"tomato1", 0xff, 0x63, 0x47},
 694    {"tomato2", 0xee, 0x5c, 0x42},
 695    {"tomato3", 0xcd, 0x4f, 0x39},
 696    {"tomato4", 0x8b, 0x36, 0x26},
 697    {"turquoise", 0x40, 0xe0, 0xd0},
 698    {"turquoise1", 0x00, 0xf5, 0xff},
 699    {"turquoise2", 0x00, 0xe5, 0xee},
 700    {"turquoise3", 0x00, 0xc5, 0xcd},
 701    {"turquoise4", 0x00, 0x86, 0x8b},
 702    {"violet", 0xee, 0x82, 0xee},
 703    {"violetred", 0xd0, 0x20, 0x90},
 704    {"violetred1", 0xff, 0x3e, 0x96},
 705    {"violetred2", 0xee, 0x3a, 0x8c},
 706    {"violetred3", 0xcd, 0x32, 0x78},
 707    {"violetred4", 0x8b, 0x22, 0x52},
 708    {"wheat", 0xf5, 0xde, 0xb3},
 709    {"wheat1", 0xff, 0xe7, 0xba},
 710    {"wheat2", 0xee, 0xd8, 0xae},
 711    {"wheat3", 0xcd, 0xba, 0x96},
 712    {"wheat4", 0x8b, 0x7e, 0x66},
 713    {"white", 0xff, 0xff, 0xff},
 714    {"whitesmoke", 0xf5, 0xf5, 0xf5},
 715    {"yellow", 0xff, 0xff, 0x00},
 716    {"yellow1", 0xff, 0xff, 0x00},
 717    {"yellow2", 0xee, 0xee, 0x00},
 718    {"yellow3", 0xcd, 0xcd, 0x00},
 719    {"yellow4", 0x8b, 0x8b, 0x00},
 720    {"yellowgreen", 0x9a, 0xcd, 0x32},
 721    {NO_TEXT, 0, 0, 0}
 722  };
 723  
 724  //! @brief Searches colour in the list.
 725  
 726  BOOL_T string_to_colour (NODE_T * p, char *name, int *iindex)
 727  {
 728    A68_REF z_ref = heap_generator (p, M_C_STRING, (int) (1 + strlen (name)));
 729    char *z = DEREF (char, &z_ref);
 730    int i, j;
 731    BOOL_T k;
 732  // First remove formatting from name: spaces and capitals are irrelevant.
 733    j = 0;
 734    for (i = 0; name[i] != NULL_CHAR; i++) {
 735      if (name[i] != BLANK_CHAR) {
 736        z[j++] = (char) TO_LOWER (name[i]);
 737      }
 738      z[j] = 0;
 739    }
 740  // Now search with the famous British Library Method.
 741    k = A68_FALSE;
 742    for (i = 0; i < COLOUR_NAMES && !k; i++) {
 743      if (!strcmp (NAME (&A68_COLOURS[i]), z)) {
 744        k = A68_TRUE;
 745        *iindex = i;
 746      }
 747    }
 748    return k;
 749  }
 750  
 751  //! @brief Scans string for an integer.
 752  
 753  BOOL_T scan_int (char **z, int *k)
 754  {
 755    char *y = *z;
 756    while (y[0] != NULL_CHAR && !IS_DIGIT (y[0])) {
 757      y++;
 758    }
 759    if (y[0] != NULL_CHAR) {
 760      (*k) = strtol (y, z, 10);
 761      return (BOOL_T) (errno == 0);
 762    } else {
 763      return A68_FALSE;
 764    }
 765  }
 766  
 767  //! @brief PROC (REF FILE, STRING, STRING) make device
 768  
 769  void genie_make_device (NODE_T * p)
 770  {
 771    int size;
 772    A68_REF ref_device, ref_page, ref_file;
 773    A68_FILE *file;
 774  // Pop arguments.
 775    POP_REF (p, &ref_page);
 776    POP_REF (p, &ref_device);
 777    POP_REF (p, &ref_file);
 778    CHECK_REF (p, ref_file, M_REF_FILE);
 779    file = FILE_DEREF (&ref_file);
 780    if (DEVICE_MADE (&DEVICE (file))) {
 781      diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_ALREADY_SET);
 782      exit_genie (p, A68_RUNTIME_ERROR);
 783    }
 784  // Fill in page_size.
 785    size = a68_string_size (p, ref_page);
 786    if (INITIALISED (&(A68_PAGE_SIZE (&DEVICE (file)))) && !IS_NIL (A68_PAGE_SIZE (&DEVICE (file)))) {
 787      UNBLOCK_GC_HANDLE (&A68_PAGE_SIZE (&DEVICE (file)));
 788    }
 789    A68_PAGE_SIZE (&DEVICE (file)) = heap_generator (p, M_STRING, 1 + size);
 790    BLOCK_GC_HANDLE (&A68_PAGE_SIZE (&DEVICE (file)));
 791    ASSERT (a_to_c_string (p, DEREF (char, &A68_PAGE_SIZE (&DEVICE (file))), ref_page) != NO_TEXT);
 792  // Fill in device.
 793    size = a68_string_size (p, ref_device);
 794    if (INITIALISED (&(DEVICE (&DEVICE (file)))) && !IS_NIL (DEVICE (&DEVICE (file)))) {
 795      UNBLOCK_GC_HANDLE (&DEVICE (&DEVICE (file)));
 796    }
 797    DEVICE (&DEVICE (file)) = heap_generator (p, M_STRING, 1 + size);
 798    BLOCK_GC_HANDLE (&DEVICE (&DEVICE (file)));
 799    ASSERT (a_to_c_string (p, DEREF (char, &DEVICE (&DEVICE (file))), ref_device) != NO_TEXT);
 800    DEVICE_MADE (&DEVICE (file)) = A68_TRUE;
 801    PUSH_VALUE (p, A68_TRUE, A68_BOOL);
 802  }
 803  
 804  //! @brief Closes the plotter.
 805  
 806  BOOL_T close_device (NODE_T * p, A68_FILE * f)
 807  {
 808    CHECK_INIT (p, INITIALISED (f), M_FILE);
 809    if (!OPENED (f)) {
 810      diagnostic (A68_RUNTIME_ERROR, p, ERROR_FILE_NOT_OPEN);
 811      exit_genie (p, A68_RUNTIME_ERROR);
 812    }
 813    if (!(DEVICE_OPENED (&DEVICE (f)))) {
 814      diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_NOT_OPEN);
 815      exit_genie (p, A68_RUNTIME_ERROR);
 816    }
 817    if (DEVICE_MADE (&DEVICE (f))) {
 818      if (!IS_NIL (DEVICE (&DEVICE (f)))) {
 819        UNBLOCK_GC_HANDLE (&(DEVICE (&DEVICE (f))));
 820      }
 821      if (!IS_NIL (A68_PAGE_SIZE (&DEVICE (f)))) {
 822        UNBLOCK_GC_HANDLE (&(A68_PAGE_SIZE (&DEVICE (f))));
 823      }
 824    }
 825    if (pl_closepl_r (PLOTTER (&DEVICE (f))) < 0) {
 826      diagnostic (A68_RUNTIME_ERROR, p, ERROR_CLOSING_DEVICE);
 827      exit_genie (p, A68_RUNTIME_ERROR);
 828    }
 829    if (pl_deletepl_r (PLOTTER (&DEVICE (f))) < 0) {
 830      diagnostic (A68_RUNTIME_ERROR, p, ERROR_CLOSING_DEVICE);
 831      exit_genie (p, A68_RUNTIME_ERROR);
 832    }
 833    if (STREAM (&DEVICE (f)) != NO_STREAM && fclose (STREAM (&DEVICE (f))) != 0) {
 834      diagnostic (A68_RUNTIME_ERROR, p, ERROR_CLOSING_FILE);
 835      exit_genie (p, A68_RUNTIME_ERROR);
 836    }
 837    DEVICE_OPENED (&DEVICE (f)) = A68_FALSE;
 838    return A68_TRUE;
 839  }
 840  
 841  //! @brief Sets up the plotter prior to using it.
 842  
 843  plPlotter *set_up_device (NODE_T * p, A68_FILE * f)
 844  {
 845    A68_REF ref_filename;
 846    char *filename, *device_type;
 847  // First set up the general device, then plotter-specific things.
 848    CHECK_INIT (p, INITIALISED (f), M_FILE);
 849    ref_filename = IDENTIFICATION (f);
 850  // This one in front as to quickly select the plotter.
 851    if (DEVICE_OPENED (&DEVICE (f))) {
 852      if (DEVICE_HANDLE (&DEVICE (f)) < 0) {
 853        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
 854        exit_genie (p, A68_RUNTIME_ERROR);
 855      }
 856      return PLOTTER (&DEVICE (f));
 857    }
 858  // Device not set up yet.
 859    if (!OPENED (f)) {
 860      diagnostic (A68_RUNTIME_ERROR, p, ERROR_FILE_NOT_OPEN);
 861      exit_genie (p, A68_RUNTIME_ERROR);
 862    }
 863    if (READ_MOOD (f)) {
 864      diagnostic (A68_RUNTIME_ERROR, p, ERROR_FILE_WRONG_MOOD, "read");
 865      exit_genie (p, A68_RUNTIME_ERROR);
 866    }
 867    if (WRITE_MOOD (f)) {
 868      diagnostic (A68_RUNTIME_ERROR, p, ERROR_FILE_WRONG_MOOD, "write");
 869      exit_genie (p, A68_RUNTIME_ERROR);
 870    }
 871    if (!DRAW (&CHANNEL (f))) {
 872      diagnostic (A68_RUNTIME_ERROR, p, ERROR_CHANNEL_DOES_NOT_ALLOW, "drawing");
 873      exit_genie (p, A68_RUNTIME_ERROR);
 874    }
 875    if (!DEVICE_MADE (&DEVICE (f))) {
 876      diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_NOT_SET);
 877      exit_genie (p, A68_RUNTIME_ERROR);
 878    }
 879    device_type = DEREF (char, &DEVICE (&DEVICE (f)));
 880    if (!strcmp (device_type, "X")) {
 881  #if defined (X_DISPLAY_MISSING)
 882      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "X plotter missing", "");
 883      exit_genie (p, A68_RUNTIME_ERROR);
 884  #else
 885  //
 886  // Supported plotter type - X Window System
 887  //
 888      char *z = DEREF (char, &A68_PAGE_SIZE (&DEVICE (f))), size[BUFFER_SIZE];
 889  // Establish page size.
 890      if (!scan_int (&z, &(WINDOW_X_SIZE (&DEVICE (f))))) {
 891        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 892        exit_genie (p, A68_RUNTIME_ERROR);
 893      }
 894      if (!scan_int (&z, &(WINDOW_Y_SIZE (&DEVICE (f))))) {
 895        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 896        exit_genie (p, A68_RUNTIME_ERROR);
 897      }
 898      if (z[0] != NULL_CHAR) {
 899        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 900        exit_genie (p, A68_RUNTIME_ERROR);
 901      }
 902  // Make the X window.
 903      FD (f) = -1;
 904      PLOTTER_PARAMS (&DEVICE (f)) = pl_newplparams ();
 905      if (PLOTTER_PARAMS (&DEVICE (f)) == NULL) {
 906        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_ALLOCATE);
 907        exit_genie (p, A68_RUNTIME_ERROR);
 908      }
 909      ASSERT (snprintf (size, SNPRINTF_SIZE, "%dx%d", WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))) >= 0);
 910      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BITMAPSIZE", size);
 911      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BG_COLOR", (void *) "black");
 912      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "VANISH_ON_DELETE", (void *) "no");
 913      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "X_AUTO_FLUSH", (void *) "yes");
 914      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "USE_DOUBLE_BUFFERING", (void *) "no");
 915      PLOTTER (&DEVICE (f)) = pl_newpl_r ("X", NULL, NULL, stderr, PLOTTER_PARAMS (&DEVICE (f)));
 916      if (PLOTTER (&DEVICE (f)) == NULL) {
 917        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
 918        exit_genie (p, A68_RUNTIME_ERROR);
 919      }
 920      if (pl_openpl_r (PLOTTER (&DEVICE (f))) < 0) {
 921        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
 922        exit_genie (p, A68_RUNTIME_ERROR);
 923      }
 924      (void) pl_space_r (PLOTTER (&DEVICE (f)), 0, 0, WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f)));
 925      (void) pl_bgcolorname_r (PLOTTER (&DEVICE (f)), "black");
 926      (void) pl_colorname_r (PLOTTER (&DEVICE (f)), "white");
 927      (void) pl_pencolorname_r (PLOTTER (&DEVICE (f)), "white");
 928      (void) pl_fillcolorname_r (PLOTTER (&DEVICE (f)), "white");
 929      (void) pl_filltype_r (PLOTTER (&DEVICE (f)), 0);
 930      DRAW_MOOD (f) = A68_TRUE;
 931      DEVICE_OPENED (&DEVICE (f)) = A68_TRUE;
 932      X_COORD (&DEVICE (f)) = 0;
 933      Y_COORD (&DEVICE (f)) = 0;
 934      return PLOTTER (&DEVICE (f));
 935  #endif
 936    } else if (!strcmp (device_type, "gif")) {
 937  //
 938  // Supported plotter type - pseudo GIF
 939  //
 940      char *z = DEREF (char, &A68_PAGE_SIZE (&DEVICE (f))), size[BUFFER_SIZE];
 941  // Establish page size.
 942      if (!scan_int (&z, &(WINDOW_X_SIZE (&DEVICE (f))))) {
 943        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 944        exit_genie (p, A68_RUNTIME_ERROR);
 945      }
 946      if (!scan_int (&z, &(WINDOW_Y_SIZE (&DEVICE (f))))) {
 947        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 948        exit_genie (p, A68_RUNTIME_ERROR);
 949      }
 950      if (z[0] != NULL_CHAR) {
 951        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
 952        exit_genie (p, A68_RUNTIME_ERROR);
 953      }
 954  // Open the output file for drawing.
 955      CHECK_REF (p, ref_filename, M_ROWS);
 956      filename = DEREF (char, &ref_filename);
 957      errno = 0;
 958      if ((STREAM (&DEVICE (f)) = fopen (filename, "wb")) == NO_STREAM) {
 959        diagnostic (A68_RUNTIME_ERROR, p, ERROR_CANNOT_OPEN_NAME, filename);
 960        exit_genie (p, A68_RUNTIME_ERROR);
 961      } else {
 962        READ_MOOD (f) = A68_FALSE;
 963        WRITE_MOOD (f) = A68_FALSE;
 964        CHAR_MOOD (f) = A68_FALSE;
 965        DRAW_MOOD (f) = A68_TRUE;
 966      }
 967  // Set up plotter.
 968      PLOTTER_PARAMS (&DEVICE (f)) = pl_newplparams ();
 969      if (PLOTTER_PARAMS (&DEVICE (f)) == NULL) {
 970        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_ALLOCATE);
 971        exit_genie (p, A68_RUNTIME_ERROR);
 972      }
 973      ASSERT (snprintf (size, SNPRINTF_SIZE, "%dx%d", WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))) >= 0);
 974      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BITMAPSIZE", size);
 975      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BG_COLOR", (void *) "black");
 976      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "GIF_ANIMATION", (void *) "no");
 977      PLOTTER (&DEVICE (f)) = pl_newpl_r ("gif", NULL, STREAM (&DEVICE (f)), stderr, PLOTTER_PARAMS (&DEVICE (f)));
 978      if (PLOTTER (&DEVICE (f)) == NULL) {
 979        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
 980        exit_genie (p, A68_RUNTIME_ERROR);
 981      }
 982      if (pl_openpl_r (PLOTTER (&DEVICE (f))) < 0) {
 983        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
 984        exit_genie (p, A68_RUNTIME_ERROR);
 985      }
 986      (void) pl_space_r (PLOTTER (&DEVICE (f)), 0, 0, WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f)));
 987      (void) pl_bgcolorname_r (PLOTTER (&DEVICE (f)), "black");
 988      (void) pl_colorname_r (PLOTTER (&DEVICE (f)), "white");
 989      (void) pl_pencolorname_r (PLOTTER (&DEVICE (f)), "white");
 990      (void) pl_fillcolorname_r (PLOTTER (&DEVICE (f)), "white");
 991      (void) pl_filltype_r (PLOTTER (&DEVICE (f)), 0);
 992      DRAW_MOOD (f) = A68_TRUE;
 993      DEVICE_OPENED (&DEVICE (f)) = A68_TRUE;
 994      X_COORD (&DEVICE (f)) = 0;
 995      Y_COORD (&DEVICE (f)) = 0;
 996      return PLOTTER (&DEVICE (f));
 997    } else if (!strcmp (device_type, "pnm")) {
 998  //
 999  // Supported plotter type - Portable aNyMap
1000  //
1001      char *z = DEREF (char, &A68_PAGE_SIZE (&DEVICE (f))), size[BUFFER_SIZE];
1002  // Establish page size.
1003      if (!scan_int (&z, &(WINDOW_X_SIZE (&DEVICE (f))))) {
1004        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1005        exit_genie (p, A68_RUNTIME_ERROR);
1006      }
1007      if (!scan_int (&z, &(WINDOW_Y_SIZE (&DEVICE (f))))) {
1008        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1009        exit_genie (p, A68_RUNTIME_ERROR);
1010      }
1011      if (z[0] != NULL_CHAR) {
1012        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1013        exit_genie (p, A68_RUNTIME_ERROR);
1014      }
1015  // Open the output file for drawing.
1016      CHECK_REF (p, ref_filename, M_ROWS);
1017      filename = DEREF (char, &ref_filename);
1018      errno = 0;
1019      if ((STREAM (&DEVICE (f)) = fopen (filename, "wb")) == NO_STREAM) {
1020        diagnostic (A68_RUNTIME_ERROR, p, ERROR_CANNOT_OPEN_NAME, filename);
1021        exit_genie (p, A68_RUNTIME_ERROR);
1022      } else {
1023        READ_MOOD (f) = A68_FALSE;
1024        WRITE_MOOD (f) = A68_FALSE;
1025        CHAR_MOOD (f) = A68_FALSE;
1026        DRAW_MOOD (f) = A68_TRUE;
1027      }
1028  // Set up plotter.
1029      ASSERT (snprintf (size, SNPRINTF_SIZE, "%dx%d", WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))) >= 0);
1030      PLOTTER_PARAMS (&DEVICE (f)) = pl_newplparams ();
1031      if (PLOTTER_PARAMS (&DEVICE (f)) == NULL) {
1032        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_ALLOCATE);
1033        exit_genie (p, A68_RUNTIME_ERROR);
1034      }
1035      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BITMAPSIZE", size);
1036      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BG_COLOR", (void *) "black");
1037      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "PNM_PORTABLE", (void *) "no");
1038      PLOTTER (&DEVICE (f)) = pl_newpl_r ("pnm", NULL, STREAM (&DEVICE (f)), stderr, PLOTTER_PARAMS (&DEVICE (f)));
1039      if (PLOTTER (&DEVICE (f)) == NULL) {
1040        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1041        exit_genie (p, A68_RUNTIME_ERROR);
1042      }
1043      if (pl_openpl_r (PLOTTER (&DEVICE (f))) < 0) {
1044        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1045        exit_genie (p, A68_RUNTIME_ERROR);
1046      }
1047      (void) pl_space_r (PLOTTER (&DEVICE (f)), 0, 0, WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f)));
1048      (void) pl_bgcolorname_r (PLOTTER (&DEVICE (f)), "black");
1049      (void) pl_colorname_r (PLOTTER (&DEVICE (f)), "white");
1050      (void) pl_pencolorname_r (PLOTTER (&DEVICE (f)), "white");
1051      (void) pl_fillcolorname_r (PLOTTER (&DEVICE (f)), "white");
1052      (void) pl_filltype_r (PLOTTER (&DEVICE (f)), 0);
1053      DRAW_MOOD (f) = A68_TRUE;
1054      DEVICE_OPENED (&DEVICE (f)) = A68_TRUE;
1055      X_COORD (&DEVICE (f)) = 0;
1056      Y_COORD (&DEVICE (f)) = 0;
1057      return PLOTTER (&DEVICE (f));
1058    } else if (!strcmp (device_type, "png")) {
1059  #if defined (X_DISPLAY_MISSING)
1060      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "PNG plotter missing", "");
1061      exit_genie (p, A68_RUNTIME_ERROR);
1062  #else
1063  //
1064  // Supported plotter type - PNG
1065  //
1066      char *z = DEREF (char, &A68_PAGE_SIZE (&DEVICE (f))), size[BUFFER_SIZE];
1067  // Establish page size.
1068      if (!scan_int (&z, &(WINDOW_X_SIZE (&DEVICE (f))))) {
1069        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1070        exit_genie (p, A68_RUNTIME_ERROR);
1071      }
1072      if (!scan_int (&z, &(WINDOW_Y_SIZE (&DEVICE (f))))) {
1073        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1074        exit_genie (p, A68_RUNTIME_ERROR);
1075      }
1076      if (z[0] != NULL_CHAR) {
1077        diagnostic (A68_RUNTIME_ERROR, p, ERROR_PAGE_SIZE);
1078        exit_genie (p, A68_RUNTIME_ERROR);
1079      }
1080  // Open the output file for drawing.
1081      CHECK_REF (p, ref_filename, M_ROWS);
1082      filename = DEREF (char, &ref_filename);
1083      errno = 0;
1084      if ((STREAM (&DEVICE (f)) = fopen (filename, "wb")) == NO_STREAM) {
1085        diagnostic (A68_RUNTIME_ERROR, p, ERROR_CANNOT_OPEN_NAME, filename);
1086        exit_genie (p, A68_RUNTIME_ERROR);
1087      } else {
1088        READ_MOOD (f) = A68_FALSE;
1089        WRITE_MOOD (f) = A68_FALSE;
1090        CHAR_MOOD (f) = A68_FALSE;
1091        DRAW_MOOD (f) = A68_TRUE;
1092      }
1093  // Set up plotter.
1094      PLOTTER_PARAMS (&DEVICE (f)) = pl_newplparams ();
1095      if (PLOTTER_PARAMS (&DEVICE (f)) == NULL) {
1096        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_ALLOCATE);
1097        exit_genie (p, A68_RUNTIME_ERROR);
1098      }
1099      ASSERT (snprintf (size, SNPRINTF_SIZE, "%dx%d", WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))) >= 0);
1100      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BITMAPSIZE", size);
1101      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "BG_COLOR", (void *) "black");
1102      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "GIF_ANIMATION", (void *) "no");
1103      PLOTTER (&DEVICE (f)) = pl_newpl_r ("png", NULL, STREAM (&DEVICE (f)), stderr, PLOTTER_PARAMS (&DEVICE (f)));
1104      if (PLOTTER (&DEVICE (f)) == NULL) {
1105        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1106        exit_genie (p, A68_RUNTIME_ERROR);
1107      }
1108      if (pl_openpl_r (PLOTTER (&DEVICE (f))) < 0) {
1109        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1110        exit_genie (p, A68_RUNTIME_ERROR);
1111      }
1112      (void) pl_space_r (PLOTTER (&DEVICE (f)), 0, 0, WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f)));
1113      (void) pl_bgcolorname_r (PLOTTER (&DEVICE (f)), "black");
1114      (void) pl_colorname_r (PLOTTER (&DEVICE (f)), "white");
1115      (void) pl_pencolorname_r (PLOTTER (&DEVICE (f)), "white");
1116      (void) pl_fillcolorname_r (PLOTTER (&DEVICE (f)), "white");
1117      (void) pl_filltype_r (PLOTTER (&DEVICE (f)), 0);
1118      DRAW_MOOD (f) = A68_TRUE;
1119      DEVICE_OPENED (&DEVICE (f)) = A68_TRUE;
1120      X_COORD (&DEVICE (f)) = 0;
1121      Y_COORD (&DEVICE (f)) = 0;
1122      return PLOTTER (&DEVICE (f));
1123  #endif
1124    } else if (!strcmp (device_type, "ps")) {
1125  #if defined (POSTSCRIPT_MISSING)
1126      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "postscript plotter missing", "");
1127      exit_genie (p, A68_RUNTIME_ERROR);
1128  #else
1129  //
1130  // Supported plotter type - Postscript
1131  //
1132  // Open the output file for drawing.
1133      CHECK_REF (p, ref_filename, M_ROWS);
1134      filename = DEREF (char, &ref_filename);
1135      errno = 0;
1136      if ((STREAM (&DEVICE (f)) = fopen (filename, "w")) == NO_STREAM) {
1137        diagnostic (A68_RUNTIME_ERROR, p, ERROR_CANNOT_OPEN_NAME, filename);
1138        exit_genie (p, A68_RUNTIME_ERROR);
1139      } else {
1140        READ_MOOD (f) = A68_FALSE;
1141        WRITE_MOOD (f) = A68_FALSE;
1142        CHAR_MOOD (f) = A68_FALSE;
1143        DRAW_MOOD (f) = A68_TRUE;
1144      }
1145  // Set up ps plotter.
1146      PLOTTER_PARAMS (&DEVICE (f)) = pl_newplparams ();
1147      if (PLOTTER_PARAMS (&DEVICE (f)) == NULL) {
1148        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_ALLOCATE);
1149        exit_genie (p, A68_RUNTIME_ERROR);
1150      }
1151      (void) pl_setplparam (PLOTTER_PARAMS (&DEVICE (f)), "PAGESIZE", DEREF (char, &A68_PAGE_SIZE (&DEVICE (f))));
1152      PLOTTER (&DEVICE (f)) = pl_newpl_r ("ps", NULL, STREAM (&DEVICE (f)), stderr, PLOTTER_PARAMS (&DEVICE (f)));
1153      if (PLOTTER (&DEVICE (f)) == NULL) {
1154        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1155        exit_genie (p, A68_RUNTIME_ERROR);
1156      }
1157      if (pl_openpl_r (PLOTTER (&DEVICE (f))) < 0) {
1158        diagnostic (A68_RUNTIME_ERROR, p, ERROR_DEVICE_CANNOT_OPEN);
1159        exit_genie (p, A68_RUNTIME_ERROR);
1160      }
1161      WINDOW_X_SIZE (&DEVICE (f)) = 1000;
1162      WINDOW_Y_SIZE (&DEVICE (f)) = 1000;
1163      (void) pl_space_r (PLOTTER (&DEVICE (f)), 0, 0, WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f)));
1164      (void) pl_bgcolorname_r (PLOTTER (&DEVICE (f)), "black");
1165      (void) pl_colorname_r (PLOTTER (&DEVICE (f)), "white");
1166      (void) pl_pencolorname_r (PLOTTER (&DEVICE (f)), "white");
1167      (void) pl_fillcolorname_r (PLOTTER (&DEVICE (f)), "white");
1168      (void) pl_filltype_r (PLOTTER (&DEVICE (f)), 0);
1169      DRAW_MOOD (f) = A68_TRUE;
1170      DEVICE_OPENED (&DEVICE (f)) = A68_TRUE;
1171      X_COORD (&DEVICE (f)) = 0;
1172      Y_COORD (&DEVICE (f)) = 0;
1173      return PLOTTER (&DEVICE (f));
1174  #endif
1175    } else {
1176      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "unindentified plotter", device_type);
1177      exit_genie (p, A68_RUNTIME_ERROR);
1178    }
1179    return NULL;
1180  }
1181  
1182  //! @brief PROC (REF FILE) VOID draw erase
1183  
1184  void genie_draw_clear (NODE_T * p)
1185  {
1186    A68_REF ref_file;
1187    A68_FILE *f;
1188    plPlotter *plotter;
1189    POP_REF (p, &ref_file);
1190    CHECK_REF (p, ref_file, M_REF_FILE);
1191    f = FILE_DEREF (&ref_file);
1192    plotter = set_up_device (p, f);
1193    (void) pl_flushpl_r (plotter);
1194    (void) pl_erase_r (plotter);
1195  }
1196  
1197  //! @brief PROC (REF FILE) VOID draw show
1198  
1199  void genie_draw_show (NODE_T * p)
1200  {
1201    A68_REF ref_file;
1202    A68_FILE *f;
1203    plPlotter *plotter;
1204    POP_REF (p, &ref_file);
1205    CHECK_REF (p, ref_file, M_REF_FILE);
1206    f = FILE_DEREF (&ref_file);
1207    plotter = set_up_device (p, f);
1208    (void) pl_flushpl_r (plotter);
1209  }
1210  
1211  //! @brief PROC (REF FILE) REAL draw aspect
1212  
1213  void genie_draw_aspect (NODE_T * p)
1214  {
1215    A68_REF ref_file;
1216    A68_FILE *f;
1217    plPlotter *plotter;
1218    POP_REF (p, &ref_file);
1219    CHECK_REF (p, ref_file, M_REF_FILE);
1220    f = FILE_DEREF (&ref_file);
1221    plotter = set_up_device (p, f);
1222    PUSH_VALUE (p, (REAL_T) WINDOW_Y_SIZE (&DEVICE (f)) / (REAL_T) WINDOW_X_SIZE (&DEVICE (f)), A68_REAL);
1223    (void) plotter;
1224  }
1225  
1226  //! @brief PROC (REF FILE, INT) VOID draw fillstyle
1227  
1228  void genie_draw_fillstyle (NODE_T * p)
1229  {
1230    A68_INT z;
1231    A68_REF ref_file;
1232    A68_FILE *f;
1233    plPlotter *plotter;
1234    POP_OBJECT (p, &z, A68_INT);
1235    POP_REF (p, &ref_file);
1236    CHECK_REF (p, ref_file, M_REF_FILE);
1237    f = FILE_DEREF (&ref_file);
1238    plotter = set_up_device (p, f);
1239    (void) pl_filltype_r (plotter, (int) VALUE (&z));
1240  }
1241  
1242  //! @brief PROC (INT) STRING draw get colour name
1243  
1244  void genie_draw_get_colour_name (NODE_T * p)
1245  {
1246    A68_INT z;
1247    int j;
1248    char *str;
1249    POP_OBJECT (p, &z, A68_INT);
1250    j = (VALUE (&z) - 1) % COLOUR_NAMES;
1251    str = NAME (&A68_COLOURS[j]);
1252    PUSH_REF (p, c_to_a_string (p, str, DEFAULT_WIDTH));
1253  }
1254  
1255  //! @brief PROC (REF FILE, REAL, REAL, REAL) VOID draw colour
1256  
1257  void genie_draw_colour (NODE_T * p)
1258  {
1259    A68_REAL x, y, z;
1260    A68_REF ref_file;
1261    A68_FILE *f;
1262    plPlotter *plotter;
1263    POP_OBJECT (p, &z, A68_REAL);
1264    POP_OBJECT (p, &y, A68_REAL);
1265    POP_OBJECT (p, &x, A68_REAL);
1266    POP_REF (p, &ref_file);
1267    CHECK_REF (p, ref_file, M_REF_FILE);
1268    f = FILE_DEREF (&ref_file);
1269    plotter = set_up_device (p, f);
1270    RED (&DEVICE (f)) = VALUE (&x);
1271    GREEN (&DEVICE (f)) = VALUE (&y);
1272    BLUE (&DEVICE (f)) = VALUE (&z);
1273    (void) pl_color_r (plotter, (int) (VALUE (&x) * COLOUR_MAX), (int) (VALUE (&y) * COLOUR_MAX), (int) (VALUE (&z) * COLOUR_MAX));
1274    (void) pl_pencolor_r (plotter, (int) (VALUE (&x) * COLOUR_MAX), (int) (VALUE (&y) * COLOUR_MAX), (int) (VALUE (&z) * COLOUR_MAX));
1275    (void) pl_fillcolor_r (plotter, (int) (VALUE (&x) * COLOUR_MAX), (int) (VALUE (&y) * COLOUR_MAX), (int) (VALUE (&z) * COLOUR_MAX));
1276  }
1277  
1278  //! @brief PROC (REF FILE, REAL, REAL, REAL) VOID draw background colour
1279  
1280  void genie_draw_background_colour (NODE_T * p)
1281  {
1282    A68_REAL x, y, z;
1283    A68_REF ref_file;
1284    A68_FILE *f;
1285    plPlotter *plotter;
1286    POP_OBJECT (p, &z, A68_REAL);
1287    POP_OBJECT (p, &y, A68_REAL);
1288    POP_OBJECT (p, &x, A68_REAL);
1289    POP_REF (p, &ref_file);
1290    CHECK_REF (p, ref_file, M_REF_FILE);
1291    f = FILE_DEREF (&ref_file);
1292    plotter = set_up_device (p, f);
1293    (void) pl_bgcolor_r (plotter, (int) (VALUE (&x) * COLOUR_MAX), (int) (VALUE (&y) * COLOUR_MAX), (int) (VALUE (&z) * COLOUR_MAX));
1294  }
1295  
1296  //! @brief PROC (REF FILE, STRING) VOID draw colour name
1297  
1298  void genie_draw_colour_name (NODE_T * p)
1299  {
1300    A68_REF ref_c, ref_file;
1301    A68_FILE *f;
1302    A68_REF name_ref;
1303    char *name;
1304    int iindex;
1305    REAL_T x, y, z;
1306    plPlotter *plotter;
1307    POP_REF (p, &ref_c);
1308    POP_REF (p, &ref_file);
1309    CHECK_REF (p, ref_file, M_REF_FILE);
1310    f = FILE_DEREF (&ref_file);
1311    name_ref = heap_generator (p, M_C_STRING, 1 + a68_string_size (p, ref_c));
1312    name = DEREF (char, &name_ref);
1313    ASSERT (a_to_c_string (p, name, ref_c) != NO_TEXT);
1314    if (!string_to_colour (p, name, &iindex)) {
1315      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "unidentified colour name", name);
1316      exit_genie (p, A68_RUNTIME_ERROR);
1317    }
1318    x = (REAL_T) (RED (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1319    y = (REAL_T) (GREEN (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1320    z = (REAL_T) (BLUE (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1321    plotter = set_up_device (p, f);
1322    RED (&DEVICE (f)) = x;
1323    GREEN (&DEVICE (f)) = y;
1324    BLUE (&DEVICE (f)) = z;
1325    (void) pl_color_r (plotter, (int) (x * COLOUR_MAX), (int) (y * COLOUR_MAX), (int) (z * COLOUR_MAX));
1326    (void) pl_pencolor_r (plotter, (int) (x * COLOUR_MAX), (int) (y * COLOUR_MAX), (int) (z * COLOUR_MAX));
1327    (void) pl_fillcolor_r (plotter, (int) (x * COLOUR_MAX), (int) (y * COLOUR_MAX), (int) (z * COLOUR_MAX));
1328  }
1329  
1330  //! @brief PROC (REF FILE, STRING) VOID draw background colour name
1331  
1332  void genie_draw_background_colour_name (NODE_T * p)
1333  {
1334    A68_REF ref_c, ref_file;
1335    A68_FILE *f;
1336    A68_REF name_ref;
1337    char *name;
1338    int iindex;
1339    REAL_T x, y, z;
1340    plPlotter *plotter;
1341    POP_REF (p, &ref_c);
1342    POP_REF (p, &ref_file);
1343    CHECK_REF (p, ref_file, M_REF_FILE);
1344    f = FILE_DEREF (&ref_file);
1345    name_ref = heap_generator (p, M_C_STRING, 1 + a68_string_size (p, ref_c));
1346    name = DEREF (char, &name_ref);
1347    ASSERT (a_to_c_string (p, name, ref_c) != NO_TEXT);
1348    if (!string_to_colour (p, name, &iindex)) {
1349      diagnostic (A68_RUNTIME_ERROR, p, ERROR_INVALID_PARAMETER, "unidentified colour name", name);
1350      exit_genie (p, A68_RUNTIME_ERROR);
1351    }
1352    x = (REAL_T) (RED (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1353    y = (REAL_T) (GREEN (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1354    z = (REAL_T) (BLUE (&A68_COLOURS[iindex])) / (REAL_T) (0xff);
1355    plotter = set_up_device (p, f);
1356    RED (&DEVICE (f)) = x;
1357    GREEN (&DEVICE (f)) = y;
1358    BLUE (&DEVICE (f)) = z;
1359    (void) pl_bgcolor_r (plotter, (int) (x * COLOUR_MAX), (int) (y * COLOUR_MAX), (int) (z * COLOUR_MAX));
1360  }
1361  
1362  //! @brief PROC (REF FILE, STRING) VOID draw linestyle
1363  
1364  void genie_draw_linestyle (NODE_T * p)
1365  {
1366    A68_REF txt, ref_file;
1367    A68_FILE *f;
1368    int size;
1369    A68_REF z_ref;
1370    char *z;
1371    plPlotter *plotter;
1372    POP_REF (p, &txt);
1373    POP_REF (p, &ref_file);
1374    CHECK_REF (p, ref_file, M_REF_FILE);
1375    f = FILE_DEREF (&ref_file);
1376    plotter = set_up_device (p, f);
1377    size = a68_string_size (p, txt);
1378    z_ref = heap_generator (p, M_C_STRING, 1 + size);
1379    z = DEREF (char, &z_ref);
1380    ASSERT (a_to_c_string (p, z, txt) != NO_TEXT);
1381    (void) pl_linemod_r (plotter, z);
1382  }
1383  
1384  //! @brief PROC (REF FILE, INT) VOID draw linewidth
1385  
1386  void genie_draw_linewidth (NODE_T * p)
1387  {
1388    A68_REAL width;
1389    A68_REF ref_file;
1390    A68_FILE *f;
1391    plPlotter *plotter;
1392    POP_OBJECT (p, &width, A68_REAL);
1393    POP_REF (p, &ref_file);
1394    CHECK_REF (p, ref_file, M_REF_FILE);
1395    f = FILE_DEREF (&ref_file);
1396    plotter = set_up_device (p, f);
1397    (void) pl_linewidth_r (plotter, (int) (VALUE (&width) * (REAL_T) WINDOW_Y_SIZE (&DEVICE (f))));
1398  }
1399  
1400  //! @brief PROC (REF FILE, REAL, REAL) VOID draw move
1401  
1402  void genie_draw_move (NODE_T * p)
1403  {
1404    A68_REAL x, y;
1405    A68_REF ref_file;
1406    A68_FILE *f;
1407    plPlotter *plotter;
1408    POP_OBJECT (p, &y, A68_REAL);
1409    POP_OBJECT (p, &x, A68_REAL);
1410    POP_REF (p, &ref_file);
1411    CHECK_REF (p, ref_file, M_REF_FILE);
1412    f = FILE_DEREF (&ref_file);
1413    plotter = set_up_device (p, f);
1414    (void) pl_fmove_r (plotter, VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)));
1415    X_COORD (&DEVICE (f)) = VALUE (&x);
1416    Y_COORD (&DEVICE (f)) = VALUE (&y);
1417  }
1418  
1419  //! @brief PROC (REF FILE, REAL, REAL) VOID draw line
1420  
1421  void genie_draw_line (NODE_T * p)
1422  {
1423    A68_REAL x, y;
1424    A68_REF ref_file;
1425    A68_FILE *f;
1426    plPlotter *plotter;
1427    POP_OBJECT (p, &y, A68_REAL);
1428    POP_OBJECT (p, &x, A68_REAL);
1429    POP_REF (p, &ref_file);
1430    CHECK_REF (p, ref_file, M_REF_FILE);
1431    f = FILE_DEREF (&ref_file);
1432    plotter = set_up_device (p, f);
1433    (void) pl_fline_r (plotter, X_COORD (&DEVICE (f)) * WINDOW_X_SIZE (&DEVICE (f)), Y_COORD (&DEVICE (f)) * WINDOW_Y_SIZE (&DEVICE (f)), VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)));
1434    X_COORD (&DEVICE (f)) = VALUE (&x);
1435    Y_COORD (&DEVICE (f)) = VALUE (&y);
1436  }
1437  
1438  //! @brief PROC (REF FILE, REAL, REAL) VOID draw point
1439  
1440  void genie_draw_point (NODE_T * p)
1441  {
1442    A68_REAL x, y;
1443    A68_REF ref_file;
1444    A68_FILE *f;
1445    plPlotter *plotter;
1446    POP_OBJECT (p, &y, A68_REAL);
1447    POP_OBJECT (p, &x, A68_REAL);
1448    POP_REF (p, &ref_file);
1449    CHECK_REF (p, ref_file, M_REF_FILE);
1450    f = FILE_DEREF (&ref_file);
1451    plotter = set_up_device (p, f);
1452    (void) pl_fpoint_r (plotter, VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)));
1453    X_COORD (&DEVICE (f)) = VALUE (&x);
1454    Y_COORD (&DEVICE (f)) = VALUE (&y);
1455  }
1456  
1457  //! @brief PROC (REF FILE, REAL, REAL) VOID draw rect
1458  
1459  void genie_draw_rect (NODE_T * p)
1460  {
1461    A68_REAL x, y;
1462    A68_REF ref_file;
1463    A68_FILE *f;
1464    plPlotter *plotter;
1465    POP_OBJECT (p, &y, A68_REAL);
1466    POP_OBJECT (p, &x, A68_REAL);
1467    POP_REF (p, &ref_file);
1468    CHECK_REF (p, ref_file, M_REF_FILE);
1469    f = FILE_DEREF (&ref_file);
1470    plotter = set_up_device (p, f);
1471    (void) pl_fbox_r (plotter, X_COORD (&DEVICE (f)) * WINDOW_X_SIZE (&DEVICE (f)), Y_COORD (&DEVICE (f)) * WINDOW_Y_SIZE (&DEVICE (f)), VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)));
1472    X_COORD (&DEVICE (f)) = VALUE (&x);
1473    Y_COORD (&DEVICE (f)) = VALUE (&y);
1474  }
1475  
1476  //! @brief PROC (REF FILE, REAL, REAL, REAL) VOID draw circle
1477  
1478  void genie_draw_circle (NODE_T * p)
1479  {
1480    A68_REAL x, y, r;
1481    A68_REF ref_file;
1482    A68_FILE *f;
1483    plPlotter *plotter;
1484    POP_OBJECT (p, &r, A68_REAL);
1485    POP_OBJECT (p, &y, A68_REAL);
1486    POP_OBJECT (p, &x, A68_REAL);
1487    POP_REF (p, &ref_file);
1488    CHECK_REF (p, ref_file, M_REF_FILE);
1489    f = FILE_DEREF (&ref_file);
1490    plotter = set_up_device (p, f);
1491    (void) pl_fcircle_r (plotter, VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)), VALUE (&r) * MAX (WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))));
1492    X_COORD (&DEVICE (f)) = VALUE (&x);
1493    Y_COORD (&DEVICE (f)) = VALUE (&y);
1494  }
1495  
1496  //! @brief PROC (REF FILE, REAL, REAL, REAL) VOID draw atom
1497  
1498  void genie_draw_atom (NODE_T * p)
1499  {
1500    A68_REAL x, y, r;
1501    REAL_T frac;
1502    int j, k;
1503    A68_REF ref_file;
1504    A68_FILE *f;
1505    plPlotter *plotter;
1506    POP_OBJECT (p, &r, A68_REAL);
1507    POP_OBJECT (p, &y, A68_REAL);
1508    POP_OBJECT (p, &x, A68_REAL);
1509    POP_REF (p, &ref_file);
1510    CHECK_REF (p, ref_file, M_REF_FILE);
1511    f = FILE_DEREF (&ref_file);
1512    plotter = set_up_device (p, f);
1513    k = (int) (VALUE (&r) * MAX (WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))));
1514    (void) pl_filltype_r (plotter, 1);
1515    for (j = k - 1; j >= 0; j--) {
1516      frac = (REAL_T) j / (REAL_T) (k - 1);
1517      frac = 0.6 + 0.3 * sqrt (1.0 - frac * frac);
1518      (void) pl_color_r (plotter, (int) (frac * RED (&DEVICE (f)) * COLOUR_MAX), (int) (frac * GREEN (&DEVICE (f)) * COLOUR_MAX), (int) (frac * BLUE (&DEVICE (f)) * COLOUR_MAX));
1519      (void) pl_fcircle_r (plotter, VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)), (REAL_T) j);
1520    }
1521    (void) pl_filltype_r (plotter, 0);
1522    X_COORD (&DEVICE (f)) = VALUE (&x);
1523    Y_COORD (&DEVICE (f)) = VALUE (&y);
1524  }
1525  
1526  //! @brief PROC (REF FILE, REAL, REAL, REAL) VOID draw atom
1527  
1528  void genie_draw_star (NODE_T * p)
1529  {
1530    A68_REAL x, y, r;
1531    REAL_T z, frac;
1532    int j, k;
1533    A68_REF ref_file;
1534    A68_FILE *f;
1535    plPlotter *plotter;
1536    POP_OBJECT (p, &r, A68_REAL);
1537    POP_OBJECT (p, &y, A68_REAL);
1538    POP_OBJECT (p, &x, A68_REAL);
1539    POP_REF (p, &ref_file);
1540    CHECK_REF (p, ref_file, M_REF_FILE);
1541    f = FILE_DEREF (&ref_file);
1542    plotter = set_up_device (p, f);
1543    k = (int) (VALUE (&r) * MAX (WINDOW_X_SIZE (&DEVICE (f)), WINDOW_Y_SIZE (&DEVICE (f))));
1544    for (j = k; j >= 0; j--) {
1545      z = (REAL_T) j / (REAL_T) k;
1546      if (z < 0.2) {
1547        z = z / 0.2;
1548        frac = 0.5 * (1 + (cos (CONST_PI / 2 * z)));
1549      } else {
1550        z = (z - 0.2) / 0.8;
1551        frac = (1 - z) * 0.3;
1552      }
1553      (void) pl_color_r (plotter, (int) (frac * RED (&DEVICE (f)) * COLOUR_MAX), (int) (frac * GREEN (&DEVICE (f)) * COLOUR_MAX), (int) (frac * BLUE (&DEVICE (f)) * COLOUR_MAX));
1554      (void) pl_fcircle_r (plotter, VALUE (&x) * WINDOW_X_SIZE (&DEVICE (f)), VALUE (&y) * WINDOW_Y_SIZE (&DEVICE (f)), (REAL_T) j);
1555    }
1556    (void) pl_color_r (plotter, (int) (RED (&DEVICE (f)) * COLOUR_MAX), (int) (GREEN (&DEVICE (f)) * COLOUR_MAX), (int) (BLUE (&DEVICE (f)) * COLOUR_MAX));
1557    X_COORD (&DEVICE (f)) = VALUE (&x);
1558    Y_COORD (&DEVICE (f)) = VALUE (&y);
1559  }
1560  
1561  //! @brief PROC (REF FILE, CHAR, CHAR, STRING) VOID draw text
1562  
1563  void genie_draw_text (NODE_T * p)
1564  {
1565    A68_CHAR just_v, just_h;
1566    A68_REF txt, ref_file;
1567    A68_FILE *f;
1568    int size;
1569    A68_REF z_ref;
1570    char *z;
1571    plPlotter *plotter;
1572    POP_REF (p, &txt);
1573    POP_OBJECT (p, &just_v, A68_CHAR);
1574    POP_OBJECT (p, &just_h, A68_CHAR);
1575    POP_REF (p, &ref_file);
1576    CHECK_REF (p, ref_file, M_REF_FILE);
1577    f = FILE_DEREF (&ref_file);
1578    plotter = set_up_device (p, f);
1579    size = a68_string_size (p, txt);
1580    z_ref = heap_generator (p, M_C_STRING, 1 + size);
1581    z = DEREF (char, &z_ref);
1582    ASSERT (a_to_c_string (p, z, txt) != NO_TEXT);
1583    size = pl_alabel_r (plotter, VALUE (&just_h), VALUE (&just_v), z);
1584  }
1585  
1586  //! @brief PROC (REF FILE, STRING) VOID draw fontname
1587  
1588  void genie_draw_fontname (NODE_T * p)
1589  {
1590    A68_REF txt, ref_file;
1591    A68_FILE *f;
1592    int size;
1593    A68_REF z_ref;
1594    char *z;
1595    plPlotter *plotter;
1596    POP_REF (p, &txt);
1597    POP_REF (p, &ref_file);
1598    CHECK_REF (p, ref_file, M_REF_FILE);
1599    f = FILE_DEREF (&ref_file);
1600    plotter = set_up_device (p, f);
1601    size = a68_string_size (p, txt);
1602    z_ref = heap_generator (p, M_C_STRING, 1 + size);
1603    z = DEREF (char, &z_ref);
1604    ASSERT (a_to_c_string (p, z, txt) != NO_TEXT);
1605    (void) pl_fontname_r (plotter, z);
1606  }
1607  
1608  //! @brief PROC (REF FILE, INT) VOID draw fontsize
1609  
1610  void genie_draw_fontsize (NODE_T * p)
1611  {
1612    A68_INT size;
1613    A68_REF ref_file;
1614    A68_FILE *f;
1615    plPlotter *plotter;
1616    POP_OBJECT (p, &size, A68_INT);
1617    POP_REF (p, &ref_file);
1618    CHECK_REF (p, ref_file, M_REF_FILE);
1619    f = FILE_DEREF (&ref_file);
1620    plotter = set_up_device (p, f);
1621    (void) pl_fontsize_r (plotter, (int) VALUE (&size));
1622  }
1623  
1624  //! @brief PROC (REF FILE, INT) VOID draw textangle
1625  
1626  void genie_draw_textangle (NODE_T * p)
1627  {
1628    A68_INT angle;
1629    A68_REF ref_file;
1630    A68_FILE *f;
1631    plPlotter *plotter;
1632    POP_OBJECT (p, &angle, A68_INT);
1633    POP_REF (p, &ref_file);
1634    CHECK_REF (p, ref_file, M_REF_FILE);
1635    f = FILE_DEREF (&ref_file);
1636    plotter = set_up_device (p, f);
1637    (void) pl_textangle_r (plotter, (int) VALUE (&angle));
1638  }
1639  
1640  #endif