casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
WorldCanvas.h
Go to the documentation of this file.
00001 //# WorldCanvas.h: class for drawing in world coordinates on the PixelCanvas
00002 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
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_WORLDCANVAS_H
00029 #define TRIALDISPLAY_WORLDCANVAS_H
00030 
00031 #include <list>
00032 #include <casa/aips.h>
00033 #include <casa/Containers/List.h>
00034 #include <casa/Arrays/Matrix.h>
00035 #include <casa/Arrays/Vector.h>
00036 #include <display/DisplayEvents/PCRefreshEH.h>
00037 #include <display/DisplayEvents/PCMotionEH.h>
00038 #include <display/DisplayEvents/PCPositionEH.h>
00039 #include <display/DisplayEvents/WCRefreshEH.h>
00040 #include <display/DisplayEvents/WCMotionEH.h>
00041 #include <display/DisplayEvents/WCPositionEH.h>
00042 #include <display/DisplayEvents/DisplayEH.h>
00043 #include <display/Display/Attribute.h>
00044 #include <display/Display/AttributeBuffer.h>
00045 #include <display/Display/AttValBase.h>
00046 #include <display/Utilities/DisplayOptions.h>
00047 
00048 namespace casa { //# NAMESPACE CASA - BEGIN
00049 
00050 class PixelCanvas;
00051 class Colormap;
00052 class WCCoordinateHandler;
00053 class WCSizeControlHandler;
00054 class WCResampleHandler;
00055 class WCDataScaleHandler;
00056 class WCPGFilter;
00057 class CoordinateSystem;
00058 class DisplayData;
00059 
00060 // <summary> 
00061 // Implementation of drawing in world coordinates on top of a PixelCanvas.
00062 //  </summary>
00063 //
00064 // <prerequisite>
00065 // <li> <linkto class="PixelCanvas">PixelCanvas</linkto>
00066 // <li> <linkto class="Attribute">Attribute</linkto>
00067 // <li> <linkto class="AttributeBuffer">AttributeBuffer</linkto>
00068 // </prerequisite>
00069 //
00070 // <etymology>
00071 // WorldCanvas is a canvas on which primitives specified in world
00072 // coordinates are drawn.
00073 // </etymology>
00074 //
00075 // <synopsis>
00076 
00077 // The world canvas manages a portion of a <linkto
00078 // class="PixelCanvas">PixelCanvas</linkto> and provides mechanisms to
00079 // allow the user to draw images and vectors in world coordinates.
00080 // The position of the WorldCanvas may be dynamically changed.
00081 //
00082 // The WorldCanvas vector graphics commands assume world coordinates
00083 // are specified and use a registered coordinate handler to map those
00084 // coordinates via a linear system to pixel coordinates.  The pixel
00085 // coordinates are then sent on to the <linkto
00086 // class="PixelCanvas">PixelCanvas</linkto> where they are plotted.
00087 //
00088 // Images are drawn by sending a Matrix and specifying the
00089 // world-coordinate location of the center of the lower-left pixel.
00090 // If the dataMin and dataMax values have been set, they will be used
00091 // to scale the data, otherwise the min and max will be scanned.
00092 //
00093 // Customizable tools associated with the WorldCanvas
00094 // available to assist with various aspects of display.
00095 // <ul>
00096 // <li> fitting specified regions of an image to a screen pixel array 
00097 // (<linkto class="WCResampleHandler">WCResampleHandler</linkto>
00098 // <li> scaling real-world values to integers in preparation for conversion to
00099 //      color indices.
00100 // (<linkto class="WCDataScaleHandler">WCDataScaleHandler</linkto>
00101 // <li> controlling the size of the <linkto class="WorldCanvas">WorldCanvas</linkto> prior
00102 //      to drawing.
00103 // (<linkto class="WCSizeControlHandler">WCSizeControlHandler</linkto>)
00104 // <li> Performing the transformation from WorldCoordinates to LinearCoordinates
00105 // (<linkto class="WCCoordinateHandler">WCCoordinateHandler</linkto>)
00106 // </ul>
00107 // 
00108 // The interface for these tools are implemented as abstract base
00109 // classes, and the tools are implemented by deriving from these
00110 // classes and overriding the functions contained therein.
00111 //
00112 // The WorldCanvas provides an interface to the <linkto
00113 // class="PixelCanvas">PixelCanvas</linkto> caching mechanism.  Clever
00114 // use of caching and parsing of the reason field of a <linkto
00115 // class="WCRefreshEvent">WCRefreshEvent</linkto> can reduce
00116 // unnecessary recomputation needed for refreshing the screen.
00117 //
00118 // The WorldCanvas maintains a set of <linkto
00119 // class="Attribute">Attribute</linkto>s which the user can set on the
00120 // WorldCanvas. An Attribute is a combination of a name and a value,
00121 // the value can be of type uInt, Int, Float, Double, Bool and String,
00122 // and Vectors of these. These Attributes serve two purposes: 1) to
00123 // allow to place (using the member functions <src>setAttribute</src>
00124 // and <src> setAttributes</src>) more or less arbitrary information
00125 // on the WorldCanvas that other classes can read from the
00126 // WorldCanvas. Since the name of an Attribute can be defined at run
00127 // time, any name can be used (i.e. there is no pre-defined set of
00128 // names that can only be used), and 2) to have a generic interface to
00129 // some of the internal variables of the WorldCanvas. Some internal
00130 // variabels can be set/read with their own interface routine
00131 // (e.g. linXMin and friends using setZoomRectangleLCS), but they can
00132 // also be modified/read using the Attribute interface (using
00133 // getAttributeValue). The use of e.g. SetZoomRectangleLCS() and
00134 // setAttribute() is equivalent. See <linkto
00135 // class="AttributeBuffer">AttributeBuffer</linkto> for more details.
00136 // The following Attributes (and their types) are pre-defined on the
00137 // WorldCanvas and can be accessed using the Attribute interface
00138 // (note: these Attributes cannot be deleted using removeAttribute()):
00139 // <ul> <li> canvasXOffset (uInt): The offset of the WorldCanvas on
00140 // the PixelCanvas (X) in 'screen pixels' <li> canvasYOffset (uInt):
00141 // The offset of the WorldCanvas on the PixelCanvas (Y) in 'screen
00142 // pixels' <li> canvasYSize (uInt): The size of the WorldCanvas on the
00143 // PixelCanvas (X) in 'screen pixels' <li> canvasYSize (uInt): The
00144 // size of the WorldCanvas on the PixelCanvas (Y) in 'screen pixels'
00145 // <li> fracXOffset (Double): The fractional offset of the WorldCanvas
00146 // on the Pixelcanvas (X) <li> fracYOffset (Double): The fractional
00147 // offset of the WorldCanvas on the Pixelcanvas (Y) <li> fracXSize
00148 // (Double): The fractional size of the WorldCanvas on the Pixelcanvas
00149 // (X) <li> fracYSize (Double): The fractional size of the WorldCanvas
00150 // on the Pixelcanvas (Y) <li> linXMin (Double): The current minimum
00151 // linear coordinate (X) <li> linXMax (Double): The current maximum
00152 // linear coordinate (X) <li> linYMin (Double): The current minimum
00153 // linear coordinate (Y) <li> linYMax (Double): The current maximum
00154 // linear coordinate (Y) <li> linXMinLimit (Double): The current limit
00155 // on the minimum linear coordinate (X) <li> linXMaxLimit (Double):
00156 // The current limit on the maximum linear coordinate (X) <li>
00157 // linYMinLimit (Double): The current limit on the minimum linear
00158 // coordinate (Y) <li> linYMaxLimit (Double): The current limit on the
00159 // maximum linear coordinate (Y) <li> dataMin (Double): The data
00160 // minimum of the WorldCanvas <li> dataMax (Double): The data maximum
00161 // of the WorldCanvas </ul>
00162 //
00163 // The WorldCanvas knows three coordinate systems. 
00164 // <ul>
00165 // <li> the Pixel coordinate system. This corresponds to the pixels in the
00166 // PixelCanvas (and usually will correspond to pixels on the screen)
00167 // <li> a Linear Coordinates system. This has to be set by the user of a
00168 // WorldCanvas (like the WorldCanvasHolder). Normally this will correspond to
00169 // the pixel coordinates of the data array that is displayed, but it is up to
00170 // you to define this. The linear coordinate system is the input for the
00171 // coordinate transformation to world coordinates using a
00172 // WCCoordinateHandler. For example, a position event on the PixelCanvas has
00173 // first its pixel coordinates converted to the linear coodinates and then
00174 // these linear coordinates are converted to world coordinates. Zooming is
00175 // defined by setting the linear coordinates to the area to which you want to
00176 // zoom in to (although the zoom area can also be set using world coordinates,
00177 // but these world coordinates are converted to linear coordinates
00178 // internally).
00179 // <li> a WorldCoordinate system. This is defined by the WCCoordinateHandler
00180 // installed on the WorldCanvas. Normally this will map to the Aips++
00181 // coordinate system that belongs to the data displayed, but this is not a
00182 // requirement.  You can define whatever coordiante system you want, as long
00183 // as you satisfy the interface (mainly that you use the linear coordinates of
00184 // the WorldCanvas as input to get to you World coordinates).
00185 // </ul>
00186 // </synopsis>
00187 // 
00188 // <motivation>
00189 // Wanted a world-coordinate plotting canvas
00190 // </motivation>
00191 //
00192 // <example>
00193 // See the test programs in Display/test
00194 // </example>
00195 //
00196 // <todo>
00197 // <li> Implement contour drawing in world coordinates.
00198 // <li> Fix clear to work correctly in multiple-WC contexts
00199 // <li> complete value-tagged primitive rendering
00200 // <li> figure out what to do with zooming
00201 // <li> stream functions
00202 // <li> drawImage function(s)
00203 // </todo>
00204 
00205 class WorldCanvas : public PCRefreshEH, 
00206                     public PCMotionEH,
00207                     public PCPositionEH,
00208                     public DisplayEH,
00209                     public DisplayOptions {
00210 
00211 public:
00212 
00213   // Construct a WorldCanvas on the given PixelCanvas, at the given
00214   // origin (in fractions of the PixelCanvas extent), and having the
00215   // given size (in the same units).
00216   WorldCanvas(PixelCanvas *pc, Double xOrigin = 0.0, Double yOrigin = 0.0,
00217               Double xSize = 1.0, Double ySize = 1.0);
00218 
00219   // Destructor.
00220   virtual ~WorldCanvas();
00221 
00222   // Return a pointer to the PixelCanvas on which this WorldCanvas is
00223   // installed.
00224   PixelCanvas *pixelCanvas() const 
00225     { return itsPixelCanvas; }
00226 
00227   // Add the given refresh, motion and position event handlers to the
00228   // WorldCanvas.  
00229   // <group>
00230   void addRefreshEventHandler(DisplayEH &eh);
00231   void addMotionEventHandler(WCMotionEH &eh);
00232   void addPositionEventHandler(WCPositionEH &eh);
00233   // </group>
00234 
00235   // Remove the given refresh, motion and position event handlers from
00236   // the WorldCanvas.  
00237   // <group>
00238   void removeRefreshEventHandler(const DisplayEH &eh);
00239   void removeMotionEventHandler(const WCMotionEH &eh);
00240   void removePositionEventHandler(const WCPositionEH &eh);
00241   // </group>
00242 
00243   // Call all of the motion and position event handlers that
00244   // are installed on the WorldCanvas. 
00245   //# (Similar method for refresh handlers has been made private;
00246   //# the public method for that is refresh().    dk 4/05)
00247   // <group>
00248   void callMotionEventHandlers(const WCMotionEvent &ev);
00249   void callPositionEventHandlers(const WCPositionEvent &ev);
00250   // </group>
00251 
00252   // Handle other, generic types of events.  As with call*Handlers above,
00253   // WC handles these new events by simply distributing them to
00254   // event handlers registered on it.  However, rather than create
00255   // any more handler lists in WorldCanvas, generic event handlers
00256   // (DisplayEHs) piggyback on the RefreshEHList.  WorldCanvas is
00257   // also a DisplayEH, and all DisplayEHs implement handling of these
00258   // new events by overriding the (null) base class version
00259   // of this method.
00260   virtual void handleEvent(DisplayEvent& ev);
00261 
00262   // Handle implicit refresh, motion and position events occuring on
00263   // the PixelCanvas on which this WorldCanvas is installed.  These
00264   // functions translate PixelCanvas events into WorldCanvas events.
00265   // <group>
00266   void operator()(const PCRefreshEvent &pev);
00267   void operator()(const PCMotionEvent &pev);
00268   void operator()(const PCPositionEvent &pev);
00269   // </group>
00270 
00271   // Refresh the WorldCanvas for the given reason.  The refresh is
00272   // prevented from occuring if the PixelCanvas is not yet mapped to
00273   // the screen, or if the refreshes have been held with earlier
00274   // call/s to hold() which has/have not been matched with the same
00275   // number of calls to release().
00276   void refresh(const Display::RefreshReason &reason = Display::UserCommand,
00277                const Bool &explicitrequest = True);
00278 
00279   // Is a refresh currently allowed?
00280   Bool refreshAllowed();
00281 
00282   // Hold and release response to refreshes requested with the
00283   // <src>refresh()</src> member function.  Multiple calls to
00284   // <src>hold()</src> can be made, and refreshes will not resume
00285   // until the same number of calls have been made to
00286   // <src>release()</src>.  Note that these functions do not affect
00287   // whether internally (implicitly) generated refreshes continue to
00288   // occur.  That is, refresh events due to PixelCanvas resize events,
00289   // or Colormap changes, for example, will continue to be acted upon.
00290   // <group>
00291   void hold();
00292   void release();
00293   // </group>
00294 
00295   // Set Coordinate, SizeControl, Resample and DataScale handlers for
00296   // the WorldCanvas.  If the given handler is 0, then resort to using
00297   // the default handler.  
00298   // <group>
00299   void setCoordinateHandler(WCCoordinateHandler *ch);
00300   void setSizeControlHandler(WCSizeControlHandler *sh);
00301   void setResampleHandler(WCResampleHandler *rh);
00302   void setDataScaleHandler(WCDataScaleHandler *sh);
00303   // </group>
00304 
00305   // Set the location of the WorldCanvas on its PixelCanvas.
00306   void setWorldCanvasPosition(Double fracXOffset, Double fracYOffset,
00307                               Double fracXSize, Double fracYSize);
00308 
00309   // Pixel, linear and world coordinate transformation functions.  For
00310   // the Vector versions, the coordinate mapping returns False if the
00311   // transformation failed.  For the Matrix versions, failures(i) on
00312   // input should be set to True if the i'th transformation should not
00313   // be attempted.  On output, failures(i) is True if the
00314   // transformation was not attempted, or failed.  If on input the
00315   // failures vector has zero length, it will be assumed that no prior
00316   // failures have occurred.  
00317   // <group>
00318   Bool pixToLin(Vector<Double> &lin, const Vector<Double> &pix);
00319   Bool pixToLin(Matrix<Double> &lin, Vector<Bool> &failures, 
00320                 const Matrix<Double> &pix);
00321   Bool linToPix(Vector<Double> &pix, const Vector<Double> &lin);
00322   Bool linToPix(Matrix<Double> &pix, Vector<Bool> &failures,
00323                 const Matrix<Double> &lin);
00324   Bool linToWorld(Vector<Double> &world, const Vector<Double> &lin);
00325   Bool linToWorld(Matrix<Double> &world, Vector<Bool> &failures,
00326                   const Matrix<Double> &lin);
00327   Bool worldToLin(Vector<Double> &lin, const Vector<Double> &world);
00328   Bool worldToLin(Matrix<Double> &lin, Vector<Bool> &failures,
00329                   const Matrix<Double> &world);
00330   Bool pixToWorld(Vector<Double> &world, const Vector<Double> &pix);
00331   Bool pixToWorld(Matrix<Double> &world, Vector<Bool> &failures,
00332                   const Matrix<Double> &pix);
00333   Bool worldToPix(Vector<Double> &pix, const Vector<Double> &world);
00334   Bool worldToPix(Matrix<Double> &pix, Vector<Bool> &failures,
00335                   const Matrix<Double> &world);
00336   // </group>
00337 
00338   // Register/unregister a Colormap on the PixelCanvas.  Registration
00339   // counts are remembered, so that a particular Colormap is
00340   // guaranteed to be available as long as that Colormap has been
00341   // registered more times than it has been unregistered.  Requests
00342   // are forwarded to the PixelCanvas.
00343   // <group>
00344   void registerColormap(Colormap *cmap, Float weight = 1.0);
00345   void registerColormap(Colormap *cmap, Colormap *cmapToReplace) ;
00346   void unregisterColormap(Colormap *cmap);
00347   // </group>
00348 
00349   // Set and retrieve the current Colormap on the PixelCanvas.  This
00350   // function must be called prior to using a WorldCanvas (or
00351   // PixelCanvas) drawing routines which is expected to use a
00352   // Colormap.  Passing an unregistered Colormap to setColormap will
00353   // result in an exception being thrown.  Requests are forwarded to
00354   // the PixelCanvas.
00355   // <group>
00356   void setColormap(Colormap *cmap); 
00357   Colormap *colormap() const; 
00358   // </group>
00359 
00360   // Display list support functions.  A display list is started with a
00361   // call to <src>newList()</src>, finished with a call to
00362   // <src>endList()</src>, and drawn with a call to
00363   // <src>drawList(x)</src>, with the argument <src>x</src> being the
00364   // list number returned by the original call to
00365   // <src>newList()</src>.  Lists can be deleted individually with
00366   // <src>deleteList(x)</src> or in total with
00367   // <src>deleteLists()</src>.  Requests are forwarded to the
00368   // PixelCanvas.  
00369   // <group>
00370   uInt newList(); 
00371   void endList();
00372   void drawList(uInt list);
00373   void deleteList(uInt list);
00374   void deleteLists();
00375   Bool validList(uInt list);
00376   // </group>
00377 
00378   // Set various graphics attributes.  All of these requests are
00379   // passed directly to the PixelCanvas, except for
00380   // <src>setColor</src>, which also installs the requested color for
00381   // subsequent calls to PgPlot functions.
00382   // <group>
00383   void setColor(const String &color);
00384   void setClearColor(const String &color);
00385   Bool setFont(const String &fontName);
00386   void setForeground(uLong color);
00387   void setBackground(uLong color);
00388   void setLineWidth(Float width);
00389   void setLineStyle(Display::LineStyle style);
00390   void setCapStyle(Display::CapStyle style);
00391   void setJoinStyle(Display::JoinStyle style);
00392   void setFillStyle(Display::FillStyle style);
00393   void setFillRule(Display::FillRule rule);
00394   void setArcMode(Display::ArcMode mode);
00395   // </group>
00396 
00397   // Set/retrieve the background and foreground colors of the
00398   // WorldCanvas.  These can be different to those for the
00399   // PixelCanvas.  Indeed, they will be used as default colors on the
00400   // WorldCanvas when necessary.  
00401   // <group>
00402   Bool setWorldBackgroundColor(const String color);
00403   Bool setWorldForegroundColor(const String color);
00404   String getWorldBackgroundColor() 
00405     { return itsWorldBackgroundColor; }
00406   String getWorldForegroundColor()
00407     { return itsWorldForegroundColor; }
00408   // </group>
00409 
00410   // Set/retrieve the drawing buffer, the target destination for
00411   // graphics.  Requests are passed directly to the PixelCanvas.
00412   // <group>
00413   virtual void setDrawBuffer(Display::DrawBuffer buf);
00414   Display::DrawBuffer drawBuffer() const;
00415   // </group>
00416 
00417   // Set/retrieve the caching strategy on the PixelCanvas.
00418   // Appropriate values are Display::ClientAlways (use client memory
00419   // to cache images [safer]), Display::ServerAlways (use server
00420   // memory to cache images [faster]), and
00421   // Display::ServerMemoryThreshold (use server memory until a
00422   // threshold is reached [not yet implemented]).  Requests are passed
00423   // to the PixelCanvas.  
00424   // <group>
00425   void setImageCacheStrategy(Display::ImageCacheStrategy strategy);
00426   Display::ImageCacheStrategy imageCacheStrategy() const;
00427   // </group>
00428 
00429   // Clear the WorldCanvas, or just the area on the WorldCanvas
00430   // but outside the drawing area, ie. the margins that are normally
00431   // reserved for axis labels and the like.
00432   // <group>
00433   void clear();
00434   void clearNonDrawArea();
00435   // </group>
00436 
00437   // Install the default options for this DisplayData
00438   virtual void setDefaultOptions();
00439 
00440   // Apply options stored in rec to the DisplayData; return value True
00441   // means a refresh is needed.  Any fields added to the
00442   // updatedOptions argument are options which have changed in some
00443   // way due to the setting of other options - ie. they are context
00444   // sensitive.
00445   virtual Bool setOptions(const Record &rec, Record &updatedOptions);
00446 
00447   // Retrieve the current and default options and parameter types.
00448   virtual Record getOptions() const;
00449 
00450   // Set an Attribute or Attributes on the WorldCanvas.
00451   // <group>
00452   void setAttribute(Attribute& at);
00453   void setAttributes(AttributeBuffer& at);
00454   // </group>
00455 
00456   // Remove an Attribute.  Pre-defined Attributes of the WorldCanvas
00457   // cannot be removed (although nothing serious will happen if you
00458   // try).
00459   void removeAttribute(String& name);
00460 
00461   // User interface to get individual values from the attribute buffer.
00462   // <group>
00463   Bool getAttributeValue(const String& name, uInt& newValue) const;  
00464   Bool getAttributeValue(const String& name, Int& newValue) const;
00465   Bool getAttributeValue(const String& name, Float& newValue) const;
00466   Bool getAttributeValue(const String& name, Double& newValue) const;
00467   Bool getAttributeValue(const String& name, Bool& newValue) const;
00468   Bool getAttributeValue(const String& name, String& newValue) const;
00469   Bool getAttributeValue(const String& name, Vector<uInt>& newValue) const;
00470   Bool getAttributeValue(const String& name, Vector<Int>& newValue) const;
00471   Bool getAttributeValue(const String& name, Vector<Float>& newValue) const;
00472   Bool getAttributeValue(const String& name, Vector<Double>& newValue) const;
00473   Bool getAttributeValue(const String& name, Vector<Bool>& newValue) const;
00474   Bool getAttributeValue(const String& name, Vector<String>& newValue) const;
00475   // </group>
00476 
00477   // Check if a certain Attribute exists.
00478   Bool existsAttribute(String& name) const;
00479 
00480   // Get the type of an Attribute.
00481   AttValue::ValueType attributeType(String& name) const;
00482   
00483   // Position the PGPLOT filter on the WorldCanvas.  If linear is
00484   // specified False, then the alignment is done by world coordinates,
00485   // assuming that a linear approximation is valid.
00486   // void verifyPGFilterAlignment(const Bool &linear = True);
00487 
00488   // Acquire and release a PGPLOT device for this WorldCanvas.  This
00489   // is necessary since PGPLOT generally only supports 8 currently
00490   // active devices.  So refresh cycles on the WorldCanvas acquire a
00491   // PGPLOT device at the start, and release it at the end.  Cycles
00492   // are counted so that external user-classes can call these functions
00493   // if necessary in a nested state.  If <src>linear</src> is specified 
00494   // as <src>False</src>, then the PGPLOT device is aligned by world
00495   // coordinates, under the assumption that a linear approximation is
00496   // valid, that is, the curvature is small.
00497   // <group>
00498   virtual void acquirePGPLOTdevice(const Bool &linear = True);
00499   virtual void releasePGPLOTdevice();
00500   // </group>
00501 
00502   // Return the PGPLOT device id for external use.
00503   virtual Int pgid() const;
00504 
00505   // Draw unrotated text at the given position.  If the conversion
00506   // from world to pixel coordinates fails, the text is not drawn, and
00507   // False is returned.  If linear is True, then the provided position
00508   // is actually in linear world canvas coordinates, rather than true
00509   // world coordinates.
00510   Bool drawText(const Vector<Double> &point, const String &text,
00511                 Display::TextAlign alignment = Display::AlignCenter,
00512                 const Bool &linear = False);
00513 
00514   // Draw a single point using the current color.  If the conversion
00515   // from world to pixel coordinates fails, the point is not drawn,
00516   // and False is the return value.  If linear is True, then the point
00517   // position is given in linear world canvas coordinates, not true
00518   // world coordinates.
00519   Bool drawPoint(const Vector<Double> &point, const Bool &linear = False);
00520 
00521   // Draw a single line using the current color.  If either of the
00522   // conversions from world to pixel coordinates fail, then the line
00523   // is not drawn, and False is returned.  If linear is True, then the
00524   // line endpoints are given in world canvas linear coordinates
00525   // rather than real world coordinates.
00526   Bool drawLine(const Vector<Double> &a, const Vector<Double> &b,
00527                 const Bool &linear = False);
00528 
00529   // Draw a bunch of points using the current color.  If any points
00530   // fail to convert then none of them are drawn, and False is
00531   // returned.  If linear is True, then the vertices are given in
00532   // linear world canvas coordinates rather than real world
00533   // coordinates.
00534   Bool drawPoints(const Matrix<Double> &points, const Bool &linear = False);
00535 
00536   // Draw a set of points using the current color.  Those points which
00537   // fail to convert, or lie outside the WorldCanvas drawing area, are
00538   // not drawn.
00539   Bool drawPoints(const Vector<Float> &px, const Vector<Float> &py,
00540                   Bool linear = False);
00541 
00542   // Draw a set of text strings using the current color.  If any
00543   // points fail to convert, then those particular strings are not
00544   // drawn.  <src>rotation</src> gives the rotation of the text in
00545   // degrees counter-clockwise from horizontal.  <src>xoffset</src>
00546   // and <src>yoffset</src> can be given to globally shift the labels
00547   // by the specified amounts (in units of the character height).  If
00548   // linear is True, then the vertices are given in linear world
00549   // canvas coordinates rather than true world coordinates.
00550   Bool drawTextStrings(const Vector<Float> &px, const Vector<Float> &py,
00551                        const Vector<String> &strings, 
00552                        const Float rotation = 0.0,
00553                        const Float xoffset = 0.0, 
00554                        const Float yoffset = 0.0,
00555                        const Bool linear = False);
00556 
00557   // Draw a set of markers using the current color and a given pixel
00558   // <src>size</src>. If any points fail to convert, then those
00559   // particular points are not marked.  <src>markertype</src> is an
00560   // <src>Display::Marker</src>. If linear is True, then the points
00561   // are given in linear world canvas coordinates rather than true
00562   // world coordinates.
00563   Bool drawMarkers(const Vector<Float> &px, const Vector<Float> &py,
00564                    const Display::Marker = Display::Cross, const Int size = 5, 
00565                    const Bool& linear = False);
00566 
00567   Bool drawMappedMarkers(const Vector<Float> &px, const Vector<Float> &py,
00568                          const Vector<Float>& values,
00569                          const Int sizemin = 1, const Int sizemax = 20, 
00570                          const Display::Marker = Display::Cross,
00571                          const Bool& linear = False);
00572 
00573   // Draw pairs of lines using the current color.  If any points fail
00574   // to convert then the lines are not drawn and False is returned.
00575   // If linear is True, then the vertices are given as linear world
00576   // coordinates rather than true world coordinates.
00577   Bool drawLines(const Matrix<Double> &vertices, const Bool &linear = False);
00578 
00579 
00580   // Draw a polyline (connected line) between the vertices using the
00581   // current color.  If any coordinates fail to convert from world to
00582   // pixel, then the entire polyline is not drawn and False is
00583   // returned.  The end point is not implicitly connected to the
00584   // starting point.  If linear is True, then the provided vertices
00585   // are actually linear world canvas coordinates.
00586   Bool drawPolyline(const Matrix<Double> &vertices,
00587                     const Bool &linear = False);
00588 
00589   // Draw a polygon (closed line, or line loop using the points)
00590   // using the current color.  If any coordinates fail to convert
00591   // then the polygon is not drawn.  The end point is implicitly
00592   // connected to the start point.  If linear is True, then the
00593   // provided vertices are actually linear world coordinates.
00594   Bool drawPolygon(const Matrix<Double> &vertices, 
00595                    const Bool &linear = False);
00596 
00597   // Draw a set of points in colors which are taken from the current
00598   // Colormap.
00599   Bool drawColormappedPoints(const Matrix<Double> &points,
00600                              const Vector<Float> &values,
00601                              const Bool &linear = False);
00602 
00603   // Draw a set of colored ellipses, possibly with outlines.  The x
00604   // and y locations must given, along with semi-major and semi-minor
00605   // axes, and position angle measured in degrees positive from the x
00606   // axis in a counter-clockwise direction.  The size of the ellipses
00607   // is globally scaled by the scale factor, and if <src>outline</src>
00608   // is <src>True</src>, then each ellipse will have an outline in the
00609   // current pen color.
00610   Bool drawColormappedEllipses(const Matrix<Double> &centres,
00611                                const Vector<Float> &smajor,
00612                                const Vector<Float> &sminor,
00613                                const Vector<Float> &pangle,
00614                                const Vector<Float> &colors,
00615                                const Float &scale = 1.0,
00616                                const Bool &outline = True,
00617                                const Bool &linear = False);
00618 
00619 
00620   // This routine is specialized for drawing image restoring-beam ellipses.
00621   // Its parameters are defined so as to require as little conversion as
00622   // possible of restoring beam information as stored in an image header.
00623   //
00624   // It does nothing unless the axes on display map to the two axes of a
00625   // DirectionCoordinate within the WC CS (WorldCanvas::itsCoordinateSystem).
00626   // Center location cx,cy is specified as a fraction of WC draw area:
00627   // (0,0) is blc, (1,1) is trc; they default to (.1, .1).  
00628   //
00629   // The unit strings for major,minor are given in in majunit, minunit, and
00630   // should be valid angular units (they default to "arcsec").  major/minor
00631   // are the _full_ major and minor axis sizes in terms of relative direction
00632   // world coordinates.
00633   //
00634   // pa specifies "position angle", in the angular units specified by paunit.
00635   // pa uses the image header convention "North-to-East"; more precisely,
00636   // 0 degrees aligns the major axis along increasing DirCoord(1) (commonly
00637   // Dec), 90 degrees aligns it along increasing DirCoord(0) (commonly RA).
00638   // (NB: increasing RA commonly means decreasing pixel/Lattice coordinates).
00639   // In the common case, this means that pa increases counterclockwise from
00640   // vertical.  Note that this is _not_ the pa convention in some other
00641   // PixelCanvas/WorldCanvas drawEllipse() routines (where pa is always
00642   // counterclockwise from horizontal).
00643   // 
00644   // Also note: this routine attempts to do the right thing in oddball cases
00645   // such as displaying Dec on the horizontal axis (pa 0 would also be
00646   // horizontal in that case), distorted ('flexible') aspect ratio (ellipse
00647   // also distorted appropriately) or all-sky images in which the beam may be
00648   // displayed in a canvas area where absolute world coordinates do not exist.
00649   // It should even take care of uneven coordinate 'increments' (non-square
00650   // image data pixels).  
00651   // (So far, it does _not_ correctly handle non-identity transformation
00652   // matrices in the DirectionCoordinate (e.g. rotated "North")-- which I
00653   // think is true in many other places as well... -- for someone's to-do list
00654   // (not mine, I hope)).
00655   Bool drawBeamEllipse(Float major, Float minor,  Float pa,
00656                        String majunit="arcsec", String minunit="arcsec",
00657                        String paunit="deg",
00658                        Float cx=.1f, Float cy=.1f, Bool outline=True);
00659   
00660   
00661   // Draw a contour map at the specified levels, and place the lower
00662   // left pixel at blPos, and the upper right pixel at trPos.  If
00663   // <src>usePixelEdges</src> is True, then the given world positions
00664   // are the position of the blc and trc of the blc and trc pixels,
00665   // otherwise they are the positions of the centres of the pixels.
00666   // Note that the contours are not intrinsically drawn in world
00667   // coordinates.  For complex data, the conversion to real values is
00668   // done according to the last call to setComplexToRealMethod.
00669   // Returns true if OK, false if error...
00670   // <group>
00671   bool drawContourMap(const Vector<Double> &blPos, 
00672                       const Vector<Double> &trPos,
00673                       const Matrix<Float> &data,
00674                       const Vector<Float> &levels,
00675                       const Bool usePixelEdges = False);
00676 
00677 
00678   bool drawContourMap(const Vector<Double> &blPos,
00679                       const Vector<Double> &trPos,
00680                       const Matrix<Complex> &data,
00681                       const Vector<Float> &levels,
00682                       const Bool usePixelEdges = False);
00683   // </group>
00684 
00685   // Draw a contour map at the specified levels, and place the lower
00686   // left pixel at blPos, and the upper right pixel at trPos.  If
00687   // <src>usePixelEdges</src> is True, then the given world positions
00688   // are the position of the blc and trc of the blc and trc pixels,
00689   // otherwise they are the positions of the centres of the pixels.
00690   // Note that the contours are not intrinsically drawn in world
00691   // coordinates.  For complex data, the conversion to real values is
00692   // done according to the last call to setComplexToRealMethod.  These
00693   // functions also have a <src>mask</src> argument, which is a
00694   // Boolean pixel mask whose shape must match that of
00695   // <src>data</src>, and only pixels in <src>data</src> where
00696   // corresponding pixels in <src>mask</src> are <src>True</src> will
00697   // be contoured.
00698   // Returns true if OK, false if error...
00699   // <group>
00700   bool drawContourMap(const Vector<Double> &blPos, 
00701                       const Vector<Double> &trPos,
00702                       const Matrix<Float> &data,
00703                       const Matrix<Bool> &mask,
00704                       const Vector<Float> &levels,
00705                       const Bool usePixelEdges = False);
00706   bool drawContourMap(const Vector<Double> &blPos,
00707                       const Vector<Double> &trPos,
00708                       const Matrix<Complex> &data,
00709                       const Matrix<Bool> &mask,
00710                       const Vector<Float> &levels,
00711                       const Bool usePixelEdges = False);
00712   // </group>
00713 
00714   // Optimization to speed up colormap fiddling in 24bit mode (software
00715   // Colormap); see images_, below for usage.  Set opaqueMask to True to
00716   // draw masked pixels in the background color; otherwise they will be
00717   // transparent (letting whatever was drawn previously at that point show
00718   // through).
00719   Bool redrawIndexedImage(void* drawObj, Display::RefreshReason reason,
00720                           Bool opaqueMask=False);
00721   
00722   // Remove image from the colormap change cache, if any (see images_, below).
00723   // Return value indicates whether there was anything to remove.
00724   Bool removeIndexedImage(void* drawObj);
00725   
00726   // Clear the whole colormap change cache (see images_, below).
00727   void clearColormapChangeCache();
00728   
00729   // Draw an image, mapping data values to Colormap entries, and place
00730   // the lower left pixel at blPos, and the upper right pixel at
00731   // trPos.  If <src>usePixelEdges</src> is True, then the given world
00732   // positions are the position of the blc and trc of the blc and trc
00733   // pixels, otherwise they are the positions of the centres of the
00734   // pixels. 
00735   // See images_, below, for non-default usage of the drawObj parameter.
00736   // <group>
00737   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00738                  const Matrix<Float> &data, const Bool usePixelEdges = False,
00739                  void* drawObj=0);
00740   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00741                  const Matrix<Complex> &data,
00742                  const Bool usePixelEdges = False, void* drawObj=0);
00743   // </group>       
00744 
00745   // Draw an image, mapping data values to Colormap entries, and place
00746   // the lower left pixel at blPos, and the upper right pixel at
00747   // trPos.  If <src>usePixelEdges</src> is True, then the given world
00748   // positions are the position of the blc and trc of the blc and trc
00749   // pixels, otherwise they are the positions of the centres of the
00750   // pixels.  These functions also have a <src>mask</src> argument,
00751   // which is a Boolean pixel mask whose shape must match that of 
00752   // <src>data</src>, and only pixels in <src>data</src> where 
00753   // corresponding pixels in <src>mask</src> are <src>True</src>
00754   // will be drawn.  Set opaqueMask to True to draw masked pixels in
00755   // the background color; otherwise they will be transparent (letting
00756   // whatever was drawn previously at that point show through).
00757   // See images_, below, for non-default usage of the drawObj parameter.
00758   // <group>
00759   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00760                  const Matrix<Float> &data, const Matrix<Bool> &mask,
00761                  const Bool usePixelEdges = False, void* drawObj=0,
00762                  Bool opaqueMask=False);
00763   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00764                  const Matrix<Complex> &data, const Matrix<Bool> &mask,
00765                  const Bool usePixelEdges = False, void* drawObj=0,
00766                  Bool opaqueMask=False);
00767 
00768   // </group>       
00769   // Draw a component of a multi-channel image, mapping data values to
00770   // component levels, and place the lower left pixel at blPos, and
00771   // the upper right pixel at trPos.  If <src>usePixelEdges</src> is
00772   // True, then the given world positions are the position of the blc
00773   // and trc of the blc and trc pixels, otherwise they are the
00774   // positions of the centres of the pixels.  The components are not
00775   // drawn until flushComponentImages() is called.  
00776   // <group>
00777   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00778                  const Matrix<Float> &data, 
00779                  const Display::ColorComponent &colorcomponent,
00780                  const Bool usePixelEdges = False);
00781   void drawImage(const Vector<Double> &blPos, const Vector<Double> &trPos,
00782                  const Matrix<Complex> &data,
00783                  const Display::ColorComponent &colorcomponent,
00784                  const Bool usePixelEdges = False);
00785   // </group>
00786 
00787   // Draw a vector map.    
00788   // <group>
00789    bool drawVectorMap(const Vector<Double>& blc,
00790                       const Vector<Double>& trc,
00791                       const Matrix<Complex>& data,
00792                       const Matrix<Bool>& mask,
00793                       Float angleConversionFactor,
00794                       Float phasePolarity,
00795                       Bool debias, Float variance,
00796                       Int xPixelInc, Int yPixelInc,
00797                       Float scale, Bool arrow, Float barb,
00798                       Float rotation,
00799                       Double xWorldInc, Double yWorldInc,
00800                       const Bool usePixelEdges);
00801 
00802    bool drawVectorMap(const Vector<Double>& blc,
00803                       const Vector<Double>& trc,
00804                       const Matrix<Float>& data,
00805                       const Matrix<Bool>& mask,
00806                       Float angleConversionFactor,
00807                       Float phasePolarity,
00808                       Bool debias, Float variance,
00809                       Int xPixelInc, Int yPixelInc,
00810                       Float scale, Bool arrow, Float barb,
00811                       Float rotation,
00812                       Double xWorldInc, Double yWorldInc,
00813                       const Bool usePixelEdges);
00814    // </group>
00815 
00816 // Draw marker maps.  Only makerType "square" available presently.
00817 // The marker holds its shape in screen pixel coordinates.  This
00818 // means a square is always a square regardless of aspect ratio
00819 // Returns true if OK, false if error...
00820 // <group>
00821    bool drawMarkerMap(const Vector<Double>& blc,
00822                       const Vector<Double>& trc,
00823                       const Matrix<Float>& data,
00824                       const Matrix<Bool>& mask,
00825                       Int xPixelInc, Int yPixelInc,
00826                       Float scale, Double xWorldInc, Double yWorldInc,
00827                       const String& markeType,
00828                       Bool usePixelEdges);
00829    bool drawMarkerMap(const Vector<Double>& blc,
00830                       const Vector<Double>& trc,
00831                       const Matrix<Complex>& data,
00832                       const Matrix<Bool>& mask,
00833                       Int xPixelInc, Int yPixelInc,
00834                       Float scale, Double xWorldInc, Double yWorldInc,
00835                       const String& markerType, 
00836                       Bool usePixelEdges);
00837 // </group>
00838 
00839 
00840   // Flush the component images, ie. compose a single image from the
00841   // buffered channel images and place it on the WorldCanvas.  This 
00842   // effectively is passed on to the PixelCanvas where the component
00843   // images are cached.
00844   void flushComponentImages();
00845 
00846   // Buffer memory exchanges which operate only on the area of the
00847   // WorldCanvas.  (Not cacheable yet.) 
00848   // <group>
00849   void copyBackBufferToFrontBuffer();
00850   void copyFrontBufferToBackBuffer();
00851   void swapBuffers();
00852   // </group>
00853 
00854   // Provide information on the extents of the linear coordinate
00855   // system. 
00856   //  <group>
00857   Double linXMin() const 
00858     { return itsLinXMin; }
00859   Double linYMin() const 
00860     { return itsLinYMin; }
00861   Double linXMax() const 
00862     { return itsLinXMax; }
00863   Double linYMax() const 
00864     { return itsLinYMax; }
00865   // </group>
00866 
00867   // Provide information on the limits of the linear coordinate
00868   // system.
00869   // <group>
00870   Double linXMinLimit() const 
00871     { return itsLinXMinLimit; }
00872   Double linYMinLimit() const 
00873     { return itsLinYMinLimit; }
00874   Double linXMaxLimit() const 
00875     { return itsLinXMaxLimit; }
00876   Double linYMaxLimit() const 
00877     { return itsLinYMaxLimit; }
00878   // </group>
00879 
00880   // Provide information on the WorldCanvas offset and size.
00881   // <group>
00882   uInt canvasXOffset() const 
00883     { return itsCanvasXOffset; }
00884   uInt canvasYOffset() const 
00885     { return itsCanvasYOffset; }
00886   uInt canvasXSize() const 
00887     { return itsCanvasXSize; }
00888   uInt canvasYSize() const
00889     { return itsCanvasYSize; }
00890   // </group>
00891 
00892   // Provide information on the WorldCanvas drawable offset and size.
00893   // <group>
00894   uInt canvasDrawXOffset() const 
00895     { return itsCanvasDrawXOffset; }
00896   uInt canvasDrawYOffset() const
00897     { return itsCanvasDrawYOffset; }
00898   uInt canvasDrawXSize() const
00899     { return itsCanvasDrawXSize; }
00900   uInt canvasDrawYSize() const
00901     { return itsCanvasDrawYSize; }
00902   // </group>
00903 
00904   // Set the zoom rectangle to the specfied linear coordinate range.
00905   void setZoomRectangleLCS(const Vector<Double> &min,
00906                            const Vector<Double> &max);
00907 
00908   // Move the zoom rectangle across the screen, ie. pan.
00909   void moveZoomRectangleLCS(double dx, double dy);
00910 
00911   // Reset the zoom to show the entire allowable range of the linear
00912   // coordinate system.
00913   void resetZoomRectangle();
00914 
00915   // Set the allowable range of the linear coordinate system.
00916   void setLinearCoordinateSystem(const Vector<Double> &blc,
00917                                  const Vector<Double> &trc,
00918                                  Bool resetZoom = True);
00919 
00920   // Functions to set and retrieve the minimum and maximum data values
00921   // for scaling data that is drawn on the WorldCanvas.  These values
00922   // are forwarded to the scale handler, when, for example, images are
00923   // drawn.
00924   // <group>
00925   Double dataMin() const 
00926     { return itsDataMin; }
00927   void setDataMin(Double min) 
00928     { itsDataMin = min; }
00929   Double dataMax() const 
00930     { return itsDataMax; }
00931   void setDataMax(Double max)
00932     { itsDataMax = max; }
00933   void setDataMinMax(Double min, Double max)
00934     { itsDataMin = min; itsDataMax = max; }
00935   // </group>
00936 
00937   // ComplexToRealMethod defines which real component of a Complex
00938   // image to extract when it is necessary to convert Complex data
00939   // into real data.
00940   // <group>
00941   Display::ComplexToRealMethod complexToRealMethod() const 
00942     { return itsComplexToRealMethod; }
00943   void setComplexToRealMethod(const Display::ComplexToRealMethod method)
00944     { itsComplexToRealMethod = method; }
00945   // </group>
00946 
00947   // Set and retrieve the CoordinateSystem of this WorldCanvas.  Set
00948   // with 0 and the WorldCanvas loses its CoordinateSystem!
00949   //#
00950   //#dk note 9/07 -- Yes, isn't that exciting, esp. since subsequent calls
00951   //# to coordinateSystem() will SEGV, and no method was provided to
00952   //# even test for it....  hasCS() added to somewhat bandage over this
00953   //# hazard...
00954   // <group>
00955   void setCoordinateSystem(const CoordinateSystem &csys);
00956   const CoordinateSystem &coordinateSystem() const;
00957   Bool hasCS() const { return itsCoordinateSystem!=0;  }
00958   // </group>
00959 
00960   // Convenience functions returning whether a pixel coordinate is
00961   // within bounds of the WC's inner draw area, the WC, or the underlying PC.
00962   // <group>
00963 
00964   Bool inDrawArea(Int x, Int y) const {
00965     Int x0 = itsCanvasXOffset + itsCanvasDrawXOffset;
00966     Int x1 = x0 + itsCanvasDrawXSize;
00967     Int y0 = itsCanvasYOffset + itsCanvasDrawYOffset;
00968     Int y1 = y0 + itsCanvasDrawYSize;
00969     return  x>=x0 && x<x1  &&  y>=y0  && y<y1 ;  }
00970 
00971   Bool inWC(Int x, Int y) const {
00972     Int x0 = itsCanvasXOffset;  Int x1 = x0 + itsCanvasXSize;
00973     Int y0 = itsCanvasYOffset;  Int y1 = y0 + itsCanvasYSize;
00974     return  x>=x0 && x<x1  &&  y>=y0  && y<y1 ;  }
00975 
00976   Bool inPC(Int x, Int y);
00977 
00978   // </group>
00979   
00980 
00981   // Install a single restriction, or a buffer of restrictions, on the
00982   // WorldCanvas which DisplayData must match in order that they
00983   // be allowed to draw themselves.
00984   // <group>
00985   void setRestriction(const Attribute& restriction);
00986   void setRestrictions(const AttributeBuffer& resBuff);
00987   // </group>
00988 
00989   // Check if a named restriction exists.
00990   const Bool existRestriction(const String& name) const;
00991   
00992   // Remove the named restriction, or all restrictions, from the
00993   // WorldCanvas.
00994   // <group>
00995   void removeRestriction(const String& restrictionName);
00996   void removeRestrictions();
00997   // </group>
00998   
00999   // Determine whether the restrictions installed on the
01000   // WorldCanvas match the given restriction or buffer of
01001   // restrictions.
01002   // <group>
01003   Bool matchesRestriction(const Attribute& restriction) const;
01004   Bool matchesRestrictions(const AttributeBuffer& buffer) const;
01005   // </group>
01006  
01007   // Return the buffer of restrictions installed on this
01008   // WorldCanvas.
01009   const AttributeBuffer *restrictionBuffer() const;
01010   // convienience function based on "restriction buffer"...
01011   int zIndex( ) const;
01012 
01013   // The DD in charge of setting WC coordinate state (0 if none).
01014   const DisplayData *csMaster() const { return itsCSmaster;  }
01015   DisplayData *&csMaster() { return itsCSmaster;  }
01016 
01017   // Is the specified DisplayData the one in charge of WC state?
01018   // (During DD::sizeControl() execution, it means instead that the
01019   // DD has permission to become CSmaster, if it can).
01020   Bool isCSmaster(const DisplayData *dd) const {
01021     return dd==csMaster() && dd!=0;  }
01022     
01023   // Return the names and units of the world coordinate axes.
01024   // <group>
01025   virtual Vector<String> worldAxisNames() const;
01026   virtual Vector<String> worldAxisUnits() const;
01027   // </group>
01028 
01029   const std::list<DisplayData*> &displaylist( ) const;
01030 
01031   static const String LEFT_MARGIN_SPACE_PG;
01032   static const String RIGHT_MARGIN_SPACE_PG;
01033   static const String BOTTOM_MARGIN_SPACE_PG;
01034   static const String TOP_MARGIN_SPACE_PG;
01035 
01036  private:
01037 
01038 
01039   // Support for construction.
01040   void ctorInit();
01041 
01042   // Call all registered refresh handlers (public method is refresh()). 
01043   void callRefreshEventHandlers(const WCRefreshEvent &ev);
01044 
01045    
01046   // Update canvas sizes/offsets from the fracOffsets, and vice versa.
01047   // <group>
01048   void updateCanvasSizesOffsets();
01049   void updateFracSizesOffsets();
01050   // </group>
01051 
01052   // Convert the given coordinate/s to pixel coordinates.  If linear
01053   // is True, then the given coordinates are in linear world coordinates,
01054   // otherwise they are real world coordinates.  A return value of False
01055   // indicates the conversion failed.
01056   // <group>
01057   Bool castingConversion(Vector<Int> &pixelpt, const Vector<Double> &worldpt,
01058                          const Bool &linear);
01059   Bool castingConversion(Matrix<Int> &pixelpts, const Matrix<Double> &worldpts,
01060                          const Bool &linear);
01061   Bool castingConversion(Matrix<Float> &pixelpts, 
01062                          const Matrix<Double> &worldpts,
01063                          const Bool &linear);
01064   // </group>
01065 
01066   // Convert the given coordinate/s to pixel coordinates.  If
01067   // <src>linear</src> is <src>True</src>, then the input coordinates
01068   // are linear world coordinates, otherwise they are true world
01069   // coordinates.  This version applies clipping, so that any points
01070   // in the series which lie outside the linear coordinate range of
01071   // the WorldCanvas are discarded.  Thus the output Vectors can be
01072   // shorter than the input Vectors.  A mask indicating which of the
01073   // input points were valid is returned for user reference.
01074   Bool castingClippingConversion(Vector<Int> &pixelx, Vector<Int> &pixely,
01075                                  Vector<Bool> &validConversions,
01076                                  const Vector<Float> &worldx, 
01077                                  const Vector<Float> &worldy,
01078                                  const Bool linear);
01079 
01080    // Actually draw the vector field.   All pa * angleConversionFactor
01081    // must be radians.  rotation  must be radians.  if amp is of
01082    // dimension 0, amplitude unity is assumed.  if mask if dimension
01083    // 0 all data are assumed good.
01084    bool drawVectorMap(const Vector<Double>& blc,
01085                       const Vector<Double>& trc,
01086                       const Matrix<Float>& amp,
01087                       const Matrix<Float>& pa,
01088                       const Matrix<Bool>& mask,
01089                       Float angleConversionFactor,
01090                       Float phasePolarity,
01091                       Bool debias, Float variance,
01092                       Int xPixelInc, Int yPixelInc,
01093                       Float scale, Bool arrow, Float barb, Float rotation,
01094                       Double xWorldInc, Double yWorldInc,
01095                       const Bool usePixelEdges);
01096 
01097 
01098   // Trim and resample an image, returning the actual world BLC and
01099   // TRC for drawing, and the resampled image.
01100   void trimAndResampleImage(Vector<Double> &drawBlc,
01101                             Vector<Double> &drawTrc,
01102                             Matrix<Float> &sampledImage,
01103                             const Vector<Double> &blc,
01104                             const Vector<Double> &trc,
01105                             const Matrix<Float> &data,
01106                             const Bool &usePixelEdges = False);
01107 
01108   // Trim and resample an image, returning the actual world BLC and
01109   // TRC for drawing, and the resampled image.  This function takes
01110   // a mask indicating which pixels should be drawn.  This function
01111   // therefore also trims and resamples the mask.
01112   void trimAndResampleImage(Vector<Double> &drawBlc,
01113                             Vector<Double> &drawTrc,
01114                             Matrix<Float> &sampledImage,
01115                             Matrix<Bool> &resampledMask,
01116                             const Vector<Double> &blc,
01117                             const Vector<Double> &trc,
01118                             const Matrix<Float> &data,
01119                             const Matrix<Bool> &mask,
01120                             const Bool &usePixelEdges = False);
01121 
01122   // Draw an image where <src>scaledImage</src> gives the Colormap
01123   // index of each screen (PixelCanvas) pixel.  'blc' contains X and Y
01124   // PixelCanvas coordinates.  Masked version as well.
01125   // For masked version, set opaqueMask to True to draw masked pixels in
01126   // the background color; otherwise they will be transparent (letting
01127   // whatever was drawn previously at that point show through).
01128   // <group>
01129   void mapToColorAndDrawImage(const Vector<Int> &blc,
01130                               const Matrix<uInt> &scaledImage);
01131   void mapToColorAndDrawImage(const Vector<Int> &blc,
01132                               const Matrix<uInt> &scaledImage,
01133                               const Matrix<Bool> &mask,
01134                               Bool opaqueMask=False);
01135   // </group>
01136   // Draw a set of points where <src>scaledValues</src> gives the
01137   // Colormap index of each point.  Point coordinates ('points')
01138   // are either linear or world coordinates, as specified by 'linear'.
01139   Bool mapToColorAndDrawPoints(const Matrix<Double> &points,
01140                                const Vector<uInt> &scaledValues,
01141                                const Bool &linear = False);
01142 
01143   // Draw a set of ellipses where <src>scaledValues</src> gives the
01144   // Colormap index of each point.  Point coordinates ('points')
01145   // are either linear or world coordinates, as specified by 'linear'.
01146   Bool mapToColorAndDrawEllipses(const Matrix<Double> &centres,
01147                                  const Vector<Float> &smajor,
01148                                  const Vector<Float> &sminor,
01149                                  const Vector<Float> &pangle,
01150                                  const Vector<uInt> scaledValues,
01151                                  const Float &scale,
01152                                  const Bool &outline,
01153                                  const Bool &linear);
01154 
01155   
01156   // <b>***Cached***</b> blc pixel where this world canvas begins =
01157   // itsPixelCanvas->width()*frac(X|Y)Offset_.
01158   // <group>
01159   uInt itsCanvasXOffset;
01160   uInt itsCanvasYOffset;
01161   // </group>
01162 
01163   // <b>***Cached***</b> number of pixels in each dimension given to
01164   // the world canvas = itsPixelCanvas->width()*(frac(X|Y)Size_.
01165   // <group>
01166   uInt itsCanvasXSize;
01167   uInt itsCanvasYSize;
01168   // </group>
01169 
01170   // Fractional position of world canvas on pixel canvas.  The offset
01171   // values are always in the range of [0.0,1.0], and sizes must be
01172   // smaller or equal to (1.0 - offset) for each dimension.
01173   // <group>
01174   Double itsFracXOffset;
01175   Double itsFracYOffset;
01176   Double itsFracXSize;
01177   Double itsFracYSize;
01178   // </group>
01179 
01180   // <b>***Cached***</b> blc pixel where the world canvas 'draw area'
01181   // (inside margins, labels) begins, relative to WC blc.
01182   // <group>
01183   uInt itsCanvasDrawXOffset;
01184   uInt itsCanvasDrawYOffset;
01185   // </group>
01186 
01187   // <b>***Cached***</b> number of pixels in each dimension given to
01188   // the drawable part of the world canvas
01189   // <group>
01190   uInt itsCanvasDrawXSize;
01191   uInt itsCanvasDrawYSize;
01192   // </group>
01193 
01194   // Linear Coordinate System ranges.
01195   // <group>
01196   Double itsLinXMin;
01197   Double itsLinYMin;
01198   Double itsLinXMax;
01199   Double itsLinYMax;
01200   // </group>
01201 
01202   // Linear Coordinate System Limits.
01203   // <group>
01204   Double itsLinXMinLimit;
01205   Double itsLinYMinLimit;
01206   Double itsLinXMaxLimit;
01207   Double itsLinYMaxLimit;
01208   // </group>
01209 
01210   // Dynamic data minimum and maximum for this WorldCanvas.
01211   Double itsDataMin, itsDataMax;
01212 
01213   // Method to use to convert complex data into real values.
01214   Display::ComplexToRealMethod itsComplexToRealMethod;
01215 
01216   // Event handler lists and convenient iterators.
01217   // <group>
01218   List<DisplayEH *> itsRefreshEHList;
01219   List<WCPositionEH *> itsPositionEHList;
01220   List<WCMotionEH *> itsMotionEHList;
01221   mutable ListIter<DisplayEH *> *itsREHListIter;
01222   mutable ListIter<WCPositionEH *> *itsPEHListIter;
01223   mutable ListIter<WCMotionEH *> *itsMEHListIter;
01224   // </group>
01225 
01226   // Other handler lists.
01227   // <group>
01228   WCSizeControlHandler *itsSizeControlHandler;
01229   WCCoordinateHandler *itsCoordinateHandler;
01230   WCResampleHandler *itsResampleHandler;
01231   WCDataScaleHandler *itsDataScaleHandler;
01232   // </group>
01233 
01234   // Store whether we "own" the various handlers.
01235   // <group>
01236   Bool itsOwnSizeControlHandler;
01237   Bool itsOwnCoordinateHandler;
01238   Bool itsOwnResampleHandler;
01239   Bool itsOwnDataScaleHandler;
01240   // </group>
01241 
01242   // Buffer for Attributes.
01243   AttributeBuffer attributes;
01244 
01245   // Background/foreground colors.
01246   String itsWorldBackgroundColor;
01247   String itsWorldForegroundColor;
01248 
01249   // PixelCanvas pointer.
01250   PixelCanvas *itsPixelCanvas;
01251 
01252   // PGPLOT filter.
01253   WCPGFilter *itsPGFilter;
01254 
01255   // Status of hold/release.
01256   Int itsHoldCount;
01257   Bool itsRefreshHeld;
01258   Display::RefreshReason itsHeldReason;
01259 
01260   // The CoordinateSystem for this WorldCanvas.  New addition, only
01261   // supported and used by "new" classes.
01262   CoordinateSystem *itsCoordinateSystem;
01263 
01264   // This state is set True when the pointer is in this WC and a pointer
01265   // button is pressed (with no buttons pressed previously).  When True,
01266   // all PC motion and pointer button events are propagated to this WC's
01267   // handlers (only), regardless of whether the pointer has moved off the WC.
01268   // It is reset to False when all buttons are released.  This simulates
01269   // the 'automatic grab' (implemented in X for whole windows), on the WC
01270   // level.
01271   Bool itsGrabbing;
01272 
01273   
01274   // ColorIndexedImage_ stores the state of a WorldCanvas::drawImage()
01275   // rendering after the chosen data plane has been resampled to screen
01276   // (Pixelcanvas) pixels and scaled to indices within a fixed-size
01277   // Colormap, but prior to mapping to actual colors for display.
01278   // 'Caching' of this state is useful in 24-bit (TrueColor) applications,
01279   // greatly speeding up redrawing when only the mapping to colors is changed.
01280   //# Formerly only one instance of this state was stored in a WorldCanvas
01281   //# (itsCachedImage and friends), but this caused confusion and errors
01282   //# when more that one DD was drawing on the WC.
01283   // Packaging this state allows different instances to be cached by
01284   // different callers of drawImage() if desired, to be reused by them
01285   // when appropriate via WC::redrawIndexedImage().  Reuse is 'appropriate'
01286   // only when nothing has changed since the original drawImage() call
01287   // except the actual colors assigned to the map indices; among other things,
01288   // the size of the Colormap used must be the same as that of the original.
01289   //
01290   // Note: this level of 'caching' is distinct from the more elaborate
01291   // 'drawlists' which are supported by WC/PC and cached in DisplayMethods.
01292   
01293   struct ColorIndexedImage_ {
01294     Matrix<uInt> data;          // colormap indices
01295     Matrix<Bool> mask;
01296     Vector<Int> blc;
01297     uInt colormapSize;
01298   
01299     ColorIndexedImage_() : data(), mask(), blc(2,0) {  }
01300     void clear() { data.resize(); mask.resize(); blc=0;  }
01301     Bool maskValid() { return mask.nelements()!=0u &&
01302                                 mask.shape().isEqual(data.shape());  }  };
01303     
01304   // Cache of pre-drawn ColorIndexedImage_'s.   When a caller of drawImage()
01305   // wants to save one, it passes a drawing-object pointer in the 'drawObj'
01306   // parameter for use as a retrieval key.  It should provide the same key
01307   // to redrawIndexedImage() in order to reuse the image.
01308   //# This mechanism attempts to avoid some erroneous reuses of
01309   //# 'itsCachedImage' among different DDs (bugs 4937, 5032).   (dk 3/05)
01310   SimpleOrderedMap<void*, ColorIndexedImage_*> images_;
01311 
01312   // Retrieve an indexed image to write onto.  Used (exclusively) by
01313   // WC::drawImage().  If one exists in the cache under this objId key,
01314   // clear it for reuse; otherwise return a new one. If a (non-zero) objId
01315   // was provided, it will be cached under that key; removeIndexedImage()
01316   // can be used to remove such cached images explicitly, but the cache is
01317   // also frequently cleared automatically.  If no caching is requested,
01318   // however, (objId=0), the caller must delete the image himself when
01319   // finished -- that type of call is equivalent to 'new ColorIndexedImage_'.
01320   ColorIndexedImage_* getClearedColorIndexedImage(void* drawObj=0);
01321 
01322   // A buffer to contain the restrictions that DisplayDatas must match
01323   // if they are to be allowed to draw themselves.
01324   AttributeBuffer itsRestrictions;
01325 
01326   
01327   // [First] responder to 'sizeControl', responsible for setting
01328   // WC CS, zoom window and draw area.  It will be 0 initially, and
01329   // whenever the old master is unregistered (until a new master responds).
01330   // This is a further attempt toward a coherent sense of 'who's in charge'
01331   // of WC[H] state (there is more to do).
01332   //
01333   // Some day, the WC CS should be directly responsible for all the Canvas's
01334   // coordinate conversions.  For now at least we'll know that they're done
01335   // by the DD below (which should be equivalent).
01336   DisplayData* itsCSmaster;
01337   
01338   // itsId & itsRef used to ensure thread-safe execution of pgplot
01339  
01340   uInt itsId; // id of wc instance
01341 
01342 
01343   // WorldCanvas::refresh is a recursive function. itsRef is used to
01344   // determine when the recursion is over. i.e, when the initial
01345   // refresh call is exiting
01346   uInt itsRef;
01347 
01348 };
01349 
01350 
01351 } //# NAMESPACE CASA - END
01352 
01353 #endif