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