blob: 596d49d8f8767f32d748a3065760ab9464d7c544 [file] [log] [blame]
Chris Craik65cd6122012-12-10 17:56:27 -08001/*
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
26namespace android {
27namespace uirenderer {
28
29class VertexBuffer {
30public:
31 VertexBuffer():
32 mBuffer(0),
33 mSize(0),
34 mCleanupMethod(NULL)
35 {}
36
37 ~VertexBuffer() {
38 if (mCleanupMethod) mCleanupMethod(mBuffer);
39 }
40
41 /**
42 This should be the only method used by the PathTessellator. Subsequent calls to alloc will
43 allocate space within the first allocation (useful if you want to eventually allocate
44 multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines()
45 */
46 template <class TYPE>
47 TYPE* alloc(int size) {
48 if (mSize) {
49 TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
50 // already have allocated the buffer, re-allocate space within
51 if (mReallocBuffer != mBuffer) {
52 // not first re-allocation, leave space for degenerate triangles to separate strips
53 reallocBuffer += 2;
54 }
55 mReallocBuffer = reallocBuffer + size;
56 return reallocBuffer;
57 }
58 mSize = size;
59 mReallocBuffer = mBuffer = (void*)new TYPE[size];
60 mCleanupMethod = &(cleanup<TYPE>);
61
62 return (TYPE*)mBuffer;
63 }
64
65 void* getBuffer() const { return mBuffer; }
66 unsigned int getSize() const { return mSize; }
67
68 template <class TYPE>
69 void createDegenerateSeparators(int allocSize) {
70 TYPE* end = (TYPE*)mBuffer + mSize;
71 for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
72 memcpy(degen, degen - 1, sizeof(TYPE));
73 memcpy(degen + 1, degen + 2, sizeof(TYPE));
74 }
75 }
76
77private:
78 template <class TYPE>
79 static void cleanup(void* buffer) {
80 delete[] (TYPE*)buffer;
81 }
82
83 void* mBuffer;
84 unsigned int mSize;
85
86 void* mReallocBuffer; // used for multi-allocation
87
88 void (*mCleanupMethod)(void*);
89};
90
91class PathTessellator {
92public:
93 static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand);
94
95 static void tessellatePath(const SkPath& path, const SkPaint* paint,
96 const mat4 *transform, VertexBuffer& vertexBuffer);
97
98 static void tessellateLines(const float* points, int count, SkPaint* paint,
99 const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
100
101private:
102 static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
103 float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
104
105/*
106 endpoints a & b,
107 control c
108 */
109 static void recursiveQuadraticBezierVertices(
110 float ax, float ay,
111 float bx, float by,
112 float cx, float cy,
113 float sqrInvScaleX, float sqrInvScaleY,
114 Vector<Vertex> &outputVertices);
115
116/*
117 endpoints p1, p2
118 control c1, c2
119 */
120 static void recursiveCubicBezierVertices(
121 float p1x, float p1y,
122 float c1x, float c1y,
123 float p2x, float p2y,
124 float c2x, float c2y,
125 float sqrInvScaleX, float sqrInvScaleY,
126 Vector<Vertex> &outputVertices);
127};
128
129}; // namespace uirenderer
130}; // namespace android
131
132#endif // ANDROID_HWUI_PATH_TESSELLATOR_H