13#include "IGraphicsNanoVG.h"
16#if defined IGRAPHICS_GL
18 #if defined IGRAPHICS_GL2
19 #define NANOVG_GL2_IMPLEMENTATION
20 #elif defined IGRAPHICS_GL3
21 #include <OpenGL/gl3.h>
22 #define NANOVG_GL3_IMPLEMENTATION
23 #elif defined IGRAPHICS_GLES2
24 #include <libGLESv2/angle_gl.h>
25 #define NANOVG_GLES2_IMPLEMENTATION
26 #elif defined IGRAPHICS_GLES3
27 #include <libGLESv2/angle_gl.h>
28 #define NANOVG_GLES3_IMPLEMENTATION
31 #if defined IGRAPHICS_GLES2
32 #include <libGLESv2/angle_gl.h>
33 #define NANOVG_GLES2_IMPLEMENTATION
34 #elif defined IGRAPHICS_GLES3
35 #include <libGLESv2/angle_gl.h>
36 #define NANOVG_GLES3_IMPLEMENTATION
38 #error Define either IGRAPHICS_GLES2 or IGRAPHICS_GLES3 for IGRAPHICS_NANOVG with OS_IOS
41 #pragma comment(lib, "opengl32.lib")
42 #if defined IGRAPHICS_GL2
43 #define NANOVG_GL2_IMPLEMENTATION
44 #elif defined IGRAPHICS_GL3
45 #define NANOVG_GL3_IMPLEMENTATION
47 #error Define either IGRAPHICS_GL2 or IGRAPHICS_GL3 when using IGRAPHICS_GL and IGRAPHICS_NANOVG with OS_WIN
49 #elif defined OS_LINUX
50 #error NOT IMPLEMENTED
52 #if defined IGRAPHICS_GLES2
53 #define NANOVG_GLES2_IMPLEMENTATION
54 #elif defined IGRAPHICS_GLES3
55 #define NANOVG_GLES3_IMPLEMENTATION
57 #error Define either IGRAPHICS_GLES2 or IGRAPHICS_GLES3 when using IGRAPHICS_GL and IGRAPHICS_NANOVG with OS_WEB
60 #include "nanovg_gl.h"
61 #include "nanovg_gl_utils.h"
62#elif defined IGRAPHICS_METAL
63 #include "nanovg_mtl.h"
66 #import <Metal/Metal.h>
69 #error you must define either IGRAPHICS_GL2, IGRAPHICS_GLES2 etc or IGRAPHICS_METAL when using IGRAPHICS_NANOVG
76using namespace igraphics;
78#pragma mark - Private Classes and Structs
83 Bitmap(NVGcontext* pContext,
const char* path,
double sourceScale,
int nvgImageID,
bool shared =
false);
84 Bitmap(
IGraphicsNanoVG* pGraphics, NVGcontext* pContext,
int width,
int height,
float scale,
float drawScale);
85 Bitmap(NVGcontext* pContext,
int width,
int height,
const uint8_t* pData,
float scale,
float drawScale);
87 NVGframebuffer* GetFBO()
const {
return mFBO; }
91 NVGframebuffer* mFBO =
nullptr;
92 bool mSharedTexture =
false;
95IGraphicsNanoVG::Bitmap::Bitmap(NVGcontext* pContext,
const char* path,
double sourceScale,
int nvgImageID,
bool shared)
97 assert(nvgImageID > 0);
100 mSharedTexture = shared;
102 nvgImageSize(mVG, nvgImageID, &w, &h);
104 SetBitmap(nvgImageID, w, h, sourceScale, 1.f);
107IGraphicsNanoVG::Bitmap::Bitmap(
IGraphicsNanoVG* pGraphics, NVGcontext* pContext,
int width,
int height,
float scale,
float drawScale)
109 assert(width > 0 && height > 0);
110 mGraphics = pGraphics;
112 mFBO = nvgCreateFramebuffer(pContext, width, height, 0);
114 nvgBindFramebuffer(mFBO);
116#ifdef IGRAPHICS_METAL
117 mnvgClearWithColor(mVG, nvgRGBAf(0, 0, 0, 0));
119 glViewport(0, 0, width, height);
120 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
121 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
123 nvgBeginFrame(mVG, width, height, 1.f);
126 SetBitmap(mFBO->image, width, height, scale, drawScale);
129IGraphicsNanoVG::Bitmap::Bitmap(NVGcontext* pContext,
int width,
int height,
const uint8_t* pData,
float scale,
float drawScale)
131 int idx = nvgCreateImageRGBA(pContext, width, height, 0, pData);
133 SetBitmap(idx, width, height, scale, drawScale);
136IGraphicsNanoVG::Bitmap::~Bitmap()
141 mGraphics->DeleteFBO(mFBO);
143 nvgDeleteImage(mVG, GetBitmap());
148static StaticStorage<IFontData> sFontCache;
150extern std::map<std::string, MTLTexturePtr> gTextureMap;
153static void nvgReadPixels(NVGcontext* pContext,
int image,
int x,
int y,
int width,
int height,
void* pData)
155#if defined(IGRAPHICS_GL)
156 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pData);
157#elif defined(IGRAPHICS_METAL)
158 mnvgReadPixels(pContext, image, x, y, width, height, pData);
162#pragma mark - Utilities
165BEGIN_IGRAPHICS_NAMESPACE
167NVGcolor NanoVGColor(
const IColor& color,
const IBlend* pBlend)
170 c.r = (float) color.R / 255.0f;
171 c.g = (
float) color.G / 255.0f;
172 c.b = (float) color.B / 255.0f;
177void NanoVGRect(NVGcontext* pContext,
const IRECT& r)
179 nvgRect(pContext, r.L, r.T, r.
W(), r.
H());
182void NanoVGSetBlendMode(NVGcontext* pContext,
const IBlend* pBlend)
186 nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OVER);
190 switch (pBlend->mMethod)
192 case EBlend::SrcOver: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OVER);
break;
193 case EBlend::SrcIn: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_IN);
break;
194 case EBlend::SrcOut: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OUT);
break;
195 case EBlend::SrcAtop: nvgGlobalCompositeOperation(pContext, NVG_ATOP);
break;
196 case EBlend::DstOver: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_OVER);
break;
197 case EBlend::DstIn: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_IN);
break;
198 case EBlend::DstOut: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_OUT);
break;
199 case EBlend::DstAtop: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_ATOP);
break;
200 case EBlend::Add: nvgGlobalCompositeBlendFunc(pContext, NVG_SRC_ALPHA, NVG_DST_ALPHA);
break;
201 case EBlend::XOR: nvgGlobalCompositeOperation(pContext, NVG_XOR);
break;
205NVGpaint NanoVGPaint(NVGcontext* pContext,
const IPattern& pattern,
const IBlend* pBlend)
207 assert(pattern.
NStops() > 0);
211 NVGcolor icol = NanoVGColor(pattern.
GetStop(0).mColor, pBlend);
212 NVGcolor ocol = NanoVGColor(pattern.
GetStop(pattern.
NStops() - 1).mColor, pBlend);
218 if (pattern.mType == EPatternType::Radial)
220 return nvgRadialGradient(pContext, s[0], s[1], inverse.mXX * pattern.
GetStop(0).mOffset, inverse.mXX, icol, ocol);
226 return nvgLinearGradient(pContext, s[0], s[1], e[0], e[1], icol, ocol);
230END_IGRAPHICS_NAMESPACE
235IGraphicsNanoVG::IGraphicsNanoVG(
IGEditorDelegate& dlg,
int w,
int h,
int fps,
float scale)
238 DBGMSG(
"IGraphics NanoVG @ %i FPS\n", fps);
239 StaticStorage<IFontData>::Accessor storage(sFontCache);
243IGraphicsNanoVG::~IGraphicsNanoVG()
245 StaticStorage<IFontData>::Accessor storage(sFontCache);
252#if defined IGRAPHICS_METAL
253 return "NanoVG | Metal";
256 return "NanoVG | WebGL";
258 #if defined IGRAPHICS_GL2
259 return "NanoVG | GL2";
260 #elif defined IGRAPHICS_GL3
261 return "NanoVG | GL3";
262 #elif defined IGRAPHICS_GLES2
263 return "NanoVG | GLES2";
264 #elif defined IGRAPHICS_GLES3
265 return "NanoVG | GLES3";
275 return (strstr(extLower,
"png") !=
nullptr) || (strstr(extLower,
"jpg") !=
nullptr) || (strstr(extLower,
"jpeg") !=
nullptr);
280 if (targetScale == 0)
284 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
285 APIBitmap* pAPIBitmap = storage.Find(name, targetScale);
290 const char* ext = name + strlen(name) - 1;
291 while (ext >= name && *ext !=
'.') --ext;
294 WDL_String fullPathOrResourceID;
296 EResourceLocation resourceFound =
SearchImageResource(name, ext, fullPathOrResourceID, targetScale, sourceScale);
300 if(resourceFound == EResourceLocation::kNotFound || !bitmapTypeSupported)
302 assert(0 &&
"Bitmap not found");
306 pAPIBitmap =
LoadAPIBitmap(fullPathOrResourceID.Get(), sourceScale, resourceFound, ext);
308 storage.Add(pAPIBitmap, name, sourceScale);
310 assert(pAPIBitmap &&
"Bitmap not loaded");
313 return IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name);
319 int nvgImageFlags = 0;
322#if defined OS_IOS && defined IGRAPHICS_METAL
323 if (location == EResourceLocation::kPreloadedTexture)
325 idx = mnvgCreateImageFromHandle(mVG, gTextureMap[fileNameOrResID], nvgImageFlags);
331 if (location == EResourceLocation::kWinBinary)
333 const void* pResData =
nullptr;
341 idx = nvgCreateImageMem(mVG, nvgImageFlags, (
unsigned char*) pResData, size);
346 if (location == EResourceLocation::kAbsolutePath)
349 idx = nvgCreateImage(mVG, fileNameOrResID, nvgImageFlags);
352 return new Bitmap(mVG, fileNameOrResID, scale, idx, location == EResourceLocation::kPreloadedTexture);
357 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
358 APIBitmap* pBitmap = storage.Find(name, scale);
363 int nvgImageFlags = 0;
367 idx = nvgCreateImageMem(mVG, nvgImageFlags, (
unsigned char*)pData, dataSize);
370 pBitmap =
new Bitmap(mVG, name, scale, idx,
false);
372 storage.Add(pBitmap, name, scale);
385 APIBitmap* pAPIBitmap =
new Bitmap(
this, mVG, width, height, scale, drawScale);
389 nvgBindFramebuffer(mMainFrameBuffer);
398 const APIBitmap* pBitmap = layer->GetAPIBitmap();
403 if (data.GetSize() >= size)
413 const APIBitmap* pBitmap = layer->GetAPIBitmap();
416 int size = width * height * 4;
418 if (mask.GetSize() >= size)
420 if (!shadow.mDrawForeground)
423 nvgGlobalCompositeBlendFunc(mVG, NVG_ZERO, NVG_ZERO);
425 nvgFillColor(mVG, NanoVGColor(COLOR_TRANSPARENT));
430 IRECT bounds(layer->Bounds());
434 IBitmap tempLayerBitmap(shadowBitmap, 1,
false);
435 IBitmap maskBitmap(&maskRawBitmap, 1,
false);
436 ILayer shadowLayer(shadowBitmap, layer->Bounds(),
nullptr,
IRECT());
441 DrawBitmap(maskBitmap, bounds, 0, 0,
nullptr);
442 IBlend blend1(EBlend::SrcIn, 1.0);
447 IBlend blend2(EBlend::DstOver, shadow.mOpacity);
448 bounds.
Translate(shadow.mXOffset, shadow.mYOffset);
449 DrawBitmap(tempLayerBitmap, bounds, 0, 0, &blend2);
457#if defined IGRAPHICS_METAL
458 mVG = nvgCreateContext(pContext, NVG_ANTIALIAS | NVG_TRIPLE_BUFFER);
460 mVG = nvgCreateContext(NVG_ANTIALIAS );
464 DBGMSG(
"Could not init nanovg.\n");
472 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
475 if(mMainFrameBuffer !=
nullptr)
476 nvgDeleteFramebuffer(mMainFrameBuffer);
478 mMainFrameBuffer =
nullptr;
481 nvgDeleteContext(mVG);
490 if (mMainFrameBuffer !=
nullptr)
491 nvgDeleteFramebuffer(mMainFrameBuffer);
497 if (mMainFrameBuffer ==
nullptr)
498 DBGMSG(
"Could not init FBO.\n");
509 glClearColor(0.f, 0.f, 0.f, 0.f);
510 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
511 #if defined OS_MAC || defined OS_IOS
512 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mInitialFBO);
516 nvgBindFramebuffer(mMainFrameBuffer);
523 nvgBindFramebuffer(
nullptr);
529 nvgResetTransform(mVG);
530 nvgTranslate(mVG, mXTranslation, mYTranslation);
533 nvgFillPaint(mVG, img);
537#if (defined OS_MAC || defined OS_IOS) && defined IGRAPHICS_GL
538 glBindFramebuffer(GL_FRAMEBUFFER, mInitialFBO);
557 nvgTransformScale(imgPaint.xform, scale, scale);
559 imgPaint.xform[4] = dest.L - srcX;
560 imgPaint.xform[5] = dest.T - srcY;
561 imgPaint.extent[0] = bitmap.
W() * bitmap.
GetScale();
562 imgPaint.extent[1] = bitmap.
H() * bitmap.
GetScale();
563 imgPaint.image = pAPIBitmap->
GetBitmap();
564 imgPaint.radius = imgPaint.feather = 0.f;
565 imgPaint.innerColor = imgPaint.outerColor = nvgRGBAf(1, 1, 1,
BlendWeight(pBlend));
570 nvgRect(mVG, dest.L, dest.T, dest.
W(), dest.
H());
571 nvgFillPaint(mVG, imgPaint);
572 NanoVGSetBlendMode(mVG, pBlend);
574 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
590 nvgArc(mVG, cx, cy, r, DegToRad(a1 - 90.f), DegToRad(a2 - 90.f), winding == EWinding::CW ? NVG_CW : NVG_CCW);
595 nvgMoveTo(mVG, x, y);
600 nvgLineTo(mVG, x, y);
605 nvgBezierTo(mVG, c1x, c1y, c2x, c2y, x2, y2);
610 nvgQuadTo(mVG, cx, cy, x2, y2);
615 nvgPathWinding(mVG, clockwise ? NVG_CW : NVG_CCW);
623void IGraphicsNanoVG::PrepareAndMeasureText(
const IText& text,
const char* str,
IRECT& r,
double& x,
double & y)
const
627 assert(nvgFindFont(mVG, text.mFont) != -1 &&
"No font found - did you forget to load it?");
630 nvgFontSize(mVG, text.mSize);
631 nvgFontFace(mVG, text.mFont);
637 case EAlign::Near: align = NVG_ALIGN_LEFT; x = r.L;
break;
638 case EAlign::Center: align = NVG_ALIGN_CENTER; x = r.
MW();
break;
639 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = r.R;
break;
642 switch (text.mVAlign)
644 case EVAlign::Top: align |= NVG_ALIGN_TOP; y = r.T;
break;
645 case EVAlign::Middle: align |= NVG_ALIGN_MIDDLE; y = r.
MH();
break;
646 case EVAlign::Bottom: align |= NVG_ALIGN_BOTTOM; y = r.B;
break;
649 nvgTextAlign(mVG, align);
650 nvgTextBounds(mVG, x, y, str, NULL, fbounds);
652 r =
IRECT(fbounds[0], fbounds[1], fbounds[2], fbounds[3]);
659 PrepareAndMeasureText(text, str, bounds, x, y);
667 IRECT measured = bounds;
670 PrepareAndMeasureText(text, str, measured, x, y);
672 DoTextRotation(text, bounds, measured);
673 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
674 NanoVGSetBlendMode(mVG, pBlend);
675 nvgText(mVG, x, y, str, NULL);
676 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
683 switch (options.mCapOption)
685 case ELineCap::Butt: nvgLineCap(mVG, NVG_BUTT);
break;
686 case ELineCap::Round: nvgLineCap(mVG, NVG_ROUND);
break;
687 case ELineCap::Square: nvgLineCap(mVG, NVG_SQUARE);
break;
690 switch (options.mJoinOption)
692 case ELineJoin::Miter: nvgLineJoin(mVG, NVG_MITER);
break;
693 case ELineJoin::Round: nvgLineJoin(mVG, NVG_ROUND);
break;
694 case ELineJoin::Bevel: nvgLineJoin(mVG, NVG_BEVEL);
break;
697 nvgMiterLimit(mVG, options.mMiterLimit);
698 nvgStrokeWidth(mVG, thickness);
701 if (pattern.mType == EPatternType::Solid)
702 nvgStrokeColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
704 nvgStrokePaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
706 nvgPathWinding(mVG, NVG_CCW);
707 NanoVGSetBlendMode(mVG, pBlend);
709 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
711 if (!options.mPreserve)
717 switch(options.mFillRule)
722 case EFillRule::Winding:
723 nvgPathWinding(mVG, NVG_CCW);
725 case EFillRule::EvenOdd:
726 nvgPathWinding(mVG, NVG_CW);
728 case EFillRule::Preserve:
734 if (pattern.mType == EPatternType::Solid)
735 nvgFillColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
737 nvgFillPaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
739 NanoVGSetBlendMode(mVG, pBlend);
741 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
743 if (!options.mPreserve)
749 StaticStorage<IFontData>::Accessor storage(sFontCache);
750 IFontData* cached = storage.Find(fontID);
754 nvgCreateFontFaceMem(mVG, fontID, cached->Get(), cached->GetSize(), cached->GetFaceIdx(), 0);
758 IFontDataPtr data = font->GetFontData();
760 if (data->IsValid() && nvgCreateFontFaceMem(mVG, fontID, data->Get(), data->GetSize(), data->GetFaceIdx(), 0) != -1)
762 storage.Add(data.release(), fontID);
769void IGraphicsNanoVG::UpdateLayer()
777 nvgBindFramebuffer(mMainFrameBuffer);
785 glViewport(0, 0, mLayers.top()->Bounds().W() * scale, mLayers.top()->Bounds().H() * scale);
787 nvgBindFramebuffer(
dynamic_cast<const Bitmap*
>(mLayers.top()->GetAPIBitmap())->GetFBO());
792void IGraphicsNanoVG::PathTransformSetMatrix(
const IMatrix& m)
794 double xTranslate = 0.0;
795 double yTranslate = 0.0;
797 if (!mLayers.empty())
799 IRECT bounds = mLayers.top()->Bounds();
801 xTranslate = -bounds.L;
802 yTranslate = -bounds.T;
805 nvgResetTransform(mVG);
807 nvgTranslate(mVG, xTranslate, yTranslate);
808 nvgTransform(mVG, m.mXX, m.mYX, m.mXY, m.mYY, m.mTX, m.mTY);
811void IGraphicsNanoVG::SetClipRegion(
const IRECT& r)
813 nvgScissor(mVG, r.L, r.T, r.
W(), r.
H());
818 const float xd = x1 - x2;
819 const float yd = y1 - y2;
820 const float len = std::sqrt(xd * xd + yd * yd);
822 const float segs = std::round(len / dashLen);
823 const float incr = 1.f / segs;
830 for (
int i = 1; i < static_cast<int>(segs); i+=2)
832 float progress = incr *
static_cast<float>(i);
834 float xe = x1 + progress * (x2 - x1);
835 float ye = y1 + progress * (y2 - y1);
841 xs = x1 + progress * (x2 - x1);
842 ys = y1 + progress * (y2 - y1);
852 const int xsegs =
static_cast<int>(std::ceil(bounds.
W() / (dashLen * 2.f)));
853 const int ysegs =
static_cast<int>(std::ceil(bounds.
H() / (dashLen * 2.f)));
863 for(
int j = 0; j < 2; j++)
865 for (
int i = 0; i < xsegs; i++)
867 x2 =
Clip(x1 + dashLen, bounds.L, bounds.R);
869 x1 =
Clip(x2 + dashLen, bounds.L, bounds.R);
875 for (
int i = 0; i < ysegs; i++)
877 y2 =
Clip(y1 + dashLen, bounds.T, bounds.B);
879 y1 =
Clip(y2 + dashLen, bounds.T, bounds.B);
891void IGraphicsNanoVG::DeleteFBO(NVGframebuffer* pBuffer)
894 nvgDeleteFramebuffer(pBuffer);
897 WDL_MutexLock lock(&mFBOMutex);
898 mFBOStack.push(pBuffer);
902void IGraphicsNanoVG::ClearFBOStack()
904 WDL_MutexLock lock(&mFBOMutex);
905 while (!mFBOStack.empty())
907 nvgDeleteFramebuffer(mFBOStack.top());
914 NVGpaint shadowPaint = nvgBoxGradient(mVG, innerBounds.L + xyDrop, innerBounds.T + xyDrop, innerBounds.
W(), innerBounds.
H(), roundness, blur, NanoVGColor(COLOR_BLACK_DROP_SHADOW, pBlend), NanoVGColor(COLOR_TRANSPARENT,
nullptr));
916 nvgRect(mVG, outerBounds.L, outerBounds.T, outerBounds.
W(), outerBounds.
H());
917 nvgFillPaint(mVG, shadowPaint);
918 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
926 nvgFontSize(mVG, text.mSize);
927 nvgFontFace(mVG, text.mFont);
929 float x = 0.0, y = 0.0;
930 const float width = bounds.
W();
932 float yOffsetScale = 0.0;
936 case EAlign::Near: align = NVG_ALIGN_LEFT; x = bounds.L;
break;
937 case EAlign::Center: align = NVG_ALIGN_CENTER; x = bounds.
MW();
break;
938 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = bounds.R;
break;
941 switch (text.mVAlign)
945 align |= NVG_ALIGN_TOP;
950 case EVAlign::Middle:
952 align |= NVG_ALIGN_MIDDLE;
957 case EVAlign::Bottom:
959 align |= NVG_ALIGN_BOTTOM;
966 nvgTextAlign(mVG, align);
974 nvgTextMetrics(mVG, NULL, NULL, &lineHeight);
975 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
977 for (
auto run : {0, 1})
980 end = str + strlen(str);
981 while ((nRows = nvgTextBreakLines(mVG, start, end, width, rows, 3))) {
982 for (
int i = 0; i < nRows; i++) {
989 NVGtextRow* row = &rows[i];
990 nvgText(mVG, x, y - ((lines*lineHeight)*yOffsetScale), row->start, row->end);
994 start = rows[nRows-1].next;
const void * LoadWinResource(const char *resID, const char *type, int &sizeInBytes, void *pHInstance)
Load a resource from the binary (windows only).
A Text entry widget drawn by IGraphics to optionally override platform text entries.
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
BitmapData GetBitmap() const
void SetBitmap(BitmapData pBitmap, int w, int h, float scale, float drawScale)
Used to initialise the members after construction.
float GetDrawScale() const
User-facing bitmap abstraction that you use to manage bitmap data, independant of draw class/platform...
APIBitmap * GetAPIBitmap() const
An editor delegate base class that uses IGraphics for the UI.
The lowest level base class of an IGraphics context.
ILayer * PopLayer()
Pop a layer off the stack.
void PathTransformTranslate(float x, float y)
Apply a translation transform to the current path.
void PathRect(const IRECT &bounds)
Add a rectangle to the current path.
virtual float GetBackingPixelScale() const
void DoMeasureTextRotation(const IText &text, const IRECT &bounds, IRECT &rect) const
Measures text bounds accounting for rotation.
int WindowWidth() const
Gets the width of the graphics context including draw scaling.
EResourceLocation SearchImageResource(const char *fileName, const char *type, WDL_String &result, int targetScale, int &sourceScale)
Search for a bitmap image resource matching the target scale.
void PathTransformRestore()
Restore the affine transform of the current path, to the previously saved state.
void PushLayer(ILayer *pLayer)
Push a layer on to the stack.
int GetRoundedScreenScale() const
Gets the screen/display scaling factor, rounded up.
void RemoveAllControls()
Removes all regular IControls from the control list, as well as special controls (frees memory).
virtual void * GetWinModuleHandle()
float GetScreenScale() const
Gets the screen/display scaling factor, e.g.
void PathTransformSave()
Save the current affine transform of the current path.
float GetDrawScale() const
Gets the graphics context scaling factor.
int WindowHeight() const
Gets the height of the graphics context including draw scaling.
virtual void BeginFrame()
Called at the beginning of drawing.
IGraphics draw class using NanoVG
const char * GetDrawingAPIStr() override
void ApplyShadowMask(ILayerPtr &layer, RawBitmapData &mask, const IShadow &shadow) override
Implemented by a graphics backend to apply a calculated shadow mask to a layer, according to the shad...
void DrawResize() override
Called to update the drawing surface after a resize.
void PathClear() override
Clear the stack of path drawing commands.
IBitmap LoadBitmap(const char *name, int nStates, bool framesAreHorizontal, int targetScale) override
Load a bitmap image from disk or from windows resource.
void PathFill(const IPattern &pattern, const IFillOptions &options, const IBlend *pBlend) override
Fill the current current path.
void GetLayerBitmapData(const ILayerPtr &layer, RawBitmapData &data) override
Get the contents of a layer as Raw RGBA bitmap data NOTE: you should only call this within IControl::...
void DrawDottedRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend, float thickness, float dashLen) override
Draw a dotted rectangle to the graphics context.
void PathSetWinding(bool clockwise) override
NanoVG only.
APIBitmap * LoadAPIBitmap(const char *fileNameOrResID, int scale, EResourceLocation location, const char *ext) override
Drawing API method to load a bitmap, called internally.
void PathStroke(const IPattern &pattern, float thickness, const IStrokeOptions &options, const IBlend *pBlend) override
Stroke the current current path.
void PathArc(float cx, float cy, float r, float a1, float a2, EWinding winding) override
Add an arc to the current path.
void PathLineTo(float x, float y) override
Add a line to the current path from the current point to the specified location.
void OnViewDestroyed() override
Called after a platform view is destroyed, so that drawing classes can e.g.
void DrawMultiLineText(const IText &text, const char *str, const IRECT &bounds, const IBlend *pBlend) override
Draw some multi-line text to the graphics context in a specific rectangle (NanoVG only)
void DrawDottedLine(const IColor &color, float x1, float y1, float x2, float y2, const IBlend *pBlend, float thickness, float dashLen) override
Draw a dotted line to the graphics context.
void PathCubicBezierTo(float c1x, float c1y, float c2x, float c2y, float x2, float y2) override
Add a cubic bezier to the current path from the current point to the specified location.
IColor GetPoint(int x, int y) override
Get the color at an X, Y location in the graphics context.
bool LoadAPIFont(const char *fontID, const PlatformFontPtr &font) override
Drawing API method to load a font from a PlatformFontPtr, called internally.
void PathClose() override
Close the path that is being specified.
void DoDrawText(const IText &text, const char *str, const IRECT &bounds, const IBlend *pBlend) override
Internal method to draw text.
void DrawFastDropShadow(const IRECT &innerBounds, const IRECT &outerBounds, float xyDrop=5.f, float roundness=0.f, float blur=10.f, IBlend *pBlend=nullptr) override
NanoVG only.
void PathMoveTo(float x, float y) override
Move the current point in the current path.
void OnViewInitialized(void *pContext) override
Called after platform view initialization, so that drawing classes can e.g.
void BeginFrame() override
Called at the beginning of drawing.
void EndFrame() override
Called by some drawing API classes to finally blit the draw bitmap onto the screen or perform other c...
APIBitmap * CreateAPIBitmap(int width, int height, float scale, double drawScale, bool cacheable=false) override
Creates a new API bitmap, either in memory or as a GPU texture.
void PathQuadraticBezierTo(float cx, float cy, float x2, float y2) override
Add a quadratic bezier to the current path from the current point to the specified location.
bool BitmapExtSupported(const char *ext) override
Checks a file extension and reports whether this drawing API supports loading that extension.
float DoMeasureText(const IText &text, const char *str, IRECT &bounds) const override
Internal method to measure text dimensions.
void DrawBitmap(const IBitmap &bitmap, const IRECT &dest, int srcX, int srcY, const IBlend *pBlend) override
Draw a bitmap (raster) image to the graphics context.
An abstraction that is used to store a temporary raster image/framebuffer.
std::unique_ptr< ILayer > ILayerPtr
ILayerPtr is a managed pointer for transferring the ownership of layers.
float BlendWeight(const IBlend *pBlend)
Helper function to extract the blend weight value from an IBlend ptr if it is valid.
Used to manage stroke behaviour for path based drawing back ends.
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
static void ToLower(char *cDest, const char *cSrc)
Converts a C string to lowercase.
Used to manage composite/blend operations, independent of draw class/platform.
Used to manage color data, independent of draw class/platform.
Used to manage fill behaviour.
Used to store transformation matrices.
IMatrix & Invert()
Changes the matrix to be the inverse of its original value.
void TransformPoint(double &x, double &y, double x0, double y0) const
Transforms a point using this matrix.
Used to store pattern information for gradients.
const IColorStop & GetStop(int idx) const
Get the IColorStop at a particular index (will crash if out of bounds)
Used to manage a rectangular area, independent of draw class/platform.
void Translate(float x, float y)
Translate this rectangle.
Used to specify properties of a drop-shadow to a layer.
IText is used to manage font and text/text entry style for a piece of text on the UI,...