Browse Source

Update everything

Signed-off-by: falkTX <falktx@falktx.com>
tags/v1.5
falkTX 3 years ago
parent
commit
e5b0edb9db
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
24 changed files with 1250 additions and 1965 deletions
  1. +18
    -8
      dpf/Makefile.plugins.mk
  2. +6
    -0
      dpf/dgl/Makefile
  3. +1
    -0
      dpf/dgl/NanoVG.hpp
  4. +2
    -2
      dpf/dgl/Window.hpp
  5. +29
    -0
      dpf/dgl/src/NanoVG.cpp
  6. +1
    -1
      dpf/dgl/src/Window.cpp
  7. +4
    -0
      dpf/dgl/src/WindowPrivateData.cpp
  8. +185
    -114
      dpf/dgl/src/nanovg/nanovg.c
  9. +8
    -4
      dpf/dgl/src/nanovg/nanovg.h
  10. +75
    -28
      dpf/dgl/src/nanovg/nanovg_gl.h
  11. +725
    -1767
      dpf/dgl/src/nanovg/stb_image.h
  12. +1
    -0
      dpf/dgl/src/pugl-upstream/bindings/cpp/include/.clang-tidy
  13. +4
    -0
      dpf/dgl/src/pugl-upstream/examples/.clang-tidy
  14. +1
    -0
      dpf/dgl/src/pugl-upstream/include/.clang-tidy
  15. +2
    -0
      dpf/dgl/src/pugl-upstream/src/.clang-tidy
  16. +1
    -4
      dpf/dgl/src/pugl-upstream/src/mac.m
  17. +2
    -3
      dpf/dgl/src/pugl-upstream/src/x11.c
  18. +4
    -1
      dpf/dgl/src/pugl-upstream/src/x11_gl.c
  19. +3
    -0
      dpf/dgl/src/pugl-upstream/test/.clang-tidy
  20. +28
    -9
      dpf/distrho/extra/ExternalWindow.hpp
  21. +29
    -0
      dpf/distrho/src/DistrhoPluginVST3.cpp
  22. +36
    -2
      dpf/distrho/src/DistrhoUIInternal.hpp
  23. +6
    -0
      dpf/distrho/src/DistrhoUIPrivateData.hpp
  24. +79
    -22
      dpf/distrho/src/DistrhoUIVST3.cpp

+ 18
- 8
dpf/Makefile.plugins.mk View File

@@ -238,26 +238,36 @@ all:
# --------------------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------------------
# Common # Common


$(BUILD_DIR)/%.S.o: %.S
$(BUILD_DIR)/%.S.o: %.S $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<" @echo "Compiling $<"
@$(CC) $< $(BUILD_C_FLAGS) -c -o $@ @$(CC) $< $(BUILD_C_FLAGS) -c -o $@


$(BUILD_DIR)/%.c.o: %.c
$(BUILD_DIR)/%.c.o: %.c $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<" @echo "Compiling $<"
$(SILENT)$(CC) $< $(BUILD_C_FLAGS) -c -o $@ $(SILENT)$(CC) $< $(BUILD_C_FLAGS) -c -o $@


$(BUILD_DIR)/%.cc.o: %.cc
$(BUILD_DIR)/%.cc.o: %.cc $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<" @echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@


