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  Context will not be deleted on class destructor.
323  */
324  explicit NanoVG(NVGcontext* context);
325 
326  /**
327  Destructor.
328  */
329  virtual ~NanoVG();
330 
331  /**
332  Get the NanoVG context.
333  You should not need this under normal circumstances.
334  */
335  NVGcontext* getContext() const noexcept
336  {
337  return fContext;
338  }
339 
340  /**
341  Begin drawing a new frame.
342  */
343  void beginFrame(const uint width, const uint height, const float scaleFactor = 1.0f);
344 
345  /**
346  Begin drawing a new frame inside a widget.
347  */
348  void beginFrame(Widget* const widget);
349 
350  /**
351  Cancels drawing the current frame.
352  */
353  void cancelFrame();
354 
355  /**
356  Ends drawing flushing remaining render state.
357  */
358  void endFrame();
359 
360  /* --------------------------------------------------------------------
361  * State Handling */
362 
363  /**
364  Pushes and saves the current render state into a state stack.
365  A matching restore() must be used to restore the state.
366  */
367  void save();
368 
369  /**
370  Pops and restores current render state.
371  */
372  void restore();
373 
374  /**
375  Resets current render state to default values. Does not affect the render state stack.
376  */
377  void reset();
378 
379  /* --------------------------------------------------------------------
380  * Render styles */
381 
382  /**
383  Sets current stroke style to a solid color.
384  */
385  void strokeColor(const Color& color);
386 
387  /**
388  Sets current stroke 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 strokeColor(const int red, const int green, const int blue, const int alpha = 255);
392 
393  /**
394  Sets current stroke style to a solid color, made from red, green, blue and alpha numeric values.
395  Values must in [0..1] range.
396  */
397  void strokeColor(const float red, const float green, const float blue, const float alpha = 1.0f);
398 
399  /**
400  Sets current stroke style to a paint, which can be a one of the gradients or a pattern.
401  */
402  void strokePaint(const Paint& paint);
403 
404  /**
405  Sets current fill style to a solid color.
406  */
407  void fillColor(const Color& color);
408 
409  /**
410  Sets current fill style to a solid color, made from red, green, blue and alpha numeric values.
411  Values must be in [0..255] range.
412  */
413  void fillColor(const int red, const int green, const int blue, const int alpha = 255);
414 
415  /**
416  Sets current fill style to a solid color, made from red, green, blue and alpha numeric values.
417  Values must in [0..1] range.
418  */
419  void fillColor(const float red, const float green, const float blue, const float alpha = 1.0f);
420 
421  /**
422  Sets current fill style to a paint, which can be a one of the gradients or a pattern.
423  */
424  void fillPaint(const Paint& paint);
425 
426  /**
427  Sets the miter limit of the stroke style.
428  Miter limit controls when a sharp corner is beveled.
429  */
430  void miterLimit(float limit);
431 
432  /**
433  Sets the stroke width of the stroke style.
434  */
435  void strokeWidth(float size);
436 
437  /**
438  Sets how the end of the line (cap) is drawn,
439  Can be one of: BUTT, ROUND, SQUARE.
440  */
441  void lineCap(LineCap cap = BUTT);
442 
443  /**
444  Sets how sharp path corners are drawn.
445  Can be one of MITER, ROUND, BEVEL.
446  */
447  void lineJoin(LineCap join = MITER);
448 
449  /**
450  Sets the transparency applied to all rendered shapes.
451  Already transparent paths will get proportionally more transparent as well.
452  */
453  void globalAlpha(float alpha);
454 
455  /**
456  Sets the color tint applied to all rendered shapes.
457  */
458  void globalTint(Color tint);
459 
460  /* --------------------------------------------------------------------
461  * Transforms */
462 
463  /**
464  Resets current transform to a identity matrix.
465  */
467 
468  /**
469  Pre-multiplies current coordinate system by specified matrix.
470  The parameters are interpreted as matrix as follows:
471  [a c e]
472  [b d f]
473  [0 0 1]
474  */
475  void transform(float a, float b, float c, float d, float e, float f);
476 
477  /**
478  Translates current coordinate system.
479  */
480  void translate(float x, float y);
481 
482  /**
483  Rotates current coordinate system. Angle is specified in radians.
484  */
485  void rotate(float angle);
486 
487  /**
488  Skews the current coordinate system along X axis. Angle is specified in radians.
489  */
490  void skewX(float angle);
491 
492  /**
493  Skews the current coordinate system along Y axis. Angle is specified in radians.
494  */
495  void skewY(float angle);
496 
497  /**
498  Scales the current coordinate system.
499  */
500  void scale(float x, float y);
501 
502  /**
503  Stores the top part (a-f) of the current transformation matrix in to the specified buffer.
504  [a c e]
505  [b d f]
506  [0 0 1]
507  */
508  void currentTransform(float xform[6]);
509 
510  /**
511  The following functions can be used to make calculations on 2x3 transformation matrices.
512  A 2x3 matrix is represented as float[6]. */
513 
514  /**
515  Sets the transform to identity matrix.
516  */
517  static void transformIdentity(float dst[6]);
518 
519  /**
520  Sets the transform to translation matrix
521  */
522  static void transformTranslate(float dst[6], float tx, float ty);
523 
524  /**
525  Sets the transform to scale matrix.
526  */
527  static void transformScale(float dst[6], float sx, float sy);
528 
529  /**
530  Sets the transform to rotate matrix. Angle is specified in radians.
531  */
532  static void transformRotate(float dst[6], float a);
533 
534  /**
535  Sets the transform to skew-x matrix. Angle is specified in radians.
536  */
537  static void transformSkewX(float dst[6], float a);
538 
539  /**
540  Sets the transform to skew-y matrix. Angle is specified in radians.
541  */
542  static void transformSkewY(float dst[6], float a);
543 
544  /**
545  Sets the transform to the result of multiplication of two transforms, of A = A*B.
546  */
547  static void transformMultiply(float dst[6], const float src[6]);
548 
549  /**
550  Sets the transform to the result of multiplication of two transforms, of A = B*A.
551  */
552  static void transformPremultiply(float dst[6], const float src[6]);
553 
554  /**
555  Sets the destination to inverse of specified transform.
556  Returns 1 if the inverse could be calculated, else 0.
557  */
558  static int transformInverse(float dst[6], const float src[6]);
559 
560  /**
561  Transform a point by given transform.
562  */
563  static void transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy);
564 
565  /**
566  Convert degrees to radians.
567  */
568  static float degToRad(float deg);
569 
570  /**
571  Convert radians to degrees.
572  */
573  static float radToDeg(float rad);
574 
575  /* --------------------------------------------------------------------
576  * Images */
577 
578  /**
579  Creates image by loading it from the disk from specified file name.
580  */
581  NanoImage::Handle createImageFromFile(const char* filename, ImageFlags imageFlags);
582 
583  /**
584  Creates image by loading it from the disk from specified file name.
585  Overloaded function for convenience.
586  @see ImageFlags
587  */
588  NanoImage::Handle createImageFromFile(const char* filename, int imageFlags);
589 
590  /**
591  Creates image by loading it from the specified chunk of memory.
592  */
593  NanoImage::Handle createImageFromMemory(const uchar* data, uint dataSize, ImageFlags imageFlags);
594 
595  /**
596  Creates image by loading it from the specified chunk of memory.
597  Overloaded function for convenience.
598  @see ImageFlags
599  */
600  NanoImage::Handle createImageFromMemory(const uchar* data, uint dataSize, int imageFlags);
601 
602  /**
603  Creates image from specified raw format image data.
604  */
605  NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
606  ImageFlags imageFlags, ImageFormat format);
607 
608  /**
609  Creates image from specified raw format image data.
610  Overloaded function for convenience.
611  @see ImageFlags
612  */
613  NanoImage::Handle createImageFromRawMemory(uint w, uint h, const uchar* data,
614  int imageFlags, ImageFormat format);
615 
616  /**
617  Creates image from specified RGBA image data.
618  */
619  NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags);
620 
621  /**
622  Creates image from specified RGBA image data.
623  Overloaded function for convenience.
624  @see ImageFlags
625  */
626  NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, int imageFlags);
627 
628  /**
629  Creates image from an OpenGL texture handle.
630  */
631  NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture = false);
632 
633  /**
634  Creates image from an OpenGL texture handle.
635  Overloaded function for convenience.
636  @see ImageFlags
637  */
638  NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture = false);
639 
640  /* --------------------------------------------------------------------
641  * Paints */
642 
643  /**
644  Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates
645  of the linear gradient, icol specifies the start color and ocol the end color.
646  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
647  */
648  Paint linearGradient(float sx, float sy, float ex, float ey, const Color& icol, const Color& ocol);
649 
650  /**
651  Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering
652  drop shadows or highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle,
653  (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry
654  the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient.
655  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
656  */
657  Paint boxGradient(float x, float y, float w, float h, float r, float f, const Color& icol, const Color& ocol);
658 
659  /**
660  Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify
661  the inner and outer radius of the gradient, icol specifies the start color and ocol the end color.
662  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
663  */
664  Paint radialGradient(float cx, float cy, float inr, float outr, const Color& icol, const Color& ocol);
665 
666  /**
667  Creates and returns an image pattern. Parameters (ox,oy) specify the left-top location of the image pattern,
668  (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render.
669  The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint().
670  */
671  Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, float alpha);
672 
673  /* --------------------------------------------------------------------
674  * Scissoring */
675 
676  /**
677  Sets the current scissor rectangle.
678  The scissor rectangle is transformed by the current transform.
679  */
680  void scissor(float x, float y, float w, float h);
681 
682  /**
683  Intersects current scissor rectangle with the specified rectangle.
684  The scissor rectangle is transformed by the current transform.
685  Note: in case the rotation of previous scissor rect differs from
686  the current one, the intersection will be done between the specified
687  rectangle and the previous scissor rectangle transformed in the current
688  transform space. The resulting shape is always rectangle.
689  */
690  void intersectScissor(float x, float y, float w, float h);
691 
692  /**
693  Reset and disables scissoring.
694  */
695  void resetScissor();
696 
697  /* --------------------------------------------------------------------
698  * Paths */
699 
700  /**
701  Clears the current path and sub-paths.
702  */
703  void beginPath();
704 
705  /**
706  Starts new sub-path with specified point as first point.
707  */
708  void moveTo(float x, float y);
709 
710  /**
711  Adds line segment from the last point in the path to the specified point.
712  */
713  void lineTo(float x, float y);
714 
715  /**
716  Adds cubic bezier segment from last point in the path via two control points to the specified point.
717  */
718  void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y);
719 
720  /**
721  Adds quadratic bezier segment from last point in the path via a control point to the specified point.
722  */
723  void quadTo(float cx, float cy, float x, float y);
724 
725  /**
726  Adds an arc segment at the corner defined by the last path point, and two specified points.
727  */
728  void arcTo(float x1, float y1, float x2, float y2, float radius);
729 
730  /**
731  Closes current sub-path with a line segment.
732  */
733  void closePath();
734 
735  /**
736  Sets the current sub-path winding.
737  */
738  void pathWinding(Winding dir);
739 
740  /**
741  Creates new circle arc shaped sub-path. The arc center is at cx,cy, the arc radius is r,
742  and the arc is drawn from angle a0 to a1, and swept in direction dir (NVG_CCW or NVG_CW).
743  Angles are specified in radians.
744  */
745  void arc(float cx, float cy, float r, float a0, float a1, Winding dir);
746 
747  /**
748  Creates new rectangle shaped sub-path.
749  */
750  void rect(float x, float y, float w, float h);
751 
752  /**
753  Creates new rounded rectangle shaped sub-path.
754  */
755  void roundedRect(float x, float y, float w, float h, float r);
756 
757  /**
758  Creates new ellipse shaped sub-path.
759  */
760  void ellipse(float cx, float cy, float rx, float ry);
761 
762  /**
763  Creates new circle shaped sub-path.
764  */
765  void circle(float cx, float cy, float r);
766 
767  /**
768  Fills the current path with current fill style.
769  */
770  void fill();
771 
772  /**
773  Fills the current path with current stroke style.
774  */
775  void stroke();
776 
777  /* --------------------------------------------------------------------
778  * Text */
779 
780  /**
781  Creates font by loading it from the disk from specified file name.
782  Returns handle to the font.
783  */
784  FontId createFontFromFile(const char* name, const char* filename);
785 
786  /**
787  Creates font by loading it from the specified memory chunk.
788  Returns handle to the font.
789  */
790  FontId createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData);
791 
792  /**
793  Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found.
794  */
795  FontId findFont(const char* name);
796 
797  /**
798  Sets the font size of current text style.
799  */
800  void fontSize(float size);
801 
802  /**
803  Sets the blur of current text style.
804  */
805  void fontBlur(float blur);
806 
807  /**
808  Sets the letter spacing of current text style.
809  */
810  void textLetterSpacing(float spacing);
811 
812  /**
813  Sets the proportional line height of current text style. The line height is specified as multiple of font size.
814  */
815  void textLineHeight(float lineHeight);
816 
817  /**
818  Sets the text align of current text style.
819  */
820  void textAlign(Align align);
821 
822  /**
823  Sets the text align of current text style.
824  Overloaded function for convenience.
825  @see Align
826  */
827  void textAlign(int align);
828 
829  /**
830  Sets the font face based on specified id of current text style.
831  */
832  void fontFaceId(FontId font);
833 
834  /**
835  Sets the font face based on specified name of current text style.
836  */
837  void fontFace(const char* font);
838 
839  /**
840  Draws text string at specified location. If end is specified only the sub-string up to the end is drawn.
841  */
842  float text(float x, float y, const char* string, const char* end);
843 
844  /**
845  Draws multi-line text string at specified location wrapped at the specified width.
846  If end is specified only the sub-string up to the end is drawn.
847  White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
848  Words longer than the max width are slit at nearest character (i.e. no hyphenation).
849  */
850  void textBox(float x, float y, float breakRowWidth, const char* string, const char* end = nullptr);
851 
852  /**
853  Measures the specified text string. The bounds value are [xmin,ymin, xmax,ymax].
854  Returns the horizontal advance of the measured text (i.e. where the next character should drawn).
855  Measured values are returned in local coordinate space.
856  */
857  float textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds);
858 
859  /**
860  Measures the specified multi-text string. Parameter bounds should be a pointer to float[4],
861  if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax]
862  Measured values are returned in local coordinate space.
863  */
864  void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float bounds[4]);
865 
866  /**
867  Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used.
868  Measured values are returned in local coordinate space.
869  */
870  int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition& positions, int maxPositions);
871 
872  /**
873  Returns the vertical metrics based on the current text style.
874  Measured values are returned in local coordinate space.
875  */
876  void textMetrics(float* ascender, float* descender, float* lineh);
877 
878  /**
879  Breaks the specified text into lines. If end is specified only the sub-string will be used.
880  White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
881  Words longer than the max width are slit at nearest character (i.e. no hyphenation).
882  */
883  int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows);
884 
885 #ifndef DGL_NO_SHARED_RESOURCES
886  /**
887  Load DPF's internal shared resources for this NanoVG class.
888  */
889  virtual bool loadSharedResources();
890 #endif
891 
892 private:
893  NVGcontext* const fContext;
894  bool fInFrame;
895  bool fIsSubWidget;
896 
897  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoVG)
898 };
899 
900 // -----------------------------------------------------------------------
901 // NanoWidget
902 
903 /**
904  NanoVG Widget class.
905 
906  This class implements the NanoVG drawing API inside a DGL Widget.
907  The drawing function onDisplay() is implemented internally but a
908  new onNanoDisplay() needs to be overridden instead.
909  */
910 template <class BaseWidget>
911 class NanoBaseWidget : public BaseWidget,
912  public NanoVG
913 {
914 public:
915  /**
916  Constructor for a NanoSubWidget.
917  @see CreateFlags
918  */
919  explicit NanoBaseWidget(Widget* parentWidget, int flags = CREATE_ANTIALIAS);
920 
921  /**
922  Constructor for a NanoSubWidget reusing a parent subwidget nanovg context.
923  */
924  explicit NanoBaseWidget(NanoBaseWidget<SubWidget>* parentWidget);
925 
926  /**
927  Constructor for a NanoSubWidget reusing a parent top-level-widget nanovg context.
928  */
930 
931  /**
932  Constructor for a NanoTopLevelWidget.
933  @see CreateFlags
934  */
935  explicit NanoBaseWidget(Window& windowToMapTo, int flags = CREATE_ANTIALIAS);
936 
937  /**
938  Constructor for a NanoStandaloneWindow without transient parent window.
939  @see CreateFlags
940  */
941  explicit NanoBaseWidget(Application& app, int flags = CREATE_ANTIALIAS);
942 
943  /**
944  Constructor for a NanoStandaloneWindow with transient parent window.
945  @see CreateFlags
946  */
947  explicit NanoBaseWidget(Application& app, Window& transientParentWindow, int flags = CREATE_ANTIALIAS);
948 
949  /**
950  Destructor.
951  */
952  ~NanoBaseWidget() override {}
953 
954 protected:
955  /**
956  New virtual onDisplay function.
957  @see onDisplay
958  */
959  virtual void onNanoDisplay() = 0;
960 
961 private:
962  /**
963  Widget display function.
964  Implemented internally to wrap begin/endFrame() automatically.
965  */
966  void onDisplay() override;
967 
968  // these should not be used
969  void beginFrame(uint,uint) {}
970  void beginFrame(uint,uint,float) {}
971  void beginFrame(Widget*) {}
972  void cancelFrame() {}
973  void endFrame() {}
974 
975  /** @internal */
976  const bool fUsingParentContext;
977  void displayChildren();
978  friend class NanoBaseWidget<TopLevelWidget>;
979  friend class NanoBaseWidget<StandaloneWindow>;
980 
981  DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoBaseWidget)
982 };
983 
987 
988 DISTRHO_DEPRECATED_BY("NanoSubWidget")
989 typedef NanoSubWidget NanoWidget;
990 
991 // -----------------------------------------------------------------------
992 
993 END_NAMESPACE_DGL
994 
995 #ifdef _MSC_VER
996 # pragma warning(pop)
997 #endif
998 
999 #endif // DGL_NANO_WIDGET_HPP_INCLUDED
Definition: Application.hpp:43
Definition: NanoVG.hpp:913
NanoBaseWidget(Window &windowToMapTo, int flags=CREATE_ANTIALIAS)
NanoBaseWidget(NanoBaseWidget< SubWidget > *parentWidget)
NanoBaseWidget(NanoBaseWidget< TopLevelWidget > *parentWidget)
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:952
NanoBaseWidget(Widget *parentWidget, 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)
NanoVG(NVGcontext *context)
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)
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)
NanoImage::Handle createImageFromMemory(const uchar *data, uint dataSize, int 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])
NanoImage::Handle createImageFromMemory(const uchar *data, uint dataSize, ImageFlags imageFlags)
void miterLimit(float limit)
NVGcontext * getContext() const noexcept
Definition: NanoVG.hpp:335
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)
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: StandaloneWindow.hpp:29
Definition: TopLevelWidget.hpp:47
Definition: Widget.hpp:56
Definition: Window.hpp:63
Definition: Color.hpp:31
Definition: NanoVG.hpp:298
Definition: NanoVG.hpp:280
Definition: NanoVG.hpp:304