blob: afd88c04a8580ccb59dadd0a31dc50ecb6db9a91 [file] [log] [blame]
John Reck013127b2020-10-29 20:53:51 -04001/*
2 * Copyright (C) 2020 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#pragma once
18
19#include <SkAndroidFrameworkUtils.h>
20#include <SkCanvas.h>
21#include <SkPath.h>
22#include <log/log.h>
Nader Jawadde3ce842020-11-06 16:54:48 -080023#include "CanvasProperty.h"
John Reck013127b2020-10-29 20:53:51 -040024
25#include "CanvasOpTypes.h"
26
27#include <experimental/type_traits>
28
29namespace android::uirenderer {
30
31template <CanvasOpType T>
32struct CanvasOp;
33
34struct CanvasOpTraits {
35 CanvasOpTraits() = delete;
36
37 template<class T>
38 using draw_t = decltype(std::integral_constant<void (T::*)(SkCanvas*) const, &T::draw>{});
39
40 template <class T>
41 static constexpr bool can_draw = std::experimental::is_detected_v<draw_t, T>;
42};
43
44#define ASSERT_DRAWABLE() private: constexpr void _check_drawable() \
45 { static_assert(CanvasOpTraits::can_draw<std::decay_t<decltype(*this)>>); }
46
47// ----------------------------------------------
48// State Ops
49// ---------------------------------------------
50
51template <>
52struct CanvasOp<CanvasOpType::Save> {
53 void draw(SkCanvas* canvas) const { canvas->save(); }
54 ASSERT_DRAWABLE()
55};
56
57template <>
58struct CanvasOp<CanvasOpType::SaveLayer> {
59 SkCanvas::SaveLayerRec saveLayerRec;
60 void draw(SkCanvas* canvas) const { canvas->saveLayer(saveLayerRec); }
61 ASSERT_DRAWABLE()
62};
63
64template <>
65struct CanvasOp<CanvasOpType::SaveBehind> {
66 SkRect bounds;
67 void draw(SkCanvas* canvas) const { SkAndroidFrameworkUtils::SaveBehind(canvas, &bounds); }
68 ASSERT_DRAWABLE()
69};
70
71template <>
72struct CanvasOp<CanvasOpType::Restore> {
73 void draw(SkCanvas* canvas) const { canvas->restore(); }
74 ASSERT_DRAWABLE()
75};
76
77template <>
78struct CanvasOp<CanvasOpType::BeginZ> {
79};
80template <>
81struct CanvasOp<CanvasOpType::EndZ> {};
82
83// ----------------------------------------------
84// Clip Ops
85// ---------------------------------------------
86
87template <>
88struct CanvasOp<CanvasOpType::ClipRect> {
89 SkRect rect;
90 SkClipOp clipOp;
91 void draw(SkCanvas* canvas) const { canvas->clipRect(rect, clipOp); }
92 ASSERT_DRAWABLE()
93};
94
95template <>
96struct CanvasOp<CanvasOpType::ClipPath> {
97 SkPath path;
98 SkClipOp op;
99 void draw(SkCanvas* canvas) const { canvas->clipPath(path, op, true); }
100 ASSERT_DRAWABLE()
101};
102
103// ----------------------------------------------
104// Drawing Ops
105// ---------------------------------------------
106
Nader Jawadde3ce842020-11-06 16:54:48 -0800107template<>
108struct CanvasOp<CanvasOpType::DrawRoundRectProperty> {
109 sp<uirenderer::CanvasPropertyPrimitive> left;
110 sp<uirenderer::CanvasPropertyPrimitive> top;
111 sp<uirenderer::CanvasPropertyPrimitive> right;
112 sp<uirenderer::CanvasPropertyPrimitive> bottom;
113 sp<uirenderer::CanvasPropertyPrimitive> rx;
114 sp<uirenderer::CanvasPropertyPrimitive> ry;
115 sp<uirenderer::CanvasPropertyPaint> paint;
116
117 void draw(SkCanvas* canvas) const {
118 SkRect rect = SkRect::MakeLTRB(left->value, top->value, right->value, bottom->value);
119 canvas->drawRoundRect(rect, rx->value, ry->value, paint->value);
120 }
121 ASSERT_DRAWABLE()
122};
123
124template<>
125struct CanvasOp<CanvasOpType::DrawCircleProperty> {
126 sp<uirenderer::CanvasPropertyPrimitive> x;
127 sp<uirenderer::CanvasPropertyPrimitive> y;
128 sp<uirenderer::CanvasPropertyPrimitive> radius;
129 sp<uirenderer::CanvasPropertyPaint> paint;
130
131 void draw(SkCanvas* canvas) const {
132 canvas->drawCircle(x->value, y->value, radius->value, paint->value);
133 }
134 ASSERT_DRAWABLE()
135};
136
John Reck013127b2020-10-29 20:53:51 -0400137template <>
138struct CanvasOp<CanvasOpType::DrawColor> {
139 SkColor4f color;
140 SkBlendMode mode;
141 void draw(SkCanvas* canvas) const { canvas->drawColor(color, mode); }
142 ASSERT_DRAWABLE()
143};
144
145template <>
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800146struct CanvasOp<CanvasOpType::DrawPaint> {
147 SkPaint paint;
148 void draw(SkCanvas* canvas) const { canvas->drawPaint(paint); }
149 ASSERT_DRAWABLE()
150};
151
152template <>
John Reck013127b2020-10-29 20:53:51 -0400153struct CanvasOp<CanvasOpType::DrawRect> {
154 SkRect rect;
155 SkPaint paint;
156 void draw(SkCanvas* canvas) const { canvas->drawRect(rect, paint); }
157 ASSERT_DRAWABLE()
158};
159
Nader Jawadd5c2b6d2020-11-05 19:12:29 -0800160template<>
161struct CanvasOp<CanvasOpType::DrawRoundRect> {
162 SkRect rect;
163 SkScalar rx;
164 SkScalar ry;
165 SkPaint paint;
166 void draw(SkCanvas* canvas) const {
167 canvas->drawRoundRect(rect, rx, ry, paint);
168 }
169 ASSERT_DRAWABLE()
170};
171
172template<>
173struct CanvasOp<CanvasOpType::DrawCircle> {
174 SkScalar cx;
175 SkScalar cy;
176 SkScalar radius;
177 SkPaint paint;
178 void draw(SkCanvas* canvas) const {
179 canvas->drawCircle(cx, cy, radius, paint);
180 }
181 ASSERT_DRAWABLE()
182};
183
184template<>
185struct CanvasOp<CanvasOpType::DrawOval> {
186 SkRect oval;
187 SkPaint paint;
188 void draw(SkCanvas* canvas) const {
189 canvas->drawOval(oval, paint);
190 }
191 ASSERT_DRAWABLE()
192};
193
194template<>
195struct CanvasOp<CanvasOpType::DrawArc> {
196 SkRect oval;
197 SkScalar startAngle;
198 SkScalar sweepAngle;
199 bool useCenter;
200 SkPaint paint;
201
202 void draw(SkCanvas* canvas) const {
203 canvas->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
204 }
205 ASSERT_DRAWABLE()
206};
John Reck013127b2020-10-29 20:53:51 -0400207
208// cleanup our macros
209#undef ASSERT_DRAWABLE
210
211} // namespace android::uirenderer