$(BUILD_DIR)/%.cpp.o: %.cpp
$(BUILD_DIR)/%.cpp.o: %.cpp $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)" -@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<" @echo "Compiling $<"
$(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ $(SILENT)$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@


$(BUILD_DIR)/%.m.o: %.m $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<"
$(SILENT)$(CC) $< $(BUILD_C_FLAGS) -ObjC -c -o $@

$(BUILD_DIR)/%.mm.o: %.mm $(EXTRA_LIBS)
-@mkdir -p "$(shell dirname $(BUILD_DIR)/$<)"
@echo "Compiling $<"
$(SILENT)$(CC) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@

clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2 rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2
@@ -312,7 +322,7 @@ $(BUILD_DIR)/DistrhoUIMain_DSSI.cpp.o: $(DPF_PATH)/distrho/DistrhoUIMain.cpp
jack: $(jack) jack: $(jack)


ifeq ($(HAVE_DGL),true) ifeq ($(HAVE_DGL),true)
$(jack): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o $(BUILD_DIR)/DistrhoUIMain_JACK.cpp.o $(DGL_LIB)
$(jack): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o $(BUILD_DIR)/DistrhoUIMain_JACK.cpp.o $(DGL_LIB) $(EXTRA_LIBS)
else else
$(jack): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o $(jack): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_JACK.cpp.o
endif endif
@@ -355,7 +365,7 @@ lv2_dsp: $(lv2_dsp)
lv2_sep: $(lv2_dsp) $(lv2_ui) lv2_sep: $(lv2_dsp) $(lv2_ui)


ifeq ($(HAVE_DGL),true) ifeq ($(HAVE_DGL),true)
$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB) $(EXTRA_LIBS)
else else
$(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o $(lv2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_LV2.cpp.o
endif endif
@@ -379,7 +389,7 @@ $(lv2_ui): $(OBJS_UI) $(BUILD_DIR)/DistrhoUIMain_LV2.cpp.o $(DGL_LIB)
vst2 vst: $(vst2) vst2 vst: $(vst2)


ifeq ($(HAVE_DGL),true) ifeq ($(HAVE_DGL),true)
$(vst2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST2.cpp.o $(DGL_LIB)
$(vst2): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST2.cpp.o $(DGL_LIB) $(EXTRA_LIBS)
else else
$(vst2): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o $(vst2): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST2.cpp.o
endif endif
@@ -393,7 +403,7 @@ endif
vst3: $(vst3) vst3: $(vst3)


ifeq ($(HAVE_DGL),true) ifeq ($(HAVE_DGL),true)
$(vst3): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST3.cpp.o $(DGL_LIB)
$(vst3): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.o $(BUILD_DIR)/DistrhoUIMain_VST3.cpp.o $(DGL_LIB) $(EXTRA_LIBS)
else else
$(vst3): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.o $(vst3): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.o
endif endif


+ 6
- 0
dpf/dgl/Makefile View File

@@ -16,6 +16,12 @@ LINK_FLAGS += $(DGL_LIBS)
ifeq ($(USE_OPENGL3),true) ifeq ($(USE_OPENGL3),true)
BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3
endif endif
ifeq ($(USE_NANOVG_FBO),true)
BUILD_CXX_FLAGS += -DDGL_USE_NANOVG_FBO
endif
ifeq ($(USE_RGBA),true)
BUILD_CXX_FLAGS += -DDGL_USE_RGBA
endif


# TODO fix these after pugl-upstream is done # TODO fix these after pugl-upstream is done
BUILD_CXX_FLAGS += -Wno-attributes -Wno-extra -Wno-missing-field-initializers BUILD_CXX_FLAGS += -Wno-attributes -Wno-extra -Wno-missing-field-initializers


+ 1
- 0
dpf/dgl/NanoVG.hpp View File

@@ -943,6 +943,7 @@ private:
inline void onDisplay() override inline void onDisplay() override
{ {
// NOTE maybe should use BaseWidget::getWindow().getScaleFactor() as 3rd arg ? // NOTE maybe should use BaseWidget::getWindow().getScaleFactor() as 3rd arg ?
NanoVG::reset();
NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight()); NanoVG::beginFrame(BaseWidget::getWidth(), BaseWidget::getHeight());
onNanoDisplay(); onNanoDisplay();
NanoVG::endFrame(); NanoVG::endFrame();


+ 2
- 2
dpf/dgl/Window.hpp View File

@@ -397,10 +397,10 @@ public:
void runAsModal(bool blockWait = false); void runAsModal(bool blockWait = false);


/** /**
Get the size constraint set for the Window.
Get the geometry constraints set for the Window.
@see setGeometryConstraints @see setGeometryConstraints
*/ */
Size<uint> getMinimumSizeConstraint(bool& keepAspectRatio);
Size<uint> getGeometryConstraints(bool& keepAspectRatio);


/** /**
Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically. Set geometry constraints for the Window when resized by the user, and optionally scale contents automatically.


+ 29
- 0
dpf/dgl/src/NanoVG.cpp View File

@@ -54,6 +54,18 @@ DGL_EXT(PFNGLUNIFORM4FVPROC, glUniform4fv)
DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram) DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram)
DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer)
DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate)
# ifdef DGL_USE_NANOVG_FBO
DGL_EXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer)
DGL_EXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
DGL_EXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus)
DGL_EXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers)
DGL_EXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers)
DGL_EXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D)
DGL_EXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
DGL_EXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers)
DGL_EXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
DGL_EXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
# endif
# ifdef DGL_USE_OPENGL3 # ifdef DGL_USE_OPENGL3
DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange) DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange)
DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
@@ -84,6 +96,11 @@ DGL_EXT(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding)


#include "nanovg/nanovg_gl.h" #include "nanovg/nanovg_gl.h"


#ifdef DGL_USE_NANOVG_FBO
# define NANOVG_FBO_VALID 1
# include "nanovg/nanovg_gl_utils.h"
#endif

#if defined(NANOVG_GL2) #if defined(NANOVG_GL2)
# define nvgCreateGL nvgCreateGL2 # define nvgCreateGL nvgCreateGL2
# define nvgDeleteGL nvgDeleteGL2 # define nvgDeleteGL nvgDeleteGL2
@@ -145,6 +162,18 @@ DGL_EXT(PFNGLUNIFORM4FVPROC, glUniform4fv)
DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram) DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram)
DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer)
DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate)
# ifdef DGL_USE_NANOVG_FBO
DGL_EXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer)
DGL_EXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer)
DGL_EXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus)
DGL_EXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers)
DGL_EXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers)
DGL_EXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D)
DGL_EXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer)
DGL_EXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers)
DGL_EXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers)
DGL_EXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage)
# endif
# ifdef DGL_USE_OPENGL3 # ifdef DGL_USE_OPENGL3
DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange) DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange)
DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)


+ 1
- 1
dpf/dgl/src/Window.cpp View File

@@ -346,7 +346,7 @@ void Window::runAsModal(bool blockWait)
pData->runAsModal(blockWait); pData->runAsModal(blockWait);
} }


Size<uint> Window::getMinimumSizeConstraint(bool& keepAspectRatio)
Size<uint> Window::getGeometryConstraints(bool& keepAspectRatio)
{ {
keepAspectRatio = pData->keepAspectRatio; keepAspectRatio = pData->keepAspectRatio;
return Size<uint>(pData->minWidth, pData->minHeight); return Size<uint>(pData->minWidth, pData->minHeight);


+ 4
- 0
dpf/dgl/src/WindowPrivateData.cpp View File

@@ -249,7 +249,11 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo
puglSetHandle(view, this); puglSetHandle(view, this);
puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE); puglSetViewHint(view, PUGL_RESIZABLE, resizable ? PUGL_TRUE : PUGL_FALSE);
puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE);
#if DGL_USE_RGBA
puglSetViewHint(view, PUGL_DEPTH_BITS, 24);
#else
puglSetViewHint(view, PUGL_DEPTH_BITS, 16); puglSetViewHint(view, PUGL_DEPTH_BITS, 16);
#endif
puglSetViewHint(view, PUGL_STENCIL_BITS, 8); puglSetViewHint(view, PUGL_STENCIL_BITS, 8);
#ifdef DGL_USE_OPENGL3 #ifdef DGL_USE_OPENGL3
puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_FALSE); puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_FALSE);


+ 185
- 114
dpf/dgl/src/nanovg/nanovg.c View File

@@ -24,8 +24,11 @@
#include "nanovg.h" #include "nanovg.h"
#define FONTSTASH_IMPLEMENTATION #define FONTSTASH_IMPLEMENTATION
#include "fontstash.h" #include "fontstash.h"

#ifndef NVG_NO_STB
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
#endif


#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable: 4100) // unreferenced formal parameter #pragma warning(disable: 4100) // unreferenced formal parameter
@@ -74,7 +77,7 @@ struct NVGstate {
float miterLimit; float miterLimit;
int lineJoin; int lineJoin;
int lineCap; int lineCap;
float alpha;
NVGcolor tint;
float xform[6]; float xform[6];
NVGscissor scissor; NVGscissor scissor;
float fontSize; float fontSize;
@@ -109,6 +112,14 @@ struct NVGpathCache {
}; };
typedef struct NVGpathCache NVGpathCache; typedef struct NVGpathCache NVGpathCache;


struct NVGfontContext { // Fontstash context plus font images; shared between shared NanoVG contexts.
int refCount;
struct FONScontext* fs;
int fontImages[NVG_MAX_FONTIMAGES];
int fontImageIdx;
};
typedef struct NVGfontContext NVGfontContext;

struct NVGcontext { struct NVGcontext {
NVGparams params; NVGparams params;
float* commands; float* commands;
@@ -122,9 +133,7 @@ struct NVGcontext {
float distTol; float distTol;
float fringeWidth; float fringeWidth;
float devicePxRatio; float devicePxRatio;
struct FONScontext* fs;
int fontImages[NVG_MAX_FONTIMAGES];
int fontImageIdx;
NVGfontContext* fontContext;
int drawCallCount; int drawCallCount;
int fillTriCount; int fillTriCount;
int strokeTriCount; int strokeTriCount;
@@ -283,7 +292,7 @@ static NVGstate* nvg__getState(NVGcontext* ctx)
return &ctx->states[ctx->nstates-1]; return &ctx->states[ctx->nstates-1];
} }


NVGcontext* nvgCreateInternal(NVGparams* params)
NVGcontext* nvgCreateInternal(NVGparams* params, NVGcontext* other) // Share the fonts and images of 'other' if it's non-NULL.
{ {
FONSparams fontParams; FONSparams fontParams;
NVGcontext* ctx = (NVGcontext*)malloc(sizeof(NVGcontext)); NVGcontext* ctx = (NVGcontext*)malloc(sizeof(NVGcontext));
@@ -292,8 +301,16 @@ NVGcontext* nvgCreateInternal(NVGparams* params)
memset(ctx, 0, sizeof(NVGcontext)); memset(ctx, 0, sizeof(NVGcontext));


ctx->params = *params; ctx->params = *params;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;
if (other) {
ctx->fontContext = other->fontContext;
ctx->fontContext->refCount++;
} else {
ctx->fontContext = (NVGfontContext*)malloc(sizeof(NVGfontContext));
if (ctx->fontContext == NULL) goto error;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontContext->fontImages[i] = 0;
ctx->fontContext->refCount = 1;
}


ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_COMMANDS_SIZE); ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_COMMANDS_SIZE);
if (!ctx->commands) goto error; if (!ctx->commands) goto error;
@@ -308,25 +325,27 @@ NVGcontext* nvgCreateInternal(NVGparams* params)


nvg__setDevicePixelRatio(ctx, 1.0f); nvg__setDevicePixelRatio(ctx, 1.0f);


if (ctx->params.renderCreate(ctx->params.userPtr) == 0) goto error;
if (ctx->params.renderCreate(ctx->params.userPtr, other ? other->params.userPtr : NULL) == 0) goto error;


// Init font rendering // Init font rendering
memset(&fontParams, 0, sizeof(fontParams));
fontParams.width = NVG_INIT_FONTIMAGE_SIZE;
fontParams.height = NVG_INIT_FONTIMAGE_SIZE;
fontParams.flags = FONS_ZERO_TOPLEFT;
fontParams.renderCreate = NULL;
fontParams.renderUpdate = NULL;
fontParams.renderDraw = NULL;
fontParams.renderDelete = NULL;
fontParams.userPtr = NULL;
ctx->fs = fonsCreateInternal(&fontParams);
if (ctx->fs == NULL) goto error;

// Create font texture
ctx->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, 0, NULL);
if (ctx->fontImages[0] == 0) goto error;
ctx->fontImageIdx = 0;
if (!other) {
memset(&fontParams, 0, sizeof(fontParams));
fontParams.width = NVG_INIT_FONTIMAGE_SIZE;
fontParams.height = NVG_INIT_FONTIMAGE_SIZE;
fontParams.flags = FONS_ZERO_TOPLEFT;
fontParams.renderCreate = NULL;
fontParams.renderUpdate = NULL;
fontParams.renderDraw = NULL;
fontParams.renderDelete = NULL;
fontParams.userPtr = NULL;
ctx->fontContext->fs = fonsCreateInternal(&fontParams);
if (ctx->fontContext->fs == NULL) goto error;

// Create font texture
ctx->fontContext->fontImages[0] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, 0, NULL);
if (ctx->fontContext->fontImages[0] == 0) goto error;
ctx->fontContext->fontImageIdx = 0;
}


return ctx; return ctx;


@@ -347,14 +366,18 @@ void nvgDeleteInternal(NVGcontext* ctx)
if (ctx->commands != NULL) free(ctx->commands); if (ctx->commands != NULL) free(ctx->commands);
if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache); if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache);


if (ctx->fs)
fonsDeleteInternal(ctx->fs);
if (ctx->fontContext != NULL && --ctx->fontContext->refCount == 0) {
if (ctx->fontContext->fs)
fonsDeleteInternal(ctx->fontContext->fs);


for (i = 0; i < NVG_MAX_FONTIMAGES; i++) {
if (ctx->fontImages[i] != 0) {
nvgDeleteImage(ctx, ctx->fontImages[i]);
ctx->fontImages[i] = 0;
for (i = 0; i < NVG_MAX_FONTIMAGES; i++) {
if (ctx->fontContext->fontImages[i] != 0) {
nvgDeleteImage(ctx, ctx->fontContext->fontImages[i]);
ctx->fontContext->fontImages[i] = 0;
}
} }

free(ctx->fontContext);
} }


if (ctx->params.renderDelete != NULL) if (ctx->params.renderDelete != NULL)
@@ -391,30 +414,30 @@ void nvgCancelFrame(NVGcontext* ctx)
void nvgEndFrame(NVGcontext* ctx) void nvgEndFrame(NVGcontext* ctx)
{ {
ctx->params.renderFlush(ctx->params.userPtr); ctx->params.renderFlush(ctx->params.userPtr);
if (ctx->fontImageIdx != 0) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
if (ctx->fontContext->fontImageIdx != 0) {
int fontImage = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];
int i, j, iw, ih; int i, j, iw, ih;
// delete images that smaller than current one // delete images that smaller than current one
if (fontImage == 0) if (fontImage == 0)
return; return;
nvgImageSize(ctx, fontImage, &iw, &ih); nvgImageSize(ctx, fontImage, &iw, &ih);
for (i = j = 0; i < ctx->fontImageIdx; i++) {
if (ctx->fontImages[i] != 0) {
for (i = j = 0; i < ctx->fontContext->fontImageIdx; i++) {
if (ctx->fontContext->fontImages[i] != 0) {
int nw, nh; int nw, nh;
nvgImageSize(ctx, ctx->fontImages[i], &nw, &nh);
nvgImageSize(ctx, ctx->fontContext->fontImages[i], &nw, &nh);
if (nw < iw || nh < ih) if (nw < iw || nh < ih)
nvgDeleteImage(ctx, ctx->fontImages[i]);
nvgDeleteImage(ctx, ctx->fontContext->fontImages[i]);
else else
ctx->fontImages[j++] = ctx->fontImages[i];
ctx->fontContext->fontImages[j++] = ctx->fontContext->fontImages[i];
} }
} }
// make current font image to first // make current font image to first
ctx->fontImages[j++] = ctx->fontImages[0];
ctx->fontImages[0] = fontImage;
ctx->fontImageIdx = 0;
ctx->fontContext->fontImages[j++] = ctx->fontContext->fontImages[0];
ctx->fontContext->fontImages[0] = fontImage;
ctx->fontContext->fontImageIdx = 0;
// clear all images after j // clear all images after j
for (i = j; i < NVG_MAX_FONTIMAGES; i++) for (i = j; i < NVG_MAX_FONTIMAGES; i++)
ctx->fontImages[i] = 0;
ctx->fontContext->fontImages[i] = 0;
} }
} }


@@ -651,7 +674,7 @@ void nvgReset(NVGcontext* ctx)
state->miterLimit = 10.0f; state->miterLimit = 10.0f;
state->lineCap = NVG_BUTT; state->lineCap = NVG_BUTT;
state->lineJoin = NVG_MITER; state->lineJoin = NVG_MITER;
state->alpha = 1.0f;
state->tint = nvgRGBAf(1, 1, 1, 1);
nvgTransformIdentity(state->xform); nvgTransformIdentity(state->xform);


state->scissor.extent[0] = -1.0f; state->scissor.extent[0] = -1.0f;
@@ -699,7 +722,33 @@ void nvgLineJoin(NVGcontext* ctx, int join)
void nvgGlobalAlpha(NVGcontext* ctx, float alpha) void nvgGlobalAlpha(NVGcontext* ctx, float alpha)
{ {
NVGstate* state = nvg__getState(ctx); NVGstate* state = nvg__getState(ctx);
state->alpha = alpha;
state->tint.a = alpha;
}

void nvgGlobalTint(NVGcontext* ctx, NVGcolor tint)
{
NVGstate* state = nvg__getState(ctx);
state->tint = tint;
}

NVGcolor nvgGetGlobalTint(NVGcontext* ctx)
{
NVGstate* state = nvg__getState(ctx);
return state->tint;
}

void nvgAlpha(NVGcontext* ctx, float alpha)
{
NVGstate* state = nvg__getState(ctx);
state->tint.a *= alpha;
}

void nvgTint(NVGcontext* ctx, NVGcolor tint)
{
NVGstate* state = nvg__getState(ctx);
int i;
for (i = 0; i < 4; i++)
state->tint.rgba[i] *= tint.rgba[i];
} }


void nvgTransform(NVGcontext* ctx, float a, float b, float c, float d, float e, float f) void nvgTransform(NVGcontext* ctx, float a, float b, float c, float d, float e, float f)
@@ -788,6 +837,7 @@ void nvgFillPaint(NVGcontext* ctx, NVGpaint paint)
nvgTransformMultiply(state->fill.xform, state->xform); nvgTransformMultiply(state->fill.xform, state->xform);
} }


#ifndef NVG_NO_STB
int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags) int nvgCreateImage(NVGcontext* ctx, const char* filename, int imageFlags)
{ {
int w, h, n, image; int w, h, n, image;
@@ -816,6 +866,7 @@ int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int
stbi_image_free(img); stbi_image_free(img);
return image; return image;
} }
#endif


int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data) int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data)
{ {
@@ -2234,9 +2285,11 @@ void nvgFill(NVGcontext* ctx)
else else
nvg__expandFill(ctx, 0.0f, NVG_MITER, 2.4f); nvg__expandFill(ctx, 0.0f, NVG_MITER, 2.4f);


// Apply global alpha
fillPaint.innerColor.a *= state->alpha;
fillPaint.outerColor.a *= state->alpha;
// Apply global tint
for (i = 0; i < 4; i++) {
fillPaint.innerColor.rgba[i] *= state->tint.rgba[i];
fillPaint.outerColor.rgba[i] *= state->tint.rgba[i];
}


ctx->params.renderFill(ctx->params.userPtr, &fillPaint, state->compositeOperation, &state->scissor, ctx->fringeWidth, ctx->params.renderFill(ctx->params.userPtr, &fillPaint, state->compositeOperation, &state->scissor, ctx->fringeWidth,
ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths);
@@ -2269,9 +2322,11 @@ void nvgStroke(NVGcontext* ctx)
strokeWidth = ctx->fringeWidth; strokeWidth = ctx->fringeWidth;
} }


// Apply global alpha
strokePaint.innerColor.a *= state->alpha;
strokePaint.outerColor.a *= state->alpha;
// Apply global tint
for (i = 0; i < 4; i++) {
strokePaint.innerColor.rgba[i] *= state->tint.rgba[i];
strokePaint.outerColor.rgba[i] *= state->tint.rgba[i];
}


nvg__flattenPaths(ctx); nvg__flattenPaths(ctx);


@@ -2294,35 +2349,35 @@ void nvgStroke(NVGcontext* ctx)
// Add fonts // Add fonts
int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename) int nvgCreateFont(NVGcontext* ctx, const char* name, const char* filename)
{ {
return fonsAddFont(ctx->fs, name, filename, 0);
return fonsAddFont(ctx->fontContext->fs, name, filename, 0);
} }


int nvgCreateFontAtIndex(NVGcontext* ctx, const char* name, const char* filename, const int fontIndex) int nvgCreateFontAtIndex(NVGcontext* ctx, const char* name, const char* filename, const int fontIndex)
{ {
return fonsAddFont(ctx->fs, name, filename, fontIndex);
return fonsAddFont(ctx->fontContext->fs, name, filename, fontIndex);
} }


int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData) int nvgCreateFontMem(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData)
{ {
return fonsAddFontMem(ctx->fs, name, data, ndata, freeData, 0);
return fonsAddFontMem(ctx->fontContext->fs, name, data, ndata, freeData, 0);
} }


int nvgCreateFontMemAtIndex(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData, const int fontIndex) int nvgCreateFontMemAtIndex(NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData, const int fontIndex)
{ {
return fonsAddFontMem(ctx->fs, name, data, ndata, freeData, fontIndex);
return fonsAddFontMem(ctx->fontContext->fs, name, data, ndata, freeData, fontIndex);
} }


int nvgFindFont(NVGcontext* ctx, const char* name) int nvgFindFont(NVGcontext* ctx, const char* name)
{ {
if (name == NULL) return -1; if (name == NULL) return -1;
return fonsGetFontByName(ctx->fs, name);
return fonsGetFontByName(ctx->fontContext->fs, name);
} }




int nvgAddFallbackFontId(NVGcontext* ctx, int baseFont, int fallbackFont) int nvgAddFallbackFontId(NVGcontext* ctx, int baseFont, int fallbackFont)
{ {
if(baseFont == -1 || fallbackFont == -1) return 0; if(baseFont == -1 || fallbackFont == -1) return 0;
return fonsAddFallbackFont(ctx->fs, baseFont, fallbackFont);
return fonsAddFallbackFont(ctx->fontContext->fs, baseFont, fallbackFont);
} }


int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallbackFont) int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallbackFont)
@@ -2332,7 +2387,7 @@ int nvgAddFallbackFont(NVGcontext* ctx, const char* baseFont, const char* fallba


void nvgResetFallbackFontsId(NVGcontext* ctx, int baseFont) void nvgResetFallbackFontsId(NVGcontext* ctx, int baseFont)
{ {
fonsResetFallbackFont(ctx->fs, baseFont);
fonsResetFallbackFont(ctx->fontContext->fs, baseFont);
} }


void nvgResetFallbackFonts(NVGcontext* ctx, const char* baseFont) void nvgResetFallbackFonts(NVGcontext* ctx, const char* baseFont)
@@ -2380,7 +2435,7 @@ void nvgFontFaceId(NVGcontext* ctx, int font)
void nvgFontFace(NVGcontext* ctx, const char* font) void nvgFontFace(NVGcontext* ctx, const char* font)
{ {
NVGstate* state = nvg__getState(ctx); NVGstate* state = nvg__getState(ctx);
state->fontId = fonsGetFontByName(ctx->fs, font);
state->fontId = fonsGetFontByName(ctx->fontContext->fs, font);
} }


static float nvg__quantize(float a, float d) static float nvg__quantize(float a, float d)
@@ -2397,12 +2452,12 @@ static void nvg__flushTextTexture(NVGcontext* ctx)
{ {
int dirty[4]; int dirty[4];


if (fonsValidateTexture(ctx->fs, dirty)) {
int fontImage = ctx->fontImages[ctx->fontImageIdx];
if (fonsValidateTexture(ctx->fontContext->fs, dirty)) {
int fontImage = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];
// Update texture // Update texture
if (fontImage != 0) { if (fontImage != 0) {
int iw, ih; int iw, ih;
const unsigned char* data = fonsGetTextureData(ctx->fs, &iw, &ih);
const unsigned char* data = fonsGetTextureData(ctx->fontContext->fs, &iw, &ih);
int x = dirty[0]; int x = dirty[0];
int y = dirty[1]; int y = dirty[1];
int w = dirty[2] - dirty[0]; int w = dirty[2] - dirty[0];
@@ -2416,37 +2471,40 @@ static int nvg__allocTextAtlas(NVGcontext* ctx)
{ {
int iw, ih; int iw, ih;
nvg__flushTextTexture(ctx); nvg__flushTextTexture(ctx);
if (ctx->fontImageIdx >= NVG_MAX_FONTIMAGES-1)
if (ctx->fontContext->fontImageIdx >= NVG_MAX_FONTIMAGES-1)
return 0; return 0;
// if next fontImage already have a texture // if next fontImage already have a texture
if (ctx->fontImages[ctx->fontImageIdx+1] != 0)
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx+1], &iw, &ih);
if (ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1] != 0)
nvgImageSize(ctx, ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1], &iw, &ih);
else { // calculate the new font image size and create it. else { // calculate the new font image size and create it.
nvgImageSize(ctx, ctx->fontImages[ctx->fontImageIdx], &iw, &ih);
nvgImageSize(ctx, ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx], &iw, &ih);
if (iw > ih) if (iw > ih)
ih *= 2; ih *= 2;
else else
iw *= 2; iw *= 2;
if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE) if (iw > NVG_MAX_FONTIMAGE_SIZE || ih > NVG_MAX_FONTIMAGE_SIZE)
iw = ih = NVG_MAX_FONTIMAGE_SIZE; iw = ih = NVG_MAX_FONTIMAGE_SIZE;
ctx->fontImages[ctx->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, 0, NULL);
ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx+1] = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, iw, ih, 0, NULL);
} }
++ctx->fontImageIdx;
fonsResetAtlas(ctx->fs, iw, ih);
++ctx->fontContext->fontImageIdx;
fonsResetAtlas(ctx->fontContext->fs, iw, ih);
return 1; return 1;
} }


static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts) static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
{ {
int i;
NVGstate* state = nvg__getState(ctx); NVGstate* state = nvg__getState(ctx);
NVGpaint paint = state->fill; NVGpaint paint = state->fill;


// Render triangles. // Render triangles.
paint.image = ctx->fontImages[ctx->fontImageIdx];
paint.image = ctx->fontContext->fontImages[ctx->fontContext->fontImageIdx];


// Apply global alpha
paint.innerColor.a *= state->alpha;
paint.outerColor.a *= state->alpha;
// Apply global tint
for (i = 0; i < 4; i++) {
paint.innerColor.rgba[i] *= state->tint.rgba[i];
paint.outerColor.rgba[i] *= state->tint.rgba[i];
}


ctx->params.renderTriangles(ctx->params.userPtr, &paint, state->compositeOperation, &state->scissor, verts, nverts, ctx->fringeWidth); ctx->params.renderTriangles(ctx->params.userPtr, &paint, state->compositeOperation, &state->scissor, verts, nverts, ctx->fringeWidth);


@@ -2454,6 +2512,12 @@ static void nvg__renderText(NVGcontext* ctx, NVGvertex* verts, int nverts)
ctx->textTriCount += nverts/3; ctx->textTriCount += nverts/3;
} }


static int nvg__isTransformFlipped(const float *xform)
{
float det = xform[0] * xform[3] - xform[2] * xform[1];
return( det < 0);
}

float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char* end) float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char* end)
{ {
NVGstate* state = nvg__getState(ctx); NVGstate* state = nvg__getState(ctx);
@@ -2464,25 +2528,26 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char*
float invscale = 1.0f / scale; float invscale = 1.0f / scale;
int cverts = 0; int cverts = 0;
int nverts = 0; int nverts = 0;
int isFlipped = nvg__isTransformFlipped(state->xform);


if (end == NULL) if (end == NULL)
end = string + strlen(string); end = string + strlen(string);


if (state->fontId == FONS_INVALID) return x; if (state->fontId == FONS_INVALID) return x;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);


cverts = nvg__maxi(2, (int)(end - string)) * 6; // conservative estimate. cverts = nvg__maxi(2, (int)(end - string)) * 6; // conservative estimate.
verts = nvg__allocTempVerts(ctx, cverts); verts = nvg__allocTempVerts(ctx, cverts);
if (verts == NULL) return x; if (verts == NULL) return x;


fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_REQUIRED);
fonsTextIterInit(ctx->fontContext->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_REQUIRED);
prevIter = iter; prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
float c[4*2]; float c[4*2];
if (iter.prevGlyphIndex == -1) { // can not retrieve glyph? if (iter.prevGlyphIndex == -1) { // can not retrieve glyph?
if (nverts != 0) { if (nverts != 0) {
@@ -2492,11 +2557,17 @@ float nvgText(NVGcontext* ctx, float x, float y, const char* string, const char*
if (!nvg__allocTextAtlas(ctx)) if (!nvg__allocTextAtlas(ctx))
break; // no memory :( break; // no memory :(
iter = prevIter; iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
if (iter.prevGlyphIndex == -1) // still can not find glyph? if (iter.prevGlyphIndex == -1) // still can not find glyph?
break; break;
} }
prevIter = iter; prevIter = iter;
if(isFlipped) {
float tmp;

tmp = q.y0; q.y0 = q.y1; q.y1 = tmp;
tmp = q.t0; q.t0 = q.t1; q.t1 = tmp;
}
// Transform corners. // Transform corners.
nvgTransformPoint(&c[0],&c[1], state->xform, q.x0*invscale, q.y0*invscale); nvgTransformPoint(&c[0],&c[1], state->xform, q.x0*invscale, q.y0*invscale);
nvgTransformPoint(&c[2],&c[3], state->xform, q.x1*invscale, q.y0*invscale); nvgTransformPoint(&c[2],&c[3], state->xform, q.x1*invscale, q.y0*invscale);
@@ -2571,18 +2642,18 @@ int nvgTextGlyphPositions(NVGcontext* ctx, float x, float y, const char* string,
if (string == end) if (string == end)
return 0; return 0;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);


fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
fonsTextIterInit(ctx->fontContext->fs, &iter, x*scale, y*scale, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
prevIter = iter; prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph? if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter; iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
} }
prevIter = iter; prevIter = iter;
positions[npos].str = iter.str; positions[npos].str = iter.str;
@@ -2635,20 +2706,20 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa


if (string == end) return 0; if (string == end) return 0;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);


breakRowWidth *= scale; breakRowWidth *= scale;


fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
fonsTextIterInit(ctx->fontContext->fs, &iter, 0, 0, string, end, FONS_GLYPH_BITMAP_OPTIONAL);
prevIter = iter; prevIter = iter;
while (fonsTextIterNext(ctx->fs, &iter, &q)) {
while (fonsTextIterNext(ctx->fontContext->fs, &iter, &q)) {
if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph? if (iter.prevGlyphIndex < 0 && nvg__allocTextAtlas(ctx)) { // can not retrieve glyph?
iter = prevIter; iter = prevIter;
fonsTextIterNext(ctx->fs, &iter, &q); // try again
fonsTextIterNext(ctx->fontContext->fs, &iter, &q); // try again
} }
prevIter = iter; prevIter = iter;
switch (iter.codepoint) { switch (iter.codepoint) {
@@ -2819,16 +2890,16 @@ float nvgTextBounds(NVGcontext* ctx, float x, float y, const char* string, const


if (state->fontId == FONS_INVALID) return 0; if (state->fontId == FONS_INVALID) return 0;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);


width = fonsTextBounds(ctx->fs, x*scale, y*scale, string, end, bounds);
width = fonsTextBounds(ctx->fontContext->fs, x*scale, y*scale, string, end, bounds);
if (bounds != NULL) { if (bounds != NULL) {
// Use line bounds for height. // Use line bounds for height.
fonsLineBounds(ctx->fs, y*scale, &bounds[1], &bounds[3]);
fonsLineBounds(ctx->fontContext->fs, y*scale, &bounds[1], &bounds[3]);
bounds[0] *= invscale; bounds[0] *= invscale;
bounds[1] *= invscale; bounds[1] *= invscale;
bounds[2] *= invscale; bounds[2] *= invscale;
@@ -2863,12 +2934,12 @@ void nvgTextBoxBounds(NVGcontext* ctx, float x, float y, float breakRowWidth, co
minx = maxx = x; minx = maxx = x;
miny = maxy = y; miny = maxy = y;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsLineBounds(ctx->fs, 0, &rminy, &rmaxy);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);
fonsLineBounds(ctx->fontContext->fs, 0, &rminy, &rmaxy);
rminy *= invscale; rminy *= invscale;
rmaxy *= invscale; rmaxy *= invscale;


@@ -2914,13 +2985,13 @@ void nvgTextMetrics(NVGcontext* ctx, float* ascender, float* descender, float* l


if (state->fontId == FONS_INVALID) return; if (state->fontId == FONS_INVALID) return;


fonsSetSize(ctx->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fs, state->textAlign);
fonsSetFont(ctx->fs, state->fontId);
fonsSetSize(ctx->fontContext->fs, state->fontSize*scale);
fonsSetSpacing(ctx->fontContext->fs, state->letterSpacing*scale);
fonsSetBlur(ctx->fontContext->fs, state->fontBlur*scale);
fonsSetAlign(ctx->fontContext->fs, state->textAlign);
fonsSetFont(ctx->fontContext->fs, state->fontId);


fonsVertMetrics(ctx->fs, ascender, descender, lineh);
fonsVertMetrics(ctx->fontContext->fs, ascender, descender, lineh);
if (ascender != NULL) if (ascender != NULL)
*ascender *= invscale; *ascender *= invscale;
if (descender != NULL) if (descender != NULL)


+ 8
- 4
dpf/dgl/src/nanovg/nanovg.h View File

@@ -279,6 +279,10 @@ void nvgLineJoin(NVGcontext* ctx, int join);
// Sets the transparency applied to all rendered shapes. // Sets the transparency applied to all rendered shapes.
// Already transparent paths will get proportionally more transparent as well. // Already transparent paths will get proportionally more transparent as well.
void nvgGlobalAlpha(NVGcontext* ctx, float alpha); void nvgGlobalAlpha(NVGcontext* ctx, float alpha);
void nvgGlobalTint(NVGcontext* ctx, NVGcolor tint);
NVGcolor nvgGetGlobalTint(NVGcontext* ctx);
void nvgAlpha(NVGcontext* ctx, float alpha);
void nvgTint(NVGcontext* ctx, NVGcolor tint);


// //
// Transforms // Transforms
@@ -385,7 +389,7 @@ int nvgCreateImageMem(NVGcontext* ctx, int imageFlags, unsigned char* data, int


// Creates image from specified image data and texture format. // Creates image from specified image data and texture format.
// Returns handle to the image. // Returns handle to the image.
int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, NVGtexture format, const unsigned char* data);
int nvgCreateImageRaw(NVGcontext* ctx, int w, int h, int imageFlags, enum NVGtexture format, const unsigned char* data);


// Creates image from specified image data. // Creates image from specified image data.
// Returns handle to the image. // Returns handle to the image.
@@ -426,7 +430,7 @@ NVGpaint nvgBoxGradient(NVGcontext* ctx, float x, float y, float w, float h,
NVGpaint nvgRadialGradient(NVGcontext* ctx, float cx, float cy, float inr, float outr, NVGpaint nvgRadialGradient(NVGcontext* ctx, float cx, float cy, float inr, float outr,
NVGcolor icol, NVGcolor ocol); NVGcolor icol, NVGcolor 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. // (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 nvgFillPaint() or nvgStrokePaint(). // The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint().
NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey, NVGpaint nvgImagePattern(NVGcontext* ctx, float ox, float oy, float ex, float ey,
@@ -667,7 +671,7 @@ typedef struct NVGpath NVGpath;
struct NVGparams { struct NVGparams {
void* userPtr; void* userPtr;
int edgeAntiAlias; int edgeAntiAlias;
int (*renderCreate)(void* uptr);
int (*renderCreate)(void* uptr, void* otherUptr);
int (*renderCreateTexture)(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data); int (*renderCreateTexture)(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);
int (*renderDeleteTexture)(void* uptr, int image); int (*renderDeleteTexture)(void* uptr, int image);
int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data);
@@ -683,7 +687,7 @@ struct NVGparams {
typedef struct NVGparams NVGparams; typedef struct NVGparams NVGparams;


// Constructor and destructor, called by the render back-end. // Constructor and destructor, called by the render back-end.
NVGcontext* nvgCreateInternal(NVGparams* params);
NVGcontext* nvgCreateInternal(NVGparams* params, NVGcontext* other);
void nvgDeleteInternal(NVGcontext* ctx); void nvgDeleteInternal(NVGcontext* ctx);


NVGparams* nvgInternalParams(NVGcontext* ctx); NVGparams* nvgInternalParams(NVGcontext* ctx);


+ 75
- 28
dpf/dgl/src/nanovg/nanovg_gl.h View File

@@ -40,9 +40,7 @@ enum NVGcreateFlags {
#elif defined NANOVG_GL3_IMPLEMENTATION #elif defined NANOVG_GL3_IMPLEMENTATION
# define NANOVG_GL3 1 # define NANOVG_GL3 1
# define NANOVG_GL_IMPLEMENTATION 1 # define NANOVG_GL_IMPLEMENTATION 1
# ifndef __APPLE__
# define NANOVG_GL_USE_UNIFORMBUFFER 1
# endif
# define NANOVG_GL_USE_UNIFORMBUFFER 1
#elif defined NANOVG_GLES2_IMPLEMENTATION #elif defined NANOVG_GLES2_IMPLEMENTATION
# define NANOVG_GLES2 1 # define NANOVG_GLES2 1
# define NANOVG_GL_IMPLEMENTATION 1 # define NANOVG_GL_IMPLEMENTATION 1
@@ -59,6 +57,7 @@ enum NVGcreateFlags {
#if defined NANOVG_GL2 #if defined NANOVG_GL2


NVGcontext* nvgCreateGL2(int flags); NVGcontext* nvgCreateGL2(int flags);
NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags);
void nvgDeleteGL2(NVGcontext* ctx); void nvgDeleteGL2(NVGcontext* ctx);


int nvglCreateImageFromHandleGL2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags); int nvglCreateImageFromHandleGL2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -69,6 +68,7 @@ GLuint nvglImageHandleGL2(NVGcontext* ctx, int image);
#if defined NANOVG_GL3 #if defined NANOVG_GL3


NVGcontext* nvgCreateGL3(int flags); NVGcontext* nvgCreateGL3(int flags);
NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags);
void nvgDeleteGL3(NVGcontext* ctx); void nvgDeleteGL3(NVGcontext* ctx);


int nvglCreateImageFromHandleGL3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags); int nvglCreateImageFromHandleGL3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -79,6 +79,7 @@ GLuint nvglImageHandleGL3(NVGcontext* ctx, int image);
#if defined NANOVG_GLES2 #if defined NANOVG_GLES2


NVGcontext* nvgCreateGLES2(int flags); NVGcontext* nvgCreateGLES2(int flags);
NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags);
void nvgDeleteGLES2(NVGcontext* ctx); void nvgDeleteGLES2(NVGcontext* ctx);


int nvglCreateImageFromHandleGLES2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags); int nvglCreateImageFromHandleGLES2(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -89,6 +90,7 @@ GLuint nvglImageHandleGLES2(NVGcontext* ctx, int image);
#if defined NANOVG_GLES3 #if defined NANOVG_GLES3


NVGcontext* nvgCreateGLES3(int flags); NVGcontext* nvgCreateGLES3(int flags);
NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags);
void nvgDeleteGLES3(NVGcontext* ctx); void nvgDeleteGLES3(NVGcontext* ctx);


int nvglCreateImageFromHandleGLES3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags); int nvglCreateImageFromHandleGLES3(NVGcontext* ctx, GLuint textureId, int w, int h, int flags);
@@ -230,9 +232,18 @@ struct GLNVGfragUniforms {
}; };
typedef struct GLNVGfragUniforms GLNVGfragUniforms; typedef struct GLNVGfragUniforms GLNVGfragUniforms;


struct GLNVGtextureContext { // Textures; shared between shared NanoVG contexts.
int refCount;
GLNVGtexture* textures;
int ntextures;
int ctextures;
int textureId;
};
typedef struct GLNVGtextureContext GLNVGtextureContext;

struct GLNVGcontext { struct GLNVGcontext {
GLNVGshader shader; GLNVGshader shader;
GLNVGtexture* textures;
GLNVGtextureContext* textureContext;
float view[2]; float view[2];
int ntextures; int ntextures;
int ctextures; int ctextures;
@@ -352,26 +363,26 @@ static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
GLNVGtexture* tex = NULL; GLNVGtexture* tex = NULL;
int i; int i;


for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].id == 0) {
tex = &gl->textures[i];
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].id == 0) {
tex = &gl->textureContext->textures[i];
break; break;
} }
} }
if (tex == NULL) { if (tex == NULL) {
if (gl->ntextures+1 > gl->ctextures) {
if (gl->textureContext->ntextures+1 > gl->textureContext->ctextures) {
GLNVGtexture* textures; GLNVGtexture* textures;
int ctextures = glnvg__maxi(gl->ntextures+1, 4) + gl->ctextures/2; // 1.5x Overallocate
textures = (GLNVGtexture*)realloc(gl->textures, sizeof(GLNVGtexture)*ctextures);
int ctextures = glnvg__maxi(gl->textureContext->ntextures+1, 4) + gl->textureContext->ctextures/2; // 1.5x Overallocate
textures = (GLNVGtexture*)realloc(gl->textureContext->textures, sizeof(GLNVGtexture)*ctextures);
if (textures == NULL) return NULL; if (textures == NULL) return NULL;
gl->textures = textures;
gl->ctextures = ctextures;
gl->textureContext->textures = textures;
gl->textureContext->ctextures = ctextures;
} }
tex = &gl->textures[gl->ntextures++];
tex = &gl->textureContext->textures[gl->textureContext->ntextures++];
} }


memset(tex, 0, sizeof(*tex)); memset(tex, 0, sizeof(*tex));
tex->id = ++gl->textureId;
tex->id = ++gl->textureContext->textureId;


return tex; return tex;
} }
@@ -379,20 +390,20 @@ static GLNVGtexture* glnvg__allocTexture(GLNVGcontext* gl)
static GLNVGtexture* glnvg__findTexture(GLNVGcontext* gl, int id) static GLNVGtexture* glnvg__findTexture(GLNVGcontext* gl, int id)
{ {
int i; int i;
for (i = 0; i < gl->ntextures; i++)
if (gl->textures[i].id == id)
return &gl->textures[i];
for (i = 0; i < gl->textureContext->ntextures; i++)
if (gl->textureContext->textures[i].id == id)
return &gl->textureContext->textures[i];
return NULL; return NULL;
} }


static int glnvg__deleteTexture(GLNVGcontext* gl, int id) static int glnvg__deleteTexture(GLNVGcontext* gl, int id)
{ {
int i; int i;
for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].id == id) {
if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textures[i].tex);
memset(&gl->textures[i], 0, sizeof(gl->textures[i]));
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].id == id) {
if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textureContext->textures[i].tex);
memset(&gl->textureContext->textures[i], 0, sizeof(gl->textureContext->textures[i]));
return 1; return 1;
} }
} }
@@ -506,9 +517,20 @@ static void glnvg__getUniforms(GLNVGshader* shader)


static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data); static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data);


static int glnvg__renderCreate(void* uptr)
static int glnvg__renderCreate(void* uptr, void* otherUptr) // Share the textures of GLNVGcontext 'otherUptr' if it's non-NULL.
{ {
GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGcontext* gl = (GLNVGcontext*)uptr;

if (otherUptr) {
GLNVGcontext* other = (GLNVGcontext*)otherUptr;
gl->textureContext = other->textureContext;
gl->textureContext->refCount++;
} else {
gl->textureContext = (GLNVGtextureContext*)malloc(sizeof(GLNVGtextureContext));
memset(gl->textureContext, 0, sizeof(GLNVGtextureContext));
gl->textureContext->refCount = 1;
}

int align = 4; int align = 4;


// TODO: mediump float may not be enough for GLES2 in iOS. // TODO: mediump float may not be enough for GLES2 in iOS.
@@ -1605,11 +1627,14 @@ static void glnvg__renderDelete(void* uptr)
if (gl->vertBuf != 0) if (gl->vertBuf != 0)
glDeleteBuffers(1, &gl->vertBuf); glDeleteBuffers(1, &gl->vertBuf);


for (i = 0; i < gl->ntextures; i++) {
if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textures[i].tex);
if (gl->textureContext != NULL && --gl->textureContext->refCount == 0) {
for (i = 0; i < gl->textureContext->ntextures; i++) {
if (gl->textureContext->textures[i].tex != 0 && (gl->textureContext->textures[i].flags & NVG_IMAGE_NODELETE) == 0)
glDeleteTextures(1, &gl->textureContext->textures[i].tex);
}
free(gl->textureContext->textures);
free(gl->textureContext);
} }
free(gl->textures);


free(gl->paths); free(gl->paths);
free(gl->verts); free(gl->verts);
@@ -1629,6 +1654,28 @@ NVGcontext* nvgCreateGLES2(int flags)
#elif defined NANOVG_GLES3 #elif defined NANOVG_GLES3
NVGcontext* nvgCreateGLES3(int flags) NVGcontext* nvgCreateGLES3(int flags)
#endif #endif
{
#if defined NANOVG_GL2
return nvgCreateSharedGL2(NULL, flags);
#elif defined NANOVG_GL3
return nvgCreateSharedGL3(NULL, flags);
#elif defined NANOVG_GLES2
return nvgCreateSharedGLES2(NULL, flags);
#elif defined NANOVG_GLES3
return nvgCreateSharedGLES3(NULL, flags);
#endif
}

// Share the fonts and textures of 'other' if it's non-NULL.
#if defined NANOVG_GL2
NVGcontext* nvgCreateSharedGL2(NVGcontext* other, int flags)
#elif defined NANOVG_GL3
NVGcontext* nvgCreateSharedGL3(NVGcontext* other, int flags)
#elif defined NANOVG_GLES2
NVGcontext* nvgCreateSharedGLES2(NVGcontext* other, int flags)
#elif defined NANOVG_GLES3
NVGcontext* nvgCreateSharedGLES3(NVGcontext* other, int flags)
#endif
{ {
NVGparams params; NVGparams params;
NVGcontext* ctx = NULL; NVGcontext* ctx = NULL;
@@ -1654,7 +1701,7 @@ NVGcontext* nvgCreateGLES3(int flags)


gl->flags = flags; gl->flags = flags;


ctx = nvgCreateInternal(&params);
ctx = nvgCreateInternal(&params, other);
if (ctx == NULL) goto error; if (ctx == NULL) goto error;


return ctx; return ctx;


+ 725
- 1767
dpf/dgl/src/nanovg/stb_image.h
File diff suppressed because it is too large
View File


+ 1
- 0
dpf/dgl/src/pugl-upstream/bindings/cpp/include/.clang-tidy View File

@@ -1,6 +1,7 @@
Checks: > Checks: >
*, *,
-*-uppercase-literal-suffix, -*-uppercase-literal-suffix,
-altera-struct-pack-align,
-clang-diagnostic-unused-macros, -clang-diagnostic-unused-macros,
-cppcoreguidelines-pro-bounds-pointer-arithmetic, -cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-reinterpret-cast, -cppcoreguidelines-pro-type-reinterpret-cast,


+ 4
- 0
dpf/dgl/src/pugl-upstream/examples/.clang-tidy View File

@@ -4,6 +4,7 @@ Checks: >
-*avoid-c-arrays, -*avoid-c-arrays,
-*magic-numbers, -*magic-numbers,
-*uppercase-literal-suffix, -*uppercase-literal-suffix,
-altera-struct-pack-align,
-android-cloexec-fopen, -android-cloexec-fopen,
-bugprone-macro-parentheses, -bugprone-macro-parentheses,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
@@ -13,6 +14,7 @@ Checks: >
-cert-flp30-c, -cert-flp30-c,
-clang-analyzer-alpha.*, -clang-analyzer-alpha.*,
-clang-analyzer-security.FloatLoopCounter, -clang-analyzer-security.FloatLoopCounter,
-concurrency-mt-unsafe,
-cppcoreguidelines-avoid-non-const-global-variables, -cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-macro-usage, -cppcoreguidelines-macro-usage,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
@@ -33,6 +35,8 @@ Checks: >
-llvmlibc-*, -llvmlibc-*,
-misc-misplaced-const, -misc-misplaced-const,
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-performance-no-int-to-ptr,
-readability-function-cognitive-complexity,
-readability-implicit-bool-conversion, -readability-implicit-bool-conversion,
-readability-named-parameter, -readability-named-parameter,
FormatStyle: file FormatStyle: file


+ 1
- 0
dpf/dgl/src/pugl-upstream/include/.clang-tidy View File

@@ -2,6 +2,7 @@ Checks: >
*, *,
-*-magic-numbers, -*-magic-numbers,
-*-uppercase-literal-suffix, -*-uppercase-literal-suffix,
-altera-struct-pack-align,
-clang-diagnostic-unused-function, -clang-diagnostic-unused-function,
-clang-diagnostic-unused-macros, -clang-diagnostic-unused-macros,
-llvmlibc-*, -llvmlibc-*,


+ 2
- 0
dpf/dgl/src/pugl-upstream/src/.clang-tidy View File

@@ -2,6 +2,7 @@ Checks: >
*, *,
-*-uppercase-literal-suffix, -*-uppercase-literal-suffix,
-*magic-numbers, -*magic-numbers,
-altera-struct-pack-align,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
-cert-dcl37-c, -cert-dcl37-c,
-cert-dcl51-cpp, -cert-dcl51-cpp,
@@ -10,5 +11,6 @@ Checks: >
-hicpp-signed-bitwise, -hicpp-signed-bitwise,
-llvm-header-guard, -llvm-header-guard,
-llvmlibc-*, -llvmlibc-*,
-readability-function-cognitive-complexity,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: 'pugl/.*' HeaderFilterRegex: 'pugl/.*'

+ 1
- 4
dpf/dgl/src/pugl-upstream/src/mac.m View File

@@ -29,12 +29,9 @@


#include <stdlib.h> #include <stdlib.h>


#ifndef __MAC_10_9
typedef NSUInteger NSEventSubtype;
#endif

#ifndef __MAC_10_10 #ifndef __MAC_10_10
typedef NSUInteger NSEventModifierFlags; typedef NSUInteger NSEventModifierFlags;
typedef NSUInteger NSEventSubtype;
#endif #endif


#ifndef __MAC_10_12 #ifndef __MAC_10_12


+ 2
- 3
dpf/dgl/src/pugl-upstream/src/x11.c View File

@@ -366,9 +366,8 @@ puglRealize(PuglView* const view)
} }


#ifdef HAVE_XRANDR #ifdef HAVE_XRANDR
int ignored;
if (XRRQueryExtension(display, &ignored, &ignored))
{
int ignored = 0;
if (XRRQueryExtension(display, &ignored, &ignored)) {
// Set refresh rate hint to the real refresh rate // Set refresh rate hint to the real refresh rate
XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent); XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent);
short current_rate = XRRConfigCurrentRate(conf); short current_rate = XRRConfigCurrentRate(conf);


+ 4
- 1
dpf/dgl/src/pugl-upstream/src/x11_gl.c View File

@@ -63,6 +63,9 @@ puglX11GlConfigure(PuglView* view)


// clang-format off // clang-format off
const int attrs[] = { const int attrs[] = {
#ifdef DGL_USE_RGBA
GLX_RGBA,
#endif
GLX_X_RENDERABLE, True, GLX_X_RENDERABLE, True,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
@@ -149,7 +152,7 @@ puglX11GlCreate(PuglView* view)


GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_PROFILE_MASK_ARB,
(view->hints[PUGL_USE_COMPAT_PROFILE] (view->hints[PUGL_USE_COMPAT_PROFILE]
? GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
: GLX_CONTEXT_CORE_PROFILE_BIT_ARB), : GLX_CONTEXT_CORE_PROFILE_BIT_ARB),
0}; 0};




+ 3
- 0
dpf/dgl/src/pugl-upstream/test/.clang-tidy View File

@@ -2,7 +2,9 @@ Checks: >
*, *,
-*-magic-numbers, -*-magic-numbers,
-*-uppercase-literal-suffix, -*-uppercase-literal-suffix,
-altera-struct-pack-align,
-bugprone-reserved-identifier, -bugprone-reserved-identifier,
-bugprone-suspicious-include,
-cert-dcl37-c, -cert-dcl37-c,
-cert-dcl51-cpp, -cert-dcl51-cpp,
-google-runtime-references, -google-runtime-references,
@@ -11,5 +13,6 @@ Checks: >
-llvm-header-guard, -llvm-header-guard,
-llvmlibc-*, -llvmlibc-*,
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-readability-function-cognitive-complexity,
FormatStyle: file FormatStyle: file
HeaderFilterRegex: 'pugl/.*|test/.*' HeaderFilterRegex: 'pugl/.*|test/.*'

+ 28
- 9
dpf/distrho/extra/ExternalWindow.hpp View File

@@ -295,7 +295,8 @@ public:
*/ */
void setSize(uint width, uint height) void setSize(uint width, uint height)
{ {
DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,);
DISTRHO_SAFE_ASSERT_UINT_RETURN(width > 1, width,);
DISTRHO_SAFE_ASSERT_UINT_RETURN(height > 1, height,);


if (pData.width == width && pData.height == height) if (pData.width == width && pData.height == height)
return; return;
@@ -314,10 +315,24 @@ public:
{ {
if (pData.title == title) if (pData.title == title)
return; return;

pData.title = title; pData.title = title;
titleChanged(title); titleChanged(title);
} }


/**
Set geometry constraints for the Window when resized by the user.
*/
void setGeometryConstraints(uint minimumWidth, uint minimumHeight, bool keepAspectRatio = false)
{
DISTRHO_SAFE_ASSERT_UINT_RETURN(minimumWidth > 0, minimumWidth,);
DISTRHO_SAFE_ASSERT_UINT_RETURN(minimumHeight > 0, minimumHeight,);

pData.minWidth = minimumWidth;
pData.minHeight = minimumHeight;
pData.keepAspectRatio = keepAspectRatio;
}

/* -------------------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------------------
* TopLevelWidget-like calls - actions called by the host */ * TopLevelWidget-like calls - actions called by the host */


@@ -339,6 +354,7 @@ public:
{ {
if (pData.visible == visible) if (pData.visible == visible)
return; return;

pData.visible = visible; pData.visible = visible;
visibilityChanged(visible); visibilityChanged(visible);
} }
@@ -351,6 +367,7 @@ public:
{ {
if (pData.transientWinId == winId) if (pData.transientWinId == winId)
return; return;

pData.transientWinId = winId; pData.transientWinId = winId;
transientParentWindowChanged(winId); transientParentWindowChanged(winId);
} }
@@ -388,39 +405,35 @@ protected:
A callback for when the window size changes. A callback for when the window size changes.
@note WIP this might need to get fed back into the host somehow. @note WIP this might need to get fed back into the host somehow.
*/ */
virtual void sizeChanged(uint width, uint height)
virtual void sizeChanged(uint /* width */, uint /* height */)
{ {
// unused, meant for custom implementations // unused, meant for custom implementations
return; (void)width; (void)height;
} }


/** /**
A callback for when the window title changes. A callback for when the window title changes.
@note WIP this might need to get fed back into the host somehow. @note WIP this might need to get fed back into the host somehow.
*/ */
virtual void titleChanged(const char* title)
virtual void titleChanged(const char* /* title */)
{ {
// unused, meant for custom implementations // unused, meant for custom implementations
return; (void)title;
} }


/** /**
A callback for when the window visibility changes. A callback for when the window visibility changes.
@note WIP this might need to get fed back into the host somehow. @note WIP this might need to get fed back into the host somehow.
*/ */
virtual void visibilityChanged(bool visible)
virtual void visibilityChanged(bool /* visible */)
{ {
// unused, meant for custom implementations // unused, meant for custom implementations
return; (void)visible;
} }


/** /**
A callback for when the transient parent window changes. A callback for when the transient parent window changes.
*/ */
virtual void transientParentWindowChanged(uintptr_t winId)
virtual void transientParentWindowChanged(uintptr_t /* winId */)
{ {
// unused, meant for custom implementations // unused, meant for custom implementations
return; (void)winId;
} }


private: private:
@@ -533,6 +546,9 @@ private:
uint height; uint height;
double scaleFactor; double scaleFactor;
String title; String title;
uint minWidth;
uint minHeight;
bool keepAspectRatio;
bool isQuitting; bool isQuitting;
bool isStandalone; bool isStandalone;
bool visible; bool visible;
@@ -544,6 +560,9 @@ private:
height(1), height(1),
scaleFactor(1.0), scaleFactor(1.0),
title(), title(),
minWidth(0),
minHeight(0),
keepAspectRatio(false),
isQuitting(false), isQuitting(false),
isStandalone(false), isStandalone(false),
visible(false) {} visible(false) {}


+ 29
- 0
dpf/distrho/src/DistrhoPluginVST3.cpp View File

@@ -757,6 +757,10 @@ public:
{ {
res = v3_cpp_obj(stream)->read(stream, buffer, sizeof(buffer)-1, &read); res = v3_cpp_obj(stream)->read(stream, buffer, sizeof(buffer)-1, &read);
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res); DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res);

if (read == 0)
return V3_OK;

DISTRHO_SAFE_ASSERT_INT_RETURN(read > 0, read, V3_INTERNAL_ERR); DISTRHO_SAFE_ASSERT_INT_RETURN(read > 0, read, V3_INTERNAL_ERR);


for (int32_t i = 0; i < read; ++i) for (int32_t i = 0; i < read; ++i)
@@ -2501,6 +2505,9 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
hostContextFromComponent(hc), hostContextFromComponent(hc),
hostContextFromInitialize(nullptr) hostContextFromInitialize(nullptr)
{ {
d_stdout("dpf_edit_controller() has contexts %p %p",
hostContextFromFactory, hostContextFromComponent);

// make sure context is valid through this controller lifetime // make sure context is valid through this controller lifetime
if (hostContextFromComponent != nullptr) if (hostContextFromComponent != nullptr)
v3_cpp_obj_ref(hostContextFromComponent); v3_cpp_obj_ref(hostContextFromComponent);
@@ -2537,6 +2544,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
v3_cpp_obj_unref(hostContextFromComponent); v3_cpp_obj_unref(hostContextFromComponent);
hostContextFromComponent = nullptr; hostContextFromComponent = nullptr;
} }

d_stdout("dpf_edit_controller::cleanup() has contexts %p %p",
hostContextFromFactory, hostContextFromComponent);

} }


// ---------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
@@ -2594,6 +2605,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {


static uint32_t V3_API ref_edit_controller(void* self) static uint32_t V3_API ref_edit_controller(void* self)
{ {
d_stdout("dpf_edit_controller::ref => %p", self);
return ++(*(dpf_edit_controller**)self)->refcounter; return ++(*(dpf_edit_controller**)self)->refcounter;
} }


@@ -2608,6 +2620,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
return refcount; return refcount;
} }


d_stdout("dpf_edit_controller::unref => %p is zero, doing cleanup", self);
controller->cleanup(); controller->cleanup();
return 0; return 0;
} }
@@ -2628,6 +2641,8 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
v3_host_application** host = nullptr; v3_host_application** host = nullptr;
v3_cpp_obj_query_interface(context, v3_host_application_iid, &host); v3_cpp_obj_query_interface(context, v3_host_application_iid, &host);


