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