From 5a65496535aa53e8d9b467beb7f6245e330fa090 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 24 May 2014 03:32:37 +0100 Subject: [PATCH] Rename Nano file; Make base nano API into class plus widget --- dgl/Makefile | 2 +- dgl/{NanoWidget.hpp => NanoVG.hpp} | 63 +++++++-- dgl/src/{NanoWidget.cpp => NanoVG.cpp} | 185 ++++++++++++------------- dgl/src/nanovg/fontstash.h | 5 +- 4 files changed, 151 insertions(+), 104 deletions(-) rename dgl/{NanoWidget.hpp => NanoVG.hpp} (95%) rename dgl/src/{NanoWidget.cpp => NanoVG.cpp} (60%) diff --git a/dgl/Makefile b/dgl/Makefile index 60858757..d107bf4e 100644 --- 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/NanoWidget.hpp b/dgl/NanoVG.hpp similarity index 95% rename from dgl/NanoWidget.hpp rename to dgl/NanoVG.hpp index fb1f67a6..7d3787e0 100644 --- a/dgl/NanoWidget.hpp +++ b/dgl/NanoVG.hpp @@ -26,12 +26,13 @@ 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 NanoWidget class. + Images need to be created within a NanoVG or NanoWidget class. */ class NanoImage { @@ -54,7 +55,7 @@ public: protected: /** Constructors are protected. - NanoImages must be created within a NanoWidget class. + NanoImages must be created within a NanoVG or NanoWidget class. */ NanoImage(const char* filename); NanoImage(uchar* data, int ndata); @@ -63,17 +64,19 @@ protected: private: NVGcontext* const fContext; const int fImageId; - friend class NanoWidget; + friend class NanoVG; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoImage) + DISTRHO_PREVENT_HEAP_ALLOCATION }; // ----------------------------------------------------------------------- +// NanoVG /** - NanoVG Widget class. + NanoVG class. - This class implements the NanoVG drawing API inside a DGL Widget. + This class exposes the NanoVG drawing API. All calls should be wrapped in beginFrame() & endFrame(). @section Color utils @@ -165,7 +168,7 @@ private: Note: currently only solid color fill is supported for text. */ -class NanoWidget : public Widget +class NanoVG { public: enum Align { @@ -254,12 +257,12 @@ public: /** Constructor. */ - NanoWidget(Window& parent); + NanoVG(); /** Destructor. */ - ~NanoWidget() override; + ~NanoVG(); /** Get the NanoVG context. @@ -275,7 +278,7 @@ 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); + void beginFrame(int width, int height, float scaleFactor = 1.0f, Alpha alpha = PREMULTIPLIED_ALPHA); /** Ends drawing flushing remaining render state. @@ -744,6 +747,48 @@ protected: 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) }; diff --git a/dgl/src/NanoWidget.cpp b/dgl/src/NanoVG.cpp similarity index 60% rename from dgl/src/NanoWidget.cpp rename to dgl/src/NanoVG.cpp index 774e7f91..229bc019 100644 --- a/dgl/src/NanoWidget.cpp +++ b/dgl/src/NanoVG.cpp @@ -14,7 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "../NanoWidget.hpp" +#include "../NanoVG.hpp" // ----------------------------------------------------------------------- @@ -40,33 +40,33 @@ START_NAMESPACE_DGL // ----------------------------------------------------------------------- // Conversions -NanoWidget::Color::Color() noexcept +NanoVG::Color::Color() noexcept : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {} -NanoWidget::Color::Color(const NVGcolor& c) noexcept +NanoVG::Color::Color(const NVGcolor& c) noexcept : r(c.r), g(c.g), b(c.b), a(c.a) {} -NanoWidget::Color::operator NVGcolor() const noexcept +NanoVG::Color::operator NVGcolor() const noexcept { NVGcolor nc = { r, g, b, a }; return nc; } -NanoWidget::Paint::Paint() noexcept +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); } -NanoWidget::Paint::Paint(const NVGpaint& p) noexcept +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(p.repeat)) { std::memcpy(xform, p.xform, sizeof(float)*6); std::memcpy(extent, p.extent, sizeof(float)*2); } -NanoWidget::Paint::operator NVGpaint() const noexcept +NanoVG::Paint::operator NVGpaint() const noexcept { NVGpaint p; p.radius = radius; @@ -120,16 +120,15 @@ void NanoImage::updateImage(const uchar* data) } // ----------------------------------------------------------------------- -// NanoWidget +// NanoVG -NanoWidget::NanoWidget(Window& parent) - : Widget(parent), - fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS)) +NanoVG::NanoVG() + : fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS)) { DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,); } -NanoWidget::~NanoWidget() +NanoVG::~NanoVG() { if (fContext == nullptr) return; @@ -139,12 +138,12 @@ NanoWidget::~NanoWidget() // ----------------------------------------------------------------------- -void NanoWidget::beginFrame(Alpha alpha) +void NanoVG::beginFrame(int width, int height, float scaleFactor, Alpha alpha) { - nvgBeginFrame(fContext, getWidth(), getHeight(), 1.0f, static_cast(alpha)); + nvgBeginFrame(fContext, width, height, scaleFactor, static_cast(alpha)); } -void NanoWidget::endFrame() +void NanoVG::endFrame() { nvgEndFrame(fContext); } @@ -152,37 +151,37 @@ void NanoWidget::endFrame() // ----------------------------------------------------------------------- // Color utils -NanoWidget::Color NanoWidget::RGB(uchar r, uchar g, uchar b) +NanoVG::Color NanoVG::RGB(uchar r, uchar g, uchar b) { return nvgRGB(r, g, b); } -NanoWidget::Color NanoWidget::RGBf(float r, float g, float b) +NanoVG::Color NanoVG::RGBf(float r, float g, float b) { return nvgRGBf(r, g, b); } -NanoWidget::Color NanoWidget::RGBA(uchar r, uchar g, uchar b, uchar a) +NanoVG::Color NanoVG::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) +NanoVG::Color NanoVG::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) +NanoVG::Color NanoVG::lerpRGBA(const Color& c0, const Color& c1, float u) { return nvgLerpRGBA(c0, c1, u); } -NanoWidget::Color NanoWidget::HSL(float h, float s, float l) +NanoVG::Color NanoVG::HSL(float h, float s, float l) { return nvgHSL(h, s, l); } -NanoWidget::Color NanoWidget::HSLA(float h, float s, float l, uchar a) +NanoVG::Color NanoVG::HSLA(float h, float s, float l, uchar a) { return nvgHSLA(h, s, l, a); } @@ -190,17 +189,17 @@ NanoWidget::Color NanoWidget::HSLA(float h, float s, float l, uchar a) // ----------------------------------------------------------------------- // State Handling -void NanoWidget::save() +void NanoVG::save() { nvgSave(fContext); } -void NanoWidget::restore() +void NanoVG::restore() { nvgRestore(fContext); } -void NanoWidget::reset() +void NanoVG::reset() { nvgReset(fContext); } @@ -208,42 +207,42 @@ void NanoWidget::reset() // ----------------------------------------------------------------------- // Render styles -void NanoWidget::strokeColor(const Color& color) +void NanoVG::strokeColor(const Color& color) { nvgStrokeColor(fContext, color); } -void NanoWidget::strokePaint(const Paint& paint) +void NanoVG::strokePaint(const Paint& paint) { nvgStrokePaint(fContext, paint); } -void NanoWidget::fillColor(const Color& color) +void NanoVG::fillColor(const Color& color) { nvgFillColor(fContext, color); } -void NanoWidget::fillPaint(const Paint& paint) +void NanoVG::fillPaint(const Paint& paint) { nvgFillPaint(fContext, paint); } -void NanoWidget::miterLimit(float limit) +void NanoVG::miterLimit(float limit) { nvgMiterLimit(fContext, limit); } -void NanoWidget::strokeWidth(float size) +void NanoVG::strokeWidth(float size) { nvgStrokeWidth(fContext, size); } -void NanoWidget::lineCap(NanoWidget::LineCap cap) +void NanoVG::lineCap(NanoVG::LineCap cap) { nvgLineCap(fContext, cap); } -void NanoWidget::lineJoin(NanoWidget::LineCap join) +void NanoVG::lineJoin(NanoVG::LineCap join) { nvgLineJoin(fContext, join); } @@ -251,102 +250,102 @@ void NanoWidget::lineJoin(NanoWidget::LineCap join) // ----------------------------------------------------------------------- // Transforms -void NanoWidget::resetTransform() +void NanoVG::resetTransform() { nvgResetTransform(fContext); } -void NanoWidget::transform(float a, float b, float c, float d, float e, float f) +void NanoVG::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) +void NanoVG::translate(float x, float y) { nvgTranslate(fContext, x, y); } -void NanoWidget::rotate(float angle) +void NanoVG::rotate(float angle) { nvgRotate(fContext, angle); } -void NanoWidget::skewX(float angle) +void NanoVG::skewX(float angle) { nvgSkewX(fContext, angle); } -void NanoWidget::skewY(float angle) +void NanoVG::skewY(float angle) { nvgSkewY(fContext, angle); } -void NanoWidget::scale(float x, float y) +void NanoVG::scale(float x, float y) { nvgScale(fContext, x, y); } -void NanoWidget::currentTransform(float xform[6]) +void NanoVG::currentTransform(float xform[6]) { nvgCurrentTransform(fContext, xform); } -void NanoWidget::transformIdentity(float dst[6]) +void NanoVG::transformIdentity(float dst[6]) { nvgTransformIdentity(dst); } -void NanoWidget::transformTranslate(float dst[6], float tx, float ty) +void NanoVG::transformTranslate(float dst[6], float tx, float ty) { nvgTransformTranslate(dst, tx, ty); } -void NanoWidget::transformScale(float dst[6], float sx, float sy) +void NanoVG::transformScale(float dst[6], float sx, float sy) { nvgTransformScale(dst, sx, sy); } -void NanoWidget::transformRotate(float dst[6], float a) +void NanoVG::transformRotate(float dst[6], float a) { nvgTransformRotate(dst, a); } -void NanoWidget::transformSkewX(float dst[6], float a) +void NanoVG::transformSkewX(float dst[6], float a) { nvgTransformSkewX(dst, a); } -void NanoWidget::transformSkewY(float dst[6], float a) +void NanoVG::transformSkewY(float dst[6], float a) { nvgTransformSkewY(dst, a); } -void NanoWidget::transformMultiply(float dst[6], const float src[6]) +void NanoVG::transformMultiply(float dst[6], const float src[6]) { nvgTransformMultiply(dst, src); } -void NanoWidget::transformPremultiply(float dst[6], const float src[6]) +void NanoVG::transformPremultiply(float dst[6], const float src[6]) { nvgTransformPremultiply(dst, src); } -int NanoWidget::transformInverse(float dst[6], const float src[6]) +int NanoVG::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) +void NanoVG::transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy) { nvgTransformPoint(&dstx, &dsty, xform, srcx, srcy); } -float NanoWidget::degToRad(float deg) +float NanoVG::degToRad(float deg) { return nvgDegToRad(deg); } -float NanoWidget::radToDeg(float rad) +float NanoVG::radToDeg(float rad) { return nvgRadToDeg(rad); } @@ -354,19 +353,19 @@ float NanoWidget::radToDeg(float rad) // ----------------------------------------------------------------------- // Images -NanoImage NanoWidget::createImage(const char* filename) +NanoImage NanoVG::createImage(const char* filename) { sLastContext = fContext; return NanoImage(filename); } -NanoImage NanoWidget::createImageMem(uchar* data, int ndata) +NanoImage NanoVG::createImageMem(uchar* data, int ndata) { sLastContext = fContext; return NanoImage(data, ndata); } -NanoImage NanoWidget::createImageRGBA(int w, int h, const uchar* data) +NanoImage NanoVG::createImageRGBA(int w, int h, const uchar* data) { sLastContext = fContext; return NanoImage(w, h, data); @@ -375,22 +374,22 @@ NanoImage NanoWidget::createImageRGBA(int w, int h, const uchar* data) // ----------------------------------------------------------------------- // Paints -NanoWidget::Paint NanoWidget::linearGradient(float sx, float sy, float ex, float ey, const NanoWidget::Color& icol, const NanoWidget::Color& ocol) +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); } -NanoWidget::Paint NanoWidget::boxGradient(float x, float y, float w, float h, float r, float f, const NanoWidget::Color& icol, const NanoWidget::Color& 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); } -NanoWidget::Paint NanoWidget::radialGradient(float cx, float cy, float inr, float outr, const NanoWidget::Color& icol, const NanoWidget::Color& 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); } -NanoWidget::Paint NanoWidget::imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, NanoWidget::PatternRepeat repeat) +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); } @@ -398,12 +397,12 @@ NanoWidget::Paint NanoWidget::imagePattern(float ox, float oy, float ex, float e // ----------------------------------------------------------------------- // Scissoring -void NanoWidget::scissor(float x, float y, float w, float h) +void NanoVG::scissor(float x, float y, float w, float h) { nvgScissor(fContext, x, y, w, h); } -void NanoWidget::resetScissor() +void NanoVG::resetScissor() { nvgResetScissor(fContext); } @@ -411,72 +410,72 @@ void NanoWidget::resetScissor() // ----------------------------------------------------------------------- // Paths -void NanoWidget::beginPath() +void NanoVG::beginPath() { nvgBeginPath(fContext); } -void NanoWidget::moveTo(float x, float y) +void NanoVG::moveTo(float x, float y) { nvgMoveTo(fContext, x, y); } -void NanoWidget::lineTo(float x, float y) +void NanoVG::lineTo(float x, float y) { nvgLineTo(fContext, x, y); } -void NanoWidget::bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float 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 NanoWidget::arcTo(float x1, float y1, float x2, float y2, float radius) +void NanoVG::arcTo(float x1, float y1, float x2, float y2, float radius) { nvgArcTo(fContext, x1, y1, x2, y2, radius); } -void NanoWidget::closePath() +void NanoVG::closePath() { nvgClosePath(fContext); } -void NanoWidget::pathWinding(NanoWidget::Winding dir) +void NanoVG::pathWinding(NanoVG::Winding dir) { nvgPathWinding(fContext, dir); } -void NanoWidget::arc(float cx, float cy, float r, float a0, float a1, NanoWidget::Winding 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 NanoWidget::rect(float x, float y, float w, float h) +void NanoVG::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) +void NanoVG::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) +void NanoVG::ellipse(float cx, float cy, float rx, float ry) { nvgEllipse(fContext, cx, cy, rx, ry); } -void NanoWidget::circle(float cx, float cy, float r) +void NanoVG::circle(float cx, float cy, float r) { nvgCircle(fContext, cx, cy, r); } -void NanoWidget::fill() +void NanoVG::fill() { nvgFill(fContext); } -void NanoWidget::stroke() +void NanoVG::stroke() { nvgStroke(fContext); } @@ -484,67 +483,67 @@ void NanoWidget::stroke() // ----------------------------------------------------------------------- // Text -NanoWidget::FontId NanoWidget::createFont(const char* name, const char* filename) +NanoVG::FontId NanoVG::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) +NanoVG::FontId NanoVG::createFontMem(const char* name, uchar* data, int ndata, bool freeData) { return nvgCreateFontMem(fContext, name, data, ndata, freeData); } -NanoWidget::FontId NanoWidget::findFont(const char* name) +NanoVG::FontId NanoVG::findFont(const char* name) { return nvgFindFont(fContext, name); } -void NanoWidget::fontSize(float size) +void NanoVG::fontSize(float size) { nvgFontSize(fContext, size); } -void NanoWidget::fontBlur(float blur) +void NanoVG::fontBlur(float blur) { nvgFontBlur(fContext, blur); } -void NanoWidget::textLetterSpacing(float spacing) +void NanoVG::textLetterSpacing(float spacing) { nvgTextLetterSpacing(fContext, spacing); } -void NanoWidget::textLineHeight(float lineHeight) +void NanoVG::textLineHeight(float lineHeight) { nvgTextLineHeight(fContext, lineHeight); } -void NanoWidget::textAlign(NanoWidget::Align align) +void NanoVG::textAlign(NanoVG::Align align) { nvgTextAlign(fContext, align); } -void NanoWidget::fontFaceId(FontId font) +void NanoVG::fontFaceId(FontId font) { nvgFontFaceId(fContext, font); } -void NanoWidget::fontFace(const char* font) +void NanoVG::fontFace(const char* font) { nvgFontFace(fContext, font); } -float NanoWidget::text(float x, float y, const char* string, const char* end) +float NanoVG::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) +void NanoVG::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& bounds) +float NanoVG::textBounds(float x, float y, const char* string, const char* end, Rectangle& bounds) { float b[4]; const float ret = nvgTextBounds(fContext, x, y, string, end, b); @@ -552,22 +551,22 @@ float NanoWidget::textBounds(float x, float y, const char* string, const char* e return ret; } -void NanoWidget::textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) +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 NanoWidget::textGlyphPositions(float x, float y, const char* string, const char* end, NanoWidget::GlyphPosition* positions, int maxPositions) +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 NanoWidget::textMetrics(float* ascender, float* descender, float* lineh) +void NanoVG::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) +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); } diff --git a/dgl/src/nanovg/fontstash.h b/dgl/src/nanovg/fontstash.h index 0d42fc5a..7fb89555 100644 --- 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);