d_stdout("dpf_edit_controller::initialize => %p %p | host %p", self, context, host);

// save it for later so we can unref it // save it for later so we can unref it
controller->hostContextFromInitialize = host; controller->hostContextFromInitialize = host;


@@ -2831,11 +2846,20 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
dpf_edit_controller* const controller = *(dpf_edit_controller**)self; dpf_edit_controller* const controller = *(dpf_edit_controller**)self;
DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, nullptr); DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, nullptr);


d_stdout("create_view has contexts %p %p",
controller->hostContextFromFactory, controller->hostContextFromComponent);

#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
// plugin must be initialized // plugin must be initialized
PluginVst3* const vst3 = controller->vst3; PluginVst3* const vst3 = controller->vst3;
DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, nullptr); DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, nullptr);


d_stdout("dpf_edit_controller::create_view => %p %s | edit-ctrl %p, host %p, factory %p",
self, name,
controller->hostContextFromInitialize,
controller->hostContextFromComponent,
controller->hostContextFromFactory);

// we require a host context for message creation // we require a host context for message creation
v3_host_application** host = controller->hostContextFromInitialize != nullptr v3_host_application** host = controller->hostContextFromInitialize != nullptr
? controller->hostContextFromInitialize ? controller->hostContextFromInitialize
@@ -3238,6 +3262,9 @@ struct dpf_component : v3_component_cpp {


if (v3_tuid_match(iid, v3_edit_controller_iid)) if (v3_tuid_match(iid, v3_edit_controller_iid))
{ {
d_stdout("query_interface_component called with contexts %p %p",
component->hostContextFromFactory, component->hostContextFromInitialize);

if (component->controller == nullptr) if (component->controller == nullptr)
component->controller = new dpf_edit_controller(component->vst3, component->controller = new dpf_edit_controller(component->vst3,
component->hostContextFromFactory, component->hostContextFromFactory,
@@ -3352,6 +3379,8 @@ struct dpf_component : v3_component_cpp {
if (context != nullptr) if (context != nullptr)
v3_cpp_obj_query_interface(context, v3_host_application_iid, &host); v3_cpp_obj_query_interface(context, v3_host_application_iid, &host);


d_stdout("dpf_component::initialize => %p %p | host %p", self, context, host);

// save it for later so we can unref it // save it for later so we can unref it
component->hostContextFromInitialize = host; component->hostContextFromInitialize = host;




+ 36
- 2
dpf/distrho/src/DistrhoUIInternal.hpp View File

@@ -132,9 +132,16 @@ public:
return uiData->window->getScaleFactor(); return uiData->window->getScaleFactor();
} }


Size<uint> getMinimumSizeConstraint(bool& keepAspectRatio)
bool getGeometryConstraints(uint& minimumWidth, uint& minimumHeight, bool& keepAspectRatio) const noexcept
{ {
return uiData->window->getMinimumSizeConstraint(keepAspectRatio);
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
uiData->window->getGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio);
#else
const DGL_NAMESPACE::Size<uint> size(uiData->window->getGeometryConstraints(keepAspectRatio));
minimumWidth = size.getWidth();
minimumHeight = size.getHeight();
#endif
return true;
} }


bool isResizable() const noexcept bool isResizable() const noexcept
@@ -269,12 +276,16 @@ public:


// ------------------------------------------------------------------- // -------------------------------------------------------------------


#ifdef DISTRHO_PLUGIN_TARGET_VST3
void setWindowSizeForVST3(const uint width, const uint height) void setWindowSizeForVST3(const uint width, const uint height)
{ {
ui->setSize(width, height); ui->setSize(width, height);
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
uiData->window->setSize(width, height); uiData->window->setSize(width, height);
// uiData->app.idle(); // uiData->app.idle();
# endif
} }
#endif


void setWindowTitle(const char* const uiTitle) void setWindowTitle(const char* const uiTitle)
{ {
@@ -320,6 +331,29 @@ public:
ui->onCharacterInput(cev); ui->onCharacterInput(cev);
return ret; return ret;
} }

bool handlePluginKeyboardVST3(const bool press, const uint keychar, const uint keycode, const uint16_t mods)
{
DGL_NAMESPACE::Widget::KeyboardEvent ev;
ev.mod = mods;
ev.press = press;
ev.key = keychar;
ev.keycode = keycode;

const bool ret = ui->onKeyboard(ev);

DGL_NAMESPACE::Widget::CharacterInputEvent cev;
cev.mod = mods;
cev.keycode = keycode;
cev.character = keychar;

// if shift modifier is on, convert a-z -> A-Z for character input
if (keychar >= 'a' && keychar <= 'z' && (mods & DGL_NAMESPACE::kModifierShift) != 0)
cev.character -= 'a' - 'A';

ui->onCharacterInput(cev);
return ret;
}
#endif #endif


// ------------------------------------------------------------------- // -------------------------------------------------------------------


+ 6
- 0
dpf/distrho/src/DistrhoUIPrivateData.hpp View File

@@ -152,6 +152,12 @@ public:
void setTitle(const char* const title) { ui->setTitle(title); } void setTitle(const char* const title) { ui->setTitle(title); }
void setVisible(const bool visible) { ui->setVisible(visible); } void setVisible(const bool visible) { ui->setVisible(visible); }
uintptr_t getNativeWindowHandle() const noexcept { return ui->getNativeWindowHandle(); } uintptr_t getNativeWindowHandle() const noexcept { return ui->getNativeWindowHandle(); }
void getGeometryConstraints(uint& minimumWidth, uint& minimumHeight, bool& keepAspectRatio) const noexcept
{
minimumWidth = ui->pData.minWidth;
minimumHeight = ui->pData.minHeight;
keepAspectRatio = ui->pData.keepAspectRatio;
}


DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow) DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow)
}; };


