1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrPathUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,173 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrPathUtils_DEFINED 1.12 +#define GrPathUtils_DEFINED 1.13 + 1.14 +#include "GrPoint.h" 1.15 +#include "SkRect.h" 1.16 +#include "SkPath.h" 1.17 +#include "SkTArray.h" 1.18 + 1.19 +class SkMatrix; 1.20 + 1.21 +/** 1.22 + * Utilities for evaluating paths. 1.23 + */ 1.24 +namespace GrPathUtils { 1.25 + SkScalar scaleToleranceToSrc(SkScalar devTol, 1.26 + const SkMatrix& viewM, 1.27 + const SkRect& pathBounds); 1.28 + 1.29 + /// Since we divide by tol if we're computing exact worst-case bounds, 1.30 + /// very small tolerances will be increased to gMinCurveTol. 1.31 + int worstCasePointCount(const SkPath&, 1.32 + int* subpaths, 1.33 + SkScalar tol); 1.34 + 1.35 + /// Since we divide by tol if we're computing exact worst-case bounds, 1.36 + /// very small tolerances will be increased to gMinCurveTol. 1.37 + uint32_t quadraticPointCount(const GrPoint points[], SkScalar tol); 1.38 + 1.39 + uint32_t generateQuadraticPoints(const GrPoint& p0, 1.40 + const GrPoint& p1, 1.41 + const GrPoint& p2, 1.42 + SkScalar tolSqd, 1.43 + GrPoint** points, 1.44 + uint32_t pointsLeft); 1.45 + 1.46 + /// Since we divide by tol if we're computing exact worst-case bounds, 1.47 + /// very small tolerances will be increased to gMinCurveTol. 1.48 + uint32_t cubicPointCount(const GrPoint points[], SkScalar tol); 1.49 + 1.50 + uint32_t generateCubicPoints(const GrPoint& p0, 1.51 + const GrPoint& p1, 1.52 + const GrPoint& p2, 1.53 + const GrPoint& p3, 1.54 + SkScalar tolSqd, 1.55 + GrPoint** points, 1.56 + uint32_t pointsLeft); 1.57 + 1.58 + // A 2x3 matrix that goes from the 2d space coordinates to UV space where 1.59 + // u^2-v = 0 specifies the quad. The matrix is determined by the control 1.60 + // points of the quadratic. 1.61 + class QuadUVMatrix { 1.62 + public: 1.63 + QuadUVMatrix() {}; 1.64 + // Initialize the matrix from the control pts 1.65 + QuadUVMatrix(const GrPoint controlPts[3]) { this->set(controlPts); } 1.66 + void set(const GrPoint controlPts[3]); 1.67 + 1.68 + /** 1.69 + * Applies the matrix to vertex positions to compute UV coords. This 1.70 + * has been templated so that the compiler can easliy unroll the loop 1.71 + * and reorder to avoid stalling for loads. The assumption is that a 1.72 + * path renderer will have a small fixed number of vertices that it 1.73 + * uploads for each quad. 1.74 + * 1.75 + * N is the number of vertices. 1.76 + * STRIDE is the size of each vertex. 1.77 + * UV_OFFSET is the offset of the UV values within each vertex. 1.78 + * vertices is a pointer to the first vertex. 1.79 + */ 1.80 + template <int N, size_t STRIDE, size_t UV_OFFSET> 1.81 + void apply(const void* vertices) { 1.82 + intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices); 1.83 + intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + UV_OFFSET; 1.84 + float sx = fM[0]; 1.85 + float kx = fM[1]; 1.86 + float tx = fM[2]; 1.87 + float ky = fM[3]; 1.88 + float sy = fM[4]; 1.89 + float ty = fM[5]; 1.90 + for (int i = 0; i < N; ++i) { 1.91 + const GrPoint* xy = reinterpret_cast<const GrPoint*>(xyPtr); 1.92 + GrPoint* uv = reinterpret_cast<GrPoint*>(uvPtr); 1.93 + uv->fX = sx * xy->fX + kx * xy->fY + tx; 1.94 + uv->fY = ky * xy->fX + sy * xy->fY + ty; 1.95 + xyPtr += STRIDE; 1.96 + uvPtr += STRIDE; 1.97 + } 1.98 + } 1.99 + private: 1.100 + float fM[6]; 1.101 + }; 1.102 + 1.103 + // Input is 3 control points and a weight for a bezier conic. Calculates the 1.104 + // three linear functionals (K,L,M) that represent the implicit equation of the 1.105 + // conic, K^2 - LM. 1.106 + // 1.107 + // Output: 1.108 + // K = (klm[0], klm[1], klm[2]) 1.109 + // L = (klm[3], klm[4], klm[5]) 1.110 + // M = (klm[6], klm[7], klm[8]) 1.111 + void getConicKLM(const SkPoint p[3], const SkScalar weight, SkScalar klm[9]); 1.112 + 1.113 + // Converts a cubic into a sequence of quads. If working in device space 1.114 + // use tolScale = 1, otherwise set based on stretchiness of the matrix. The 1.115 + // result is sets of 3 points in quads (TODO: share endpoints in returned 1.116 + // array) 1.117 + // When we approximate a cubic {a,b,c,d} with a quadratic we may have to 1.118 + // ensure that the new control point lies between the lines ab and cd. The 1.119 + // convex path renderer requires this. It starts with a path where all the 1.120 + // control points taken together form a convex polygon. It relies on this 1.121 + // property and the quadratic approximation of cubics step cannot alter it. 1.122 + // Setting constrainWithinTangents to true enforces this property. When this 1.123 + // is true the cubic must be simple and dir must specify the orientation of 1.124 + // the cubic. Otherwise, dir is ignored. 1.125 + void convertCubicToQuads(const GrPoint p[4], 1.126 + SkScalar tolScale, 1.127 + bool constrainWithinTangents, 1.128 + SkPath::Direction dir, 1.129 + SkTArray<SkPoint, true>* quads); 1.130 + 1.131 + // Chops the cubic bezier passed in by src, at the double point (intersection point) 1.132 + // if the curve is a cubic loop. If it is a loop, there will be two parametric values for 1.133 + // the double point: ls and ms. We chop the cubic at these values if they are between 0 and 1. 1.134 + // Return value: 1.135 + // Value of 3: ls and ms are both between (0,1), and dst will contain the three cubics, 1.136 + // dst[0..3], dst[3..6], and dst[6..9] if dst is not NULL 1.137 + // Value of 2: Only one of ls and ms are between (0,1), and dst will contain the two cubics, 1.138 + // dst[0..3] and dst[3..6] if dst is not NULL 1.139 + // Value of 1: Neither ls or ms are between (0,1), and dst will contain the one original cubic, 1.140 + // dst[0..3] if dst is not NULL 1.141 + // 1.142 + // Optional KLM Calculation: 1.143 + // The function can also return the KLM linear functionals for the chopped cubic implicit form 1.144 + // of K^3 - LM. 1.145 + // It will calculate a single set of KLM values that can be shared by all sub cubics, except 1.146 + // for the subsection that is "the loop" the K and L values need to be negated. 1.147 + // Output: 1.148 + // klm: Holds the values for the linear functionals as: 1.149 + // K = (klm[0], klm[1], klm[2]) 1.150 + // L = (klm[3], klm[4], klm[5]) 1.151 + // M = (klm[6], klm[7], klm[8]) 1.152 + // klm_rev: These values are flags for the corresponding sub cubic saying whether or not 1.153 + // the K and L values need to be flipped. A value of -1.f means flip K and L and 1.154 + // a value of 1.f means do nothing. 1.155 + // *****DO NOT FLIP M, JUST K AND L***** 1.156 + // 1.157 + // Notice that the klm lines are calculated in the same space as the input control points. 1.158 + // If you transform the points the lines will also need to be transformed. This can be done 1.159 + // by mapping the lines with the inverse-transpose of the matrix used to map the points. 1.160 + int chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10] = NULL, 1.161 + SkScalar klm[9] = NULL, SkScalar klm_rev[3] = NULL); 1.162 + 1.163 + // Input is p which holds the 4 control points of a non-rational cubic Bezier curve. 1.164 + // Output is the coefficients of the three linear functionals K, L, & M which 1.165 + // represent the implicit form of the cubic as f(x,y,w) = K^3 - LM. The w term 1.166 + // will always be 1. The output is stored in the array klm, where the values are: 1.167 + // K = (klm[0], klm[1], klm[2]) 1.168 + // L = (klm[3], klm[4], klm[5]) 1.169 + // M = (klm[6], klm[7], klm[8]) 1.170 + // 1.171 + // Notice that the klm lines are calculated in the same space as the input control points. 1.172 + // If you transform the points the lines will also need to be transformed. This can be done 1.173 + // by mapping the lines with the inverse-transpose of the matrix used to map the points. 1.174 + void getCubicKLM(const SkPoint p[4], SkScalar klm[9]); 1.175 +}; 1.176 +#endif