1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_HWUI_PATH_TESSELLATOR_H
18 #define ANDROID_HWUI_PATH_TESSELLATOR_H
19 
20 #include <utils/Vector.h>
21 
22 #include "Matrix.h"
23 #include "Rect.h"
24 #include "Vertex.h"
25 #include "VertexBuffer.h"
26 
27 namespace android {
28 namespace uirenderer {
29 
30 /**
31  * Structure used for threshold values in outline path tessellation.
32  *
33  * TODO: PaintInfo should store one of this object, and initialized all values in constructor
34  * depending on its type (point, line or path).
35  */
36 struct PathApproximationInfo {
PathApproximationInfoPathApproximationInfo37     PathApproximationInfo(float invScaleX, float invScaleY, float pixelThreshold)
38         : thresholdSquared(pixelThreshold * pixelThreshold)
39         , sqrInvScaleX(invScaleX * invScaleX)
40         , sqrInvScaleY(invScaleY * invScaleY)
41         , thresholdForConicQuads(pixelThreshold * MathUtils::min(invScaleX, invScaleY) / 2.0f) {
42     };
43 
44     const float thresholdSquared;
45     const float sqrInvScaleX;
46     const float sqrInvScaleY;
47     const float thresholdForConicQuads;
48 };
49 
50 class PathTessellator {
51 public:
52     /**
53      * Populates scaleX and scaleY with the 'tessellation scale' of the transform - the effective X
54      * and Y scales that tessellation will take into account when generating the 1.0 pixel thick
55      * ramp.
56      *
57      * Two instances of the same shape (size, paint, etc.) will only generate the same vertices if
58      * their tessellation scales are equal.
59      */
60     static void extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY);
61 
62     /**
63      * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
64      * triangle strip. Note: joins are not currently supported.
65      *
66      * @param path The path to be approximated
67      * @param paint The paint the path will be drawn with, indicating AA, painting style
68      *        (stroke vs fill), stroke width, stroke cap & join style, etc.
69      * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
70      *        vertex approximation, and correct AA ramp offsetting.
71      * @param vertexBuffer The output buffer
72      */
73     static void tessellatePath(const SkPath& path, const SkPaint* paint,
74             const mat4& transform, VertexBuffer& vertexBuffer);
75 
76     /**
77      * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
78      * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
79      *
80      * @param points The center vertices of the points to be drawn
81      * @param count The number of floats making up the point vertices
82      * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
83      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
84      *        vertex approximation, and correct AA ramp offsetting
85      * @param vertexBuffer The output buffer
86      */
87     static void tessellatePoints(const float* points, int count, const SkPaint* paint,
88             const mat4& transform, VertexBuffer& vertexBuffer);
89 
90     /**
91      * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
92      * strip (with degenerate tris separating).
93      *
94      * @param points Pairs of endpoints defining the lines to be drawn
95      * @param count The number of floats making up the line vertices
96      * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
97      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
98      *        vertex approximation, and correct AA ramp offsetting
99      * @param vertexBuffer The output buffer
100      */
101     static void tessellateLines(const float* points, int count, const SkPaint* paint,
102             const mat4& transform, VertexBuffer& vertexBuffer);
103 
104     /**
105      * Approximates a convex outline into a clockwise Vector of 2d vertices.
106      *
107      * @param path The outline to be approximated
108      * @param threshold The threshold of acceptable error (in pixels) when approximating
109      * @param outputVertices An empty Vector which will be populated with the output
110      */
111     static bool approximatePathOutlineVertices(const SkPath &path, float threshold,
112             Vector<Vertex> &outputVertices);
113 
114 private:
115     static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
116             const PathApproximationInfo& approximationInfo, Vector<Vertex> &outputVertices);
117 
118 /*
119   endpoints a & b,
120   control c
121  */
122     static void recursiveQuadraticBezierVertices(
123             float ax, float ay,
124             float bx, float by,
125             float cx, float cy,
126             const PathApproximationInfo& approximationInfo,
127             Vector<Vertex> &outputVertices, int depth = 0);
128 
129 /*
130   endpoints p1, p2
131   control c1, c2
132  */
133     static void recursiveCubicBezierVertices(
134             float p1x, float p1y,
135             float c1x, float c1y,
136             float p2x, float p2y,
137             float c2x, float c2y,
138             const PathApproximationInfo& approximationInfo,
139             Vector<Vertex> &outputVertices, int depth = 0);
140 };
141 
142 }; // namespace uirenderer
143 }; // namespace android
144 
145 #endif // ANDROID_HWUI_PATH_TESSELLATOR_H
146