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 class PathTessellator {
31 public:
32     /**
33      * Populates scaleX and scaleY with the 'tessellation scale' of the transform - the effective X
34      * and Y scales that tessellation will take into account when generating the 1.0 pixel thick
35      * ramp.
36      *
37      * Two instances of the same shape (size, paint, etc.) will only generate the same vertices if
38      * their tessellation scales are equal.
39      */
40     static void extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY);
41 
42     /**
43      * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
44      * triangle strip. Note: joins are not currently supported.
45      *
46      * @param path The path to be approximated
47      * @param paint The paint the path will be drawn with, indicating AA, painting style
48      *        (stroke vs fill), stroke width, stroke cap & join style, etc.
49      * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
50      *        vertex approximation, and correct AA ramp offsetting.
51      * @param vertexBuffer The output buffer
52      */
53     static void tessellatePath(const SkPath& path, const SkPaint* paint,
54             const mat4& transform, VertexBuffer& vertexBuffer);
55 
56     /**
57      * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
58      * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
59      *
60      * @param points The center vertices of the points to be drawn
61      * @param count The number of floats making up the point vertices
62      * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
63      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
64      *        vertex approximation, and correct AA ramp offsetting
65      * @param vertexBuffer The output buffer
66      */
67     static void tessellatePoints(const float* points, int count, const SkPaint* paint,
68             const mat4& transform, VertexBuffer& vertexBuffer);
69 
70     /**
71      * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
72      * strip (with degenerate tris separating).
73      *
74      * @param points Pairs of endpoints defining the lines to be drawn
75      * @param count The number of floats making up the line vertices
76      * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
77      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
78      *        vertex approximation, and correct AA ramp offsetting
79      * @param vertexBuffer The output buffer
80      */
81     static void tessellateLines(const float* points, int count, const SkPaint* paint,
82             const mat4& transform, VertexBuffer& vertexBuffer);
83 
84     /**
85      * Approximates a convex, CW outline into a Vector of 2d vertices.
86      *
87      * @param path The outline to be approximated
88      * @param thresholdSquared The threshold of acceptable error (in pixels) when approximating
89      * @param outputVertices An empty Vector which will be populated with the output
90      */
91     static bool approximatePathOutlineVertices(const SkPath &path, float thresholdSquared,
92             Vector<Vertex> &outputVertices);
93 
94 private:
95     static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
96             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
97             Vector<Vertex> &outputVertices);
98 
99 /*
100   endpoints a & b,
101   control c
102  */
103     static void recursiveQuadraticBezierVertices(
104             float ax, float ay,
105             float bx, float by,
106             float cx, float cy,
107             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
108             Vector<Vertex> &outputVertices, int depth = 0);
109 
110 /*
111   endpoints p1, p2
112   control c1, c2
113  */
114     static void recursiveCubicBezierVertices(
115             float p1x, float p1y,
116             float c1x, float c1y,
117             float p2x, float p2y,
118             float c2x, float c2y,
119             float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
120             Vector<Vertex> &outputVertices, int depth = 0);
121 };
122 
123 }; // namespace uirenderer
124 }; // namespace android
125 
126 #endif // ANDROID_HWUI_PATH_TESSELLATOR_H
127