mirror of
				https://github.com/Atmosphere-NX/Atmosphere.git
				synced 2025-10-31 11:15:51 +01:00 
			
		
		
		
	* Implemented a system updater homebrew (titled Daybreak) * git subrepo pull ./troposphere/daybreak/nanovg subrepo: subdir: "troposphere/daybreak/nanovg" merged: "c197ba2f" upstream: origin: "https://github.com/Adubbz/nanovg-deko.git" branch: "master" commit: "c197ba2f" git-subrepo: version: "0.4.1" origin: "???" commit: "???" (+1 squashed commits) Squashed commits: [232dc943] git subrepo clone https://github.com/Adubbz/nanovg-deko.git troposphere/daybreak/nanovg subrepo: subdir: "troposphere/daybreak/nanovg" merged: "52bb784b" upstream: origin: "https://github.com/Adubbz/nanovg-deko.git" branch: "master" commit: "52bb784b" git-subrepo: version: "0.4.1" origin: "???" commit: "???" * daybreak: switch to using hiddbg for home blocking (+1 squashed commits) Squashed commits: [4bfc7b0d] daybreak: block the home button during installation
		
			
				
	
	
		
			520 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			520 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <stdarg.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <math.h>
 | |
| 
 | |
| #include "nanovg.h"
 | |
| #include "nanovg/dk_renderer.hpp"
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| static int dknvg__maxi(int a, int b) { return a > b ? a : b; }
 | |
| 
 | |
| static const DKNVGtextureDescriptor* dknvg__findTexture(DKNVGcontext* dk, int id) {
 | |
|     return dk->renderer->GetTextureDescriptor(*dk, id);
 | |
| }
 | |
| 
 | |
| static int dknvg__renderCreate(void* uptr)
 | |
| {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     return dk->renderer->Create(*dk);
 | |
| }
 | |
| 
 | |
| static int dknvg__renderCreateTexture(void* uptr, int type, int w, int h, int imageFlags, const unsigned char* data)
 | |
| {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     return dk->renderer->CreateTexture(*dk, type, w, h, imageFlags, data);
 | |
| }
 | |
| 
 | |
| static int dknvg__renderDeleteTexture(void* uptr, int image) {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     return dk->renderer->DeleteTexture(*dk, image);
 | |
| }
 | |
| 
 | |
| static int dknvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data) {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     return dk->renderer->UpdateTexture(*dk, image, x, y, w, h, data);
 | |
| }
 | |
| 
 | |
| static int dknvg__renderGetTextureSize(void* uptr, int image, int* w, int* h) {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     return dk->renderer->GetTextureSize(*dk, image, w, h);
 | |
| }
 | |
| 
 | |
| static void dknvg__xformToMat3x4(float* m3, float* t) {
 | |
|     m3[0] = t[0];
 | |
|     m3[1] = t[1];
 | |
|     m3[2] = 0.0f;
 | |
|     m3[3] = 0.0f;
 | |
|     m3[4] = t[2];
 | |
|     m3[5] = t[3];
 | |
|     m3[6] = 0.0f;
 | |
|     m3[7] = 0.0f;
 | |
|     m3[8] = t[4];
 | |
|     m3[9] = t[5];
 | |
|     m3[10] = 1.0f;
 | |
|     m3[11] = 0.0f;
 | |
| }
 | |
| 
 | |
| static NVGcolor dknvg__premulColor(NVGcolor c) {
 | |
|     c.r *= c.a;
 | |
|     c.g *= c.a;
 | |
|     c.b *= c.a;
 | |
|     return c;
 | |
| }
 | |
| 
 | |
| static int dknvg__convertPaint(DKNVGcontext* dk, DKNVGfragUniforms* frag, NVGpaint* paint,
 | |
|                                NVGscissor* scissor, float width, float fringe, float strokeThr)
 | |
