DISTRHO Plugin Framework
NanoVG.hpp
1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
6  * or without fee is hereby granted, provided that the above copyright notice and this
7  * permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DGL_NANO_WIDGET_HPP_INCLUDED
18 #define DGL_NANO_WIDGET_HPP_INCLUDED
19 
20 #include "Color.hpp"
21 #include "Widget.hpp"
22 
23 struct NVGcontext;
24 struct NVGpaint;
25 
26 START_NAMESPACE_DGL
27 
28 // -----------------------------------------------------------------------
29 // Forward class names
30 
31 class NanoVG;
32 
33 // -----------------------------------------------------------------------
34 // NanoImage
35 
36 /**
37  NanoVG Image class.
38 
39  This implements NanoVG images as a C++ class where deletion is handled automatically.
40  Images need to be created within a NanoVG or NanoWidget class.
41  */
42 class NanoImage
43 {
44 private:
45  struct Handle {
46  NVGcontext* context;
47  int imageId;
48 
49  Handle() noexcept
50  : context(nullptr),
51  imageId(0) {}
52 
53  Handle(NVGcontext* c, int id) noexcept
54  : context(c),
55  imageId(id) {}
56  };
57 
58 public:
59  /**
60  Constructor for an invalid/null image.
61  */
62  NanoImage();
63 
64  /**
65  Constructor.
66  */
67  NanoImage(const Handle& handle);
68 
69  /**
70  Destructor.
71  */
72  ~NanoImage();
73 
74  /**
75  Create a new image without recreating the C++ class.
76  */
77  NanoImage& operator=(const Handle& handle);
78 
79  /**
80  Wherever this image is valid.
81  */
82  bool isValid() const noexcept;
83 
84  /**
85  Get size.
86  */
87  Size<uint> getSize() const noexcept;
88 
89  /**
90  Get the OpenGL texture handle.
91  */
92  GLuint getTextureHandle() const;
93 
94 private:
95  Handle fHandle;
96  Size<uint> fSize;
97  friend class NanoVG;
98 
99  /** @internal */
100  void _updateSize();
101 
102  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoImage)
103 };
104 
105 // -----------------------------------------------------------------------
106 // NanoVG
107 
108 /**
109  NanoVG class.
110 
111  This class exposes the NanoVG drawing API.
112  All calls should be wrapped in beginFrame() and endFrame().
113 
114  @section State Handling
115  NanoVG contains state which represents how paths will be rendered.
116  The state contains transform, fill and stroke styles, text and font styles, and scissor clipping.
117 
118  @section Render styles
119  Fill and stroke render style can be either a solid color or a paint which is a gradient or a pattern.
120  Solid color is simply defined as a color value, different kinds of paints can be created
121  using linearGradient(), boxGradient(), radialGradient() and imagePattern().
122 
123  Current render style can be saved and restored using save() and restore().
124 
125  @section Transforms
126  The paths, gradients, patterns and scissor region are transformed by an transformation
127  matrix at the time when they are passed to the API.
128  The current transformation matrix is a affine matrix:
129  [sx kx tx]
130  [ky sy ty]
131  [ 0 0 1]
132  Where: sx,sy define scaling, kx,ky skewing, and tx,ty translation.
133  The last row is assumed to be 0,0,1 and is not stored.
134 
135  Apart from resetTransform(), each transformation function first creates
136  specific transformation matrix and pre-multiplies the current transformation by it.
137 
138  Current coordinate system (transformation) can be saved and restored using save() and restore().
139 
140  @section Images
141  NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering.
142  In addition you can upload your own image. The image loading is provided by stb_image.
143 
144  @section Paints
145  NanoVG supports four types of paints: linear gradient, box gradient, radial gradient and image pattern.
146  These can be used as paints for strokes and fills.
147 
148  @section Scissoring
149  Scissoring allows you to clip the rendering into a rectangle. This is useful for various
150  user interface cases like rendering a text edit or a timeline.
151 
152  @section Paths
153  Drawing a new shape starts with beginPath(), it clears all the currently defined paths.
154  Then you define one or more paths and sub-paths which describe the shape. The are functions
155  to draw common shapes like rectangles and circles, and lower level step-by-step functions,
156  which allow to define a path curve by curve.
157 
158  NanoVG uses even-odd fill rule to draw the shapes. Solid shapes should have counter clockwise
159  winding and holes should have counter clockwise order. To specify winding of a path you can
160  call pathWinding(). This is useful especially for the common shapes, which are drawn CCW.
161 
162  Finally you can fill the path using current fill style by calling fill(), and stroke it
163  with current stroke style by calling stroke().
164 
165  The curve segments and sub-paths are transformed by the current transform.
166 
167  @section Text
168  NanoVG allows you to load .ttf files and use the font to render text.
169 
170  The appearance of the text can be defined by setting the current text style
171  and by specifying the fill color. Common text and font settings such as
172  font size, letter spacing and text align are supported. Font blur allows you
173  to create simple text effects such as drop shadows.
174 
175  At render time the font face can be set based on the font handles or name.
176 
177  Font measure functions return values in local space, the calculations are
178  carried in the same resolution as the final rendering. This is done because
179  the text glyph positions are snapped to the nearest pixels sharp rendering.
180 
181  The local space means that values are not rotated or scale as per the current
182  transformation. For example if you set font size to 12, which would mean that
183  line height is 16, then regardless of the current scaling and rotation, the
184  returned line height is always 16. Some measures may vary because of the scaling
185  since aforementioned pixel snapping.
186 
187  While this may sound a little odd, the setup allows you to always render the
188  same way regardless of scaling. i.e. following works regardless of scaling:
189 
190  @code
191  const char* txt = "Text me up.";
192  textBounds(vg, x,y, txt, NULL, bounds);
193  beginPath(vg);
194  roundedRect(vg, bounds[0], bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]);
195  fill(vg);
196  @endcode
197 
198  Note: currently only solid color fill is supported for text.
199  */
200 class NanoVG
201 {
202 public:
203  enum CreateFlags {
204  /**
205  Flag indicating if geometry based anti-aliasing is used (may not be needed when using MSAA).
206  */
208 
209  /**
210  Flag indicating if strokes should be drawn using stencil buffer. The rendering will be a little
211  slower, but path overlaps (i.e. self-intersecting or sharp turns) will be drawn just once.
212  */
214 
215  /**
216  Flag indicating that additional debug checks are done.
217  */
218  CREATE_DEBUG = 1 << 2,
219  };
220 
221  enum ImageFlags {
222  IMAGE_GENERATE_MIPMAPS = 1 << 0, // Generate mipmaps during creation of the image.
223  IMAGE_REPEAT_X = 1 << 1, // Repeat image in X direction.
224  IMAGE_REPEAT_Y = 1 << 2, // Repeat image in Y direction.
225  IMAGE_FLIP_Y = 1 << 3, // Flips (inverses) image in Y direction when rendered.
226  IMAGE_PREMULTIPLIED = 1 << 4 // Image data has premultiplied alpha.
227  };
228 
229  enum Align {
230  // Horizontal align
231  ALIGN_LEFT = 1 << 0, // Align horizontally to left (default).
232  ALIGN_CENTER = 1 << 1, // Align horizontally to center.
233  ALIGN_RIGHT = 1 << 2, // Align horizontally to right.
234  // Vertical align
235  ALIGN_TOP = 1 << 3, // Align vertically to top.
236  ALIGN_MIDDLE = 1 << 4, // Align vertically to middle.
237  ALIGN_BOTTOM = 1 << 5, // Align vertically to bottom.
238  ALIGN_BASELINE = 1 << 6 // Align vertically to baseline (default).
239  };
240 
241  enum LineCap {
242  BUTT,
243  ROUND,
244  SQUARE,
245  BEVEL,
246  MITER
247  };
248 
249  enum Solidity {
250  SOLID = 1, // CCW
251  HOLE = 2 // CW
252  };
253 
254  enum Winding {
255  CCW = 1, // Winding for solid shapes
256  CW = 2 // Winding for holes
257  };
258 
259  struct Paint {
260  float xform[6];
261  float extent[2];
262  float radius;
263  float feather;
264  Color innerColor;
265  Color outerColor;
266  int imageId;
267 
268  Paint() noexcept;
269 
270  /**
271  @internal
272  */
273  Paint(const NVGpaint&) noexcept;
274  operator NVGpaint() const noexcept;
275  };
276 
277  struct GlyphPosition {
278  const char* str; // Position of the glyph in the input string.
279  float x; // The x-coordinate of the logical glyph position.
280  float minx, maxx; // The bounds of the glyph shape.
281  };
282 
283  struct TextRow {
284  const char* start; // Pointer to the input text where the row starts.
285  const char* end; // Pointer to the input text where the row ends (one past the last character).
286  const char* next; // Pointer to the beginning of the next row.
287  float width; // Logical width of the row.
288  float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending.
289  };
290 
291  typedef int FontId;
292 
293  /**
294  Constructor.
295  @see CreateFlags
296  */
297  NanoVG(int flags = CREATE_ANTIALIAS);
298 
299  /**
300  Constructor reusing a NanoVG context, used for subwidgets.
301  */
302  NanoVG(NanoWidget* groupWidget);
303 
304  /**
305  Destructor.
306  */
307  virtual ~NanoVG();
308 
309  /**
310  Get the NanoVG context.
311  You should not need this under normal circumstances.
312  */
313  NVGcontext* getContext() const noexcept
314  {
315  return fContext;
316  }
317 
318  /**
319  Begin drawing a new frame.
320  */
321  void beginFrame(const uint width, const uint height, const float scaleFactor = 1.0f);
322 
323  /**
324  Begin drawing a new frame inside a widget.
325  */
326  void beginFrame(Widget* const widget);
327 
328  /**
329  Cancels drawing the current frame.
330  */
331  void cancelFrame();
332 
333  /**
334  Ends drawing flushing remaining render state.
335  */
336  void endFrame();
337 
338  /* --------------------------------------------------------------------
339  * State Handling */
340 
341  /**
342  Pushes and saves the current render state into a state stack.
343  A matching restore() must be used to restore the state.
344  */
345  void save();
346 
347  /**
348  Pops and restores current render state.
349  */
350  void restore();
351 
352  /**
353  Resets current render state to default values. Does not affect the render state stack.
354  */
355  void reset();
356 
357  /* --------------------------------------------------------------------
358  * Render styles */
359 
360  /**
361  Sets current stroke style to a solid color.
362  */
363  void strokeColor(const Color& color);
364 
365  /**
366  Sets current stroke style to a solid color, made from red, green, blue and alpha numeric values.
367  Values must be in [0..255] range.
368  */
369  void strokeColor(const int red, const int green, const int blue, const int alpha = 255);
370 
371  /**
372  Sets current stroke style to a solid color, made from red, green, blue and alpha numeric values.
373  Values must in [0..1] range.
374  */
375  void strokeColor(const float red, const float green, const float blue, const float alpha = 1.0f);
376 
377  /**
378  Sets current stroke style to a paint, which can be a one of the gradients or a pattern.
379  */
380  void strokePaint(const Paint& paint);
381 
382  /**
383  Sets current fill style to a solid color.
384  */
385  void fillColor(const Color& color);
386 
387  /**
388  Sets current fill style to a solid color, made from red, green, blue and alpha numeric values.
389  Values must be in [0..255] range.
390  */
391  void fillColor(const int red, const int green, const int blue, const int alpha = 255);
392 
393  /**
394  Sets current fill style to a solid color, made from red, green, blue and alpha numeric values.
395  Values must in [0..1] range.
396  */
397  void fillColor(const float red, const float green, const float blue, const float alpha = 1.0f);
398 
399  /**
400  Sets current fill style to a paint, which can be a one of the gradients or a pattern.
401  */
402  void fillPaint(const Paint& paint);
403 
404  /**
405  Sets the miter limit of the stroke style.
406  Miter limit controls when a sharp corner is beveled.
407  */
408  void miterLimit(float limit);
409 
410  /**
411  Sets the stroke width of the stroke style.
412  */
413  void strokeWidth(float size);
414 
415  /**
416  Sets how the end of the line (cap) is drawn,
417  Can be one of: BUTT, ROUND, SQUARE.
418  */
419  void lineCap(LineCap cap = BUTT);
420 
421  /**
422  Sets how sharp path corners are drawn.
423  Can be one of MITER, ROUND, BEVEL.
424  */
425  void lineJoin(LineCap join = MITER);
426 
427  /**
428  Sets the transparency applied to all rendered shapes.
429  Already transparent paths will get proportionally more transparent as well.
430  */
431  void globalAlpha(float alpha);
432 
433  /* --------------------------------------------------------------------
434  * Transforms */
435 
436  /**
437  Resets current transform to a identity matrix.
438  */
439  void resetTransform();
440 
441  /**
442  Pre-multiplies current coordinate system by specified matrix.
443  The parameters are interpreted as matrix as follows:
444  [a c e]
445  [b d f]
446  [0 0 1]
447  */
448  void transform(float a, float b, float c, float d, float e, float f);
449 
450  /**
451  Translates current coordinate system.
452  */
453  void translate(float x, float y);
454 
455  /**
456  Rotates current coordinate system. Angle is specified in radians.
457  */
458  void rotate(float angle);
459 
460  /**
461  Skews the current coordinate system along X axis. Angle is specified in radians.
462  */
463  void skewX(float angle);
464 
465  /**
466  Skews the current coordinate system along Y axis. Angle is specified in radians.
467  */
468  void skewY(float angle);
469 
470  /**
471  Scales the current coordinate system.
472  */
473  void scale(float x, float y);
474 
475  /**
476  Stores the top part (a-f) of the current transformation matrix in to the specified buffer.
477  [a c e]
478  [b d f]
479  [0 0 1]
480  */
481  void currentTransform(float xform[6]);
482 
483  /**
484  The following functions can be used to make calculations on 2x3 transformation matrices.
485  A 2x3 matrix is represented as float[6]. */
486 
487  /**
488  Sets the transform to identity matrix.
489  */
490  static void transformIdentity(float dst[6]);
491 
492  /**
493  Sets the transform to translation matrix
494  */
495  static void transformTranslate(float dst[6], float tx, float ty);
496 
497  /**
498  Sets the transform to scale matrix.
499  */
500  static void transformScale(float dst[6], float sx, float sy);
501 
502  /**
503  Sets the transform to rotate matrix. Angle is specified in radians.
504  */
505  static void transformRotate(float dst[6], float a);
506 
507  /**
508  Sets the transform to skew-x matrix. Angle is specified in radians.
509  */
510  static void transformSkewX(float dst[6], float a);
511 
512  /**
513  Sets the transform to skew-y matrix. Angle is specified in radians.
514  */
515  static void transformSkewY(float dst[6], float a);
516 
517  /**
518  Sets the transform to the result of multiplication of two transforms, of A = A*B.
519  */
520  static void transformMultiply(float dst[6], const float src[6]);
521 
522  /**
523  Sets the transform to the result of multiplication of two transforms, of A = B*A.
524  */
525  static void transformPremultiply(float dst[6], const float src[6]);
526 
527  /**
528  Sets the destination to inverse of specified transform.
529  Returns 1 if the inverse could be calculated, else 0.
530  */
531  static int transformInverse(float dst[6], const float src[6]);
532 
533  /**
534  Transform a point by given transform.
535  */
536  static void transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy);
537 
538  /**
539  Convert degrees to radians.
540  */
541  static float degToRad(float deg);
542 
543  /**
544  Convert radians to degrees.
545  */
546  static float radToDeg(float rad);
547 
548  /* --------------------------------------------------------------------
549  * Images */
550 
551  /**
552  Creates image by loading it from the disk from specified file name.
553  */
554  NanoImage::Handle createImageFromFile(const char* filename, ImageFlags imageFlags);
555 
556  /**
557  Creates image by loading it from the disk from specified file name.
558  Overloaded function for convenience.
559  @see ImageFlags
560  */
561  NanoImage::Handle createImageFromFile(const char* filename, int imageFlags);
562 
563  /**
564  Creates image by loading it from the specified chunk of memory.
565  */
566  NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, ImageFlags imageFlags);
567 
568  /**
569  Creates image by loading it from the specified chunk of memory.
570  Overloaded function for convenience.
571  @see ImageFlags
572  */
573  NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, int imageFlags);
574 
575  /**
576  Creates image from specified image data.
577  */
578  NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags);
579 
580  /**
581  Creates image from specified image data.
582  Overloaded function for convenience.
583  @see ImageFlags
584  */
585  NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, int imageFlags);
586 
587  /**
588  Creates image from an OpenGL texture handle.
589  */
590  NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture = false);
591 
592  /**
593  Creates image from an OpenGL texture handle.
594  Overloaded function for convenience.
595  @see ImageFlags
596  */
597  NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture = false);
598 
599  /* --------------------------------------------------------------------
600  * Paints */
601 
602  /**
603  Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates
604  of the linear gradient, icol specifies the start color and ocol the end color.
605  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
606  */
607  Paint linearGradient(float sx, float sy, float ex, float ey, const Color& icol, const Color& ocol);
608 
609  /**
610  Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering
611  drop shadows or highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
612  (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry
613  the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient.
614  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
615  */
616  Paint boxGradient(float x, float y, float w, float h, float r, float f, const Color& icol, const Color& ocol);
617 
618  /**
619  Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify
620  the inner and outer radius of the gradient, icol specifies the start color and ocol the end color.
621  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
622  */
623  Paint radialGradient(float cx, float cy, float inr, float outr, const Color& icol, const Color& ocol);
624 
625  /**
626  Creates and returns an image pattern. Parameters (ox,oy) specify the left-top location of the image pattern,
627  (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render.
628  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
629  */
630  Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, float alpha);
631 
632  /* --------------------------------------------------------------------
633  * Scissoring */
634 
635  /**
636  Sets the current scissor rectangle.
637  The scissor rectangle is transformed by the current transform.
638  */
639  void scissor(float x, float y, float w, float h);
640 
641  /**
642  Intersects current scissor rectangle with the specified rectangle.
643  The scissor rectangle is transformed by the current transform.
644  Note: in case the rotation of previous scissor rect differs from
645  the current one, the intersection will be done between the specified
646  rectangle and the previous scissor rectangle transformed in the current
647  transform space. The resulting shape is always rectangle.
648  */
649  void intersectScissor(float x, float y, float w, float h);
650 
651  /**
652  Reset and disables scissoring.
653  */
654  void resetScissor();
655 
656  /* --------------------------------------------------------------------
657  * Paths */
658 
659  /**
660  Clears the current path and sub-paths.
661  */
662  void beginPath();
663 
664  /**
665  Starts new sub-path with specified point as first point.
666  */
667  void moveTo(float x, float y);
668 
669  /**
670  Adds line segment from the last point in the path to the specified point.
671  */
672  void lineTo(float x, float y);
673 
674  /**
675  Adds cubic bezier segment from last point in the path via two control points to the specified point.
676  */
677  void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y);
678 
679  /**
680  Adds quadratic bezier segment from last point in the path via a control point to the specified point.
681  */
682  void quadTo(float cx, float cy, float x, float y);
683 
684  /**
685  Adds an arc segment at the corner defined by the last path point, and two specified points.
686  */
687  void arcTo(float x1, float y1, float x2, float y2, float radius);
688 
689  /**
690  Closes current sub-path with a line segment.
691  */
692  void closePath();
693 
694  /**
695  Sets the current sub-path winding.
696  */
697  void pathWinding(Winding dir);
698 
699  /**
700  Creates new circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r,
701  and the arc is drawn from angle a0 to a1, and swept in direction dir (NVG_CCW or NVG_CW).
702  Angles are specified in radians.
703  */
704  void arc(float cx, float cy, float r, float a0, float a1, Winding dir);
705 
706  /**
707  Creates new rectangle shaped sub-path.
708  */
709  void rect(float x, float y, float w, float h);
710 
711  /**
712  Creates new rounded rectangle shaped sub-path.
713  */
714  void roundedRect(float x, float y, float w, float h, float r);
715 
716  /**
717  Creates new ellipse shaped sub-path.
718  */
719  void ellipse(float cx, float cy, float rx, float ry);
720 
721  /**
722  Creates new circle shaped sub-path.
723  */
724  void circle(float cx, float cy, float r);
725 
726  /**
727  Fills the current path with current fill style.
728  */
729  void fill();
730 
731  /**
732  Fills the current path with current stroke style.
733  */
734  void stroke();
735 
736  /* --------------------------------------------------------------------
737  * Text */
738 
739  /**
740  Creates font by loading it from the disk from specified file name.
741  Returns handle to the font.
742  */
743  FontId createFontFromFile(const char* name, const char* filename);
744 
745  /**
746  Creates font by loading it from the specified memory chunk.
747  Returns handle to the font.
748  */
749  FontId createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData);
750 
751  /**
752  Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found.
753  */
754  FontId findFont(const char* name);
755 
756  /**
757  Sets the font size of current text style.
758  */
759  void fontSize(float size);
760 
761  /**
762  Sets the blur of current text style.
763  */
764  void fontBlur(float blur);
765 
766  /**
767  Sets the letter spacing of current text style.
768  */
769  void textLetterSpacing(float spacing);
770 
771  /**
772  Sets the proportional line height of current text style. The line height is specified as multiple of font size.
773  */
774  void textLineHeight(float lineHeight);
775 
776  /**
777  Sets the text align of current text style.
778  */
779  void textAlign(Align align);
780 
781  /**
782  Sets the text align of current text style.
783  Overloaded function for convenience.
784  @see Align
785  */
786  void textAlign(int align);
787 
788  /**
789  Sets the font face based on specified id of current text style.
790  */
791  void fontFaceId(FontId font);
792 
793  /**
794  Sets the font face based on specified name of current text style.
795  */
796  void fontFace(const char* font);
797 
798  /**
799  Draws text string at specified location. If end is specified only the sub-string up to the end is drawn.
800  */
801  float text(float x, float y, const char* string, const char* end);
802 
803  /**
804  Draws multi-line text string at specified location wrapped at the specified width.
805  If end is specified only the sub-string up to the end is drawn.
806  White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
807  Words longer than the max width are slit at nearest character (i.e. no hyphenation).
808  */
809  void textBox(float x, float y, float breakRowWidth, const char* string, const char* end = nullptr);
810 
811  /**
812  Measures the specified text string. The bounds value are [xmin,ymin, xmax,ymax].
813  Returns the horizontal advance of the measured text (i.e. where the next character should drawn).
814  Measured values are returned in local coordinate space.
815  */
816  float textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds);
817 
818  /**
819  Measures the specified multi-text string. Parameter bounds should be a pointer to float[4],
820  if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax]
821  Measured values are returned in local coordinate space.
822  */
823  void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float bounds[4]);
824 
825  /**
826  Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used.
827  Measured values are returned in local coordinate space.
828  */
829  int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition& positions, int maxPositions);
830 
831  /**
832  Returns the vertical metrics based on the current text style.
833  Measured values are returned in local coordinate space.
834  */
835  void textMetrics(float* ascender, float* descender, float* lineh);
836 
837  /**
838  Breaks the specified text into lines. If end is specified only the sub-string will be used.
839  White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
840  Words longer than the max width are slit at nearest character (i.e. no hyphenation).
841  */
842  int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows);
843 
844 private:
845  NVGcontext* const fContext;
846  bool fInFrame;
847  bool fIsSubWidget;
848 
849  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoVG)
850 };
851 
852 // -----------------------------------------------------------------------
853 // NanoWidget
854 
855 /**
856  NanoVG Widget class.
857 
858  This class implements the NanoVG drawing API inside a DGL Widget.
859  The drawing function onDisplay() is implemented internally but a
860  new onNanoDisplay() needs to be overridden instead.
861  */
862 class NanoWidget : public Widget,
863  public NanoVG
864 {
865 public:
866  /**
867  Constructor.
868  @see CreateFlags
869  */
870  explicit NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS);
871 
872  /**
873  Constructor for a subwidget.
874  */
875  explicit NanoWidget(Widget* groupWidget, int flags = CREATE_ANTIALIAS);
876 
877  /**
878  Constructor for a subwidget, reusing a NanoVG context.
879  */
880  explicit NanoWidget(NanoWidget* groupWidget);
881 
882  /**
883  Destructor.
884  */
885  virtual ~NanoWidget();
886 
887 protected:
888  /**
889  New virtual onDisplay function.
890  @see onDisplay
891  */
892  virtual void onNanoDisplay() = 0;
893 
894 private:
895  struct PrivateData;
896  PrivateData* const nData;
897 
898  /**
899  Widget display function.
900  Implemented internally to wrap begin/endFrame() automatically.
901  */
902  void onDisplay() override;
903 
904  // these should not be used
905  void beginFrame(uint,uint) {}
906  void beginFrame(uint,uint,float) {}
907  void beginFrame(Widget*) {}
908  void cancelFrame() {}
909  void endFrame() {}
910 
911  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget)
912 };
913 
914 // -----------------------------------------------------------------------
915 
916 END_NAMESPACE_DGL
917 
918 #endif // DGL_NANO_WIDGET_HPP_INCLUDED
static void transformPoint(float &dstx, float &dsty, const float xform[6], float srcx, float srcy)
NVGcontext * getContext() const noexcept
Definition: NanoVG.hpp:313
void textAlign(Align align)
Definition: NanoVG.hpp:283
void beginPath()
void textBox(float x, float y, float breakRowWidth, const char *string, const char *end=nullptr)
Definition: NanoVG.hpp:42
void lineTo(float x, float y)
void globalAlpha(float alpha)
virtual ~NanoWidget()
static void transformScale(float dst[6], float sx, float sy)
NanoImage::Handle createImageFromMemory(uchar *data, uint dataSize, ImageFlags imageFlags)
void stroke()
void currentTransform(float xform[6])
void circle(float cx, float cy, float r)
int textBreakLines(const char *string, const char *end, float breakRowWidth, TextRow &rows, int maxRows)
static void transformMultiply(float dst[6], const float src[6])
void fontSize(float size)
FontId createFontFromMemory(const char *name, const uchar *data, uint dataSize, bool freeData)
Definition: NanoVG.hpp:862
void intersectScissor(float x, float y, float w, float h)
void textBoxBounds(float x, float y, float breakRowWidth, const char *string, const char *end, float bounds[4])
int textGlyphPositions(float x, float y, const char *string, const char *end, GlyphPosition &positions, int maxPositions)
NanoWidget(Window &parent, int flags=CREATE_ANTIALIAS)
void miterLimit(float limit)
Definition: Window.hpp:30
void strokeWidth(float size)
virtual void onNanoDisplay()=0
Paint linearGradient(float sx, float sy, float ex, float ey, const Color &icol, const Color &ocol)
void translate(float x, float y)
static void transformPremultiply(float dst[6], const float src[6])
void arcTo(float x1, float y1, float x2, float y2, float radius)
void scale(float x, float y)
Definition: Color.hpp:31
void cancelFrame()
static void transformSkewX(float dst[6], float a)
void rect(float x, float y, float w, float h)
Paint radialGradient(float cx, float cy, float inr, float outr, const Color &icol, const Color &ocol)
Definition: NanoVG.hpp:213
void fontBlur(float blur)
void strokePaint(const Paint &paint)
void reset()
NanoImage::Handle createImageFromFile(const char *filename, ImageFlags imageFlags)
void save()
void fontFaceId(FontId font)
void moveTo(float x, float y)
void transform(float a, float b, float c, float d, float e, float f)
void ellipse(float cx, float cy, float rx, float ry)
void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y)
void fontFace(const char *font)
NanoVG(int flags=CREATE_ANTIALIAS)
Definition: Geometry.hpp:30
void restore()
void skewY(float angle)
Definition: NanoVG.hpp:207
void endFrame()
FontId findFont(const char *name)
void rotate(float angle)
void beginFrame(const uint width, const uint height, const float scaleFactor=1.0f)
virtual ~NanoVG()
Definition: NanoVG.hpp:259
void pathWinding(Winding dir)
Definition: NanoVG.hpp:200
void textLineHeight(float lineHeight)
void closePath()
static void transformIdentity(float dst[6])
void skewX(float angle)
Size< uint > getSize() const noexcept
float textBounds(float x, float y, const char *string, const char *end, Rectangle< float > &bounds)
static float radToDeg(float rad)
Definition: NanoVG.hpp:277
static void transformSkewY(float dst[6], float a)
static int transformInverse(float dst[6], const float src[6])
void roundedRect(float x, float y, float w, float h, float r)
NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar *data, ImageFlags imageFlags)
FontId createFontFromFile(const char *name, const char *filename)
static float degToRad(float deg)
static void transformTranslate(float dst[6], float tx, float ty)
Definition: NanoVG.hpp:218
void arc(float cx, float cy, float r, float a0, float a1, Winding dir)
Definition: Widget.hpp:59
void lineCap(LineCap cap=BUTT)
NanoImage & operator=(const Handle &handle)
void resetTransform()
float text(float x, float y, const char *string, const char *end)
void lineJoin(LineCap join=MITER)
GLuint getTextureHandle() const
void fillColor(const Color &color)
void scissor(float x, float y, float w, float h)
void strokeColor(const Color &color)
void textMetrics(float *ascender, float *descender, float *lineh)
void quadTo(float cx, float cy, float x, float y)
void fillPaint(const Paint &paint)
bool isValid() const noexcept
static void transformRotate(float dst[6], float a)
CreateFlags
Definition: NanoVG.hpp:203
Paint boxGradient(float x, float y, float w, float h, float r, float f, const Color &icol, const Color &ocol)
NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture=false)
void textLetterSpacing(float spacing)
void fill()
Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage &image, float alpha)
void resetScissor()