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