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 G R A P H I C A L E X T E N S I O N F O R P A S C A L B A S E D O N T H E G R A P H I C A L K E R N E L S Y S T E M 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 R E Q U I R E M E N T S F O R T H E D E G R E E O F M A S T E R O F S C I E N C E 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 . STARR, 1987 In presenting this thesis in partial fulfilment of the requirements for an advanced degree at the University of British Columbia, I agree that the Library shall make it freely available for reference and study. I further agree that permission for extensive copying of this thesis for scholarly purposes may be granted by the head of my department or by his or her representatives. It is understood that copying or publication of this thesis for financial gain shall not be allowed without my written permission. Department of Computer Science The University of British Columbia 1956 Main Mall Vancouver, Canada V6T 1Y3 ii Abstract The Graphical Kernel System (GKS), the first international standard in the area of computer graphics, was adopted by the International Standards Organization in 1985. The United Kingdom, France, Germany and the United States have also adopted GKS as a national standard. This thesis examines the feasibility of developing a high-level graphical extension to a general-purpose programming language based on the GKS standard. Because GKS was designed as a subroutine system, programming with it is awkward. The subroutine call provides a low-level mechanism for accessing the graphical capabilities standardized by GKS. EZ/GKS is a high-level graphical extension to the Pascal/VS language implementing the functionality found in GKS level 2A. The level of abstraction for graphics programming is elevated in EZ/GKS through the use of abstract graphical data types. Operations on graphical data types are provided by structured graphical assignments, high-level graphical statements, graphical expressions and system-defined functions. Complex user-defined data types may be constructed from any of the predefined graphical data types in the usual manner provided by Pascal. No major syntactic or semantic difficulties were encountered during the design and implementation of EZ/GKS. Thus, it appears that the GKS standard can indeed be elevated successfully to a high-level graphical extension of a general-purpose programming language. iii Table of Contents Abstract ii List of Figures v Acknowledgment vii 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 10 1.4 Organization 11 Chapter 2 Language Design 12 2.1 Contributions and Constraints of GKS 13 2.2 Contributions and Constraints of Pascal 16 Chapter 3 Abstract Graphical Data Types 18 3.1 Individual Graphical Types 20 3.2 Compound Graphical Types 24 3.3 Summary 27 Chapter 4 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 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 Chapter 6 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 v i 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 and Segment Sets 53 Figure 25 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. Their contribution allowed work on the GKS Pascal Binding to begin. 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 a high-level graphical extension to the Pascal/VS language 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. Developing a new language allows unlimited creative freedom in the language design. The development of an extensive compiler is necessary, however, resulting in a significant lead time for implementation. The non-geometric and arithmetic capabilities provided by a new language usually are not sufficient to support customary programming tasks. In addition, high training costs are incurred in a production environment educating programmers in the use of the language. When a graphics programming language is based on an existing host language, many of the preceding problems are avoided. Although the language design of the graphical extension is restricted by the characteristics of the host language chosen, significantly less time and effort are required for implementation. All non-geometric and arithmetic functions are automatically inherited from the 2 host language. The t ra ining costs are l imi ted to the costs o f teaching experienced programmers the speci f ics o f the graphica l extension. A graphics sys tem based on a host language may be des igned ei ther as a subroutine system or as a language extension. W i t h a subroutine system, routines p r o v i d i n g g raph ica l capabi l i t ies are added to the run t ime l ib ra ry , a l l o w i n g the system to be eas i ly extended or t ransported. N o separate p r e - c o m p i l a t i o n is requi red o f g raph ica l app l i ca t ion programs. M o s t p r o g r a m m i n g errors however can on ly be detected at run time, result ing i n a longer lead time necessary for the deve lopmen t o f g r a p h i c a l a p p l i c a t i o n programs due to the ex tens ive tes t ing required. In pract ice , subroutine systems are d i f f i cu l t to use and place a large burden o n the programmer . T h e G K S graphics standard serves both as a gu ide l ine for mig ra t ing graphical functions into hardware and also as a standardized, device independent means for access ing these g raph ica l capab i l i t i e s through software (F igure 1). G K S was designed as a subroutine system. Al though G K S is easily extended and very Graphical Graphical Applications Devices Figure 1 - The Role of GKS 3 portable, programming with it can be awkward. The subroutine calls with their parameter lists are difficult to remember. The resulting code is hard to understand and maintain. The standard subroutine call provides a low-level mechanism for accessing the graphical capabilities standardized by GKS. An alternative method by which a host language may be extended is by "the definition of additional data types, expressions and statements not . . . found in the original host language." [GiEn72]. Implementation of a graphical extension requires the development of a pre-compiler or compiler extension. A pre-compilation or extra compilation time is necessary during the development of a graphical application program. Many programming errors can be detected during the pre-compilation phase, however, reducing the testing required for application programs. The most significant benefit of a language extension is its ease of use. Given a clean and intuitive language syntax, the graphical extension to a standard programming language can increase the productivity of graphics programmers while reducing training costs. The lead time necessary for application program development is thereby reduced. The readable source code generated by using a high level graphical extension can also cut the cost of maintenance for application programs running in a production environment. Pascal was selected as the host language for this high-level graphical extension based on wide acceptance in the academic community and on characteristics of the language itself. Pascal is an excellent language on which to base a graphical extension. 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. The dynamic storage allocation mechanism allows data structures to expand as needed throughout program execution. All of these capabilities assisted with the 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 graphical statements embedded within an ordinary Pascal program. 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 originally found in the host language (Figure 2). The graphical extension provides support for both individual application programs and for the application-oriented layer. The application-oriented layer may provide modeling, charting or windowing Application Program Application Oriented Layer (modeling) EZ/GKS High -level Language Extension J La ng uage De pe nde nt La ye r (Pascal) i Graphical Kernel System Operating System Other Resources Graphical Resources Figure 2 - Layer Model of GKS Incorporating EZ/GKS 5 sub-systems specifically useful to certain application programs. As in GKS, all application specific functions have been excluded from EZ/GKS, resulting in a general purpose graphical extension. EZ/GKS is a graphical extension to the Pascal/VS language implementing the functionality found in level 2a of GKS. 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. Much of the syntax of the graphical statements is consistent with that of the regular Pascal language, allowing a natural representation familiar to Pascal programmers. Many concepts from Pascal are applied in the context of graphical operations, including records, arrays, linked lists, sets and assignment statements. Due to time restrictions, the inquiry, error and metafile 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 a high-level extension of the Pascal/VS language in order to simplify 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 full functionality of GKS by clearly defining the relationships between EZ/GKS and the GKS subroutine system, allowing both to be mixed compatibly within the same application program. 5. Assist the graphics programmer in gradually learning the concepts of GKS, lowering training costs for graphics programmers. 6. Assist programmers in producing successful graphics programs, reducing the lead time necessary to implement graphical applications. 7. 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 graphical extension. 1.3 Contributions The benefits derived from the use of high-level programming languages are no longer disputed. High-level languages such as Fortran, Cobol, Pascal and PL/1 have become the norm for developing non-graphical application programs. The utility of a graphical extension to a general purpose programming language was recognized in 1968 when David Smith began the design for GPL/I [Smit71]. Since then many researchers have studied the use of high-level graphical extensions to general purpose programming languages [McLe78]. Of these contributions, the GPL/I, MIRA and HL/GKS graphical extensions have been selected for further discussion in the following sections. 7 1.3.1 GPL/I GPL/I was designed as a graphical extension to the PL/I programming language. The design of the language was machine and device independent, defining graphical output conceptually rather than in hardware specific 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. A variable of data type VECTOR described a line radiating from the origin and was represented by a two-dimensional or three-dimensional point. The IMAGE data type contained a combination of pictorial and attribute values which were derived from VECTOR variables, text and the result of IMAGE functions. An IMAGE variable, which could be any of PL/I's storage classes, was either 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 incl u3ion vector product connection scalar product positioning addition scaling subtraction rotation Figure 3 - Example of Graphical Data Types in GPL/I v i th 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 defined and manipulated by name in assignment statements and expressions. A number of PL/I statements, such as the OPEN, ON, SIGNAL and PUT, were extended to handle the graphical options permitted by the language extension. Additional high-level statement types included in GPL/I were the TAKE, ERASE and ANIMATE statements. Although the use of graphical data types in GPL/I was visionary, the high-level statement types provided for graphical manipulation were minimal. 1.3.2 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, facilities in MIRA permitted the programmer to construct hierarchical, user-defined graphical 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. The syntax for the declaration of a FIGURE type was similar to that of a Pascal procedure, including in the definition an identifier 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 DELETE 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). Several standard FIGURE types which were also provided by the system 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 1985 when the GKS system was adopted by the ISO. The GKS standard defined a common terminology and a A. Standard Procedures B. Standard Functions C. Standard Figure Type3 symmetry translation rotation homothety union angle intersection centre distance segment line circle square triangle Figure 4 - Example of Standard Procedures, Standard Functions and Standard Figure Type3 in MIRA 10 methodological framework for computer graphics programming. 1.3.3 HL/GKS GKS was used as the foundation for a graphical extension to the Fortran-77 in HL/GKS [Sun86]. The HL/GKS language extension adopted many of the concepts of GKS, 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 as either individual variables or as single dimensional arrays. High-level graphical statements such as SEND, DISPLAY, MESSAGE, REDRAW and ERASE provided operations on the graphical variables. HL/GKS made many of the details of GKS transparent to the user, including opening, closing, activating and deactivating workstations. Facilities were provided for updating and partial deletion of segments after closing. Explicit specification of attributes, transformations and output replaced the modal default provided by GKS. The major disadvantage of HL/GKS is the inflexibility of the host language. The capability for defining structures of non-homogeneous elements is notably absent from Fortran-77, as are the block structure and dynamic storage allocation mechanisms found in most modern programming languages. The host language selected restricts the utility of the HL/GKS graphical extension. 11 1.4 Organization Chapter 2 begins by examining the design constraints on the language that distinguish this work from that of its predecessors. 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 graphical data types provided by the EZ/GKS language. The distinction between individual and compound graphical data types is explained. Chapter 4 presents the operations which characterize the graphical data types presented in Chapter 3. Operations include structured graphical assignments, graphical statements, graphical expressions and system-defined functions. Chapter 5 discusses the development of the EZ/GKS pre-compiler and the translation techniques it utilizes. First, a simple translation is examined where a high-level EZ/GKS statement is directly translated into a GKS subroutine call. The use of the run time library and inquiry functions are described. Finally, methods for handling attribute values and high-level references to workstation tables are explained. The appendices contain details of the language syntax, data types of attribute values and system-defined functions. Example programs are also provided written in EZ/GKS and GKS, producing identical output. 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. In this manner, the EZ/GKS language extension conceptually allows 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. Finally, the benefits derived from the host language are program !with graphical / statements EZ/GKS Pre-processor / program -^/with GKS sub-rout ine calls Figure 5 - Translation of an EZ/GKS Program 13 A. Access provided by GKS Pascal program ( subroutine call \ / GKS subroutine system B. Access provided by EZ/GKS Pascal program • EZ/GKS: state-ments subroutine call GKS subroutine sustem nej Figure 6 - Conceptual Access to Graphical Capabilities discussed. 2.1 Contributions and Constraints of G K S The benefits of a standard for computer graphics were recognized a decade before G K S was adopted by the ISO as an international standard. In 1974, the In ternat ional Federa t ion for Informat ion P rocess ing ( IFIP) Graph ics 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 in computer graphics. The principles formulated at the Seillac workshop provided a foundation for the graphics standards subsequently developed. Two underlying principles defined at the Seillac workshop were the concept of portability and the differentiation between modeling and viewing functions 14 [Ende85]. The concept of portability referred to the mobility of graphical application programs, graphical data and graphics programmers between different installations, operating systems, and changing hardware configurations. Providing standardized interfaces to both application programs and to device drivers enhanced portability. Modeling was defined as the process of building a picture from component parts while viewing treated the picture as a whole. The participants at the Seillac workshop decided that only viewing functions were application independent. They determined that modeling functions were application dependent and therefore should be excluded from any graphics standardization efforts. GKS was chosen as the foundation for the high-level graphical extension to Pascal/VS because of its acceptance as the international standard for computer graphics programming. Designed as a kernel system, it provides the minimal set of 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. All but the most rudimentary aspects of modeling are excluded. 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. Unlike most of its predecessors, EZ/GKS excludes all but the basic aspects of modeling. The philosophy behind the design of EZ/GKS is similar to that of GKS: 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), not to the language extension. Exclusion of all application dependent features is necessary to produce a general purpose graphical extension. Instead of expanding the basic modeling facilities provided by GKS, EZ/GKS provides language constructs to assist with the design and implementation of application-oriented graphical software. The graphical data types discussed in Section 3.1 simplify the temporary storage of graphical data while high-level graphical statements assist with manipulation of the data. Compound data types such as the WKSTNSET and SEGMENTSET discussed in Section 3.2 assist with manipulating sets of workstations and segments in an intuitive manner. For example, the SEGMENTSET primitive data type could be utilized to implement concepts such as the inclusion filter and exclusion filter defined in PHIGS [Brow85]. The decision to base the design of a graphical extension on a preexisting subroutine system constrains the design of the language extension twofold. First, the preexisting subroutine system defines the minimal graphical facilities which must be provided by the high-level language. The functions available are specified in detail by the subroutine system, but the methods for providing them are left to the discretion of the language designer. Second, the subroutine system implicitly defines concepts which are an integral part of its philosophy (Figure 7). 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 a graphical extension delineates the syntactic framework within which the language extension must function. The syntactic framework defines the manner in which the features provided by the host language are specified by the user. The syntax design for a language extension should be orthogonal to the host language. The style should be internally consistent with that of the host, allowing programmers proficient in the host language to easily extend their knowledge to encompass the new capabilities added by the language extension. The host language also restricts the language extension by its basic structure, philosophy and design. For example in Pascal/VS, modules to be compiled separately must be defined in segments. Communication between Pascal segments and the main program is restricted to parameters passed to the procedures and functions declared therein and to variables defined as DEF or REF. All variables are 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 of abstract data types that are inherited by any extension to the language. ENUMERATION and SUBRANGE data types provide the security of range checking on the base type INTEGER. RECORDS of nonhomogeneous data types can be declared and used as elements in multidimensional arrays or in linked lists. Typed pointers 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 operations such as union, intersection and difference. All of these features are inherited when Pascal is selected as the host language for a graphical extension. Pascal/VS provides the syntactic base for the design of the EZ/GKS graphical extension. Complex data types can be built from the predefined graphical types, Pascal types and user-defined types in the usual manner provided by Pascal, allowing graphical types to be elements in multidimensional arrays, record structures or linked lists. 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 to a problem may become apparent when examining the problem from an appropriate level of abstraction [Pres82]. At the lowest level of abstraction, all of the procedural details are evident. At higher levels, the focus shifts to the essential elements of the problem; irrelevant low level details are disregarded. Viewing the problem from an appropriate level of abstraction permits alternative solutions to be examined in terms that are meaningful to the problem environment [Dyme84]. Regarding solutions in meaningful terms can assist in determining the best one for the problem. Early graphics programming systems viewed graphical concepts at a very low level of abstraction. Graphical output was generated by numerous MOVE-TO, PEN-UP and PEN-DOWN commands. All attributes were specified individually in a device-dependent manner. During the past decade, research in computer graphics has elevated the level of abstraction by introducing such concepts as output primitives, workstations, segments and attribute bundles. Graphics programming, however, still requires attending to tedious detail at a much lower level of abstraction. For example, while the language bindings for GKS define a multitude of data types describing the parameters passed in GKS subroutine calls, no operations on the data types are provided. Therefore, the only operations available are the low-level operations for the general purpose data types provided by the host language, directing the focus on the internal representation of the graphical types rather than on their conceptual use. The following two chapters describe methods by which the 19 EZ/GKS graphical extension elevates the level of abstraction for graphics programming, thereby easing the burden of developing application and application-oriented graphical software. The graphical data types provided by the EZ/GKS 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 as a useful construct for organizing and manipulating graphical data. An abstract data type represents 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 be classified as either an individual or a compound type. Unlike many previously developed graphical languages, a data type in EZ/GKS does not represent a geometric shape such as a circle, square or triangle. Instead, an individual graphical type is an atomic element representing a well-defined concept useful in graphics programming, such as a segment, window or colour (Figure 8A). A compound graphical type represents 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, complex user-defined data types may be constructed from any of the predefined graphical data types, in the usual 20 A. Individual Data Types B. Compound Data Types POINT POLYPOINT WKSTN WKSTNSET SEGMENT SEGMENTSET WINDOW NORMXFORM COLOUR PATTERN SEGXFORM BUNDLE Figure 8 - Abstract Data Types i n EZ/GKS manner provided by Pascal. Graphical types may be elements of multidimensional arrays, record structures or linked lists. The atomic graphical elements within a complex structure may be addressed by using the standard Pascal path notation. The characteristics of the individual and 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). Several of these data types have proved useful in previous graphical language extensions. For example, many high-level graphical languages have a representation for a point or vector [Smit71] [MaTh81]. In addition to the vector type, 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 a location, is the basis for defining the shape of graphical output primitives. 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 represents the concept of an abstract graphical workstation as defined by GKS. The GKS workstation is device independent, providing a "logical interface through which the application program controls physical devices" [IS085a]. Unlike all other graphical data types defined in EZ/GKS, workstations are defined as Pascal structured constants. 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 of display elements that can be manipulated as a unit" [IS085a]. EZ/GKS maintains compatibility with the segment concept defined in GKS. Thus, SEGMENT variables are handled as autonomous units. A segment is created by defining a sequence of output primitives within the body of the high-level C R E A T E statement. Once created, the internal representation can not be altered with operations that add or delete primitives from the original segment. The appearance of the graphical output, however, may be changed geometrically by applying segment transformations or visibly by altering the segment's attributes. The WINDOW data type represents a generalized two-dimensional rectangle aligned with the coordinate axes. A window variable may represent either a window, viewport, workstation window or workstation viewport in EZ/GKS. Which 22 of these the variable represents is determined by its context within a high-level graphical statement. Window variables representing a window are defined in World Coordinates (WC), while those representing a viewport or workstation window are described in Normalized Device Coordinates (NDC). Window variables representing a workstation viewport are defined by the user in Device Coordinates (DC). Normalization and workstation transformations describe a mapping between the different coordinate spaces (eg., WC -> NDC -> DC). In EZ/GKS 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. GKS subroutine calls are issued to store the necessary colour values in the workstation colour table of each workstation. The colour attribute of output primitives is specified by the integer index referencing the entry of the workstation colour table containing the desired colour value. Hence, the programmer must remember the current status of all workstation colour tables in order to select the desired index. EZ/GKS provides the data type COLOUR to elevate the method by which colour attributes are managed by the application programmer. The COLOUR data type represents what the name implies. A limited number of system constants of data type COLOUR are predefined by the EZ/GKS system (Figure 9A). Incorporation of a system such as the Artist's Colour Naming System (ACNS) would be a useful addition to EZ/GKS, as it provides a natural representation for a much broader 23 A. EZ/GKS Colour Constants B. Example of ACNS Colours RED YELLOW GREEN MAGENTA BLUE CYAN BLACK WHITE BRILLIANT ORANGE-YELLOW PALE BLUISH-GREEN BLACKISH BLUE DEEP PURPLE -RED VERY LIGHT GREY DARK GREYISH ORANGE MEDIUM RED VIVID GREENISH-YELLOW Figure 9 - Colour Specif icat ion i n EZ/GKS compared to the ACNS range of colour constants [Kauf86] (Figure 9B). User-defined values for variables of data type COLOUR may also be computed from colour constants and colour variables using a graphical colour expression (Section 4.3). High-level referencing to workstation tables elevates the manner in which workstation tables are initialized and altered by the programmer (Section 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 transformation variables using a graphical segment expression (Section 4.3). 3.2 Compound Graphical Types Compound graphical data types represent multiple occurrences of an individual graphical element. 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, representing a number of selected individual graphical variables. A variable of type WKSTNSET contains a set of workstations to be referenced as a unit in high-level graphical statements. Similarly, a variable of type SEGMENTSET refers to a set of segments to be manipulated simultaneously. Values for variables of these data types are defined by assigning variables of their related individual graphical type (ie. WKSTN or SEGMENT, resp.) in the standard Pascal set-constructor format. Expressions of workstation sets or segment sets may compute a new set membership using any of the set operators defined by the host language. The set operators union, intersection, difference, exclusive union and all relational set operators are inherited by the 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. A variable number of points may be stored in a POLYPOINT variable, up to the maximum permitted by the GKS implementation. A series of values may be assigned to a POLYPOINT variable using the structured point assignment (Section 4.1). Individual points may be 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 graphical output primitive. The POLYPOINT value assignment allows values for POLYPOINT variables to be initialized at compile time, assisting with the definition of non-uniform shapes (Figure 10). The POLYPOINT value assignment, similar to ordinary value assignments, may appear within any Pascal/VS value declaration. 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 (Section 4.1). This declaration form provides a concise method for initializing the geometric shapes of asymmetric graphical objects at compile time. A normalization transformation "maps positions in the world coordinates to normalized device coordinates " [IS085a]. 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 the viewport in NDC. The current normalization transformation may be set by naming a NORMXFORM variable 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. The workstation pattern table is an array of pattern values. 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 later be selected by referencing the appropriate index of the workstation pattern 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. The appearance of a pattern specified by a numeric index will depend on the colour values stored in the colour table of the workstation in question. A pattern specified by a colour variable will be composed of identical colour values on each workstation on which it is displayed. The style type attribute of the fill 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 p r i m i t i v e (eg. l i ne , marker , f i l l or text). At t r ibutes may be c lass i f ied as either geometr ic or non-geometr ic . W h i l e geometr ic attributes define propert ies w h i c h affect the s i ze o r shape o f the ent i re p r i m i t i v e , n o n - g e o m e t r i c p r i m i t i v e attributes on ly affect the appearance o f a d isplay element. G K S works ta t ions ma in ta in four bundle tables, one for each type o f output p r i m i t i v e . A n entry i n a bundle table contains values for a l l non-geometr ic attributes associated w i t h the related p r imi t ive type. A va r i ab le o f data type B U N D L E contains values for the set o f nongeometr ic p r imi t ive attributes associated wi th one type o f output p r imi t ive (Figure 11). The structured bundle assignment s imp l i f i e s the assignment o f attribute values to a bundle var iab le . The bundle var iable may be subsequently referenced as a unit i n h i g h - l e v e l g r aph i ca l statements. 3.3 Summary E a c h graphical data type presented i n this chapter may be c lass i f ied as either an ind iv idua l or compound type. A n ind iv idua l graphical type represents an atomic LINE MARKER FILLAREA TEXT TYPE WIDTH COLOUR TYPE SIZE COLOUR INTERIOR STYLETYPE COLOUR FONTPRECISION EXPANSION SPACING COLOUR Figure 11 -Output Primitive Types and their Compatible Bundle Attributes 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. Chapter 4 expounds on the abstract graphical data types by describing the operations EZ/GKS provides for variables of each graphical data type. 29 Chapter 4 Operations on Graphical Data Types A high-level language may employ several methods to define the operations characterizing an abstract data type. Assignment statements may alter a variable's current value. The language syntax may be extended with additional high-level statements to manipulate the variables in a predefined manner. The symbols representing host language operators may be overloaded or new operators may be defined for expressions containing variables of the new data types. Specific characteristics of a variable may be returned to the programmer through the use of system-defined functions. A variety of these techniques have been incorporated into E Z / G K S to specify the operations on variables of the abstract graphical data types. Structured graphical assignments promote encapsulation of abstract graphical data types by defining a structured format in which a series of values may be assigned to certain types of graphical variables. High-level graphical statements control the generation of graphical output by defining operations on graphical variables. Graphical expressions provide a mechanism for computing the values for particular types of graphical variables. System-defined functions return to the user specific attributes of a graphical variable. These concepts are further examined in the following sections. 4.1 Structured Graphical Assignments A n essential element necessary for implementing an abstract data type is encapsulation. Encapsulation restricts access to the internal 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 to a graphical variable in a single assignment statement. Structured graphical assignments promote encapsulation by defining a format in which to specify a series of values to be assigned to certain types of graphical variables. The use of high-level syntax allows the programmer to initialize variables of complex graphical data types without knowledge of the internal representation of the data type. Encapsulation of graphical data types is enforced by the use of structured graphical assignments. Access to individual components of a graphical data type, except in the manner designated by the high-level 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, NORMXFORM structure, BUNDLE structure and PATTERN structure. Although the format of each structure differs, the syntax for each is representative of its related data abstraction. Organization and manipulation of point data is a fundamental operation in computer graphics. The POINT data type together with the point structure and point expressions (Section 4.3) assist the programmer in manipulating point data in an intuitive manner. A POINT structure defines a sequence of one or more point elements. 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 structure is assignment-compatible with variables of data type POINT, WINDOW or POLYPOINT, provided that the semantically appropriate number of point elements are present in the structure. The point structure may also describe the shape of output primitives directly in output primitive commands such as LINE, MARKER and FILL (Section 4.2.1). A normalization transformation represents a mapping from a window defined in World 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 be assigned to graphical variables of type NORMXFORM (Figure 13). 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 GKS default of the unit square is Var Max : REAL; WCwindow : WINDOW; UpperRight : POINT; FigureX : POLYPOINT; Max := 12 .5 ; UpperRight := ( 2 5 , Max * 2 ) ; WCwindow := ( ORIGIN ; UpperR ight) ; FigureX := ( 1 2 . 5 , M a x ; UpperR ight ; . 12.5 , (Max * 2 ) ; 25 , 12.5 ) ; Figure 12 - Examples of Structured POINT Assignments 32 VAR WCWindow, NDC Window : WINDOW; NT1, NT2, NT3 : NORMXFORM; 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 to a BUNDLE variable, provides a high-level syntax for defining a set of nongeometric attributes related to a specific type of output primitive. The BUNDLE structure consists of a list of attribute specifications following a designated 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). The data type of an attribute's value depends on the primitive type and the attribute kind named (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 33 A pattern is a two-dimensional array of colours. The pattern structure allows the value of pattern variables to be defined by syntactically representing this intrinsic property (Figure 15). The pattern structure permits a list of rows of colours to be assigned to a PATTERN variable. 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 for a colour may be mixed within a given pattern structure. 4.2 Graphical Statement Types Graphical statements provide a user-friendly method for manipulating graphical data by performing a set of well-defined operations on the graphical variables named therein. Three categories of graphical statements are distinguished in EZ/GKS: graphical commands, graphical state changes and high-level references to workstation tables. Graphical commands specify how graphical data is defined and determine where it is stored and displayed. Graphical state changes alter the graphical environment by changing the global values that govern the final appearance of the graphical data. High-level references to workstation tables elevate the manner that workstation-dependent attributes, colours and patterns are managed by the programmer. Each of these categories are described in the following 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 Commands Graphical commands generate output primitives and manipulate graphical variables representing workstations and segments. Output primitive commands define the geometric properties of graphical output primitives and generate each primitive in its distinctive manner. Workstation commands control the graphical display on selected output surfaces, while segment commands provide for the creation, deletion, storage and display of graphical segments. Output primitive commands provide a simple method of generating the output primitives of GKS. The commands LINE, MARKER and FILL generate the GKS Polyline, Polymarker and Fill Area primitives, respectively, the shape of which is defined by a polypoint variable or a point structure. The subrange specification may be used to restrict output to a subset of the points provided. The TEXT 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. Workstation commands provide control over display surfaces (Figure 16A). A high-level graphical statement which operates on WKSTN variables may also manipulate variables containing sets of workstation elements. 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 A. WKSTN Statement Types B. SEGMENT Statement Type3 OUTPUT CREATE MESSAGE DELETE CLEAR RENAME REDRAW SAVE UPDATE DISPLAY INSERT Figure 16 - High- leve l Statements to Manipulate WKSTN and SEGMENT Var iables as segment sets. As with workstation sets, the requested operation referencing a segment set variable is performed once for each segment in the set. Implicit regeneration is temporarily disabled during a segment set operation, preventing the display surface from being redrawn until the set operation is completed. Graphical output may be generated either modally or explicitly. Modal output causes display on all active workstations as the graphical primitives are being defined. 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 provide a simple manner for requesting either modal or explicit output. 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. The ALSO option generates output on those named in the command in addition to the workstations that are currently active. The necessary workstations are automatically activated and deactivated when an OUTPUT statement block is entered and restored upon exiting the block. 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 otherwise directed by the modal OUTPUT statement. 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 Storage Var ClassA, Teacher A : WKSTNSET; OUTPUT ON Clas3A ALSO Begin { display the next problem ) NextProblem (ProblemNbr); OUTPUT ON TeacherA ONLY NextAnswer (ProblemNbr) { display the related answer } End; Figure 17 - Example of Nested OUTPUT Commands i 37 (WDSS), using a SAVE 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 DELETE 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) on which they are to be shown. 4.2.2 Graphical State Changes Graphical state changes alter the graphical environment by changing the global state of GKS or by altering the state of individual workstations or segments. The state of GKS, workstations and segments in turn determine the manner in which graphical output is displayed by defining transformations, attributes and other settings that govern its final appearance. A unique state change operator has been created to distinguish graphical state changes from ordinary Pascal and EZ/GKS commands. The operator's symbol is "<-" and can be read as "is set to". Statements using the state change operator set transformations, attributes and miscellaneous other global graphical variables used by GKS. Three kinds of transformations alter the final appearance of graphical output: the normalization transformation, workstation transformation and segment transformation. All three kinds are set using the TRANSFORM 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 mapping (Figure 18A). A simple method is thus provided for setting the current normalization transformation by selecting one of possibly several normalization transformation variables defined in an 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). The window variable identified in the FROM clause is the workstation window specified in NDC. The variable identified in the TO clause 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). When a segment set variable is referenced, implicit regeneration is disabled until the set VAR NT1 : NORMXFORM; F loorP lan : SEGMENTSET; PlanSize : SEGXFORM; Planners : WKSTNSET; Zoom, Show : WINDOW; A. Normal izat ion Transformat ion TRANSFORM NT <- NT1; B. Workstat ion Transformat ion TRANSFORM Planners <- FROM Zoom TO Show; C. Seg me nt T ra nsfo r mati o n TRANSFORM FloorP lan <- PlanSize; Figure 18 - Examples of the TRANSFORM Statement 39 operation is complete, allowing all segments to be transformed before the display surface is 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 is obtained from the individual attribute stored in the GKS state list. Individual attributes appear as similar as possible on all workstations. If the ASF indicates BUNDLED, the value is obtained from a bundle table entry in the workstation. The appearance of a bundled attribute may differ from workstation to workstation. In GKS, the ASF's are maintained in a single array and are set by a single subroutine call. 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 segment attributes as well as individual primitive attributes (Figure 19B). Segment attributes are altered by referencing a segment or segment set variable in an ATTRIBUTES statement followed by a list of segment attribute kinds, each with its related value. Individual primitive attributes may be specified in two ways: by referencing a bundle variable containing the desired attribute values or by listing the attribute values in a format similar to a BUNDLE structure. Unlike the BUNDLE structure, however, the attribute types listed in an ATTRIBUTES statement may be either geometric or 40 A. ASF Statement ASF of Line <- indiv idual EXCEPT Colour; B. ATTRIBUTES Statement ATTRIBUTES of Line <- (Type IS "DOTTED"; Width IS 2 . 0 ) ; C. BUNDLE Statement BUNDLE of Line <- 2; Figure 19 - Example of the ASF, 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 the value for the segment priority, deferral mode and clipping. 4.2.3 High-Level References to Workstation Tables In each GKS workstation capable of output, six tables retain the values of workstation-dependent attributes. The colour table is an array of RGB colour values. The pattern table is an array of pattern values, each of which is 41 represented by a two-dimensional array of indices referencing entries in the workstation colour table. The other four tables are bundle tables, one for each type of output primitive, containing bundles of nongeometric attributes. In the bundle tables, 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. Every table entry to be referenced must be defined by a GKS subroutine call. 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 and high-level graphical statements. The graphical variables COLOUR, PATTERN and BUNDLE retain complex attribute values initialized by structured graphical assignments. The high-level statements STORE, CHANGE, FIND 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. Subsequent reference to the variable's name will be interpreted by the pre-compiler to 42 CONST Wk3tn1 = ( f i l eA , 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 lue ,Green TO Wks tn2 ; B. SEND ( Red TO W k s t n l ; Blue TO Wks t n2 ) ; Figure 20 - Examples of the SEND Statement reference the appropriate workstation table index. The second format associates a different variable with each workstation set named. A workstation table index free on all workstations is selected. The value stored in this table entry in each workstation is determined by its associated graphical variable. 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 CHANGE 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. When a CHANGE statement defines a new value for a graphical variable, its value is changed in all workstation tables to which the graphical variable had been sent. The CHANGE statement provides a concise method for altering the values in workstation tables. The RELEASE statement frees the variable named from the indicated group of workstations. 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. The value in the workstation table remains unchanged until it is selected by the system for use in a subsequent SEND statement. 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 methods defined by GKS, assisting the programmer with initializing, altering and referencing workstation tables. 4.3 Graphical 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 overloaded to permit addition and subtraction of point variables. The default order of evaluation is the same as Pascal: from left to right. 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 COLOUR variables (Figure 21B). 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 transformation factors (Figure 21C). Segment transformation factors allow specification of uniform or differential scaling, rotation, translation, shearing and reflection in an easy manner (Figure 22). Any series of 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 45 SEGXFORM variables and segment transformation factors may be accumulated in a segment transformation expression. 4.4 System-Defined Functions System-defined functions in EZ/GKS relay information about a graphical variable to the programmer (Appendix C). System-defined functions also defend encapsulation of abstract data types by defining an interface through which communication with the programmer is channeled, thereby avoiding access to the internal representation of graphical variables. As a result, any subsequent change in the internal representation of graphical variables can be handled entirely within the EZ/GKS system and will require no change in graphical application programs using the system. 4.5 Summary In summary, the operations described on graphical variables in EZ/GKS include structured graphical assignments, high-level graphical statements, graphical expressions and system-defined functions. Structured graphical assignments defend the encapsulation of abstract graphical data types by defining structured formats in which to initialize certain types of graphical variables. High-level graphical statements define operations on graphical variables, alter the SCALE ROTATE SHIFT SHEAR REFLECT IDENTITY Figure 2 2 - Factor Types for Segment Transformations 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 system-defined functions return to the user specific information about a graphical variable. Together, these techniques elevate the level 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 pre-compiler is a portable Pascal program which generates the appropriate GKS subroutine calls from an application program containing high-level graphical statements. A Pascal program extended with graphical statements defined in the EZ/GKS syntax is the input for the pre-compiler. The output consists of a listing of two files: the original input program and a generated Pascal program including the necessary GKS subroutine calls and supporting code. The EZ/GKS pre-compiler was developed with the assistance of the 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 integrated description defines the language syntax by production rules specified in Backus Naur Form (BNF). Semantic actions are described by sections of Pascal code interlaced within the BNF. CWS-TD inserts the user-defined semantic actions into the generated translator at the designated places. Some modifications of the CWS-TD system were necessary to facilitate the development of the EZ/GKS translator. Minor modifications include the generation of the input file listing. The underscore is now permitted in identifier names. 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. Thus, all reserved words and identifiers used in EZ/GKS appear to be case insensitive as well. When implementing a language extension, a technique must be used to distinguish between statements of the host language and those of the graphical extension. Graphical statements defined by the 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, assuming that all others belong to the host language. Graphical statements can easily be identified as such if each statement is begun with a reserved word that is not reserved by the host language. Two problems arise when this method is used. One occurs when the first reserved word in a graphical statement is mistyped. 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. The second problem arises when the symbol terminating a host language statement is 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. Neither of these errors can be detected by the translator. Hence, no error message can be issued to warn the programmer. 49 A safer method for distinguishing statements of the host language from those of the graphical extension is used in the language LIG [BuDi82]. In LIG, both host statements and those of the graphical extension are positively identified by the initial reserved word in each statement. Graphical statements are translated while statements of the host language are copied without modification to the file of translated code. Statements which do not belong to either the host or extension can easily be identified as errors, thereby preventing the first problem described above. For assignment statements, LIG examines the first character of the assignment operator to determine whether the statement is a Pascal assignment or a graphical assignment. The operator ":=" distinguishes Pascal assignments while the operators "<-" and "<=" distinguish graphical assignments. The responsibility for deciding if an assignment statement is host or extension is thus shifted from the translator to the 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. In addition, the author believes that the responsibility for distinguishing between statements of the host language and graphical extension should rest with the translator, not with the application programmer. Because Pascal is a strongly typed language, the EZ/GKS graphical extension benefits by being strongly typed as well. By the data type of a variable, the translator can easily determine if an assignment statement belongs to the host language or to the graphical extension. The data type also assists with the 50 translation of graphical statements and the generation of meaningful error messages. The EZ/GKS translator parses both the host language and the graphical extension. In so doing, no statements are ever flushed to the output file, avoiding the problem of bypassing an erroneous statement without warning the programmer. By parsing Pascal, the translator is able to derive the data types of all variables declared. Information on the data type of variables referenced in high-level statements is valuable throughout the translation of EZ/GKS 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. When the flag is set, the previous symbol parsed is copied to the output file. The flag is manipulated as needed within the semantic actions of the integrated description, providing a mechanism to allow host-language statements to pass through the translator unchanged. The final modification to the CWS-TD 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. Variable references, factors and expressions are saved in the buffers. Each buffer is controlled by a boolean flag which is manipulated as needed from semantic actions within the integrated description. When a flag is set, symbols parsed are appended to the related buffer. The buffer can subsequently be referenced in semantic actions and inserted into the generated code in the appropriate places. 51 5.2 Translation Techniques The encapsulation of graphical data types is difficult to achieve when the Pascal language is chosen as the host language. As previously noted, the Pascal language is strongly typed. Therefore, all data types referenced in constant and variable declarations must be fully described in the data type declarations. Pointers are also typed. Thus, much of the implementation of graphical data types is visible in the translated code. The designer of EZ/GKS assumes that the application programmer does not alter the output from the pre-processor. The pre-processor prevents programmer access to the implementation of graphical variables from within the application's source code. To enforce the concept of encapsulation, the only use of graphical data types and variables permitted to the application programmer are those expressly designated by the syntax of the EZ/GKS language. 5.2.1 Simple Translation EZ/GKS begins translation of an application program by including the GKS constant and type declarations together with the external procedure declarations for the GKS subroutine calls. The declarations for predefined graphical data types referenced in the application program are subsequently generated with the declaration of numerous graphical variables reserved for internal use by the translator. The external procedure declarations for routines in the EZ/GKS run-time library are also 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 program. Subsequent calls to activate and deactivate workstations are generated throughout the program as implied by the high-level workstation commands. For example, if an explicit SEND statement references a workstation which is not currently active, EZ/GKS automatically activates it. After the segments have been transmitted, the workstation is returned to its original state. Workstations are automatically deactivated and closed upon leaving the main procedure. GKS is subsequently closed. Simple translation of a high-level statement into a GKS subroutine call is achieved using variables predefined by EZ/GKS and user-defined graphical variables as the actual parameters for the appropriate GKS subroutine calls (Figure 23). Frequently, assignment statements are generated to assign values to a predefined EZ/GKS variable. For example, when an output primitive command such as LINE, A. An EZ/GKS Statement CONST HomeWkstn = WKSTN (8, Tek4027) MESSAGE "** Er r o r i n Input Data * *' to HomeWkstn; B. Generated Code CONST HomeWk3tn = 1; VAR GXVString : string; GXVString:= '* * Er r o r in Input Data * *"; GMe3sageStr (HomeWkstn, length (GXVString), GXVString); Figure 23 - Simple Translation of an EZ/GKS Statement 53 MARKER or FILL is defined by a point structure, a statement is generated to assign each expression in the point structure to a sequential element of a predefined EZ/GKS array variable. 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 allow the programmer to designate an action to be performed on each member of the set(s) named. Translation of high-level statements referencing SEGMENTSET 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 set. Statements referencing both a segment set and workstation set variable require the generation of two nested FOR loops (Figure 24). A. An EZ/GKS Statement YAR BldgDesign: SEGMENTSET; Planners: WKSTNSET; DISPLAY BldgDesign TO Planners; B. Generated Code YAR BldgDesign: SEGMENTSET; Planners: WKSTNSET; GXYi, GXVj: INTEGER; FOR GXVi := 0 TO GXYMaxSetSize DO FOR GXVj := 0 TO GXCMaxSetSize DO IF (GXYi IN Planners) & (GXVj IN BldgDesign) THEN GCopySegWs (GXYi , GXVj ) ; Figure 2 4 - Translat ion Generated by References to Workstat ion and Segment Sets 54 5.2.2 The Run-Time Library and Inquiry Functions The code generated in Figure 24B is not sufficient to accomplish the action specified in Figure 24A. If output is requested on a workstation that is inactive, the action would not be visible on the workstation requested. In addition, if a workstation in the set allows implicit regeneration, its display surface may be redrawn after the receipt of each segment. The EZ/GKS run-time library contains procedures and functions that are useful repeatedly throughout the translated application program. All routine identifiers reserved for use by the translator begin with the prefix GX. In addition, the library contains the user-accessible 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 a simple interface (ie. the subroutine call) for requesting a complex operation. The subroutine call is 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 within the run-time library use GKS inquiry functions to determine the current state of GKS and of the individual workstations. For example, the function GXWsSet calls a GKS inquiry function to obtain a list of the workstations currently active or open. The list is converted into a workstation set and returned to the caller. The routine GXSuppR uses the set of active 55 workstations returned from GXWsSet and issues a GKS inquiry function to determine the deferral state of each workstation in the set. If the deferral state is allowed, a call is generated to temporarily suppress implicit regeneration. The routine GXRestR restores the deferral state of each workstation suppressed by GXSuppR to its original state. 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 in the Pascal binding of GKS are specified using a variety of enumerated data types and integers identifying different attribute styles. To allow consistent specification of attribute values, the values for all attribute types having enumerated set of values are defined by string constants or variables in EZ/GKS (Appendix B). The parameter to the GKS subroutine call defining the attribute's value is a call to a function in the run-time library returning an integer value. The value returned by the function call is coerced into the data type appropriate for the actual parameter being generated (Figure 25). This technique allows the programmer to indicate attribute values using mnemonic strings rather than integer values. Upon initialization of an EZ/GKS program, a procedure in the run-time library is called to read the Attribute Value File. The Attribute Value File contains a mnemonic name, context and integer value for each valid enumerated attribute value. Two arrays are created within the application program: the Context Limit Array 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 GSetF i l l ln tSty le (GTInter ior (GXAtrVal (GXYAr ray , GXVL imi tAr ray [ 13] . m in , GXYL imi tAr ray [ 1 3 ] . max, 'SOLI D ' ) ) ) ; Figure 25 - Translat ion Generated to Set an Attr ibute Value i beginning and ending indices within which the values for a given attribute type may be found in the Attribute Value Array. The Attribute Value Array stores the mnemonic names representing attribute values and an associated numeric value. When an attribute value is set by referencing a particular string, the routine GXAtrVal 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 style. No change in the EZ/GKS translator is required to accommodate additional attribute values. 5.2.4 Workstation Table Management Workstation tables 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 manner in which workstation tables are referenced by the programmer. High-level statements permit values to be specified by referencing a colour, pattern or bundle variable. If an ambiguity arises by referencing a graphical variable, the workstation index may be located with the help of the FIND command. Management of workstation tables is accomplished through the use of one Master Workstation Array (MWA) and six Index Arrays (IA), one for each type of workstation table. The MWA stores the union of all workstations to which a graphical variable has been sent and references an Index List. The Index List identifies 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 table. The Workstation Description Table in GKS stores the allowable number of table indices for each type of workstation. Inquiry functions in EZ/GKS access this information 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 MWA. 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 MWA is selected and the index value is stored in the variable. The 58 appropriate IA is searched to find the first index available on all workstations in the set. 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. A node in the Index List is updated or deleted. 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, the connection to all table indices is broken. The Index List is deleted and the associated MWA is designated as unused. The workstation set union in the IA is updated to show the new indices available and the value of the MWA 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 entry under which the variable's old value had been stored. The value in each workstation in the list is updated with the new value defined in the statement. The FIND command searches the Index Lists associated with the specified graphical variables to locate one index in common on all of the workstations. When an available index is located, its is returned. 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 statements assist the application programmer with the management of workstation tables. 59 Chapter 6 Conclusion This thesis has demonstrated the feasibility of elevating the functionality defined in the GKS subroutine system to a high-level graphical extension of a general-purpose programming language. Although the design of EZ/GKS is dependent on the features present in Pascal/VS, the concepts presented are essentially language independent. Equivalent functionality could be provided in other general purpose programming languages with varying degrees of difficulty. The GKS subroutine system has the advantage over a high-level language extension in being relatively language independent. The standard subroutine call is an interface mechanism available in most general purpose programming languages. A particular procedure defined in GKS requires little alteration from one language to another. As a result, a programmer proficient in using GKS through one language will have little trouble adapting this knowledge to use GKS in a different language. A high-level graphical extension is more dependent than a subroutine system on the features and facilities of the host language. As a result, an implementation of a high-level graphical extension providing similar functionality will vary more from one host language to another. The author believes, however, that the benefits of graphics programming using a high-level language far exceed this disadvantage. A high-level language extension is able to hide much of the detail required in GKS programming, making the high-level language easier to learn and use. 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. In EZ/GKS, the workstation data type may only be used to declare workstation constants while all other graphical data types may be only used to declare graphical variables. While the ability to define certain types of graphical constants could be added to EZ/GKS, the semantics of the graphical types prohibits complete compatibility with Pascal in this regard. In practice, this minor variation 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 for further investigation. First, the inquiry, error and metafile functions of level 2A were excluded from the scope of this work. While error and metafile functions are areas of small concern, finding a user-friendly manner to handle the 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 addressed. The ability to manage graphical input through a high-level extension to a general purpose programming language could revolutionize interactive graphics 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. Modifications to Pascal syntax diagrams n . Declaration of graphical data types III. Graphical initialization IV. Structured graphical assignments V. High-level graphical statements A. Graphical commands 1. Workstation commands 2. Output primitive commands 3. Segment commands B. Graphical State Changes 1. Transformations 2. Attribute specification 3. Miscellaneous settings C. High-level referencing to workstation tables VI. Graphical expressions VII. Summary of notation I. Modifications to Pascal/VS Syntax Diagrams 1. Constant-del: 64 - • C O N S T - >{ constant expr )-{ <workstation declaration> }- 1* 2. Type-del •TYPE- - ^ • { id }-j-^= . - • { typ e } graphical typo 3. Var-dcl •VAR- A A » { i d )-r^= r ^ l t vP e 1 L— • L^f <grar { <graphical typo } 4. Static-del •STATIC ^ i d ^ | • - | -»-( type } '• { <graphical typo } 1 5. Def-dcl = - T - ^ { type } '-•{ <graphical typo } 1*; 6. Value-del •VALUE- value assignment } ( <graphical value assignment } 7. Statement { statement }--•{ <graphical statements ) 8. Assignment-statement i •{ variable ) *—• { id : function •{ expr } <graphical expr> ) "{ <graphical initialization> } "{ <structured graphical assignments II. Declaration of graphical data types: <workstation declaration> ::= <variable*: wkstn> = WKSTN ( <integer>, <device typo ) <device typo ::= PLOTFILE I GKSMETAOUT I GKSMETAIN I TEK4027 I JUPITER7 I PRINTRONIX I QMS I < other device type > <graphical type> ::= POINT I SEGMENT I WINDOW I BUNDLE I COLOUR I POLYPOINT I SEGMENTSET I WKSTNSET I NORMXFORM I PATTERN I 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> ::= 0 I 1 I 2 I 3 I 4 I 5 I 6 I 7 I 8 I 9 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 { ; { <expr : point> I <expr : numerio * , <expr : numeno <normxform structuro { FROM <variable* : window> { TO <variable*: window> I EMPTY } I TO <variable* : window> } <bundle structure> <primitive typo <nongeometric attribute list> <primitive typo LINE I FILLAREA I MARKER I TEXT <nongeometric attribute list> ( <nongeometric attribute> { ; <nongeometric attributo } <nongeometric attribute> oiongeometric attribute typo IS <attribute value**> <nongeometric attribute typo T Y P E W I D T H C O L O U R S I Z E I N T E R I O R S T Y L E T Y P E F O N T P R E C I S I O N E X P A N S I O N S P A C I N G <pattern structure> < pattern element > { , < pattern element > }+ < pattern element > { , < pattern element > }+ <pattern elements <colour> <variable*: integer> <integer> <colour> <variable* : colour> <colour constant> <colour constants R E D I B L U E I M A G E N T A I B L A C K I G R E E N Y E L L O W C Y A N W H I T E 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 workstation> <messageto workstation> <clear workstation> <redraw workstations <update workstations <output to workstations OUTPUT T O workstation group> { O N L Y I A L S O } <statement > <message to workstation> M E S S A G E { <string > I -cvariable : string> } T O <workstation group> <clear workstations C L E A R <workstation group> { A L W A Y S I E M P T Y } <redraw workstation> R E D R A W <workstation group> <update workstation UPDATE <workstation group> { NOW I EMPTY } <workstation group> { <id : wkstn> I <variable* : wkstnseo } 2. Output primitive commands: <output primitive command> <line primitive> onarker primitivO <fillarea primitive> <text primitive> <cell array primitive> <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 { <string*> I <variable*: string> } AT <point> <cell array primitivO CELLARRAY IN <variable*:window> OF <pattern> <subrange> [ 1.. <integer value> ] I EMPTY <point> <variable : point> <point strucruro 3. Segment commands <segment command> <create segmeno <delete segments> <rename segmeno <save segments> <display segments> <insert segments <create segmeno CREATE <variable* : segment> <statement> <delete segments> DELETE <segment group> { FROM workstation group> I EMPTY } <segment group> •cvariable : segmeno I <variable : segmentseo <rename segmeno RENAME <variable* : segmeno TO <variable* : segmeno <save segments> SAVE <segment group> TO <workstation group> <display segmentss DISPLAY { <segment group> TO I EMPTY } workstation group> <insert segmeno INSERT <variable* : segmeno { WITH <variable* : segxforno I EMPTY } 74 B. Graphical state changes: <graphical state change> 1. Transformation: <transformation> 2. Attribute specification: <attribute specifications <set aspect source> <transformation> <attribute specification> <miscellaneous settings> ::= TRANSFORM { NT <- <variable*: normxform> I <segment group> <- <variable* : segxform> I workstation group> <-{ FROM <variable* : window> { TO <variable* : window> I EMPTY } I TO <variable*: window> } } <set aspect source> I <set attributes> I <select bundled attributes> ASF OF <primitive typo <- <attribute source> { EXCEPT <nongeometric attribute typo { , <nongeometric attribute typo } I EMPTY } <attribute sourco INDIVIDUAL I BUNDLED 7 5 <set attributes ATTRIBUTES OF { <primitive type> <- { <variable*: bundle> I <attribute list> } I <segment group> <- <segment attribute list> <attribute list> ( <attribute> { ; <attribute> } ) <attribute> <nongeometric attribute> I <geometric attributo <geometric attributo <geometric attribute typo IS <attribute value* *> <geometric attribute typo 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 typo HIGHLIGHTING I VISIBILITY <select bundled attributes BUNDLE OF <primitive type> <- { <integer> I <variable : integer> I <variable*: bundlo } 3. Miscellaneous settings: <miscellaneous settings> <set segment pnonty> <set implicit regeneration> <set deferral state> <set clipping> <set segment priority> PRIORITY O F <segment group> <- <real value> <set deferral> <defer list> D E F E R R A L O F <- { I ( <deferitem> workstation group> <defer item> <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 } U P D A T E T I M E IS { N O W I L A T E R } <set clippings CLIPPING <- { O N I O F F } 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> S T O R E { ( Workstation table entry> IN <workstation group> { ; workstation table entry> IN workstation group> workstation table list> IN <workstation group> 77 Workstation table entry> <variable* : colour> <variable*: patterns •cvariable* : bundle> <workstation table lists ( workstation table entry> { , workstation table entry> } ) <change workstation table entry> TO <expr: colour> CHANGE { <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> <segxform factor> : I I I I I <direction> : <expr: point> I <expr: colour> I <expr: segxform> <variable : point> { + <variable : pomt> I - <variable : point> } { <integer> I <variable* : integer> } { PART I PARTS } <colour> { + { <integer> I -cvariable* : integer> } { PART I PARTS } <colour> }+ { -cvariable* : segxform> I <segxform factor> } { + { <variable* : segxform> I <segxform factor> } } + SCALE { <realvalue> I <point> } FROM <point> ROTATE <real value> ABOUT <point> SHIFT <point> SHEAR <realvalue> % IN <direction> REFLECT IN <direction> IDENTITY 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 Nongeometric Output Primitive Attributes Primitive Attribute Type Data Type Values LINE TYPE STRING SOLID, DASHED, DOTTED, DASHDOT @ WIDTH REAL any >= 0 COLOUR COLOUR* any MARKER TYPE STRING DOT, PLUS, STAR. X, 0 @ SIZE REAL any >= 0 COLOUR COLOUR* any FILLAREA INTERIOR STRING HOLLOW, SOLID, PATTERN. HATCH STYLETYPE PATTERN* or any @ STRING COLOUR COLOUR* any TEXT FONTPRECISION font structure STRING ( font ; precision ) @ precision STRING STRING, CHAR, STROKE EXPANSION REAL any >= 0 SPACING REAL any COLOUR COLOUR* 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 B.2 Geometric Output Primitives Primitive Attribute Type Data Type Values FILLAREA PATTERNSIZE POINT any PATTERNSTART POINT any TEXT 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 B.3 Segment Attributes Attribute Type Data Type Values VISIBILITY HIGHLIGHTING STRING STRING VISIBLE, INVISIBLE NORMAL, HIGHLIGHT 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 lower right corner WINDOW POINT UpLeft Get upper left corner WINDOW POINT UpRight Get upper right corner 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 E Z G K S _ D e m o 1 ; * * * T h i s program d e m o n s t r a t e s the use o f the EZ/GKS p r e c o m p i l e r . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * CONST P r i n t e r = WKSTN ( 2 1 , QMS); TYPE N a t i o n R e c = r e c o r d f l a g : SEGMENT; p o s i t i o n : SEGXFORM; E n d ; N a t i o n = ( C a n a d a , USA, E n g l a n d , C h i n a , F r a n c e , Germany, USSR, J a p a n ) ; N a t i o n A r r a y = a r r a y [Canada . . Japan] o f N a t i o n R e c ; VAR A r r a y O f N a t i o n s S t a r P i Nat i o n A r r a y ; SEGMENT; r e a l ; PROCEDURE G e n e r a t e F 1 a g s (Var 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 G r e y : G A C o l A r r a y ; F l a g S i z e : POLYPOINT; PROCEDURE ComputeArc (CONST c e n t e r : POINT; CONST r a d i u s , a l p h a , b e t a : r e a l 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 : POLYPOINT); { T h i s r o u t i n e computes 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 between a n g l e s ALPHA and BETA. The d i r e c t i o n o f the 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 and the d i s t a n c e between the p o i n t s i s d e t e r m i n e d by the NBRPTS and the l e n g t h of the a r c r e q u e s t e d . The p o i n t s computed a r e s t o r e d i n the RESULT b e g i n n i n g w i t h the INITIALINDEX. } Var I i n t e g e r ; 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 Then If C l o c k W i s e Then i n c r e : = E1se i n c r e : = E l s e i f C l o c k w i s e Then 1ncre := E l s e i n c r e := - ( a l p h a -(2 * P i -( N b r P t s • - ( 2 * P i (NbrP ts ( a l p h a -b e t a ) / (NbrP ts - 1) ( a l p h a - b e t a ) ) / 1) - ( b e t a - D b e t a ) / - a l p h a ) ) / (NbrP ts - 1); F o r i := 0 to N b r P t s - 1 Do B e g i n 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 * c o s ( t e m p ) , 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 ) ) ; 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 ; E n d ; END; { Compute A r c > PROCEDURE D e t e r m i n e S i z e (Name : N a t i o n ; Var 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 based on the a s p e c t r a t i o s t o r e d . } CONST L e n g t h 20; TYPE A s p e c t A r r a y = STATIC A s p e c t R a t i o s VALUE A s p e c t R a t i os ARRAY [Canada : A s p e c t A r r a y ; Japan] o f r e a l ; a s p e c t A r r a y ( 0 . 5 , 0 . 5128 , 0 .5428 , 0 .67857 , 0 . 6 4 2 8 , 0 . 6 1 2 9 , 0 .57142 , 0 . 6 4 2 8 ) ; VAR bot tom r e a 1 BEGIN O u t L i n e bot tom Out 1i ne O u t L i n e O u t L i n e [5] := ( - 1 0 , 10; := ( l e n g t h * [3] := ( 10, [4] := ( -10 , 10, 10) ; A s p e c t R a t i os[name]) b o t t o m ) ; b o t t o m ) ; - 10; O u t L i n e [1 ] ; 00 END; { D e t e r m i n e S i z e } 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 ; Var 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 rom -1,-1 to 1,1 i n WC. I f 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 . O t h e r w i s e , an o u t l i n e i s c r e a t e d . } VAR S t a r U n i t s : WINDOW; S t a r N T : NORMXFORM; STATIC S t a r P o i n t s POLYPOINT; VALUE S t a r P o i n t s 0.95, -0.95, -0.95, -0.3 -0.3 0.3 0 , 0.95, 0.95, BEGIN C r e a t e S t a r S e g Beg i n A t t r i b u t e s of F i l l < S t a r U n i t s := (-1, -1 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 ; I f F i l l S t a r Then A t t r i b u t e s o f F i l l <-E l s e A t t r i b u t e s o f F i l l <-F i l l a t S t a r P o i n t s ; E n d ; { c r e a t e S t a r S e g } END; { C r e a t e S t a r > 3; 3); ( c o l o u r i s 0); 1, D; ( i n t e r i o r ( i n t e r i o r i s i s ' s o l i d ' ) ' h o i 1ow' ) ; PROCEDURE DoCanada ( o u t l i n e : POLYPOINT; VAR F l a g S e g { D e f i n e the n a t i o n a l f l a g o f Canada } SEGMENT); STATIC M a p l e L e a f POLYPOINT; VALUE M a p l e L e a f ( -o 3, -10 0 -0 3, -2 4; -3 3, -4 3; -3 3, -3 3 -5 8, -3 3; -4 4, -1 5; -5 8, -1 2 -4 0, 0 0; -7 9, 2 9; -6 9, 2 7 -8 3, 4 6; -5 8, 4 6; -6 3, 5 9 -2 0, 3 3; -2 0, 7 9; -1 0, 7 4 0 0, 9 4) VAR TempPT : POINT; TempPolyPt : POLYPOINT; BEGIN C r e a t e F l a g S e g B e g i n L i n e a t O u t L i 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 ' ) : F i l l a t M a p l e L e a f ; TempPt := ( 5 , 0 ) ; TempPolyPt := ( 0 u t l i n e [ 1 ] ; 0 u t l i n e [ 1 ] + TempPt; 0 u t l i n e [ 4 ] + TempPt; 0 u t l i n e [ 4 ] ) ; F i l l a t TempPolyPt ; TempPolyPt := ( 0 u t l i n e [ 2 ] - TempPt; 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 a t TempPolyPt ; Tex t ' C a n a d a ' a t ( -6 , - 8 ) ; E n d ; END; PROCEDURE DoUSA ( o u t l i n e : POLYPOINT; VAR 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 the U . S . A . } VAR 1, j : i n t e g e r ; 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 , 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 : POINT; 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 : b o o l e a n ; X i n c , Y i n c : r e a l ; 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; Ypos := - 1 0 ; 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); C r e a t e F l a g S e g B e g i n L i n e a t O u t L i n e ; F o r i := 1 to 7 DO B e g i n S t r i p e := ( - 1 0 , Y p o s ; 10, Y p o s ; 10, Ypos + 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 S t r i p e ; Ypos := Ypos + (2 * S t r i p e W i d t h ) ; 00 00 E n d ; C a n t o n ' : = (- 10, - 1 0 , F i l l a t C a n t o n ; C r e a t e S t a r ( t r u e Pos i t i on S t a r X F o r m 10; - 1 . 2 , 10; - 1 . 2 , (7 * S t r i p e W i d t h ) ) ; (7 * S t r i p e W i d t h ) ; S t a r S e g ) ; ( -10 + X i n c , 10 - Y i n c ) ; S c a l e 0 . 3 f rom o r i g i n + S h i f t p o s i t i o n ; = t r u e ; 0 ) ; 0 ) ; = ( X i n c = ( Y i n c t o 9 Do I n s e r t S t a r S t e p R i g h t StepDown F o r j := 1 Beg i n SaveXform := S t a r X f o r m ; F o r i := 1 to 11 Do B e g i n If I n s e r t S t a r 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 ; I n s e r t S t a r := not I n s e r t S t a r ; S t a r X f o r m := S t a r X f o r m + S h i f t S t e p R i g h t ; End; S t a r X f o r m : = SaveXform + S h i f t StepDown; END; E n d ; T e x t ' U . S . A . E n d ; { DoUSA } a t ( - 6 , - 8 ) ; PROCEDURE D o F r a n c e ( O u t L i n e : POLYPOINT; Var 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 o f F r a n c e } VAR S t r i p e W i d t h : r e a l ; V e r t l n c r e , TwoByTwo : 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 , 0 ) ; C r e a t e F l a g S e g Beg i n L i n e a t O u t l i n e ; A t t r i b u t e s of 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) ; F i l l a t ( 0 u t 1 1 n e [ 1 ] ; 0 u t l i n e [ 1 ] + V e r t l n c r e ; 0 u t l i n e [ 4 ] + V e r t l n c r e ; 0 u t l i n e [ 4 ] ) ; A t t r i b u t e s of F i l l <- ( i n t e r i o r i s ' p a t t e r n ' ; S t y l e T y p e i s ' g r e y ' ; P a t t e r n s t a r t i s o r i g i n ; 00 P a t t e r n S i z e i s TwoByTwo); F i l l a t ( O u t l i n e [ 2 ] ; 0 u t l i n e [ 3 ] ; 0 u t l i n e [ 3 ] - V e r t l n c r e ; 0 u t l i n e [ 2 ] - V e r t l n c r e ) ; T e x t ' F r a n c e ' a t ( - 6 , - 8 ) ; E n d ; END; { D o F r a n c e } PROCEDURE D o E n g l a n d ( O u t L i n e : POLYPOINT; Var 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 o f E n g l a n d } VAR L o w L i m i t , C e n t e r , Y i n c r e l , Y 1 n c r e 2 , L e f t s i d e , R i g h t S i d e : 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 : i n t e g e r ; BEGIN L o w L i m i t := 0 u t l i n e [ 4 ] ; Midy := Ycoord(1 o w l i m i t ) / 2; C e n t e r := ( 0 , M i d y ) ; 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 , M i d Y ) ; R i g h t S i d e := (10, M i d Y ) ; C r e a t e S t r i p e B e g i 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 i s ' s o l i d ' ; c o l o u r i s 0 ) ; F i l l a t ( L e f t s i d e + Y i n c r e 2 ; R i g h t S i d e + Y i n c r e 2 ; R i g h t S i d e - Y i n c r e 2 ; L e f t s i d e - Y 1 n c r e 2 ) ; 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 a t ( L e f t s i d e + Y i n c r e l ; R i g h t S i d e + Y i n c r e l ; R i g h t S i d e - Y i n c r e l ; L e f t s i d e - Y i n c r e l ) ; E n d ; C r e a t e C r o s s B e g i n F i l l a t ( c e n t e r ; 0 , MidY - 0 . 5 ; - 1 0 , Ycoord(1 o w l i m i t ) - 0 . 5 ; l o w l i m i t ) ; E n d ; C r e a t e F l a g S e g B e g i 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 i s ' s o l i d ' ; c o l our i s 1); L i n e a t 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 a t ( 0 u t l i n e [ 2 ] + Y i n c r e l ; 0 u t l i n e [ 2 ] - Y i n c r e l ; O 0 u t l i n e [ 4 ] - Y i n c r e l ; 0 u t l i n e [ 4 ] + Y i n c r e l ) ; F i l l a t ( O u t l i n e [ 1 ] + Y i n c r e l ; O u t l i n e [ 1 ] - Y i n c r e l ; 0 u t l i n e [ 3 ] - Y i n c r e l ; 0 u t l i n e [ 3 ] + Y i n c r e l ) ; C r o s s X f o r r a := ' ' ; F o r i := 1 to 4 Do B e g i n I n s e r t C r o s s w i t h C r o s s X f o r m ; 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 C e n t e r ; E n d ; S t r ipeXform := ' ' ; I n s e r t s t r i p e w i t h S t r i p e X f o r m ; S t r i p e X f o r m := S t r i p e X f o r m + R o t a t e P i about C e n t e r ; T e x t ' E n g l a n d ' a t ( - 6 , - 8 ) ; E n d ; END; { D o E n g l a n d } PROCEDURE D o C h i n a ( O u t L i n e : POLYPOINT; Var 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 o f C h i n a } VAR i i n t e g e r ; P o s i t i o n : SEGXFORM; A n g l e , I n c r e : 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 ' s o l i d ' ) ; C r e a t e F l a g S e g B e g i n F i l l a t O u t L i n e ; P o s i t i o n := S c a l e 2.1 f rom O r i g i n + S h i f t ( - 7 , 4 . 4 2 ) ; I n s e r t S t a r w i t h P o s i t i o n ; A n g l e := 0 .25 * 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 .53 f rom 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 . 4 2 ) ; F o r 1 := 1 to 4 Do B e g i n I n s e r t S t a r w i t h 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 Ang le about ( - 7 , 4 . 4 2 ) ; E n d ; T e x t ' C h i n a ' a t ( - 6 , - 8 ) ; E n d ; END; { D o C h i n a } PROCEDURE DoGermany ( O u t L i n e : POLYPOINT; Var 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 o f Germany } VAR F l a g W i d t h , Bandwidth : R e a l ; L o w L i m i t , TwoByTwo : P o i n t ; 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 ) ) ; BandWidth := F l a g W i d t h / 3; C r e a t e F l a g S e g B e g i n 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 ( - 10 , 10; 10, 10; 10, 10 - BandWidth; - 1 0 , 10 - BandWid th ) ; 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 ' ; S t y l e T y p e i s ' g r e y ' ; P a t t e r n S i z e i s TwoByTwo; P a t t e r n S t a r t i s o r i g i n ) ; F i l l a t ( - 1 0 , 10 - BandWidth; 10, 10 - BandWidth; 10, 10 - (2 * B a n d W i d t h ) ; - 1 0 , 10 - (2 * BandWidth) ); T e x t 'Germany ' a t ( - 6 , - 8 ) ; E n d ; END; PROCEDURE DoUSSR ( O u t L i n e : POLYPOINT; Var 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 o f 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; S t a r X f o r m : SEGXFORM; STATIC Hammer, C y c l e : POLYPOINT; VALUE Hammer := ( - 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 { C o m p u t e C y c l e ( c y c l e ) ; } C r e a t e S t a r ( f a l s e , S t a r S e g ) ; 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 from O r i g i n + S h i f t S t a r P o s i t i o n ; C r e a t e F l a g S e g to B e g i n A t t r i b u t e s of 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) ; F i l l a t O u t l i n e ; 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 ; A t t r i b u t e s o f F i l l <- ( c o l o u r i s O); F i l l a t Hammer; { F i l l a t C y c l e ; } T e x t ' U . S . S . R . ' a t ( - 6 , - 8 ) ; E n d ; END; < DoUSSR > PROCEDURE DoJapan ( O u t L i n e : POLYPOINT; Var 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 Japan } VAR C i r c l e : POLYPOINT; BEGIN C r e a t e c 1 a g S e g B e g i n L i n e a t O u t L i n e ; ComputeArc ( o r i g i n , 5, 0 , 2 * P i , t r u e , 1, 100, c i r c l 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 ' ) ; F i l l a t C i r c l e ; T e x t ' J a p a n ' a t ( -6 , - 8 ) ; E n d ; END; { DoJapan } BEGIN C 1 i pp1ng <- ' o n ' ; A t t r i b u t e s o f Tex t <- ( h e i g h t i s 2 0 . 0 ; e x p a n s i o n i s 1 .5) ; 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 ) ; D e t e r m i n e S i z e (Canada , F l a g s i z e ) ; DoCanada ( F l a g S i z e , N a t n A r r [ C a n a d a ] . 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 , N a t n A r r [ U S A ] . F 1 a g ) ; D e t e r m i n e S i z e ( E n g l a n d , F l a g s i z e ) ; D o E n g l a n d ( F l a g S i z e , N a t n A r r [ E n g l a n d ] . F 1 a g ) ; D e t e r m i n e S i z e ( C h i n a , F l a g s i z e ) ; DoCh ina ( F l a g S i z e , N a t n A r r [ C h i n a ] . F 1 a g ) ; D e t e r m i n e S i z e ( F r a n c e , F l a g s i z e ) ; D o F r a n c e ( F l a g S i z e , N a t n A r r [ F r a n c e ] . F 1 a g ) ; D e t e r m i n e S i z e (Germany, F l a g s i z e ) ; DoGermany ( F l a g S i z e , N a t n A r r [ G e r m a n y ] . F 1 a g ) ; 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 , N a t n A r r [ U S S R ] . F 1 a g ) ; D e t e r m i n e S i z e ( J a p a n , F l a g s i z e ) ; DoJapan ( F l a g S i z e , N a t n A r r [ J a p a n ] . F 1 a g ) ; END; { G e n e r a t e F 1 a g s } PROCEDURE G e n e r a t e P o s i t i o n s (Var 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 g e n e r a t e s 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 a r e a l s o s t o r e d i n the N a t n A r r a l o n g w i t h the r e l a t e d f l a g segment to which they w i l l be a p p l i e d . } Var i n a t i o n ; a n g l e , i n c r e : r e a l ; I n i t L o c a t n : SEGXFORM; BEGIN I n i t L o c a t n := ROTATE - 0 . 5 ABOUT O r i g i n + TRANSLATE (40, 0 ) ; A n g l e := 0 .125 * P i ; I n c r e := 0 .25 * P i ; F o r 1 := Canada to Japan Do B e g i n I n i t L o c a t n := I n i t L o c a t n + ROTATE A n g l e ABOUT o r i g i n ; N a t n A r r [ i ] . p o s 1 t i o n := I n i t L o c a t n ; I f i = C h i n a Then B e g i n A n g l e : = 0 .125 * P i ; I n i t L o c a t n := ROTATE - 0 . 5 ABOUT O r i g i n TRANSLATE ( -40 , 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 ; E n d ; { F o r Stmt > END; { G e n e r a t e P o s i t i o n s } PROCEDURE D i s p l a y E x h i b i t ( 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 g e n e r a t e s the g r a p h i c a l o u t p u t u s i n g the 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 d e f i n e d . ) VAR E x h i b i tU n i t s , E x h i b i tNT E x h i b i t NDCUni ts WINDOW; NORMXFORM; SEGMENT; 1 nat i o n ; BEGIN F o r I := Canada t o Japan Do B e g i n D i s p l a y N a t n A r r [ i ] . f 1 a g to P r i n t e r ; C l e a r P r i n t e r ; E n d ; E x h i b i t U n i t s := ( - 100 , - 6 5 ; 100, 6 5 ) ; NDCUni ts := ( 0 . 0 6 8 1 , 0 . 0 9 3 7 5 ; 0 . 9 3 1 8 , 0 . 8 4 2 7 5 ) ; E x h i b i t N T := FROM E x h i b i t U n i t s TO N D C U n i t s ; TRANSFORM NT <- E x h i b i t N T ; C r e a t e E x h i b i t ; Beg 1 n F o r i := Canada to Japan Do I n s e r t N a t n A r r [ i ] . f 1 a g w i t h N a t n A r r [ i ] . p o s i t i o n ; A t t r i b u t e s of Tex t <- ( h e i g h t i s 130 .0; e x p a n s i o n i s 2 . 0 ; s p a c i n g i s 0 . 5 ) ; T e x t ' P E A C E ' at ( - 1 0 , 30 ) ; T e x t ' O N ' at ( - 5 , 0 ); Tex t ' E A R T H ' at ( - 1 0 , - 3 0 ) ; E n d ; { 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; { D i s p l a y E x h i b i t } BEGIN { main > P i := 3 .141592 ; G e n e r a t e F 1 a g s ( A r r a y O f N a t i o n s ) ; G e n e r a t e P o s 1 1 i o n s ( A r r a y O f N a t i o n s ) ; D 1 s p l a y E x h i b i t ( A r r a y O f N a t i o n s ) ; END. program ezgks_demo1 ; {****************************************^ {** T h i s i s t h e program t r a n s l a t e d i n t o GKS s u b r o u t i n e c a l l s . **} % P r i n t O f f "/ . Include GKS_BASICS "/ . Include GKS_SEGMENTS "/ .Print On c o n s t G X C M a x S e t S i z e = 31; G X C M a x B u n d l e S e t S i z e = 10; GXCMaxATrVal = 50; GXCMaxAtrTypes = 26; t y p e G X T P r i m i t i v e = ( l i n e , marker , f l l l a r e a , g r a p h i c T e x t ) ; GXTSetRange = 0 . . G X C M a x S e t S i z e ; GXTEZSet = p a c k e d s e t of GXTSetRange; Wkstn = GXTSetRange; P o i n t = G R P o i n t ; G X T P o l y P o i n t R a n g e = O . . G C M a x P o i n t ; P o l y P o i n t = r e c o r d p o i n t s : G A P o i n t A r r a y ; max : G X T P o l y P o i n t R a n g e ; E n d ; C o l o u r = r e c o r d m a s t e r i n d e x : G T i n t O ; c o l o u r : G R c o l ; E n d ; P a t t e r n = r e c o r d m a s t e r i n d e x : G T i n t O ; RowLength , C o l u m n L e n g t h : i n t e g e r ; P a t t e r n ; G A C o l A r r a y ; C o l o u r S o u r c e : G A C o l A r r a y ; { 0 = c o l o u r t a b l e ; 1 = MWT; } E n d ; B u n d l e = r e c o r d m a s t e r i n d e x G T i n t O ; A t t r l n i t A r r a y [ 1 - 4 ] of b o o l e a n ; C o l o u r S o u r c e : I n t e g e r ; {0 = c o l o u r t a b l e ; 1 = MWT } A t t r i b u t e s GRPrimRep; E n d ; Segment = GXTSetRange; WkstnSet = G X T E Z S e t ; SegmentSet = G X T E Z S e t ; Window = r e c o r d v a l i d P e r c e n t : b o o l e a n ; c o r n e r : GRbound; E n d ; NormXform = G T i n t l ; SegXform = G A M a t r i x ; G X T W s O p e r a t i o n = (GXSave , G X R e s t o r e ) ; GXTTypeSave = ( G X O n l y , G X A l s o ) ; GXTWkstnSetType = (GXOpenWs, G X A c t i v e W s ) ; G X T A t r V a l R e c = r e c o r d AtrName : s t r i n g ; A t r V a l u e : i n t e g e r ; D e f e u l t F l a g : i n t e g e r ; E n d ; G X T A v A r r a y T y p e = a r r a y [1 . . G X C M a x A t r V a l ] of G X T A t r V a l R e c ; G X T C o n t e x t L i m i t = r e c o r d M i n , Max : i n t e g e r ; E n d ; G X T C t x A r r a y T y p e = a r r a y [ 0 . .GXCMaxAt rTypes ] of G X T C o n t e x t L i m i t ; c o n s t r e d = g r e e n = b l ue = yel1ow = magenta = c y a n = b l a c k = w h i t e = o r i g i n = C e n t r a l S e g S t o r e 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)) p o i n t (0.0, 0.0); = wkstn (0); i d e n t i t y = s e g x f o r m ( ( 1 .0 , 0 . 0 , 0 . 0 ) , ( 0 . 0 , 1 .0 , 0 . 0 ) ) ; G X V p o i n t , GXVpo in t2 : 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 w k s t n s e t ; G X V c o l o u r G X V p a t t e r n GXVbundle GXVsegment GXVwkstnset GXVsegmentset GXVwi ndow GXVnormxform GXVsegxform G X V f o n t p r e c G X V a l i g n G X V v e c t o r G X V s t r i n g G X V i , GXVj G X V M , GXVr2 : p o l y p o i n t ; c o l o u r ; p a t t e r n ; b u n d l e ; segment; w k s t n s e t ; s e g m e n t s e t ; w i ndow; normxform; s e g x f o r m ; G R F o n t P r e c ; GRa l1gn ; G A V e c t o r ; G A s t r i n g ; i n t e g e r ; r e a l ; GXVAsf GXVAvArray GXVLimi t A r r a y GXVAtr G A a s f ; GXTAVArrayType ; G X T C t x A r r a y T y p e ; t e x t ; F u n c t i o n GXSetMax (CONST NbrRange, NbrP ts : i n t e g e r ) : i n t e g e r ; E x t e r n a l ; P r o c e d u r e GXSetPt (CONST P t S e t : p o l y p o i n t ; VAR Pt : p o i n t ) ; E x t e r n a l ; P r o c e d u r e GXSetWin (CONST P t S e t : p o l y p o i n t ; VAR Win E x t e r n a l ; F u n c t i o n GXNTNum : i n t e g e r ; E x t e r n a l ; F u n c t i o n GXSegNum : i n t e g e r ; E x t e r n a l ; F u n c t i o n GXAddPT (CONST P T a , PTb E x t e r n a l ; F u n c t i o n GXSubPT (CONST P T a , PTb E x t e r n a l ; F u n c t i o n GXWsSet (CONST t y p e s e t : E x t e r n a l ; P r o c e d u r e GXSuppR (Var changedSet : W k s t n S e t ) ; E x t e r n a l ; P r o c e d u r e GXRestR (Const c h a n g e d s e t : W k s t n S e t ) ; E x t e r n a l ; w i ndow ); p o i n t ) : p o i n t ; p o i n t ) : p o i n t ; GXTWkstnSetType) : wks tnse t oo P r o c e d u r e GXStChg (op : GXTWsOpera t ion ; SaveMethod : GXTTypeSave; SaveSet : WkstnSet ) E x t e r n a l ; P r o c e d u r e G X S t a t e (op : GXTWsOpera t ion ; WkstnsNamed : W k s t n s e t ; SegSetOp : b o o l e a n ) ; E x t e r n a l ; P r o c e d u r e GXGetASF (Var a s f F l a g s : G A A s f ; A S F t y p e : G T a s f ; Pr imNbr : i n t e g e r ) ; E x t e r n a l ; P r o c e d u r e G X I n i t A v (CONST maxAtr , MaxCtx : i n t e g e r ; Var A V A r r a y : G X T A v A r r a y T y p e ; V a r L i m i t A r r a y : G X T C t x A r r a y T y p e ) ; E x t e r n a l ; 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 : GXTAvAr rayType ; CONST m i n , max; i n t e g e r ; CONST searchname : s t r i n g ) : E x t e r n a l ; P r o c e d u r e GXColExp (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 ; V a r E x p r C o l o u r : G R c o l ) ; E x t e r n a l ; 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 Xform2 : s e g x f o r m ) ; E x t e r n a l ; 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 ; E x t e r n a l ; F u n c t i o n Y c o o r d (CONST Pt : p o i n t ) : r e a l ; E x t e r n a l ; F u n c t i o n L o L e f t (CONST win1 : window) : p o i n t ; E x t e r n a l ; F u n c t i o n L o R i g h t (CONST win1 : window) : p o i n t ; E x t e r n a l ; F u n c t i o n U p L e f t (CONST win1 : window) : p o 1 n t ; E x t e r n a l ; F u n c t i o n U p R i g h t (CONST win1 : window) : p o i n t ; E x t e r n a l ; F u n c t i o n RedVal (CONST Co l Rec : c o l o u r ) : r e a l ; E x t e r n a l ; 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 ) : r e a l ; E x t e r n a l ; 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 ) : r e a l ; E x t e r n a l ; F u n c t i o n MaxPts (CONST P o l y P t R e c : p o l y p o i n t ) : i n t e g e r ; E x t e r n a l ; F u n c t i o n XMax (CONST P o l y P t R e c E x t e r n a l ; F u n c t i o n XMin (CONST P o l y P t R e c E x t e r n a l ; F u n c t i o n YMax (CONST P o l y P t R e c E x t e r n a l ; F u n c t i o n YMin (CONST P o l y P t R e c p o l y p o i n t ) : r e a l ; p o l y p o i n t ) : r e a l ; p o l y p o i n t ) : r e a l ; p o l y p o i n t ) : r e a l ; E x t e r n a l ; F u n c t i o n G e t P t (CONST P o l y P t R e c : p o l y p o i n t ; CONST Index : I n t e g e r ) : p o i n t ; E x t e r n a l ; F u n c t i o n GetWin (CONST NTNbr : normxform) : window; E x t e r n a l ; F u n c t i o n GetVP (CONST NTNbr : normxform) : window; E x t e r n a l ; F u n c t i o n RowLen (CONST P a t t R e c : p a t t e r n ) : i n t e g e r ; E x t e r n a l ; 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 ) : i n t e g e r ; E x t e r n a l ; c o n s t p r i n t e r = wkstn ( 1) ; t y p e n a t i o n r e c = r e c o r d f l a g : segment ; p o s i t i o n : segx form ; end n a t i o n = ( Canada , usa , england , c h i n a , f r a n c e , germany u s s r , j a p a n ) ; n a t i o n a r r a y = a r r a y [ Canada . ; japan ] of n a t i o n r e c ; a r r a y o f n a t i o n s : n a t i o n a r r a y ; s t a r : segment ; p i : r e a l ; p r o c e d u r e 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 ) ; v a r g r e y : g a c o l a r r a y ; f l a g s i z e : p o l y p o i n t ; p r o c e d u r e computearc ( c o n s t c e n t e r : p o i n t ; c o n s t 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 : i n t e g e r ; v a r r e s u l t : p o l y p o i n t ) ; pha , b e t a : r e a l i : i n t e g e r ; temp , i n c r e : r e a l ; h o l d p t : p o i n t ; b e g i n r e s u l t . m a x := 0 ; i f a l p h a >= b e t a t h e n 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 - b e t a ) / ( n b r p t s - 1 ) e l 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 ) e l s e i f c l o c k w i s e t h e n i n c r e : = - ( 2 * p i - ( b e t a - a l p h a ) ) / ( n b r p t s - 1 ) 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 ) ; f o r i := 0 t o n b r p t s - 1 do b e g i n 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 ) 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 ) ; h o l d p t := G X V p o i n t ; r e s u l t . p o i n t s [ i + i n i t i a l i n d e x ] := h o l d p t ; I f i + 1 n i t i a l i n d e x > r e s u l t . m a x Then r e s u l t . m a x := i + i n i t i a l i n d e x ; end end ; p r o c e d u r e 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 : p o l y p o i n t ) ; c o n s t l e n g t h = 2 0 ; t y p e a s p e c t a r r a y = a r r a y [ Canada j a p a n ] o f r e a l s t a t i c a s p e c t r a t i o s a s p e c t a r r a y v a l u e 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 .5128 , 0 .5428 , 0 .67857 0 .6428 , 0 .6129 , 0 .57142 , 0 .6428 ) v a r bo t tom r e a l b e g i n G X V p o l y p o i n 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 G X V p o l y p o i n 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 G X V p o l y p o i n t . m a x := out 1i ne bot tom G X V p o l y p o i n 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 G X V p o l y p o i n t . m a x := o u t l i n e . p o i n t s f 3] I f 3 > o u t l i n e . m a x Then o u t l I n e . m a x := G X V p o l y p o i n t . p o i n t s GXVpolypo i n t . p o i n t s G X V p o l y p o i n t . m a x := out 1 i n e . p o i n t s [ 4] I f 4 > o u t l i n e . m a x Then o u t l i n e . m a x := o u t l 1 n e . p o i n t s [ 5] I f 5 > o u t l i n e . m a x Then o u t l i n e . m a x := [ 1 ] . x := - 10 ; [ 1 ] . y := 10; [ 2 ] . x := 10 ; [ 2 ] . y := 10; 2; = G X V p o l y p o i n t ; ( l e n g t h * a s p e c t r a t i o s [ name ] ) -[ 1 ] . x := 10 ; [ 1 ] . y := bo t tom; 1 ; = G X V p o l y p o i n t . p o i n t s [ 1 ] ; 10 3; [ 1 ] . x t 1 ] . y 1 ; = G X V p o l y p o i n t = - 10 ; = bo t tom; p o i n t s [ 1 ]; = o u t l 1 n e . p o i n t s ! 1] 5; end ; p r o c e d u r e 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 ) v a r s t a r u n i t s : window s t a r n t : normxform O N3 s t a t i c s t a r p o i n t s p o l y p o i nt v a l u e s t a r p o i n t s := p o l y p o i n t ( G A P o i n t A r r a y ( G R P o i n t ( 0 . 9 5 , - 0 . 3 ) , G R p o i n t ( 0 . 0 , 1 . 0 ) , G R p o i n t ( - 0 . 9 5 , - 0 . 3 ) , G R p o i n t ( 0 . 9 5 , 0 . 3 ) , G R p o i n t ( - 0 . 9 5 , 0 . 3 ) , G R p o i n t ( 0 . 9 5 , - 0 . 3 ) , G R P o i n t ( 0 . 0 , 0 . 0 ) : 94) , 6 ): b e g i n s t a r s e g := GXSegNum; G C r e a t e S e g ( s t a r s e g ); b e g i n G S e t F i1 I C o l I n d ( 0 ) ; G X V p o l y p o i n t . p o i n t s [ 1 ] :x := - 1 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := - 1; G X V p o l y p o i n t . p o i n t s [ 2 ] . x := 1 ; G X V p o l y p o i n t . p o i n t s 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); s t a r u n i t s := 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 ); G S e l e c t N T r a n ( s t a r n t ) ; i f f i l l s t a r t h e n G S e t F i11 I n t S t y l e ( G T i n t e r i o r (GXAtrVa l (GXVAVArray , e l s e G S e t F i11 I n t S t y l e ( G T i n t e r i o r (GXAtrVa l (GXVAVArray , GXVi := GXSetMax (O, s t a r p o i n t s . m a x ) ; GF i l l ( G X V i , s t a r p o i n t s . p o i n t s ) ; G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) G X V L i 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 [ 13] .max, ' h o l l o w ' ) ) ) end ; G C l o s e S e g ; end p r o c e d u r e d o c a n a d a ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) s t a t i c m a p l e l e a f : p o l y p o i n t ; O v a l ue m a p l e l e a f G R P o i n t G R p o i n t G R p o i n t G R p o i n t GRpoi n t G R p o i n t GRpoi n t GRpoi n t GRpoi n t G R p o i n t GRpoi nt GRpoi nt G R p o i n t GRpoi nt GRpoi nt G R p o i n t G R p o i n t G R P o i n t p o l y p o i n t ( G A P o i n t A r r a y ( - 0 3 , - 1 0 . O ) -o 3 , - 2 . 4 ) -3 3 , " 4 . 3 ) -3 3 , - 3 . 3 ) - 5 8 , " 3 . 3 ) -4 4 , - 1 . 5 ) - 5 8 , - 1 . 2 ) -4 0 , 0 . 0 ) , -7 g . 2 .9 ) , - 6 9 , 2 .7 ) , -8 3 , 4 . 6 ) , - 5 8 , 4 . 6 ) , -6 3 . 5 .9 ) , -2 0 , 3 .3 ) , -2 0 , 7 .9 ) . -1 0 , 7 .4 ) , 0 . 0 , 9 4 ) , 0 . 0 , 0 .0 ) 83) 17 ); v a r temppt : p o i n t ; t e m p p o l y p t : p o l y p o i n t ; b e g i n 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 ); b e g i n GXVi := GXSetMax (0 , out 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 1 1 I n t S t y l e ( G T i n t e r i o r (GXAtrVa l (GXVAVArray , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; GXVi := GXSetMax (0 , m a p l e l e a f . m a x ) ; G F i l l ( G X V i , m a p l e l e a f . 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 ] . x := 5 ; 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 ) ; temppt := 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] := out 1 i n e . p o i n t s [ 1] ; G X V p o l y p o i n t . p o i n t s [ 2 ] := GXAddPT (out 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 (out 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] := out 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; 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 ) ; O GF i l l ( GXV1, 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 (out 1 1 n e . p o i n t s [ 2] , t e m p p t ) ; G X V p o l y p o i n t . p o i n t s [ 2] := out 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 (out 1 i n e . p o i n t s [ 3] , 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] := out 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 ) ; G X V s t r i n g := ' 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; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); end ; G C l o s e S e g ; end ; p r o c e d u r e dousa ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) ; v a r i , j : i n t e g e r ; 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 , c a n t o n : p o l y p o i n t ; 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 : p o i n t ; s t a r s e g : segment ; s t a r x f o r m , savex form : segxform ; i n s e r t s t a r : b o o l e a n ; x i n c , y i n c : r e a l ; b e g i n x i nc : = 0 . 4 ; y i n c := 0 .3065 ; l o w l i m i t := out 1 i n e . p o i n t s [ 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 ; ypos := - 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L i 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 [ 13] .max, ' S O L I D ' ) ) ) ; G S e t F i 1 I C o l I n d ( 1); 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 ); b e g i n GXVi := GXSetMax (0 , out 1 i n e . m a x ) ; O G P o l y l i n e ( G X V i , out 1 i n e . p o i n t s ) ; f o r i := 1 to 7 do beg i n 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 po i n t s [ 1] y = y p o s ; G X V p o l y p o i nt p o i n t s t 2] X = 10 ; G X V p o l y p o i n t p o i n t s C 2] y = y p o s ; G X V p o l y p o i n t p o i n t s t 3] X = 10 ; G X V p o l y p o i n t po i n t s [ 3] y = y p o s + 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 [ 4] X = - 10 ; G X V p o l y p o i n t p o i n t s [ 4] y = y p o s + s t r i p e w i d t h ; 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 ( G X V i , s t r i p e . p o i n t s ) ; ypos := ypos + ( 2 * s t r i p e w i d t h ) ; end G X V p o l y p o i nt p o i n t s [ 1] X = - 10 ; G X V p o l y p o i nt p o i n t s [ 1] y = 10; G X V p o l y p o i nt p o i n t s [ 2] X = - 1 . 2 ; G X V p o l y p o i nt p o i n t s [ 2] y = 10; G X V p o l y p o i n t p o i n t s [ 3] X = - 1 . 2 ; G X V p o l y p o i n t p o i n t s t 3] y = ( 7 * 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 [ 4] X = - 10 ; G X V p o l y p o i nt po1nts [ 4] y = ( 7 * s t r i p e w i d t h ) G X V p o l y p o i nt 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 ( G X V i , c a n t o n . p o i n t s ) ; c r e a t e s t a r ( t r u e , s t a r s e g ) ; G X V p o l y p o i n t . p o i n t s [ 1 ] .x := - 10+xinc ; G X V p o l y p o i n t . p o i n t s [ 1 ] y • : = 1 0 - y i n c ; 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 ) ; p o s i t i o n := G X V p o i n t ; GXVSegXform := 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, GXVSegXform); 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 (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, GXVSegxform); s t a r x f o r m := GXVsegxform; 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 ; 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 ) ; s t e p r i g h 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 ] . x := y i n c ; 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 ) ; s tepdown := G X V p o i n t ; f o r j := 1 to 9 do b e g i n GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, s t a r x f o r m ) ; savex form := GXVsegxform; f o r 1 := 1 to 11 do b e g i n i f i n s e r t s t a r 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 := not i n s e r t s t a r ; GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, s t a r 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; GXVPoint := 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 , 0 , G X V v e c t o r , WC, GXVSegxform); s t a r x f o r m := GXVsegxform; end GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, 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 tepdown; Gaccumtran (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, GXVSegxform); s t a r x f o r m := GXVsegxform; 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 ; 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; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); i— o end ; G C l o s e S e g ; end ; p r o c e d u r e d o f r a n c e ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) ; v a r s t r i p e w i d t h : r e a l ; v e r t i n c r e , twobytwo : p o i n t ; 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 ) ; twobytwo := 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; G C r e a t e S e g ( f l a g s e g ); b e g i n GXVi := GXSetMax (0 , out 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 1 1 I n t S t y l e ( 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 , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; G S e t F i 1 I C o l I n d ( 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 (out 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 (out 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] := out 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 ( G X V i , G X V p o l y p o i n t . 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L i 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 [ 13] .max, ' p a t t e r n ' ) ) ) ; G S e t F i 1 I S t y l e l n d ( G X A t r V a l ( G X V A V A r r a y , 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, ' g r e y ' ) ) ; G S e t P a t t e r n R e f P o i n t ( o r i g i n ) ; G X V v e c t o r [ 1 ] := twobytwo.x; G X V v e c t o r [ 2 ] := twobytwo.y; G S e t P a t t e r n S i z e ( G X V v e c t o r ) ; 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 [ 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] ; O 00 G X V p o l y p o i n t . p o i n t s [ 3] := GXSubPT (out 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 (out 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 ) ; G F i l l ( G X V i , G X V p o l y p o i n t . p o i n t s ) ; 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 ; 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 ; 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 ] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ) end ; G C l o s e S e g ; end p r o c e d u r e d o e n g l a n d ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) ; v a r l o w l i m i t , c e n t e r , y i n c r e l , y i n c r e 2 , l e f t s i d e , r i g h t s i d e : p o i n t ; midy , a n g l e : r e a l ; 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 i n t e g e r ; b e g i n l o w l i m i t := out 1 i n e . p o i n t s [ 4] ; midy := 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 := midy; 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 ; 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 l := 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 := midy; 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 ) ; l e f t s i d e := 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 := midy; 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; G C r e a t e S e g ( s t r i p e ) ; b e g i n 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; G S e t F i 1 I C o l I n d ( 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 , y i n c r e 2 ) ; 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 , y i n c r e 2 ) ; 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 , y i n c r e 2 ) ; 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 , y i n c r e 2 ) ) ; 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 ( G X V i , G X V p o l y p o i n t . p o i n t s G S e t F i 1 I C o l I n d ( 1); G X V p o l y p o i n t . p o i n t s G X V p o l y p o 1 n 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 GXVpo1ypo i n t . p o 1 n t s 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 ( G X V i , G X V p o l y p o i n t . p o i n t s ) 1] 2] 3] 4] ) GXAddPT GXAddPT GXSubPT (GXSubPT ( l e f t s i d e , y i n c r e l ) ; ( r i g h t s i d e , y i n c r e l ) ; ( r i g h t s i d e , y i n c r e l ) : ( l e f t s i d e , y i n c r e l ) ) ; end ; G C l o s e S e g ; c r o s s := GXSegNum; G C r e a t e S e g ( c r o s s ) ; b e g i n G X V p o l y p o i nt po i n t s [ 1] : = c e n t e r ; G X V p o l y p o i nt po i n t s [ 2] X := 0 ; G X V p o l y p o i nt 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 nt p o i n t s C 3] y := ycoord(1 o w l i m11 ) - 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 ( G X V i , G X V p o l y p o i n t . p o i n t s ) ; end ; G C l o s e S e g ; 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 ); b e g i n G S e t F I l 1 I n t S t y l e G S e t F i 1 I C o l I n d ( GXVi := GXSetMax G P o l y l i n e ( GXVi G S e t F i 1 I C o l I n d ( 0 ) ; G X V p o l y p o i n t . p o i n t s G X V p o l y p o i nt G X V p o l y p o i nt G X V p o l y p o i n t G X V p o l y p o i nt ( 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 , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; (0 , o u t l i n e . m a x ) ; o u t l i n e . p o i n t s ) ; .po i n t s . p o i n t s .po i n t s .max := 1] 2] 3] 4] GXAddPT GXSubPT GXSubPT (GXAddPT ( o u t l i n e . p o i n t s ! 2] ( o u t l i n e . p o i n t s ! 2] ( o u t l i n e . p o i n t s ! 4] , (out 1 i n e . p o i n t s [ 4] GXVi G F i l l GXSetMax (0 , 4 ) ; ( G X V i , G X V p o l y p o i n 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 G X V p o l y p o i n 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 G X V p o l y p o i n t . p o i n t s G X V p o l y p o i n t . m a x := GXV1 := GXSetMax (0 , G F i l l ( G X V i , G X V p o l y p o i n t . p o i n t s ) GXVSegXform := 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 1] [ 2] [. 3] t 4] 4; 4 ) ; = GXAddPT ( o u t l i n e . p o i n t s ! 1] , = GXSubPT ( o u t l i n e . p o i n t s ! 1] , = GXSubPT ( o u t l i n e . p o i n t s ! 3] , = (GXAddPT ( o u t l i n e . p o i n t s ! 3] y i n c r e l ) ; y i n c r e l ) ; y i n c r e l ) ; , y i n c r e 1 ) ) ; y i n c r e 1 ) ; y i n c r e 1 ) ; y i n c r e l ) ; , y i n c r e 1)) ; b e g i n GXVSegXForm := c r o s s x f o r m ; G I n s e r t S e g ( c r o s s , GXVSegXForm); a n g l e := 0 . 5 * p i ; GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, c r o s s 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 := c e n t e r ; 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, GXVSegxform); c r o s s x f o r m := GXVsegxform; end GXVSegXform := 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 ; G I n s e r t S e g ( s t r i p e , GXVSegXForm); GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, s t r i p 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 := 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, GXVSegxform); s t r i p e x f o r m := GXVsegxform; G X V S t r i n g := ' E n g l a n d ' ; 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; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ) ; end ; G C l o s e S e g ; end ; p r o c e d u r e d o c h i n a ( o u t l i n e : p o l y p o i n t ; var f l a g s e g : segment ) ; i i n t e g e r ; p o s i t i o n : segxform ; a n g l e , i n c r e : r e a l ; b e g i n 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; 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 ); b e g i n GXVi := GXSetMax (0 , out 1 i n e . m a x ) ; G F i l l ( G X V i , o u t l i n e . p o i n t s ) ; GXVSegXform := 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 ; G X V v e c t o r [ 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, GXVSegXform); 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 . x := - 7 ; G X V P o l n t . y := 4 . 4 2 ; 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, GXVSegxform); p o s i t i o n := GXVsegxform; 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 .25 * p i ; i n c r e := - 0 .1875 * p i ; GXVSegXform := I d e n t i t y ; G X V P o i n t := o r i g i n ; GXVvectorf . 1] := 0 . 5 3 ; G X V v e c t o r [ 2 ] := 0 . 5 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, GXVSegXform); 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 . x := - 4 ; G X V P o i n t . y := 4 . 4 2 ; 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, GXVSegxform); G X V v e c t o r f 1 ] := 1.0; G X V v e c t o r [ 2 ] := 1.0; G X V P o i n t . x := - 7 ; G X V P o i n t . y := 4 . 4 2 ; GAc c u mt r a n (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, GXVSegxform); p o s i t i o n := GXVsegxform; f o r i : = 1 to 4 do b e g i n GXVSegXForm := p o s i t i o n ; G I n s e r t S e g ( s t a r , GXVSegXForm); GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, p o s i t i o n ) ; G X V v e c t o r f 1 ] := 1.0; G X V v e c t o r [ 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, GXVSegXform); p o s i t i o n := GXVsegxform; end G X V s t r i n g : = ' C h i n 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; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ) end ; GC1oseSeg; end ; p r o c e d u r e dogermany ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) ; v a r f l a g w i d t h 1 o w l i m i t bandwidth : r e a l twobytwo : p o i n t ; b e g i n l o w l i m i t := out 1 i n e . p o i n t s [ 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 ; 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 ); ( G X V A V A r r a y , G X V L i m i t A r r a y [ 1 3 ] . m i n , G X V L i m 1 t A r r a y [ 13] .max, ' s o l i d ' ) ) ) ; b e g i n GXVi := GXSetMax (0 , out 1 ine .max) ; 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 ( G X A t r V a l G S e t F i 1 I C o l I n d ( 1 ) ; 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 ) ; twobytwo ;= 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 G X V p o l y p o i n t . p o i n t s [ 1 ] . y G X V p o l y p o i n t . p o i n t s [ 2 ] . x G X V p o l y p o i n t . p o i n t s [ 2 ] . y G X V p o l y p o i n t . p o i n t s [ 3 ] . x G X V p o l y p o i n t . p o i n t s [ 3 ] . y G X V p o l y p o i n t . p o i n t s [ 4 ] . x 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 1 n t . m a x := 4; GXVi := GXSetMax (0 , 4 ) ; G F i l l ( G X V i , G X V p o l y p o i n t . 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 ( 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 [ 13] .max, G S e t F i 1 I S t y l e I n d ( G X A t r V a l ( G X V A V A r r a y , G X V L i m 1 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, ' g r e y ' ) ) ; G X V v e c t o r [ 1 ] := twobytwo.x; G X V v e c t o r [ 2 ] := twobytwo .y ; G S e t P a t t e r n S i z e ( G X V v e c t o r ) ; 10 ; 10; 10 ; 10; 10 ; 10-bandwidth; 10 ; 10 -bandwidth; ' P a t t e r n ' ) ) ) ; 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 nt po i n t s 1] X = - 10 G X V p o l y p o i n t po i n t s 1] y 10 -bandwidth; G X V p o l y p o i nt po1nt s 2] X = 10 ; G X V p o l y p o i nt p o i n t s 2] y = 10-bandwidth; G X V p o l y p o i n t p o i n t s 3] X = 10 ; G X V p o l y p o i n t p o i n t s 3] y = 10-( 2*bandw1dth) G X V p o l y p o i n t po i n t s 4] X = - 10 G X V p o l y p o i n t po i n t s 4] y = 10-( 2*bandwidth) 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 ( G X V i , G X V p o l y p o i n t . p o i n t s ) G X V s t r i n g := 'Germany' ; 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; 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 end ; G C l o s e S e g ; end ; p r o c e d u r e d o u s s r ( o u t l i n e : p o l y p o i n t ; s t a r s e g : segment ; s t a r p o o i t i o n : p o i n t ; s t a r x f o r m : segxform ; s t a t i c hammer , c y c l e : p o l y p o i n t ; v a l u e hammer := p o l y p o i n t ( G A P o i n t A r r a y ( GRPoi nt ( -7 . 5 6 5 ) GRpoi nt ( "7. 3 6 7 ) GRpoi nt ( - 8 . 0 7 4 ) G R p o i n t ( "7. 8 7 5 ) G R p o i n t ( "8 . 2 7 8 ) G R p o i n t ( "8. 5 7 5 ) G R p o i n t ( "8. 4 7 2 ) G R p o i n t ( - 8 . 3 7 3 ) G R P o i n t ( 0 . 0 , 0 0) b e g i n c r e a t e s t a r ( f a l s e , s t a r s e g ) ; 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 ; GXVSegXform := 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 ; , l e n g t h ( G X V S t r i n g ) , G X V S t r i n g ) f l a g s e g : 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, GXVSegXform); 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 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, GXVSegxform); s t a r x f o r m := GXVsegxform; 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 ); b e g i n 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L 1 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 [ 13] .max, ' s o l i d ' ) ) ) ; G S e t F i 1 I C o l I n d ( 1 ) ; GXVi := GXSetMax (0 , out 1 i n e . m a x ) ; G F i l l ( G X V i , o u t l i n e . p o i n t s ) ; 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); G S e t F i 1 I C o l I n d ( 0 ) ; GXVi := GXSetMax (0 , hammer.max); G F i l l ( G X V i , h a m m e r . p o i n t s ) ; G X V S t r i n g := ' U . S . S . R . ' ; 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; 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] , 1 e n g t h ( G X V S t r 1 n g ) , G X V S t r i n g ); end ; G C l o s e S e g ; end ; p r o c e d u r e d o j a p a n ( o u t l i n e : p o l y p o i n t ; v a r f l a g s e g : segment ) v a r c i r c l e : p o l y p o i n t b e g i n 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 ); b e g i n GXVi := GXSetMax (0 , out 1 i n e . m a x ) ; G P o l y l i n e ( G X V i , o u t l i n e . p o i n t s ) ; 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 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 ( G X A t r V a l ( G X V A V A r r a y , G X V L i 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 [ 13] .max, ' s o l i d ' ) ) ) ; GXVi := GXSetMax (0 , c i r c l e . m a x ) ; G F i l l ( G X V i , 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; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); end ; G C l o s e S e g ; end b e g i n G S e t C h a r H e i g h t ( 2 0 . 0 ) ; G S e t C h a r E x p a n ( 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; 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 ) ; d e t e r m i n e s i z e ( Canada , f l a g s i z e ) ; docanada ( 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 , n a t n a r r [ u s a ] . f l a g ) ; d e t e r m i n e s i z e ( e n g l a n d , f l a g s i z e ) ; d o e n g l a n d ( f l a g s i z e , n a t n a r r [ e n g l a n d ] . f l a g ) ; d e t e r m i n e s i z e ( c h i n a , f l a g s i z e ) ; d o c h i n a ( f l a g s i z e , n a t n a r r [ c h i n a ] . f l a g ) ; d e t e r m i n e s i z e ( f r a n c e , f l a g s i z e ) ; d o f r a n e e ( f l a g s i z e , n a t n a r r [ f r a n c e ] . f l a g ) ; d e t e r m i n e s i z e ( germany , f l a g s i z e ) ; dogermany ( f l a g s i z e , n a t n a r r [ germany ] . f l a g ) ; d e t e r m i n e s i z e ( u s s r , f l a g s i z e ) ; d o u s s r ( f l a g s i z e , n a t n a r r [ u s s r ] . f l a g ) ; d e t e r m i n e s i z e ( j a p a n , f l a g s i z e ) ; d o j a p a n ( f l a g s i z e , n a t n a r r [ j a p a n ] . f l a g ) ; end ; p r o c e d u r e g e n e r a t e p o s i t i o n ( v a r n a t n a r r : n a t i o n a r r a y ) i : n a t i o n ; a n g l e , i n c r e : r e a l ; i n i t l o c a t n : segxform b e g i n GXVSegXform := I d e n t i t y ; 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, G X V P o i n t , o r i g i n , 0 . 5 , G X V v e c t o r , WC, GXVSegxform); i n i t l o c a t n := GXVsegxform; a n g l e := 0 .125 * p i ; i n c r e := 0 .25 * p i ; f o r i := c a n a d a to j a p a n do b e g i n GXVSegXform : = I d e n t i t y ; GXAccum (GXVSegxform, i n i t l o c a t n ) ; 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 ; GAc c u mt r a n (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, GXVSegxform); i n i t l o c a t n := GXVsegxform; GXVSegXform := I d e n t i t y ; GXAccum (GXVSegxform, i n i t l o c a t n ) ; n a t n a r r [ i ] . p o s i t i o n := GXVsegxform; i f i = c h i n a t h e n beg i n a n g l e := 0 .125 * p i ; GXVSegXform := I d e n t i t y ; 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, G X V P o i n t , o r i g i n , 0 . 5 , G X V v e c t o r , WC, GXVSegxform); 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, 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, GXVSegxform); i n i t l o c a t n := GXVsegxform; end e l s e a n g l e := a n g l e + i n c r e ; end end ; p r o c e d u r e d i s p l a y e x h i b i t ( n a t n a r r : n a t i o n a r r a y e x h i b i t u n i t s , n d c u n i t s : window ; e x h i b i t n t : normxform ; e x h i b i t : segment ; i : n a t i o n ; b e g i n f o r i := Canada to j a p a n do b e g i n G X S t a t e ( GXsave , [ p r i n t e r ] , f a l s e ) ; GCopySegWs ( p r i n t e r , n a t n a r r [ i ] . f 1 a g ) ; G X S t a t e ( G X r e s t o r e , [ p r i n t e r ] , f a l s e ) ; G X S t a t e ( GXsave , [ p r i n t e r ] , f a l s e ) ; GClearWs ( p r i n t e r , C l e a r C o n d ); G X S t a t e ( G X r e s t o r e , [ p r i n t e r ] , f a l s e ) ; end G X V p o l y p o i n t . p o i n t s [ 1 ] . x := - 100 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := - 65; G X V p o l y p o i n t . p o i n t s [ 2 ] . x := 100 ; G X V p o l y p o i n t . p o i n t s [ 2 ] . y := 65; 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); 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.0681 ; G X V p o l y p o i n t . p o i n t s [ 1 ] . y := 0 .09375; G X V p o l y p o i n t . p o i n t s [ 2 ] . x := 0 .9318 ; G X V p o l y p o i n t . p o i n t s [ 2 ] . y := 0 .84275; 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); 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 ) ; G S e l e c t N T r a n ( e x h i b i t n t ) ; e x h i b i t := GXSegNum; G C r e a t e S e g ( e x h i b i t ) ; G C l o s e S e g ; b e g i n f o r i := Canada to 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) G S e t C h a r H e i g h t ( 1 3 0 . 0 ) ; G S e t C h a r E x p a n ( 2 . 0 ) ; G S e t C h a r S p a c i n g ( 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); G X V S t r i n g := 'ON' ; 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] , 1 e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); 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 := - 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] l e n g t h ( G X V S t r i n g ) , G X V S t r i n g ); end ; G X S t a t e ( GXsave , [ p r i n t e r ] , f a l s e ) ; GCopySegWs ( p r i n t e r , e x h i b i t ) ; G X S t a t e ( G X r e s t o r e , [ p r i n t e r ] , f a l s e ) ; end b e g i 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) ; G A c t i v a t e W S ( C e n t r a l S e g S t o r e ) ; GopenWs ( 1, 21 , 7370); G X I n i t A v ( G X C M a x A t r V a l , GXCMaxAtrTypes , G X V A v a r r a y , G X V L i m i t A r r a y ) ; p i := 3 .141592 ; g e n e r a t e f 1 a g s ( a r r a y o f n a t i o n s ) ; g e n e r a t e p o s i t i o n ( a r r a y o f n a t i o n s ) ; d i s p l a y e x h i b i t ( a r r a y o f n a t i o n s ) ; GXVopenWkstns := GXWsSet (GXopenWs); G X V a c t i v e W k s t n s := GXWsSet (GXAct iveWs) F o r GXVI := 0 t o GXCMaxSetS ize DO B e g i n I f GXVi IN G X V A c t i v e W k s t n s Then G D e a c t i v a t e W S ( G X V i ) ; I f GXVi IN GXVopenwkstns Then Gc loseWs ( G X V i ) ; E n d ; G c l o s e G K S ; 

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