1/*
2 * Copyright (C) 2011 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#define LOG_TAG "OpenGLRenderer"
18
19#include "ShapeCache.h"
20
21namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Rounded rects
26///////////////////////////////////////////////////////////////////////////////
27
28RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>(
29        "round rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
30}
31
32PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
33        float rx, float ry, SkPaint* paint) {
34    RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
35    PathTexture* texture = get(entry);
36
37    if (!texture) {
38        SkPath path;
39        SkRect r;
40        r.set(0.0f, 0.0f, width, height);
41        path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
42
43        texture = addTexture(entry, &path, paint);
44    }
45
46    return texture;
47}
48
49///////////////////////////////////////////////////////////////////////////////
50// Circles
51///////////////////////////////////////////////////////////////////////////////
52
53CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>(
54        "circle", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
55}
56
57PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
58    CircleShapeCacheEntry entry(radius, paint);
59    PathTexture* texture = get(entry);
60
61    if (!texture) {
62        SkPath path;
63        path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
64
65        texture = addTexture(entry, &path, paint);
66    }
67
68    return texture;
69}
70
71///////////////////////////////////////////////////////////////////////////////
72// Ovals
73///////////////////////////////////////////////////////////////////////////////
74
75OvalShapeCache::OvalShapeCache(): ShapeCache<OvalShapeCacheEntry>(
76        "oval", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
77}
78
79PathTexture* OvalShapeCache::getOval(float width, float height, SkPaint* paint) {
80    OvalShapeCacheEntry entry(width, height, paint);
81    PathTexture* texture = get(entry);
82
83    if (!texture) {
84        SkPath path;
85        SkRect r;
86        r.set(0.0f, 0.0f, width, height);
87        path.addOval(r, SkPath::kCW_Direction);
88
89        texture = addTexture(entry, &path, paint);
90    }
91
92    return texture;
93}
94
95///////////////////////////////////////////////////////////////////////////////
96// Rects
97///////////////////////////////////////////////////////////////////////////////
98
99RectShapeCache::RectShapeCache(): ShapeCache<RectShapeCacheEntry>(
100        "rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
101}
102
103PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) {
104    RectShapeCacheEntry entry(width, height, paint);
105    PathTexture* texture = get(entry);
106
107    if (!texture) {
108        SkRect bounds;
109        bounds.set(0.0f, 0.0f, width, height);
110
111        float left, top, offset;
112        uint32_t rectWidth, rectHeight;
113        computeBounds(bounds, paint, left, top, offset, rectWidth, rectHeight);
114
115        if (!checkTextureSize(rectWidth, rectHeight)) return NULL;
116
117        purgeCache(rectWidth, rectHeight);
118
119        SkBitmap bitmap;
120        initBitmap(bitmap, rectWidth, rectHeight);
121
122        SkPaint pathPaint(*paint);
123        initPaint(pathPaint);
124
125        SkCanvas canvas(bitmap);
126        canvas.translate(-left + offset, -top + offset);
127        canvas.drawRect(bounds, pathPaint);
128
129        texture = createTexture(0, 0, offset, rectWidth, rectHeight, 0);
130        addTexture(entry, &bitmap, texture);
131    }
132
133    return texture;
134}
135
136///////////////////////////////////////////////////////////////////////////////
137// Arcs
138///////////////////////////////////////////////////////////////////////////////
139
140ArcShapeCache::ArcShapeCache(): ShapeCache<ArcShapeCacheEntry>(
141        "arc", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
142}
143
144PathTexture* ArcShapeCache::getArc(float width, float height,
145        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
146    ArcShapeCacheEntry entry(width, height, startAngle, sweepAngle, useCenter, paint);
147    PathTexture* texture = get(entry);
148
149    if (!texture) {
150        SkPath path;
151        SkRect r;
152        r.set(0.0f, 0.0f, width, height);
153        if (useCenter) {
154            path.moveTo(r.centerX(), r.centerY());
155        }
156        path.arcTo(r, startAngle, sweepAngle, !useCenter);
157        if (useCenter) {
158            path.close();
159        }
160
161        texture = addTexture(entry, &path, paint);
162    }
163
164    return texture;
165}
166
167}; // namespace uirenderer
168}; // namespace android
169