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