SkGeometry.h revision 0c5c3867bdbde1005a7bbb9de9df93cc10e27782
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkGeometry_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGeometry_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com/** An XRay is a half-line that runs from the specific point/origin to
16945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    +infinity in the X direction. e.g. XRay(3,5) is the half-line
17945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    (3,5)....(infinity, 5)
18945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com */
19945a139553a9c9da03766213661d7f5fd6ed3042reed@android.comtypedef SkPoint SkXRay;
20945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com
212e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org/** Given a line segment from pts[0] to pts[1], and an xray, return true if
222e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    they intersect. Optional outgoing "ambiguous" argument indicates
232e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    whether the answer is ambiguous because the query occurred exactly at
242e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    one of the endpoints' y coordinates, indicating that another query y
252e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    coordinate is preferred for robustness.
26945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com*/
27ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.combool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2],
28ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                       bool* ambiguous = NULL);
29945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a quadratic equation Ax^2 + Bx + C = 0, return 0, 1, 2 roots for the
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    equation.
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]);
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Set pt to the point on the src quadratic specified by t. t must be
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    0 <= t <= 1.0
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
40ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comvoid SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt,
41ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                  SkVector* tangent = NULL);
42ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comvoid SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt,
43ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                      SkVector* tangent = NULL);
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a src quadratic bezier, chop it at the specified t value,
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    where 0 < t < 1, and return the two new quadratics in dst:
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    dst[0..2] and dst[2..4]
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t);
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a src quadratic bezier, chop it at the specified t == 1/2,
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    The new quads are returned in dst[0..2] and dst[2..4]
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]);
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the 3 coefficients for a quadratic bezier (either X or Y values), look
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for extrema, and return the number of t-values that are found that represent
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    these extrema. If the quadratic has no extrema betwee (0..1) exclusive, the
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    function returns 0.
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Returned count      tValues[]
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    0                   ignored
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    1                   0 < tValues[0] < 1
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValues[1]);
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given 3 points on a quadratic bezier, chop it into 1, 2 beziers such that
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    the resulting beziers are monotonic in Y. This is called by the scan converter.
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Depending on what is returned, dst[] is treated as follows
69909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com    0   dst[0..2] is the original quad
70909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com    1   dst[0..2] and dst[2..4] are the two new quads
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]);
7377f0ef726f1f8b6769ed2509171afce8bac00b23reed@android.comint SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]);
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given 3 points on a quadratic bezier, divide it into 2 quadratics
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if the point of maximum curvature exists on the quad segment.
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Depending on what is returned, dst[] is treated as follows
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    1   dst[0..2] is the original quad
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    2   dst[0..2] and dst[2..4] are the two new quads
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If dst == null, it is ignored and only the count is returned.
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]);
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
84945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com/** Given 3 points on a quadratic bezier, use degree elevation to
85945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    convert it into the cubic fitting the same curve. The new cubic
86945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    curve is returned in dst[0..3].
87945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com*/
887ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgSK_API void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]);
89945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com
90ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com///////////////////////////////////////////////////////////////////////////////
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Convert from parametric from (pts) to polynomial coefficients
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    coeff[0]*T^3 + coeff[1]*T^2 + coeff[2]*T + coeff[3]
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkGetCubicCoeff(const SkPoint pts[4], SkScalar cx[4], SkScalar cy[4]);
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Set pt to the point on the src cubic specified by t. t must be
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    0 <= t <= 1.0
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
100ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comvoid SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* locOrNull,
101ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                   SkVector* tangentOrNull, SkVector* curvatureOrNull);
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a src cubic bezier, chop it at the specified t value,
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    where 0 < t < 1, and return the two new cubics in dst:
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    dst[0..3] and dst[3..6]
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t);
108647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com/** Given a src cubic bezier, chop it at the specified t values,
109647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    where 0 < t < 1, and return the new cubics in dst:
110647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    dst[0..3],dst[3..6],...,dst[3*t_count..3*(t_count+1)]
111647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com*/
112647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.comvoid SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar t[],
113ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                   int t_count);
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a src cubic bezier, chop it at the specified t == 1/2,
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    The new cubics are returned in dst[0..3] and dst[3..6]
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]);
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the 4 coefficients for a cubic bezier (either X or Y values), look
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for extrema, and return the number of t-values that are found that represent
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    these extrema. If the cubic has no extrema betwee (0..1) exclusive, the
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    function returns 0.
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Returned count      tValues[]
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    0                   ignored
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    1                   0 < tValues[0] < 1
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    2                   0 < tValues[0] < tValues[1] < 1
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
129ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comint SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d,
130ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                       SkScalar tValues[2]);
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    the resulting beziers are monotonic in Y. This is called by the scan converter.
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Depending on what is returned, dst[] is treated as follows
135909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com    0   dst[0..3] is the original cubic
136909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com    1   dst[0..3] and dst[3..6] are the two new cubics
137909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.com    2   dst[0..3], dst[3..6], dst[6..9] are the three new cubics
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If dst == null, it is ignored and only the count is returned.
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkChopCubicAtYExtrema(const SkPoint src[4], SkPoint dst[10]);
141909994fbae0ffb532f42feac8859f8d86bbf64dereed@android.comint SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10]);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given a cubic bezier, return 0, 1, or 2 t-values that represent the
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inflection points.
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2]);
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
148647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com/** Return 1 for no chop, 2 for having chopped the cubic at a single
149647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    inflection point, 3 for having chopped at 2 inflection points.
150dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com    dst will hold the resulting 1, 2, or 3 cubics.
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10]);
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]);
155ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comint SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13],
156ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                              SkScalar tValues[3] = NULL);
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com/** Given a monotonic cubic bezier, determine whether an xray intersects the
159945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    cubic.
160945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    By definition the cubic is open at the starting point; in other
161945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    words, if pt.fY is equivalent to cubic[0].fY, and pt.fX is to the
162945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    left of the curve, the line is not considered to cross the curve,
163945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    but if it is equal to cubic[3].fY then it is considered to
164945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    cross.
1652e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    Optional outgoing "ambiguous" argument indicates whether the answer is
1662e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    ambiguous because the query occurred exactly at one of the endpoints' y
1672e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    coordinates, indicating that another query y coordinate is preferred
1682e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    for robustness.
169945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com */
170ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.combool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4],
171ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                                 bool* ambiguous = NULL);
172945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com
173945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com/** Given an arbitrary cubic bezier, return the number of times an xray crosses
174945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    the cubic. Valid return values are [0..3]
175945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    By definition the cubic is open at the starting point; in other
176945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    words, if pt.fY is equivalent to cubic[0].fY, and pt.fX is to the
177945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    left of the curve, the line is not considered to cross the curve,
178945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    but if it is equal to cubic[3].fY then it is considered to
179945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com    cross.
1802e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    Optional outgoing "ambiguous" argument indicates whether the answer is
1812e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    ambiguous because the query occurred exactly at one of the endpoints' y
1822e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    coordinates or at a tangent point, indicating that another query y
1832e086190e55a01dc2f7b74df6f2828e8cac2b9abkbr@chromium.org    coordinate is preferred for robustness.
184945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com */
185ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comint SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4],
186ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                               bool* ambiguous = NULL);
187945a139553a9c9da03766213661d7f5fd6ed3042reed@android.com
188ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com///////////////////////////////////////////////////////////////////////////////
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comenum SkRotationDirection {
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    kCW_SkRotationDirection,
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    kCCW_SkRotationDirection
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Maximum number of points needed in the quadPoints[] parameter for
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBuildQuadArc()
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kSkBuildQuadArcStorage  17
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given 2 unit vectors and a rotation direction, fill out the specified
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    array of points with quadratic segments. Return is the number of points
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    written to, which will be { 0, 3, 5, 7, ... kSkBuildQuadArcStorage }
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    matrix, if not null, is appled to the points before they are returned.
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
206ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.comint SkBuildQuadArc(const SkVector& unitStart, const SkVector& unitStop,
207ad91799832b9ba2a3de30c0f57968148b4be17afreed@google.com                   SkRotationDirection, const SkMatrix*, SkPoint quadPoints[]);
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
209c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com// experimental
210c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.comstruct SkRationalQuad {
211c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    SkPoint  fPts[3];
212c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    SkScalar fW;
213c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com
214c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    void set(const SkPoint pts[3], SkScalar w) {
215c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com        memcpy(fPts, pts, 3 * sizeof(SkPoint));
216c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com        fW = w;
217c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    }
218c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com
219c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    void evalAt(SkScalar t, SkPoint* pt) const;
220c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com    void chopAt(SkScalar t, SkRationalQuad dst[2]) const;
2218d551011966a1bc14a654dbde704f343c0e222b6mike@reedtribe.org    void chop(SkRationalQuad dst[2]) const;
2227841c63136e8aa2d3aadbeab8432405abcd73c32skia.committer@gmail.com
2233df87cb36e9f9d2e04d2f81ac64cf3d778c33847mike@reedtribe.org    int computeQuadPOW2(SkScalar tol) const;
2243df87cb36e9f9d2e04d2f81ac64cf3d778c33847mike@reedtribe.org    int chopIntoQuadsPOW2(SkPoint pts[], int pow2) const;
2250c5c3867bdbde1005a7bbb9de9df93cc10e27782mike@reedtribe.org
2260c5c3867bdbde1005a7bbb9de9df93cc10e27782mike@reedtribe.org    bool findXExtrema(SkScalar* t) const;
2270c5c3867bdbde1005a7bbb9de9df93cc10e27782mike@reedtribe.org    bool findYExtrema(SkScalar* t) const;
2280c5c3867bdbde1005a7bbb9de9df93cc10e27782mike@reedtribe.org    bool chopAtXExtrema(SkRationalQuad dst[2]) const;
2290c5c3867bdbde1005a7bbb9de9df93cc10e27782mike@reedtribe.org    bool chopAtYExtrema(SkRationalQuad dst[2]) const;
230c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com};
231c518710d9a99c4d0adf759a102f4a1cb582f5939reed@google.com
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
233