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 "SkPathOpsCubic.h" 11 #include "SkPathOpsLine.h" 12 #include "SkPathOpsQuad.h" 13 14 static SkDPoint dline_xy_at_t(const SkPoint a[2], double t) { 15 SkDLine line; 16 line.set(a); 17 return line.ptAtT(t); 18 } 19 20 static SkDPoint dquad_xy_at_t(const SkPoint a[3], double t) { 21 SkDQuad quad; 22 quad.set(a); 23 return quad.ptAtT(t); 24 } 25 26 static SkDPoint dcubic_xy_at_t(const SkPoint a[4], double t) { 27 SkDCubic cubic; 28 cubic.set(a); 29 return cubic.ptAtT(t); 30 } 31 32 static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], double ) = { 33 NULL, 34 dline_xy_at_t, 35 dquad_xy_at_t, 36 dcubic_xy_at_t 37 }; 38 39 static SkPoint fline_xy_at_t(const SkPoint a[2], double t) { 40 return dline_xy_at_t(a, t).asSkPoint(); 41 } 42 43 static SkPoint fquad_xy_at_t(const SkPoint a[3], double t) { 44 return dquad_xy_at_t(a, t).asSkPoint(); 45 } 46 47 static SkPoint fcubic_xy_at_t(const SkPoint a[4], double t) { 48 return dcubic_xy_at_t(a, t).asSkPoint(); 49 } 50 51 static SkPoint (* const CurvePointAtT[])(const SkPoint[], double ) = { 52 NULL, 53 fline_xy_at_t, 54 fquad_xy_at_t, 55 fcubic_xy_at_t 56 }; 57 58 static SkDVector dline_dxdy_at_t(const SkPoint a[2], double ) { 59 SkDLine line; 60 line.set(a); 61 return line[1] - line[0]; 62 } 63 64 static SkDVector dquad_dxdy_at_t(const SkPoint a[3], double t) { 65 SkDQuad quad; 66 quad.set(a); 67 return quad.dxdyAtT(t); 68 } 69 70 static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], double t) { 71 SkDCubic cubic; 72 cubic.set(a); 73 return cubic.dxdyAtT(t); 74 } 75 76 static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], double ) = { 77 NULL, 78 dline_dxdy_at_t, 79 dquad_dxdy_at_t, 80 dcubic_dxdy_at_t 81 }; 82 83 static SkVector fline_dxdy_at_t(const SkPoint a[2], double ) { 84 return a[1] - a[0]; 85 } 86 87 static SkVector fquad_dxdy_at_t(const SkPoint a[3], double t) { 88 return dquad_dxdy_at_t(a, t).asSkVector(); 89 } 90 91 static SkVector fcubic_dxdy_at_t(const SkPoint a[4], double t) { 92 return dcubic_dxdy_at_t(a, t).asSkVector(); 93 } 94 95 static SkVector (* const CurveSlopeAtT[])(const SkPoint[], double ) = { 96 NULL, 97 fline_dxdy_at_t, 98 fquad_dxdy_at_t, 99 fcubic_dxdy_at_t 100 }; 101 102 static SkPoint quad_top(const SkPoint a[3], double startT, double endT) { 103 SkDQuad quad; 104 quad.set(a); 105 SkDPoint topPt = quad.top(startT, endT); 106 return topPt.asSkPoint(); 107 } 108 109 static SkPoint cubic_top(const SkPoint a[4], double startT, double endT) { 110 SkDCubic cubic; 111 cubic.set(a); 112 SkDPoint topPt = cubic.top(startT, endT); 113 return topPt.asSkPoint(); 114 } 115 116 static SkPoint (* const CurveTop[])(const SkPoint[], double , double ) = { 117 NULL, 118 NULL, 119 quad_top, 120 cubic_top 121 }; 122 123 static bool line_is_vertical(const SkPoint a[2], double startT, double endT) { 124 SkDLine line; 125 line.set(a); 126 SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) }; 127 return AlmostEqualUlps(dst[0].fX, dst[1].fX); 128 } 129 130 static bool quad_is_vertical(const SkPoint a[3], double startT, double endT) { 131 SkDQuad quad; 132 quad.set(a); 133 SkDQuad dst = quad.subDivide(startT, endT); 134 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX); 135 } 136 137 static bool cubic_is_vertical(const SkPoint a[4], double startT, double endT) { 138 SkDCubic cubic; 139 cubic.set(a); 140 SkDCubic dst = cubic.subDivide(startT, endT); 141 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX) 142 && AlmostEqualUlps(dst[2].fX, dst[3].fX); 143 } 144 145 static bool (* const CurveIsVertical[])(const SkPoint[], double , double) = { 146 NULL, 147 line_is_vertical, 148 quad_is_vertical, 149 cubic_is_vertical 150 }; 151 152 #endif 153