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 = 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);
483 if (mMainFrameBuffer !=
nullptr)
484 nvgDeleteFramebuffer(mMainFrameBuffer);
490 if (mMainFrameBuffer ==
nullptr)
491 DBGMSG(
"Could not init FBO.\n");
502 glClearColor(0.f, 0.f, 0.f, 0.f);
503 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
505 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mInitialFBO);
509 nvgBindFramebuffer(mMainFrameBuffer);
516 nvgBindFramebuffer(
nullptr);
522 nvgResetTransform(mVG);
523 nvgTranslate(mVG, mXTranslation, mYTranslation);
526 nvgFillPaint(mVG, img);
530#if defined OS_MAC && defined IGRAPHICS_GL
531 glBindFramebuffer(GL_FRAMEBUFFER, mInitialFBO);
550 nvgTransformScale(imgPaint.xform, scale, scale);
552 imgPaint.xform[4] = dest.L - srcX;
553 imgPaint.xform[5] = dest.T - srcY;
554 imgPaint.extent[0] = bitmap.
W() * bitmap.
GetScale();
555 imgPaint.extent[1] = bitmap.
H() * bitmap.
GetScale();
556 imgPaint.image = pAPIBitmap->
GetBitmap();
557 imgPaint.radius = imgPaint.feather = 0.f;
558 imgPaint.innerColor = imgPaint.outerColor = nvgRGBAf(1, 1, 1,
BlendWeight(pBlend));
563 nvgRect(mVG, dest.L, dest.T, dest.
W(), dest.
H());
564 nvgFillPaint(mVG, imgPaint);
565 NanoVGSetBlendMode(mVG, pBlend);
567 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
583 nvgArc(mVG, cx, cy, r, DegToRad(a1 - 90.f), DegToRad(a2 - 90.f), winding == EWinding::CW ? NVG_CW : NVG_CCW);
588 nvgMoveTo(mVG, x, y);
593 nvgLineTo(mVG, x, y);
598 nvgBezierTo(mVG, c1x, c1y, c2x, c2y, x2, y2);
603 nvgQuadTo(mVG, cx, cy, x2, y2);
608 nvgPathWinding(mVG, clockwise ? NVG_CW : NVG_CCW);
616void IGraphicsNanoVG::PrepareAndMeasureText(
const IText& text,
const char* str,
IRECT& r,
double& x,
double & y)
const
620 assert(nvgFindFont(mVG, text.mFont) != -1 &&
"No font found - did you forget to load it?");
623 nvgFontSize(mVG, text.mSize);
624 nvgFontFace(mVG, text.mFont);
630 case EAlign::Near: align = NVG_ALIGN_LEFT; x = r.L;
break;
631 case EAlign::Center: align = NVG_ALIGN_CENTER; x = r.
MW();
break;
632 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = r.R;
break;
635 switch (text.mVAlign)
637 case EVAlign::Top: align |= NVG_ALIGN_TOP; y = r.T;
break;
638 case EVAlign::Middle: align |= NVG_ALIGN_MIDDLE; y = r.
MH();
break;
639 case EVAlign::Bottom: align |= NVG_ALIGN_BOTTOM; y = r.B;
break;
642 nvgTextAlign(mVG, align);
643 nvgTextBounds(mVG, x, y, str, NULL, fbounds);
645 r =
IRECT(fbounds[0], fbounds[1], fbounds[2], fbounds[3]);
652 PrepareAndMeasureText(text, str, bounds, x, y);
660 IRECT measured = bounds;
663 PrepareAndMeasureText(text, str, measured, x, y);
665 DoTextRotation(text, bounds, measured);
666 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
667 NanoVGSetBlendMode(mVG, pBlend);
668 nvgText(mVG, x, y, str, NULL);
669 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
676 switch (options.mCapOption)
678 case ELineCap::Butt: nvgLineCap(mVG, NVG_BUTT);
break;
679 case ELineCap::Round: nvgLineCap(mVG, NVG_ROUND);
break;
680 case ELineCap::Square: nvgLineCap(mVG, NVG_SQUARE);
break;
683 switch (options.mJoinOption)
685 case ELineJoin::Miter: nvgLineJoin(mVG, NVG_MITER);
break;
686 case ELineJoin::Round: nvgLineJoin(mVG, NVG_ROUND);
break;
687 case ELineJoin::Bevel: nvgLineJoin(mVG, NVG_BEVEL);
break;
690 nvgMiterLimit(mVG, options.mMiterLimit);
691 nvgStrokeWidth(mVG, thickness);
694 if (pattern.mType == EPatternType::Solid)
695 nvgStrokeColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
697 nvgStrokePaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
699 nvgPathWinding(mVG, NVG_CCW);
700 NanoVGSetBlendMode(mVG, pBlend);
702 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
704 if (!options.mPreserve)
710 switch(options.mFillRule)
715 case EFillRule::Winding:
716 nvgPathWinding(mVG, NVG_CCW);
718 case EFillRule::EvenOdd:
719 nvgPathWinding(mVG, NVG_CW);
721 case EFillRule::Preserve:
727 if (pattern.mType == EPatternType::Solid)
728 nvgFillColor(mVG, NanoVGColor(pattern.
GetStop(0).mColor, pBlend));
730 nvgFillPaint(mVG, NanoVGPaint(mVG, pattern, pBlend));
732 NanoVGSetBlendMode(mVG, pBlend);
734 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
736 if (!options.mPreserve)
742 StaticStorage<IFontData>::Accessor storage(sFontCache);
743 IFontData* cached = storage.Find(fontID);
747 nvgCreateFontFaceMem(mVG, fontID, cached->Get(), cached->GetSize(), cached->GetFaceIdx(), 0);
751 IFontDataPtr data = font->GetFontData();
753 if (data->IsValid() && nvgCreateFontFaceMem(mVG, fontID, data->Get(), data->GetSize(), data->GetFaceIdx(), 0) != -1)
755 storage.Add(data.release(), fontID);
762void IGraphicsNanoVG::UpdateLayer()
770 nvgBindFramebuffer(mMainFrameBuffer);
778 glViewport(0, 0, mLayers.top()->Bounds().W() * scale, mLayers.top()->Bounds().H() * scale);
780 nvgBindFramebuffer(
dynamic_cast<const Bitmap*
>(mLayers.top()->GetAPIBitmap())->GetFBO());
785void IGraphicsNanoVG::PathTransformSetMatrix(
const IMatrix& m)
787 double xTranslate = 0.0;
788 double yTranslate = 0.0;
790 if (!mLayers.empty())
792 IRECT bounds = mLayers.top()->Bounds();
794 xTranslate = -bounds.L;
795 yTranslate = -bounds.T;
798 nvgResetTransform(mVG);
800 nvgTranslate(mVG, xTranslate, yTranslate);
801 nvgTransform(mVG, m.mXX, m.mYX, m.mXY, m.mYY, m.mTX, m.mTY);
804void IGraphicsNanoVG::SetClipRegion(
const IRECT& r)
806 nvgScissor(mVG, r.L, r.T, r.
W(), r.
H());
811 const float xd = x1 - x2;
812 const float yd = y1 - y2;
813 const float len = std::sqrt(xd * xd + yd * yd);
815 const float segs = std::round(len / dashLen);
816 const float incr = 1.f / segs;
823 for (
int i = 1; i < static_cast<int>(segs); i+=2)
825 float progress = incr *
static_cast<float>(i);
827 float xe = x1 + progress * (x2 - x1);
828 float ye = y1 + progress * (y2 - y1);
834 xs = x1 + progress * (x2 - x1);
835 ys = y1 + progress * (y2 - y1);
845 const int xsegs =
static_cast<int>(std::ceil(bounds.
W() / (dashLen * 2.f)));
846 const int ysegs =
static_cast<int>(std::ceil(bounds.
H() / (dashLen * 2.f)));
856 for(
int j = 0; j < 2; j++)
858 for (
int i = 0; i < xsegs; i++)
860 x2 =
Clip(x1 + dashLen, bounds.L, bounds.R);
862 x1 =
Clip(x2 + dashLen, bounds.L, bounds.R);
868 for (
int i = 0; i < ysegs; i++)
870 y2 =
Clip(y1 + dashLen, bounds.T, bounds.B);
872 y1 =
Clip(y2 + dashLen, bounds.T, bounds.B);
884void IGraphicsNanoVG::DeleteFBO(NVGframebuffer* pBuffer)
887 nvgDeleteFramebuffer(pBuffer);
890 WDL_MutexLock lock(&mFBOMutex);
891 mFBOStack.push(pBuffer);
895void IGraphicsNanoVG::ClearFBOStack()
897 WDL_MutexLock lock(&mFBOMutex);
898 while (!mFBOStack.empty())
900 nvgDeleteFramebuffer(mFBOStack.top());
907 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));
909 nvgRect(mVG, outerBounds.L, outerBounds.T, outerBounds.
W(), outerBounds.
H());
910 nvgFillPaint(mVG, shadowPaint);
911 nvgGlobalCompositeOperation(mVG, NVG_SOURCE_OVER);
919 nvgFontSize(mVG, text.mSize);
920 nvgFontFace(mVG, text.mFont);
922 float x = 0.0, y = 0.0;
923 const float width = bounds.
W();
925 float yOffsetScale = 0.0;
929 case EAlign::Near: align = NVG_ALIGN_LEFT; x = bounds.L;
break;
930 case EAlign::Center: align = NVG_ALIGN_CENTER; x = bounds.
MW();
break;
931 case EAlign::Far: align = NVG_ALIGN_RIGHT; x = bounds.R;
break;
934 switch (text.mVAlign)
938 align |= NVG_ALIGN_TOP;
943 case EVAlign::Middle:
945 align |= NVG_ALIGN_MIDDLE;
950 case EVAlign::Bottom:
952 align |= NVG_ALIGN_BOTTOM;
959 nvgTextAlign(mVG, align);
967 nvgTextMetrics(mVG, NULL, NULL, &lineHeight);
968 nvgFillColor(mVG, NanoVGColor(text.mFGColor, pBlend));
970 for (
auto run : {0, 1})
973 end = str + strlen(str);
974 while ((nRows = nvgTextBreakLines(mVG, start, end, width, rows, 3))) {
975 for (
int i = 0; i < nRows; i++) {
982 NVGtextRow* row = &rows[i];
983 nvgText(mVG, x, y - ((lines*lineHeight)*yOffsetScale), row->start, row->end);
987 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 for a SOMETHING that uses IGraphics for it's 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 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.
void DrawMultiLineText(const IText &text, const char *str, IRECT &bounds, const IBlend *pBlend) override
Draw some multi-line text to the graphics context in a specific rectangle (NanoVG only)
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,...