+ 79
- 22
dpf/distrho/src/DistrhoUIVST3.cpp View File

@@ -75,10 +75,11 @@ struct ScopedUTF16String {


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------


static bool checkSizeConstraint(const Size<uint>& size, const bool keepAspectRatio, v3_view_rect* const rect)
static bool applyGeometryConstraints(const uint minimumWidth, const uint minimumHeight, const bool keepAspectRatio,
v3_view_rect* const rect)
{ {
const int32_t minWidth = static_cast<int32_t>(size.getWidth());
const int32_t minHeight = static_cast<int32_t>(size.getHeight());
const int32_t minWidth = static_cast<int32_t>(minimumWidth);
const int32_t minHeight = static_cast<int32_t>(minimumHeight);
bool changed = false; bool changed = false;


if (keepAspectRatio) if (keepAspectRatio)
@@ -92,10 +93,10 @@ static bool checkSizeConstraint(const Size<uint>& size, const bool keepAspectRat


// fix width // fix width
if (reqRatio > ratio) if (reqRatio > ratio)
rect->right = static_cast<uint>(rect->bottom * ratio + 0.5);
rect->right = static_cast<int32_t>(rect->bottom * ratio + 0.5);
// fix height // fix height
else else
rect->bottom = static_cast<uint>(static_cast<double>(rect->right) / ratio + 0.5);
rect->bottom = static_cast<int32_t>(static_cast<double>(rect->right) / ratio + 0.5);
} }
} }


