165cd612face362d054a85d0f7e5881c59cd523beChris Craik/*
265cd612face362d054a85d0f7e5881c59cd523beChris Craik * Copyright (C) 2012 The Android Open Source Project
365cd612face362d054a85d0f7e5881c59cd523beChris Craik *
465cd612face362d054a85d0f7e5881c59cd523beChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
565cd612face362d054a85d0f7e5881c59cd523beChris Craik * you may not use this file except in compliance with the License.
665cd612face362d054a85d0f7e5881c59cd523beChris Craik * You may obtain a copy of the License at
765cd612face362d054a85d0f7e5881c59cd523beChris Craik *
865cd612face362d054a85d0f7e5881c59cd523beChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
965cd612face362d054a85d0f7e5881c59cd523beChris Craik *
1065cd612face362d054a85d0f7e5881c59cd523beChris Craik * Unless required by applicable law or agreed to in writing, software
1165cd612face362d054a85d0f7e5881c59cd523beChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
1265cd612face362d054a85d0f7e5881c59cd523beChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365cd612face362d054a85d0f7e5881c59cd523beChris Craik * See the License for the specific language governing permissions and
1465cd612face362d054a85d0f7e5881c59cd523beChris Craik * limitations under the License.
1565cd612face362d054a85d0f7e5881c59cd523beChris Craik */
1665cd612face362d054a85d0f7e5881c59cd523beChris Craik
1765cd612face362d054a85d0f7e5881c59cd523beChris Craik#ifndef ANDROID_HWUI_PATH_TESSELLATOR_H
1865cd612face362d054a85d0f7e5881c59cd523beChris Craik#define ANDROID_HWUI_PATH_TESSELLATOR_H
1965cd612face362d054a85d0f7e5881c59cd523beChris Craik
2065cd612face362d054a85d0f7e5881c59cd523beChris Craik#include "Matrix.h"
2165cd612face362d054a85d0f7e5881c59cd523beChris Craik#include "Rect.h"
2265cd612face362d054a85d0f7e5881c59cd523beChris Craik#include "Vertex.h"
2355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui#include "VertexBuffer.h"
2465cd612face362d054a85d0f7e5881c59cd523beChris Craik
259db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik#include <algorithm>
26272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck#include <vector>
27272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck
289db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craikclass SkPath;
299db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craikclass SkPaint;
309db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik
3165cd612face362d054a85d0f7e5881c59cd523beChris Craiknamespace android {
3265cd612face362d054a85d0f7e5881c59cd523beChris Craiknamespace uirenderer {
3365cd612face362d054a85d0f7e5881c59cd523beChris Craik
3421ef8205a1c741ab4021c2d99c568bed39fc136eztenghui/**
3521ef8205a1c741ab4021c2d99c568bed39fc136eztenghui * Structure used for threshold values in outline path tessellation.
3621ef8205a1c741ab4021c2d99c568bed39fc136eztenghui *
3721ef8205a1c741ab4021c2d99c568bed39fc136eztenghui * TODO: PaintInfo should store one of this object, and initialized all values in constructor
3821ef8205a1c741ab4021c2d99c568bed39fc136eztenghui * depending on its type (point, line or path).
3921ef8205a1c741ab4021c2d99c568bed39fc136eztenghui */
4021ef8205a1c741ab4021c2d99c568bed39fc136eztenghuistruct PathApproximationInfo {
4121ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    PathApproximationInfo(float invScaleX, float invScaleY, float pixelThreshold)
4221ef8205a1c741ab4021c2d99c568bed39fc136eztenghui        : thresholdSquared(pixelThreshold * pixelThreshold)
4321ef8205a1c741ab4021c2d99c568bed39fc136eztenghui        , sqrInvScaleX(invScaleX * invScaleX)
4421ef8205a1c741ab4021c2d99c568bed39fc136eztenghui        , sqrInvScaleY(invScaleY * invScaleY)
459db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik        , thresholdForConicQuads(pixelThreshold * std::min(invScaleX, invScaleY) / 2.0f) {
4621ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    };
4721ef8205a1c741ab4021c2d99c568bed39fc136eztenghui
4821ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    const float thresholdSquared;
4921ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    const float sqrInvScaleX;
5021ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    const float sqrInvScaleY;
5121ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    const float thresholdForConicQuads;
5221ef8205a1c741ab4021c2d99c568bed39fc136eztenghui};
5321ef8205a1c741ab4021c2d99c568bed39fc136eztenghui
5465cd612face362d054a85d0f7e5881c59cd523beChris Craikclass PathTessellator {
5565cd612face362d054a85d0f7e5881c59cd523beChris Craikpublic:
5605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik    /**
5705f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     * Populates scaleX and scaleY with the 'tessellation scale' of the transform - the effective X
5805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     * and Y scales that tessellation will take into account when generating the 1.0 pixel thick
5905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     * ramp.
6005f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     *
6105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     * Two instances of the same shape (size, paint, etc.) will only generate the same vertices if
6205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     * their tessellation scales are equal.
6305f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik     */
6405f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik    static void extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY);
6565cd612face362d054a85d0f7e5881c59cd523beChris Craik
6615a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik    /**
6715a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
6815a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * triangle strip. Note: joins are not currently supported.
6915a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *
7015a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param path The path to be approximated
7115a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param paint The paint the path will be drawn with, indicating AA, painting style
7215a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *        (stroke vs fill), stroke width, stroke cap & join style, etc.
7315a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
7415a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *        vertex approximation, and correct AA ramp offsetting.
7515a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param vertexBuffer The output buffer
7615a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     */
7765cd612face362d054a85d0f7e5881c59cd523beChris Craik    static void tessellatePath(const SkPath& path, const SkPaint* paint,
78d6b65f67717025b1162f86f04e2caa5723566cacChris Craik            const mat4& transform, VertexBuffer& vertexBuffer);
7965cd612face362d054a85d0f7e5881c59cd523beChris Craik
8015a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik    /**
8115a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
8215a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
8315a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *
8415a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param points The center vertices of the points to be drawn
8515a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param count The number of floats making up the point vertices
8615a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
8715a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
8815a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *        vertex approximation, and correct AA ramp offsetting
8915a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param vertexBuffer The output buffer
9015a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     */
91d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    static void tessellatePoints(const float* points, int count, const SkPaint* paint,
9205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik            const mat4& transform, VertexBuffer& vertexBuffer);
936d29c8d5218cac0fb35f3b7c253f2bdebd44f15aChris Craik
9415a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik    /**
9515a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
9615a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * strip (with degenerate tris separating).
9715a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *
9815a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param points Pairs of endpoints defining the lines to be drawn
9915a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param count The number of floats making up the line vertices
10015a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
10115a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
10215a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *        vertex approximation, and correct AA ramp offsetting
10315a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param vertexBuffer The output buffer
10415a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     */
105d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    static void tessellateLines(const float* points, int count, const SkPaint* paint,
10605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik            const mat4& transform, VertexBuffer& vertexBuffer);
10765cd612face362d054a85d0f7e5881c59cd523beChris Craik
10815a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik    /**
109fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik     * Approximates a convex outline into a clockwise Vector of 2d vertices.
11015a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     *
11115a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param path The outline to be approximated
11221ef8205a1c741ab4021c2d99c568bed39fc136eztenghui     * @param threshold The threshold of acceptable error (in pixels) when approximating
11315a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     * @param outputVertices An empty Vector which will be populated with the output
11415a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik     */
11521ef8205a1c741ab4021c2d99c568bed39fc136eztenghui    static bool approximatePathOutlineVertices(const SkPath &path, float threshold,
116272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck            std::vector<Vertex> &outputVertices);
11715a07a21eb33e8ca1c7444944fe0541a53380c0cChris Craik
11865cd612face362d054a85d0f7e5881c59cd523beChris Craikprivate:
11965cd612face362d054a85d0f7e5881c59cd523beChris Craik    static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
120272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck            const PathApproximationInfo& approximationInfo, std::vector<Vertex> &outputVertices);
12165cd612face362d054a85d0f7e5881c59cd523beChris Craik
12265cd612face362d054a85d0f7e5881c59cd523beChris Craik/*
12365cd612face362d054a85d0f7e5881c59cd523beChris Craik  endpoints a & b,
12465cd612face362d054a85d0f7e5881c59cd523beChris Craik  control c
12565cd612face362d054a85d0f7e5881c59cd523beChris Craik */
12665cd612face362d054a85d0f7e5881c59cd523beChris Craik    static void recursiveQuadraticBezierVertices(
12765cd612face362d054a85d0f7e5881c59cd523beChris Craik            float ax, float ay,
12865cd612face362d054a85d0f7e5881c59cd523beChris Craik            float bx, float by,
12965cd612face362d054a85d0f7e5881c59cd523beChris Craik            float cx, float cy,
13021ef8205a1c741ab4021c2d99c568bed39fc136eztenghui            const PathApproximationInfo& approximationInfo,
131272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck            std::vector<Vertex> &outputVertices, int depth = 0);
13265cd612face362d054a85d0f7e5881c59cd523beChris Craik
13365cd612face362d054a85d0f7e5881c59cd523beChris Craik/*
13465cd612face362d054a85d0f7e5881c59cd523beChris Craik  endpoints p1, p2
13565cd612face362d054a85d0f7e5881c59cd523beChris Craik  control c1, c2
13665cd612face362d054a85d0f7e5881c59cd523beChris Craik */
13765cd612face362d054a85d0f7e5881c59cd523beChris Craik    static void recursiveCubicBezierVertices(
13865cd612face362d054a85d0f7e5881c59cd523beChris Craik            float p1x, float p1y,
13965cd612face362d054a85d0f7e5881c59cd523beChris Craik            float c1x, float c1y,
14065cd612face362d054a85d0f7e5881c59cd523beChris Craik            float p2x, float p2y,
14165cd612face362d054a85d0f7e5881c59cd523beChris Craik            float c2x, float c2y,
14221ef8205a1c741ab4021c2d99c568bed39fc136eztenghui            const PathApproximationInfo& approximationInfo,
143272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck            std::vector<Vertex> &outputVertices, int depth = 0);
14465cd612face362d054a85d0f7e5881c59cd523beChris Craik};
14565cd612face362d054a85d0f7e5881c59cd523beChris Craik
14665cd612face362d054a85d0f7e5881c59cd523beChris Craik}; // namespace uirenderer
14765cd612face362d054a85d0f7e5881c59cd523beChris Craik}; // namespace android
14865cd612face362d054a85d0f7e5881c59cd523beChris Craik
14965cd612face362d054a85d0f7e5881c59cd523beChris Craik#endif // ANDROID_HWUI_PATH_TESSELLATOR_H
150