1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkContext2D.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 // .NAME vtkContext2D - Class for drawing 2D primitives to a graphical context.
17 //
18 // .SECTION Description
19 // This defines the interface for drawing onto a 2D context. The context must
20 // be set up with a vtkContextDevice2D derived class that provides the functions
21 // to facilitate the low level calls to the context. Currently only an OpenGL
22 // based device is provided, but this could be extended in the future.
23 
24 #ifndef vtkContext2D_h
25 #define vtkContext2D_h
26 
27 #include "vtkRenderingContext2DModule.h" // For export macro
28 #include "vtkObject.h"
29 
30 class vtkWindow;
31 
32 class vtkContext3D;
33 class vtkStdString;
34 class vtkUnicodeString;
35 class vtkTextProperty;
36 
37 class vtkPoints2D;
38 class vtkVector2f;
39 class vtkRectf;
40 class vtkUnsignedCharArray;
41 class vtkContextDevice2D;
42 class vtkPen;
43 class vtkBrush;
44 class vtkImageData;
45 class vtkTransform2D;
46 class vtkAbstractContextBufferId;
47 
48 class VTKRENDERINGCONTEXT2D_EXPORT vtkContext2D : public vtkObject
49 {
50 public:
51   vtkTypeMacro(vtkContext2D, vtkObject);
52   virtual void PrintSelf(ostream &os, vtkIndent indent);
53 
54   // Description:
55   // Creates a 2D Painter object.
56   static vtkContext2D *New();
57 
58 //BTX
59   // Description:
60   // Begin painting on a vtkContextDevice2D, no painting can occur before this call
61   // has been made. Only one painter is allowed at a time on any given paint
62   // device. Returns true if successful, otherwise false.
63   bool Begin(vtkContextDevice2D *device);
64 
65   vtkGetObjectMacro(Device, vtkContextDevice2D);
66 
67   // Description:
68   // Ends painting on the device, you would not usually need to call this as it
69   // should be called by the destructor. Returns true if the painter is no
70   // longer active, otherwise false.
71   bool End();
72 
73   // Description:
74   // Tell if the context is in BufferId creation mode. Initial value is false.
75   bool GetBufferIdMode() const;
76 
77   // Description:
78   // Start BufferId creation Mode.
79   // \pre not_yet: !GetBufferIdMode()
80   // \pre bufferId_exists: bufferId!=0
81   // \post started: GetBufferIdMode()
82   void BufferIdModeBegin(vtkAbstractContextBufferId *bufferId);
83 
84   // Description:
85   // Finalize BufferId creation Mode. It makes sure that the content of the
86   // bufferId passed in argument of BufferIdModeBegin() is correctly set.
87   // \pre started: GetBufferIdMode()
88   // \post done: !GetBufferIdMode()
89   void BufferIdModeEnd();
90 
91   // Description:
92   // Draw a line between the specified points.
93   void DrawLine(float x1, float y1, float x2, float y2);
94 
95   // Description:
96   // Draw a line between the specified points.
97   void DrawLine(float p[4]);
98 
99   // Description:
100   // Draw a line between the specified points.
101   // Note: Fastest path - points packed in x and y.
102   void DrawLine(vtkPoints2D *points);
103 
104   // Description:
105   // Draw a poly line between the specified points.
106   void DrawPoly(float *x, float *y, int n);
107 
108   // Description:
109   // Draw a poly line between the specified points - fastest code path due to
110   // memory layout of the coordinates.
111   void DrawPoly(vtkPoints2D *points);
112 
113   // Description:
114   // Draw a poly line between the specified points, where the float array is of
115   // size 2*n and the points are packed x1, y1, x2, y2 etc.
116   // Note: Fastest code path - points packed in x and y.
117   void DrawPoly(float *points, int n);
118 
119   // Description:
120   // Draw a poly line between the specified points, where the float array is of
121   // size 2*n and the points are packed x1, y1, x2, y2 etc. The line will be colored by
122   // the colors array, which must have nc_comps components (defining a single color).
123   // Note: Fastest code path - points packed in x and y.
124   void DrawPoly(float *points, int n,
125                 unsigned char *colors, int nc_comps);
126 
127   // Description:
128   // Draw a point at the supplied x and y coordinate
129   void DrawPoint(float x, float y);
130 
131   // Description:
132   // Draw the specified number of points using the x and y arrays supplied
133   void DrawPoints(float *x, float *y, int n);
134 
135   // Description:
136   // Draw a poly line between the specified points - fastest code path due to
137   // memory layout of the coordinates.
138   void DrawPoints(vtkPoints2D *points);
139 
140   // Description:
141   // Draw a poly line between the specified points, where the float array is of
142   // size 2*n and the points are packed x1, y1, x2, y2 etc.
143   // Note: Fastest code path - points packed in x and y.
144   void DrawPoints(float *points, int n);
145 
146   // Description:
147   // Draw a series of point sprites, images centred at the points supplied.
148   // The supplied vtkImageData is the sprite to be drawn, only squares will be
149   // drawn and the size is set using SetPointSize.
150   void DrawPointSprites(vtkImageData *sprite, vtkPoints2D *points);
151 
152   // Description:
153   // Draw a series of point sprites, images centred at the points supplied.
154   // The supplied vtkImageData is the sprite to be drawn, only squares will be
155   // drawn and the size is set using SetPointSize. Points will be colored by
156   // the colors array, which must be the same length as points.
157   void DrawPointSprites(vtkImageData *sprite, vtkPoints2D *points,
158                         vtkUnsignedCharArray *colors);
159   void DrawPointSprites(vtkImageData *sprite, float *points, int n,
160                         unsigned char *colors, int nc_comps);
161 
162   // Description:
163   // Draw a series of point sprites, images centred at the points supplied.
164   // The supplied vtkImageData is the sprite to be drawn, only squares will be
165   // drawn and the size is set using SetPointSize.
166   void DrawPointSprites(vtkImageData *sprite, float *points, int n);
167 
168   // Description:
169   // Draw a series of markers centered at the points supplied. The \a shape
170   // argument controls the marker shape, and can be one of
171   //   - VTK_MARKER_CROSS
172   //   - VTK_MARKER_PLUS
173   //   - VTK_MARKER_SQUARE
174   //   - VTK_MARKER_CIRCLE
175   //   - VTK_MARKER_DIAMOND
176   // Marker size is determined by the current pen width.
177   // \param colors is an optional array of colors.
178   // \param nc_comps is the number of components for the color.
179   virtual void DrawMarkers(int shape, bool highlight, float *points, int n,
180                            unsigned char *colors, int nc_comps);
181   virtual void DrawMarkers(int shape, bool highlight, float *points, int n);
182   virtual void DrawMarkers(int shape, bool highlight, vtkPoints2D *points);
183   virtual void DrawMarkers(int shape, bool highlight, vtkPoints2D *points,
184                            vtkUnsignedCharArray *colors);
185 
186   // Description:
187   // Draw a rectangle with origin at x, y and width w, height h
188   void DrawRect(float x, float y, float w, float h);
189 
190   // Description:
191   // Draw a quadrilateral at the specified points (4 points, 8 floats in x, y).
192   void DrawQuad(float x1, float y1, float x2, float y2,
193                 float x3, float y3, float x4, float y4);
194   void DrawQuad(float *p);
195 
196   // Description:
197   // Draw a strip of quads
198   void DrawQuadStrip(vtkPoints2D *points);
199   void DrawQuadStrip(float *p, int n);
200 
201   // Description:
202   // Draw a polygon specified specified by the points using the x and y arrays
203   // supplied
204   void DrawPolygon(float *x, float *y, int n);
205 
206   // Description:
207   // Draw a polygon defined by the specified points - fastest code path due to
208   // memory layout of the coordinates.
209   void DrawPolygon(vtkPoints2D *points);
210 
211   // Description:
212   // Draw a polygon defined by the specified points, where the float array is
213   // of size 2*n and the points are packed x1, y1, x2, y2 etc.
214   // Note: Fastest code path - points packed in x and y.
215   void DrawPolygon(float *points, int n);
216 
217   // Description:
218   // Draw an ellipse with center at x, y and radii rx, ry.
219   // \pre positive_rx: rx>=0
220   // \pre positive_ry: ry>=0
221   void DrawEllipse(float x, float y, float rx, float ry);
222 
223   // Description:
224   // Draw a circular wedge with center at x, y, outer radius outRadius,
225   // inner radius inRadius between angles startAngle and stopAngle
226   // (expressed in degrees).
227   // \pre positive_outRadius: outRadius>=0
228   // \pre positive_inRadius: inRadius>=0
229   // \pre ordered_radii: inRadius<=outRadius
230   void DrawWedge(float x, float y, float outRadius,
231                  float inRadius,float startAngle,
232                  float stopAngle);
233 
234   // Description:
235   // Draw an elliptic wedge with center at x, y, outer radii outRx, outRy,
236   // inner radii inRx, inRy between angles startAngle and stopAngle
237   // (expressed in degrees).
238   // \pre positive_outRx: outRx>=0
239   // \pre positive_outRy: outRy>=0
240   // \pre positive_inRx: inRx>=0
241   // \pre positive_inRy: inRy>=0
242   // \pre ordered_rx: inRx<=outRx
243   // \pre ordered_ry: inRy<=outRy
244   void DrawEllipseWedge(float x, float y, float outRx, float outRy,
245                         float inRx, float inRy, float startAngle,
246                         float stopAngle);
247 
248 
249   // Description:
250   // Draw a circular arc with center at x,y with radius r between angles
251   // startAngle and stopAngle (expressed in degrees).
252   // \pre positive_radius: r>=0
253   void DrawArc(float x, float y, float r, float startAngle,
254                float stopAngle);
255 
256   // Description:
257   // Draw an elliptic arc with center at x,y with radii rX and rY between
258   // angles startAngle and stopAngle (expressed in degrees).
259   // \pre positive_rX: rX>=0
260   // \pre positive_rY: rY>=0
261   void DrawEllipticArc(float x, float y, float rX, float rY, float startAngle,
262                        float stopAngle);
263 
264 
265   // Description:
266   // Draw the supplied image at the given x, y location (bottom corner).
267   void DrawImage(float x, float y, vtkImageData *image);
268 
269   // Description:
270   // Draw the supplied image at the given x, y location (bottom corner).
271   // Scale the supplied image by scale.
272   void DrawImage(float x, float y, float scale, vtkImageData *image);
273 
274   // Description:
275   // Draw the supplied image at the given position. The origin, width, and
276   // height are specified by the supplied vtkRectf variable pos. The image
277   // will be drawn scaled to that size.
278   void DrawImage(const vtkRectf& pos, vtkImageData *image);
279 
280   // Description:
281   // Draw some text to the screen in a bounding rectangle with the alignment
282   // of the text properties respecting the rectangle. The points should be
283   // supplied as bottom corner (x, y), width, height.
284   void DrawStringRect(vtkPoints2D *rect, const vtkStdString &string);
285   void DrawStringRect(vtkPoints2D *rect, const vtkUnicodeString &string);
286   void DrawStringRect(vtkPoints2D *rect, const char* string);
287 
288   // Description:
289   // Draw some text to the screen.
290   void DrawString(vtkPoints2D *point, const vtkStdString &string);
291   void DrawString(float x, float y, const vtkStdString &string);
292   void DrawString(vtkPoints2D *point, const vtkUnicodeString &string);
293   void DrawString(float x, float y, const vtkUnicodeString &string);
294   void DrawString(vtkPoints2D *point, const char* string);
295   void DrawString(float x, float y, const char* string);
296 
297   // Description:
298   // Compute the bounds of the supplied string. The bounds will be copied to the
299   // supplied bounds variable, the first two elements are the bottom corner of
300   // the string, and the second two elements are the width and height of the
301   // bounding box.
302   void ComputeStringBounds(const vtkStdString &string, vtkPoints2D *bounds);
303   void ComputeStringBounds(const vtkStdString &string, float bounds[4]);
304   void ComputeStringBounds(const vtkUnicodeString &string, vtkPoints2D *bounds);
305   void ComputeStringBounds(const vtkUnicodeString &string, float bounds[4]);
306   void ComputeStringBounds(const char* string, vtkPoints2D *bounds);
307   void ComputeStringBounds(const char* string, float bounds[4]);
308 
309   // Description:
310   // Calculate the largest possible font size where the supplied string will fit
311   // within the specified bounds.  In addition to being returned, this font size
312   // is also used to update the vtkTextProperty used by this object.
313   // NOTE: text rotation is ignored for the purposes of this function.
314   int ComputeFontSizeForBoundedString(const vtkStdString &string, float width,
315                                       float height);
316 
317   // Description:
318   // Draw a MathText formatted equation to the screen. See
319   // http://matplotlib.sourceforge.net/users/mathtext.html for more information.
320   // MathText requires matplotlib and python, and the vtkMatplotlib module must
321   // be enabled manually during build configuration. This method will do nothing
322   // but print a warning if vtkMathTextUtilities::GetInstance() returns NULL.
323   void DrawMathTextString(vtkPoints2D *point, const vtkStdString &string);
324   void DrawMathTextString(float x, float y, const vtkStdString &string);
325   void DrawMathTextString(vtkPoints2D *point, const char *string);
326   void DrawMathTextString(float x, float y, const char *string);
327 
328   // Description:
329   // Draw a MathText formatted equation to the screen. See
330   // http://matplotlib.sourceforge.net/users/mathtext.html for more information.
331   // MathText requires matplotlib and python, and the vtkMatplotlib module must
332   // be enabled manually during build configuration.
333   // If MathText is not available on the target device the non-MathText string
334   // in "fallback" is rendered using DrawString.
335   void DrawMathTextString(vtkPoints2D *point, const vtkStdString &string,
336                           const vtkStdString &fallback);
337   void DrawMathTextString(float x, float y, const vtkStdString &string,
338                           const vtkStdString &fallback);
339   void DrawMathTextString(vtkPoints2D *point, const char *string,
340                           const char *fallback);
341   void DrawMathTextString(float x, float y, const char *string,
342                           const char *fallback);
343 
344 
345   // Description:
346   // Return true if MathText rendering available on the current device.
347   bool MathTextIsSupported();
348 
349   // Description:
350   // Apply the supplied pen which controls the outlines of shapes, as well as
351   // lines, points and related primitives. This makes a deep copy of the vtkPen
352   // object in the vtkContext2D, it does not hold a pointer to the supplied object.
353   void ApplyPen(vtkPen *pen);
354 
355   // Description:
356   // Get the pen which controls the outlines of shapes, as well as lines,
357   // points and related primitives. This object can be modified and the changes
358   // will be reflected in subsequent drawing operations.
359   vtkPen* GetPen();
360 
361   // Description:
362   // Apply the supplied brush which controls the outlines of shapes, as well as
363   // lines, points and related primitives. This makes a deep copy of the vtkBrush
364   // object in the vtkContext2D, it does not hold a pointer to the supplied object.
365   void ApplyBrush(vtkBrush *brush);
366 
367   // Description:
368   // Get the pen which controls the outlines of shapes as well as lines, points
369   // and related primitives.
370   vtkBrush* GetBrush();
371 
372   // Description:
373   // Apply the supplied text property which controls how text is rendered.
374   // This makes a deep copy of the vtkTextProperty object in the vtkContext2D,
375   // it does not hold a pointer to the supplied object.
376   void ApplyTextProp(vtkTextProperty *prop);
377 
378   // Description:
379   // Get the text properties object for the vtkContext2D.
380   vtkTextProperty* GetTextProp();
381 
382   // Description:
383   // Set the transform for the context, the underlying device will use the
384   // matrix of the transform. Note, this is set immediately, later changes to
385   // the matrix will have no effect until it is set again.
386   void SetTransform(vtkTransform2D *transform);
387 
388   // Description:
389   // Compute the current transform applied to the context.
390   vtkTransform2D* GetTransform();
391 
392   // Description:
393   // Append the transform for the context, the underlying device will use the
394   // matrix of the transform. Note, this is set immediately, later changes to
395   // the matrix will have no effect until it is set again. The matrix of the
396   // transform will multiply the current context transform.
397   void AppendTransform(vtkTransform2D *transform);
398 
399   // Description:
400   // Push/pop the transformation matrix for the painter (sets the underlying
401   // matrix for the device when available).
402   void PushMatrix();
403   void PopMatrix();
404 
405   // Description:
406   // Apply id as a color.
407   void ApplyId(vtkIdType id);
408 
409   // Description:
410   // Float to int conversion, performs truncation but with a rounding
411   // tolerance for float values that are within 1/256 of their closest
412   // integer.
413   static int FloatToInt(float x);
414 
415   // Description:
416   // Get the vtkContext3D device, in order to do some 3D rendering. This API
417   // is very experimental, and may be moved around.
418   vtkGetObjectMacro(Context3D, vtkContext3D)
419   virtual void SetContext3D(vtkContext3D *context);
420 
421 //BTX
422 protected:
423   vtkContext2D();
424   ~vtkContext2D();
425 
426   vtkContextDevice2D *Device; // The underlying device
427   vtkTransform2D *Transform;  // Current transform
428 
429   vtkAbstractContextBufferId *BufferId;
430   vtkContext3D *Context3D; // May be very temporary - get at a 3D version.
431 
432 private:
433   vtkContext2D(const vtkContext2D &); // Not implemented.
434   void operator=(const vtkContext2D &);   // Not implemented.
435 
436   // Description:
437   // Calculate position of text for rendering in a rectangle.
438   vtkVector2f CalculateTextPosition(vtkPoints2D* rect);
439 
440 //ETX
441 };
442 
FloatToInt(float x)443 inline int vtkContext2D::FloatToInt(float x)
444 {
445   // Use a tolerance of 1/256 of a pixel when converting.
446   // A float has only 24 bits of precision, so we cannot
447   // make the tolerance too small.  For example, a tolerance
448   // of 2^-8 means that the tolerance will be significant
449   // for float values up to 2^16 or 65536.0.  But a
450   // tolerance of 2^-16 would only be significant for
451   // float values up to 2^8 or 256.0.  A small tolerance
452   // disappears into insignificance when added to a large float.
453   float tol = 0.00390625; // 1.0/256.0
454   tol = (x >= 0 ? tol : -tol);
455   return static_cast<int>(x + tol);
456 }
457 
458 #endif //vtkContext2D_h
459