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 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: public:
/**
Constructor for an invalid/null image.
*/
NanoImage();

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

/** /**
Destructor. Destructor.
*/ */
~NanoImage(); ~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. Get size.
*/ */
@@ -57,16 +91,8 @@ public:
*/ */
void updateImage(const uchar* const data); 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: private:
NVGcontext* fContext;
int fImageId;
Handle fHandle;
Size<uint> fSize; Size<uint> fSize;
friend class NanoVG; friend class NanoVG;


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


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


@@ -519,30 +546,50 @@ public:
/** /**
Creates image by loading it from the disk from specified file name. 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. 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. 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. 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 */ * 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. (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(). 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 */ * Scissoring */
@@ -688,13 +735,13 @@ public:
Creates font by loading it from the disk from specified file name. Creates font by loading it from the disk from specified file name.
Returns handle to the font. 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. Creates font by loading it from the specified memory chunk.
Returns handle to the font. 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. 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] 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. 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. 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. 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. 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. 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). 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: private:
NVGcontext* const fContext; NVGcontext* const fContext;
@@ -811,10 +858,11 @@ class NanoWidget : public Widget,
public: public:
/** /**
Constructor. Constructor.
@see CreateFlags
*/ */
NanoWidget(Window& parent)
NanoWidget(Window& parent, int flags = CREATE_ANTIALIAS)
: Widget(parent), : Widget(parent),
NanoVG(),
NanoVG(flags),
leakDetector_NanoWidget() leakDetector_NanoWidget()
{ {
setNeedsScaling(true); setNeedsScaling(true);
@@ -834,12 +882,9 @@ private:
*/ */
void onDisplay() override void onDisplay() override
{ {
//glPushAttrib(GL_PIXEL_MODE_BIT|GL_STENCIL_BUFFER_BIT|GL_ENABLE_BIT);
beginFrame(getWidth(), getHeight()); beginFrame(getWidth(), getHeight());
onNanoDisplay(); onNanoDisplay();
endFrame(); endFrame();
//glPopAttrib();
glDisable(GL_CULL_FACE);
} }


DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NanoWidget) 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::NanoImage(NVGcontext* const context, const int imageId) noexcept
: fContext(context),
fImageId(imageId),
NanoImage::NanoImage()
: fHandle(),
fSize(), fSize(),
leakDetector_NanoImage() leakDetector_NanoImage()
{ {
}

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

_updateSize(); _updateSize();
} }


NanoImage::~NanoImage() 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 Size<uint> NanoImage::getSize() const noexcept
@@ -132,31 +156,28 @@ Size<uint> NanoImage::getSize() const noexcept


GLuint NanoImage::getTextureHandle() const 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) void NanoImage::updateImage(const uchar* const data)
{ {
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr,); 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() void NanoImage::_updateSize()
{ {
int w=0, h=0; 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)); fSize.setSize(static_cast<uint>(w), static_cast<uint>(h));
} }
@@ -488,52 +509,65 @@ float NanoVG::radToDeg(float rad)
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Images // 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) if (! deleteTexture)
imageFlags |= NVG_IMAGE_NODELETE; 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); 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(); 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 // 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; if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -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); 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; if (fContext == nullptr) return -1;
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1); DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', -1);
DISTRHO_SAFE_ASSERT_RETURN(data != nullptr, -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) 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; 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; if (fContext == nullptr) return;
DISTRHO_SAFE_ASSERT_RETURN(string != nullptr && string[0] != '\0',); 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); 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; if (fContext == nullptr) return 0;
DISTRHO_SAFE_ASSERT_RETURN(string != nullptr && string[0] != '\0', 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) 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); 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) if (fContext != nullptr)
return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)rows, maxRows);
return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)&rows, maxRows);
return 0; return 0;
} }




Loading…
Cancel
Save