From 1cda6159c7f171f5d7c8a623a4719a4642871938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sat, 26 Apr 2014 23:50:11 -0700 Subject: [PATCH] Added 20-nanovg example. --- examples/20-nanovg/nanovg.cpp | 1109 +++++++++ examples/20-nanovg/screenshot.png | Bin 0 -> 107871 bytes examples/common/nanovg/fontstash.h | 1668 +++++++++++++ examples/common/nanovg/fs_nanovg_fill.bin.h | 513 ++++ examples/common/nanovg/fs_nanovg_fill.sc | 89 + examples/common/nanovg/makefile | 9 + examples/common/nanovg/nanovg.cpp | 2399 +++++++++++++++++++ examples/common/nanovg/nanovg.h | 550 +++++ examples/common/nanovg/nanovg_bgfx.cpp | 1010 ++++++++ examples/common/nanovg/varying.def.sc | 5 + examples/common/nanovg/vs_nanovg_fill.bin.h | 122 + examples/common/nanovg/vs_nanovg_fill.sc | 11 + examples/makefile | 2 + examples/runtime/font/entypo.ttf | Bin 0 -> 35392 bytes examples/runtime/font/roboto-bold.ttf | Bin 0 -> 135820 bytes examples/runtime/font/roboto-regular.ttf | Bin 0 -> 145348 bytes examples/runtime/images/image1.jpg | Bin 0 -> 25760 bytes examples/runtime/images/image10.jpg | Bin 0 -> 3439 bytes examples/runtime/images/image11.jpg | Bin 0 -> 3818 bytes examples/runtime/images/image12.jpg | Bin 0 -> 5452 bytes examples/runtime/images/image2.jpg | Bin 0 -> 24091 bytes examples/runtime/images/image3.jpg | Bin 0 -> 29282 bytes examples/runtime/images/image4.jpg | Bin 0 -> 23830 bytes examples/runtime/images/image5.jpg | Bin 0 -> 27131 bytes examples/runtime/images/image6.jpg | Bin 0 -> 25116 bytes examples/runtime/images/image7.jpg | Bin 0 -> 25590 bytes examples/runtime/images/image8.jpg | Bin 0 -> 24607 bytes examples/runtime/images/image9.jpg | Bin 0 -> 4035 bytes premake/premake4.lua | 1 + 29 files changed, 7488 insertions(+) create mode 100644 examples/20-nanovg/nanovg.cpp create mode 100644 examples/20-nanovg/screenshot.png create mode 100644 examples/common/nanovg/fontstash.h create mode 100644 examples/common/nanovg/fs_nanovg_fill.bin.h create mode 100644 examples/common/nanovg/fs_nanovg_fill.sc create mode 100644 examples/common/nanovg/makefile create mode 100644 examples/common/nanovg/nanovg.cpp create mode 100644 examples/common/nanovg/nanovg.h create mode 100644 examples/common/nanovg/nanovg_bgfx.cpp create mode 100644 examples/common/nanovg/varying.def.sc create mode 100644 examples/common/nanovg/vs_nanovg_fill.bin.h create mode 100644 examples/common/nanovg/vs_nanovg_fill.sc create mode 100644 examples/runtime/font/entypo.ttf create mode 100644 examples/runtime/font/roboto-bold.ttf create mode 100644 examples/runtime/font/roboto-regular.ttf create mode 100644 examples/runtime/images/image1.jpg create mode 100644 examples/runtime/images/image10.jpg create mode 100644 examples/runtime/images/image11.jpg create mode 100644 examples/runtime/images/image12.jpg create mode 100644 examples/runtime/images/image2.jpg create mode 100644 examples/runtime/images/image3.jpg create mode 100644 examples/runtime/images/image4.jpg create mode 100644 examples/runtime/images/image5.jpg create mode 100644 examples/runtime/images/image6.jpg create mode 100644 examples/runtime/images/image7.jpg create mode 100644 examples/runtime/images/image8.jpg create mode 100644 examples/runtime/images/image9.jpg diff --git a/examples/20-nanovg/nanovg.cpp b/examples/20-nanovg/nanovg.cpp new file mode 100644 index 00000000..f147fad4 --- /dev/null +++ b/examples/20-nanovg/nanovg.cpp @@ -0,0 +1,1109 @@ +/* + * Copyright 2011-2014 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +// +// Copyright (c) 2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include "common.h" + +#include +#include + +#include +#include +#include +#include "entry/entry.h" +#include "nanovg/nanovg.h" + +#define ICON_SEARCH 0x1F50D +#define ICON_CIRCLED_CROSS 0x2716 +#define ICON_CHEVRON_RIGHT 0xE75E +#define ICON_CHECK 0x2713 +#define ICON_LOGIN 0xE740 +#define ICON_TRASH 0xE729 + +// Returns 1 if col.rgba is 0.0f,0.0f,0.0f,0.0f, 0 otherwise +int isBlack( struct NVGcolor col ) +{ + if( col.r == 0.0f && col.g == 0.0f && col.b == 0.0f && col.a == 0.0f ) + { + return 1; + } + return 0; +} + +static char* cpToUTF8(int cp, char* str) +{ + int n = 0; + if (cp < 0x80) n = 1; + else if (cp < 0x800) n = 2; + else if (cp < 0x10000) n = 3; + else if (cp < 0x200000) n = 4; + else if (cp < 0x4000000) n = 5; + else if (cp <= 0x7fffffff) n = 6; + str[n] = '\0'; + switch (n) + { + case 6: str[5] = 0x80 | (cp & 0x3f); cp = cp >> 6; cp |= 0x4000000; + case 5: str[4] = 0x80 | (cp & 0x3f); cp = cp >> 6; cp |= 0x200000; + case 4: str[3] = 0x80 | (cp & 0x3f); cp = cp >> 6; cp |= 0x10000; + case 3: str[2] = 0x80 | (cp & 0x3f); cp = cp >> 6; cp |= 0x800; + case 2: str[1] = 0x80 | (cp & 0x3f); cp = cp >> 6; cp |= 0xc0; + case 1: str[0] = cp; + } + return str; +} + + +void drawWindow(struct NVGcontext* vg, const char* title, float x, float y, float w, float h) +{ + float cornerRadius = 3.0f; + struct NVGpaint shadowPaint; + struct NVGpaint headerPaint; + + nvgSave(vg); + // nvgClearState(vg); + + // Window + nvgBeginPath(vg); + nvgRoundedRect(vg, x,y, w,h, cornerRadius); + nvgFillColor(vg, nvgRGBA(28,30,34,192)); + // nvgFillColor(vg, nvgRGBA(0,0,0,128)); + nvgFill(vg); + + // Drop shadow + shadowPaint = nvgBoxGradient(vg, x,y+2, w,h, cornerRadius*2, 10, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, x-10,y-10, w+20,h+30); + nvgRoundedRect(vg, x,y, w,h, cornerRadius); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, shadowPaint); + nvgFill(vg); + + // Header + headerPaint = nvgLinearGradient(vg, x,y,x,y+15, nvgRGBA(255,255,255,8), nvgRGBA(0,0,0,16)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+1,y+1, w-2,30, cornerRadius-1); + nvgFillPaint(vg, headerPaint); + nvgFill(vg); + nvgBeginPath(vg); + nvgMoveTo(vg, x+0.5f, y+0.5f+30); + nvgLineTo(vg, x+0.5f+w-1, y+0.5f+30); + nvgStrokeColor(vg, nvgRGBA(0,0,0,32)); + nvgStroke(vg); + + nvgFontSize(vg, 18.0f); + nvgFontFace(vg, "sans-bold"); + nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); + + nvgFontBlur(vg,2); + nvgFillColor(vg, nvgRGBA(0,0,0,128)); + nvgText(vg, x+w/2,y+16+1, title, NULL); + + nvgFontBlur(vg,0); + nvgFillColor(vg, nvgRGBA(220,220,220,160)); + nvgText(vg, x+w/2,y+16, title, NULL); + + nvgRestore(vg); +} + +void drawSearchBox(struct NVGcontext* vg, const char* text, float x, float y, float w, float h) +{ + struct NVGpaint bg; + char icon[8]; + float cornerRadius = h/2-1; + + // Edit + bg = nvgBoxGradient(vg, x,y+1.5f, w,h, h/2,5, nvgRGBA(0,0,0,16), nvgRGBA(0,0,0,92)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x,y, w,h, cornerRadius); + nvgFillPaint(vg, bg); + nvgFill(vg); + + /* nvgBeginPath(vg); + nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, cornerRadius-0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,48)); + nvgStroke(vg);*/ + + nvgFontSize(vg, h*1.3f); + nvgFontFace(vg, "icons"); + nvgFillColor(vg, nvgRGBA(255,255,255,64)); + nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); + nvgText(vg, x+h*0.55f, y+h*0.55f, cpToUTF8(ICON_SEARCH,icon), NULL); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,32)); + + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+h*1.05f,y+h*0.5f,text, NULL); + + nvgFontSize(vg, h*1.3f); + nvgFontFace(vg, "icons"); + nvgFillColor(vg, nvgRGBA(255,255,255,32)); + nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); + nvgText(vg, x+w-h*0.55f, y+h*0.55f, cpToUTF8(ICON_CIRCLED_CROSS,icon), NULL); +} + +void drawDropDown(struct NVGcontext* vg, const char* text, float x, float y, float w, float h) +{ + struct NVGpaint bg; + char icon[8]; + float cornerRadius = 4.0f; + + bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,16), nvgRGBA(0,0,0,16)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+1,y+1, w-2,h-2, cornerRadius-1); + nvgFillPaint(vg, bg); + nvgFill(vg); + + nvgBeginPath(vg); + nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, cornerRadius-0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,48)); + nvgStroke(vg); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,160)); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+h*0.3f,y+h*0.5f,text, NULL); + + nvgFontSize(vg, h*1.3f); + nvgFontFace(vg, "icons"); + nvgFillColor(vg, nvgRGBA(255,255,255,64)); + nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); + nvgText(vg, x+w-h*0.5f, y+h*0.5f, cpToUTF8(ICON_CHEVRON_RIGHT,icon), NULL); +} + +void drawLabel(struct NVGcontext* vg, const char* text, float x, float y, float w, float h) +{ + NVG_NOTUSED(w); + + nvgFontSize(vg, 18.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,128)); + + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x,y+h*0.5f,text, NULL); +} + +void drawEditBoxBase(struct NVGcontext* vg, float x, float y, float w, float h) +{ + struct NVGpaint bg; + // Edit + bg = nvgBoxGradient(vg, x+1,y+1+1.5f, w-2,h-2, 3,4, nvgRGBA(255,255,255,32), nvgRGBA(32,32,32,32)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+1,y+1, w-2,h-2, 4-1); + nvgFillPaint(vg, bg); + nvgFill(vg); + + nvgBeginPath(vg); + nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, 4-0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,48)); + nvgStroke(vg); +} + +void drawEditBox(struct NVGcontext* vg, const char* text, float x, float y, float w, float h) +{ + drawEditBoxBase(vg, x,y, w,h); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,64)); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+h*0.3f,y+h*0.5f,text, NULL); +} + +void drawEditBoxNum(struct NVGcontext* vg, + const char* text, const char* units, float x, float y, float w, float h) +{ + float uw; + + drawEditBoxBase(vg, x,y, w,h); + + uw = nvgTextBounds(vg, 0,0, units, NULL, NULL); + + nvgFontSize(vg, 18.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,64)); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+w-h*0.3f,y+h*0.5f,units, NULL); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,128)); + nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+w-uw-h*0.5f,y+h*0.5f,text, NULL); +} + +void drawCheckBox(struct NVGcontext* vg, const char* text, float x, float y, float w, float h) +{ + struct NVGpaint bg; + char icon[8]; + NVG_NOTUSED(w); + + nvgFontSize(vg, 18.0f); + nvgFontFace(vg, "sans"); + nvgFillColor(vg, nvgRGBA(255,255,255,160)); + + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+28,y+h*0.5f,text, NULL); + + bg = nvgBoxGradient(vg, x+1,y+(int)(h*0.5f)-9+1, 18,18, 3,3, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,92)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+1,y+(int)(h*0.5f)-9, 18,18, 3); + nvgFillPaint(vg, bg); + nvgFill(vg); + + nvgFontSize(vg, 40); + nvgFontFace(vg, "icons"); + nvgFillColor(vg, nvgRGBA(255,255,255,128)); + nvgTextAlign(vg,NVG_ALIGN_CENTER|NVG_ALIGN_MIDDLE); + nvgText(vg, x+9+2, y+h*0.5f, cpToUTF8(ICON_CHECK,icon), NULL); +} + +void drawButton(struct NVGcontext* vg, int preicon, const char* text, float x, float y, float w, float h, struct NVGcolor col) +{ + struct NVGpaint bg; + char icon[8]; + float cornerRadius = 4.0f; + float tw = 0, iw = 0; + + bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(255,255,255,isBlack(col)?16:32), nvgRGBA(0,0,0,isBlack(col)?16:32)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+1,y+1, w-2,h-2, cornerRadius-1); + if (!isBlack(col)) { + nvgFillColor(vg, col); + nvgFill(vg); + } + nvgFillPaint(vg, bg); + nvgFill(vg); + + nvgBeginPath(vg); + nvgRoundedRect(vg, x+0.5f,y+0.5f, w-1,h-1, cornerRadius-0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,48)); + nvgStroke(vg); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans-bold"); + tw = nvgTextBounds(vg, 0,0, text, NULL, NULL); + if (preicon != 0) { + nvgFontSize(vg, h*1.3f); + nvgFontFace(vg, "icons"); + iw = nvgTextBounds(vg, 0,0, cpToUTF8(preicon,icon), NULL, NULL); + iw += h*0.15f; + } + + if (preicon != 0) { + nvgFontSize(vg, h*1.3f); + nvgFontFace(vg, "icons"); + nvgFillColor(vg, nvgRGBA(255,255,255,96)); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgText(vg, x+w*0.5f-tw*0.5f-iw*0.75f, y+h*0.5f, cpToUTF8(preicon,icon), NULL); + } + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "sans-bold"); + nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); + nvgFillColor(vg, nvgRGBA(0,0,0,160)); + nvgText(vg, x+w*0.5f-tw*0.5f+iw*0.25f,y+h*0.5f-1,text, NULL); + nvgFillColor(vg, nvgRGBA(255,255,255,160)); + nvgText(vg, x+w*0.5f-tw*0.5f+iw*0.25f,y+h*0.5f,text, NULL); +} + +void drawSlider(struct NVGcontext* vg, float pos, float x, float y, float w, float h) +{ + struct NVGpaint bg, knob; + float cy = y+(int)(h*0.5f); + float kr = (float)( (int)(h*0.25f) ); + + nvgSave(vg); + // nvgClearState(vg); + + // Slot + bg = nvgBoxGradient(vg, x,cy-2+1, w,4, 2,2, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,128)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x,cy-2, w,4, 2); + nvgFillPaint(vg, bg); + nvgFill(vg); + + // Knob Shadow + bg = nvgRadialGradient(vg, x+(int)(pos*w),cy+1, kr-3,kr+3, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, x+(int)(pos*w)-kr-5,cy-kr-5,kr*2+5+5,kr*2+5+5+3); + nvgCircle(vg, x+(int)(pos*w),cy, kr); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, bg); + nvgFill(vg); + + // Knob + knob = nvgLinearGradient(vg, x,cy-kr,x,cy+kr, nvgRGBA(255,255,255,16), nvgRGBA(0,0,0,16)); + nvgBeginPath(vg); + nvgCircle(vg, x+(int)(pos*w),cy, kr-1); + nvgFillColor(vg, nvgRGBA(40,43,48,255)); + nvgFill(vg); + nvgFillPaint(vg, knob); + nvgFill(vg); + + nvgBeginPath(vg); + nvgCircle(vg, x+(int)(pos*w),cy, kr-0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,92)); + nvgStroke(vg); + + nvgRestore(vg); +} + +void drawEyes(struct NVGcontext* vg, float x, float y, float w, float h, float mx, float my, float t) +{ + struct NVGpaint gloss, bg; + float ex = w *0.23f; + float ey = h * 0.5f; + float lx = x + ex; + float ly = y + ey; + float rx = x + w - ex; + float ry = y + ey; + float dx,dy,d; + float br = (ex < ey ? ex : ey) * 0.5f; + float blink = 1 - pow(sinf(t*0.5f),200)*0.8f; + + bg = nvgLinearGradient(vg, x,y+h*0.5f,x+w*0.1f,y+h, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,16)); + nvgBeginPath(vg); + nvgEllipse(vg, lx+3.0f,ly+16.0f, ex,ey); + nvgEllipse(vg, rx+3.0f,ry+16.0f, ex,ey); + nvgFillPaint(vg, bg); + nvgFill(vg); + + bg = nvgLinearGradient(vg, x,y+h*0.25f,x+w*0.1f,y+h, nvgRGBA(220,220,220,255), nvgRGBA(128,128,128,255)); + nvgBeginPath(vg); + nvgEllipse(vg, lx,ly, ex,ey); + nvgEllipse(vg, rx,ry, ex,ey); + nvgFillPaint(vg, bg); + nvgFill(vg); + + dx = (mx - rx) / (ex * 10); + dy = (my - ry) / (ey * 10); + d = sqrtf(dx*dx+dy*dy); + if (d > 1.0f) { + dx /= d; dy /= d; + } + dx *= ex*0.4f; + dy *= ey*0.5f; + nvgBeginPath(vg); + nvgEllipse(vg, lx+dx,ly+dy+ey*0.25f*(1-blink), br,br*blink); + nvgFillColor(vg, nvgRGBA(32,32,32,255)); + nvgFill(vg); + + dx = (mx - rx) / (ex * 10); + dy = (my - ry) / (ey * 10); + d = sqrtf(dx*dx+dy*dy); + if (d > 1.0f) { + dx /= d; dy /= d; + } + dx *= ex*0.4f; + dy *= ey*0.5f; + nvgBeginPath(vg); + nvgEllipse(vg, rx+dx,ry+dy+ey*0.25f*(1-blink), br,br*blink); + nvgFillColor(vg, nvgRGBA(32,32,32,255)); + nvgFill(vg); + + gloss = nvgRadialGradient(vg, lx-ex*0.25f,ly-ey*0.5f, ex*0.1f,ex*0.75f, nvgRGBA(255,255,255,128), nvgRGBA(255,255,255,0)); + nvgBeginPath(vg); + nvgEllipse(vg, lx,ly, ex,ey); + nvgFillPaint(vg, gloss); + nvgFill(vg); + + gloss = nvgRadialGradient(vg, rx-ex*0.25f,ry-ey*0.5f, ex*0.1f,ex*0.75f, nvgRGBA(255,255,255,128), nvgRGBA(255,255,255,0)); + nvgBeginPath(vg); + nvgEllipse(vg, rx,ry, ex,ey); + nvgFillPaint(vg, gloss); + nvgFill(vg); +} + +void drawGraph(struct NVGcontext* vg, float x, float y, float w, float h, float t) +{ + struct NVGpaint bg; + float samples[6]; + float sx[6], sy[6]; + float dx = w/5.0f; + int i; + + samples[0] = (1+sinf(t*1.2345f+cosf(t*0.33457f)*0.44f))*0.5f; + samples[1] = (1+sinf(t*0.68363f+cosf(t*1.3f)*1.55f))*0.5f; + samples[2] = (1+sinf(t*1.1642f+cosf(t*0.33457f)*1.24f))*0.5f; + samples[3] = (1+sinf(t*0.56345f+cosf(t*1.63f)*0.14f))*0.5f; + samples[4] = (1+sinf(t*1.6245f+cosf(t*0.254f)*0.3f))*0.5f; + samples[5] = (1+sinf(t*0.345f+cosf(t*0.03f)*0.6f))*0.5f; + + for (i = 0; i < 6; i++) { + sx[i] = x+i*dx; + sy[i] = y+h*samples[i]*0.8f; + } + + // Graph background + bg = nvgLinearGradient(vg, x,y,x,y+h, nvgRGBA(0,160,192,0), nvgRGBA(0,160,192,64)); + nvgBeginPath(vg); + nvgMoveTo(vg, sx[0], sy[0]); + for (i = 1; i < 6; i++) + nvgBezierTo(vg, sx[i-1]+dx*0.5f,sy[i-1], sx[i]-dx*0.5f,sy[i], sx[i],sy[i]); + nvgLineTo(vg, x+w, y+h); + nvgLineTo(vg, x, y+h); + nvgFillPaint(vg, bg); + nvgFill(vg); + + // Graph line + nvgBeginPath(vg); + nvgMoveTo(vg, sx[0], sy[0]+2); + for (i = 1; i < 6; i++) + nvgBezierTo(vg, sx[i-1]+dx*0.5f,sy[i-1]+2, sx[i]-dx*0.5f,sy[i]+2, sx[i],sy[i]+2); + nvgStrokeColor(vg, nvgRGBA(0,0,0,32)); + nvgStrokeWidth(vg, 3.0f); + nvgStroke(vg); + + nvgBeginPath(vg); + nvgMoveTo(vg, sx[0], sy[0]); + for (i = 1; i < 6; i++) + nvgBezierTo(vg, sx[i-1]+dx*0.5f,sy[i-1], sx[i]-dx*0.5f,sy[i], sx[i],sy[i]); + nvgStrokeColor(vg, nvgRGBA(0,160,192,255)); + nvgStrokeWidth(vg, 3.0f); + nvgStroke(vg); + + // Graph sample pos + for (i = 0; i < 6; i++) { + bg = nvgRadialGradient(vg, sx[i],sy[i]+2, 3.0f,8.0f, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, sx[i]-10, sy[i]-10+2, 20,20); + nvgFillPaint(vg, bg); + nvgFill(vg); + } + + nvgBeginPath(vg); + for (i = 0; i < 6; i++) + nvgCircle(vg, sx[i], sy[i], 4.0f); + nvgFillColor(vg, nvgRGBA(0,160,192,255)); + nvgFill(vg); + nvgBeginPath(vg); + for (i = 0; i < 6; i++) + nvgCircle(vg, sx[i], sy[i], 2.0f); + nvgFillColor(vg, nvgRGBA(220,220,220,255)); + nvgFill(vg); + + nvgStrokeWidth(vg, 1.0f); +} + +void drawThumbnails(struct NVGcontext* vg, float x, float y, float w, float h, const int* images, int nimages, float t) +{ + float cornerRadius = 3.0f; + struct NVGpaint shadowPaint, imgPaint, fadePaint; + float ix,iy,iw,ih; + float thumb = 60.0f; + float arry = 30.5f; + int imgw, imgh; + float stackh = (nimages/2) * (thumb+10) + 10; + int i; + float u = (1+cosf(t*0.5f))*0.5f; + float scrollh; + + nvgSave(vg); + // nvgClearState(vg); + + // Drop shadow + shadowPaint = nvgBoxGradient(vg, x,y+4, w,h, cornerRadius*2, 20, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, x-10,y-10, w+20,h+30); + nvgRoundedRect(vg, x,y, w,h, cornerRadius); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, shadowPaint); + nvgFill(vg); + + // Window + nvgBeginPath(vg); + nvgRoundedRect(vg, x,y, w,h, cornerRadius); + nvgMoveTo(vg, x-10,y+arry); + nvgLineTo(vg, x+1,y+arry-11); + nvgLineTo(vg, x+1,y+arry+11); + nvgFillColor(vg, nvgRGBA(200,200,200,255)); + nvgFill(vg); + + nvgSave(vg); + nvgScissor(vg, x,y,w,h); + nvgTranslate(vg, 0, -(stackh - h)*u); + + for (i = 0; i < nimages; i++) { + float tx, ty; + tx = x+10; + ty = y+10; + tx += (i%2) * (thumb+10); + ty += (i/2) * (thumb+10); + nvgImageSize(vg, images[i], &imgw, &imgh); + if (imgw < imgh) { + iw = thumb; + ih = iw * (float)imgh/(float)imgw; + ix = 0; + iy = -(ih-thumb)*0.5f; + } else { + ih = thumb; + iw = ih * (float)imgw/(float)imgh; + ix = -(iw-thumb)*0.5f; + iy = 0; + } + imgPaint = nvgImagePattern(vg, tx+ix, ty+iy, iw,ih, 0.0f/180.0f*NVG_PI, images[i], 0); + nvgBeginPath(vg); + nvgRoundedRect(vg, tx,ty, thumb,thumb, 5); + nvgFillPaint(vg, imgPaint); + nvgFill(vg); + + shadowPaint = nvgBoxGradient(vg, tx-1,ty, thumb+2,thumb+2, 5, 3, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, tx-5,ty-5, thumb+10,thumb+10); + nvgRoundedRect(vg, tx,ty, thumb,thumb, 6); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, shadowPaint); + nvgFill(vg); + + nvgBeginPath(vg); + nvgRoundedRect(vg, tx+0.5f,ty+0.5f, thumb-1,thumb-1, 4-0.5f); + nvgStrokeWidth(vg,1.0f); + nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); + nvgStroke(vg); + } + nvgRestore(vg); + + // Hide fades + fadePaint = nvgLinearGradient(vg, x,y,x,y+6, nvgRGBA(200,200,200,255), nvgRGBA(200,200,200,0)); + nvgBeginPath(vg); + nvgRect(vg, x+4,y,w-8,6); + nvgFillPaint(vg, fadePaint); + nvgFill(vg); + + fadePaint = nvgLinearGradient(vg, x,y+h,x,y+h-6, nvgRGBA(200,200,200,255), nvgRGBA(200,200,200,0)); + nvgBeginPath(vg); + nvgRect(vg, x+4,y+h-6,w-8,6); + nvgFillPaint(vg, fadePaint); + nvgFill(vg); + + // Scroll bar + shadowPaint = nvgBoxGradient(vg, x+w-12+1,y+4+1, 8,h-8, 3,4, nvgRGBA(0,0,0,32), nvgRGBA(0,0,0,92)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+w-12,y+4, 8,h-8, 3); + nvgFillPaint(vg, shadowPaint); + // nvgFillColor(vg, nvgRGBA(255,0,0,128)); + nvgFill(vg); + + scrollh = (h/stackh) * (h-8); + shadowPaint = nvgBoxGradient(vg, x+w-12-1,y+4+(h-8-scrollh)*u-1, 8,scrollh, 3,4, nvgRGBA(220,220,220,255), nvgRGBA(128,128,128,255)); + nvgBeginPath(vg); + nvgRoundedRect(vg, x+w-12+1,y+4+1 + (h-8-scrollh)*u, 8-2,scrollh-2, 2); + nvgFillPaint(vg, shadowPaint); + // nvgFillColor(vg, nvgRGBA(0,0,0,128)); + nvgFill(vg); + + nvgRestore(vg); +} + +void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, float t) +{ + int i; + float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; + float hue = sinf(t * 0.12f); + struct NVGpaint paint; + + nvgSave(vg); + + /* nvgBeginPath(vg); + nvgRect(vg, x,y,w,h); + nvgFillColor(vg, nvgRGBA(255,0,0,128)); + nvgFill(vg);*/ + + cx = x + w*0.5f; + cy = y + h*0.5f; + r1 = (w < h ? w : h) * 0.5f - 5.0f; + r0 = r1 - 20.0f; + aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). + + for (i = 0; i < 6; i++) + { + float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; + float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; + nvgBeginPath(vg); + nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); + nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); + nvgClosePath(vg); + ax = cx + cosf(a0) * (r0+r1)*0.5f; + ay = cy + sinf(a0) * (r0+r1)*0.5f; + bx = cx + cosf(a1) * (r0+r1)*0.5f; + by = cy + sinf(a1) * (r0+r1)*0.5f; + paint = nvgLinearGradient(vg, ax,ay, bx,by, nvgHSLA(a0/(NVG_PI*2),1.0f,0.55f,255), nvgHSLA(a1/(NVG_PI*2),1.0f,0.55f,255)); + nvgFillPaint(vg, paint); + nvgFill(vg); + } + + nvgBeginPath(vg); + nvgCircle(vg, cx,cy, r0-0.5f); + nvgCircle(vg, cx,cy, r1+0.5f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); + nvgStrokeWidth(vg, 1.0f); + nvgStroke(vg); + + // Selector + nvgSave(vg); + nvgTranslate(vg, cx,cy); + nvgRotate(vg, hue*NVG_PI*2); + + // Marker on + nvgStrokeWidth(vg, 2.0f); + nvgBeginPath(vg); + nvgRect(vg, r0-1,-3,r1-r0+2,6); + nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); + nvgStroke(vg); + + paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); + nvgRect(vg, r0-2,-4,r1-r0+4,8); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, paint); + nvgFill(vg); + + // Center triangle + r = r0 - 6; + ax = cosf(120.0f/180.0f*NVG_PI) * r; + ay = sinf(120.0f/180.0f*NVG_PI) * r; + bx = cosf(-120.0f/180.0f*NVG_PI) * r; + by = sinf(-120.0f/180.0f*NVG_PI) * r; + nvgBeginPath(vg); + nvgMoveTo(vg, r,0); + nvgLineTo(vg, ax,ay); + nvgLineTo(vg, bx,by); + nvgClosePath(vg); + paint = nvgLinearGradient(vg, r,0, ax,ay, nvgHSLA(hue,1.0f,0.5f,255), nvgRGBA(255,255,255,255)); + nvgFillPaint(vg, paint); + nvgFill(vg); + paint = nvgLinearGradient(vg, (r+ax)*0.5f,(0+ay)*0.5f, bx,by, nvgRGBA(0,0,0,0), nvgRGBA(0,0,0,255)); + nvgFillPaint(vg, paint); + nvgFill(vg); + nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); + nvgStroke(vg); + + // Select circle on triangle + ax = cosf(120.0f/180.0f*NVG_PI) * r*0.3f; + ay = sinf(120.0f/180.0f*NVG_PI) * r*0.4f; + nvgStrokeWidth(vg, 2.0f); + nvgBeginPath(vg); + nvgCircle(vg, ax,ay,5); + nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); + nvgStroke(vg); + + paint = nvgRadialGradient(vg, ax,ay, 7,9, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0)); + nvgBeginPath(vg); + nvgRect(vg, ax-20,ay-20,40,40); + nvgCircle(vg, ax,ay,7); + nvgPathWinding(vg, NVG_HOLE); + nvgFillPaint(vg, paint); + nvgFill(vg); + + nvgRestore(vg); + + nvgRestore(vg); +} + +void drawLines(struct NVGcontext* vg, float x, float y, float w, float h, float t) +{ + int i, j; + float pad = 5.0f, s = w/9.0f - pad*2; + float pts[4*2], fx, fy; + int joins[3] = {NVG_MITER, NVG_ROUND, NVG_BEVEL}; + int caps[3] = {NVG_BUTT, NVG_ROUND, NVG_SQUARE}; + NVG_NOTUSED(h); + + nvgSave(vg); + pts[0] = -s*0.25f + cosf(t*0.3f) * s*0.5f; + pts[1] = sinf(t*0.3f) * s*0.5f; + pts[2] = -s*0.25f; + pts[3] = 0; + pts[4] = s*0.25f; + pts[5] = 0; + pts[6] = s*0.25f + cosf(-t*0.3f) * s*0.5f; + pts[7] = sinf(-t*0.3f) * s*0.5f; + + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + fx = x + s*0.5f + (i*3+j)/9.0f*w + pad; + fy = y - s*0.5f + pad; + + nvgLineCap(vg, caps[i]); + nvgLineJoin(vg, joins[j]); + + nvgStrokeWidth(vg, s*0.3f); + nvgStrokeColor(vg, nvgRGBA(0,0,0,160)); + nvgBeginPath(vg); + nvgMoveTo(vg, fx+pts[0], fy+pts[1]); + nvgLineTo(vg, fx+pts[2], fy+pts[3]); + nvgLineTo(vg, fx+pts[4], fy+pts[5]); + nvgLineTo(vg, fx+pts[6], fy+pts[7]); + nvgStroke(vg); + + nvgLineCap(vg, NVG_BUTT); + nvgLineJoin(vg, NVG_BEVEL); + + nvgStrokeWidth(vg, 1.0f); + nvgStrokeColor(vg, nvgRGBA(0,192,255,255)); + nvgBeginPath(vg); + nvgMoveTo(vg, fx+pts[0], fy+pts[1]); + nvgLineTo(vg, fx+pts[2], fy+pts[3]); + nvgLineTo(vg, fx+pts[4], fy+pts[5]); + nvgLineTo(vg, fx+pts[6], fy+pts[7]); + nvgStroke(vg); + } + } + + nvgRestore(vg); +} + +struct DemoData +{ + int fontNormal, fontBold, fontIcons; + int images[12]; +}; + +int loadDemoData(struct NVGcontext* vg, struct DemoData* data) +{ + for (uint32_t ii = 0; ii < 12; ++ii) + { + char file[128]; + bx::snprintf(file, 128, "images/image%d.jpg", ii+1); + data->images[ii] = nvgCreateImage(vg, file); + if (data->images[ii] == bgfx::invalidHandle) + { + printf("Could not load %s.\n", file); + return -1; + } + } + + data->fontIcons = nvgCreateFont(vg, "icons", "font/entypo.ttf"); + if (data->fontIcons == -1) + { + printf("Could not add font icons.\n"); + return -1; + } + + data->fontNormal = nvgCreateFont(vg, "sans", "font/roboto-regular.ttf"); + if (data->fontNormal == -1) + { + printf("Could not add font italic.\n"); + return -1; + } + + data->fontBold = nvgCreateFont(vg, "sans-bold", "font/roboto-bold.ttf"); + if (data->fontBold == -1) + { + printf("Could not add font bold.\n"); + return -1; + } + + return 0; +} + +void freeDemoData(struct NVGcontext* vg, struct DemoData* data) +{ + int i; + + if (vg == NULL) + return; + + for (i = 0; i < 12; i++) + nvgDeleteImage(vg, data->images[i]); +} + +inline float round(float _f) +{ + return float(int(_f) ); +} + +void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float height, float mx, float my) +{ + struct NVGtextRow rows[3]; + struct NVGglyphPosition glyphs[100]; + const char* text = "This is longer chunk of text.\n \n Would have used lorem ipsum but she was busy jumping over the lazy dog with the fox and all the men who came to the aid of the party."; + const char* start; + const char* end; + int nrows, i, nglyphs, j, lnum = 0; + float lineh; + float caretx, px; + float bounds[4]; + float gx = 0.0f, gy = 0.0f; + int gutter = 0; + NVG_NOTUSED(height); + + nvgSave(vg); + + nvgFontSize(vg, 18.0f); + nvgFontFace(vg, "sans"); + nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); + nvgTextMetrics(vg, NULL, NULL, &lineh); + + // The text break API can be used to fill a large buffer of rows, + // or to iterate over the text just few lines (or just one) at a time. + // The "next" variable of the last returned item tells where to continue. + start = text; + end = text + strlen(text); + for (nrows = nvgTextBreakLines(vg, start, end, width, rows, 3); 0 != nrows; nrows = nvgTextBreakLines(vg, start, end, width, rows, 3) ) + { + for (i = 0; i < nrows; i++) { + struct NVGtextRow* row = &rows[i]; + int hit = mx > x && mx < (x+width) && my >= y && my < (y+lineh); + + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(255,255,255,hit?64:8)); + nvgRect(vg, x, y, row->width, lineh); + nvgFill(vg); + + nvgFillColor(vg, nvgRGBA(255,255,255,255)); + nvgText(vg, x, y, row->start, row->end); + + if (hit) { + caretx = (mx < x+row->width/2) ? x : x+row->width; + px = x; + nglyphs = nvgTextGlyphPositions(vg, x, y, row->start, row->end, glyphs, 100); + for (j = 0; j < nglyphs; j++) { + float x0 = glyphs[j].x; + float x1 = (j+1 < nglyphs) ? glyphs[j+1].x : x+row->width; + float gx = x0 * 0.3f + x1 * 0.7f; + if (mx >= px && mx < gx) + caretx = glyphs[j].x; + px = gx; + } + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(255,192,0,255)); + nvgRect(vg, caretx, y, 1, lineh); + nvgFill(vg); + + gutter = lnum+1; + gx = x - 10; + gy = y + lineh/2; + } + lnum++; + y += lineh; + } + // Keep going... + start = rows[nrows-1].next; + } + + if (gutter) + { + char txt[16]; + bx::snprintf(txt, sizeof(txt), "%d", gutter); + nvgFontSize(vg, 13.0f); + nvgTextAlign(vg, NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); + + nvgTextBounds(vg, gx,gy, txt, NULL, bounds); + + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(255,192,0,255)); + nvgRoundedRect(vg + , round(bounds[0])-4.0f + , round(bounds[1])-2.0f + , round(bounds[2]-bounds[0])+8.0f + , round(bounds[3]-bounds[1])+4.0f + , (round(bounds[3]-bounds[1])+4.0f)/2.0f-1.0f + ); + nvgFill(vg); + + nvgFillColor(vg, nvgRGBA(32,32,32,255)); + nvgText(vg, gx,gy, txt, NULL); + } + + y += 20.0f; + + nvgFontSize(vg, 13.0f); + nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); + nvgTextLineHeight(vg, 1.2f); + + nvgTextBoxBounds(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL, bounds); + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(220,220,220,255)); + nvgRoundedRect(vg + , round(bounds[0]-2.0f) + , round(bounds[1]-2.0f) + , round(bounds[2]-bounds[0])+4.0f + , round(bounds[3]-bounds[1])+4.0f + , 3.0f + ); + px = float( (int)((bounds[2]+bounds[0])/2) ); + nvgMoveTo(vg, px,bounds[1] - 10); + nvgLineTo(vg, px+7,bounds[1]+1); + nvgLineTo(vg, px-7,bounds[1]+1); + nvgFill(vg); + + nvgFillColor(vg, nvgRGBA(0,0,0,220)); + nvgTextBox(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL); + + nvgRestore(vg); +} + +void drawWidths(struct NVGcontext* vg, float x, float y, float width) +{ + nvgSave(vg); + + nvgStrokeColor(vg, nvgRGBA(0,0,0,255)); + + for (uint32_t ii = 0; ii < 20; ++ii) + { + float w = (ii+0.5f)*0.1f; + nvgStrokeWidth(vg, w); + nvgBeginPath(vg); + nvgMoveTo(vg, x,y); + nvgLineTo(vg, x+width,y+width*0.3f); + nvgStroke(vg); + y += 10; + } + + nvgRestore(vg); +} + +void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float height, float t, int blowup, struct DemoData* data) +{ + float x,y,popy; + + drawEyes(vg, width - 250, 50, 150, 100, mx, my, t); + drawParagraph(vg, width - 450, 50, 150, 100, mx, my); + drawGraph(vg, 0, height/2, width, height/2, t); + drawColorwheel(vg, width - 300, height - 300, 250.0f, 250.0f, t); + + // Line joints + drawLines(vg, 50, height-50, 600, 50, t); + + // Line width; + drawWidths(vg, 10, 50, 30); + + nvgSave(vg); + if (blowup) + { + nvgRotate(vg, sinf(t*0.3f)*5.0f/180.0f*NVG_PI); + nvgScale(vg, 2.0f, 2.0f); + } + + // Widgets + drawWindow(vg, "Widgets `n Stuff", 50, 50, 300, 400); + x = 60; y = 95; + drawSearchBox(vg, "Search", x,y,280,25); + y += 40; + drawDropDown(vg, "Effects", x,y,280,28); + popy = y + 14; + y += 45; + + // Form + drawLabel(vg, "Login", x,y, 280,20); + y += 25; + drawEditBox(vg, "Email", x,y, 280,28); + y += 35; + drawEditBox(vg, "Password", x,y, 280,28); + y += 38; + drawCheckBox(vg, "Remember me", x,y, 140,28); + drawButton(vg, ICON_LOGIN, "Sign in", x+138, y, 140, 28, nvgRGBA(0,96,128,255)); + y += 45; + + // Slider + drawLabel(vg, "Diameter", x,y, 280,20); + y += 25; + drawEditBoxNum(vg, "123.00", "px", x+180,y, 100,28); + drawSlider(vg, 0.4f, x,y, 170,28); + y += 55; + + drawButton(vg, ICON_TRASH, "Delete", x, y, 160, 28, nvgRGBA(128,16,8,255)); + drawButton(vg, 0, "Cancel", x+170, y, 110, 28, nvgRGBA(0,0,0,0)); + + // Thumbnails box + drawThumbnails(vg, 365, popy-30, 160, 300, data->images, 12, t); + + nvgRestore(vg); +} + +int _main_(int /*_argc*/, char** /*_argv*/) +{ + uint32_t width = 1280; + uint32_t height = 720; + uint32_t debug = BGFX_DEBUG_TEXT; + uint32_t reset = BGFX_RESET_VSYNC; + + bgfx::init(); + bgfx::reset(width, height, reset); + + // Enable debug text. + bgfx::setDebug(debug); + + // Set view 0 clear state. + bgfx::setViewClear(0 + , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT + , 0x303030ff + , 1.0f + , 0 + ); + + NVGcontext* nvg = nvgCreate(512, 512, 1); + bgfx::setViewSeq(0, true); + + DemoData data; + loadDemoData(nvg, &data); + + int64_t timeOffset = bx::getHPCounter(); + + entry::MouseState mouseState; + while (!entry::processEvents(width, height, debug, reset, &mouseState) ) + { + int64_t now = bx::getHPCounter(); + const double freq = double(bx::getHPFrequency() ); + float time = (float)( (now-timeOffset)/freq); + + // Set view 0 default viewport. + bgfx::setViewRect(0, 0, 0, width, height); + + // This dummy draw call is here to make sure that view 0 is cleared + // if no other draw calls are submitted to view 0. + bgfx::submit(0); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/20-nanovg"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: NanoVG is small antialiased vector graphics rendering library."); + + float ratio = float(width)/float(height); + + nvgBeginFrame(nvg, width, height, ratio, NVG_STRAIGHT_ALPHA); + + renderDemo(nvg, float(mouseState.m_mx), float(mouseState.m_my), float(width), float(height), time, 0, &data); + + nvgEndFrame(nvg); + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + } + + freeDemoData(nvg, &data); + + nvgDelete(nvg); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; +} diff --git a/examples/20-nanovg/screenshot.png b/examples/20-nanovg/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9c24c7e2acbf58f88da8af7fc60dc824c4f37b GIT binary patch literal 107871 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

09GzHci}o1qRYDcRMy1D}zLmak68tUZ{zuuSq;i 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 D_N7_P literal 0 HcmV?d00001 diff --git a/examples/common/nanovg/fontstash.h b/examples/common/nanovg/fontstash.h new file mode 100644 index 00000000..bf5de24e --- /dev/null +++ b/examples/common/nanovg/fontstash.h @@ -0,0 +1,1668 @@ +// +// Copyright (c) 2009-2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef FONS_H +#define FONS_H + +#define FONS_INVALID -1 + +enum FONSflags { + FONS_ZERO_TOPLEFT = 1, + FONS_ZERO_BOTTOMLEFT = 2, +}; + +enum FONSalign { + // Horizontal align + FONS_ALIGN_LEFT = 1<<0, // Default + FONS_ALIGN_CENTER = 1<<1, + FONS_ALIGN_RIGHT = 1<<2, + // Vertical align + FONS_ALIGN_TOP = 1<<3, + FONS_ALIGN_MIDDLE = 1<<4, + FONS_ALIGN_BOTTOM = 1<<5, + FONS_ALIGN_BASELINE = 1<<6, // Default +}; + +enum FONSerrorCode { + // Font atlas is full. + FONS_ATLAS_FULL = 1, + // Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE. + FONS_SCRATCH_FULL = 2, + // Calls to fonsPushState has craeted too large stack, if you need deep state stack bump up FONS_MAX_STATES. + FONS_STATES_OVERFLOW = 3, + // Trying to pop too many states fonsPopState(). + FONS_STATES_UNDERFLOW = 4, +}; + +struct FONSparams { + int width, height; + unsigned char flags; + void* userPtr; + int (*renderCreate)(void* uptr, int width, int height); + int (*renderResize)(void* uptr, int width, int height); + void (*renderUpdate)(void* uptr, int* rect, const unsigned char* data); + void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned int* colors, int nverts); + void (*renderDelete)(void* uptr); +}; + +struct FONSquad +{ + float x0,y0,s0,t0; + float x1,y1,s1,t1; +}; + +struct FONStextIter { + float x, y, nextx, nexty, scale, spacing; + unsigned int codepoint; + short isize, iblur; + struct FONSfont* font; + struct FONSglyph* prevGlyph; + const char* str; + const char* next; + const char* end; + unsigned int utf8state; +}; + +// Contructor and destructor. +struct FONScontext* fonsCreateInternal(struct FONSparams* params); +void fonsDeleteInternal(struct FONScontext* s); + +void fonsSetErrorCallback(struct FONScontext* s, void (*callback)(void* uptr, int error, int val), void* uptr); +// Returns current atlas size. +void fonsGetAtlasSize(struct FONScontext* s, int* width, int* height); +// Expands the atlas size. +int fonsExpandAtlas(struct FONScontext* s, int width, int height); +// Reseta the whole stash. +int fonsResetAtlas(struct FONScontext* stash, int width, int height); + +// Add fonts +int fonsAddFont(struct FONScontext* s, const char* name, const char* path); +int fonsAddFontMem(struct FONScontext* s, const char* name, unsigned char* data, int ndata, int freeData); +int fonsGetFontByName(struct FONScontext* s, const char* name); + +// State handling +void fonsPushState(struct FONScontext* s); +void fonsPopState(struct FONScontext* s); +void fonsClearState(struct FONScontext* s); + +// State setting +void fonsSetSize(struct FONScontext* s, float size); +void fonsSetColor(struct FONScontext* s, unsigned int color); +void fonsSetSpacing(struct FONScontext* s, float spacing); +void fonsSetBlur(struct FONScontext* s, float blur); +void fonsSetAlign(struct FONScontext* s, int align); +void fonsSetFont(struct FONScontext* s, int font); + +// Draw text +float fonsDrawText(struct FONScontext* s, float x, float y, const char* string, const char* end); + +// Measure text +float fonsTextBounds(struct FONScontext* s, float x, float y, const char* string, const char* end, float* bounds); +void fonsLineBounds(struct FONScontext* s, float y, float* miny, float* maxy); +void fonsVertMetrics(struct FONScontext* s, float* ascender, float* descender, float* lineh); + +// Text iterator +int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter, float x, float y, const char* str, const char* end); +int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struct FONSquad* quad); + +// Pull texture changes +const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, int* height); +int fonsValidateTexture(struct FONScontext* s, int* dirty); + +// Draws the stash texture for debugging +void fonsDrawDebug(struct FONScontext* s, float x, float y); + +#endif // FONS_H + + +#ifdef FONTSTASH_IMPLEMENTATION + +#define FONS_NOTUSED(v) (void)sizeof(v) + +#ifdef FONS_USE_FREETYPE + +#include +#include FT_FREETYPE_H +#include FT_ADVANCES_H +#include + +struct FONSttFontImpl { + FT_Face font; +}; + +static FT_Library ftLibrary; + +int fons__tt_init() +{ + FT_Error ftError; + ftError = FT_Init_FreeType(&ftLibrary); + return ftError == 0; +} + +int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font, unsigned char *data, int dataSize) +{ + FT_Error ftError; + FONS_NOTUSED(context); + + //font->font.userdata = stash; + ftError = FT_New_Memory_Face(ftLibrary, (const FT_Byte*)data, dataSize, 0, &font->font); + return ftError == 0; +} + +void fons__tt_getFontVMetrics(struct FONSttFontImpl *font, int *ascent, int *descent, int *lineGap) +{ + *ascent = font->font->ascender; + *descent = font->font->descender; + *lineGap = font->font->height - (*ascent - *descent); +} + +float fons__tt_getPixelHeightScale(struct FONSttFontImpl *font, float size) +{ + return size / (font->font->ascender - font->font->descender); +} + +int fons__tt_getGlyphIndex(struct FONSttFontImpl *font, int codepoint) +{ + return FT_Get_Char_Index(font->font, codepoint); +} + +int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) +{ + FT_Error ftError; + FT_GlyphSlot ftGlyph; + FONS_NOTUSED(scale); + + ftError = FT_Set_Pixel_Sizes(font->font, 0, (FT_UInt)(size * (float)font->font->units_per_EM / (float)(font->font->ascender - font->font->descender))); + if (ftError) return 0; + ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER); + if (ftError) return 0; + ftError = FT_Get_Advance(font->font, glyph, FT_LOAD_NO_SCALE, (FT_Fixed*)advance); + if (ftError) return 0; + ftGlyph = font->font->glyph; + *lsb = ftGlyph->metrics.horiBearingX; + *x0 = ftGlyph->bitmap_left; + *x1 = *x0 + ftGlyph->bitmap.width; + *y0 = -ftGlyph->bitmap_top; + *y1 = *y0 + ftGlyph->bitmap.rows; + return 1; +} + +void fons__tt_renderGlyphBitmap(struct FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) +{ + FT_GlyphSlot ftGlyph = font->font->glyph; + int ftGlyphOffset = 0; + int x, y; + FONS_NOTUSED(outWidth); + FONS_NOTUSED(outHeight); + FONS_NOTUSED(scaleX); + FONS_NOTUSED(scaleY); + FONS_NOTUSED(glyph); // glyph has already been loaded by fons__tt_buildGlyphBitmap + + for ( y = 0; y < ftGlyph->bitmap.rows; y++ ) { + for ( x = 0; x < ftGlyph->bitmap.width; x++ ) { + output[(y * outStride) + x] = ftGlyph->bitmap.buffer[ftGlyphOffset++]; + } + } +} + +int fons__tt_getGlyphKernAdvance(struct FONSttFontImpl *font, int glyph1, int glyph2) +{ + FT_Vector ftKerning; + FT_Get_Kerning(font->font, glyph1, glyph2, FT_KERNING_DEFAULT, &ftKerning); + return ftKerning.x; +} + +#else + +#if 0 +# define STB_TRUETYPE_IMPLEMENTATION +# define STBTT_malloc(x,u) fons__tmpalloc(x,u) +# define STBTT_free(x,u) fons__tmpfree(x,u) +static void* fons__tmpalloc(size_t size, void* up); +static void fons__tmpfree(void* ptr, void* up); +#else +# include +# include +#endif // 0 + +#include + +struct FONSttFontImpl { + stbtt_fontinfo font; +}; + +int fons__tt_init(struct FONScontext *context) +{ + FONS_NOTUSED(context); + return 1; +} + +int fons__tt_loadFont(struct FONScontext *context, struct FONSttFontImpl *font, unsigned char *data, int dataSize) +{ + int stbError; + FONS_NOTUSED(dataSize); + + font->font.userdata = context; + stbError = stbtt_InitFont(&font->font, data, 0); + return stbError; +} + +void fons__tt_getFontVMetrics(struct FONSttFontImpl *font, int *ascent, int *descent, int *lineGap) +{ + stbtt_GetFontVMetrics(&font->font, ascent, descent, lineGap); +} + +float fons__tt_getPixelHeightScale(struct FONSttFontImpl *font, float size) +{ + return stbtt_ScaleForPixelHeight(&font->font, size); +} + +int fons__tt_getGlyphIndex(struct FONSttFontImpl *font, int codepoint) +{ + return stbtt_FindGlyphIndex(&font->font, codepoint); +} + +int fons__tt_buildGlyphBitmap(struct FONSttFontImpl *font, int glyph, float size, float scale, int *advance, int *lsb, int *x0, int *y0, int *x1, int *y1) +{ + FONS_NOTUSED(size); + stbtt_GetGlyphHMetrics(&font->font, glyph, advance, lsb); + stbtt_GetGlyphBitmapBox(&font->font, glyph, scale, scale, x0, y0, x1, y1); + return 1; +} + +void fons__tt_renderGlyphBitmap(struct FONSttFontImpl *font, unsigned char *output, int outWidth, int outHeight, int outStride, float scaleX, float scaleY, int glyph) +{ + stbtt_MakeGlyphBitmap(&font->font, output, outWidth, outHeight, outStride, scaleX, scaleY, glyph); +} + +int fons__tt_getGlyphKernAdvance(struct FONSttFontImpl *font, int glyph1, int glyph2) +{ + return stbtt_GetGlyphKernAdvance(&font->font, glyph1, glyph2); +} + +#endif + +#ifndef FONS_SCRATCH_BUF_SIZE +# define FONS_SCRATCH_BUF_SIZE 16000 +#endif +#ifndef FONS_HASH_LUT_SIZE +# define FONS_HASH_LUT_SIZE 256 +#endif +#ifndef FONS_INIT_FONTS +# define FONS_INIT_FONTS 4 +#endif +#ifndef FONS_INIT_GLYPHS +# define FONS_INIT_GLYPHS 256 +#endif +#ifndef FONS_INIT_ATLAS_NODES +# define FONS_INIT_ATLAS_NODES 256 +#endif +#ifndef FONS_VERTEX_COUNT +# define FONS_VERTEX_COUNT 1024 +#endif +#ifndef FONS_MAX_STATES +# define FONS_MAX_STATES 20 +#endif + +static unsigned int fons__hashint(unsigned int a) +{ + a += ~(a<<15); + a ^= (a>>10); + a += (a<<3); + a ^= (a>>6); + a += ~(a<<11); + a ^= (a>>16); + return a; +} + +static int fons__mini(int a, int b) +{ + return a < b ? a : b; +} + +static int fons__maxi(int a, int b) +{ + return a > b ? a : b; +} + +struct FONSglyph +{ + unsigned int codepoint; + int index; + int next; + short size, blur; + short x0,y0,x1,y1; + short xadv,xoff,yoff; +}; + +struct FONSfont +{ + struct FONSttFontImpl font; + char name[64]; + unsigned char* data; + int dataSize; + unsigned char freeData; + float ascender; + float descender; + float lineh; + struct FONSglyph* glyphs; + int cglyphs; + int nglyphs; + int lut[FONS_HASH_LUT_SIZE]; +}; + +struct FONSstate +{ + int font; + int align; + float size; + unsigned int color; + float blur; + float spacing; +}; + +struct FONSatlasNode { + short x, y, width; +}; + +struct FONSatlas +{ + int width, height; + struct FONSatlasNode* nodes; + int nnodes; + int cnodes; +}; + +struct FONScontext +{ + struct FONSparams params; + float itw,ith; + unsigned char* texData; + int dirtyRect[4]; + struct FONSfont** fonts; + struct FONSatlas* atlas; + int cfonts; + int nfonts; + float verts[FONS_VERTEX_COUNT*2]; + float tcoords[FONS_VERTEX_COUNT*2]; + unsigned int colors[FONS_VERTEX_COUNT]; + int nverts; + unsigned char scratch[FONS_SCRATCH_BUF_SIZE]; + int nscratch; + struct FONSstate states[FONS_MAX_STATES]; + int nstates; + void (*handleError)(void* uptr, int error, int val); + void* errorUptr; +}; + +static void* fons__tmpalloc(size_t size, void* up) +{ + unsigned char* ptr; + + struct FONScontext* stash = (struct FONScontext*)up; + if (stash->nscratch+(int)size > FONS_SCRATCH_BUF_SIZE) { + if (stash->handleError) + stash->handleError(stash->errorUptr, FONS_SCRATCH_FULL, stash->nscratch+(int)size); + return NULL; + } + ptr = stash->scratch + stash->nscratch; + stash->nscratch += (int)size; + return ptr; +} + +static void fons__tmpfree(void* ptr, void* up) +{ + (void)ptr; + (void)up; + // empty +} + +// Copyright (c) 2008-2010 Bjoern Hoehrmann +// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + +#define FONS_UTF8_ACCEPT 0 +#define FONS_UTF8_REJECT 12 + +static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsigned int byte) +{ + static const unsigned char utf8d[] = { + // The first part of the table maps bytes to character classes that + // to reduce the size of the transition table and create bitmasks. + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + // The second part is a transition table that maps a combination + // of a state of the automaton and a character class to a state. + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, + }; + + unsigned int type = utf8d[byte]; + + *codep = (*state != FONS_UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state + type]; + return *state; +} + +// Atlas based on Skyline Pin Packer by Jukka Jylänki + +static void fons__deleteAtlas(struct FONSatlas* atlas) +{ + if (atlas == NULL) return; + if (atlas->nodes != NULL) free(atlas->nodes); + free(atlas); +} + +static struct FONSatlas* fons__allocAtlas(int w, int h, int nnodes) +{ + struct FONSatlas* atlas = NULL; + + // Allocate memory for the font stash. + atlas = (struct FONSatlas*)malloc(sizeof(struct FONSatlas)); + if (atlas == NULL) goto error; + memset(atlas, 0, sizeof(struct FONSatlas)); + + atlas->width = w; + atlas->height = h; + + // Allocate space for skyline nodes + atlas->nodes = (struct FONSatlasNode*)malloc(sizeof(struct FONSatlasNode) * nnodes); + if (atlas->nodes == NULL) goto error; + memset(atlas->nodes, 0, sizeof(struct FONSatlasNode) * nnodes); + atlas->nnodes = 0; + atlas->cnodes = nnodes; + + // Init root node. + atlas->nodes[0].x = 0; + atlas->nodes[0].y = 0; + atlas->nodes[0].width = (short)w; + atlas->nnodes++; + + return atlas; + +error: + if (atlas) fons__deleteAtlas(atlas); + return NULL; +} + +static int fons__atlasInsertNode(struct FONSatlas* atlas, int idx, int x, int y, int w) +{ + int i; + // Insert node + if (atlas->nnodes+1 > atlas->cnodes) { + atlas->cnodes = atlas->cnodes == 0 ? 8 : atlas->cnodes * 2; + atlas->nodes = (struct FONSatlasNode*)realloc(atlas->nodes, sizeof(struct FONSatlasNode) * atlas->cnodes); + if (atlas->nodes == NULL) + return 0; + } + for (i = atlas->nnodes; i > idx; i--) + atlas->nodes[i] = atlas->nodes[i-1]; + atlas->nodes[idx].x = (short)x; + atlas->nodes[idx].y = (short)y; + atlas->nodes[idx].width = (short)w; + atlas->nnodes++; + + return 1; +} + +static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx) +{ + int i; + if (atlas->nnodes == 0) return; + for (i = idx; i < atlas->nnodes-1; i++) + atlas->nodes[i] = atlas->nodes[i+1]; + atlas->nnodes--; +} + +static void fons__atlasExpand(struct FONSatlas* atlas, int w, int h) +{ + // Insert node for empty space + if (w > atlas->width) + fons__atlasInsertNode(atlas, atlas->nnodes, atlas->width, 0, w - atlas->width); + atlas->width = w; + atlas->height = h; +} + +static void fons__atlasReset(struct FONSatlas* atlas, int w, int h) +{ + atlas->width = w; + atlas->height = h; + atlas->nnodes = 0; + + // Init root node. + atlas->nodes[0].x = 0; + atlas->nodes[0].y = 0; + atlas->nodes[0].width = (short)w; + atlas->nnodes++; +} + +static int fons__atlasAddSkylineLevel(struct FONSatlas* atlas, int idx, int x, int y, int w, int h) +{ + int i; + + // Insert new node + if (fons__atlasInsertNode(atlas, idx, x, y+h, w) == 0) + return 0; + + // Delete skyline segments that fall under the shaodw of the new segment. + for (i = idx+1; i < atlas->nnodes; i++) { + if (atlas->nodes[i].x < atlas->nodes[i-1].x + atlas->nodes[i-1].width) { + int shrink = atlas->nodes[i-1].x + atlas->nodes[i-1].width - atlas->nodes[i].x; + atlas->nodes[i].x += (short)shrink; + atlas->nodes[i].width -= (short)shrink; + if (atlas->nodes[i].width <= 0) { + fons__atlasRemoveNode(atlas, i); + i--; + } else { + break; + } + } else { + break; + } + } + + // Merge same height skyline segments that are next to each other. + for (i = 0; i < atlas->nnodes-1; i++) { + if (atlas->nodes[i].y == atlas->nodes[i+1].y) { + atlas->nodes[i].width += atlas->nodes[i+1].width; + fons__atlasRemoveNode(atlas, i+1); + i--; + } + } + + return 1; +} + +static int fons__atlasRectFits(struct FONSatlas* atlas, int i, int w, int h) +{ + // Checks if there is enough space at the location of skyline span 'i', + // and return the max height of all skyline spans under that at that location, + // (think tetris block being dropped at that position). Or -1 if no space found. + int x = atlas->nodes[i].x; + int y = atlas->nodes[i].y; + int spaceLeft; + if (x + w > atlas->width) + return -1; + spaceLeft = w; + while (spaceLeft > 0) { + if (i == atlas->nnodes) return -1; + y = fons__maxi(y, atlas->nodes[i].y); + if (y + h > atlas->height) return -1; + spaceLeft -= atlas->nodes[i].width; + ++i; + } + return y; +} + +static int fons__atlasAddRect(struct FONSatlas* atlas, int rw, int rh, int* rx, int* ry) +{ + int besth = atlas->height, bestw = atlas->width, besti = -1; + int bestx = -1, besty = -1, i; + + // Bottom left fit heuristic. + for (i = 0; i < atlas->nnodes; i++) { + int y = fons__atlasRectFits(atlas, i, rw, rh); + if (y != -1) { + if (y + rh < besth || (y + rh == besth && atlas->nodes[i].width < bestw)) { + besti = i; + bestw = atlas->nodes[i].width; + besth = y + rh; + bestx = atlas->nodes[i].x; + besty = y; + } + } + } + + if (besti == -1) + return 0; + + // Perform the actual packing. + if (fons__atlasAddSkylineLevel(atlas, besti, bestx, besty, rw, rh) == 0) + return 0; + + *rx = bestx; + *ry = besty; + + return 1; +} + +static void fons__addWhiteRect(struct FONScontext* stash, int w, int h) +{ + int x, y, gx, gy; + unsigned char* dst; + if (fons__atlasAddRect(stash->atlas, w, h, &gx, &gy) == 0) + return; + + // Rasterize + dst = &stash->texData[gx + gy * stash->params.width]; + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) + dst[x] = 0xff; + dst += stash->params.width; + } + + stash->dirtyRect[0] = fons__mini(stash->dirtyRect[0], gx); + stash->dirtyRect[1] = fons__mini(stash->dirtyRect[1], gy); + stash->dirtyRect[2] = fons__maxi(stash->dirtyRect[2], gx+w); + stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], gy+h); +} + +struct FONScontext* fonsCreateInternal(struct FONSparams* params) +{ + struct FONScontext* stash = NULL; + + // Allocate memory for the font stash. + stash = (struct FONScontext*)malloc(sizeof(struct FONScontext)); + if (stash == NULL) goto error; + memset(stash, 0, sizeof(struct FONScontext)); + + stash->params = *params; + + // Initialize implementation library + if (!fons__tt_init(stash)) goto error; + + if (stash->params.renderCreate != NULL) { + if (stash->params.renderCreate(stash->params.userPtr, stash->params.width, stash->params.height) == 0) + goto error; + } + + stash->atlas = fons__allocAtlas(stash->params.width, stash->params.height, FONS_INIT_ATLAS_NODES); + if (stash->atlas == NULL) goto error; + + // Allocate space for fonts. + stash->fonts = (struct FONSfont**)malloc(sizeof(struct FONSfont*) * FONS_INIT_FONTS); + if (stash->fonts == NULL) goto error; + memset(stash->fonts, 0, sizeof(struct FONSfont*) * FONS_INIT_FONTS); + stash->cfonts = FONS_INIT_FONTS; + stash->nfonts = 0; + + // Create texture for the cache. + stash->itw = 1.0f/stash->params.width; + stash->ith = 1.0f/stash->params.height; + stash->texData = (unsigned char*)malloc(stash->params.width * stash->params.height); + if (stash->texData == NULL) goto error; + memset(stash->texData, 0, stash->params.width * stash->params.height); + + stash->dirtyRect[0] = stash->params.width; + stash->dirtyRect[1] = stash->params.height; + stash->dirtyRect[2] = 0; + stash->dirtyRect[3] = 0; + + // Add white rect at 0,0 for debug drawing. + fons__addWhiteRect(stash, 2,2); + + fonsPushState(stash); + fonsClearState(stash); + + return stash; + +error: + fonsDeleteInternal(stash); + return NULL; +} + +static struct FONSstate* fons__getState(struct FONScontext* stash) +{ + return &stash->states[stash->nstates-1]; +} + +void fonsSetSize(struct FONScontext* stash, float size) +{ + fons__getState(stash)->size = size; +} + +void fonsSetColor(struct FONScontext* stash, unsigned int color) +{ + fons__getState(stash)->color = color; +} + +void fonsSetSpacing(struct FONScontext* stash, float spacing) +{ + fons__getState(stash)->spacing = spacing; +} + +void fonsSetBlur(struct FONScontext* stash, float blur) +{ + fons__getState(stash)->blur = blur; +} + +void fonsSetAlign(struct FONScontext* stash, int align) +{ + fons__getState(stash)->align = align; +} + +void fonsSetFont(struct FONScontext* stash, int font) +{ + fons__getState(stash)->font = font; +} + +void fonsPushState(struct FONScontext* stash) +{ + if (stash->nstates >= FONS_MAX_STATES) { + if (stash->handleError) + stash->handleError(stash->errorUptr, FONS_STATES_OVERFLOW, 0); + return; + } + if (stash->nstates > 0) + memcpy(&stash->states[stash->nstates], &stash->states[stash->nstates-1], sizeof(struct FONSstate)); + stash->nstates++; +} + +void fonsPopState(struct FONScontext* stash) +{ + if (stash->nstates <= 1) { + if (stash->handleError) + stash->handleError(stash->errorUptr, FONS_STATES_UNDERFLOW, 0); + return; + } + stash->nstates--; +} + +void fonsClearState(struct FONScontext* stash) +{ + struct FONSstate* state = fons__getState(stash); + state->size = 12.0f; + state->color = 0xffffffff; + state->font = 0; + state->blur = 0; + state->spacing = 0; + state->align = FONS_ALIGN_LEFT | FONS_ALIGN_BASELINE; +} + +static void fons__freeFont(struct FONSfont* font) +{ + if (font == NULL) return; + if (font->glyphs) free(font->glyphs); + if (font->freeData && font->data) free(font->data); + free(font); +} + +static int fons__allocFont(struct FONScontext* stash) +{ + struct FONSfont* font = NULL; + if (stash->nfonts+1 > stash->cfonts) { + stash->cfonts = stash->cfonts == 0 ? 8 : stash->cfonts * 2; + stash->fonts = (struct FONSfont**)realloc(stash->fonts, sizeof(struct FONSfont*) * stash->cfonts); + if (stash->fonts == NULL) + return -1; + } + font = (struct FONSfont*)malloc(sizeof(struct FONSfont)); + if (font == NULL) goto error; + memset(font, 0, sizeof(struct FONSfont)); + + font->glyphs = (struct FONSglyph*)malloc(sizeof(struct FONSglyph) * FONS_INIT_GLYPHS); + if (font->glyphs == NULL) goto error; + font->cglyphs = FONS_INIT_GLYPHS; + font->nglyphs = 0; + + stash->fonts[stash->nfonts++] = font; + return stash->nfonts-1; + +error: + fons__freeFont(font); + + return FONS_INVALID; +} + +int fonsAddFont(struct FONScontext* stash, const char* name, const char* path) +{ + FILE* fp = 0; + int dataSize = 0; + unsigned char* data = NULL; + + // Read in the font data. + fp = fopen(path, "rb"); + if (!fp) goto error; + fseek(fp,0,SEEK_END); + dataSize = (int)ftell(fp); + fseek(fp,0,SEEK_SET); + data = (unsigned char*)malloc(dataSize); + if (data == NULL) goto error; + fread(data, 1, dataSize, fp); + fclose(fp); + fp = 0; + + return fonsAddFontMem(stash, name, data, dataSize, 1); + +error: + if (data) free(data); + if (fp) fclose(fp); + return FONS_INVALID; +} + +int fonsAddFontMem(struct FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData) +{ + int i, ascent, descent, fh, lineGap; + struct FONSfont* font; + + int idx = fons__allocFont(stash); + if (idx == FONS_INVALID) + return FONS_INVALID; + + font = stash->fonts[idx]; + + strncpy(font->name, name, sizeof(font->name)); + font->name[sizeof(font->name)-1] = '\0'; + + // Init hash lookup. + for (i = 0; i < FONS_HASH_LUT_SIZE; ++i) + font->lut[i] = -1; + + // Read in the font data. + font->dataSize = dataSize; + font->data = data; + font->freeData = (unsigned char)freeData; + + // Init font + stash->nscratch = 0; + if (!fons__tt_loadFont(stash, &font->font, data, dataSize)) goto error; + + // Store normalized line height. The real line height is got + // by multiplying the lineh by font size. + fons__tt_getFontVMetrics( &font->font, &ascent, &descent, &lineGap); + fh = ascent - descent; + font->ascender = (float)ascent / (float)fh; + font->descender = (float)descent / (float)fh; + font->lineh = (float)(fh + lineGap) / (float)fh; + + return idx; + +error: + fons__freeFont(font); + stash->nfonts--; + return FONS_INVALID; +} + +int fonsGetFontByName(struct FONScontext* s, const char* name) +{ + int i; + for (i = 0; i < s->nfonts; i++) { + if (strcmp(s->fonts[i]->name, name) == 0) + return i; + } + return FONS_INVALID; +} + + +static struct FONSglyph* fons__allocGlyph(struct FONSfont* font) +{ + if (font->nglyphs+1 > font->cglyphs) { + font->cglyphs = font->cglyphs == 0 ? 8 : font->cglyphs * 2; + font->glyphs = (struct FONSglyph*)realloc(font->glyphs, sizeof(struct FONSglyph) * font->cglyphs); + if (font->glyphs == NULL) return NULL; + } + font->nglyphs++; + return &font->glyphs[font->nglyphs-1]; +} + + +// Based on Exponential blur, Jani Huhtanen, 2006 + +#define APREC 16 +#define ZPREC 7 + +static void fons__blurCols(unsigned char* dst, int w, int h, int dstStride, int alpha) +{ + int x, y; + for (y = 0; y < h; y++) { + int z = 0; // force zero border + for (x = 1; x < w; x++) { + z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC; + dst[x] = (unsigned char)(z >> ZPREC); + } + dst[w-1] = 0; // force zero border + z = 0; + for (x = w-2; x >= 0; x--) { + z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC; + dst[x] = (unsigned char)(z >> ZPREC); + } + dst[0] = 0; // force zero border + dst += dstStride; + } +} + +static void fons__blurRows(unsigned char* dst, int w, int h, int dstStride, int alpha) +{ + int x, y; + for (x = 0; x < w; x++) { + int z = 0; // force zero border + for (y = dstStride; y < h*dstStride; y += dstStride) { + z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC; + dst[y] = (unsigned char)(z >> ZPREC); + } + dst[(h-1)*dstStride] = 0; // force zero border + z = 0; + for (y = (h-2)*dstStride; y >= 0; y -= dstStride) { + z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC; + dst[y] = (unsigned char)(z >> ZPREC); + } + dst[0] = 0; // force zero border + dst++; + } +} + + +static void fons__blur(struct FONScontext* stash, unsigned char* dst, int w, int h, int dstStride, int blur) +{ + int alpha; + float sigma; + (void)stash; + + if (blur < 1) + return; + // Calculate the alpha such that 90% of the kernel is within the radius. (Kernel extends to infinity) + sigma = (float)blur * 0.57735f; // 1 / sqrt(3) + alpha = (int)((1< 20) iblur = 20; + pad = iblur+2; + + // Reset allocator. + stash->nscratch = 0; + + // Find code point and size. + h = fons__hashint(codepoint) & (FONS_HASH_LUT_SIZE-1); + i = font->lut[h]; + while (i != -1) { + if (font->glyphs[i].codepoint == codepoint && font->glyphs[i].size == isize && font->glyphs[i].blur == iblur) + return &font->glyphs[i]; + i = font->glyphs[i].next; + } + + // Could not find glyph, create it. + scale = fons__tt_getPixelHeightScale(&font->font, size); + g = fons__tt_getGlyphIndex(&font->font, codepoint); + fons__tt_buildGlyphBitmap(&font->font, g, size, scale, &advance, &lsb, &x0, &y0, &x1, &y1); + gw = x1-x0 + pad*2; + gh = y1-y0 + pad*2; + + // Find free spot for the rect in the atlas + added = fons__atlasAddRect(stash->atlas, gw, gh, &gx, &gy); + if (added == 0 && stash->handleError != NULL) { + // Atlas is full, let the user to resize the atlas (or not), and try again. + stash->handleError(stash->errorUptr, FONS_ATLAS_FULL, 0); + added = fons__atlasAddRect(stash->atlas, gw, gh, &gx, &gy); + } + if (added == 0) return NULL; + + // Init glyph. + glyph = fons__allocGlyph(font); + glyph->codepoint = codepoint; + glyph->size = isize; + glyph->blur = iblur; + glyph->index = g; + glyph->x0 = (short)gx; + glyph->y0 = (short)gy; + glyph->x1 = (short)(glyph->x0+gw); + glyph->y1 = (short)(glyph->y0+gh); + glyph->xadv = (short)(scale * advance * 10.0f); + glyph->xoff = (short)(x0 - pad); + glyph->yoff = (short)(y0 - pad); + glyph->next = 0; + + // Insert char to hash lookup. + glyph->next = font->lut[h]; + font->lut[h] = font->nglyphs-1; + + // Rasterize + dst = &stash->texData[(glyph->x0+pad) + (glyph->y0+pad) * stash->params.width]; + fons__tt_renderGlyphBitmap(&font->font, dst, gw-pad*2,gh-pad*2, stash->params.width, scale,scale, g); + + // Make sure there is one pixel empty border. + dst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; + for (y = 0; y < gh; y++) { + dst[y*stash->params.width] = 0; + dst[gw-1 + y*stash->params.width] = 0; + } + for (x = 0; x < gw; x++) { + dst[x] = 0; + dst[x + (gh-1)*stash->params.width] = 0; + } + + // Debug code to color the glyph background +/* unsigned char* fdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; + for (y = 0; y < gh; y++) { + for (x = 0; x < gw; x++) { + int a = (int)fdst[x+y*stash->params.width] + 20; + if (a > 255) a = 255; + fdst[x+y*stash->params.width] = a; + } + }*/ + + // Blur + if (iblur > 0) { + stash->nscratch = 0; + bdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width]; + fons__blur(stash, bdst, gw,gh, stash->params.width, iblur); + } + + stash->dirtyRect[0] = fons__mini(stash->dirtyRect[0], glyph->x0); + stash->dirtyRect[1] = fons__mini(stash->dirtyRect[1], glyph->y0); + stash->dirtyRect[2] = fons__maxi(stash->dirtyRect[2], glyph->x1); + stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], glyph->y1); + + return glyph; +} + +static void fons__getQuad(struct FONScontext* stash, struct FONSfont* font, + struct FONSglyph* prevGlyph, struct FONSglyph* glyph, + float scale, float spacing, float* x, float* y, struct FONSquad* q) +{ + float rx,ry,xoff,yoff,x0,y0,x1,y1; + + if (prevGlyph) { + float adv = fons__tt_getGlyphKernAdvance(&font->font, prevGlyph->index, glyph->index) * scale; + *x += (int)(adv + 0.5f); + } + + // Each glyph has 2px border to allow good interpolation, + // one pixel to prevent leaking, and one to allow good interpolation for rendering. + // Inset the texture region by one pixel for corret interpolation. + xoff = (short)(glyph->xoff+1); + yoff = (short)(glyph->yoff+1); + x0 = (float)(glyph->x0+1); + y0 = (float)(glyph->y0+1); + x1 = (float)(glyph->x1-1); + y1 = (float)(glyph->y1-1); + + if (stash->params.flags & FONS_ZERO_TOPLEFT) { + rx = (float)(int)(*x + xoff); + ry = (float)(int)(*y + yoff); + + q->x0 = rx; + q->y0 = ry; + q->x1 = rx + x1 - x0; + q->y1 = ry + y1 - y0; + + q->s0 = x0 * stash->itw; + q->t0 = y0 * stash->ith; + q->s1 = x1 * stash->itw; + q->t1 = y1 * stash->ith; + } else { + rx = (float)(int)(*x + xoff); + ry = (float)(int)(*y - yoff); + + q->x0 = rx; + q->y0 = ry; + q->x1 = rx + x1 - x0; + q->y1 = ry - y1 + y0; + + q->s0 = x0 * stash->itw; + q->t0 = y0 * stash->ith; + q->s1 = x1 * stash->itw; + q->t1 = y1 * stash->ith; + } + + *x += (int)(glyph->xadv / 10.0f + spacing + 0.5f); +} + +static void fons__flush(struct FONScontext* stash) +{ + // Flush texture + if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) { + if (stash->params.renderUpdate != NULL) + stash->params.renderUpdate(stash->params.userPtr, stash->dirtyRect, stash->texData); + // Reset dirty rect + stash->dirtyRect[0] = stash->params.width; + stash->dirtyRect[1] = stash->params.height; + stash->dirtyRect[2] = 0; + stash->dirtyRect[3] = 0; + } + + // Flush triangles + if (stash->nverts > 0) { + if (stash->params.renderDraw != NULL) + stash->params.renderDraw(stash->params.userPtr, stash->verts, stash->tcoords, stash->colors, stash->nverts); + stash->nverts = 0; + } +} + +static __inline void fons__vertex(struct FONScontext* stash, float x, float y, float s, float t, unsigned int c) +{ + stash->verts[stash->nverts*2+0] = x; + stash->verts[stash->nverts*2+1] = y; + stash->tcoords[stash->nverts*2+0] = s; + stash->tcoords[stash->nverts*2+1] = t; + stash->colors[stash->nverts] = c; + stash->nverts++; +} + +static float fons__getVertAlign(struct FONScontext* stash, struct FONSfont* font, int align, short isize) +{ + if (stash->params.flags & FONS_ZERO_TOPLEFT) { + if (align & FONS_ALIGN_TOP) { + return font->ascender * (float)isize/10.0f; + } else if (align & FONS_ALIGN_MIDDLE) { + return (font->ascender + font->descender) / 2.0f * (float)isize/10.0f; + } else if (align & FONS_ALIGN_BASELINE) { + return 0.0f; + } else if (align & FONS_ALIGN_BOTTOM) { + return font->descender * (float)isize/10.0f; + } + } else { + if (align & FONS_ALIGN_TOP) { + return -font->ascender * (float)isize/10.0f; + } else if (align & FONS_ALIGN_MIDDLE) { + return -(font->ascender + font->descender) / 2.0f * (float)isize/10.0f; + } else if (align & FONS_ALIGN_BASELINE) { + return 0.0f; + } else if (align & FONS_ALIGN_BOTTOM) { + return -font->descender * (float)isize/10.0f; + } + } + return 0.0; +} + +float fonsDrawText(struct FONScontext* stash, + float x, float y, + const char* str, const char* end) +{ + struct FONSstate* state = fons__getState(stash); + unsigned int codepoint; + unsigned int utf8state = 0; + struct FONSglyph* glyph = NULL; + struct FONSglyph* prevGlyph = NULL; + struct FONSquad q; + short isize = (short)(state->size*10.0f); + short iblur = (short)state->blur; + float scale; + struct FONSfont* font; + float width; + + if (stash == NULL) return x; + if (state->font < 0 || state->font >= stash->nfonts) return x; + font = stash->fonts[state->font]; + if (!font->data) return x; + + scale = fons__tt_getPixelHeightScale(&font->font, (float)isize/10.0f); + + if (end == NULL) + end = str + strlen(str); + + // Align horizontally + if (state->align & FONS_ALIGN_LEFT) { + // empty + } else if (state->align & FONS_ALIGN_RIGHT) { + width = fonsTextBounds(stash, x,y, str, end, NULL); + x -= width; + } else if (state->align & FONS_ALIGN_CENTER) { + width = fonsTextBounds(stash, x,y, str, end, NULL); + x -= width * 0.5f; + } + // Align vertically. + y += fons__getVertAlign(stash, font, state->align, isize); + + for (; str != end; ++str) { + if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str)) + continue; + glyph = fons__getGlyph(stash, font, codepoint, isize, iblur); + if (glyph) { + fons__getQuad(stash, font, prevGlyph, glyph, scale, state->spacing, &x, &y, &q); + + if (stash->nverts+6 > FONS_VERTEX_COUNT) + fons__flush(stash); + + fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color); + fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color); + fons__vertex(stash, q.x1, q.y0, q.s1, q.t0, state->color); + + fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color); + fons__vertex(stash, q.x0, q.y1, q.s0, q.t1, state->color); + fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color); + } + prevGlyph = glyph; + } + fons__flush(stash); + + return x; +} + +int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter, + float x, float y, const char* str, const char* end) +{ + struct FONSstate* state = fons__getState(stash); + float width; + + memset(iter, 0, sizeof(*iter)); + + if (stash == NULL) return 0; + if (state->font < 0 || state->font >= stash->nfonts) return 0; + iter->font = stash->fonts[state->font]; + if (!iter->font->data) return 0; + + iter->isize = (short)(state->size*10.0f); + iter->iblur = (short)state->blur; + iter->scale = fons__tt_getPixelHeightScale(&iter->font->font, (float)iter->isize/10.0f); + + // Align horizontally + if (state->align & FONS_ALIGN_LEFT) { + // empty + } else if (state->align & FONS_ALIGN_RIGHT) { + width = fonsTextBounds(stash, x,y, str, end, NULL); + x -= width; + } else if (state->align & FONS_ALIGN_CENTER) { + width = fonsTextBounds(stash, x,y, str, end, NULL); + x -= width * 0.5f; + } + // Align vertically. + y += fons__getVertAlign(stash, iter->font, state->align, iter->isize); + + if (end == NULL) + end = str + strlen(str); + + iter->x = iter->nextx = x; + iter->y = iter->nexty = y; + iter->spacing = state->spacing; + iter->str = str; + iter->next = str; + iter->end = end; + iter->codepoint = 0; + + return 1; +} + +int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struct FONSquad* quad) +{ + struct FONSglyph* glyph = NULL; + const char* str = iter->next; + iter->str = iter->next; + + if (str == iter->end) + return 0; + + for (; str != iter->end; str++) { + if (fons__decutf8(&iter->utf8state, &iter->codepoint, *(const unsigned char*)str)) + continue; + str++; + // Get glyph and quad + iter->x = iter->nextx; + iter->y = iter->nexty; + glyph = fons__getGlyph(stash, iter->font, iter->codepoint, iter->isize, iter->iblur); + if (glyph != NULL) + fons__getQuad(stash, iter->font, iter->prevGlyph, glyph, iter->scale, iter->spacing, &iter->nextx, &iter->nexty, quad); + iter->prevGlyph = glyph; + break; + } + iter->next = str; + + return 1; +} + +void fonsDrawDebug(struct FONScontext* stash, float x, float y) +{ + int i; + int w = stash->params.width; + int h = stash->params.height; + float u = w == 0 ? 0 : (1.0f / w); + float v = h == 0 ? 0 : (1.0f / h); + + if (stash->nverts+6+6 > FONS_VERTEX_COUNT) + fons__flush(stash); + + // Draw background + fons__vertex(stash, x+0, y+0, u, v, 0x0fffffff); + fons__vertex(stash, x+w, y+h, u, v, 0x0fffffff); + fons__vertex(stash, x+w, y+0, u, v, 0x0fffffff); + + fons__vertex(stash, x+0, y+0, u, v, 0x0fffffff); + fons__vertex(stash, x+0, y+h, u, v, 0x0fffffff); + fons__vertex(stash, x+w, y+h, u, v, 0x0fffffff); + + // Draw texture + fons__vertex(stash, x+0, y+0, 0, 0, 0xffffffff); + fons__vertex(stash, x+w, y+h, 1, 1, 0xffffffff); + fons__vertex(stash, x+w, y+0, 1, 0, 0xffffffff); + + fons__vertex(stash, x+0, y+0, 0, 0, 0xffffffff); + fons__vertex(stash, x+0, y+h, 0, 1, 0xffffffff); + fons__vertex(stash, x+w, y+h, 1, 1, 0xffffffff); + + // Drawbug draw atlas + for (i = 0; i < stash->atlas->nnodes; i++) { + struct FONSatlasNode* n = &stash->atlas->nodes[i]; + + if (stash->nverts+6 > FONS_VERTEX_COUNT) + fons__flush(stash); + + fons__vertex(stash, x+n->x+0, y+n->y+0, u, v, 0xc00000ff); + fons__vertex(stash, x+n->x+n->width, y+n->y+1, u, v, 0xc00000ff); + fons__vertex(stash, x+n->x+n->width, y+n->y+0, u, v, 0xc00000ff); + + fons__vertex(stash, x+n->x+0, y+n->y+0, u, v, 0xc00000ff); + fons__vertex(stash, x+n->x+0, y+n->y+1, u, v, 0xc00000ff); + fons__vertex(stash, x+n->x+n->width, y+n->y+1, u, v, 0xc00000ff); + } + + fons__flush(stash); +} + +float fonsTextBounds(struct FONScontext* stash, + float x, float y, + const char* str, const char* end, + float* bounds) +{ + struct FONSstate* state = fons__getState(stash); + unsigned int codepoint; + unsigned int utf8state = 0; + struct FONSquad q; + struct FONSglyph* glyph = NULL; + struct FONSglyph* prevGlyph = NULL; + short isize = (short)(state->size*10.0f); + short iblur = (short)state->blur; + float scale; + struct FONSfont* font; + float startx, advance; + float minx, miny, maxx, maxy; + + if (stash == NULL) return 0; + if (state->font < 0 || state->font >= stash->nfonts) return 0; + font = stash->fonts[state->font]; + if (!font->data) return 0; + + scale = fons__tt_getPixelHeightScale(&font->font, (float)isize/10.0f); + + // Align vertically. + y += fons__getVertAlign(stash, font, state->align, isize); + + minx = maxx = x; + miny = maxy = y; + startx = x; + + if (end == NULL) + end = str + strlen(str); + + for (; str != end; ++str) { + if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str)) + continue; + glyph = fons__getGlyph(stash, font, codepoint, isize, iblur); + if (glyph) { + fons__getQuad(stash, font, prevGlyph, glyph, state->spacing, scale, &x, &y, &q); + if (q.x0 < minx) minx = q.x0; + if (q.x1 > maxx) maxx = q.x1; + if (stash->params.flags & FONS_ZERO_TOPLEFT) { + if (q.y0 < miny) miny = q.y0; + if (q.y1 > maxy) maxy = q.y1; + } else { + if (q.y1 < miny) miny = q.y1; + if (q.y0 > maxy) maxy = q.y0; + } + } + prevGlyph = glyph; + } + + advance = x - startx; + + // Align horizontally + if (state->align & FONS_ALIGN_LEFT) { + // empty + } else if (state->align & FONS_ALIGN_RIGHT) { + minx -= advance; + maxx -= advance; + } else if (state->align & FONS_ALIGN_CENTER) { + minx -= advance * 0.5f; + maxx -= advance * 0.5f; + } + + if (bounds) { + bounds[0] = minx; + bounds[1] = miny; + bounds[2] = maxx; + bounds[3] = maxy; + } + + return advance; +} + +void fonsVertMetrics(struct FONScontext* stash, + float* ascender, float* descender, float* lineh) +{ + struct FONSfont* font; + struct FONSstate* state = fons__getState(stash); + short isize; + + if (stash == NULL) return; + if (state->font < 0 || state->font >= stash->nfonts) return; + font = stash->fonts[state->font]; + isize = (short)(state->size*10.0f); + if (!font->data) return; + + if (ascender) + *ascender = font->ascender*isize/10.0f; + if (descender) + *descender = font->descender*isize/10.0f; + if (lineh) + *lineh = font->lineh*isize/10.0f; +} + +void fonsLineBounds(struct FONScontext* stash, float y, float* miny, float* maxy) +{ + struct FONSfont* font; + struct FONSstate* state = fons__getState(stash); + short isize; + + if (stash == NULL) return; + if (state->font < 0 || state->font >= stash->nfonts) return; + font = stash->fonts[state->font]; + isize = (short)(state->size*10.0f); + if (!font->data) return; + + y += fons__getVertAlign(stash, font, state->align, isize); + + if (stash->params.flags & FONS_ZERO_TOPLEFT) { + *miny = y - font->ascender * (float)isize/10.0f; + *maxy = *miny + font->lineh*isize/10.0f; + } else { + *maxy = y + font->descender * (float)isize/10.0f; + *miny = *maxy - font->lineh*isize/10.0f; + } +} + +const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, int* height) +{ + if (width != NULL) + *width = stash->params.width; + if (height != NULL) + *height = stash->params.height; + return stash->texData; +} + +int fonsValidateTexture(struct FONScontext* stash, int* dirty) +{ + if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) { + dirty[0] = stash->dirtyRect[0]; + dirty[1] = stash->dirtyRect[1]; + dirty[2] = stash->dirtyRect[2]; + dirty[3] = stash->dirtyRect[3]; + // Reset dirty rect + stash->dirtyRect[0] = stash->params.width; + stash->dirtyRect[1] = stash->params.height; + stash->dirtyRect[2] = 0; + stash->dirtyRect[3] = 0; + return 1; + } + return 0; +} + +void fonsDeleteInternal(struct FONScontext* stash) +{ + int i; + if (stash == NULL) return; + + if (stash->params.renderDelete) + stash->params.renderDelete(stash->params.userPtr); + + for (i = 0; i < stash->nfonts; ++i) + fons__freeFont(stash->fonts[i]); + + if (stash->atlas) fons__deleteAtlas(stash->atlas); + if (stash->fonts) free(stash->fonts); + if (stash->texData) free(stash->texData); + free(stash); +} + +void fonsSetErrorCallback(struct FONScontext* stash, void (*callback)(void* uptr, int error, int val), void* uptr) +{ + if (stash == NULL) return; + stash->handleError = callback; + stash->errorUptr = uptr; +} + +void fonsGetAtlasSize(struct FONScontext* stash, int* width, int* height) +{ + if (stash == NULL) return; + *width = stash->params.width; + *height = stash->params.height; +} + +int fonsExpandAtlas(struct FONScontext* stash, int width, int height) +{ + int i, maxy = 0; + unsigned char* data = NULL; + if (stash == NULL) return 0; + + width = fons__maxi(width, stash->params.width); + height = fons__maxi(height, stash->params.height); + + if (width == stash->params.width && height == stash->params.height) + return 1; + + // Flush pending glyphs. + fons__flush(stash); + + // Create new texture + if (stash->params.renderResize != NULL) { + if (stash->params.renderResize(stash->params.userPtr, width, height) == 0) + return 0; + } + // Copy old texture data over. + data = (unsigned char*)malloc(width * height); + if (data == NULL) + return 0; + for (i = 0; i < stash->params.height; i++) { + unsigned char* dst = &data[i*width]; + unsigned char* src = &stash->texData[i*stash->params.width]; + memcpy(dst, src, stash->params.width); + if (width > stash->params.width) + memset(dst+stash->params.width, 0, width - stash->params.width); + } + if (height > stash->params.height) + memset(&data[stash->params.height * width], 0, (height - stash->params.height) * width); + + free(stash->texData); + stash->texData = data; + + // Increase atlas size + fons__atlasExpand(stash->atlas, width, height); + + // Add axisting data as dirty. + for (i = 0; i < stash->atlas->nnodes; i++) + maxy = fons__maxi(maxy, stash->atlas->nodes[i].y); + stash->dirtyRect[0] = 0; + stash->dirtyRect[1] = 0; + stash->dirtyRect[2] = stash->params.width; + stash->dirtyRect[3] = maxy; + + stash->params.width = width; + stash->params.height = height; + stash->itw = 1.0f/stash->params.width; + stash->ith = 1.0f/stash->params.height; + + return 1; +} + +int fonsResetAtlas(struct FONScontext* stash, int width, int height) +{ + int i, j; + if (stash == NULL) return 0; + + // Flush pending glyphs. + fons__flush(stash); + + // Create new texture + if (stash->params.renderResize != NULL) { + if (stash->params.renderResize(stash->params.userPtr, width, height) == 0) + return 0; + } + + // Reset atlas + fons__atlasReset(stash->atlas, width, height); + + // Clear texture data. + stash->texData = (unsigned char*)realloc(stash->texData, width * height); + if (stash->texData == NULL) return 0; + memset(stash->texData, 0, width * height); + + // Reset dirty rect + stash->dirtyRect[0] = width; + stash->dirtyRect[1] = height; + stash->dirtyRect[2] = 0; + stash->dirtyRect[3] = 0; + + // Reset cached glyphs + for (i = 0; i < stash->nfonts; i++) { + struct FONSfont* font = stash->fonts[i]; + font->nglyphs = 0; + for (j = 0; j < FONS_HASH_LUT_SIZE; j++) + font->lut[j] = -1; + } + + stash->params.width = width; + stash->params.height = height; + stash->itw = 1.0f/stash->params.width; + stash->ith = 1.0f/stash->params.height; + + // Add white rect at 0,0 for debug drawing. + fons__addWhiteRect(stash, 2,2); + + return 1; +} + + +#endif diff --git a/examples/common/nanovg/fs_nanovg_fill.bin.h b/examples/common/nanovg/fs_nanovg_fill.bin.h new file mode 100644 index 00000000..73bc3bea --- /dev/null +++ b/examples/common/nanovg/fs_nanovg_fill.bin.h @@ -0,0 +1,513 @@ +static const uint8_t fs_nanovg_fill_glsl[3149] = +{ + 0x46, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x08, 0x00, 0x0c, 0x75, 0x5f, 0x73, 0x63, 0x69, // FSH........u_sci + 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x08, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x75, 0x5f, // ssorMat.......u_ + 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x08, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x75, // paintMat.......u + 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, // _innerCol....... + 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00, // u_outerCol...... + 0x11, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, // .u_scissorExtSca + 0x6c, 0x65, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0e, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, // le.......u_exten + 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00, 0x08, 0x75, 0x5f, // tRadius.......u_ + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00, 0x05, 0x73, 0x5f, 0x74, // params.......s_t + 0x65, 0x78, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0x76, 0x61, 0x72, 0x79, // ex..........vary + 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, // ing mediump vec2 + 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, // v_position;.var + 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, // ying mediump vec + 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x75, // 2 v_texcoord0;.u + 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x6d, // niform mediump m + 0x61, 0x74, 0x33, 0x20, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, // at3 u_scissorMat + 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, // ;.uniform medium + 0x70, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x20, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, // p mat3 u_paintMa + 0x74, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, // t;.uniform mediu + 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, // mp vec4 u_innerC + 0x6f, 0x6c, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, // ol;.uniform medi + 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, // ump vec4 u_outer + 0x43, 0x6f, 0x6c, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, // Col;.uniform med + 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, // iump vec4 u_scis + 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x3b, 0x0a, 0x75, 0x6e, 0x69, // sorExtScale;.uni + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, // form mediump vec + 0x34, 0x20, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, // 4 u_extentRadius + 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, // ;.uniform medium + 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3b, // p vec4 u_params; + 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, // .uniform sampler + 0x32, 0x44, 0x20, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, // 2D s_tex;.void m + 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, // ain ().{. lowp + 0x76, 0x65, 0x63, 0x34, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x3b, 0x0a, 0x20, // vec4 result_1;. + 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, // mediump float t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, // mpvar_2;. mediu + 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // mp vec3 tmpvar_3 + 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x2e, 0x7a, 0x20, 0x3d, // ;. tmpvar_3.z = + 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, // 1.0;. tmpvar_3 + 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // .xy = v_position + 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, // ;. mediump vec2 + 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, // tmpvar_4;. tmp + 0x76, 0x61, 0x72, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x28, 0x76, 0x65, 0x63, 0x32, 0x28, 0x30, 0x2e, // var_4 = (vec2(0. + 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x20, 0x2d, 0x20, 0x28, 0x28, 0x0a, 0x20, 0x20, 0x20, // 5, 0.5) - ((. + 0x20, 0x61, 0x62, 0x73, 0x28, 0x28, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, // abs((u_scissorM + 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x2e, 0x78, // at * tmpvar_3).x + 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, // y). - u_scisso + 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x78, 0x79, 0x29, 0x20, 0x2a, 0x20, // rExtScale.xy) * + 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, // u_scissorExtScal + 0x65, 0x2e, 0x7a, 0x77, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // e.zw));. tmpvar + 0x5f, 0x32, 0x20, 0x3d, 0x20, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, 0x28, 0x74, 0x6d, 0x70, // _2 = (clamp (tmp + 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x78, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, // var_4.x, 0.0, 1. + 0x30, 0x29, 0x20, 0x2a, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, // 0) * clamp (tmpv + 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x79, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, // ar_4.y, 0.0, 1.0 + 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x66, 0x6c, // ));. mediump fl + 0x6f, 0x61, 0x74, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x3b, 0x0a, 0x20, 0x20, // oat tmpvar_5;. + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x3d, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x20, // tmpvar_5 = (min + 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x31, 0x2e, 0x30, // (1.0, (. (1.0 + 0x20, 0x2d, 0x20, 0x61, 0x62, 0x73, 0x28, 0x28, 0x28, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, // - abs(((v_texco + 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x20, 0x2d, 0x20, // ord0.x * 2.0) - + 0x31, 0x2e, 0x30, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x2a, 0x20, 0x75, 0x5f, 0x70, 0x61, // 1.0))). * u_pa + 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x79, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x28, // rams.y)) * min ( + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // 1.0, v_texcoord0 + 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x75, 0x5f, 0x70, // .y));. if ((u_p + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, // arams.w == 0.0)) + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, // {. mediump v + 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x20, // ec4 color_6;. + 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x74, 0x6d, // mediump vec3 tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // pvar_7;. tmpv + 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, // ar_7.z = 1.0;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x37, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, // tmpvar_7.xy = + 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // v_position;. + 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x6d, 0x70, // mediump vec2 tmp + 0x76, 0x61, 0x72, 0x5f, 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // var_8;. tmpva + 0x72, 0x5f, 0x38, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x62, 0x73, 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, // r_8 = (abs((u_pa + 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // intMat * tmpvar_ + 0x37, 0x29, 0x2e, 0x78, 0x79, 0x29, 0x20, 0x2d, 0x20, 0x28, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, // 7).xy) - (u_exte + 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x78, 0x79, 0x20, 0x2d, 0x20, 0x75, 0x5f, // ntRadius.xy - u_ + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x7a, 0x7a, 0x29, // extentRadius.zz) + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, // );. mediump v + 0x65, 0x63, 0x32, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x3b, 0x0a, 0x20, 0x20, // ec2 tmpvar_9;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, // tmpvar_9 = max + 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, // (tmpvar_8, 0.0) + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, // ;. mediump ve + 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, // c4 tmpvar_10;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x20, 0x3d, 0x20, 0x6d, 0x69, // tmpvar_10 = mi + 0x78, 0x20, 0x28, 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x2c, 0x20, 0x75, // x (u_innerCol, u + 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x2c, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, // _outerCol, clamp + 0x20, 0x28, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x6d, 0x69, 0x6e, // ((. (((min + 0x20, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x28, // (. max ( + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x38, 0x2e, 0x78, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_8.x, tmpv + 0x61, 0x72, 0x5f, 0x38, 0x2e, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x20, // ar_8.y). , + 0x30, 0x2e, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x71, 0x72, 0x74, 0x28, 0x0a, 0x20, 0x20, 0x20, // 0.0) + sqrt(. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // dot (tmpvar + 0x5f, 0x39, 0x2c, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x39, 0x29, 0x0a, 0x20, 0x20, // _9, tmpvar_9). + 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20, 0x2d, 0x20, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, // )) - u_exten + 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x7a, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x75, 0x5f, // tRadius.z) + (u_ + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, // params.x * 0.5)) + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x20, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, // . / u_params + 0x2e, 0x78, 0x29, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, // .x), 0.0, 1.0)); + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x2e, 0x78, 0x79, 0x7a, // . color_6.xyz + 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x78, 0x79, 0x7a, // = tmpvar_10.xyz + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x2e, 0x77, 0x20, // ;. color_6.w + 0x3d, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x30, 0x2e, 0x77, 0x20, 0x2a, // = (tmpvar_10.w * + 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, // (tmpvar_5 * tmp + 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, // var_2));. res + 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x36, 0x3b, // ult_1 = color_6; + 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, // . } else {. + 0x69, 0x66, 0x20, 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, // if ((u_params.w + 0x3d, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // == 1.0)) {. + 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // lowp vec4 color + 0x5f, 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, // _11;. mediu + 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // mp vec3 tmpvar_1 + 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // 2;. tmpvar_ + 0x31, 0x32, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // 12.z = 1.0;. + 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x32, 0x2e, 0x78, 0x79, 0x20, 0x3d, // tmpvar_12.xy = + 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, // v_position;. + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, // lowp vec4 tmp + 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, // var_13;. tm + 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, // pvar_13 = textur + 0x65, 0x32, 0x44, 0x20, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x28, 0x28, 0x75, 0x5f, // e2D (s_tex, ((u_ + 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // paintMat * tmpva + 0x72, 0x5f, 0x31, 0x32, 0x29, 0x2e, 0x78, 0x79, 0x20, 0x2f, 0x20, 0x75, 0x5f, 0x65, 0x78, 0x74, // r_12).xy / u_ext + 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x2e, 0x78, 0x79, 0x29, 0x29, 0x3b, 0x0a, // entRadius.xy));. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x20, 0x3d, // color_11 = + 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, // tmpvar_13;. + 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, // lowp vec4 tmpv + 0x61, 0x72, 0x5f, 0x31, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, // ar_14;. if + 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x7a, 0x20, 0x3d, 0x3d, 0x20, // ((u_params.z == + 0x30, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // 0.0)) {. + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_14 = tmpv + 0x61, 0x72, 0x5f, 0x31, 0x33, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, // ar_13;. } e + 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, // lse {. lo + 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // wp vec4 tmpvar_1 + 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // 5;. tmpva + 0x72, 0x5f, 0x31, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, // r_15.xyz = vec3( + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, // 1.0, 1.0, 1.0);. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // tmpvar_1 + 0x35, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x33, 0x2e, // 5.w = tmpvar_13. + 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // x;. tmpva + 0x72, 0x5f, 0x31, 0x34, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x35, // r_14 = tmpvar_15 + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // ;. };. + 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, // color_11.xyz = + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, // tmpvar_14.xyz;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x31, 0x2e, 0x77, 0x20, // color_11.w + 0x3d, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x34, 0x2e, 0x77, 0x20, 0x2a, // = (tmpvar_14.w * + 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x35, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, // (tmpvar_5 * tmp + 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, // var_2));. r + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, // esult_1 = color_ + 0x31, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, // 11;. } else { + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, // . if ((u_pa + 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x29, 0x29, 0x20, // rams.w == 2.0)) + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // {. result + 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, // _1 = vec4(1.0, 1 + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, // .0, 1.0, 1.0);. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, // } else {. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, 0x72, // if ((u_par + 0x61, 0x6d, 0x73, 0x2e, 0x77, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, // ams.w == 3.0)) { + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, // . lowp + 0x76, 0x65, 0x63, 0x34, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x36, 0x3b, 0x0a, 0x20, // vec4 color_16;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, 0x65, // lowp ve + 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x37, 0x3b, 0x0a, 0x20, 0x20, // c4 tmpvar_17;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // tmpvar_1 + 0x37, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x20, 0x28, 0x73, // 7 = texture2D (s + 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // _tex, v_texcoord + 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, // 0);. co + 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x36, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // lor_16 = tmpvar_ + 0x31, 0x37, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, // 17;. lo + 0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // wp vec4 tmpvar_1 + 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, // 8;. if + 0x28, 0x28, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x7a, 0x20, 0x3d, 0x3d, 0x20, // ((u_params.z == + 0x30, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // 0.0)) {. + 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x20, 0x3d, 0x20, // tmpvar_18 = + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x37, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, // tmpvar_17;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, // } else {. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, 0x76, // lowp v + 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x39, 0x3b, 0x0a, 0x20, // ec4 tmpvar_19;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // tmpva + 0x72, 0x5f, 0x31, 0x39, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, // r_19.xyz = vec3( + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, // 1.0, 1.0, 1.0);. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpv + 0x61, 0x72, 0x5f, 0x31, 0x39, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // ar_19.w = tmpvar + 0x5f, 0x31, 0x37, 0x2e, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // _17.x;. + 0x20, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x20, 0x3d, 0x20, 0x74, // tmpvar_18 = t + 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x39, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // mpvar_19;. + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // };. + 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, // color_16.xyz = + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, // tmpvar_18.xyz;. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, // color_1 + 0x36, 0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x38, // 6.w = (tmpvar_18 + 0x2e, 0x77, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x3b, 0x0a, // .w * tmpvar_2);. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // result + 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x28, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x31, 0x36, 0x20, 0x2a, // _1 = (color_16 * + 0x20, 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, // u_innerCol);. + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, // };. } + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, // ;. };. };. + 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x72, // gl_FragColor = r + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // esult_1;.}... +}; +static const uint8_t fs_nanovg_fill_dx9[1531] = +{ + 0x46, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x07, 0x00, 0x0e, 0x75, 0x5f, 0x65, 0x78, 0x74, // FSH........u_ext + 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x15, 0x01, 0x09, 0x00, 0x01, 0x00, 0x0a, // entRadius....... + 0x75, 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x15, 0x01, 0x06, 0x00, 0x01, 0x00, // u_innerCol...... + 0x0a, 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x15, 0x01, 0x07, 0x00, 0x01, // .u_outerCol..... + 0x00, 0x0a, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x18, 0x01, 0x03, 0x00, // ..u_paintMat.... + 0x03, 0x00, 0x08, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x15, 0x01, 0x0a, 0x00, 0x01, // ...u_params..... + 0x00, 0x11, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, // ..u_scissorExtSc + 0x61, 0x6c, 0x65, 0x15, 0x01, 0x08, 0x00, 0x01, 0x00, 0x0c, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, // ale.......u_scis + 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x18, 0x01, 0x00, 0x00, 0x03, 0x00, 0x6c, 0x05, 0x00, 0x03, // sorMat......l... + 0xff, 0xff, 0xfe, 0xff, 0x63, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x57, 0x01, // ....c.CTAB....W. + 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x81, // ................ + 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, // ..P............. + 0x02, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x02, 0x00, // ................ + 0x09, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, // ................ + 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, // ................ + 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x02, 0x00, // ..........(..... + 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x01, // ..............1. + 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x01, // ..C............. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x00, 0xab, 0xab, 0x04, 0x00, // ......s_tex..... + 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ..............u_ + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x00, 0xab, 0x01, 0x00, // extentRadius.... + 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ..............u_ + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x00, 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, // innerCol.u_outer + 0x43, 0x6f, 0x6c, 0x00, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x00, 0xab, // Col.u_paintMat.. + 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x00, 0x75, 0x5f, 0x73, 0x63, 0x69, // ..u_params.u_sci + 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x75, 0x5f, 0x73, // ssorExtScale.u_s + 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x00, 0x70, 0x73, 0x5f, 0x33, 0x5f, 0x30, // cissorMat.ps_3_0 + 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, // .Microsoft (R) H + 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, // LSL Shader Compi + 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, // ler 9.29.952.311 + 0x31, 0x00, 0x51, 0x00, 0x00, 0x05, 0x0b, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, // 1.Q..........?.. + 0x00, 0x40, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x51, 0x00, 0x00, 0x05, 0x0c, 0x00, // .@.......?Q..... + 0x0f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, // .........?..@@.. + 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x90, 0x1f, 0x00, // ................ + 0x00, 0x02, 0x05, 0x00, 0x01, 0x80, 0x01, 0x00, 0x03, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, // ................ + 0x00, 0x90, 0x00, 0x08, 0x0f, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, // ................ + 0x00, 0x90, 0x0b, 0x00, 0x55, 0xa0, 0x0b, 0x00, 0xaa, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, // ....U........... + 0x01, 0x80, 0x00, 0x00, 0x00, 0x8c, 0x0b, 0x00, 0xff, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ + 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x55, 0xa0, 0x0a, 0x00, 0x00, 0x03, 0x01, 0x00, // ........U....... + 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x0b, 0x00, 0xff, 0xa0, 0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ + 0x01, 0x80, 0x01, 0x00, 0x55, 0x90, 0x0b, 0x00, 0xff, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, // ....U........... + 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ + 0x06, 0x80, 0x04, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, // ........U....... + 0x06, 0x80, 0x03, 0x00, 0xd0, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0xe4, 0x80, 0x02, 0x00, // ................ + 0x00, 0x03, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x05, 0x00, 0xd0, 0xa0, 0x06, 0x00, // ................ + 0x00, 0x02, 0x01, 0x00, 0x01, 0x80, 0x09, 0x00, 0x00, 0xa0, 0x06, 0x00, 0x00, 0x02, 0x01, 0x00, // ................ + 0x02, 0x80, 0x09, 0x00, 0x55, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x80, 0x00, 0x00, // ....U........... + 0xe9, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x01, 0x00, 0x0c, 0x80, 0x01, 0x00, // ................ + 0x44, 0xa0, 0x00, 0x00, 0x55, 0x90, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x00, // D...U........... + 0x44, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, // D............... + 0x0c, 0x80, 0x01, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x44, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, // ........D....... + 0x0c, 0x80, 0x01, 0x00, 0xe4, 0x8b, 0x08, 0x00, 0x44, 0xa1, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, // ........D....... + 0x07, 0x80, 0x0b, 0x00, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x01, 0x00, 0x1c, 0x80, 0x01, 0x00, // ................ + 0xe4, 0x80, 0x08, 0x00, 0xe4, 0xa1, 0x02, 0x00, 0x00, 0x80, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ + 0x08, 0x80, 0x01, 0x00, 0xff, 0x80, 0x01, 0x00, 0xaa, 0x80, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, // ................ + 0x01, 0x80, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x03, 0x01, 0x00, // ................ + 0x04, 0x80, 0x02, 0x00, 0xaa, 0x80, 0x0a, 0x00, 0xff, 0xa0, 0x23, 0x00, 0x00, 0x02, 0x02, 0x00, // ..........#..... + 0x0c, 0x80, 0x0a, 0x00, 0xb4, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x03, 0x00, 0x0f, 0x80, 0x01, 0x00, // ......B......... + 0xe4, 0x80, 0x00, 0x08, 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0f, 0x80, 0x03, 0x00, // ................ + 0x00, 0x80, 0x0c, 0x00, 0x40, 0xa0, 0x0c, 0x00, 0x15, 0xa0, 0x58, 0x00, 0x00, 0x04, 0x03, 0x00, // ....@.....X..... + 0x0f, 0x80, 0x02, 0x00, 0xff, 0x81, 0x03, 0x00, 0xe4, 0x80, 0x04, 0x00, 0xe4, 0x80, 0x05, 0x00, // ................ + 0x00, 0x03, 0x03, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xff, 0x80, 0x29, 0x00, // ..............). + 0x02, 0x02, 0x0a, 0x00, 0xff, 0xa0, 0x02, 0x00, 0x55, 0x80, 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, // ........U....... + 0x0f, 0x80, 0x0b, 0x00, 0xff, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x05, 0x00, // ......*......... + 0x04, 0x80, 0x0c, 0x00, 0xaa, 0xa0, 0x29, 0x00, 0x02, 0x02, 0x0a, 0x00, 0xff, 0xa0, 0x05, 0x00, // ......)......... + 0xaa, 0x80, 0x42, 0x00, 0x00, 0x03, 0x05, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x90, 0x00, 0x08, // ..B............. + 0xe4, 0xa0, 0x04, 0x00, 0x00, 0x04, 0x06, 0x00, 0x0f, 0x80, 0x05, 0x00, 0x00, 0x80, 0x0c, 0x00, // ................ + 0x40, 0xa0, 0x0c, 0x00, 0x15, 0xa0, 0x58, 0x00, 0x00, 0x04, 0x05, 0x00, 0x0f, 0x80, 0x02, 0x00, // @.....X......... + 0xff, 0x81, 0x05, 0x00, 0xe4, 0x80, 0x06, 0x00, 0xe4, 0x80, 0x05, 0x00, 0x00, 0x03, 0x05, 0x00, // ................ + 0x08, 0x80, 0x00, 0x00, 0xff, 0x80, 0x05, 0x00, 0xff, 0x80, 0x05, 0x00, 0x00, 0x03, 0x04, 0x00, // ................ + 0x0f, 0x80, 0x05, 0x00, 0xe4, 0x80, 0x06, 0x00, 0xe4, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x00, // ..........*..... + 0x00, 0x02, 0x04, 0x00, 0x0f, 0x80, 0x0c, 0x00, 0x00, 0xa0, 0x2b, 0x00, 0x00, 0x00, 0x2b, 0x00, // ..........+...+. + 0x00, 0x00, 0x58, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xaa, 0x8c, 0x03, 0x00, // ..X............. + 0xe4, 0x80, 0x04, 0x00, 0xe4, 0x80, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x0a, 0x80, 0x09, 0x00, // ................ + 0xaa, 0xa1, 0x09, 0x00, 0x60, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, // ....`........... + 0xe4, 0x8b, 0x02, 0x00, 0xf4, 0x81, 0x0b, 0x00, 0x00, 0x03, 0x02, 0x00, 0x0a, 0x80, 0x00, 0x00, // ................ + 0xa4, 0x80, 0x0c, 0x00, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x08, 0x80, 0x02, 0x00, // ......Z......... + 0xed, 0x80, 0x02, 0x00, 0xed, 0x80, 0x0c, 0x00, 0x00, 0xa0, 0x07, 0x00, 0x00, 0x02, 0x00, 0x00, // ................ + 0x08, 0x80, 0x00, 0x00, 0xff, 0x80, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, // ................ + 0xff, 0x80, 0x0b, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x80, 0x00, 0x00, 0x55, 0x80, 0x00, 0x00, // ............U... + 0xaa, 0x80, 0x0a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x55, 0x80, 0x0c, 0x00, // ............U... + 0x00, 0xa0, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, // ................ + 0x55, 0x80, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x55, 0x80, 0x09, 0x00, // U...........U... + 0xaa, 0xa1, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x00, 0xa0, 0x02, 0x00, // ................ + 0x00, 0x80, 0x00, 0x00, 0x55, 0x80, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x80, 0x0a, 0x00, // ....U........... + 0x00, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x12, 0x80, 0x00, 0x00, 0xaa, 0x80, 0x00, 0x00, // ................ + 0x55, 0x80, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x0f, 0x80, 0x06, 0x00, 0xe4, 0xa0, 0x02, 0x00, // U............... + 0x00, 0x03, 0x03, 0x00, 0x0f, 0x80, 0x03, 0x00, 0xe4, 0x81, 0x07, 0x00, 0xe4, 0xa0, 0x04, 0x00, // ................ + 0x00, 0x04, 0x03, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x55, 0x80, 0x03, 0x00, 0xe4, 0x80, 0x06, 0x00, // ........U....... + 0xe4, 0xa0, 0x05, 0x00, 0x00, 0x03, 0x03, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, // ................ + 0xff, 0x80, 0x58, 0x00, 0x00, 0x04, 0x00, 0x08, 0x0f, 0x80, 0x02, 0x00, 0xaa, 0x81, 0x03, 0x00, // ..X............. + 0xe4, 0x80, 0x01, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, // ........... +}; +static const uint8_t fs_nanovg_fill_dx11[3372] = +{ + 0x46, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x07, 0x00, 0x0c, 0x75, 0x5f, 0x73, 0x63, 0x69, // FSH........u_sci + 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x18, 0x00, 0xb0, 0x09, 0x03, 0x00, 0x0a, 0x75, 0x5f, // ssorMat.......u_ + 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x18, 0x00, 0xe0, 0x09, 0x03, 0x00, 0x0a, 0x75, // paintMat.......u + 0x5f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x15, 0x00, 0x10, 0x0a, 0x01, 0x00, 0x0a, // _innerCol....... + 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x15, 0x00, 0x20, 0x0a, 0x01, 0x00, // u_outerCol.. ... + 0x11, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, 0x63, 0x61, // .u_scissorExtSca + 0x6c, 0x65, 0x15, 0x00, 0x30, 0x0a, 0x01, 0x00, 0x0e, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, // le..0....u_exten + 0x74, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x15, 0x00, 0x40, 0x0a, 0x01, 0x00, 0x08, 0x75, 0x5f, // tRadius..@....u_ + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x15, 0x00, 0x50, 0x0a, 0x01, 0x00, 0x8c, 0x0c, 0x44, 0x58, // params..P.....DX + 0x42, 0x43, 0x4a, 0x85, 0xd2, 0x66, 0x3b, 0xfa, 0xb9, 0x35, 0xcc, 0x17, 0x20, 0x80, 0xf6, 0x89, // BCJ..f;..5.. ... + 0x8e, 0x7a, 0x01, 0x00, 0x00, 0x00, 0x8c, 0x0c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, // .z............4. + 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x84, 0x04, 0x00, 0x00, 0x10, 0x0c, // ......P......... + 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa4, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x00, // ..RDEF.......... + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x91, // ................ + 0x00, 0x00, 0x73, 0x03, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ..s...|......... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ................ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, // ................ + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ................ + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x53, 0x61, 0x6d, 0x70, 0x6c, // ......s_texSampl + 0x65, 0x72, 0x00, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, // er.s_texTexture. + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0x96, 0x00, 0x00, 0x00, 0x11, 0x00, // $Globals........ + 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x60, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......`......... + 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ..P............. + 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x02, 0x00, 0x00, 0x10, 0x00, // ..........l..... + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x78, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // ..x... ...@..... + 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x02, 0x00, 0x00, 0x60, 0x00, // ..............`. + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, // ..@............. + 0x00, 0x00, 0x9b, 0x02, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0xa4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x02, 0x00, 0x00, 0xa0, 0x08, // ................ + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, // ..@............. + 0x00, 0x00, 0xc0, 0x02, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........@..... + 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x20, 0x09, // .............. . + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, // ..@............. + 0x00, 0x00, 0xe1, 0x02, 0x00, 0x00, 0x60, 0x09, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // ......`...@..... + 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x02, 0x00, 0x00, 0xa0, 0x09, // ................ + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0xb0, 0x09, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x00, // ..........,..... + 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00, 0xe0, 0x09, // ..........(..... + 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, // ..,............. + 0x00, 0x00, 0x33, 0x03, 0x00, 0x00, 0x10, 0x0a, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, // ..3............. + 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0x20, 0x0a, // ..........>... . + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x49, 0x03, 0x00, 0x00, 0x30, 0x0a, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, // ..I...0......... + 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x03, 0x00, 0x00, 0x40, 0x0a, // ..........[...@. + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x6a, 0x03, 0x00, 0x00, 0x50, 0x0a, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, // ..j...P......... + 0x00, 0x00, 0x5c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, // ..........u_view + 0x52, 0x65, 0x63, 0x74, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, // Rect............ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x54, 0x65, 0x78, 0x65, // ......u_viewTexe + 0x6c, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x00, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, // l.u_view........ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, // ..........u_view + 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0xab, 0x03, 0x00, // Proj.u_model.... + 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ...... .......u_ + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // modelView.u_mode + 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, // lViewProj.u_mode + 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, // lViewProjX.u_vie + 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x75, 0x5f, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x52, 0x65, // wProjX.u_alphaRe + 0x66, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f............... + 0x00, 0x00, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x00, 0xab, // ..u_scissorMat.. + 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x75, 0x5f, 0x70, 0x61, 0x69, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x00, 0x75, 0x5f, 0x69, // ..u_paintMat.u_i + 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6c, 0x00, 0x75, 0x5f, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x43, // nnerCol.u_outerC + 0x6f, 0x6c, 0x00, 0x75, 0x5f, 0x73, 0x63, 0x69, 0x73, 0x73, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x53, // ol.u_scissorExtS + 0x63, 0x61, 0x6c, 0x65, 0x00, 0x75, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x64, // cale.u_extentRad + 0x69, 0x75, 0x73, 0x00, 0x75, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x00, 0x4d, 0x69, 0x63, // ius.u_params.Mic + 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, // rosoft (R) HLSL + 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, // Shader Compiler + 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x49, 0x53, // 9.29.952.3111.IS + 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, // GNh...........P. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x5c, 0x00, // ................ + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, // ................ + 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, // ......SV_POSITIO + 0x4e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0xab, 0xab, 0x4f, 0x53, // N.TEXCOORD....OS + 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, // GN,........... . + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, // ......SV_TARGET. + 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x84, 0x07, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe1, 0x01, // ..SHDR....@..... + 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, // ..Y...F. ....... + 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, // ..Z....`......X. + 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, // ...p......UU..b. + 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xc2, 0x10, // ..2.......b..... + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, // ......e.... .... + 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x32, 0x00, // ..h.......8...2. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, // ......V.......F. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x32, 0x00, // .........2...2. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x00, // ......F. ....... + 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........F..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, // ......2.......F. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x00, // ......F. ....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, // ......2.......F. + 0x10, 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x80, 0x41, 0x00, // ..........F. .A. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x0e, 0x32, 0x00, // ..........2 ..2. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, // ......F...A..... + 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x02, 0x40, // .... ..........@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....?...?...... + 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, // ..8............. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, // ..............2. + 0x00, 0x09, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x10, 0x10, 0x00, 0x01, 0x00, // ..".......*..... + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, // ...@.....@.@.... + 0x80, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, // ......"......... + 0x10, 0x80, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, // ...........@.... + 0x80, 0x3f, 0x38, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, // .?8..."......... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, // ........ ....... + 0x00, 0x00, 0x33, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, // ..3..."......... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x33, 0x00, // .......@.....?3. + 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, // ..B.......:..... + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x38, 0x00, 0x00, 0x07, 0x22, 0x00, // ...@.....?8...". + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, // ......*......... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........B..... + 0x00, 0x00, 0x3a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, // ..:. ..........@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x04, 0x03, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........*..... + 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, // ..8...........V. + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x00, // ........ ....... + 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, // ..2............. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, // ............... + 0x00, 0x00, 0xa6, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc2, 0x00, // ................ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, // ................ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, // .............2. + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x8a, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ .A..... + 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, // ......F. ....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, // ................ + 0x10, 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0x10, 0x80, 0x41, 0x00, // ..............A. + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, // ......4......... + 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, // ..:.......*..... + 0x00, 0x00, 0x33, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, // ..3............. + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, // .......@......4. + 0x00, 0x0a, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, 0x10, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...@............ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........B..... + 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x4b, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, // ..K...B.......*. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........B..... + 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, // ..*............. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, // ......B.......*. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, // ......*. .A..... + 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, // ......2...B..... + 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, // .... ..........@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x20, // .....?*........ + 0x00, 0x08, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, // ..B.......*..... + 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, // .... ........... + 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x80, 0x41, 0x00, // ..........F. .A. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..........F. ... + 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, // ......2......... + 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, // ..........F..... + 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x38, 0x00, // ..F. .........8. + 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, // ..B............. + 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x82, 0x20, // ..........8.... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, // ......*.......:. + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, // ......6...r .... + 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, 0x18, 0x00, // ..F............. + 0x00, 0x08, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x80, 0x20, 0x00, 0x00, 0x00, // ..B.......:. ... + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x1f, 0x00, // .......@.....?.. + 0x04, 0x03, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xc2, 0x00, // ..*.......8..... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x84, // ......V......... + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xc2, 0x00, // .........2..... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, // ........ ....... + 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x0e, 0x10, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, // ................ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, // ........ ....... + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x0e, // ................ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, // ........ ....... + 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe6, 0x0a, // ..E............. + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, // ......F~.......` + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, // ..........B..... + 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, // ..*. ..........@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, // ......6......... + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x82, 0x00, // ...@.....?6..... + 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x37, 0x00, // ..............7. + 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x10, 0x00, 0x02, 0x00, // ..F............. + 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, // ..8..."......... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, // ..............8. + 0x00, 0x07, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, // ... ............ + 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, // ..:.......6...r + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, // ......F......... + 0x00, 0x01, 0x18, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x80, // ......".......:. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, // ..........@.... + 0x00, 0x40, 0x1f, 0x00, 0x04, 0x03, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, // .@............6. + 0x00, 0x08, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, // ... .......@.... + 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x12, 0x00, // .?...?...?...?.. + 0x00, 0x01, 0x18, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x80, // ......".......:. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, // ..........@.... + 0x40, 0x40, 0x1f, 0x00, 0x04, 0x03, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, // @@............E. + 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe6, 0x1a, 0x10, 0x00, 0x01, 0x00, // ................ + 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, // ..F~.......`.... + 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, // ......".......*. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, // ..........@.... + 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, // ..6............@ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, // .....?6......... + 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x09, 0xf2, 0x00, // ..........7..... + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, // ......V.......F. + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, // ..............8. + 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xf2, 0x20, // ..:.......8.... + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, // ......F.......F. + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x15, 0x00, // ............... + 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, // ..........>...ST + 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ATt...C......... + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ......%......... + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0a, // ..........`. +}; diff --git a/examples/common/nanovg/fs_nanovg_fill.sc b/examples/common/nanovg/fs_nanovg_fill.sc new file mode 100644 index 00000000..15b0e6c7 --- /dev/null +++ b/examples/common/nanovg/fs_nanovg_fill.sc @@ -0,0 +1,89 @@ +$input v_position, v_texcoord0 + +#include "../common.sh" + +#define EDGE_AA 1 + +uniform mat3 u_scissorMat; +uniform mat3 u_paintMat; +uniform vec4 u_innerCol; +uniform vec4 u_outerCol; +uniform vec4 u_scissorExtScale; +uniform vec4 u_extentRadius; +uniform vec4 u_params; +SAMPLER2D(s_tex, 0); + +#define u_scissorExt (u_scissorExtScale.xy) +#define u_scissorScale (u_scissorExtScale.zw) +#define u_extent (u_extentRadius.xy) +#define u_radius (u_extentRadius.z) +#define u_feather (u_params.x) +#define u_strokeMult (u_params.y) +#define u_texType (u_params.z) +#define u_type (u_params.w) + +float sdroundrect(vec2 pt, vec2 ext, float rad) +{ + vec2 ext2 = ext - vec2(rad,rad); + vec2 d = abs(pt) - ext2; + return min(max(d.x, d.y), 0.0) + length(max(d, 0.0) ) - rad; +} + +// Scissoring +float scissorMask(vec2 p) +{ + vec2 sc = abs(mul(u_scissorMat, vec3(p, 1.0) ).xy) - u_scissorExt; + sc = vec2(0.5, 0.5) - sc * u_scissorScale; + return clamp(sc.x, 0.0, 1.0) * clamp(sc.y, 0.0, 1.0); +} + +// Stroke - from [0..1] to clipped pyramid, where the slope is 1px. +float strokeMask(vec2 _texcoord) +{ +#if EDGE_AA + return min(1.0, (1.0 - abs(_texcoord.x*2.0 - 1.0) )*u_strokeMult) * min(1.0, _texcoord.y); +#else + return 1.0; +#endif // EDGE_AA +} + +void main() +{ + vec4 result; + float scissor = scissorMask(v_position); + float strokeAlpha = strokeMask(v_texcoord0); + + if (u_type == 0.0) // Gradient + { + // Calculate gradient color using box gradient + vec2 pt = mul(u_paintMat, vec3(v_position, 1.0) ).xy; + float d = clamp( (sdroundrect(pt, u_extent, u_radius) + u_feather*0.5) / u_feather, 0.0, 1.0); + vec4 color = mix(u_innerCol, u_outerCol, d); + // Combine alpha + color.w *= strokeAlpha * scissor; + result = color; + } + else if (u_type == 1.0) // Image + { + // Calculate color fron texture + vec2 pt = mul(u_paintMat, vec3(v_position, 1.0) ).xy / u_extent; + vec4 color = texture2D(s_tex, pt); + color = u_texType == 0.0 ? color : vec4(1.0, 1.0, 1.0, color.x); + // Combine alpha + color.w *= strokeAlpha * scissor; + result = color; + } + else if (u_type == 2.0) // Stencil fill + { + result = vec4(1.0, 1.0, 1.0, 1.0); + } + else if (u_type == 3.0) // Textured tris + { + vec4 color = texture2D(s_tex, v_texcoord0); + color = u_texType == 0.0 ? color : vec4(1.0, 1.0, 1.0, color.x); + color.w *= scissor; + result = color * u_innerCol; + } + + gl_FragColor = result; +} diff --git a/examples/common/nanovg/makefile b/examples/common/nanovg/makefile new file mode 100644 index 00000000..d3bc6dd5 --- /dev/null +++ b/examples/common/nanovg/makefile @@ -0,0 +1,9 @@ +# +# Copyright 2011-2014 Branimir Karadzic. All rights reserved. +# License: http://www.opensource.org/licenses/BSD-2-Clause +# + +include ../../../premake/shader-embeded.mk + +rebuild: + @make -s --no-print-directory clean all diff --git a/examples/common/nanovg/nanovg.cpp b/examples/common/nanovg/nanovg.cpp new file mode 100644 index 00000000..a9920bfc --- /dev/null +++ b/examples/common/nanovg/nanovg.cpp @@ -0,0 +1,2399 @@ +// +// Copyright (c) 2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include +#include +#include "nanovg.h" +#define FONTSTASH_IMPLEMENTATION +#include "fontstash.h" +#include + + +#define NVG_INIT_PATH_SIZE 256 +#define NVG_MAX_STATES 32 + +#define NVG_KAPPA90 0.5522847493f // Lenght proportional to radius of a cubic bezier handle for 90deg arcs. + +#define NVG_COUNTOF(arr) (sizeof(arr) / sizeof(0[arr])) + + +enum NVGcommands { + NVG_MOVETO = 0, + NVG_LINETO = 1, + NVG_BEZIERTO = 2, + NVG_CLOSE = 3, + NVG_WINDING = 4, +}; + +enum NVGpointFlags +{ + NVG_PT_CORNER = 0x01, + NVG_PT_LEFT = 0x02, + NVG_PT_BEVEL = 0x04, + NVG_PR_INNERBEVEL = 0x08, +}; + +enum NVGexpandFeatures { + NVG_FILL = 0x01, + NVG_STROKE = 0x02, + NVG_CAPS = 0x04, +}; + +struct NVGstate { + struct NVGpaint fill; + struct NVGpaint stroke; + float strokeWidth; + float miterLimit; + int lineJoin; + int lineCap; + float xform[6]; + struct NVGscissor scissor; + float fontSize; + float letterSpacing; + float lineHeight; + float fontBlur; + int textAlign; + int fontId; +}; + +struct NVGpoint { + float x,y; + float dx, dy; + float len; + float dmx, dmy; + unsigned char flags; +}; + +struct NVGpathCache { + struct NVGpoint* points; + int npoints; + int cpoints; + struct NVGpath* paths; + int npaths; + int cpaths; + struct NVGvertex* verts; + int nverts; + int cverts; + float bounds[4]; +}; + +struct NVGcontext { + struct NVGparams params; + float* commands; + int ccommands; + int ncommands; + float commandx, commandy; + struct NVGstate states[NVG_MAX_STATES]; + int nstates; + struct NVGpathCache* cache; + float tessTol; + float distTol; + float fringeWidth; + float devicePxRatio; + struct FONScontext* fs; + int fontImage; + int alphaBlend; + int drawCallCount; + int fillTriCount; + int strokeTriCount; + int textTriCount; +}; + +static float nvg__sqrtf(float a) { return sqrtf(a); } +static float nvg__modf(float a, float b) { return fmodf(a, b); } +static float nvg__sinf(float a) { return sinf(a); } +static float nvg__cosf(float a) { return cosf(a); } +static float nvg__tanf(float a) { return tanf(a); } +static float nvg__atan2f(float a,float b) { return atan2f(a, b); } +static float nvg__acosf(float a) { return acosf(a); } + +static int nvg__mini(int a, int b) { return a < b ? a : b; } +static int nvg__maxi(int a, int b) { return a > b ? a : b; } +static int nvg__clampi(int a, int mn, int mx) { return a < mn ? mn : (a > mx ? mx : a); } +static float nvg__minf(float a, float b) { return a < b ? a : b; } +static float nvg__maxf(float a, float b) { return a > b ? a : b; } +static float nvg__absf(float a) { return a >= 0.0f ? a : -a; } +static float nvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); } +static float nvg__cross(float dx0, float dy0, float dx1, float dy1) { return dx1*dy0 - dx0*dy1; } + +static float nvg__normalize(float *x, float* y) +{ + float d = nvg__sqrtf((*x)*(*x) + (*y)*(*y)); + if (d > 1e-6f) { + float id = 1.0f / d; + *x *= id; + *y *= id; + } + return d; +} + + +static void nvg__deletePathCache(struct NVGpathCache* c) +{ + if (c == NULL) return; + if (c->points != NULL) free(c->points); + if (c->paths != NULL) free(c->paths); + if (c->verts != NULL) free(c->verts); + free(c); +} + +static struct NVGpathCache* nvg__allocPathCache() +{ + struct NVGpathCache* c = (struct NVGpathCache*)malloc(sizeof(struct NVGpathCache)); + if (c == NULL) goto error; + memset(c, 0, sizeof(struct NVGpathCache)); + + c->points = (struct NVGpoint*)malloc(sizeof(struct NVGpoint)*4); + if (!c->points) goto error; + c->npoints = 0; + c->cpoints = 4; + + c->paths = (struct NVGpath*)malloc(sizeof(struct NVGpath)*4); + if (!c->paths) goto error; + c->npaths = 0; + c->cpaths = 4; + + c->verts = (struct NVGvertex*)malloc(sizeof(struct NVGvertex)*4); + if (!c->verts) goto error; + c->nverts = 0; + c->cverts = 4; + + return c; +error: + nvg__deletePathCache(c); + return NULL; +} + +static void nvg__setDevicePixelRatio(struct NVGcontext* ctx, float ratio) +{ + ctx->tessTol = 1.0f / ratio; + ctx->distTol = 0.01f / ratio; + ctx->fringeWidth = 1.0f / ratio; + ctx->devicePxRatio = ratio; +} + +struct NVGcontext* nvgCreateInternal(struct NVGparams* params) +{ + struct FONSparams fontParams; + struct NVGcontext* ctx = (struct NVGcontext*)malloc(sizeof(struct NVGcontext)); + if (ctx == NULL) goto error; + memset(ctx, 0, sizeof(struct NVGcontext)); + + ctx->params = *params; + + ctx->commands = (float*)malloc(sizeof(float)*NVG_INIT_PATH_SIZE); + if (!ctx->commands) goto error; + ctx->ncommands = 0; + ctx->ccommands = NVG_INIT_PATH_SIZE; + + ctx->alphaBlend = NVG_STRAIGHT_ALPHA; + + ctx->cache = nvg__allocPathCache(); + if (ctx->cache == NULL) goto error; + + nvgSave(ctx); + nvgReset(ctx); + + nvg__setDevicePixelRatio(ctx, 1.0f); + + if (ctx->params.renderCreate(ctx->params.userPtr) == 0) goto error; + + // Init font rendering + memset(&fontParams, 0, sizeof(fontParams)); + fontParams.width = params->atlasWidth; + fontParams.height = params->atlasHeight; + fontParams.flags = FONS_ZERO_TOPLEFT; + fontParams.renderCreate = NULL; + fontParams.renderUpdate = NULL; + fontParams.renderDraw = NULL; + fontParams.renderDelete = NULL; + fontParams.userPtr = NULL; + ctx->fs = fonsCreateInternal(&fontParams); + if (ctx->fs == NULL) goto error; + + // Create font texture + ctx->fontImage = ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_ALPHA, fontParams.width, fontParams.height, NULL); + if (ctx->fontImage == 0) goto error; + + return ctx; + +error: + nvgDeleteInternal(ctx); + return 0; +} + +void nvgDeleteInternal(struct NVGcontext* ctx) +{ + if (ctx == NULL) return; + if (ctx->commands != NULL) free(ctx->commands); + if (ctx->cache != NULL) nvg__deletePathCache(ctx->cache); + + if (ctx->fs) + fonsDeleteInternal(ctx->fs); + + if (ctx->params.renderDelete != NULL) + ctx->params.renderDelete(ctx->params.userPtr); + + free(ctx); +} + +void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio, int alphaBlend) +{ +/* printf("Tris: draws:%d fill:%d stroke:%d text:%d TOT:%d\n", + ctx->drawCallCount, ctx->fillTriCount, ctx->strokeTriCount, ctx->textTriCount, + ctx->fillTriCount+ctx->strokeTriCount+ctx->textTriCount);*/ + + ctx->nstates = 0; + nvgSave(ctx); + nvgReset(ctx); + + nvg__setDevicePixelRatio(ctx, devicePixelRatio); + ctx->alphaBlend = alphaBlend; + + ctx->params.renderViewport(ctx->params.userPtr, windowWidth, windowHeight, ctx->alphaBlend); + + ctx->drawCallCount = 0; + ctx->fillTriCount = 0; + ctx->strokeTriCount = 0; + ctx->textTriCount = 0; +} + +void nvgEndFrame(struct NVGcontext* ctx) +{ + ctx->params.renderFlush(ctx->params.userPtr, ctx->alphaBlend); +} + +struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b) +{ + return nvgRGBA(r,g,b,255); +} + +struct NVGcolor nvgRGBf(float r, float g, float b) +{ + return nvgRGBAf(r,g,b,1.0f); +} + +struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + struct NVGcolor color; + // Use longer initialization to suppress warning. + color.r = r / 255.0f; + color.g = g / 255.0f; + color.b = b / 255.0f; + color.a = a / 255.0f; + return color; +} + +struct NVGcolor nvgRGBAf(float r, float g, float b, float a) +{ + struct NVGcolor color; + // Use longer initialization to suppress warning. + color.r = r; + color.g = g; + color.b = b; + color.a = a; + return color; +} + +struct NVGcolor nvgTransRGBA(struct NVGcolor c, unsigned char a) +{ + c.a = a / 255.0f; + return c; +} + +struct NVGcolor nvgTransRGBAf(struct NVGcolor c, float a) +{ + c.a = a; + return c; +} + +struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u) +{ + int i; + float oneminu; + struct NVGcolor cint; + + u = nvg__clampf(u, 0.0f, 1.0f); + oneminu = 1.0f - u; + for( i = 0; i <4; ++i ) + { + cint.rgba[i] = c0.rgba[i] * oneminu + c1.rgba[i] * u; + } + + return cint; +} + +struct NVGcolor nvgHSL(float h, float s, float l) +{ + return nvgHSLA(h,s,l,255); +} + +static float nvg__hue(float h, float m1, float m2) +{ + if (h < 0) h += 1; + if (h > 1) h -= 1; + if (h < 1.0f/6.0f) + return m1 + (m2 - m1) * h * 6.0f; + else if (h < 3.0f/6.0f) + return m2; + else if (h < 4.0f/6.0f) + return m1 + (m2 - m1) * (2.0f/3.0f - h) * 6.0f; + return m1; +} + +struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a) +{ + float m1, m2; + struct NVGcolor col; + h = nvg__modf(h, 1.0f); + if (h < 0.0f) h += 1.0f; + s = nvg__clampf(s, 0.0f, 1.0f); + l = nvg__clampf(l, 0.0f, 1.0f); + m2 = l <= 0.5f ? (l * (1 + s)) : (l + s - l * s); + m1 = 2 * l - m2; + col.r = nvg__clampf(nvg__hue(h + 1.0f/3.0f, m1, m2), 0.0f, 1.0f); + col.g = nvg__clampf(nvg__hue(h, m1, m2), 0.0f, 1.0f); + col.b = nvg__clampf(nvg__hue(h - 1.0f/3.0f, m1, m2), 0.0f, 1.0f); + col.a = a/255.0f; + return col; +} + + + +static struct NVGstate* nvg__getState(struct NVGcontext* ctx) +{ + return &ctx->states[ctx->nstates-1]; +} + +static void nvg__xformIdentity(float* t) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nvg__xformTranslate(float* t, float tx, float ty) +{ + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = tx; t[5] = ty; +} + +static void nvg__xformScale(float* t, float sx, float sy) +{ + t[0] = sx; t[1] = 0.0f; + t[2] = 0.0f; t[3] = sy; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nvg__xformRotate(float* t, float a) +{ + float cs = nvg__cosf(a), sn = nvg__sinf(a); + t[0] = cs; t[1] = sn; + t[2] = -sn; t[3] = cs; + t[4] = 0.0f; t[5] = 0.0f; +} + +static void nvg__xformMultiply(float* t, float* s) +{ + float t0 = t[0] * s[0] + t[1] * s[2]; + float t2 = t[2] * s[0] + t[3] * s[2]; + float t4 = t[4] * s[0] + t[5] * s[2] + s[4]; + t[1] = t[0] * s[1] + t[1] * s[3]; + t[3] = t[2] * s[1] + t[3] * s[3]; + t[5] = t[4] * s[1] + t[5] * s[3] + s[5]; + t[0] = t0; + t[2] = t2; + t[4] = t4; +} + +static void nvg__xformPremultiply(float* t, float* s) +{ + float s2[6]; + memcpy(s2, s, sizeof(float)*6); + nvg__xformMultiply(s2, t); + memcpy(t, s2, sizeof(float)*6); +} + +static void nvg__setPaintColor(struct NVGpaint* p, struct NVGcolor color) +{ + memset(p, 0, sizeof(*p)); + nvg__xformIdentity(p->xform); + p->radius = 0.0f; + p->feather = 1.0f; + p->innerColor = color; + p->outerColor = color; +} + + +// State handling +void nvgSave(struct NVGcontext* ctx) +{ + if (ctx->nstates >= NVG_MAX_STATES) + return; + if (ctx->nstates > 0) + memcpy(&ctx->states[ctx->nstates], &ctx->states[ctx->nstates-1], sizeof(struct NVGstate)); + ctx->nstates++; +} + +void nvgRestore(struct NVGcontext* ctx) +{ + if (ctx->nstates <= 1) + return; + ctx->nstates--; +} + +void nvgReset(struct NVGcontext* ctx) +{ + struct NVGstate* state = nvg__getState(ctx); + memset(state, 0, sizeof(*state)); + + nvg__setPaintColor(&state->fill, nvgRGBA(255,255,255,255)); + nvg__setPaintColor(&state->stroke, nvgRGBA(0,0,0,255)); + state->strokeWidth = 1.0f; + state->miterLimit = 10.0f; + state->lineCap = NVG_BUTT; + state->lineJoin = NVG_MITER; + nvg__xformIdentity(state->xform); + + state->scissor.extent[0] = 0.0f; + state->scissor.extent[1] = 0.0f; + + state->fontSize = 16.0f; + state->letterSpacing = 0.0f; + state->lineHeight = 0.0f; + state->fontBlur = 0.0f; + state->textAlign = NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE; + state->fontId = 0; +} + +// State setting +void nvgStrokeWidth(struct NVGcontext* ctx, float width) +{ + struct NVGstate* state = nvg__getState(ctx); + state->strokeWidth = width; +} + +void nvgMiterLimit(struct NVGcontext* ctx, float limit) +{ + struct NVGstate* state = nvg__getState(ctx); + state->miterLimit = limit; +} + +void nvgLineCap(struct NVGcontext* ctx, int cap) +{ + struct NVGstate* state = nvg__getState(ctx); + state->lineCap = cap; +} + +void nvgLineJoin(struct NVGcontext* ctx, int join) +{ + struct NVGstate* state = nvg__getState(ctx); + state->lineJoin = join; +} + + +void nvgTransform(struct NVGcontext* ctx, float a, float b, float c, float d, float e, float f) +{ + struct NVGstate* state = nvg__getState(ctx); + float t[6] = { a, b, c, d, e, f }; + nvg__xformPremultiply(state->xform, t); +} + +void nvgResetTransform(struct NVGcontext* ctx) +{ + struct NVGstate* state = nvg__getState(ctx); + nvg__xformIdentity(state->xform); +} + +void nvgTranslate(struct NVGcontext* ctx, float x, float y) +{ + struct NVGstate* state = nvg__getState(ctx); + float t[6]; + nvg__xformTranslate(t, x,y); + nvg__xformPremultiply(state->xform, t); +} + +void nvgRotate(struct NVGcontext* ctx, float angle) +{ + struct NVGstate* state = nvg__getState(ctx); + float t[6]; + nvg__xformRotate(t, angle); + nvg__xformPremultiply(state->xform, t); +} + +void nvgScale(struct NVGcontext* ctx, float x, float y) +{ + struct NVGstate* state = nvg__getState(ctx); + float t[6]; + nvg__xformScale(t, x,y); + nvg__xformPremultiply(state->xform, t); +} + + +void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color) +{ + struct NVGstate* state = nvg__getState(ctx); + nvg__setPaintColor(&state->stroke, color); +} + +void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint) +{ + struct NVGstate* state = nvg__getState(ctx); + state->stroke = paint; + nvg__xformMultiply(state->stroke.xform, state->xform); +} + +void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color) +{ + struct NVGstate* state = nvg__getState(ctx); + nvg__setPaintColor(&state->fill, color); +} + +void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint) +{ + struct NVGstate* state = nvg__getState(ctx); + state->fill = paint; + nvg__xformMultiply(state->fill.xform, state->xform); +} + +int nvgCreateImage(struct NVGcontext* ctx, const char* filename) +{ + int w, h, n, image; + unsigned char* img = stbi_load(filename, &w, &h, &n, 4); + if (img == NULL) { +// printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); + return 0; + } + image = nvgCreateImageRGBA(ctx, w, h, img); + stbi_image_free(img); + return image; +} + +int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata) +{ + int w, h, n, image; + unsigned char* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4); + if (img == NULL) { +// printf("Failed to load %s - %s\n", filename, stbi_failure_reason()); + return 0; + } + image = nvgCreateImageRGBA(ctx, w, h, img); + stbi_image_free(img); + return image; +} + +int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, const unsigned char* data) +{ + return ctx->params.renderCreateTexture(ctx->params.userPtr, NVG_TEXTURE_RGBA, w, h, data); +} + +void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data) +{ + int w, h; + ctx->params.renderGetTextureSize(ctx->params.userPtr, image, &w, &h); + ctx->params.renderUpdateTexture(ctx->params.userPtr, image, 0,0, w,h, data); +} + +void nvgImageSize(struct NVGcontext* ctx, int image, int* w, int* h) +{ + ctx->params.renderGetTextureSize(ctx->params.userPtr, image, w, h); +} + +void nvgDeleteImage(struct NVGcontext* ctx, int image) +{ + ctx->params.renderDeleteTexture(ctx->params.userPtr, image); +} + +struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, + float sx, float sy, float ex, float ey, + struct NVGcolor icol, struct NVGcolor ocol) +{ + struct NVGpaint p; + float dx, dy, d; + const float large = 1e5; + NVG_NOTUSED(ctx); + memset(&p, 0, sizeof(p)); + + // Calculate transform aligned to the line + dx = ex - sx; + dy = ey - sy; + d = sqrtf(dx*dx + dy*dy); + if (d > 0.0001f) { + dx /= d; + dy /= d; + } else { + dx = 0; + dy = 1; + } + + p.xform[0] = dy; p.xform[1] = -dx; + p.xform[2] = dx; p.xform[3] = dy; + p.xform[4] = sx - dx*large; p.xform[5] = sy - dy*large; + + p.extent[0] = large; + p.extent[1] = large + d*0.5f; + + p.radius = 0.0f; + + p.feather = nvg__maxf(1.0f, d); + + p.innerColor = icol; + p.outerColor = ocol; + + return p; +} + +struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, + float cx, float cy, float inr, float outr, + struct NVGcolor icol, struct NVGcolor ocol) +{ + struct NVGpaint p; + float r = (inr+outr)*0.5f; + float f = (outr-inr); + NVG_NOTUSED(ctx); + memset(&p, 0, sizeof(p)); + + nvg__xformIdentity(p.xform); + p.xform[4] = cx; + p.xform[5] = cy; + + p.extent[0] = r; + p.extent[1] = r; + + p.radius = r; + + p.feather = nvg__maxf(1.0f, f); + + p.innerColor = icol; + p.outerColor = ocol; + + return p; +} + +struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, + float x, float y, float w, float h, float r, float f, + struct NVGcolor icol, struct NVGcolor ocol) +{ + struct NVGpaint p; + NVG_NOTUSED(ctx); + memset(&p, 0, sizeof(p)); + + nvg__xformIdentity(p.xform); + p.xform[4] = x+w*0.5f; + p.xform[5] = y+h*0.5f; + + p.extent[0] = w*0.5f; + p.extent[1] = h*0.5f; + + p.radius = r; + + p.feather = nvg__maxf(1.0f, f); + + p.innerColor = icol; + p.outerColor = ocol; + + return p; +} + + +struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, + float cx, float cy, float w, float h, float angle, + int image, int repeat) +{ + struct NVGpaint p; + NVG_NOTUSED(ctx); + memset(&p, 0, sizeof(p)); + + nvg__xformRotate(p.xform, angle); + p.xform[4] = cx; + p.xform[5] = cy; + + p.extent[0] = w; + p.extent[1] = h; + + p.image = image; + p.repeat = repeat; + + return p; +} + +// Scissoring +void nvgScissor(struct NVGcontext* ctx, float x, float y, float w, float h) +{ + struct NVGstate* state = nvg__getState(ctx); + + nvg__xformIdentity(state->scissor.xform); + state->scissor.xform[4] = x+w*0.5f; + state->scissor.xform[5] = y+h*0.5f; + nvg__xformMultiply(state->scissor.xform, state->xform); + + state->scissor.extent[0] = w*0.5f; + state->scissor.extent[1] = h*0.5f; +} + +void nvgResetScissor(struct NVGcontext* ctx) +{ + struct NVGstate* state = nvg__getState(ctx); + memset(state->scissor.xform, 0, sizeof(state->scissor.xform)); + state->scissor.extent[0] = 0; + state->scissor.extent[1] = 0; +} + +static void nvg__xformPt(float* dx, float* dy, float sx, float sy, const float* t) +{ + *dx = sx*t[0] + sy*t[2] + t[4]; + *dy = sx*t[1] + sy*t[3] + t[5]; +} + +static int nvg__ptEquals(float x1, float y1, float x2, float y2, float tol) +{ + float dx = x2 - x1; + float dy = y2 - y1; + return dx*dx + dy*dy < tol*tol; +} + +static float nvg__distPtSeg(float x, float y, float px, float py, float qx, float qy) +{ + float pqx, pqy, dx, dy, d, t; + pqx = qx-px; + pqy = qy-py; + dx = x-px; + dy = y-py; + d = pqx*pqx + pqy*pqy; + t = pqx*dx + pqy*dy; + if (d > 0) t /= d; + if (t < 0) t = 0; + else if (t > 1) t = 1; + dx = px + t*pqx - x; + dy = py + t*pqy - y; + return dx*dx + dy*dy; +} + +static void nvg__appendCommands(struct NVGcontext* ctx, float* vals, int nvals) +{ + struct NVGstate* state = nvg__getState(ctx); + int i; + + if (ctx->ncommands+nvals > ctx->ccommands) { + if (ctx->ccommands == 0) ctx->ccommands = 8; + while (ctx->ccommands < ctx->ncommands+nvals) + ctx->ccommands *= 2; + ctx->commands = (float*)realloc(ctx->commands, ctx->ccommands*sizeof(float)); + if (ctx->commands == NULL) return; + } + + // transform commands + i = 0; + while (i < nvals) { + int cmd = (int)vals[i]; + switch (cmd) { + case NVG_MOVETO: + nvg__xformPt(&vals[i+1],&vals[i+2], vals[i+1],vals[i+2], state->xform); + i += 3; + break; + case NVG_LINETO: + nvg__xformPt(&vals[i+1],&vals[i+2], vals[i+1],vals[i+2], state->xform); + i += 3; + break; + case NVG_BEZIERTO: + nvg__xformPt(&vals[i+1],&vals[i+2], vals[i+1],vals[i+2], state->xform); + nvg__xformPt(&vals[i+3],&vals[i+4], vals[i+3],vals[i+4], state->xform); + nvg__xformPt(&vals[i+5],&vals[i+6], vals[i+5],vals[i+6], state->xform); + i += 7; + break; + case NVG_CLOSE: + i++; + break; + case NVG_WINDING: + i += 2; + break; + default: + i++; + } + } + + memcpy(&ctx->commands[ctx->ncommands], vals, nvals*sizeof(float)); + + ctx->ncommands += nvals; + + if ((int)vals[0] != NVG_CLOSE && (int)vals[0] != NVG_WINDING) { + ctx->commandx = vals[nvals-2]; + ctx->commandy = vals[nvals-1]; + } +} + + +static void nvg__clearPathCache(struct NVGcontext* ctx) +{ + ctx->cache->npoints = 0; + ctx->cache->npaths = 0; +} + +static struct NVGpath* nvg__lastPath(struct NVGcontext* ctx) +{ + if (ctx->cache->npaths > 0) + return &ctx->cache->paths[ctx->cache->npaths-1]; + return NULL; +} + +static void nvg__addPath(struct NVGcontext* ctx) +{ + struct NVGpath* path; + if (ctx->cache->npaths+1 > ctx->cache->cpaths) { + ctx->cache->cpaths = (ctx->cache->cpaths == 0) ? 8 : (ctx->cache->cpaths*2); + ctx->cache->paths = (struct NVGpath*)realloc(ctx->cache->paths, sizeof(struct NVGpath)*ctx->cache->cpaths); + if (ctx->cache->paths == NULL) return; + } + path = &ctx->cache->paths[ctx->cache->npaths]; + memset(path, 0, sizeof(*path)); + path->first = ctx->cache->npoints; + path->winding = NVG_CCW; + + ctx->cache->npaths++; +} + +static struct NVGpoint* nvg__lastPoint(struct NVGcontext* ctx) +{ + if (ctx->cache->npoints > 0) + return &ctx->cache->points[ctx->cache->npoints-1]; + return NULL; +} + +static void nvg__addPoint(struct NVGcontext* ctx, float x, float y, int flags) +{ + struct NVGpath* path = nvg__lastPath(ctx); + struct NVGpoint* pt; + if (path == NULL) return; + + if (ctx->cache->npoints > 0) { + pt = nvg__lastPoint(ctx); + if (nvg__ptEquals(pt->x,pt->y, x,y, ctx->distTol)) { + pt->flags |= flags; + return; + } + } + + if (ctx->cache->npoints+1 > ctx->cache->cpoints) { + ctx->cache->cpoints = (ctx->cache->cpoints == 0) ? 8 : (ctx->cache->cpoints*2); + ctx->cache->points = (struct NVGpoint*)realloc(ctx->cache->points, sizeof(struct NVGpoint)*ctx->cache->cpoints); + if (ctx->cache->points == NULL) return; + } + + pt = &ctx->cache->points[ctx->cache->npoints]; + memset(pt, 0, sizeof(*pt)); + pt->x = x; + pt->y = y; + pt->flags = flags; + + ctx->cache->npoints++; + path->count++; +} + +static void nvg__closePath(struct NVGcontext* ctx) +{ + struct NVGpath* path = nvg__lastPath(ctx); + if (path == NULL) return; + path->closed = 1; +} + +static void nvg__pathWinding(struct NVGcontext* ctx, int winding) +{ + struct NVGpath* path = nvg__lastPath(ctx); + if (path == NULL) return; + path->winding = winding; +} + +static float nvg__getAverageScale(float *t) +{ + float sx = sqrtf(t[0]*t[0] + t[2]*t[2]); + float sy = sqrtf(t[1]*t[1] + t[3]*t[3]); + return (sx + sy) * 0.5f; +} + +static struct NVGvertex* nvg__allocTempVerts(struct NVGcontext* ctx, int nverts) +{ + if (nverts > ctx->cache->cverts) { + if (ctx->cache->cverts == 0) ctx->cache->cverts = 8; + while (ctx->cache->cverts < nverts) + ctx->cache->cverts *= 2; + ctx->cache->verts = (struct NVGvertex*)realloc(ctx->cache->verts, sizeof(struct NVGvertex)*ctx->cache->cverts); + if (ctx->cache->verts == NULL) return NULL; + } + return ctx->cache->verts; +} + +static float nvg__triarea2(float ax, float ay, float bx, float by, float cx, float cy) +{ + float abx = bx - ax; + float aby = by - ay; + float acx = cx - ax; + float acy = cy - ay; + return acx*aby - abx*acy; +} + +static float nvg__polyArea(struct NVGpoint* pts, int npts) +{ + int i; + float area = 0; + for (i = 2; i < npts; i++) { + struct NVGpoint* a = &pts[0]; + struct NVGpoint* b = &pts[i-1]; + struct NVGpoint* c = &pts[i]; + area += nvg__triarea2(a->x,a->y, b->x,b->y, c->x,c->y); + } + return area * 0.5f; +} + +static void nvg__polyReverse(struct NVGpoint* pts, int npts) +{ + struct NVGpoint tmp; + int i = 0, j = npts-1; + while (i < j) { + tmp = pts[i]; + pts[i] = pts[j]; + pts[j] = tmp; + i++; + j--; + } +} + + +static void nvg__vset(struct NVGvertex* vtx, float x, float y, float u, float v) +{ + vtx->x = x; + vtx->y = y; + vtx->u = u; + vtx->v = v; +} + +static void nvg__tesselateBezier(struct NVGcontext* ctx, + float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4, + int level, int type) +{ + float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234; + float dx,dy,d2,d3; + + if (level > 10) return; + + x12 = (x1+x2)*0.5f; + y12 = (y1+y2)*0.5f; + x23 = (x2+x3)*0.5f; + y23 = (y2+y3)*0.5f; + x34 = (x3+x4)*0.5f; + y34 = (y3+y4)*0.5f; + x123 = (x12+x23)*0.5f; + y123 = (y12+y23)*0.5f; + + dx = x3 - x1; + dy = y3 - y1; + d2 = nvg__absf(((x2 - x4) * dy - (y2 - y4) * dx)); + d3 = nvg__absf(((x3 - x4) * dy - (y3 - y4) * dx)); + + if ((d2 + d3)*(d2 + d3) < ctx->tessTol * (dx*dx + dy*dy)) { + nvg__addPoint(ctx, x4, y4, type); + return; + } + +/* if (nvg__absf(x1+x3-x2-x2) + nvg__absf(y1+y3-y2-y2) + nvg__absf(x2+x4-x3-x3) + nvg__absf(y2+y4-y3-y3) < ctx->tessTol) { + nvg__addPoint(ctx, x4, y4, type); + return; + }*/ + + x234 = (x23+x34)*0.5f; + y234 = (y23+y34)*0.5f; + x1234 = (x123+x234)*0.5f; + y1234 = (y123+y234)*0.5f; + + nvg__tesselateBezier(ctx, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0); + nvg__tesselateBezier(ctx, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type); +} + +static void nvg__flattenPaths(struct NVGcontext* ctx) +{ + struct NVGpathCache* cache = ctx->cache; +// struct NVGstate* state = nvg__getState(ctx); + struct NVGpoint* last; + struct NVGpoint* p0; + struct NVGpoint* p1; + struct NVGpoint* pts; + struct NVGpath* path; + int i, j; + float* cp1; + float* cp2; + float* p; + float area; + + if (cache->npaths > 0) + return; + + // Flatten + i = 0; + while (i < ctx->ncommands) { + int cmd = (int)ctx->commands[i]; + switch (cmd) { + case NVG_MOVETO: + nvg__addPath(ctx); + p = &ctx->commands[i+1]; + nvg__addPoint(ctx, p[0], p[1], NVG_PT_CORNER); + i += 3; + break; + case NVG_LINETO: + p = &ctx->commands[i+1]; + nvg__addPoint(ctx, p[0], p[1], NVG_PT_CORNER); + i += 3; + break; + case NVG_BEZIERTO: + last = nvg__lastPoint(ctx); + if (last != NULL) { + cp1 = &ctx->commands[i+1]; + cp2 = &ctx->commands[i+3]; + p = &ctx->commands[i+5]; + nvg__tesselateBezier(ctx, last->x,last->y, cp1[0],cp1[1], cp2[0],cp2[1], p[0],p[1], 0, NVG_PT_CORNER); + } + i += 7; + break; + case NVG_CLOSE: + nvg__closePath(ctx); + i++; + break; + case NVG_WINDING: + nvg__pathWinding(ctx, (int)ctx->commands[i+1]); + i += 2; + break; + default: + i++; + } + } + + cache->bounds[0] = cache->bounds[1] = 1e6f; + cache->bounds[2] = cache->bounds[3] = -1e6f; + + // Calculate the direction and length of line segments. + for (j = 0; j < cache->npaths; j++) { + path = &cache->paths[j]; + pts = &cache->points[path->first]; + + // If the first and last points are the same, remove the last, mark as closed path. + p0 = &pts[path->count-1]; + p1 = &pts[0]; + if (nvg__ptEquals(p0->x,p0->y, p1->x,p1->y, ctx->distTol)) { + path->count--; + p0 = &pts[path->count-1]; + path->closed = 1; + } + + // Enforce winding. + if (path->count > 2) { + area = nvg__polyArea(pts, path->count); + if (path->winding == NVG_CCW && area < 0.0f) + nvg__polyReverse(pts, path->count); + if (path->winding == NVG_CW && area > 0.0f) + nvg__polyReverse(pts, path->count); + } + + for(i = 0; i < path->count; ++i) { + // Calculate segment direction and length + p0->dx = p1->x - p0->x; + p0->dy = p1->y - p0->y; + p0->len = nvg__normalize(&p0->dx, &p0->dy); + // Update bounds + cache->bounds[0] = nvg__minf(cache->bounds[0], p0->x); + cache->bounds[1] = nvg__minf(cache->bounds[1], p0->y); + cache->bounds[2] = nvg__maxf(cache->bounds[2], p0->x); + cache->bounds[3] = nvg__maxf(cache->bounds[3], p0->y); + // Advance + p0 = p1++; + } + } +} + +static int nvg__curveDivs(float r, float arc, float tol) +{ + float da = acosf(r / (r + tol)) * 2.0f; + return nvg__maxi(2, (int)ceilf(arc / da)); +} + +static void nvg__chooseBevel(int bevel, struct NVGpoint* p0, struct NVGpoint* p1, float w, + float* x0, float* y0, float* x1, float* y1) +{ + if (bevel) { + *x0 = p1->x + p0->dy * w; + *y0 = p1->y - p0->dx * w; + *x1 = p1->x + p1->dy * w; + *y1 = p1->y - p1->dx * w; + } else { + *x0 = p1->x + p1->dmx * w; + *y0 = p1->y + p1->dmy * w; + *x1 = p1->x + p1->dmx * w; + *y1 = p1->y + p1->dmy * w; + } +} + +static struct NVGvertex* nvg__roundJoin(struct NVGvertex* dst, struct NVGpoint* p0, struct NVGpoint* p1, + float lw, float rw, float lu, float ru, int ncap, float fringe) +{ + int i, n; + float dlx0 = p0->dy; + float dly0 = -p0->dx; + float dlx1 = p1->dy; + float dly1 = -p1->dx; + NVG_NOTUSED(fringe); + + if (p1->flags & NVG_PT_LEFT) { + float lx0,ly0,lx1,ly1,a0,a1; + nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, lw, &lx0,&ly0, &lx1,&ly1); + a0 = atan2f(-dly0, -dlx0); + a1 = atan2f(-dly1, -dlx1); + if (a1 > a0) a1 -= NVG_PI*2; + + nvg__vset(dst, lx0, ly0, lu,1); dst++; + nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; + + n = nvg__clampi((int)ceilf(((a0 - a1) / NVG_PI) * ncap), 2, ncap); + for (i = 0; i < n; i++) { + float u = i/(float)(n-1); + float a = a0 + u*(a1-a0); + float rx = p1->x + cosf(a) * rw; + float ry = p1->y + sinf(a) * rw; + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + nvg__vset(dst, rx, ry, ru,1); dst++; + } + + nvg__vset(dst, lx1, ly1, lu,1); dst++; + nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; + + } else { + float rx0,ry0,rx1,ry1,a0,a1; + nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1); + a0 = atan2f(dly0, dlx0); + a1 = atan2f(dly1, dlx1); + if (a1 < a0) a1 += NVG_PI*2; + + nvg__vset(dst, p1->x + dlx0*rw, p1->y + dly0*rw, lu,1); dst++; + nvg__vset(dst, rx0, ry0, ru,1); dst++; + + n = nvg__clampi((int)ceilf(((a1 - a0) / NVG_PI) * ncap), 2, ncap); + for (i = 0; i < n; i++) { + float u = i/(float)(n-1); + float a = a0 + u*(a1-a0); + float lx = p1->x + cosf(a) * lw; + float ly = p1->y + sinf(a) * lw; + nvg__vset(dst, lx, ly, lu,1); dst++; + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + } + + nvg__vset(dst, p1->x + dlx1*rw, p1->y + dly1*rw, lu,1); dst++; + nvg__vset(dst, rx1, ry1, ru,1); dst++; + + } + return dst; +} + +static struct NVGvertex* nvg__bevelJoin(struct NVGvertex* dst, struct NVGpoint* p0, struct NVGpoint* p1, + float lw, float rw, float lu, float ru, float fringe) +{ + float rx0,ry0,rx1,ry1; + float lx0,ly0,lx1,ly1; + float mx,my,len,mu; + float dlx0 = p0->dy; + float dly0 = -p0->dx; + float dlx1 = p1->dy; + float dly1 = -p1->dx; + NVG_NOTUSED(fringe); + + if (p1->flags & NVG_PT_LEFT) { + nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, lw, &lx0,&ly0, &lx1,&ly1); + + nvg__vset(dst, lx0, ly0, lu,1); dst++; + nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; + + if (p1->flags & NVG_PT_BEVEL) { + // TODO: this needs more work. + mx = (dlx0 + dlx1) * 0.5f; + my = (dly0 + dly1) * 0.5f; + len = sqrtf(mx*mx + my*my); + mu = ru + len*(lu-ru)*0.5f; + + nvg__vset(dst, lx0, ly0, lu,1); dst++; + nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; + + nvg__vset(dst, lx1, ly1, lu,1); dst++; + nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; + } else { + rx0 = p1->x - p1->dmx * rw; + ry0 = p1->y - p1->dmy * rw; + + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + nvg__vset(dst, p1->x - dlx0*rw, p1->y - dly0*rw, ru,1); dst++; + + nvg__vset(dst, rx0, ry0, ru,1); dst++; + nvg__vset(dst, rx0, ry0, ru,1); dst++; + + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; + } + + nvg__vset(dst, lx1, ly1, lu,1); dst++; + nvg__vset(dst, p1->x - dlx1*rw, p1->y - dly1*rw, ru,1); dst++; + + } else { + nvg__chooseBevel(p1->flags & NVG_PR_INNERBEVEL, p0, p1, -rw, &rx0,&ry0, &rx1,&ry1); + + nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; + nvg__vset(dst, rx0, ry0, ru,1); dst++; + + if (p1->flags & NVG_PT_BEVEL) { + // TODO: this needs more work. + mx = (dlx0 + dlx1) * 0.5f; + my = (dly0 + dly1) * 0.5f; + len = sqrtf(mx*mx + my*my); + mu = lu + len*(ru-lu)*0.5f; + + nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; + nvg__vset(dst, rx0, ry0, ru,1); dst++; + + nvg__vset(dst, p1->x + dlx1*lw, p1->y + dly1*lw, lu,1); dst++; + nvg__vset(dst, rx1, ry1, ru,1); dst++; + } else { + lx0 = p1->x + p1->dmx * lw; + ly0 = p1->y + p1->dmy * lw; + + nvg__vset(dst, p1->x + dlx0*lw, p1->y + dly0*lw, lu,1); dst++; + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + + nvg__vset(dst, lx0, ly0, lu,1); dst++; + nvg__vset(dst, lx0, ly0, lu,1); dst++; + + nvg__vset(dst, p1->x + dlx1*lw, p1->y + dly1*lw, lu,1); dst++; + nvg__vset(dst, p1->x, p1->y, 0.5f,1); dst++; + } + + nvg__vset(dst, p1->x + dlx1*rw, p1->y + dly1*rw, lu,1); dst++; + nvg__vset(dst, rx1, ry1, ru,1); dst++; + } + + return dst; +} + +static int nvg__expandStrokeAndFill(struct NVGcontext* ctx, int feats, float w, int lineCap, int lineJoin, float miterLimit) +{ + struct NVGpathCache* cache = ctx->cache; + struct NVGpath* path; + struct NVGpoint* pts; + struct NVGvertex* verts; + struct NVGvertex* dst; + struct NVGpoint* p0; + struct NVGpoint* p1; + int cverts, convex, i, j, s, e; + float wo = 0, iw = 0, aa = ctx->fringeWidth; + int ncap = nvg__curveDivs(w, NVG_PI, ctx->tessTol / 4.0f); + int nleft = 0; + + if (w > 0.0f) iw = 1.0f / w; + + // Calculate which joins needs extra vertices to append, and gather vertex count. + for (i = 0; i < cache->npaths; i++) { + path = &cache->paths[i]; + pts = &cache->points[path->first]; + path->nbevel = 0; + nleft = 0; + + p0 = &pts[path->count-1]; + p1 = &pts[0]; + for (j = 0; j < path->count; j++) { + float dlx0, dly0, dlx1, dly1, dmr2, cross, limit; + dlx0 = p0->dy; + dly0 = -p0->dx; + dlx1 = p1->dy; + dly1 = -p1->dx; + // Calculate extrusions + p1->dmx = (dlx0 + dlx1) * 0.5f; + p1->dmy = (dly0 + dly1) * 0.5f; + dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy; + if (dmr2 > 0.000001f) { + float scale = 1.0f / dmr2; + if (scale > 600.0f) { + scale = 600.0f; + } + p1->dmx *= scale; + p1->dmy *= scale; + } + + // Clear flags, but keep the corner. + p1->flags = (p1->flags & NVG_PT_CORNER) ? NVG_PT_CORNER : 0; + + // Keep track of left turns. + cross = p1->dx * p0->dy - p0->dx * p1->dy; + if (cross > 0.0f) { + nleft++; + p1->flags |= NVG_PT_LEFT; + } + + // Calculate if we should use bevel or miter for inner join. + limit = nvg__maxf(1.01f, nvg__minf(p0->len, p1->len) * iw); + if ((dmr2 * limit*limit) < 1.0f) + p1->flags |= NVG_PR_INNERBEVEL; + + // Check to see if the corner needs to be beveled. + if (p1->flags & NVG_PT_CORNER) { + if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NVG_BEVEL || lineJoin == NVG_ROUND) { + p1->flags |= NVG_PT_BEVEL; + } + } + + if ((p1->flags & (NVG_PT_BEVEL | NVG_PR_INNERBEVEL)) != 0) + path->nbevel++; + + p0 = p1++; + } + + path->convex = (nleft == path->count) ? 1 : 0; + } + + // Calculate max vertex usage. + cverts = 0; + for (i = 0; i < cache->npaths; i++) { + path = &cache->paths[i]; + if (feats & NVG_FILL) + cverts += path->count + path->nbevel + 1; + if (feats & NVG_STROKE) { + int loop = ((feats & NVG_CAPS) && path->closed == 0) ? 0 : 1; + if (lineCap == NVG_ROUND) + cverts += (path->count + path->nbevel*(ncap+2) + 1) * 2; // plus one for loop + else + cverts += (path->count + path->nbevel*5 + 1) * 2; // plus one for loop + if (loop == 0) { + // space for caps + if (lineCap == NVG_ROUND) { + cverts += (ncap*2 + 2)*2; + } else { + cverts += (3+3)*2; + } + } + } + } + + verts = nvg__allocTempVerts(ctx, cverts); + if (verts == NULL) return 0; + + if ((feats & NVG_FILL) && cache->npaths == 1 && cache->paths[0].convex) + convex = 1; + else + convex = 0; + + for (i = 0; i < cache->npaths; i++) { + path = &cache->paths[i]; + pts = &cache->points[path->first]; + + // Calculate shape vertices. + if (feats & NVG_FILL) { + wo = 0.5f*aa; + dst = verts; + path->fill = dst; + + if (w == 0.0f) { + for (j = 0; j < path->count; ++j) { + nvg__vset(dst, pts[j].x, pts[j].y, 0.5f,1); + dst++; + } + } else { + // Looping + p0 = &pts[path->count-1]; + p1 = &pts[0]; + for (j = 0; j < path->count; ++j) { + if (p1->flags & NVG_PT_BEVEL) { + float dlx0 = p0->dy; + float dly0 = -p0->dx; + float dlx1 = p1->dy; + float dly1 = -p1->dx; + if (p1->flags & NVG_PT_LEFT) { + float lx = p1->x + p1->dmx * wo; + float ly = p1->y + p1->dmy * wo; + nvg__vset(dst, lx, ly, 0.5f,1); dst++; + } else { + float lx0 = p1->x + dlx0 * wo; + float ly0 = p1->y + dly0 * wo; + float lx1 = p1->x + dlx1 * wo; + float ly1 = p1->y + dly1 * wo; + nvg__vset(dst, lx0, ly0, 0.5f,1); dst++; + nvg__vset(dst, lx1, ly1, 0.5f,1); dst++; + } + } else { + nvg__vset(dst, p1->x + (p1->dmx * wo), p1->y + (p1->dmy * wo), 0.5f,1); dst++; + } + p0 = p1++; + } + } + + path->nfill = (int)(dst - verts); + verts = dst; + } else { + wo = 0.0f; + path->fill = 0; + path->nfill = 0; + } + + // Calculate fringe or stroke + if (feats & NVG_STROKE) { + float lw = w + wo, rw = w - wo; + float lu = 0, ru = 1; + int loop = ((feats & NVG_CAPS) && path->closed == 0) ? 0 : 1; + dst = verts; + path->stroke = dst; + + // Create only half a fringe for convex shapes so that + // the shape can be rendered without stenciling. + if (convex) { + lw = wo; // This should generate the same vertex as fill inset above. + lu = 0.5f; // Set outline fade at middle. + } + + if (loop) { + // Looping + p0 = &pts[path->count-1]; + p1 = &pts[0]; + s = 0; + e = path->count; + } else { + // Add cap + p0 = &pts[0]; + p1 = &pts[1]; + s = 1; + e = path->count-1; + } + + if (loop == 0) { + // Add cap + float dx, dy, dlx, dly, px, py; + dx = p1->x - p0->x; + dy = p1->y - p0->y; + nvg__normalize(&dx, &dy); + dlx = dy; + dly = -dx; + if (lineCap == NVG_BUTT || lineCap == NVG_SQUARE) { + if (lineCap == NVG_BUTT) { + px = p0->x; + py = p0->y; + } else /*if (lineCap == NVG_SQUARE)*/ { + px = p0->x - dx*w; + py = p0->y - dy*w; + } + nvg__vset(dst, px + dlx*lw - dx*aa, py + dly*lw - dy*aa, lu,0); dst++; + nvg__vset(dst, px - dlx*rw - dx*aa, py - dly*rw - dy*aa, ru,0); dst++; + nvg__vset(dst, px + dlx*lw, py + dly * lw, lu,1); dst++; + nvg__vset(dst, px - dlx*rw, py - dly * rw, ru,1); dst++; + } else if (lineCap == NVG_ROUND) { + px = p0->x; + py = p0->y; + for (j = 0; j < ncap; j++) { + float a = j/(float)(ncap-1)*NVG_PI; + float ax = cosf(a) * w, ay = sinf(a) * w; + nvg__vset(dst, px - dlx*ax - dx*ay, py - dly*ax - dy*ay, lu,1); dst++; + nvg__vset(dst, px, py, 0.5f,1); dst++; + } + nvg__vset(dst, px + dlx*lw, py + dly * lw, lu,1); dst++; + nvg__vset(dst, px - dlx*rw, py - dly * rw, ru,1); dst++; + } + } + + for (j = s; j < e; ++j) { + if ((p1->flags & (NVG_PT_BEVEL | NVG_PR_INNERBEVEL)) != 0) { + if (lineJoin == NVG_ROUND) { + dst = nvg__roundJoin(dst, p0, p1, lw, rw, lu, ru, ncap, ctx->fringeWidth); + } else { + dst = nvg__bevelJoin(dst, p0, p1, lw, rw, lu, ru, ctx->fringeWidth); + } + } else { + nvg__vset(dst, p1->x + (p1->dmx * lw), p1->y + (p1->dmy * lw), lu,1); dst++; + nvg__vset(dst, p1->x - (p1->dmx * rw), p1->y - (p1->dmy * rw), ru,1); dst++; + } + p0 = p1++; + } + + if (loop) { + // Loop it + nvg__vset(dst, verts[0].x, verts[0].y, lu,1); dst++; + nvg__vset(dst, verts[1].x, verts[1].y, ru,1); dst++; + } else { + // Add cap + float dx, dy, dlx, dly, px, py; + dx = p1->x - p0->x; + dy = p1->y - p0->y; + nvg__normalize(&dx, &dy); + dlx = dy; + dly = -dx; + if (lineCap == NVG_BUTT || lineCap == NVG_SQUARE) { + if (lineCap == NVG_BUTT) { + px = p1->x; + py = p1->y; + } else /*if (lineCap == NVG_SQUARE)*/ { + px = p1->x + dx*w; + py = p1->y + dy*w; + } + nvg__vset(dst, px + dlx*lw, py + dly * lw, lu,1); dst++; + nvg__vset(dst, px - dlx*rw, py - dly * rw, ru,1); dst++; + nvg__vset(dst, px + dlx*lw + dx*aa, py + dly*lw + dy*aa, lu,0); dst++; + nvg__vset(dst, px - dlx*rw + dx*aa, py - dly*rw + dy*aa, ru,0); dst++; + } else if (lineCap == NVG_ROUND) { + px = p1->x; + py = p1->y; + nvg__vset(dst, px + dlx*lw, py + dly * lw, lu,1); dst++; + nvg__vset(dst, px - dlx*rw, py - dly * rw, ru,1); dst++; + for (j = 0; j < ncap; j++) { + float a = j/(float)(ncap-1)*NVG_PI; + float ax = cosf(a) * w, ay = sinf(a) * w; + nvg__vset(dst, px, py, 0.5f,1); dst++; + nvg__vset(dst, px - dlx*ax + dx*ay, py - dly*ax + dy*ay, lu,1); dst++; + } + } + } + + path->nstroke = (int)(dst - verts); + + verts = dst; + } else { + path->stroke = 0; + path->nstroke = 0; + } + } + + return 1; +} + + +// Draw +void nvgBeginPath(struct NVGcontext* ctx) +{ + ctx->ncommands = 0; + nvg__clearPathCache(ctx); +} + +void nvgMoveTo(struct NVGcontext* ctx, float x, float y) +{ + float vals[] = { NVG_MOVETO, x, y }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgLineTo(struct NVGcontext* ctx, float x, float y) +{ + float vals[] = { NVG_LINETO, x, y }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgBezierTo(struct NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y) +{ + float vals[] = { NVG_BEZIERTO, c1x, c1y, c2x, c2y, x, y }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgArcTo(struct NVGcontext* ctx, float x1, float y1, float x2, float y2, float radius) +{ + float x0 = ctx->commandx; + float y0 = ctx->commandy; + float dx0,dy0, dx1,dy1, a, d, cx,cy, a0,a1; + int dir; + + if (ctx->ncommands == 0) { + return; + } + + // Handle degenerate cases. + if (nvg__ptEquals(x0,y0, x1,y1, ctx->distTol) || + nvg__ptEquals(x1,y1, x2,y2, ctx->distTol) || + nvg__distPtSeg(x1,y1, x0,y0, x2,y2) < ctx->distTol*ctx->distTol || + radius < ctx->distTol) { + nvgLineTo(ctx, x1,y1); + return; + } + + // Calculate tangential circle to lines (x0,y0)-(x1,y1) and (x1,y1)-(x2,y2). + dx0 = x0-x1; + dy0 = y0-y1; + dx1 = x2-x1; + dy1 = y2-y1; + nvg__normalize(&dx0,&dy0); + nvg__normalize(&dx1,&dy1); + a = nvg__acosf(dx0*dx1 + dy0*dy1); + d = radius / nvg__tanf(a/2.0f); + +// printf("a=%f° d=%f\n", a/NVG_PI*180.0f, d); + + if (d > 10000.0f) { + nvgLineTo(ctx, x1,y1); + return; + } + + if (nvg__cross(dx0,dy0, dx1,dy1) > 0.0f) { + cx = x1 + dx0*d + dy0*radius; + cy = y1 + dy0*d + -dx0*radius; + a0 = nvg__atan2f(dx0, -dy0); + a1 = nvg__atan2f(-dx1, dy1); + dir = NVG_CW; +// printf("CW c=(%f, %f) a0=%f° a1=%f°\n", cx, cy, a0/NVG_PI*180.0f, a1/NVG_PI*180.0f); + } else { + cx = x1 + dx0*d + -dy0*radius; + cy = y1 + dy0*d + dx0*radius; + a0 = nvg__atan2f(-dx0, dy0); + a1 = nvg__atan2f(dx1, -dy1); + dir = NVG_CCW; +// printf("CCW c=(%f, %f) a0=%f° a1=%f°\n", cx, cy, a0/NVG_PI*180.0f, a1/NVG_PI*180.0f); + } + + nvgArc(ctx, cx, cy, radius, a0, a1, dir); +} + +void nvgClosePath(struct NVGcontext* ctx) +{ + float vals[] = { NVG_CLOSE }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgPathWinding(struct NVGcontext* ctx, int dir) +{ + float vals[] = { NVG_WINDING, (float)dir }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgArc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir) +{ + float a = 0, da = 0, hda = 0, kappa = 0; + float dx = 0, dy = 0, x = 0, y = 0, tanx = 0, tany = 0; + float px = 0, py = 0, ptanx = 0, ptany = 0; + float vals[3 + 5*7 + 100]; + int i, ndivs, nvals; + int move = ctx->ncommands > 0 ? NVG_LINETO : NVG_MOVETO; + + // Clamp angles + da = a1 - a0; + if (dir == NVG_CW) { + if (nvg__absf(da) >= NVG_PI*2) { + da = NVG_PI*2; + } else { + while (da < 0.0f) da += NVG_PI*2; + } + } else { + if (nvg__absf(da) >= NVG_PI*2) { + da = -NVG_PI*2; + } else { + while (da > 0.0f) da -= NVG_PI*2; + } + } + + // Split arc into max 90 degree segments. + ndivs = nvg__maxi(1, nvg__mini((int)(nvg__absf(da) / (NVG_PI*0.5f) + 0.5f), 5)); + hda = (da / (float)ndivs) / 2.0f; + kappa = nvg__absf(4.0f / 3.0f * (1.0f - nvg__cosf(hda)) / nvg__sinf(hda)); + + if (dir == NVG_CCW) + kappa = -kappa; + + nvals = 0; + for (i = 0; i <= ndivs; i++) { + a = a0 + da * (i/(float)ndivs); + dx = nvg__cosf(a); + dy = nvg__sinf(a); + x = cx + dx*r; + y = cy + dy*r; + tanx = -dy*r*kappa; + tany = dx*r*kappa; + + if (i == 0) { + vals[nvals++] = (float)move; + vals[nvals++] = x; + vals[nvals++] = y; + } else { + vals[nvals++] = NVG_BEZIERTO; + vals[nvals++] = px+ptanx; + vals[nvals++] = py+ptany; + vals[nvals++] = x-tanx; + vals[nvals++] = y-tany; + vals[nvals++] = x; + vals[nvals++] = y; + } + px = x; + py = y; + ptanx = tanx; + ptany = tany; + } + + nvg__appendCommands(ctx, vals, nvals); +} + +void nvgRect(struct NVGcontext* ctx, float x, float y, float w, float h) +{ + float vals[] = { + NVG_MOVETO, x,y, + NVG_LINETO, x+w,y, + NVG_LINETO, x+w,y+h, + NVG_LINETO, x,y+h, + NVG_CLOSE + }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgRoundedRect(struct NVGcontext* ctx, float x, float y, float w, float h, float r) +{ + if (r < 0.1f) { + nvgRect(ctx, x,y,w,h); + return; + } + else { + float vals[] = { + NVG_MOVETO, x+r, y, + NVG_LINETO, x+w-r, y, + NVG_BEZIERTO, x+w-r*(1-NVG_KAPPA90), y, x+w, y+r*(1-NVG_KAPPA90), x+w, y+r, + NVG_LINETO, x+w, y+h-r, + NVG_BEZIERTO, x+w, y+h-r*(1-NVG_KAPPA90), x+w-r*(1-NVG_KAPPA90), y+h, x+w-r, y+h, + NVG_LINETO, x+r, y+h, + NVG_BEZIERTO, x+r*(1-NVG_KAPPA90), y+h, x, y+h-r*(1-NVG_KAPPA90), x, y+h-r, + NVG_LINETO, x, y+r, + NVG_BEZIERTO, x, y+r*(1-NVG_KAPPA90), x+r*(1-NVG_KAPPA90), y, x+r, y, + NVG_CLOSE + }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); + } +} + +void nvgEllipse(struct NVGcontext* ctx, float cx, float cy, float rx, float ry) +{ + float vals[] = { + NVG_MOVETO, cx+rx, cy, + NVG_BEZIERTO, cx+rx, cy+ry*NVG_KAPPA90, cx+rx*NVG_KAPPA90, cy+ry, cx, cy+ry, + NVG_BEZIERTO, cx-rx*NVG_KAPPA90, cy+ry, cx-rx, cy+ry*NVG_KAPPA90, cx-rx, cy, + NVG_BEZIERTO, cx-rx, cy-ry*NVG_KAPPA90, cx-rx*NVG_KAPPA90, cy-ry, cx, cy-ry, + NVG_BEZIERTO, cx+rx*NVG_KAPPA90, cy-ry, cx+rx, cy-ry*NVG_KAPPA90, cx+rx, cy, + NVG_CLOSE + }; + nvg__appendCommands(ctx, vals, NVG_COUNTOF(vals)); +} + +void nvgCircle(struct NVGcontext* ctx, float cx, float cy, float r) +{ + nvgEllipse(ctx, cx,cy, r,r); +} + +void nvgDebugDumpPathCache(struct NVGcontext* ctx) +{ + const struct NVGpath* path; + int i, j; + + printf("Dumping %d cached paths\n", ctx->cache->npaths); + for (i = 0; i < ctx->cache->npaths; i++) { + path = &ctx->cache->paths[i]; + printf(" - Path %d\n", i); + if (path->nfill) { + printf(" - fill: %d\n", path->nfill); + for (j = 0; j < path->nfill; j++) + printf("%f\t%f\n", path->fill[j].x, path->fill[j].y); + } + if (path->nstroke) { + printf(" - stroke: %d\n", path->nstroke); + for (j = 0; j < path->nstroke; j++) + printf("%f\t%f\n", path->stroke[j].x, path->stroke[j].y); + } + } +} + +void nvgFill(struct NVGcontext* ctx) +{ + struct NVGstate* state = nvg__getState(ctx); + const struct NVGpath* path; + int i; + + nvg__flattenPaths(ctx); + if (ctx->params.edgeAntiAlias) + nvg__expandStrokeAndFill(ctx, NVG_FILL|NVG_STROKE, ctx->fringeWidth, NVG_BUTT, NVG_MITER, 3.6f); + else + nvg__expandStrokeAndFill(ctx, NVG_FILL, 0.0f, NVG_BUTT, NVG_MITER, 1.2f); + + ctx->params.renderFill(ctx->params.userPtr, &state->fill, &state->scissor, ctx->fringeWidth, + ctx->cache->bounds, ctx->cache->paths, ctx->cache->npaths); + + // Count triangles + for (i = 0; i < ctx->cache->npaths; i++) { + path = &ctx->cache->paths[i]; + ctx->fillTriCount += path->nfill-2; + ctx->fillTriCount += path->nstroke-2; + ctx->drawCallCount += 2; + } +} + +void nvgStroke(struct NVGcontext* ctx) +{ + struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getAverageScale(state->xform); + float strokeWidth = nvg__clampf(state->strokeWidth * scale, 0.0f, 20.0f); + struct NVGpaint strokePaint = state->stroke; + const struct NVGpath* path; + int i; + + if (strokeWidth < ctx->fringeWidth) { + // If the stroke width is less than pixel size, use alpha to emulate coverate. + // Since coverage is area, scale by alpha*alpha. + float alpha = nvg__clampf(strokeWidth / ctx->fringeWidth, 0.0f, 1.0f); + strokePaint.innerColor.a *= alpha*alpha; + strokePaint.outerColor.a *= alpha*alpha; + strokeWidth = ctx->fringeWidth; + } + + nvg__flattenPaths(ctx); + if (ctx->params.edgeAntiAlias) + nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f + ctx->fringeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit); + else + nvg__expandStrokeAndFill(ctx, NVG_STROKE|NVG_CAPS, strokeWidth*0.5f, state->lineCap, state->lineJoin, state->miterLimit); + + ctx->params.renderStroke(ctx->params.userPtr, &strokePaint, &state->scissor, ctx->fringeWidth, + strokeWidth, ctx->cache->paths, ctx->cache->npaths); + + // Count triangles + for (i = 0; i < ctx->cache->npaths; i++) { + path = &ctx->cache->paths[i]; + ctx->strokeTriCount += path->nstroke-2; + ctx->drawCallCount++; + } +} + +// Add fonts +int nvgCreateFont(struct NVGcontext* ctx, const char* name, const char* path) +{ + return fonsAddFont(ctx->fs, name, path); +} + +int nvgCreateFontMem(struct NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData) +{ + return fonsAddFontMem(ctx->fs, name, data, ndata, freeData); +} + +int nvgFindFont(struct NVGcontext* ctx, const char* name) +{ + if (name == NULL) return -1; + return fonsGetFontByName(ctx->fs, name); +} + +// State setting +void nvgFontSize(struct NVGcontext* ctx, float size) +{ + struct NVGstate* state = nvg__getState(ctx); + state->fontSize = size; +} + +void nvgFontBlur(struct NVGcontext* ctx, float blur) +{ + struct NVGstate* state = nvg__getState(ctx); + state->fontBlur = blur; +} + +void nvgTextLetterSpacing(struct NVGcontext* ctx, float spacing) +{ + struct NVGstate* state = nvg__getState(ctx); + state->letterSpacing = spacing; +} + +void nvgTextLineHeight(struct NVGcontext* ctx, float lineHeight) +{ + struct NVGstate* state = nvg__getState(ctx); + state->lineHeight = lineHeight; +} + +void nvgTextAlign(struct NVGcontext* ctx, int align) +{ + struct NVGstate* state = nvg__getState(ctx); + state->textAlign = align; +} + +void nvgFontFaceId(struct NVGcontext* ctx, int font) +{ + struct NVGstate* state = nvg__getState(ctx); + state->fontId = font; +} + +void nvgFontFace(struct NVGcontext* ctx, const char* font) +{ + struct NVGstate* state = nvg__getState(ctx); + state->fontId = fonsGetFontByName(ctx->fs, font); +} + +static float nvg__quantize(float a, float d) +{ + return ((int)(a / d + 0.5f)) * d; +} + +static float nvg__getFontScale(struct NVGstate* state) +{ + return nvg__minf(nvg__quantize(nvg__getAverageScale(state->xform), 0.01f), 4.0f); +} + +float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end) +{ + struct NVGstate* state = nvg__getState(ctx); + struct NVGpaint paint; + struct FONStextIter iter; + struct FONSquad q; + struct NVGvertex* verts; + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + int dirty[4]; + int cverts = 0; + int nverts = 0; + + if (end == NULL) + end = string + strlen(string); + + if (state->fontId == FONS_INVALID) return x; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + + cverts = nvg__maxi(2, (int)(end - string)) * 6; // conservative estimate. + verts = nvg__allocTempVerts(ctx, cverts); + if (verts == NULL) return x; + + fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end); + while (fonsTextIterNext(ctx->fs, &iter, &q)) { + // Trasnform corners. + float c[4*2]; + nvg__xformPt(&c[0],&c[1], q.x0*invscale, q.y0*invscale, state->xform); + nvg__xformPt(&c[2],&c[3], q.x1*invscale, q.y0*invscale, state->xform); + nvg__xformPt(&c[4],&c[5], q.x1*invscale, q.y1*invscale, state->xform); + nvg__xformPt(&c[6],&c[7], q.x0*invscale, q.y1*invscale, state->xform); + // Create triangles + if (nverts+6 <= cverts) { + nvg__vset(&verts[nverts], c[0], c[1], q.s0, q.t0); nverts++; + nvg__vset(&verts[nverts], c[4], c[5], q.s1, q.t1); nverts++; + nvg__vset(&verts[nverts], c[2], c[3], q.s1, q.t0); nverts++; + nvg__vset(&verts[nverts], c[0], c[1], q.s0, q.t0); nverts++; + nvg__vset(&verts[nverts], c[6], c[7], q.s0, q.t1); nverts++; + nvg__vset(&verts[nverts], c[4], c[5], q.s1, q.t1); nverts++; + } + } + + if (fonsValidateTexture(ctx->fs, dirty)) { + // Update texture + if (ctx->fontImage != 0) { + int iw, ih; + const unsigned char* data = fonsGetTextureData(ctx->fs, &iw, &ih); + int x = dirty[0]; + int y = dirty[1]; + int w = dirty[2] - dirty[0]; + int h = dirty[3] - dirty[1]; + ctx->params.renderUpdateTexture(ctx->params.userPtr, ctx->fontImage, x,y, w,h, data); + } + } + + // Render triangles. + paint = state->fill; + paint.image = ctx->fontImage; + ctx->params.renderTriangles(ctx->params.userPtr, &paint, &state->scissor, verts, nverts); + + ctx->drawCallCount++; + ctx->textTriCount += nverts/3; + + return iter.x; +} + +void nvgTextBox(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end) +{ + struct NVGstate* state = nvg__getState(ctx); + struct NVGtextRow rows[2]; + int nrows = 0, i; + int oldAlign = state->textAlign; + int haling = state->textAlign & (NVG_ALIGN_LEFT | NVG_ALIGN_CENTER | NVG_ALIGN_RIGHT); + int valign = state->textAlign & (NVG_ALIGN_TOP | NVG_ALIGN_MIDDLE | NVG_ALIGN_BOTTOM | NVG_ALIGN_BASELINE); + float lineh = 0; + + if (state->fontId == FONS_INVALID) return; + + nvgTextMetrics(ctx, NULL, NULL, &lineh); + + state->textAlign = NVG_ALIGN_LEFT | valign; + + while ((nrows = nvgTextBreakLines(ctx, string, end, breakRowWidth, rows, 2))) { + for (i = 0; i < nrows; i++) { + struct NVGtextRow* row = &rows[i]; + if (haling & NVG_ALIGN_LEFT) + nvgText(ctx, x, y, row->start, row->end); + else if (haling & NVG_ALIGN_CENTER) + nvgText(ctx, x + breakRowWidth*0.5f - row->width*0.5f, y, row->start, row->end); + else if (haling & NVG_ALIGN_RIGHT) + nvgText(ctx, x + breakRowWidth - row->width, y, row->start, row->end); + y += lineh * state->lineHeight; + } + string = rows[nrows-1].next; + } + + state->textAlign = oldAlign; +} + +int nvgTextGlyphPositions(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, struct NVGglyphPosition* positions, int maxPositions) +{ + struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + struct FONStextIter iter; + struct FONSquad q; + int npos = 0; + float px; + + if (state->fontId == FONS_INVALID) return 0; + + if (end == NULL) + end = string + strlen(string); + + if (string == end) + return 0; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + + px = x*scale; + fonsTextIterInit(ctx->fs, &iter, x*scale, y*scale, string, end); + while (fonsTextIterNext(ctx->fs, &iter, &q)) { + positions[npos].str = iter.str; + positions[npos].x = px * invscale; + px = iter.x; + npos++; + if (npos >= maxPositions) + break; + } + + return npos; +} + +enum NVGcodepointType { + NVG_SPACE, + NVG_NEWLINE, + NVG_CHAR, +}; + +int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* end, float breakRowWidth, struct NVGtextRow* rows, int maxRows) +{ + struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + struct FONStextIter iter; + struct FONSquad q; + int nrows = 0; + float rowStartX = 0; + float rowWidth = 0; + float rowMinX = 0; + float rowMaxX = 0; + const char* rowStart = NULL; + const char* rowEnd = NULL; + const char* wordStart = NULL; + float wordStartX = 0; + float wordMinX = 0; + const char* breakEnd = NULL; + float breakWidth = 0; + float breakMaxX = 0; + int type = NVG_SPACE, ptype = NVG_SPACE; + unsigned int pcodepoint = 0; + + if (maxRows == 0) return 0; + if (state->fontId == FONS_INVALID) return 0; + + if (end == NULL) + end = string + strlen(string); + + if (string == end) return 0; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + + breakRowWidth *= scale; + + fonsTextIterInit(ctx->fs, &iter, 0, 0, string, end); + while (fonsTextIterNext(ctx->fs, &iter, &q)) { + switch (iter.codepoint) { + case 9: // \t + case 11: // \v + case 12: // \f + case 32: // space + case 0x00a0: // NBSP + type = NVG_SPACE; + break; + case 10: // \n + type = pcodepoint == 13 ? NVG_SPACE : NVG_NEWLINE; + break; + case 13: // \r + type = pcodepoint == 10 ? NVG_SPACE : NVG_NEWLINE; + break; + case 0x0085: // NEL + type = NVG_NEWLINE; + break; + default: + type = NVG_CHAR; + break; + } + + if (type == NVG_NEWLINE) { + // Always handle new lines. + rows[nrows].start = rowStart != NULL ? rowStart : iter.str; + rows[nrows].end = rowEnd != NULL ? rowEnd : iter.str; + rows[nrows].width = rowWidth * invscale; + rows[nrows].minx = rowMinX * invscale; + rows[nrows].maxx = rowMaxX * invscale; + rows[nrows].next = iter.next; + nrows++; + if (nrows >= maxRows) + return nrows; + // Set null break point + breakEnd = rowStart; + breakWidth = 0.0; + breakMaxX = 0.0; + // Indicate to skip the white space at the beginning of the row. + rowStart = NULL; + rowEnd = NULL; + rowWidth = 0; + rowMinX = rowMaxX = 0; + } else { + if (rowStart == NULL) { + // Skip white space until the beginning of the line + if (type == NVG_CHAR) { + // The current char is the row so far + rowStartX = iter.x; + rowStart = iter.str; + rowEnd = iter.next; + rowWidth = iter.nextx - rowStartX; // q.x1 - rowStartX; + rowMinX = q.x0 - rowStartX; + rowMaxX = q.x1 - rowStartX; + wordStart = iter.str; + wordStartX = iter.x; + wordMinX = q.x0 - rowStartX; + // Set null break point + breakEnd = rowStart; + breakWidth = 0.0; + breakMaxX = 0.0; + } + } else { + float nextWidth = iter.nextx - rowStartX; //q.x1 - rowStartX; + + if (nextWidth > breakRowWidth) { + // The run length is too long, need to break to new line. + if (breakEnd == rowStart) { + // The current word is longer than the row length, just break it from here. + rows[nrows].start = rowStart; + rows[nrows].end = iter.str; + rows[nrows].width = rowWidth * invscale; + rows[nrows].minx = rowMinX * invscale; + rows[nrows].maxx = rowMaxX * invscale; + rows[nrows].next = iter.str; + nrows++; + if (nrows >= maxRows) + return nrows; + rowStartX = iter.x; + rowStart = iter.str; + rowEnd = iter.next; + rowWidth = iter.nextx - rowStartX; + rowMinX = q.x0 - rowStartX; + rowMaxX = q.x1 - rowStartX; + wordStart = iter.str; + wordStartX = iter.x; + wordMinX = q.x0 - rowStartX; + } else { + // Break the line from the end of the last word, and start new line from the begining of the new. + rows[nrows].start = rowStart; + rows[nrows].end = breakEnd; + rows[nrows].width = breakWidth * invscale; + rows[nrows].minx = rowMinX * invscale; + rows[nrows].maxx = breakMaxX * invscale; + rows[nrows].next = wordStart; + nrows++; + if (nrows >= maxRows) + return nrows; + rowStartX = wordStartX; + rowStart = wordStart; + rowEnd = iter.next; + rowWidth = iter.nextx - rowStartX; // q.x1 - rowStartX; + rowMinX = wordMinX; + rowMaxX = q.x1 - rowStartX; + // No change to the word start + } + // Set null break point + breakEnd = rowStart; + breakWidth = 0.0; + breakMaxX = 0.0; + } + + // track last non-white space character + if (type == NVG_CHAR) { + rowEnd = iter.next; + rowWidth = iter.nextx - rowStartX; // q.x1 - rowStartX; + rowMaxX = q.x1 - rowStartX; + } + // track last end of a word + if (ptype == NVG_CHAR && (type == NVG_SPACE || type == NVG_SPACE)) { + breakEnd = iter.str; + breakWidth = rowWidth; + breakMaxX = rowMaxX; + } + // track last beginning of a word + if ((ptype == NVG_SPACE || ptype == NVG_SPACE) && type == NVG_CHAR) { + wordStart = iter.str; + wordStartX = iter.x; + wordMinX = q.x0 - rowStartX; + } + } + } + + pcodepoint = iter.codepoint; + ptype = type; + } + + // Break the line from the end of the last word, and start new line from the begining of the new. + if (rowStart != NULL) { + rows[nrows].start = rowStart; + rows[nrows].end = rowEnd; + rows[nrows].width = rowWidth * invscale; + rows[nrows].minx = rowMinX * invscale; + rows[nrows].maxx = rowMaxX * invscale; + rows[nrows].next = end; + nrows++; + } + + return nrows; +} + +float nvgTextBounds(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, float* bounds) +{ + struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + float width; + + if (state->fontId == FONS_INVALID) return 0; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + + width = fonsTextBounds(ctx->fs, x, y, string, end, bounds); + if (bounds != NULL) { + bounds[0] *= invscale; + bounds[1] *= invscale; + bounds[2] *= invscale; + bounds[3] *= invscale; + } + return width * invscale; +} + +void nvgTextBoxBounds(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) +{ + struct NVGstate* state = nvg__getState(ctx); + struct NVGtextRow rows[2]; + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + int nrows = 0, i; + int oldAlign = state->textAlign; + int haling = state->textAlign & (NVG_ALIGN_LEFT | NVG_ALIGN_CENTER | NVG_ALIGN_RIGHT); + int valign = state->textAlign & (NVG_ALIGN_TOP | NVG_ALIGN_MIDDLE | NVG_ALIGN_BOTTOM | NVG_ALIGN_BASELINE); + float lineh = 0, rminy = 0, rmaxy = 0; + float minx, miny, maxx, maxy; + + if (state->fontId == FONS_INVALID) { + if (bounds != NULL) + bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0f; + return; + } + + nvgTextMetrics(ctx, NULL, NULL, &lineh); + + nvgTextMetrics(ctx, NULL, NULL, &lineh); + + state->textAlign = NVG_ALIGN_LEFT | valign; + + minx = maxx = x; + miny = maxy = y; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + fonsLineBounds(ctx->fs, 0, &rminy, &rmaxy); + rminy *= invscale; + rmaxy *= invscale; + + while ((nrows = nvgTextBreakLines(ctx, string, end, breakRowWidth, rows, 2))) { + for (i = 0; i < nrows; i++) { + struct NVGtextRow* row = &rows[i]; + float rminx, rmaxx, dx = 0; + // Horizontal bounds + if (haling & NVG_ALIGN_LEFT) + dx = 0; + else if (haling & NVG_ALIGN_CENTER) + dx = breakRowWidth*0.5f - row->width*0.5f; + else if (haling & NVG_ALIGN_RIGHT) + dx = breakRowWidth - row->width; + rminx = x + row->minx + dx; + rmaxx = x + row->maxx + dx; + minx = nvg__minf(minx, rminx); + maxx = nvg__maxf(maxx, rmaxx); + // Vertical bounds. + miny = nvg__minf(miny, y + rminy); + maxy = nvg__maxf(maxy, y + rmaxy); + + y += lineh * state->lineHeight; + } + string = rows[nrows-1].next; + } + + state->textAlign = oldAlign; + + if (bounds != NULL) { + bounds[0] = minx; + bounds[1] = miny; + bounds[2] = maxx; + bounds[3] = maxy; + } +} + +void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh) +{ + struct NVGstate* state = nvg__getState(ctx); + float scale = nvg__getFontScale(state) * ctx->devicePxRatio; + float invscale = 1.0f / scale; + + if (state->fontId == FONS_INVALID) return; + + fonsSetSize(ctx->fs, state->fontSize*scale); + fonsSetSpacing(ctx->fs, state->letterSpacing*scale); + fonsSetBlur(ctx->fs, state->fontBlur*scale); + fonsSetAlign(ctx->fs, state->textAlign); + fonsSetFont(ctx->fs, state->fontId); + + fonsVertMetrics(ctx->fs, ascender, descender, lineh); + if (ascender != NULL) + *ascender *= invscale; + if (descender != NULL) + *descender *= invscale; + if (lineh != NULL) + *lineh *= invscale; +} diff --git a/examples/common/nanovg/nanovg.h b/examples/common/nanovg/nanovg.h new file mode 100644 index 00000000..71f90de0 --- /dev/null +++ b/examples/common/nanovg/nanovg.h @@ -0,0 +1,550 @@ +// +// Copyright (c) 2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef NANOVG_H +#define NANOVG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define NVG_PI 3.14159265358979323846264338327f + +struct NVGcontext; + +struct NVGcolor { + union { + float rgba[4]; + struct { + float r,g,b,a; + }; + }; +}; + +struct NVGpaint { + float xform[6]; + float extent[2]; + float radius; + float feather; + struct NVGcolor innerColor; + struct NVGcolor outerColor; + int image; + int repeat; +}; + +enum NVGwinding { + NVG_CCW = 1, // Winding for solid shapes + NVG_CW = 2, // Winding for holes +}; + +enum NVGsolidity { + NVG_SOLID = 1, // CCW + NVG_HOLE = 2, // CW +}; + +enum NVGlineCap { + NVG_BUTT, + NVG_ROUND, + NVG_SQUARE, + NVG_BEVEL, + NVG_MITER, +}; + +enum NVGpatternRepeat { + NVG_REPEATX = 0x01, // Repeat image pattern in X direction + NVG_REPEATY = 0x02, // Repeat image pattern in Y direction +}; + +enum NVGalign { + // Horizontal align + NVG_ALIGN_LEFT = 1<<0, // Default, align text horizontally to left. + NVG_ALIGN_CENTER = 1<<1, // Align text horizontally to center. + NVG_ALIGN_RIGHT = 1<<2, // Align text horizontally to right. + // Vertical align + NVG_ALIGN_TOP = 1<<3, // Align text vertically to top. + NVG_ALIGN_MIDDLE = 1<<4, // Align text vertically to middle. + NVG_ALIGN_BOTTOM = 1<<5, // Align text vertically to bottom. + NVG_ALIGN_BASELINE = 1<<6, // Default, align text vertically to baseline. +}; + +enum NVGalpha { + NVG_STRAIGHT_ALPHA, + NVG_PREMULTIPLIED_ALPHA, +}; + +struct NVGglyphPosition { + const char* str; // Position of the glyph in the input string. + float x; // The x- coordinate of the position of the glyph . +}; + +struct NVGtextRow { + const char* start; // Pointer to the input text where the row starts. + const char* end; // Pointer to the input text where the row ends (one past the last character). + const char* next; // Pointer to the beginning of the next row. + float width; // Logical width of the row. + float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending. +}; + + +// Begin drawing a new frame +// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame() +// nvgBeginFrame() defines the size of the window to render to in relation currently +// set viewport (i.e. glViewport on GL backends). Device pixel ration allows to +// control the rendering on Hi-DPI devices. +// For example, GLFW returns two dimension for an opened window: window size and +// frame buffer size. In that case you would set windowWidth/Height to the window size +// devicePixelRatio to: frameBufferWidth / windowWidth. +// AlphaBlend controls if drawing the shapes to the render target should be done using straight or +// premultiplied alpha. If rendering directly to framebuffer you probably want to use NVG_STRAIGHT_ALPHA, +// if rendering to texture which should contain transparent regions NVG_PREMULTIPLIED_ALPHA is the +// right choice. +void nvgBeginFrame(struct NVGcontext* ctx, int windowWidth, int windowHeight, float devicePixelRatio, int alphaBlend); + +// Ends drawing flushing remaining render state. +void nvgEndFrame(struct NVGcontext* ctx); + +// +// Color utils +// +// Colors in NanoVG are stored as unsigned ints in ABGR format. + +// Returns a color value from red, green, blue values. Alpha will be set to 255 (1.0f). +struct NVGcolor nvgRGB(unsigned char r, unsigned char g, unsigned char b); + +// Returns a color value from red, green, blue values. Alpha will be set to 1.0f. +struct NVGcolor nvgRGBf(float r, float g, float b); + + +// Returns a color value from red, green, blue and alpha values. +struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +// Returns a color value from red, green, blue and alpha values. +struct NVGcolor nvgRGBAf(float r, float g, float b, float a); + + +// Linearly interpoaltes from color c0 to c1, and returns resulting color value. +struct NVGcolor nvgLerpRGBA(struct NVGcolor c0, struct NVGcolor c1, float u); + +// Sets transparency of a color value. +struct NVGcolor nvgTransRGBA(struct NVGcolor c0, unsigned char a); + +// Sets transparency of a color value. +struct NVGcolor nvgTransRGBAf(struct NVGcolor c0, float a); + +// Returns color value specified by hue, saturation and lightness. +// HSL values are all in range [0..1], alpha will be set to 255. +struct NVGcolor nvgHSL(float h, float s, float l); + +// Returns color value specified by hue, saturation and lightness and alpha. +// HSL values are all in range [0..1], alpha in range [0..255] +struct NVGcolor nvgHSLA(float h, float s, float l, unsigned char a); + +// +// State Handling +// +// NanoVG contains state which represents how paths will be rendered. +// The state contains transform, fill and stroke styles, text and font styles, +// and scissor clipping. + +// Pushes and saves the current render state into a state stack. +// A matching nvgRestore() must be used to restore the state. +void nvgSave(struct NVGcontext* ctx); + +// Pops and restores current render state. +void nvgRestore(struct NVGcontext* ctx); + +// Resets current render state to default values. Does not affect the render state stack. +void nvgReset(struct NVGcontext* ctx); + +// +// Render styles +// +// Fill and stroke render style can be either a solid color or a paint which is a gradient or a pattern. +// Solid color is simply defined as a color value, different kinds of paints can be created +// using nvgLinearGradient(), nvgBoxGradient(), nvgRadialGradient() and nvgImagePattern(). +// +// Current render style can be saved and restored using nvgSave() and nvgRestore(). + +// Sets current stroke style to a solid color. +void nvgStrokeColor(struct NVGcontext* ctx, struct NVGcolor color); + +// Sets current stroke style to a paint, which can be a one of the gradients or a pattern. +void nvgStrokePaint(struct NVGcontext* ctx, struct NVGpaint paint); + +// Sets current fill cstyle to a solid color. +void nvgFillColor(struct NVGcontext* ctx, struct NVGcolor color); + +// Sets current fill style to a paint, which can be a one of the gradients or a pattern. +void nvgFillPaint(struct NVGcontext* ctx, struct NVGpaint paint); + +// Sets the miter limit of the stroke style. +// Miter limit controls when a sharp corner is beveled. +void nvgMiterLimit(struct NVGcontext* ctx, float limit); + +// Sets the stroke witdth of the stroke style. +void nvgStrokeWidth(struct NVGcontext* ctx, float size); + +// Sets how the end of the line (cap) is drawn, +// Can be one of: NVG_BUTT (default), NVG_ROUND, NVG_SQUARE. +void nvgLineCap(struct NVGcontext* ctx, int cap); + +// Sets how sharp path corners are drawn. +// Can be one of NVG_MITER (default), NVG_ROUND, NVG_BEVEL. +void nvgLineJoin(struct NVGcontext* ctx, int join); + +// +// Transforms +// +// The paths, gradients, patterns and scissor region are transformed by an transformation +// matrix at the time when they are passed to the API. +// The current transformation matrix is a affine matrix: +// [sx kx tx] +// [ky sy ty] +// [ 0 0 1] +// Where: sx,sy define scaling, kx,ky skewing, and tx,ty translation. +// The last row is assumed to be 0,0,1 and is not stored. +// +// Apart from nvgResetTransform(), each transformation function first creates +// specific transformation matrix and pre-multiplies the current transformation by it. +// +// Current coordinate system (transformation) can be saved and restored using nvgSave() and nvgRestore(). + +// Resets current transform to a identity matrix. +void nvgResetTransform(struct NVGcontext* ctx); + +// Premultiplies current coordinate system by specified matrix. +// The parameters are interpreted as matrix as follows: +// [a c e] +// [b d f] +// [0 0 1] +void nvgTransform(struct NVGcontext* ctx, float a, float b, float c, float d, float e, float f); + +// Translates current coordinate system. +void nvgTranslate(struct NVGcontext* ctx, float x, float y); + +// Rotates current coordinate system. +void nvgRotate(struct NVGcontext* ctx, float angle); + +// Scales the current coordinat system. +void nvgScale(struct NVGcontext* ctx, float x, float y); + +// +// Images +// +// NanoVG allows you to load jpg, png, psd, tga, pic and gif files to be used for rendering. +// In addition you can upload your own image. The image loading is provided by stb_image. + +// Creates image by loading it from the disk from specified file name. +// Returns handle to the image. +int nvgCreateImage(struct NVGcontext* ctx, const char* filename); + +// Creates image by loading it from the specified chunk of memory. +// Returns handle to the image. +int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata); + +// Creates image from specified image data. +// Returns handle to the image. +int nvgCreateImageRGBA(struct NVGcontext* ctx, int w, int h, const unsigned char* data); + +// Updates image data specified by image handle. +void nvgUpdateImage(struct NVGcontext* ctx, int image, const unsigned char* data); + +// Returns the domensions of a created image. +void nvgImageSize(struct NVGcontext* ctx, int image, int* w, int* h); + +// Deletes created image. +void nvgDeleteImage(struct NVGcontext* ctx, int image); + +// +// Paints +// +// NanoVG supports four types of paints: linear gradient, box gradient, radial gradient and image pattern. +// These can be used as paints for strokes and fills. + +// Creates and returns a linear gradient. Parameters (sx,sy)-(ex,ey) specify the start and end coordinates +// of the linear gradient, icol specifies the start color and ocol the end color. +// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). +struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx, float sx, float sy, float ex, float ey, + struct NVGcolor icol, struct NVGcolor ocol); + +// Creates and returns a box gradient. Box gradient is a feathered rounded rectangle, it is useful for rendering +// drop shadows or hilights for boxes. Parameters (x,y) define the top-left corner of the rectangle, +// (w,h) define the size of the rectangle, r defines the corner radius, and f feather. Feather defines how blurry +// the border of the rectangle is. Parameter icol specifies the inner color and ocol the outer color of the gradient. +// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). +struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx, float x, float y, float w, float h, + float r, float f, struct NVGcolor icol, struct NVGcolor ocol); + +// Creates and returns a radial gradient. Parameters (cx,cy) specify the center, inr and outr specify +// the inner and outer radius of the gradient, icol specifies the start color and ocol the end color. +// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). +struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx, float cx, float cy, float inr, float outr, + struct NVGcolor icol, struct NVGcolor ocol); + +// Creates and returns an image patter. Parameters (ox,oy) specify the left-top location of the image pattern, +// (ex,ey) the size of one image, angle rotation around the top-left corner, image is handle to the image to render, +// and repeat is combination of NVG_REPEATX and NVG_REPEATY which tells if the image should be repeated across x or y. +// The gradient is transformed by the current transform when it is passed to nvgFillPaint() or nvgStrokePaint(). +struct NVGpaint nvgImagePattern(struct NVGcontext* ctx, float ox, float oy, float ex, float ey, + float angle, int image, int repeat); + +// +// Scissoring +// +// Scissoring allows you to clip the rendering into a rectangle. This is useful for varius +// user interface cases like rendering a text edit or a timeline. + +// Sets the current +// The scissor rectangle is transformed by the current transform. +void nvgScissor(struct NVGcontext* ctx, float x, float y, float w, float h); + +// Reset and disables scissoring. +void nvgResetScissor(struct NVGcontext* ctx); + +// +// Paths +// +// Drawing a new shape starts with nvgBeginPath(), it clears all the currently defined paths. +// Then you define one or more paths and sub-paths which describe the shape. The are functions +// to draw common shapes like rectangles and circles, and lower level step-by-step functions, +// which allow to define a path curve by curve. +// +// NanoVG uses even-odd fill rule to draw the shapes. Solid shapes should have counter clockwise +// winding and holes should have counter clockwise order. To specify winding of a path you can +// call nvgPathWinding(). This is useful especially for the common shapes, which are drawn CCW. +// +// Finally you can fill the path using current fill style by calling nvgFill(), and stroke it +// with current stroke style by calling nvgStroke(). +// +// The curve segments and sub-paths are transformed by the current transform. + +// Clears the current path and sub-paths. +void nvgBeginPath(struct NVGcontext* ctx); + +// Starts new sub-path with specified point as first point. +void nvgMoveTo(struct NVGcontext* ctx, float x, float y); + +// Adds line segment from the last point in the path to the specified point. +void nvgLineTo(struct NVGcontext* ctx, float x, float y); + +// Adds bezier segment from last point in the path via two control points to the specified point. +void nvgBezierTo(struct NVGcontext* ctx, float c1x, float c1y, float c2x, float c2y, float x, float y); + +// Adds an arc segment at the corner defined by the last path point, and two specified points. +void nvgArcTo(struct NVGcontext* ctx, float x1, float y1, float x2, float y2, float radius); + +// Closes current sub-path with a line segment. +void nvgClosePath(struct NVGcontext* ctx); + +// Sets the current sub-path winding, see NVGwinding and NVGsolidity. +void nvgPathWinding(struct NVGcontext* ctx, int dir); + +// Creates new arc shaped sub-path. +void nvgArc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir); + +// Creates new rectangle shaped sub-path. +void nvgRect(struct NVGcontext* ctx, float x, float y, float w, float h); + +// Creates new rounded rectangle shaped sub-path. +void nvgRoundedRect(struct NVGcontext* ctx, float x, float y, float w, float h, float r); + +// Creates new ellipse shaped sub-path. +void nvgEllipse(struct NVGcontext* ctx, float cx, float cy, float rx, float ry); + +// Creates new circle shaped sub-path. +void nvgCircle(struct NVGcontext* ctx, float cx, float cy, float r); + +// Fills the current path with current fill style. +void nvgFill(struct NVGcontext* ctx); + +// Fills the current path with current stroke style. +void nvgStroke(struct NVGcontext* ctx); + + +// +// Text +// +// NanoVG allows you to load .ttf files and use the font to render text. +// +// The appearance of the text can be defined by setting the current text style +// and by specifying the fill color. Common text and font settings such as +// font size, letter spacing and text align are supported. Font blur allows you +// to create simple text effects such as drop shadows. +// +// At render time the font face can be set based on the font handles or name. +// +// Font measure functions return values in local space, the calculations are +// carried in the same resolution as the final rendering. This is done because +// the text glyph positions are snapped to the nearest pixels sharp rendering. +// +// The local space means that values are not rotated or scale as per the current +// transformation. For example if you set font size to 12, which would mean that +// line height is 16, then regardless of the current scaling and rotation, the +// returned line height is always 16. Some measures may vary because of the scaling +// since aforementioned pixel snapping. +// +// While this may sound a little odd, the setup allows you to always render the +// same way regardless of scaling. I.e. following works regardless of scaling: +// +// const char* txt = "Text me up."; +// nvgTextBounds(vg, x,y, txt, NULL, bounds); +// nvgBeginPath(vg); +// nvgRoundedRect(vg, bounds[0],bounds[1], bounds[2]-bounds[0], bounds[3]-bounds[1]); +// nvgFill(vg); +// +// Note: currently only solid color fill is supported for text. + +// Creates font by loading it from the disk from specified file name. +// Returns handle to the font. +int nvgCreateFont(struct NVGcontext* ctx, const char* name, const char* filename); + +// Creates image by loading it from the specified memory chunk. +// Returns handle to the font. +int nvgCreateFontMem(struct NVGcontext* ctx, const char* name, unsigned char* data, int ndata, int freeData); + +// Finds a loaded font of specified name, and returns handle to it, or -1 if the font is not found. +int nvgFindFont(struct NVGcontext* ctx, const char* name); + +// Sets the font size of current text style. +void nvgFontSize(struct NVGcontext* ctx, float size); + +// Sets the blur of current text style. +void nvgFontBlur(struct NVGcontext* ctx, float blur); + +// Sets the letter spacing of current text style. +void nvgTextLetterSpacing(struct NVGcontext* ctx, float spacing); + +// Sets the proportional line height of current text style. The line height is specified as multiple of font size. +void nvgTextLineHeight(struct NVGcontext* ctx, float lineHeight); + +// Sets the text align of current text style, see NVGaling for options. +void nvgTextAlign(struct NVGcontext* ctx, int align); + +// Sets the font face based on specified id of current text style. +void nvgFontFaceId(struct NVGcontext* ctx, int font); + +// Sets the font face based on specified name of current text style. +void nvgFontFace(struct NVGcontext* ctx, const char* font); + +// Draws text string at specified location. If end is specified only the sub-string up to the end is drawn. +float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end); + +// Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn. +// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. +// Words longer than the max width are slit at nearest character (i.e. no hyphenation). +void nvgTextBox(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end); + +// Measures the specified text string. Parameter bounds should be a pointer to float[4], +// if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] +// Returns the horizontal advance of the measured text (i.e. where the next character should drawn). +// Measured values are returned in local coordinate space. +float nvgTextBounds(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, float* bounds); + +// Measures the specified multi-text string. Parameter bounds should be a pointer to float[4], +// if the bounding box of the text should be returned. The bounds value are [xmin,ymin, xmax,ymax] +// Measured values are returned in local coordinate space. +void nvgTextBoxBounds(struct NVGcontext* ctx, float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds); + +// Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used. +// Measured values are returned in local coordinate space. +int nvgTextGlyphPositions(struct NVGcontext* ctx, float x, float y, const char* string, const char* end, struct NVGglyphPosition* positions, int maxPositions); + +// Returns the vertical metrics based on the current text style. +// Measured values are returned in local coordinate space. +void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh); + +// Breaks the specified text into lines. If end is specified only the sub-string will be used. +// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered. +// Words longer than the max width are slit at nearest character (i.e. no hyphenation). +int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* end, float breakRowWidth, struct NVGtextRow* rows, int maxRows); + +// +// Internal Render API +// +enum NVGtexture { + NVG_TEXTURE_ALPHA = 0x01, + NVG_TEXTURE_RGBA = 0x02, +}; + +struct NVGscissor +{ + float xform[6]; + float extent[2]; +}; + +struct NVGvertex { + float x,y,u,v; +}; + +struct NVGpath { + int first; + int count; + unsigned char closed; + int nbevel; + struct NVGvertex* fill; + int nfill; + struct NVGvertex* stroke; + int nstroke; + int winding; + int convex; +}; + +struct NVGparams { + void* userPtr; + int atlasWidth, atlasHeight; + int edgeAntiAlias; + int (*renderCreate)(void* uptr); + int (*renderCreateTexture)(void* uptr, int type, int w, int h, const unsigned char* data); + int (*renderDeleteTexture)(void* uptr, int image); + int (*renderUpdateTexture)(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data); + int (*renderGetTextureSize)(void* uptr, int image, int* w, int* h); + void (*renderViewport)(void* uptr, int width, int height, int alphaBlend); + void (*renderFlush)(void* uptr, int alphaBlend); + void (*renderFill)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, const float* bounds, const struct NVGpath* paths, int npaths); + void (*renderStroke)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, float strokeWidth, const struct NVGpath* paths, int npaths); + void (*renderTriangles)(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, const struct NVGvertex* verts, int nverts); + void (*renderDelete)(void* uptr); +}; + +// Contructor and destructor, called by the render back-end. +struct NVGcontext* nvgCreateInternal(struct NVGparams* params); +void nvgDeleteInternal(struct NVGcontext* ctx); + +// Debug function to dump cached path data. +void nvgDebugDumpPathCache(struct NVGcontext* ctx); + +// +struct NVGcontext* nvgCreate(int atlasw, int atlash, int edgeaa); + +// +void nvgDelete(struct NVGcontext* ctx); + +// Compiler references +// http://sourceforge.net/p/predef/wiki/Compilers/ +#if _MSC_VER >= 1800 + // VS 2013 seems to be too smart for school, it will still list the variable as unused if passed into sizeof(). + #define NVG_NOTUSED(v) do { (void)(v); } while(0) +#else + #define NVG_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef __cplusplus +} +#endif + +#endif // NANOVG_H diff --git a/examples/common/nanovg/nanovg_bgfx.cpp b/examples/common/nanovg/nanovg_bgfx.cpp new file mode 100644 index 00000000..20ae557f --- /dev/null +++ b/examples/common/nanovg/nanovg_bgfx.cpp @@ -0,0 +1,1010 @@ +/* + * Copyright 2011-2014 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +// +// Copyright (c) 2009-2013 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +#define NVG_ANTIALIAS 1 + +#include +#include +#include +#include +#include "nanovg.h" + +#include + +namespace +{ +#include "vs_nanovg_fill.bin.h" +#include "fs_nanovg_fill.bin.h" + + static bgfx::VertexDecl s_nvgDecl; + + enum GLNVGshaderType + { + NSVG_SHADER_FILLGRAD, + NSVG_SHADER_FILLIMG, + NSVG_SHADER_SIMPLE, + NSVG_SHADER_IMG + }; + + struct GLNVGtexture + { + bgfx::TextureHandle id; + int width, height; + int type; + }; + + enum GLNVGcallType + { + GLNVG_FILL, + GLNVG_CONVEXFILL, + GLNVG_STROKE, + GLNVG_TRIANGLES, + }; + + struct GLNVGcall + { + int type; + int image; + int pathOffset; + int pathCount; + int vertexOffset; + int vertexCount; + int uniformOffset; + }; + + struct GLNVGpath + { + int fillOffset; + int fillCount; + int strokeOffset; + int strokeCount; + }; + + struct GLNVGfragUniforms + { + float scissorMat[12]; // matrices are actually 3 vec4s + float paintMat[12]; + NVGcolor innerCol; + NVGcolor outerCol; + + // u_scissorExtScale + float scissorExt[2]; + float scissorScale[2]; + + // u_extentRadius + float extent[2]; + float radius; + + // u_params + float feather; + float strokeMult; + float texType; + float type; + }; + + struct GLNVGcontext + { + bgfx::ProgramHandle prog; + bgfx::UniformHandle u_scissorMat; + bgfx::UniformHandle u_paintMat; + bgfx::UniformHandle u_innerCol; + bgfx::UniformHandle u_outerCol; + bgfx::UniformHandle u_viewSize; + bgfx::UniformHandle u_scissorExtScale; + bgfx::UniformHandle u_extentRadius; + bgfx::UniformHandle u_params; + + bgfx::UniformHandle s_tex; + + uint64_t state; + bgfx::TextureHandle th; + + bgfx::TransientVertexBuffer tvb; + uint8_t viewid; + + struct GLNVGtexture* textures; + float view[2]; + int ntextures; + int ctextures; + int textureId; + int vertBuf; + int fragSize; + int edgeAntiAlias; + + // Per frame buffers + struct GLNVGcall* calls; + int ccalls; + int ncalls; + struct GLNVGpath* paths; + int cpaths; + int npaths; + struct NVGvertex* verts; + int cverts; + int nverts; + unsigned char* uniforms; + int cuniforms; + int nuniforms; + }; + + static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl) + { + struct GLNVGtexture* tex = NULL; + int i; + + for (i = 0; i < gl->ntextures; i++) + { + if (gl->textures[i].id.idx == bgfx::invalidHandle) + { + tex = &gl->textures[i]; + break; + } + } + + if (tex == NULL) + { + if (gl->ntextures+1 > gl->ctextures) + { + int old = gl->ctextures; + gl->ctextures = (gl->ctextures == 0) ? 2 : gl->ctextures*2; + gl->textures = (struct GLNVGtexture*)realloc(gl->textures, sizeof(struct GLNVGtexture)*gl->ctextures); + memset(&gl->textures[old], 0xff, (gl->ctextures-old)*sizeof(struct GLNVGtexture) ); + + if (gl->textures == NULL) + { + return NULL; + } + } + tex = &gl->textures[gl->ntextures++]; + } + + memset(tex, 0, sizeof(*tex)); + + return tex; + } + + static struct GLNVGtexture* glnvg__findTexture(struct GLNVGcontext* gl, int id) + { + int i; + for (i = 0; i < gl->ntextures; i++) + { + if (gl->textures[i].id.idx == id) + { + return &gl->textures[i]; + } + } + + return NULL; + } + + static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id) + { + int i; + for (i = 0; i < gl->ntextures; i++) + { + if (gl->textures[i].id.idx == id) + { + if (bgfx::isValid(gl->textures[i].id) ) + { + bgfx::destroyTexture(gl->textures[i].id); + } + memset(&gl->textures[i], 0, sizeof(gl->textures[i])); + gl->textures[i].id.idx = bgfx::invalidHandle; + return 1; + } + } + return 0; + } + + static int nvgRenderCreate(void* _userPtr) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + + const bgfx::Memory* vs_nanovg_fill; + const bgfx::Memory* fs_nanovg_fill; + + switch (bgfx::getRendererType() ) + { + case bgfx::RendererType::Direct3D9: + vs_nanovg_fill = bgfx::makeRef(vs_nanovg_fill_dx9, sizeof(vs_nanovg_fill_dx9) ); + fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_dx9, sizeof(fs_nanovg_fill_dx9) ); + break; + + case bgfx::RendererType::Direct3D11: + vs_nanovg_fill = bgfx::makeRef(vs_nanovg_fill_dx11, sizeof(vs_nanovg_fill_dx11) ); + fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_dx11, sizeof(fs_nanovg_fill_dx11) ); + break; + + default: + vs_nanovg_fill = bgfx::makeRef(vs_nanovg_fill_glsl, sizeof(vs_nanovg_fill_glsl) ); + fs_nanovg_fill = bgfx::makeRef(fs_nanovg_fill_glsl, sizeof(fs_nanovg_fill_glsl) ); + break; + } + + gl->prog = bgfx::createProgram( + bgfx::createShader(vs_nanovg_fill) + , bgfx::createShader(fs_nanovg_fill) + , true + ); + + gl->u_scissorMat = bgfx::createUniform("u_scissorMat", bgfx::UniformType::Uniform3x3fv); + gl->u_paintMat = bgfx::createUniform("u_paintMat", bgfx::UniformType::Uniform3x3fv); + gl->u_innerCol = bgfx::createUniform("u_innerCol", bgfx::UniformType::Uniform4fv); + gl->u_outerCol = bgfx::createUniform("u_outerCol", bgfx::UniformType::Uniform4fv); + gl->u_viewSize = bgfx::createUniform("u_viewSize", bgfx::UniformType::Uniform2fv); + gl->u_scissorExtScale = bgfx::createUniform("u_scissorExtScale", bgfx::UniformType::Uniform4fv); + gl->u_extentRadius = bgfx::createUniform("u_extentRadius", bgfx::UniformType::Uniform4fv); + gl->u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv); + gl->s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Uniform1i); + + gl->viewid = 0; + + s_nvgDecl.begin(); + s_nvgDecl.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float); + s_nvgDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float); + s_nvgDecl.end(); + + int align = 1; + gl->fragSize = sizeof(struct GLNVGfragUniforms) + align - sizeof(struct GLNVGfragUniforms) % align; + + return 1; + } + + static int nvgRenderCreateTexture(void* _userPtr, int _type, int _width, int _height, const unsigned char* _rgba) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + struct GLNVGtexture* tex = glnvg__allocTexture(gl); + + if (tex == NULL) + { + return 0; + } + + tex->width = _width; + tex->height = _height; + tex->type = _type; + + uint32_t bytesPerPixel = NVG_TEXTURE_RGBA == tex->type ? 4 : 1; + uint32_t pitch = tex->width * bytesPerPixel; + + const bgfx::Memory* mem = NULL; + if (NULL != _rgba) + { + mem = bgfx::alloc(tex->height * pitch); + bgfx::imageSwizzleBgra8(tex->width, tex->height, pitch, _rgba, mem->data); + } + + tex->id = bgfx::createTexture2D(tex->width + , tex->height + , 1 + , NVG_TEXTURE_RGBA == _type ? bgfx::TextureFormat::BGRA8 : bgfx::TextureFormat::R8 + , BGFX_TEXTURE_NONE + , mem + ); + + return tex->id.idx; + } + + static int nvgRenderDeleteTexture(void* _userPtr, int image) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + return glnvg__deleteTexture(gl, image); + } + + static int nvgRenderUpdateTexture(void* _userPtr, int image, int x, int y, int w, int h, const unsigned char* data) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + struct GLNVGtexture* tex = glnvg__findTexture(gl, image); + if (tex == NULL) + { + return 0; + } + + uint32_t bytesPerPixel = NVG_TEXTURE_RGBA == tex->type ? 4 : 1; + uint32_t pitch = tex->width * bytesPerPixel; + + bgfx::updateTexture2D(tex->id, 0, x, y, w, h + , bgfx::makeRef(data + y*pitch + x*bytesPerPixel, h*pitch) + , pitch + ); + + return 1; + } + + static int nvgRenderGetTextureSize(void* _userPtr, int image, int* w, int* h) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + struct GLNVGtexture* tex = glnvg__findTexture(gl, image); + + if (!bgfx::isValid(tex->id) ) + { + return 0; + } + + *w = tex->width; + *h = tex->height; + + return 1; + } + + static void glnvg__xformIdentity(float* t) + { + t[0] = 1.0f; t[1] = 0.0f; + t[2] = 0.0f; t[3] = 1.0f; + t[4] = 0.0f; t[5] = 0.0f; + } + + static void glnvg__xformInverse(float* inv, float* t) + { + double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1]; + if (det > -1e-6 && det < 1e-6) { + glnvg__xformIdentity(t); + return; + } + invdet = 1.0 / det; + inv[0] = (float)(t[3] * invdet); + inv[2] = (float)(-t[2] * invdet); + inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet); + inv[1] = (float)(-t[1] * invdet); + inv[3] = (float)(t[0] * invdet); + inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet); + } + + static void glnvg__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 int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms* frag, struct NVGpaint* paint, + struct NVGscissor* scissor, float width, float fringe) + { + struct GLNVGtexture* tex = NULL; + float invxform[6] = {}; + + memset(frag, 0, sizeof(*frag)); + + frag->innerCol = paint->innerColor; + frag->outerCol = paint->outerColor; + + glnvg__xformInverse(invxform, paint->xform); + glnvg__xformToMat3x4(frag->paintMat, invxform); + + 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 + { + glnvg__xformInverse(invxform, scissor->xform); + glnvg__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; + + bgfx::TextureHandle invalid = BGFX_INVALID_HANDLE; + gl->th = invalid; + if (paint->image != 0) + { + tex = glnvg__findTexture(gl, paint->image); + if (tex == NULL) + { + return 0; + } + frag->type = NSVG_SHADER_FILLIMG; + frag->texType = tex->type == NVG_TEXTURE_RGBA ? 0.0f : 1.0f; + gl->th = tex->id; + } + else + { + frag->type = NSVG_SHADER_FILLGRAD; + frag->radius = paint->radius; + frag->feather = paint->feather; + } + + return 1; + } + + static void glnvg__mat3(float* dst, float* src) + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + + dst[3] = src[4]; + dst[4] = src[5]; + dst[5] = src[6]; + + dst[6] = src[8]; + dst[7] = src[9]; + dst[8] = src[10]; + } + + static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i) + { + return (struct GLNVGfragUniforms*)&gl->uniforms[i]; + } + + static void nvgRenderSetUniforms(struct GLNVGcontext* gl, int uniformOffset, int image) + { + struct GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset); + float tmp[9]; // Maybe there's a way to get rid of this... + glnvg__mat3(tmp, frag->scissorMat); + bgfx::setUniform(gl->u_scissorMat, tmp); + glnvg__mat3(tmp, frag->paintMat); + bgfx::setUniform(gl->u_paintMat, tmp); + + bgfx::setUniform(gl->u_innerCol, frag->innerCol.rgba); + bgfx::setUniform(gl->u_outerCol, frag->outerCol.rgba); + bgfx::setUniform(gl->u_scissorExtScale, &frag->scissorExt[0]); + bgfx::setUniform(gl->u_extentRadius, &frag->extent[0]); + bgfx::setUniform(gl->u_params, &frag->feather); + + bgfx::TextureHandle handle = BGFX_INVALID_HANDLE; + + if (image != 0) + { + struct GLNVGtexture* tex = glnvg__findTexture(gl, image); + if (tex != NULL) + { + handle = tex->id; + } + } + + gl->th = handle; + } + + static void nvgRenderViewport(void* _userPtr, int width, int height, int alphaBlend) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + NVG_NOTUSED(alphaBlend); + gl->view[0] = (float)width; + gl->view[1] = (float)height; + } + + static void fan(uint32_t _start, uint32_t _count) + { + uint32_t numTris = _count-2; + bgfx::TransientIndexBuffer tib; + bgfx::allocTransientIndexBuffer(&tib, numTris*3); + uint16_t* data = (uint16_t*)tib.data; + for (uint32_t ii = 0; ii < numTris; ++ii) + { + data[ii*3+0] = _start; + data[ii*3+1] = _start + ii + 1; + data[ii*3+2] = _start + ii + 2; + } + + bgfx::setIndexBuffer(&tib); + } + + static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call) + { + struct GLNVGpath* paths = &gl->paths[call->pathOffset]; + int i, npaths = call->pathCount; + + // set bindpoint for solid loc + nvgRenderSetUniforms(gl, call->uniformOffset, 0); + + for (i = 0; i < npaths; i++) + { + if (2 < paths[i].fillCount) + { + bgfx::setProgram(gl->prog); + bgfx::setState(0); + bgfx::setStencil(0 + | BGFX_STENCIL_TEST_ALWAYS + | BGFX_STENCIL_FUNC_RMASK(0xff) + | BGFX_STENCIL_OP_FAIL_S_KEEP + | BGFX_STENCIL_OP_FAIL_Z_KEEP + | BGFX_STENCIL_OP_PASS_Z_INCR + , 0 + | BGFX_STENCIL_TEST_ALWAYS + | BGFX_STENCIL_FUNC_RMASK(0xff) + | BGFX_STENCIL_OP_FAIL_S_KEEP + | BGFX_STENCIL_OP_FAIL_Z_KEEP + | BGFX_STENCIL_OP_PASS_Z_DECR + ); + bgfx::setVertexBuffer(&gl->tvb); + bgfx::setTexture(0, gl->s_tex, gl->th); + fan(paths[i].fillOffset, paths[i].fillCount); + bgfx::submit(gl->viewid); + } + } + + // Draw aliased off-pixels + nvgRenderSetUniforms(gl, call->uniformOffset + gl->fragSize, call->image); + + if (gl->edgeAntiAlias) + { + // Draw fringes + for (i = 0; i < npaths; i++) + { + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state + | BGFX_STATE_PT_TRISTRIP + ); + bgfx::setStencil(0 + | BGFX_STENCIL_TEST_EQUAL + | BGFX_STENCIL_FUNC_RMASK(0xff) + | BGFX_STENCIL_OP_FAIL_S_KEEP + | BGFX_STENCIL_OP_FAIL_Z_KEEP + | BGFX_STENCIL_OP_PASS_Z_KEEP + ); + bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::submit(gl->viewid); + } + } + + // Draw fill + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state); + bgfx::setVertexBuffer(&gl->tvb, call->vertexOffset, call->vertexCount); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::setStencil(0 + | BGFX_STENCIL_TEST_NOTEQUAL + | BGFX_STENCIL_FUNC_RMASK(0xff) + | BGFX_STENCIL_OP_FAIL_S_ZERO + | BGFX_STENCIL_OP_FAIL_Z_ZERO + | BGFX_STENCIL_OP_PASS_Z_ZERO + ); + bgfx::submit(gl->viewid); + } + + static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call) + { + struct GLNVGpath* paths = &gl->paths[call->pathOffset]; + int i, npaths = call->pathCount; + + nvgRenderSetUniforms(gl, call->uniformOffset, call->image); + + for (i = 0; i < npaths; i++) + { + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state); + bgfx::setVertexBuffer(&gl->tvb); + bgfx::setTexture(0, gl->s_tex, gl->th); + fan(paths[i].fillOffset, paths[i].fillCount); + bgfx::submit(gl->viewid); + } + + if (gl->edgeAntiAlias) + { + // Draw fringes + for (i = 0; i < npaths; i++) + { + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state + | BGFX_STATE_PT_TRISTRIP + ); + bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::submit(gl->viewid); + } + } + } + + static void glnvg__stroke(struct GLNVGcontext* gl, struct GLNVGcall* call) + { + struct GLNVGpath* paths = &gl->paths[call->pathOffset]; + int npaths = call->pathCount, i; + + nvgRenderSetUniforms(gl, call->uniformOffset, call->image); + + // Draw Strokes + for (i = 0; i < npaths; i++) + { + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state + | BGFX_STATE_PT_TRISTRIP + ); + bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::submit(gl->viewid); + } + } + + static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call) + { + if (3 <= call->vertexCount) + { + nvgRenderSetUniforms(gl, call->uniformOffset, call->image); + + bgfx::setProgram(gl->prog); + bgfx::setState(gl->state); + bgfx::setVertexBuffer(&gl->tvb, call->vertexOffset, call->vertexCount); + bgfx::setTexture(0, gl->s_tex, gl->th); + bgfx::submit(gl->viewid); + } + } + + static void nvgRenderFlush(void* _userPtr, int alphaBlend) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + + if (gl->ncalls > 0) + { + bgfx::allocTransientVertexBuffer(&gl->tvb, gl->nverts, s_nvgDecl); + + memcpy(gl->tvb.data, gl->verts, gl->nverts * sizeof(struct NVGvertex) ); + + gl->state = 0 + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + ; + + if (alphaBlend == NVG_PREMULTIPLIED_ALPHA) + { + gl->state |= BGFX_STATE_BLEND_FUNC_SEPARATE( + BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA + , BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA + ); + } + else + { + gl->state |= BGFX_STATE_BLEND_FUNC( + BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA + ); + } + + bgfx::setUniform(gl->u_viewSize, gl->view); + + for (uint32_t ii = 0, num = gl->ncalls; ii < num; ++ii) + { + struct GLNVGcall* call = &gl->calls[ii]; + switch (call->type) + { + case GLNVG_FILL: + glnvg__fill(gl, call); + break; + + case GLNVG_CONVEXFILL: + glnvg__convexFill(gl, call); + break; + + case GLNVG_STROKE: + glnvg__stroke(gl, call); + break; + + case GLNVG_TRIANGLES: + glnvg__triangles(gl, call); + break; + } + } + } + + // Reset calls + gl->nverts = 0; + gl->npaths = 0; + gl->ncalls = 0; + gl->nuniforms = 0; + } + + static int glnvg__maxVertCount(const struct 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 int glnvg__maxi(int a, int b) { return a > b ? a : b; } + + static struct GLNVGcall* glnvg__allocCall(struct GLNVGcontext* gl) + { + struct GLNVGcall* ret = NULL; + if (gl->ncalls+1 > gl->ccalls) + { + gl->ccalls = gl->ccalls == 0 ? 32 : gl->ccalls * 2; + gl->calls = (struct GLNVGcall*)realloc(gl->calls, sizeof(struct GLNVGcall) * gl->ccalls); + } + ret = &gl->calls[gl->ncalls++]; + memset(ret, 0, sizeof(struct GLNVGcall)); + return ret; + } + + static int glnvg__allocPaths(struct GLNVGcontext* gl, int n) + { + int ret = 0; + if (gl->npaths+n > gl->cpaths) + { + gl->cpaths = gl->cpaths == 0 ? glnvg__maxi(n, 32) : gl->cpaths * 2; + gl->paths = (struct GLNVGpath*)realloc(gl->paths, sizeof(struct GLNVGpath) * gl->cpaths); + } + ret = gl->npaths; + gl->npaths += n; + return ret; + } + + static int glnvg__allocVerts(struct GLNVGcontext* gl, int n) + { + int ret = 0; + if (gl->nverts+n > gl->cverts) + { + gl->cverts = gl->cverts == 0 ? glnvg__maxi(n, 256) : gl->cverts * 2; + gl->verts = (struct NVGvertex*)realloc(gl->verts, sizeof(struct NVGvertex) * gl->cverts); + } + ret = gl->nverts; + gl->nverts += n; + return ret; + } + + static int glnvg__allocFragUniforms(struct GLNVGcontext* gl, int n) + { + int ret = 0, structSize = gl->fragSize; + if (gl->nuniforms+n > gl->cuniforms) + { + gl->cuniforms = gl->cuniforms == 0 ? glnvg__maxi(n, 32) : gl->cuniforms * 2; + gl->uniforms = (unsigned char*)realloc(gl->uniforms, gl->cuniforms * structSize); + } + ret = gl->nuniforms * structSize; + gl->nuniforms += n; + return ret; + } + + static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float v) + { + vtx->x = x; + vtx->y = y; + vtx->u = u; + vtx->v = v; + } + + static void nvgRenderFill(void* _userPtr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, + const float* bounds, const struct NVGpath* paths, int npaths) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + + struct GLNVGcall* call = glnvg__allocCall(gl); + struct NVGvertex* quad; + struct GLNVGfragUniforms* frag; + int i, maxverts, offset; + + call->type = GLNVG_FILL; + call->pathOffset = glnvg__allocPaths(gl, npaths); + call->pathCount = npaths; + call->image = paint->image; + + if (npaths == 1 && paths[0].convex) + { + call->type = GLNVG_CONVEXFILL; + } + + // Allocate vertices for all the paths. + maxverts = glnvg__maxVertCount(paths, npaths) + 6; + offset = glnvg__allocVerts(gl, maxverts); + + for (i = 0; i < npaths; i++) + { + struct GLNVGpath* copy = &gl->paths[call->pathOffset + i]; + const struct NVGpath* path = &paths[i]; + memset(copy, 0, sizeof(struct GLNVGpath)); + if (path->nfill > 0) + { + copy->fillOffset = offset; + copy->fillCount = path->nfill; + memcpy(&gl->verts[offset], path->fill, sizeof(struct NVGvertex) * path->nfill); + offset += path->nfill; + } + + if (path->nstroke > 0) + { + copy->strokeOffset = offset; + copy->strokeCount = path->nstroke; + memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke); + offset += path->nstroke; + } + } + + // Quad + call->vertexOffset = offset; + call->vertexCount = 6; + quad = &gl->verts[call->vertexOffset]; + glnvg__vset(&quad[0], bounds[0], bounds[3], 0.5f, 1.0f); + glnvg__vset(&quad[1], bounds[2], bounds[3], 0.5f, 1.0f); + glnvg__vset(&quad[2], bounds[2], bounds[1], 0.5f, 1.0f); + + glnvg__vset(&quad[3], bounds[0], bounds[3], 0.5f, 1.0f); + glnvg__vset(&quad[4], bounds[2], bounds[1], 0.5f, 1.0f); + glnvg__vset(&quad[5], bounds[0], bounds[1], 0.5f, 1.0f); + + // Setup uniforms for draw calls + if (call->type == GLNVG_FILL) + { + call->uniformOffset = glnvg__allocFragUniforms(gl, 2); + // Simple shader for stencil + frag = nvg__fragUniformPtr(gl, call->uniformOffset); + memset(frag, 0, sizeof(*frag)); + frag->type = NSVG_SHADER_SIMPLE; + // Fill shader + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, fringe, fringe); + } + else + { + call->uniformOffset = glnvg__allocFragUniforms(gl, 1); + // Fill shader + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, fringe, fringe); + } + } + + static void nvgRenderStroke(void* _userPtr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe, + float strokeWidth, const struct NVGpath* paths, int npaths) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + + struct GLNVGcall* call = glnvg__allocCall(gl); + int i, maxverts, offset; + + call->type = GLNVG_STROKE; + call->pathOffset = glnvg__allocPaths(gl, npaths); + call->pathCount = npaths; + call->image = paint->image; + + // Allocate vertices for all the paths. + maxverts = glnvg__maxVertCount(paths, npaths); + offset = glnvg__allocVerts(gl, maxverts); + + for (i = 0; i < npaths; i++) + { + struct GLNVGpath* copy = &gl->paths[call->pathOffset + i]; + const struct NVGpath* path = &paths[i]; + memset(copy, 0, sizeof(struct GLNVGpath)); + if (path->nstroke) + { + copy->strokeOffset = offset; + copy->strokeCount = path->nstroke; + memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke); + offset += path->nstroke; + } + } + + // Fill shader + call->uniformOffset = glnvg__allocFragUniforms(gl, 1); + glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth, fringe); + } + + static void nvgRenderTriangles(void* _userPtr, struct NVGpaint* paint, struct NVGscissor* scissor, + const struct NVGvertex* verts, int nverts) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + struct GLNVGcall* call = glnvg__allocCall(gl); + struct GLNVGfragUniforms* frag; + + call->type = GLNVG_TRIANGLES; + call->image = paint->image; + + // Allocate vertices for all the paths. + call->vertexOffset = glnvg__allocVerts(gl, nverts); + call->vertexCount = nverts; + memcpy(&gl->verts[call->vertexOffset], verts, sizeof(struct NVGvertex) * nverts); + + // Fill shader + call->uniformOffset = glnvg__allocFragUniforms(gl, 1); + frag = nvg__fragUniformPtr(gl, call->uniformOffset); + glnvg__convertPaint(gl, frag, paint, scissor, 1.0f, 1.0f); + frag->type = NSVG_SHADER_IMG; + } + + static void nvgRenderDelete(void* _userPtr) + { + struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + + if (gl == NULL) + { + return; + } + + bgfx::destroyProgram(gl->prog); + + bgfx::destroyUniform(gl->u_scissorMat); + bgfx::destroyUniform(gl->u_paintMat); + bgfx::destroyUniform(gl->u_innerCol); + bgfx::destroyUniform(gl->u_outerCol); + bgfx::destroyUniform(gl->u_viewSize); + bgfx::destroyUniform(gl->u_scissorExtScale); + bgfx::destroyUniform(gl->u_extentRadius); + bgfx::destroyUniform(gl->u_params); + bgfx::destroyUniform(gl->s_tex); + + for (uint32_t ii = 0, num = gl->ntextures; ii < num; ++ii) + { + if (bgfx::isValid(gl->textures[ii].id) ) + { + bgfx::destroyTexture(gl->textures[ii].id); + } + } + + free(gl->textures); + + free(gl); + } + +} // namespace + +struct NVGcontext* nvgCreate(int atlasw, int atlash, int edgeaa) +{ + struct NVGparams params; + struct NVGcontext* ctx = NULL; + struct GLNVGcontext* gl = (struct GLNVGcontext*)malloc(sizeof(struct GLNVGcontext)); + if (gl == NULL) goto error; + memset(gl, 0, sizeof(struct GLNVGcontext)); + + memset(¶ms, 0, sizeof(params)); + params.renderCreate = nvgRenderCreate; + params.renderCreateTexture = nvgRenderCreateTexture; + params.renderDeleteTexture = nvgRenderDeleteTexture; + params.renderUpdateTexture = nvgRenderUpdateTexture; + params.renderGetTextureSize = nvgRenderGetTextureSize; + params.renderViewport = nvgRenderViewport; + params.renderFlush = nvgRenderFlush; + params.renderFill = nvgRenderFill; + params.renderStroke = nvgRenderStroke; + params.renderTriangles = nvgRenderTriangles; + params.renderDelete = nvgRenderDelete; + params.userPtr = gl; + params.atlasWidth = atlasw; + params.atlasHeight = atlash; + params.edgeAntiAlias = edgeaa; + + gl->edgeAntiAlias = edgeaa; + + ctx = nvgCreateInternal(¶ms); + if (ctx == NULL) goto error; + + return ctx; + +error: + // 'gl' is freed by nvgDeleteInternal. + if (ctx != NULL) + { + nvgDeleteInternal(ctx); + } + + return NULL; +} + +void nvgDelete(struct NVGcontext* ctx) +{ + nvgDeleteInternal(ctx); +} diff --git a/examples/common/nanovg/varying.def.sc b/examples/common/nanovg/varying.def.sc new file mode 100644 index 00000000..f836bcf2 --- /dev/null +++ b/examples/common/nanovg/varying.def.sc @@ -0,0 +1,5 @@ +vec2 v_position : TEXCOORD0 = vec2(0.0, 0.0); +vec2 v_texcoord0 : TEXCOORD1 = vec2(0.0, 0.0); + +vec2 a_position : POSITION; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/examples/common/nanovg/vs_nanovg_fill.bin.h b/examples/common/nanovg/vs_nanovg_fill.bin.h new file mode 100644 index 00000000..1fd465cd --- /dev/null +++ b/examples/common/nanovg/vs_nanovg_fill.bin.h @@ -0,0 +1,122 @@ +static const uint8_t vs_nanovg_fill_glsl[484] = +{ + 0x56, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x01, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH........u_vie + 0x77, 0x53, 0x69, 0x7a, 0x65, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00, 0xc4, 0x01, 0x00, 0x00, 0x61, // wSize..........a + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, // ttribute mediump + 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // vec2 a_position + 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x64, 0x69, // ;.attribute medi + 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, // ump vec2 a_texco + 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, // ord0;.varying me + 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, // diump vec2 v_pos + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x6d, // ition;.varying m + 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, // ediump vec2 v_te + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, // xcoord0;.uniform + 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x75, 0x5f, // mediump vec2 u_ + 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, // viewSize;.void m + 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x70, 0x6f, 0x73, // ain ().{. v_pos + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, // ition = a_positi + 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, // on;. v_texcoord + 0x30, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, // 0 = a_texcoord0; + 0x0a, 0x20, 0x20, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, // . mediump vec4 + 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // tmpvar_1;. tmpv + 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x7a, 0x77, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x30, // ar_1.zw = vec2(0 + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, // .0, 1.0);. tmpv + 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x28, 0x32, 0x2e, 0x30, 0x20, // ar_1.x = (((2.0 + 0x2a, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x29, 0x20, // * a_position.x) + 0x2f, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x2e, 0x78, 0x29, 0x20, // / u_viewSize.x) + 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // - 1.0);. tmpvar + 0x5f, 0x31, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x28, // _1.y = (1.0 - (( + 0x32, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, // 2.0 * a_position + 0x2e, 0x79, 0x29, 0x20, 0x2f, 0x20, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, // .y) / u_viewSize + 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, // .y));. gl_Posit + 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x3b, 0x0a, // ion = tmpvar_1;. + 0x7d, 0x0a, 0x0a, 0x00, // }... +}; +static const uint8_t vs_nanovg_fill_dx9[378] = +{ + 0x56, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x01, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH........u_vie + 0x77, 0x53, 0x69, 0x7a, 0x65, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00, 0x5c, 0x01, 0x00, 0x03, 0xfe, // wSize........... + 0xff, 0xfe, 0xff, 0x22, 0x00, 0x43, 0x54, 0x41, 0x42, 0x1c, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, // ...".CTAB....S.. + 0x00, 0x00, 0x03, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, // ................ + 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // .L...0.......... + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, // .<.......u_viewS + 0x69, 0x7a, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, // ize............. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x73, 0x5f, 0x33, 0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, // .....vs_3_0.Micr + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, // osoft (R) HLSL S + 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, // hader Compiler 9 + 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0x51, 0x00, 0x00, // .29.952.3111.Q.. + 0x05, 0x01, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, // ............?... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, // ................ + 0x90, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, // ................ + 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, // ................ + 0x80, 0x01, 0x00, 0x03, 0xe0, 0x1f, 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x80, 0x02, 0x00, 0x03, // ................ + 0xe0, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, // ................ + 0x03, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0xd0, 0x90, 0x00, 0x00, 0xd0, 0x90, 0x04, 0x00, 0x00, // ................ + 0x04, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x55, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, // .......U........ + 0xa0, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x55, 0xa0, 0x04, 0x00, 0x00, // ...........U.... + 0x04, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x55, // ...............U + 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0c, 0xe0, 0x01, 0x00, 0x64, 0xa0, 0x01, 0x00, 0x00, // ...........d.... + 0x02, 0x01, 0x00, 0x03, 0xe0, 0x00, 0x00, 0xe4, 0x90, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x03, // ................ + 0xe0, 0x01, 0x00, 0xe4, 0x90, 0xff, 0xff, 0x00, 0x00, 0x00, // .......... +}; +static const uint8_t vs_nanovg_fill_dx11[927] = +{ + 0x56, 0x53, 0x48, 0x02, 0xcf, 0xda, 0x1b, 0x94, 0x01, 0x00, 0x0a, 0x75, 0x5f, 0x76, 0x69, 0x65, // VSH........u_vie + 0x77, 0x53, 0x69, 0x7a, 0x65, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x03, 0x44, 0x58, 0x42, // wSize......p.DXB + 0x43, 0x8b, 0x9a, 0x0e, 0x46, 0x1f, 0x82, 0x67, 0x51, 0x86, 0xb5, 0x12, 0xb7, 0x89, 0xa7, 0x1e, // C...F..gQ....... + 0x1b, 0x01, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, // .....p.......4.. + 0x00, 0x04, 0x01, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0xf4, 0x02, 0x00, // .....X.......... + 0x00, 0x52, 0x44, 0x45, 0x46, 0xc8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, // .RDEF........H.. + 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x91, 0x00, // ................ + 0x00, 0x94, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....<.......... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, // .....$Globals... + 0xab, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, // .<.......`...... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........x...... + 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, // .u_viewSize..... + 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, // .............Mic + 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, // rosoft (R) HLSL + 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, // Shader Compiler + 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, // 9.29.952.3111... + 0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, // .ISGNL.......... + 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .8.............. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........A...... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, // ................ + 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, // .POSITION.TEXCOO + 0x52, 0x44, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // RD...OSGNh...... + 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // .....P.......... + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................ + 0x00, 0x03, 0x0c, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, // .............SV_ + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, // POSITION.TEXCOOR + 0x44, 0x00, 0xab, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x24, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, // D....SHDR$...@.. + 0x00, 0x49, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, // .I...Y...F. .... + 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, // ....._...2...... + 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, // ._...2.......g.. + 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, // .. ..........e.. + 0x03, 0x32, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xc2, 0x20, 0x10, // .2 ......e.... . + 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....h.......... + 0x07, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, // .2.......F...... + 0x00, 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x08, 0x32, 0x00, 0x10, // .F...........2.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, // .....F.......F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, // .............. . + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, // ..............@. + 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x22, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // ........." ..... + 0x00, 0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, // .....A........@. + 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // ....?6.... ..... + 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..@............. + 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, // ....?6...2 ..... + 0x00, 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xc2, 0x20, 0x10, // .F.......6.... . + 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x14, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, // .............>.. + 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // .STATt.......... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, // ................ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, // ............... +}; diff --git a/examples/common/nanovg/vs_nanovg_fill.sc b/examples/common/nanovg/vs_nanovg_fill.sc new file mode 100644 index 00000000..86d3345a --- /dev/null +++ b/examples/common/nanovg/vs_nanovg_fill.sc @@ -0,0 +1,11 @@ +$input a_position, a_texcoord0 +$output v_position, v_texcoord0 + +uniform vec2 u_viewSize; + +void main() +{ + v_position = a_position; + v_texcoord0 = a_texcoord0; + gl_Position = vec4(2.0*v_position.x/u_viewSize.x - 1.0, 1.0 - 2.0*v_position.y/u_viewSize.y, 0.0, 1.0); +} diff --git a/examples/makefile b/examples/makefile index ad9ce94b..f2029a6a 100644 --- a/examples/makefile +++ b/examples/makefile @@ -23,5 +23,7 @@ rebuild: @make -s --no-print-directory rebuild -C 17-drawstress @make -s --no-print-directory rebuild -C 18-ibl @make -s --no-print-directory rebuild -C 19-oit +# @make -s --no-print-directory rebuild -C 20-nanovg @make -s --no-print-directory rebuild -C common/font @make -s --no-print-directory rebuild -C common/imgui + @make -s --no-print-directory rebuild -C common/nanovg diff --git a/examples/runtime/font/entypo.ttf b/examples/runtime/font/entypo.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fc305d2a9ab50a0e4862a144ef9e4b9bf00dce4d GIT binary patch literal 35392 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 FirMxiNxRrNX8#X1F5=oA^hRozV~ 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 literal 0 HcmV?d00001 diff --git a/examples/runtime/font/roboto-bold.ttf b/examples/runtime/font/roboto-bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aaf374d2cc000c058f434f43c3b53bcaf315e2a0 GIT binary patch literal 135820 zcmdSCd3Y2>*Ed|%-P4nVER#JXkj!K!`yL2efDrZ&k^mtjBy0h~ju2J>0TGZ*L_kEs zCL)`Yh=|Iq2#6pEsECN55D^g+5fM?6p7&SP)5%QK=efV@yWT(E30*ziT~l@H>~-o? zLntA{9fd>;-E#Zp-&*v=dP3ieB&4rTxBUK{Tl)tsAc9LKA-bNu3-Y^XcMJZK5Dz1M z;MO-kKIxs`=mA6Ml1e)X*m;5eMRl{#xL<^Qdt%%Ts^f@){u#R|uUDIeO&K5r3E?t5BCcPaBOJ zE`Cm3ab1Ax(9z?k&RBQEH4fL02r)#Cn>c)^u3Om+^mm*P2fy({XH1e?i+|zy4AeJH z7&?Arx30SLgszhSf9a%&PfXo^Kjk?>H)0GS2PaJ#Imy^_C!V$3h2LBy3^zD#ojkpv z)UDm`q`3ob5OVyUJNhK#tk;>~$G_Kq;kd+M4(d4)f!)Oizi}8={{JfrR2!&NX^K4;zLS_&idSypa~KGa4kx&2#4{6=r-z-(PWT%7C$BBtQ)N>Laq_v zmt0~TjGIQ*c(;iYN8y``rCx=>VVDqYB($n8>oG%T#xo-ksKV-^U7Xn=#FE9rYLX-! zBMH)aQmp%tlOcn~rYO#&wKI)g^*n^`R zj!rn*;248rIF5EW2II&RvdL;8iA<3^Nt*OBSt13K>0&);sc%jabwR{g7fhDuT9Oi7 z2Rz$=V>7M?k>R@CWQj0{Y?PiO8M5qCXbo0mz zoiEYreTg5=K{{umlMa$TLI(OQB?8Va;(QV#t|3&|N%}~=NxHO%Op-!L2b{Y|?NIj$ z#>>7hB4dOQGEWGyY?gYEN$k7)6Y4G^W3A8G_b$RGxMw68!fE2jek1u1gYG-h5@$~w zIvl-(9V9`}lYKY`>*C26j{7XK68PvY9l;oul3eL~;v?wDJe{5lkvfx2ayA(tu0Y$A z43ox?xeWL0o+OdAVhb`?>O+deVp1*^l0m|kWSn%5JS(M<_QF_FC4`ZoLVJ=UzD6qX z`*PhE2=$|GcqXnk}qlNVl23byk78`Irg5z~vF>tHVfziU| zkTOZ8ZUOEwTG$?p7T=OZI#==x$2-G)lSBT1#Bo}H4vZGsAtYI9z(b30-izZU=_vTM zkq(SjjmK)z(Rw|G(}U4OrHf8lMrJaauyM1#|8{0$2QP3O{L>jcs`DpZ*!ZPw=#$}x z!TGiu7 znapD{B6POwOam=;lc$6Vk}qC{o*7402ph;|Lh63R@du7438`;M z$m8E}mW8*-U1=nFk@dx7RjRX8%C43w;XjsLx@RrF>Lyt_=%!k33a?pKu{umYO4Go1 z7l{w&GmMAJ9$;hok+?p!wlC(ui6xn4X?TI;zxOG06!aOx0e|iUd@{Lvn~dc37@y@pmYD8g^?Hy|tgbGR zY5~2v7PcXUB;$Ir?oX16I=;GxBul^}PqJF|PbsbrQ^WBEe*^`A_nK&VdZjuY$a(He;SR5O`p+uj-+((j4I8N#Z7Z zKwJ&kdS*ktogdQ9#%_gJdm&jOsM>1A^mAoKL$L}IZM|m!J8ox=_bRXpK zSKe17=*W1G*(B&dW|!nUq`7>H_tBE~&-!D1;H(oNznzJPGz<1{9@!_Clb!M-(BLYW z;MkXJbZ|vKEl}4HV`cmRns6HWSUz=JL5dwVf{s@Hm+B!0-C%njld9lS`o{ygcyaI5tzO@SQL0G4T%2jW1>XAIvAK3zAmNZNvPN6S&E#PW%zbM)VV z9y?JVc$a`Ds~j5|&Y%Tg^VBDjXx(ziC1}F%r<;QF9GqVSzs(_~@@mUn>6GO#mkZFB z(L?K_;cWdaqdlV)uiL~PX!5V=bzLpS-Uhyr^{l@~JmkxyIpZm*CCP>@C}2ke4m4b7 z`VzduXltcE^9gj?7?^A``Z6Bld~lBR63a+$#(!+g4QG+`27bFh-%gP)kRrJ+>7)xK zvCSzqW9E2(U!&>J zre{qj{{3v(CH1zn{`>uZv8_#Tto=^I@xPxfQ>Av6jDLI1^#N=l&PyR16PPSBJpKJ_ z`5dw|=a{yr;83%imD;1H&Xsf083Q2=+IRO5+2Yl2*`36~m z-*=IUNjKd!GD3Vn{2h+LUv(vA;I*}kC-vhFOc@qb>byiNPzx7IKCzUY>W;uWS~PTY+Z!q zH8Gn^5f_kBaR}tDHyJ7o1uw^f{{!H+zX)6N0`3(%z%X;^*+Up$o*rc(w{h5d4t{=&2}t{||kX0(+);++k@eS z9k%e}yTdn}x3eV1KN=5VT%3pSTvtZ|k=gQE%mt=fZt6qHQ?e78s#^e_T?AboLR{FP zUxGR_$vFM9jdkIBEP+2ZNqQ3J_V5|3_DA|jwLkJE!1WINp%U1%pJ7WzlA*d7z+j!v z$nL6L)P4tlagnqJxYPR9&KMK_LzF^K^?DlVL-7e?1$E(NL*W`EYu{bs*;ALGV1FZ} zj?|Y%$FWB(DK)ml9V3ot8eqf+ca8BhJ{~`yE%ZUItQuu^BXP8#{*-#KJCrt8PbhH@ zAN(X9J+KeDz$cpDW(B&jepnCagO}*VdbcHNu)jd98b6~N`*T6(tg8CQL5U8=SlAy1 z?1Bm|tjQq$$6#fD_8&)M;~&Nz9~~FZ{s4FqM;*SfpCk(QKcmek)v;T_I6^6nbKxMn z_y)NIqZ#%jKAOhz{^E_X)aZ6++aWT_Z+G0SNNbg{&7KD>Nh~Z z{uzU5BEwHhUtZl^0yfo0yqdEy*ci`%b>x?f@bU3U_#Fq7-(yeFJeqX}dT`;35d(cP z`yT9%`-~enVre3$fl5LCV^(l%8dWAhLx6x|pZ(mY6^+HofP;UbG{6_^xCB-~ns3Jf#{O1=0ECs!Jl zfNw7GEvX-8UJ=+n;L|)(*HEM32^Sa2e!!RmAD!qevNK0z2>XT)`ZYRWJoqr|^G|GW z6waDVsmxCB5v@lHLiyzx++p8Z5J@!SyqC-;GKnEBWGM4~;P3 zAl=t_2GYQeflmki8Pvzv%;;?l1ebT6pN+aVgb}H#7MRP+AZ{TK>L^A$Dus| zXfFX;(g5uuK)X`hE`ADViR3GVNUfzTsh3nHl}l5k`O*?;g|t_CPx?^0CH)pi0y_lG z58MK1iP6*O3vmkrv`NM`4bW}}w0rEJ9c+cx-3Hnb99jx!>ns+_@0RZ@M=fT{cFQ`; zKueA#&C*9HV%qgD<9G?jIvgwO zSD>7OqY}r&8w+oAyP^N?=kGSw-m1M`d#(1{+N-q}YCo?%Tl-1viQ4tGD{3ohN7s(5 zb*UxSmFvGu>v4MA$l1P$BGD#t+B#oq#)}#%|AZgpd&q8Ru6^WnvY(hqHF<-)Ne+;M>C| zDBhXEUxFe^WD!|T7LpZY8CgYEljq1v@&bWOleJ_Md6~RKexrG`kW8ipv_Bm{X3;@( zAk8bxf9-mc^Qd7&DDB#hS$!W42ig z%g!qd8Dv~$T-Ia6GGn%J^w1GzDU6@-VC1qv@kTSrFC2ripwMK_92C&-b>yHy8L?)G zHG^NE_Od}}pu*Y!&iqzy zlr+7OX?p`0=z56G&qY%>g_r`^jSy3a2@np-iZwgN^vW;n3J^^I(J98 zR<|Ts0dHgaeJcz1oukc=mm2CQM3c8@a#X0lfjC6JC3H--eiOT-#|C+@ds22A>o;AW zj)@`O?4I1CU3{6u%e>@l_#>|eGk@=2kup|0+&;3+&u6A_fUA@X(=mSXN83o zeZ5fS94o3=5#+_1Vnvk?p8mp$jy`x$%8GNWu&^S?2UYN3T1{V8Ok_o=A1cpd#VS_3 z&x#;FRPM_PH$POtC4R;V+`}kYfyw~QAC)_@Vje3dTEAfk{;W$BO!-EU>(Ds6p_A4^ zen&&TcjK3giEl?BA5HFfv&}_%U!Ry8Qluq*0>#VJMZ?u;A4n1 z3@}`AZ|Ab-4wb%^mypSu)wgnVXMQog&hbx5q3H3Uii`Q zv*Fjm??*@xei2a-?ILm_Mns&AxE66gQi}9}lieDN&1})G*9}^yv z6q6M*AZB#TteE97n`6u|M`JF<+>WV>b&Z`Hdo%V?oKswjxVX5?xV*R_aTRfM;x@$X zh%?6>jk^$cJD$Y%jvo>~DSmPMrudrplku10ZzUuoOh}lYuqI(w!g~ql6KWG4B^D&s zBpy$^n0PDkuOvfKXwu%~oaD0PDalKcHz%8uk0xJ8zM1?e#VN%nB{(G|B|D`!WlGAT zl(i`rQqxkqrxvA-OP!m#I(1v>q13afH&P#^Noj_(;Ix#q?6ktP32F1w)}-x7JD7Gd z?Q*(P`l9sO)~#DFXnnEutu~~MUz?~l?b_tDDQh#O&7w93+nj9kAR{ThsRAwzX}4Y8Toruid0}i`yM(_gTBk?S5*fv^TU5ZlBUVyZw;%R)^jl3OX$6u)M?C4wpOBcJ%1z-?6;ogpQRRYdhY~%*x!6`A+8f%-YNc zo#ak_o#Hxe>+IDzxAVa+#x8Ta9M6i%D$W{_bv)}#)`hO!yXJP?()CexLH4ff3*CIW z&F}W0dtUcL-OqNf?f#&L+{3TOoF3PD=JYJfdyVKdtJi{FcY7E09@l$r z@72A}_P*FByiZ)8v_2jB?C6w$4Qd6_m%sW^*x%~ zIyWzS9Aw;*p>-o<<=-#OnaKPP`p{$~Y&1(gMd`iJ&k z+y7?&M+2M(tQ@dqpwmE)f&K#%2DTo!rBEmwS2(wDb>X(c+CiCvRt~yYlvK2`sBZAE z!8eOX6xWsPDA`+bprmey$B@7wQA0MCI+PZaZZ5r0T341(*1fE3Xu;6qLoW}#H!Nq^ zjA6Tm-5VY^JY#tF@J++-jVKs#V8oFTXGZ#uTr_g^$W0@6jNCi&L3z9K?&SsLo6B#O z-!E52<&D}o>ei^b(G{a_j=nqkuQBqNvN7+BIWgw5G2e{2J?3GBP~lY3q9U#$tD>-? ztYUP}{dnrdskKw@P9xJiriD&Ro7R0=(X>g^7EfC85 zP5Y@*sPw6fsm!b#P+3tqzj9sW-pV7D7b|a1C)2&AM@{cAy#1g->r z3pMME>o%?1zwXw0uk{_)k6!=IhNunWHk^4e<;98@Z*J_paplI_FXg?o|E0T|CTx1| zWuKQbUtaR^?aiY%Z`^!l^M%cis#;VfRCTT@s4B0TQMJ5kTh%*NC#o)0-L9(JV%QSA zC1p$Ymf|fFw#?tMX3LH(2e*8@<;s@3Tgg_ht>If+Z|%8tz}C@QXKh`+b@Nv9)}vc5 zY`wYl{x)fw&$h^I8QXHV4cj(#+p=w&w(Z*X&bBk#YPUVu?zG*wJz;z2?S}D#JA@ssJB&Nhc68rSv}4?kxjWYG*s`N$$MGE(cii4l_loN){;$k` z<-*SJo$GeqdUe37D_=dcD{$AaT?b!_du`5Zw|0-%eSc5qJsbBt+&f_Jm3_1J-P~Wc zfA9XIuUDGm%zLY&suxvXsVS)0UGv}#@`m#pes6@nQTfKn1Ca;jylHrI%bR=OJoM)A zH_yLW`{sj#IR`f#+;MR4!J`K+9=vr>dCLpl!D7spcf)rOF=tD}yryfRS%?p)77QH* z@e2tTk`pfUW~b=FO95AKTlBmnENG3I_2<#9KEyp)E&R&o-=x_nbPj(C&dSdySld|Ll9mJR z0L&fd0it-b9M5}jL8C4j^aflQvbfOph}6@rTpjHJdt#L?ZOjoIH&Ez(Bt0kt!Oz1qv> zW{AOTJZ}y$R7W@7#5hvIBf`T|Q_|8?lf8X>^m%Bu#!^6|l zOeXo{PJLx`II0k-wiDoP%vov)h{j{s(SZQKZCN-aO>p3{AZXh8sG{^^+6 zR}ypUcyoqIRZcr?#NilmIHMi-#!2IwYImt|(4wK*&*m~5l+)^&!wuE3HqU|#)hUga z35lL5X~{`G-WYC3aCmAmA8Kl`TFqwbUWd-pum zXTk10PqpdSt7D%w{ra_e)JvMu3)0!%a!1z!_%R_O(graB&ct?n5Cp6QHD&Lb7D1dT zS{Tgk=gk;va3jHM64Yl226H&)ko3l991rQ785lM|dp%7{13F~Auig|P1396(q_lLZ zml=PEV3Bk@=V)rb;OVR`m)@-UXjuOe>J=J!IV=0Tpd9Yg|G=oribC(CRwODHJd?vF zxI{+}XdTg`ZKrIyq;gM5@rJ(p&V9Ii*tYhamG{~$&slb>=z(rfdiwXefB;(Tk}x=K z&=cZQ(Sy@lhxU$5${EOIBT2kR{V>l#cCx*O0XvIKi7@@4Yo>fJMDqG`ln%nHa&JVV z9En+sH@n1Rs0Nar>?;fI-Ubg}eMmTQpF_y74qjK6)2M*3llaJE& zLWc5G{pY!>h9P>G?@x2-+rwAp)_u3e_5@YI=VRUmHUB<@W zQTdE+C4ceApIHJz!=MjSO>}G3v25DHMfs3s-C*@5Q$=`1_!is@S^@WVh9uP_yi$Kg zNTJGgR(Cau127{ZqJ(_#1nf;1dpB5$ghUenqX)RzL3PW0%R(^}I1>?PG!qqPnlVdA z)S0M>x+*sWAKKzcITkjg)N)5^ZPht#)n1&?i<72j8Vm+3f_tNEK{p&PZ`oqzG(sM{@CU}DL)??&KnLh_8gv>$Y9t+DdS8mS)%z-PQp1El zlqgP)x(?SJJ++uMk+P9H;GG7eB0 zZyNjpz^{qAXE6LBZ4|=Zyl1mhI*-bFdaEoZt{Zafs`ATMKPcbOo`?HQ33_sL(fA3v z4}$_P`ucuk)+J{scfP!$)Y3N88;J~oG_O8BC3fh(cV3w`6CrwvH4P$l0zI6u?!mdd z8K7^b4W)q{n%N5{Ve}USQEy83@JKhMnxsy*_k_7BS6qXy9jo`k`p!A!t`e?PuU$(! z3C*uV%|cTS2JYGccfMGAiO1Rn?=Kep#cCqvjSFwBbIzCykFj=$t8oj6W%>eQCvsQ9 zWP?<11ESmwz8QdoZqVe4Ih$55LxTIMdYjC-wD~UiKQVIZV&(4DZo3ZIe(54 zMVT_Vc;cjz!IMlSeRGQj_v<@YiW|QxKJnnRkH7lrs6kyn>=VdV<&WayK%!3+j>;6d{82(%sUcNk;e>c z0HXjuG9ul_#}n?7Rl#`q2o6s?m-tN1=^v@r7vEAJ<=DzfHTI}L2J9kvhc@ZSU+BCP7$dQBN0`}3f zQXGd>I82EW67hTr?DGXYkH8Zuj-xVh!-gR|7w{bXmPWdYYhgw7%ootbS4)l5szD+m z2n(Wl>)dH7@;LH^PIcSFAwsx(TDeCjen%%L_n^m?(B6`Rcnut-2OKp-FJh6vPFt9P zI-8c!BzV-F@u@@Id~rTIgva04kNX~jqGUQ?`c{JprcGx96V+f!4RePGxeFiE9~4K| zZ4g4`v(!ad^PTb>bp=ewqZiL{8V6$K@9);GVGh``!R={qNou5jw1Dnh+e*w1VgO8~ zS&asq;&2!Z?kdA2_QbdlW$!n$TmPX&Jx5U(KO{7qzh-%1Qu}a0xs2S6&C3^*WGv1v z9$na9K62)}WAiTch%e1ohG91vU{6%q%Ae_$!SZ(@6NuR@-kcb3j#jy}K?s=z)SMK% z2~VP-ID{IcJJr%)-JI>%E%){MytN1)?rl9~Jt{)?{aRqGF8cU_n=?XMRXzE^jL9fli7N3D2?%rYd&$RKrbuD z3;X8f-94_*q?9zN{#a@Dl`dihm`ER^e^+Q*BUYU`N7@-$KlJFQ zDPGONGy55;-MH7wLliX*ZhlPHLb?o%LcvUPP~&AnVzRr*$lWki)lzqmjH#b6tDh6H zg#Lu=9pl*Yg$tFR>XqN9%hXw;Cn;Ayn>Kge+><)<$&W@>MYcFJ^V2VdMN09=;bSL% zTvj}?46<1Q-T5`-swHOW|FeDaY=p=x8LIsoFTrNMK8%@|hQz5M*r55%p9_-mmGYPJ zr*ep9QbJv6f+Q$6maSR1aoe(`3+XTN9pz^%VmpBVjmrz@1YgXbiK>8ZT8;5=;(>Npxq}V`yALA0R2ONZG0Ue*S}( zYieHBnUy`t@4qS!lzq~dxnBY_2Bh>t7K*s0$FktM4QX7UnBu*L3FV${L0b6_%+SA6DO=D-sQs zf0hI2iYBngO*>b+mt5;ND_6vy>RSuLgp&I0tlx=hzsx_o34SqZIQX|&77MgtuI16# z1Dk8vOg3tQL?_1kLGjgrjg??_WeKXt%1Q`Oa2@2WvQj#?F*iFYKYynDuI#5>!Awpx zKopdp9Tv@7ykqz3@;OFD5yC$ju$cA+FC`#vua8pyxjglmbK8}(JI_T0QP+=E{OL@b zmR4(Ghd(=7+KsS*&zOd3pfWIPLsoUZrbbiUk?qC2b~dpU@@R;P&ia+Y6cwKvLCp66 zhX@JeJf%%?`GwY-+9G|AwSvlkKLd1d!B>OkSMsVF`|-&o({_&M%{oK1i!FY^WA@V^ z;WiBcLNT$0uij!pNx#WDbDi$;ih#Gk0dj!XV=_@a<5LR3 z;(U5Q=8W1~MjZS*S{DdT2&Ce5h93d3>pQvt$Uckf{{M`zm>ML!NsL7ofRNm;%5RF9 z_C+$b8?3>V-7mbbW9Qm+yM+GG$lK@;>P%%Q>{4Z`^1HD6@>hG5NBb^c-p65NI{F7- z$_aL&12Cle1$MOKc7v14&NeXhWTUM>EryvS!h!~2R)cGzdzC9f)?;c^u02++QRA$+ zPtI1Z35NQ6In3wDH;sb zzKsF`Sa`5DjC*NT)%Z8W4aoiVedVvTsU7|edyB5;|FlW*^!|4YayzT@0RH?jhs^um z@CV-afS2Q8MW)T{yT*wGuyFvVHc@H~rHGq zkMx^9PPtt-d*;ka#Uf}#*Z8*N;dEd7nGM!hT==xtHcHsiU^bmMw=`6T*%1Y6ETN&PDJ;O$ z;PY4)SZo7L;>PJOD0PS%CjNYn#_0s*`)6iNo4<6|uaA_k?%!25Gqqc_a{634r=UEx z*V#AT_|EdKJo3rW{d$(BcDeG#yO(~yDleEhjE}7a_`4GH(QA6&&QvvMTPRpNQ_p5N zO!KfQTBR}qal~?|NILg8Q98$j8ySv}Z3ndLjv3_Nb)TI|*Q{O>v*PZ>e7{t5qDE5O zbq>m5IDLESaAAXJW-didezG3#1p)4Y#Y-V(09YiqMZ)6>zj|3 zu^VM0@=Z=>E<0>RrHAZJ+tU=qUAdrm&=k6`ZyzcCuUxcBk)KNB$N1)^>2*6BYo{}L zbWGEx+CVuzI2f#F%oq@0cjW;)2R4NSAjzH#j1UHjr!P&`ImqW}OJy$<+3zwOm0y)T zH1JcIx_?PO7H|HQD}GSd5!eWz;!TG8AdFuR_?jW(mG@=m+1kNp2a+C~tY@4o>$xWd z)y@M)07LsHEX6dxK*^=2lq%&1{OzId;wn$vD@gTm^}&Km{cplI0?WImu%Rj(j>yC1 zaMWcl*`_<%I*YrJgB$e79V?ht;k4I((|^xS`7hCP*qBE0E-;pF2lg#-0{B;RY- zHc08$t$y=##VoYK{%bw71B(<%@hp~MCo6XP0K~=06Z6M~Rx4I0IkZN1?9UG`>F)r3 z0c#WsK{vieA*dQ&bHflR1v3cvSEhWcGynNH>btKAj930GPO)X*KDtr^s${WaVmZI6JN~%d*RX0Uk`SsU~ANoj#g&w*SSdYs9 zxD4c)QbJ2=US~xRp_6Oov2Pt&;fBJ@!xSv9;GmlnB*jZ&2}2)EHwis{R(=&|s&tr2 zGI|wAI&`!f_NE$<=end}RjfHUy16TajJZ_}vd%6vPx!z*msKu8Nlm;9oqV9LOR0-6 zxyIrG0N!UsDJ$@(#N6C&nWx6fr8#3$s72doCL(@ejgxV>L*dp?2|}64$<_d0SVTBq zMTT1QMMy9`RSj$kcMQI|*yqc4ANu{y_PpF~eUzJ2U-!w;`@YTVKkYNadwWS)_prR^ zzN24XU-kNcoB>_iQ+eq}A0AXX^cmy&rOzu4P?XIQ+=-qu-C@59RymV&B zibS8kXh{6R{%0>KS4$>k4G9P+?K-&#YjMgqeS0sK{pw%ul&zdn>NmgLCRIsGOsTTU zR0qo)@jhsY6lRqlxeu%Xtifm}WKf(4E+fS3$x3@)hs9k@zCH-N5;z8kyf$Vpz+n*5 za)wYxQL_B!zVa8<-9Py|LJ1Fx`%Nt^Jw3R$yyGfOx)=BhO}X)oTrly#%E0HUIgYyk z#~$`L=GsQXF-NNga>E*lop=Ag;Mmi^!)w5B2#>c3scLRTy1P1q?Q->0zXe$5ee9R~ zY|%$oX-L_)jzaikPsK!IW=L4=>Mg6m6W zHmq0K(ZUld!L#Ww8H3wSAn#%Es^*9T(@6MsAl{*)19U_JyRn5mA`Wzl8LL@tHZp>Q zALRe|zJwE;U53v!KjiwP5!`f%kuwPbg$41VJiD_U$POCAn*DOE7Q?u9H`Ts`= z;=^WxV-mz?J?sKwakd=`g6=HL4w2zYMCw#@Me^FB*FI3L3@U6_9LQ#)Vs+2_>v!ts z3XA5BiH@lI0T2kt6C-pxzOglmbQ>$EaSAsc8fcnyK>wR{+WLSRQ(+!4-OjpUhm=7@ zm_Atc%}Ou22kpCIwAKilomR6OI`_&zSKCmd*#l`hT3>TFm8|U9PlLjeY(=aLH@#go=IXHeR%lQMOVHDfQIsPXB|3d(ieGJCWie(Oj zHe#-HHC$+(6eq@i8-s!S0x#}HE<;QA$23pbNmnV=^h2y=_|-j2*DF5t%(rf&gKhju z14Bc+ifa|m7yy2UvB+~EH(}T%#o^-MYY=mvSGx#1aV^K$2 zd19;9l&|>usAVI+dD-(Go#&kL@~F{k!;`j*+w!(@CAV*f!2yDDH8;2Ipq9#2DPvVm z|KgH?!>-oWPZn0sE=y1J3~;S)Bdne=JhoNc9qino1WS^VKgQJ{BX;AmQ)ZfB=w7wY=UJ!(*X{pFtW zD-9Vvb@G^sDU-(t5%+1Ta^^Sh2g)Zj`N7&Z4m|I@`run|H{t6jWgI3OU&qe9;f{|+ zY_3H#eaS&*82VrAu+`TAnoJyZ9)I(7zWJ#CqIl&hLSG5b6rK7;xl%r+b4frzNmj*h zYPqLe>Da#hPu=DDaOqB1$cyi#B`M)?2|HIZy#Re*#{E_XKZ}om@$7JFr|h*OIf&}Rghs$$EIz)fN?2WI*%^%Y9Y2+7!l(`#HE zTf%ui(9AW!6%P?>cW?AiYJzzb=YSOK6^w^0MAP^X0BdQmwqB$)L<0wtCBSlBEWBMZ z_sFq3AD;Ui;hCHHx!wBpUvTp1U!PohEDN-mIBsCS{xm8fJ0Rl4Maz#JT`PCW>zb03 z**x;4C2QXPdbvC>Clh0JwA>Na=(@m{>8FmB&*L?e^4tsUq9ICbpM}GGVVeaZ7)<6M zdoc}$Noa_55ri$)BA=CcE$;O6!GkF=z9ygMF$Ib1w{PC8>!SSeN&QzH({%FZZf-jd z2$7#qN7a6?+#o+_h6dea$E@5+Yw$G)8)I;;wV32Jwcjir$pEp2d=Nx-4-s`q8%ON< zfQIDeWREb?&_6fzFaG)mVMYDq%2BZ~qUU2Z=3{`K)B_g#n2*-I9b-1|q89Vv!4?z! z!&COEp^3_BTUbyi5h!Mi8k58ac&;t1ax}*4NAM?@Lx3e#H`iHA)HdZ$91`TZ+ z^U-4YEarn`aS>4;Po#-UE#(!|L;3l^Df!fISk3fUC4YR3E)?E+d_q`MKS#=_?V7Ot^^jc|ir-bs5Z@6dkA zTh-OdL7d;F-Gy3OSpQ@FRXR#}Q3w%yRXB9;UEKkPx8~2;X)>NNqrt&30Zmrp>EOk> z_JmqE-^8N^lln4HI8#`CoOBkTd+02m!}@uTxXqixI>rXO1Uh%m@eWqz(+ql|onU?( zIGBadK`OY zU{TS)SB|yrpFOCkXi#>4WkdSCJ*S6HI5i%rK)9Sdw+sf{zs8F!af?pG(YU<-Yu$T0a=@PPKtIFy8DFU+rrHuin>(!wVw_d(Bg` zFkfSIVQ?mU!+tZcgZpO}4;fON-M{tGodb%C2kbohF^6wUZ0y!C48E7sf7x?-Vp6(&yl-j#`re7XVv>3a54V2ZF*_!*yqo{FFS~S(jTqen_IIVSjMjiRnBR{G zo)uGEMKA_wh(MWn7L3(uu|OIQ#L=vNzOqbw`ys`on{>A{6BS)J-dA9aU2w-<<2B7$ zw&gWUkDyWit2Kwk%5rqRu>ejohhW-W?=y(7>Y^RccGjCT&0jcOEtOQ{wz)ih{_;uJJ*R07kc;4S>5K^HRqj$!>(Wa?B2I;$z_A5 zjk|aqw9K`9uj?%R%Ci;Yh}l~mk!E_TBO006jJ(6x#!HqYz${OMK0?hnOpi!c-DKZ% zU!IT1wl+{LqZ0u;DWT7y5hLI3_0)=I5|dk}u3oXSXZ6ssnqI3{u1#*89RKXfx|w(P z?*8SM-Fxqj?a--H`$eml_I_j7$aiv{U;SKqyY{WuKDR#Str0`3d#!j*nEke5IrNr- z_h^HEd_a@4kXv88`GG5GUra-MHG*go%%AXtM3|NuPlFg;LtK0zo;CA4K`CfcFKw#G z;^?^6pJyB9OPKV4QYhUTD)4+I7Gg(OTK!7}d$T{N|A{i*p_QpDc%U4nSy+F$qU@vj zIGQO7XeTijOXz7QC!D->3x)78XfO|Y=V`8Y^q7k=dBRd9RVl&Q2}7yD3xi4yxFO$4 zz$BI}TQe7M9+eS*la>2oK;8G^Nr5fM3uK6rENudhCga^5h*h!O2-@6?wdCsO6s=J_&0hiKv*WB_vb~~9PS=nUIld6TS*$oY8$<}>PEH(A- zD|KN!XRQ`mT5(CewQx&k}}`jJ7`%< z(u!ewKmF#UT=>MmF1`9BWWH-~@@eMNGa)xW#mS3(=~e{%ZIW(?8?E#}1}By$U}xce zG;Y}wm^TPw^Jx7>ww{LN6_nDAGiT0#1|k`NwY*y0ari*3@P-xeC0aqy(4f+SCj@H@ znhb7D22UPf0eghZ42Tjk1?SnoZRp#-;R1XJ>?dP2wBc5)!5pDo05Bf6Wed72vZL3B zsJXw);J{plsk7hxA`IdBzh<^UI!A9x3bT z807uvnYW|-N!wC0UXb*ma-6N+@Hwb(Ky(3*vb6`~V`8(RbyE&seqd}mPe#zNqm1z3 z>+GA+T1;U9ByyfDI85d%3_O^mX7bsrFf`s}ImKa(m%z_ItuRFV%L+rWgOg~Qm@|FB zYulE#ZPU5?D^%XSeDTZ9uF5mXPm5iUp(5?!`N`IOKY~o)!DD4eE-I}8?1b`3y4Cds9XTg5SOmj3hn4`~|vF)R+_JoB*8(9h8 zS*kW?G3t&nsA;@b=gd3A>bylTb_8#R3~0(#vut^e9$rtIuiu~1IwMu@^pd00rT6A% zx(&}6xxRCTzD)d0os~GB;yjP~iBUty^{SHhA}oO6!)jxLxb+EKamm=PXXt zRYO{Vdji}yrueGjEl#Wt6Ta3tzXCKvFU%Ep2rq$W8J-Io^eVTNjA4&B0%^n%!Tx#d z+a&hw9{ZNb3IhtJTiqI2kvWZ=RgmEjul(XHN!Sk>v~Vt}YPp@#q392%Kn4Zf)oB*h0)mD4)jz zX4Np+wGRiwoH5J7eKnNAtF)W)wuLBf&_3|hT$b4EEir9 zuIWBPzDi$iy_mJpwn5e0V=I$Jwor*sWl7C^R;at7svY_EICY;ecu?I6<==Rd6Cq5? z2=@-LiYP1$);)x4^=oKqyO8+A^wy^Yxq9vD&10V&FVG_4rI+fGy0nT&Z5JJQU?qe-A3U7Kb`>V3SC!U~QwcOaR+0_8Qtmbup5U|uA@CLDO^H|ZB z6~FjnG~cpsM)vI|lS5EK<31^sS`!m_DbR8W*K zrRLixT5^!x?-(UcHn-B`>7cpQkyhth@wHo3NH9~d89&QG=1h`q-B8QKD3xyL(5_8- za+{NaY+k&fx?B6~UT50U+@Z^{vdF1Tr6VeAa_bbhsH0R05 za#VamOj6p@3`gUz-dw@gn^U2Vm`bYYC;+P%b&|L<6 z?P0W$*od4pYYd%(q$y3C7`i(P!6F`uyums7KPvT9{ExWNNwxe#y=5K?f^7{Si#gv+fu)*%s`DI(J8 z;AWWv-rA*4ZkL%8B)4gnmpgX;)>cuiOuCh5J4bktZh^ki@mvy>-+3^DX)7ZW$@xqg zxrB1zwAuOC$iTpE2*O-pbj#=SXrAz*P+7%e7Xqmi-VmeFK8tN*&kx=iz=+hK4_|je z&^6=)(|2h0})qh?u?4MUSD8FE! zRJr!uch^pP;qA9y=s#*y|7rQ7N9V)dmXr13TJa$4tplb9c%K_Z;FgQIUt@M0V zqo=IlnD5oFsZ&XdHF`Fw!|2J|0X;`*^lVax(Ms*Bf^<@8e&8$8rR9w&@vMyd9cnNmt==aM0SZypB5i^b9Vw zuL=tS35+jz9Yki$x(2>Lh*7eDFPN?@Q*{idw#F283a5c7un%{}ig%=kbNOzmchc~#)=5V@YMn~F z-E}gPOJmbI1GPHfhvRe%ujA09odpeb3dtvUbp+Z8YFZ~)s{{GoLZ>j=m{=XNiA|!p ze8Wy=l5^r8(hB&^m{U+F)V<1i z>Y;iX7jM+U> z&uvn+%~5~@FGVo%^f4A~V^ek{%A_YVe*iHyUtdgWSxy{6oDmUJjp?ds{C!uq&s{Zr z^kkOGKLS}Cs}}U_UpFEsP^K56CS|>_Lzv;(OjbIY^5V7Req+$mGx_x!)cpR`gq7ds zUwcaVtLMBJyZ|IN>8m}l1wpi~-pBXyKJW(5S>|+aZKZoNmF}K;M~&`H>r~PsY8{`Z zb(p;Ic0l)2s=WC)G--#)o7z_ec}0~sUseYJEwiUeQ^3XZXgOTiDhPX1NtdgAx?1~$ zu3iM0tb$BB!z;zR0uU#&2Hm*)X;!zv>BLORCM$r=AN}`AM9+q|LEkYM=U25xze5Hm6k35zfkfF)&@_@VTh?)vt77S(DFDM zvJ)5=HSC{&CAU=o&Q=~OA7p04kP#mFPyqcg>Mhs9ZO?w ze$}rkB0XYCr``jU3*(D2dY4LlY9GFD9(OFOwetP){~QkV|JKLUyHhvnva;x8udJeH zrU885oadA3E`vT<7>-Q3jP+tt8SBuTbHYE=VRSL#9mc2?Z>^=ZBNMG1n%ByM)kqMV zwj)P3)G16#;;lF~t)n}w)gcwS0Hy&FSRHeM!5quDrJ=t*)_QupzxOouOQU8ggUOtV zK!?g#km)$f9eD-T(&O-^iO%F3f|M66a>ZX5q|Ipl`z+eN2xR?NnX@(ThromG8-nUV zA((uwV&5#dcc3(6A~vVV;k&LWu zTV|oeCb_sg)^DGXXp@;swcJGMo2O27X?ObBBcCe2y_wguUom^fhvh=~uD0#B55I7~ zzEY6p%qgCe)2GA5x|cHMhP^Rte7+c5Iz%tfivHgHdS?xK^X00&ZTk-H)!IW|eK;LE zqLoLro8?JQN47eY(Bo|TD05-Qwq1n-v&ZOK3_(64=-EL@VY#rNXEqp<`79l{&%$#! zb=PpeyUL&A{Ta`g9Q2L+XM%B zD%25m%%KS0s=Q}GFqH1+F#U#a@QW=Y)&6u1eg@N1!UE36td2}7{dBB9%@bi`w(Lcn zmAaqNA8!Z#N(dljwZsO0Mca5jAaz$OGD-loV5u5CtZbdd&lv= zlw-8{`C91PSSf!+`jW{NvZ00ZWzR10<0n5J^})Kzh?LDwO+xYwurU_;-kpfeARsm?Wj%f@>6GVKS|mG!_TTOM@$uas0iXze zeFC{;@7w!0+^x|xp_X}C-NeViw7;p3!}HuUw}!I~m?eZcJjkiF_i;qk$6?uTNhLAa zTSt|aBLyy@FtXd$Q6tA7V&NfE$+MO3F5A1y*j7H9wn*_=CQBRF4OeQNK zji8ZBV?03hOR7;v^-Crj@gGIQFR}F%csu&hT08JPPt!xJmQ7rNw+pW z6Pmm_D}}lYomp*%=;=T)jmvSmQYf|JHVH7W`$8DM&)@x^XLBOVuQ@%ps&k@XeKSqp z@Vy;eC&8ZaI-aV&33hPP>Zt9oc@u93{_}2i-W2R$-wxMFtR3)S3$BxbMYRy8_~|K|2>8n(Lbc;nt1>GYf{KtTAB|PW_uzRdtJPHsCby!gwz0Y8+@XDb{4Y zAr7JXZ%o!zA8&Fnmvs~KyEGYPJT;!nI&TNEzCn|9`*!3AtsPo0WIE$I?!Vc$lY}~I zJN*$E;2Ob&#idXS`bmZ7S8F?Z$ja}?2S7_2M5wa_x&iMrQQKjQQLX4p`8Nq4gG}o*0dd_JJogyMq72KjjyA&!*q`d zPk%a1)jd3BqmGNi!*$R9;qJZTt0=zy@jJVF_XZM3LP$a&5JEx%1Pl;D01-m(y+i1T zbO<7%fHYAMsUl4UMMM;k5COZ`#U6VDr72*+-bn7``#xuO_wI(^^Lf6{^Zott`}pF1 zvNx02Gc#w-oH^xvs2`foQYCvDSy~h3XS@t2d=$GMAbEZuZ^vnRsBv0u8tzH=r%@sZ z#4y^b@!e<970?HWroL@Ndy|kZhxvy6i)<6H?&F>PeP1fuM3n1{$C^|NbU>RPR+~uB z7UnCg7NaZ1(;$(2{_U_g#K3>N(y`ZbOtNhTWLJZ2dEhWO`@xBWrOnKS0SaSUgq)Vb zO!@%!(?~Lf`ijW99~TNEpvWGCZnBT0P%txle>t`#X%Qe82{mQz zT!oubvP$b8e9Snox448LR19OUK!GeFf@@yGWQtNCZ5hoWpK7314@DplrHsI2OD87V z)(ahP1~ucM(tvg#=%6sO21zISsV&7I09w*5onYf|8D4PVB}oO9APy=4B+}*iOqNX2 zwqEq6HLYGPQZE`W%AdWtO~#9dckTplls;Z z&qrvpg5{Q?XJF|RCAaLGAZUI8ZRVKKc0XcZ>0sYj>L<+U$5&qt6<@HtK|iQTHRKbu z7b@fXqh>YyZBO<6GwS;dSlpKaB9t?+-NrQtW+rnF}1U(}{*NMBkZ;|WU#{ai(DAR~6myO8~Rq;Zwp zDt)WykP=l`N`S^$vKr-lp>1!g?O?gFytbH!CD;QSF|>cl53?u5*qV#*-0;5P zG;auBQ?h!7tVa2Pc7J+0Q25lmRmiQ-w*s|AP>gEJ^!W=z{b~)2owg3gCRhkU655~v z`EJ@@%o|K6XgC_u_jpzb44qex#ho{Guv5pV% ziu6FOBR>++K=?!I?bf@W0KUTUTW`giS7pAO3GA`!GG5L=8Ec+*bqc+j2+ivA9%dqod5&)`&>wQ2nDBr zaAfGyZMRI~YPN$K<6|T*mT?3VsMYSk(%InbmPi_S``Zp%s37b zhpmqsBB2~(q)%pVAG_;GB;JDbxTZB)wdvO{cU*1CqukPO#D`~t?TGl3ra8F3_WYc& znGH%VLaZ_$DnDWX>(i8ZEZ_GGZ1#|4HC_59&WT+AL9|hJv;1~^52)$3t*L%UZ{>cV z)BUCN*4kzI;X6O~BL*(ylaK9h%mR=xs-H1VKf`?gC|_e5^@9Ql2o1B_(j9K5S;3}D z3|qwZyfo4_LoGGm*wXIgGrYp7yt7kY{UXuKs;8UeaU@!OFGD3fw5Y1&ZG7nAis7OM@B4br$-ouun9b_sv{{6tj=MUO?T#&}J6SLzCq z!B(3vHO`EXzghJ|_haq{_r4A4e%v6`hWp|BG4+G{aWvnL8|cbwt>}@B2n$X1!~Up) zrGI0tTggV0my7T5xBPuA{$9P8Y-j4d1ALDt+gZc1@1=QA?;TK&=b>Q**LxFjb^@mi zZE|RgSf{Dh+(+a_^o^jokFe*yf~-t=vuHa+we=OrJNV9=n43s<=0tAE<4MH%IG5Ln z`^7p7B7^U@Vt)}Y0?ZIs>K`e2F`lq3I>C`Y zOsFO*6@vkv5n;zRGrD?H9`Wn1yE2In9kOzX?>qdllT7@{;rl3?82qE+DyC!2I35CV zIUlI|X>3@Sy;s?RBYI}rE7_fzi2m+yN)-A`l6^uza4<)6sU<=biO zW&QB|RM9igSEBBxab^19`>CR5-~zs#R=d2Pwa&N(i>WH!u0{akqN_f8Pnj3h_*$SX z^+&$@?~!W(&q>Vyc}}o+DbCre=8Nt(ioRh!3BEhuWxqzC;`D2e!1Yp{rsJ!Y!{E-lh8K@ANakcas=J zZ6eF|bIIxl=S4%4TR8j%U3d=eRJ(wG6zM}YtD$6(tvwWGQlz_AFQ))Il{~9zS;R)q z0Y*`e#tGFM)a=sJC?tHMPyJ@UZpE+{K-Rnqd&GJ4Pc^G;y@i!ITh?%tul>MAGE%qe zK=8SA4w${XL7;Ruh%PE@Oxnx+q}D7V6(%#jEmWAopXrMi=vO|dIHaw39e63aS1~6W znP*I~S=!$B1mogF#y76fvhDr%e{hrr8J}6ROSkv*=_OO0+l79&8EKhBLMk#X z367gy>;WbkjefVjeW3#c2+kRzMt6q z&B?j;gA-gw=fAC_)9LO)4+4$IXbf1cCJ)pF)9#5m-wr@9yO!tCG0*yk^JHLm1r z8T5+#wLGGbF|hymlfv>KKiI#l=ZofI6XFFQ zufeh3IEy0L_-w`Vs2I3Fb+jj6b3o7cz2+N8?XM0{EZNmj1(`+k*^Z{P?s^Ir_DCBO++$L(O(AY;2kA#%nIxWqVWVAIWPFqAEpu%^E;eTv<7n<$>VJ!= zW;NZ^{=vFg{$B3dvj0K0uS72IRK(zh!Om+ZGZkpwblxM8fuulYKp$D)1}s3nRRC!( zS^CuTcdj}ksy|{B$1h)A{b#%i{fx45F%epRZuq*0 z`y&b>UWh1)@Q*BTvN?0ZcSIhDJR134dn63f?I8^!^Iza)!LJmRfiNX{=Y`fK(4 zpTHg&4{s!5Xbam?qN6jBhuZ3WbVdxKjRNB*saRLab6hfi_|Thg8a90XoEG)#XJ^-M zkmIj1AU}V=z-iM4X5{2#G;Gn5=o=u1Y6kS47^>qIQ&NXrGi_Dgxa{stYGg!&ZHr0BzqZ#Z zT*K(SHyZEi6a4?+y~tSBF;X2Pbz-R~O*uceLR+(sIoh0Q8u>I@*jSN|QORDr!Z8T; z%&l;LrGiQ?R4S@uV4`5+vww?U;OT{^q9|iz;g~4oHzUT5LYjd*o>GU61`7Lu4iJ69 zjUzfAY?j*i-W!LvcmdVK{cn%CeMq}T4MwdRk_#I@)@C($^k?wCANv=YjlDJw#YZB| zBs0?lW5RF^%x!~SMfrQ_dUCv;qJ1jjHF@ScZKH_Me*WHn5y^ah;rGj8^u1l)tW_+1 zk=Gq{Zjov1EP03*LlI@X^7c3zH;KPOqU-i4y?aiY)U(gz+386&>(;HAlzz6$s8L-y z=jC;-nVwdwb~*)tlw2_O%OU=6!Jn}>UtDi4jKqpy45$(-ha7zFoUva3%ckTnqfk!p z|Df7aMvhGgBj%!gmYx#4<=dl=`F}tlQfbLTG{45_Zmt#j@ zv`Er(c6UK2SI>!`BVT~CA<=(&^XBQ<&C^nHR3db2ut`++wtj#24uPj$8JuhUyi%`K z%S=gHK50a5*9tIH`n2LdjI*Uft+fLt1gPc|IVDek0+H#*vLUF?EGqDmHy3XS5Xvvc zo|7C5Y8T`gO~h$Ee)w4vF~$WyFn|f~MRqdzG%md?c~H8(O*0%=AHKAo@fI zpzHR`B05<_Y{{#Uwh1 zyseTrR!nRXXMA+s#xsO8p}g2@h5n(V`tdJ@>H|F^W$?>jaJHyku#r(0Q1bDDeO{YG zamMj^EykAK47%aNY70bSy2zl7m7l4Zz&j;9U@q(#@0-J6tEe}D?qp--3UIjRZ%TJS z4_JYI&F#={?!wXq#5nmUc5GE&Vbw@f z6N7UBC2aAjlGp6H!(G;-xx+Iw5~{C+=ep=y)w{uI0eR9;>2-Y8+H2`}FmYLO-CKw+ z$XjV#6P$^9HirrD9(|B}io-Zx#m~eaNHr$zU@f6+kM3OG0ywT1VH*i;b;0f0NYPMh zeW{{EYjn`aS!hOp5CO6>P_c%^m6K*cn!R zAv-}lWR$W^@J@IY?kuhW7nH$9M1-`{M}f~7|eZj%zXg%bRJsyYw7G*vV=jYVQhQG*ayzd zHd7vy?~044(RES2XUr;IN7L`jy@@(5cwb}Z{p9mA$v1}?9tYmavDQ8u8Zy)1$+>2N z?76m?%QMknGy9Ek1xb>wl1p)s~ujIY*$>Z9O&S^U1Pn2UaR zUj*zlm(PQ32rV>q0zV_sh~pYO=Z*~U3!Q%FodRIg*)<8cLINd&W(%mEvB^SjAvbEv zi~m9?f=>EHWP44~K9ZGAZP7Yutv8>Nal|v0jTUsm&WmTZ6*1kgIbjX21`j<6x}$OX zOo1Jm?6?-#kSEK{30;CU38X{Qz^R4wDR-GuSb5zZs9HdUjw+~4$66fHmV5zF4tGN{ zUk>z7#DeEUBks_TWVb*xuCMy)zeSdO8>M+K$+tzbOCmM+_S*TTIe)F5yZR>6ylJ&@ zE=qp&%_(^%^5vH+iNw?AL~7+Xg0&WIFg2~27Pe){lFbz~luHiVfN>^aT&M+sabtww z2UrXJYcS3P_!4cOJ6maNL1lwo@Zzz9*!~S4aI|+27vN$}B&?E-z!6Jy{RXE*`3Te# zB`5L815DQEnb*%l$o zFJh}!LFt(6tTceEDaaR;qYVHNOZz%+%I))RTt0QI4EufF2GO>(RJ6Zq?j;#Ghhj%R zjyihmjps-GB#V>Jof#o&-Jd6-MV{Oxf699Rm}O^(*Z%X|TAMF950`DBZW|`$1$u0l z-Qa&+V>ZB)vtC4$en5BNCV^`9J$ZEL55`qyeY9Dt+W5XJeV^J~6{v2vnJUKu zhnxCYZ?!qC`iT$4)2zh#yTYt$oxi3S`}VWcOH9BOZ=DZ%TADl11{wzZN8@V0L??80 zA5Lgsio}y&L7BTXAJYyWXd+^thN@L%X0weciHHPFv>zPKqa}872jR+f0cX&fq8MU> zkd+bp%>!`ijqc5{!g|x1Wm|q;!=I8`sY=C!l-vd*mn1h?G2+;XuihB4yvbFv{pe{| z53C^)`?s7r&S)8o$j#D?527M^_U_RKu(%xO+qe7j;A?9iYSb_g87|&z)Z{1*Ez%3t z$mzxk@NQMaflg54Y=EIPunz-|lE9M2j!xjn9Aag7aNWi^z`MJwiUkd#%48`y07c3G zfi2i9HAW?Hg3ql24UDm(UH@t6#9=or|LMK%8?HglWWupgLq`r8JS}~Chih+~HF1pp z)eoK;_h93UrM?%0yzT1hvJnzra&$do8Knz2{I?K&?W z`v@O6_Db>rfDsmII+bW6tsm|teDdAis`3(pIy~AZKw{klxVg=u$q@jv!esI(@U{*c zX~AI=CaAfk_=8-?vN-5?ICZPItlgK%EKH*NjKP}G>k&E-&sRtV+yjpCT9#3w061=T z))&wh+iG>Q;q1mYw&hd*P)^f+pSxArJ3o6QOkgHAV?>2 zqFOCs{&+C>+!JeKEyp&EMWEh1_NmbeTw>`D^}!|eZ7g=SecE%#S{xX|qcFf@=jMv~ z*a;!y0d@jtRwOGd3{;t71kbVvc3D}mTGufXuNygPib&A>^1_S97HZm+;?E}@WsigH+9|g(BtdP=DFRQ=Cpl|#?(U&(%;AW zBr}#$S&f+Gw$1Du_-`@0D?X!8B=I`Mc`zg}oLJy{(10i%7)T$ulrkg$VSH4{$w^Pn z){n_8)APnoY<}0HTH)Pe+x2PFt;vgT+`8%=Em-0&xL5XFa`cvo<2T&4@Qns9CU(xQ zmvMaOR#ENIU;QW5daz7{d~&djS%tHgz{B9I64(QAq!Sc6SB5o6<{*kP0P!3+^w1OX zOLx3b(K(dp%bqhHxa&W{>Ztp!1)sNp45M9^yCu*U5Vs1Q=MwL&h|*t;8)1J)hDXm% zaOM?ch67*P#hwebO3ZGEkZ~*Hh}o_hI#x(pQ4CaavOwl1qF;#nC><0~1@UoBa{xO- z8KFArC3TUnih0ee_06u-Al$6quI~07jl|R{SJ#h7h>WS-A$if=4cC~FM#{9D&W84W zc*OQOB@44V1~l;{Hd=)zmWdU(fM7fp-W0}jBR@xBe89TKGvbS}&#sfXMsw`5t9(G? zfc47KTRle$Cv;mI%q0j(b#?1Nrh<@xuhM`yM{%aVlHAWlOsI;N~DzCfsSNp zo|BTTe=N^WpE`B+=C$`dc*~5Nwmzmka$o$+xNDCg z=a($V%fEBw>KB^qtKO}3qpS->%b(1wb7TKb*Cn6FFfk7-?-65SQXCw{-5dMj6n02F z;vZQRWGQ0r(a`yc6?P!UAxYf#TO6jY!e4YDha-~l(Juo>$3dEc1k%@EbTQxO^28S7 zCVfKiM2H2GO77Jsd_reG)h1{I8A6C+77Bs~6uwK@L!pkN^wh+`*7X)!qQle?*Xg8dH}h#tkNrv| zmxc_OHD>Ah=k{xb8^^YTX7$hSB4G6X`lvZ*#*sT~t=Je_Yw>Nj9Bc4m&5q6MHL9E{ z!oI5Yqi9a^+zx!O5PT2?>?mMgkdo-}(z)(zp2f!v)4i{;_+&m3$?g*$;Aq}ZH)Elc zeJ9Ajzx@RvZjnD}ZA#8hnlpLa_$m35^`Y$#kB>bezouBW??nCJXMDup{^;J@m|t;2 zWL2MNN*>Zje9ir`-i`6c+I~~dy756_ zZwmW(Dp$Z}r)lZQNOF%taj#T}*^So@oIFNvc9n>0ntP`78(9j#xqH_v{BX-HLc4Xc z3~qtp=EdLt(Z*p7vSl6r6QH3Qq%1TTpuf>FcnI;ViIXvN`SrO>#3Js_wP*@z)7{yR zc}OL!j~vLM0N*Wv786i6=jDjKtcMuQ<2am7$UnQZ5|K??ikt2*wI-k1 zVEOm-xYJk1c zom1xU=B*iR%vUhTZBJHhRWCdtDmG6^?a6p-m@&8 z8W|y(126PFCfNvl*4;iS6ep|h?Xgy0)aK99=je8y5U}%*)I6Ki=0Vku7Ny!W zwAw%h+zfv}HR!2?5d{oIE2`OJjCB+|x8Q}U?9R-E+Um{BRlz*51QbODVe4AA`m|J3 zV<9aBnreKGR_D`wdymQI9WXmg!{ADPgPcCvP%VK5U&*M zX*w#LJwX~@G6s~cWHW6Y*k^eUnOhcBOFVXZ&i*D@`)8kdy+*=ZbGh80*Q{3ZeDy@F zL+?IgMAqouy*lanUGE$0-W`MQ>-t8pr04d2eYW@B@%GA1@4SP31pZ%vHJZ+`CiRFP zfx&ns%sz?-RBiqRYmfW8hWZmTxWBn#yoz11bIKrVX5fzgga0+0aF#!Xx!Gm~&mD}J zo(^-E6x^3C@OFZ09>MuugF}2A@wioyI}os|Jiy9rUB`^Gnjt?&8RUQDlfZEEiOL9H zKzW2aHZ0pF4$B@p?^wA^{A_-YiZT6h93~?bVW9l}Cv)A_j~_}pUFYGC?}CjFW8t`L z?A8C@)wBk0l<^n+x9qQ!lUa%F<&7{;8f9;XUClNoj;<~bRLzkABq|)e2Isr`Vg(Qq z*TsrV=x!GQZegw@6*@O@2d5xAXniF1;3;m}JUW`bWCz==0iRt8o|dZM`~@ly;jcz}{Z^&2kDzxCGndN=L5;4f0X^R6t>CIz?n3xZKH^^S?-SMs@tars-a zT!3$oV$j5JwU47iw(MKbCZ6~D3rco~IMt>S#bm2bDg52+2}nm-hbq2gfE z2;Y3U#a|V37*4uJm`iW6XV7!>vGT}QCa{SeE9k~EhYm<{V*NKC?veh0d+rad2+q#p z#zxVlzH*D0gyjQ|b1Wb8Dg4`5Pgn*F@;?*)UoS6Kt4)o=npg_=9T=FaZp9S5=&~B| zLWP#eSt6rhaDlx*AM1zlFn{^-`QW%y@)GeLmL*9>gWpywda*7c|GOo>;eXdmlDD=z z=ke6T9|(%MHBLi5HSmp6XRyb2?cqkJY9pN0ZnF(`pbI^&uxdTF?RX8P7@lJqPfkxu z&8lqxSdfvajpRD1DCeeBKxHq#XXULMR!v_gzkze3)i)5Y&6mzza)&%5|M*rGnnEOQ zoww$pyVkv`51cl3;LOSW&BLcYJ2qi=X2!mSZ=C()9dpo}8%A6|^-CHb^C0sM(2gC2 z+g>VGxa|kqU(C%yT*Q`h(~6fNrb*{56|etF&{k&fFiZd`97LeMB}$MtT+&>qwNU&I z-WD$?-UfeL_&^T-^FHGBz&--Kkb{WSp*TLbZNMhcfpDaeIM;0~fbKf%ybfK=JhOU~ zW=l6e3Qx*$rSh+gdMihf_nqa}aJl;A@1m2oSzOWlE@967#^Yu5Ks~oViC~j5;fpyN8E^~Y+-X6XbZ2q4aJ{6BVW+!sl6U}pE!H4WVq{}L6G3jYQu4QEn8KjP=$cCN9GMSIk z{Gui>MF>VWD1-7W)&IHa)+Kk!cH-!rOP0+8EW~-#+j&g>0qgniNG=r@%{8~b|47EE z_&p!3Tm!kj4LW==XtSqkC?lWx0jGc||0&&f|~XefO^28*M0FF-k-Pg1fLrt80mH zFk+3YL`>xWs!L0vtO3pSg}_>rBDej0DPs6CZ;VQw+R?bK#;Y zs1t?hTY@&rLErxyJP|>*Hq4gAt1zV@tSfdFQ9SX2$d^0B5;@-mC!z&k!JGkug6GV8 zuGw?u$Wof7e>vA&KnF_BCezJ0B|QhqMYNHC8+^$tKW6Gl6I#>U=|jJlFUSwS6}wI& zN1t(4{3|dok#;>1ULBhT4-A@fuk;cG>Ku0mpxP0bgt9Lc)j5L#CafJG(3DH`?mLuPBG-|Ml1(xwzZ<28uEyHIZy z&m$C{$Zf`9=94lyk-ZGe3-*J36uH-+Je>%TF=C=fy;q(n`5flp-TLs7-NC2DM7$E? zg=)mLW@E_XQ`x19*st*xTrGD1e}2`2Mc*}xi+?2FG@C|imSFIH{v% z)$NuBYKDXb-u?gw+rFv&fl@_+k7c?^@K52sZso{aK7(zFSRt|>?8}%tDuqH}OtzY{ z#Ao$btQBdZF8-xn>SE7=K3r8L=J(4jFyxZ#fKCRy|I5Vwl}WJ8f0vU$sUC15Lx5C7 zhPz-wh$Mxm79#0u1S#GbqN-$X@NqE-#3+5ye+EC6t1sGq=(De345W!B;e6w!ud1cIffY;i5tK+5%_bB4kUlZxZBfO-tT- z&TYrog3FY9BYR~`VH5)J3;WcB%w0r3<!N)7%roYonX6{{5BR4nr@gBAmP3bag>eyvucgC!Bm(bFJJiXuZ$sAxoN%`9lC(FM zg@R11|E8vktmdd1U=1%doz(-cOIJK{FQT&E|5-#Ki0d=?SHf04eV(v^O0>#f3aPo$!L~Ly84d#V9Ct-#G&}_kckS9nb=+YTGrIz?ip2^em%ftjVXnyck;<<7SK)zM~E1XWY>k7tbV|Mffo9!G`#c zaQV@8JMwDx0#nbVY!>XJ1lSm!#y+AbHz1j~ZSD3x`hR3=x8!w-(%R{^7qYb*)!+J} zxcCbheg31Lpu!IysyBXX_|T!)Yx2Q2ahQ-c|B8I?%nNUdcOcGB56o@d8^ghPpqrXU zFdnk8PjqbTEDFk%c8+j|_Z%5xi1kLfbKFhc*4Z*vbp#8QXH|F3AJ3V%mK17r4n->s zTU(({qpjirxsy&t@sxy`;S57S&jl7N_IeH9&Hqa{sE0CZw5@@?{@+1DO}-)$YO?mM zeBTR&+OsD%ai;N%{Id)e>NAJ;>>(cJd#L|S?A=enz2qZk1p$t|8y&*+<9h|~Z@SNt ze{r?i-<8T>k}&=Y^kTa6cHuj3^$Ip73F(K>jn$nT`eAudF&_QQIT`2xDOW}0YR!&9 z2LJI|Qj+B}xME`Kkd|Ehn%pKPg6)V0Ik%4d0>p#k*)L#)Ni(zAwmSP&g>3;8T9||n z3XOJ)V!%6sE0O8}Z-MJ{qWD2C0|FGtc3mlfo2A=Ikhc7UW5wIP9TkL5D5pXD4a$UP zv_JgRQ^C(Hw}A$leg3v=YmFrAe@h;)K4cT_Tx@8HR5b-~3k$;Rg2OXTr6i(!GCvE+IzM1=6mI}q8n z=uJ6IPYwIxJGn;;T{bazRBJbJ8U6h0=bE-ExETPs_@4$u0H1#*)+7Pa|2pT~@+fuo zg_=j?(bAo<8q7gpc9(oW5DeI#Mnt+?XeEI{L@|9JpJFfBd~Odc7VDQX@7G5fgyjo8n$` ztaA=a5xTrzVdb?+8EVKK_Zz={!a3Usjy@p1WFpuv8Xt3Mu?k0_{Y!XK@fSxNkThPEfgbFOfl6b%yhY`0IjVbsBlkb|T!GNU2g*bp+6;{LWN&d;V%1&!={e|pHa zAC5$3CuL`51M=W1l1|F~jJtNzkmostb~J+85GO_;8J70}MX`|vtngND&7Xe#Y*`|V zUq$>)Gj3ZWfBd%9)y)UC?!RM?cy3Sbl=*kwwpMfqfwJhMCJyO0^4ts0&E1`mv46pv zXR;c#?p}Rw>I-+SyKCy;8FS9-+ilbq&6g;9>s!qfp05MAxirMh#hNh>!!X96eY3m5 zj1{8PB1{ntacB97K915ylJzmWFbcmdph*q!MfsEZKbcSSO7j`x%;(0uVb@(t^ZBi) zFlzAhIl&K`bZFC~dH-d*#r|zAuAMtCe@Ag>HnrJZ+hpgyvw7pd`6TQq08Qu z&VIw82fLHY3<6d{@L-H5z>pQ2)6r&BUgJGWIHa&nrL=1z&dUpO7f$TEh7J{TcRm;v zenRM1X9UT7%y+o=q1)6obG0-rjC5ZyT0aiE2I5ewQC%ju)C#P6qZnJB>`{U88yR;P zT2Y=Kktp~cwJ5^w#+W$nl)g7^WqF)eI?rFjtPdY@CdG)-Xjw0@MX+OJgSrHL1jjfc zr(Djtf{djI9uS3D|@4{Fx)8~_OY&L&J!n|$3+}$?6`m`A}Zrld@ z*0!4xwAveoH;S7wH7;}bU9sy%WW)~}72jk8%v|8pJh{Qxi?vQDYaz84&lwy}19!9= z#^()hLvpy5O_^r3eNK=gMfGOs-Q|go{t{WG0-ka>KEAnW+0r}jT>7lsAjT$(jz8g? z2p9cj@JDm?iVyb46OVidx(3Vjh7Ml4j4pfE{P*a(+$RIN!sPLz?;&;b_20-HGosJT zv14XGC)bPdwME*8wJwTm_+tjlLZZsr$9b;k{G83m5^6Hn5eNOXZxI)# ziR0)F^EuHUua7ZfakFW}`2Y@FS3#&V>`kD;;xpPl*C>U7%d=v;k^8afW2hRLVtpoV@}4sI?4x4I7BzP%FYVJ2NpgrTJ`fE zU%g{G0s?TCM*DGgdpA}R+M^6(R_wF=S^+2|q2u%&h&l`N<;Yh8Mg9YjTuG2NZ4u2q z+BXwX1vmH#24)sa$SjzXS2=0p`V zKYz@a*@iZ`aaPl-`tcL}5>J`(1J7e{i04m(gYer>Pg3<{|LrxNevRME zKG$8>$INKeDnov6_MU{F8@9yH6+%A;{|Wsp&zgNFPV9>|EgSl)yZ-hH?P;C6$?<`e zi1Q&EPG#)31muCGAm$r5JiwYlxzF@WURO`ob7Dk%4E$|9!*3qbxm5%{v|5!!FS)yTP9^!c7_Q%| ziFO_9%F>eGH2Fd&k(Lp?vE6I>nCQFPzuLO8+%Lu&J1awe-7ljf7L4n1HGPQ3qPBL7 zKUlIRdTXa++F4C>?j%1hIityEx`+%uOK*{T&18y2rFcDGx)@0Dday}F8jDLmC%aWt z$R;&a?)9hGaTvZdio>9m`ckW9C?4bg$~IKSEL0e!L4W)I-ZljMI>^^90URIDQu&m1 zb}${ej=;zD)8!_^CbVu>MwcM2$J#ywlQD*qm__mh28kQ}H(*A~^P$_)o5BZNeHK6y z(@6tKq0#~LpMGO~3e^!8fL}IDP_&M?n&fKf@1U75rz*j3&NO?j9DL)lFC%=#v>%+& zz}oA!$w5VerRK7*O1?Q$^(#US*X}wek8j+F2;G_Iv@O9&+LpuG_)`)gpaK{lDjum4 z;g(xl!=vCkFGl)DnHK}i4{?nD_HKag=AV|ww{F$W$abg2>$0VI{jhlcG!7Z)hb!bg ze$-0RxMqqq@O<1cd@e!@?Ef8@WA0d_lE0G|!#= z;0%G-!m$Yg&D?!kWqfm}V~v|s(162*158~@v*7X068;>y3}GmD%8Sh(9zfUc0T0&` z2JY9BOU`L|-+aR{ZI1{PZ_|b_tz=)`3uW4&m0e)A$=~A_WLhs%Q#`c73Fd}}$BHAi zr;4IgchL&XHY>)s2Z5Z~a@9lCH(yPpUcEVC8!pF)brN^)+owt?9X%@UWqy1KbJ~mN zbfIILX1kj`tsegLsOg?*b&MkfZ|}MXFA6|7;Fe;9E_Zk&gNQ+{jlwFv$WX|ZWh{U5v@EPv~$a~^>V>o|56?@@b-V0x-@Aba4Zj`$bxQpe8m6ysa zWiJ{pjm`d^z2LFwIC}xgxqC0bx$a^&B{6Nu20P6@t-pSEaE&Uahop=)+U!%sO{jz( z2vRcC4|5D;+&0Hz&lK5n@8S4zDLS+WP7Q73Ap)A!@(b4rvK`RJXhD_Y=_83gj^evR zeZ**Lgr7&!@8MI%2VJP#V}kMD74&-9nBW)FZbT5P6?UfGDvq2gd00iB(fTA}9h}+| zv_2XlpzwWTe2+^rWEJIM<9oq)Pta#=%&pek&cesReIIHm=E(ZJFN*Lep!Yf_mc44_ z`etAQnTNGMKo01!@q40)p7J~yo)AP{O}6?(kxv8s67AaGI22Hek#P3wTIY~RrmRNn ziY$HnYx4Nv`SN`Q=~D=VpQ1Y}$id>#!}u`wa&yYLJKfr!5l=%`}&U}WfCQ+VXC-@BD=5hsZlB)wgSH7DQn@}t_ zQt#Bk&e2Z@oP1uihob-)y_BDG5h45c8tgUFv1zN_Rme}C+QNXmwf zaM5J%1J6Or6HMktFs@62()_Z#_t+pAAQhRG5S2ujA}j0*?d4YmT!9=frw==IDtNmS zF^4%_g*iP+bBc&lC1cw0oL+}HJ;po?-sQRO&U3m7JWM$UiGo|AEMTBcIdsD6 zg4k4w3QP|K9^N@_32K4IBt0A!sGA0E7!qcP4V$X;o~Ysj>ql1CiyvN4w2xsV;o*WKZY?%0vrGy`>$d=xsE>bvP7fF-H7q8|Nj^KNhV=nwE zuNJSao*q*(?W_}E7vCzorb7fUagVg6UJ_I1gZ zXzeIZa)(1LHapy#sM6|2pTY?bvEYV8gaYYG@y1oFwhyodfa;Hnui}eGP63Cfz|c*F zWOTcl6mWj`%asxLJp4-g_Q_(*ADHMCB?GkzMIX+2x@VJSU;n!Lu^3HTz9}BXbz4?D zeqivdSl|N;6mp|{X_NWCxA@0Rp9kPd`{U3 z(4IXjzYCkc?1}pI>y#Yz7Sg)UuAU`ooJf6bW7|N3k3u+tU zjALC8>v9LL3*GCJd0ki+#El+zf3zpL&NX{%xvstG$n|KqT&FlS)qh|C_m7BiT6h1K z+|LrccLTTo+~S8{`1`Va!+ED%7bz7SMR~Dr*|~#;ojc2UJX~jx%yx*2$>TbMjVqvP zgpFUJ`k~x>?g!aDb5yOKD2l;Rp$K+c?vLy6aDTojey%gf{S`EZpAB-G#s-&fpd0fz zG-Nz;tqG1*+oQ$~8T>!4l@1&K;L`8>LtqD|I5lV-?x<^XOrv` zzuoy*RV_GRkN;JfFAq16FUji!N=>!dWIlT?y~e4;oZ|R5AM__}dkXV18Zxk|(MKTX z#TaX}!Z`pNH7TJE)pQbq4bYayYJLJ=5Kb^ylBW1pi!|~DrBaRJg48Hi{VML){}$|S zR={5-gaQ``FI9&%gXj}y6dzR&tK>pL;jvJB;p>E%0)LijI|xnAN1oCPo|$hTa5Xy>fEw|r={=> z#JrDXoeK6Jm?ddOJi?OiMx+KJFxYhqEwm7k5nE6rbjTE%H5g#zvJgND+$J!(*s2C_ zoa}gR#z)N7e$s=x^g03X%N%(94a3$hI}D!X{AQ{FNA^C9Qt)F0^x z+!B3qelp_|G`0BZe#KW@r?sHA+qbIlO%Y=Z?<@0F8p}Pd*Xp$7J&HV6s%0kLv-+GQ zt|tymV_BN!t{cZW1{~K2dmHg;P}OW@I_;L|Q`K9e8t!@AE-C*Fx|blPCdR+}lm z@|bH-8>(!_Qp9T4lIzcLUt(A{ZdaSV$rv$3X_2hqI|t7z_n)++%@f3 z?`QlY+*@cIN!(`w)r=p-v4 z13*ttpD#`Ce4s7fJ{luXeAE-Q;tS9Z=z`Xc-xsV$Rie>81f5aU1fNM25iqVK=ws{n z99MVb(YhK}4EoNlMnULCn_Q*hOuhU3?j}ADo*V2`eXB z4f=i=d$5nAy};~Zt ztqac5Dg}Sj)*aTS21_&}h{YhtL{KYR z0oeLW6zd3@V2WcXZZJz9I}d^JPaHfbkBC|`uLb;R*PZ5W(Ov#IL%a`6vg_nl@%~|P zh{EV3R+M4@@PEc?tZ_w9PW9rHr1#wRSnNa6dyEgz6}*W=qy{5N5IKS|9OMTNxjq?y z@TZF9=OVqhxOo1uW%Km{&4>8Pun&ra8Ehf29N)Pz)U^rK?k<*}iF(Dw zBBj%a@rFpMC2A(80=($_n{rF>f@QbPS0rn`;wED9sGhrfkKfego#Q8+0cgJAxQE^j zyKWt1*jOGD)=+Glu19J2grzxXr%2&;l?zJ9~!x5ln{@T!a| z=_rH(T+8$Ri&(FQHUxs47edI)I9_k1~e*N*DC&R=o z<8L}MY5LG{XFq;x&h92DyBBn9+(wQ4w#SFl*!2ew(w-5%My03yvDo7c38^eW?U*_k zR2}KJt<&B0m1Ef8U8Cf(@I96*u?X)o0>{E}x#$ zXD{v1w8h7*TeR+a`q8a@@>3J$4pL)lFN?T7NF93}*_2|(nX>=c-hZ}SD1gDlwQwjP z;f9whtQk>>))DONLS=)=75?iKFz021vqKAGvy7Y_FSom{Ui^*Ik<|Cw{CPLsAd5`V z{BKcx?(D_+yTXB3+_?6}PLrnHeCoQ16Xu>e^H%=OrfCP4O~o3`kk1VWR1$ zazNja10JdX;yXrG&%I~x5FPNdfBHFbWJ56yK zi^kI*9Q~l8@wRLxXUjEbf}*xoQ2dIL7H?g5^K;0<#EyBM6cb*20q97{Udz zHIV@dW68ss&>hJc3-1SeO*{sF<}ce4Dmjhshg73vzmk}?Hz2(tC&bst~?ob39M>1#X^Ps8LNMrd0*GAH<50&=DbZ#i&LN-%Cz8xl8{2@JVs=^uCXc+C8<$*FVsH z=nQ%R7Y%wXTn10rtdr{Q-plX-xaw*^dP0#w6&@%uz^D#^GuV`q`DH?<9KB)%kyxp+ z@$FM3sAE&@mr-jnugbisQ~sQV?~1FhX*Rt{y9tf<9uzIlHaIO>r6e7%k@U>M28*92 z8f)V`9}iwnAj|?pE@jI`Z~hoU1G+W@3H+20uD@aGbJc&z%Q*vmVrjdNh$VC0q+%hhXEX|nJboFzXUaO!_SIVej(4UpSpV8(mP&#b^V52>*n4g zY9Q^V@GM}R4vQ@d_Ge`7o^b55Q-{s|lV=VbJMGJ<*N?bi&LH!hPtLNgZq@&Qj~KDG z(A^uz9%cu=x3Ya+A8l;m?;~;VyN2(rY@gRh>rnR5J_6}!z-Pm~FBOMf0H}u@`1>5W z!iaN|u02;c>@YUiCwEW&18ZQ{CTV*@h5{fK|t4qv#_0g`#VU?_+gukF9`r7I@l5$nBo_ z9b>5bc8=WVncp!+GoIfFj5#UrI{LAAPWIljuRVohsB1U06spQ#V7SAkkKrQRriqJ^@vP;E!h zcG~H4h;IwH1udhvPXzT+VOx-b9PJj^cai4(PM<^S5oXfkjk!vZzzfZ>bdc=Ih>2qkxxhwY>W;%Ti^W7_AJbik`4mw|R`W%-0p{Gx4?ARw*$3T14 zr!QUf_ub9$l)Roa_w0XA_9$Lk)2I4`MW%oKDp*NgVQSe}zs#TUvqS4}*c?ZBXr-DV zJf{lh%zV_Lb$IV;9$MRa<}}nN`C7QoSY9XaCzZl0zt4fAxzB7~r|c+YttL4^Yah12 zp>u@qjWTp5dixACcjz3^$4h5VH=SX~7g4;f=lR|#(`VVSUvm1)8|v-T89T2NVqRIE zA?B6*Og#J8cjc~An(7nl1b>rfo!ow>6>^U;o#kXb^h2xpxUVASrI*}pXuwiSV=OiL z9>ymnC*d=qeT??#b(Ded4|;z@m}$#N#$hvWQ-8~CZpCRz91<3=+d$r;pXp9NLwz&E z9BLC;wx5PpKc*PkEQ?yCR8YOx^!U57JYaet4<^|10Q7j}0qF8q=6%)`v_l>=s7QR4 zN>q{OhCLYA<8zock_W2KA?VYR2h^uW9uPjVWY2bKru(?{~)T1y^)FKG6oT)mOJKg=!rv=@#BtT0c-LQ33?Uj4Lua$9 zAwcI8{+9XsK{evUFx?&t_49C`)b0m-`LY;8GhUm{Z}L`94io;2XhGXXd`?k+;LC1& zPSvK~oR;9r57Dkh;4i1oA?R}`^;wJitQA#I*Y2})82B=m&neaCkZycV)#5(wmUuVO z*)brUK8O0A7p=?hlkKN(^8QhM4(-V2RJncD2&>`rIn4L0sORa^Gj`BP=alMmSbILF zoIbfF(MjtV7^3=QzI;VYCT^qkr1h!gS|3_lKBv$p@nv^)PGN<)rLI92(z9s2FOuFTST8}F_O{;Vthef?j?+&E8$&z&%KZ?A2J4UMA-+-l zJZJX<{%a&!5IxOZ<0E=Z@SmawGI*EbzvgB88SnHn)OSKm;c=DiC&TIo@^wH{ZsD09 zx!tU8_EY`PKJkYup2ZwrG~QEx%ll_5@1J>CCyu|MEKhD9&)-jmtfBa{1? z2mT9Vxq$Y(-|8s2P=)+UO7EDA@m6EGfWPJawo}Q4s-Zj&^kXh&|8ys79p6#zJv=RU^zx z4~=btc&uAl0R1YL^}-TS%?pd z4ZYVd_i(-4H01IsIeUiXvOo9>;T2kcOMEr3bO3G}sFK3|JoSD$ulW6;`$EMKU-0{x zFX;WGi%eI15ob|=^;G?ko}u~~>f5g7&*l48{b2soIKtY9UXT{J%}< zU3z2rp6@ds;ssMP5A{hMor=gel?04;ZqbGrAL-ZlI_tH*@D0eyB^kd>8|E)k-xc^K zPQ2oGnoQT%VW!f3?GeeZ!4KMA_+WD?ETHJ_`$d7!X6IJ$i6~K9G#19lBkBizw*5nX zZul&*SgaG&)(__>I)nDrRR2qihwq4U3(3~P?l*XjaKlG}S8PhtooieFVLTzm%KKkL z`B#p?QhYIzXvVav;6%( z{QWWjiZxoOQbTR8gYPiK8|#U z;jlf9*87({ruRQD=E^(h{o_y%kMMkAe7C6gd+hI?S6(6F9P8+q9%)f+hl3|R8a^*q zv_H9bQPU5=BPONI6vSZ40Qiajh+;)G3~9+mTTuR`d{_*le}LQsKsEl25%-_e=AEV? zoDQx~^LV@XUYlT4M2-XY1JM2|hLSvCJtFi+f`3FU(%Y9#ow0Pu^yy3WvyGdJG0ykt>U;V<{Qoes_=c7K5SR`dSORuSHY8L( zpdxMX74*-fbXJ-U24t{pVvfCzeq(#js1kW7i5F9Y;Dl70{DT<={itf;0x7bo>k;bBx_`=^rlHQMWI#I=j|w`kI&#r{RT7Vpbx+B9e1Vtw(V$M!GowP@eIMXmbu zY1OM$zkaPs7PsuzqiwI2{ra}ThxOCnJ&f5sc+dVUfQN=S+KOrq8-W&r6sr+h(?DTp~m16$EKEKq zA>{;N{$zTfbQ2`YC8r}!B062yewZ=igv>C+N2gDiXY^Yiee}@<+RWflQD2iEW2}R< z)wifIhyak45y6L?1`#w?9+6+W3iL zPQcA@DY{U;AnGkH1oo2^ET0lxT01qr`=S*e=eBLqA^H>lWAk&nY`PDa*w0=&v_V?% zQ$3mIvI=D79L#YvqUL#SJhIAm4;Dt55i~1NnVtYRO?``5b#m@0TOJdMxr0a175j`y zD|8Ih)Bw<=}SMj*I2-xpVa&f-SUh+Q_Gmefi}vqtYoklh#lG?bl~4#u_#N z@+8ye0i1H^ORJCC>+mGG@Q#U+`cVZ9ob?3^1)d=z5&i`+iO;&u@2WEPRPB%xt*~a@ z+88m&CZ{Y&&ql;VHqoA*lAc9qH7+=7LY>4vtzO+!?SYcSijA+@yUVy=Y}0>v^V1)x zYE@pB&V6+;K|W|eHO@037ub(i-jJRRwR6JqKnr}69-WFIB zLZ(^dL}k-HCR^_J%?3;yLVSTbR~s1SVOwy`6Z z@c!>0A2xQ9et^7PXij=(ah=v0I%|91#?qz8eJ|Wmhagq!w5_9I7vbl^MfCAAKA;{6 zUl-t#{s`X5zHI z!gP;P1n(mHDG5JOz-~R~Z^2V|jxQnvNKXKOU2~dpK-m8Vt|HD-fEceTg<&(?2`k$mNDb+1-^+SChPvv}X$CB2qDx_60n^7U)UCm-*>>ZL#G2QXJPpnpIrTJ;@0 zdBKi$7Ej56o*)qThF$Jfg7tBUl>+$cT-y!7AOSNqI~#nEjo9~STdUFnG#$F7GEi|* z?Sj8l2AfRCYJP2_Hx6t%`sL9vb8_p~s$0+O)UC3nU;Ic93wx$Q1+n@4i_hHGV4XZR zzS;bn^nMMSv>q}LuqrKg;XGZ0(8}xmFCng_2{h#t-vWP1X%MGql>gn*ILMtb`dtS3 zZ6lFM0)%@yDOtH9O)JJ(UIY^&6AJnj}374Il0>mbIFby&3W6F$cV-3ZV_vY{Q|Y78VLERR#R>gQ-Ws@XxLj6PR4S8u8pW~ zvlc$@SnPR3Wm^$Be2CksyAw}T#i0UccbxrDI4chOv?vZS^_76tW`B)Kh1!8sodC$$ z$*Q(=4$#6WyEHA$s50c)(O<}SMTa-u6SafBoYlQXKRraQ>%O{`me_pNsGO@sxAUh( zANl6FO!;JX%hql52JKqP??tU<*MM})`S8*|%rX8#NUzzx2<5*&3~#rUt|(LafYz2Eu)fL|=dTUqBx-p$l!~zBpV~w0lEz61U6lsV9rM9s}c3psi>e)R6#$xuil_* zG52*N#;E#gZjEtjs4tIZ;lzS8Eh?xURnUg}!dfG4+nDA55jpP3@N7~{sT<3LUJe-y z$%=psR|E!yk$EHi3?!JKt{{bPa?m4U8Pkzol8qw0q=i?F6W<|N_geYd_vhvD(o+NO z%G9f0*!|+v4Jo${yMFFs|BtQZ6#3clKja%Cq3Dc=YMNo*^Gd_wqUYDlZ;-Qn$*iq7 zUv`y-89!ma1mI5~?UFVOYb3OgNd3q03zfuEg2T_r!nlR~^lfnIIittl{r(b?G5rk;xz6JDLQm)Ew;W{N7VjI zj{5Gouf#24+kpc{97=V?;WeOSOzHOl!Wvh1L&Qltw?11Gu*k9>9J%1A{X_yTd9Ex? znoXBXrd@~IVpDLWAP!QYv33a)R{u_3Y5sR7q_13-t*MvpCHz1 z{J8a0&+ezU{U8$M@f&6?-W648&%#-AFYTK%d%>Pckq<4JHAfTQ$&U)|Sam=&{I2;0 zan-)tZrdk6xNyh5^8;!P`u&mBs~`DeV6FZa_QAS+9@<52x}X_4_w6I$ke@O<4KjT5RjsM)1wy`zAJKVb%j z_cy*c@@ja+PyJ>;m~TifU+eqM$TD=SMHVpb3gc=*2glU9YvJLpf&&7_1P+L(BIFd% z)TZ!f8hsvY98xw58Wa^|Vb)`Cqi!BY#lcmYEG+?QpF<`GuK1gonG4!=9yz#sUWeQT zjVm@@klP`z`{0qC+bzhfdd1)9(>wMSwHu@*_3HF-r(Q{E4Qh+t9X~JUJL2yZzTJq; z{|v z%K;PLxz4H`(-{V$F=jFR#W(lho2%lRaO^4Y{>EQ?gZb`svC~4-C-zPVy%|4?yNhgD zUei{0V-lS|Dwgl|k$WD(89X^N?g4>3fMb{D>l@&FaRdGM&8C)SZ|ueotOp|-y3nu5 zC+X>WAH8pSI_G7rzjGDoMfmyOhHlZ?5l#(BuN8~?zgP0}pO1piu<68<1AcD-j(^B? z8liy3Xy>BKG;T!SV%)e!YFq-i3@Fj$JvW|RX#~Q(--wUpakVSD(ZEKSQpE5F+xaW4 z5k?LWuO1Uxt|15kUxNY|-tfUYAI`c4?|jz8)o*V;_0+Z6k(+b74p}%NFYm+&x|W+O zvU!Jx9y-&$-TCG%r%W7rxc(urC$)I zHiSRt-w@{mh9b=WyQLcoh*hEY(VbbkL=DhYkexRJ?Z5*>}@c#m%i`Z4O z;PL{{uw((5zkB+Ek_F2bu&E9w?i>LNu-9?vK(s_m)O_8}hL?d&65 z35N&TXII;2R@SLsJJ1WqYU089lksLbDU&qLQvv&95>?eOmI* zJYuUdUm}Sm^;4F`+2W(k)uegDWD?Rag*2m$-Pil3_UYHV|J3@c^Tj`FhZ6CRd^z*> z+h>-}SORz0duZoj!y*R+G|B8SJc|rY&&oeRa^hok#~)}^U;+n zE%6BhZE+*oCQX_!`Q?V;rpD_`upM{_9q}sjPVC9WYy!HG`OXl)h*d(fvcG`*EHjnR z1DMb9^^|r}u6vE^4U=bZSJU_q*0FO^JRF0N2WKBYKUP2caM9@3P4|=DA^Hc8?LBl4 zu*Tehg|P0B#~rZ;8oNb%NI@Z7BOBX2#Pke}?GcIn$BY?}G_2Kt?r~}9aozjVQGF)2X*+9R>C&a81822uGr3Pe zMY(S4)~i>yZt?MCS?6wDBO;=)cuH|r^Plt&;N2Q}fw8WAWnP-l@6a-W_0V zZ;i&5Og?Gx#1@m54(?=_jPm)3)Ug?g0FEhl4S}gklF|lX>aww4cG&2y4?Mkl!$VaE zAGMXob?lZsqQ`*1;k|4FlQ)d$-?Lr2hnJRZdE>t0E1wMx+#KXj{Mxn*&73+oE-?dm z>Jg~1{xe*f`CHzAQnQ!2M*_PKv5Ue?QDmP$S?ycGK=mAv=;Cr)e@Y&xK z<2R+_Nr<3x$E;3?PMnuE`>xp4S$huPT#V24KS<=;sX47m#ta=l%Jf95mM5AuU0RgU zE#~8wcAjy5PTC&3*07{oL}2ckse`hh78YmLn_8RJfvW@g*%VMiD+fMeiOoR8SUZDS z+OyB+T53x*@5M1X_2Ehk@D~~=mw%Cvec0j>X=NMNu7wM*!@)FzbZq#Lw6O$`SI!M z?27I>uq#?fNmn$P8vb-S|JlZG_v6RjHE?Ga_kJTsvo2l5_x`PUFZo}d_-%-z|FB)Y z$*@7gGcvOEbJX(Zo@2kw$exj}UqAMi{x7!8x1K&?$fPl257Av2skV^=6D^x}zq)WB{a&U)%C`%9L@VPpG@&Qxo~BQQzZEqH6Nlr&-ki$MruFy>&`F9DD-LGhRf@?IP2 zQm~xIS-pG}(?$%*st$1zJEd^g6Wd+?5_u^lt$*s!G1y>e`Tg*xC)Yju6eTCWBNgd$ zWBQJnI@t33H}Ac&bnnVXx!MK$K{Xl(_{^BI2u>H8mz&@-nZ+UMrfAREj95_ZXzNS^ z_0v1Z7wnPqd<{jmr=G~O3C5>Z$*6@>~6P;`{9>(nLR9IB8Nr!IX&wWJ}dgKUIhlO{9?5L6y&Z-ZuJGEAAOAc(crJ=k!NWgFOSbza)b=vr_+G)qGvOT@TvxvAmGUaDR}n; z$Ksq5EnKg{J3zjbo9~TA!2=GE(fSi)uD*fuu)kp!xkq0}htm`e z11u`dR{=u+RyhR>UO0Qf;3XEk01~9($_a=g%q20z6-Q*MLtVIsd#*?|^|GvlJGo!= zAKtXs^&j+KN$d*Cn^(vO^w9Nk`clJq)4GN@ik)*Dt^m+xqo|7>5-w4oK^w2SFc#9F zodFT}EDi;N1R0G$A1g|ninG6_Ku6OnA{<9Al_OVzvBoc^Rk#Y$5@r5gU5Hoy2C6sg z?Fv#Hug+<=1({aqKV14n|ABN`P+D36WC9QUcj3UM{M&82kfOAcYc0S-5$Kn>4 z|3IbhrSkA@YBLd+fV`y2ItiL})&!K7HxABiD|f{>x1D^JAw? z96f2>*I(#=oxZ65W`R(q^JnEwC#i{p+jigf)I%SB@}gz%$kg~g>Fv5dy=CjWpS)_x z&P;)9!b+NH1ZdS7V>O&?ruOIyiDV!pS`6nrj;^75cC6RX^OR`ld7S(wK;vuC{HjL1 znCcjaD=w`)Mg)$=n(%%C(dIoc;D#u!sS3scEkeT823})xa!2wUrp8CUcIMA2%kvA+ zkNaAtPI}|zaZ{#^eVIJ1PcyB1@0scMcMIK6IJQ%MQ~#y~aid3Ne?KZCX}MW`h#`nIqNa}K5X(+q*E1~I16 zeo5=!c|4{d>AZf1gkLz%PYz#NShVQ&qB%>*;c43kY`Fiiz#!s#;`c9!kN($jGH=8B z;y+3se6W@$pc_WyOC5eOBf*nEf;j2lj@H;vZ+Ja?Y=8RyTT&p0zD zFRyUU?A$_{q}S*tNH?_b6cR>y=*RW%Lw9W7zC&Ma-@e_BhCsE+Xa`0AD}5S=4~u*E^x-Y|Xw$KrlBqaX zz%_jV+n{e`eH(J$;}D=_jF)DSDrT=qa%dn)9xNG3)cST^Jc@?H?VQPW~x zJLCU>dhrn)|9UTZPfsn=We{Mb8>Q%O7^f0f2nK^PHn$Tj_7fwbu~^^*O(Xb zx`t;sj10VhI#TUo*zu1n3nDwQ{OE8QOJk4I2I1Yh$uUk9*Cu?wM_4S9WN%e&#bTkjwhzfhmKB>>b!I zgBv6eZK-J#S#M#G`+?FT(oj4b_To#+w{^U1a>60OZ_j~u=9u=e_LhyXAZo^aDWO%l z4#KfFGrqOE4WPJaliT)L>6iUe z1`aTvc*_Dik=3gUEnE-B$0K|$a}4!lMQg(NPK{%4*}6sjxh6Cqv!{vy%ksjQ94m2h ziUTv1F?zqD`a$v$=}$h?59ukS(+11Yqo#G&%gO6}n>sIllIcg&kCtulP3FgKP)yN| zfhJU~U{H?k?f}C5xI@Y3Hibl4&@kcGeb|o6gnD;Cenc{gZO`S$b6x}vVOgVys2Lmus8!vKeEkkSTGV9h>?iBkx?DH0~)n& z6x|50xa$C8226nP>tm#{`x;lf1AN>2M*9j_BqW{V%^g`d+YCT9Zw4Tw%N0H4&#T5cU{zZr|o)r1QV0nhda+Oappbw>~$-28bVf%+j!=g0*aA32jp{ene7# zE36d&|9I2SY`x`oz~5GzcnkQGeI+3WHp*&bzL}U9jJYc|fG_!SyLR9ug_#B$8YG|s(tC`=VZop z2+f$6p4bsE8|^Uw?Xg7g;d1byBY^)*=RbliU2r+P5& zO`ow2)=;$LFn)Rk+RuLk`6xj40CG8iRPcovkh?j>F_2qDyEw#y_OO(0Z=}Bk>^JdG z8)A89+f)0jZZ`n*tA)!5X*wg0TdwCfXS|>^|DArrqUs z42MLtLu*F@7daf4!%)FT!)n4Vhq3w6#NuX@o8F55ni0$1C!c%=g12At!2T~z&**hu zWV?vlrw;12scV}^j`*E-=32VhY~4uU(7EYxox+FAON;G<_CvHu`WCWGyNF&CYxk5J z^kXPOmho|=zJ+FqG~xPm9Je+Q^YU1i)E2TCwkpX1-Y1q>r+Qnpcjh_~V+BO6Kt__N z$rCrs8#uXB#}+->+d9X@4NSOiSl;|rO&@RM*R4(Tpm^BFJgE;OuV{axKH6*c0FU_y zw~z4}(R9AS`8Ih44y;o<`!|nk-Dkkx`dRL``g^nWwlUcKM4Vfl-?Qdy6Y>p_t3T16 z1_3d#EF2Eynp5t{7!GzihUb!=*cz2g-+yz-tbDTdKK%=}>H4KL`qke1y06Yzwu;jb zI~wRr*iCusqYW*9F*0-fXMJ=y^wBdhoWD$MrX5ETc%CECR}P16p*8k|i_TE!;BU(F zf1-oOY+m?UBQ3&B!|OxI*RyY%H94;kI(Rc_^5a=T9(+M>pfqYJ*7+ZUs zQ45|_OV<#);gJzSvo5`?-Rw1(tbcZHe*VlcrF!C3{}!jB;-92$_J}o;W)vKR2}PhaR4zkT2ApEK{l%4M7T!+4a_ki(xN_&AdLANO3RG%)xduT!=V z27N%lP@{RTQ@%Ck-pu&a{EXF4Sy=2N(?0r6zkKRE{9z4!XLMQnr3I7b6`Mb9ANo~` z7N6S9@qP54zdo(klHS#`&{MikMMShF)TZb`tZZ5xm){TpyFZ& z%!52ftYTS$Qf3WL3J&I0W9;yWtziNBY5%Z8I~yjm_e@8z9?)5LJp3?8p{>rI1??F0 zcR$0H`(w36pC`)`2E0bI607w_;f8KhEXaE_D%Pe48kHlUhtTTs<$3o@J71o6-=e8` zG%P5%x%*JDl%>p4Zd#rv;re0tgnLo{Td!^(dc0K&axt;z z>g~@zyI|>N$^R=LLuO&l!~N@G?)6{m?!D&fTn*!)l|j{TT?H4}ChT6qxDzc@>f8VR z4w~WLzdL?>>fE_gp`+FxGOauNy8Zj_XAd4S2RzHywl4#Q_S`1fQ-&DR_x~V69P7Cf z%3EXzx#FG(D+yxd5=3_NaN_PIK}rVEt9o#&h`fQjk6yTRK)=F;aNgMQ6Q+*J7!ySP zp_{(@Eu<}>2X;BWc;RVFVBgG~v7@GUX$wBchmA^*vekh0#Zz_|7AgiG@R_*PZHM6q z^p}vg5i>bqnBv&b2BR}>?ch!aqTX!nAS_eB`(9Fn)F#b}>kv6QW@t|5+(^@tQ8Z^0IoDJLCx$MXR zKEBwqcatnPu<@z~Hc#Z`Pe{RYm#knA*rm9JaB+L2K~Na zBeC`C7#*9`>vL+^`S6A(=PsQ`$)qjyacNy5ZT+Gxa~@f_V9e6|sj$Z2{nQ3iHvQ1@ z3C6!c&<{eh5)i#RAfSCfbO6jn_w)JbHa`DzZQ1eAU$~VUZuJu;v95hcAa!^PGxP=0 zm`cnfl03MYyiYW$U)xC+Ro<3eUY>nh<^1@_&attbBjYWfSPq+i9XV&t$WgQNvm#?- zBO~MEMLWdUnrsI>y~pb}(bHqR?nSzeFt_YXwjWYz{3v>mFYGWOg3=v${p!B1xTh)`>KKgLmlOG=+k(N4QczW7!62I}) zS2yl`aL0}Z$*>6%hP^X#+&G|zebbQnhoGl#|%-hb7ncsCz?~l(C%aIQV(SQ4V*z-eU`Y*^&%5FV-#GrBG50~AR(V^op`}1d= z+GqL)dw*%&@>tVgvbIzEA=8)588kW{d^H^F7(T$^mNtq87RIPY+9pUEZW_cl448B%oIEd`v{hcKHGboX&~(q zx3?N+S}1nGVat>lXXd`LK|lTN9SvWy1h(T_y|(`Cx37^^i(n~%aRC_RG01iAG7OIO zD#Oj9SiA(6!Xg$jT$Vu}TVD9Z*715N9Zy$pet*aE<*yOnkz0WV_Aksa-OEDZ6AULS z@p~r42dBrr&a1k(Bh8r-E+eip@;lnSP%P(Ua)TgW~k=EMENXzD9 zPsdp3N#1B9d^qBi6lh5C8_vG~zSDJ^32Q<~KN=ZWwZ#Nx9C(f~FFPSS^F$p>Z;d}?rvuvENp_G>d zOwz_W%{fEXpV{j2akm`pVX2wJ#M4-`1x-cmHBu=!Zq65w<{mSLN#sMuI789vp>~W^ zNP~$YeOT0uENhPbFXS+2F4AB$XXi#tlIDDVuu0T)2B!mj#;t>vP1LrF4#JK@zz%Cb z!Fx|h*xR}Nm&r6ZM~KNZ3s4u`c|O9YovbgB#uBX3fcK_%@=PJ>PNwPaN;9D#ou_H9 zJd?T8n9mq#v^jlyaO_;(^Mtb{)Ss{|6L7;~Q^37P!rj!0lZGTrGEFV=l4%x@dC=se z#O61ou~3x;a4%@)nL@xM^Eqs!(dNL<7GM&&a20G*#k0b;QPi>Yxx0XLk$mUxE-wIe za!lCc%eFOtjTA$Nq_G63G{8AK+%ttoKAaatK4csTg#sWD6M^Dm>q{vXUFyE8n9a+u8i~iY7O-wz;A`%(EKWD*fn9P%z$x<|J5azW+Pcx6gzbZ%+X#Wnm_k9f z&Z?!j=vHB|A%C8Rp9{EETg_oGQgPYFZ74)Lmube4cuCt1?lw1F_v3aJMm{VO2WPJZ z*X@ewoZK0`*Y?it{)5watH=*NFj3|h%w@c!8RW*3kQ?_2Ss-Q01ZSj_1y;8oPR{3B zEWRjHv==f_dj(@|aC%$Lzi|Cwcl$$zrzTn=>ORz4B>V~fEWAW(BDUr zO#MMYqu}IVPNQHqjlg|ut(mvs!Msdu!H-s6D~(kTD|tX~&S3MT((wFz^^GWXcZ_ec z?8Q{DQI?8Xu zRsMisa1Z`%50$(4HU>Dk$AO%$Yzn6)$xTKz;W#xh>Q0Oq1x{kjNXFU(PKE>%`HB9> z(gS7kb_&0b%M*B+A<8SJJB`_4q|xTj6P}ox-jv1?rPA>FeMwuybGoU2ggft9?q%p(C zH{)p_y9w0KRJ&{(;akbWw##8|A(mC(JPk83k26o~INQq85DGgY_{o7-_~Bcs zpu^QVM@C{lm|SJyid~q^J)n2WxV_guq=WvCe!)y0n?qJsrY-CTPk#^M4D6%&y1?MN z)1T^2Mh~wjn0uF>Z^Kg4(X&7WxOB$;g}uO~1^ny@Tm<-ry4-cByi4+N#9;L9g-ftF zbHW^b!!apv)nP#Hb(XgTdYRs(@4^^yqW75<>tYu70=UnZCIZ}deS9zeruQRN>xzAS z8pd%@sn!N(&3_L#{V}hAUcw|-cD>w+xQt6-bpuBe&?tHmwrMptoW<6B?^Boo42<~V z6N9m$1-F(KYQ?>|O8=++F8%iwr6VgFN3l0vtKaH#TPE$Tuht(Yv-QVmW*QdbTGH(6 zG4zfz`hh}rnbQ)!Q>=A>F+{sd(o%qDthtDe!yv5KIB48>Ez!D-m%vyq?GLBFShV5v z2NIqq01-H@^D}YHF6>V*)51J~k6MNKtU8`hoM8u$Nw|67%lere`dg!L7ER$Bl4?`eURSjf|WRvq-1Uz$T0?2(pd?c`=Vzu3aaLIdn=b*zP)+RPfIpIE z(GIOyV@@C~+Tqu@nIKg(X9p|TNLcO!M|-Ys^39r_i(PH2`B|`-4YaR@T`b^@$C*EY zS~%Y@*il}_W7i-wZcs4_T1!1IJI!$J;{^Q${R-1hTd-935>Ar~f`PgI)#G;izk*X#-r2X0q@zs)l9BuM(feP2c{e@M5cl>=ufNObzZ(423H0|hY$=5b z*Py@PFR+KFEj7muZYi+Q(Jc1Gi``Y6l_;(Zv;pOR1 zTX}s4@bYjTF0XR0A_W)oB0bkEp|_{P$Q}iImlw}?x$ZI#G}EtMgYYrRy&i*YmfVpH z+IwrrrC)IAhnmC+HZR(1`P#tNfz9H)KC#G-g=`N4j~m-R^rs%DIAPTT&0Q{v0VwQ_ zmo?U!?*6v{Hm%=WZ>ZIaakFIgDjX%=aPIFT$DF344d?Xk_Y~$X*3D_L{(PHd>=}%#&_w* z!wS`E!4{vy#1?KHIhHi&+#dX4?CG>FTDYq=ypc7ZjAwFPy`4 z{X$L1d3aR|JO3aYBd_cpXzOSBa9PKu_bxHV4mi7YNyzG_o?0EUWGnb19A^n$!dX+i z&l==vL1G_*;i1G}V^8yPNN*@hxiE)i9>xP+9TqT1;;bv0QaFRqM2FRJd2WW;%tE)K zK{c$l2cM&stc@17ifOe{0{Mc>p*nS>+JTl7+5&m~;N0Wq=L!*u6z{mims*yS-z z-$hDK&LJJ=o+72Vo{DFi^#UH~Fqk-tE8GPM$5q_62`h@?Z19~S6PENEu_{Ou34!ON!*zzfxcf9(v zrPt7ry)#qx@_sK}pJCnvf0^wuL+fjdON9V3T9+707}Y48;lLzLkVp()`M?5ee%OHu zT>v-`3rxK{DAbWZ-x=%iq$|c4?o(y?@H7~1*I)}25s7-_ojJA1JzrMoTF<6jWx=-| zmmlfJ_IFMRB^^W4Blmyt#k-N2q57H7^iJAy;4t(?p*{p7m>j!(~Gr-)~|Ka~XU7f%VT(MjvHt|Kn(f z9nhDw2CsYcB|-`s#PE>QzEbY+QF&tzTwx{PIhKUv_L7c}+`@!+|k3aMFYcljz^aUVZTkod4EvM*nPlTKXg|7m2n6e$C8~-(iN$o|iqGAtLOi zYPfX^-~gg8^PD7L>VvKGFbc&u1wJXm_~1{iukmVt3kKI7Ti1ovtY0}*va5HWH;YeU zmtd#-DKqAhh&j`y7Mkt#L1+IQl{IqopJ&o=8Y~YSyP$N#|jM$4nrd zM~xaX!qlhX_S2U#@$b@UdUwO^3(CqC@Oa^T9&6MIEvhNQ(hB4BHbx5(n?#KkV!-DJ z3Kacy5Ii2c*EBKG2;{^UBMrAu2w$?~=N6X<-^ z{Gtn}+r{YRMZaR)MBq&XZ_-=@ib}wZBREVPjm(c1=RJ$PvFKksIU7fadtwvj<)wh1 zThm4`8b6bU#M>|g4%1p#v71+{HuJ4WVvRj1yoH6o3bKhUeB`-3B$;T$hlDnTLu9`d z>+gCTI~s;PeeasZexwa;qMz4w{hGdK4>uoX69bVlTfh3J<>5^yo(n!3^TLVsn=F^n zD~}a>gWX)icfon=F2=3Bbu~Z2s)Hb5B8+L98~d4HL;(+RV*X^|z z-Hed$KKm2?r2m>SdRC5=lD_)K)SNSWLOwM;}biLUcPCmNm7%~62*OFbbW{!E6 zxp>Xw;g)C55c8LMKQvkVW3VUs*&GHtIX+%&kNt9Yz|Cz-!6~8z7(8T5J{=l-x;c*W zA3OHEJCfDLcaMEdytnY=8?*usBU12+;1qF8D!9U|*u>Tu%gusy%whU#`c?gR-A=M_ z4r&0Z|8&FJ=O2FL#fG(X(aW1QJxj-7dh|4z28Zz$OptJJf&S;W-CjF&>b06KFP}R3 z3dalQd6))(CnR3WfLE}>%d77*nmGsBLySAVhf3M8od0A61K0M!*!6x{UCrNhXYht# zTILAk@2}t$7s8$ui9M%2cQ+e)lD*|!Wk!3aGPqD2S>Gtx`CM{fnbZi>@XI|;!EiwCZ~izksuk?|qsCKl|b z(tkfyWbf10K8JU|ekUwb@W2*-I;{RDQh%Y|L{F|bC}Q(w#H&MWUveke9>KDdNR#Y6WtSGO1 z>7~l@ips+k735Dh!Dl4RTV0NErx@2+t2UMkACap_&rT?i8z z!Jt-y743rMg;UQ8oh)&bsNFk0n^coRc|Dl`l(fHNQ8@yV1I9G z%BhdUp7mchb#vd*h4-LsmExQwob`xxi!R&?As^<7vAn@W!bs7$5qe5vw(Bzd^Yh`F zU`J3hp$GFmDV;08JT?J1B0KO+5J1RDh&;Q`@wen%=)_MZuKj#Cc_-iIq;7A2YCj!!`4%WtqeEPn_Cg z?4mdn`6ALw!a31r+zW|IL zIkI`r-iD`m-w#;l>b2||2Ad&Th6`4&p2gL~(Vuv(B++2ePta&jrUKEy)~?-kT)Ydw z*a$r(9xySCo74iBRTFWN9&$rqA*7w~WtFX;Z$E;9{M}qY&ji&H3M%fpD5e^wG z--+j~^et9@er6pzEuWh=i09+=NK-Aw$Pr|}d`|9m-j8ujrXI!hOGtl4J@4w|{;;r) zX5sbY&;3vE`tTZhd5x=G>r_0M(aGZMA)(G}O@5yy0-R;=Gls{f1E3n*d!4D@ipD8Mori2&HR`Co-m z`c<1ys-Mv->5lw5DDt+E75W`ylRg*95IvV{)oDW&=*jtfXQL3%v89&l+QH*>?2l^| zj8o5GB!?C({VHHp=Y}0r-kuiVj=^J|0z%%3<+;!@ci8OB^qVmw0pptLce!=tmbVYlTE09k+%oPPs{-=W^)zvq`kF; zl4FIMz>xP|3zTl9Z?%J2_}NI@z}wRyHk^}q><>gYva_puSnlWl9Q_^2>V%^(on1r^PpHnmEpqJUDywkdeV1J9g?!?j{kRVIDHYOlyxnci^+@l;z+k zgwKB_ee~UW!&~eAnbEir^-D>{W@q!wy4 z6hSBB#+y#Ux!8Y8rzrRNIQG!Moju$Ha@azpBP2y9;YuqQbmB(T&6+3iJ$7PZ5zJ4U z6I23utQ{l7YfdiHAGxm$>9=-pgZ|Mk?^t@L+*@jnjeGa;ZJ%VObR5}L|J>Ha(lsHv zhowh+%hs)1wjzD6Og#)g5A>{cW&ZSab|03wed?xNzv%ydvOd?IZnct%2PZ8wnTp0f zHfT||jtlraZ>rwY^sP9HIRf;8TqQ3%AHwqiIAr2C6F-ZY+okj8{rPj}uX>E75%?~G z_L9%(N6t-nzEAIED&grVY(zx*ADmAhpJ3e7S#d@>m)oenY}%jf;T9&X8#OU(#l%{M zB}mF}o`&p&mvf%RN2Wo$T&3^iXV{`$!rO!LQzg1ggW5Q_k(pyxJvJ zlZ6`gCXYPL`Cd|&fd(2T{ve@QH)v;g?@1mhK=;WHJtLiFlX6nXdWY#Jum8hk$zgP% z?=(Dvg}v7)%rdzwT%mt$%0qi?&Mh7k%tGQB{N~lE3MDLuxoJQ!hqI4F4pIo`fy>* z>s{%PsD+&q{iV{q;9lCQiubTTjNtEK4>m`8SDtI#iCdxBJ1J{$_qXN?NQ-Z|T~D(l zt|{mQ#g;oI$`tko7H;o#T;w@lTSHQKJ-2Ao%-{u)#@fV{W{x(OOy#+?;c2)PdJ8Dt zKwcw1>o6lN?Axkj+Au3m3vDO2z2SACX>G_*)QJ2C6IOLiVCe_%0OB##Oc({oYbM5} z^4f&;`egOojJh1At}S?;qpq!57*17`>3xvr{p#8mYs(wewI5cQx2o$Vn8UxWuKgjy zEQQ5MsP$pB)X z#P;Pms02Ou2P$o0d00+ZMOjX6-n^W$xnU)fNLt3ou^By(5<;;APT(p~?YUrr3WP8W980uP7~qxRc!qqfK)fA< zXC=5R((;fZPK$wIZybgeCE84c3WQXIBIM$kvX57aFjtyBDu?+0@cuTGQU(_-g~+oQ z<#Clp-9CbWB6$)R`@OQfo$-_nr0J>=L57rXn=zu zA(~;<)g02NC06)bW1Xul=JTPDQDN|n+5tXlIzdK7VAUiF^X9JDKh+&T^aNm%vEot9 zHhA<+!f2;AQ0$AdQ~PTJ;KL;uR(u)ifB0423Kk4(|*jp?e;MlX}MhschI0 z-iA5q1oX3$w8=Pqd#W}~o370OiC)#7fz8Zn?Op8=?I)Z&@&L|Qe*$)?&l0BHOH5eR zdI(nizhfuMquN?x*1prOYENn}Ykz8gXn$!>Yp-daYoBU6!1}XrzHqK~5Y_mZc0fC- z9nubKN3=RH)N!p^I|kX9uU*j|)V|Wb)J~wve%5}`?m-_^2*#U-YAM#Xqmt&M(m1!bV>VF+lz$)PRHp@`jEb)AKa4-AOp2p?FX!+rI1vT z2HkxI$s~iwU^0XZCBw*YGJ!j1{52SQuO;`8 zd&zy|ezFcn1mTQd@*vqr9wHBuP2>^sC=AdZBaf3UFh+ZVJW00Uob#v1)8rZQEF6wL zPhKD|!f5Pe`1RR_<1Sw#JK&nlPIeLpd4udCZ<5{QEwYEaP4<#^$UgEed5`SJ{@xF? zE#yNucB>*ElTXN}87 zlIx_NG!Pxfyla$DxbC1PYNjwNrH!Z$ZA^WsA8kVYX#fqRLGabmls2OwFq3LQThdmv zHEl!N(sneIwx?kT9G&Z49qVs4mEup1!J}sl=w1QUB z1#}@@L~o~y=@NPeT}qeH<@8Rvg07@@(N%OcT|@7tYw11oUV0zBpRS`1(Dif!eUNUX z57CF|Ci)0{ly0Vv(Z}f)x|KdbpM(?L?er=7G<}9XOP{09(--KA^d*Jo}gdRujx1RBt1pHrKjl``W>uFzo%zuE&YN1NYByp^aA~f z*3pafXL^bLLVu-~=@ojF{ziYNf6zbaU-WPK54}eJrPpaaZJ;`JGK~>N8Dl1#7hz#m z)`C4+HUPFt%|kNc45Eh z$2g_wL+x%Biak4@u=XrWdr#Ys{kQvA2i8&hn{{HHSpW! zDJ+$xv2>QfGT9(Dm>Byg=`VKoh@cd*d1&s zTgH~NJJ|}hlHJ8tvDIu1yPK_L_pp1}ee8a=jy=HEvkmM)wvj!=9%h@^BkWPO89o3X zXIt1-_5^#9ZDZTnQ|xK>411P6$DU^|uou}&>}B=}dzHP$cCgo(o$X`}_6FO<-ekMk zTWk+|o9$)quzl=Z_8!~M-e(`M57|eoihayJVV|^!@`eqwd(BKw(LV!yCo*=2Tx zU1h(q-`OARPxcr4oBhMCv47chR?ixk&YUI3J$zrnN{5c;}W0Nn=ZfRoj zHwBmiO+lt$)5vkdhg&O)3u9tZ(k=6HW|fr``wCcU6i-Tcb5BFlo1<~qT*Cb`m7w3WyzIM zIttFIz#WgQ8LC8#w>dzT3|V5Hh#F_)mQ>`-;@~yTb6r|96dZXnwq(eR^F-u3$PI~a zzWZ826Bnc6SieCS#m~!;x%=gN-1rW5f8|@?zBUb>nNwyez>j4}MPX5Ho~2Mk)*%Xq zLWRQ+i9?~J+7Jb8p^O_3aUnv745fv0e22P=@SWqn_8aB_liysgoBXo8yyBvq;@rYn zmf<VPNcnxS{C=dzCw|2qH%9~Yk_624j zQju4bSD53MQCeOIw8i5_85QdN5J(O2$S-SNAr~w1W}HXj##!_7@@1l+LL~Pp%Ph(= zrRG)Sm+7*$^A$MZ4Z2v7-(`^Gsg^!@TY@Mr`8 zBvCjP;;LDtd~bXz9-77XrkO}?&KD@<3Y1h{rp0){_)DlQfD+HlJXfGpBv6udl$u71 zE9s&_Yl*~*l@*j&$~jW8W)ZOp;HJuFrNCCksaB}9D-YS-TS3->B;)IxV z^*lqxnKF)5<;AMWAv%H^Ah*SB-sr=$pe(?(Kc=dg}f;V2}6R+TmS8&EFIOA1*@e0m( zm2bR}uYxl{<)5J7Oi<+{sB#iiISC5h1O;z`DmOuuo1n@|P~|14@)A^e393AsD$l0M zv#IiIsyv&jf14`TrpmRca&4+yn=03)@U^M(ZK`~mD&MBcx2f_IRe6aj-$a#fqRKZ> z<(sJTO;q_Ns(cewzKJT|M3rxn!YfJPm89TLQu!yT{F7AvNh<#&m47eweJ}NWF9l~W zMVDTRF1=K~y%hYtRKC4bzP(hwy^MSn+`U!)y;c6bRsOwI{=L^3zrM>8kv6ReriEKV6lduF6kW<)^Fi(^dKDs{9O9eukoFhAKZp zm7k%?&rs!OsPZ#Z`57wz43&R|$~RNxm#Ol}RQY78d@@x&nJS-5g-52sBU9m#sqn~D zL&Aqx&?PoQ%2ULdmhocvWLYSq@nQ&N zStuf(@kUqbv(UKWaz8dBMbsN&m7i=^xEJ(BEbv7v@I@@}MJ(_|Ea;6`;EPz$8?nF_ zv7k3%L2twYU&I36*bLbY5v%fLJH)*zU$#TstMX+##JwtCwnN;j@?|^3y((X}L)@$K zQ&st?s(jflV>8lJ`DvoQaj(ixQ~1kvi{}b|*=}*K@R#it_X>a6ZgH>hm+cn!s(jgQ zV>4vCMXbt~?H2c{eA#Ysuke@c7WWE&*=}*K@R#it_X>a6ZgH>hm+cn!3V+#dV>4vC zMXd0b?H2b6f7xzvuke@c7WWGO3{`%H!aqZmFWWWJsq!-v{<3|?W@IY<%Z#;5l#F}3 zh$MH)){ayPd)eA?udtV`9rv>IOxf$l#mH8ISWp$QzzVUTDq?{ZVv#RmffZtrFJgfe zVv#RmffZtb71jf7O~lF_W;M`-%q(g$zY^07t^g^+svd_uE+)=qnO9iM=iB9&(-i0W zU}41ReoB4OvwYsHQlH$M^1_^wMTI#&BI}+&rcrTWah|v+FI*&3%`T}d6IYD| zc;d2A#ljMK0pMk_#d&4&k!6y2V3{bR2{IZlquXROPDa@>8Y`nQG8!!+ACX^CapgQq zmV7=^M2#@TD=+6W_Yv~(a2XAg(NGx;kSw2*LoU`!05w9suPf>ULLe(d~^bwUTufTRP9p?a% zPH>;Rl#C)03QplymQjKzKAd62l~wQ#m`Oh27lMZ>OMMgzRhC)>2jPiZEg@J5i6tlD zmE=WmYGcKp{89oV_*Y$4mNqf)7L@aqT1Np2^aKSGI4{ZouySKLa)int7L>sZ8nleAfRxu~HWap#-iQJ7S_i06SBHx%Zd;Z=a|5RdPM zcmO%%#_xuBe>c(%vu~D19$6lFWZjU5Zj1ZEStXQ; zIhD|zTcC$NS-u=3I7)scV2FzmH$k2nW$`4?Lz67Om5O6=9qgqpRIfdogO*HWD;uKkoU zSG{mkyRp#YipK#Ekn^BgpIKBclTC7$6yR38s&{S%^`Gd)?SUSeT#+`=L**+T_$i&R zxZz`hm;^O3Nl+7ugjmsQ$0Wpxp$rr{qBlpZp2vwH4erH|2C*2@AXXEiI5`1Hh!;bq zn1p!sUA)RqscRDw)bj-OeWIH9C93ZdRk?{OU7{Fb#Uv!jiBv+8dY`1;C#n3C6dXxn zposKhpomz()k{6^rJnav&wHzUdaH7JtNeP4p*yJ?AjvwyBm*BoJ>}b+8nw~j4TSLcOQ4AX#6F2BV3jW@GjW6fsl@)9L@)z&; zdx8|)7Kmz%ZyNvW zPiQCv=Q3prtg4p*u zp62w4nAvF>?iNHIi9Q6_jzk{mv=&g#?7TJh8~(>(;}~JmfqIaX6I8;t{28YRrz-#B z-$l%Hr7Vize;(BSzq!7t25zhok6JKl!-zo}UJC+V4zmiEI4^qqHH+#RH7aUmR8iE* zsI^f$qTY}CBI>6u!Cg9a>Dncs%cL$dx*qAS0gJso`*0dZ{}wYmHX?3g?C{w4IHiCu z|9g+)3HnFy7#y~j|7iriGR?xu&C_a4+N;IE`zyCqyU|iD9rkJ5Hf^M^MjPj{LYoE~ zio1mM*&29Iy$5Ht-3Ke%b+C(g7#0zaz~XE(JZWx)J=&AnHrSdyqdg0&iRWQ6@iMF~ zUWM%$x5VI98GE$-+WXoEu*mpGtAcIDC$LH5R%nM{fmW@3AuP_m(!Pc@)Jg4>vWNN$ z_FvawGv*|OTa3A^#ah5htPSZzB47*F6?R}fNet}25@7pfSbp^<1BHdxXjp0G3HvNz zo24wX%7r}^x5e_Z#Ddk;eZtae18l4|Df_A|!nSI=vaEVuSyCAmRC~Ovr#^(mlwmLB zX({zJ?4!=OY@^O8t0-<0#Vw+^CDb);0VQmm0+cmVC@h&ezGt%vT0-Ozpi>o!CGm95YbSOy)xg#{3|@DcVs!lK99UWQxCqzfyV zk+6*!2U{1njmWL+Lu!>($Yo&#@)xTY79Yya12&w!VZ+%6y+=RTac4mrt zLLtI(gwV2sOAri|_-&Ijt3T;J08uA-{uKfc}magwPJ5lXEIs zPctpuxes2G4rzlB1|tkb7~?#EoiB&9an4$8g7X4SQu$Gvg0K?b+=Z|TVKu@Ugu4-* zMjp=~Jd5xg!t)3(AiRV;UPgEY;Z=m!5OyK&HxYItyoIm_;T@E*58+*e_Yn4@tPc=A zMBX1EpDM&3BmM;Or-(mCJ_ivFBOFCIhHwJmYlM>s-y)nrs6jZ3@B_j*=OGf{JV1gF znj(bYzLVCBL?Co?ULZXXq7h;d;t^~Jy`4Xjbfn9~^_5$L)_~ro0Jchi!#QSgY{5!8VKl;2=K(qc>2eTe zB9!9Ue1tNDI}lKhbQQi?hxh@+>k)52{2=0uh#x}yFyc*!A3^*m;?0O3L;N`6Er_=w zegg56h_@l$j`%6W;0O8)V(s4?VQzr!d3Lm210 zn;q4fv1$a+oSk6bph5PG>8=QwsW&|sEvb~n%JgN1@i4lFAby`2?+uAng+oY58 zB#A&sbk>nxxbK5dh_D=CHNpYsNg9RF)%iB}jOJjtpNE;wu0PY8dZ+*T<4EK0wKl0QYspQ2` z)K5|BrzrI-O8OKfeTtGkMM2+x7 zb!h2zXz6um>2+x7b!h2zXz6um>2+x7b!h2zXz6um-F0ZWb!eS+Xqk0rjdf^^b!c&Q zXl-?9X?196b!cgIXjye=S#@YVb!a_xXgzgkEp=!ub!aVhXf1W%;yQ3~9k{p-TwDh( zt^*g>fs5wMI@CoS>Y@&HQHQ#yLtWINF6yuw zV3Kn)>*IWx^>bFU{?1p}0O!wapmQfnbzWiV2qSR1&uHgWa9wlkB^ZKT0^_kqU=l(j ze0!GM>HLs94Gv5N)Sw>H|Ah1xkv;&uQH1lV))gTRApzkYgohC}Av}WcD8goh#}Ph5 zIDl{n;RwQa2;U>rBK+vQO8gN55rPq#A*3M;M<_rjM_7!2(^kprh(AI2+a)&kR7U|I`IYk_GkFs%iqwZOC%nAQT* zT3}iWOlyH@EikPGrnSJd7MRuo(^_C!3%b7rY?}hxT3}lXY-@pSEwHTxwza^v7TDGT z+ge~-3v6qFZ7r~^1-7-owiejd0^3?(TMKM!fo(0Ytp&EVz_u3H)&kpFU|S1pYk_So zu&u=ypc7HEV z)<7B^M6XzbUaQ|NQv*qN5R&d7B;7$s zx`XTsNcG>G2TU4pib9)Pi8i+qZEhtntpbKsz_1D!Rsq8*U|0nVtAJe*aUL;SU726>jzk+Q13bOI5|I^;R$H`HY zdjs$8nO(xNY%*CwxGE|jM?9b+A{P-6Q9LLF@F*ak1A-`uq9W))f|Az@UWkYa2ngX4 z1QAd`53+JexF^68E}LYt$+A0}-O0|3dtv2H`h2T)6B0pD-+$ge-s#WN{Y*`FPgOln zKhLkKy6RyYJCcL*mB|crNZy_t>Ufy6PvncCvM#8si{0#CH#^wP4tBGH-Rwwia^B6( z|2_Hx`X6))YIEJ6&~4~;bcgHbp$A;E5Iuz2(IWH&T8x&WWoS9-Mm?yER^}aPW4`C~E^mFq{`qR80vg%4N$m`HmdwOABX45;^^bR$*0?JyP&dKj#y&g=j$e&2(`hJ!3 ze&zU>dpz#ECmcJ_Vzd->qGitMa$Js9IOj?K(TndxE71U2g{pq5p+Dn?9RK3@40;wl zmv?28(1vKEyn`?4$TrJYX0J!vp*N!){kFH`K4?Gm5$7C)W}w4;KN204w?k}Q5L*|- z)|DME?X&1}=u6J~GWrTS9er2YRgPC9vgeaJ_@oX#se@1I;FCHat9Hn$9kOcA?nLv^ z-RNF)zuy<22hqd6KjQdkz8JDvoOPfjs1tRe6-d26R$Y))7i85{P*;Wiyq%Bh;Nv>@ zxQ=22+JKIonl$8(CrxPoyiSwrG`UWb>om7cb89rWgXVV7+&ayz)7(1Et<&5(4Xx48 z8V#+{&>9WxprIW!v`$0oG_+1b>ol}ZL+doOPDAT7v`$0oG_+1b>ol}ZL+iA#P77DEcNPP%o{t-}Bf`D~J% zog845qfc0Q`tZDsB-==Bh}4EiZHUx{NUe?3+SL4znjcd0Lu!6V%@3*hAvNEo)`!&k zY&AZlw%gQpHG0AG@fWK3OY$4l@(`=|xLO`k%R_3nO^vpx(Ka>OrY76eUYpu$Q+sVn zKcw_SN1QkbY`sX6wU|q2 zYqWn}rpIM^T&BlmdR(TvWx89YyJfmtrn_Z2TBf6AI$EZqWjb1>qh&f;rlVy#TBf6A zI$EZqWjb1>qh&f;riW$vSEhUAsB;%P{t`WoR-h`Xp`pA?kIM9@Ooz&Js7!~-^rlR2 z%Jim8Z_4zhOmE8crc7_j^rlR2%Jim8Z_4zhOmE8crc7_j+4ITtY_*<(44J=9{$=tn zlYg1~%j93?t1f}_&w%+`VEz{M(x+bf)Jq>U*`jXxc&P#P)2HXH+3e3|_0*@H`qWdO zdg@b8eLT|u&osa@4e(3@Jd-xRbLXK4{Js!9gxb*}^aNUrmZD{7IqF6|sEk%>D^K=( zmQX92=KJpEyzl2YBWY2ued@I@JzLsre)fFFUpVhV$BU)^5?$iFtE4@SU*@>N@kzf| z9cyR^J!j7QBoyYpZ=`)W8SRMwh~q(M20BVR^k`|vpiiMMN&7PT3OXHKg|0^Ggk1W_ zrH@?t$fb{5`dIA&R(pWe9$>WxSnUB;dw|s*AhSL)>m##1R(pWl`Z9UUdQl(hN6#iL z+FdQ$T`k&OE!tfz+FdQ$T`l6FOfI|!y;rMqpL}cr=MTd9s|qu;6+V{VMDBeo`vBSZ zk$oT8_mO=c%RZpBccd2SQEG56v^UxZUB+kjb^bKRxNEC;jxKpPuy7j|%;$(2olJ zsL+oJ{ix873jL_ij|%;$(2olJsL+oJ{ix87e)`c*KlF>nMl;>0(2dFj;uxkE z{dA&2Co1ea>%;zE!M?>s5 zOxDe0-AvZaWZg{G&1Bt7jumq3C&vmoR>-kJjumpGCFD3vj>F_QOpe3kI827aWH?NQ z!(=#2hQnkyOoqdHLk`bJ<5iz@JW4C+4##=uhl(kz~ zyOp&^Syw1)Pqvre4srZE`Wl+)clXO?N$U#r*#Z28}pQo zCG+UP?r4T*;B3e9QFnYo$2^^5p3X5(=a{E+43--6RE~Kn$LRN%r*h0wIp(Px^Hh#y z&(e+O&pe)<;P z2i=DraPC6%5Nb#Ig?ZyDZ(QY#tGscQH?H!=Ro=Lol+j8yd4052oj_|8CJCQa3_U z&n`i8koq?w5?XXsD4?3Db10w+1yrGcDilzK0;;cp0IS&o=RAnU5n%OI5a48}U@}xN z87i0z6-J+6&Lnh7Yf&haV>E!_ceg*T1Sa)5vu{v_?PH=tR_oWQwP` zD(5TYe1)fa9bHJo4^wAB_Pg*0yQ00M?d!O%?2q&POU_v%?;z(hq|I{fYsu|?=dO{> zBkFWnGA-71sOM+$AFf-^$u<*ss?JJ}u7{=8;HM=#_&A2D)8vs?!BJ$PNBdARSRYG~ ziS)n5Q_DhR9CqX>ZTXa}n)r%#zM`F9XlK{k+4XjIy`5ceXV=@=^>%jMInG?^%$3eu z>CBbRT=QmJdk`r%-EUvp*;V4lB@GyCb#D2q~FS~g#w1s zALqxXKh2NT#{YhLQGQH%Nq%KIN7`li-1PGN)6n*D>7)7ux~2E~Udcb34m$7o{L`M_ zuV-84-^t#9-!(rj+YP-tKP%fkpOJkOCOauVIQwdTMs{j`Np@O(Y&J6~k>AYhoBY$B z+9Z3yEbm48KJpU}e_L)LWkH}E| zIdYs^&}RUheavc2N8~?FzOZ_JGIRBPRxX{Rr0-YKos=}-okzs=9Z=FwDCxV!bX~5b zUrgsnyDUE>y?ph`^orHJO1h(x9-Q|3URgbu4m$67;ea+?y;@1P%-(?Cb#-sH8+v!X zjVOfkmGqCdqw1O0&K>sxTwto#8z7CS55?LlVn^I>E&OKyKfE{o-M7{0tBJ0+h7a~&p^-zw~p zf1NBA8>PD2C{>WjZT@Y{zl{|ZC7a6O*~td(R#(OmWgKzU5J?Ov!-!uOc~kBPHVpoC zpF#Jj>z(L^K2kZYSm$a(%C{*E{XPx7n}&X!+nxlra$^IOR9cG`NTQih)9TgmWI+8TPBuPUVZ`LwGhCnHKS zqVBF$nroHjT6K559GztJk6(@`IP^MP#E0o|Q2#^f{|4i4XXSUL|Lr-S$>#nXBAuCc zy62c{2g&m;?*<;BJPqz$ckjA;*WJ5rY_28QP|LoxuowIO9>@36-!zh=LIyYE4l_LAfGM0pO!lpZNVQYz}D-@oiZW_#*w z7(XZUIE*AsQm=B}!%}}u8&)~@hKX|4l(RZf&P~=UK}1L~hYOTr{C}$4!hTIyy{`AlQrb?*tL1^`vR@32Paxt3)$x0+)Zm_A^Y45Mfbw@ z3*h?&arA3<-@^#ljC`Kf$-;De#4EJG7DCy*P_?BMcUe3?ZimkOnr629QW6-D2vC=~e?nLP) zdq3iaXmau#O&j?a23pF=O87tu@kJobDZ zdp=M5V}bU^f{7O2U}1@OB=jYF4#Rr{4;Ct@rj-<0e@{t&+PTl7EqRI7t(v!WJnREtZkkGHKA{kGS?`4*&S zBGEIU7CY%`r^ zopU$37wJ!EIySmNPZFV;LG5QJmDKbu;e z!s#@_x>7tMnH2PMd+s_tcb$b*czx5frL*w7Q&@j-xpxniBfVdcDsug|_t4 zmJ)3#(UuZzDbbb^Z7I=+UK&xN5hWT?BH=ZCYQe(wl5UA)OQhOMswGk_k!XoDd($&v z?(aC>?05^mcB}Ne@UhR$@gex2o%MsMJd0&g?IYC^sg_7G^uYy-*PHDGUyt{{^}y$$ z53Ywa`$%#MNtQ^mha~$*vP6=l>=5b4N;^*4=kea8Ajw{moI;ABZ>~&=Q%JEyiX~Dk zkz$DyOQcvL#S$r&NU=nUB~ldd80qaL#S*Cmiy5qCu#~+dGTyHju*sv)(PMg8L*HJ& z_~9*!3L2F@-mh2oqW_elkpk=RHWx$B_l8P;uTqs+kEL?^fZVQ<)7f(RfIHpdiN6Ob z*$sAqBFJQf94el)iYIM^97fdth&mrp-y`Zb^deQ%--!AfQFj%29+Bq}c^;AH5qYlA zqF_%d*7Q7>g`I);55BF=>IQ3DV{L1!ZH=`J7B*Pd8mn4kRcowjja99&sx?-%#;Vp> z)ta(Y`LH^xT4PmftZI!_t+A@!1V(>B&!A^nxy{h)(RS#~XlIyiZ^wPmekinGcmftQ zSj`%%Sz|S8{8?yU)>zFNgjD5s>MZ0a3po_pFzTzu$JArZ4$`YZdNW982I<_tz{u!!P>uoUPLeXj|QYZtd88BUmx%DRXI47H8=y3=*b`R&rkT* z*%2#GhbcFKCzl5-312)0lRXBjJO*DpRtRl_Mo2Lr{XX}rxW_7`xYzZo*xV!XKfs!8 z&bZ32*Fk{`{Ns1or$=~;@A=nny5elMsOH{laConK_rdg!$jy~i^!Yg=YlT|CO_o^$?r_iJp;P9$QKK z!uspt{zb`F{Y=Y-%)vD>#c3Z05wm`eB({=Y` zTk7q61AbRlcsEvecO%Xx<-gNTTdMW436y)OR?9T?bcuFXyY|*%t(49r+hEf$b7sTy zCO>Z+Vr#Q$p2!c$Z^*CASLN5_*O)K!4}Vsd|KU^r?uogP$NUVa{Ga~l=l&-?p4_z` z|2dF9tn^nq_U8|+{o!vi`BTmw^z$a`pOV*D{J;6p1N49K33t|y|B8#^Z_Nx(+{HyMH59-T*_;UI<=bm~;{D#(iR?o_B%9rNH`(9d; z=8Vf;<^z{soO?d<>vAnP&t%w=eAoEPeAi!^8+*u)^SzWGpV#xb-T-b^B!eZQ|OWvbCQG4#>uTY| zFZ3!%`PIuAwDj+N*pR>R(cAQQKicizODrX2P^_pJObzXvS{&q;h%c8tHwi~FP5vHr;25ccbT zVhyRKzyHy9wa#blv$js!y6m{siB>!&uYCg2bZ;X-Vf?4WC$3r5{pHzl>(7h}^Wye5 zGwwguuGAjp#vK{gXa8qr!(Fp>KHN>Om=SlE*>GVl+yiFAEu2`Bz5Q>_i5sw{`^&T9 z8m+9}B(Up0H#=@(U36=rA7I7v@%eF9E|060hq-ZKUR+q8{7f_A&N3tJC+5Qa!aC!x zoc%VwZuq+M-WJ8R!NYvF6>%-_0V{xy&vcuZ=N4zVjj!1K$~kVkS#kS-?6qgOeLJp= z9cH-Awj%bqR>M9oyTCfw7h3~+j`go!d-dyobtc=|wW{MP)nSe5u%2;P$=KVSRxp0W z47I{b>&;Qi(kXN=%zG}`QaZS`{dTs@`^?*$Ul1k_7rlYK13mqBTcbz=JLv}vffFVP zeee#y?qb`}JLtR7i1GW-<-e1gv z57}Dj^?&eRAqv4JW_}*xxjocY5{)3tbvWEMowgro#=|FV(?umX${d^T+r%C)546Ed z&~xSIXXb$x%>=zfPA;{zm<#$V|9FjUD&4=%f8Au;g!bR!U+%C?PwuppyuCILf0u2F zC*dCZ`)pG@5%>F-2W(S484K_WZBsoV58@xPO*MD)VSKx7swd_Vd3e-TG@JBsd3(av zDw=_QS~E)*B?WSf-a zwn^rrruL0#qt?QtbdtTN(7q*Yu>|#G(G8}VtvUr?N=x{u=~R4c+KQi^P8SRSw@tTAn#^Y1-hPL42m80AZ_yHZYx-9Eozk7`-?)db&2`8R;2v z`%UvITUd)TlZ{!7@8Hi$&r%y_8;73Gdi(@`zPAUbvm(Dx0~e+G4p@_`@V`l~^Doz@ z*Zaqt(wmg)=JfaC2K^!Zga5ik@5ol76Z}c8ZcA@-&h6>#&Yz#o_v^jsy>fDYdcT}J z5TfmfRIosP7N!g3WKp_E86Qg@OSTrR;Bl?1WvPA#mT9?vUy-gzrm|2^%2iL=qZK%i z4kWK*ttx(Hv7GLpKIhCA(if5~g9Y=}=N8!(W{qx{ZJBH>`oLEB*JZCu zHZX5@8~ZnAZ?xaRyu&7Qc;BL>xTDeY>EaN)6~B|7n~lxs-8tDz3vkzt;)bDaY zMlS5%fk}f|z8}#qc2IVZ{fume{UO;Qt~xY3)K#C%KA9BF{yi$0W(M$o>3ccady~^e z9r(1I9G@L8SD(v1Xa9LUJsXQZaH6ZeoqgN=zngv6KYlO!o)P))oB!I(j{eYob~f9u z=Va&DpPQX)|Fi68_UC2i*{0Y zmc*|#Q@BN(gMR!#HsEg0dm}g%$zZk75^)UdAJy}PO3|NfA<|B02ZWGOQ^mG9 z6F*B2Z;0-D7Cv~pR^BdP=-}sC#fJC={z6-8^m)^w&udENB$r7Kp0AKxZA*B+>*VTs z@hOt%{~DtIYfS!_+$yClxn16ZFDyl0m_%P#(yKh*zXy+4(7Sv$KKR9gUgmr8!8;bB zcWjN`u^7E$YxIuA=p9?5cPvKl*c!cKF?z>DjGr(999COMqIWDt@0djISd88=iQcgo zy<-x+V=;QiBzni9=t3)$y4zM1ujWa7kF6-iPA}fO`FJBB_?5Pz7&w3NU%{JhnLLv= zSga*@%?2@nHoynp*&sF$EsY+uAw&nl2S3^x{b*zKqpi`8Hby_ni}It5Vg_yEoN4Ja zK7c26)mG_N?D*E{)_lY3(%0c%FNV+t={D&$_&20)z`rqlBmPb4oAAN!PD-~+w{vaq zzLU~7r}R8}-)SNY?Z|%wA3RN@p?}8*PdqK%Io%l_{PDE(?djX`!7EQocS(1_2j4s` z-8J16A3XG?>2B$6?iu`aQ}olN=%<^apKghMdW-0%TcV%dBKql;=%=>`F^gRL{`CDy zx?j4Vl71llfRz2y{oVhA=?C#2GSZMmk6s87jiely9_aj!q#wb5RCJ@w#5Ouec@Itx zmNLVeVyQSspTZw&gd!8i=rj0$16m^vXbRDcq?~BnB8xGN5-Vq%gb$b?iI|`z{Yv^3 zd_V@RA;J;5Yn^KVm6Ys4a3!Xh_AKfh1^ zM@qmV8;O^sKg+5gw<>8H6q1OQbeD7PPVd17MA90fCgB4jX^n_v(gY%TFxC4dj?zOg z&BN&<_<&Ig;we3f4@jjUB9)@pN{jJJ(j_p*(iBdO*rhQr#9`r3JCDF2e_GS`ZWK3VcAQg@{m-h)|0Wp(YWb79&DUB0?=jgqlQzT8s!ai3qhA z5o!_Z8!_%QQM?|!JC6^*fZi*P;A_myg$y71Gp21rs z2yPDO*}NR@-i~AF<}5Fy34uY<&0>N9ykQj~sCt9K!+5I&d0%gl5&vWzoV}6wQgRz{ z_U0l>$!$d2#fY{OQKsM)k*4~juPm&@2jtxtk@tooP8n+yb!yOiQ`JHhUn`6_^JOf) zd5AwHB_Q%iqEJ1Df4=a%GhZmY;HrSpTO&p<>2J;BF@po+tz(LCib=yU$DAlU>iGV|6FzfH zvVB;DHhF7U5*A7yzi-%Qk(U#ESU;~RJEC|_@wfPpVs$<~sb3_sV+x=8t9WD|6TxhT z)tU|x(d;84oBf9fX9rlr>4RdP?Pmq2eZ@fAM=Z3x#YEdnY_vVZNc&f=SvRKHDtc$gtW`VNDEQY zLY%Y^DQ&JuX(3ixh?aIuVQ1U5F=pC$)U*&cEksTWvC~5Iv=BcnL{JMc)It=s5JxRU zQVX%vLNv7yPc1}L3o+F~RJ9OSEkstkQ*5;mU2VR2Z{HAOEks!han?elwR=Tr`?Uyb z4~w(*kZ5ZUin+GH_JHkv+pNMY5)Wf_p{=*A_EwWt)={|7(%D-J=K|j^(vCSy8|GJ9 zOV{Y9J6a3n4lSa2+7_p1P4pz+g6s#hf(DaOS3I3O=j<2KESZ}&q)o|naJzm!XnddK zk74~aXTPjZw3&6-u?p$B)Ir4m9{c-%`B+ TYqd&VnqJLHIX9iq_T+y7#;O#c literal 0 HcmV?d00001 diff --git a/examples/runtime/font/roboto-regular.ttf b/examples/runtime/font/roboto-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3e6e2e76134cd6040a49ccf9961d302f7d139fcd GIT binary patch literal 145348 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 Z>xIt?4!_lDDyqtkd+Gd=Z8Nj&{{YK~!&(3U literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image10.jpg b/examples/runtime/images/image10.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d443fb0cbf4e0ffa7a190f54472a53774718d7c1 GIT binary patch literal 3439 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 literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image11.jpg b/examples/runtime/images/image11.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7429fe52ab750bde420e3ee8f18b87196208200d GIT binary patch literal 3818 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 aQ&nyhlyZOV@8%ng!#RgSK*!;1^1lH3hx#c1 literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image2.jpg b/examples/runtime/images/image2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1db15ab2490d971d8cb197a6608dcebf70101a2a GIT binary patch literal 24091 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 literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image3.jpg b/examples/runtime/images/image3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..884f9f2bbe847fe0d7523cd085170484a72efb43 GIT binary patch literal 29282 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 literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image4.jpg b/examples/runtime/images/image4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f6e103912dbf56537371d36bb069e7067f6b4a93 GIT binary patch literal 23830 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 AVE_OC literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image5.jpg b/examples/runtime/images/image5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d952d16119f9906330dd31f4fdeadeb4eccba27c GIT binary patch literal 27131 zcmeIa2Urx%(kMKzL`fnFh$t(9Ad+^8iv)>+l9PfW!m_}U7Iqg2lEi=#6hTlhpacnu zNRpt4D1v~AjDi@*C@3H(ac|EO1Ygg4&i~)%-h0mZoPDOZy1J^ms=B9prl+PUZIt)W z>fJheIuH#l4WtWx5aq+_9ooKlM+h=7fW#mOVuBcH)<6gV(SRRB!w1n*VF|afdalM6p>?Je_A;`>(0WZq;TW^8A4aewIqu}VV_UUi z%^kEKrI6)$8Z18IM)Qw9ZuIUN(-AqJdZHk%vZ?!9TH%xCo^eaZ!zbf!+^uTqolw}d z*U2aBLV8hkYu|THh?W*;OGnj-k%3;0s={W}8akkXmmn8C`slf}um%;T^^~4g zV>HdyVM($h!VItij9cX%H2@`2cpS7X|tAWXYA#kA6-v49c<1HJ|OrQ);t=Nd{X1lYN|*6y7R-(oaVX2_Zr`ZbH`mdZkcYh zlPF-qeLj6`vb@&iy;61aa7z79D^VET-K9?n2+8vvgHxsSCqUf zG8md)DHyLC?fupK&1l;$T&?K_lZ&qnCHZ_em-NRgax&X}u(@){aGh{+dk63HUb@M& zYfS@bNyxjzRQ5bS;|*8ew}kGAgy>>|W8S?uc=W`aSW?PVysz^Y8#W45A3sciGHr}> zr}FFlcQ`TfZrIVif7oxXJucw#u;@$?<}gi2cUh9`fUSu?1v1^-dp57ZdmOD&8oV{9 zj|baO{^X@@h2XP3{`RomdpZaTw2lJB?l05KvHKYMw)fMn-o1RmR&_~FKb5?uZ@1~c z)6e%Jh%mKVz~^FJ(O}oK+JKCGj|{G*SkS+2&ta0}!-tNIckjr$yU_+eXGt7fZ|mwS zehZb2e%Cn}w}z#LlvX*~l{wwS62MtqSH&3qEFz_DH2O*AR?{zcbkqc+b&uB`db8QL z!AvgC>5eJiQ{9WJF^2p1;P2H4y^YamG@`s>6^+k)WSpUL+U?ui&A3pz^ro9-9zc)M zBC$cw-ANyclG4##opbH=AMZoTVaw#gvK%7=Y;Z&UEilGHX)+2YZ` z1N+pT6LRgkDNsasA_Zz5+f?Pd@8OpxmpC&9-x~3|-{>n$2|09jO1JA1kJXmRFZUIu zqY)R+yp|ohr$35OZ!l3geUAbqw?3gjJjGGI<6{!VKDTc$ynHhJwvb?Ew6p&?TiW@C z2_~N#Z(EALe-D1wap(46nGurvb+<>zpJKQixoLO zq~F)ld4Mr8dTpS8RmkuU&(y7@dAmJNjdKdfKNLC@$3yc~ot<>_&EYH_t7!4pUSo|r zHE0j@E1`C&V)#y%i|9uCD*0xdZ#o(N&@O&-ZHyazK@``$J6~$_&kN9*>=C*mbe;lH z>Q@^cCvM{-FtfY~icE^Ro*vtpP)R^4H*PhiuPzX6$BJ>eUkc#EXh!;!OYBQ~_CX+R zfC(>}S?Ri+xm=UyWTiS3=m4Or;9zQu36*bqD*z6GCq+vAnmc?%ZTL&Ehtg4ZPR zYi1V`1NKVwYoNx)gFAOzm?Z=ZRadXp3Tyi^{YjkyWm%P6Ig-^OWRn}Fd&^ybqtk+) z`9@KJIw_=m#B!)VP<^^gX=Co!_clYVQ@3ZwMUOM8k2hz=UhZ}BiEeeC%LyJX*u+06 zCH$i2NtJzY_TXqsZQP{Tdw($T*9hMxjCD9>{5@F{F>RSB!V`8>-7mp5@~yTrGS20qP= zlkJJUn9kW}Rwc7)+v%p?XtExYHkz2IJ$c{(W~PXl{6WPEn#c=WlHR!5ry>8`zqEYgGNp8qG;AL-r zq4U7L$jp{;+V4Ya#4_}xu|*{g@6Gq0#SIJj8+x=%yj8ng`XK5`W9Idt7wn}ScexJ^ zDSY-++d1c|mX)aOn{)50i+!M7PMR%lEjf}XhJJt0=hU%bUu^rmj?$p)*r+D|!vg!N z@VBg)0<{KPiB>-(9XmrhK37}m91+8%cTR8jBv&`SQMp&1H55)(o!L+HKQhd1zZV~KrO9McF+Ee zJiM<`n$PMS-lcV;x2>uiUBh}kbw|Uv{8aow3UqzYJ^PY#HsbU5UKZZLh&L7Y1fMq! zt7*w3J=b|z8EA2#sIw+QKBiSq=}2{7Y6pMq*8~r_KHjE1SN3QPcLWaK3sbEwnv+ng zeuAy*`Jftx$=zIftUDMZ&Yl@}d?2mo+U(ZR##zT8V!zT2L;CSNREL}6iHC*9gQO;I zd$iai#J%HUpZdCnO*U)D3W;e%E#)r>P(9X+epat1m-IC!UV#G9ZMZUfqA+S)@*_=M4cnZyd(zb5-~qYy z6`SJKxF-Zo^@iO1h)4|^@>X*;o37c+adV@nrPuSjUj+Glg5O~q^%UNWuqA!FOo7O1 zl*ZB2ugHXtJcjQwUR%m4-O4(^bn!b!na0Zu8~1Xp=0hVKTSg1FZ{&KU`CJ5wMO>}J zQ6TfFx00>A_kF}A)Xo<&&kAHVct0+AV0Wo}tn*u(cD9Z*>i)wkc7`{a`1$H@&1uux z?ul@Bz3Fr4y>;-wBY$!1#{1_)j%_j8WIAGT_xZ^j(+lUmKxZCn6_EO z+AE~*jQV@t^bS z!x0e*B$#s9htc%)j+0SXr`h1=mLp0waWQT}rH@OieS}^1p0%*&t5>N-a(%F=C(y*c z8tx2~|BUY*lJpXpy173&(7LM1^KR|;eQ$lNZgI^dr3_IZ+iUl@Wj7+3wAbypL+88t zENf10?wf+C(bxiW8W*9db4_Nx+r0ha#l#^{VA@_qioDOSolYb)n3zxjfq{cSsmWdL7E)YeSvPvZhgY# zABeTQBlFBTm`?d>tf7J9y{AWvoI?74cv#wA39l$=fikZaot%~r3uPpC**?vn^$%jo z=qEQFzN;eN53SB-PcqY$ICQRJIJGn9WXmk_`0%~s9F5Kfv|I9AY!YUZ@G(M@>ECJ+ zhBMxdC((rMVqC{JHNH0q53LoBK@hL5KTN)9zk|GK_X#Vxd!}DaY`mSqL|;lP(cX=D z>uN2Mgv@M@vzrp6jVC#fw9w1 z4j56In+Z3SD!1evsjl%Q>RmtoplA3BSJ0&bDR#YejO`NBj-9Xa(GOnVZkyaa>Tn)& z*M{xguA+(5D;Xja)%b$}G1=U9b1d!Mb4_mo-KQ;F%J37knBri?&@z{G{#+Pi9QI!Tc^vU;MZq_4KdITJ7Yv;tbr zC=Bs(351Vy#~mF%lvF>FKdrNi^WFIi;X)UFwC9#nUQ>o7Xn#Jw%ScK?iW+(bbnrto z1Tpf1MFDtSfQl2Q;#T*M92k?T;Ju!F#3}oULvtxyh8Tp)csZ2SeBIrUhjBy_p5UP( zh?0~RMB+TK1P8o_lZv2)xsHUQpqlC`<;_|~n&wu<+DK0~Jc*1nw$RYm(?kkNNJ*)C zdb;7Hq_oVnkjDCYX68sBLrO~9P!K8TOeT9ONlE$m_(@g#zT-Tz}> z|Jtf6Zu8U~T)atSoCAzB#bL?+iCzBxpMh{IExV9FZtFMy_J5K*2!i-o@QgkGXuC}I(qq@(J)!sqZf@WYeyhY_Pw@6|AQ{=aU_owy&lF2WfgJS(lsSkfbt8B< zfjsrl$2pRh=QYR#_k}!F4O1uQ#d4}SBsV-3N3wL&CjoYv74^_l%K&-}I2oxKJ*{Q3 z8J&m(Z_gDd2Jkw_3GadP@OB40tlDOA{^Fxa_~&F!34;MlP^z=!iC z>ydQL4fO2^1UFb9(;|8WF|#v)=&$aEcUtrm$Gq|2ZQ48KMq694*2}{I#!r`_^SfU+Rs3WTg0(Gf&knxT`<*x7; zTtao(A}J1hm%gOJ3R1Xa1u5|M?%fZ3_ zOGQ@8i(p4ki>OO>X5iw&sR&8{?@^H}t(1{hl$RBkmBz?RQ&XV70t!8!qN$kqR0iPX zQ1djh;xLy2H3hZ;I{*fx03)j?CrwR(od5<_f)w~gK?ZmYP60hgF>tB~C_xI>B?Ej2 zr*JJYz_)M;ctJ|#1)h~f$%0Zi1=@mi9-}~o72y;E^aLrD1|tVx1vHFT0IdL0&{nc2 z43G(@FfT?C=EW$&G#Evg27{r}U{F*TmWH89!(iYVF;tltSQD`Cg1k6rPjS!(#O1{m z#1+Lc;=na1lsF14j*<~a$%=#a1w<$XanKpS=z<1a1oRNldE`Jp0^I=g7|;=R$jHdZ zX~>}!RMVDl)Acxj)IPs3`PzEE;Kt&B~9?kmWM9R2=6y0|~Y3Q{meI@poz{v~3n3SeCrtW7VDra!-H zS+OmJAkqP={-6Ip9{A&dKOXqwfj=Jj z=yAD$UA;4fuqkr3qWK_%EP?64$Hbz@_F@Nf*lwDAARW1?j~dZ1C__vI_8f61{pfJaI2+zrR5 z5FAKY5II5P3qka5SWhB&`_Iq~@QOZUPXIIW19&YFC`K@J%YkX0Vo92C*y`e2Y9+s z`y$YdE|utQ3hM^s)4j4IYVQItkV7|$^RR&Z24H$#2Rkj;w~_!>g)C|8z#`H7QV|yN zfM&shktwtb(g6RS5D}C(f(R!!fWd)M9Khgd*dSMc`#qg8m1dsjCj}fG+z=Kl zNWpS`rJ1i`V1b4}$3rJgCj-tMboz8Ebc%Es2uY_#x06nlP77c$bUT(bFa|t}dLlt2 z)&Qt$UXB;!4eEmRu!J)gN( z_M$sD@zjmuT_Nm@*)L; zHiH&}I)r2pW56(=7oXRSYZKf85Qu#k{k(YuY>z4%zYT> z?FRJ5kwH`%xc(tcf~OxfPHTQ`R2|+R0;%VLl@v$Xxw#>!MIZDM{z<9+N13|OrD3s}B3S~A0$nSulhi=QZnS@#9x0z(1qobpz zW1y#JU}gX(3ljqa6ASCARV=Gkv96xqQ*z<&*9|7;^E8Z%jBKoIysKC9{%>zH3HD|D zxy>XO*k&>rsL8l|mr00@9zn}M11)SbNlS}ZUb-@}ik8O2ZA`hRT0 z=vm?YPA6oR)Vv;;6jR!5?cyJvm{nT)W^ihLTS^2yJ=iLfjtPNqr*07m?~JKVZvr%C z@H%=9eLeT<+KT!QTQt_0+7m})gk&{Cxns#9r`#Ih}lhS8ggBa9ur+a?}c@5ifqkCaHJ$ zkxkF%gO*?uDX-D^NYkzZmj}N`Xb9RpTD|MIeOmeJ%Z-COY=!P3j?G?}Zi=|D)gb%e z=&l=3YrgXZnrF zvc^M-)niw0YF}48@otS}nX1+K&vEqlsnJ8Z60b}jY$O_x^JKew?y)B+GpD`dP;+C= zq`ZoFnx%s`u({BdO6${Ogkn?Dbn>hoG%eH&e$e(^pgXozy08=*?ZuHL8Bsvy56XQx z()(2T?WAk!8AJ~^O*Dv!Smuc@;BZW!EXQ~#Z z+k%;o?4BE*kk)rpcv(-STpRe*q=W`H#$LuR zs^BZ$mAOgnest20GkEkwA4j9WgzZSnRgo;eU89d{4w~(pQccVu((gCDpYk;Dv79ai zvX?Q)Y{fl)**vPtHhE!;OS5s^$MLA4H{&NeLTJ7^iELDj5Goq@de~a^SzUBn&&*JH z$B6PflbMRvaRx8`nc#_u{@XGTtM47VOQj@n$Vq~J<$G&eA2-7FWx9wxE z{G88>H)Cdy_S`{N{=Pj5`RAK16dsOT<1;Oo`2#mHq#yn1dvIkjozEQ`vpKI?-aZPX z-rRFW>|611J@qk-l1pcc6idz)%_&`l6qur9=Da@XSzY*4`us`T7y4V95`=v35kD$> z8r?N;=lel{s;#&>Ub?%hNhv4sRpU3NWmk%EYts6+5~VvrAA1ddCLJ^kRDai`_MGVH zJlZ|QIDKA@0`-2p_~Uh3K@59LN11kjhNM+Q-jSDGvoiTlK2xBvw29#Ai}5*qMktrc zh?_;6SIT%F(507inSJlAAJ>zJ-YsN-hh}^-JE1s>L!0{THvpe#bVw@n9b8@>OKmM*RH=Tmi z&a$bbfz!s^jR>(|O2Zj5*_=G?f$zare>6yRFo;Pc(}p(`OjlGL?XHaW-^v$!`F>;i zweZ>r=Z_m#M?aq9<@(WsZp12AcYYe}_v-Gb9@1y*b-KFh)jRi(HS5(vYF|XGADD!o#tHvjax;}qK$um%(zMz7V zH6e|?0eWA|W{Go0b})sntAC)_Jf>??$uD~^E=QJ0b=$fCmxqLJmxYg~A83mD%#wH2 zsZ2p2XlG5u^EbZNU(SA?*<-)=oDt&j;|FHqO$V4KUXJbJ=$gu0*D)3P!oC#SQqKM` zr>H(bI_~6*b%{}ek$8)62vZbx$Mp%p@*F{%`|FqiNE)tX84Tf{hpUM(~br5=b=j16@y|y=m9>4(XvaYgEVd3l7C*)eUi9RX)q}$aaKz zV_)y_%DDVo8r`fKnc%7{j+s4@e1@Zgqtj-)8aXC{M=Hb2#?B^4T9)tsmh6(l3#q?X zS96s($;58gJOLR&9>uHDSMX5 zJiWax=4w)2#mT+OUKiv|YVGa`H3mx$r?8B-d!f(da6EjsyKwK^1{B(P*VjZ6>JyuP znf|9bzVGLhYx@kEB%jC4be&9+O|9a_PM8cT#*w~8wmMc^;>c1nvQ2x@csS(rw>i}( z@_VxRrfgIvSIHWhgdJtf0GD{rk6tuOL#EBMpKC%}G@>>ntx*^ndzx27X$rr4-SOUf%Li5EH)WfqMxJv%E4J0CI>i!jG`;H_ z+N!7)19N1xX)sMuvTeo^nb$>J}{HWv=q?VONQkJjVfBKQHV0g(SdohFF zCPVRQ7aRJ3;I3PH500HEyd!p|emwbDt>$;Pk_%yUXBEschb|Ys44ajj*~4?px}?PC z{7a#bEAcuar&W=@6VKkUZ@H9u^|l{-Z)@RW{mA?4T$~Ry=6rg%#b9qhLqc-YzOwDr zBdV|69IR7!Bzj8_)}9i5@xiyTveB+JKsh=f7IQ!Cwl4o;oJi`-J|2379d7ItX!S(J zdb$@hYNPLZP8QxeAQ4GeWptRCro?z%TlCJMkgMxXG2%K2Gv$o|$#({(TJmBC)tuX2 zYuPj_(Y~k-r}ZaJ+vc7+e^%%zO|ClrpqYVXTj6~L`tGP3CsMxItTzdj6RkL(A`lVN z?OQE*t5{vPFp$T%p>3)@uS(DCX{d|RD2qwF*1N5FOh(@b&$bEcex9j#;hSP{X8X_^ zoW)v;pi!|iQ4pppM|IraW1-+Eb@mJ|MSgX23 zu;VIcjujwx-5iOtAc3-Jc z?e2Mj+MeCxo0K>cezoh}nrrFo_aEG@*=w~^)V1SE%dv;!wU1r5mb0TUuBR{1*!Bki((35wK&C!osMEL{JZ7G+So5(d1HVttWKhBS5#Wn@=M+@bm z*z0F1G6rI}3ldTohpL-5%sTAgKckOIlK*Udj9ow9Xy#!^+|;wJj0|bXKe|N9jAvYJ zNB1}i6{Nj$o+j>_{PJTiE6}}D2>-v>=TZ_a(#Z-M$RitXB`Yzo1+-G2qkxXy;=u8k=i$0Y~7r;=y z>R96$GlOJ3a;M(0ea%<*8xS}6rrQnHdC_I`WNLh1eEf7aIjbX>KqrZ^st$L}cD&!% zS6(l4k82?MS&}L3HFKm!lZZ>U+J`)W$95MtWm%rV<>n{2R-cxO3{ki2IA&0~F;CfM zgRiT1r=G%ud}~B%L2moO;ZGaf3fjzPZ)0R04EfY+S~uJ%3VBxk;1r+HK(3DP>GUc! z*Zw+tAD3tk6#iyf; zDi4Kzh}pV)PP?YF z+jm$>e=m;7-DPw+gga+a`Hq>i!+OW0NrS`v8%)a0N5bjEgWq30Hpj*Ap%i%)Upr^x z=d97vY8jQD?YCsSmX+x1>#zrT z>A-&L$8;W&2U!xB1=q3mf3wNpzOC@EMtSto0d0bC)8+aKC}CZziy02-=6WvvSu&?} zXT%X7SIM-rM`Kg$ET<|QKkCuHw#n!&V zZQhZAm^F0G^1iBPc1&-&o;E4@MQgMt??BDKAdvwdxK2WFyLr}`OmoIyvk$f3(byN; z+;6qqIXG)6D|3+ZdB>g2yLRfODNNfkQJ~No+Fd2LGC#RF>@D2+Y@;rx&WRJcovDfL z?H{^MAv0MwP1k%6%3NKAjSNRI+0>}u)eWzp;*;;!=^Yar4el9=OT9@_=1mBlUdOHe+#n8o_Vy|Uy zUfVOP1c?HM7U!>}*}m zMWq~NR)|-w@CZ_o>|s20s%S189HX<)KDb?|grV#yZHG#!b7IX}ds z(05&(d_9_l8zqABh3bq?acpHX){GV{|7vBi-`Qbq|Ja5Bu3JixMt1&cZ@EwhcV0Oq zySe;*UWrD+>1*TDDrgGyj5~26fi~ge`8|HDjNd&Tf3B^q6v?>7XjC{?EpbX&oV8S> zwewJmltlO~Q{~XG^Y=BHl1LMW=MIEHS%n`*)$yu(i%%q^JE9K=nEEljJ^k*Gp6te= zhlhe#k8LY#%yzF{8_E49dv|Nc<)@K?YuDB?oy(v-YWS^&!SXbBp4kWEy4KUs*=l+L z|B=nZ1y6<4_*D~zpF#pBO;lt#gbRd}gj3y3Z?%8sm^gGM9xK_+kIiwK?^Tt0T+{!$>w^XAN?92sZLQ zRkuE)Qnf1*CF=UAIGI0+=`-VjllmiPg+gL%Tw+T$L+amqSqsBb4lyAmcPBWzDD=d2 zl-zhnX;`=E0;g(PUA)JAo*VXTDq|#f>pi?SyRO|(^2Mr1E62C6ZL-Y7i*+)JDsAb! zZ?N^!;q*gBC;P;d{OAkx{oNZxGM-uZkJtE;!WH8-$BSNy)!oApkW(p^xc`%-_m5N- z!!nuen{LH32(RZZxxqC%ZuC-yVduV!@i)d8;?`U^5*-+{}+pfnVUC|7< zo$57ump&X~JdJUX-hH6qbWv`>>x9X3?J^_yklyOkd|M(K)tEkXI2tiLbEh<-jcyZv z6gReSds`>^1Jn4i>l^NzM%Uozn~TP+Q{EixifJr9Q%((PPG`%A==LR-hJMm&;S2>{eHjC=ksmm_1x#&bI&>V+;g|*-se1*`(Vm078I2gph~$c`yV8AQUFy z5X8c98a_aSg+K@?f{TT~@n9JMCvBrasBzvLaDND4s;)zj`izOY1%(+vMY{$wIZSpi zGaPN@jz>F@$TS8Vhj6-Byb%^_q)R~Kbd3P4M}#0`24XBoHtN>)-#Oj1^E=1kd{Gv%bjc)#)6 zSmf6bAucK^E+IZcLSlxDgoK0)97xEFu}J+Z0=U;9DIq8rq975<5T6tRDTUxZ2gMfT zRwB%Smi!3b4=4=(kf5QU_yq)oghfO_bC{lpfcTITi8CMs3W4N9@$m}^2=ODu@E}nN ziJC8s<+oTynyDPI5hoy%oO!`=fr_l#jR3qJE1}*>P&LK<m!ZGkl)7tWA9YRXjA(=NN>^rn{o$z1_9I(C2aWWShx3NlXGFdC^vS8}t_Z%c zhm1DZ7ApU}K<9#|A6wM=VGKQDDmU=XU z?bF;Byth_qP&M+>_W?n{t(VIEleo~m1M#P>*Y(L;Z-`CilRe}1TFu(w`IjFL6H}Yy z{2v}syX)5%{_6W3>b>U;pF@fpS`aD;IO_@VGK1C3p$Tho;{Tpw~kY_cS(tzGhFXzz+1gY`)%*JH?Q zB%g;o>z)^+{NhN^nRQL+1rZApjE}cx#s}EArQ_KG1k@1Hk6x%*XK95M>NsL>N}=UO4U%tG2sJ}XkYeAn)m4)-Ng z!W1YYb-uTWt4jR#oY~-V$#9-fdYR0t8U5mSQTlxYbmI+tK~8(zFPgYhIrqF_TvoGJFDLxbv_=1J{e!ZV7Y3 zJe9tQJ{xd!^!&4^4t#ItfsK0DmpP$+*>j_n8o1CR+MB?@jthHYWbYS{Qpi{CQraxL zl6s_99r5aMr6J5=y-VURCwdkYBEvN3~p@X|%I9+~6g3nHn_1 zWy46*`9jTGXNvbogq~DCwtDvLMQxlDQlrDIU$3R_k(YRdEJj6dQOs@lR2cC-Bi;8g z_Ra7O)^~rOh*KFQEi=OyPevMZ=0$NK)!>T-jge~(iPIw*N=KBHqYVa)_g$gKDqoR2 zvdzV5Si(E9QOm5pD8!;MGI7Z9?2UEbq{vS~kvrb{zYy71==-g-0otS(Y9;qr6T^ocTNP;`?1iaS}R2I2=$_;z|bzAkxk!zn2B`At;3z1 zWf*tj)=Tnb4O7B0)D`t7I*0aMe2e``j((q0e(v$}*@F+P?W7i|-jtPqJ=GS= zf8}xaRUBr9bEFWU?Ji(hw`RLnce)=YSN4DmrTtz2nAZ;M~|XzByd8lhX{rpx!a zP~J*Y$pYM!2>0NE;ufUpr}xU{`W4+Cti%xh7u$RSUiS^Gj6SLRJT)wFeKYcGeeGIH z!Da8fzY`CLJacsDyQh@!kf_Cwy{y;LUD9Ud6Z`a)@1yFDl3EO5)_eTPGWCraT~{P; zG!s4AFFs=L@?K+{HuB)b=-s;e)sNR{qpf3HC?d3LTaR9S)sA2CPT5<2O|jRo(;%v> zYTL}O+k|>%L&=rt(MKE_(EF5B3#^Xb-IU(rylKtg#;-o+DTSYG?x_?V;EUPebLhG; zt>~a)W0s|3p4a^rm!4SyTPvPO)`y#Ky4h0quBp*6L>v>f`QV&=KT>Av_aJ+bG$TE6 zN@gdnr|Rim`HjzH=&42XO4m`#Zj|JcUDmJXLO*UhUn@TF+0=5bdE6T9z;dkxt=HR6 zUuyd(jFwsCvV1srsV$li4ib6}1HMm7%j zm>1rsyg)Rs-TyiG+I8QaXXsnG*3ylRK0-}5p5*QzAC0U(puh6Oh50#*JtU<*0%y3F z?1MQ~r{8pg3+4Nq=^Dgz)v-6NZy4?@DH@q&dSRCNpz}8_bmP>^6+`TQ=|1g{?uW~GwUBztbeR)9{x#`~jVq1?K2>aOZrxlpIWr`~%#b!Xa}7~%?{ zF;RE)Vk^F!9xc4=J-o*Ddy+((KyK;f;5N|ViV&q6=US_7aBc24##UKN61*$CaO;dP z4{8V^Rn1udvR7Ia((xnD4y2b?(RJ z^m5c^{bTjRr>;4K)GDB32;G@CPEF8LlG*e`L*|*(2^sl|a@kJIkRnL;%f2utBL6-Np^f;(NKx;MW|Fx zn1+c_GdU1mRhz%1PQ^pT%v_^*k3g}KXU^r4{*~A2{LFH%mDXl0MvI?eHI@8u-_TpG zedMJ}mWGnus_4+czrmgTfwIC?htbsGAeq{DK%f_}R!wT2#4CI*| z>$|A5==gI7-(km!)p7EDhx#gWvU9qha~~-=vxD<{Lmg1JTw=cGmwi+utXcga{&K93 z{hP8O?ALYWvlo1|av*QL+AqSmuO7KJiLzl0|Ld9s`t|GTN{5c@eh{p2$MHO)b+x)1 zam%Y68W+pyw)sPTTMFnVwCc^qiHiGFcOa*C=~ zD)n^h;p;Q=R}oU`w}g+#)wSj}r#Be|5=4XVl4dF8JodeB^Qfa^qkB|wr9g26O|7F$ z!A;^r>1bWIf8qKEMT}O3T&Mcs8l4#q%lqeZTe*E2*MBa)@Y=eNp{0Wp3SP27klIH>2y5?-!jLa+z6cf(mX^9+kmq$R0RNPSV6YCX9}bqO#aDCc{)2tF5by zrZUJ(3XKtDs_f}ui!oF-Hxn_LZ|!2`vBK2`9ZsjQIcQf;%cTxhXl0C!jzxGlovNc_ z?O}~}UFzWOfd(>kbZnfJ(aOObPPmbdPIPp%HVLNECNsleLbi@8iy2O3ablMOVHm)m zP2o_KK{jL3r>O(56dIXhCL(MSN{uxGBF2SH-RwRu> z4YOdeNU=YKlHe#%2{2A5^$%qH^J2k5fYNj`1DuHt4}j(VtwwAPi9@xelY%BS0`$O$ z)F3L$OxHwb0^}*EGohi0&V+=9CecAt{_m-VUkWtY5rF;w?fQWi80Bc70{*MUqu&&2vJ(C+N23Xae`z`Y z`6JRlDA;6e{F`(Mc4UCZ*gP9f0`tBJ!BT@2}4}2Bj^#9n_zt-xs$2<#4 zNFrNBrxDw*@2*yR8J6%ekaDIE#KCZ4H&ZP9<9H1<4fh@bi(062JPeSP9I^pplEL_o%c>bjh80D3weS0hVi!z;=CyQ9zu~vIcItt`Gpr3 z=7k_YjJ=}};l+W27R&>j%;290&tVIO_;~Ls`e6{bYUu<9f)qLkfomA}A;vM8X@@5< zI3C^ygcCISJPhV1h9~noh(k~~aR2)457`AL|2B#HzmvwZj1Vjvg3AiZ&9`{$8n+_s zjtB7^+Q#f74@Z#}AQ&qT9EE@<7z9zkB>>T&Fo*;NK~#tU;;^IJufM4{mEH&xRT2nbMlvXDmw*s5h>i2PkvUip- zC5IU{9_Ojy78E>@&MOX^P9syb)f4?iyrpryej$cs2wPmwJc#9~H zP-p@@jaWFC$%?a}(}E@}B{^1j@HTA>4LAiU)Id@sodZDOD6psf8*+Frl82s7E*cPI z#iTP?Q;aJ$Cg0L-G6Aqa&P)buYheyE+$EC3rcN{rI8B5O8q!~|VgXDJXi$H_i-IZ+ z{*|29^A^IwATe+u%s=wrv0er{zK%6v1dk4;fW%&c05;oruYt$G*jE653z7qlp?_RS z!QAl2mGqA*=^t0pKdz*ITuJ}9lKyce{o_jd$CdPtE9oCs(*F=w(y_JAe6YfSAWv{1 z;Khz4WC0dDOeg?sDWD-&uwB4}IN)OQAh2Nq&HN`6Xvhk3hw!k#u^h&BE(Cd71RxLY zYl*6H*H8vqn*@JO$ny-1A%*L}&Z7`;N)0E$Zkgx+Dp;$VDt{=iP)5@zrpn9pophbT zt*F5?`#2WWJ=8T+voc78R|hjm404@dUIUK^td4Fu>_*p`Dlvv@JCNjU|FF8FdZNI2`YD zMm&1_rwp=WQ38$JtZm0L1ToX8POs5;Z6+&72TLRpb#!q$I2;C0VA!$1F){|jU@w@E zU`=I{S+sE2SrQFPB!O)fj;S(GmsbuBE%2w@X%>T1cqW@5rGjrlCsmk63a3mX1=jvO zB7PO1g}UGvJRC_4FfKoY#0sg8IKhg4M({J;lR*Qv$Bi>O0~gjP zsx>W$%7(G}1TCDt0k{moMbyF(a9TJ6J#Yb>p`MmLUKd zxQJT%IB?-{00-n4=z(+~||8X}QLL&Wl6SQ?Qh zjYx!ZB=TeuVNJkS&jc+{pIV>|Xc4pwv<$U~TEH||tQHohg~e-O^|V0!0wSz|7HAA$ ze8GVx0$K=YJo=y=fo1?&3}^_(Rs?-K(Uxdqh_@ivSQ!wl@B~{tQO^Q21_Hs-!Ul9T zQn-;7c;&{ST7wI;O7O`w28+e$5U9d6<3x)dyrA($4vPyY=xkG=hE z#QZ*eI`uCxQ3_a0f|a)rz%waqGI;Zih=Cw}IysyL-rfqd1H550Cmg_na{(;F0ty0H z7lwnzU~3o-7=yieG#+kNfCko8f*ec&??VOG0$3|x3O;BGJf;Jn0CIlw)W%B~3;s#+ z6w1E?!|0K)LjwGR{U^lOq3(|04&L@6VuD%rZsTwUnPlS*U=@I`4(C|Hcr^g`MuvJ? z02myk#3vodvW53T056|OT(HM-0M7z2g~oC47{|vk0-Rj{40!pnLYa=R9GIq>%(j9( zPm}@tBADs`*D=rs2~nulHUQQFuwrne{kVMO5_Xh3jOWRT3$}6wFpz^}g^-rG0vPyy zAh)xaZg5^eXJi(YZU^TDb3YBow2g$I{0YAMPTWr!j|Xp}i>G0F^O4X{L% z@uUW>fM-HaH1MS926>IiiGU(OUa%fskY$p5XL7x*qybI3vV;-Z|uw8&fmrV2!yTt&wldr zKjnW0{;goUjt>5?6~n+qz+o$_TH&Zu9_uaHSeo7pxSzfz<$jE)jV&qliWn>xh9)w0-N8UhI zAghq)kmZvye_!`wQYP!3SKf)z!YyYazp1vSLUajB2?dD-64nw*5~>nQC#ld9vn8++ z_7dtKMPahu=s(k^m4yba0JfU2>hJS{djJjWurfdx4QN@ws<4F_P%Mx-#i|o|pcGM9 zl*2Er)(~#X6BGhA0@eZ+5L!S(fGB_!SOUWnJx@R#q!B@AGpYSp&zYo{Rs!l2DqxjK zIT&86gWD?19R>8J1HGvn;8g_rKV-!WkLCH+=A!a@JiQ_mykm-9cW9Qx189 zS;h`|6F{L*{3ro_egRv~R@gw;J5YYG`Z+v{nsj1UFbNCQQ_>eaNK_m$H z*a$wP6bj-8r@UD#6PQT?r@YDFk~0Nm#|~M0jh_|pQH7Q8N!3cvJteD<%)Y5_t-de& zB4M@%g>$Q+O-OB%u!!88&HHU^bBeqgJr~M7vbKIs`6I}{Gd&kqi&LkS^~VY~y{ z;B)CL_?H2V1tK;k<1#ONl(|v=dV!^^TL9}5UPaF;VOEN}Y8JWhrXagPzs-8nY>$25 z2t2ttY6Kg3bqdGR;B)rHTMHL8zWK6we@@YKm2IaSP&f5_x@kK9jmp!{kz2Ui|Bi?a z_HoMM)fS&J)x(AZ5uLA|ymM%m@Ud$vM)emM_w^n4=pD$P>#}anR);69R8?8GEnDnW z)}D8B=n`$Dz8tVyTcaYeG<%D-wB6ig+uPhuCS;$E zFn-8|_Q$_wnK)$$fAtAG!b;h3fVkqDUhnMHlIIzhzVE&yU1#GS^Ts#^e@I9i^>hMh+tF0>)jP;63NH*EwT?<3(-ZX0A)Q>P#P7Zuu^58)R>Z+zQ z+CBdBjq8gDsYfo&l3b;V;7iC`|B#B7vgnO)aOP~|Nc`9)a(-Xs)~@UdMZ3P$C-_sI zKCcj|ve;u3w>WG$$;zcOmo6CPb?3@E)v^_4xhTsvZ;$wF5vWpLn%0Y(%gNH2`9&#x zZB5LJD|;TER!R^WXyZ4Ng+{)A37qqG-<3~!&jwe$d6&2XBd5ZerLfg!gEJSB{_&}O z2ezUi_iJ7Jn*MViOqU$fJGbrgt2UojZvD!|S603|D2@A^7+NVg^8zY{DrXam&SV!@i+Y#tHX90?Sx!PzT4j09yDux5Ur?-A?11} zTzsAUj1yayTpIRQyHO{!>s@U%CS>+&NF&oE>YY#Wvo#&N~d{SYi--@HbXAM)Vq1p_Oq=No2>$ljH1)K!Za{=7yo6i&m6?pEG}FUOw?}%jRfW9TCMV1;y1%R!;Y{_^K2>N zPcc0&EFSF|?P&MmWTT)h#_~;TtvWWPM@|25~SY9PtBKI{qrCjRLw_1&)TD?U%$yW((3l=wd@D*z=b~)d7z@1-5-w~5| zWx4Z7g4@klgy3$Hod#mGm(++5+vs%W%8j=Ri@N#^eQum-6TW|U&f?3~Y-@6LgI{+| z{M{<=BpfbXXJw0i@ah!Tk{@~GEj!qY4OB{MuaVk!t)Rh0pw7Jt-9BX#snty52m6`&VQz6QRis2_M zM1;umZA4{IsevblJ93^Xo#?yf{`vk5b)*Bl~yaU4Q=eG?UTNS3{B_1UlyejY5;UDzekg~+<#2JfHpSEy>`$el( z?jRGoDk#MW)kFu<)2GB0HAar^6I}#i)!9$ykJorhGk^2tLc$!{^P_3Bvxn520aPZ5t=2<1S z#@nLHwtTnuKX@Iy+LDf*!HvidXEze^OrQ{VCPz zQE_blCq=Y~uKAh$dtO8D7RLv7_%6NVe%0LSbNU%^nN9Cp(8_Ce*o(bTza{2${v&9g z8-HwbIWyw4&g^Kc{PO;FbBulBxsTcp`yXjb4=7FZ5?Zaneg%kS>P>~=G8jleB=)Fzkgb3CF^P*{22467@pqJALr&eu!o`L>lXRMDD|>ECgV>{Ld%l)~rLaU|X|H-N8UOQLD@$8UFb97-(IbfD~c zPKhwk*|Lu2P$09+!=q(;UrLc&BkuF)RU_LAwI3IuvlDDwHYE;x3|VWK)+nJs9eR1Z zx8Tg1V*7LznP}QvT`j?0sggIExT1{?b1TvgemQp{^sZ2~49O1FcuCJRE~5IQ+M|LW zeP@=`zB`|6*Vj^PkfHeImbj)07n)l;WYE|znZL?p*eyMF`N842>DYK~^Q)Fw1{JPl zWxDG}+8twBA+(MnYoFEYkFP$5KE}ON8>}*3DMc^Q)sm8x-&~~ne38{{=NFk~gS)gA z>^d@MvBSQayjzO9*m*urEBvfQ?p}kbjG>M zH5(pV)`qSr_b_O4Wh&=w74WH&`Nnt6khW0mT3LBOKWCVk4FO3ROe)i zMf)r-r6*qGOXJ_}U^u6iDEL~C^t~^o&Eh$s|Aw-v;t_e2t3|&02JoZ0%SzM)yx^C+9D)jON9?snYV zE&D4kmR=lcIWU?p$7lb>OXh@`YF_5IvkF;vwamojxscmV5?Q38N!jZd0j)2Ws)hLG zp5}YAl2OGt`_T6`l_u*ZlJlk5(YWO8UXuK=v=#e;_;U}dA8fmvzT}7F!gj)o>_GQX zx1(oSbSdZKcM}YfZ}RPUHp3kGz0*Kpb%LLG(&1i>9|#LnlB8eB9F9|#Zrh4T`hkO? z_hv0b6gUXp+@!sy&V7qU{MC=OCJml%P+%cC9#^Qe%~`fB&*NcZK(Lwj z_JVAI?1-#YE;13jcE#S2Hx=b)WbADvZSJkUUGcDG6&G6eb+ow0qp{)K-UqMm=FbJk z{wA#OZe95-Zno6^z|{HQ+cDRd1p9B0eO}f{Fga>-XGhUDrwbRoBTY5EOIM1s?td5& znbV}PD|&IxqJ01Dd%YIP{O~6aUc_&nt!(&kcG;OvT{F60?AYbiFya_WOG;5IwS9rN zux)c$$c6UxlCYObgnBZrbRDb74)?K#zF($BTlNQ+!D6+%fZd*f_HKNYMV zMV8!uGE|**9T!&Z!H0NBa_U)kQK;1Vyrga{d0Ej_gIV=Mc}<-&qI(zL+wK5;yij0y zcVP7c6$wM>v);0qAJLslor>F^3sn!)XBGai-PU-*=&PW1Sw#0SoA$mX=4w`&XX0~C zUKMy@_{_^Na5tYyTv*MhS%m<_N?yp33*pz6V-B25lv{Jq(NJ-;Po{7O?RMJT-eSG) zg-0LeJe|pfq+)k{b?IUj9Iqcecly@OFWoLKP4Bu{-$%^9y}eyKz&fVJ{(PRTmlw6`PI^WK?&$LS4;D{Gpc?8#QWpB{c% z=H=C`IGfo!6MDqWDPOseI^LOpaD)q!+*4_}uK+h2#a01G?{%eB?;>p`o=Zj?p66lU6xa%-mdl*98T$wr<#C_I&T! zR=%*~1{qIZ3=O!}-BVm>hPGRku&KMsCP0Q+^f;&ZO{MURCcccsItLUpb&1n;)#U_f zOu1f&@RB$*Jvi=gSW~Co+pveiFSe#QUswn?p)3==CjB& z)2rJZ{yDUayuhg$^D1^h)T|8I!<*eQT$Au7mWQ6___Q26Ae42;{#=hpQbyl0zXwaV zF7?19VlS&*vLBIN&*x-9xECPqhDjaWx9^8=KW446z)-*=u5ga+I#5$0RT_NA5DdtHZa>~Be3FTJ_{grslfUEf2f z2X~h{_6*^(4-2$`=*46qj)!!4bQJq0v-RpC5_^=0|!PvELhAxUK&S#A1-t literal 0 HcmV?d00001 diff --git a/examples/runtime/images/image7.jpg b/examples/runtime/images/image7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..623b4cb91d1951c56b97d3df8659373c73ca6ba4 GIT binary patch literal 25590 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 F{|EKqH$wmb literal 0 HcmV?d00001 diff --git a/premake/premake4.lua b/premake/premake4.lua index bd22e770..51f70ed9 100644 --- a/premake/premake4.lua +++ b/premake/premake4.lua @@ -171,6 +171,7 @@ exampleProject("16-shadowmaps", "f9a91cb0-7b1b-11e3-981f-0800200c9a66") exampleProject("17-drawstress", "9aeea4c6-80dc-11e3-b3ca-4da6db0f677b") exampleProject("18-ibl", "711bcbb0-9531-11e3-a5e2-0800200c9a66") exampleProject("19-oit", "d7eca4fc-96d7-11e3-a73b-fcafdb0f677b") +exampleProject("20-nanovg", "359ce7c4-cd06-11e3-bb8b-6c2f9a125b5a") dofile "makedisttex.lua" dofile "shaderc.lua"