26#include <emscripten.h>
27#include <emscripten/bind.h>
52 JSArray cmds = emscripten::val::array();
54 JSArray cmd = emscripten::val::array();
57 cmd.call<
void>(
"push",
MOVE, pts[0].x(), pts[0].y());
60 cmd.call<
void>(
"push",
LINE, pts[1].x(), pts[1].y());
63 cmd.call<
void>(
"push",
QUAD, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
66 cmd.call<
void>(
"push",
CONIC,
67 pts[1].x(), pts[1].y(),
68 pts[2].x(), pts[2].y(), *
w);
71 cmd.call<
void>(
"push",
CUBIC,
72 pts[1].x(), pts[1].y(),
73 pts[2].x(), pts[2].y(),
74 pts[3].x(), pts[3].y());
77 cmd.call<
void>(
"push",
CLOSE);
80 cmds.call<
void>(
"push", cmd);
96 const auto* cmds =
reinterpret_cast<const float*
>(cptr);
98 float x1, y1, x2, y2, x3, y3;
101 #define CHECK_NUM_ARGS(n) \
102 if ((i + n) > numCmds) { \
103 SkDebugf("Not enough args to match the verbs. Saw %d commands\n", numCmds); \
104 return emscripten::val::null(); \
107 for(
int i = 0; i < numCmds;){
111 x1 = cmds[i++]; y1 = cmds[i++];
116 x1 = cmds[i++]; y1 = cmds[i++];
121 x1 = cmds[i++]; y1 = cmds[i++];
122 x2 = cmds[i++]; y2 = cmds[i++];
123 path.quadTo(x1, y1, x2, y2);
127 x1 = cmds[i++]; y1 = cmds[i++];
128 x2 = cmds[i++]; y2 = cmds[i++];
130 path.conicTo(x1, y1, x2, y2, x3);
134 x1 = cmds[i++]; y1 = cmds[i++];
135 x2 = cmds[i++]; y2 = cmds[i++];
136 x3 = cmds[i++]; y3 = cmds[i++];
137 path.cubicTo(x1, y1, x2, y2, x3, y3);
143 SkDebugf(
" path: UNKNOWN command %f, aborting dump...\n", cmds[i-1]);
144 return emscripten::val::null();
148 #undef CHECK_NUM_ARGS
150 return emscripten::val(path);
178 p.arcTo(x1, y1, x2, y2, radius);
187 p.conicTo(x1, y1, x2, y2,
w);
192 p.cubicTo(x1, y1, x2, y2, x3, y3);
204 p.quadTo(x1, y1, x2, y2);
225 return emscripten::val(path);
227 return emscripten::val::null();
239 return Op(pathOne, pathTwo, op, &pathOne);
244 if (Op(pathOne, pathTwo, op, &out)) {
245 return emscripten::val(out);
247 return emscripten::val::null();
252 if (builder.resolve(&path)) {
253 return emscripten::val(path);
255 return emscripten::val::null();
269 ctx.call<
void>(
"moveTo", pts[0].
x(), pts[0].
y());
272 ctx.call<
void>(
"lineTo", pts[1].
x(), pts[1].
y());
275 ctx.call<
void>(
"quadraticCurveTo", pts[1].
x(), pts[1].
y(), pts[2].
x(), pts[2].
y());
281 ctx.call<
void>(
"quadraticCurveTo", quads[1].
x(), quads[1].
y(), quads[2].
x(), quads[2].
y());
282 ctx.call<
void>(
"quadraticCurveTo", quads[3].
x(), quads[3].
y(), quads[4].
x(), quads[4].
y());
285 ctx.call<
void>(
"bezierCurveTo", pts[1].
x(), pts[1].
y(), pts[2].
x(), pts[2].
y(),
286 pts[3].
x(), pts[3].
y());
289 ctx.call<
void>(
"closePath");
297emscripten::val
JSPath2D = emscripten::val::global(
"Path2D");
300 emscripten::val retVal =
JSPath2D.new_();
341 skewY , scaleY, transY,
342 pers0 , pers1 , pers2);
348 return emscripten::val(
"nonzero");
350 return emscripten::val(
"evenodd");
352 SkDebugf(
"warning: can't translate inverted filltype to HTML Canvas\n");
353 return emscripten::val(
"nonzero");
365 SkDebugf(
"Invalid args to dash()\n");
369 if (pe->filterPath(&path, path, &rec,
nullptr)) {
372 SkDebugf(
"Could not make dashed path\n");
380 SkDebugf(
"Invalid args to trim(): startT and stopT must be in [0,1]\n");
384 if (pe->filterPath(&path, path, &rec,
nullptr)) {
405 p.setStrokeCap(opts.
cap);
406 p.setStrokeJoin(opts.
join);
407 p.setStrokeWidth(opts.
width);
441 skewY , scaleY, transY,
442 pers0 , pers1 , pers2);
475 class_<SkPath>(
"SkPath")
477 .constructor<const SkPath&>()
503 .function(
"equals", &
Equals)
513 .function(
"_transform", select_overload<
void(
SkPath& orig,
SkScalar,
SkScalar,
SkScalar,
SkScalar,
SkScalar,
SkScalar,
SkScalar,
SkScalar,
SkScalar)>(&
ApplyTransform))
520 .function(
"toCmds", &
ToCmds)
525#ifdef PATHKIT_TESTING
526 .function(
"dump", select_overload<
void()
const>(&
SkPath::dump))
531 class_<SkOpBuilder>(
"SkOpBuilder")
552 enum_<SkPathOp>(
"PathOp")
559 enum_<SkPathFillType>(
"FillType")
565 constant(
"MOVE_VERB",
MOVE);
566 constant(
"LINE_VERB",
LINE);
567 constant(
"QUAD_VERB",
QUAD);
568 constant(
"CONIC_VERB",
CONIC);
569 constant(
"CUBIC_VERB",
CUBIC);
570 constant(
"CLOSE_VERB",
CLOSE);
575 value_object<SkRect>(
"SkRect")
584 enum_<SkPaint::Join>(
"StrokeJoin")
589 enum_<SkPaint::Cap>(
"StrokeCap")
594 value_object<StrokeOpts>(
"StrokeOpts")
607 value_array<SimpleMatrix>(
"SkMatrix")
620 value_array<SkPoint>(
"SkPoint")
626 class_<SkCubicMap>(
"_SkCubicMap")
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static float SkBits2Float(uint32_t bits)
#define sk_float_floor2int(x)
@ kReverseDifference_SkPathOp
subtract the first path from the op path
@ kDifference_SkPathOp
subtract the op path from the first path
@ kIntersect_SkPathOp
intersect the two paths
@ kUnion_SkPathOp
union (inclusive-or) the two paths
@ kXOR_SkPathOp
exclusive-or the two paths
bool SK_API Simplify(const SkPath &path, SkPath *result)
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
#define SkRadiansToDegrees(radians)
emscripten::val SkPathOrNull
SkPath CopyPath(const SkPath &a)
float computeYFromX(float x) const
SkPoint computeFromT(float t) const
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
void add(const SkPath &path, SkPathOp _operator)
@ kButt_Cap
no stroke extension
@ kStroke_Style
set to stroke geometry
@ kMiter_Join
extends to miter limit
@ kBevel_Join
connects outside edges
static SkString ToSVGString(const SkPath &, PathEncoding=PathEncoding::Absolute)
static bool FromSVGString(const char str[], SkPath *)
Verb next(SkPoint pts[4])
SkScalar conicWeight() const
SkPathFillType getFillType() const
void setFillType(SkPathFillType ft)
SkPath & addPath(const SkPath &src, SkScalar dx, SkScalar dy, AddPathMode mode=kAppend_AddPathMode)
SkRect computeTightBounds() const
SkPath & addArc(const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle)
static int ConvertConicToQuads(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2, SkScalar w, SkPoint pts[], int pow2)
const SkRect & getBounds() const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static sk_sp< SkPathEffect > Make(SkScalar startT, SkScalar stopT, Mode=Mode::kNormal)
Dart_NativeFunction function
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
SkPathOrNull EMSCRIPTEN_KEEPALIVE FromSVGString(std::string str)
bool EMSCRIPTEN_KEEPALIVE ApplySimplify(SkPath &path)
bool ApplyStroke(SkPath &path, StrokeOpts opts)
JSString EMSCRIPTEN_KEEPALIVE ToSVGString(const SkPath &path)
void ApplyClose(SkPath &p)
float SkBits2FloatUnsigned(uint32_t floatAsBits)
bool EMSCRIPTEN_KEEPALIVE ApplyPathOp(SkPath &pathOne, const SkPath &pathTwo, SkPathOp op)
JSArray EMSCRIPTEN_KEEPALIVE ToCmds(const SkPath &path)
void ApplyCubicTo(SkPath &p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
void ApplyMoveTo(SkPath &p, SkScalar x, SkScalar y)
void ApplyArcTo(SkPath &p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius)
void ApplyEllipse(SkPath &path, SkScalar x, SkScalar y, SkScalar radiusX, SkScalar radiusY, SkScalar rotation, SkScalar startAngle, SkScalar endAngle, bool ccw)
SkMatrix toSkMatrix(const SimpleMatrix &sm)
void ApplyConicTo(SkPath &p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w)
SkPathOrNull EMSCRIPTEN_KEEPALIVE MakeFromOp(const SkPath &pathOne, const SkPath &pathTwo, SkPathOp op)
bool ApplyDash(SkPath &path, SkScalar on, SkScalar off, SkScalar phase)
JSString GetFillTypeString(const SkPath &path)
void ApplyTransform(SkPath &orig, const SimpleMatrix &sm)
bool EMSCRIPTEN_KEEPALIVE Equals(const SkPath &a, const SkPath &b)
#define CHECK_NUM_ARGS(n)
emscripten::val EMSCRIPTEN_KEEPALIVE ToPath2D(const SkPath &path)
SkPathOrNull EMSCRIPTEN_KEEPALIVE ResolveBuilder(SkOpBuilder &builder)
void EMSCRIPTEN_KEEPALIVE ToCanvas(const SkPath &path, emscripten::val ctx)
SkPathOrNull EMSCRIPTEN_KEEPALIVE FromCmds(uintptr_t cptr, int numCmds)
void ApplyQuadTo(SkPath &p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
EMSCRIPTEN_BINDINGS(skia)
void ApplyAddArc(SkPath &path, SkScalar x, SkScalar y, SkScalar radius, SkScalar startAngle, SkScalar endAngle, bool ccw)
bool ApplyTrim(SkPath &path, SkScalar startT, SkScalar stopT, bool isComplement)
void ApplyAddRect(SkPath &path, SkScalar x, SkScalar y, SkScalar width, SkScalar height)
void ApplyAddPath(SkPath &orig, const SkPath &newPath, SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
SkPath EMSCRIPTEN_KEEPALIVE NewPath()
void ApplyLineTo(SkPath &p, SkScalar x, SkScalar y)
constexpr float y() const
constexpr float x() const
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
SkScalar fTop
smaller y-axis bounds