\documentclass{article} \usepackage{axiom} \begin{document} \title{clim.lisp} \author{Timothy Daly} \maketitle \begin{abstract} \end{abstract} \eject \tableofcontents \eject \section{Overview of CLIM} The Common Lisp Interface Manager (CLIM) is a powerful Lisp-based programming interface that provides a layered set of portable facilities for constructing user interfaces. These include basic windowing, input, output, and graphics services; stream-oriented input and output extended with facilities such as output recording, presentations, and context sensitive input; high level ``formatted output'' facilities; application building facilities; command processing; and a compositional toolkit similar to those found in the X world that supports look and feel independence. CLIM provides an API (applications programmer interface) to user interface facilities for the Lisp application programmer. CLIM does not compete with the window system or toolkits of the host machine (such as Motif or OpenLook), but rather uses their services (to the extent that it makes sense) to integrate Lisp applications into the host's window environment. For example, CLIM ``windows'' are mapped onto one or more host windows, and input and output operations performed on the CLIM window are ultimately carried out by the host window system. CLIM will support a large number of host environments including Genera, Motif, OpenLook, the Macintosh, CLOE-386/486, and the Next machine. The programmer using CLIM is insulated from most of the complexities of portability, since the Lisp-based application need only deal with CLIM objects and functions regardless of their operating platform (that is, the combination of Lisp system, host computer, and host window environment). CLIM abstracts out many of the concepts common to all window environments. The programmer is encouraged to think in terms of these abstractions, rather than in the specific capabilities of a particular host system. For example, using CLIM, the programmer can specify the appearance of output in high-level terms and those high-level descriptions are turned into the appropriate appearance for the given host. Thus, the application has the same fundamental interface across multiple environments, although the details will differ from system to system. Another important goal in the design and organization of CLIM is to provide a spectrum of user interface building options, all the way from detailed, low-level specification of ``what goes where'', to high-level user interface specification where the programmer leaves all of the details up to CLIM. This allows CLIM to balance the ease of use on one hand, and versatility on the other. By using high level facilities, a programmer can build portable user interfaces quickly, whereas by recombining lower level facilities he can build his own programming and user interfaces according to his specific needs or requirements. For example, CLIM supports the development of applications independent of look and feel, as well as the portable development of toolkit libraries that define and implement a particular look and feel. In addition, CLIM's layered design allows application programs to exclude facilities that they do not use, or reimplement or extend any part of the substrate. To these ends, CLIM is specified and implemented in a layered, modular fashion based on protocols. Each facility documented in this specification has several layers of interface, and each facility is independently specified and has a documented external interface. The facilities provided by CLIM include: \begin{list}{} \item [Geometry] CLIM provides provides geometric objects like point, rectangle, and transformations and functions for manipulating them. \item [Graphics] CLIM provides a rich set of drawing functions, including ones for drawing complex geometric shapes, a wide variety of drawing options (such as line thickness), a sophisticated inking model, and color. CLIM provides full affine transforms, so that a drawing may be arbitrarily translated, rotated, and scaled (to the extent that the underlying window system supports the rendering of such objects). \item [Windowing] CLIM provides a portable layer for implementing sheet classes (types of window-like objects) that are suited to support particular high level facilities or interfaces. The windowing module of CLIM defines a uniform interface for creating and managing hierarchies of these objects regardless of their sheet class. This layer also provides event management. \item [Output Recording] CLIM provides a facility for capturing all output done to a window. This facility provides the support for arbitrarily scrollable windows. In addition, this facility serves as the root for a variety of interesting high-level tools. \item [Formatted Output] CLIM provides a set of macros and functions that enable programs to produce neatly formatted tabular and graphical displays with very little effort. \item [Context Senstive Input] The presentation type facility of CLIM provides the ability to associate semantics with output, such that objects may be retrieved later by selecting their displayed representation with the pointer. This sensitivity comes along automatically and is integrated with the Common Lisp type system. A mechanism for type coercion is also included, providing the basis for powerful user interfaces. \item [Application Building] CLIM provides a set of tools for organizing an application's top-level user interface and command processing loops centered on objects called frames. CLIM provides functionality for laying out frames under arbitrary constraints, managing command menus and/or menu bars, and associating user interface gestures with application commands. Using these tools, application writers can easily and quickly construct user interfaces that can grow flexibly from prototype to delivery. \item [Adaptive Toolkit] CLIM provides a uniform interface to the standard compositional toolkits available in many environments. CLIM defines abstract panes that are analogous to the gadgets or widgets of a toolkit like Motif or OpenLook. CLIM fosters look and feel independence by specifying the interface of these abstract panes in terms of their function and not in terms of the details of their appearance or operation. If an application uses these interfaces, its user interface will adapt to use whatever toolkit is available in the host environment. By using this facility, application programmers can easily construct applications that will automatically conform to a variety of user interface standards. In addition, a portable Lisp-based implementation of the abstract panes is provided. \section{Conventions} This chapter describes the conventions used in this specification and in the CLIM software itself. \subsection{Audience, Goals, and Purpose} This document, the CLIM Release 2 Specification, is intended for vendors. While it does define the Application Programmer's Interface (API), that is, the functionality that a customer/consumer would use to write an application, it also defines the names and functionality of some internal parts of CLIM. These ``portals'' in implementation space allow one vendor to extend, for example, the output record mechanism and have it work with another vendor's implementation of incremental redisplay. We have attempted to carefully identify the appropriate ``portals'' so that the API can be implemented efficiently, but we have also tried not to overconstrain the specification so that it restricts creativity of implementation or the possibility for extension. This also affects the more sophisticated application writers who want to go a little below the published API but still want portable applications. This document defines which functionality is part of the advertised API, and which is part of the internal protocols. In this document, we refer to three different audiences. A CLIM user is a person who uses an application program that was written using CLIM. A CLIM programmer is a person who writes application programs using CLIM. A CLIM implementor is a programmer who implements CLIM or extends it in some non-trivial way. \subsection{Package Structure} CLIM defines a variety of packages in order to provide its functionality. In general, no symbols except for the symbols in this specification should be added to those packages. The clim-lisp package is intended to implement as much of the draft X3J13 Common Lisp as possible, independent of the conformance of individual vendors. (When all Lisp vendors implement X3J13 Common Lisp, the clim-lisp package could be eliminated.) clim-lisp is the version of Common Lisp in which CLIM is implemented and which the clim-user package uses instead of common-lisp . clim-lisp contains only exported symbols, and is locked in those implementations that allow package locking. <>= (make-package "CLIM-LISP") @ clim is the package where the symbols specified in this specification live. It contains only exported symbols and is locked in those implementations that allow package locking. <>= (make-package "CLIM") @ clim-sys is the package where useful ``system-like'' functionality lives, including such things as resources and multi-processing primitives. It contains functionality that is not part of Common Lisp, but which is not conceptually the province of CLIM itself. It contains only exported symbols and is locked in those implementations that allow package locking. <>= (make-package "CLIM-SYS") @ No code is written in any of the above packages, but rather code is written for symbols in the above packages. None of the above use any other packages (in the sense of the :use option to defpackage ). A CLIM implementation might define a clim-internals package that uses each of the above packages, thus getting the definition of Lisp from clim-lisp . It would then implement the functionality of the symbols in clim and clim-sys in the clim-internals package. <>= (make-package "CLIM-INTERNALS" :use "CLIM-LISP" "CLIM" "CLIM-SYS") @ clim-user is a package that programmers can use if they don't wish to create their own package. It is the CLIM analog of common-lisp-user . <>= (make-package "CLIM-USER") @ \subsection{``Spread'' Point Arguments to Functions} Many functions that take point arguments come in two forms: structured and spread . Functions that take structured point arguments take the argument as a single point object. Functions that take spread point arguments take a pair of arguments that correspond to the x and y coordinates of the point. Functions that take spread point arguments, or return spread point values have an asterisk in their name, for example, draw-line* . \subsection{Immutability of Objects} Most CLIM objects are immutable , that is, at the protocol level none of their components can be modified once the object is created. Examples of immutable objects include all of the members of the region classes, colors and opacities, text styles, and line styles. Since immutable objects by definition never change, functions in the CLIM API can safely capture immutable objects without first copying them. This also allows CLIM to cache immutable objects. Constructor functions that return immutable objects are free to either create and return a new object, or return an already existing object. A few CLIM objects are mutable . Examples of mutable objects include streams and output records. Some components of mutable objects can be modified once the object has been created, usually via setf accessors. In CLIM, object immutability is maintained at the class level. Throughout this specification, the immutability or mutability of a class will be explicitly specified. Some immutable classes also allow interning. A class is said to be interning if it guarantees that two instances that are equivalent will always be eq. For example, if the class color were interning, calling make-rgb-color twice with the same arguments would return eq values. CLIM does not specify that any class is interning, however all immutable classes are allowed to be interning at the discretion of the implementation. In some rare cases, CLIM will modify objects that are members of immutable classes. Such objects are referred to as being volatile. Extreme care must be take with volatile objects. This specification will note whenever some object that is part of the API is volatile. \subsection{Behavior of Interfaces} In this specification, any interfaces that take or return mutable objects can be classified in a few different ways. Most functions do not capture their mutable input objects, that is, these functions will either not store the objects at all, or will copy any mutable objects before storing them, or perhaps store only some of the components of the objects. Later modifications to those objects will not affect the internal state of CLIM. Some functions may capture their mutable input objects. That is, it is unspecified as to whether a CLIM implementation will or will not capture the mutable inputs to some function. For such functions, programmers should assume that these objects will be captured and must not modify these objects capriciously. Furthermore, it is unspecifed what will happen if these objects are later modified. Some programmers might choose to create a mutable subclass of an immutable class. If CLIM captures an object that is a member of such a class, it is unspecified what will happen if the programmer later modifies that object. If a programmer passes such an object to a CLIM function that may capture its inputs, he is responsible for either first copying the object or ensuring that the object does not change later. Some functions that return mutable objects are guaranteed to create fresh outputs. These objects can be modified without affecting the internal state of CLIM. Functions that return mutable objects that are not fresh objects fall into two categories: those that return read-only state , and those that return read-write state. If a function returns read-only state, programmers must not modify that object; doing so might corrupt the state of CLIM. If a function returns read/write state, the modification of that object is part of CLIM's interface, and programmers are free to modify the object in ways that ``make sense''. \subsection{Protocol Classes and Predicates} CLIM supplies a set of predicates that can be called on an object to determine whether or not that object satisfies a certain protocol. These predicates can be implemented in one of two ways. The first way is that a class implementing a particular protocol will inherit from a protocol class that corresponds to that protocol. A protocol class is an ``abstract'' class with no slots and no methods (except perhaps for some default methods), and exists only to indicate that some subclass obeys the protocol. In the case when a class inherits from a protocol class, the predicate could be implemented using typep. All of the CLIM region, design, sheet, and output record classes use this convention. For example, the presentation protocol class and predicate could be implemented in this way: \begin{verbatim} (defclass presentation () ()) (defun presentationp (object) (typep object 'presentation)) \end{verbatim} Note that in some implementations, it may be more efficient not to use typep, and instead use a generic function for the predicate. However, simply implementing a method for the predicate that returns true is not necessarily enough to assert that a class supports that protocol; the class must include the protocol class as a superclass. CLIM always provides at least one ``standard'' instantiable class that implements each protocol. The second way is that a class implementing a particular protocol must simply implement a method for a predicate generic function that returns true if and only if that class supports the protocol (otherwise, it returns false ). Most of the CLIM stream classes use this convention. Protocol classes are not used in these cases because, as in the case of some of the stream classes, the underlying Lisp implementation may not be arranged so as to permit it. For example, the extended input stream protocol might be implemented in this way: \begin{verbatim} (defgeneric extended-input-stream-p (object)) (defmethod extended-input-stream-p ((object t)) nil) (defmethod extended-input-stream-p ((object basic-extended-input-protocol)) t) (defmethod extended-input-stream-p ((encapsulating-stream standard-encapsulating-stream)) (with-slots (stream) encapsulating-stream (extended-input-stream-p stream))) \end{verbatim} Whenever a class inherits from a protocol class or returns true from the protocol predicate, the class must implement methods for all of the generic functions that make up the protocol. \subsection{Specialized Arguments to Generic Functions} Unless otherwise stated, this specification uses the following convention for specifying which arguments to generic functions are specialized: \begin{list}{} \item If the generic function is a setf function, the second argument is the one that is intended to be specialized. \item If the generic function is a ``mapping'' function (such as map-over-region-set-regions ), the second argument (the object that specifies what is being mapped over) is the one that is specialized. The first argument (the functional argument) is not intended to be specialized. \item Otherwise, the first argument is the one that is intended to be specialized. \end{list} \subsection{Multiple Value setf} Some functions in CLIM that return multiple values have setf functions associated with them. For example, output-record-position returns the position of an output record as two values that correspond to the x and y coordinates. In order to change the position of an output record, the programmer would like to invoke (setf output-record-position) . Normally however, setf only takes a single value with which to modify the specified place. CLIM provides a ``multiple value'' version of setf that allows an expression that returns multiple values to be used in updating the specified place. In this specification, this facility will be referred to as setf* in the guise of function names such as (setf* output-record-position) , even though setf* is not actually a defined form. For example, the modifying function for output-record-position might be called in either of the following two ways: \begin{verbatim} (setf (output-record-position record) (values nx ny)) (setf (output-record-position record1) (output-record-position record2)) \end{verbatim} The second form works because output-record-position itself returns two values. Some CLIM implementations may not support setf* due to restrictions imposed by the underlying Lisp implementation. In this case, programmers may use special ``setter'' function instead. In the above example, output-record-set-position is the ``setter'' function. \subsection{Sheet, Stream, or Medium Arguments to Macros} There are many macros that take a sheet, stream, or medium as one of the arguments, for example, with-new-output-record and formatting-table. In CLIM, this argument must be a variable bound to a sheet, stream, or medium; it may not be an arbitrary form that evaluates to a sheet, stream, or medium. t and sometimes nil are usually allowed as special cases; this causes the variable to be interpreted as a reference to another stream variable (usually *standard-output* for output macros, or *standard-input* for input macros). Note that, while the variable outside the macro form and the variable inside the body share the same name, they cannot be assumed to be the same reference. That is, the macro is free to create a new binding for the variable. Thus, the following code fragment will not necessarily affect the value of stream outside the formatting-table form: \begin{verbatim} (formatting-table (stream) (setq stream some-other-stream) ...) \end{verbatim} Furthermore, for the macros that take a sheet, stream, or medium argument, the position of that variable is always before any forms or other ``inputs''. \subsection{Macros that Expand into Calls to Advertised Functions} Some macros that take a ``body'' argument expand into a call to an advertised function that takes a functional argument. This functional argument will execute the suppled body. For a macro named ``with- environment'', the function is generally named ``invoke-with- environment''. For example, with-drawing-options might be defined as follows: \begin{verbatim} (defgeneric invoke-with-drawing-options (medium continuation &key) (declare (dynamic-extent continuation))) (defmacro with-drawing-options ((medium &rest drawing-options) &body body) `(flet ((with-drawing-options-body (,medium) ,@body)) (declare (dynamic-extent #'with-drawing-options-body)) (invoke-with-drawing-options ,medium #'with-drawing-options-body ,@drawing-options))) (defmethod invoke-with-drawing-options ((medium clx-display-medium) continuation &rest drawing-options) (with-drawing-options-merged-into-medium (medium drawing-options) (funcall continuation medium))) \end{verbatim} \subsection{Terminology Pertaining to Error Conditions} When this specification specifies that it ``is an error'' for some situation to occur, this means that: \begin{list}{} \item No valid CLIM program should cause this situation to occur. \item If this situation does occur, the effects and results are undefined as far as adherence to the CLIM specification is concerned. \item CLIM implementations are not required to detect such an error, although implementations are encouraged to provide such error detection whenever it is reasonable to do so. \end{list} When this specification specifies that some argument ``must be a type '' or uses the phrase ``the type argument '', this means that it is an error if the argument is not of the specified type. CLIM implementations are encouraged, but not required, to generate an argument type error for these situations. When this specification says that ``an error is signalled'' in some situation, this means that: \begin{list}{} \item If the situation occurs, an error will be signalled using either error or cerror . \item Valid CLIM programs may rely on the fact that an error will be signalled. \item Every CLIM implementation is required to detect such an error. \end{list} When this specification says that ``a condition is signalled'' in some situation, this is just like ``an error is signalled'' with the exception that the condition will be signalled using signal instead of error . \section{Regions} CLIM provides definitions for a variety of geometric objects, including points, lines, elliptical arcs, regions, and transformations. Both the graphics and windowing modules use the same set of geometric objects and functions. In this section, we describe regions, points, and the basic region classes. Transformations will be described in Chapter Affine Transformations. Most of these objects are described as if they are implemented using standard classes. However, this need not be the case. In particular, they may be implemented using structure classes, and some classes may exist only to name a place in the hierarchy---all members of such a class will be instances of that class's subclasses. The most important concern is that these classes must allow specializing generic functions. The coordinate system in which the geometric objects reside is an abstract, continuous coordinate system. This abstract coordinate system is converted into ``real world'' coordinates only during operations such as rendering one of the objects on a display device. Angles are measured in radians. Following standard conventions, when an angle is measured relative to a given line, a positive angle indicates an angle counter-clockwise from the line in the plane. When the angle from the positive x axis to the positive y axis is positive (that is, the positive y axis is counter-clockwise from the positive x axis), the coordinate system is said to be right-handed . When this angle is negative, the coordinate system is said to be left-handed. Thus, the cartesian coordinate system with x increasing to the right and y increasing upward is right-handed. A coordinate system with y increasing down is left-handed. (By default, CLIM streams are left handed, but no such default exists for sheets in general.) \subsection{General Regions} A region is an object that denotes a set of mathematical points in the plane. Regions include their boundaries, that is, they are closed. Regions have infinite resolution. A bounded region is a region that contains at least one point and for which there exists a number, d, called the region's diameter, such that if p1 and p2 are points in the region, the distance between p1 and p2 is always less than or equal to d. An unbounded region either contains no points or contains points arbitrarily far apart. Another way to describe a region is that it maps every (x,y) pair into either true or false (meaning member or not a member, respectively, of the region). Later, in Chapter General Designs , we will generalize a region to something called a design that maps every point (x,y) into color and opacity values. \noindent {\bf region} {\bf [Protocol Class]} The protocol class that corresponds to a set of points. This includes both bounded and unbounded regions. This is a subclass of design (see Chapter Drawing in Color ). If you want to create a new class that behaves like a region, it should be a subclass of region. Subclasses of region must obey the region protocol.There is no general constructor called make-region because of the impossibility of a uniform way to specify the arguments to such a function. \noindent {\bf regionp object} {\bf [Predicate]} Returns true if object is a region , otherwise returns false . \noindent {\bf path} {\bf [Protocol Class]} The protocol class path denotes bounded regions that have dimensionality 1 (that is, have length). It is a subclass of region and bounding-rectangle. If you want to create a new class that behaves like a path, it should be a subclass of path. Subclasses of path must obey the path protocol.Constructing a path object with no length (via make-line* , for example) may canonicalize it to +nowhere+. Some rendering models support the constructing of areas by filling a closed path. In this case, the path needs a direction associated with it. Since CLIM does not currently support the path-filling model, paths are directionless. \noindent {\bf pathp object} {\bf [Predicate]} Returns true if object is a path , otherwise returns false . Note that constructing a path object with no length (such as calling make-line with two coincident points), for example) may canonicalize it to +nowhere+ . \noindent {\bf area} {\bf [Protocol Class]} The protocol class area denotes bounded regions that have dimensionality 2 (that is, have area). It is a subclass of region and bounding-rectangle . If you want to create a new class that behaves like an area, it should be a subclass of area. Subclasses of area must obey the area protocol.Note that constructing an area object with no area (such as calling make-rectangle with two coincident points), for example) may canonicalize it to +nowhere+ . \noindent {\bf areap object} {\bf [Predicate]} Returns true if object is an area , otherwise returns false . \noindent {\bf coordinate} {\bf [Type]} The type that represents a coordinate. This must either be t , or a subtype of real . CLIM implementations may use a more specific subtype of real , such as single-float , for reasons of efficiency. All of the specific region classes and subclasses of bounding-rectangle will use this type to store their coordinates. However, the constructor functions for the region classes and for bounding rectangles must accept numbers of any type and coerce them to coordinate . \noindent {\bf coordinate n} {\bf [Function]} Coerces the number n to be a coordinate. \noindent {\bf +everywhere+} {\bf [Constant]} \noindent {\bf +nowhere+} {\bf [Constant]} +everywhere+ is the region that includes all the points on the two-dimensional infinite drawing plane. +nowhere+ is the empty region, the opposite of +everywhere+ . \subsubsection{The Region Predicate Protocol} The following generic functions comprise the region predicate protocol. All classes that are subclasses of region must either inherit or implement methods for these generic functions. The methods for region-equal , region-contains-region-p , and region-intersects-region-p will typically specialize both the region1 and region2 arguments. \noindent {\bf region-equal region1 region2} {\bf [Generic function]} Returns true if the two regions region1 and region2 contain exactly the same set of points, otherwise returns false . \noindent {\bf region-contains-region-p region1 region2} {\bf [Generic function]} Returns true if all points in the region region2 are members of the region region1 , otherwise returns false . \noindent {\bf region-contains-position-p region x y} {\bf [Generic function]} Returns true if the point at (x,y) is contained in the region region , otherwise returns false . Since regions in CLIM are closed, this must return true if the point at (x,y) is on the region's boundary. CLIM implementations are permitted to return different non-nil values depending on whether the point is completely inside the region or is on the border. region-contains-position-p is a special case of region-contains-region-p in which the region is the point (x,y). \noindent {\bf region-intersects-region-p region1 region2} {\bf [Generic function]} Returns false if region-intersection of the two regions region1 and region2 would be +nowhere+ , otherwise returns true . \subsubsection{Region Composition Protocol} Region composition is not always equivalent to simple set operations. Instead, composition attempts to return an object that has the same dimensionality as one of its arguments. If this is not possible, then the result is defined to be an empty region, which is canonicalized to +nowhere+ . (The exact details of this are specified with each function.) Sometimes, composition of regions can produce a result that is not a simple contiguous region. For example, region-union of two rectangular regions might not be a single rectangle. In order to support cases like this, CLIM has the concept of a region set , which is an object that represents one or more region objects related by some region operation, usually a union. CLIM provides standard classes to cover the cases of region union, intersection, and difference. Some CLIM implementations might only implement a subset of full region composition. Because of the importance of rectangular regions and region sets that are the union of rectangular regions, every CLIM implementation is required to fully support all functions that use regions for those cases. (For example, CLIM implementations must be able do clipping and repainting on region sets composed entirely of axis-aligned rectangles.) If a CLIM implementation does not support some functions on non-rectangular region sets (for example, clipping), it must signal an error when an unsupported case is encountered; the exact details of this depend on the particular CLIM implementation. \noindent {\bf region-set} {\bf [Protocol Class]} The protocol class that represents a region set; a subclass of region and bounding-rectangle. In addition to the three classes below, there may be other instantiable subclasses of region-set that represent special cases, for instance, some implementations might have a standard-rectangle-set class that represents the union of several axis-aligned rectangles. Members of this class are immutable. \noindent {\bf region-set-p object} {\bf [Predicate]} Returns true if object is a region set , otherwise returns false . \noindent {\bf standard-region-union} {\bf [Class]} \noindent {\bf standard-region-intersection} {\bf [Class]} \noindent {\bf standard-region-difference} {\bf [Class]} These three instantiable classes respectively implement the union, intersection, and differences of regions. Implementations may, but are not required to, take advantage of the commutativity and associativity of union and intersection in order to ``collapse'' complicated region sets into simpler ones. Region sets that are composed entirely of axis-aligned rectangles must be canonicalized into either a single rectangle or a union of rectangles. Furthermore, the rectangles in the union must not overlap each other. The following generic functions comprise the region composition protocol. All classes that are subclasses of region must implement methods for these generic functions. The methods for region-union , region-intersection , and region-difference will typically specialize both the region1 and region2 arguments. \noindent {\bf region-set-regions region &key normalize} {\bf [Generic function]} Returns a sequence of the regions in the region set region . region can be either a region set or a ``simple'' region, in which case the result is simply a sequence of one element: region . This function returns objects that reveal CLIM's internal state; do not modify those objects. For the case of region sets that are unions of axis-aligned rectangles, the rectangles returned by region-set-regions are guaranteed not to overlap. If normalize is supplied, it must be either :x-banding or :y-banding. If it is :x-banding and all the regions in region are axis-aligned rectangles, the result is normalized by merging adjacent rectangles with banding done in the x direction. If it is :y-banding and all the regions in region are rectangles, the result is normalized with banding done in the y direction. Normalizing a region set that is not composed entirely of axis-aligned rectangles using x- or y-banding causes CLIM to signal the region-set-not-rectangular error. \noindent {\bf map-over-region-set-regions function region &key normalize} {\bf [Generic function]} Calls function on each region in the region set region . This is often more efficient than calling region-set-regions . function is a function of one argument, a region; it has dynamic extent. region can be either a region set or a ``simple'' region, in which case function is called once on region itself. normalize is as for region-set-regions. Figure 3.1: Normalization of rectangular region sets. \noindent {\bf region-union region1 region2} {\bf [Generic function]} Returns a region that contains all points that are in either of the regions region1 or region2 (possibly with some points removed in order to satisfy the dimensionality rule). The result of region-union always has dimensionality that is the maximum dimensionality of region1 and region2 . For example, the union of a path and an area produces an area; the union of two paths is a path. region-union will return either a simple region, a region set, or a member of the class standard-region-union . This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \noindent {\bf region-intersection region1 region2} {\bf [Generic function]} Returns a region that contains all points that are in both of the regions region1 and region2 (possibly with some points removed in order to satisfy the dimensionality rule). The result of region-intersection has dimensionality that is the minimum dimensionality of region1 and region2 , or is +nowhere+ . For example, the intersection of two areas is either another area or +nowhere+ ; the intersection of two paths is either another path or +nowhere+ ; the intersection of a path and an area produces the path clipped to stay inside of the area. region-intersection will return either a simple region or a member of the class standard-region-intersection. This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \noindent {\bf region-difference region1 region2} {\bf [Generic function]} Returns a region that contains all points in the region region1 that are not in the region region2 (possibly plus additional boundary points to make the result closed). The result of region-difference has the same dimensionality as region1 , or is +nowhere+ . For example, the difference of an area and a path produces the same area; the difference of a path and an area produces the path clipped to stay outside of the area. region-difference will return either a simple region, a region set, or a member of the class standard-region-difference . This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. Figure 3.2: Examples of region union, intersection, and difference. \subsection{Other Region Types} The other types of regions are points, polylines, polygons, elliptical arcs, and ellipses. All of these region types are closed under affine transformations. {\bf Issue: SWM, York} There is a proposal to remove the polygon , polyline , line , ellipse , and elliptical-arc classes, since they are only of limited utility, and CLIM itself doesn't use the classes at all. The advantage of removing these classes is that both the spec and CLIM itself become a little simpler, and there are fewer cases of the region protocol to implement. However, removing these classes results in a geometric model that is no longer closed (in the mathematical sense). This lack of closure makes it difficult to specify the design-based drawing model. Furthermore, these are intuitive objects that are used by a small, but important, class of applications, and some people feel that CLIM should relieve programmers from having to implement these classes for himself or herself. The advocates of removing these classes also propose removing the design-based drawing model. In this case, a more consistent proposal is to remove all of the geometric classes, including point and rectangle . Again, the opposing point of view believes that the power and flexibility of the design-based drawing model does not justify the removal of any of these classes. One counter-proposal is to require CLIM not to use any of the extended region classes internally, and to move the implementation of the extended region classes to a separately loadable module (via provide and require ). Figure 3.3: The class structure for all regions. \subsubsection{Points} A point is a mathematical point in the plane, designated by its coordinates, which are a pair of real numbers (where a real number is defined as either an integer, a ratio, or a floating point number). Points have neither area nor length (that is, they have dimensionality 0). Note well that a point is not a pixel; CLIM models a drawing plane with continuous coordinates. This is discussed in more detail in Chapter Graphics . \noindent {\bf point} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical point. This is a subclass of region and bounding-rectangle . If you want to create a new class that behaves like a point, it should be a subclass of point. Subclasses of point must obey the point protocol. \noindent {\bf pointp object} {\bf [Predicate]} Returns true if object is a point , otherwise returns false . \noindent {\bf standard-point} {\bf [Class]} An instantiable class that implements a point. This is a subclass of point . This is the class that make-point instantiates. Members of this class are immutable. \noindent {\bf make-point x y} {\bf [Function]} Returns an object of class standard-point whose coordinates are x and y . x and y must be real numbers. \subsubsection{The Point Protocol} The following generic functions comprise the point API. Only point-position is in the point protocol, that is, all classes that are subclasses of point must implement methods for point-position , but need not implement methods for point-x and point-y . \noindent {\bf point-position point} {\bf [Generic function]} Returns both the x and y coordinates of the point point as two values. \noindent {\bf point-x point} {\bf [Generic function]} \noindent {\bf point-y point} {\bf [Generic function]} Returns the x or y coordinate of the point point , respectively. CLIM will supply default methods for point-x and point-y on the protocol class point that are implemented by calling point-position. \subsubsection{Polygons and Polylines} A polyline is a path that consists of one or more line segments joined consecutively at their end-points. Polylines that have the end-point of their last line segment coincident with the start-point of their first line segment are called closed ; this use of the term ``closed'' should not be confused with closed sets of points. A polygon is an area bounded by a closed polyline. If the boundary of a polygon intersects itself, the odd-even winding-rule defines the polygon: a point is inside the polygon if a ray from the point to infinity crosses the boundary an odd number of times. \noindent {\bf polyline} {\bf [Protocol Class]} The protocol class that corresponds to a polyline. This is a subclass of path . If you want to create a new class that behaves like a polyline, it should be a subclass of polyline. Subclasses of polyline must obey the polyline protocol. \noindent {\bf polylinep object} {\bf [Predicate]} Returns true if object is a polyline , otherwise returns false . \noindent {\bf standard-polyline} {\bf [Class]} An instantiable class that implements a polyline. This is a subclass of polyline . This is the class that make-polyline and make-polyline* instantiate. Members of this class are immutable. \noindent {\bf make-polyline point-seq &key closed} {\bf [Function]} \noindent {\bf make-polyline* coord-seq &key closed} {\bf [Function]} Returns an object of class standard-polyline consisting of the segments connecting each of the points in point-seq (or the points represented by the coordinate pairs in coord-seq ). point-seq is a sequence of points ; coord-seq is a sequence of coordinate pairs, which are real numbers. It is an error if coord-seq does not contain an even number of elements. If closed is true , then the segment connecting the first point and the last point is included in the polyline. The default for closed is false . This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \noindent {\bf polygon} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical polygon. This is a subclass of area . If you want to create a new class that behaves like a polygon, it should be a subclass of polygon. Subclasses of polygon must obey the polygon protocol. \noindent {\bf polygonp object} {\bf [Predicate]} Returns true if object is a polygon , otherwise returns false . \noindent {\bf standard-polygon} {\bf [Class]} An instantiable class that implements a polygon. This is a subclass of polygon. This is the class that make-polygon and make-polygon* instantiate. Members of this class are immutable. \noindent {\bf make-polygon point-seq} {\bf [Function]} \noindent {\bf make-polygon* coord-seq} {\bf [Function]} Returns an object of class standard-polygon consisting of the area contained in the boundary that is specified by the segments connecting each of the points in point-seq (or the points represented by the coordinate pairs in coord-seq ). point-seq is a sequence of points ; coord-seq is a sequence of coordinate pairs, which are real numbers. It is an error if coord-seq does not contain an even number of elements. This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \subsubsectin{The Polygon and Polyline Protocol} The following generic functions comprise the polygon and polyline protocol. All classes that are subclasses of either polygon or polyline must implement methods for these generic functions. Some of the functions below take an argument named polygon-or-polyline ; this argument may be either a polygon or a polyline . \noindent {\bf polygon-points polygon-or-polyline} {\bf [Generic function]} Returns a sequence of points that specify the segments in polygon-or-polyline. This function returns objects that reveal CLIM's internal state; do not modify those objects. \noindent {\bf map-over-polygon-coordinates function polygon-or-polyline} {\bf [Generic function]} Applies function to all of the coordinates of the vertices of polygon-or-polyline . function is a function of two arguments, the x and y coordinates of the vertex; it has dynamic extent. \noindent {\bf map-over-polygon-segments function polygon-or-polyline} {\bf [Generic function]} Applies function to the segments that compose polygon-or-polyline. function is a function of four arguments, the x and y coordinates of the start of the segment, and the x and y coordinates of the end of the segment; it has dynamic extent. When map-over-polygon-segments is called on a closed polyline, it will call function on the segment that connects the last point back to the first point. \noindent {\bf polyline-closed polyline} {\bf [Generic function]} Returns true if the polyline polyline is closed, otherwise returns false . This function need be implemented only for polylines , not for polygons . \subsubsection{Lines} A line is a polyline consisting of a single segment. \noindent {\bf line} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical line segment, that is, a polyline with only a single segment. This is a subclass of polyline . If you want to create a new class that behaves like a line, it should be a subclass of line. Subclasses of line must obey the line protocol. \noindent {\bf linep object} {\bf [Predicate]} Returns true if object is a line , otherwise returns false . \noindent {\bf standard-line} {\bf [Class]} An instantiable class that implements a line segment. This is a subclass of line. This is the class that make-line and make-line* instantiate. Members of this class are immutable. \noindent {\bf make-line start-point end-point} {\bf [Function]} \noindent {\bf make-line* start-x start-y end-x end-y} {\bf [Function]} Returns an object of class standard-line that connects the two points start-point and end-point (or the positions (start-x ,start-y ) and (end-x ,end-y )). This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \subsubsection{The Line Protocol} The following generic functions comprise the line API. Only line-start-point* and line-end-point* are in the line protocol, that is, all classes that are subclasses of line must implement methods for line-start-point* and line-end-point* , but need not implement methods for line-start-point and line-end-point . \noindent {\bf line-start-point* line} {\bf [Generic function]} \noindent {\bf line-end-point* line} {\bf [Generic function]} Returns the starting or ending point, respectively, of the line line as two real numbers representing the coordinates of the point. \noindent {\bf line-start-point line} {\bf [Generic function]} \noindent {\bf line-end-point line} {\bf [Generic function]} Returns the starting or ending point of the line line , respectively. CLIM will supply default methods for line-start-point and line-end-point on the protocol class line that are implemented by calling line-start-point* and line-end-point* . \subsubsection{Rectangles} Rectangles whose edges are parallel to the coordinate axes are a special case of polygon that can be specified completely by four real numbers (x1 ,y1 ,x2 ,y2 ). They are not closed under general affine transformations (although they are closed under rectilinear transformations). \noindent {\bf rectangle} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical rectangle, that is, rectangular polygons whose sides are parallel to the coordinate axes. This is a subclass of polygon . If you want to create a new class that behaves like a rectangle, it should be a subclass of rectangle. Subclasses of rectangle must obey the rectangle protocol. \noindent {\bf rectanglep object} {\bf [Predicate]} Returns true if object is a rectangle , otherwise returns false . \noindent {\bf standard-rectangle} {\bf [Class]} An instantiable class that implements an axis-aligned rectangle. This is a subclass of rectangle . This is the class that make-rectangle and make-rectangle* instantiate. Members of this class are immutable. \noindent {\bf make-rectangle point1 point2} {\bf [Function]} \noindent {\bf make-rectangle* x1 y1 x2 y2} {\bf [Function]} Returns an object of class standard-rectangle whose edges are parallel to the coordinate axes. One corner is at the point point1 (or the position (x1 ,y1 )) and the opposite corner is at the point point2 (or the position (x2 ,y2 )). There are no ordering constraints among point1 and point2 (or x1 and x2 , and y1 and y2 ). Most CLIM implementations will choose to represent rectangles in the most efficient way, such as by storing the coordinates of two opposing corners of the rectangle. Because this representation is not sufficient to represent the result of arbitrary transformations of arbitrary rectangles, CLIM is allowed to return a polygon as the result of such a transformation. (The most general class of transformations that is guaranteed to always turn a rectangle into another rectangle is the class of transformations that satisfy rectilinear-transformation-p .) This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \subsubsection{The Rectangle Protocol} The following generic functions comprise the rectangle API. Only rectangle-edges* is in the rectangle protocol, that is, all classes that are subclasses of rectangle must implement methods for rectangle-edges* , but need not implement methods for the remaining functions. \noindent {\bf rectangle-edges* rectangle} {\bf [Generic function]} Returns the coordinates of the minimum x and y and maximum x and y of the rectangle rectangle as four values, min-x , min-y , max-x , and max-y . \noindent {\bf rectangle-min-point rectangle} {\bf [Generic function]} \noindent {\bf rectangle-max-point rectangle} {\bf [Generic function]} Returns the min point and max point of the rectangle rectangle , respectively. The position of a rectangle is specified by its min point. CLIM will supply default methods for rectangle-min-point and rectangle-max-point on the protocol class rectangle that are implemented by calling rectangle-edges* . \noindent {\bf rectangle-min-x rectangle} {\bf [Generic function]} \noindent {\bf rectangle-min-y rectangle} {\bf [Generic function]} \noindent {\bf rectangle-max-x rectangle} {\bf [Generic function]} \noindent {\bf rectangle-max-y rectangle} {\bf [Generic function]} Returns (respectively) the minimum x and y coordinate and maximum x and y coordinate of the rectangle rectangle . CLIM will supply default methods for these four generic functions on the protocol class rectangle that are implemented by calling rectangle-edges* . \noindent {\bf rectangle-width rectangle} {\bf [Generic function]} \noindent {\bf rectangle-height rectangle} {\bf [Generic function]} \noindent {\bf rectangle-size rectangle} {\bf [Generic function]} rectangle-width returns the width of the rectangle rectangle , which is the difference between the maximum x and its minimum x. rectangle-height returns the height, which is the difference between the maximum y and its minimum y. rectangle-size returns two values, the width and the height. CLIM will supply default methods for these four generic functions on the protocol class rectangle that are implemented by calling rectangle-edges* . \subsubsection{Ellipses and Elliptical Arcs} An ellipse is an area that is the outline and interior of an ellipse. Circles are special cases of ellipses. An elliptical arc is a path consisting of all or a portion of the outline of an ellipse. Circular arcs are special cases of elliptical arcs. An ellipse is specified in a manner that is easy to transform, and treats all ellipses on an equal basis. An ellipse is specified by its center point and two vectors that describe a bounding parallelogram of the ellipse. The bounding parallelogram is made by adding and subtracting the vectors from the the center point in the following manner: \begin{verbatim} | | | | x coordinate y coordinate | | | | Center of Ellipse | xc yc | | | | Vectors | dx1 dy1 | | | dx2 dy2 | | | | Corners of Parallelogram | xc + dx1 + dx2 yc + dy1 + dy2 | | | xc + dx1 - dx2 yc + dy1 - dy2 | | | xc - dx1 - dx2 yc - dy1 - dy2 | | | xc - dx1 + dx2 yc - dy1 + dy2 | | | \end{verbatim} Note that several different parallelograms specify the same ellipse. One parallelogram is bound to be a rectangle---the vectors will be perpendicular and correspond to the semi-axes of the ellipse. Figure 3.4: Different vectors may specify the same ellipse. The special case of an ellipse with its axes aligned with the coordinate axes can be obtained by setting dx2 = dy1 = 0 or dx1 = dy2 = 0. \noindent {\bf ellipse} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical ellipse. This is a subclass of area. If you want to create a new class that behaves like an ellipse, it should be a subclass of ellipse. Subclasses of ellipse must obey the ellipse protocol. \noindent {\bf ellipsep object} {\bf [Predicate]} Returns true if object is an ellipse , otherwise returns false . \noindent {\bf standard-ellipse} {\bf [Class]} An instantiable class that implements an ellipse. This is a subclass of ellipse. This is the class that make-ellipse and make-ellipse* instantiate. Members of this class are immutable. \noindent {\bf make-ellipse center-point radius-1-dx radius-1-dy radius-2-dx radius-2-dy &key start-angle end-angle} {\bf [Function]} \noindent {\bf make-ellipse* center-x center-y radius-1-dx radius-1-dy radius-2-dx radius-2-dy &key start-angle end-angle} {\bf [Function]} Returns an object of class standard-ellipse . The center of the ellipse is at the point center-point (or the position (center-x, center-y )). Two vectors, (radius-1-dx ,radius-1-dy ) and (radius-2-dx ,radius-2-dy ) specify the bounding parallelogram of the ellipse as explained above. All of the radii are real numbers. If the two vectors are collinear, the ellipse is not well-defined and the ellipse-not-well-defined error will be signalled. The special case of an ellipse with its axes aligned with the coordinate axes can be obtained by setting both radius-1-dy and radius-2-dx to 0. If start-angle or end-angle are supplied, the ellipse is the ``pie slice'' area swept out by a line from the center of the ellipse to a point on the boundary as the boundary point moves from the angle start-angle to end-angle . Angles are measured counter-clockwise with respect to the positive x axis. If end-angle is supplied, the default for start-angle is 0; if start-angle is supplied, the default for end-angle is 2pi ; if neither is supplied then the region is a full ellipse and the angles are meaningless. This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \noindent {\bf elliptical-arc} {\bf [Protocol Class]} The protocol class that corresponds to a mathematical elliptical arc. This is a subclass of path . If you want to create a new class that behaves like an elliptical arc, it should be a subclass of elliptical-arc. Subclasses of elliptical-arc must obey the elliptical arc protocol. \noindent {\bf elliptical-arc-p object} {\bf [Predicate]} Returns true if object is an elliptical arc , otherwise returns false . \noindent {\bf standard-elliptical-arc} {\bf [Class]} An instantiable class that implements an elliptical arc. This is a subclass of elliptical-arc . This is the class that make-elliptical-arc and make-elliptical-arc* instantiate. Members of this class are immutable. \noindent {\bf make-elliptical-arc center-point radius-1-dx radius-1-dy radius-2-dx radius-2-dy &key start-angle end-angle} {\bf [Function]} \noindent {\bf make-elliptical-arc* center-x center-y radius-1-dx radius-1-dy radius-2-dx radius-2-dy &key start-angle end-angle} {\bf [Function]} Returns an object of class standard-elliptical-arc . The center of the ellipse is at the point center-point (or the position (center-x, center-y )). Two vectors, (radius-1-dx ,radius-1-dy ) and (radius-2-dx ,radius-2-dy ), specify the bounding parallelogram of the ellipse as explained above. All of the radii are real numbers. If the two vectors are collinear, the ellipse is not well-defined and the ellipse-not-well-defined error will be signalled. The special case of an elliptical arc with its axes aligned with the coordinate axes can be obtained by setting both radius-1-dy and radius-2-dx to 0. If start-angle and start-angle are supplied, the arc is swept from start-angle to end-angle . Angles are measured counter-clockwise with respect to the positive x axis. If end-angle is supplied, the default for start-angle is 0; if start-angle is supplied, the default for end-angle is 2pi ; if neither is supplied then the region is a closed elliptical path and the angles are meaningless. This function is permitted to capture its mutable inputs; the consequences of modifying those objects are unspecified. \subsection{The Ellipse and Elliptical Arc Protocol} The following functions apply to both ellipses and elliptical arcs. In all cases, the name elliptical-object means that the argument may be an ellipse or an elliptical arc . These generic functions comprise the ellipse protocol. All classes that are subclasses of either ellipse or elliptical-arc must implement methods for these functions. \noindent {\bf ellipse-center-point* elliptical-object} {\bf [Generic function]} Returns the center point of elliptical-object as two values representing the coordinate pair. \noindent {\bf ellipse-center-point elliptical-object} {\bf [Generic function]} Returns the center point of elliptical-object . ellipse-center-point is part of the ellipse API, but not part of the ellipse protocol. CLIM will supply default methods for ellipse-center-point on the protocol classes ellipse and elliptical-arc that are implemented by calling ellipse-center-point* . \noindent {\bf ellipse-radii elliptical-object} {\bf [Generic function]} Returns four values corresponding to the two radius vectors of elliptical-arc . These values may be canonicalized in some way, and so may not be the same as the values passed to the constructor function. \noindent {\bf ellipse-start-angle elliptical-object} {\bf [Generic function]} Returns the start angle of elliptical-object . If elliptical-object is a full ellipse or closed path then ellipse-start-angle will return nil ; otherwise the value will be a number greater than or equal to zero, and less than 2pi . \noindent {\bf ellipse-end-angle elliptical-object} {\bf [Generic function]} Returns the end angle of elliptical-object . If elliptical-object is a full ellipse or closed path then ellipse-end-angle will return nil ; otherwise the value will be a number greater than zero, and less than or equal to 2pi . \section{code} <<*>>= <> <> <> <> <> \begin{thebibliography}{99} \bibitem{1} nothing \end{thebibliography} \end{document}