summaryrefslogtreecommitdiff
path: root/libs/dgl/src/NanoVG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/dgl/src/NanoVG.cpp')
-rw-r--r--libs/dgl/src/NanoVG.cpp626
1 files changed, 626 insertions, 0 deletions
diff --git a/libs/dgl/src/NanoVG.cpp b/libs/dgl/src/NanoVG.cpp
new file mode 100644
index 0000000..b4e3103
--- /dev/null
+++ b/libs/dgl/src/NanoVG.cpp
@@ -0,0 +1,626 @@
+/*
+ * 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() noexcept
+ : fContext(nullptr),
+ fImageId(0) {}
+
+#if 0
+NanoImage::NanoImage(NanoImage& img) noexcept
+ : fContext(img.fContext),
+ fImageId(img.fImageId)
+{
+ img.fContext = nullptr;
+ img.fImageId = 0;
+}
+#endif
+
+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);
+}
+
+bool NanoImage::isValid() const noexcept
+{
+ return (fContext != nullptr && fImageId != 0);
+}
+
+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);
+}
+
+NanoImage NanoImage::operator=(NanoImage img) noexcept
+{
+ if (fContext != nullptr && fImageId != 0)
+ nvgDeleteImage(fContext, fImageId);
+
+ fContext = img.fContext;
+ fImageId = img.fImageId;
+
+ img.fContext = nullptr;
+ img.fImageId = 0;
+
+ return *this;
+}
+
+// -----------------------------------------------------------------------
+// NanoVG
+
+NanoVG::NanoVG()
+ : fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS))
+{
+ DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,);
+}
+
+NanoVG::NanoVG(int textAtlasWidth, int textAtlasHeight)
+ : fContext(nvgCreateGL(textAtlasWidth, textAtlasHeight, 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::textAlign(int 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"
+}
+
+// -----------------------------------------------------------------------