@@ -168,10 +169,10 @@ public:
disconnect(); disconnect();
} }


void postInit(const Size<uint>& requestedSize)
void postInit(const int32_t nextWidth, const int32_t nextHeight)
{ {
if (fIsResizingFromHost && requestedSize.isValid())
fUI.setWindowSizeForVST3(requestedSize.getWidth(), requestedSize.getHeight());
if (fIsResizingFromHost && nextWidth > 0 && nextHeight > 0)
fUI.setWindowSizeForVST3(nextWidth, nextHeight);


if (fConnection != nullptr) if (fConnection != nullptr)
connect(fConnection); connect(fConnection);
@@ -190,16 +191,66 @@ public:
return V3_NOT_IMPLEMENTED; return V3_NOT_IMPLEMENTED;
} }


v3_result onKeyDown(int16_t /*key_char*/, int16_t /*key_code*/, int16_t /*modifiers*/)
v3_result onKeyDown(const int16_t keychar, const int16_t keycode, const int16_t modifiers)
{ {
d_stdout("onKeyDown %i %i %x\n", keychar, keycode, modifiers);
DISTRHO_SAFE_ASSERT_INT_RETURN(keychar >= 0 && keychar < 0x7f, keychar, V3_FALSE);

using namespace DGL_NAMESPACE;

// TODO // TODO
return V3_NOT_IMPLEMENTED;
uint dglcode = 0;

// TODO verify these
uint dglmods = 0;
if (modifiers & (1 << 0))
dglmods |= kModifierShift;
if (modifiers & (1 << 1))
dglmods |= kModifierAlt;
#ifdef DISTRHO_OS_MAC
if (modifiers & (1 << 2))
dglmods |= kModifierSuper;
if (modifiers & (1 << 3))
dglmods |= kModifierControl;
#else
if (modifiers & (1 << 2))
dglmods |= kModifierControl;
if (modifiers & (1 << 3))
dglmods |= kModifierSuper;
#endif

return fUI.handlePluginKeyboardVST3(true, static_cast<uint>(keychar), dglcode, dglmods) ? V3_TRUE : V3_FALSE;
} }


