summaryrefslogtreecommitdiffstats
path: root/libs/hwui/PathTessellator.h
blob: 16c8b36a6a9d2d97fec23462a8e7b363ca695ac1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HWUI_PATH_TESSELLATOR_H
#define ANDROID_HWUI_PATH_TESSELLATOR_H

#include <utils/Vector.h>

#include "Matrix.h"
#include "Rect.h"
#include "Vertex.h"
#include "VertexBuffer.h"

namespace android {
namespace uirenderer {

/**
 * Structure used for threshold values in outline path tessellation.
 *
 * TODO: PaintInfo should store one of this object, and initialized all values in constructor
 * depending on its type (point, line or path).
 */
struct PathApproximationInfo {
    PathApproximationInfo(float invScaleX, float invScaleY, float pixelThreshold)
        : thresholdSquared(pixelThreshold * pixelThreshold)
        , sqrInvScaleX(invScaleX * invScaleX)
        , sqrInvScaleY(invScaleY * invScaleY)
        , thresholdForConicQuads(pixelThreshold * MathUtils::min(invScaleX, invScaleY) / 2.0f) {
    };

    const float thresholdSquared;
    const float sqrInvScaleX;
    const float sqrInvScaleY;
    const float thresholdForConicQuads;
};

class PathTessellator {
public:
    /**
     * Populates scaleX and scaleY with the 'tessellation scale' of the transform - the effective X
     * and Y scales that tessellation will take into account when generating the 1.0 pixel thick
     * ramp.
     *
     * Two instances of the same shape (size, paint, etc.) will only generate the same vertices if
     * their tessellation scales are equal.
     */
    static void extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY);

    /**
     * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
     * triangle strip. Note: joins are not currently supported.
     *
     * @param path The path to be approximated
     * @param paint The paint the path will be drawn with, indicating AA, painting style
     *        (stroke vs fill), stroke width, stroke cap & join style, etc.
     * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
     *        vertex approximation, and correct AA ramp offsetting.
     * @param vertexBuffer The output buffer
     */
    static void tessellatePath(const SkPath& path, const SkPaint* paint,
            const mat4& transform, VertexBuffer& vertexBuffer);

    /**
     * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
     * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
     *
     * @param points The center vertices of the points to be drawn
     * @param count The number of floats making up the point vertices
     * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
     *        vertex approximation, and correct AA ramp offsetting
     * @param vertexBuffer The output buffer
     */
    static void tessellatePoints(const float* points, int count, const SkPaint* paint,
            const mat4& transform, VertexBuffer& vertexBuffer);

    /**
     * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
     * strip (with degenerate tris separating).
     *
     * @param points Pairs of endpoints defining the lines to be drawn
     * @param count The number of floats making up the line vertices
     * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
     *        vertex approximation, and correct AA ramp offsetting
     * @param vertexBuffer The output buffer
     */
    static void tessellateLines(const float* points, int count, const SkPaint* paint,
            const mat4& transform, VertexBuffer& vertexBuffer);

    /**
     * Approximates a convex outline into a clockwise Vector of 2d vertices.
     *
     * @param path The outline to be approximated
     * @param threshold The threshold of acceptable error (in pixels) when approximating
     * @param outputVertices An empty Vector which will be populated with the output
     */
    static bool approximatePathOutlineVertices(const SkPath &path, float threshold,
            Vector<Vertex> &outputVertices);

private:
    static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
            const PathApproximationInfo& approximationInfo, Vector<Vertex> &outputVertices);

/*
  endpoints a & b,
  control c
 */
    static void recursiveQuadraticBezierVertices(
            float ax, float ay,
            float bx, float by,
            float cx, float cy,
            const PathApproximationInfo& approximationInfo,
            Vector<Vertex> &outputVertices, int depth = 0);

/*
  endpoints p1, p2
  control c1, c2
 */
    static void recursiveCubicBezierVertices(
            float p1x, float p1y,
            float c1x, float c1y,
            float p2x, float p2y,
            float c2x, float c2y,
            const PathApproximationInfo& approximationInfo,
            Vector<Vertex> &outputVertices, int depth = 0);
};

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_PATH_TESSELLATOR_H