Browse Source

Change how NanoImages are handled; Minor update to NanoVG class

pull/6/head
falkTX 10 years ago
parent
commit
3a77a1144f
2 changed files with 163 additions and 82 deletions
  1. +73
    -28
      dgl/NanoVG.hpp
  2. +90
    -54
      dgl/src/NanoVG.cpp

+ 73
- 28
dgl/NanoVG.hpp View File

@@ -36,12 +36,46 @@ START_NAMESPACE_DGL
*/
class NanoImage
{
private:
struct Handle {
NVGcontext* context;
int imageId;

Handle() noexcept
: context(nullptr),
imageId(0) {}

Handle(NVGcontext* c, int id) noexcept
: context(c),
imageId(id) {}
};

public:
/**
Constructor for an invalid/null image.
*/
NanoImage();

/**
Constructor.
*/
NanoImage(const Handle& handle);

/**
Destructor.
*/
~NanoImage();

/**
Create a new image without recreating the C++ class.
*/
NanoImage& operator=(const Handle& handle);

/**
Wherever the image is valid.
*/
bool isValid() const noexcept;

/**
Get size.
*/
@@ -57,16 +91,8 @@ public:
*/
void updateImage(const uchar* const data);

protected:
/**
Constructors are protected.
NanoImages must be created within a NanoVG or NanoWidget class.
*/
NanoImage(NVGcontext* const context, const int imageId) noexcept;

private:
NVGcontext* fContext;
int fImageId;
Handle fHandle;
Size<uint> fSize;
friend class NanoVG;

@@ -265,6 +291,7 @@ public:

/**
Constructor.
@see CreateFlags
*/
NanoVG(int flags = CREATE_ANTIALIAS);

@@ -519,30 +546,50 @@ public:
/**
Creates image by loading it from the disk from specified file name.
*/
NanoImage* createImage(const char* filename, int imageFlags);
NanoImage::Handle createImageFromFile(const char* filename, ImageFlags imageFlags);

// TODO overloaded?
/**
Creates image by loading it from the disk from specified file name.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromFile(const char* filename, int imageFlags);

/**
Creates image by loading it from the specified chunk of memory.
*/
NanoImage* createImageMem(uchar* data, int ndata, int imageFlags);
NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, ImageFlags imageFlags);

// TODO overloaded?
/**
Creates image by loading it from the specified chunk of memory.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromMemory(uchar* data, uint dataSize, int imageFlags);

/**
Creates image from specified image data.
*/
NanoImage* createImageRGBA(uint w, uint h, const uchar* data, int imageFlags);
NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags);

// TODO overloaded?
/**
Creates image from specified image data.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromRGBA(uint w, uint h, const uchar* data, int imageFlags);

/**
Creates image from an OpenGL texture handle.
*/
NanoImage* createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture = false);
NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture = false);

// TODO overloaded?
/**
Creates image from an OpenGL texture handle.
Overloaded function for convenience.
@see ImageFlags
*/
NanoImage::Handle createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture = false);

/* --------------------------------------------------------------------
* Paints */
@@ -575,7 +622,7 @@ public:
(ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render.
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, float alpha);
Paint imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, float alpha);

/* --------------------------------------------------------------------
* Scissoring */
@@ -688,13 +735,13 @@ public:
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);
FontId createFontFromFile(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, const uchar* data, int ndata, bool freeData);
FontId createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData);

/**
Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found.
@@ -767,13 +814,13 @@ public:
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);
void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float bounds[4]);

/**
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);
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.
@@ -786,7 +833,7 @@ public:
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);
int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow& rows, int maxRows);

private:
NVGcontext* const fContext;
@@ -811,10 +858,11 @@ class NanoWidget : public Widget,
public:
/**
Constructor.
@see CreateFlags
*/
NanoWidget(Window& parent)
NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS)
: Widget(parent),
NanoVG(),
NanoVG(flags),
leakDetector_NanoWidget()
{
setNeedsScaling(true);
@@ -834,12 +882,9 @@ private:
*/
void onDisplay() override
{
//glPushAttrib(GL_PIXEL_MODE_BIT|GL_STENCIL_BUFFER_BIT|GL_ENABLE_BIT);
beginFrame(getWidth(), getHeight());
onNanoDisplay();
endFrame();
//glPopAttrib();
glDisable(GL_CULL_FACE);
}

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget)


+ 90
- 54
dgl/src/NanoVG.cpp View File

@@ -110,19 +110,43 @@ NanoVG::Paint::operator NVGpaint() const noexcept
// -----------------------------------------------------------------------
// NanoImage