v3_result onKeyUp(int16_t /*key_char*/, int16_t /*key_code*/, int16_t /*modifiers*/)
v3_result onKeyUp(const int16_t keychar, const int16_t keycode, const int16_t modifiers)
{ {
d_stdout("onKeyDown %i %i %x\n", keychar, keycode, modifiers);
DISTRHO_SAFE_ASSERT_INT_RETURN(keychar >= 0 && keychar < 0x7f, keychar, V3_FALSE);

using namespace DGL_NAMESPACE;

// TODO // TODO
return V3_NOT_IMPLEMENTED;
uint dglcode = 0;

// TODO verify these
uint dglmods = 0;
if (modifiers & (1 << 0))
dglmods |= kModifierShift;
if (modifiers & (1 << 1))
dglmods |= kModifierAlt;
#ifdef DISTRHO_OS_MAC
if (modifiers & (1 << 2))
dglmods |= kModifierSuper;
if (modifiers & (1 << 3))
dglmods |= kModifierControl;
#else
if (modifiers & (1 << 2))
dglmods |= kModifierControl;
if (modifiers & (1 << 3))
dglmods |= kModifierSuper;
#endif

return fUI.handlePluginKeyboardVST3(false, static_cast<uint>(keychar), dglcode, dglmods) ? V3_TRUE : V3_FALSE;
} }


