casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Display.h
Go to the documentation of this file.
00001 //# Display.h: Display module header file
00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 #ifndef TRIALDISPLAY_DISPLAY_H
00029 #define TRIALDISPLAY_DISPLAY_H
00030 
00031 //#include <graphics/X11/X11Util.h>
00032 #include <display/Display/DisplayEnums.h>
00033 #include <display/Display/PixelCanvasColorTable.h>
00034 #include <display/Display/PixelCanvas.h>
00035 #include <display/Display/WorldCanvas.h>
00036 
00037 // Go ahead and include X11 stuff for now
00038 //#include <display/Display/X11PixelCanvasColorTable.h>
00039 //#include <display/Display/X11PixelCanvas.h>
00040 
00041 // Include Simple{World,Pixel}CanvasApp stuff
00042 #include <display/Display/SimplePixelCanvasApp.h>
00043 #include <display/Display/SimpleWorldCanvasApp.h>
00044 
00045 namespace casa { //# NAMESPACE CASA - BEGIN
00046 
00047 //
00048 // <module>
00049 //
00050 // <summary>A module providing graphical display classes for use with AIPS++ </summary>
00051 //
00052 // <prerequisite>
00053 // <li> <linkto class="Vector">Vector</linkto>
00054 // <li> <linkto class="Matrix">Matrix</linkto>
00055 // </prerequisite>
00056 //
00057 // <reviewed reviewer="None yet" date="yyyy/mm/dd" demos="">
00058 // </reviewed>
00059 //
00060 // <etymology>
00061 // Module provides classes for an Image Display Library
00062 // </etymology>
00063 //
00064 // <synopsis> The purpose of the Display library is twofold: 1) to provide a
00065 // set of tools for the AIPS++ programmer which make it easier to create
00066 // drawing windows and use those drawing windows as output devices for
00067 // graphical primitives, including images, and 2) to provide a set of higher-
00068 // level classes to display datasets in a number of ways (images, contours, ...)
00069 // as well as classes to help build an application that needs to display
00070 // several datasets.
00071 //
00072 // A design goal is to have Display Library applications portable to
00073 // another graphics system by augmenting the Library to provide an 
00074 // interface to that graphics system.
00075 //
00076 // <h1><center><Display Library Contents></center></h1>
00077 //
00078 // <ol>
00079 //  <li> <a href="#Overview">Display Library Overview</a>
00080 //  <li> <a href="#PixelCanvas">PixelCanvas</a>
00081 //   <ol>
00082 //    <li> <a href="#PCDrawingCommands">Drawing Commands</a>
00083 //    <li> <a href="#PCEvents">Event Handling</a>
00084 //    <li> <a href="#PCCaching">Caching Mechanism</a>
00085 //    <li> <a href="#PCColormaps">Colormap System</a>
00086 //   </ol>
00087 //  <li> <a href="#WorldCanvas">WorldCanvas</a>
00088 //   <ol>
00089 //    <li> <a href="#WCDrawingCommands">Drawing Commands</a>
00090 //    <li> <a href="#WCEvents">Event Handling</a>
00091 //    <li> <a href="#WCHandlers">Other Handlers</a>
00092 //   </ol> 
00093 //  <li> <a href="#WorldCanvasHolder">WorldCanvasHolder</a>
00094 //  <li> <a href="#DisplayData">DisplayData</a>
00095 //  <li> <a href="#Zoomer">Zoomer</a>
00096 //  <li> <a href="#Animator">Animator</a>
00097 // </ol>
00098 //
00099 // <hr>
00100 //
00101 // <h2><a name="Overview">Display Library Overview</a></h2>
00102 // 
00103 // The Display library is a set of tools for the AIPS++ programmer which make
00104 // it easier to create drawing windows and use those drawing windows as output
00105 // devices for graphical primitives, including images. To some extent, the
00106 // Display Library consists of two parts. One part is a set of device
00107 // indepentent classes that give the basic functionality for data display. The
00108 // classes of the first group are quite generic and can basically be used for
00109 // any application that needs an interactive display window and these classes
00110 // not tied to AIPS++ data sets or AIPS++ coordinate systems. They make only
00111 // very few assumptions for what they will be used.  The second part is more
00112 // concerned with transforming data sets into objects that are understood by
00113 // the first layer, as well as classes that should make it easier to build a
00114 // full application that displays data. The classes of the second group can be
00115 // quite data specific.
00116 // 
00117 // The main classes from the first group are the PixelCanvas, the WorldCanvas
00118 // and the ColorMap classes. The PixelCanvas conceptually corresponds to the
00119 // window on the screen. It works only in 'screen' units, ie. screen pixel
00120 // coordiantes and screen data values. The PixelCanvas is, to some extent, the
00121 // interface between Aips++ and the display hardware and graphics environment
00122 // (e.g. X11). The WorldCanvas is mostly an interface layer between the 'real
00123 // world' and the PixelCanvas. Its main responsibility is to transform drawing
00124 // instruction that are specified in world coordinates and world values to the
00125 // corresponding instructions of the PixelCanvas specified in pixel
00126 // coordinates and pixel values. The PixelCanvas and the WorldCanvas are
00127 // intended to be relatively 'raw' devices. With this we mean that both
00128 // classes have basically no knowledge of the classes that use these Canvases
00129 // to display data. In effect, The PixelCanvas does not know what a
00130 // WorldCanvas is. The reason to make the canvases relatively ignorant, is
00131 // that by putting in as few assumptions as possible in the canvases, they
00132 // (hopefully) can be used in a very wide range of applications. For example,
00133 // it is quite easy to make a 2D colormap editor (an application that is quite
00134 // different from e.g. displaying a contour map) based on the PixelCanvas or
00135 // on the WorldCanvas. To achieve that only a few assumption have to be built
00136 // in in the canvases, the canvases communicate to other classes via event
00137 // handlers that these other classes have to register with the canvases. Also
00138 // the PixelCanvas communicates with the WorldCanvas thourg such event
00139 // handlers. For example, if the window corresponding to the Pixelcanvas is
00140 // resized by the user, this generates a refresh event and the Pixelcanvas
00141 // calls the refresh event handlers registered with the PixelCanvas. When a
00142 // WorldCanvas is created, the first thing the WorldCanvas does is to install
00143 // a number of event handlers on the PixelCanvas. This means that if e.g. the
00144 // refresh event occurs on the PixelCanvas, the WorldCanvas is notified and
00145 // takes the necessary action. This scheme of communication through event
00146 // handlers is used throughout the Display Library. The classes that generate
00147 // events do not have to know what classes consume these events, the only
00148 // thing that is defined is the interface (and content) of the event. This
00149 // means that one could build a class on top of the PixelCanvas that is quite
00150 // different from the WorldCanvas.
00151 //
00152 // To keep the WorldCanvas as generic as possible, the coordinate system the
00153 // WorldCanvas uses to transform from screen pixels to world coordinates and
00154 // back is not stored in the WorldCnvas but is also defined through an event
00155 // handler (a CoordinateHandler). If the WorldCanvas has to do a coordinate
00156 // transformation, it asks the CoordinateHandler to do this. In many cases,
00157 // this CoordinateHandler will use a standard Aips++ CoordinateSystem to do
00158 // the transformation, but this is not a requirement, and the programmer can
00159 // implement any tranformation required, as long as it satisfies the interface
00160 // of the CoordinateHandler.
00161 //
00162 // The features of the first group include
00163 //
00164 // <ul>
00165 // <li> Multi-layer programming library (PixelCanvas, WorldCanvas, Application)
00166 // <li> PixelCanvas Interface which abstracts the underlying graphics library.
00167 // <li> Colormap system allows applications to function independent of the
00168 //      number of available colors.
00169 // <li> System color resources can be changed while running.
00170 // <li> Drawing commands in world or pixel coordinates and values.
00171 // <li> Events represented in world and pixel coordinates.
00172 // </ul>
00173 //
00174 // The classes of the second group have a quite different purpose. They are
00175 // much more concerned with building an application that needs to display one
00176 // or more aips++ datasets in a number of ways. 
00177 //
00178 // To make the link between the relatively generic display classes
00179 // (PixelCanvas, WorldCanvas etc) and classes quite specific for displaying
00180 // Aips++ datasets, an intermediate class is required. This class is called
00181 // the WorldCanvasHolder. The main role of the WorldCanvasHolder is to catch
00182 // the events that occur on a WorldCanvas and distribute these events to the
00183 // data that is being displayed on the Worldcanvas. Another important role of
00184 // the WorldCanvasHolder is that it is the class that is used to control what
00185 // is actually displayed on the WorldCanvas.  One important design requirement
00186 // for the Display Library was that, from the programmer point of view, it
00187 // should be easy to display more than one dataset in a window at the same
00188 // time. A standard example is a contourmap on top of a greyscale image.
00189 // Consequently, one can register more than one display object with the
00190 // WorldCanvasHolder so that they are displayed at the same time. 
00191 //
00192 // One important aspect that the WorldCanvasHolder takes care of is the
00193 // sizeControl of the WorldCanvas. If a refresh event happens on the
00194 // WorldCanvas, before invoking the refresh event handlers installed on the
00195 // WorldCanvas, the WorldCanvas invokes a sizeControl event. The meaning of
00196 // this event is to ask the object that draws on the WorldCanvas (e.g. the
00197 // WorldCanvasHolder) to check if the state of the WorldCanvas is ok so that
00198 // it can be drawn on, and if it is not ok, that the state of the WorldCanvas
00199 // be modified. For example, if an image is drwan as a pseudeocolor image and
00200 // the window (or WorldCanvas) is much larger that the data array, one wants
00201 // to expand the data array so that it fills more or less the window. One way
00202 // of doing this is to do this by pixelreplication. But this means that there
00203 // are requirements on the size of the area that the WorldCanvas uses for
00204 // drawing the image (it has to be a integer multiple of the size of the data
00205 // array. This explains the name sizeControl). It is the responsibility of the
00206 // objects that draw on the WorldCanvas, to get these size right. What in
00207 // practice happens is that the WorldCanvasHolder asks the display objects to
00208 // sort this out and set the correct size on the WorldCanvas. Once this is
00209 // sorted out, the WorldCanvas is in the coreect state and things can be
00210 // drawn. The name sizeControl is not entirely correct. The obvious use of
00211 // this mechanism is as in the example described above, but the problem is
00212 // more general: before display objects can draw on the WorldCanvas they have
00213 // to be sure that the WorldCanvas is in the correct state and possibly they
00214 // have to modify the attributes of the WorldCanvas. Because more than one
00215 // display object can draw on the WorldCanvas, this has to be done before the
00216 // actual drawing occurs (because the display objects do not know if there are
00217 // more than one display objects drawing on the WorldCanvas). 
00218 //
00219 // Another requirement for the Display Library was that no distinction should
00220 // be made based on how data is displayed. For example, displaying an image as
00221 // a pseudocolor image on the screen should, from the Display Library point of
00222 // view, be the same operation as displaying that image as a contourmap.  This
00223 // means that the display object is quite an 'abstract' class. Display Objects
00224 // in the Display Library are called DisplayData (or better: are derived from
00225 // DisplayData). The role of the DisplayData is, using a certain algorithm, to
00226 // transform data into one or more draw instructions for the WorldCanvas. An
00227 // example is ImageDisplayData that takes an Aips++ dataset and display its
00228 // contents as images, Another example would be ContourDisplayData that draws
00229 // images as contourmaps. Also here, the communication to the DisplayData goes
00230 // via calling event handlers. Depending on what happens (e.g. a refresh
00231 // event, or a position event), the WorldCanvasHolder (who catches these
00232 // events from the WorldCanvas), invokes member functions of the DisplayData
00233 // registered with the WorldCanvasHolder (so to a large extent, a DisplayData
00234 // is an event handler on the WorldCanvasHolder). For example, if a refresh
00235 // event happens, the WorldCanvasHolder will ask the DisplayData to draw what
00236 // they should draw. If a programmer wants to implement a new way of
00237 // displaying data, what this programmer has to do is to implement a new class
00238 // derived from DisplayData that computes whatever it has to compute (say a
00239 // volume rendering of a datacube) and transform this into draw instructions
00240 // for the WorldCanvas (in this example, just call WorldCanvas.drawImage() on
00241 // the result of the volume rendering). A class derived from DisplayData does
00242 // not need to have an Aips++ dataset, but one could for example image a
00243 // DisplayData class that reads positions from a catalog and plots these
00244 // positions on the WorldCanvas. 
00245 //
00246 // Because everything in the Display Library is event driven, it is also easy
00247 // to make applications that require more than one display window. The
00248 // programmer only has to decide how to link the various windows by installng
00249 // the appropriate event handlers on the various classes. An example of how
00250 // this can be done is the Zoomer class. This class is a high-level class that
00251 // catches position events on the WorldCanvases (possibly more than one) that
00252 // are registered with the Zoomer. If the right event happens on one of the
00253 // WorldCanvases (say, the user is rubberbanding a rectangle), the Zoomer sets
00254 // the correct attributes on all the WorldCanvases registered with the Zoomer
00255 // (meaning: it defines the area to which should be zoomed in) and invokes a
00256 // refresh event on all these WorldCanvases. This means that all the
00257 // WorldCanvases will zoom in synch. 
00258 //
00259 // Another design requirement of the Display Library was that it should be
00260 // easy to display movies, and the DisplayData are build with sequences in
00261 // mind (as is clear from their interface). The programmer is free to define
00262 // what a sequence really means, but it is probably best to keep the structure
00263 // of the sequence in a DisplayData logical to at least some extent. But there
00264 // is no real requirement on the structure of the sequence.  Movies can be
00265 // controlled using the Animator class. The easy way is to use indices, but
00266 // there is a generic way of defining movies using restrictions (see later
00267 // what these mean). So a sequence does not have to correspond to a 'physical'
00268 // sequence in one datastructure (channels in a cube for example), but can be
00269 // made of representations of different datasets (e.g. blinking), or more
00270 // exotic combinations of different datasets displayed in different form
00271 // (e.g. blink between a greyscale and a contourmap, if such a thing would be
00272 // useful). This system is very flexible and there are no real limits to what
00273 // a movie really means.
00274 //
00275 // An important concept in the Display Library is that of Attributes (and
00276 // their use as restrictions). Attributes are name-value pairs. Many classes
00277 // of the Display Library have a buffer where they can store these Attributes.
00278 // They can be used for various things (see AttributeBuffer for a number of
00279 // examples). One applications is that a uniform userinterface can be defined
00280 // for changing attributes of a class (meaning internal members), but since
00281 // Attributes can have an arbitrary name, they can be used to place (almost)
00282 // any kind of information on classes <em> at run time</em>. This provides a
00283 // mechanism of distributing information in a display aplication, while at
00284 // compile time it is not yet defined what that information is (name, type,
00285 // etc).
00286 //
00287 // An important application of Attributes is their use as
00288 // <em>restrictions</em>: they are used to select which data is actually
00289 // displayed. DisplayData classes, like ImageDisplayData, are supposed to have
00290 // defined, for each distinct representation that they can draw, one or more
00291 // Attributes, specifically defined to select what data is displayed. These
00292 // Attributes are in a separate (or several separate) AttributeBuffer, called
00293 // the <em>restriction buffer</em>. Also the WorldCanvasHolder has such a
00294 // restriction buffer whose content should be controlled by the application
00295 // programmer.  If a refresh happens, the WorldCanvasHolder, after the
00296 // sizeControl step, asks each DisplayData that is registered with the
00297 // WorldCanvasHolder to draw itself, by calling the refreshEH() member of each
00298 // DisplayData. The first thing that a DisplayData should do it to see if the
00299 // restrictions that are placed on the WorldCanvasHolder are compatible with
00300 // this DisplayData and/or check with which element of the DisplayData the
00301 // restriction buffer WorldCanvasHolder is compatible. If the DisplayData has
00302 // compatible data, it should draw this data. An example may make this process
00303 // clearer. An ImageDisplayData is a class derived from DisplayData that
00304 // displays the 2D slices from a n-dimensional dataset on a canvas (for
00305 // example the channels from a datacube). An ImageDisplayData has two general
00306 // restrictions (meaning they apply to all channels): the names of the axes
00307 // ("xAxisName" = "Ra" and "yAxisName" = "Dec"). Since an ImageDisplayData
00308 // (possibly) consists of a number of channels, additional restrictions exist,
00309 // but these have a different value for each element (ie. channel). In the
00310 // case of an ImageDisplayData, each 2D subset has defined "zIndex" and
00311 // "zValue", the first has the value of the pixelcoordinate of the 2D image
00312 // (in our example channel number), the second has the value of the
00313 // WorldCoordinate of centre of the 2D image (in our example the velocity of
00314 // the channel). So to display a channel, a programmer has to set 3
00315 // restrictions on the WorldCanvasHolder: "xAxisName", "yAxisName" to select
00316 // channels from a datacube and set these to "Ra" and "Dec" (or whatever is in
00317 // the header of the data), plus a restriction to select the actual channel,
00318 // e.g. set "zIndex" to 20 to select channel 20, or "zValue" to 1200.0, to
00319 // select the channel corresponding to velocity 1200.0. To display a position
00320 // velocity image, one would have to specify e.g. "xAxisName" = "Dec" and
00321 // "yAxisName" = "Velocity" and set "zValue" to 5.23443311 (the Ra of the
00322 // slice you want to look at). 
00323 //
00324 // To determine if restrictionbuffers match, one can simply use the member
00325 // matches() of an AttributeBuffer. The logic of matching restrictions is
00326 // perhaps a bit distorted: restrictions (or Attributes in general) of
00327 // different names <em> always match</em>. So if a DisplayData has a
00328 // restriction called "A" and the WorldCanvasHolder specifies "B", the
00329 // DisplayData should draw itself. Restrictions (and Attributes) can have some
00330 // tolerance. In our example we could have specified "zValue" to be 1200.0,
00331 // plus or minus 5.0. This obviously can be used e.g. to match the channels of
00332 // two data cubes that are on a different velocity grid. The Animator class,
00333 // who can be used to make movies, completely relies on this restriction
00334 // mechanism. 
00335 //
00336 //
00337 //
00338 // <hr>
00339 //
00340 // <h2><a name="PixelCanvas">The PixelCanvas</a></h2>
00341 //
00342 // The PixelCanvas display library defines an interface to an underlying
00343 // 2D graphics library.
00344 //
00345 // The design of the PixelCanvas emphasizes the following features:
00346 //
00347 // <ul>
00348 // <li> Straightforward drawing interface using simple Aips++ array types
00349 // <li> Enhanced event handling - Event classes can be derived from to
00350 //      add extra functionality.
00351 // <li> Advanced caching system - User can create sequences of drawing commands
00352 //      for later recall.  Sequences can be compacted and stored into
00353 //      native structures for increased drawing performance.
00354 // <li> Ability to register and use several colormaps in the same window at
00355 //      the same time.
00356 // <li> Minimize the dependency on the underlying graphics system, in
00357 //      this case, X11.
00358 // </ul>
00359 //
00360 //
00361 // <h3><a name="PCDrawingCommands">PixelCanvas Drawing Commands</a></h3>
00362 //
00363 // PixelCanvas drawing commands accept simple AIPS++ objects.  Presently the
00364 // drawing commands accept points as Vector<t>'s, where t can be
00365 // any scalar type but Bool.   Bool images are not supported because a Bool 
00366 // cannot represent a color index.  Complex values are not supported because
00367 // there are many ways of creating a single scalar value from complex
00368 // values. 
00369 //
00370 //
00371 // <h3><a name="PCEvents">PixelCanvas Event Handling</a></h3>
00372 //
00373 // There are 3 kinds of events the PixelCanvas reports
00374 //
00375 // <ol>
00376 // <li> refresh event - sent when the canvas must be redrawn.
00377 // <li> position event - sent when a button or key is pressed.
00378 // <li> motion event - sent when the mouse moves over the cursor.
00379 // </ol>
00380 //
00381 // Applications handle 
00382 // <linkto class=PixelCanvas>PixelCanvas</linkto> events by creating 
00383 // <linkto class=PixelCanvas>PixelCanvas</linkto> event handlers
00384 // that must be derived from the appropriate event class, either
00385 // <linkto class=PCRefreshEH>PCRefreshEH</linkto>, 
00386 // <linkto class=PCPositionEH>PCPositionEH</linkto>, or
00387 // <linkto class=PCMotionEH>PCMotionEH</linkto>.  The () operator
00388 // must be overridden and implemented by responding to the
00389 // information contained in the 
00390 // <linkto class=PCRefreshEvent>PCRefreshEvent</linkto>, 
00391 // <linkto class=PCPositionEvent>PCPositionEvent</linkto>, or
00392 // <linkto class=PCMotionEvent>PCMotionEvent</linkto>, as appropriate.
00393 // 
00394 //
00395 // <h3><a name="PCCaching">PixelCanvas Caching Mechanism</a></h3>
00396 //
00397 // There is a system for creating sequences of commands.  It works
00398 // be turning on caching, performing drawing commands, then shutting
00399 // it off.  An id is returned to the user to recall the stored 
00400 // sequence.  This gives the user control over what is to be cached
00401 // while still abstracting the business of caching.
00402 // 
00403 // The cache system improves drawing speed by storing drawing data
00404 // in native library formats.
00405 //
00406 // Data stored in native formats means that, for the X11PixelCanvas, 
00407 //
00408 // <ul>
00409 // <li> images are stored in terms of pixels as XImages, 
00410 // <li> coordinate positions are stored how X likes them (upper left is 0,0), 
00411 // <li> lines are stored as XLines or XSegments, as appropriate 
00412 // <li> Points are stored as XPoints.
00413 // <li> Pixmap Text is stored as drawing strings
00414 // <li> Stroked Text is stored as XSegments or XLines
00415 // </ul>
00416 //
00417 // It is the responsibility of the user to rebuild display lists
00418 // when necessary.  Normally this means when the canvas changes
00419 // size or colormap distribution (if colormaps are in use).
00420 //
00421 //
00422 // <h3><a name="PCColormaps">PixelCanvas Colormap System</a></h3>
00423 //
00424 // The PixelCanvas colormap system design was one of the most difficult
00425 // design problems we faced in building this system.  The design goals
00426 // were as follows:
00427 //
00428 // <ol>
00429 // <li> Wanted to be able to pretend we had multiple simultaneous
00430 //      colormaps available in some display window.
00431 // <li> Wanted to allow for but not demand that multiple windows
00432 //      share the same hardware colormap.
00433 // <li> Wanted to distribute the same colormap to different windows
00434 //      potentially displaying on different terminals.
00435 // <li> Wanted to allow for customizing the colormaps, and allow for
00436 //      data-dependent colormaps.
00437 // <li> Wanted to be able to resize the available colormap while
00438 //      a Display library application was running.
00439 // </ol>
00440 // 
00441 // The constraints above have driven us to the following scheme:
00442 //
00443 // <ol>
00444 // <li> Create something called a 
00445 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00446 // and let it define a table of available colors for one or more
00447 // <linkto class="PixelCanvas">PixelCanvas</linkto>es and be responsible
00448 // for interfacing to the underlying graphics system's color allocation
00449 // facilities.  Through the 
00450 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00451 // one can abstract away the underlying graphic library's tedious and
00452 // cumbersome constructs and functions required to manage color resources
00453 // and visuals and provide a high-level interface based on concepts
00454 // that are better understood.  This interface is implemented as the
00455 // constructors for the classes derived from the
00456 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00457 // class.
00458 //
00459 // <li> Define a <linkto class=Colormap>Colormap</linkto> to mean not a 
00460 // table of colors, but rather a function that takes a floating-point
00461 // parameter in [0.0,1.0] and returns an RGB triple.  This function can
00462 // then be used to fill some arbitrary number of consecutive colorcells.
00463 // Allow for <linkto class=Colormap>Colormap</linkto>s to be of a fixed
00464 // size if needed (then they are called 'rigid')
00465 // and design them for derivation so custom colormaps can be created
00466 // and used in this system.
00467 //
00468 // <li> Define a <linkto class=ColormapManager>ColormapManager</linkto> to be
00469 // responsible for dynamically partitioning its
00470 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00471 // into chunks, one chunk for each registered 
00472 // <linkto class=Colormap>Colormap</linkto>, allowing for rigid
00473 // <linkto class=Colormap>Colormap</linkto>s (that must be for some reason
00474 // of a particular size) and weights to give greater color resolution
00475 // to certain maps.  Make it responsible for filling in the color based
00476 // on its distribution of <linkto class=Colormap>Colormap</linkto>s
00477 // in the <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>.
00478 //
00479 // <li> Allow for <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>s
00480 // to be shared by more than one <linkto class="PixelCanvas">PixelCanvas</linkto>,
00481 // and allow <linkto class="PixelCanvas">PixelCanvas</linkto>es to share
00482 // <linkto class=Colormap>Colormap</linkto>s. 
00483 //
00484 // <li> Try to abstract away all this mess by placing gateways to necessary
00485 // functionality in the <linkto class="PixelCanvas">PixelCanvas</linkto>
00486 // itself.  For example images are drawn on the
00487 // <linkto class="PixelCanvas">PixelCanvas</linkto> through the following
00488 // process:
00489 //
00490 // <ol>
00491 // <li> register a <linkto class=Colormap>Colormap</linkto> with the
00492 // <linkto class="PixelCanvas">PixelCanvas</linkto> (needed only once).
00493 // <li> set the active colormap to the one used in step 1.
00494 // <li> create an image whose values range from 0 to N-1, where N is the size
00495 //      of the active colormap 
00496 //     (<linkto class="PixelCanvas">PixelCanvas</linkto>::getColormapSize()).
00497 // <li> call <linkto class="PixelCanvas">PixelCanvas</linkto>::mapToColor().
00498 // to convert to color values.
00499 // <li> call <linkto class="PixelCanvas">PixelCanvas</linkto>drawImage() 
00500 // with the Matrix of color values
00501 // </ol>
00502 //
00503 // The color image can be reused as long as the distribution of colors
00504 // on the
00505 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00506 // doesn't change.  Any such change will trigger a refresh event with the
00507 // reason Display::ColorTableChange on the affected
00508 // <linkto class="PixelCanvas">PixelCanvas</linkto>. 
00509 // This process can also be used to draw other primitives that each have
00510 // a value associated with it.
00511 // Several colormaps can be switched between by setting the active
00512 // colormap and querying the range, and using the mapToColor function.
00513 //
00514 // <li> Implement a function that resizes the 
00515 // <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>,
00516 // forcing a redistribution of colormaps on affected
00517 // <linkto class="PixelCanvas">PixelCanvas</linkto>es followed by a
00518 // refresh event.  This ultimately causes a reallocation of writable
00519 // color cells on the underlying graphics library and can be
00520 // used to increase or decrease the number of color cells available to
00521 // the <linkto class="PixelCanvasColorTable">PixelCanvasColorTable</linkto>
00522 // and hence to the application.  This mechanism can be used to recover
00523 // allocated color cells from the system map released by other applications
00524 // when they exit, or to balance color resources between two or more
00525 // applications.
00526 //
00527 // </ol>
00528 //
00529 // <hr>
00530 //
00531 // <h2><a name="WorldCanvas">The WorldCanvas</a></h2>
00532 //
00533 // The <linkto class=WorldCanvas>WorldCanvas</linkto> is intended to
00534 // serve as a world-coordinate plotting canvas
00535 //
00536 //
00537 // <h3><a name="WCDrawingCommands">WorldCanvas DrawingCommands</a></h3>
00538 //
00539 // The <linkto class=WorldCanvas>WorldCanvas</linkto> drawing commands
00540 // expect to be given world coordinate values for position information.
00541 //
00542 //
00543 // <h3><a name="WCEvents">WorldCanvas Event Handling</a></h3>
00544 //
00545 // The <linkto class=WorldCanvas>WorldCanvas</linkto> event handling
00546 // is similar to the <linkto class=PixelCanvas>PixelCanvas</linkto>
00547 // event handling, but the <linkto class=WorldCanvas>WorldCanvas</linkto>
00548 // events contain extra information which includes the world coordinate
00549 // and linear coordinate position of the mouse pointer.  The same
00550 // basic three events are available:
00551 //
00552 // <ol>
00553 // <li> refresh event - sent when the canvas must be redrawn.
00554 // <li> position event - sent when a button or key is pressed.
00555 // <li> motion event - sent when the mouse moves over the cursor.
00556 // </ol>
00557 //
00558 // Applications handle 
00559 // <linkto class=WorldCanvas>WorldCanvas</linkto> events by creating 
00560 // <linkto class=WorldCanvas>WorldCanvas</linkto> event handlers
00561 // that must be derived from the appropriate event class, either
00562 // <linkto class=WCRefreshEH>WCRefreshEH</linkto>, 
00563 // <linkto class=WCPositionEH>WCPositionEH</linkto>, or
00564 // <linkto class=WCMotionEH>WCMotionEH</linkto>.  The () operator
00565 // must be overridden and implemented by responding to the
00566 // information contained in the 
00567 // <linkto class=WCRefreshEvent>WCRefreshEvent</linkto>, 
00568 // <linkto class=WCPositionEvent>WCPositionEvent</linkto>, or
00569 // <linkto class=WCMotionEvent>WCMotionEvent</linkto>, as appropriate.
00570 // 
00571 //
00572 // <h3><a name="WCHandlers">Other WorldCanvas Handlers</a></h3>
00573 //
00574 // Other handlers can be registered with the WorldCanvas to customize:
00575 // <ul>
00576 // <li> World Coordinate transformations
00577 // <li> Linear resampling algorithm
00578 // <li> Data scaling methods
00579 // <li> Size control function
00580 // </ul>
00581 //
00582 //
00583 // <h2><a name="WorldCanvasHolder">The WorldCanvasHolder</a></h2>
00584 //
00585 //  The WorldCanvasHolder is a user of a WorldCanvas. It installs handlers on
00586 //  the WorldCanvas for each event a WorldCanvas can generate. The main role
00587 //  of the WorldCanvasHolder is to allow to have more than one DisplayData
00588 //  object draw on a WorldCanvas (e.g contours on top of an image). A number
00589 //  of DisplayDatas can be registered with a WorldCanvasHolder, and the
00590 //  WorldCanvasHolder passes WorldCanvas events to these DisplayData.
00591 //  To control what is displayed on a WorldCanvas, the programmer can put
00592 //  restrictions on a WorldCanvasHolder. Only those DisplayData do actually
00593 //  draw whose restrictions match those of the WorldCanvasHolder. See the
00594 //  example given above, or have a look at the doc of the Animator. 
00595 //
00596 // <h2><a name="DisplayData">The DisplayData Interface</a></h2>
00597 //
00598 // A DisplayData is the class that transforms data (in whatever form: an
00599 // image, a cube, a catalog or whatever) into drawing instructions for the
00600 // WorldCanvas. A DisplayData is the 'workhorse' of the display libary: here
00601 // is defined in what way on can represent data. If one want to add a new way
00602 // of displaying data to aips++, they only thing that has to be done is to
00603 // write a new class, derived from DisplayData, that computes this new
00604 // representation and draws it. For example, if one would want to add volume
00605 // rendering to aips++, one would have to write a class that computes this
00606 // volume rendering (e.g. using some hot-gas algorithm), and draw the result
00607 // of this on a WorldCanvas (ie. simply WorldCanvas.drawImage() on the
00608 // result). DisplayDatas are registered witha WorldCanvasHolder and the
00609 // restriction mechanism is used to select what is being
00610 // displayed. DisplayDatas are also responsible for defining the
00611 // WorldCoordinate system of the WorldCanvas (they have an interface that can
00612 // be called (indirectly) by the WorldCanvas to do the transformations), as
00613 // wel las they have to insure that the state of the WorldCanvas is ok (the
00614 // sizeControl, see above). An example of a DisplayData is the
00615 // ImageDisplayData class, that draws pseudocolor images from a data set.
00616 //
00617 // <h2><a name="Zoomer">The Zoomer</a></h2>
00618 //
00619 // Zooming is done by setying the linear coordinates of the WorldCanvas to
00620 // define the zoom area (using a set function of the WorldCanvas) and force a
00621 // refresh of the WorldCanvas. The Zoomer class defines the userinterface for
00622 // zooming. One can register one (or more) WorldCanvas with a Zoomer. This
00623 // Zoomer installs  a position event handler on the WorldCanvas that listens
00624 // to certain key- and mouse events. The Zoomer defines a default
00625 // userinterface, but this can be re-defined. A Zoomer can also handle more
00626 // than one WorldCanvas, so it is easy to let different WorldCanvases zoom in synch.
00627 //
00628 // <h2><a name="Animator">The Animator</a></h2>
00629 //
00630 // The role of the Animator is to give an easy way of controling what is
00631 // displayed on one or more WorldCanvases. By specifying how an Animator
00632 // controls what is displayed (by using indices, world coordinates or
00633 // restrictions), the Animator sets the necessary restrictions on the
00634 // WorldCanvasHolders that are registered with the Animator, and forces a
00635 // refresh on all of them. All WorldCanvasHolder registered on an Animator
00636 // move in synch. 
00637 //
00638 //
00639 //
00640 
00641 // <hr>
00642 //
00643 // <motivation>
00644 // Need to provide some usefull tools to assist in developing graphical
00645 // C++ applications, addressing the problems encountered in trying to
00646 // use other graphical libraries.
00647 // </motivation>
00648 //
00649 // <hr>
00650 // This section is intended as information about what tasks remain to be
00651 // accomplished for the Display library.
00652 // 
00653 // The following list illustrates work remaining at the PixelCanvas level:
00654 //
00655 // <todo asof="1997/10/06">
00656 // <li> <b>PixelCanvas</b>: change/add PixelCanvas interface to use Matrices for multiple
00657 //      vector graphic primitives, and use those interfaces at the
00658 //      WorldCanvas level.
00659 // <li> compact sequences of drawPoint and drawLine into drawPoints and
00660 //      drawLines, respectively.
00661 // <li> add circle, arc, rounded rectangle drawing primitives.
00662 // <li> implement rotated text perhaps at this level or maybe at the WorldCanvas level
00663 // <li> More testing of the drawing primitives.
00664 // <li> Correct bug related to clipwindow location when XCS (X coordinate syste) y
00665 //      value is less than zero.
00666 // <li> Check function visibility for X11PixelCanvasColorTable
00667 // <li> WorldCanvas Coordinate routines.
00668 // <li> Check all HTML docs for problems.
00669 // </todo>
00670 //
00671 // The following is the todo list for the WorldCanvas and related classes
00672 //
00673 // <todo asof="1997/10/06">
00674 //
00675 // <li> mapToColor and mapToColor3 functions that redirect to pixelCanvas
00676 // <li> decide what drawImage interface higher classes require, and implement
00677 //      those in terms of the PixelCanvas interface.
00678 // <li> test multiple WorldCanvases on a single PixelCanvas.
00679 // <li> WCSplineResampleHandler class to handle bicubic interpolation of arrays ?
00680 // <li> WCFunctionalScaleHandler class to take a functional as a scale function ?
00681 // </todo>
00682 //
00683 // The following is the todo list for the application level classes:
00684 // <todo asof="1997/10/06">
00685 // <li> Write simple display app with colormap editor.
00686 // <li> Demonstrate use of RonAndRenzo colormap implementation.
00687 // </todo>
00688 //
00689 // <hr>
00690 //
00691 // <b>The following section is intended for a programmer who wants to 
00692 // improve the Display Library</b>
00693 //
00694 // <h3>Caching System Optimization</h3>
00695 //
00696 // An advanced optimization to the 
00697 // <linkto class="PixelCanvas">PixelCanvas</linkto>
00698 // caching system would be to compact sequences 
00699 // of drawing commands.  This would mean that a sequence received
00700 // by the PixelCanvas would be transformed into a more efficient sequence
00701 // of drawing commands that produces the same result.  Obviously, sequences 
00702 // of the same commands can often be combined into a single command.  
00703 // But consider for example a drawn raster image I followed by a set of
00704 // vectors V on  top of the image.  This sequence can be represented by 
00705 // { I V }.
00706 //
00707 // We can partition V into 2 sets: Vin (contains vectors drawn inside the 
00708 // image) and Vout (vectors that have portions drawn outside the image). 
00709 // A new image I' can be created from I by drawing I onto a pixmap, then
00710 // painting the vectors Vin on top, and storing the resultant image I'.
00711 //
00712 // The cached sequence is then { I' Vout }, and I and V can be discarded  
00713 // This will result in faster drawing times and reduced memory usage if 
00714 // Vin has significant size because the vectors in Vin are not drawn explicitly.
00715 //
00716 // Similar results can be achieved with drawn text and points, so that some
00717 // sequence { I V P T } can be replaced with { I' Vout Pout Tout }.  Also
00718 // overlapping images can be stored to avoid drawing the overlapping region
00719 // more than once.
00720 //
00721 // It is not clear whether this would be worthwhile to pursue, so it has not
00722 // been implemented.
00723 //
00724 // </synopsis>
00725 //
00726 // </module>
00727 //
00728 
00729 
00730 } //# NAMESPACE CASA - END
00731 
00732 #endif
00733 
00734 // ---- End of module Display ----