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