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