blob: 2d6045e00c0c827e4dd2f71f75a94e29c612f52a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +000010#ifndef GrPathUtils_DEFINED
11#define GrPathUtils_DEFINED
12
bsalomon@google.comb9086a02012-11-01 18:02:54 +000013#include "GrRect.h"
bsalomon@google.com8d033a12012-04-27 15:52:53 +000014#include "SkPath.h"
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +000015#include "SkTArray.h"
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +000016
bsalomon@google.comb9086a02012-11-01 18:02:54 +000017class SkMatrix;
18
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +000019/**
20 * Utilities for evaluating paths.
21 */
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000022namespace GrPathUtils {
bsalomon@google.com81712882012-11-01 17:12:34 +000023 SkScalar scaleToleranceToSrc(SkScalar devTol,
bsalomon@google.comb9086a02012-11-01 18:02:54 +000024 const SkMatrix& viewM,
bsalomon@google.com38396322011-09-09 19:32:04 +000025 const GrRect& pathBounds);
tomhudson@google.comc10a8882011-06-28 15:19:32 +000026
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000027 /// Since we divide by tol if we're computing exact worst-case bounds,
28 /// very small tolerances will be increased to gMinCurveTol.
bsalomon@google.com8d033a12012-04-27 15:52:53 +000029 int worstCasePointCount(const SkPath&,
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000030 int* subpaths,
bsalomon@google.com81712882012-11-01 17:12:34 +000031 SkScalar tol);
bsalomon@google.com19713172012-03-15 13:51:08 +000032
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000033 /// Since we divide by tol if we're computing exact worst-case bounds,
34 /// very small tolerances will be increased to gMinCurveTol.
bsalomon@google.com81712882012-11-01 17:12:34 +000035 uint32_t quadraticPointCount(const GrPoint points[], SkScalar tol);
bsalomon@google.com19713172012-03-15 13:51:08 +000036
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000037 uint32_t generateQuadraticPoints(const GrPoint& p0,
38 const GrPoint& p1,
39 const GrPoint& p2,
bsalomon@google.com81712882012-11-01 17:12:34 +000040 SkScalar tolSqd,
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000041 GrPoint** points,
42 uint32_t pointsLeft);
bsalomon@google.com19713172012-03-15 13:51:08 +000043
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000044 /// Since we divide by tol if we're computing exact worst-case bounds,
45 /// very small tolerances will be increased to gMinCurveTol.
bsalomon@google.com81712882012-11-01 17:12:34 +000046 uint32_t cubicPointCount(const GrPoint points[], SkScalar tol);
bsalomon@google.com19713172012-03-15 13:51:08 +000047
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000048 uint32_t generateCubicPoints(const GrPoint& p0,
49 const GrPoint& p1,
50 const GrPoint& p2,
51 const GrPoint& p3,
bsalomon@google.com81712882012-11-01 17:12:34 +000052 SkScalar tolSqd,
bsalomon@google.com181e9bd2011-09-07 18:42:30 +000053 GrPoint** points,
54 uint32_t pointsLeft);
bsalomon@google.com19713172012-03-15 13:51:08 +000055
56 // A 2x3 matrix that goes from the 2d space coordinates to UV space where
57 // u^2-v = 0 specifies the quad. The matrix is determined by the control
58 // points of the quadratic.
59 class QuadUVMatrix {
60 public:
61 QuadUVMatrix() {};
62 // Initialize the matrix from the control pts
63 QuadUVMatrix(const GrPoint controlPts[3]) { this->set(controlPts); }
64 void set(const GrPoint controlPts[3]);
65
66 /**
67 * Applies the matrix to vertex positions to compute UV coords. This
68 * has been templated so that the compiler can easliy unroll the loop
69 * and reorder to avoid stalling for loads. The assumption is that a
70 * path renderer will have a small fixed number of vertices that it
71 * uploads for each quad.
72 *
73 * N is the number of vertices.
74 * STRIDE is the size of each vertex.
75 * UV_OFFSET is the offset of the UV values within each vertex.
76 * vertices is a pointer to the first vertex.
77 */
78 template <int N, size_t STRIDE, size_t UV_OFFSET>
79 void apply(const void* vertices) {
80 intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices);
81 intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + UV_OFFSET;
82 float sx = fM[0];
83 float kx = fM[1];
84 float tx = fM[2];
85 float ky = fM[3];
86 float sy = fM[4];
87 float ty = fM[5];
88 for (int i = 0; i < N; ++i) {
89 const GrPoint* xy = reinterpret_cast<const GrPoint*>(xyPtr);
90 GrPoint* uv = reinterpret_cast<GrPoint*>(uvPtr);
91 uv->fX = sx * xy->fX + kx * xy->fY + tx;
92 uv->fY = ky * xy->fX + sy * xy->fY + ty;
93 xyPtr += STRIDE;
94 uvPtr += STRIDE;
95 }
96 }
97 private:
98 float fM[6];
99 };
100
bsalomon@google.coma51ab842012-07-10 19:53:34 +0000101
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000102 // Converts a cubic into a sequence of quads. If working in device space
103 // use tolScale = 1, otherwise set based on stretchiness of the matrix. The
104 // result is sets of 3 points in quads (TODO: share endpoints in returned
105 // array)
bsalomon@google.coma51ab842012-07-10 19:53:34 +0000106 // When we approximate a cubic {a,b,c,d} with a quadratic we may have to
107 // ensure that the new control point lies between the lines ab and cd. The
108 // convex path renderer requires this. It starts with a path where all the
109 // control points taken together form a convex polygon. It relies on this
110 // property and the quadratic approximation of cubics step cannot alter it.
111 // Setting constrainWithinTangents to true enforces this property. When this
112 // is true the cubic must be simple and dir must specify the orientation of
113 // the cubic. Otherwise, dir is ignored.
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000114 void convertCubicToQuads(const GrPoint p[4],
115 SkScalar tolScale,
bsalomon@google.coma51ab842012-07-10 19:53:34 +0000116 bool constrainWithinTangents,
117 SkPath::Direction dir,
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000118 SkTArray<SkPoint, true>* quads);
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +0000119};
120#endif