NanoImage::NanoImage(NVGcontext* const context, const int imageId) noexcept
: fContext(context),
fImageId(imageId),
NanoImage::NanoImage()
: fHandle(),
fSize(),
leakDetector_NanoImage()
{
}

NanoImage::NanoImage(const Handle& handle)
: fHandle(handle),
fSize(),
leakDetector_NanoImage()
{
DISTRHO_SAFE_ASSERT_RETURN(fHandle.context != nullptr && fHandle.imageId != 0,);

_updateSize();
}

NanoImage::~NanoImage()
{
if (fContext != nullptr && fImageId != 0)
nvgDeleteImage(fContext, fImageId);
if (fHandle.context != nullptr && fHandle.imageId != 0)
nvgDeleteImage(fHandle.context, fHandle.imageId);
}

NanoImage& NanoImage::operator=(const Handle& handle)
{
if (fHandle.context != nullptr && fHandle.imageId != 0)
nvgDeleteImage(fHandle.context, fHandle.imageId);

fHandle.context = handle.context;
fHandle.imageId = handle.imageId;

return *this;
}

bool NanoImage::isValid() const noexcept
{
return (fHandle.context != nullptr && fHandle.imageId != 0);
}

Size<uint> NanoImage::getSize() const noexcept
@@ -132,31 +156,28 @@ Size<uint> NanoImage::getSize() const noexcept

GLuint NanoImage::getTextureHandle() const
{
return nvglImageHandle(fContext, fImageId);
DISTRHO_SAFE_ASSERT_RETURN(fHandle.context != nullptr && fHandle.imageId != 0, 0);

return nvglImageHandle(fHandle.context, fHandle.imageId);
}

void NanoImage::updateImage(const uchar* const data)
{
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fHandle.context != nullptr && fHandle.imageId != 0,);

if (fContext != nullptr && fImageId != 0)
{
nvgUpdateImage(fContext, fImageId, data);
_updateSize();
}
nvgUpdateImage(fHandle.context, fHandle.imageId, data);
_updateSize();
}

void NanoImage::_updateSize()
{
int w=0, h=0;

if (fContext != nullptr && fImageId != 0)
{
nvgImageSize(fContext, fImageId, &w, &h);
nvgImageSize(fHandle.context, fHandle.imageId, &w, &h);

if (w < 0) w = 0;
if (h < 0) h = 0;
}
if (w < 0) w = 0;
if (h < 0) h = 0;

fSize.setSize(static_cast<uint>(w), static_cast<uint>(h));
}
@@ -488,52 +509,65 @@ float NanoVG::radToDeg(float rad)
// -----------------------------------------------------------------------
// Images

NanoImage* NanoVG::createImage(const char* filename, int imageFlags)
NanoImage::Handle NanoVG::createImageFromFile(const char* filename, ImageFlags imageFlags)
{
if (fContext == nullptr) return nullptr;
DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr);
return createImageFromFile(filename, static_cast<int>(imageFlags));
}

if (const int imageId = nvgCreateImage(fContext, filename, imageFlags))
return new NanoImage(fContext, imageId);
NanoImage::Handle NanoVG::createImageFromFile(const char* filename, int imageFlags)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', NanoImage::Handle());

return nullptr;
return NanoImage::Handle(fContext, nvgCreateImage(fContext, filename, imageFlags));
}

NanoImage* NanoVG::createImageMem(uchar* data, int ndata, int imageFlags)
NanoImage::Handle NanoVG::createImageFromMemory(uchar* data, uint dataSize, ImageFlags imageFlags)
{
if (fContext == nullptr) return nullptr;
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, nullptr);
DISTRHO_SAFE_ASSERT_RETURN(ndata > 0, nullptr);
return createImageFromMemory(data, dataSize, static_cast<int>(imageFlags));
}

if (const int imageId = nvgCreateImageMem(fContext, imageFlags, data, ndata))
return new NanoImage(fContext, imageId);
NanoImage::Handle NanoVG::createImageFromMemory(uchar* data, uint dataSize, int imageFlags)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, NanoImage::Handle());
DISTRHO_SAFE_ASSERT_RETURN(dataSize > 0, NanoImage::Handle());

return nullptr;
return NanoImage::Handle(fContext, nvgCreateImageMem(fContext, imageFlags, data,static_cast<int>(dataSize)));
}

NanoImage* NanoVG::createImageRGBA(uint w, uint h, const uchar* data, int imageFlags)
NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data, ImageFlags imageFlags)
{
if (fContext == nullptr) return nullptr;
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, nullptr);
return createImageFromRGBA(w, h, data, static_cast<int>(imageFlags));
}

