1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #ifndef SkPathOpsCurve_DEFINE 8 #define SkPathOpsCurve_DEFINE 9 10 #include "SkIntersections.h" 11 #include "SkPathOpsCubic.h" 12 #include "SkPathOpsLine.h" 13 #include "SkPathOpsQuad.h" 14 15 static SkDPoint dline_xy_at_t(const SkPoint a[2], double t) { 16 SkDLine line; 17 line.set(a); 18 return line.ptAtT(t); 19 } 20 21 static SkDPoint dquad_xy_at_t(const SkPoint a[3], double t) { 22 SkDQuad quad; 23 quad.set(a); 24 return quad.ptAtT(t); 25 } 26 27 static SkDPoint dcubic_xy_at_t(const SkPoint a[4], double t) { 28 SkDCubic cubic; 29 cubic.set(a); 30 return cubic.ptAtT(t); 31 } 32 33 static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], double ) = { 34 NULL, 35 dline_xy_at_t, 36 dquad_xy_at_t, 37 dcubic_xy_at_t 38 }; 39 40 static SkPoint fline_xy_at_t(const SkPoint a[2], double t) { 41 return dline_xy_at_t(a, t).asSkPoint(); 42 } 43 44 static SkPoint fquad_xy_at_t(const SkPoint a[3], double t) { 45 return dquad_xy_at_t(a, t).asSkPoint(); 46 } 47 48 static SkPoint fcubic_xy_at_t(const SkPoint a[4], double t) { 49 return dcubic_xy_at_t(a, t).asSkPoint(); 50 } 51 52 static SkPoint (* const CurvePointAtT[])(const SkPoint[], double ) = { 53 NULL, 54 fline_xy_at_t, 55 fquad_xy_at_t, 56 fcubic_xy_at_t 57 }; 58 59 static SkDVector dline_dxdy_at_t(const SkPoint a[2], double ) { 60 SkDLine line; 61 line.set(a); 62 return line[1] - line[0]; 63 } 64 65 static SkDVector dquad_dxdy_at_t(const SkPoint a[3], double t) { 66 SkDQuad quad; 67 quad.set(a); 68 return quad.dxdyAtT(t); 69 } 70 71 static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], double t) { 72 SkDCubic cubic; 73 cubic.set(a); 74 return cubic.dxdyAtT(t); 75 } 76 77 static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], double ) = { 78 NULL, 79 dline_dxdy_at_t, 80 dquad_dxdy_at_t, 81 dcubic_dxdy_at_t 82 }; 83 84 static SkVector fline_dxdy_at_t(const SkPoint a[2], double ) { 85 return a[1] - a[0]; 86 } 87 88 static SkVector fquad_dxdy_at_t(const SkPoint a[3], double t) { 89 return dquad_dxdy_at_t(a, t).asSkVector(); 90 } 91 92 static SkVector fcubic_dxdy_at_t(const SkPoint a[4], double t) { 93 return dcubic_dxdy_at_t(a, t).asSkVector(); 94 } 95 96 static SkVector (* const CurveSlopeAtT[])(const SkPoint[], double ) = { 97 NULL, 98 fline_dxdy_at_t, 99 fquad_dxdy_at_t, 100 fcubic_dxdy_at_t 101 }; 102 103 static SkPoint quad_top(const SkPoint a[3], double startT, double endT) { 104 SkDQuad quad; 105 quad.set(a); 106 SkDPoint topPt = quad.top(startT, endT); 107 return topPt.asSkPoint(); 108 } 109 110 static SkPoint cubic_top(const SkPoint a[4], double startT, double endT) { 111 SkDCubic cubic; 112 cubic.set(a); 113 SkDPoint topPt = cubic.top(startT, endT); 114 return topPt.asSkPoint(); 115 } 116 117 static SkPoint (* const CurveTop[])(const SkPoint[], double , double ) = { 118 NULL, 119 NULL, 120 quad_top, 121 cubic_top 122 }; 123 124 static bool line_is_vertical(const SkPoint a[2], double startT, double endT) { 125 SkDLine line; 126 line.set(a); 127 SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) }; 128 return AlmostEqualUlps(dst[0].fX, dst[1].fX); 129 } 130 131 static bool quad_is_vertical(const SkPoint a[3], double startT, double endT) { 132 SkDQuad quad; 133 quad.set(a); 134 SkDQuad dst = quad.subDivide(startT, endT); 135 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX); 136 } 137 138 static bool cubic_is_vertical(const SkPoint a[4], double startT, double endT) { 139 SkDCubic cubic; 140 cubic.set(a); 141 SkDCubic dst = cubic.subDivide(startT, endT); 142 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX) 143 && AlmostEqualUlps(dst[2].fX, dst[3].fX); 144 } 145 146 static bool (* const CurveIsVertical[])(const SkPoint[], double , double) = { 147 NULL, 148 line_is_vertical, 149 quad_is_vertical, 150 cubic_is_vertical 151 }; 152 153 static void line_intersect_ray(const SkPoint a[2], const SkDLine& ray, SkIntersections* i) { 154 SkDLine line; 155 line.set(a); 156 i->intersectRay(line, ray); 157 } 158 159 static void quad_intersect_ray(const SkPoint a[3], const SkDLine& ray, SkIntersections* i) { 160 SkDQuad quad; 161 quad.set(a); 162 i->intersectRay(quad, ray); 163 } 164 165 static void cubic_intersect_ray(const SkPoint a[4], const SkDLine& ray, SkIntersections* i) { 166 SkDCubic cubic; 167 cubic.set(a); 168 i->intersectRay(cubic, ray); 169 } 170 171 static void (* const CurveIntersectRay[])(const SkPoint[] , const SkDLine& , SkIntersections* ) = { 172 NULL, 173 line_intersect_ray, 174 quad_intersect_ray, 175 cubic_intersect_ray 176 }; 177 178 #endif 179