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