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
24 #error Define either IGRAPHICS_GL2 or IGRAPHICS_GL3 for IGRAPHICS_NANOVG with OS_MAC
34 #error NOT IMPLEMENTED
36 #pragma comment(lib, "opengl32.lib")
37 #if defined IGRAPHICS_GL2
38 #define NANOVG_GL2_IMPLEMENTATION
39 #elif defined IGRAPHICS_GL3
40 #define NANOVG_GL3_IMPLEMENTATION
42 #error Define either IGRAPHICS_GL2 or IGRAPHICS_GL3 when using IGRAPHICS_GL and IGRAPHICS_NANOVG with OS_WIN
44 #elif defined OS_LINUX
45 #error NOT IMPLEMENTED
47 #if defined IGRAPHICS_GLES2
48 #define NANOVG_GLES2_IMPLEMENTATION
49 #elif defined IGRAPHICS_GLES3
50 #define NANOVG_GLES3_IMPLEMENTATION
52 #error Define either IGRAPHICS_GLES2 or IGRAPHICS_GLES3 when using IGRAPHICS_GL and IGRAPHICS_NANOVG with OS_WEB
55 #include "nanovg_gl.h"
56 #include "nanovg_gl_utils.h"
57#elif defined IGRAPHICS_METAL
58 #include "nanovg_mtl.h"
61 #import <Metal/Metal.h>
64 #error you must define either IGRAPHICS_GL2, IGRAPHICS_GLES2 etc or IGRAPHICS_METAL when using IGRAPHICS_NANOVG
71using namespace igraphics;
73#pragma mark - Private Classes and Structs
78 Bitmap(NVGcontext* pContext,
const char* path,
double sourceScale,
int nvgImageID,
bool shared =
false);
79 Bitmap(
IGraphicsNanoVG* pGraphics, NVGcontext* pContext,
int width,
int height,
float scale,
float drawScale);
80 Bitmap(NVGcontext* pContext,
int width,
int height,
const uint8_t* pData,
float scale,
float drawScale);
82 NVGframebuffer* GetFBO()
const {
return mFBO; }
86 NVGframebuffer* mFBO =
nullptr;
87 bool mSharedTexture =
false;
90IGraphicsNanoVG::Bitmap::Bitmap(NVGcontext* pContext,
const char* path,
double sourceScale,
int nvgImageID,
bool shared)
92 assert(nvgImageID > 0);
95 mSharedTexture = shared;
97 nvgImageSize(mVG, nvgImageID, &w, &h);
99 SetBitmap(nvgImageID, w, h, sourceScale, 1.f);
102IGraphicsNanoVG::Bitmap::Bitmap(
IGraphicsNanoVG* pGraphics, NVGcontext* pContext,
int width,
int height,
float scale,
float drawScale)
104 assert(width > 0 && height > 0);
105 mGraphics = pGraphics;
107 mFBO = nvgCreateFramebuffer(pContext, width, height, 0);
109 nvgBindFramebuffer(mFBO);
111#ifdef IGRAPHICS_METAL
112 mnvgClearWithColor(mVG, nvgRGBAf(0, 0, 0, 0));
114 glViewport(0, 0, width, height);
115 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
116 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
118 nvgBeginFrame(mVG, width, height, 1.f);
121 SetBitmap(mFBO->image, width, height, scale, drawScale);
124IGraphicsNanoVG::Bitmap::Bitmap(NVGcontext* pContext,
int width,
int height,
const uint8_t* pData,
float scale,
float drawScale)
126 int idx = nvgCreateImageRGBA(pContext, width, height, 0, pData);
128 SetBitmap(idx, width, height, scale, drawScale);
131IGraphicsNanoVG::Bitmap::~Bitmap()
136 mGraphics->DeleteFBO(mFBO);
138 nvgDeleteImage(mVG, GetBitmap());
143static StaticStorage<IFontData> sFontCache;
145extern std::map<std::string, MTLTexturePtr> gTextureMap;
148static void nvgReadPixels(NVGcontext* pContext,
int image,
int x,
int y,
int width,
int height,
void* pData)
150#if defined(IGRAPHICS_GL)
151 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pData);
152#elif defined(IGRAPHICS_METAL)
153 mnvgReadPixels(pContext, image, x, y, width, height, pData);
157#pragma mark - Utilities
160BEGIN_IGRAPHICS_NAMESPACE
162NVGcolor NanoVGColor(
const IColor& color,
const IBlend* pBlend)
165 c.r = (float) color.R / 255.0f;
166 c.g = (
float) color.G / 255.0f;
167 c.b = (float) color.B / 255.0f;
172void NanoVGRect(NVGcontext* pContext,
const IRECT& r)
174 nvgRect(pContext, r.L, r.T, r.
W(), r.
H());
177void NanoVGSetBlendMode(NVGcontext* pContext,
const IBlend* pBlend)
181 nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OVER);
185 switch (pBlend->mMethod)
187 case EBlend::SrcOver: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OVER);
break;
188 case EBlend::SrcIn: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_IN);
break;
189 case EBlend::SrcOut: nvgGlobalCompositeOperation(pContext, NVG_SOURCE_OUT);
break;
190 case EBlend::SrcAtop: nvgGlobalCompositeOperation(pContext, NVG_ATOP);
break;
191 case EBlend::DstOver: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_OVER);
break;
192 case EBlend::DstIn: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_IN);
break;
193 case EBlend::DstOut: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_OUT);
break;
194 case EBlend::DstAtop: nvgGlobalCompositeOperation(pContext, NVG_DESTINATION_ATOP);
break;
195 case EBlend::Add: nvgGlobalCompositeBlendFunc(pContext, NVG_SRC_ALPHA, NVG_DST_ALPHA);
break;
196 case EBlend::XOR: nvgGlobalCompositeOperation(pContext, NVG_XOR);
break;
200NVGpaint NanoVGPaint(NVGcontext* pContext,
const IPattern& pattern,
const IBlend* pBlend)
202 assert(pattern.
NStops() > 0);
206 NVGcolor icol = NanoVGColor(pattern.
GetStop(0).mColor, pBlend);
207 NVGcolor ocol = NanoVGColor(pattern.
GetStop(pattern.
NStops() - 1).mColor, pBlend);
213 if (pattern.mType == EPatternType::Radial)
215 return nvgRadialGradient(pContext, s[0], s[1], inverse.mXX * pattern.
GetStop(0).mOffset, inverse.mXX, icol, ocol);
221 return nvgLinearGradient(pContext, s[0], s[1], e[0], e[1], icol, ocol);
225END_IGRAPHICS_NAMESPACE
230IGraphicsNanoVG::IGraphicsNanoVG(
IGEditorDelegate& dlg,
int w,
int h,
int fps,
float scale)
233 DBGMSG(
"IGraphics NanoVG @ %i FPS\n", fps);
234 StaticStorage<IFontData>::Accessor storage(sFontCache);
238IGraphicsNanoVG::~IGraphicsNanoVG()
240 StaticStorage<IFontData>::Accessor storage(sFontCache);
247#if defined IGRAPHICS_METAL
248 return "NanoVG | Metal";
251 return "NanoVG | WebGL";
253 #if defined IGRAPHICS_GL2
254 return "NanoVG | GL2";
255 #elif defined IGRAPHICS_GL3
256 return "NanoVG | GL3";
257 #elif defined IGRAPHICS_GLES2
258 return "NanoVG | GLES2";
259 #elif defined IGRAPHICS_GLES3
260 return "NanoVG | GLES3";
270 return (strstr(extLower,
"png") !=
nullptr) || (strstr(extLower,
"jpg") !=
nullptr) || (strstr(extLower,
"jpeg") !=
nullptr);
275 if (targetScale == 0)
279 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
280 APIBitmap* pAPIBitmap = storage.Find(name, targetScale);
285 const char* ext = name + strlen(name) - 1;
286 while (ext >= name && *ext !=
'.') --ext;
289 WDL_String fullPathOrResourceID;
291 EResourceLocation resourceFound =
SearchImageResource(name, ext, fullPathOrResourceID, targetScale, sourceScale);
295 if(resourceFound == EResourceLocation::kNotFound || !bitmapTypeSupported)
297 assert(0 &&
"Bitmap not found");
301 pAPIBitmap =
LoadAPIBitmap(fullPathOrResourceID.Get(), sourceScale, resourceFound, ext);
303 storage.Add(pAPIBitmap, name, sourceScale);
305 assert(pAPIBitmap &&
"Bitmap not loaded");
308 return IBitmap(pAPIBitmap, nStates, framesAreHorizontal, name);
314 int nvgImageFlags = 0;
317 if (location == EResourceLocation::kPreloadedTexture)
319 idx = mnvgCreateImageFromHandle(mVG, gTextureMap[fileNameOrResID], nvgImageFlags);
325 if (location == EResourceLocation::kWinBinary)
327 const void* pResData =
nullptr;
335 idx = nvgCreateImageMem(mVG, nvgImageFlags, (
unsigned char*) pResData, size);
340 if (location == EResourceLocation::kAbsolutePath)
343 idx = nvgCreateImage(mVG, fileNameOrResID, nvgImageFlags);
346 return new Bitmap(mVG, fileNameOrResID, scale, idx, location == EResourceLocation::kPreloadedTexture);
351 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
352 APIBitmap* pBitmap = storage.Find(name, scale);
357 int nvgImageFlags = 0;
361 idx = nvgCreateImageMem(mVG, nvgImageFlags, (
unsigned char*)pData, dataSize);
364 pBitmap =
new Bitmap(mVG, name, scale, idx,
false);
366 storage.Add(pBitmap, name, scale);
379 APIBitmap* pAPIBitmap =
new Bitmap(
this, mVG, width, height, scale, drawScale);
383 nvgBindFramebuffer(mMainFrameBuffer);
392 const APIBitmap* pBitmap = layer->GetAPIBitmap();
397 if (data.GetSize() >= size)
407 const APIBitmap* pBitmap = layer->GetAPIBitmap();
410 int size = width * height * 4;
412 if (mask.GetSize() >= size)
414 if (!shadow.mDrawForeground)
417 nvgGlobalCompositeBlendFunc(mVG, NVG_ZERO, NVG_ZERO);
419 nvgFillColor(mVG, NanoVGColor(COLOR_TRANSPARENT));
424 IRECT bounds(layer->Bounds());
428 IBitmap tempLayerBitmap(shadowBitmap, 1,
false);
429 IBitmap maskBitmap(&maskRawBitmap, 1,
false);
430 ILayer shadowLayer(shadowBitmap, layer->Bounds(),
nullptr,
IRECT());
435 DrawBitmap(maskBitmap, bounds, 0, 0,
nullptr);
436 IBlend blend1(EBlend::SrcIn, 1.0);
441 IBlend blend2(EBlend::DstOver, shadow.mOpacity);
442 bounds.
Translate(shadow.mXOffset, shadow.mYOffset);
443 DrawBitmap(tempLayerBitmap, bounds, 0, 0, &blend2);
451#if defined IGRAPHICS_METAL
452 mVG = nvgCreateContext(pContext, NVG_ANTIALIAS | NVG_TRIPLE_BUFFER);
454 mVG = nvgCreateContext(NVG_ANTIALIAS );
458 DBGMSG(
"Could not init nanovg.\n");
466 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
469 if(mMainFrameBuffer !=
nullptr)
470 nvgDeleteFramebuffer(mMainFrameBuffer);
472 mMainFrameBuffer =
nullptr;
475 nvgDeleteContext(mVG);
484 if (mMainFrameBuffer !=
nullptr)
485 nvgDeleteFramebuffer(mMainFrameBuffer);
491 if (mMainFrameBuffer ==
nullptr)
492 DBGMSG(
"Could not init FBO.\n");
503 glClearColor(0.f, 0.f, 0.f, 0.f);
504 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
506 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mInitialFBO);
510 nvgBindFramebuffer(mMainFrameBuffer);
517 nvgBindFramebuffer(
nullptr);
523 nvgResetTransform(mVG);
524 nvgTranslate(mVG, mXTranslation, mYTranslation);
527 nvgFillPaint(mVG, img);
531#if defined OS_MAC && defined IGRAPHICS_GL
532 glBindFramebuffer(GL_FRAMEBUFFER, mInitialFBO);
551 nvgTransformScale(imgPaint.xform, scale, scale);
553 imgPaint.xform[4] = dest.L - srcX;
554 imgPaint.xform[5] = dest.T - srcY;
555 imgPaint.extent[0] = bitmap.
W() * bitmap.
GetScale();
556 imgPaint.extent[1] = bitmap.
H() * bitmap.
GetScale();
557 imgPaint.image = pAPIBitmap->
GetBitmap();
558 imgPaint.radius = imgPaint.feather = 0.f;
559 imgPaint.innerColor = imgPaint.outerColor = nvgRGBAf(1, 1, 1,
BlendWeight(pBlend));
564 nvgRect(mVG, dest.L, dest.T, dest.
W(), dest.
H());
565 nvgFillPaint(mVG, imgPaint);
566 NanoVGSetBlendMode(mVG, pBlend);
568 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
584 nvgArc(mVG, cx, cy, r, DegToRad(a1 - 90.f), DegToRad(a2 - 90.f), winding == EWinding::CW ? NVG_CW : NVG_CCW);
589 nvgMoveTo(mVG, x, y);
594 nvgLineTo(mVG, x, y);
599 nvgBezierTo(mVG, c1x, c1y, c2x, c2y, x2, y2);
604 nvgQuadTo(mVG, cx, cy, x2, y2);
609 nvgPathWinding(mVG, clockwise ? NVG_CW : NVG_CCW);
617void IGraphicsNanoVG::PrepareAndMeasureText(
const IText& text,
const char* str,
IRECT& r,
double& x,
double & y)
const
621 assert(nvgFindFont(mVG, text.mFont) != -1 &&
"No font found - did you forget to load it?");
624 nvgFontSize(mVG, text.mSize);
625 nvgFontFace(mVG, text.mFont);
631 case EAlign::Near: align = NVG_ALIGN_LEFT; x = r.L;
break;
632 case EAlign::Center: align = NVG_ALIGN_CENTER; x = r.
MW();
break;
633 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = r.R;
break;
636 switch (text.mVAlign)
638 case EVAlign::Top: align |= NVG_ALIGN_TOP; y = r.T;
break;
639 case EVAlign::Middle: align |= NVG_ALIGN_MIDDLE; y = r.
MH();
break;
640 case EVAlign::Bottom: align |= NVG_ALIGN_BOTTOM; y = r.B;
break;
643 nvgTextAlign(mVG, align);
644 nvgTextBounds(mVG, x, y, str, NULL, fbounds);
646 r =
IRECT(fbounds[0], fbounds[1], fbounds[2], fbounds[3]);
653 PrepareAndMeasureText(text, str, bounds, x, y);
661 IRECT measured = bounds;
664 PrepareAndMeasureText(text, str, measured, x, y);
666 DoTextRotation(text, bounds, measured);
667 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
668 NanoVGSetBlendMode(mVG, pBlend);
669 nvgText(mVG, x, y, str, NULL);
670 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
677 switch (options.mCapOption)
679 case ELineCap::Butt: nvgLineCap(mVG, NVG_BUTT);
break;
680 case ELineCap::Round: nvgLineCap(mVG, NVG_ROUND);
break;
681 case ELineCap::Square: nvgLineCap(mVG, NVG_SQUARE);
break;
684 switch (options.mJoinOption)
686 case ELineJoin::Miter: nvgLineJoin(mVG, NVG_MITER);
break;
687 case ELineJoin::Round: nvgLineJoin(mVG, NVG_ROUND);
break;
688 case ELineJoin::Bevel: nvgLineJoin(mVG, NVG_BEVEL);
break;
691 nvgMiterLimit(mVG, options.mMiterLimit);
692 nvgStrokeWidth(mVG, thickness);
695 if (pattern.mType == EPatternType::Solid)
696 nvgStrokeColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
698 nvgStrokePaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
700 nvgPathWinding(mVG, NVG_CCW);
701 NanoVGSetBlendMode(mVG, pBlend);
703 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
705 if (!options.mPreserve)
711 switch(options.mFillRule)
716 case EFillRule::Winding:
717 nvgPathWinding(mVG, NVG_CCW);
719 case EFillRule::EvenOdd:
720 nvgPathWinding(mVG, NVG_CW);
722 case EFillRule::Preserve:
728 if (pattern.mType == EPatternType::Solid)
729 nvgFillColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
731 nvgFillPaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
733 NanoVGSetBlendMode(mVG, pBlend);
735 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
737 if (!options.mPreserve)
743 StaticStorage<IFontData>::Accessor storage(sFontCache);
744 IFontData* cached = storage.Find(fontID);
748 nvgCreateFontFaceMem(mVG, fontID, cached->Get(), cached->GetSize(), cached->GetFaceIdx(), 0);
752 IFontDataPtr data = font->GetFontData();
754 if (data->IsValid() && nvgCreateFontFaceMem(mVG, fontID, data->Get(), data->GetSize(), data->GetFaceIdx(), 0) != -1)
756 storage.Add(data.release(), fontID);
763void IGraphicsNanoVG::UpdateLayer()
771 nvgBindFramebuffer(mMainFrameBuffer);
779 glViewport(0, 0, mLayers.top()->Bounds().W() * scale, mLayers.top()->Bounds().H() * scale);
781 nvgBindFramebuffer(
dynamic_cast<const Bitmap*
>(mLayers.top()->GetAPIBitmap())->GetFBO());
786void IGraphicsNanoVG::PathTransformSetMatrix(
const IMatrix& m)
788 double xTranslate = 0.0;
789 double yTranslate = 0.0;
791 if (!mLayers.empty())
793 IRECT bounds = mLayers.top()->Bounds();
795 xTranslate = -bounds.L;
796 yTranslate = -bounds.T;
799 nvgResetTransform(mVG);
801 nvgTranslate(mVG, xTranslate, yTranslate);
802 nvgTransform(mVG, m.mXX, m.mYX, m.mXY, m.mYY, m.mTX, m.mTY);
805void IGraphicsNanoVG::SetClipRegion(
const IRECT& r)
807 nvgScissor(mVG, r.L, r.T, r.
W(), r.
H());
812 const float xd = x1 - x2;
813 const float yd = y1 - y2;
814 const float len = std::sqrt(xd * xd + yd * yd);
816 const float segs = std::round(len / dashLen);
817 const float incr = 1.f / segs;
824 for (
int i = 1; i < static_cast<int>(segs); i+=2)
826 float progress = incr *
static_cast<float>(i);
828 float xe = x1 + progress * (x2 - x1);
829 float ye = y1 + progress * (y2 - y1);
835 xs = x1 + progress * (x2 - x1);
836 ys = y1 + progress * (y2 - y1);
846 const int xsegs =
static_cast<int>(std::ceil(bounds.
W() / (dashLen * 2.f)));
847 const int ysegs =
static_cast<int>(std::ceil(bounds.
H() / (dashLen * 2.f)));
857 for(
int j = 0; j < 2; j++)
859 for (
int i = 0; i < xsegs; i++)
861 x2 =
Clip(x1 + dashLen, bounds.L, bounds.R);
863 x1 =
Clip(x2 + dashLen, bounds.L, bounds.R);
869 for (
int i = 0; i < ysegs; i++)
871 y2 =
Clip(y1 + dashLen, bounds.T, bounds.B);
873 y1 =
Clip(y2 + dashLen, bounds.T, bounds.B);
885void IGraphicsNanoVG::DeleteFBO(NVGframebuffer* pBuffer)
888 nvgDeleteFramebuffer(pBuffer);
891 WDL_MutexLock lock(&mFBOMutex);
892 mFBOStack.push(pBuffer);
896void IGraphicsNanoVG::ClearFBOStack()
898 WDL_MutexLock lock(&mFBOMutex);
899 while (!mFBOStack.empty())
901 nvgDeleteFramebuffer(mFBOStack.top());
908 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));
910 nvgRect(mVG, outerBounds.L, outerBounds.T, outerBounds.
W(), outerBounds.
H());
911 nvgFillPaint(mVG, shadowPaint);
912 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
920 nvgFontSize(mVG, text.mSize);
921 nvgFontFace(mVG, text.mFont);
923 float x = 0.0, y = 0.0;
924 const float width = bounds.
W();
926 float yOffsetScale = 0.0;
930 case EAlign::Near: align = NVG_ALIGN_LEFT; x = bounds.L;
break;
931 case EAlign::Center: align = NVG_ALIGN_CENTER; x = bounds.
MW();
break;
932 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = bounds.R;
break;
935 switch (text.mVAlign)
939 align |= NVG_ALIGN_TOP;
944 case EVAlign::Middle:
946 align |= NVG_ALIGN_MIDDLE;
951 case EVAlign::Bottom:
953 align |= NVG_ALIGN_BOTTOM;
960 nvgTextAlign(mVG, align);
968 nvgTextMetrics(mVG, NULL, NULL, &lineHeight);
969 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
971 for (
auto run : {0, 1})
974 end = str + strlen(str);
975 while ((nRows = nvgTextBreakLines(mVG, start, end, width, rows, 3))) {
976 for (
int i = 0; i < nRows; i++) {
983 NVGtextRow* row = &rows[i];
984 nvgText(mVG, x, y - ((lines*lineHeight)*yOffsetScale), row->start, row->end);
988 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
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
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
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
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)
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 the point x, y.
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,...