diff --git a/source/modules/dgl/NanoVG.hpp b/source/modules/dgl/NanoVG.hpp index 3e04f3e0f..8d6642b93 100644 --- a/source/modules/dgl/NanoVG.hpp +++ b/source/modules/dgl/NanoVG.hpp @@ -37,21 +37,11 @@ START_NAMESPACE_DGL class NanoImage { public: - /** - Constructor for null image. - */ - NanoImage() noexcept; - /** Destructor. */ ~NanoImage(); - /** - Check if this is a valid image. - */ - bool isValid() const noexcept; - /** Get size. */ @@ -62,25 +52,19 @@ public: */ void updateImage(const uchar* data); - /** - Operator =. - Takes the image data from @a img, invalidating it. - */ - NanoImage operator=(NanoImage img) noexcept; - 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); + NanoImage(NVGcontext* context, int imageId) noexcept; private: NVGcontext* fContext; int fImageId; friend class NanoVG; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoImage) }; // ----------------------------------------------------------------------- @@ -534,17 +518,17 @@ public: /** Creates image by loading it from the disk from specified file name. */ - NanoImage createImage(const char* filename); + NanoImage* createImage(const char* filename); /** Creates image by loading it from the specified chunk of memory. */ - NanoImage createImageMem(uchar* data, int ndata); + NanoImage* createImageMem(uchar* data, int ndata); /** Creates image from specified image data. */ - NanoImage createImageRGBA(int w, int h, const uchar* data); + NanoImage* createImageRGBA(int w, int h, const uchar* data); /* -------------------------------------------------------------------- * Paints */ @@ -573,12 +557,12 @@ public: 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, + Creates and returns an image pattern. 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); + Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage* image, PatternRepeat repeat); /* -------------------------------------------------------------------- * Scissoring */ diff --git a/source/modules/dgl/src/NanoVG.cpp b/source/modules/dgl/src/NanoVG.cpp index b46bb0b6a..78b6bc238 100644 --- a/source/modules/dgl/src/NanoVG.cpp +++ b/source/modules/dgl/src/NanoVG.cpp @@ -49,7 +49,7 @@ NanoVG::Color::Color(const NVGcolor& c) noexcept NanoVG::Color::operator NVGcolor() const noexcept { - NVGcolor nc = { r, g, b, a }; + NVGcolor nc = {{{ r, g, b, a }}}; return nc; } @@ -84,33 +84,9 @@ NanoVG::Paint::operator NVGpaint() const noexcept // ----------------------------------------------------------------------- // 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(NVGcontext* context, int imageId) noexcept + : fContext(context), + fImageId(imageId) {} NanoImage::~NanoImage() { @@ -118,11 +94,6 @@ NanoImage::~NanoImage() nvgDeleteImage(fContext, fImageId); } -bool NanoImage::isValid() const noexcept -{ - return (fContext != nullptr && fImageId != 0); -} - Size NanoImage::getSize() const { int w=0, h=0; @@ -139,20 +110,6 @@ void NanoImage::updateImage(const uchar* data) 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 @@ -401,22 +358,25 @@ float NanoVG::radToDeg(float rad) // ----------------------------------------------------------------------- // Images -NanoImage NanoVG::createImage(const char* filename) +NanoImage* NanoVG::createImage(const char* filename) { - sLastContext = fContext; - return NanoImage(filename); + if (const int imageId = nvgCreateImage(fContext, filename)) + return new NanoImage(fContext, imageId); + return nullptr; } -NanoImage NanoVG::createImageMem(uchar* data, int ndata) +NanoImage* NanoVG::createImageMem(uchar* data, int ndata) { - sLastContext = fContext; - return NanoImage(data, ndata); + if (const int imageId = nvgCreateImageMem(fContext, data, ndata)) + return new NanoImage(fContext, imageId); + return nullptr; } -NanoImage NanoVG::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); + if (const int imageId = nvgCreateImageRGBA(fContext, w, h, data)) + return new NanoImage(fContext, imageId); + return nullptr; } // ----------------------------------------------------------------------- @@ -437,9 +397,10 @@ NanoVG::Paint NanoVG::radialGradient(float cx, float cy, float inr, float outr, 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) +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); + DISTRHO_SAFE_ASSERT_RETURN(image != nullptr, Paint()); + return nvgImagePattern(fContext, ox, oy, ex, ey, angle, image->fImageId, repeat); } // ----------------------------------------------------------------------- diff --git a/source/modules/dgl/src/Window.cpp b/source/modules/dgl/src/Window.cpp index 2d3cdca62..e94b70492 100644 --- a/source/modules/dgl/src/Window.cpp +++ b/source/modules/dgl/src/Window.cpp @@ -14,9 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -// we need this for now -#define PUGL_GRAB_FOCUS 1 - #include "AppPrivateData.hpp" #include "../Widget.hpp" #include "../Window.hpp" @@ -562,6 +559,8 @@ struct Window::PrivateData { { fSelf->onDisplayBefore(); + bool needsDisableScissor = false; + FOR_EACH_WIDGET(it) { Widget* const widget(*it); @@ -575,32 +574,30 @@ struct Window::PrivateData { { // full viewport size glViewport(0, 0, fView->width, fView->height); - - // display widget - widget->onDisplay(); } else if (! widget->fNeedsScaling) { // only set viewport pos glViewport(widget->getAbsoluteX(), /*fView->height - widget->getHeight()*/ - widget->getAbsoluteY(), fView->width, fView->height); - // display widget - widget->onDisplay(); + // then cut the outer bounds + glScissor(widget->getAbsoluteX(), fView->height - widget->getHeight() - widget->getAbsoluteY(), widget->getWidth(), widget->getHeight()); + glEnable(GL_SCISSOR_TEST); + needsDisableScissor = true; } else { // limit viewport to widget bounds glViewport(widget->getAbsoluteX(), fView->height - widget->getHeight() - widget->getAbsoluteY(), widget->getWidth(), widget->getHeight()); + } - // scale contents to match viewport size - glPushMatrix(); - glScalef(float(fView->width)/float(widget->getWidth()), float(fView->height)/float(widget->getHeight()), 1.0f); - - // display widget - widget->onDisplay(); + // display widget + widget->onDisplay(); - // done - glPopMatrix(); + if (needsDisableScissor) + { + glDisable(GL_SCISSOR_TEST); + needsDisableScissor = false; } } }