NanoVG.hpp (31987B)
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 */ 83 NanoImage(); 84 85 /** 86 Constructor. 87 */ 88 NanoImage(const Handle& handle); 89 90 /** 91 Destructor. 92 */ 93 ~NanoImage(); 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 */ 466 void resetTransform(); 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 */ 929 explicit NanoBaseWidget(NanoBaseWidget<TopLevelWidget>* parentWidget); 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 984 typedef NanoBaseWidget<SubWidget> NanoSubWidget; 985 typedef NanoBaseWidget<TopLevelWidget> NanoTopLevelWidget; 986 typedef NanoBaseWidget<StandaloneWindow> NanoStandaloneWindow; 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