/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPathOpsCurve_DEFINE
#define SkPathOpsCurve_DEFINE
#include "SkIntersections.h"
#include "SkPathOpsCubic.h"
#include "SkPathOpsLine.h"
#include "SkPathOpsQuad.h"
static SkDPoint dline_xy_at_t(const SkPoint a[2], double t) {
SkDLine line;
line.set(a);
return line.ptAtT(t);
}
static SkDPoint dquad_xy_at_t(const SkPoint a[3], double t) {
SkDQuad quad;
quad.set(a);
return quad.ptAtT(t);
}
static SkDPoint dcubic_xy_at_t(const SkPoint a[4], double t) {
SkDCubic cubic;
cubic.set(a);
return cubic.ptAtT(t);
}
static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], double ) = {
NULL,
dline_xy_at_t,
dquad_xy_at_t,
dcubic_xy_at_t
};
static SkPoint fline_xy_at_t(const SkPoint a[2], double t) {
return dline_xy_at_t(a, t).asSkPoint();
}
static SkPoint fquad_xy_at_t(const SkPoint a[3], double t) {
return dquad_xy_at_t(a, t).asSkPoint();
}
static SkPoint fcubic_xy_at_t(const SkPoint a[4], double t) {
return dcubic_xy_at_t(a, t).asSkPoint();
}
static SkPoint (* const CurvePointAtT[])(const SkPoint[], double ) = {
NULL,
fline_xy_at_t,
fquad_xy_at_t,
fcubic_xy_at_t
};
static SkDVector dline_dxdy_at_t(const SkPoint a[2], double ) {
SkDLine line;
line.set(a);
return line[1] - line[0];
}
static SkDVector dquad_dxdy_at_t(const SkPoint a[3], double t) {
SkDQuad quad;
quad.set(a);
return quad.dxdyAtT(t);
}
static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], double t) {
SkDCubic cubic;
cubic.set(a);
return cubic.dxdyAtT(t);
}
static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], double ) = {
NULL,
dline_dxdy_at_t,
dquad_dxdy_at_t,
dcubic_dxdy_at_t
};
static SkVector fline_dxdy_at_t(const SkPoint a[2], double ) {
return a[1] - a[0];
}
static SkVector fquad_dxdy_at_t(const SkPoint a[3], double t) {
return dquad_dxdy_at_t(a, t).asSkVector();
}
static SkVector fcubic_dxdy_at_t(const SkPoint a[4], double t) {
return dcubic_dxdy_at_t(a, t).asSkVector();
}
static SkVector (* const CurveSlopeAtT[])(const SkPoint[], double ) = {
NULL,
fline_dxdy_at_t,
fquad_dxdy_at_t,
fcubic_dxdy_at_t
};
static SkPoint quad_top(const SkPoint a[3], double startT, double endT) {
SkDQuad quad;
quad.set(a);
SkDPoint topPt = quad.top(startT, endT);
return topPt.asSkPoint();
}
static SkPoint cubic_top(const SkPoint a[4], double startT, double endT) {
SkDCubic cubic;
cubic.set(a);
SkDPoint topPt = cubic.top(startT, endT);
return topPt.asSkPoint();
}
static SkPoint (* const CurveTop[])(const SkPoint[], double , double ) = {
NULL,
NULL,
quad_top,
cubic_top
};
static bool line_is_vertical(const SkPoint a[2], double startT, double endT) {
SkDLine line;
line.set(a);
SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) };
return AlmostEqualUlps(dst[0].fX, dst[1].fX);
}
static bool quad_is_vertical(const SkPoint a[3], double startT, double endT) {
SkDQuad quad;
quad.set(a);
SkDQuad dst = quad.subDivide(startT, endT);
return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX);
}
static bool cubic_is_vertical(const SkPoint a[4], double startT, double endT) {
SkDCubic cubic;
cubic.set(a);
SkDCubic dst = cubic.subDivide(startT, endT);
return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX)
&& AlmostEqualUlps(dst[2].fX, dst[3].fX);
}
static bool (* const CurveIsVertical[])(const SkPoint[], double , double) = {
NULL,
line_is_vertical,
quad_is_vertical,
cubic_is_vertical
};
static void line_intersect_ray(const SkPoint a[2], const SkDLine& ray, SkIntersections* i) {
SkDLine line;
line.set(a);
i->intersectRay(line, ray);
}
static void quad_intersect_ray(const SkPoint a[3], const SkDLine& ray, SkIntersections* i) {
SkDQuad quad;
quad.set(a);
i->intersectRay(quad, ray);
}
static void cubic_intersect_ray(const SkPoint a[4], const SkDLine& ray, SkIntersections* i) {
SkDCubic cubic;
cubic.set(a);
i->intersectRay(cubic, ray);
}
static void (* const CurveIntersectRay[])(const SkPoint[] , const SkDLine& , SkIntersections* ) = {
NULL,
line_intersect_ray,
quad_intersect_ray,
cubic_intersect_ray
};
#endif