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