Home | History | Annotate | Download | only in pathops
      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