Flutter Engine
The Flutter Engine
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()) {
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];
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_mask_filter()) {
174 switch (uint_data[kMaskFilterIndex]) {
175 case kNull:
176 paint.setMaskFilter(nullptr);
177 break;
178 case kBlur:
179 DlBlurStyle blur_style =
180 static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
181 double sigma = float_data[kMaskFilterSigmaIndex];
183 DlBlurMaskFilter::Make(blur_style, SafeNarrow(sigma)));
184 break;
185 }
186 }
187
188 return &paint;
189}
190
192 if (isNull()) {
193 return;
194 }
196
197 tonic::DartByteData byte_data(paint_data_);
199
200 const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
201 const float* float_data = static_cast<const float*>(byte_data.data());
202
204 if (!Dart_IsNull(paint_objects_)) {
205 FML_DCHECK(Dart_IsList(paint_objects_));
206 intptr_t length = 0;
207 Dart_ListLength(paint_objects_, &length);
208
210 if (Dart_IsError(
211 Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
212 return;
213 }
214
216 if (!Dart_IsNull(shader)) {
217 if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
218 auto sampling =
220 paint.setColorSource(decoded->shader(sampling));
221 }
222 }
223
226 ColorFilter* decoded =
228 paint.setColorFilter(decoded->filter());
229 }
230
231 Dart_Handle image_filter = values[kImageFilterIndex];
232 if (!Dart_IsNull(image_filter)) {
233 ImageFilter* decoded =
235 paint.setImageFilter(decoded->filter());
236 }
237 }
238
239 paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
240
241 uint32_t encoded_color = uint_data[kColorIndex];
242 paint.setColor(DlColor(encoded_color ^ kColorDefault));
243
244 uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
245 uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
246 paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
247
248 uint32_t style = uint_data[kStyleIndex];
249 paint.setDrawStyle(static_cast<DlDrawStyle>(style));
250
251 float stroke_width = float_data[kStrokeWidthIndex];
253
254 float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
255 paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
256
257 uint32_t stroke_cap = uint_data[kStrokeCapIndex];
258 paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));
259
260 uint32_t stroke_join = uint_data[kStrokeJoinIndex];
261 paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
262
263 paint.setInvertColors(uint_data[kInvertColorIndex] != 0);
264
265 switch (uint_data[kMaskFilterIndex]) {
266 case kNull:
267 break;
268 case kBlur:
269 DlBlurStyle blur_style =
270 static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
271 float sigma = SafeNarrow(float_data[kMaskFilterSigmaIndex]);
272 // Make could return a nullptr here if the values are NOP or
273 // do not make sense. We could interpret that as if there was
274 // no value passed from Dart at all (i.e. don't change the
275 // setting in the paint object as in the kNull branch right
276 // above here), but the maskfilter flag was actually set
277 // indicating that the developer "tried" to set a mask, so we
278 // should set the null value rather than do nothing.
279 paint.setMaskFilter(DlBlurMaskFilter::Make(blur_style, sigma));
280 break;
281 }
282}
283
284} // namespace flutter
285
286namespace tonic {
287
290 int index,
291 Dart_Handle& exception) {
292 Dart_Handle paint_objects = Dart_GetNativeArgument(args, index);
293 FML_DCHECK(!CheckAndHandleError(paint_objects));
294
295 Dart_Handle paint_data = Dart_GetNativeArgument(args, index + 1);
296 FML_DCHECK(!CheckAndHandleError(paint_data));
297
298 return flutter::Paint(paint_objects, paint_data);
299}
300
303 int index,
304 Dart_Handle& exception) {
305 return flutter::PaintData();
306}
307
308} // 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
Definition: color_filter.h:31
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
DlPaint & setColor(DlColor color)
Definition: dl_paint.h:70
DlPaint & setAntiAlias(bool isAntiAlias)
Definition: dl_paint.h:58
DlPaint & setInvertColors(bool isInvertColors)
Definition: dl_paint.h:64
DlPaint & setColorFilter(const std::shared_ptr< const DlColorFilter > &filter)
Definition: dl_paint.h:144
DlPaint & setMaskFilter(const std::shared_ptr< DlMaskFilter > &filter)
Definition: dl_paint.h:170
DlPaint & setStrokeCap(DlStrokeCap cap)
Definition: dl_paint.h:102
DlPaint & setStrokeWidth(float width)
Definition: dl_paint.h:116
DlPaint & setStrokeMiter(float miter)
Definition: dl_paint.h:122
DlPaint & setBlendMode(DlBlendMode mode)
Definition: dl_paint.h:86
DlDrawStyle getDrawStyle() const
Definition: dl_paint.h:91
DlPaint & setImageFilter(const std::shared_ptr< const DlImageFilter > &filter)
Definition: dl_paint.h:157
DlPaint & setDrawStyle(DlDrawStyle style)
Definition: dl_paint.h:94
DlPaint & setStrokeJoin(DlStrokeJoin join)
Definition: dl_paint.h:110
DlPaint & setColorSource(std::shared_ptr< const DlColorSource > source)
Definition: dl_paint.h:131
const std::shared_ptr< const DlImageFilter > filter() const
Definition: image_filter.h:38
static DlImageSampling SamplingFromIndex(int filterQualityIndex)
Definition: image_filter.cc:32
Paint()=default
void toDlPaint(DlPaint &paint) const
Definition: paint.cc:191
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
Definition: color_source.cc:38
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:3019
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
SkSamplingOptions sampling
Definition: SkRecords.h:337
constexpr int kStrokeJoinIndex
Definition: paint.cc:30
constexpr int kMaskFilterIndex
Definition: paint.cc:33
DlStrokeJoin
Definition: dl_paint.h:37
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:28
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:19
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
flutter::DlColor DlColor
flutter::DlPaint DlPaint
bool CheckAndHandleError(Dart_Handle handle)
Definition: dart_error.cc:33
const Scalar stroke_width