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/fml/logging.h"
8 #include "flutter/lib/ui/painting/color_filter.h"
9 #include "flutter/lib/ui/painting/image_filter.h"
10 #include "flutter/lib/ui/painting/shader.h"
11 #include "third_party/skia/include/core/SkColorFilter.h"
12 #include "third_party/skia/include/core/SkImageFilter.h"
13 #include "third_party/skia/include/core/SkMaskFilter.h"
14 #include "third_party/skia/include/core/SkShader.h"
15 #include "third_party/skia/include/core/SkString.h"
18 
19 namespace flutter {
20 
21 // Indices for 32bit values.
22 constexpr int kIsAntiAliasIndex = 0;
23 constexpr int kColorIndex = 1;
24 constexpr int kBlendModeIndex = 2;
25 constexpr int kStyleIndex = 3;
26 constexpr int kStrokeWidthIndex = 4;
27 constexpr int kStrokeCapIndex = 5;
28 constexpr int kStrokeJoinIndex = 6;
29 constexpr int kStrokeMiterLimitIndex = 7;
30 constexpr int kFilterQualityIndex = 8;
31 constexpr int kMaskFilterIndex = 9;
32 constexpr int kMaskFilterBlurStyleIndex = 10;
33 constexpr int kMaskFilterSigmaIndex = 11;
34 constexpr int kInvertColorIndex = 12;
35 constexpr int kDitherIndex = 13;
36 constexpr size_t kDataByteCount = 56; // 4 * (last index + 1)
37 
38 // Indices for objects.
39 constexpr int kShaderIndex = 0;
40 constexpr int kColorFilterIndex = 1;
41 constexpr int kImageFilterIndex = 2;
42 constexpr int kObjectCount = 3; // One larger than largest object index.
43 
44 // Must be kept in sync with the default in painting.dart.
45 constexpr uint32_t kColorDefault = 0xFF000000;
46 
47 // Must be kept in sync with the default in painting.dart.
48 constexpr uint32_t kBlendModeDefault =
49  static_cast<uint32_t>(SkBlendMode::kSrcOver);
50 
51 // Must be kept in sync with the default in painting.dart, and also with the
52 // default SkPaintDefaults_MiterLimit in Skia (which is not in a public header).
53 constexpr double kStrokeMiterLimitDefault = 4.0;
54 
55 // A color matrix which inverts colors.
56 // clang-format off
57 constexpr float invert_colors[20] = {
58  -1.0, 0, 0, 1.0, 0,
59  0, -1.0, 0, 1.0, 0,
60  0, 0, -1.0, 1.0, 0,
61  1.0, 1.0, 1.0, 1.0, 0
62 };
63 // clang-format on
64 
65 // Must be kept in sync with the MaskFilter private constants in painting.dart.
67 
68 Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) {
69  is_null_ = Dart_IsNull(paint_data);
70  if (is_null_) {
71  return;
72  }
73 
74  Dart_Handle values[kObjectCount];
75  if (!Dart_IsNull(paint_objects)) {
76  FML_DCHECK(Dart_IsList(paint_objects));
77  intptr_t length = 0;
78  Dart_ListLength(paint_objects, &length);
79 
80  FML_CHECK(length == kObjectCount);
81  if (Dart_IsError(
82  Dart_ListGetRange(paint_objects, 0, kObjectCount, values))) {
83  return;
84  }
85 
86  Dart_Handle shader = values[kShaderIndex];
87  if (!Dart_IsNull(shader)) {
89  paint_.setShader(decoded->shader());
90  }
91 
92  Dart_Handle color_filter = values[kColorFilterIndex];
93  if (!Dart_IsNull(color_filter)) {
94  ColorFilter* decoded_color_filter =
96  paint_.setColorFilter(decoded_color_filter->filter());
97  }
98 
99  Dart_Handle image_filter = values[kImageFilterIndex];
100  if (!Dart_IsNull(image_filter)) {
101  ImageFilter* decoded =
103  paint_.setImageFilter(decoded->filter());
104  }
105  }
106 
107  tonic::DartByteData byte_data(paint_data);
108  FML_CHECK(byte_data.length_in_bytes() == kDataByteCount);
109 
110  const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
111  const float* float_data = static_cast<const float*>(byte_data.data());
112 
113  paint_.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
114 
115  uint32_t encoded_color = uint_data[kColorIndex];
116  if (encoded_color) {
117  SkColor color = encoded_color ^ kColorDefault;
118  paint_.setColor(color);
119  }
120 
121  uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
122  if (encoded_blend_mode) {
123  uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
124  paint_.setBlendMode(static_cast<SkBlendMode>(blend_mode));
125  }
126 
127  uint32_t style = uint_data[kStyleIndex];
128  if (style) {
129  paint_.setStyle(static_cast<SkPaint::Style>(style));
130  }
131 
132  float stroke_width = float_data[kStrokeWidthIndex];
133  if (stroke_width != 0.0) {
134  paint_.setStrokeWidth(stroke_width);
135  }
136 
137  uint32_t stroke_cap = uint_data[kStrokeCapIndex];
138  if (stroke_cap) {
139  paint_.setStrokeCap(static_cast<SkPaint::Cap>(stroke_cap));
140  }
141 
142  uint32_t stroke_join = uint_data[kStrokeJoinIndex];
143  if (stroke_join) {
144  paint_.setStrokeJoin(static_cast<SkPaint::Join>(stroke_join));
145  }
146 
147  float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
148  if (stroke_miter_limit != 0.0) {
149  paint_.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
150  }
151 
152  uint32_t filter_quality = uint_data[kFilterQualityIndex];
153  if (filter_quality) {
154  paint_.setFilterQuality(static_cast<SkFilterQuality>(filter_quality));
155  }
156 
157  if (uint_data[kInvertColorIndex]) {
158  sk_sp<SkColorFilter> invert_filter =
160  sk_sp<SkColorFilter> current_filter = paint_.refColorFilter();
161  if (current_filter) {
162  invert_filter = invert_filter->makeComposed(current_filter);
163  }
164  paint_.setColorFilter(invert_filter);
165  }
166 
167  if (uint_data[kDitherIndex]) {
168  paint_.setDither(true);
169  }
170 
171  switch (uint_data[kMaskFilterIndex]) {
172  case Null:
173  break;
174  case Blur:
175  SkBlurStyle blur_style =
176  static_cast<SkBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
177  double sigma = float_data[kMaskFilterSigmaIndex];
178  paint_.setMaskFilter(SkMaskFilter::MakeBlur(blur_style, sigma));
179  break;
180  }
181 }
182 
183 } // namespace flutter
184 
185 namespace tonic {
186 
188  Dart_NativeArguments args,
189  int index,
190  Dart_Handle& exception) {
191  Dart_Handle paint_objects = Dart_GetNativeArgument(args, index);
192  FML_DCHECK(!LogIfError(paint_objects));
193 
194  Dart_Handle paint_data = Dart_GetNativeArgument(args, index + 1);
195  FML_DCHECK(!LogIfError(paint_data));
196 
197  return flutter::Paint(paint_objects, paint_data);
198 }
199 
201  Dart_NativeArguments args,
202  int index,
203  Dart_Handle& exception) {
204  return flutter::PaintData();
205 }
206 
207 } // namespace tonic
constexpr uint32_t kColorDefault
Definition: paint.cc:45
G_BEGIN_DECLS FlValue * args
constexpr int kImageFilterIndex
Definition: paint.cc:41
constexpr int kStrokeJoinIndex
Definition: paint.cc:28
constexpr int kFilterQualityIndex
Definition: paint.cc:30
constexpr size_t kDataByteCount
Definition: paint.cc:36
constexpr int kIsAntiAliasIndex
Definition: paint.cc:22
const void * data() const
constexpr int kColorFilterIndex
Definition: paint.cc:40
#define FML_DCHECK(condition)
Definition: logging.h:86
constexpr int kShaderIndex
Definition: paint.cc:39
MaskFilterType
Definition: paint.cc:66
constexpr int kStyleIndex
Definition: paint.cc:25
constexpr float invert_colors[20]
Definition: paint.cc:57
constexpr int kMaskFilterBlurStyleIndex
Definition: paint.cc:32
constexpr uint32_t kBlendModeDefault
Definition: paint.cc:48
sk_sp< SkShader > shader()
Definition: shader.h:22
constexpr double kStrokeMiterLimitDefault
Definition: paint.cc:53
size_t length_in_bytes() const
size_t length
constexpr int kBlendModeIndex
Definition: paint.cc:24
constexpr int kMaskFilterSigmaIndex
Definition: paint.cc:33
constexpr int kDitherIndex
Definition: paint.cc:35
Paint()=default
constexpr int kMaskFilterIndex
Definition: paint.cc:31
constexpr int kColorIndex
Definition: paint.cc:23
static sk_sp< SkColorFilter > MakeColorMatrixFilter255(const float array[20])
Definition: color_filter.cc:47
#define FML_CHECK(condition)
Definition: logging.h:68
const sk_sp< SkImageFilter > & filter() const
Definition: image_filter.h:29
constexpr int kObjectCount
Definition: paint.cc:42
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
constexpr int kStrokeCapIndex
Definition: paint.cc:27
constexpr int kStrokeMiterLimitIndex
Definition: paint.cc:29
constexpr int kInvertColorIndex
Definition: paint.cc:34
constexpr int kStrokeWidthIndex
Definition: paint.cc:26
sk_sp< SkColorFilter > filter() const
Definition: color_filter.h:42