DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 5a65496535aa53e8d9b467beb7f6245e330fa090
parent af09cb0a1284337a2592d237caa9ac5a274ce059
Author: falkTX <falktx@gmail.com>
Date:   Sat, 24 May 2014 03:32:12 +0100

Rename Nano file; Make base nano API into class plus widget

Diffstat:
Mdgl/Makefile | 2+-
Adgl/NanoVG.hpp | 799+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddgl/NanoWidget.hpp | 754-------------------------------------------------------------------------------
Adgl/src/NanoVG.cpp | 582++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ddgl/src/NanoWidget.cpp | 583-------------------------------------------------------------------------------
Mdgl/src/nanovg/fontstash.h | 5++++-
6 files changed, 1386 insertions(+), 1339 deletions(-)

diff --git a/dgl/Makefile b/dgl/Makefile @@ -23,7 +23,7 @@ OBJS = \ src/ImageKnob.cpp.o \ src/ImageSlider.cpp.o \ src/ImageSwitch.cpp.o \ - src/NanoWidget.cpp.o \ + src/NanoVG.cpp.o \ src/Widget.cpp.o ifeq ($(MACOS),true) diff --git a/dgl/NanoVG.hpp b/dgl/NanoVG.hpp @@ -0,0 +1,799 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef DGL_NANO_WIDGET_HPP_INCLUDED +#define DGL_NANO_WIDGET_HPP_INCLUDED + +#include "Widget.hpp" + +struct NVGcolor; +struct NVGcontext; +struct NVGpaint; + +START_NAMESPACE_DGL + +// ----------------------------------------------------------------------- +// NanoImage + +/** + NanoVG Image class. + + This implements NanoVG images as a C++ class where deletion is handled automatically. + Images need to be created within a NanoVG or NanoWidget class. + */ +class NanoImage +{ +public: + /** + Destructor. + */ + ~NanoImage(); + + /** + Get size. + */ + Size<int> getSize() const; + + /** + Update image data. + */ + void updateImage(const uchar* data); + +protected: + /** + Constructors are protected. + NanoImages must be created within a NanoVG or NanoWidget class. + */ + NanoImage(const char* filename); + NanoImage(uchar* data, int ndata); + NanoImage(int w, int h, const uchar* data); + +private: + NVGcontext* const fContext; + const int fImageId; + friend class NanoVG; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoImage) + DISTRHO_PREVENT_HEAP_ALLOCATION +}; + +// ----------------------------------------------------------------------- +// NanoVG + +/** + NanoVG class. + + This class exposes the NanoVG drawing API. + All calls should be wrapped in beginFrame() & endFrame(). + + @section Color utils + Colors in NanoVG are stored as uints in ABGR format. + + @section State Handling + NanoVG contains state which represents how paths will be rendered. + The state contains transform, fill and stroke styles, text and font styles, and scissor clipping. + + @section Render styles + Fill and stroke render style can be either a solid color or a paint which is a gradient or a pattern. + Solid color is simply defined as a color value, different kinds of paints can be created + using linearGradient(), boxGradient(), radialGradient() and imagePattern(). + + Current render style can be saved and restored using save() and restore(). + + @section Transforms + The paths, gradients, patterns and scissor region are transformed by an transformation + matrix at the time when they are passed to the API. + The current transformation matrix is a affine matrix: + [sx kx tx] + [ky sy ty] + [ 0 0 1] + Where: sx,sy define scaling, kx,ky skewing, and tx,ty translation. + The last row is assumed to be 0,0,1 and is not stored. + + Apart from resetTransform(), each transformation function first creates + specific transformation matrix and pre-multiplies the current transformation by it. + + Current coordinate system (transformation) can be saved and restored using save() and restore(). + + @section Images + NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering. + In addition you can upload your own image. The image loading is provided by stb_image. + + @section Paints + NanoVG supports four types of paints: linear gradient, box gradient, radial gradient and image pattern. + These can be used as paints for strokes and fills. + + @section Scissoring + Scissoring allows you to clip the rendering into a rectangle. This is useful for varius + user interface cases like rendering a text edit or a timeline. + + @section Paths + Drawing a new shape starts with beginPath(), it clears all the currently defined paths. + Then you define one or more paths and sub-paths which describe the shape. The are functions + to draw common shapes like rectangles and circles, and lower level step-by-step functions, + which allow to define a path curve by curve. + + NanoVG uses even-odd fill rule to draw the shapes. Solid shapes should have counter clockwise + winding and holes should have counter clockwise order. To specify winding of a path you can + call pathWinding(). This is useful especially for the common shapes, which are drawn CCW. + + Finally you can fill the path using current fill style by calling fill(), and stroke it + with current stroke style by calling stroke(). + + The curve segments and sub-paths are transformed by the current transform. + + @section Text + NanoVG allows you to load .ttf files and use the font to render text. + + The appearance of the text can be defined by setting the current text style + and by specifying the fill color. Common text and font settings such as + font size, letter spacing and text align are supported. Font blur allows you + to create simple text effects such as drop shadows. + + At render time the font face can be set based on the font handles or name. + + Font measure functions return values in local space, the calculations are + carried in the same resolution as the final rendering. This is done because + the text glyph positions are snapped to the nearest pixels sharp rendering. + + The local space means that values are not rotated or scale as per the current + transformation. For example if you set font size to 12, which would mean that + line height is 16, then regardless of the current scaling and rotation, the + returned line height is always 16. Some measures may vary because of the scaling + since aforementioned pixel snapping. + + While this may sound a little odd, the setup allows you to always render the + same way regardless of scaling. I.e. following works regardless of scaling: + + @code + const char* txt = "Text me up."; + textBounds(vg, x,y, txt, NULL, bounds); + beginPath(vg); + roundedRect(vg, bounds[0],bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]); + fill(vg); + @endcode + + Note: currently only solid color fill is supported for text. + */ +class NanoVG +{ +public: + enum Align { + // Horizontal align + ALIGN_LEFT = 1 << 0, // Align horizontally to left (default). + ALIGN_CENTER = 1 << 1, // Align horizontally to center. + ALIGN_RIGHT = 1 << 2, // Align horizontally to right. + // Vertical align + ALIGN_TOP = 1 << 3, // Align vertically to top. + ALIGN_MIDDLE = 1 << 4, // Align vertically to middle. + ALIGN_BOTTOM = 1 << 5, // Align vertically to bottom. + ALIGN_BASELINE = 1 << 6 // Align vertically to baseline (default). + }; + + enum Alpha { + STRAIGHT_ALPHA, + PREMULTIPLIED_ALPHA, + }; + + enum LineCap { + BUTT, + ROUND, + SQUARE, + BEVEL, + MITER + }; + + enum PatternRepeat { + REPEAT_NONE = 0x0, // No repeat + REPEAT_X = 0x1, // Repeat in X direction + REPEAT_Y = 0x2 // Repeat in Y direction + }; + + enum Solidity { + SOLID = 1, // CCW + HOLE = 2 // CW + }; + + enum Winding { + CCW = 1, // Winding for solid shapes + CW = 2 // Winding for holes + }; + + struct Color { + union { + float rgba[4]; + struct { float r,g,b,a; }; + }; + + Color() noexcept; + Color(const NVGcolor&) noexcept; + operator NVGcolor() const noexcept; + }; + + struct Paint { + float xform[6]; + float extent[2]; + float radius; + float feather; + Color innerColor; + Color outerColor; + int imageId; + PatternRepeat repeat; + + Paint() noexcept; + Paint(const NVGpaint&) noexcept; + operator NVGpaint() const noexcept; + }; + + struct GlyphPosition { + const char* str; // Position of the glyph in the input string. + float x; // The x-coordinate of the logical glyph position. + float minx, maxx; // The bounds of the glyph shape. + }; + + struct TextRow { + const char* start; // Pointer to the input text where the row starts. + const char* end; // Pointer to the input text where the row ends (one past the last character). + const char* next; // Pointer to the beginning of the next row. + float width; // Logical width of the row. + float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending. + }; + + typedef int FontId; + + /** + Constructor. + */ + NanoVG(); + + /** + Destructor. + */ + ~NanoVG(); + + /** + Get the NanoVG context. + You should not need this under normal circumstances. + */ + NVGcontext* getContext() const noexcept + { + return fContext; + } + +protected: + /** + Begin drawing a new frame. + @param withAlha Controls if drawing the shapes to the render target should be done using straight or pre-multiplied alpha. + */ + void beginFrame(int width, int height, float scaleFactor = 1.0f, Alpha alpha = PREMULTIPLIED_ALPHA); + + /** + Ends drawing flushing remaining render state. + */ + void endFrame(); + + /* -------------------------------------------------------------------- + * Color utils */ + + /** + Returns a color value from red, green, blue values. Alpha will be set to 255 (1.0f). + */ + static Color RGB(uchar r, uchar g, uchar b); + + /** + Returns a color value from red, green, blue values. Alpha will be set to 1.0f. + */ + static Color RGBf(float r, float g, float b); + + /** + Returns a color value from red, green, blue and alpha values. + */ + static Color RGBA(uchar r, uchar g, uchar b, uchar a); + + /** + Returns a color value from red, green, blue and alpha values. + */ + static Color RGBAf(float r, float g, float b, float a); + + /** + Linearly interpolates from color c0 to c1, and returns resulting color value. + */ + static Color lerpRGBA(const Color& c0, const Color& c1, float u); + + /** + Returns color value specified by hue, saturation and lightness. + HSL values are all in range [0..1], alpha will be set to 255. + */ + static Color HSL(float h, float s, float l); + + /** + Returns color value specified by hue, saturation and lightness and alpha. + HSL values are all in range [0..1], alpha in range [0..255] + */ + static Color HSLA(float h, float s, float l, uchar a); + + /* -------------------------------------------------------------------- + * State Handling */ + + /** + Pushes and saves the current render state into a state stack. + A matching restore() must be used to restore the state. + */ + void save(); + + /** + Pops and restores current render state. + */ + void restore(); + + /** + Resets current render state to default values. Does not affect the render state stack. + */ + void reset(); + + /* -------------------------------------------------------------------- + * Render styles */ + + /** + Sets current stroke style to a solid color. + */ + void strokeColor(const Color& color); + + /** + Sets current stroke style to a paint, which can be a one of the gradients or a pattern. + */ + void strokePaint(const Paint& paint); + + /** + Sets current fill style to a solid color. + */ + void fillColor(const Color& color); + + /** + Sets current fill style to a paint, which can be a one of the gradients or a pattern. + */ + void fillPaint(const Paint& paint); + + /** + Sets the miter limit of the stroke style. + Miter limit controls when a sharp corner is beveled. + */ + void miterLimit(float limit); + + /** + Sets the stroke width of the stroke style. + */ + void strokeWidth(float size); + + /** + Sets how the end of the line (cap) is drawn, + Can be one of: BUTT, ROUND, SQUARE. + */ + void lineCap(LineCap cap = BUTT); + + /** + Sets how sharp path corners are drawn. + Can be one of MITER, ROUND, BEVEL. + */ + void lineJoin(LineCap join = MITER); + + /* -------------------------------------------------------------------- + * Transforms */ + + /** + Resets current transform to a identity matrix. + */ + void resetTransform(); + + /** + Pre-multiplies current coordinate system by specified matrix. + The parameters are interpreted as matrix as follows: + [a c e] + [b d f] + [0 0 1] + */ + void transform(float a, float b, float c, float d, float e, float f); + + /** + Translates current coordinate system. + */ + void translate(float x, float y); + + /** + Rotates current coordinate system. Angle is specified in radians. + */ + void rotate(float angle); + + /** + Skews the current coordinate system along X axis. Angle is specified in radians. + */ + void skewX(float angle); + + /** + Skews the current coordinate system along Y axis. Angle is specified in radians. + */ + void skewY(float angle); + + /** + Scales the current coordinate system. + */ + void scale(float x, float y); + + /** + Stores the top part (a-f) of the current transformation matrix in to the specified buffer. + [a c e] + [b d f] + [0 0 1] + */ + void currentTransform(float xform[6]); + + /** + The following functions can be used to make calculations on 2x3 transformation matrices. + A 2x3 matrix is represented as float[6]. */ + + /** + Sets the transform to identity matrix. + */ + static void transformIdentity(float dst[6]); + + /** + Sets the transform to translation matrix matrix. + */ + static void transformTranslate(float dst[6], float tx, float ty); + + /** + Sets the transform to scale matrix. + */ + static void transformScale(float dst[6], float sx, float sy); + + /** + Sets the transform to rotate matrix. Angle is specified in radians. + */ + static void transformRotate(float dst[6], float a); + + /** + Sets the transform to skew-x matrix. Angle is specified in radians. + */ + static void transformSkewX(float dst[6], float a); + + /** + Sets the transform to skew-y matrix. Angle is specified in radians. + */ + static void transformSkewY(float dst[6], float a); + + /** + Sets the transform to the result of multiplication of two transforms, of A = A*B. + */ + static void transformMultiply(float dst[6], const float src[6]); + + /** + Sets the transform to the result of multiplication of two transforms, of A = B*A. + */ + static void transformPremultiply(float dst[6], const float src[6]); + + /** + Sets the destination to inverse of specified transform. + Returns 1 if the inverse could be calculated, else 0. + */ + static int transformInverse(float dst[6], const float src[6]); + + /** + Transform a point by given transform. + */ + static void transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy); + + /** + Convert degrees to radians. + */ + static float degToRad(float deg); + + /** + Convert radians to degrees. + */ + static float radToDeg(float rad); + + /* -------------------------------------------------------------------- + * Images */ + + /** + Creates image by loading it from the disk from specified file name. + */ + NanoImage createImage(const char* filename); + + /** + Creates image by loading it from the specified chunk of memory. + */ + NanoImage createImageMem(uchar* data, int ndata); + + /** + Creates image from specified image data. + */ + NanoImage createImageRGBA(int w, int h, const uchar* data); + + /* -------------------------------------------------------------------- + * Paints */ + + /** + Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates + of the linear gradient, icol specifies the start color and ocol the end color. + The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). + */ + Paint linearGradient(float sx, float sy, float ex, float ey, const Color& icol, const Color& ocol); + + /** + Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering + drop shadows or highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle, + (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry + the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient. + The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). + */ + Paint boxGradient(float x, float y, float w, float h, float r, float f, const Color& icol, const Color& ocol); + + /** + Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify + the inner and outer radius of the gradient, icol specifies the start color and ocol the end color. + The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). + */ + Paint radialGradient(float cx, float cy, float inr, float outr, const Color& icol, const Color& ocol); + + /** + Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern, + (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render, + and repeat tells if the image should be repeated across x or y. + The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). + */ + Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, PatternRepeat repeat); + + /* -------------------------------------------------------------------- + * Scissoring */ + + /** + Sets the current + The scissor rectangle is transformed by the current transform. + */ + void scissor(float x, float y, float w, float h); + + /** + Reset and disables scissoring. + */ + void resetScissor(); + + /* -------------------------------------------------------------------- + * Paths */ + + /** + Clears the current path and sub-paths. + */ + void beginPath(); + + /** + Starts new sub-path with specified point as first point. + */ + void moveTo(float x, float y); + + /** + Adds line segment from the last point in the path to the specified point. + */ + void lineTo(float x, float y); + + /** + Adds bezier segment from last point in the path via two control points to the specified point. + */ + void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y); + + /** + Adds an arc segment at the corner defined by the last path point, and two specified points. + */ + void arcTo(float x1, float y1, float x2, float y2, float radius); + + /** + Closes current sub-path with a line segment. + */ + void closePath(); + + /** + Sets the current sub-path winding. + */ + void pathWinding(Winding dir); + + /** + Creates new arc shaped sub-path. + */ + void arc(float cx, float cy, float r, float a0, float a1, Winding dir); + + /** + Creates new rectangle shaped sub-path. + */ + void rect(float x, float y, float w, float h); + + /** + Creates new rounded rectangle shaped sub-path. + */ + void roundedRect(float x, float y, float w, float h, float r); + + /** + Creates new ellipse shaped sub-path. + */ + void ellipse(float cx, float cy, float rx, float ry); + + /** + Creates new circle shaped sub-path. + */ + void circle(float cx, float cy, float r); + + /** + Fills the current path with current fill style. + */ + void fill(); + + /** + Fills the current path with current stroke style. + */ + void stroke(); + + /* -------------------------------------------------------------------- + * Text */ + + /** + Creates font by loading it from the disk from specified file name. + Returns handle to the font. + */ + FontId createFont(const char* name, const char* filename); + + /** + Creates font by loading it from the specified memory chunk. + Returns handle to the font. + */ + FontId createFontMem(const char* name, uchar* data, int ndata, bool freeData); + + /** + Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. + */ + FontId findFont(const char* name); + + /** + Sets the font size of current text style. + */ + void fontSize(float size); + + /** + Sets the blur of current text style. + */ + void fontBlur(float blur); + + /** + Sets the letter spacing of current text style. + */ + void textLetterSpacing(float spacing); + + /** + Sets the proportional line height of current text style. The line height is specified as multiple of font size. + */ + void textLineHeight(float lineHeight); + + /** + Sets the text align of current text style. + */ + void textAlign(Align align); + + /** + Sets the font face based on specified id of current text style. + */ + void fontFaceId(FontId font); + + /** + Sets the font face based on specified name of current text style. + */ + void fontFace(const char* font); + + /** + Draws text string at specified location. If end is specified only the sub-string up to the end is drawn. + */ + float text(float x, float y, const char* string, const char* end); + + /** + Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn. + White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. + Words longer than the max width are slit at nearest character (i.e. no hyphenation). + */ + void textBox(float x, float y, float breakRowWidth, const char* string, const char* end); + + /** + Measures the specified text string. The bounds value are [xmin,ymin, xmax,ymax]. + Returns the horizontal advance of the measured text (i.e. where the next character should drawn). + Measured values are returned in local coordinate space. + */ + float textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds); + + /** + Measures the specified multi-text string. Parameter bounds should be a pointer to float[4], + if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] + Measured values are returned in local coordinate space. + */ + void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds); + + /** + Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used. + Measured values are returned in local coordinate space. + */ + int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions); + + /** + Returns the vertical metrics based on the current text style. + Measured values are returned in local coordinate space. + */ + void textMetrics(float* ascender, float* descender, float* lineh); + + /** + Breaks the specified text into lines. If end is specified only the sub-string will be used. + White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. + Words longer than the max width are slit at nearest character (i.e. no hyphenation). + */ + int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows); + +private: + NVGcontext* fContext; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoVG) +}; + +// ----------------------------------------------------------------------- +// NanoWidget + +/** + NanoVG Widget class. + + This class implements the NanoVG drawing API inside a DGL Widget. + onDisplay is implemented internally. + */ +class NanoWidget : public Widget, + public NanoVG +{ +public: + /** + Constructor. + */ + NanoWidget(Window& parent) + : Widget(parent), + NanoVG() {} + +protected: + /** + New virtual onDisplay function. + @see onDisplay + */ + virtual void onNanoDisplay() = 0; + +private: + /** + Widget display function. + Implemented internally to wrap begine/endFrame() automaticaly. + */ + void onDisplay() override + { + beginFrame(getWidth(), getHeight()); + onNanoDisplay(); + endFrame(); + } + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget) +}; + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DGL + +#endif // DGL_NANO_WIDGET_HPP_INCLUDED diff --git a/dgl/NanoWidget.hpp b/dgl/NanoWidget.hpp @@ -1,754 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef DGL_NANO_WIDGET_HPP_INCLUDED -#define DGL_NANO_WIDGET_HPP_INCLUDED - -#include "Widget.hpp" - -struct NVGcolor; -struct NVGcontext; -struct NVGpaint; - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- - -/** - NanoVG Image class. - - This implements NanoVG images as a C++ class where deletion is handled automatically. - Images need to be created within a NanoWidget class. - */ -class NanoImage -{ -public: - /** - Destructor. - */ - ~NanoImage(); - - /** - Get size. - */ - Size<int> getSize() const; - - /** - Update image data. - */ - void updateImage(const uchar* data); - -protected: - /** - Constructors are protected. - NanoImages must be created within a NanoWidget class. - */ - NanoImage(const char* filename); - NanoImage(uchar* data, int ndata); - NanoImage(int w, int h, const uchar* data); - -private: - NVGcontext* const fContext; - const int fImageId; - friend class NanoWidget; - - DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoImage) -}; - -// ----------------------------------------------------------------------- - -/** - NanoVG Widget class. - - This class implements the NanoVG drawing API inside a DGL Widget. - All calls should be wrapped in beginFrame() & endFrame(). - - @section Color utils - Colors in NanoVG are stored as uints in ABGR format. - - @section State Handling - NanoVG contains state which represents how paths will be rendered. - The state contains transform, fill and stroke styles, text and font styles, and scissor clipping. - - @section Render styles - Fill and stroke render style can be either a solid color or a paint which is a gradient or a pattern. - Solid color is simply defined as a color value, different kinds of paints can be created - using linearGradient(), boxGradient(), radialGradient() and imagePattern(). - - Current render style can be saved and restored using save() and restore(). - - @section Transforms - The paths, gradients, patterns and scissor region are transformed by an transformation - matrix at the time when they are passed to the API. - The current transformation matrix is a affine matrix: - [sx kx tx] - [ky sy ty] - [ 0 0 1] - Where: sx,sy define scaling, kx,ky skewing, and tx,ty translation. - The last row is assumed to be 0,0,1 and is not stored. - - Apart from resetTransform(), each transformation function first creates - specific transformation matrix and pre-multiplies the current transformation by it. - - Current coordinate system (transformation) can be saved and restored using save() and restore(). - - @section Images - NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering. - In addition you can upload your own image. The image loading is provided by stb_image. - - @section Paints - NanoVG supports four types of paints: linear gradient, box gradient, radial gradient and image pattern. - These can be used as paints for strokes and fills. - - @section Scissoring - Scissoring allows you to clip the rendering into a rectangle. This is useful for varius - user interface cases like rendering a text edit or a timeline. - - @section Paths - Drawing a new shape starts with beginPath(), it clears all the currently defined paths. - Then you define one or more paths and sub-paths which describe the shape. The are functions - to draw common shapes like rectangles and circles, and lower level step-by-step functions, - which allow to define a path curve by curve. - - NanoVG uses even-odd fill rule to draw the shapes. Solid shapes should have counter clockwise - winding and holes should have counter clockwise order. To specify winding of a path you can - call pathWinding(). This is useful especially for the common shapes, which are drawn CCW. - - Finally you can fill the path using current fill style by calling fill(), and stroke it - with current stroke style by calling stroke(). - - The curve segments and sub-paths are transformed by the current transform. - - @section Text - NanoVG allows you to load .ttf files and use the font to render text. - - The appearance of the text can be defined by setting the current text style - and by specifying the fill color. Common text and font settings such as - font size, letter spacing and text align are supported. Font blur allows you - to create simple text effects such as drop shadows. - - At render time the font face can be set based on the font handles or name. - - Font measure functions return values in local space, the calculations are - carried in the same resolution as the final rendering. This is done because - the text glyph positions are snapped to the nearest pixels sharp rendering. - - The local space means that values are not rotated or scale as per the current - transformation. For example if you set font size to 12, which would mean that - line height is 16, then regardless of the current scaling and rotation, the - returned line height is always 16. Some measures may vary because of the scaling - since aforementioned pixel snapping. - - While this may sound a little odd, the setup allows you to always render the - same way regardless of scaling. I.e. following works regardless of scaling: - - @code - const char* txt = "Text me up."; - textBounds(vg, x,y, txt, NULL, bounds); - beginPath(vg); - roundedRect(vg, bounds[0],bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]); - fill(vg); - @endcode - - Note: currently only solid color fill is supported for text. - */ -class NanoWidget : public Widget -{ -public: - enum Align { - // Horizontal align - ALIGN_LEFT = 1 << 0, // Align horizontally to left (default). - ALIGN_CENTER = 1 << 1, // Align horizontally to center. - ALIGN_RIGHT = 1 << 2, // Align horizontally to right. - // Vertical align - ALIGN_TOP = 1 << 3, // Align vertically to top. - ALIGN_MIDDLE = 1 << 4, // Align vertically to middle. - ALIGN_BOTTOM = 1 << 5, // Align vertically to bottom. - ALIGN_BASELINE = 1 << 6 // Align vertically to baseline (default). - }; - - enum Alpha { - STRAIGHT_ALPHA, - PREMULTIPLIED_ALPHA, - }; - - enum LineCap { - BUTT, - ROUND, - SQUARE, - BEVEL, - MITER - }; - - enum PatternRepeat { - REPEAT_NONE = 0x0, // No repeat - REPEAT_X = 0x1, // Repeat in X direction - REPEAT_Y = 0x2 // Repeat in Y direction - }; - - enum Solidity { - SOLID = 1, // CCW - HOLE = 2 // CW - }; - - enum Winding { - CCW = 1, // Winding for solid shapes - CW = 2 // Winding for holes - }; - - struct Color { - union { - float rgba[4]; - struct { float r,g,b,a; }; - }; - - Color() noexcept; - Color(const NVGcolor&) noexcept; - operator NVGcolor() const noexcept; - }; - - struct Paint { - float xform[6]; - float extent[2]; - float radius; - float feather; - Color innerColor; - Color outerColor; - int imageId; - PatternRepeat repeat; - - Paint() noexcept; - Paint(const NVGpaint&) noexcept; - operator NVGpaint() const noexcept; - }; - - struct GlyphPosition { - const char* str; // Position of the glyph in the input string. - float x; // The x-coordinate of the logical glyph position. - float minx, maxx; // The bounds of the glyph shape. - }; - - struct TextRow { - const char* start; // Pointer to the input text where the row starts. - const char* end; // Pointer to the input text where the row ends (one past the last character). - const char* next; // Pointer to the beginning of the next row. - float width; // Logical width of the row. - float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending. - }; - - typedef int FontId; - - /** - Constructor. - */ - NanoWidget(Window& parent); - - /** - Destructor. - */ - ~NanoWidget() override; - - /** - Get the NanoVG context. - You should not need this under normal circumstances. - */ - NVGcontext* getContext() const noexcept - { - return fContext; - } - -protected: - /** - Begin drawing a new frame. - @param withAlha Controls if drawing the shapes to the render target should be done using straight or pre-multiplied alpha. - */ - void beginFrame(Alpha alpha = PREMULTIPLIED_ALPHA); - - /** - Ends drawing flushing remaining render state. - */ - void endFrame(); - - /* -------------------------------------------------------------------- - * Color utils */ - - /** - Returns a color value from red, green, blue values. Alpha will be set to 255 (1.0f). - */ - static Color RGB(uchar r, uchar g, uchar b); - - /** - Returns a color value from red, green, blue values. Alpha will be set to 1.0f. - */ - static Color RGBf(float r, float g, float b); - - /** - Returns a color value from red, green, blue and alpha values. - */ - static Color RGBA(uchar r, uchar g, uchar b, uchar a); - - /** - Returns a color value from red, green, blue and alpha values. - */ - static Color RGBAf(float r, float g, float b, float a); - - /** - Linearly interpolates from color c0 to c1, and returns resulting color value. - */ - static Color lerpRGBA(const Color& c0, const Color& c1, float u); - - /** - Returns color value specified by hue, saturation and lightness. - HSL values are all in range [0..1], alpha will be set to 255. - */ - static Color HSL(float h, float s, float l); - - /** - Returns color value specified by hue, saturation and lightness and alpha. - HSL values are all in range [0..1], alpha in range [0..255] - */ - static Color HSLA(float h, float s, float l, uchar a); - - /* -------------------------------------------------------------------- - * State Handling */ - - /** - Pushes and saves the current render state into a state stack. - A matching restore() must be used to restore the state. - */ - void save(); - - /** - Pops and restores current render state. - */ - void restore(); - - /** - Resets current render state to default values. Does not affect the render state stack. - */ - void reset(); - - /* -------------------------------------------------------------------- - * Render styles */ - - /** - Sets current stroke style to a solid color. - */ - void strokeColor(const Color& color); - - /** - Sets current stroke style to a paint, which can be a one of the gradients or a pattern. - */ - void strokePaint(const Paint& paint); - - /** - Sets current fill style to a solid color. - */ - void fillColor(const Color& color); - - /** - Sets current fill style to a paint, which can be a one of the gradients or a pattern. - */ - void fillPaint(const Paint& paint); - - /** - Sets the miter limit of the stroke style. - Miter limit controls when a sharp corner is beveled. - */ - void miterLimit(float limit); - - /** - Sets the stroke width of the stroke style. - */ - void strokeWidth(float size); - - /** - Sets how the end of the line (cap) is drawn, - Can be one of: BUTT, ROUND, SQUARE. - */ - void lineCap(LineCap cap = BUTT); - - /** - Sets how sharp path corners are drawn. - Can be one of MITER, ROUND, BEVEL. - */ - void lineJoin(LineCap join = MITER); - - /* -------------------------------------------------------------------- - * Transforms */ - - /** - Resets current transform to a identity matrix. - */ - void resetTransform(); - - /** - Pre-multiplies current coordinate system by specified matrix. - The parameters are interpreted as matrix as follows: - [a c e] - [b d f] - [0 0 1] - */ - void transform(float a, float b, float c, float d, float e, float f); - - /** - Translates current coordinate system. - */ - void translate(float x, float y); - - /** - Rotates current coordinate system. Angle is specified in radians. - */ - void rotate(float angle); - - /** - Skews the current coordinate system along X axis. Angle is specified in radians. - */ - void skewX(float angle); - - /** - Skews the current coordinate system along Y axis. Angle is specified in radians. - */ - void skewY(float angle); - - /** - Scales the current coordinate system. - */ - void scale(float x, float y); - - /** - Stores the top part (a-f) of the current transformation matrix in to the specified buffer. - [a c e] - [b d f] - [0 0 1] - */ - void currentTransform(float xform[6]); - - /** - The following functions can be used to make calculations on 2x3 transformation matrices. - A 2x3 matrix is represented as float[6]. */ - - /** - Sets the transform to identity matrix. - */ - static void transformIdentity(float dst[6]); - - /** - Sets the transform to translation matrix matrix. - */ - static void transformTranslate(float dst[6], float tx, float ty); - - /** - Sets the transform to scale matrix. - */ - static void transformScale(float dst[6], float sx, float sy); - - /** - Sets the transform to rotate matrix. Angle is specified in radians. - */ - static void transformRotate(float dst[6], float a); - - /** - Sets the transform to skew-x matrix. Angle is specified in radians. - */ - static void transformSkewX(float dst[6], float a); - - /** - Sets the transform to skew-y matrix. Angle is specified in radians. - */ - static void transformSkewY(float dst[6], float a); - - /** - Sets the transform to the result of multiplication of two transforms, of A = A*B. - */ - static void transformMultiply(float dst[6], const float src[6]); - - /** - Sets the transform to the result of multiplication of two transforms, of A = B*A. - */ - static void transformPremultiply(float dst[6], const float src[6]); - - /** - Sets the destination to inverse of specified transform. - Returns 1 if the inverse could be calculated, else 0. - */ - static int transformInverse(float dst[6], const float src[6]); - - /** - Transform a point by given transform. - */ - static void transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy); - - /** - Convert degrees to radians. - */ - static float degToRad(float deg); - - /** - Convert radians to degrees. - */ - static float radToDeg(float rad); - - /* -------------------------------------------------------------------- - * Images */ - - /** - Creates image by loading it from the disk from specified file name. - */ - NanoImage createImage(const char* filename); - - /** - Creates image by loading it from the specified chunk of memory. - */ - NanoImage createImageMem(uchar* data, int ndata); - - /** - Creates image from specified image data. - */ - NanoImage createImageRGBA(int w, int h, const uchar* data); - - /* -------------------------------------------------------------------- - * Paints */ - - /** - Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates - of the linear gradient, icol specifies the start color and ocol the end color. - The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). - */ - Paint linearGradient(float sx, float sy, float ex, float ey, const Color& icol, const Color& ocol); - - /** - Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering - drop shadows or highlights for boxes. Parameters (x,y) define the top-left corner of the rectangle, - (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry - the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient. - The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). - */ - Paint boxGradient(float x, float y, float w, float h, float r, float f, const Color& icol, const Color& ocol); - - /** - Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify - the inner and outer radius of the gradient, icol specifies the start color and ocol the end color. - The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). - */ - Paint radialGradient(float cx, float cy, float inr, float outr, const Color& icol, const Color& ocol); - - /** - Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern, - (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render, - and repeat tells if the image should be repeated across x or y. - The gradient is transformed by the current transform when it is passed to fillPaint() or strokePaint(). - */ - Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, PatternRepeat repeat); - - /* -------------------------------------------------------------------- - * Scissoring */ - - /** - Sets the current - The scissor rectangle is transformed by the current transform. - */ - void scissor(float x, float y, float w, float h); - - /** - Reset and disables scissoring. - */ - void resetScissor(); - - /* -------------------------------------------------------------------- - * Paths */ - - /** - Clears the current path and sub-paths. - */ - void beginPath(); - - /** - Starts new sub-path with specified point as first point. - */ - void moveTo(float x, float y); - - /** - Adds line segment from the last point in the path to the specified point. - */ - void lineTo(float x, float y); - - /** - Adds bezier segment from last point in the path via two control points to the specified point. - */ - void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y); - - /** - Adds an arc segment at the corner defined by the last path point, and two specified points. - */ - void arcTo(float x1, float y1, float x2, float y2, float radius); - - /** - Closes current sub-path with a line segment. - */ - void closePath(); - - /** - Sets the current sub-path winding. - */ - void pathWinding(Winding dir); - - /** - Creates new arc shaped sub-path. - */ - void arc(float cx, float cy, float r, float a0, float a1, Winding dir); - - /** - Creates new rectangle shaped sub-path. - */ - void rect(float x, float y, float w, float h); - - /** - Creates new rounded rectangle shaped sub-path. - */ - void roundedRect(float x, float y, float w, float h, float r); - - /** - Creates new ellipse shaped sub-path. - */ - void ellipse(float cx, float cy, float rx, float ry); - - /** - Creates new circle shaped sub-path. - */ - void circle(float cx, float cy, float r); - - /** - Fills the current path with current fill style. - */ - void fill(); - - /** - Fills the current path with current stroke style. - */ - void stroke(); - - /* -------------------------------------------------------------------- - * Text */ - - /** - Creates font by loading it from the disk from specified file name. - Returns handle to the font. - */ - FontId createFont(const char* name, const char* filename); - - /** - Creates font by loading it from the specified memory chunk. - Returns handle to the font. - */ - FontId createFontMem(const char* name, uchar* data, int ndata, bool freeData); - - /** - Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. - */ - FontId findFont(const char* name); - - /** - Sets the font size of current text style. - */ - void fontSize(float size); - - /** - Sets the blur of current text style. - */ - void fontBlur(float blur); - - /** - Sets the letter spacing of current text style. - */ - void textLetterSpacing(float spacing); - - /** - Sets the proportional line height of current text style. The line height is specified as multiple of font size. - */ - void textLineHeight(float lineHeight); - - /** - Sets the text align of current text style. - */ - void textAlign(Align align); - - /** - Sets the font face based on specified id of current text style. - */ - void fontFaceId(FontId font); - - /** - Sets the font face based on specified name of current text style. - */ - void fontFace(const char* font); - - /** - Draws text string at specified location. If end is specified only the sub-string up to the end is drawn. - */ - float text(float x, float y, const char* string, const char* end); - - /** - Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn. - White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. - Words longer than the max width are slit at nearest character (i.e. no hyphenation). - */ - void textBox(float x, float y, float breakRowWidth, const char* string, const char* end); - - /** - Measures the specified text string. The bounds value are [xmin,ymin, xmax,ymax]. - Returns the horizontal advance of the measured text (i.e. where the next character should drawn). - Measured values are returned in local coordinate space. - */ - float textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds); - - /** - Measures the specified multi-text string. Parameter bounds should be a pointer to float[4], - if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] - Measured values are returned in local coordinate space. - */ - void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds); - - /** - Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used. - Measured values are returned in local coordinate space. - */ - int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions); - - /** - Returns the vertical metrics based on the current text style. - Measured values are returned in local coordinate space. - */ - void textMetrics(float* ascender, float* descender, float* lineh); - - /** - Breaks the specified text into lines. If end is specified only the sub-string will be used. - White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. - Words longer than the max width are slit at nearest character (i.e. no hyphenation). - */ - int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows); - -private: - NVGcontext* fContext; - - DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget) -}; - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL - -#endif // DGL_NANO_WIDGET_HPP_INCLUDED diff --git a/dgl/src/NanoVG.cpp b/dgl/src/NanoVG.cpp @@ -0,0 +1,582 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../NanoVG.hpp" + +// ----------------------------------------------------------------------- + +#define NANOVG_GL2_IMPLEMENTATION +#include "nanovg/nanovg_gl.h" + +#if defined(NANOVG_GL2) +# define nvgCreateGL nvgCreateGL2 +# define nvgDeleteGL nvgDeleteGL2 +#elif defined(NANOVG_GL3) +# define nvgCreateGL nvgCreateGL3 +# define nvgDeleteGL nvgDeleteGL3 +#elif defined(NANOVG_GLES2) +# define nvgCreateGL nvgCreateGLES2 +# define nvgDeleteGL nvgDeleteGLES2 +#elif defined(NANOVG_GLES3) +# define nvgCreateGL nvgCreateGLES3 +# define nvgDeleteGL nvgDeleteGLES3 +#endif + +START_NAMESPACE_DGL + +// ----------------------------------------------------------------------- +// Conversions + +NanoVG::Color::Color() noexcept + : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {} + +NanoVG::Color::Color(const NVGcolor& c) noexcept + : r(c.r), g(c.g), b(c.b), a(c.a) {} + +NanoVG::Color::operator NVGcolor() const noexcept +{ + NVGcolor nc = { r, g, b, a }; + return nc; +} + +NanoVG::Paint::Paint() noexcept + : radius(0.0f), feather(0.0f), innerColor(), outerColor(), imageId(0), repeat(REPEAT_NONE) +{ + std::memset(xform, 0, sizeof(float)*6); + std::memset(extent, 0, sizeof(float)*2); +} + +NanoVG::Paint::Paint(const NVGpaint& p) noexcept + : radius(p.radius), feather(p.feather), innerColor(p.innerColor), outerColor(p.outerColor), imageId(p.image), repeat(static_cast<PatternRepeat>(p.repeat)) +{ + std::memcpy(xform, p.xform, sizeof(float)*6); + std::memcpy(extent, p.extent, sizeof(float)*2); +} + +NanoVG::Paint::operator NVGpaint() const noexcept +{ + NVGpaint p; + p.radius = radius; + p.feather = feather; + p.innerColor = innerColor; + p.outerColor = outerColor; + p.image = imageId; + p.repeat = repeat; + std::memcpy(p.xform, xform, sizeof(float)*6); + std::memcpy(p.extent, extent, sizeof(float)*2); + return p; +} + +// ----------------------------------------------------------------------- +// NanoImage + +static NVGcontext* sLastContext = nullptr; + +NanoImage::NanoImage(const char* filename) + : fContext(sLastContext), + fImageId((fContext != nullptr) ? nvgCreateImage(fContext, filename) : 0) {} + +NanoImage::NanoImage(uchar* data, int ndata) + : fContext(sLastContext), + fImageId((fContext != nullptr) ? nvgCreateImageMem(fContext, data, ndata) : 0) {} + +NanoImage::NanoImage(int w, int h, const uchar* data) + : fContext(sLastContext), + fImageId((fContext != nullptr) ? nvgCreateImageRGBA(fContext, w, h, data) : 0) {} + +NanoImage::~NanoImage() +{ + if (fContext != nullptr && fImageId != 0) + nvgDeleteImage(fContext, fImageId); +} + +Size<int> NanoImage::getSize() const +{ + int w=0, h=0; + + if (fContext != nullptr && fImageId != 0) + nvgImageSize(fContext, fImageId, &w, &h); + + return Size<int>(w, h); +} + +void NanoImage::updateImage(const uchar* data) +{ + if (fContext != nullptr && fImageId != 0) + nvgUpdateImage(fContext, fImageId, data); +} + +// ----------------------------------------------------------------------- +// NanoVG + +NanoVG::NanoVG() + : fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS)) +{ + DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,); +} + +NanoVG::~NanoVG() +{ + if (fContext == nullptr) + return; + + nvgDeleteGL(fContext); +} + +// ----------------------------------------------------------------------- + +void NanoVG::beginFrame(int width, int height, float scaleFactor, Alpha alpha) +{ + nvgBeginFrame(fContext, width, height, scaleFactor, static_cast<NVGalpha>(alpha)); +} + +void NanoVG::endFrame() +{ + nvgEndFrame(fContext); +} + +// ----------------------------------------------------------------------- +// Color utils + +NanoVG::Color NanoVG::RGB(uchar r, uchar g, uchar b) +{ + return nvgRGB(r, g, b); +} + +NanoVG::Color NanoVG::RGBf(float r, float g, float b) +{ + return nvgRGBf(r, g, b); +} + +NanoVG::Color NanoVG::RGBA(uchar r, uchar g, uchar b, uchar a) +{ + return nvgRGBA(r, g, b, a); +} + +NanoVG::Color NanoVG::RGBAf(float r, float g, float b, float a) +{ + return nvgRGBAf(r, g, b, a); +} + +NanoVG::Color NanoVG::lerpRGBA(const Color& c0, const Color& c1, float u) +{ + return nvgLerpRGBA(c0, c1, u); +} + +NanoVG::Color NanoVG::HSL(float h, float s, float l) +{ + return nvgHSL(h, s, l); +} + +NanoVG::Color NanoVG::HSLA(float h, float s, float l, uchar a) +{ + return nvgHSLA(h, s, l, a); +} + +// ----------------------------------------------------------------------- +// State Handling + +void NanoVG::save() +{ + nvgSave(fContext); +} + +void NanoVG::restore() +{ + nvgRestore(fContext); +} + +void NanoVG::reset() +{ + nvgReset(fContext); +} + +// ----------------------------------------------------------------------- +// Render styles + +void NanoVG::strokeColor(const Color& color) +{ + nvgStrokeColor(fContext, color); +} + +void NanoVG::strokePaint(const Paint& paint) +{ + nvgStrokePaint(fContext, paint); +} + +void NanoVG::fillColor(const Color& color) +{ + nvgFillColor(fContext, color); +} + +void NanoVG::fillPaint(const Paint& paint) +{ + nvgFillPaint(fContext, paint); +} + +void NanoVG::miterLimit(float limit) +{ + nvgMiterLimit(fContext, limit); +} + +void NanoVG::strokeWidth(float size) +{ + nvgStrokeWidth(fContext, size); +} + +void NanoVG::lineCap(NanoVG::LineCap cap) +{ + nvgLineCap(fContext, cap); +} + +void NanoVG::lineJoin(NanoVG::LineCap join) +{ + nvgLineJoin(fContext, join); +} + +// ----------------------------------------------------------------------- +// Transforms + +void NanoVG::resetTransform() +{ + nvgResetTransform(fContext); +} + +void NanoVG::transform(float a, float b, float c, float d, float e, float f) +{ + nvgTransform(fContext, a, b, c, d, e, f); +} + +void NanoVG::translate(float x, float y) +{ + nvgTranslate(fContext, x, y); +} + +void NanoVG::rotate(float angle) +{ + nvgRotate(fContext, angle); +} + +void NanoVG::skewX(float angle) +{ + nvgSkewX(fContext, angle); +} + +void NanoVG::skewY(float angle) +{ + nvgSkewY(fContext, angle); +} + +void NanoVG::scale(float x, float y) +{ + nvgScale(fContext, x, y); +} + +void NanoVG::currentTransform(float xform[6]) +{ + nvgCurrentTransform(fContext, xform); +} + +void NanoVG::transformIdentity(float dst[6]) +{ + nvgTransformIdentity(dst); +} + +void NanoVG::transformTranslate(float dst[6], float tx, float ty) +{ + nvgTransformTranslate(dst, tx, ty); +} + +void NanoVG::transformScale(float dst[6], float sx, float sy) +{ + nvgTransformScale(dst, sx, sy); +} + +void NanoVG::transformRotate(float dst[6], float a) +{ + nvgTransformRotate(dst, a); +} + +void NanoVG::transformSkewX(float dst[6], float a) +{ + nvgTransformSkewX(dst, a); +} + +void NanoVG::transformSkewY(float dst[6], float a) +{ + nvgTransformSkewY(dst, a); +} + +void NanoVG::transformMultiply(float dst[6], const float src[6]) +{ + nvgTransformMultiply(dst, src); +} + +void NanoVG::transformPremultiply(float dst[6], const float src[6]) +{ + nvgTransformPremultiply(dst, src); +} + +int NanoVG::transformInverse(float dst[6], const float src[6]) +{ + return nvgTransformInverse(dst, src); +} + +void NanoVG::transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy) +{ + nvgTransformPoint(&dstx, &dsty, xform, srcx, srcy); +} + +float NanoVG::degToRad(float deg) +{ + return nvgDegToRad(deg); +} + +float NanoVG::radToDeg(float rad) +{ + return nvgRadToDeg(rad); +} + +// ----------------------------------------------------------------------- +// Images + +NanoImage NanoVG::createImage(const char* filename) +{ + sLastContext = fContext; + return NanoImage(filename); +} + +NanoImage NanoVG::createImageMem(uchar* data, int ndata) +{ + sLastContext = fContext; + return NanoImage(data, ndata); +} + +NanoImage NanoVG::createImageRGBA(int w, int h, const uchar* data) +{ + sLastContext = fContext; + return NanoImage(w, h, data); +} + +// ----------------------------------------------------------------------- +// Paints + +NanoVG::Paint NanoVG::linearGradient(float sx, float sy, float ex, float ey, const NanoVG::Color& icol, const NanoVG::Color& ocol) +{ + return nvgLinearGradient(fContext, sx, sy, ex, ey, icol, ocol); +} + +NanoVG::Paint NanoVG::boxGradient(float x, float y, float w, float h, float r, float f, const NanoVG::Color& icol, const NanoVG::Color& ocol) +{ + return nvgBoxGradient(fContext, x, y, w, h, r, f, icol, ocol); +} + +NanoVG::Paint NanoVG::radialGradient(float cx, float cy, float inr, float outr, const NanoVG::Color& icol, const NanoVG::Color& ocol) +{ + return nvgRadialGradient(fContext, cx, cy, inr, outr, icol, ocol); +} + +NanoVG::Paint NanoVG::imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, NanoVG::PatternRepeat repeat) +{ + return nvgImagePattern(fContext, ox, oy, ex, ey, angle, image.fImageId, repeat); +} + +// ----------------------------------------------------------------------- +// Scissoring + +void NanoVG::scissor(float x, float y, float w, float h) +{ + nvgScissor(fContext, x, y, w, h); +} + +void NanoVG::resetScissor() +{ + nvgResetScissor(fContext); +} + +// ----------------------------------------------------------------------- +// Paths + +void NanoVG::beginPath() +{ + nvgBeginPath(fContext); +} + +void NanoVG::moveTo(float x, float y) +{ + nvgMoveTo(fContext, x, y); +} + +void NanoVG::lineTo(float x, float y) +{ + nvgLineTo(fContext, x, y); +} + +void NanoVG::bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y) +{ + nvgBezierTo(fContext, c1x, c1y, c2x, c2y, x, y); +} + +void NanoVG::arcTo(float x1, float y1, float x2, float y2, float radius) +{ + nvgArcTo(fContext, x1, y1, x2, y2, radius); +} + +void NanoVG::closePath() +{ + nvgClosePath(fContext); +} + +void NanoVG::pathWinding(NanoVG::Winding dir) +{ + nvgPathWinding(fContext, dir); +} + +void NanoVG::arc(float cx, float cy, float r, float a0, float a1, NanoVG::Winding dir) +{ + nvgArc(fContext, cx, cy, r, a0, a1, dir); +} + +void NanoVG::rect(float x, float y, float w, float h) +{ + nvgRect(fContext, x, y, w, h); +} + +void NanoVG::roundedRect(float x, float y, float w, float h, float r) +{ + nvgRoundedRect(fContext, x, y, w, h, r); +} + +void NanoVG::ellipse(float cx, float cy, float rx, float ry) +{ + nvgEllipse(fContext, cx, cy, rx, ry); +} + +void NanoVG::circle(float cx, float cy, float r) +{ + nvgCircle(fContext, cx, cy, r); +} + +void NanoVG::fill() +{ + nvgFill(fContext); +} + +void NanoVG::stroke() +{ + nvgStroke(fContext); +} + +// ----------------------------------------------------------------------- +// Text + +NanoVG::FontId NanoVG::createFont(const char* name, const char* filename) +{ + return nvgCreateFont(fContext, name, filename); +} + +NanoVG::FontId NanoVG::createFontMem(const char* name, uchar* data, int ndata, bool freeData) +{ + return nvgCreateFontMem(fContext, name, data, ndata, freeData); +} + +NanoVG::FontId NanoVG::findFont(const char* name) +{ + return nvgFindFont(fContext, name); +} + +void NanoVG::fontSize(float size) +{ + nvgFontSize(fContext, size); +} + +void NanoVG::fontBlur(float blur) +{ + nvgFontBlur(fContext, blur); +} + +void NanoVG::textLetterSpacing(float spacing) +{ + nvgTextLetterSpacing(fContext, spacing); +} + +void NanoVG::textLineHeight(float lineHeight) +{ + nvgTextLineHeight(fContext, lineHeight); +} + +void NanoVG::textAlign(NanoVG::Align align) +{ + nvgTextAlign(fContext, align); +} + +void NanoVG::fontFaceId(FontId font) +{ + nvgFontFaceId(fContext, font); +} + +void NanoVG::fontFace(const char* font) +{ + nvgFontFace(fContext, font); +} + +float NanoVG::text(float x, float y, const char* string, const char* end) +{ + return nvgText(fContext, x, y, string, end); +} + +void NanoVG::textBox(float x, float y, float breakRowWidth, const char* string, const char* end) +{ + nvgTextBox(fContext, x, y, breakRowWidth, string, end); +} + +float NanoVG::textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds) +{ + float b[4]; + const float ret = nvgTextBounds(fContext, x, y, string, end, b); + bounds = Rectangle<float>(b[0], b[1], b[2], b[3]); + return ret; +} + +void NanoVG::textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) +{ + nvgTextBoxBounds(fContext, x, y, breakRowWidth, string, end, bounds); +} + +int NanoVG::textGlyphPositions(float x, float y, const char* string, const char* end, NanoVG::GlyphPosition* positions, int maxPositions) +{ + return nvgTextGlyphPositions(fContext, x, y, string, end, (NVGglyphPosition*)positions, maxPositions); +} + +void NanoVG::textMetrics(float* ascender, float* descender, float* lineh) +{ + nvgTextMetrics(fContext, ascender, descender, lineh); +} + +int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWidth, NanoVG::TextRow* rows, int maxRows) +{ + return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)rows, maxRows); +} + +// ----------------------------------------------------------------------- + +END_NAMESPACE_DGL + +extern "C" { +#include "nanovg/nanovg.c" +} + +// ----------------------------------------------------------------------- diff --git a/dgl/src/NanoWidget.cpp b/dgl/src/NanoWidget.cpp @@ -1,583 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "../NanoWidget.hpp" - -// ----------------------------------------------------------------------- - -#define NANOVG_GL2_IMPLEMENTATION -#include "nanovg/nanovg_gl.h" - -#if defined(NANOVG_GL2) -# define nvgCreateGL nvgCreateGL2 -# define nvgDeleteGL nvgDeleteGL2 -#elif defined(NANOVG_GL3) -# define nvgCreateGL nvgCreateGL3 -# define nvgDeleteGL nvgDeleteGL3 -#elif defined(NANOVG_GLES2) -# define nvgCreateGL nvgCreateGLES2 -# define nvgDeleteGL nvgDeleteGLES2 -#elif defined(NANOVG_GLES3) -# define nvgCreateGL nvgCreateGLES3 -# define nvgDeleteGL nvgDeleteGLES3 -#endif - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- -// Conversions - -NanoWidget::Color::Color() noexcept - : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {} - -NanoWidget::Color::Color(const NVGcolor& c) noexcept - : r(c.r), g(c.g), b(c.b), a(c.a) {} - -NanoWidget::Color::operator NVGcolor() const noexcept -{ - NVGcolor nc = { r, g, b, a }; - return nc; -} - -NanoWidget::Paint::Paint() noexcept - : radius(0.0f), feather(0.0f), innerColor(), outerColor(), imageId(0), repeat(REPEAT_NONE) -{ - std::memset(xform, 0, sizeof(float)*6); - std::memset(extent, 0, sizeof(float)*2); -} - -NanoWidget::Paint::Paint(const NVGpaint& p) noexcept - : radius(p.radius), feather(p.feather), innerColor(p.innerColor), outerColor(p.outerColor), imageId(p.image), repeat(static_cast<PatternRepeat>(p.repeat)) -{ - std::memcpy(xform, p.xform, sizeof(float)*6); - std::memcpy(extent, p.extent, sizeof(float)*2); -} - -NanoWidget::Paint::operator NVGpaint() const noexcept -{ - NVGpaint p; - p.radius = radius; - p.feather = feather; - p.innerColor = innerColor; - p.outerColor = outerColor; - p.image = imageId; - p.repeat = repeat; - std::memcpy(p.xform, xform, sizeof(float)*6); - std::memcpy(p.extent, extent, sizeof(float)*2); - return p; -} - -// ----------------------------------------------------------------------- -// NanoImage - -static NVGcontext* sLastContext = nullptr; - -NanoImage::NanoImage(const char* filename) - : fContext(sLastContext), - fImageId((fContext != nullptr) ? nvgCreateImage(fContext, filename) : 0) {} - -NanoImage::NanoImage(uchar* data, int ndata) - : fContext(sLastContext), - fImageId((fContext != nullptr) ? nvgCreateImageMem(fContext, data, ndata) : 0) {} - -NanoImage::NanoImage(int w, int h, const uchar* data) - : fContext(sLastContext), - fImageId((fContext != nullptr) ? nvgCreateImageRGBA(fContext, w, h, data) : 0) {} - -NanoImage::~NanoImage() -{ - if (fContext != nullptr && fImageId != 0) - nvgDeleteImage(fContext, fImageId); -} - -Size<int> NanoImage::getSize() const -{ - int w=0, h=0; - - if (fContext != nullptr && fImageId != 0) - nvgImageSize(fContext, fImageId, &w, &h); - - return Size<int>(w, h); -} - -void NanoImage::updateImage(const uchar* data) -{ - if (fContext != nullptr && fImageId != 0) - nvgUpdateImage(fContext, fImageId, data); -} - -// ----------------------------------------------------------------------- -// NanoWidget - -NanoWidget::NanoWidget(Window& parent) - : Widget(parent), - fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS)) -{ - DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,); -} - -NanoWidget::~NanoWidget() -{ - if (fContext == nullptr) - return; - - nvgDeleteGL(fContext); -} - -// ----------------------------------------------------------------------- - -void NanoWidget::beginFrame(Alpha alpha) -{ - nvgBeginFrame(fContext, getWidth(), getHeight(), 1.0f, static_cast<NVGalpha>(alpha)); -} - -void NanoWidget::endFrame() -{ - nvgEndFrame(fContext); -} - -// ----------------------------------------------------------------------- -// Color utils - -NanoWidget::Color NanoWidget::RGB(uchar r, uchar g, uchar b) -{ - return nvgRGB(r, g, b); -} - -NanoWidget::Color NanoWidget::RGBf(float r, float g, float b) -{ - return nvgRGBf(r, g, b); -} - -NanoWidget::Color NanoWidget::RGBA(uchar r, uchar g, uchar b, uchar a) -{ - return nvgRGBA(r, g, b, a); -} - -NanoWidget::Color NanoWidget::RGBAf(float r, float g, float b, float a) -{ - return nvgRGBAf(r, g, b, a); -} - -NanoWidget::Color NanoWidget::lerpRGBA(const Color& c0, const Color& c1, float u) -{ - return nvgLerpRGBA(c0, c1, u); -} - -NanoWidget::Color NanoWidget::HSL(float h, float s, float l) -{ - return nvgHSL(h, s, l); -} - -NanoWidget::Color NanoWidget::HSLA(float h, float s, float l, uchar a) -{ - return nvgHSLA(h, s, l, a); -} - -// ----------------------------------------------------------------------- -// State Handling - -void NanoWidget::save() -{ - nvgSave(fContext); -} - -void NanoWidget::restore() -{ - nvgRestore(fContext); -} - -void NanoWidget::reset() -{ - nvgReset(fContext); -} - -// ----------------------------------------------------------------------- -// Render styles - -void NanoWidget::strokeColor(const Color& color) -{ - nvgStrokeColor(fContext, color); -} - -void NanoWidget::strokePaint(const Paint& paint) -{ - nvgStrokePaint(fContext, paint); -} - -void NanoWidget::fillColor(const Color& color) -{ - nvgFillColor(fContext, color); -} - -void NanoWidget::fillPaint(const Paint& paint) -{ - nvgFillPaint(fContext, paint); -} - -void NanoWidget::miterLimit(float limit) -{ - nvgMiterLimit(fContext, limit); -} - -void NanoWidget::strokeWidth(float size) -{ - nvgStrokeWidth(fContext, size); -} - -void NanoWidget::lineCap(NanoWidget::LineCap cap) -{ - nvgLineCap(fContext, cap); -} - -void NanoWidget::lineJoin(NanoWidget::LineCap join) -{ - nvgLineJoin(fContext, join); -} - -// ----------------------------------------------------------------------- -// Transforms - -void NanoWidget::resetTransform() -{ - nvgResetTransform(fContext); -} - -void NanoWidget::transform(float a, float b, float c, float d, float e, float f) -{ - nvgTransform(fContext, a, b, c, d, e, f); -} - -void NanoWidget::translate(float x, float y) -{ - nvgTranslate(fContext, x, y); -} - -void NanoWidget::rotate(float angle) -{ - nvgRotate(fContext, angle); -} - -void NanoWidget::skewX(float angle) -{ - nvgSkewX(fContext, angle); -} - -void NanoWidget::skewY(float angle) -{ - nvgSkewY(fContext, angle); -} - -void NanoWidget::scale(float x, float y) -{ - nvgScale(fContext, x, y); -} - -void NanoWidget::currentTransform(float xform[6]) -{ - nvgCurrentTransform(fContext, xform); -} - -void NanoWidget::transformIdentity(float dst[6]) -{ - nvgTransformIdentity(dst); -} - -void NanoWidget::transformTranslate(float dst[6], float tx, float ty) -{ - nvgTransformTranslate(dst, tx, ty); -} - -void NanoWidget::transformScale(float dst[6], float sx, float sy) -{ - nvgTransformScale(dst, sx, sy); -} - -void NanoWidget::transformRotate(float dst[6], float a) -{ - nvgTransformRotate(dst, a); -} - -void NanoWidget::transformSkewX(float dst[6], float a) -{ - nvgTransformSkewX(dst, a); -} - -void NanoWidget::transformSkewY(float dst[6], float a) -{ - nvgTransformSkewY(dst, a); -} - -void NanoWidget::transformMultiply(float dst[6], const float src[6]) -{ - nvgTransformMultiply(dst, src); -} - -void NanoWidget::transformPremultiply(float dst[6], const float src[6]) -{ - nvgTransformPremultiply(dst, src); -} - -int NanoWidget::transformInverse(float dst[6], const float src[6]) -{ - return nvgTransformInverse(dst, src); -} - -void NanoWidget::transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy) -{ - nvgTransformPoint(&dstx, &dsty, xform, srcx, srcy); -} - -float NanoWidget::degToRad(float deg) -{ - return nvgDegToRad(deg); -} - -float NanoWidget::radToDeg(float rad) -{ - return nvgRadToDeg(rad); -} - -// ----------------------------------------------------------------------- -// Images - -NanoImage NanoWidget::createImage(const char* filename) -{ - sLastContext = fContext; - return NanoImage(filename); -} - -NanoImage NanoWidget::createImageMem(uchar* data, int ndata) -{ - sLastContext = fContext; - return NanoImage(data, ndata); -} - -NanoImage NanoWidget::createImageRGBA(int w, int h, const uchar* data) -{ - sLastContext = fContext; - return NanoImage(w, h, data); -} - -// ----------------------------------------------------------------------- -// Paints - -NanoWidget::Paint NanoWidget::linearGradient(float sx, float sy, float ex, float ey, const NanoWidget::Color& icol, const NanoWidget::Color& ocol) -{ - return nvgLinearGradient(fContext, sx, sy, ex, ey, icol, ocol); -} - -NanoWidget::Paint NanoWidget::boxGradient(float x, float y, float w, float h, float r, float f, const NanoWidget::Color& icol, const NanoWidget::Color& ocol) -{ - return nvgBoxGradient(fContext, x, y, w, h, r, f, icol, ocol); -} - -NanoWidget::Paint NanoWidget::radialGradient(float cx, float cy, float inr, float outr, const NanoWidget::Color& icol, const NanoWidget::Color& ocol) -{ - return nvgRadialGradient(fContext, cx, cy, inr, outr, icol, ocol); -} - -NanoWidget::Paint NanoWidget::imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, NanoWidget::PatternRepeat repeat) -{ - return nvgImagePattern(fContext, ox, oy, ex, ey, angle, image.fImageId, repeat); -} - -// ----------------------------------------------------------------------- -// Scissoring - -void NanoWidget::scissor(float x, float y, float w, float h) -{ - nvgScissor(fContext, x, y, w, h); -} - -void NanoWidget::resetScissor() -{ - nvgResetScissor(fContext); -} - -// ----------------------------------------------------------------------- -// Paths - -void NanoWidget::beginPath() -{ - nvgBeginPath(fContext); -} - -void NanoWidget::moveTo(float x, float y) -{ - nvgMoveTo(fContext, x, y); -} - -void NanoWidget::lineTo(float x, float y) -{ - nvgLineTo(fContext, x, y); -} - -void NanoWidget::bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y) -{ - nvgBezierTo(fContext, c1x, c1y, c2x, c2y, x, y); -} - -void NanoWidget::arcTo(float x1, float y1, float x2, float y2, float radius) -{ - nvgArcTo(fContext, x1, y1, x2, y2, radius); -} - -void NanoWidget::closePath() -{ - nvgClosePath(fContext); -} - -void NanoWidget::pathWinding(NanoWidget::Winding dir) -{ - nvgPathWinding(fContext, dir); -} - -void NanoWidget::arc(float cx, float cy, float r, float a0, float a1, NanoWidget::Winding dir) -{ - nvgArc(fContext, cx, cy, r, a0, a1, dir); -} - -void NanoWidget::rect(float x, float y, float w, float h) -{ - nvgRect(fContext, x, y, w, h); -} - -void NanoWidget::roundedRect(float x, float y, float w, float h, float r) -{ - nvgRoundedRect(fContext, x, y, w, h, r); -} - -void NanoWidget::ellipse(float cx, float cy, float rx, float ry) -{ - nvgEllipse(fContext, cx, cy, rx, ry); -} - -void NanoWidget::circle(float cx, float cy, float r) -{ - nvgCircle(fContext, cx, cy, r); -} - -void NanoWidget::fill() -{ - nvgFill(fContext); -} - -void NanoWidget::stroke() -{ - nvgStroke(fContext); -} - -// ----------------------------------------------------------------------- -// Text - -NanoWidget::FontId NanoWidget::createFont(const char* name, const char* filename) -{ - return nvgCreateFont(fContext, name, filename); -} - -NanoWidget::FontId NanoWidget::createFontMem(const char* name, uchar* data, int ndata, bool freeData) -{ - return nvgCreateFontMem(fContext, name, data, ndata, freeData); -} - -NanoWidget::FontId NanoWidget::findFont(const char* name) -{ - return nvgFindFont(fContext, name); -} - -void NanoWidget::fontSize(float size) -{ - nvgFontSize(fContext, size); -} - -void NanoWidget::fontBlur(float blur) -{ - nvgFontBlur(fContext, blur); -} - -void NanoWidget::textLetterSpacing(float spacing) -{ - nvgTextLetterSpacing(fContext, spacing); -} - -void NanoWidget::textLineHeight(float lineHeight) -{ - nvgTextLineHeight(fContext, lineHeight); -} - -void NanoWidget::textAlign(NanoWidget::Align align) -{ - nvgTextAlign(fContext, align); -} - -void NanoWidget::fontFaceId(FontId font) -{ - nvgFontFaceId(fContext, font); -} - -void NanoWidget::fontFace(const char* font) -{ - nvgFontFace(fContext, font); -} - -float NanoWidget::text(float x, float y, const char* string, const char* end) -{ - return nvgText(fContext, x, y, string, end); -} - -void NanoWidget::textBox(float x, float y, float breakRowWidth, const char* string, const char* end) -{ - nvgTextBox(fContext, x, y, breakRowWidth, string, end); -} - -float NanoWidget::textBounds(float x, float y, const char* string, const char* end, Rectangle<float>& bounds) -{ - float b[4]; - const float ret = nvgTextBounds(fContext, x, y, string, end, b); - bounds = Rectangle<float>(b[0], b[1], b[2], b[3]); - return ret; -} - -void NanoWidget::textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) -{ - nvgTextBoxBounds(fContext, x, y, breakRowWidth, string, end, bounds); -} - -int NanoWidget::textGlyphPositions(float x, float y, const char* string, const char* end, NanoWidget::GlyphPosition* positions, int maxPositions) -{ - return nvgTextGlyphPositions(fContext, x, y, string, end, (NVGglyphPosition*)positions, maxPositions); -} - -void NanoWidget::textMetrics(float* ascender, float* descender, float* lineh) -{ - nvgTextMetrics(fContext, ascender, descender, lineh); -} - -int NanoWidget::textBreakLines(const char* string, const char* end, float breakRowWidth, NanoWidget::TextRow* rows, int maxRows) -{ - return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)rows, maxRows); -} - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL - -extern "C" { -#include "nanovg/nanovg.c" -} - -// ----------------------------------------------------------------------- diff --git a/dgl/src/nanovg/fontstash.h b/dgl/src/nanovg/fontstash.h @@ -837,6 +837,7 @@ int fonsAddFont(struct FONScontext* stash, const char* name, const char* path) FILE* fp = 0; int dataSize = 0; unsigned char* data = NULL; + size_t r; // Read in the font data. fp = fopen(path, "rb"); @@ -846,12 +847,14 @@ int fonsAddFont(struct FONScontext* stash, const char* name, const char* path) fseek(fp,0,SEEK_SET); data = (unsigned char*)malloc(dataSize); if (data == NULL) goto error; - fread(data, 1, dataSize, fp); + r = fread(data, 1, dataSize, fp); fclose(fp); fp = 0; return fonsAddFontMem(stash, name, data, dataSize, 1); + NVG_NOTUSED(r); + error: if (data) free(data); if (fp) fclose(fp);