|  | /* | 
|  | * 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 |