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
27namespace android {
28namespace uirenderer {
29
30class PathTessellator {
31public:
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
94private:
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