| {
 | |
|     const DKNVGtextureDescriptor *tex = NULL;
 | |
|     float invxform[6];
 | |
| 
 | |
|     memset(frag, 0, sizeof(*frag));
 | |
| 
 | |
|     frag->innerCol = dknvg__premulColor(paint->innerColor);
 | |
|     frag->outerCol = dknvg__premulColor(paint->outerColor);
 | |
| 
 | |
|     if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) {
 | |
|         memset(frag->scissorMat, 0, sizeof(frag->scissorMat));
 | |
|         frag->scissorExt[0] = 1.0f;
 | |
|         frag->scissorExt[1] = 1.0f;
 | |
|         frag->scissorScale[0] = 1.0f;
 | |
|         frag->scissorScale[1] = 1.0f;
 | |
|     } else {
 | |
|         nvgTransformInverse(invxform, scissor->xform);
 | |
|         dknvg__xformToMat3x4(frag->scissorMat, invxform);
 | |
|         frag->scissorExt[0] = scissor->extent[0];
 | |
|         frag->scissorExt[1] = scissor->extent[1];
 | |
|         frag->scissorScale[0] = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe;
 | |
|         frag->scissorScale[1] = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe;
 | |
|     }
 | |
| 
 | |
|     memcpy(frag->extent, paint->extent, sizeof(frag->extent));
 | |
|     frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe;
 | |
|     frag->strokeThr = strokeThr;
 | |
| 
 | |
|     if (paint->image != 0) {
 | |
|         tex = dknvg__findTexture(dk, paint->image);
 | |
|         if (tex == NULL) return 0;
 | |
|         if ((tex->flags & NVG_IMAGE_FLIPY) != 0) {
 | |
|             float m1[6], m2[6];
 | |
|             nvgTransformTranslate(m1, 0.0f, frag->extent[1] * 0.5f);
 | |
|             nvgTransformMultiply(m1, paint->xform);
 | |
|             nvgTransformScale(m2, 1.0f, -1.0f);
 | |
|             nvgTransformMultiply(m2, m1);
 | |
|             nvgTransformTranslate(m1, 0.0f, -frag->extent[1] * 0.5f);
 | |
|             nvgTransformMultiply(m1, m2);
 | |
|             nvgTransformInverse(invxform, m1);
 | |
|         } else {
 | |
|             nvgTransformInverse(invxform, paint->xform);
 | |
|         }
 | |
|         frag->type = NSVG_SHADER_FILLIMG;
 | |
| 
 | |
|         if (tex->type == NVG_TEXTURE_RGBA)
 | |
|             frag->texType = (tex->flags & NVG_IMAGE_PREMULTIPLIED) ? 0 : 1;
 | |
|         else
 | |
|             frag->texType = 2;
 | |
| //		printf("frag->texType = %d\n", frag->texType);
 | |
|     } else {
 | |
|         frag->type = NSVG_SHADER_FILLGRAD;
 | |
|         frag->radius = paint->radius;
 | |
|         frag->feather = paint->feather;
 | |
|         nvgTransformInverse(invxform, paint->xform);
 | |
|     }
 | |
| 
 | |
|     dknvg__xformToMat3x4(frag->paintMat, invxform);
 | |
| 
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| static DKNVGfragUniforms* nvg__fragUniformPtr(DKNVGcontext* dk, int i);
 | |
| 
 | |
| static void dknvg__renderViewport(void* uptr, float width, float height, float devicePixelRatio)
 | |
