1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 69d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 79d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 89d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org#ifndef GrPathUtils_DEFINED 99d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org#define GrPathUtils_DEFINED 109d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 11febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton#include "SkGeometry.h" 12fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org#include "SkRect.h" 13026beb52a29a620290fcfb24f1e7e9e75547b80freed#include "SkPathPriv.h" 1469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com#include "SkTArray.h" 159d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 16b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.comclass SkMatrix; 17b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com 189d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/** 199d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Utilities for evaluating paths. 209d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 21181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.comnamespace GrPathUtils { 2225294d76b1c5ca34ba6cc7033ee42af6484b046bBrian Osman // Very small tolerances will be increased to a minimum threshold value, to avoid division 2325294d76b1c5ca34ba6cc7033ee42af6484b046bBrian Osman // problems in subsequent math. 2481712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar scaleToleranceToSrc(SkScalar devTol, 25b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix& viewM, 26fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org const SkRect& pathBounds); 27181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com 288d033a1b125886c62906d975b5cc28a382064526bsalomon@google.com int worstCasePointCount(const SkPath&, 29181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com int* subpaths, 3081712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar tol); 311971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 32972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org uint32_t quadraticPointCount(const SkPoint points[], SkScalar tol); 331971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 34972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org uint32_t generateQuadraticPoints(const SkPoint& p0, 35972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint& p1, 36972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint& p2, 3781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar tolSqd, 38972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint** points, 39181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com uint32_t pointsLeft); 401971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 41972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org uint32_t cubicPointCount(const SkPoint points[], SkScalar tol); 421971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 43972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org uint32_t generateCubicPoints(const SkPoint& p0, 44972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint& p1, 45972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint& p2, 46972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint& p3, 4781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalar tolSqd, 48972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint** points, 49181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com uint32_t pointsLeft); 501971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 511971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com // A 2x3 matrix that goes from the 2d space coordinates to UV space where 521971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com // u^2-v = 0 specifies the quad. The matrix is determined by the control 531971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com // points of the quadratic. 541971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com class QuadUVMatrix { 551971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com public: 56fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein QuadUVMatrix() {} 571971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com // Initialize the matrix from the control pts 58972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org QuadUVMatrix(const SkPoint controlPts[3]) { this->set(controlPts); } 59972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org void set(const SkPoint controlPts[3]); 601971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 611971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com /** 621971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * Applies the matrix to vertex positions to compute UV coords. This 631971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * has been templated so that the compiler can easliy unroll the loop 641971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * and reorder to avoid stalling for loads. The assumption is that a 651971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * path renderer will have a small fixed number of vertices that it 661971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * uploads for each quad. 671971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * 681971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * N is the number of vertices. 691971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * STRIDE is the size of each vertex. 701971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * UV_OFFSET is the offset of the UV values within each vertex. 711971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com * vertices is a pointer to the first vertex. 721971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com */ 731971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com template <int N, size_t STRIDE, size_t UV_OFFSET> 74144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void apply(const void* vertices) const { 751971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices); 761971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + UV_OFFSET; 771971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float sx = fM[0]; 781971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float kx = fM[1]; 791971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float tx = fM[2]; 801971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float ky = fM[3]; 811971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float sy = fM[4]; 821971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float ty = fM[5]; 831971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com for (int i = 0; i < N; ++i) { 84972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org const SkPoint* xy = reinterpret_cast<const SkPoint*>(xyPtr); 85972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint* uv = reinterpret_cast<SkPoint*>(uvPtr); 861971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com uv->fX = sx * xy->fX + kx * xy->fY + tx; 871971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com uv->fY = ky * xy->fX + sy * xy->fY + ty; 881971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com xyPtr += STRIDE; 891971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com uvPtr += STRIDE; 901971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com } 911971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com } 921971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com private: 931971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com float fM[6]; 941971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com }; 951971317bb43580330a9e7e9a1c09c5025fe84aacbsalomon@google.com 96139484095f014ab08265c32337fddeeec6c0877dcommit-bot@chromium.org // Input is 3 control points and a weight for a bezier conic. Calculates the 97139484095f014ab08265c32337fddeeec6c0877dcommit-bot@chromium.org // three linear functionals (K,L,M) that represent the implicit equation of the 98cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // conic, k^2 - lm. 99139484095f014ab08265c32337fddeeec6c0877dcommit-bot@chromium.org // 100cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // Output: klm holds the linear functionals K,L,M as row vectors: 101cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // 102cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // | ..K.. | | x | | k | 103cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // | ..L.. | * | y | == | l | 104cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // | ..M.. | | 1 | | m | 105cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // 106cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton void getConicKLM(const SkPoint p[3], const SkScalar weight, SkMatrix* klm); 107a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com 10869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com // Converts a cubic into a sequence of quads. If working in device space 10969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com // use tolScale = 1, otherwise set based on stretchiness of the matrix. The 11018fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon // result is sets of 3 points in quads. 11118fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon void convertCubicToQuads(const SkPoint p[4], 11218fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon SkScalar tolScale, 11318fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon SkTArray<SkPoint, true>* quads); 11418fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon 115a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // When we approximate a cubic {a,b,c,d} with a quadratic we may have to 116a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // ensure that the new control point lies between the lines ab and cd. The 117a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // convex path renderer requires this. It starts with a path where all the 118a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // control points taken together form a convex polygon. It relies on this 119a51ab8416db9772a2eae3122f4f69801642daeb5bsalomon@google.com // property and the quadratic approximation of cubics step cannot alter it. 12018fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon // This variation enforces this constraint. The cubic must be simple and dir 12118fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon // must specify the orientation of the contour containing the cubic. 12218fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon void convertCubicToQuadsConstrainToTangents(const SkPoint p[4], 12318fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon SkScalar tolScale, 12418fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon SkPathPriv::FirstDirection dir, 12518fab30d7c4858ef2521e0380573aac5a21b2ed9bsalomon SkTArray<SkPoint, true>* quads); 126858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org 127695db408437807d049ecc02b3b852704092728f2Chris Dalton enum class ExcludedTerm { 128695db408437807d049ecc02b3b852704092728f2Chris Dalton kNonInvertible, 129695db408437807d049ecc02b3b852704092728f2Chris Dalton kQuadraticTerm, 130695db408437807d049ecc02b3b852704092728f2Chris Dalton kLinearTerm 131695db408437807d049ecc02b3b852704092728f2Chris Dalton }; 132695db408437807d049ecc02b3b852704092728f2Chris Dalton 133695db408437807d049ecc02b3b852704092728f2Chris Dalton // Computes the inverse-transpose of the cubic's power basis matrix, after removing a specific 134695db408437807d049ecc02b3b852704092728f2Chris Dalton // row of coefficients. 135695db408437807d049ecc02b3b852704092728f2Chris Dalton // 136695db408437807d049ecc02b3b852704092728f2Chris Dalton // E.g. if the cubic is defined in power basis form as follows: 137695db408437807d049ecc02b3b852704092728f2Chris Dalton // 138695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x3 y3 0 | 139695db408437807d049ecc02b3b852704092728f2Chris Dalton // C(t,s) = [t^3 t^2*s t*s^2 s^3] * | x2 y2 0 | 140695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x1 y1 0 | 141695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x0 y0 1 | 142695db408437807d049ecc02b3b852704092728f2Chris Dalton // 143695db408437807d049ecc02b3b852704092728f2Chris Dalton // And the excluded term is "kQuadraticTerm", then the resulting inverse-transpose will be: 144695db408437807d049ecc02b3b852704092728f2Chris Dalton // 145695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x3 y3 0 | -1 T 146695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x1 y1 0 | 147695db408437807d049ecc02b3b852704092728f2Chris Dalton // | x0 y0 1 | 148695db408437807d049ecc02b3b852704092728f2Chris Dalton // 149695db408437807d049ecc02b3b852704092728f2Chris Dalton // (The term to exclude is chosen based on maximizing the resulting matrix determinant.) 150695db408437807d049ecc02b3b852704092728f2Chris Dalton // 151695db408437807d049ecc02b3b852704092728f2Chris Dalton // This can be used to find the KLM linear functionals: 152695db408437807d049ecc02b3b852704092728f2Chris Dalton // 153695db408437807d049ecc02b3b852704092728f2Chris Dalton // | ..K.. | | ..kcoeffs.. | 154695db408437807d049ecc02b3b852704092728f2Chris Dalton // | ..L.. | = | ..lcoeffs.. | * inverse_transpose_power_basis_matrix 155695db408437807d049ecc02b3b852704092728f2Chris Dalton // | ..M.. | | ..mcoeffs.. | 156695db408437807d049ecc02b3b852704092728f2Chris Dalton // 157695db408437807d049ecc02b3b852704092728f2Chris Dalton // NOTE: the same term that was excluded here must also be removed from the corresponding column 158695db408437807d049ecc02b3b852704092728f2Chris Dalton // of the klmcoeffs matrix. 159695db408437807d049ecc02b3b852704092728f2Chris Dalton // 160695db408437807d049ecc02b3b852704092728f2Chris Dalton // Returns which row of coefficients was removed, or kNonInvertible if the cubic was degenerate. 161695db408437807d049ecc02b3b852704092728f2Chris Dalton ExcludedTerm calcCubicInverseTransposePowerBasisMatrix(const SkPoint p[4], SkMatrix* out); 162695db408437807d049ecc02b3b852704092728f2Chris Dalton 163febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // Computes the KLM linear functionals for the cubic implicit form. The "right" side of the 164febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // curve (when facing in the direction of increasing parameter values) will be the area that 165febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // satisfies: 166febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 167febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // k^3 < l*m 168febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 169febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // Output: 170febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 171febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // klm: Holds the linear functionals K,L,M as row vectors: 172febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 173febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // | ..K.. | | x | | k | 174febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // | ..L.. | * | y | == | l | 175febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // | ..M.. | | 1 | | m | 176febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 177febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // NOTE: the KLM lines are calculated in the same space as the input control points. If you 178febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // transform the points the lines will also need to be transformed. This can be done by mapping 179febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // the lines with the inverse-transpose of the matrix used to map the points. 180febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 181febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // t[],s[]: These are set to the two homogeneous parameter values at which points the lines L&M 182febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // intersect with K (See SkClassifyCubic). 183febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // 184febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // Returns the cubic's classification. 185390f6cd6f9f9ddd8a53da804cee3eff60cd2e2b4Chris Dalton SkCubicType getCubicKLM(const SkPoint src[4], SkMatrix* klm, double t[2], double s[2]); 186febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton 187858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // Chops the cubic bezier passed in by src, at the double point (intersection point) 188858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // if the curve is a cubic loop. If it is a loop, there will be two parametric values for 189cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // the double point: t1 and t2. We chop the cubic at these values if they are between 0 and 1. 190858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // Return value: 191cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // Value of 3: t1 and t2 are both between (0,1), and dst will contain the three cubics, 19296fcdcc219d2a0d3579719b84b28bede76efba64halcanary // dst[0..3], dst[3..6], and dst[6..9] if dst is not nullptr 193cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // Value of 2: Only one of t1 and t2 are between (0,1), and dst will contain the two cubics, 19496fcdcc219d2a0d3579719b84b28bede76efba64halcanary // dst[0..3] and dst[3..6] if dst is not nullptr 195cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // Value of 1: Neither t1 nor t2 are between (0,1), and dst will contain the one original cubic, 196febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // src[0..3] 197cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // 198858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // Output: 199858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // 200febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // klm: Holds the linear functionals K,L,M as row vectors. (See getCubicKLM().) 201cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // 202cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // loopIndex: This value will tell the caller which of the chopped sections (if any) are the 203cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // actual loop. A value of -1 means there is no loop section. The caller can then use 204cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // this value to decide how/if they want to flip the orientation of this section. 205cc26127920069cbd83e92cca3c69bb56cb165bcccsmartdalton // The flip should be done by negating the k and l values as follows: 206858638d8a5bef8f9940ccec2346a9bcc5f804979commit-bot@chromium.org // 207febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton // KLM.postScale(-1, -1) 208febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton int chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10], SkMatrix* klm, 209febbffad1c24136f041d7fc2d5ffcd50e47a047fChris Dalton int* loopIndex); 2102b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco 2112b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco // When tessellating curved paths into linear segments, this defines the maximum distance 2122b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco // in screen space which a segment may deviate from the mathmatically correct value. 2132b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco // Above this value, the segment will be subdivided. 2142b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco // This value was chosen to approximate the supersampling accuracy of the raster path (16 2152b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco // samples, or one quarter pixel). 2162b4bb07492790d7d18dc046f05999915d4384c5dsenorblanco static const SkScalar kDefaultTolerance = SkDoubleToScalar(0.25); 21749b7b6f38fc9d6cbcfa5865db364ff79c3ed7bfeBrian Osman 21849b7b6f38fc9d6cbcfa5865db364ff79c3ed7bfeBrian Osman // We guarantee that no quad or cubic will ever produce more than this many points 21949b7b6f38fc9d6cbcfa5865db364ff79c3ed7bfeBrian Osman static const int kMaxPointsPerCurve = 1 << 10; 2209d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org}; 2219d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org#endif 222