if (const int imageId = nvgCreateImageRGBA(fContext, static_cast<int>(w), static_cast<int>(h), imageFlags, data))
return new NanoImage(fContext, imageId);
NanoImage::Handle NanoVG::createImageFromRGBA(uint w, uint h, const uchar* data, int imageFlags)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, NanoImage::Handle());

return nullptr;
return NanoImage::Handle(fContext, nvgCreateImageRGBA(fContext,
static_cast<int>(w),
static_cast<int>(h), imageFlags, data));
}

NanoImage* NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture)
NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, ImageFlags imageFlags, bool deleteTexture)
{
if (fContext == nullptr) return nullptr;
DISTRHO_SAFE_ASSERT_RETURN(textureId != 0, nullptr);
return createImageFromTextureHandle(textureId, w, h, static_cast<int>(imageFlags), deleteTexture);
}

NanoImage::Handle NanoVG::createImageFromTextureHandle(GLuint textureId, uint w, uint h, int imageFlags, bool deleteTexture)
{
if (fContext == nullptr) return NanoImage::Handle();
DISTRHO_SAFE_ASSERT_RETURN(textureId != 0, NanoImage::Handle());

if (! deleteTexture)
imageFlags |= NVG_IMAGE_NODELETE;

if (const int imageId = nvglCreateImageFromHandle(fContext, textureId, static_cast<int>(w), static_cast<int>(h), imageFlags))
return new NanoImage(fContext, imageId);
return nullptr;
return NanoImage::Handle(fContext, nvglCreateImageFromHandle(fContext,
textureId,
static_cast<int>(w),
static_cast<int>(h), imageFlags));
}

// -----------------------------------------------------------------------
@@ -557,12 +591,14 @@ 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, float alpha)
NanoVG::Paint NanoVG::imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, float alpha)
{
if (fContext == nullptr) return Paint();
DISTRHO_SAFE_ASSERT_RETURN(image != nullptr, Paint());

return nvgImagePattern(fContext, ox, oy, ex, ey, angle, image->fImageId, alpha);
const int imageId(image.fHandle.imageId);
DISTRHO_SAFE_ASSERT_RETURN(imageId != 0, Paint());

return nvgImagePattern(fContext, ox, oy, ex, ey, angle, imageId, alpha);
}

// -----------------------------------------------------------------------
@@ -682,7 +718,7 @@ void NanoVG::stroke()
// -----------------------------------------------------------------------
// Text

NanoVG::FontId NanoVG::createFont(const char* name, const char* filename)
NanoVG::FontId NanoVG::createFontFromFile(const char* name, const char* filename)
{
if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
@@ -691,13 +727,13 @@ NanoVG::FontId NanoVG::createFont(const char* name, const char* filename)
return nvgCreateFont(fContext, name, filename);
}

NanoVG::FontId NanoVG::createFontMem(const char* name, const uchar* data, int ndata, bool freeData)
NanoVG::FontId NanoVG::createFontFromMemory(const char* name, const uchar* data, uint dataSize, bool freeData)
{
if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, -1);

return nvgCreateFontMem(fContext, name, const_cast<uchar*>(data), ndata, freeData);
return nvgCreateFontMem(fContext, name, const_cast<uchar*>(data), static_cast<int>(dataSize), freeData);
}

NanoVG::FontId NanoVG::findFont(const char* name)
@@ -795,7 +831,7 @@ float NanoVG::textBounds(float x, float y, const char* string, const char* end,
return ret;
}

void NanoVG::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[4])
{
if (fContext == nullptr) return;
DISTRHO_SAFE_ASSERT_RETURN(string != nullptr && string[0] != '\0',);
@@ -803,12 +839,12 @@ void NanoVG::textBoxBounds(float x, float y, float breakRowWidth, const char* st
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)
int NanoVG::textGlyphPositions(float x, float y, const char* string, const char* end, NanoVG::GlyphPosition& positions, int maxPositions)
{
if (fContext == nullptr) return 0;
DISTRHO_SAFE_ASSERT_RETURN(string != nullptr && string[0] != '\0', 0);

return nvgTextGlyphPositions(fContext, x, y, string, end, (NVGglyphPosition*)positions, maxPositions);
return nvgTextGlyphPositions(fContext, x, y, string, end, (NVGglyphPosition*)&positions, maxPositions);
}

void NanoVG::textMetrics(float* ascender, float* descender, float* lineh)
@@ -817,10 +853,10 @@ 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)
int NanoVG::textBreakLines(const char* string, const char* end, float breakRowWidth, NanoVG::TextRow& rows, int maxRows)
{
if (fContext != nullptr)
return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)rows, maxRows);
return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)&rows, maxRows);
return 0;
}



Loading…
Cancel
Save