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);
336 DeactivateGLContext();
341 if (location == EResourceLocation::kAbsolutePath)
344 idx = nvgCreateImage(mVG, fileNameOrResID, nvgImageFlags);
345 DeactivateGLContext();
348 return new Bitmap(mVG, fileNameOrResID, scale, idx, location == EResourceLocation::kPreloadedTexture);
353 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
354 APIBitmap* pBitmap = storage.Find(name, scale);
359 int nvgImageFlags = 0;
362 idx = nvgCreateImageMem(mVG, nvgImageFlags, (
unsigned char*)pData, dataSize);
363 DeactivateGLContext();
365 pBitmap =
new Bitmap(mVG, name, scale, idx,
false);
367 storage.Add(pBitmap, name, scale);
380 APIBitmap* pAPIBitmap =
new Bitmap(
this, mVG, width, height, scale, drawScale);
384 nvgBindFramebuffer(mMainFrameBuffer);
393 const APIBitmap* pBitmap = layer->GetAPIBitmap();
398 if (data.GetSize() >= size)
408 const APIBitmap* pBitmap = layer->GetAPIBitmap();
411 int size = width * height * 4;
413 if (mask.GetSize() >= size)
415 if (!shadow.mDrawForeground)
418 nvgGlobalCompositeBlendFunc(mVG, NVG_ZERO, NVG_ZERO);
420 nvgFillColor(mVG, NanoVGColor(COLOR_TRANSPARENT));
425 IRECT bounds(layer->Bounds());
429 IBitmap tempLayerBitmap(shadowBitmap, 1,
false);
430 IBitmap maskBitmap(&maskRawBitmap, 1,
false);
431 ILayer shadowLayer(shadowBitmap, layer->Bounds(),
nullptr,
IRECT());
436 DrawBitmap(maskBitmap, bounds, 0, 0,
nullptr);
437 IBlend blend1(EBlend::SrcIn, 1.0);
442 IBlend blend2(EBlend::DstOver, shadow.mOpacity);
443 bounds.
Translate(shadow.mXOffset, shadow.mYOffset);
444 DrawBitmap(tempLayerBitmap, bounds, 0, 0, &blend2);
452#if defined IGRAPHICS_METAL
453 mVG = nvgCreateContext(pContext, NVG_ANTIALIAS | NVG_TRIPLE_BUFFER);
455 mVG = nvgCreateContext(NVG_ANTIALIAS );
459 DBGMSG(
"Could not init nanovg.\n");
467 StaticStorage<APIBitmap>::Accessor storage(mBitmapCache);
470 if(mMainFrameBuffer !=
nullptr)
471 nvgDeleteFramebuffer(mMainFrameBuffer);
473 mMainFrameBuffer =
nullptr;
476 nvgDeleteContext(mVG);
485 if (mMainFrameBuffer !=
nullptr)
486 nvgDeleteFramebuffer(mMainFrameBuffer);
492 if (mMainFrameBuffer ==
nullptr)
493 DBGMSG(
"Could not init FBO.\n");
496 DeactivateGLContext();
506 glClearColor(0.f, 0.f, 0.f, 0.f);
507 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
509 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mInitialFBO);
513 nvgBindFramebuffer(mMainFrameBuffer);
520 nvgBindFramebuffer(
nullptr);
526 nvgResetTransform(mVG);
527 nvgTranslate(mVG, mXTranslation, mYTranslation);
530 nvgFillPaint(mVG, img);
534#if defined OS_MAC && defined IGRAPHICS_GL
535 glBindFramebuffer(GL_FRAMEBUFFER, mInitialFBO);
554 nvgTransformScale(imgPaint.xform, scale, scale);
556 imgPaint.xform[4] = dest.L - srcX;
557 imgPaint.xform[5] = dest.T - srcY;
558 imgPaint.extent[0] = bitmap.
W() * bitmap.
GetScale();
559 imgPaint.extent[1] = bitmap.
H() * bitmap.
GetScale();
560 imgPaint.image = pAPIBitmap->
GetBitmap();
561 imgPaint.radius = imgPaint.feather = 0.f;
562 imgPaint.innerColor = imgPaint.outerColor = nvgRGBAf(1, 1, 1,
BlendWeight(pBlend));
567 nvgRect(mVG, dest.L, dest.T, dest.
W(), dest.
H());
568 nvgFillPaint(mVG, imgPaint);
569 NanoVGSetBlendMode(mVG, pBlend);
571 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
587 nvgArc(mVG, cx, cy, r, DegToRad(a1 - 90.f), DegToRad(a2 - 90.f), winding == EWinding::CW ? NVG_CW : NVG_CCW);
592 nvgMoveTo(mVG, x, y);
597 nvgLineTo(mVG, x, y);
602 nvgBezierTo(mVG, c1x, c1y, c2x, c2y, x2, y2);
607 nvgQuadTo(mVG, cx, cy, x2, y2);
612 nvgPathWinding(mVG, clockwise ? NVG_CW : NVG_CCW);
620void IGraphicsNanoVG::PrepareAndMeasureText(
const IText& text,
const char* str,
IRECT& r,
double& x,
double & y)
const
624 assert(nvgFindFont(mVG, text.mFont) != -1 &&
"No font found - did you forget to load it?");
627 nvgFontSize(mVG, text.mSize);
628 nvgFontFace(mVG, text.mFont);
634 case EAlign::Near: align = NVG_ALIGN_LEFT; x = r.L;
break;
635 case EAlign::Center: align = NVG_ALIGN_CENTER; x = r.
MW();
break;
636 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = r.R;
break;
639 switch (text.mVAlign)
641 case EVAlign::Top: align |= NVG_ALIGN_TOP; y = r.T;
break;
642 case EVAlign::Middle: align |= NVG_ALIGN_MIDDLE; y = r.
MH();
break;
643 case EVAlign::Bottom: align |= NVG_ALIGN_BOTTOM; y = r.B;
break;
646 nvgTextAlign(mVG, align);
647 nvgTextBounds(mVG, x, y, str, NULL, fbounds);
649 r =
IRECT(fbounds[0], fbounds[1], fbounds[2], fbounds[3]);
656 PrepareAndMeasureText(text, str, bounds, x, y);
664 IRECT measured = bounds;
667 PrepareAndMeasureText(text, str, measured, x, y);
669 DoTextRotation(text, bounds, measured);
670 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
671 NanoVGSetBlendMode(mVG, pBlend);
672 nvgText(mVG, x, y, str, NULL);
673 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
680 switch (options.mCapOption)
682 case ELineCap::Butt: nvgLineCap(mVG, NVG_BUTT);
break;
683 case ELineCap::Round: nvgLineCap(mVG, NVG_ROUND);
break;
684 case ELineCap::Square: nvgLineCap(mVG, NVG_SQUARE);
break;
687 switch (options.mJoinOption)
689 case ELineJoin::Miter: nvgLineJoin(mVG, NVG_MITER);
break;
690 case ELineJoin::Round: nvgLineJoin(mVG, NVG_ROUND);
break;
691 case ELineJoin::Bevel: nvgLineJoin(mVG, NVG_BEVEL);
break;
694 nvgMiterLimit(mVG, options.mMiterLimit);
695 nvgStrokeWidth(mVG, thickness);
698 if (pattern.mType == EPatternType::Solid)
699 nvgStrokeColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
701 nvgStrokePaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
703 nvgPathWinding(mVG, NVG_CCW);
704 NanoVGSetBlendMode(mVG, pBlend);
706 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
708 if (!options.mPreserve)
714 switch(options.mFillRule)
719 case EFillRule::Winding:
720 nvgPathWinding(mVG, NVG_CCW);
722 case EFillRule::EvenOdd:
723 nvgPathWinding(mVG, NVG_CW);
725 case EFillRule::Preserve:
731 if (pattern.mType == EPatternType::Solid)
732 nvgFillColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
734 nvgFillPaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
736 NanoVGSetBlendMode(mVG, pBlend);
738 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
740 if (!options.mPreserve)
746 StaticStorage<IFontData>::Accessor storage(sFontCache);
747 IFontData* cached = storage.Find(fontID);
751 nvgCreateFontFaceMem(mVG, fontID, cached->Get(), cached->GetSize(), cached->GetFaceIdx(), 0);
755 IFontDataPtr data = font->GetFontData();
757 if (data->IsValid() && nvgCreateFontFaceMem(mVG, fontID, data->Get(), data->GetSize(), data->GetFaceIdx(), 0) != -1)
759 storage.Add(data.release(), fontID);
766void IGraphicsNanoVG::UpdateLayer()
774 nvgBindFramebuffer(mMainFrameBuffer);
782 glViewport(0, 0, mLayers.top()->Bounds().W() * scale, mLayers.top()->Bounds().H() * scale);
784 nvgBindFramebuffer(
dynamic_cast<const Bitmap*
>(mLayers.top()->GetAPIBitmap())->GetFBO());
789void IGraphicsNanoVG::PathTransformSetMatrix(
const IMatrix& m)
791 double xTranslate = 0.0;
792 double yTranslate = 0.0;
794 if (!mLayers.empty())
796 IRECT bounds = mLayers.top()->Bounds();
798 xTranslate = -bounds.L;
799 yTranslate = -bounds.T;
802 nvgResetTransform(mVG);
804 nvgTranslate(mVG, xTranslate, yTranslate);
805 nvgTransform(mVG, m.mXX, m.mYX, m.mXY, m.mYY, m.mTX, m.mTY);
808void IGraphicsNanoVG::SetClipRegion(
const IRECT& r)
810 nvgScissor(mVG, r.L, r.T, r.
W(), r.
H());
815 const float xd = x1 - x2;
816 const float yd = y1 - y2;
817 const float len = std::sqrt(xd * xd + yd * yd);
819 const float segs = std::round(len / dashLen);
820 const float incr = 1.f / segs;
827 for (
int i = 1; i < static_cast<int>(segs); i+=2)
829 float progress = incr *
static_cast<float>(i);
831 float xe = x1 + progress * (x2 - x1);
832 float ye = y1 + progress * (y2 - y1);
838 xs = x1 + progress * (x2 - x1);
839 ys = y1 + progress * (y2 - y1);
849 const int xsegs =
static_cast<int>(std::ceil(bounds.
W() / (dashLen * 2.f)));
850 const int ysegs =
static_cast<int>(std::ceil(bounds.
H() / (dashLen * 2.f)));
860 for(
int j = 0; j < 2; j++)
862 for (
int i = 0; i < xsegs; i++)
864 x2 =
Clip(x1 + dashLen, bounds.L, bounds.R);
866 x1 =
Clip(x2 + dashLen, bounds.L, bounds.R);
872 for (
int i = 0; i < ysegs; i++)
874 y2 =
Clip(y1 + dashLen, bounds.T, bounds.B);
876 y1 =
Clip(y2 + dashLen, bounds.T, bounds.B);
888void IGraphicsNanoVG::DeleteFBO(NVGframebuffer* pBuffer)
891 nvgDeleteFramebuffer(pBuffer);
894 WDL_MutexLock lock(&mFBOMutex);
895 mFBOStack.push(pBuffer);
899void IGraphicsNanoVG::ClearFBOStack()
901 WDL_MutexLock lock(&mFBOMutex);
902 while (!mFBOStack.empty())
904 nvgDeleteFramebuffer(mFBOStack.top());
911 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));
913 nvgRect(mVG, outerBounds.L, outerBounds.T, outerBounds.
W(), outerBounds.
H());
914 nvgFillPaint(mVG, shadowPaint);
915 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
923 nvgFontSize(mVG, text.mSize);
924 nvgFontFace(mVG, text.mFont);
926 float x = 0.0, y = 0.0;
927 const float width = bounds.
W();
929 float yOffsetScale = 0.0;
933 case EAlign::Near: align = NVG_ALIGN_LEFT; x = bounds.L;
break;
934 case EAlign::Center: align = NVG_ALIGN_CENTER; x = bounds.
MW();
break;
935 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = bounds.R;
break;
938 switch (text.mVAlign)
942 align |= NVG_ALIGN_TOP;
947 case EVAlign::Middle:
949 align |= NVG_ALIGN_MIDDLE;
954 case EVAlign::Bottom:
956 align |= NVG_ALIGN_BOTTOM;
963 nvgTextAlign(mVG, align);
971 nvgTextMetrics(mVG, NULL, NULL, &lineHeight);
972 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
974 for (
auto run : {0, 1})
977 end = str + strlen(str);
978 while ((nRows = nvgTextBreakLines(mVG, start, end, width, rows, 3))) {
979 for (
int i = 0; i < nRows; i++) {
986 NVGtextRow* row = &rows[i];
987 nvgText(mVG, x, y - ((lines*lineHeight)*yOffsetScale), row->start, row->end);
991 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,...