mirror of https://github.com/adamdruppe/arsd.git
nanovega: changed outline API a little (it is just an ordinary struct with refcounted payload now)
This commit is contained in:
parent
b56d59f208
commit
88ca1e2556
307
nanovega.d
307
nanovega.d
|
@ -7563,7 +7563,7 @@ public bool charPathBounds (NVGContext ctx, dchar dch, float[] bounds) nothrow @
|
|||
return fonsPathBounds(ctx.fs, dch, bounds);
|
||||
}
|
||||
|
||||
/** [charOutline] will return malloced [NVGGlyphOutline].
|
||||
/** [charOutline] will return [NVGPathOutline].
|
||||
|
||||
some usage samples:
|
||||
|
||||
|
@ -7627,29 +7627,102 @@ public bool charPathBounds (NVGContext ctx, dchar dch, float[] bounds) nothrow @
|
|||
|
||||
Group: text_api
|
||||
*/
|
||||
public struct NVGGlyphOutline {
|
||||
public struct NVGPathOutline {
|
||||
private nothrow @trusted @nogc:
|
||||
struct DataStore {
|
||||
uint rc; // refcount
|
||||
ubyte* data;
|
||||
uint used;
|
||||
uint size;
|
||||
uint ccount; // number of commands
|
||||
float[4] bounds = 0; /// outline bounds
|
||||
nothrow @trusted @nogc:
|
||||
void putBytes (const(void)[] b) {
|
||||
if (b.length == 0) return;
|
||||
if (b.length >= int.max/8) assert(0, "NanoVega: out of memory");
|
||||
if (int.max/8-used < b.length) assert(0, "NanoVega: out of memory");
|
||||
if (used+cast(uint)b.length > size) {
|
||||
import core.stdc.stdlib : realloc;
|
||||
uint newsz = size;
|
||||
while (newsz < used+cast(uint)b.length) newsz = (newsz == 0 ? 2048 : newsz < 32768 ? newsz*2 : newsz+8192);
|
||||
assert(used+cast(uint)b.length <= newsz);
|
||||
data = cast(ubyte*)realloc(data, newsz);
|
||||
if (data is null) assert(0, "NanoVega: out of memory");
|
||||
size = newsz;
|
||||
}
|
||||
import core.stdc.string : memcpy;
|
||||
memcpy(data+used, b.ptr, b.length);
|
||||
used += cast(uint)b.length;
|
||||
}
|
||||
void putCommand (ubyte cmd) { pragma(inline, true); ++ccount; putBytes((&cmd)[0..1]); }
|
||||
void putArgs (const(float)[] f...) { pragma(inline, true); putBytes(f[]); }
|
||||
}
|
||||
|
||||
static void incRef (DataStore* ds) {
|
||||
pragma(inline, true);
|
||||
if (ds !is null) {
|
||||
++ds.rc;
|
||||
//{ import core.stdc.stdio; printf("ods(%p): incref: newrc=%u\n", ds, ds.rc); }
|
||||
}
|
||||
}
|
||||
|
||||
static void decRef (DataStore* ds) {
|
||||
version(aliced) pragma(inline, true);
|
||||
if (ds !is null) {
|
||||
//{ import core.stdc.stdio; printf("ods(%p): decref: newrc=%u\n", ds, ds.rc-1); }
|
||||
if (--ds.rc == 0) {
|
||||
import core.stdc.stdlib : free;
|
||||
import core.stdc.string : memset;
|
||||
if (ds.data !is null) free(ds.data);
|
||||
memset(ds, 0, DataStore.sizeof); // just in case
|
||||
free(ds);
|
||||
//{ import core.stdc.stdio; printf(" ods(%p): killed.\n"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static NVGPathOutline createNew () {
|
||||
import core.stdc.stdlib : malloc;
|
||||
import core.stdc.string : memset;
|
||||
auto ds = cast(DataStore*)malloc(DataStore.sizeof);
|
||||
if (ds is null) assert(0, "NanoVega: out of memory");
|
||||
memset(ds, 0, DataStore.sizeof);
|
||||
ds.rc = 1;
|
||||
NVGPathOutline res;
|
||||
res.dsaddr = cast(usize)ds;
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
usize dsaddr; // fool GC
|
||||
|
||||
@property inout(DataStore)* ds () inout pure { pragma(inline, true); return cast(DataStore*)dsaddr; }
|
||||
|
||||
public:
|
||||
/// commands
|
||||
static struct Command {
|
||||
///
|
||||
enum Kind : ubyte {
|
||||
MoveTo, ///
|
||||
LineTo, ///
|
||||
QuadTo, ///
|
||||
BezierTo, ///
|
||||
End, /// no more commands (this command is not `valid`!)
|
||||
}
|
||||
Kind code; ///
|
||||
const(float)[] args; ///
|
||||
@property bool valid () const pure nothrow @safe @nogc { pragma(inline, true); return (code >= 0 && code <= 3 && args.length >= 2); } ///
|
||||
@property bool valid () const pure nothrow @safe @nogc { pragma(inline, true); return (code >= Kind.min && code < Kind.End && args.length >= 2); } ///
|
||||
|
||||
/// perform NanoVega command with stored data.
|
||||
void perform (NVGContext ctx) const nothrow @trusted @nogc {
|
||||
if (ctx is null) return;
|
||||
switch (code) {
|
||||
final switch (code) {
|
||||
case Kind.MoveTo: if (args.length > 1) ctx.moveTo(args.ptr[0..2]); break;
|
||||
case Kind.LineTo: if (args.length > 1) ctx.lineTo(args.ptr[0..2]); break;
|
||||
case Kind.QuadTo: if (args.length > 3) ctx.quadTo(args.ptr[0..4]); break;
|
||||
case Kind.BezierTo: if (args.length > 5) ctx.bezierTo(args.ptr[0..6]); break;
|
||||
default: break;
|
||||
case Kind.End: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7659,71 +7732,83 @@ public:
|
|||
float[6] pts = void;
|
||||
pts[0..args.length] = args[];
|
||||
foreach (immutable pidx; 0..args.length/2) xform.point(pts.ptr[pidx*2+0], pts.ptr[pidx*2+1]);
|
||||
switch (code) {
|
||||
final switch (code) {
|
||||
case Kind.MoveTo: if (args.length > 1) ctx.moveTo(pts.ptr[0..2]); break;
|
||||
case Kind.LineTo: if (args.length > 1) ctx.lineTo(pts.ptr[0..2]); break;
|
||||
case Kind.QuadTo: if (args.length > 3) ctx.quadTo(pts.ptr[0..4]); break;
|
||||
case Kind.BezierTo: if (args.length > 5) ctx.bezierTo(pts.ptr[0..6]); break;
|
||||
default: break;
|
||||
case Kind.End: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@disable this (this); // no copies
|
||||
public:
|
||||
this (this) { pragma(inline, true); incRef(cast(DataStore*)dsaddr); }
|
||||
~this () { pragma(inline, true); decRef(cast(DataStore*)dsaddr); }
|
||||
|
||||
private:
|
||||
ubyte* data;
|
||||
uint used;
|
||||
uint size;
|
||||
uint ccount; // number of commands
|
||||
|
||||
private:
|
||||
void clear () nothrow @trusted @nogc {
|
||||
import core.stdc.stdlib : free;
|
||||
if (data !is null) { free(data); data = null; }
|
||||
used = size = ccount = 0;
|
||||
bounds[] = 0;
|
||||
void opAssign() (in auto ref NVGPathOutline a) {
|
||||
incRef(cast(DataStore*)a.dsaddr);
|
||||
decRef(cast(DataStore*)dsaddr);
|
||||
dsaddr = a.dsaddr;
|
||||
}
|
||||
|
||||
public:
|
||||
float[4] bounds = 0; /// glyph outline bounds
|
||||
/// Clear storage.
|
||||
void clear () {
|
||||
pragma(inline, true);
|
||||
decRef(ds);
|
||||
dsaddr = 0;
|
||||
}
|
||||
|
||||
@property int length () const pure { pragma(inline, true); return ccount; } /// number of commands in outline
|
||||
/// Is this outline empty?
|
||||
@property empty () const pure { pragma(inline, true); return (dsaddr == 0 || ds.ccount == 0); }
|
||||
|
||||
/// Returns umber of commands in outline.
|
||||
@property int length () const pure { pragma(inline, true); return (dsaddr ? ds.ccount : 0); }
|
||||
|
||||
public:
|
||||
/// Returns forward range with all glyph commands.
|
||||
/// $(WARNING returned rande should not outlive parent struct!)
|
||||
auto commands () nothrow @trusted @nogc {
|
||||
static struct Range {
|
||||
private nothrow @trusted @nogc:
|
||||
const(ubyte)* data;
|
||||
usize dsaddr;
|
||||
uint cpos; // current position in data
|
||||
uint cleft; // number of commands left
|
||||
@property const(ubyte)* data () inout pure { pragma(inline, true); return (dsaddr ? (cast(DataStore*)dsaddr).data : null); }
|
||||
public:
|
||||
this (this) { pragma(inline, true); incRef(cast(DataStore*)dsaddr); }
|
||||
~this () { pragma(inline, true); decRef(cast(DataStore*)dsaddr); }
|
||||
void opAssign() (in auto ref Range a) {
|
||||
incRef(cast(DataStore*)a.dsaddr);
|
||||
decRef(cast(DataStore*)dsaddr);
|
||||
dsaddr = a.dsaddr;
|
||||
cpos = a.cpos;
|
||||
cleft = a.cleft;
|
||||
}
|
||||
float[4] bounds () const pure { float[4] res = 0; pragma(inline, true); if (dsaddr) res[] = (cast(DataStore*)dsaddr).bounds[]; return res; } /// outline bounds
|
||||
@property bool empty () const pure { pragma(inline, true); return (cleft == 0); }
|
||||
@property int length () const pure { pragma(inline, true); return cleft; }
|
||||
@property Range save () const pure { pragma(inline, true); Range res = this; return res; }
|
||||
@property Range save () const { pragma(inline, true); Range res = this; return res; }
|
||||
@property Command front () const {
|
||||
Command res = void;
|
||||
if (cleft > 0) {
|
||||
res.code = cast(Command.Kind)data[0];
|
||||
res.code = cast(Command.Kind)data[cpos];
|
||||
switch (res.code) {
|
||||
case Command.Kind.MoveTo:
|
||||
case Command.Kind.LineTo:
|
||||
res.args = (cast(const(float*))(data+1))[0..1*2];
|
||||
res.args = (cast(const(float*))(data+cpos+1))[0..1*2];
|
||||
break;
|
||||
case Command.Kind.QuadTo:
|
||||
res.args = (cast(const(float*))(data+1))[0..2*2];
|
||||
res.args = (cast(const(float*))(data+cpos+1))[0..2*2];
|
||||
break;
|
||||
case Command.Kind.BezierTo:
|
||||
res.args = (cast(const(float*))(data+1))[0..3*2];
|
||||
res.args = (cast(const(float*))(data+cpos+1))[0..3*2];
|
||||
break;
|
||||
default:
|
||||
res.code = cast(Command.Kind)255;
|
||||
res.code = Command.Kind.End;
|
||||
res.args = null;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
res.code = cast(Command.Kind)255;
|
||||
res.code = Command.Kind.End;
|
||||
res.args = null;
|
||||
}
|
||||
return res;
|
||||
|
@ -7731,16 +7816,16 @@ public:
|
|||
void popFront () {
|
||||
if (cleft == 0) return;
|
||||
if (--cleft == 0) return; // don't waste time skipping last command
|
||||
switch (data[0]) {
|
||||
switch (data[cpos]) {
|
||||
case Command.Kind.MoveTo:
|
||||
case Command.Kind.LineTo:
|
||||
data += 1+1*2*cast(uint)float.sizeof;
|
||||
cpos += 1+1*2*cast(uint)float.sizeof;
|
||||
break;
|
||||
case Command.Kind.QuadTo:
|
||||
data += 1+2*2*cast(uint)float.sizeof;
|
||||
cpos += 1+2*2*cast(uint)float.sizeof;
|
||||
break;
|
||||
case Command.Kind.BezierTo:
|
||||
data += 1+3*2*cast(uint)float.sizeof;
|
||||
cpos += 1+3*2*cast(uint)float.sizeof;
|
||||
break;
|
||||
default:
|
||||
cleft = 0;
|
||||
|
@ -7748,19 +7833,22 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
return Range(data, ccount);
|
||||
if (dsaddr) {
|
||||
incRef(cast(DataStore*)dsaddr); // range anchors it
|
||||
return Range(dsaddr, 0, ds.ccount);
|
||||
} else {
|
||||
return Range.init;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public alias NVGGlyphOutline = NVGPathOutline; /// For backwards compatibility.
|
||||
|
||||
/// Destroy glyph outiline and free allocated memory.
|
||||
/// Group: text_api
|
||||
public void kill (ref NVGGlyphOutline* ol) nothrow @trusted @nogc {
|
||||
if (ol !is null) {
|
||||
import core.stdc.stdlib : free;
|
||||
ol.clear();
|
||||
free(ol);
|
||||
ol = null;
|
||||
}
|
||||
public void kill (ref NVGPathOutline ol) nothrow @trusted @nogc {
|
||||
pragma(inline, true);
|
||||
ol.clear();
|
||||
}
|
||||
|
||||
static if (is(typeof(&fons__nvg__toOutline))) {
|
||||
|
@ -7773,17 +7861,14 @@ static if (is(typeof(&fons__nvg__toOutline))) {
|
|||
/// The glyph is not scaled in any way, so you have to use NanoVega transformations instead.
|
||||
/// Returns `null` if there is no such glyph, or current font is not scalable.
|
||||
/// Group: text_api
|
||||
public NVGGlyphOutline* charOutline (NVGContext ctx, dchar dch) nothrow @trusted @nogc {
|
||||
public NVGPathOutline charOutline (NVGContext ctx, dchar dch) nothrow @trusted @nogc {
|
||||
import core.stdc.stdlib : malloc;
|
||||
import core.stdc.string : memcpy;
|
||||
NVGstate* state = nvg__getState(ctx);
|
||||
fonsSetFont(ctx.fs, state.fontId);
|
||||
NVGGlyphOutline oline;
|
||||
if (!fonsToOutline(ctx.fs, dch, &oline)) { oline.clear(); return null; }
|
||||
auto res = cast(NVGGlyphOutline*)malloc(NVGGlyphOutline.sizeof);
|
||||
if (res is null) { oline.clear(); return null; }
|
||||
memcpy(res, &oline, oline.sizeof);
|
||||
return res;
|
||||
auto oline = NVGPathOutline.createNew();
|
||||
if (!fonsToOutline(ctx.fs, dch, oline.ds)) oline.clear();
|
||||
return oline;
|
||||
}
|
||||
|
||||
|
||||
|
@ -9139,38 +9224,20 @@ extern(C) nothrow @trusted @nogc {
|
|||
static struct OutlinerData {
|
||||
@disable this (this);
|
||||
NVGContext vg;
|
||||
NVGGlyphOutline* ol;
|
||||
NVGPathOutline.DataStore* ol;
|
||||
FT_BBox outlineBBox;
|
||||
nothrow @trusted @nogc:
|
||||
static float transx(T) (T v) pure { pragma(inline, true); return cast(float)v; }
|
||||
static float transy(T) (T v) pure { pragma(inline, true); return -cast(float)v; }
|
||||
void putBytes (const(void)[] b) {
|
||||
assert(b.length <= 512);
|
||||
if (b.length == 0) return;
|
||||
if (ol.used+cast(uint)b.length > ol.size) {
|
||||
import core.stdc.stdlib : realloc;
|
||||
uint newsz = (ol.size == 0 ? 2048 : ol.size < 32768 ? ol.size*2 : ol.size+8192);
|
||||
assert(ol.used+cast(uint)b.length <= newsz);
|
||||
auto nd = cast(ubyte*)realloc(ol.data, newsz);
|
||||
if (nd is null) assert(0, "FONS: out of memory");
|
||||
ol.size = newsz;
|
||||
ol.data = nd;
|
||||
}
|
||||
import core.stdc.string : memcpy;
|
||||
memcpy(ol.data+ol.used, b.ptr, b.length);
|
||||
ol.used += cast(uint)b.length;
|
||||
}
|
||||
void newCommand (ubyte cmd) { pragma(inline, true); ++ol.ccount; putBytes((&cmd)[0..1]); }
|
||||
void putArg (float f) { putBytes((&f)[0..1]); }
|
||||
}
|
||||
|
||||
int fons__nvg__moveto_cb (const(FT_Vector)* to, void* user) {
|
||||
auto odata = cast(OutlinerData*)user;
|
||||
if (odata.vg !is null) odata.vg.moveTo(odata.transx(to.x), odata.transy(to.y));
|
||||
if (odata.ol !is null) {
|
||||
odata.newCommand(odata.ol.Command.Kind.MoveTo);
|
||||
odata.putArg(odata.transx(to.x));
|
||||
odata.putArg(odata.transy(to.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.MoveTo);
|
||||
odata.ol.putArgs(odata.transx(to.x));
|
||||
odata.ol.putArgs(odata.transy(to.y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -9179,9 +9246,9 @@ extern(C) nothrow @trusted @nogc {
|
|||
auto odata = cast(OutlinerData*)user;
|
||||
if (odata.vg !is null) odata.vg.lineTo(odata.transx(to.x), odata.transy(to.y));
|
||||
if (odata.ol !is null) {
|
||||
odata.newCommand(odata.ol.Command.Kind.LineTo);
|
||||
odata.putArg(odata.transx(to.x));
|
||||
odata.putArg(odata.transy(to.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.LineTo);
|
||||
odata.ol.putArgs(odata.transx(to.x));
|
||||
odata.ol.putArgs(odata.transy(to.y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -9190,11 +9257,11 @@ extern(C) nothrow @trusted @nogc {
|
|||
auto odata = cast(OutlinerData*)user;
|
||||
if (odata.vg !is null) odata.vg.quadTo(odata.transx(c1.x), odata.transy(c1.y), odata.transx(to.x), odata.transy(to.y));
|
||||
if (odata.ol !is null) {
|
||||
odata.newCommand(odata.ol.Command.Kind.QuadTo);
|
||||
odata.putArg(odata.transx(c1.x));
|
||||
odata.putArg(odata.transy(c1.y));
|
||||
odata.putArg(odata.transx(to.x));
|
||||
odata.putArg(odata.transy(to.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.QuadTo);
|
||||
odata.ol.putArgs(odata.transx(c1.x));
|
||||
odata.ol.putArgs(odata.transy(c1.y));
|
||||
odata.ol.putArgs(odata.transx(to.x));
|
||||
odata.ol.putArgs(odata.transy(to.y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -9203,13 +9270,13 @@ extern(C) nothrow @trusted @nogc {
|
|||
auto odata = cast(OutlinerData*)user;
|
||||
if (odata.vg !is null) odata.vg.bezierTo(odata.transx(c1.x), odata.transy(c1.y), odata.transx(c2.x), odata.transy(c2.y), odata.transx(to.x), odata.transy(to.y));
|
||||
if (odata.ol !is null) {
|
||||
odata.newCommand(odata.ol.Command.Kind.BezierTo);
|
||||
odata.putArg(odata.transx(c1.x));
|
||||
odata.putArg(odata.transy(c1.y));
|
||||
odata.putArg(odata.transx(c2.x));
|
||||
odata.putArg(odata.transy(c2.y));
|
||||
odata.putArg(odata.transx(to.x));
|
||||
odata.putArg(odata.transy(to.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.BezierTo);
|
||||
odata.ol.putArgs(odata.transx(c1.x));
|
||||
odata.ol.putArgs(odata.transy(c1.y));
|
||||
odata.ol.putArgs(odata.transx(c2.x));
|
||||
odata.ol.putArgs(odata.transy(c2.y));
|
||||
odata.ol.putArgs(odata.transx(to.x));
|
||||
odata.ol.putArgs(odata.transy(to.y));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -9243,7 +9310,7 @@ bool fons__nvg__toPath (NVGContext vg, FONSttFontImpl* font, uint glyphidx, floa
|
|||
return true;
|
||||
}
|
||||
|
||||
bool fons__nvg__toOutline (FONSttFontImpl* font, uint glyphidx, NVGGlyphOutline* ol) nothrow @trusted @nogc {
|
||||
bool fons__nvg__toOutline (FONSttFontImpl* font, uint glyphidx, NVGPathOutline.DataStore* ol) nothrow @trusted @nogc {
|
||||
FT_Outline_Funcs funcs;
|
||||
funcs.move_to = &fons__nvg__moveto_cb;
|
||||
funcs.line_to = &fons__nvg__lineto_cb;
|
||||
|
@ -9377,28 +9444,10 @@ static if (is(typeof(STBTT_vcubic))) {
|
|||
|
||||
static struct OutlinerData {
|
||||
@disable this (this);
|
||||
NVGGlyphOutline* ol;
|
||||
NVGPathOutline.DataStore* ol;
|
||||
nothrow @trusted @nogc:
|
||||
static float transx(T) (T v) pure { pragma(inline, true); return cast(float)v; }
|
||||
static float transy(T) (T v) pure { pragma(inline, true); return -cast(float)v; }
|
||||
void putBytes (const(void)[] b) {
|
||||
assert(b.length <= 512);
|
||||
if (b.length == 0) return;
|
||||
if (ol.used+cast(uint)b.length > ol.size) {
|
||||
import core.stdc.stdlib : realloc;
|
||||
uint newsz = (ol.size == 0 ? 2048 : ol.size < 32768 ? ol.size*2 : ol.size+8192);
|
||||
assert(ol.used+cast(uint)b.length <= newsz);
|
||||
auto nd = cast(ubyte*)realloc(ol.data, newsz);
|
||||
if (nd is null) assert(0, "FONS: out of memory");
|
||||
ol.size = newsz;
|
||||
ol.data = nd;
|
||||
}
|
||||
import core.stdc.string : memcpy;
|
||||
memcpy(ol.data+ol.used, b.ptr, b.length);
|
||||
ol.used += cast(uint)b.length;
|
||||
}
|
||||
void newCommand (ubyte cmd) { pragma(inline, true); ++ol.ccount; putBytes((&cmd)[0..1]); }
|
||||
void putArg (float f) { putBytes((&f)[0..1]); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -9442,7 +9491,7 @@ bool fons__nvg__toPath (NVGContext vg, FONSttFontImpl* font, uint glyphidx, floa
|
|||
return okflag;
|
||||
}
|
||||
|
||||
bool fons__nvg__toOutline (FONSttFontImpl* font, uint glyphidx, NVGGlyphOutline* ol) nothrow @trusted @nogc {
|
||||
bool fons__nvg__toOutline (FONSttFontImpl* font, uint glyphidx, NVGPathOutline.DataStore* ol) nothrow @trusted @nogc {
|
||||
bool okflag = false;
|
||||
|
||||
forceNoThrowNoGC({
|
||||
|
@ -9469,30 +9518,30 @@ bool fons__nvg__toOutline (FONSttFontImpl* font, uint glyphidx, NVGGlyphOutline*
|
|||
foreach (const ref vt; verts[0..vcount]) {
|
||||
switch (vt.type) {
|
||||
case STBTT_vmove:
|
||||
odata.newCommand(odata.ol.Command.Kind.MoveTo);
|
||||
odata.putArg(odata.transx(vt.x));
|
||||
odata.putArg(odata.transy(vt.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.MoveTo);
|
||||
odata.ol.putArgs(odata.transx(vt.x));
|
||||
odata.ol.putArgs(odata.transy(vt.y));
|
||||
break;
|
||||
case STBTT_vline:
|
||||
odata.newCommand(odata.ol.Command.Kind.LineTo);
|
||||
odata.putArg(odata.transx(vt.x));
|
||||
odata.putArg(odata.transy(vt.y));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.LineTo);
|
||||
odata.ol.putArgs(odata.transx(vt.x));
|
||||
odata.ol.putArgs(odata.transy(vt.y));
|
||||
break;
|
||||
case STBTT_vcurve:
|
||||
odata.newCommand(odata.ol.Command.Kind.QuadTo);
|
||||
odata.putArg(odata.transx(vt.x));
|
||||
odata.putArg(odata.transy(vt.y));
|
||||
odata.putArg(odata.transx(vt.cx));
|
||||
odata.putArg(odata.transy(vt.cy));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.QuadTo);
|
||||
odata.ol.putArgs(odata.transx(vt.x));
|
||||
odata.ol.putArgs(odata.transy(vt.y));
|
||||
odata.ol.putArgs(odata.transx(vt.cx));
|
||||
odata.ol.putArgs(odata.transy(vt.cy));
|
||||
break;
|
||||
case STBTT_vcubic:
|
||||
odata.newCommand(odata.ol.Command.Kind.BezierTo);
|
||||
odata.putArg(odata.transx(vt.x));
|
||||
odata.putArg(odata.transy(vt.y));
|
||||
odata.putArg(odata.transx(vt.cx));
|
||||
odata.putArg(odata.transy(vt.cy));
|
||||
odata.putArg(odata.transx(vt.cx1));
|
||||
odata.putArg(odata.transy(vt.cy1));
|
||||
odata.ol.putCommand(NVGPathOutline.Command.Kind.BezierTo);
|
||||
odata.ol.putArgs(odata.transx(vt.x));
|
||||
odata.ol.putArgs(odata.transy(vt.y));
|
||||
odata.ol.putArgs(odata.transx(vt.cx));
|
||||
odata.ol.putArgs(odata.transy(vt.cy));
|
||||
odata.ol.putArgs(odata.transx(vt.cx1));
|
||||
odata.ol.putArgs(odata.transy(vt.cy1));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
@ -10603,7 +10652,7 @@ public bool fonsToPath (FONScontext* stash, NVGContext vg, dchar dch, float[] bo
|
|||
}
|
||||
}
|
||||
|
||||
public bool fonsToOutline (FONScontext* stash, dchar dch, NVGGlyphOutline* ol) nothrow @trusted @nogc {
|
||||
public bool fonsToOutline (FONScontext* stash, dchar dch, NVGPathOutline.DataStore* ol) nothrow @trusted @nogc {
|
||||
if (stash is null || ol is null) return false;
|
||||
static if (is(typeof(&fons__nvg__toOutline))) {
|
||||
FONSstate* state = fons__getState(stash);
|
||||
|
|
Loading…
Reference in New Issue