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 146 147 148 149
|
/*
* 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 "Matrix.h"
#include "Rect.h"
#include "Vertex.h"
#include "VertexBuffer.h"
#include <algorithm>
#include <vector>
class SkPath;
class SkPaint;
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 * std::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,
std::vector<Vertex> &outputVertices);
private:
static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
const PathApproximationInfo& approximationInfo, std::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,
std::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,
std::vector<Vertex> &outputVertices, int depth = 0);
};
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_HWUI_PATH_TESSELLATOR_H
|