v3_result getSize(v3_view_rect* const rect) const noexcept v3_result getSize(v3_view_rect* const rect) const noexcept
@@ -255,9 +306,10 @@ public:


v3_result checkSizeConstraint(v3_view_rect* const rect) v3_result checkSizeConstraint(v3_view_rect* const rect)
{ {
uint minimumWidth, minimumHeight;
bool keepAspectRatio; bool keepAspectRatio;
const Size<uint> size(fUI.getMinimumSizeConstraint(keepAspectRatio));
return ::checkSizeConstraint(size, keepAspectRatio, rect) ? V3_FALSE : V3_TRUE;
fUI.getGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio);
return applyGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, rect) ? V3_FALSE : V3_TRUE;
} }


// ---------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
@@ -919,14 +971,16 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
void* const instancePointer; void* const instancePointer;
double sampleRate; double sampleRate;
v3_plugin_frame** frame; v3_plugin_frame** frame;
Size<uint> nextSize;
int32_t nextWidth, nextHeight;


dpf_plugin_view(v3_host_application** const h, void* const instance, const double sr) dpf_plugin_view(v3_host_application** const h, void* const instance, const double sr)
: refcounter(1), : refcounter(1),
host(h), host(h),
instancePointer(instance), instancePointer(instance),
sampleRate(sr), sampleRate(sr),
frame(nullptr)
frame(nullptr),
nextWidth(0),
nextHeight(0)
{ {
// v3_funknown, everything custom // v3_funknown, everything custom
query_interface = query_interface_view; query_interface = query_interface_view;
@@ -1083,10 +1137,11 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
scaleFactor, scaleFactor,
view->sampleRate, view->sampleRate,
view->instancePointer, view->instancePointer,
view->nextSize.isValid());
view->nextWidth > 0 && view->nextHeight > 0);


