Open Collections

UBC Theses and Dissertations

UBC Theses Logo

UBC Theses and Dissertations

A graphical extension for Pascal based on the Graphical Kernel System Starr, Cynthia Louise 1987

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Item Metadata

Download

Media
831-UBC_1988_A6_7 S72.pdf [ 4.68MB ]
Metadata
JSON: 831-1.0051949.json
JSON-LD: 831-1.0051949-ld.json
RDF/XML (Pretty): 831-1.0051949-rdf.xml
RDF/JSON: 831-1.0051949-rdf.json
Turtle: 831-1.0051949-turtle.txt
N-Triples: 831-1.0051949-rdf-ntriples.txt
Original Record: 831-1.0051949-source.json
Full Text
831-1.0051949-fulltext.txt
Citation
831-1.0051949.ris

Full Text

A GRAPHICAL EXTENSION FOR PASCAL BASED ON T H E GRAPHICAL K E R N E L SYSTEM By C Y N T H I A LOUISE S T A R R B.S., University of Kentucky, 1975 A THESIS S U B M I T T E D IN P A R T I A L F U L F I L L M E N T O F T H E REQUIREMENTS FOR T H E D E G R E E OF M A S T E R OF SCIENCE in T H E F A C U L T Y O F G R A D U A T E STUDIES ( D E P A R T M E N T O F C O M P U T E R SCIENCE)  We accept this thesis as conforming to the required standard  T H E U N I V E R S I T Y O F BRITISH C O L U M B I A December 1987 © C Y N T H I A L . S T A R R , 1987  In  presenting  degree freely  at  this  the  available  copying  of  department publication  of  in  partial  fulfilment  University  of  British  Columbia,  for  this or  thesis  reference  thesis by  this  for  his thesis  and  study.  scholarly  or for  her  of  financial  Computer Science  The University of British 1956 Main Mall Vancouver, Canada V6T  1Y3  Columbia  I further  purposes  gain  the  requirements  I agree  shall  that  agree  may  representatives.  permission.  Department  of  be  It not  is  that  the  Library  permission  granted  by  understood be  for  allowed  an  advanced  shall for  the that  without  make  it  extensive  head  of  my  copying  or  my  written  ii  Abstract  The  Graphical Kernel System (GKS), the first international standard in the area of  computer 1985.  graphics,  was  adopted  by  the  International  Standards  Organization in  The United Kingdom, France, Germany and the United States have also  adopted  GKS as  developing  a national  a high-level  standard.  graphical  This  extension  thesis examines to  the  feasibility  a general-purpose  of  programming  language based on the GKS standard.  Because  GKS was  awkward.  designed  a subroutine  system,  The subroutine call provides a low-level  graphical capabilities  EZ/GKS  as  is  a  programming with  mechanism for accessing  graphics  graphical  high-level  graphical  programming is  data  types.  graphical  expressions  and system-defined  constructed  from  elevated  Operations  structured  be  is the  standardized by GKS.  extension  to  the  implementing the functionality found in GKS level 2A. for  it  assignments,  any  of  in EZ/GKS  on  graphical  high-level  functions. the  Pascal/VS  The level of abstraction  through the data  types  graphical  use are  of  abstract  provided by  statements,  Complex user-defined  predefined  language  graphical  data types may  graphical data types  in  the  usual  manner provided by Pascal.  No  major syntactic  or semantic  and implementation of EZ/GKS. be elevated programming  successfully language.  difficulties  were encountered  during the  design  Thus, it appears that the GKS standard can indeed  to a high-level  graphical extension  of a general-purpose  iii  Table of Contents Abstract  ii  List of Figures  v  Acknowledgment Chapter  1  Introduction  1  1.1  The Problem  1  1.2  Goals  4  1.3  Contributions  6  1.3.1  GPL/I  7  1.3.2  MIRA  8  1.3.3  HL/GKS  1.4 Chapter 2  Chapter 3  Chapter 4  vii  Organization  10 11  Language Design  12  2.1  Contributions and Constraints of GKS  13  2.2  Contributions and Constraints of Pascal  16  Abstract Graphical Data Types  18  3.1  Individual Graphical Types  20  3.2  Compound Graphical Types  24  3.3  Summary  27  Operations on Graphical Data Types  29  4.1  Structured Graphical Assignments  29  4.2  Graphical Statement Types  33  4.2.1  Graphical Commands  34  4.2.2  Graphical State Changes  37  4.2.3  High-Level References to Workstation Tables  40  4.3  Graphical Expressions  43  4.4  System Defined Functions  45  4.5  Summary  45  iv  Chapter 5 Implementation  Chapter 6  47  5.1  Development of the Pre-Compiler  47  5.2  Translation Techniques  51  5.2.1  Simple Translation  51  5.2.2  Run-Time Library and Inquiry Functions  54  5.2.3  Translation of Attribute Values  55  5.2.4  Workstation Table Management  56  Conclusion  59  References  61  Appendix A - Syntax Specification for EZ/GKS  63  Appendix B - Attribute Data Types and Values  80  Appendix C - System Defined Functions  83  Appendix D - Example Programs  84  V  List of Figures  Figure  1  The Role of GKS  2  Figure  2  Layer Model of GKS Incorporating EZ/GKS  4  Figure  3  Example of Graphical Data Types in GPL/I with Related Operations  7  Figure  4  Example of Standard Procedures, Standard Functions and Standard Figure Types in MTRA  9  Figure  5  Translation of an EZ/GKS Program  12  Figure  6  Conceptual Access to Graphical Capabilities  13  Figure  7  Outline of the Concepts in GKS  16  Figure  8  Abstract Data Types in EZ/GKS  20  Figure  9  Colour Specification in EZ/GKS compared to the ACNS  23  Figure  10  Example of the Graphical Value Assignment  26  Figure  11  Output Primitive Types and their Compatible Bundle Attributes  27  Figure  12  Examples of Structured POINT Assignments  31  Figure  13  Examples of Structured NORMXFORM Assignments  32  Figure  14  Example of a Structured BUNDLE Assignment  32  Figure  15  Example of a Structured PATTERN Assignment  33  Figure  16  High-level Statements to Manipulate WKSTN and SEGMENT Variables  35  Figure  17  Example of Nested OUTPUT Commands  36  Figure  18  Examples of the TRANSFORM Statement  38  Figure  19  Example of me ASF, ATTRIBUTES and BUNDLE Statements  40  Figure  20  Examples of the SEND Statement  42  Figure  21  Examples of Graphical Expressions  44  vi  Figure  22  Factor Types for Segment Transformations  45  Figure  23  Simple Translation of an EZ/GKS Statement  52  Figure  24  Translation Generated by References to Workstation  Figure  25  and Segment Sets  53  Translation Generated to Set an Attribute Value  55  vii  Acknowledgment  I express my appreciation to Dr. G. F. Schrack for his unfailing guidance and encouragement throughout the course of this project. Thanks also to Dr. R. Woodham for his careful reading of this document. I thank Tektronics for their donation to the University of Plot-10 GKS. contribution allowed work on the GKS Pascal Binding to begin.  Their  I am grateful to the Computer Science Department for their financial support. I thank Sandra Litchfield, Reeta Tyagi and the staff of Discovery Day Care for their excellent child care. Without their help, this work would never have been completed. I give special thanks to my husband, Alec Hoon, for patiently waiting more than three years for me to complete this work. I also express my appreciation to Alec for his help proof-reading the numerous draft versions of this thesis.  1  Chapter 1  Introduction  1.1  The Problem  The Graphical Kernel System (GKS), the first international standard in the area of computer graphics, was adopted by the International Standards Organization (ISO) in 1985  [IS085a].  The United Kingdom, France, Germany and the United States  have also adopted GKS as a national standard.  This thesis examines the feasibility  of developing  to the Pascal/VS language  a high-level  graphical extension  based  on the GKS standard.  A system to support graphics programming may be developed by designing a new language or by enhancing the facilities of an existing host language. a new language  allows unlimited creative freedom in the language  development  an  of  extensive  significant  lead  time  for  capabilities  provided by  compiler  is  necessary,  implementation.  a new  customary programming tasks.  language  The usually  however,  non-geometric are not  When a graphics programming language  is based  many of the preceding problems are avoided.  chosen,  significantly  non-geometric  and  is  design.  The  resulting  in a  and  sufficient  arithmetic to  support  In addition, high training costs are incurred in a  production environment educating programmers in the use  the graphical extension  Developing  on an existing  and effort  arithmetic  functions  language.  host  Although the language  restricted by the characteristics  less time  of the  of the host  language, design of language  are required for implementation. are  automatically  inherited  from  All the  2  host  language.  The  programmers  the  A  system  graphics  specifics  subroutine  system  providing  graphical  system  to  required can  be  of  burden  The  of  the  accessing designed  into  at  language  added  or  costs  o f teaching  experienced  extension.  extension.  are  the  to  may  With the  transported. programs.  be  designed  a subroutine  run  time  No  separate  Most  either  system,  library,  application  subroutine  programs  allowing  systems  are  to  difficult  to  the use  errors  is  however for  extensive and  a  the  pre-compilation  programming  due  as  routines  run time, resulting i n a longer l e a d time necessary  standard  hardware  a  host  to  place  the  testing a  large  programmer.  these as  a  application  limited  graphical  a language  graphical  G K S graphics  functions  on  extended  practice,  are  the  capabilities  easily  In on  or as  detected  development  of  based  graphical  o n l y be  required.  t r a i n i n g costs  and  graphical subroutine  serves also  as  both a  capabilities system.  as  a  guideline  standardized, through  Although  device  software GKS  Graphical Applications  for  is  migrating  independent  (Figure easily  1).  extended  Graphical Devices  Figure 1 - The Role of GKS  graphical means  for  GKS  was  and  very  3  portable, programming with it can be lists  understand  and  mechanism  for accessing the graphical capabilities  alternative  difficult  maintain.  method  to  remember.  The subroutine calls with their  parameter  An  are  awkward.  The  standard  by which  The  resulting  subroutine  call  code  is  hard  to  provides  a  low-level  standardized by GKS.  a host language may  be extended is by  "the  definition of additional data types, expressions and statements not . . . found in the original  host  requires  the  language."  [GiEn72].  development  of  a  Implementation pre-compiler  or  of  a  graphical  compiler  extension  extension.  pre-compilation or extra compilation time is necessary during the development a  graphical  during  application  the  program.  pre-compilation  application  Many  phase,  programming  however,  reducing  errors the  can  be  testing  A of  detected  required  for  programs.  The most significant benefit of a language extension is its ease of use.  Given a  clean  standard  and  intuitive  programming while  language  language  can  syntax,  increase  reducing training costs.  development  is thereby reduced.  high  graphical  level  the  the  graphical  productivity  extension of  graphics  extension running in  The readable source code generated can  also  cut  cost  of  Pascal was  selected as the host language for this high-level  on wide acceptance in the  extension.  a production  the  programs  the language itself.  a  programmers  The lead time necessary for application program  application  based  to  academic  by using a  maintenance  for  environment.  community  graphical extension  and on characteristics  of  Pascal is an excellent language on which to base a graphical  The strong typing of Pascal aids in error detection while allowing the  programmer to define new and more complex graphical data types.  The use of a  4  block structure clearly depicts the scope of commands. allocation  mechanism  program execution.  allows data structures  The dynamic storage  to expand  All of these capabilities  as needed  assisted with the  throughout design and  implementation of EZ/GKS.  1.2  Goals  EZ/GKS is a high-level graphical extension to Pascal which provides access to the GKS  subroutine  system  via  graphical  data  types  and high-level  statements embedded within an ordinary Pascal program.  graphical  The major goal of  EZ/GKS is to provide a high-level language support for graphics programming, easing the burden imposed on the programmer by the GKS subroutine system.  To  achieve this goal, the Pascal language has been extended by adding graphical data types  and high-level  graphical statements not The  (Figure  individual  application programs and for the application-oriented layer  graphical  may  provide  extension  found  language  application-oriented  2).  originally provides  modeling,  support  charting  Application Program Application Oriented Layer (modeling) EZ/GKS High -level Language Extension J i  La ng uage De pe nde nt La ye r  (Pascal)  Graphical Kernel System Operating System  Other Resources  Graphical Resources  Figure 2 - Layer Model of GKS Incorporating EZ/GKS  in the host for  layer. or  both The  windowing  5  sub-systems specifically useful to certain application programs. application specific general  As in GKS, all  functions have been excluded from EZ/GKS, resulting in a  purpose graphical extension.  EZ/GKS  is a graphical extension to the Pascal/VS language  functionality found in level 2a of GKS.  implementing the  Level 2a includes basic segmentation with  full output and Workstation Independent Segment Storage (WISS), but excludes all forms of graphical input.  The  language design  provides easy-to-use graphical  statements integrated with ordinary Pascal statements. graphical  statements is  allowing  a natural  concepts  from Pascal  Much of the syntax of the  consistent with that of the  representation are  familiar  applied in the  to  regular Pascal  language,  Pascal  programmers.  context of  graphical  including records, arrays, linked lists, sets and assignment statements. time restrictions, the inquiry, error and metafile  Many  operations, Due to  functions have been excluded  from the scope of this project.  The seven major goals of the EZ/GKS language design are to:  1.  Elevate the GKS subroutine system to Pascal/VS  language  in order to  a high-level  simplify  extension of the  graphics programming using  GKS.  2.  Provide  high-level language statements useful in graphical applications,  allowing the programmer to focus on concepts relating to the application rather than on the details of graphics programming.  3.  Maintain complete compatibility with the concepts of GKS.  6  4.  Maintain  the  relationships  full  functionality  between EZ/GKS  of  GKS  by  clearly  defining  and the GKS subroutine system,  the  allowing  both to be mixed compatibly within the same application program.  5.  Assist GKS,  6.  the  graphics  programmer in gradually learning the  lowering training costs for graphics programmers.  Assist  programmers  in  producing  reducing the lead time necessary  7.  concepts of  successful  to implement  graphics  programs,  graphical applications.  Produce clear graphics programs which are easy to read, understand and maintain.  These goals provided the basis for the decisions which governed the design of the EZ/GKS  1.3  The  graphical  extension.  Contributions  benefits derived from the use  longer  disputed.  have become the  of high-level  programming languages are no  High-level languages such as Fortran, Cobol, Pascal and PL/1 norm for developing non-graphical application programs.  utility of a graphical extension  to a general purpose programming language  recognized in 1968 when David Smith began the design for GPL/I [Smit71]. then many  researchers  have  studied the use  of high-level  to general purpose programming languages [McLe78]. GPL/I,  MIRA  and HL/GKS  discussion in the  graphical extensions have  following sections.  The was Since  graphical extensions  Of these contributions, the been  selected for further  7  1.3.1  GPL/I  GPL/I  was designed  The  design  graphical  of  output  the  as a graphical extension to the PL/I programming language. language  was  conceptually  machine  and  device  independent,  rather than in hardware specific  defining  commands.  To  accomplish this goal, GPL/I proposed the use of graphical data types to assist with the manipulation of graphical data.  Operations were provided on each data type  in the form of function calls (Figure 3).  The four graphical data types provided by GPL/I were VECTOR, IMAGE, INTERRUPT and GRAPHIC. origin The  and  was  represented  by  IMAGE data type contained  which  were  functions. either  A variable of data type VECTOR described a line radiating from the  derived  a two-dimensional  or  three-dimensional  point.  a combination of pictorial and attribute values  from V E C T O R  variables,  text  and the  result  of  IMAGE  An IMAGE variable, which could be any of PL/I's storage classes, was  structured or sequential.  Although the  internal structure  of  an IMAGE  variable could be quite complex, all details of the structure were hidden from the  VECTOR Data Type  IMAGE Data Type  magnitude vector product scalar product addition subtraction  incl u3ion connection positioning scaling rotation  Figure 3 - Example of Graphical Data Types i n GPL/I v i t h Related Operations  8  user.  The INTERRUPT data type was provided to control interrupts for graphical  input.  Finally, the GRAPHIC data type allowed three types of graphical files to be  declared: DISPLAY, DESIGN and STORAGE.  Variables  of  these data types could be  assignment statements and expressions. OPEN,  O N , SIGNAL  permitted  by  the  included in GPL/I  defined  and manipulated  name  in  A number of PL/I statements, such as the  and PUT, were extended to  language  by  extension.  handle the  Additional high-level  graphical statement  were the T A K E , ERASE and ANIMATE statements.  options types  Although the  use of graphical data types in GPL/I was visionary, the high-level statement types provided  1.3.2  for graphical manipulation were minimal.  MIRA  MIRA, a graphical extension to the Pascal language, also provided the use of data types  and high-level  statements to  assist with graphics  programming [MaTh81].  MIRA provided two predefined graphical data types similar to the ones in GPL/I. In  addition,  hierarchical,  facilities user-defined  in  MIRA  graphical  permitted  the  programmer  to  construct  data types.  As with GPL/I, MIRA provided a VECTOR data type and a vector arithmetic for operating on variables of the VECTOR type.  The graphical statement CONNECT was  provided for connecting multiple VECTOR variables.  A structured data type FIGURE was also introduced. of  a FIGURE type was  definition  an  identifier  The syntax for the declaration  similar to that of a Pascal procedure, including in the name,  parameters,  local  declarations  and  instructions.  9  The  graphical statement INCLUDE permitted the inclusion of other FIGURE types  within the declaration of a complex figure,  allowing simple FIGURE types to be  used to build more complex data types in a hierarchical fashion.  Declaring variables to be of a particular FIGURE type did not create the graphical variable in MIRA.  The high-level CREATE statement dynamically created a new  FIGURE variable while the D E L E T E statement destroyed it.  The DRAW statement  output the FIGURE variable to a graphical device.  As in GPL/I, MIRA provided standard procedures and functions to operate on the graphical variables (Figure  4A & 4B).  also provided by the system  Several standard FIGURE types which were  could be included in more complex  FIGURE type  declarations (Figure 4C).  The  designers of GPL/I and MIRA were at a disadvantage, for the basic graphical  programming functions  were not standardized until  was adopted by the ISO. The GKS standard defined  A. Standard Procedures symmetry translation rotation homothety union  B. Standard Functions angle intersection centre distance  1985 a  when the GKS system  common  terminology  C. Standard Figure T y p e 3 segment line circle square triangle  Figure 4 - Example of Standard Procedures, Standard Functions and Standard Figure T y p e 3 in MIRA  and a  10  methodological  1.3.3  GKS  framework  HL/GKS  was used as the foundation for a graphical extension  HL/GKS [Sun86]. GKS,  for computer graphics programming.  to the Fortran-77 in  The HL/GKS language extension adopted many of the concepts of  including workstations,  segments and transformations.  These concepts were  represented as graphical data types in the graphical extension.  A VECTOR data  type was also provided.  Graphical  variables could be defined  dimensional  arrays.  as either individual variables or as  High-level graphical statements such  as  SEND,  single  DISPLAY,  MESSAGE, REDRAW and ERASE provided operations on the graphical variables.  HL/GKS  made  many of  the  and  of  GKS transparent to  opening,  closing,  provided  for updating and partial deletion  specification  activating  details  deactivating  of attributes, transformations  of  workstations. segments after  the  user, including Facilities  closing.  were  Explicit  and output replaced the modal default  provided by GKS.  The  major disadvantage of HL/GKS is the inflexibility of the host language.  capability  for  defining  structures  of  non-homogeneous  elements  is  The  notably  absent from Fortran-77, as are the block structure and dynamic storage allocation mechanisms  found in most modern programming languages.  selected restricts the utility of the HL/GKS  graphical extension.  The host  language  11  1.4  Organization  Chapter  2  begins  by  examining  the  design  constraints  distinguish this work from that of its predecessors.  on  the  language  that  The constraints include those  imposed by the graphics subroutine system, GKS, and those imposed by the host language, Pascal.  The advantages derived from GKS and Pascal are also discussed.  Chapter 3 describes The  distinction  the graphical data types provided by the EZ/GKS  between  individual  and  compound  graphical  data  language. types  is  explained.  Chapter 4  presents  presented  in  graphical  statements,  Chapter  5  the  operations  Chapter 3.  discusses  which  Operations  characterize  include  graphical expressions  the  development  translation techniques it utilizes.  the  graphical data types  structured graphical  and system-defined  of  the  EZ/GKS  assignments,  functions.  pre-compiler  and  First, a simple translation is examined where a  high-level EZ/GKS statement is directly translated into a GKS subroutine call. use of the run time library and inquiry functions are described. for  handling attribute values  the  and high-level  references  The  Finally, methods  to workstation tables are  explained.  The  appendices  values  and  written in  contain details  system-defined  of the language  functions.  syntax,  data types of attribute  Example programs  EZ/GKS and GKS, producing identical output.  are  also provided  12  Chapter 2 Language Design  The goal of EZ/GKS is to provide access to the GKS subroutine system via graphical data types and high-level graphical statements integrated in an ordinary Pascal program.  The input to the EZ/GKS pre-processor is  a program containing  predefined graphical data types and high-level graphical statements (Figure 5). A Pascal program containing the necessary GKS subroutine calls is generated. this manner, the EZ/GKS language extension  conceptually allows  In  access to the  facilities of GKS through the use of high-level graphical statements (Figure 6). The use of a mixture of  high-level statements and GKS subroutine calls within the  same application program is not precluded, thereby allowing an EZ/GKS program access to the full functionality of GKS.  The following sections examine how the language design is constrained by both the subroutine system whose procedures it must access and by the host language in which i t is imbedded.  program !with graphical / statements  Finally, the benefits  EZ/GKS Pre-processor  derived from the host language are  / program -^/with GKS subr o u t i n e calls  Figure 5 - Translation of an EZ/GKS Program  13  B. Access provided by EZ/GKS  A. Access provided by GKS  Pascal program  Pascal program  (  • EZ/GKS: statements subroutine call  subroutine call \/ GKS subroutine system  GKS subroutine inej sustem  Figure 6 - Conceptual Access to Graphical Capabilities  discussed.  2.1  Contributions and Constraints of G K S  The benefits GKS  was  of a standard adopted  International  by  for computer graphics were recognized a decade  the  Federation  ISO  as  an  international  for  Information  standard.  Processing  In  before  1974,  (IFIP)  the  Graphics  Subcommittee W . G . 5.2 organized a committee to investigate standardization in the field  of  computer  graphics  [BoEn82].  As  a  result,  a  workshop  entitled  "Methodology in Computer Graphics"  was held in Seillac, France in May of 1976 to  investigate  the  underlying concepts  used  formulated  at  the  standards  Two  Seillac  subsequently  workshop  and  the  provided  a  graphics.  foundation  The for  the  principles graphics  developed.  underlying principles defined  portability  in computer  at the  differentiation  Seillac  between  workshop were  modeling  and  the  viewing  concept of functions  14  [Ende85].  The concept  application  programs,  different  of portability referred to the mobility graphical  installations,  configurations.  data  operating  and  graphics  systems,  and  Providing standardized interfaces  and to device drivers enhanced portability.  of graphical  programmers changing  between hardware  to both application programs  Modeling was defined as the process  of building a picture from component parts while viewing treated the picture as a whole.  The participants  functions  were  at the  application  Seillac  workshop  independent.  They  decided  that  determined  only that  viewing modeling  functions were application dependent and therefore should be excluded from any graphics  GKS  standardization  was chosen  efforts.  as the foundation for the high-level  Pascal/VS because of its acceptance graphics programming. of  graphical extension to  as the international standard for computer  Designed as a kernel system,  it provides the minimal set  functions necessary to access the capabilities of a wide range of graphical  devices in a device independent fashion [IS085a].  Consistent with the principles  formulated at the Seillac workshop, GKS includes only the fundamental graphical operations  which are application independent.  aspects of modeling are excluded.  All but the most rudimentary  The set of functions defined by GKS provided a  foundation for graphics programming which has proved to be sufficient  for the  majority of graphical applications.  The design of EZ/GKS is compatible with the philosophy of GKS. predecessors,  EZ/GKS  excludes all but the basic  Unlike most of its  aspects of modeling.  philosophy behind the design of EZ/GKS is similar to that of GKS:  The  to include only  those aspects of graphics programming that are application independent.  The  designer believes that any application dependent facilities should be added to the  15  Application-Oriented Layer (Figure 2), of  all application dependent  graphical  Instead  is necessary  extension.  Exclusion  to produce a general purpose  extension.  of  provides  expanding  language  application-oriented Section  features  not to the language  3.1  the  basic  constructs  to  modeling assist  with  graphical software.  simplify  the  facilities the  provided by  design  manipulating  sets  of  temporary storage  and SEGMENTSET  workstations  example,  the SEGMENTSET  concepts  such  as  the  and implementation  The graphical data types of  discussed  and segments  discussed  graphical data while  graphical statements assist with manipulation of the data. such as the WKSTNSET  G K S , EZ/GKS  in  filter  in Section 3.2 an intuitive  and exclusion  in  high-level  Compound data types  filter  assist with  manner.  primitive data type could be utilized to  inclusion  of  defined  For  implement in  PHIGS  [Brow85].  The  decision  to  base  the  design  of  a  graphical  extension  on  subroutine system constrains the design of the language extension the preexisting must  be  specified  subroutine  provided  by  the  system defines high-level  7).  preexisting  twofold.  First,  the minimal graphical facilities  which  language.  The  functions  available  are  in detail by the subroutine system, but the methods for providing them  are left to the discretion of the language designer. implicitly  a  Second, the subroutine system  defines concepts which are an integral part of its philosophy (Figure  The underlying concepts and philosophy of the subroutine system must be  reflected in the design of the high-level language based upon it.  16  1. Workstations 1.1 Control Functions 1.2 Modal Settings  3. Output Primitives 3.1 Workstation I ndependent Attri butes 3.2 Workstation Dependent Attributes  2. Segments 2.1 Manipulation 2.2 Attributes 2.3 Transformations  4. Transformations 4.1 Normalization Transformations 4.2 Workstation Transformations  Figure 7 - Outline of the Concepts in GKS  2.2  Contributions and Constraints of Pascal  The  host  language  chosen  for  framework  within which the  framework  defines  the  a graphical  language  manner in  language are specified by the user. should  be  consistent language  orthogonal to  the  with that of the to  easily  extend  host host,  extension  extension  which  the  delineates  the  must function. features  syntactic  The syntactic  provided  by  the  host  The syntax design for a language extension language.  The style  should be internally  allowing programmers proficient in the  their knowledge  to  encompass  the  new  host  capabilities  added by the language extension.  The  host  philosophy  language  also  and design.  restricts the language For example  separately must be defined in segments. and  extension  in Pascal/VS,  by its  modules  basic structure, to  Communication between Pascal segments  the main program is restricted to parameters passed to the procedures and  functions declared therein and to variables defined as D E F or REF. are  be compiled  All variables  restricted to the static scoping and strong typing rules of the host language.  17 Executable  statements exist within a block structured environment that  provides  the foundation for Pascal programs.  Pascal/VS  provides  a rich set  extension to the language. security  of  range  nonhomogeneous multidimensional  ENUMERATION and SUBRANGE data types provide the  checking data  of abstract data types that are inherited by any  on  types  the  can  base  be  type  declared  arrays or in linked lists.  INTEGER. and  used  Typed pointers  as  RECORDS  of  elements  in  along with  Pascal's  dynamic storage allocation statements provide security over list processing.  The  SET data type, representing a combination of values from any scalar base type, is provided along with mathematical set difference. language  Pascal/VS extension. Pascal  operations  such as union, intersection and  All of these features are inherited when Pascal is selected as the host for a graphical  provides the  extension.  syntactic  Complex data types  types  graphical  types  structures  or linked lists.  to  design  of the EZ/GKS graphical  can be built from the predefined graphical types,  and user-defined  allowing  base for the  types be  in the  elements  usual in  manner provided by Pascal,  multidimensional  arrays, record  Declaration of graphical variables is compatible with  the declaration of other Pascal types, allowing them to be declared as VAR, STATIC, DEF or REF.  The scope of EZ/GKS statements  is comparable to that of statements in  Pascal, requiring the BEGIN END block notation when encompassing more than a single  statement.  The syntactic  structure of Pascal provides a sound foundation  on which to base EZ/GKS graphical extension.  18  Chapter 3  Abstract Graphical Data Types  The  solution  from  an  to  a problem may become  appropriate level  of  apparent when  abstraction  [Pres82].  abstraction, all of the procedural details are evident. shifts to the essential disregarded.  Viewing  permits alternative problem  elements of the problem; the  solutions  environment  problem  from  an  examining the problem  At the  lowest  level  of  At higher levels, the focus  irrelevant low level details are appropriate  level  of  abstraction  to be examined in terms that are meaningful to the  [Dyme84].  Regarding solutions  in meaningful  terms  can  a very  low  assist in determining the best one for the problem.  Early  graphics programming systems viewed  graphical concepts  level  of  generated  abstraction.  Graphical  output  PEN-UP and PEN-DOWN commands. device-dependent  by  by numerous  MOVE-TO,  All attributes were specified individually in a  manner.  During the past decade, abstraction  was  at  research in computer graphics has elevated  introducing  such  segments and attribute bundles. attending to tedious  concepts  as  output  primitives,  workstations,  Graphics programming, however,  still  detail at a much lower level of abstraction.  while the language bindings for GKS define  the level of  requires  For example,  a multitude of data types describing  the parameters passed in GKS subroutine calls, no operations on the data types are provided. for  Therefore, the  only operations  available are the  low-level  the general purpose data types provided by the host language,  focus  on the  conceptual  internal representation  use.  The following  of the  two  operations  directing the  graphical types rather than on their  chapters  describe  methods  by  which  the  19  EZ/GKS  graphical  programming,  thereby  application-oriented the EZ/GKS  extension  elevates  the  the  burden  easing  graphical software.  level  of  of  abstraction  developing  for  graphics  application  The graphical data types  and  provided by  language are described in the remainder of this chapter.  Chapter 4  provides details of the operations available for the graphical data types.  Abstract  data  types  have  long  been  recognized  organizing and manipulating graphical data.  as  a  useful  construct  An abstract data type represents  for a  class of abstract objects and explicitly defines all operations possible on members of the class.  Accessing a member of the class by any other means is not permitted.  Mallgren defined the term abstract data type as [Mall82]: ... a data type that provide(s) a particular well-defined level of abstraction: The semantics of the operations are considered characteristic, and objects are taken as atomic; the implementation of the operations and the representation of the objects are considered irrelevant.  An  abstract  graphical data  type  in  EZ/GKS  may  classified  an  languages,  a data type in EZ/GKS does not represent a geometric shape such as a  element  representing  a  Instead,  well-defined  an individual graphical type concept  useful  such as a segment, window or colour (Figure 8A). represents  developed  either  or a compound type.  square or triangle.  previously  as  individual  circle,  Unlike many  be  in  is  graphical  an atomic  graphics programming,  A compound graphical type  either a set or a sequence of individual graphical elements which can  be referenced and manipulated as a unit (Figure 8B).  With the exception  of the workstation constant,  may be constructed from any of the predefined  complex  user-defined  graphical data types,  data types in the usual  20  B. Compound Data Types  A. Individual Data Types  POINT WKSTN SEGMENT WINDOW COLOUR SEGXFORM  POLYPOINT WKSTNSET SEGMENTSET NORMXFORM PATTERN BUNDLE  Figure 8 - Abstract Data Types i n EZ/GKS  manner  provided  by  Pascal.  Graphical  multidimensional  arrays, record structures  elements within  a complex  Pascal  path  notation.  structure  The  types  may  or linked lists.  may  be  characteristics  addressed of  the  be  elements  of  The atomic graphical by  using  individual  the  and  standard compound  graphical data types of the EZ/GKS system are portrayed in the following sections.  3.1  Individual Graphical Types  The individual data types provided by EZ/GKS are the POINT, workstation (WKSTN), SEGMENT, WINDOW, COLOUR and segment transformation (SEGXFORM). these data types have For  example,  point  many  or vector  proved useful  high-level  in previous  graphical language  graphical languages have  [Smit71] [MaTh81].  In  addition to  the  Several of extensions.  a representation vector  type,  for a  HL/GKS  represented the GKS concepts of workstation and segment as graphical data types [Sun86].  Colour was proposed as an abstract data type by Mallgren [Mall82].  The  individual data types provided by EZ/GKS incorporate these concepts as well as several  others.  21  The  point, a graphical element that identifies  the shape of graphical output primitives.  a location, is the basis for defining  Points in EZ/GKS may be represented by  a pair of numeric expressions, or by a point expression.  The variable of data type  POINT represents a location in the two-dimensional plane.  A POINT variable is  characterized by its absolute position with respect to the X and Y axes.  The  graphical data type WKSTN  workstation as defined providing physical  a "logical devices"  EZ/GKS,  by GKS. interface  the concept of an abstract graphical  The GKS workstation is  through which  [IS085a].  workstations  represents  Unlike  are defined  all other  the  device  independent,  application program controls  graphical data types  as Pascal structured constants.  defined in  Each one  is  associated with a particular file and device type which may not be altered during the execution of the program.  A  segment  in GKS represents  "a collection  manipulated as a unit" [IS085a]. concept defined in GKS. units. the  body  from  the  may  be  The  display  elements  that  can be  EZ/GKS maintains compatibility with the segment  Thus, SEGMENT  variables are handled as autonomous  A segment is created by defining a sequence of output primitives within of  representation  by  of  the  can not be  original segment. changed  altering the  WINDOW  aligned  high-level  with the  CREATE  statement.  altered with operations  Once that  The appearance of the  geometrically  by  applying segment  created,  the internal  add or delete primitives graphical output, transformations  however,  or visibly  segment's attributes.  data  type  represents  coordinate axes.  a  generalized  two-dimensional  A window variable may  represent  window, viewport, workstation window or workstation viewport in EZ/GKS.  rectangle either a Which  22  of  these the variable represents  graphical World  statement.  Coordinates  is determined by its context within a high-level  Window variables (WC), while  those  representing  a window  representing  are defined  a viewport  or  in  workstation  window are described in Normalized Device Coordinates (NDC).  Window variables  representing  user  a  workstation  viewport  are  defined  by  the  in  Device  Coordinates (DC).  Normalization different  and workstation  coordinate  spaces  transformations  (eg.,  W C ->  describe  NDC ->  a mapping between  DC).  In  EZ/GKS  the  these  transformations are described by a mapping between a pair of window variables, each  of  which  defines  a  rectangular  region  in  a different  coordinate  space  (Section 4.2.2).  In  GKS colour values  are defined  in terms of the RGB colour model.  subroutine calls are issued to store the necessary colour table specified table  of each workstation.  by the  containing  integer the  index  desired  GKS  colour values in the workstation  The colour attribute of output primitives is  referencing colour  the  value.  entry of the Hence,  the  workstation programmer  colour must  remember the current status of all workstation colour tables in order to select the desired index.  EZ/GKS attributes  provides the data type COLOUR to elevate the method by which colour are managed by the application programmer.  represents what the name implies.  The COLOUR  A limited number of system constants of data  type COLOUR are predefined by the EZ/GKS system (Figure 9A). system such as the Artist's Colour Naming System addition  to  EZ/GKS,  as  data type  it provides  a  (ACNS)  natural representation  Incorporation of a would be a useful for a  much broader  23  B. Example of ACNS Colours  A. EZ/GKS Colour Constants  RED  YELLOW  GREEN  MAGENTA  BLUE  CYAN  BLACK  WHITE  BRILLIANT ORANGE-YELLOW PALE B L U I S H - G R E E N BLACKISH BLUE DEEP P U R P L E - R E D VERY LIGHT GREY DARK GREYISH ORANGE M E D I U M RED VIVID GREENISH-YELLOW  Figure 9 - Colour Specification i n EZ/GKS compared to the ACNS  range of colour constants [Kauf86] (Figure 9B). of  User-defined values for variables  data type COLOUR may also be computed from colour constants and colour  variables referencing tables  using to  a  graphical  workstation  are initialized  colour  tables  and altered  expression  elevates by  the  the  (Section manner  in  4.3). which  programmer (Section  High-level workstation  4.2.3).  Colour  variables may then be referenced by name in graphical statements to define  the  colour attribute for output primitives.  The shape of a graphical object defined by a series of points may be changed by applying a geometric transformation to each point defining the object.  Geometric  transformations are defined in [HeBa86] as: . . . procedures for calculating new coordinate positions for these points, as required by a specified change in size [.position] and orientation for the object.  In GKS, geometric transformations may only be applied to graphical objects stored in a segment.  The SEGXFORM data type in EZ/GKS provides a means for retaining  the specification of a geometric  segment transformation.  Values for variables of  type SEGXFORM are computed from segment transformation factors and previously  24  defined  segment  (Section  4.3).  3.2  transformation variables  using  a graphical segment  expression  Compound Graphical Types  Compound  graphical data types represent  graphical element.  multiple occurrences  of  an individual  A compound graphical type may be viewed as either a set or a  sequence of individual  graphical elements.  The compound types representing a  set of graphical elements are the workstation set (WKSTNSET) and the segment set (SEGMENTSET).  The POLYPOINT, normalization transformation  (NORMXPORM),  PATTERN and BUNDLE data types can be conceptualized as a sequence of individual graphical  elements.  The compound data types WKSTNSET and SEGMENTSET define a set of workstations or  segments respectively,  variables.  representing a number of selected individual graphical  A variable of type WKSTNSET contains a set of workstations to be  referenced as a unit in high-level graphical statements. type SEGMENTSET  Similarly, a variable of  refers to a set of segments to be manipulated simultaneously.  Values for variables of these data types are defined by assigning their related individual graphical type (ie.  WKSTN  standard  Expressions  Pascal  set-constructor  format.  variables of  or SEGMENT, resp.) of  workstation  in the sets  or  segment sets may compute a new set membership using any of the set operators defined by the host language. exclusive  The set operators union, intersection,  union and all relational set operators are inherited by the  difference, WKSTNSET  and SEGMENTSET data types.  A  series  of  points  are  frequently  used  to  portray the  shape  of  a graphical  25  primitive.  The POLYPOINT data type provided by EZ/GKS serves to retain the  information about a geometric shape. in  a  POLYPOINT  implementation. using the  variable,  A variable number of points may be stored  up  to  the  maximum  permitted  by  the GKS  A series of values may be assigned to a POLYPOINT variable  structured point assignment  (Section  Individual points may be  4.1).  assigned to or from a POLYPOINT variable using Pascal's usual indexed notation. When  an output  primitive command references  a POLYPOINT  variable without  indicating a subrange, all points through the maximum initialized value are used to generate  The  the graphical output primitive.  POLYPOINT value assignment  initialized (Figure  at compile time,  10).  assignments,  allows values for POLYPOINT variables to be  assisting  The POLYPOINT  with the  value  definition  assignment,  of non-uniform shapes  similar to  may appear within any Pascal/VS value declaration.  ordinary  value  Variables to be  initialized at compile time must be declared as Static or Ref variables.  The values  assigned in a POLYPOINT value assignment are numeric constants in the format of a  structured point assignment  concise  method  for  (Section  initializing the  4.1).  This  geometric  declaration form  shapes  of  provides a  asymmetric graphical  objects at compile time.  A  normalization  transformation  "maps  positions  normalized device coordinates " [IS085a].  in  the  world  coordinates  to  The NORMXFORM data type in EZ/GKS  retains the specification of a window-viewport mapping between the WC and NDC coordinate spaces.  The value of NORMXFORM variable is defined by describing a  mapping between two WINDOW variables, the first defining the window in WC and the  second  defining  transformation may be  the set  by  viewport naming  in a  NDC.  The  NORMXFORM  current variable  normalization in  a  high-level  26  Static Star : POLYPOINT; Yal ue Star := (0.95,-0.3; 0, 1; -0.95, -0.3; 0.95, 0.3; -0.95, 0.3; 0.95, -0.3); Figure 10 - Example of the Graphical Value Assignment  TRANSFORM NT statement (Section 4.2.2).  A pattern's value is defined in GKS as a two-dimensional matrix of integers which index the colour table of a workstation. of pattern values.  The workstation pattern table is an array  As with colours, a pattern is defined by a GKS subroutine call  that stores the pattern's value in the pattern table of a workstation.  The pattern  can  workstation  later be  pattern  selected  by  referencing  the  appropriate index  of  the  table.  In EZ/GKS the PATTERN data type representing a two-dimensional array of colours may be specified by either integer indices of the workstation colour table or by colour variables. depend question.  on the  The appearance of a pattern specified by a numeric index will colour values  stored  in the  colour table  of the  workstation in  A pattern specified by a colour variable will be composed of identical  colour values  on each  attribute of the fill  workstation on which it  is  displayed.  The style type  area output primitive may be described by referencing either  the desired PATTERN variable or the index of the pattern table entry in which it is stored.  An  output primitive attribute defines  a property of a particular type  of output  27  primitive  (eg.  geometric  or  affect  GKS  size  only  or  An  attributes  the  entry  of  data  in with  type  of  a the  associated  structured  bundle  assignment  in  high-level  3.3  Each  The  bundle  graphical  Attributes may  geometric  the  entire  primitive,  of a display  bundle  tables,  bundle  table  contains  related  with  primitive  contains one  simplifies  type  variable may  one  define  as  properties  non-geometric  for  values  either which  primitive  each for  type  all  of  output  non-geometric  type.  values  for  the  set  primitive  assignment be  classified  element.  o f output  the  be  attributes  four  BUNDLE  attributes  variable.  text).  appearance  primitive  bundle  or While  maintain  associated  variable  fill  shape  affect  workstations  primitive.  A  marker,  non-geometric.  the  attributes  line,  of  of  (Figure  attribute  subsequently  nongeometric  values  referenced  The  11).  as  to a  a  unit  statements.  Summary  g r a p h i c a l data  individual  type  presented  o r c o m p o u n d type.  i n this  chapter  A n individual  may  be  classified  g r a p h i c a l type  as  represents  LINE  MARKER  FILLAREA  TEXT  TYPE WIDTH COLOUR  TYPE SIZE COLOUR  INTERIOR STYLETYPE COLOUR  FONTPRECISION EXPANSION SPACING COLOUR  either an  Figure 11 -Output Primitive Types and their Compatible Bundle Attributes  an  atomic  28  concept  which provides  an abstraction  useful  in graphics programming.  A  compound graphical data type represents either a set or a sequence of atomic graphical elements which can be referenced and manipulated as a unit. 4 expounds  on the abstract graphical data types by describing the  EZ/GKS provides for variables of each graphical data type.  Chapter operations  29  Chapter 4  Operations on Graphical Data Types  A  high-level  language  characterizing variable's  an  abstract  current value.  high-level  statements  to  symbols  representing  operators  may  types.  A  be  Specific  through  may  the  variety  employ data  The  defined  of  assignments  promote  of  the  graphical expressions graphical attributes following  4.1  An  variables. output  by  provide variables. of  a  may  be  variables  be  operations  may with  alter  of  returned to  manner.  the the  a  additional  overloaded  of  graphical data types. abstract  High-level  graphical  defining  operations  a mechanism  extended  incorporated into E Z / G K S  structured format in which a series of values graphical  the  a predefined  containing may  define  statements  be  in  operators  been  abstract  encapsulation  to  The  or  new  new  data  programmer  functions.  have  the  may  variables  a variable  system-defined  on variables  syntax  expressions of  of these techniques  operations  language  for  methods  Assignment  language  characteristics  use  type.  manipulate host  several  graphical variable.  functions  These  values return  concepts  are  the  by  defining  the  generation  variables.  the  further  of  Graphical  for particular types to  a  to certain types of  control  graphical  for computing the  System-defined  types  may be assigned  on  specify  Structured graphical  graphical data  statements  to  user  of  specific  examined  in  the  type  is  sections.  Structured  essential  encapsulation.  Graphical  element  Assignments  necessary  for  Encapsulation restricts  implementing access  to  the  an  abstract  internal  data  representation  of  an  30  abstract type.  Mallgren defines encapsulation  in the following manner [Mall82]:  . . . the primary role of a data type specification is to make explicit the boundary between an abstraction and its implementation. An encapsulation "defends" this boundary by ensuring that programs cannot access the data type representation.  Structured graphical assignments allow a sequence of values to be assigned graphical  variable  in  assignments promote  a  single  assignment  encapsulation  statement.  by defining  a format  Structured  syntax  allows  the  programmer  graphical data types without knowledge type.  to  initialize  graphical  in which to specify  series of values to be assigned to certain types of graphical variables. high-level  to a  a  The use of  variables  of  of the internal representation  complex  of the data  Encapsulation of graphical data types is enforced by the use of structured  graphical assignments.  Access to individual components  except in the manner designated  by the high-level  of a graphical data type,  language  syntax,  is prohibited  by the EZ/GKS pre-compiler.  Four different graphical structures are defined in the syntax of EZ/GKS: the POINT structure, Although  NORMXFORM the  format  structure, of  each  BUNDLE structure  differs,  representative  of its related data abstraction.  Organization  and  manipulation  computer graphics.  point  data  is  and P A T T E R N the  a  syntax  for  fundamental  structure. each  is  operation  in  The POINT data type together with the point structure and  point expressions (Section in an intuitive manner. point elements.  of  structure  4.3)  assist the programmer in manipulating point data  A POINT structure defines a sequence of one or more  A point element may be either a point expression or a pair of  numerical Pascal expressions which define  the X and Y coordinates  of a point.  31  Both formats for point elements may be mixed within a point structure (Figure 12),  giving  the  programmer  a flexible  construct  for  defining  the  geometric  shapes of graphical objects.  A  point  WINDOW point  structure is  or POLYPOINT,  elements  describe  assignment-compatible  the  are  shape  present of  with variables  provided that the semantically in  output  the  structure.  of  POINT,  appropriate number of  The point  primitives directly  data type  structure  in output  may  also  primitive commands  such as LINE, MARKER and FILL (Section 4.2.1).  A  normalization transformation represents  World  a mapping from  a window  defined in  Coordinates (WC) to a viewport defined in Normalized Device Coordinates  (NDC).  The NORMXFORM structure defines a normalization transformation by the  mapping  between  two  WINDOW  variables  and may  variables of type NORMXFORM (Figure 13).  be  assigned  to graphical  The WINDOW variable referenced in  the FROM clause of a NORMXFORM structure is interpreted as a window defined in WC, while the variable referenced in the TO clause is interpreted as a viewport defined in NDC. If either  clause is  omitted, the  Var Max : REAL; UpperRight : POINT;  WCwindow FigureX  GKS default  of the  : WINDOW; : POLYPOINT;  Max := 1 2 . 5 ; UpperRight := ( 2 5 , Max * 2 ) ; WCwindow := ( ORIGIN FigureX  ;  UpperRight);  := ( 1 2 . 5 , M a x ; U p p e r R i g h t ; .  12.5 , ( M a x * 2 ) ; 2 5 , 12.5 ) ;  Figure 12 - Examples of S t r u c t u r e d POINT Assignments  unit square  is  32  VAR WCWindow, NDC Window : WINDOW; : NORMXFORM; NT1, NT2, NT3 NT1 := FROM WCWindow; NT 2 := TO NDC Window; NT3 := FROM WCWindow TO NDCWindow; Figure 13 - Examples of Structured NORMXFORM Assignments  assumed.  A  bundle structure, which may be assigned  high-level specific  syntax  for  defining  a set  type of output primitive.  attribute specifications  following  of  to a BUNDLE nongeometric  The B U N D L E a designated  variable, provides a  attributes  related  to  a  structure consists of a list of  output primitive type  (Figure  14).  Each attribute specification associates the kind of attribute (eg. type, size, spacing, etc.)  with an appropriate value.  The attributes defined in the structure must be  compatible with the named output primitive type (Figure 11). attribute's  value  depends  on  the  primitive type  and the  The data type of an attribute  (Appendix B).  Var Li neBundle : BUNDLE; LineBundle := LINE ( TYPE is 'DASHED'; WIDTH is 2.5 ; COLOUR is RED ); Figure 1 4 - Example of a Structured BUNDLE Assignment  kind  named  33  A pattern is a two-dimensional array of colours.  The pattern structure allows the  value  syntactically  of  pattern  variables  to  be  intrinsic property (Figure 15).  defined  by  representing  The pattern structure permits a list  colours to be assigned to a PATTERN variable.  this  of rows of  A colour may be represented by a  COLOUR variable, a COLOUR constant or by an index into the workstation colour table.  Any of these representations  pattern  4.2  structure.  Graphical  Graphical  Statement  therein.  EZ/GKS:  a user-friendly  of well-defined  Three categories of  graphical commands,  to workstation tables. and  Types  statements provide  data by performing a set named  for a colour may be mixed within a given  method  operations  environment  appearance elevate  of  the  the  changing  graphical data.  manner that  graphical variables  are  distinguished  the  global  in  references  how graphical data is defined  Graphical state changes alter the values  that  govern  High-level  references  to  workstation-dependent  attributes,  colours  are managed by the programmer. following  on the  graphical state changes and high-level  Graphical commands specify  by  manipulating graphical  graphical statements  determine where it is stored and displayed.  graphical  for  the  workstation and  final tables  patterns  Each of these categories are described in the  sections.  Var Checked : PATTERN; Checked := ( BLUE, BLUE, 2, 2; BLUE, BLUE, 2, 2; 2, 2, BLUE, BLUE; 2, 2, BLUE, BLUE); Figure 15 - Example of Structured PATTERN Assignment  34  4.2.1  Graphical  Graphical  commands  variables define  Commands  generate  representing  the geometric  output  workstations  and segments.  on  selected  and  manipulate  graphical  Output primitive  commands  properties of graphical output primitives and generate each  primitive in its distinctive manner. display  primitives  output  Workstation commands control the graphical  surfaces,  while  segment commands  provide for  the  creation, deletion, storage and display of graphical segments.  Output  primitive commands  primitives of GKS.  provide a simple  method  of  generating  the  output  The commands LINE, MARKER and FILL generate the GKS  Polyline, Polymarker and Fill Area primitives, respectively, defined by a polypoint variable or a point structure.  the shape of which is  The subrange  specification  may be used to restrict output to a subset of the points provided.  The T E X T  command defines  a high-level  syntax  within which the  location  and content  of  textual output may be described.  High-level  graphical  statements  provide  an  intuitive  mechanism  for  manipulating variables of type WKSTN  and SEGMENT.  provide  surfaces  (Figure  16A).  A  high-level  graphical  WKSTN  variables  may  also  manipulate  variables  control  statement  which  containing  over  display  operates  on  sets of workstation elements.  Workstation commands  When referencing  a variable of  type  WKSTNSET, the action specified is performed on each workstation in the set.  Segment  commands permit the definition of a segment and provide a means for  manipulating  a segment or set  of  segments.  Of the  segment statement types  (Figure 16B), the DELETE, SAVE and DISPLAY may also reference variables defined  35  B. SEGMENT Statement T y p e 3  A. W K S T N Statement Types  CREATE DELETE RENAME SAVE DISPLAY INSERT  OUTPUT MESSAGE CLEAR REDRAW UPDATE  Figure 16 - H i g h - l e v e l Statements to Manipulate W K S T N and SEGMENT Variables  as segment sets. As with workstation sets, the requested operation referencing a segment  set variable is performed once for each segment  regeneration  is temporarily disabled during a segment  set  in the set.  Implicit  operation, preventing  the display surface from being redrawn until the set operation is completed.  Graphical output may be generated causes defined.  either modally or explicitly.  Modal  output  display on all active workstations as the graphical primitives are being Explicit output displays a graphical segment after it has been defined.  GKS defaults to modal output.  In GKS the programmer is responsible for opening,  activating, deactivating and closing workstations at the required time in order to generate the desired output on each display surface.  Graphical commands in EZ/GKS modal or explicit output.  provide a simple manner for requesting either  In addition, the responsibility for opening, activating,  deactivating and closing workstations is assumed by the pre-compiler of EZ/GKS, thereby  easing the burden on the graphics programmer.  36  Modal output in EZ/GKS is generated by the OUTPUT statement.  The ONLY option  restricts the destination workstations to those named in the command. option generates workstations  The ALSO  output on those named in the command in addition to the  that  are  currently  active.  The  necessary  automatically activated and deactivated when an OUTPUT entered and restored upon exiting the block.  workstations statement  are  block is  OUTPUT statements may be nested  within the compound statement of other OUTPUT statements in the usual Pascal manner, providing a high-level mechanism for controlling output displayed on multiple workstations (Figure 17).  Explicit output allows named segments to be displayed on specified workstations. To provide explicit access in EZ/GKS, all segments created are automatically stored in Workstation Independent Segment Storage (WISS) [Sun86], unless directed by the modal OUTPUT statement.  otherwise  Segments or sets of segments stored in  WISS can be temporarily displayed on any workstation or set of workstations using a DISPLAY  command.  Such segments are erased when the workstation's  display surface is regenerated.  Furthermore, segments may be copied from WISS  into the local storage  of a  workstation,  Workstation Dependent Segment  Var ClassA, Teacher A : WKSTNSET; OUTPUT ON Clas3A ALSO Begin NextProblem ( P r o b l e m N b r ) ; OUTPUT ON TeacherA ONLY NextAnswer (ProblemNbr) End;  { display the next problem ) { display the related answer }  Figure 17 - Example of Nested OUTPUT Commands i  Storage  37  (WDSS), using a S A V E command.  All visible segments saved in a workstation's  WDSS are permanently displayed on the its output surface and are redrawn each time the display surface is regenerated.  The D E L E T E statement allows the named  segment(s) to be removed from a workstation's WDSS.  The DISPLAY and SAVE  commands provide explicit output by naming the segment(s) to be displayed and the workstation(s)  4.2.2  Graphical  Graphical  on which they are to be shown.  State Changes  state changes alter the  graphical environment by changing the global  state of GKS or by altering the state of individual workstations or segments. state of GKS, workstations graphical  output  is  The  and segments in turn determine the manner in which  displayed  by  defining  transformations,  attributes  and other  settings that govern its final appearance.  A  unique state change  operator has been  created to  changes from ordinary Pascal and EZ/GKS  commands.  "<-" and can be read as "is set to". transformations,  attributes  and  distinguish  graphical state  The operator's symbol is  Statements using the state change operator set  miscellaneous  other  global  graphical  variables  used by GKS.  Three the  kinds  of  transformations  normalization  transformation.  alter the  transformation,  final  workstation  appearance  of  graphical output:  transformation  All three kinds are set using the TRANSFORM  and  segment  statement (Figure  18).  The  reserved word NT is an abbreviated reference to the current Normalization  38  Transformation in EZ/GKS.  A TRANSFORM NT statement sets the current window  and viewport by naming a NORMXFORM variable which is initialized to the desired window-viewport setting  the  several  mapping (Figure 18A).  current  A simple method is thus provided for  normalization transformation  normalization  transformation  by  variables  selecting  defined  one  in  of  an  possibly  application  program.  The  TRANSFORM statement referencing a workstation or workstation set variable  defines  a new  workstation  window  and workstation viewport  for the  respective  device(s) using syntax similar to the NORMXFORM structure (Figure 18B). window specified  variable in NDC.  identified  in  the  FROM  clause  is  the  workstation  The variable identified in the TO clause  The  window  is the workstation  viewport in device coordinates (DC).  Finally, the TRANSFORM statement referencing a segment or segment set variable applies a segment transformation to the segment(s) named (Figure 18C). segment set variable is referenced, implicit regeneration is disabled  VAR NT1 NORMXFORM; PlanSize : SEGXFORM; Zoom, Show : WINDOW; :  F l o o r P l a n : SEGMENTSET; Planners : WKSTNSET;  A. N o r m a l i z a t i o n T r a n s f o r m a t i o n TRANSFORM NT <- N T 1 ; B. W o r k s t a t i o n T r a n s f o r m a t i o n TRANSFORM P l a n n e r s <- FROM Zoom TO Show; C. Seg me nt T ra nsfo r mati o n TRANSFORM F l o o r P l a n <- P l a n S i z e ; Figure 18 - Examples of the TRANSFORM Statement  When a  until the  set  39  operation is complete, surface  is  allowing all segments to be transformed before the display  regenerated.  GKS maintains a set of thirteen aspect source flags (ASF's), one for each kind of nongeometric  primitive attribute.  At the time an output primitive is  generated,  the ASF determines the source from which the value for each attribute will be obtained.  If the  ASF indicates  INDIVIDUAL,  the value  individual attribute stored in the GKS state list. similar as possible on all workstations. obtained from a bundle table  is  obtained from the  Individual attributes appear as  If the ASF indicates BUNDLED, the value is  entry in the  workstation.  The appearance  of a  bundled attribute may differ from workstation to workstation.  In  G K S , the ASF's  subroutine call.  are maintained in a single  array and are set  by a single  In EZ/GKS, the aspect source flags relating to a primitive type  may be set using the ASF statement (Figure 19A).  An optional EXCEPT clause allows  specific attribute types to be excluded, implicitly setting their ASF opposite to the value named.  ASF's for other primitive types, not named in the statement remain  unchanged.  The  ATTRIBUTES  statement  defines  primitive attributes (Figure 19B).  segment  Segment  attributes  attributes  as  well  as individual  are altered by referencing  a segment or segment set variable in an ATTRIBUTES statement followed by a list of  segment  attribute  attributes  may  containing  the  be  kinds, each  specified  desired  in  attribute  with two  values  format similar to a BUNDLE structure. attribute  types  listed  in  an  its  related  ways:  by  or by  value.  Individual primitive  referencing  listing  the  a bundle  attribute  variable  values  in a  Unlike the BUNDLE structure, however, the  ATTRIBUTES  statement may  be either  geometric  or  40  A. ASF Statement ASF of Line <- individual  EXCEPT Colour;  B. ATTRIBUTES Statement ATTRIBUTES of Line <- (Type IS "DOTTED"; W i d t h IS 2 . 0 ) ;  C. BUNDLE Statement BUNDLE of Line <- 2 ;  Figure 1 9 - Example of the A S F , ATTRIBUTES and BUNDLE Statements  nongeometric.  When the ASF of an output primitive attribute is BUNDLED, the appearance of the attribute  for  a primitive subsequently  defined  is  workstation  dependent.  The  value for the attribute is obtained from the appropriate workstation bundle table. The  current index designating the bundle table entry to be used is obtained from  the GKS state list.  In EZ/GKS, the entry of the workstation bundle table is selected  by the BUNDLE statement (Figure 19C).  The high-level FIND statement assists the  programmer in locating the desired bundle index (Section 4.2.3).  Other  miscellaneous  high-level  statements  defining  graphical state  changes  set  values  of  the value for the segment priority, deferral mode and clipping.  4.2.3  In  High-Level References  each  GKS workstation  workstation-dependent values.  The pattern  to Workstation Tables  capable  attributes. table  is  of  output,  six  The colour table an array  of  tables is  retain the  an array  pattern values,  of RGB colour  each  of  which is  41  represented  by a two-dimensional  workstation colour table.  array of indices  referencing entries  The other four tables are bundle tables, one for each  type of output primitive, containing bundles of nongeometric attributes. bundle tables,  in the  In the  colours are also represented by an index into the workstation  colour table.  Although a GKS installation may predefine a limited number of values in the workstation tables, extending the number of values or customizing the tables for a particular application program requires considerable effort. be referenced must be defined by a GKS subroutine call.  Every table entry to Also, in order to select  the appropriate table index, the programmer must remember the current status of all  workstation tables.  EZ/GKS elevates the manner by which workstation tables are managed utilizing graphical  variables  variables  COLOUR,  and  high-level  PATTERN  graphical  and BUNDLE  initialized by structured graphical assignments. CHANGE,  FIND  statements. retain complex  The graphical attribute  values  The high-level statements STORE,  and RELEASE assist with manipulating and referencing the  workstation tables in a more friendly manner.  The STORE statement stores the value of COLOUR, PATTERN or BUNDLE variables in the appropriate workstation table(s).  Two forms of the STORE  statement are  provided: one names a list of variables to be sent to a single workstation set (Figure 20A) while the other defines a variable to be sent to each of several workstation sets (Figure 20B). If a  single workstation set is named, each variable's  value is stored in the same table entry in all workstations in the set. reference  to  the  variable's  name  will  be  interpreted  by  the  Subsequent  pre-compiler to  42  CONST Wk3tn1 = ( f i l e A , J u p i t e r 7 ) ; Wk3tn2 = ( f i l e B , T e k 4 0 2 7 ) ;  A.  SEND Red, B l u e , G r e e n TO W k s t n 2 ;  B.  SEND ( Red TO W k s t n l ; Blue TO W k s t n 2 ) ;  Figure 2 0 - Examples of the SEND Statement  reference  The  the  second  named.  appropriate workstation table  format  associates  a different  index.  variable  with  each  workstation  A workstation table index free on all workstations is selected.  stored in this  table  graphical variable.  entry in each workstation is  determined by  its  set  The value associated  Hence, all the variables named in a SEND statement of this  form may be associated with only one type of workstation table. In addition, the workstation sets named within a SEND statement may not intersect.  The  FIND statement assists with finding a particular index for a workstation table  entry, permitting the programmer to recall the current status of the workstation tables.  For example, the statement "FIND index FOR red ON Wkstnl; blue ON  Wkstn2" would set  the variable named "index" to the colour table entry having  RED in Wkstn2 and BLUE in Wkstn2.  If the requested combination of values is not  located in the named workstations, the value of zero is returned.  After one or more SEND statements have been issued to store a graphical variable in  workstation tables,  a C H A N G E statement may be used to change the values  43  stored.  The CHANGE statement provides a high-level mechanism for changing the  values in workstation tables that were initialized by a SEND statement. CHANGE  statement defines  a new  value  When a  for a graphical variable, its value  is  changed in all workstation tables to which the graphical variable had been sent. The  CHANGE  workstation  The  statement provides  a concise  method  for altering the  values  tables.  RELEASE  workstations.  statement frees the variable named from the  indicated group of  When a variable is freed, the association between the variable and  the workstation table entries is broken.  The variable name then no longer may  be used to reference the workstation table entries to which it had been sent. value  in  in the  workstation  table  remains  unchanged  system for use in a subsequent SEND statement.  until  it  is  selected by  The the  When this index is selected for use  in another SEND statement, the old value in the table entry is replaced by the new one  defined.  The SEND, CHANGE, FIND and RELEASE statements elevate the workstation table manipulation initializing,  4.3  methods altering  Graphical  defined  by  and referencing  GKS,  assisting  workstation  the  programmer  with  tables.  Expressions  Expressions provide a means for calculating the value of a variable.  The values  for variables of the graphical data types POINT, COLOUR and SEGXFORM may be computed  using  graphical  expressions.  Factors in a POINT expression are variables of data  type POINT (Figure 21 A).  The  44  Pascal  operators  "+" and "-" have been  subtraction of point variables. Pascal: from left to right.  overloaded to permit addition and  The default order of evaluation is the same as  Like Pascal, any pair of factors may be parenthesized to  alter the order of evaluation.  The colour expression permits new colour values to be derived by conceptually mixing ratios of colour constants and previously defined (Figure 21B).  COLOUR variables  The ratio of colours to mix is specified using a "part" notation.  A  specification as "3 PARTS GREEN + 2 PARTS BLUE" defines a new colour value created by mixing the colours green and blue in a ratio of 3:2.  The colour  expression provides the programmer with a simple mechanism for defining new colour values.  The  segment transformation expression  accumulates  the composite  value of a  segment transformation by combining previously defined SEGXFORM variables and  segment  factors  allow  transformation specification  factors of  (Figure  uniform  or  21C).  Segment  differential  scaling,  translation, shearing and reflection in an easy manner (Figure 22).  Yar pointA, pointB, pointC : POINT; A. Point Expression  ( pointC + ( pointB - pointA ) )  B. Colour Expression  3 parts WHITE + 1 part RED  C. Segment Expression  ROTATE 45 ABOUT pointC + SHIFT ( 5 , 7 )  Figure 21 - Examples of Graphical Expressions  transformation rotation,  Any series of  45  SEGXFORM variables and segment transformation factors may be accumulated in a segment  4.4  transformation  System-Defined  System-defined to  the  functions  of  communication the  Functions  programmer  encapsulation  expression.  in EZ/GKS relay information about a graphical variable  (Appendix  abstract  with  the  data  in  the  entirely  within  internal the  types  by  defining  representation  EZ/GKS  system  the  an  channeled,  of graphical variables.  application programs using  4.5  System-defined  programmer is  internal representation  change  C).  of  will  also  interface  thereby  variables  require no  defend  through  avoiding  As a result,  graphical  and  functions  which  access  to  any subsequent can  change  be  handled  in graphical  system.  Summary  In summary, the operations structured expressions defend formats graphical  the  graphical and  described on graphical variables  assignments,  system-defined  encapsulation  in which to statements  of  define  functions.  abstract  initialize  high-level  graphical Structured  in EZ/GKS  statements, graphical  operations  on  graphical variables.  graphical  variables,  SCALE  ROTATE  SHIFT  SHEAR  REFLECT  IDENTITY  Figure 2 2 - Factor Types for Segment Transformations  graphical  assignments  graphical data types by defining  certain types of  include  structured High-level alter  the  46  graphical state and elevate the manner in which workstation tables are managed by the programmer.  Graphical expressions compute new values for certain types  of graphical variables, while information level  about  system-defined  a graphical variable.  functions Together,  return to the user these techniques  specific  elevate the  of abstraction necessary for graphics programming by hiding many of the  tedious details required in GKS programming.  47  Chapter 5  Implementation  5.1  Development of the EZ/GKS Pre-Compiler  The  EZ/GKS  appropriate high-level  pre-compiler is GKS  subroutine  graphical  a portable calls  statements.  output  consists  generated  Pascal  supporting  The  of  a listing  from A  statements defined in the EZ/GKS of  Pascal an  Pascal  program which  application  generates  program  program extended  containing  with graphical  syntax is the input for the pre-compiler. two  program including  files:  the  the  The  original input program and a  the  necessary  GKS subroutine  developed  with the  assistance of the  calls  and  code.  EZ/GKS  pre-compiler was  Top-Down  Compiler Writing System (CWS-TD) developed by Bochmann, Lecarme and Ward [ScCh86].  The CWS-TD  system generates a complete translator by analysing an  integrated description of an LL(1) language. the language  syntax by production rules specified  Semantic actions BNF.  CWS-TD  inserts  the  modifications  development  of  the  of  the  user-defined  semantic  interlaced within the  actions  into  the  generated  places.  CWS-TD  EZ/GKS  system  translator.  generation of the input file listing. names.  defines  in Backus Naur Form (BNF).  are described by sections of Pascal code  translator at the designated  Some  The integrated description  were Minor  necessary  to  modifications  facilitate  the  include  the  The underscore is now permitted in identifier  48  All identifiers handled in the CWS-TD  system are case sensitive.  Since the host  language used for EZ/GKS is case insensitive, all symbols read from the input file are changed to  lower case prior to being parsed by the translator.  reserved words and identifiers  used in EZ/GKS  Thus, all  appear to be case insensitive  as  well.  When  implementing  a  language  extension,  a  technique  distinguish between statements of the host language extension.  Graphical  statements  defined  by  the  must  be  used  to  and those of the graphical extension  require  translation  while statements of the host language should be copied unchanged to the file of generated code.  One method of identification is to recognize only those statements  which belong to the graphical extension, host language. statement  is  Graphical begun  with  assuming that all others belong to the  statements can easily a reserved  word that  be  identified  is  not  as  reserved  such if each by  the  host  language.  Two  problems arise when this method is used.  word in a graphical statement is mistyped.  One occurs when the first reserved As the translator does not recognize  the mistyped word, it assumes that the statement belongs to the host language, copying it verbatim to the file of translated code. when  the  symbol  terminating  a host  language  The second  statement  is  problem arises  omitted.  As the  missing terminator is not detected by the translator, more than one statement is copied to the output file, creating errors in the translated code if the following statement is a graphical statement in need of translation. can  be detected by the translator.  the  programmer.  Neither of these errors  Hence, no error message can be issued to warn  49  A  safer method for distinguishing statements of the host language from those of  the graphical extension is used in the language LIG [BuDi82]. statements and those of the graphical extension initial  reserved  word  in  each  statement.  In LIG, both host  are positively  Graphical  identified by the  statements  are  translated  while statements of the host language are copied without modification to the file of translated code. can  easily  Statements which do not belong to either the host or extension  be identified as errors, thereby preventing the first problem described  above.  For  assignment  statements, LIG examines  operator  to  determine  graphical  assignment.  whether  the  the  first  statement  is  character of a  The operator ":=" distinguishes  Pascal  deciding if an assignment  the  translator to the  assignment  assignment  or  a  Pascal assignments while  the operators "<-" and "<=" distinguish graphical assignments. for  the  statement is host or extension  The responsibility is thus shifted from  application programmer.  Although this method provides more security than the one previously described, it was not deemed adequate for the purposes of EZ/GKS.  If the symbol terminating  a host statement is omitted, the second problem described above will still occur. addition,  the  author believes  statements of translator, not  Because  Pascal  the  host  with  is  the  that  language  the  responsibility  and graphical extension  language  or to  the  should rest  between with  the  application programmer.  a strongly  typed  language,  benefits by being strongly typed as well. translator can easily  for distinguishing  In  determine  the  graphical  extension  By the data type of a variable, the  if an assignment  graphical extension.  EZ/GKS  statement belongs to the host  The data type  also  assists with  the  50  translation  of  graphical  statements  and  the  generation  of  meaningful  error  messages.  The  EZ/GKS  In so  doing,  problem By  translator parses both the host language and the graphical extension.  of  no  statements are ever  bypassing  an erroneous  flushed  to  the  output  statement without  file,  avoiding  the  warning the programmer.  parsing Pascal, the translator is able to derive the data types of all variables  declared.  Information  on the  data type  of  variables  referenced  statements is valuable throughout the translation of EZ/GKS  in  high-level  graphical statements.  In order to assist EZ/GKS with the task of echoing parsed host-language symbols to the output file, a modification was made to the CWS-TD  system.  A global boolean  flag has been defined to control the printing of the previous symbol parsed onto the file of generated code. copied to the output file. actions  of  the  host-language  The  final  When the flag is set, the previous symbol parsed is The flag is manipulated as needed within the  integrated  statements to  description,  providing  pass through the  modification to the CWS-TD  a  translator  mechanism  semantic  to  allow  unchanged.  system consists of the addition of three  global buffers used to accumulate groups of symbols to be referenced as a unit in the integrated description. in the buffers.  Variable references,  factors  and expressions are saved  Each buffer is controlled by a boolean flag which is manipulated  as needed from semantic actions within the integrated description. set,  symbols  subsequently  parsed be  are  referenced  appended  to  in semantic  code in the appropriate places.  the  related  actions  buffer.  and inserted  When a flag is The  into  buffer  the  can  generated  51  5.2  Translation Techniques  The  encapsulation of graphical data types is difficult to achieve when the Pascal  language  is  chosen  as  the  language  is strongly typed.  variable  declarations  host  As  previously  noted,  the  Pascal  Therefore, all data types referenced in constant and  must  Pointers are also typed.  language.  be  fully  described  in  the  data  type  declarations.  Thus, much of the implementation of graphical data types  is visible in the translated code.  The  designer of EZ/GKS  the  output  from  prevents  programmer  access to the implementation of graphical variables from within the  application's  source code. data  types  the  assumes that the application programmer does not alter  pre-processor.  The  pre-processor  To enforce the concept of encapsulation, the only use of graphical and  variables  permitted  to  the  application  expressly designated by the syntax of the EZ/GKS  5.2.1  those  language.  Simple Translation  EZ/GKS  begins  constant  and type  for  programmer are  translation  of  declarations  the GKS subroutine calls.  referenced  in  the  declaration  of  numerous  translator.  The  run-time library  application  external are also  an  application program by  together with the  external  including the GKS  procedure  declarations  The declarations for predefined graphical data types program  are  graphical variables procedure  subsequently reserved  declarations  for  for  generated internal  routines  in  use the  with  the  by  the  EZ/GKS  generated.  Upon entering the main program body of an EZ/GKS program, the GKS subroutine  52  calls to open GKS, open WISS and activate WISS are automatically generated.  In  addition, a call to GKS is generated to open each workstation which is declared as a workstation  constant  within the  Subsequent calls to activate  program.  and deactivate  workstations  are generated throughout  the program as implied by the high-level workstation commands. an  explicit  active,  SEND  EZ/GKS  statement  references  automatically  a  activates  workstation  it.  After  which the  For example, if is  not currently  segments  have  been  the  main  transmitted, the workstation is returned to its original state.  Workstations procedure.  are  automatically  deactivated  and closed  upon  leaving  GKS is subsequently closed.  Simple translation of a high-level statement into a GKS subroutine call is achieved using variables predefined by EZ/GKS actual  parameters  for  Frequently, assignment EZ/GKS variable.  the  and user-defined graphical variables as the  appropriate  GKS  subroutine  calls  (Figure  23).  statements are generated to assign values to a predefined  For example, when an  output primitive  command such  A. An EZ/GKS Statement CONST HomeWkstn = WKSTN ( 8 , T e k 4 0 2 7 ) MESSAGE "** E r r o r i n Input Data * *' to HomeWkstn; B. Generated Code CONST HomeWk3tn = 1; VAR GXVString : string; GXVString:= '* * E r r o r i n Input Data * *"; GMe3sageStr (HomeWkstn, length (GXVString), GXVString); Figure 23 - Simple Translation of an EZ/GKS Statement  as LINE,  53  MARKER or FILL is defined by a point structure, a statement is generated to assign each  expression  EZ/GKS  in the point structure to  array variable.  a sequential  element of a predefined  The array variable is subsequently  passed  as the actual  parameter of the GKS subroutine call generated by the translator.  The  graphical data types SEGMENTSET and WKSTNSET  designate  an  Translation  action  of  to  high-level  be  performed  statements  on  each  referencing  allow the programmer to  member  of  the  SEGMENTSET  set(s) named. or  WKSTNSET  variables require the GKS subroutine call to be generated within a FOR loop.  A  conditional statement within the loop allows execution of the GKS subroutine call if the loop variable is a member of the designated both a segment set  and workstation set  set.  Statements referencing  variable require the  generation  nested FOR loops (Figure 24).  A. An EZ/GKS Statement YAR BldgDesign: SEGMENTSET;  Planners: WKSTNSET;  DISPLAY BldgDesign TO P l a n n e r s ; B. Generated Code YAR BldgDesign: SEGMENTSET; GXYi, GXVj: INTEGER;  Planners: WKSTNSET;  FOR GXVi := 0 TO GXYMaxSetSize DO FOR GXVj := 0 TO GXCMaxSetSize DO IF (GXYi IN P l a n n e r s ) & (GXVj IN BldgDesign) THEN GCopySegWs ( G X Y i , G X V j ) ; Figure 2 4 - T r a n s l a t i o n Generated by References to W o r k s t a t i o n and Segment Sets  of  two  54  5.2.2  The  The Run-Time Library and Inquiry Functions  code  generated  in Figure  specified in Figure 24A.  24B  is  not  sufficient  to  accomplish the  If output is requested on a workstation that is inactive,  the action would not be visible on the workstation requested. workstation in the  set  action  allows  implicit regeneration, its  In addition, if a  display  surface may be  redrawn after the receipt of each segment.  The EZ/GKS repeatedly  run-time library  contains  procedures and functions  throughout the translated application program.  that  All routine  reserved for use by the translator begin with the prefix G X . library contains the user-accessible  are useful identifiers  In addition, the  routines defined in Appendix C.  At run time, the library is loaded with the object code of the application program. Procedures in the  run-time library  assist with translation by defining  interface  subroutine  for  (ie.  the  subroutine call is  call)  requesting  a complex  a simple  operation.  The  generated by the translator and is inserted into the generated  code whenever the complex operation is needed.  Routines in the run-time library  also serve to hide from the application programmer the data types, static variables and  implementation  details  of  the  procedures  and  functions  used  by  the  translator.  Many  procedures  determine  the  within  the  current state of  run-time  library  GKS and of  use the  GKS inquiry  individual  functions  workstations.  to For  example, the function GXWsSet calls a GKS inquiry function to obtain a list of the workstations currently active or open. and  returned to  the  caller.  The  The list is converted into a workstation set routine  GXSuppR  uses  the  set  of  active  55  workstations  returned  from  GXWsSet  and  issues  a GKS inquiry function  determine the deferral state of each workstation in the set. allowed, routine  a call is generated GXRestR  restores  to temporarily suppress  the  deferral state of  GXSuppR to its original state.  each  to  If the deferral state is  implicit regeneration. workstation  suppressed  The by  Procedures such as these in the run-time library  are called from the translated program to alter and restore the state of GKS and of the  individual  workstations  as  needed  throughout  the  translated  application  program.  5.2.3  Translation of Attribute Values  Attribute values enumerated  in the Pascal binding of GKS are specified  data  types  and integers  identifying  different  using a variety of  attribute  styles.  To  allow consistent specification of attribute values, the values for all attribute types having enumerated set EZ/GKS  (Appendix B).  attribute's  value  integer value. type  is  technique  are defined by string constants or variables in  The parameter to the GKS subroutine call defining the  a call  to  a function  in the  run-time library  returning an  The value returned by the function call is coerced into the data  appropriate for  strings  of values  allows  the  the  rather than  actual  parameter being  programmer to  integer  indicate  generated  attribute  (Figure  values  25).  using  This  mnemonic  values.  Upon initialization of an EZ/GKS program, a procedure in the run-time library is called to  read the  mnemonic  name,  value. Array  Attribute Value File.  context and integer  The Attribute Value File  value  for each  contains a  valid enumerated  attribute  Two arrays are created within the application program: the Context Limit and  the  Attribute Value Array.  The  Context  Limit  Array  defines  the  56  A. An EZ/GKS Statement ATTRIBUTES of FILL <- (INTERIOR i s  SOLID');  B. Generated Code G S e t F i l l l n t S t y l e ( G T I n t e r i o r (GXAtrVal ( G X Y A r r a y , GXVLimitArray [ 13]. min, G X Y L i m i t A r r a y [ 1 3 ] . max, 'SOLI D ' ) ) ) ;  Figure 2 5 - T r a n s l a t i o n Generated to Set an A t t r i b u t e Value i  beginning and ending indices within which the values for a given attribute type may  be found in the Attribute Value Array.  mnemonic names  When  representing attribute values  an attribute value  GXAtrVal  is  set  The Attribute Value Array stores the and an associated  by referencing  numeric value.  a particular string, the routine  in the run-time library is called to search for the string within the  appropriate context  limits.  If the string is found, the related value is returned.  Otherwise, a designated default value is returned.  The  Attribute Value File may be extended to include additional mnemonic names  for  the installation-dependent values of attributes such as line type, marker type,  font  and hatch  accommodate  5.2.4  style.  No  change  in  the  EZ/GKS  translator is  required to  additional attribute values.  Workstation Table  Workstation tables  Management  in GKS are addressed by an integer index.  The programmer  must recall the current status of the tables in order to specify  the index of the  57  desired colour, pattern or bundle entry.  EZ/GKS provides the high-level statements STORE, CHANGE, FIND and RELEASE to elevate  the  programmer.  manner  in  which  workstation  tables  are  referenced  High-level statements permit values to be specified  a colour, pattern or bundle variable. graphical variable, the  workstation  If an ambiguity  index  may be located  by  by  the  referencing  arises by referencing a with the  help of the  FIND command.  Management of workstation tables is accomplished through the use of one Master Workstation  Array  workstation table.  (MWA) and six  Index  Arrays  (IA),  one  for each  The M W A stores the union of all workstations  graphical variable has been sent and references an Index List. identifies  type  of  to which a  The Index List  the workstation table index used for each subset of workstations.  Each  entry of an IA stores the union of the workstations for which the related index is available.  The size of an IA is the same as the maximum size for the related type of  workstation  The  table.  Workstation Description Table in GKS stores the allowable  indices  for each type of workstation.  information  Inquiry functions  number of table  in EZ/GKS  access this  in order to appropriately initialize the IAs, thereby preventing any  indices out of range from being selected in a SEND statement.  Each variable of type colour, pattern or bundle has associated with it an index into the M W A .  If the  index  is zero, the variable's value has not been sent to a  workstation.  When a variable is first sent to a set of workstations,  an unused  entry in the M W A is selected and the index value is stored in the variable.  The  58  appropriate IA the set.  is searched to find the first index available on all workstations in  The workstation union is updated by the workstation set to indicate that  the index is in use.  The workstation set union is updated in the MWA and an Index  node is inserted in the list.  Processing for the RELEASE statement is the reverse of the SEND statement. node in the Index List is updated or deleted.  A  Workstations are removed from the  workstation set union stored in the MWA and the related IA.  When the value of a graphical variable is altered in an assignment statement, connection to  all table indices is broken.  associated MWA is designated as unused.  The Index  List is  deleted  the  and the  The workstation set union in the IA is  updated to show the new indices available and the value of the M W A index stored in the variable is reset to zero.  The  CHANGE statement updates the values in all workstations to which a variable  has been  stored.  The Index  List assists by identifying the index  which the variable's old value had been stored.  entry under  The value in each workstation in  the list is updated with the new value defined in the statement.  The  FIND  command  searches  graphical variables to locate  the  one  Index  index  Lists  associated  with  the  in common on all of the  When an available index is located, its is returned.  specified  workstations.  An index value of zero is  returned if no index is available on all of the designated workstations.  The  SEND,  CHANGE,  FIND  and R E L E A S E  programmer with the management  statements  of workstation tables.  assist  the  application  59 Chapter 6 Conclusion  This thesis has demonstrated the feasibility in  the  GKS  subroutine  general-purpose  to  a  programming language.  dependent  on  essentially  language  other  system  the  general  features  present  independent.  purpose  of elevating the functionality high-level  graphical  Although the  in  languages  of  concepts  Equivalent functionality  programming  extension  design  Pascal/VS, the  defined of  EZ/GKS  presented  a is are  could be provided in  with  varying  degrees  of  difficulty.  The  GKS subroutine  extension call  is  in  an interface  languages. one  being  system  has  relatively  the  advantage  language  mechanism  over  independent.  available  in most  a  high-level  The  general  standard  language subroutine  purpose programming  A particular procedure defined in GKS requires little alteration from  language  to another.  As a result,  a programmer proficient  in using GKS  through one language will have little trouble adapting this knowledge to use in a different  A  language.  high-level graphical extension  is more dependent  the features and facilities of the host language. a high-level from  one  benefits  disadvantage. required and use.  graphical extension  host  of  GKS  language  graphics  to  than a subroutine system on  As a result, an implementation of  providing similar functionality  another.  programming using  The author believes, a high-level  A high-level language extension  in GKS programming, making the  will  however,  language  vary more that  the  far exceed  this  is able to hide much of the detail high-level  language  easier  to learn  60  Despite efforts to do so, the objective of making EZ/GKS compatible with the host language has not been entirely accomplished.  For example, any Pascal data type  may be used to declare either constants or variables. data type  may only  be  used  to  declare  In EZ/GKS, the workstation  workstation  constants  while  graphical data types may be only used to declare graphical variables.  all  other  While the  ability to define certain types of graphical constants could be added to EZ/GKS, the semantics this  of the graphical types prohibits complete  regard.  In  practice,  this  minor  variation  compatibility with Pascal in should  pose  no  significant  difficulty.  Three areas related to this topic have not been considered within the scope of this project  and are prime candidates  error and metafile work.  functions  manner to  First,  the  inquiry,  of level 2A were excluded from the scope of this  While error and metafile  user-friendly  for further investigation.  handle  functions the  are areas of small concern, finding a  information accessible  through the  host of  inquiry functions provided by GKS is a significant issue.  Secondly, a method for handling GKS input functions associated with levels 2b and 2c  has not been  high-level revolutionize  addressed.  extension  to  interactive  The ability to manage a  general  graphics  purpose  graphical input through a  programming  language  could  programming.  Finally, a method for extending this work to encompass the new GKS-3D [IS085b] draft standard could also be considered.  61  References  [BoEn82]  Bono, Peter R., Jose L. Encarnacao, F. Robert A. Hopgood and Paul J. W. ten Hagen, "GKS - The First Graphics Standard," IEEE Computer Graphics & Applications, Vol. 2 (July 1982): 9-23.  [Brow85]  Brown, Maxine D., Understanding PHIGS, Megatek Corporation, San Diego, CA., 1985.  [BuDi82]  Burger, S., E. Dietrich and G. F. Schrack, "Development of a Preprocessor for the Pascal-extended Graphical Language LIG/P with the aid of Compiler/Compiler," in: W. Henhapl, Ed., GI-Fachgesprach, Munich, (1982): 120-154.  [Dyme84]  Dyment, Doug, CPSC 538B - Software Engineering Class Notes, University of British Columbia, Fall term, 1984.  [Ende85]  Enderle, Gunter, "Guest Editor's Introduction, Computer Graphics Standards," Computers & Graphics, Vol. 9 (No. 1,1985): 1-8.  [GiEn72]  Giloi, W.K., J. Encarancao and W. Kestner, "APL-G APL Extended for Graphics," ONLINE '72 International Conference on Online Interactive Computing, Uxbridge, England (Sept 1972): 579-599.  [HeBa86]  Hearn, Donald and M. Pauline Baker, Computer Graphics, Englewood Cliffs, NJ.: Prentice-Hall, 1986.  [IBM81 ]  Pascal/VS Language Reference Manual 2nd Ed., IBM Corporation, 1981.  [IS085a]  ISO DIS 7942, Graphical Kernel System Functional Description, Oct. 1985.  [IS085b]  ISO-DP 8805, GKS-3D Functional Description, March, 1985.  [Kauf86]  Kaufman, Arie, "Computer Artist's Colour Naming System," The Visual Computer, Vol. 2 (No. 4,1986): 255-260.  [Mall82]  Mallgren, William R., Formal Specification of Interactive Graphics Programming Languages, Cambridge, MA.: MIT Press, 1982.  [MaTh81]  Magnenat-Thalmann, Nadia and Daniel Thalmann, "A Graphical Pascal Extension Based on Graphical Types," Software: Practice & Experience, Vol. 11 (Jan., 1981): 53-61.  [McLe78]  McLean, M.J., "A Survey of Interactive Graphics Software," The Australian Computer Journal, Vol. 10 (Feb. 1978): 11-22.  Pressman, Roger S., Software Engineering: A Practitioner's Approach, New York, NY.: McGraw Hill, 1982. Smith, David N., "GPL/I - A PL/I Extension for Computer Graphics," Spring Joint Computer Conference, Atlantic City, NJ. (May 1971): 511-528. Sun, Hanqui, A High-Level Graphics Language Based on the Graphical Kernel System, M . A. Sc. Thesis, University of British Columbia, 1986. Schrack, G.F, Gordon Gheng, Harold Leung and Benjamin Yu, CWS-TD User's Manual 2nd ed., University of British Columbia, Department of Electrical Engineering, Feb. 1986.  63  Appendix A Syntax Specification for EZ/GKS Outline  I. n.  Modifications to Pascal syntax diagrams Declaration of graphical data types  III.  Graphical initialization  IV.  Structured graphical assignments  V.  High-level graphical statements A.  B.  C.  Graphical commands 1.  Workstation commands  2.  Output primitive commands  3.  Segment commands  Graphical State Changes 1.  Transformations  2.  Attribute specification  3.  Miscellaneous settings  High-level referencing to workstation tables  VI.  Graphical expressions  VII.  Summary of notation  64  I. Modifications to Pascal/VS Syntax Diagrams  1. Constant-del:  >{ constant expr ){ <workstation declaration> }-  -•CONST-  1*  2. Type-del  •TYPE-  - ^ • { id }-j-^=  type } . - • { typ graphical typo  3. Var-dcl •VAR-  A  A » { i d )-r^=  r^l P 1  L—  L^f  •  t v  e  { <graphical typo } <grar  4. Static-del •STATIC  ^  id^ | • -  | - » - ( type } '• { <graphical typo }  1  5. Def-dcl  =-T-^{  '-•{  type } <graphical typo }  1*;  6. Value-del  value assignment }  •VALUE(  <graphical value assignment  }  7. Statement  { statement }-•{  8.  <graphical statements )  Assignment-statement  i •{  variable )  •{ expr } <graphical expr> )  *—• { id : function "{  <graphical initialization>  }  "{  <structured graphical assignments  II. Declaration of graphical data types:  <workstation declaration>  ::=  <device typo  ::=  <graphical type>  <variable*: wkstn> = WKSTN ( <integer>, <device typo )  I I I I I I I  PLOTFILE GKSMETAOUT GKSMETAIN TEK4027 JUPITER7 PRINTRONIX QMS < other device type >  I I I I I I I I I I  POINT SEGMENT WINDOW BUNDLE COLOUR POLYPOINT SEGMENTSET WKSTNSET NORMXFORM PATTERN SEGXFORM  ::=  <graphical value assignment  ::=  <variable* : polypoint> := <constant point list>  <constant point list>  ::=  ( <constant point> { ; <constant point> }  <constant point>  ::=  <signed number> , <signed number>  <signed number>  ::=  { + I - I EMPTY } <unsigned number>  <unsigned number>  ::=  <integer>  +  I  <realnumber>  <integer>  ::=  <digit>  <real number>  ::=  <digit>  <digit>  ::=  . <digit>  0I1I2I3I4I5I6I7I8I9  Graphical initialization:  <graphical initialization>  69 IV.  Structured Graphical Assignments:  structured graphical assignment <point structure> <normxform structure> <bundle structure> <pattern structure>  <point structure>  (  { ;  {  <expr: point>  I  <expr : numerio , <expr : numerio  { I  <expr : point> <expr : numerio * , <expr : numeno  <normxform structuro  { FROM { I I TO  <bundle structure>  <primitive typo <nongeometric attribute list>  <primitive typo I  <variable* : window> TO <variable*: window> EMPTY } <variable* : window> }  LINE FILLAREA  I I  MARKER TEXT  <nongeometric attribute list>  ( <nongeometric attribute> { ; <nongeometric attributo }  <nongeometric attribute>  oiongeometric attribute typo IS <attribute value**>  <nongeometric attribute typo  TYPE WIDTH COLOUR SIZE INTERIOR STYLETYPE FONTPRECISION EXPANSION SPACING  <pattern structure>  < pattern element > { , < pattern element > } < pattern element > { , < pattern element > }  +  +  <pattern elements  <colour> <variable*: integer> <integer>  <colour>  <variable* : colour> <colour constant>  <colour constants  RED  I  GREEN  BLUE  I  YELLOW  MAGENTA  I  CYAN  BLACK  I  WHITE  V. High-level graphical statements:  <graphical statements  <graphical command> <graphical state changes> <workstation table manipulation>  A. Graphical commands:  <graphical commands  <workstation command> <output primitive commands <segment commands  1. Workstation commands:  <workstation commands  <output to workstations  <output to workstation> <messageto workstation> <clear workstation> <redraw workstations <update workstations OUTPUT  T O workstation group>  { ONLY  I  ALSO }  <statement >  <message to workstation>  MESSAGE  TO <clear workstations  <redraw workstation>  CLEAR { I  {  <string > I -cvariable : string> } <workstation group>  <workstation group> ALWAYS EMPTY }  R E D R A W <workstation group>  <update workstation  UPDATE <workstation group>  { I  <workstation group>  { I  NOW EMPTY }  <id : wkstn> <variable* : wkstnseo }  2. Output primitive commands: <line primitive> onarker primitivO <fillarea primitive> <text primitive> <cell array primitive>  <output primitive command>  <line primitive>  LINE <subrange> AT { <variable* : polypoint> I <point structuro }  <marker primitivO  MARKER <subrange> AT { <variable* : polypoint> I <point structuro }  <fillarea primitivO  FILL <subrange> AT { <variable* : polypoint> I <point structure> }  <text pnmitivO  TEXT  <cell array primitivO  CELLARRAY IN <variable*:window> OF <pattern>  <subrange>  I  { <string*> I <variable*: string> } AT <point>  [ 1.. <integer value> ]  EMPTY  <variable : point> <point strucruro  <point>  3. Segment commands <create segmeno <delete segments> <rename segmeno <save segments> <display segments> <insert segments  <segment command>  <create segmeno  CREATE <variable* : segment> <statement>  <delete segments>  DELETE <segment group> { FROM workstation group> I EMPTY }  <segment group>  I  •cvariable : segmeno <variable : segmentseo  <rename segmeno  RENAME <variable* : segmeno TO <variable* : segmeno  <save segments>  SAVE <segment group> TO <workstation group>  <display segmentss  DISPLAY  <insert segmeno  INSERT <variable* : segmeno { WITH <variable* : segxforno I EMPTY }  { <segment group> TO I EMPTY } workstation group>  74 B. Graphical state changes:  <transformation> <attribute specification> <miscellaneous settings>  <graphical state change>  1. Transformation:  <transformation>  ::=  TRANSFORM { NT <<variable*: normxform> I <segment group> <<variable* : segxform> I workstation group>  <-  {  I  FROM <variable* : window> { T O <variable* : window> I EMPTY } T O <variable*: window> } }  2. Attribute specification:  <attribute specifications I I  <set aspect source> <set attributes> <select bundled attributes>  <set aspect source>  ASF OF <primitive typo <<attribute source> { EXCEPT <nongeometric attribute typo { , <nongeometric attribute typo } I EMPTY }  <attribute sourco  INDIVIDUAL I BUNDLED  75  <set attributes  ATTRIBUTES OF {  I  <attribute list>  (  <attribute> I  <geometric attributo  <primitive type> <{ <variable*: bundle> I <attribute list> } <segment group> <<segment attribute list>  <attribute> { ;  <attribute> }  <nongeometric attribute> <geometric attributo  <geometric attribute t y p o IS <attribute value* *>  <geometric attribute t y p o  PATTERNSIZE PATTERNSTART PATH HEIGHT ALIGNMENT ANGLE  <segment group>  •cvariable* : segment> <variable* : segmentset>  <segment attribute list>  )  (  <segment attributo { ; <segment attributo } )  <segment attributo  <segment attribute type> IS <attribute value* *>  <segment attribute t y p o  HIGHLIGHTING  <select bundled attributes  BUNDLE OF <primitive type> <-  I VISIBILITY  {  <integer>  I I  <variable : integer> <variable*: bundlo }  3. Miscellaneous settings:  <set segment pnonty> <set implicit regeneration> <set deferral state> <set clipping>  <miscellaneous settings>  <set segment priority>  P R I O R I T Y O F <segment group> <- <real value>  <set deferral>  DEFERRAL OF  <-  { I  workstation group> <defer item> <defer list> }  <defer list>  ( <deferitem>  <defer item>  I M P L I C I T R E D R A W IS { SUPPRESSED I A L L O W E D } UPDATETIME IS { NOW I LATER }  <set clippings  CLIPPING  <-  {  ; <deferitem>  { ON I OFF }  High-level referencing of workstation tables:  workstation table manipulations <store in workstation tables> <change workstation table entries> <release from workstation tables>  <store in workstation tables>  STORE {  Workstation table entry> IN <workstation group> { ; workstation table entry> IN workstation group> workstation table list> IN <workstation group> (  }*  77  <variable* : colour> <variable*: patterns •cvariable* : bundle>  Workstation table entry>  <workstation table lists  ( workstation table entry> { , workstation table entry> } )  <change workstation table entry> CHANGE TO <expr: colour> { <variable* : colour> I wariable*: patterns TO <pattern structuro I <variable*: bundle> TO <nongeometric attribute lists }  <find workstation index>  FIND wariable : integer> FOR workstation table entry> ON <workstation group> { ; workstation table entry> ON workstation group> }  <release from workstation table> RELEASE workstation table entry> Workstation table list> FROM workstation group> EMPTY  Graphical Expressions  <graphical expr>  <expr: point> <expr: colour> <expr: segxform>  I I  <expr: point>  <variable : point> { + <variable : pomt> I - <variable : point> }  <expr: colour>  { <integer> I <variable* : integer> } { PART I PARTS } <colour> { + { <integer> I -cvariable* : integer> } { PART I PARTS } <colour> }  { I {  <expr: segxform>  }  <segxform factor>  -cvariable* : segxform> <segxform factor> } + { <variable* : segxform> I <segxform factor> } +  { <realvalue> I <point> } FROM <point>  :  SCALE  I  ROTATE <real value> ABOUT <point>  I  SHIFT  <point>  I  SHEAR  <realvalue> % IN  <direction>  IN  <direction>  I  REFLECT I  IDENTITY <direction>  :  X  I  Y  +  7 9  VII.  Summary of notation  SYMBOL  DEFINITION  <x>  Nonterminal symbol x  <x : y>  Nonterminal x of data type y  x  Terminal symbol x  ::=  "is defined as"  ^{ }  Grouping  I  Alternation  <x>  One or more repetitions of <x>  <x>  Zero or more repetitions of <x>  <x >  Nonterminal x is defined by the host language (For definition of x, see [IBM81])  +  **  <x >  See Appendix B for details  Appendix B B.l  Primitive  LINE  MARKER  FILLAREA  TEXT  Nongeometric Output Primitive Attributes  Attribute Type  Data Type  TYPE  STRING  SOLID, DASHED, DOTTED, DASHDOT @  WIDTH  REAL  any >= 0  COLOUR  COLOUR*  any  TYPE  STRING  DOT, PLUS, STAR. X, 0 @  SIZE  REAL  any >= 0  COLOUR  COLOUR*  any  INTERIOR  STRING  HOLLOW, SOLID, PATTERN. HATCH  STYLETYPE COLOUR  PATTERN* or STRING COLOUR*  any @ any  FONTPRECISION font precision  structure STRING STRING  ( font ; precision ) @ STRING, CHAR, STROKE  EXPANSION  REAL  SPACING  REAL  COLOUR  COLOUR*  Values  any >= 0 any any NOTES:  @ *  indicates that implementation dependent names can be added to the values listed indicates that an integer index of the workstation table may be substituted oo  o  Appendix B.2  Primitive  FILLAREA  TEXT  Attribute Type  B  Geometric Output Primitives  Data Type  Values  PATTERNSIZE  POINT  any  PATTERNSTART  POINT  any  PATH  STRING  RIGHT, LEFT, UP, DOWN  HEIGHT  REAL  any > 0  ALIGNMENT horizontal vertical  structure STRING STRING  ( horizontal ; vertical ) NORMAL, LEFT, CENTRE, RIGHT NORMAL, TOP, CAP, HALF, BASE, BOTTOM  ANGLE  REAL  any  Appendix B.3  Attribute Type  B  Segment Attributes  Data Type  Values  VISIBILITY  STRING  VISIBLE,  HIGHLIGHTING  STRING  NORMAL, HIGHLIGHT  INVISIBLE  Appendix C System Defined Functions  Name  Description  Parameter Pata Types  Result  XCoord  Get X coordinate  POINT  REAL  YCoord  Get Y coordinate  POINT  REAL  LoLeft  Get lower left comer  WINDOW  POINT  LoRight  Get lowerrightcorner  WINDOW  POINT  UpLeft  Get upper left corner  WINDOW  POINT  UpRight  Get upperrightcorner  WINDOW  POINT  RedVal  Get RED component of RGB value  COLOUR  REAL  GreenVal  Get GREEN component of RGB value  COLOUR  REAL  BlueVal  Get BLUE component of RGB value  COLOUR  REAL  MaxPts  Get index value of the last initialize point  POLYPOINT  INTEGER  XMax  Get the largest X value  POLYPOINT  REAL  XMin  Get the smallest X value  POLYPOINT  REAL  YMax  Get the largest Y value  POLYPOINT  REAL  YMin  Get the smallest Y value  POLYPOINT  REAL  GetPt*  Get a point  POLYPOINT X INTEGER  POINT  GetWin  Get the window  NORMXFORM  WINDOW  GetVP  Get the viewport  NORMXFORM  WINDOW  RowLen  Get row length  PATTERN  INTEGER  ColLen  Get column length  PATTERN  INTEGER  •Synonym: GetPt(Pl,Il) is PI [II]  Appendix D Example Programs  Program  EZGKS_Demo1;  * *  * This  program demonstrates  the  use of  the  EZ/GKS p r e c o m p i l e r .  * ********************************************************************  *  *  CONST Printer  = WKSTN ( 2 1 ,  QMS);  TYPE NationRec = record flag : SEGMENT; p o s i t i o n : SEGXFORM; End; N a t i o n = ( C a n a d a , USA, E n g l a n d , USSR, J a p a n ) ; NationArray  = array  VAR ArrayOfNat ions Star Pi  [Canada  ..  China,  Japan]  France,  of  Germany,  NationRec;  Nat i o n A r r a y ; SEGMENT; real ;  PROCEDURE G e n e r a t e F 1 a g s ( V a r N a t n A r r : N a t i o n A r r a y ) ; { T h i s r o u t i n e c a l l s a r o u t i n e to g e n e r a t e the g r a p h i c a l segment f o r e a c h c o u n t r y ' s f l a g . } Var Grey FlagSize  : GAColArray; : POLYPOINT;  PROCEDURE C o m p u t e A r c (CONST c e n t e r : POINT; CONST r a d i u s , a l p h a , b e t a : real CONST C l o c k w i s e : b o o l e a n ; CONST I n i t i a 11ndex, N b r P t s i n t e g e r ; VAR r e s u l t : P O L Y P O I N T ) ; { T h i s r o u t i n e c o m p u t e s an a r c c e n t e r e d a t CENTER w i t h a r a d i u s o f RADIUS b e t w e e n a n g l e s ALPHA and B E T A . The d i r e c t i o n o f t h e a r c i s d e t e r m i n e d by C l o c k w i s e a n d t h e d i s t a n c e b e t w e e n t h e p o i n t s i s d e t e r m i n e d by t h e NBRPTS a n d t h e l e n g t h of t h e a r c r e q u e s t e d . The p o i n t s c o m p u t e d a r e s t o r e d i n t h e RESULT b e g i n n i n g w i t h t h e I N I T I A L I N D E X . } Var  I integer; temp, 1 n c r e : r e a l h o l d p t : POINT; BEGIN R e s u l t := ''; I f a l p h a >= b e t a T h e n If C l o c k W i s e T h e n i n c r e : = - ( a l p h a - b e t a ) / ( N b r P t s - 1) E 1 s e i n c r e : = (2 * P i - ( a l p h a - b e t a ) ) / ( N b r P t s • 1) Else if Clockwise T h e n 1 n c r e := - ( 2 * P i - ( b e t a - a l p h a ) ) / (NbrPts - D E l s e i n c r e := ( a l p h a - b e t a ) / ( N b r P t s 1); For  END;  i := 0 t o N b r P t s - 1 Do Begin temp := a l p h a + i * i n c r e ; h o l d p t := ( X c o o r d ( c e n t e r ) + r a d i u s * Ycoord(center) + radius * r e s u l t [ i + I n i t i a l I n d e x ] := h o l d p t ; End; { Compute A r c >  cos(temp), sin(temp));  PROCEDURE D e t e r m i n e S i z e (Name : N a t i o n ; V a r O u t L i n e : POLYPOINT) { T h i s r o u t i n e d e t e r m i n e s the s i z e of the f l a g b a s e d on the a s p e c t r a t i o s t o r e d . } CONST Length  20;  TYPE AspectArray = STATIC AspectRat ios VALUE AspectRat i os VAR bottom BEGIN OutLine bottom Out 1i ne OutLine OutLine  ARRAY  [Canada  Japan]  of  real;  : AspectArray;  aspectArray (0.5, 0.5128, 0.6428, 0.6129, 0.57142,  0.5428, 0.67857, 0.6428);  rea 1  := ( - 1 0 , 10; 10, 10); := ( l e n g t h * A s p e c t R a t i o s [ n a m e ] ) [3] := ( 10, b o t t o m ) ; [4] := (-10, bottom); [5] OutLine [1];  -  10;  00  END;  { DetermineSize  }  PROCEDURE C r e a t e S t a r ( C o n s t F i l l S t a r : b o o l e a n ; V a r S t a r S e g : SEGMENT) { T h i s r o u t i n e c r e a t e s a s t a r f r o m -1,-1 t o 1,1 i n WC. If F i l l S t a r i s t r u e , a f i l l e d s t a r i s c r e a t e d . Otherwise, an o u t l i n e i s c r e a t e d . } VAR StarUnits StarNT  : WINDOW; : NORMXFORM;  STATIC StarPoints  POLYPOINT;  VALUE StarPoi nts  0.95, -0.95, -0.95,  -0.3 -0.3 0.3  0 , 0.95, 0.95,  BEGIN Create StarSeg Begi n A t t r i b u t e s of F i l l < ( c o l o u r i s 0); S t a r U n i t s := (-1, -1 1, D ; StarNT := FROM S t a r U n i t s T r a n s f o r m NT <- S t a r N T ; If FillStar T h e n A t t r i b u t e s o f F i l l <- ( i n t e r i o r E l s e A t t r i b u t e s o f F i l l <- ( i n t e r i o r F i l l at S t a r P o i n t s ; End; { c r e a t e StarSeg } END; { CreateStar >  3; 3);  i s 'sol id') i s ' h o i 1ow' ) ;  SEGMENT);  PROCEDURE D o C a n a d a ( o u t l i n e : POLYPOINT; VAR F l a g S e g { D e f i n e t h e n a t i o n a l f l a g o f Canada } STATIC MapleLeaf VALUE MapleLeaf  POLYPOINT;  ( -o -3 -5 -6 -6 -1  3, 3, 8, 9, 3, 0,  -10 -3 -1 2 5 7  VAR TempPT : POINT; T e m p P o l y P t : POLYPOINT;  0 3 2 7 9 4  -0 -5 -4 -8 -2 0  3, 8, 0, 3, 0, 0,  -2 -3 0 4 3 9  4; 3; 0; 6; 3; 4)  -3 -4 -7 -5 -2  3, 4, 9, 8, 0,  -4 -1 2 4 7  3; 5; 9; 6; 9;  BEGIN Create FlagSeg Begi n L i n e at OutLine; A t t r i b u t e s o f F i l l <- ( i n t e r i o r i s ' s o l i d ' ) : F i l l at MapleLeaf; TempPt := ( 5 , 0 ) ; T e m p P o l y P t := ( 0 u t l i n e [ 1 ] ; 0 u t l i n e [ 1 ] + T e m p P t ; 0 u t l i n e [ 4 ] + TempPt; 0 u t l i n e [ 4 ] ) ; F i l l at TempPolyPt; T e m p P o l y P t := ( 0 u t l i n e [ 2 ] - T e m p P t ; 0 u t l i n e [ 2 ] ; 0 u t l i n e [ 3 ] - TempPt; 0 u t l i n e [ 3 ] ) ; F i l l at TempPolyPt; Text ' C a n a d a ' at (-6, -8); End; END;  PROCEDURE DoUSA ( o u t l i n e { D e f i n e the n a t i o n a l  : POLYPOINT; VAR F l a g S e g f l a g of the U . S . A . }  VAR 1, j : i n t e g e r ; flagwidth, stripewidth, Ypos : r e a l ; S t r i p e , c a n t o n : POLYPOINT; L o w L i m i t , P o s i t i o n , S t e p R i g h t , StepDown S t a r S e g : SEGMENT; S t a r X f o r m , S a v e X f o r m : SEGXFORM; InsertStar : boolean; Xinc, Yinc : real;  :  : SEGMENT)  POINT;  BEGIN X i nc : = 0. 4 ; Y i n c := 0 . 3 0 6 5 ; L o w L i m i t := o u t l i n e [ 3 ] ; F l a g W i d t h := 10 + ABS ( Y c o o r d ( L o w L i m i t ) ) ; S t r i p e W i d t h := F l a g W i d t h / 13; Y p o s := -10; A t t r i b u t e s o f f i l l <- ( i n t e r i o r i s ' S O L I D ' ; c o l o u r i s 1); Create FlagSeg Begin Line at OutLine; F o r i := 1 t o 7 DO Begin S t r i p e := ( - 1 0 , Y p o s ; 10, Y p o s ; 10, Y p o s + S t r i p e W i d t h ; - 1 0 , Ypos + S t r i p e W i d t h ) ; F i l l at Stripe; Y p o s := Y p o s + (2 * StripeWidth);  00 00  END;  End; 10; - 1 . 2 , (7 * S t r i p e W i d t h ) ; C a n t o n ' : = (- 10, 10; - 1 . 2 , StripeWidth)); - 1 0 , (7 * F i l l at Canton; StarSeg); CreateStar (true ( - 1 0 + X i n c , 10 - Y i n c ) ; Pos i t i on S c a l e 0.3 from o r i g i n + StarXForm Shift position; = true; InsertStar StepRight = (Xinc 0); StepDown = (Yinc 0); F o r j := 1 t o 9 Do Beg i n S a v e X f o r m := S t a r X f o r m ; F o r i := 1 t o 11 Do Begin If InsertStar Then I n s e r t S t a r S e g w i t h S t a r X f o r m ; InsertStar := n o t InsertStar; S t a r X f o r m := S t a r X f o r m + Shift StepRight; End; StarXform : = SaveXform + S h i f t StepDown; End; at (-6, -8); Text 'U.S.A. End; { DoUSA }  PROCEDURE D o F r a n c e ( O u t L i n e : POLYPOINT; V a r { D e f i n e the n a t i o n a l f l a g of France } VAR StripeWidth : real; V e r t l n c r e , TwoByTwo  :  FlagSeg:  SEGMENT);  POINT;  Beg i n TwoByTwo := ( 2 , 2); S t r i p e W i d t h := 20 / 3 ; V e r t l n c r e := ( S t r i p e W i d t h , Create FlagSeg Beg i n Line at O u t l i n e ; A t t r i b u t e s o f f i l l <-  0);  (interior is 'solid'; c o l o u r i s 1); F i l l at ( 0ut11ne[1]; 0 u t l i n e [ 1 ] + V e r t l n c r e ; 0utline[4] + Vertlncre; 0utline[4]); A t t r i b u t e s o f F i l l <- ( i n t e r i o r is 'pattern'; StyleType is ' g r e y ' ; Patternstart is o r i g i n ;  00  Fill  END;  PatternSize (Outline[2] ; 0utline[3]; 0utline[3] - Vertlncre; 0utline[2] Vertlncre); ' F r a n c e ' at (-6, -8);  is  TwoByTwo);  at  Text End; { DoFrance  }  PROCEDURE D o E n g l a n d ( O u t L i n e : POLYPOINT; V a r F l a g S e g : SEGMENT); { D e f i n e the n a t i o n a l f l a g of England } VAR LowLimit, Center, Y i n c r e l , Y1ncre2, L e f t s i d e , RightSide : P o i n t ; M1dy, a n g l e : r e a 1 ; S t r i p e , C r o s s : SEGMENT; C r o s s X f o r m , S t r i p e X f o r m : SEGXFORM; i : integer; BEGIN L o w L i m i t := 0 u t l i n e [ 4 ] ; M i d y := Y c o o r d ( 1 o w l i m i t ) C e n t e r := ( 0 , Midy); Y i n c r e l := ( O , 1); Y i n c r e 2 := ( 0 , 2); L e f t S i d e := ( - 1 0 , MidY); R i g h t S i d e := ( 1 0 , MidY); Create Stripe Begin Attributes  of  Fill  /  2;  <-  ( i n t e r i o r is ' s o colour is 0); F i l l at ( L e f t s i d e + Y i n c r e 2 ; RightSide RightSide - Yincre2; Leftside A t t r i b u t e s o f F i l l <- ( c o l o u r i s 1 ) ; F i l l at ( L e f t s i d e + Y i n c r e l ; R i g h t S i d e RightSide - Y i n c r e l ; Leftside End;  Create Cross Begi n F i l l a t ( c e n t e r ; 0 , MidY - 0 . 5 ; Ycoord(1 o w l i m i t ) - 0 . 5 ; End; Create FlagSeg Begin Attributes  of  Fill  <-  lid'; + -  Yincre2; Y1ncre2);  + -  Yincrel; Yincrel);  -10, lowlimit);  ( i n t e r i o r is ' s o l i d ' ; c o l our i s 1);  L i n e at O u t L i n e ; A t t r i b u t e s o f F i l l <- ( c o l o u r i s 0 ) ; F i l l at ( 0 u t l i n e [ 2 ] + Y i n c r e l ; 0 u t l i n e [ 2 ]  -  Yincrel;  O  0utline[4] - Yincrel; 0utline[4] + Yincrel); (Outline[1] + Yincrel; Outline[1] - Yincrel; 0utline[3] - Yincrel; 0utline[3] + Yincrel); C r o s s X f o r r a := ''; F o r i := 1 t o 4 Do Begin Insert Cross with CrossXform; A n g l e := 0 . 5 * P i ; C r o s s X f o r m := C r o s s X f o r m + R o t a t e A n g l e about Center; End; S t r i p e X f o r m := ''; Insert s t r i p e with StripeXform; StripeXform := S t r i p e X f o r m + R o t a t e P i a b o u t Center; Text ' E n g l a n d ' at (-6, -8); End; { DoEngland } Fill  END;  at  PROCEDURE D o C h i n a ( O u t L i n e : POLYPOINT; V a r { D e f i n e the n a t i o n a l f l a g of C h i n a }  FlagSeg:  SEGMENT);  VAR i integer; P o s i t i o n : SEGXFORM; Angle, Incre : r e a l ; BEGIN A t t r i b u t e s o f F i l l <- ( i n t e r i o r i s 'solid'); Create FlagSeg Begin F i l l at OutLine; P o s i t i o n := S c a l e 2.1 f r o m O r i g i n + S h i f t ( - 7 , 4.42); Insert Star with P o s i t i o n ; A n g l e := 0 . 2 5 * P i ; I n c r e := - 0 . 1 8 7 5 * P i ; P o s i t i o n := S c a l e 0 . 5 3 f r o m O r i g i n + S h i f t ( - 4 , 4.42) + R o t a t e A n g l e about (-7, 4.42); F o r 1 := 1 t o 4 Do Begin Insert Star with P o s i t i o n ; P o s i t i o n := P o s i t i o n + R o t a t e A n g l e a b o u t (-7, 4.42); End; Text ' C h i n a ' at (-6, -8); End; END; { DoChina }  PROCEDURE DoGermany ( O u t L i n e : POLYPOINT; V a r { D e f i n e t h e n a t i o n a l f l a g o f Germany }  FlagSeg:  SEGMENT)  VAR F l a g W i d t h , Bandwidth L o w L i m i t , TwoByTwo :  : Real; Point;  BEGIN L o w L i m i t := 0 u t l i n e [ 3 ] ; F l a g W i d t h := 10 + ABS ( Y c o o r d ( L o w L i m i t ) ) ; B a n d W i d t h := F l a g W i d t h / 3 ; Create FlagSeg Begin L i ne a t Out 1i n e ; A t t r i b u t e s o f F i l l <- ( i n t e r i o r i s ' s o l i d ' ; c o l our i s 1); TwoByTwo := ( 2 , 2 ) ; F i l l a t ( - 1 0 , 10; 10, 10; 10, 10 - B a n d W i d t h ; -10, 10 - B a n d W i d t h ) ; A t t r i b u t e s o f F i l l <- ( i n t e r i o r i s ' P a t t e r n ' ; StyleType is ' g r e y ' ; P a t t e r n S i z e i s TwoByTwo; PatternStart is origin); F i l l a t ( - 1 0 , 10 - B a n d W i d t h ; 10, 10 - B a n d W i d t h ; 10, 10 - (2 * B a n d W i d t h ) ; -10, 10 - (2 * B a n d W i d t h ) ); Text 'Germany' at (-6, -8); End; END;  PROCEDURE DoUSSR ( O u t L i n e : POLYPOINT; V a r F l a g S e g : SEGMENT) { Define the national f l a g of the U . S . S . R . } VAR S t a r S e g : SEGMENT; S t a r P o s i t i o n : POINT; StarXform : SEGXFORM; STATIC Hammer, VALUE Hammer  Cycle  :=  : POLYPOINT;  (-7.5, 6.5; - 7 . 3 , 6.7; - 8 , 7.4; - 7 . 8 , 7.5; - 8 . 2 , 7.8; - 8 . 5 , 7.5; - 8 . 4 , 7.2; - 8 . 3 , 7.3)  BEGIN { ComputeCycle ( c y c l e ) ; } CreateStar (false, StarSeg); S t a r P o s i t i o n := ( - 8 , 9); S t a r X f o r m := S c a l e 0 . 5 f r o m O r i g i n Shift StarPosition; Create FlagSeg  + to  Begin Attributes  END;  of  Fill  <-  ( i n t e r i o r is 'solid'; c o l o u r i s 1);  F i l l at O u t l i n e ; Insert StarSeg with StarXform; A t t r i b u t e s o f F i l l <- ( c o l o u r i s F i l l a t Hammer; { F i l l at C y c l e ; } Text ' U . S . S . R . ' at (-6, -8); End; < DoUSSR >  PROCEDURE D o J a p a n ( O u t L i n e : POLYPOINT; V a r { D e f i n e the n a t i o n a l f l a g of Japan } VAR Circle  O);  F l a g S e g : SEGMENT)  : POLYPOINT;  BEGIN Create 1agSeg Begin L i n e at O u t L i n e ; C o m p u t e A r c ( o r i g i n , 5, 0 , 2 * P i , t r u e , 1, 100, circle); A t t r i b u t e s o f F i l l <- ( i n t e r i o r i s ' s o l i d ' ) ; F i l l at Ci r c l e ; Text ' J a p a n ' at (-6, -8); End; END; { DoJapan } c  BEGIN C 1 i p p 1 n g <'on'; A t t r i b u t e s o f T e x t <- ( h e i g h t i s 2 0 . 0 ; e x p a n s i o n G r e y [ 1 , 1 ] := O; G r e y [ 1 , 2 ] := 1 G r e y [ 2 , 1 ] := 1 G r e y [ 2 , 2 ] := 0 G S e t P a t t e r n R e p ( P r i n t e r , 1, 2 , 2 , G r e y ) ; DetermineSize (Canada, F l a g s i z e ) ; DoCanada ( F l a g S i z e , NatnArr[Canada].Flag); D e t e r m i n e S i z e (USA, F l a g s i z e ) ; DoUSA ( F l a g S i z e , N a t n A r r [ U S A ] . F 1 a g ) ; DetermineSize (England, F l a g s i z e ) ; DoEngland ( F l a g S i z e , NatnArr[Engl a n d ] . F 1 a g ) ; DetermineSize (China, F l a g s i z e ) ; DoChina ( F l a g S i z e , N a t n A r r [ C h i n a ] . F 1 a g ) ; DetermineSize (France, Flagsize); DoFrance ( F l a g S i z e , NatnArr[France].F1ag); D e t e r m i n e S i z e (Germany, Flagsize);  is  1.5);  DoGermany ( F l a g S i z e , NatnArr[Germany].F1ag); D e t e r m i n e S i z e (USSR, F l a g s i z e ) ; DoUSSR ( F l a g S i z e , NatnArr[USSR].F1ag); DetermineSize (Japan, Flagsize); DoJapan ( F l a g S i z e , NatnArr[Japan].F1ag); END; { GenerateF1ags }  PROCEDURE G e n e r a t e P o s i t i o n s ( V a r N a t n A r r : N a t i o n A r r a y ) ; { T h i s r o u t i n e generates the t r a n s f o r m a t i o n s to l a t e r be a p p l i e d to the f l a g s p r e v i o u s l y g e n e r a t e d . T r a n s f o r m a t i o n s are a l s o s t o r e d in the NatnArr a l o n g w i t h t h e r e l a t e d f l a g segment t o w h i c h t h e y w i l l be a p p l i e d . } Var i angle, incre InitLocatn BEGIN InitLocatn  : :  nation; real; SEGXFORM;  :=  ROTATE - 0 . 5 ABOUT O r i g i n TRANSLATE ( 4 0 , 0); := 0 . 1 2 5 * P i ; := 0 . 2 5 * P i ; C a n a d a t o J a p a n Do  Angle Incre F o r 1 := Begi n InitLocatn  END;  +  :=  InitLocatn + ROTATE A n g l e ABOUT o r i g i n ; NatnArr[i].pos1tion := InitLocatn; If i = China Then B e g i n Angle : = 0.125 * P i ; InitLocatn := ROTATE - 0 . 5 ABOUT O r i g i n TRANSLATE ( - 4 0 , 0) + ROTATE A n g l e ABOUT O r i g i n End { 1 = 4 } E l s e A n g l e := A n g l e + I n c r e ; End; { F o r Stmt > { GeneratePositions }  PROCEDURE D i s p l a y E x h i b i t ( N a t n A r r : NationArray); { T h i s r o u t i n e g e n e r a t e s the g r a p h i c a l output u s i n g t h e segments and t r a n s f o r m a t i o n p r e v i o u s l y defined. ) VAR E x h i b i tUni t s , E x h i b i tNT Exhibi t  NDCUnits  WINDOW; NORMXFORM; SEGMENT;  1  nat i o n ;  BEGIN For  I := C a n a d a t o J a p a n Do Begin D i s p l a y N a t n A r r [ i ] . f 1 a g to Printer; Clear Printer; End; ExhibitUnits := ( - 1 0 0 , - 6 5 ; 100, 65); NDCUnits := ( 0 . 0 6 8 1 , 0 . 0 9 3 7 5 ; 0.9318, 0.84275); ExhibitNT := FROM E x h i b i t U n i t s TO N D C U n i t s ; TRANSFORM NT <ExhibitNT; Create Exhibit; Beg 1 n F o r i := C a n a d a t o J a p a n Do Insert N a t n A r r [ i ] . f 1 a g with NatnArr[i].position; A t t r i b u t e s o f T e x t <- ( h e i g h t i s 1 3 0 . 0 ; expansion is 2.0; spacing is 0.5); T e x t ' P E A C E ' at ( - 1 0 , 30); Text 'ON' a t ( - 5 , 0 ); Text 'EARTH' at ( - 1 0 , -30); End; { C r e a t e Seg ) D i s p l a y E x h i b i t to P r i n t e r ; • END; { DisplayExhibit }  BEGIN { main > P i := 3 . 1 4 1 5 9 2 ; GenerateF1ags (ArrayOfNations); GeneratePos11 ions (ArrayOfNat i o n s ) ; D1splayExhibi t (ArrayOfNat i o n s ) ; END.  program ezgks_demo1 ; {****************************************^ {**  This  i s t h e program  translated  i n t o GKS s u b r o u t i n e  %Print O f f "/.Include GKS_BASICS " / . I n c l u d e GKS_SEGMENTS " / . P r i n t On const GXCMaxSetSize GXCMaxBundleSetSize GXCMaxATrVal GXCMaxAtrTypes  = = = =  31; 10; 50; 26;  type GXTPrimitive  = ( line,  GXTSetRange  =  GXTEZSet  =  packed  =  GXTSetRange;  Point  =  GRPoint;  PolyPoint  =  flllarea,  graphicText);  0..GXCMaxSetSize;  Wkstn  GXTPolyPointRange  marker,  =  s e t o f GXTSetRange;  O..GCMaxPoint;  record  points : GAPointArray; max : GXTPolyPointRange; End; Colour = record masterindex : GTintO; col our : GRcol; End; Pattern = record masterindex : GTintO; RowLength, ColumnLength : i n t e g e r ; Pattern ; GAColArray; ColourSource : GAColArray; { 0 = c o l o u r t a b l e ; 1 = MWT; } End; Bundle = record masterindex Attrlnit  GTintO; Array [ 1 - 4 ] of boolean;  calls.  **}  ColourSource {0 = c o l o u r Attributes End; Segment  =  WkstnSet  GXTSetRange; =  SegmentSet Window  : Integer; t a b l e ; 1 = MWT } GRPrimRep;  =  GXTEZSet; =  GXTEZSet;  record  validPercent corner End;  : boolean; : GRbound;  NormXform  =  GTintl;  SegXform  =  GAMatrix;  GXTWsOperation GXTTypeSave  = (GXSave,  = (GXOnly,  GXTWkstnSetType  GXRestore);  GXAlso);  = (GXOpenWs,  GXActiveWs);  GXTAtrValRec = record AtrName : s t r i n g ; AtrValue: integer; DefeultFlag : integer; End; GXTAvArrayType  = array  [1..GXCMaxAtrVal]  of  GXTAtrValRec;  GXTContextLimit = record M i n , Max : i n t e g e r ; End; GXTCtxArrayType const red = green = b l ue = yel1ow = magenta = cyan = black = white = origin = CentralSegStore  = array  [0..GXCMaxAtrTypes]  c o l o u r (0, (1,0,0)) c o l o u r (0, (0,1,0)) c o l o u r (0, (0,0,1)) c o l o u r (0, (1,1,0)) c o l o u r (0, (1,0,1)) c o l o u r (0, (0,1,1)) c o l o u r (0, (0,0,0)) c o l o u r (0, (1,1,1)) point (0.0, 0.0); = wkstn (0);  of  GXTContextLimit;  identity  =  segxform  (  (  1.0, 0 . 0 , (0.0, 1.0,  GXVpoint, GXVpoint2 : p o i n t ; G X V a c t i v e W k s t n s , GXVopenWkstns G X V p o l y p o i nt : polypoint; col our; GXVcolour pattern; GXVpattern bundle; GXVbundle segment; GXVsegment wkstnset; GXVwkstnset segmentset; GXVsegmentset w i ndow; GXVwi ndow normxform; GXVnormxform segxform; GXVsegxform GRFontPrec; GXVfontprec GRal1gn; GXValign GAVector; GXVvector GAstring; GXVstring integer; G X V i , GXVj real ; G X V M , GXVr2 GXVAsf GXVAvArray GXVLimi t A r r a y GXVAtr Function  GXSetMax  External; Procedure GXSetPt External; P r o c e d u r e GXSetWin  0.0), 0.0));  wkstnset;  GAasf; GXTAVArrayType; GXTCtxArrayType; text; (CONST N b r R a n g e , : integer;  NbrPts  :  integer)  (CONST P t S e t : p o l y p o i n t ; VAR Pt : p o i n t ) ; (CONST P t S e t VAR Win  :  polypoint; w i ndow );  External; F u n c t i o n GXNTNum : integer; External; F u n c t i o n GXSegNum : integer; External; point) : point; F u n c t i o n GXAddPT (CONST P T a , PTb External; point) : point; F u n c t i o n GXSubPT (CONST P T a , PTb External; F u n c t i o n GXWsSet (CONST t y p e s e t : G X T W k s t n S e t T y p e ) External; P r o c e d u r e GXSuppR ( V a r c h a n g e d S e t : W k s t n S e t ) ; External; P r o c e d u r e GXRestR ( C o n s t c h a n g e d s e t : W k s t n S e t ) ; External;  :  wkstnset  oo  Procedure  G X S t C h g (op : G X T W s O p e r a t i o n ; SaveMethod : GXTTypeSave; SaveSet : WkstnSet) External; Procedure GXState (op : G X T W s O p e r a t i o n ; WkstnsNamed : W k s t n s e t ; S e g S e t O p : b o o l e a n ) ; External; P r o c e d u r e GXGetASF ( V a r a s f F l a g s : G A A s f ; ASFtype : G T a s f ; PrimNbr : i n t e g e r ) ; External; P r o c e d u r e G X I n i t A v (CONST m a x A t r , MaxCtx : i n t e g e r ; Var AVArray : GXTAvArrayType; Var L i m i t A r r a y : GXTCtxArrayType); External; F u n c t i o n G x A t r V a l (CONST A t r A r r a y : G X T A v A r r a y T y p e ; CONST m i n , max; i n t e g e r ; CONST s e a r c h n a m e : s t r i n g ) : External; P r o c e d u r e G X C o l E x p (CONST p r o c e s s f l a g : b o o l e a n ; CONST N b r P a r t s : i n t e g e r ; CONST I n C o l o u r : G R c o l ; Var ExprColour : G R c o l ) ; External; P r o c e d u r e GXAccum (VAR X f o r m l : s e g x f o r m ; CONST X f o r m 2 : s e g x f o r m ) ; External; F u n c t i o n X c o o r d (CONST Pt : p o i n t ) : r e a l ; External; F u n c t i o n Y c o o r d (CONST P t : p o i n t ) : r e a l ; External; F u n c t i o n L o L e f t (CONST win1 : window) :point; External; F u n c t i o n L o R i g h t (CONST win1 : window) : p o i n t ; External; F u n c t i o n U p L e f t (CONST win1 : window) : p o 1 n t ; External; F u n c t i o n U p R i g h t (CONST win1 : window) :point; External; F u n c t i o n R e d V a l (CONST C o l Rec : c o l o u r ) : real; External; F u n c t i o n G r e e n V a l (CONST C o l R e c : c o l o u r ) : real; External; F u n c t i o n B l u e V a l (CONST C o l R e c : c o l o u r ) : real; External; F u n c t i o n M a x P t s (CONST P o l y P t R e c : p o l y p o i n t ) : integer; External; polypoint): real; F u n c t i o n XMax (CONST P o l y P t R e c External; F u n c t i o n X M i n (CONST P o l y P t R e c polypoint): real; External; polypoint): real; F u n c t i o n YMax (CONST P o l y P t R e c External; F u n c t i o n Y M i n (CONST P o l y P t R e c polypoi nt): real;  External; Function GetPt  (CONST P o l y P t R e c : p o l y p o i n t ; CONST I n d e x : I n t e g e r ) : p o i n t ;  External; F u n c t i o n G e t W i n (CONST NTNbr : n o r m x f o r m ) : window; External; F u n c t i o n G e t V P (CONST NTNbr : n o r m x f o r m ) : window; External; F u n c t i o n RowLen (CONST P a t t R e c : p a t t e r n ) : integer; External; F u n c t i o n C o l L e n (CONST P a t t R e c : p a t t e r n ) : integer; External; const p r i n t e r = wkstn ( 1) ;  type nationrec = record f l a g : segment ; p o s i t i o n : segxform end  n a t i o n = ( Canada ussr , japan ) ; nationarray  , usa , england  = array  arrayofnations s t a r : segment pi : real ;  ;  [ Canada  : nationarray ;  procedure generatef1ags  var grey : gacolarray ; f l a g s i z e : polypoint  (  var  , china  .; japan  , france  , germany  ] of n a t i o n r e c ;  ;  natnarr  : nationarray  )  ;  ;  procedure computearc ( const center : point ; const r a d i u s c o n s t c l o c k w i s e : b o o l e a n ; c o n s t i n i t i a l index , n b r p t s : integer ; var r e s u l t : polypoint ) ;  pha  , beta  :  real  i : integer ; temp , i n c r e : r e a l holdpt : point ;  ;  begin r e s u l t . m a x := 0 ; i f a l p h a >= b e t a then i f c l o c k w i s e t h e n i n c r e := - ( a l p h a else incre ( nbrpts -  2  := ( 1 )  else if clockwise then i n c r e : = - ( ( nbrpts 1 ) else for  *  pi  2  *  incre  :=  (  0  to  nbrpts  i  :=  alpha  -  -  beta  -  (  alpha  pi  -  (  beta  )  /  ( -  beta  )  /  (  nbrpts beta  -  -  1 )  )  )  /  alpha  )  )  nbrpts  -  /  1 )  ;  1 do  begin temp := a l p h a + i * i n c r e ; G X V p o l y p o i n t . p o i n t s t 1].x := x c o o r d ( c e n t e r ) + r a d i u s * c o s ( t e m p ) G X V p o l y p o i n t . p o i n t s [ 1].y := y c o o r d ( c e n t e r ) + r a d i u s * s i n ( t e m p ) GXVpolypoint.max :=. 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; h o l d p t := G X V p o i n t ; result.points[i+initialindex] := h o l d p t ; If i + 1 n i t i a l i n d e x > result.max T h e n r e s u l t . m a x := i + i n i t i a l i n d e x ; end  end  ;  procedure  const length  type  determinesize  =  20 ;  (  name  : nation  ; var  outline  : polypoint  )  ;  aspectarray  = array  static aspectratios  [  Canada  japan  ] of  aspectarray  value a s p e c t r a t i o s := a s p e c t a r r a y ( 0 . 5 , 0 . 5 1 2 8 0.6428 , 0.6129 , 0.57142 , 0.6428 ) var bottom  real  , 0.5428  0.67857  real  begin G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 10 ; 10; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 10 ; G X V p o l y p o i n t . p o i n t s [ 2 ] . x := 10; G X V p o l y p o i n t . p o i n t s [ 2 ] . y := 2; G X V p o l y p o i n t . m a x := = GXVpolypoint; o u t 1i n e ( l e n g t h * a s p e c t r a t i o s [ name ] ) bottom 10 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := G X V p o l y p o i n t . p o i n t s [ 1 ] . y := b o t t o m ; 1 ; G X V p o l y p o i n t . m a x := = GXVpolypoint.points [1]; outline.pointsf 3] If 3 > outline.max T h e n o u t l I n e . m a x := 3; GXVpolypoint.poi nts [ 1].x = - 10 ; = bottom; GXVpolypo i n t . p o i n t s t 1].y G X V p o l y p o i n t . m a x := 1 ; = G X V p o l y p o i n t p o i n t s [ 1 ]; out 1 i n e . p o i n t s [ 4] If 4 > outline.max Then o u t l i n e . m a x := outl1ne.points[ 5] = outl1ne.points! 1] If 5 > outline.max Then o u t l i n e . m a x := 5; end  ,  10  ;  procedure  createstar  ( const  fillstar  : boolean  ; var starseg  : segment  )  var s t a r u n i t s : window starnt : normxform  O  N3  stat ic starpoi nts  p o l y p o i nt  value starpoints := p o l y p o i n t ( G A P o i n t A r r a y GRPoint ( 0.95 , -0.3 ) , GRpoint ( 0.0 , 1 . 0 ) , GRpoint ( -0.95 , -0.3 ) , GRpoint ( 0.95 , 0.3 ) , GRpoint ( -0.95 , 0.3 ) , GRpoint ( 0.95 , -0.3 ) , GRPoint (0.0, 0.0) : 94) ,  begin s t a r s e g := GCreateSeg  GXSegNum; ( starseg  (  6  ):  );  begi n GSetFi1IColInd (0); G X V p o l y p o i n t . p o i n t s [ 1]:x := - 1 ; GXVpolypoint.points [ 1].y := - 1; GXVpolypoint.points [ 2].x := 1 ; GXVpolypoint.points j 2].y := 1; G X V p o l y p o i n t . m a x := 2; GXSetWin ( G X V p o l y p o i n t , GXVWindow); starunits := GXVwindow; s t a r n t := GXNTNum; GSetWindow ( s t a r n t , s t a r u n i t s . c o r n e r ); GSelectNTran ( s t a r n t ) ; if f i l l star then GSetFi11IntStyle ( G T i n t e r i o r (GXAtrVal else GSetFi11IntStyle (GTinterior (GXAtrVal GXVi := GXSetMax ( O , starpoints.max); GF i l l ( GXVi, s t a r p o i n t s . p o i n t s ) ;  (GXVAVArray, (GXVAVArray,  GXVLimitArray GXVLimitArray  [ [  13].min, 13].min,  GXVLimitArray GXVLimitArray  [ [  13].max, 13].max,  'solid'))) 'hollow')))  end ; GCloseSeg; end  procedure  docanada  stat i c mapleleaf  ( outline  : polypoint  : polypoint  ; var  flagseg  : segment  )  ; O  v a l ue mapleleaf GRPoint -0 GRpoint -o GRpoint -3 GRpoint -3 GRpoi nt -5 GRpoint -4 GRpoi nt -5 GRpoi nt -4 GRpoi nt -7 GRpoint -6 GRpoi nt -8 GRpoi n t -5 GRpoint -6 GRpoi nt -2 GRpoi nt -2 GRpoint -1 GRpoint 0.0 GRPoint 0.0,  polypoint ( GAPointArray 3 , -10.O ) 3 , -2.4 ) 3 , "4.3 ) ) 3 , -3.3 8 , "3.3 ) 4 , -1.5 ) 8 , -1.2 ) 0 , 0.0 ) , g . 2.9 ) , 9 , 2.7 ) , 3 , 4.6 ) , 8 , 4.6 ) , 3 . 5.9 ) , 0 , 3.3 ) , 0 , 7.9 ) . ) , 0 , 7.4 ) , , 94 83) 0.0)  var temppt : p o i n t ; temppolypt : polypoint  begin f l a g s e g := GXSegNum; GCreateSeg ( flagseg  (  17  );  ;  );  begin GXVi := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; G P o l y l i n e ( GXVi, out 1 i n e . p o i n t s ) ; GSetFi11IntStyle (GTinterior (GXAtrVal (GXVAVArray, GXVLimitArray [ GXVi := GXSetMax ( 0 , mapleleaf.max); G F i l l ( GXVi, mapleleaf.points ) ; G X V p o l y p o i n t . p o i n t s [ 1].x := 5 ; GXVpolypoint.points [ 1].y := 0 ; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; t e m p p t := G X V p o i n t ; G X V p o l y p o i n t . p o i n t s [ 1] := o u t 1 i n e . p o i n t s [ 1] ; GXVpolypoint.points [ 2 ] := GXAddPT ( o u t 1 i n e . p o i n t s [ 1] , t e m p p t ) ; G X V p o l y p o i n t . p o i n t s [ 3] := GXAddPT ( o u t 1 i n e . p o i n t s [ 4] , t e m p p t ) ; G X V p o l y p o i n t . p o i n t s [ 4] := o u t 1 i n e . p o i n t s [ 4] ; G X V p o l y p o i n t . m a x := 4; temppolypt := G X V P o l y P o i n t ; GXVi := GXSetMax ( 0 , t e m p p o l y p t . m a x ) ;  13].min,  GXVLimitArray  [  13].max,  'solid')));  O  GF i l l ( G X V 1 , t e m p p o l y p t . p o i n t s ) ; G X V p o l y p o i n t . p o i n t s [ 1] := GXSubPT ( o u t 1 1 n e . p o i n t s [ G X V p o l y p o i n t . p o i n t s [ 2] := o u t 1 i n e . p o i n t s [ 2] ; G X V p o l y p o i n t . p o i n t s [ 3] := GXSubPT ( o u t 1 i n e . p o i n t s [ G X V p o l y p o i n t . p o i n t s [ 4] := o u t 1 i n e . p o i n t s [ 3] ; G X V p o l y p o i n t . m a x := 4; t e m p p o l y p t := G X V P o l y P o i n t ; GXVi := GXSetMax ( 0 , t e m p p o l y p t . m a x ) ; GF i l l ( G X V i , t e m p p o l y p t . p o i n t s ) ; GXVstring := ' C a n a d a ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 6 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := - 8; G X V p o l y p o i n t . m a x := 1; GTextString end  ( GXVPolyPoint.points  [1]  ,  2]  ,  temppt);  3]  ,  temppt);  1ength(GXVString),  GXVString  );  ;  GCloseSeg; end  ;  procedure  dousa  ( outline  : polypoint  ; var flagseg  var i , j : integer ; f l a g w i d t h , s t r i p e w i d t h , ypos : r e a l ; s t r i p e , canton : polypoint ; l o w l i m i t , p o s i t i o n , s t e p r i g h t , stepdown s t a r s e g : segment ; s t a r x f o r m , savexform : segxform ; i n s e r t s t a r : boolean ; xinc , yinc : real ;  : segment  : point  begin x i nc : = 0 . 4 ; y i n c := 0 . 3 0 6 5 ; l o w l i m i t := o u t 1 i n e . p o i n t s [ 3] ; f l a g w i d t h := 10 + a b s ( y c o o r d ( l o w l i m i t ) ) ; s t r i p e w i d t h := f l a g w i d t h / 13 ; y p o s := 10 ; G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal (GXVAVArray, G S e t F i 1 I C o l I n d ( 1); flagseg := GXSegNum; GCreateSeg ( flagseg ); begin GXVi := GXSetMax  (0,  out 1ine.max);  ) ;  ;  GXVLimitArray  [  13].min,  GXVLimitArray  [  13].max,  'SOLID')));  O  GPolyline f o r i :=  ( GXVi, out 1 i n e . p o i n t s 1 to 7 do  )  ;  beg i n = - 10 ; G X V p o l y p o i n t p o i n t s [ 1] X = ypos; G X V p o l y p o i n t po i n t s [ 1] y = 10 ; G X V p o l y p o i n t p o i n t s t 2] X = ypos; G X V p o l y p o i n t p o i n t s C 2] y = 10 ; G X V p o l y p o i n t p o i n t s t 3] X = ypos+stripewidth; G X V p o l y p o i n t po i n t s [ 3] y = - 10 ; G X V p o l y p o i n t p o i n t s [ 4] X = ypos+stripewidth; G X V p o l y p o i n t p o i n t s [ 4] y G X V p o l y p o i n t max : = 4; s t r i p e := G X V p o l y p o i n t ; GXVi := GXSetMax ( 0 , s t r i p e . m a x ) ; G F i l l ( GXVi, s t r i p e . p o i n t s ) ; y p o s := y p o s + ( 2 * stripewidth ) ; end = - 10 ; G X V p o l y p o i n t p o i n t s [ 1] X G X V p o l y p o i n t p o i n t s [ 1] y = 10; G X V p o l y p o i n t p o i n t s [ 2] X = -1.2 ; G X V p o l y p o i n t p o i n t s [ 2] y = 10; = -1.2 ; G X V p o l y p o i n t p o i n t s [ 3] X = ( 7*stripewidth) G X V p o l y p o i n t p o i n t s t 3] y G X V p o l y p o i n t p o i n t s [ 4] X = - 10 ; = ( 7*stripewidth) G X V p o l y p o i n t p o 1 n t s [ 4] y G X V p o l y p o i n t max : = 4; c a n t o n := G X V p o l y p o i n t ; GXVi := GXSetMax ( 0 , c a n t o n . m a x ) ; G F i l l ( GXVi, canton.points ) ; createstar ( true , starseg ) ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 1 0 + x i n c ; GXVpolypoint.points [ 1]y•:= 10-yinc; GXVpolypoint.max := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; p o s i t i o n := G X V p o i n t ; G X V S e g X f o r m := I d e n t i t y ; G X V P o i n t := o r i g i n ; G X V v e c t o r ! 1 ] := 0 . 3 ; G X V v e c t o r [ 2 ] := 0 . 3 ; GAccumTran (GXVSegxform , G X V P o i n t , o r i g i n , 0, G X V v e c t o r , NDC, G X V S e g X f o r m ) ; G X V v e c t o r [ 1 ] := 1.0; G X V v a c t o r t 2 ] := 1.0; G X V P o i n t := p o s i t i o n ; G a c c u m t r a n ( G X V S e g X f o r m , O r i g i n , G X V P o i n t , 0, G X V v e c t o r , WC, G X V S e g x f o r m ) ; s t a r x f o r m := G X V s e g x f o r m ; i n s e r t s t a r := t r u e ;  G X V p o l y p o i n t . p o i n t s [ 1].x := x i n c GXVpolypoint.points [ 1].y := 0; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; s t e p r i g h t := G X V p o i n t ; GXVpolypoint.points [ 1].x := y i n c GXVpolypoint.points [ 1].y := 0; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; s t e p d o w n := G X V p o i n t ; f o r j := 1 to 9 do  ;  ;  begin G X V S e g X f o r m := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , starxform); s a v e x f o r m := G X V s e g x f o r m ; f o r 1 := 1 to 11 do begin if insertstar t h e n GXVSegXForm := s t a r x f o r m ; G I n s e r t S e g ( s t a r s e g , GXVSegXForm); i n s e r t s t a r := n o t i n s e r t s t a r ; GXVSegXform := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , starxform); G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := s t e p r i g h t ; Gaccumtran (GXVSegXform, O r i g i n , G X V P o i n t , G X V v e c t o r , WC, G X V S e g x f o r m ) ; s t a r x f o r m := G X V s e g x f o r m ;  0,  end G X V S e g X f o r m := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , s a v e x f o r m ) ; G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := s t e p d o w n ; Gaccumtran (GXVSegXform, O r i g i n , GXVPoint, G X V v e c t o r , WC, G X V S e g x f o r m ) ; s t a r x f o r m := G X V s e g x f o r m ;  0,  end G X V s t r i n g := ' U . S . A . ' ; G X V p o l y p o i n t . p o i n t s [ 1].x := - 6 ; GXVpolypoint.points [ 1].y := - 8; G X V p o l y p o i n t . m a x := 1; G T e x t S t r i n g ( G X V P o l y P o i n t . p o i n t s [1]  ,  1ength(GXVString),  G X V S t r i n g );  i—  o  end  ;  GCloseSeg; end  ;  procedure  dofrance  var stripewidth vertincre ,  ( outline  : real ; twobytwo  : polypoint  : point  ; var flagseg  : segment  ) ;  ;  beg i n G X V p o l y p o i n t . p o i n t s [ 1 ] . x := 2 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 2; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; t w o b y t w o := G X V p o i n t ; s t r i p e w i d t h := 20 / 3 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := s t r i p e w i d t h ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 0; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; v e r t i n c r e := G X V p o i n t ; f l a g s e g := GXSegNum; GCreateSeg ( flagseg ); begin GXVi := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; G P o l y l i n e ( GXVi, out 1 i n e . p o i n t s ) ; G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal (GXVAVArray, GXVLimitArray [ 1 3 ] . m i n , GXVLimitArray [ 13].max, GSetFi1IColInd (1); G X V p o l y p o i n t . p o i n t s [ 1] := o u t l i n e . p o i n t s t 1] ; G X V p o l y p o i n t . p o i n t s [ 2] := GXAddPT ( o u t 1 i n e . p o i n t s [ 1] , v e r t i n c r e ) ; G X V p o l y p o i n t . p o i n t s [ 3] := GXAddPT ( o u t 1 i n e . p o i n t s [ 4] , v e r t i n c r e ) ; G X V p o l y p o i n t . p o i n t s [ 4] := o u t 1 1 n e . p o i n t s [ 4] ; G X V p o l y p o i n t . m a x := 4; GXVi := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) ; G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal (GXVAVArray, GXVLimitArray [ 1 3 ] . m i n , GXVLimitArray [ 13].max, G S e t F i 1 I S t y l e l n d (GXAtrVal (GXVAVArray, G X V L i m i t A r r a y [ 1 4 ] . m i n , G X V L i m i t A r r a y [ 14].max, 'grey')); GSetPatternRefPoint (origin); G X V v e c t o r [ 1 ] := t w o b y t w o . x ; G X V v e c t o r [ 2 ] := t w o b y t w o . y ; GSetPatternSize (GXVvector); G X V p o l y p o i n t . p o i n t s [ 1] := o u t 1 i n e . p o i n t s [ 2] ; G X V p o l y p o i n t . p o i n t s [ 2] := o u t l i n e . p o i n t s t 3] ;  'solid')));  'pattern')));  O 00  G X V p o l y p o i n t . p o i n t s [ 3] := GXSubPT ( o u t 1 i n e . p o i n t s [ 3] , v e r t i n c r e ) ; G X V p o l y p o i n t . p o i n t s [ 4] := (GXSubPT ( o u t 1 i n e . p o i n t s [ 2] , v e r t i n c r e ) ) GXVpolypo1nt.max := 4; GXVi := GXSetMax ( 0 , 4); GFill ( GXVi, GXVpolypoint.points ) ; G X V s t r i n g := ' F r a n c e ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 6 ; GXVpolypoint.points [ 1].y := - 8; G X V p o l y p o i n t . m a x := 1; GTextString  ( GXVPolyPoint.points  [1] ,  1ength(GXVString),  GXVString  end ; GCloseSeg; end  procedure  doengland  ( outline  : polypoint  ; var  flagseg  : segment  )  ;  var lowlimit , center , yincrel , yincre2 midy , a n g l e : r e a l ; s t r i p e , c r o s s : segment ; crossxform , stripexform : segxform ; i integer ;  begin l o w l i m i t := o u t 1 i n e . p o i n t s [ 4] ; m i d y := y c o o r d ( l o w l i m i t ) / 2 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := 0 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := m i d y ; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; c e n t e r := G X V p o i n t ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := 0 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 1; GXVpolypoint.max : = 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; yincrel := G X V p o i n t ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := 0 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 2; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; y i n c r e 2 := G X V p o i n t ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 1 0 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := m i d y ; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ;  ,  leftside  ,  rightside  : point  ;  )  leftside := G X V p o i n t ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := 10 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := m i d y ; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; r i g h t s i d e := G X V p o i n t ; s t r i p e := GXSegNum; GCreateSeg ( s t r i p e  );  begin G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal (GXVAVArray, G X V L i m i t A r r a y GSetFi1IColInd (0); G X V p o l y p o i n t . p o i n t s [ 1] := GXAddPT ( l e f t s i d e , yincre2); G X V p o l y p o i n t . p o i n t s [ 2] := GXAddPT ( r i g h t s i d e , yincre2); G X V p o l y p o i n t . p o i n t s [ 3] := GXSubPT ( r i g h t s i d e , yincre2); G X V p o l y p o i n t . p o i n t s [ 4] := (GXSubPT ( l e f t s i d e , yincre2)); G X V p o l y p o i n t . m a x := 4; GXVi := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) G S e t F i 1 I C o l I n d ( 1); GXVpolypo i n t . p o i nts GXAddPT ( l e f t s i d e , yincrel); 1] GXVpolypo1nt.poi nts GXAddPT ( r i g h t s i d e , y i n c r e l ) ; 2] GXVpolypoint.points GXSubPT ( r i g h t s i d e , y i n c r e l ) : 3] GXVpo1ypo i n t . p o 1 n t s (GXSubPT ( l e f t s i d e , yincrel)); 4] G X V p o l y p o i n t . m a x := 4; GXVi := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) end ; GCloseSeg; c r o s s := GXSegNum; GCreateSeg ( cross  );  begin G X V p o l y p o i n t po i n t s [ 1] : = c e n t e r ; G X V p o l y p o i n t po i n t s [ 2] X := 0 ; G X V p o l y p o i n t po i n t s [ 2] y := m i d y - 0 . 5 ; G X V p o l y p o i n t p o i n t s [ 33 X := - 10 ; G X V p o l y p o i n t p o i n t s C 3] y := y c o o r d ( 1 o w l i m 1 1 ) - 0 . 5 G X V p o l y p o i n t po i n t s [ 4] : = l o w l i m i t ; G X V p o l y p o i n t . m a x := 4; GXVi := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) ; end ; GCloseSeg; flagseg := GXSegNum; GCreateSeg ( flagseg  );  [  13].min,  GXVLimitArray  [  13].max,  'solid')));  begi n (GXAtrVal (GXVAVArray, G X V L i m i t A r r a y [ 13].min, GSetFIl1IntStyle (GTinterior GSetFi1IColInd ( G X V i := GXSetMax ( 0 , o u t l i n e . m a x ) ; G P o l y l i n e ( GXVi outline.points ) ; GSetFi1IColInd (0); GXVpolypoi nt.po i nts yincrel); GXAddPT ( o u t l i n e . p o i n t s ! 2] 1] G X V p o l y p o i nt .po i n t s yincrel); GXSubPT ( o u t l i n e . p o i n t s ! 2] 2] G X V p o l y p o i nt . p o i n t s GXSubPT ( o u t l i n e . p o i n t s ! 4] , y i n c r e l ) ; 3] G X V p o l y p o i n t .po i n t s (GXAddPT ( o u t 1 i n e . p o i n t s [ 4] , y i n c r e 1 ) ) ; 4] G X V p o l y p o i n t .max := GXVi GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) = GXAddPT ( o u t l i n e . p o i n t s ! 1] , y i n c r e 1 ) ; GXVpolypo i n t . p o i nts 1] = GXSubPT ( o u t l i n e . p o i n t s ! 1] , y i n c r e 1 ) ; G X V p o l y p o i n t . p o i n t s [ 2] G X V p o l y p o i n t . p o i n t s [. 3] = GXSubPT ( o u t l i n e . p o i n t s ! 3] , y i n c r e l ) ; G X V p o l y p o i n t . p o i n t s t 4] = (GXAddPT ( o u t l i n e . p o i n t s ! 3] , y i n c r e 1 ) ) ; G X V p o l y p o i n t . m a x := 4; 4); GXV1 := GXSetMax (0, GFill ( GXVi, GXVpolypoint.points ) G X V S e g X f o r m := I d e n t i t y ; c r o s s x f o r m : = GXVSegXform; f o r i := 1 to 4 do begin GXVSegXForm := c r o s s x f o r m ; GInsertSeg (cross, GXVSegXForm); a n g l e := 0 . 5 * p i ; G X V S e g X f o r m := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , crossxform); G X V v e c t o r ! 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := c e n t e r ; GAccumtran (GXVSegXform, G X V P o i n t , G X V v e c t o r , WC, G X V S e g x f o r m ) ; c r o s s x f o r m := GXVsegxform;  origin,angle,  end G X V S e g X f o r m := I d e n t i t y ; s t r i p e x f o r m : = GXVSegXform; GXVSegXForm := s t r i p e x f o r m ; GInsertSeg ( s t r i p e , GXVSegXForm); G X V S e g X f o r m := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , stripexform); G X V v e c t o r ! 1] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := c e n t e r ; GAccumtran (GXVSegXform, G X V P o i n t , o r i g i n , p i , G X V v e c t o r , WC, G X V S e g x f o r m ) ;  GXVLimitArray [  13].max,  'solid')));  s t r i p e x f o r m := G X V s e g x f o r m ; G X V S t r i n g := ' E n g l a n d ' ; GXVpolypoint.points [ 1].x := GXVpolypoint.points [ 1].y := G X V p o l y p o i n t . m a x := 1; GTextString end  -  6 ; 8;  ( GXVPolyPoint.points  [1]  ,  ( outline  ; var  1ength(GXVString),  GXVString  );  ;  GCloseSeg; end  ;  procedure  dochina  : polypoint  flagseg  : segment  )  ;  i integer ; p o s i t i o n : segxform ; angle , incre : real ;  begin GSetFi11IntStyle (GTinterior f l a g s e g := GXSegNum; G C r e a t e S e g ( f l a g s e g );  (GXAtrVal  (GXVAVArray,  begi n GXVi := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; GFill ( GXVi, o u t l i n e . p o i n t s ) ; G X V S e g X f o r m := I d e n t i t y ; G X V P o i n t := o r i g i n ; G X V v e c t o r [ 1 ] := 2.1; GXVvector[2] := 2.1; GAccumTran (GXVSegxform , G X V P o i n t , o r i g i n , 0, G X V v e c t o r , NDC, G X V S e g X f o r m ) ; GXVvector[1] := 1.0; GXVvector[2] := 1.0; G X V P o i n t . x := - 7 ; G X V P o l n t . y := 4.42; G a c c u m t r a n (GXVSegXform, O r i g i n , G X V P o i n t , 0, G X V v e c t o r , WC, G X V S e g x f o r m ) ; p o s i t i o n := G X V s e g x f o r m ; GXVSegXForm := p o s i t i o n ; G I n s e r t S e g ( s t a r , GXVSegXForm); a n g l e := 0 . 2 5 * p i ; i n c r e := - 0 . 1 8 7 5 * p i ; G X V S e g X f o r m := I d e n t i t y ; G X V P o i n t := o r i g i n ;  GXVLimitArray  [  13].min,  GXVLimitArray  [  13].max,  'solid')));  G X V v e c t o r f . 1] := 0.53; GXVvector[2] := 0.53; GAccumTran (GXVSegxform , G X V P o i n t , o r i g i n , 0, G X V v e c t o r , NDC, G X V S e g X f o r m ) ; G X V v e c t o r ! 1 ] := 1.0; GXVvector[2] := 1.0; G X V P o i n t . x := - 4 ; G X V P o i n t . y := 4.42; G a c c u m t r a n ( G X V S e g X f o r m , O r i g i n , G X V P o i n t , 0, G X V v e c t o r , WC, G X V S e g x f o r m ) ; G X V v e c t o r f 1 ] := 1.0; GXVvector[2] := 1.0; G X V P o i n t . x := - 7 ; G X V P o i n t . y := 4.42; GAccumtran (GXVSegXform, G X V P o i n t , o r i g i n , a n g l e , G X V v e c t o r , WC, G X V S e g x f o r m ) ; p o s i t i o n := G X V s e g x f o r m ; for i : = 1 to 4 do begin GXVSegXForm := p o s i t i o n ; G I n s e r t S e g ( s t a r , GXVSegXForm); G X V S e g X f o r m := I d e n t i t y ; GXAccum ( G X V S e g x f o r m , p o s i t i o n ) ; G X V v e c t o r f 1 ] := 1.0; GXVvector[2] := 1.0; G X V P o i n t . x := - 7 ; G X V P o i n t . y := 4.42; GAccumtran (GXVSegXform, G X V P o i n t , G X V v e c t o r , WC, G X V S e g X f o r m ) ; p o s i t i o n := G X V s e g x f o r m ;  origin,angle,  end GXVstring : = 'China' ; GXVpolypoint.points [ 1].x GXVpolypoint.points [ 1].y G X V p o l y p o i n t . m a x := 1; GTextString end  := :=  -  6 ; 8;  ( GXVPolyPoint.points  [1]  ,  1ength(GXVString),  GXVString )  ;  GC1oseSeg; end  ;  procedure  var  dogermany  ( outline  : polypoint  ; var  flagseg  : segment  )  ;  flagwidth 1owli mi t  bandwidth : r e a l twobytwo : p o i n t ;  begin l o w l i m i t := o u t 1 i n e . p o i n t s [ 3] ; f l a g w i d t h := 10 + a b s ( y c o o r d ( bandwidth := f l a g w i d t h / 3 ; f l a g s e g := GXSegNum; G C r e a t e S e g ( f l a g s e g );  lowlimit  )  )  ;  begin G X V i := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; G P o l y l i n e ( G X V i , out 1 i n e . p o i n t s ) ; G S e t F i l U n t S t y l e ( G T i n t e r i o r (GXAtrVal (GXVAVArray, G X V L i m i t A r r a y [ 1 3 ] . m i n , GXVLim1tArray [ 13].max, GSetFi1IColInd (1); G X V p o l y p o i n t . p o i n t s [ 1].x := 2 ; GXVpolypoint.points [ 1].y := 2; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; t w o b y t w o ;= G X V p o i n t ; GXVpolypoint.points [ 1].x 10 ; GXVpolypoint.points [ 1].y 10; 10 ; GXVpolypoint.points [ 2].x 10; GXVpolypoint.points [ 2].y 10 ; GXVpolypoint.points [ 3].x 10-bandwidth; GXVpolypoint.points [ 3].y GXVpolypoint.points [ 4].x 10 ; GXVpolypoint.points [ 4].y 10-bandwidth; G X V p o l y p o 1 n t . m a x := 4; G X V i := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) ; GSetFi11IntStyle ( G T i n t e r i o r ( G X A t r V a l ( G X V A V A r r a y , GXVL1 m i t A r r a y [ 1 3 ] . m i n , G X V L i m i t A r r a y [ 1 3 ] . m a x , GSetFi1IStyleInd (GXAtrVal (GXVAVArray, GXVLim1tArray [ 1 4 ] . m i n , G X V L i m i t A r r a y [ 14].max, 'grey')); G X V v e c t o r [ 1 ] := t w o b y t w o . x ; G X V v e c t o r [ 2 ] := t w o b y t w o . y ; GSetPatternSize (GXVvector); G S e t P a t t e r n R e f P o i nt o r 1gi n ) ; G X V p o l y p o i n t po i n t s = - 10 1] X G X V p o l y p o i n t po i n t s 10-bandwidth; 1] y G X V p o l y p o i nt p o 1 n t s = 10 ; 2] X G X V p o l y p o i nt p o i n t s = 10-bandwidth; 2] y GXVpolypoint points = 10 ; 3] X GXVpolypoint points = 10-( 2 * b a n d w 1 d t h ) 3] y G X V p o l y p o i n t po i n t s = - 10 4] X G X V p o l y p o i n t po i n t s = 10-( 2 * b a n d w i d t h ) 4] y G X V p o l y p o i n t . m a x := 4; G X V i := GXSetMax ( 0 , 4); G F i l l ( GXVi, GXVpolypoint.points ) G X V s t r i n g := ' G e r m a n y ' ;  'solid')));  'Pattern')));  G X V p o l y p o i n t . p o i n t s [ 1].x := - G G X V p o l y p o i n t . p o i n t s [ 1 ] . y := - 8; G X V p o l y p o i n t . m a x := 1; GTextString ( GXVPolyPoint.points end  ,  length(GXVString),  GXVString  ;  GCloseSeg; end  ;  procedure  doussr  ( outline  s t a r s e g : segment ; starpooition : point s t a r x f o r m : segxform  : polypoint  ;  ; ;  static hammer  ,  cycle  : polypoint  value GRPoi n t ( - 7 . 5 6 hammer G R p o i n t :=( p"o7 l. y3 p o i n 6t 7 GRpoi nt ( - 8 . 0 7 G R p o i n t ( "7. 8 G R p o i n t ( "8 . 2 7 G R p o i n t ( "8. 5 7 7 G R p o i n t ( "8. 4 GRpoint ( -8. 3 7 G R P o i n t ( 0 . 0 , 0 0)  5 7( 4 5 8 5 2 3  ;  ) )GAPointArray ( ) ) ) ) ) )  begi n createstar ( false , starseg ) ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 8 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 9; G X V p o l y p o i n t . m a x := 1; GXSetPT ( G X V P o l y P o i n t , G X V P o i n t ) ; s t a r p o s i t i o n := G X V p o i n t ; G X V S e g X f o r m := I d e n t i t y ; G X V P o i n t := o r i g i n ; G X V v e c t o r [ 1 ] := 0 . 5 ; G X V v e c t o r ! 2 ] := 0 . 5 ;  flagseg  : segment  ) ;  )  GAccumTran (GXVSegxform , G X V P o i n t , o r i g i n , 0, G X V v e c t o r , NDC, G X V S e g X f o r m ) ; GXVvector[1] := 1.0; GXVvector[2] := 1.0; G X V P o i n t := s t a r p o s i t i o n ; G a c c u m t r a n (GXVSegXform, O r i g i n , G X V P o i n t , 0, G X V v e c t o r , WC, G X V S e g x f o r m ) ; starxform := G X V s e g x f o r m ; f l a g s e g := GXSegNum; G C r e a t e S e g ( f l a g s e g ); begin G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal GSetFi1IColInd (1); GXVi := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; G F i l l ( GXVi, o u t l i n e . p o i n t s ) ; GXVSegXForm := starxform; G I n s e r t S e g ( s t a r s e g , GXVSegXForm); GSetFi1IColInd (0); GXVi := GXSetMax ( 0 , hammer.max); G F i l l ( GXVi, hammer.points ) ; G X V S t r i n g := ' U . S . S . R . ' ; GXVpolypoint.points [ 1].x GXVpolypoint.points [ 1].y G X V p o l y p o i n t . m a x := 1; GTextString end  := :=  -  (GXVAVArray,  GXVL1mitArray  ( GXVPolyPoint.points  [1]  ( outline  ; var  1ength(GXVStr1ng),  ,  GXVString  ;  ;  procedure  var circle  dojapan  :  : polypoint  flagseg  polypoint  begin f l a g s e g := GCreateSeg  GXSegNum; ( flagseg  13].min,  6 ; 8;  GCloseSeg; end  [  );  begin GXVi := GXSetMax ( 0 , o u t 1 i n e . m a x ) ; G P o l y l i n e ( GXVi, o u t l i n e . p o i n t s ) ; computearc ( o r i g i n , 5 , 0 , 2 * pi  ,  true  : segment  )  );  GXVLimitArray  [  13].max,  'solid')));  100 . c i r c l e ) ; G S e t F i 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVal GXVi := GXSetMax ( 0 , c i r c l e . m a x ) ; G F i l l ( GXVi, c i r c l e . p o i n t s ) ; G X V s t r i n g := ' J a p a n ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 6 ; G X V p o l y p o i n t . p o i n t s [ i j . y := - 8; G X V p o l y p o i n t . m a x := 1; GTextString  ( GXVPolyPoint.points  [1]  (GXVAVArray,  ,  1ength(GXVString),  end ; GCloseSeg; end  begin GSetCharHeight (20.0); GSetCharExpan (1.5); g r e y [ 1, 1] := 0; g r e y [ 1, 2] := 1; g r e y t 2 , 1] := 1; g r e y [ 2 , 2] := 0 ; gsetpatternrep ( printer , 1 , 2 , 2 , grey ) ; d e t e r m i n e s i z e ( Canada , f l a g s i z e ) ; d o c a n a d a ( f l a g s i z e , n a t n a r r [ Canada ] . f l a g ) d e t e r m i n e s i z e ( usa , f l a g s i z e ) ; dousa ( f l a g s i z e , natnarr [ usa ] . f l a g ) ; determinesize ( england , f l a g s i z e ) ; doengland ( f l a g s i z e , natnarr [ england ] . f l a g determinesize ( china , flagsize ) ; dochina ( flagsize , natnarr [ china ] . flag ) ; determinesize ( france , f l a g s i z e ) ; dofranee ( flagsize , natnarr [ france ] . flag ) d e t e r m i n e s i z e ( germany , f l a g s i z e ) ; d o g e r m a n y ( f l a g s i z e , n a t n a r r [ germany ] . f l a g determinesize ( ussr , f l a g s i z e ) ; doussr ( f l a g s i z e , natnarr [ ussr ] . f l a g ) ; determinesize ( japan , f l a g s i z e ) ; dojapan ( f l a g s i z e , natnarr [ japan ] . f l a g ) ; end  ;  ) ;  ; )  ;  procedure  generateposition  ( var natnarr  GXVLimitArray  : nationarray )  ;  [  GXVString  13].min,  );  GXVLimitArray  [  13].max,  'solid')));  i : nation ; angle , incre : real ; i n i t l o c a t n : segxform  begin G X V S e g X f o r m := Identity; G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := o r i g i n ; GAccumtran (GXVSegXform, GXVPoint, G X V v e c t o r , WC, G X V S e g x f o r m ) ; i n i t l o c a t n := G X V s e g x f o r m ; a n g l e := 0 . 1 2 5 * p i ; i n c r e := 0 . 2 5 * p i ; f o r i := c a n a d a t o j a p a n do  origin,0.5,  begin GXVSegXform : = I d e n t i t y ; GXAccum ( G X V S e g x f o r m , initlocatn); G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := o r i g i n ; GAccumtran (GXVSegXform, GXVPoint, origin,angle, G X V v e c t o r , WC, G X V S e g x f o r m ) ; i n i t l o c a t n := G X V s e g x f o r m ; G X V S e g X f o r m := Identity; GXAccum ( G X V S e g x f o r m , initlocatn); n a t n a r r [ i ] . p o s i t i o n := G X V s e g x f o r m ; if i = china then beg i n a n g l e := 0 . 1 2 5 * p i ; G X V S e g X f o r m := Identity; G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := o r i g i n ; GAccumtran (GXVSegXform, GXVPoint, origin,0.5, G X V v e c t o r , WC, G X V S e g x f o r m ) ; G X V v e c t o r [ 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t := o r i g i n ; GAccumtran (GXVSegXform, GXVPoint, origin,angle, G X V v e c t o r , WC, G X V S e g x f o r m ) ; i n i t l o c a t n := G X V s e g x f o r m ; end else  angle  := a n g l e  + incre  ;  end  end  ;  procedure  displayexhibit  (  natnarr  e x h i b i t u n i t s , ndcunits e x h i b i t n t : normxform ; e x h i b i t : segment ; i : nation ;  begin for i  :=  Canada  to japan  :  nationarray  : window ;  do  begin GXState ( GXsave, [ p r i n t e r ] , false); GCopySegWs ( p r i n t e r , natnarr[i].f1ag); GXState ( GXrestore, [ p r i n t e r ] , false); GXState ( GXsave, [ p r i n t e r ] , false); GClearWs ( p r i n t e r , C l e a r C o n d ); GXState ( GXrestore, [ p r i n t e r ] , false); end G X V p o l y p o i n t . p o i n t s [ 1].x := - 100 ; GXVpolypoint.points [ 1].y := - 6 5 ; GXVpolypoint.points [ 2].x := 100 ; GXVpolypoint.points [ 2].y := 65; G X V p o l y p o i n t . m a x := 2; G X S e t W i n ( G X V p o l y p o i n t , GXVWindow); e x h i b i t u n i t s := GXVwindow; G X V p o l y p o i n t . p o i n t s [ 1].x := 0 . 0 6 8 1 ; GXVpolypoint.points [ 1].y := 0 . 0 9 3 7 5 ; GXVpolypoint.points [ 2].x := 0 . 9 3 1 8 ; GXVpolypoint.points [ 2].y := 0 . 8 4 2 7 5 ; G X V p o l y p o i n t . m a x := 2; G X S e t W i n ( G X V p o l y p o i n t , GXVWindow); n d c u n i t s := GXVwindow; e x h i b i t n t := GXNTNum; GSetWindow ( e x h i b i t n t , e x h i b i t u n i t s . c o r n e r ) G S e t V i e w p o r t ( e x h i b i t n t , n d c u n 1 t s . c o r n e r ); GSelectNTran ( exhibitnt);  e x h i b i t := GXSegNum; GCreateSeg ( e x h i b i t  );  GCloseSeg; begi n f o r i := C a n a d a t o j a p a n do GXVSegXForm := n a t n a r r [ i ] . p o s i t i o n ; G I n s e r t S e g ( n a t n a r r [ i ] . f 1 a g , GXVSegXForm) GSetCharHeight (130.0); GSetCharExpan (2.0); GSetCharSpacing (0.5); G X V S t r i n g := ' P E A C E ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 10 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 30; G X V p o l y p o i n t . m a x := 1; G T e x t S t r i n g ( G X V P o l y P o i n t . p o i n t s [1] G X V S t r i n g := ' O N ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 5 ; G X V p o l y p o i n t . p o i n t s [ i j . y ' : = 0; G X V p o l y p o i n t . m a x := 1; G T e x t S t r i n g ( G X V P o l y P o i n t . p o i n t s [1] G X V S t r i n g := ' E A R T H ' ; G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 10 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := - 3 0 ; G X V p o l y p o i n t . m a x := 1; GTextString ( GXVPolyPoint.points [1]  ,  1ength(GXVString),  ,  1 ength(GXVString) , GXVString  length(GXVString),  GXVString  GXVString  end ; GXState ( GXsave, [ p r i n t e r ] , false); GCopySegWs ( p r i n t e r , exhibit); GXState ( GXrestore, [ p r i n t e r ] , false); end  begi n GopenGKS ( 0 , 1 0 0 0 ) ; GopenWs ( C e n t r a l S e g S t o r e , 0 , 3) ; GActivateWS (CentralSegStore); GopenWs ( 1, 21, 7370); G X I n i t A v (GXCMaxAtrVal, GXCMaxAtrTypes, p i := 3 . 1 4 1 5 9 2 ; generatef1ags ( arrayofnations ) ; generateposition ( arrayofnations ) ; displayexhibit ( arrayofnations ) ; GXVopenWkstns  := GXWsSet  (GXopenWs);  GXVAvarray,  GXVLimitArray);  );  );  );  G X V a c t i v e W k s t n s := GXWsSet ( G X A c t i v e W s ) F o r GXVI := 0 t o G X C M a x S e t S i z e DO Begin I f GXVi IN G X V A c t i v e W k s t n s Then GDeactivateWS (GXVi); I f GXVi IN G X V o p e n w k s t n s Then GcloseWs (GXVi); End; GcloseGKS;  

Cite

Citation Scheme:

        

Citations by CSL (citeproc-js)

Usage Statistics

Share

Embed

Customize your widget with the following options, then copy and paste the code below into the HTML of your page to embed this item in your website.
                        
                            <div id="ubcOpenCollectionsWidgetDisplay">
                            <script id="ubcOpenCollectionsWidget"
                            src="{[{embed.src}]}"
                            data-item="{[{embed.item}]}"
                            data-collection="{[{embed.collection}]}"
                            data-metadata="{[{embed.showMetadata}]}"
                            data-width="{[{embed.width}]}"
                            async >
                            </script>
                            </div>
                        
                    
IIIF logo Our image viewer uses the IIIF 2.0 standard. To load this item in other compatible viewers, use this url:
http://iiif.library.ubc.ca/presentation/dsp.831.1-0051949/manifest

Comment

Related Items