casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Display.h
Go to the documentation of this file.
1 //# Display.h: Display module header file
2 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef TRIALDISPLAY_DISPLAY_H
29 #define TRIALDISPLAY_DISPLAY_H
30 
31 //#include <graphics/X11/X11Util.h>
36 
37 // Go ahead and include X11 stuff for now
38 //#include <display/Display/X11PixelCanvasColorTable.h>
39 //#include <display/Display/X11PixelCanvas.h>
40 
41 // Include Simple{World,Pixel}CanvasApp stuff
42 #include <display/Display/SimplePixelCanvasApp.h>
43 #include <display/Display/SimpleWorldCanvasApp.h>
44 
45 namespace casa { //# NAMESPACE CASA - BEGIN
46 
47 //
48 // <module>
49 //
50 // <summary>A module providing graphical display classes for use with AIPS++ </summary>
51 //
52 // <prerequisite>
53 // <li> <linkto class="casacore::Vector">casacore::Vector</linkto>
54 // <li> <linkto class="casacore::Matrix">casacore::Matrix</linkto>
55 // </prerequisite>
56 //
57 // <reviewed reviewer="None yet" date="yyyy/mm/dd" demos="">
58 // </reviewed>
59 //
60 // <etymology>
61 // Module provides classes for an Image Display Library
62 // </etymology>
63 //
64 // <synopsis> The purpose of the Display library is twofold: 1) to provide a
65 // set of tools for the AIPS++ programmer which make it easier to create
66 // drawing windows and use those drawing windows as output devices for
67 // graphical primitives, including images, and 2) to provide a set of higher-
68 // level classes to display datasets in a number of ways (images, contours, ...)
69 // as well as classes to help build an application that needs to display
70 // several datasets.
71 //
72 // A design goal is to have Display Library applications portable to
73 // another graphics system by augmenting the Library to provide an
74 // interface to that graphics system.
75 //
76 // <h1><center><Display Library Contents></center></h1>
77 //
78 // <ol>
79 // <li> <a href="#Overview">Display Library Overview</a>
80 // <li> <a href="#PixelCanvas">PixelCanvas</a>
81 // <ol>
82 // <li> <a href="#PCDrawingCommands">Drawing Commands</a>
83 // <li> <a href="#PCEvents">Event Handling</a>
84 // <li> <a href="#PCCaching">Caching Mechanism</a>
85 // <li> <a href="#PCColormaps">Colormap System</a>
86 // </ol>
87 // <li> <a href="#WorldCanvas">WorldCanvas</a>
88 // <ol>
89 // <li> <a href="#WCDrawingCommands">Drawing Commands</a>
90 // <li> <a href="#WCEvents">Event Handling</a>
91 // <li> <a href="#WCHandlers">Other Handlers</a>
92 // </ol>
93 // <li> <a href="#WorldCanvasHolder">WorldCanvasHolder</a>
94 // <li> <a href="#DisplayData">DisplayData</a>
95 // <li> <a href="#Zoomer">Zoomer</a>
96 // <li> <a href="#Animator">Animator</a>
97 // </ol>
98 //
99 // <hr>
100 //
101 // <h2><a name="Overview">Display Library Overview</a></h2>
102 //
103 // The Display library is a set of tools for the AIPS++ programmer which make
104 // it easier to create drawing windows and use those drawing windows as output
105 // devices for graphical primitives, including images. To some extent, the
106 // Display Library consists of two parts. One part is a set of device
107 // indepentent classes that give the basic functionality for data display. The
108 // classes of the first group are quite generic and can basically be used for
109 // any application that needs an interactive display window and these classes
110 // not tied to AIPS++ data sets or AIPS++ coordinate systems. They make only
111 // very few assumptions for what they will be used. The second part is more
112 // concerned with transforming data sets into objects that are understood by
113 // the first layer, as well as classes that should make it easier to build a
114 // full application that displays data. The classes of the second group can be
115 // quite data specific.
116 //
117 // The main classes from the first group are the PixelCanvas, the WorldCanvas
118 // and the ColorMap classes. The PixelCanvas conceptually corresponds to the
119 // window on the screen. It works only in 'screen' units, ie. screen pixel
120 // coordiantes and screen data values. The PixelCanvas is, to some extent, the
121 // interface between Aips++ and the display hardware and graphics environment
122 // (e.g. X11). The WorldCanvas is mostly an interface layer between the 'real
123 // world' and the PixelCanvas. Its main responsibility is to transform drawing
124 // instruction that are specified in world coordinates and world values to the
125 // corresponding instructions of the PixelCanvas specified in pixel
126 // coordinates and pixel values. The PixelCanvas and the WorldCanvas are
127 // intended to be relatively 'raw' devices. With this we mean that both
128 // classes have basically no knowledge of the classes that use these Canvases
129 // to display data. In effect, The PixelCanvas does not know what a
130 // WorldCanvas is. The reason to make the canvases relatively ignorant, is
131 // that by putting in as few assumptions as possible in the canvases, they
132 // (hopefully) can be used in a very wide range of applications. For example,
133 // it is quite easy to make a 2D colormap editor (an application that is quite
134 // different from e.g. displaying a contour map) based on the PixelCanvas or
135 // on the WorldCanvas. To achieve that only a few assumption have to be built
136 // in in the canvases, the canvases communicate to other classes via event
137 // handlers that these other classes have to register with the canvases. Also
138 // the PixelCanvas communicates with the WorldCanvas thourg such event
139 // handlers. For example, if the window corresponding to the Pixelcanvas is
140 // resized by the user, this generates a refresh event and the Pixelcanvas
141 // calls the refresh event handlers registered with the PixelCanvas. When a
142 // WorldCanvas is created, the first thing the WorldCanvas does is to install
143 // a number of event handlers on the PixelCanvas. This means that if e.g. the
144 // refresh event occurs on the PixelCanvas, the WorldCanvas is notified and
145 // takes the necessary action. This scheme of communication through event
146 // handlers is used throughout the Display Library. The classes that generate
147 // events do not have to know what classes consume these events, the only
148 // thing that is defined is the interface (and content) of the event. This
149 // means that one could build a class on top of the PixelCanvas that is quite
150 // different from the WorldCanvas.
151 //
152 // To keep the WorldCanvas as generic as possible, the coordinate system the
153 // WorldCanvas uses to transform from screen pixels to world coordinates and
154 // back is not stored in the WorldCnvas but is also defined through an event
155 // handler (a CoordinateHandler). If the WorldCanvas has to do a coordinate
156 // transformation, it asks the CoordinateHandler to do this. In many cases,
157 // this CoordinateHandler will use a standard Aips++ casacore::CoordinateSystem to do
158 // the transformation, but this is not a requirement, and the programmer can
159 // implement any tranformation required, as long as it satisfies the interface
160 // of the CoordinateHandler.
161 //
162 // The features of the first group include
163 //
164 // <ul>
165 // <li> Multi-layer programming library (PixelCanvas, WorldCanvas, Application)
166 // <li> PixelCanvas Interface which abstracts the underlying graphics library.
167 // <li> Colormap system allows applications to function independent of the
168 // number of available colors.
169 // <li> System color resources can be changed while running.
170 // <li> Drawing commands in world or pixel coordinates and values.
171 // <li> Events represented in world and pixel coordinates.
172 // </ul>
173 //
174 // The classes of the second group have a quite different purpose. They are
175 // much more concerned with building an application that needs to display one
176 // or more aips++ datasets in a number of ways.
177 //
178 // To make the link between the relatively generic display classes
179 // (PixelCanvas, WorldCanvas etc) and classes quite specific for displaying
180 // Aips++ datasets, an intermediate class is required. This class is called
181 // the WorldCanvasHolder. The main role of the WorldCanvasHolder is to catch
182 // the events that occur on a WorldCanvas and distribute these events to the
183 // data that is being displayed on the Worldcanvas. Another important role of
184 // the WorldCanvasHolder is that it is the class that is used to control what
185 // is actually displayed on the WorldCanvas. One important design requirement
186 // for the Display Library was that, from the programmer point of view, it
187 // should be easy to display more than one dataset in a window at the same
188 // time. A standard example is a contourmap on top of a greyscale image.
189 // Consequently, one can register more than one display object with the
190 // WorldCanvasHolder so that they are displayed at the same time.
191 //
192 // One important aspect that the WorldCanvasHolder takes care of is the
193 // sizeControl of the WorldCanvas. If a refresh event happens on the
194 // WorldCanvas, before invoking the refresh event handlers installed on the
195 // WorldCanvas, the WorldCanvas invokes a sizeControl event. The meaning of
196 // this event is to ask the object that draws on the WorldCanvas (e.g. the
197 // WorldCanvasHolder) to check if the state of the WorldCanvas is ok so that
198 // it can be drawn on, and if it is not ok, that the state of the WorldCanvas
199 // be modified. For example, if an image is drwan as a pseudeocolor image and
200 // the window (or WorldCanvas) is much larger that the data array, one wants
201 // to expand the data array so that it fills more or less the window. One way
202 // of doing this is to do this by pixelreplication. But this means that there
203 // are requirements on the size of the area that the WorldCanvas uses for
204 // drawing the image (it has to be a integer multiple of the size of the data
205 // array. This explains the name sizeControl). It is the responsibility of the
206 // objects that draw on the WorldCanvas, to get these size right. What in
207 // practice happens is that the WorldCanvasHolder asks the display objects to
208 // sort this out and set the correct size on the WorldCanvas. Once this is
209 // sorted out, the WorldCanvas is in the coreect state and things can be
210 // drawn. The name sizeControl is not entirely correct. The obvious use of
211 // this mechanism is as in the example described above, but the problem is
212 // more general: before display objects can draw on the WorldCanvas they have
213 // to be sure that the WorldCanvas is in the correct state and possibly they
214 // have to modify the attributes of the WorldCanvas. Because more than one
215 // display object can draw on the WorldCanvas, this has to be done before the
216 // actual drawing occurs (because the display objects do not know if there are
217 // more than one display objects drawing on the WorldCanvas).
218 //
219 // Another requirement for the Display Library was that no distinction should
220 // be made based on how data is displayed. For example, displaying an image as
221 // a pseudocolor image on the screen should, from the Display Library point of
222 // view, be the same operation as displaying that image as a contourmap. This
223 // means that the display object is quite an 'abstract' class. Display Objects
224 // in the Display Library are called DisplayData (or better: are derived from
225 // DisplayData). The role of the DisplayData is, using a certain algorithm, to
226 // transform data into one or more draw instructions for the WorldCanvas. An
227 // example is ImageDisplayData that takes an Aips++ dataset and display its
228 // contents as images, Another example would be ContourDisplayData that draws
229 // images as contourmaps. Also here, the communication to the DisplayData goes
230 // via calling event handlers. Depending on what happens (e.g. a refresh
231 // event, or a position event), the WorldCanvasHolder (who catches these
232 // events from the WorldCanvas), invokes member functions of the DisplayData
233 // registered with the WorldCanvasHolder (so to a large extent, a DisplayData
234 // is an event handler on the WorldCanvasHolder). For example, if a refresh
235 // event happens, the WorldCanvasHolder will ask the DisplayData to draw what
236 // they should draw. If a programmer wants to implement a new way of
237 // displaying data, what this programmer has to do is to implement a new class
238 // derived from DisplayData that computes whatever it has to compute (say a
239 // volume rendering of a datacube) and transform this into draw instructions
240 // for the WorldCanvas (in this example, just call WorldCanvas.drawImage() on
241 // the result of the volume rendering). A class derived from DisplayData does
242 // not need to have an Aips++ dataset, but one could for example image a
243 // DisplayData class that reads positions from a catalog and plots these
244 // positions on the WorldCanvas.
245 //
246 // Because everything in the Display Library is event driven, it is also easy
247 // to make applications that require more than one display window. The
248 // programmer only has to decide how to link the various windows by installng
249 // the appropriate event handlers on the various classes. An example of how
250 // this can be done is the Zoomer class. This class is a high-level class that
251 // catches position events on the WorldCanvases (possibly more than one) that
252 // are registered with the Zoomer. If the right event happens on one of the
253 // WorldCanvases (say, the user is rubberbanding a rectangle), the Zoomer sets
254 // the correct attributes on all the WorldCanvases registered with the Zoomer
255 // (meaning: it defines the area to which should be zoomed in) and invokes a
256 // refresh event on all these WorldCanvases. This means that all the
257 // WorldCanvases will zoom in synch.
258 //
259 // Another design requirement of the Display Library was that it should be
260 // easy to display movies, and the DisplayData are build with sequences in
261 // mind (as is clear from their interface). The programmer is free to define
262 // what a sequence really means, but it is probably best to keep the structure
263 // of the sequence in a DisplayData logical to at least some extent. But there
264 // is no real requirement on the structure of the sequence. Movies can be
265 // controlled using the Animator class. The easy way is to use indices, but
266 // there is a generic way of defining movies using restrictions (see later
267 // what these mean). So a sequence does not have to correspond to a 'physical'
268 // sequence in one datastructure (channels in a cube for example), but can be
269 // made of representations of different datasets (e.g. blinking), or more
270 // exotic combinations of different datasets displayed in different form
271 // (e.g. blink between a greyscale and a contourmap, if such a thing would be
272 // useful). This system is very flexible and there are no real limits to what
273 // a movie really means.
274 //
275 // An important concept in the Display Library is that of Attributes (and
276 // their use as restrictions). Attributes are name-value pairs. Many classes
277 // of the Display Library have a buffer where they can store these Attributes.
278 // They can be used for various things (see AttributeBuffer for a number of
279 // examples). One applications is that a uniform userinterface can be defined
280 // for changing attributes of a class (meaning internal members), but since
281 // Attributes can have an arbitrary name, they can be used to place (almost)
282 // any kind of information on classes <em> at run time</em>. This provides a
283 // mechanism of distributing information in a display aplication, while at
284 // compile time it is not yet defined what that information is (name, type,
285 // etc).
286 //
287 // An important application of Attributes is their use as
288 // <em>restrictions</em>: they are used to select which data is actually
289 // displayed. DisplayData classes, like ImageDisplayData, are supposed to have
290 // defined, for each distinct representation that they can draw, one or more
291 // Attributes, specifically defined to select what data is displayed. These
292 // Attributes are in a separate (or several separate) AttributeBuffer, called
293 // the <em>restriction buffer</em>. Also the WorldCanvasHolder has such a
294 // restriction buffer whose content should be controlled by the application
295 // programmer. If a refresh happens, the WorldCanvasHolder, after the
296 // sizeControl step, asks each DisplayData that is registered with the
297 // WorldCanvasHolder to draw itself, by calling the refreshEH() member of each
298 // DisplayData. The first thing that a DisplayData should do it to see if the
299 // restrictions that are placed on the WorldCanvasHolder are compatible with
300 // this DisplayData and/or check with which element of the DisplayData the
301 // restriction buffer WorldCanvasHolder is compatible. If the DisplayData has
302 // compatible data, it should draw this data. An example may make this process
303 // clearer. An ImageDisplayData is a class derived from DisplayData that
304 // displays the 2D slices from a n-dimensional dataset on a canvas (for
305 // example the channels from a datacube). An ImageDisplayData has two general
306 // restrictions (meaning they apply to all channels): the names of the axes
307 // ("xAxisName" = "Ra" and "yAxisName" = "Dec"). Since an ImageDisplayData
308 // (possibly) consists of a number of channels, additional restrictions exist,
309 // but these have a different value for each element (ie. channel). In the
310 // case of an ImageDisplayData, each 2D subset has defined "zIndex" and
311 // "zValue", the first has the value of the pixelcoordinate of the 2D image
312 // (in our example channel number), the second has the value of the
313 // WorldCoordinate of centre of the 2D image (in our example the velocity of
314 // the channel). So to display a channel, a programmer has to set 3
315 // restrictions on the WorldCanvasHolder: "xAxisName", "yAxisName" to select
316 // channels from a datacube and set these to "Ra" and "Dec" (or whatever is in
317 // the header of the data), plus a restriction to select the actual channel,
318 // e.g. set "zIndex" to 20 to select channel 20, or "zValue" to 1200.0, to
319 // select the channel corresponding to velocity 1200.0. To display a position
320 // velocity image, one would have to specify e.g. "xAxisName" = "Dec" and
321 // "yAxisName" = "Velocity" and set "zValue" to 5.23443311 (the Ra of the
322 // slice you want to look at).
323 //
324 // To determine if restrictionbuffers match, one can simply use the member
325 // matches() of an AttributeBuffer. The logic of matching restrictions is
326 // perhaps a bit distorted: restrictions (or Attributes in general) of
327 // different names <em> always match</em>. So if a DisplayData has a
328 // restriction called "A" and the WorldCanvasHolder specifies "B", the
329 // DisplayData should draw itself. Restrictions (and Attributes) can have some
330 // tolerance. In our example we could have specified "zValue" to be 1200.0,
331 // plus or minus 5.0. This obviously can be used e.g. to match the channels of
332 // two data cubes that are on a different velocity grid. The Animator class,
333 // who can be used to make movies, completely relies on this restriction
334 // mechanism.
335 //
336 //
337 //
338 // <hr>
339 //
340 // <h2><a name="PixelCanvas">The PixelCanvas</a></h2>
341 //
342 // The PixelCanvas display library defines an interface to an underlying
343 // 2D graphics library.
344 //
345 // The design of the PixelCanvas emphasizes the following features:
346 //
347 // <ul>
348 // <li> Straightforward drawing interface using simple Aips++ array types
349 // <li> Enhanced event handling - Event classes can be derived from to
350 // add extra functionality.
351 // <li> Advanced caching system - User can create sequences of drawing commands
352 // for later recall. Sequences can be compacted and stored into
353 // native structures for increased drawing performance.
354 // <li> Ability to register and use several colormaps in the same window at
355 // the same time.
356 // <li> Minimize the dependency on the underlying graphics system, in
357 // this case, X11.
358 // </ul>
359 //
360 //
361 // <h3><a name="PCDrawingCommands">PixelCanvas Drawing Commands</a></h3>
362 //
363 // PixelCanvas drawing commands accept simple AIPS++ objects. Presently the
364 // drawing commands accept points as casacore::Vector<t>'s, where t can be
365 // any scalar type but Bool. casacore::Bool images are not supported because a Bool
366 // cannot represent a color index. casacore::Complex values are not supported because
367 // there are many ways of creating a single scalar value from complex
368 // values.
369 //
370 //
371 // <h3><a name="PCEvents">PixelCanvas Event Handling</a></h3>
372 //
373 // There are 3 kinds of events the PixelCanvas reports
374 //
375 // <ol>
376 // <li> refresh event - sent when the canvas must be redrawn.
377 // <li> position event - sent when a button or key is pressed.
378 // <li> motion event - sent when the mouse moves over the cursor.
379 // </ol>
380 //
381 // Applications handle
382 // <linkto class=PixelCanvas>PixelCanvas</linkto> events by creating
383 // <linkto class=PixelCanvas>PixelCanvas</linkto> event handlers
384 // that must be derived from the appropriate event class, either
385 // <linkto class=PCRefreshEH>PCRefreshEH</linkto>,
386 // <linkto class=PCPositionEH>PCPositionEH</linkto>, or
387 // <linkto class=PCMotionEH>PCMotionEH</linkto>. The () operator
388 // must be overridden and implemented by responding to the
389 // information contained in the
390 // <linkto class=PCRefreshEvent>PCRefreshEvent</linkto>,
391 // <linkto class=PCPositionEvent>PCPositionEvent</linkto>, or
392 // <linkto class=PCMotionEvent>PCMotionEvent</linkto>, as appropriate.
393 //
394 //
395 // <h3><a name="PCCaching">PixelCanvas Caching Mechanism</a></h3>
396 //
397 // There is a system for creating sequences of commands. It works
398 // be turning on caching, performing drawing commands, then shutting
399 // it off. An id is returned to the user to recall the stored
400 // sequence. This gives the user control over what is to be cached
401 // while still abstracting the business of caching.
402 //
403 // The cache system improves drawing speed by storing drawing data
404 // in native library formats.
405 //
406 // casacore::Data stored in native formats means that, for the X11PixelCanvas,
407 //
408 // <ul>
409 // <li> images are stored in terms of pixels as XImages,
410 // <li> coordinate positions are stored how X likes them (upper left is 0,0),
411 // <li> lines are stored as XLines or XSegments, as appropriate
412 // <li> Points are stored as XPoints.
413 // <li> Pixmap Text is stored as drawing strings
414 // <li> Stroked Text is stored as XSegments or XLines
415 // </ul>
416 //
417 // It is the responsibility of the user to rebuild display lists
418 // when necessary. Normally this means when the canvas changes
419 // size or colormap distribution (if colormaps are in use).
420 //
421 //
422 // <h3><a name="PCColormaps">PixelCanvas Colormap System</a></h3>
423 //
424 // The PixelCanvas colormap system design was one of the most difficult
425 // design problems we faced in building this system. The design goals
426 // were as follows:
427 //
428 // <ol>
429 // <li> Wanted to be able to pretend we had multiple simultaneous
430 // colormaps available in some display window.
431 // <li> Wanted to allow for but not demand that multiple windows
432 // share the same hardware colormap.
433 // <li> Wanted to distribute the same colormap to different windows
434 // potentially displaying on different terminals.
435 // <li> Wanted to allow for customizing the colormaps, and allow for
436 // data-dependent colormaps.
437 // <li> Wanted to be able to resize the available colormap while
438 // a Display library application was running.
439 // </ol>
440 //
441 // The constraints above have driven us to the following scheme:
442 //
443 // <ol>
444 // <li> Create something called a
445 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
446 // and let it define a table of available colors for one or more
447 // <linkto class="PixelCanvas">PixelCanvas</linkto>es and be responsible
448 // for interfacing to the underlying graphics system's color allocation
449 // facilities. Through the
450 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
451 // one can abstract away the underlying graphic library's tedious and
452 // cumbersome constructs and functions required to manage color resources
453 // and visuals and provide a high-level interface based on concepts
454 // that are better understood. This interface is implemented as the
455 // constructors for the classes derived from the
456 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
457 // class.
458 //
459 // <li> Define a <linkto class=Colormap>Colormap</linkto> to mean not a
460 // table of colors, but rather a function that takes a floating-point
461 // parameter in [0.0,1.0] and returns an RGB triple. This function can
462 // then be used to fill some arbitrary number of consecutive colorcells.
463 // Allow for <linkto class=Colormap>Colormap</linkto>s to be of a fixed
464 // size if needed (then they are called 'rigid')
465 // and design them for derivation so custom colormaps can be created
466 // and used in this system.
467 //
468 // <li> Define a <linkto class=ColormapManager>ColormapManager</linkto> to be
469 // responsible for dynamically partitioning its
470 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
471 // into chunks, one chunk for each registered
472 // <linkto class=Colormap>Colormap</linkto>, allowing for rigid
473 // <linkto class=Colormap>Colormap</linkto>s (that must be for some reason
474 // of a particular size) and weights to give greater color resolution
475 // to certain maps. Make it responsible for filling in the color based
476 // on its distribution of <linkto class=Colormap>Colormap</linkto>s
477 // in the <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>.
478 //
479 // <li> Allow for <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>s
480 // to be shared by more than one <linkto class="PixelCanvas">PixelCanvas</linkto>,
481 // and allow <linkto class="PixelCanvas">PixelCanvas</linkto>es to share
482 // <linkto class=Colormap>Colormap</linkto>s.
483 //
484 // <li> Try to abstract away all this mess by placing gateways to necessary
485 // functionality in the <linkto class="PixelCanvas">PixelCanvas</linkto>
486 // itself. For example images are drawn on the
487 // <linkto class="PixelCanvas">PixelCanvas</linkto> through the following
488 // process:
489 //
490 // <ol>
491 // <li> register a <linkto class=Colormap>Colormap</linkto> with the
492 // <linkto class="PixelCanvas">PixelCanvas</linkto> (needed only once).
493 // <li> set the active colormap to the one used in step 1.
494 // <li> create an image whose values range from 0 to N-1, where N is the size
495 // of the active colormap
496 // (<linkto class="PixelCanvas">PixelCanvas</linkto>::getColormapSize()).
497 // <li> call <linkto class="PixelCanvas">PixelCanvas</linkto>::mapToColor().
498 // to convert to color values.
499 // <li> call <linkto class="PixelCanvas">PixelCanvas</linkto>drawImage()
500 // with the casacore::Matrix of color values
501 // </ol>
502 //
503 // The color image can be reused as long as the distribution of colors
504 // on the
505 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
506 // doesn't change. Any such change will trigger a refresh event with the
507 // reason Display::ColorTableChange on the affected
508 // <linkto class="PixelCanvas">PixelCanvas</linkto>.
509 // This process can also be used to draw other primitives that each have
510 // a value associated with it.
511 // Several colormaps can be switched between by setting the active
512 // colormap and querying the range, and using the mapToColor function.
513 //
514 // <li> Implement a function that resizes the
515 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>,
516 // forcing a redistribution of colormaps on affected
517 // <linkto class="PixelCanvas">PixelCanvas</linkto>es followed by a
518 // refresh event. This ultimately causes a reallocation of writable
519 // color cells on the underlying graphics library and can be
520 // used to increase or decrease the number of color cells available to
521 // the <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
522 // and hence to the application. This mechanism can be used to recover
523 // allocated color cells from the system map released by other applications
524 // when they exit, or to balance color resources between two or more
525 // applications.
526 //
527 // </ol>
528 //
529 // <hr>
530 //
531 // <h2><a name="WorldCanvas">The WorldCanvas</a></h2>
532 //
533 // The <linkto class=WorldCanvas>WorldCanvas</linkto> is intended to
534 // serve as a world-coordinate plotting canvas
535 //
536 //
537 // <h3><a name="WCDrawingCommands">WorldCanvas DrawingCommands</a></h3>
538 //
539 // The <linkto class=WorldCanvas>WorldCanvas</linkto> drawing commands
540 // expect to be given world coordinate values for position information.
541 //
542 //
543 // <h3><a name="WCEvents">WorldCanvas Event Handling</a></h3>
544 //
545 // The <linkto class=WorldCanvas>WorldCanvas</linkto> event handling
546 // is similar to the <linkto class=PixelCanvas>PixelCanvas</linkto>
547 // event handling, but the <linkto class=WorldCanvas>WorldCanvas</linkto>
548 // events contain extra information which includes the world coordinate
549 // and linear coordinate position of the mouse pointer. The same
550 // basic three events are available:
551 //
552 // <ol>
553 // <li> refresh event - sent when the canvas must be redrawn.
554 // <li> position event - sent when a button or key is pressed.
555 // <li> motion event - sent when the mouse moves over the cursor.
556 // </ol>
557 //
558 // Applications handle
559 // <linkto class=WorldCanvas>WorldCanvas</linkto> events by creating
560 // <linkto class=WorldCanvas>WorldCanvas</linkto> event handlers
561 // that must be derived from the appropriate event class, either
562 // <linkto class=WCRefreshEH>WCRefreshEH</linkto>,
563 // <linkto class=WCPositionEH>WCPositionEH</linkto>, or
564 // <linkto class=WCMotionEH>WCMotionEH</linkto>. The () operator
565 // must be overridden and implemented by responding to the
566 // information contained in the
567 // <linkto class=WCRefreshEvent>WCRefreshEvent</linkto>,
568 // <linkto class=WCPositionEvent>WCPositionEvent</linkto>, or
569 // <linkto class=WCMotionEvent>WCMotionEvent</linkto>, as appropriate.
570 //
571 //
572 // <h3><a name="WCHandlers">Other WorldCanvas Handlers</a></h3>
573 //
574 // Other handlers can be registered with the WorldCanvas to customize:
575 // <ul>
576 // <li> World casacore::Coordinate transformations
577 // <li> Linear resampling algorithm
578 // <li> casacore::Data scaling methods
579 // <li> Size control function
580 // </ul>
581 //
582 //
583 // <h2><a name="WorldCanvasHolder">The WorldCanvasHolder</a></h2>
584 //
585 // The WorldCanvasHolder is a user of a WorldCanvas. It installs handlers on
586 // the WorldCanvas for each event a WorldCanvas can generate. The main role
587 // of the WorldCanvasHolder is to allow to have more than one DisplayData
588 // object draw on a WorldCanvas (e.g contours on top of an image). A number
589 // of DisplayDatas can be registered with a WorldCanvasHolder, and the
590 // WorldCanvasHolder passes WorldCanvas events to these DisplayData.
591 // To control what is displayed on a WorldCanvas, the programmer can put
592 // restrictions on a WorldCanvasHolder. Only those DisplayData do actually
593 // draw whose restrictions match those of the WorldCanvasHolder. See the
594 // example given above, or have a look at the doc of the Animator.
595 //
596 // <h2><a name="DisplayData">The DisplayData Interface</a></h2>
597 //
598 // A DisplayData is the class that transforms data (in whatever form: an
599 // image, a cube, a catalog or whatever) into drawing instructions for the
600 // WorldCanvas. A DisplayData is the 'workhorse' of the display libary: here
601 // is defined in what way on can represent data. If one want to add a new way
602 // of displaying data to aips++, they only thing that has to be done is to
603 // write a new class, derived from DisplayData, that computes this new
604 // representation and draws it. For example, if one would want to add volume
605 // rendering to aips++, one would have to write a class that computes this
606 // volume rendering (e.g. using some hot-gas algorithm), and draw the result
607 // of this on a WorldCanvas (ie. simply WorldCanvas.drawImage() on the
608 // result). DisplayDatas are registered witha WorldCanvasHolder and the
609 // restriction mechanism is used to select what is being
610 // displayed. DisplayDatas are also responsible for defining the
611 // WorldCoordinate system of the WorldCanvas (they have an interface that can
612 // be called (indirectly) by the WorldCanvas to do the transformations), as
613 // wel las they have to insure that the state of the WorldCanvas is ok (the
614 // sizeControl, see above). An example of a DisplayData is the
615 // ImageDisplayData class, that draws pseudocolor images from a data set.
616 //
617 // <h2><a name="Zoomer">The Zoomer</a></h2>
618 //
619 // Zooming is done by setying the linear coordinates of the WorldCanvas to
620 // define the zoom area (using a set function of the WorldCanvas) and force a
621 // refresh of the WorldCanvas. The Zoomer class defines the userinterface for
622 // zooming. One can register one (or more) WorldCanvas with a Zoomer. This
623 // Zoomer installs a position event handler on the WorldCanvas that listens
624 // to certain key- and mouse events. The Zoomer defines a default
625 // userinterface, but this can be re-defined. A Zoomer can also handle more
626 // than one WorldCanvas, so it is easy to let different WorldCanvases zoom in synch.
627 //
628 // <h2><a name="Animator">The Animator</a></h2>
629 //
630 // The role of the Animator is to give an easy way of controling what is
631 // displayed on one or more WorldCanvases. By specifying how an Animator
632 // controls what is displayed (by using indices, world coordinates or
633 // restrictions), the Animator sets the necessary restrictions on the
634 // WorldCanvasHolders that are registered with the Animator, and forces a
635 // refresh on all of them. All WorldCanvasHolder registered on an Animator
636 // move in synch.
637 //
638 //
639 //
640 
641 // <hr>
642 //
643 // <motivation>
644 // Need to provide some usefull tools to assist in developing graphical
645 // C++ applications, addressing the problems encountered in trying to
646 // use other graphical libraries.
647 // </motivation>
648 //
649 // <hr>
650 // This section is intended as information about what tasks remain to be
651 // accomplished for the Display library.
652 //
653 // The following list illustrates work remaining at the PixelCanvas level:
654 //
655 // <todo asof="1997/10/06">
656 // <li> <b>PixelCanvas</b>: change/add PixelCanvas interface to use Matrices for multiple
657 // vector graphic primitives, and use those interfaces at the
658 // WorldCanvas level.
659 // <li> compact sequences of drawPoint and drawLine into drawPoints and
660 // drawLines, respectively.
661 // <li> add circle, arc, rounded rectangle drawing primitives.
662 // <li> implement rotated text perhaps at this level or maybe at the WorldCanvas level
663 // <li> More testing of the drawing primitives.
664 // <li> Correct bug related to clipwindow location when XCS (X coordinate syste) y
665 // value is less than zero.
666 // <li> Check function visibility for X11PixelCanvasColorTable
667 // <li> WorldCanvas casacore::Coordinate routines.
668 // <li> Check all HTML docs for problems.
669 // </todo>
670 //
671 // The following is the todo list for the WorldCanvas and related classes
672 //
673 // <todo asof="1997/10/06">
674 //
675 // <li> mapToColor and mapToColor3 functions that redirect to pixelCanvas
676 // <li> decide what drawImage interface higher classes require, and implement
677 // those in terms of the PixelCanvas interface.
678 // <li> test multiple WorldCanvases on a single PixelCanvas.
679 // <li> WCSplineResampleHandler class to handle bicubic interpolation of arrays ?
680 // <li> WCFunctionalScaleHandler class to take a functional as a scale function ?
681 // </todo>
682 //
683 // The following is the todo list for the application level classes:
684 // <todo asof="1997/10/06">
685 // <li> Write simple display app with colormap editor.
686 // <li> Demonstrate use of RonAndRenzo colormap implementation.
687 // </todo>
688 //
689 // <hr>
690 //
691 // <b>The following section is intended for a programmer who wants to
692 // improve the Display Library</b>
693 //
694 // <h3>Caching System Optimization</h3>
695 //
696 // An advanced optimization to the
697 // <linkto class="PixelCanvas">PixelCanvas</linkto>
698 // caching system would be to compact sequences
699 // of drawing commands. This would mean that a sequence received
700 // by the PixelCanvas would be transformed into a more efficient sequence
701 // of drawing commands that produces the same result. Obviously, sequences
702 // of the same commands can often be combined into a single command.
703 // But consider for example a drawn raster image I followed by a set of
704 // vectors V on top of the image. This sequence can be represented by
705 // { I V }.
706 //
707 // We can partition V into 2 sets: Vin (contains vectors drawn inside the
708 // image) and Vout (vectors that have portions drawn outside the image).
709 // A new image I' can be created from I by drawing I onto a pixmap, then
710 // painting the vectors Vin on top, and storing the resultant image I'.
711 //
712 // The cached sequence is then { I' Vout }, and I and V can be discarded
713 // This will result in faster drawing times and reduced memory usage if
714 // Vin has significant size because the vectors in Vin are not drawn explicitly.
715 //
716 // Similar results can be achieved with drawn text and points, so that some
717 // sequence { I V P T } can be replaced with { I' Vout Pout Tout }. Also
718 // overlapping images can be stored to avoid drawing the overlapping region
719 // more than once.
720 //
721 // It is not clear whether this would be worthwhile to pursue, so it has not
722 // been implemented.
723 //
724 // </synopsis>
725 //
726 // </module>
727 //
728 
729 
730 } //# NAMESPACE CASA - END
731 
732 #endif
733 
734 // ---- End of module Display ----