view->uivst3->postInit(view->nextSize);
view->nextSize = Size<uint>();
view->uivst3->postInit(view->nextWidth, view->nextHeight);
view->nextWidth = 0;
view->nextHeight = 0;


#ifdef DPF_VST3_USING_HOST_RUN_LOOP #ifdef DPF_VST3_USING_HOST_RUN_LOOP
// register a timer host run loop stuff // register a timer host run loop stuff
@@ -1206,7 +1261,8 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
if (UIVst3* const uivst3 = view->uivst3) if (UIVst3* const uivst3 = view->uivst3)
return uivst3->onSize(rect); return uivst3->onSize(rect);


view->nextSize = Size<uint>(rect->right - rect->left, rect->bottom - rect->top);
view->nextWidth = rect->right - rect->left;
view->nextHeight = rect->bottom - rect->top;
return V3_OK; return V3_OK;
} }


@@ -1261,9 +1317,10 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
UIExporter tmpUI(nullptr, 0, view->sampleRate, UIExporter tmpUI(nullptr, 0, view->sampleRate,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
view->instancePointer, scaleFactor); view->instancePointer, scaleFactor);
uint minimumWidth, minimumHeight;
bool keepAspectRatio; bool keepAspectRatio;
const Size<uint> size(tmpUI.getMinimumSizeConstraint(keepAspectRatio));
return ::checkSizeConstraint(size, keepAspectRatio, rect) ? V3_FALSE : V3_TRUE;
tmpUI.getGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio);
return applyGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, rect) ? V3_FALSE : V3_TRUE;
} }
}; };




Loading…
Cancel
Save