| {
 | |
|     NVG_NOTUSED(devicePixelRatio);
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     dk->view[0] = width;
 | |
|     dk->view[1] = height;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderCancel(void* uptr) {
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     dk->nverts = 0;
 | |
|     dk->npaths = 0;
 | |
|     dk->ncalls = 0;
 | |
|     dk->nuniforms = 0;
 | |
| }
 | |
| 
 | |
| static int dknvg_convertBlendFuncFactor(int factor) {
 | |
|     switch (factor) {
 | |
|         case NVG_ZERO:
 | |
|             return DkBlendFactor_Zero;
 | |
|         case NVG_ONE:
 | |
|             return DkBlendFactor_One;
 | |
|         case NVG_SRC_COLOR:
 | |
|             return DkBlendFactor_SrcColor;
 | |
|         case NVG_ONE_MINUS_SRC_COLOR:
 | |
|             return DkBlendFactor_InvSrcColor;
 | |
|         case NVG_DST_COLOR:
 | |
|             return DkBlendFactor_DstColor;
 | |
|         case NVG_ONE_MINUS_DST_COLOR:
 | |
|             return DkBlendFactor_InvDstColor;
 | |
|         case NVG_SRC_ALPHA:
 | |
|             return DkBlendFactor_SrcAlpha;
 | |
|         case NVG_ONE_MINUS_SRC_ALPHA:
 | |
|             return DkBlendFactor_InvSrcAlpha;
 | |
|         case NVG_DST_ALPHA:
 | |
|             return DkBlendFactor_DstAlpha;
 | |
|         case NVG_ONE_MINUS_DST_ALPHA:
 | |
|             return DkBlendFactor_InvDstAlpha;
 | |
|         case NVG_SRC_ALPHA_SATURATE:
 | |
|             return DkBlendFactor_SrcAlphaSaturate;
 | |
|         default:
 | |
|             return -1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static DKNVGblend dknvg__blendCompositeOperation(NVGcompositeOperationState op) {
 | |
|     DKNVGblend blend;
 | |
|     blend.srcRGB = dknvg_convertBlendFuncFactor(op.srcRGB);
 | |
|     blend.dstRGB = dknvg_convertBlendFuncFactor(op.dstRGB);
 | |
|     blend.srcAlpha = dknvg_convertBlendFuncFactor(op.srcAlpha);
 | |
|     blend.dstAlpha = dknvg_convertBlendFuncFactor(op.dstAlpha);
 | |
| 
 | |
|     if (blend.srcRGB == -1 || blend.dstRGB == -1 || blend.srcAlpha == -1 || blend.dstAlpha == -1) {
 | |
|         blend.srcRGB = DkBlendFactor_One;
 | |
|         blend.dstRGB = DkBlendFactor_InvSrcAlpha;
 | |
|         blend.srcAlpha = DkBlendFactor_One;
 | |
|         blend.dstAlpha = DkBlendFactor_InvSrcAlpha;
 | |
|     }
 | |
|     return blend;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderFlush(void* uptr) {
 | |
|     DKNVGcontext *dk = (DKNVGcontext*)uptr;
 | |
|     dk->renderer->Flush(*dk);
 | |
| }
 | |
| 
 | |
| static int dknvg__maxVertCount(const NVGpath* paths, int npaths) {
 | |
|     int i, count = 0;
 | |
|     for (i = 0; i < npaths; i++) {
 | |
|         count += paths[i].nfill;
 | |
|         count += paths[i].nstroke;
 | |
|     }
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| static DKNVGcall* dknvg__allocCall(DKNVGcontext* dk)
 | |
| {
 | |
|     DKNVGcall* ret = NULL;
 | |
|     if (dk->ncalls+1 > dk->ccalls) {
 | |
|         DKNVGcall* calls;
 | |
|         int ccalls = dknvg__maxi(dk->ncalls+1, 128) + dk->ccalls/2; // 1.5x Overallocate
 | |
|         calls = (DKNVGcall*)realloc(dk->calls, sizeof(DKNVGcall) * ccalls);
 | |
|         if (calls == NULL) return NULL;
 | |
|         dk->calls = calls;
 | |
|         dk->ccalls = ccalls;
 | |
|     }
 | |
|     ret = &dk->calls[dk->ncalls++];
 | |
|     memset(ret, 0, sizeof(DKNVGcall));
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static int dknvg__allocPaths(DKNVGcontext* dk, int n)
 | |
| {
 | |
|     int ret = 0;
 | |
|     if (dk->npaths+n > dk->cpaths) {
 | |
|         DKNVGpath* paths;
 | |
|         int cpaths = dknvg__maxi(dk->npaths + n, 128) + dk->cpaths/2; // 1.5x Overallocate
 | |
|         paths = (DKNVGpath*)realloc(dk->paths, sizeof(DKNVGpath) * cpaths);
 | |
|         if (paths == NULL) return -1;
 | |
|         dk->paths = paths;
 | |
|         dk->cpaths = cpaths;
 | |
|     }
 | |
|     ret = dk->npaths;
 | |
|     dk->npaths += n;
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static int dknvg__allocVerts(DKNVGcontext* dk, int n)
 | |
| {
 | |
|     int ret = 0;
 | |
|     if (dk->nverts+n > dk->cverts) {
 | |
|         NVGvertex* verts;
 | |
|         int cverts = dknvg__maxi(dk->nverts + n, 4096) + dk->cverts/2; // 1.5x Overallocate
 | |
|         verts = (NVGvertex*)realloc(dk->verts, sizeof(NVGvertex) * cverts);
 | |
|         if (verts == NULL) return -1;
 | |
|         dk->verts = verts;
 | |
|         dk->cverts = cverts;
 | |
|     }
 | |
|     ret = dk->nverts;
 | |
|     dk->nverts += n;
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static int dknvg__allocFragUniforms(DKNVGcontext* dk, int n)
 | |
| {
 | |
|     int ret = 0, structSize = dk->fragSize;
 | |
|     if (dk->nuniforms+n > dk->cuniforms) {
 | |
|         unsigned char* uniforms;
 | |
|         int cuniforms = dknvg__maxi(dk->nuniforms+n, 128) + dk->cuniforms/2; // 1.5x Overallocate
 | |
|         uniforms = (unsigned char*)realloc(dk->uniforms, structSize * cuniforms);
 | |
|         if (uniforms == NULL) return -1;
 | |
|         dk->uniforms = uniforms;
 | |
|         dk->cuniforms = cuniforms;
 | |
|     }
 | |
|     ret = dk->nuniforms * structSize;
 | |
|     dk->nuniforms += n;
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static DKNVGfragUniforms* nvg__fragUniformPtr(DKNVGcontext* dk, int i)
 | |
| {
 | |
|     return (DKNVGfragUniforms*)&dk->uniforms[i];
 | |
| }
 | |
| 
 | |
| static void dknvg__vset(NVGvertex* vtx, float x, float y, float u, float v)
 | |
| {
 | |
|     vtx->x = x;
 | |
|     vtx->y = y;
 | |
|     vtx->u = u;
 | |
|     vtx->v = v;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderFill(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
 | |
|                               const float* bounds, const NVGpath* paths, int npaths)
 | |
| {
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     DKNVGcall* call = dknvg__allocCall(dk);
 | |
|     NVGvertex* quad;
 | |
|     DKNVGfragUniforms* frag;
 | |
|     int i, maxverts, offset;
 | |
| 
 | |
|     if (call == NULL) return;
 | |
| 
 | |
|     call->type = DKNVG_FILL;
 | |
|     call->triangleCount = 4;
 | |
|     call->pathOffset = dknvg__allocPaths(dk, npaths);
 | |
|     if (call->pathOffset == -1) goto error;
 | |
|     call->pathCount = npaths;
 | |
|     call->image = paint->image;
 | |
|     call->blendFunc = dknvg__blendCompositeOperation(compositeOperation);
 | |
| 
 | |
|     if (npaths == 1 && paths[0].convex)
 | |
|     {
 | |
|         call->type = DKNVG_CONVEXFILL;
 | |
|         call->triangleCount = 0;	// Bounding box fill quad not needed for convex fill
 | |
|     }
 | |
| 
 | |
|     // Allocate vertices for all the paths.
 | |
|     maxverts = dknvg__maxVertCount(paths, npaths) + call->triangleCount;
 | |
|     offset = dknvg__allocVerts(dk, maxverts);
 | |
|     if (offset == -1) goto error;
 | |
| 
 | |
|     for (i = 0; i < npaths; i++) {
 | |
|         DKNVGpath* copy = &dk->paths[call->pathOffset + i];
 | |
|         const NVGpath* path = &paths[i];
 | |
|         memset(copy, 0, sizeof(DKNVGpath));
 | |
|         if (path->nfill > 0) {
 | |
|             copy->fillOffset = offset;
 | |
|             copy->fillCount = path->nfill;
 | |
|             memcpy(&dk->verts[offset], path->fill, sizeof(NVGvertex) * path->nfill);
 | |
|             offset += path->nfill;
 | |
|         }
 | |
|         if (path->nstroke > 0) {
 | |
|             copy->strokeOffset = offset;
 | |
|             copy->strokeCount = path->nstroke;
 | |
|             memcpy(&dk->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
 | |
|             offset += path->nstroke;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Setup uniforms for draw calls
 | |
|     if (call->type == DKNVG_FILL) {
 | |
|         // Quad
 | |
|         call->triangleOffset = offset;
 | |
|         quad = &dk->verts[call->triangleOffset];
 | |
|         dknvg__vset(&quad[0], bounds[2], bounds[3], 0.5f, 1.0f);
 | |
|         dknvg__vset(&quad[1], bounds[2], bounds[1], 0.5f, 1.0f);
 | |
|         dknvg__vset(&quad[2], bounds[0], bounds[3], 0.5f, 1.0f);
 | |
|         dknvg__vset(&quad[3], bounds[0], bounds[1], 0.5f, 1.0f);
 | |
| 
 | |
|         call->uniformOffset = dknvg__allocFragUniforms(dk, 2);
 | |
|         if (call->uniformOffset == -1) goto error;
 | |
|         // Simple shader for stencil
 | |
|         frag = nvg__fragUniformPtr(dk, call->uniformOffset);
 | |
|         memset(frag, 0, sizeof(*frag));
 | |
|         frag->strokeThr = -1.0f;
 | |
|         frag->type = NSVG_SHADER_SIMPLE;
 | |
|         // Fill shader
 | |
|         dknvg__convertPaint(dk, nvg__fragUniformPtr(dk, call->uniformOffset + dk->fragSize), paint, scissor, fringe, fringe, -1.0f);
 | |
|     } else {
 | |
|         call->uniformOffset = dknvg__allocFragUniforms(dk, 1);
 | |
|         if (call->uniformOffset == -1) goto error;
 | |
|         // Fill shader
 | |
|         dknvg__convertPaint(dk, nvg__fragUniformPtr(dk, call->uniformOffset), paint, scissor, fringe, fringe, -1.0f);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| 
 | |
| error:
 | |
|     // We get here if call alloc was ok, but something else is not.
 | |
|     // Roll back the last call to prevent drawing it.
 | |
|     if (dk->ncalls > 0) dk->ncalls--;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderStroke(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor, float fringe,
 | |
|                                 float strokeWidth, const NVGpath* paths, int npaths)
 | |
| {
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     DKNVGcall* call = dknvg__allocCall(dk);
 | |
|     int i, maxverts, offset;
 | |
| 
 | |
|     if (call == NULL) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     call->type = DKNVG_STROKE;
 | |
|     call->pathOffset = dknvg__allocPaths(dk, npaths);
 | |
|     if (call->pathOffset == -1) goto error;
 | |
|     call->pathCount = npaths;
 | |
|     call->image = paint->image;
 | |
|     call->blendFunc = dknvg__blendCompositeOperation(compositeOperation);
 | |
| 
 | |
|     // Allocate vertices for all the paths.
 | |
|     maxverts = dknvg__maxVertCount(paths, npaths);
 | |
|     offset = dknvg__allocVerts(dk, maxverts);
 | |
|     if (offset == -1) goto error;
 | |
| 
 | |
|     for (i = 0; i < npaths; i++) {
 | |
|         DKNVGpath* copy = &dk->paths[call->pathOffset + i];
 | |
|         const NVGpath* path = &paths[i];
 | |
|         memset(copy, 0, sizeof(DKNVGpath));
 | |
|         if (path->nstroke) {
 | |
|             copy->strokeOffset = offset;
 | |
|             copy->strokeCount = path->nstroke;
 | |
|             memcpy(&dk->verts[offset], path->stroke, sizeof(NVGvertex) * path->nstroke);
 | |
|             offset += path->nstroke;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (dk->flags & NVG_STENCIL_STROKES) {
 | |
|         // Fill shader
 | |
|         call->uniformOffset = dknvg__allocFragUniforms(dk, 2);
 | |
|         if (call->uniformOffset == -1) goto error;
 | |
| 
 | |
|         dknvg__convertPaint(dk, nvg__fragUniformPtr(dk, call->uniformOffset), paint, scissor, strokeWidth, fringe, -1.0f);
 | |
|         dknvg__convertPaint(dk, nvg__fragUniformPtr(dk, call->uniformOffset + dk->fragSize), paint, scissor, strokeWidth, fringe, 1.0f - 0.5f/255.0f);
 | |
|     } else {
 | |
|         // Fill shader
 | |
|         call->uniformOffset = dknvg__allocFragUniforms(dk, 1);
 | |
|         if (call->uniformOffset == -1) goto error;
 | |
| 
 | |
|         dknvg__convertPaint(dk, nvg__fragUniformPtr(dk, call->uniformOffset), paint, scissor, strokeWidth, fringe, -1.0f);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| 
 | |
| error:
 | |
|     // We get here if call alloc was ok, but something else is not.
 | |
|     // Roll back the last call to prevent drawing it.
 | |
|     if (dk->ncalls > 0) dk->ncalls--;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderTriangles(void* uptr, NVGpaint* paint, NVGcompositeOperationState compositeOperation, NVGscissor* scissor,
 | |
|                                    const NVGvertex* verts, int nverts, float fringe)
 | |
| {
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     DKNVGcall* call = dknvg__allocCall(dk);
 | |
|     DKNVGfragUniforms* frag;
 | |
| 
 | |
|     if (call == NULL) return;
 | |
| 
 | |
|     call->type = DKNVG_TRIANGLES;
 | |
|     call->image = paint->image;
 | |
|     call->blendFunc = dknvg__blendCompositeOperation(compositeOperation);
 | |
| 
 | |
|     // Allocate vertices for all the paths.
 | |
|     call->triangleOffset = dknvg__allocVerts(dk, nverts);
 | |
|     if (call->triangleOffset == -1) goto error;
 | |
|     call->triangleCount = nverts;
 | |
| 
 | |
|     memcpy(&dk->verts[call->triangleOffset], verts, sizeof(NVGvertex) * nverts);
 | |
| 
 | |
|     // Fill shader
 | |
|     call->uniformOffset = dknvg__allocFragUniforms(dk, 1);
 | |
|     if (call->uniformOffset == -1) goto error;
 | |
|     frag = nvg__fragUniformPtr(dk, call->uniformOffset);
 | |
|     dknvg__convertPaint(dk, frag, paint, scissor, 1.0f, fringe, -1.0f);
 | |
|     frag->type = NSVG_SHADER_IMG;
 | |
| 
 | |
|     return;
 | |
| 
 | |
| error:
 | |
|     // We get here if call alloc was ok, but something else is not.
 | |
|     // Roll back the last call to prevent drawing it.
 | |
|     if (dk->ncalls > 0) dk->ncalls--;
 | |
| }
 | |
| 
 | |
| static void dknvg__renderDelete(void* uptr) {
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)uptr;
 | |
|     if (dk == NULL) return;
 | |
| 
 | |
|     free(dk->paths);
 | |
|     free(dk->verts);
 | |
|     free(dk->uniforms);
 | |
|     free(dk->calls);
 | |
| 
 | |
|     free(dk);
 | |
| }
 | |
| 
 | |
| NVGcontext* nvgCreateDk(nvg::DkRenderer *renderer, int flags) {
 | |
|     NVGparams params;
 | |
|     NVGcontext* ctx = NULL;
 | |
|     DKNVGcontext* dk = (DKNVGcontext*)malloc(sizeof(DKNVGcontext));
 | |
|     if (dk == NULL) goto error;
 | |
|     memset(dk, 0, sizeof(DKNVGcontext));
 | |
| 
 | |
|     memset(¶ms, 0, sizeof(params));
 | |
|     params.renderCreate = dknvg__renderCreate;
 | |
|     params.renderCreateTexture = dknvg__renderCreateTexture;
 | |
|     params.renderDeleteTexture = dknvg__renderDeleteTexture;
 | |
|     params.renderUpdateTexture = dknvg__renderUpdateTexture;
 | |
|     params.renderGetTextureSize = dknvg__renderGetTextureSize;
 | |
|     params.renderViewport = dknvg__renderViewport;
 | |
|     params.renderCancel = dknvg__renderCancel;
 | |
|     params.renderFlush = dknvg__renderFlush;
 | |
|     params.renderFill = dknvg__renderFill;
 | |
|     params.renderStroke = dknvg__renderStroke;
 | |
|     params.renderTriangles = dknvg__renderTriangles;
 | |
|     params.renderDelete = dknvg__renderDelete;
 | |
|     params.userPtr = dk;
 | |
|     params.edgeAntiAlias = flags & NVG_ANTIALIAS ? 1 : 0;
 | |
| 
 | |
|     dk->renderer = renderer;
 | |
|     dk->flags = flags;
 | |
| 
 | |
|     ctx = nvgCreateInternal(¶ms);
 | |
|     if (ctx == NULL) goto error;
 | |
| 
 | |
|     return ctx;
 | |
| 
 | |
| error:
 | |
|     // 'dk' is freed by nvgDeleteInternal.
 | |
|     if (ctx != NULL) nvgDeleteInternal(ctx);
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| void nvgDeleteDk(NVGcontext* ctx)
 | |
| {
 | |
|     nvgDeleteInternal(ctx);
 | |
| }
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif |