Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
paint.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/lib/ui/painting/paint.h"
6
7#include "flutter/display_list/dl_builder.h"
8#include "flutter/fml/logging.h"
9#include "flutter/lib/ui/floating_point.h"
10#include "flutter/lib/ui/painting/color_filter.h"
11#include "flutter/lib/ui/painting/image_filter.h"
12#include "flutter/lib/ui/painting/shader.h"
20
21namespace flutter {
22
23// Indices for 32bit values.
24constexpr int kIsAntiAliasIndex = 0;
25constexpr int kColorIndex = 1;
26constexpr int kBlendModeIndex = 2;
27constexpr int kStyleIndex = 3;
28constexpr int kStrokeWidthIndex = 4;
29constexpr int kStrokeCapIndex = 5;
30constexpr int kStrokeJoinIndex = 6;
31constexpr int kStrokeMiterLimitIndex = 7;
32constexpr int kFilterQualityIndex = 8;
33constexpr int kMaskFilterIndex = 9;
34constexpr int kMaskFilterBlurStyleIndex = 10;
35constexpr int kMaskFilterSigmaIndex = 11;
36constexpr int kInvertColorIndex = 12;
37constexpr size_t kDataByteCount = 52; // 4 * (last index + 1)
38static_assert(kDataByteCount == sizeof(uint32_t) * (kInvertColorIndex + 1),
39 "kDataByteCount must match the size of the data array.");
40
41// Indices for objects.
42constexpr int kShaderIndex = 0;
43constexpr int kColorFilterIndex = 1;
44constexpr int kImageFilterIndex = 2;
45constexpr int kObjectCount = 3; // One larger than largest object index.
46
47// Must be kept in sync with the default in painting.dart.
48constexpr uint32_t kColorDefault = 0xFF000000;
49
50// Must be kept in sync with the default in painting.dart.
51constexpr uint32_t kBlendModeDefault =
52 static_cast<uint32_t>(SkBlendMode::kSrcOver);
53
54// Must be kept in sync with the default in painting.dart, and also with the
55// default SkPaintDefaults_MiterLimit in Skia (which is not in a public header).
56constexpr float kStrokeMiterLimitDefault = 4.0f;
57
58// Must be kept in sync with the MaskFilter private constants in painting.dart.
60
61Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data)
62 : paint_objects_(paint_objects), paint_data_(paint_data) {}
63
65 const DisplayListAttributeFlags& flags) const {
66 if (isNull()) {
67 return nullptr;
68 }
69 tonic::DartByteData byte_data(paint_data_);
71
72 const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
73 const float* float_data = static_cast<const float*>(byte_data.data());
74
76 if (Dart_IsNull(paint_objects_)) {
77 if (flags.applies_shader()) {
78 paint.setColorSource(nullptr);
79 }
80 if (flags.applies_color_filter()) {
81 paint.setColorFilter(nullptr);
82 }
83 if (flags.applies_image_filter()) {
84 paint.setImageFilter(nullptr);
85 }
86 } else {
87 FML_DCHECK(Dart_IsList(paint_objects_));
88 intptr_t length = 0;
89 Dart_ListLength(paint_objects_, &length);
90
92 if (Dart_IsError(
93 Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
94 return nullptr;
95 }
96
97 if (flags.applies_shader()) {
98 Dart_Handle shader = values[kShaderIndex];
99 if (Dart_IsNull(shader)) {
100 paint.setColorSource(nullptr);
101 } else {
102 if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
103 auto sampling =
105 paint.setColorSource(decoded->shader(sampling));
106 } else {
107 paint.setColorSource(nullptr);
108 }
109 }
110 }
111
112 if (flags.applies_color_filter()) {
115 paint.setColorFilter(nullptr);
116 } else {
117 ColorFilter* decoded =
119 paint.setColorFilter(decoded->filter());
120 }
121 }
122
123 if (flags.applies_image_filter()) {
124 Dart_Handle image_filter = values[kImageFilterIndex];
125 if (Dart_IsNull(image_filter)) {
126 paint.setImageFilter(nullptr);
127 } else {
128 ImageFilter* decoded =
130 paint.setImageFilter(decoded->filter());
131 }
132 }
133 }
134
135 if (flags.applies_anti_alias()) {
136 paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
137 }
138
139 if (flags.applies_alpha_or_color()) {
140 uint32_t encoded_color = uint_data[kColorIndex];
141 paint.setColor(DlColor(encoded_color ^ kColorDefault));
142 }
143
144 if (flags.applies_blend()) {
145 uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
146 uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
147 paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
148 }
149
150 if (flags.applies_style()) {
151 uint32_t style = uint_data[kStyleIndex];
152 paint.setDrawStyle(static_cast<DlDrawStyle>(style));
153 }
154
155 if (flags.is_stroked(paint.getDrawStyle())) {
156 float stroke_width = float_data[kStrokeWidthIndex];
157 paint.setStrokeWidth(stroke_width);
158
159 float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
160 paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
161
162 uint32_t stroke_cap = uint_data[kStrokeCapIndex];
163 paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));
164
165 uint32_t stroke_join = uint_data[kStrokeJoinIndex];
166 paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
167 }
168
169 if (flags.applies_color_filter()) {
170 paint.setInvertColors(uint_data[kInvertColorIndex] != 0);
171 }
172
173 if (flags.applies_path_effect()) {
174 // The paint API exposed to Dart does not support path effects. But other
175 // operations such as text may set a path effect, which must be cleared.
176 paint.setPathEffect(nullptr);
177 }
178
179 if (flags.applies_mask_filter()) {
180 switch (uint_data[kMaskFilterIndex]) {
181 case kNull:
182 paint.setMaskFilter(nullptr);
183 break;
184 case kBlur:
185 DlBlurStyle blur_style =
186 static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
187 double sigma = float_data[kMaskFilterSigmaIndex];
188 paint.setMaskFilter(
189 DlBlurMaskFilter::Make(blur_style, SafeNarrow(sigma)));
190 break;
191 }
192 }
193
194 return &paint;
195}
196
198 if (isNull()) {
199 return;
200 }
202
203 tonic::DartByteData byte_data(paint_data_);
205
206 const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
207 const float* float_data = static_cast<const float*>(byte_data.data());
208
210 if (!Dart_IsNull(paint_objects_)) {
211 FML_DCHECK(Dart_IsList(paint_objects_));
212 intptr_t length = 0;
213 Dart_ListLength(paint_objects_, &length);
214
216 if (Dart_IsError(
217 Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
218 return;
219 }
220
221 Dart_Handle shader = values[kShaderIndex];
222 if (!Dart_IsNull(shader)) {
223 if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
224 auto sampling =
226 paint.setColorSource(decoded->shader(sampling));
227 }
228 }
229
232 ColorFilter* decoded =
234 paint.setColorFilter(decoded->filter());
235 }
236
237 Dart_Handle image_filter = values[kImageFilterIndex];
238 if (!Dart_IsNull(image_filter)) {
239 ImageFilter* decoded =
241 paint.setImageFilter(decoded->filter());
242 }
243 }
244
245 paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
246
247 uint32_t encoded_color = uint_data[kColorIndex];
248 paint.setColor(DlColor(encoded_color ^ kColorDefault));
249
250 uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
251 uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
252 paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
253
254 uint32_t style = uint_data[kStyleIndex];
255 paint.setDrawStyle(static_cast<DlDrawStyle>(style));
256
257 float stroke_width = float_data[kStrokeWidthIndex];
258 paint.setStrokeWidth(stroke_width);
259
260 float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
261 paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
262
263 uint32_t stroke_cap = uint_data[kStrokeCapIndex];
264 paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));
265
266 uint32_t stroke_join = uint_data[kStrokeJoinIndex];
267 paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
268
269 paint.setInvertColors(uint_data[kInvertColorIndex] != 0);
270
271 switch (uint_data[kMaskFilterIndex]) {
272 case kNull:
273 break;
274 case kBlur:
275 DlBlurStyle blur_style =
276 static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
277 float sigma = SafeNarrow(float_data[kMaskFilterSigmaIndex]);
278 // Make could return a nullptr here if the values are NOP or
279 // do not make sense. We could interpret that as if there was
280 // no value passed from Dart at all (i.e. don't change the
281 // setting in the paint object as in the kNull branch right
282 // above here), but the maskfilter flag was actually set
283 // indicating that the developer "tried" to set a mask, so we
284 // should set the null value rather than do nothing.
285 paint.setMaskFilter(DlBlurMaskFilter::Make(blur_style, sigma));
286 break;
287 }
288}
289
290} // namespace flutter
291
292namespace tonic {
293
294flutter::Paint DartConverter<flutter::Paint>::FromArguments(
296 int index,
297 Dart_Handle& exception) {
298 Dart_Handle paint_objects = Dart_GetNativeArgument(args, index);
299 FML_DCHECK(!CheckAndHandleError(paint_objects));
300
301 Dart_Handle paint_data = Dart_GetNativeArgument(args, index + 1);
302 FML_DCHECK(!CheckAndHandleError(paint_data));
303
304 return flutter::Paint(paint_objects, paint_data);
305}
306
307flutter::PaintData DartConverter<flutter::PaintData>::FromArguments(
309 int index,
310 Dart_Handle& exception) {
311 return flutter::PaintData();
312}
313
314} // namespace tonic
@ kSrcOver
r = s + (1-sa)*d
static sk_sp< SkImage > color_filter(const SkImage *image, SkColorFilter *colorFilter)
const std::shared_ptr< const DlColorFilter > filter() const
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
const std::shared_ptr< const DlImageFilter > filter() const
static DlImageSampling SamplingFromIndex(int filterQualityIndex)
Paint()=default
void toDlPaint(DlPaint &paint) const
Definition paint.cc:197
bool isNull() const
Definition paint.h:25
const DlPaint * paint(DlPaint &paint, const DisplayListAttributeFlags &flags) const
Definition paint.cc:64
const void * data() const
size_t length_in_bytes() const
const Paint & paint
DART_EXPORT Dart_Handle Dart_ListGetRange(Dart_Handle list, intptr_t offset, intptr_t length, Dart_Handle *result)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition dart_api.h:3010
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *length)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT bool Dart_IsList(Dart_Handle object)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_DCHECK(condition)
Definition logging.h:103
size_t length
constexpr int kStrokeJoinIndex
Definition paint.cc:30
constexpr int kMaskFilterIndex
Definition paint.cc:33
DlStrokeJoin
Definition dl_paint.h:38
constexpr int kShaderIndex
Definition paint.cc:42
constexpr uint32_t kColorDefault
Definition paint.cc:48
constexpr int kInvertColorIndex
Definition paint.cc:36
constexpr int kBlendModeIndex
Definition paint.cc:26
DlStrokeCap
Definition dl_paint.h:29
constexpr int kStyleIndex
Definition paint.cc:27
constexpr int kMaskFilterSigmaIndex
Definition paint.cc:35
constexpr int kStrokeCapIndex
Definition paint.cc:29
constexpr int kObjectCount
Definition paint.cc:45
DlDrawStyle
Definition dl_paint.h:20
constexpr uint32_t kBlendModeDefault
Definition paint.cc:51
static float SafeNarrow(double value)
constexpr int kColorFilterIndex
Definition paint.cc:43
constexpr int kStrokeMiterLimitIndex
Definition paint.cc:31
constexpr int kImageFilterIndex
Definition paint.cc:44
constexpr int kIsAntiAliasIndex
Definition paint.cc:24
constexpr int kStrokeWidthIndex
Definition paint.cc:28
MaskFilterType
Definition paint.cc:59
@ kBlur
Definition paint.cc:59
@ kNull
Definition paint.cc:59
constexpr float kStrokeMiterLimitDefault
Definition paint.cc:56
constexpr int kFilterQualityIndex
Definition paint.cc:32
constexpr int kColorIndex
Definition paint.cc:25
constexpr int kMaskFilterBlurStyleIndex
Definition paint.cc:34
constexpr size_t kDataByteCount
Definition paint.cc:37
const Scalar stroke_width