Skip to content

Commit

Permalink
Add option to invert paint colors to be used for smart invert accessi…
Browse files Browse the repository at this point in the history
…bility on iOS (flutter#6176)
  • Loading branch information
jonahwilliams authored and Amir Hardon committed Sep 21, 2018
1 parent 9a72b35 commit e75f793
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
20 changes: 19 additions & 1 deletion lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ class Paint {
static const int _kMaskFilterIndex = 12;
static const int _kMaskFilterBlurStyleIndex = 13;
static const int _kMaskFilterSigmaIndex = 14;
static const int _kInvertColorIndex = 15;

static const int _kIsAntiAliasOffset = _kIsAntiAliasIndex << 2;
static const int _kColorOffset = _kColorIndex << 2;
Expand All @@ -1081,6 +1082,7 @@ class Paint {
static const int _kMaskFilterOffset = _kMaskFilterIndex << 2;
static const int _kMaskFilterBlurStyleOffset = _kMaskFilterBlurStyleIndex << 2;
static const int _kMaskFilterSigmaOffset = _kMaskFilterSigmaIndex << 2;
static const int _kInvertColorOffset = _kInvertColorIndex << 2;
// If you add more fields, remember to update _kDataByteCount.
static const int _kDataByteCount = 75;

Expand Down Expand Up @@ -1363,6 +1365,18 @@ class Paint {
}
}

/// Whether the colors of the image are inverted when drawn.
///
/// inverting the colors of an image applies a new color filter that will
/// be composed with any user provided color filters. This is primarily
/// used for implementing smart invert on iOS.
bool get invertColors {
return _data.getInt32(_kInvertColorOffset, _kFakeHostEndian) == 1;
}
set invertColors(bool value) {
_data.setInt32(_kInvertColorOffset, value ? 1 : 0, _kFakeHostEndian);
}

@override
String toString() {
final StringBuffer result = new StringBuffer();
Expand Down Expand Up @@ -1411,8 +1425,12 @@ class Paint {
result.write('${semicolon}filterQuality: $filterQuality');
semicolon = '; ';
}
if (shader != null)
if (shader != null) {
result.write('${semicolon}shader: $shader');
semicolon = '; ';
}
if (invertColors)
result.write('${semicolon}invert: $invertColors');
result.write(')');
return result.toString();
}
Expand Down
25 changes: 24 additions & 1 deletion lib/ui/painting/paint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ constexpr int kColorFilterBlendModeIndex = 11;
constexpr int kMaskFilterIndex = 12;
constexpr int kMaskFilterBlurStyleIndex = 13;
constexpr int kMaskFilterSigmaIndex = 14;
constexpr int kInvertColorIndex = 15;
constexpr size_t kDataByteCount = 75; // 4 * (last index + 1)

// Indices for objects.
Expand All @@ -47,6 +48,16 @@ constexpr uint32_t kBlendModeDefault =
// default SkPaintDefaults_MiterLimit in Skia (which is not in a public header).
constexpr double kStrokeMiterLimitDefault = 4.0;

// A color matrix which inverts colors.
// clang-format off
constexpr SkScalar invert_colors[20] = {
-1.0, 0, 0, 1.0, 0,
0, -1.0, 0, 1.0, 0,
0, 0, -1.0, 1.0, 0,
1.0, 1.0, 1.0, 1.0, 0
};
// clang-format on

// Must be kept in sync with the MaskFilter private constants in painting.dart.
enum MaskFilterType { Null, Blur };

Expand Down Expand Up @@ -116,7 +127,19 @@ Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data) {
if (filter_quality)
paint_.setFilterQuality(static_cast<SkFilterQuality>(filter_quality));

if (uint_data[kColorFilterIndex]) {
if (uint_data[kColorFilterIndex] && uint_data[kInvertColorIndex]) {
SkColor color = uint_data[kColorFilterColorIndex];
SkBlendMode blend_mode =
static_cast<SkBlendMode>(uint_data[kColorFilterBlendModeIndex]);
sk_sp<SkColorFilter> color_filter =
SkColorFilter::MakeModeFilter(color, blend_mode);
sk_sp<SkColorFilter> invert_filter =
SkColorFilter::MakeMatrixFilterRowMajor255(invert_colors);
paint_.setColorFilter(invert_filter->makeComposed(color_filter));
} else if (uint_data[kInvertColorIndex]) {
paint_.setColorFilter(
SkColorFilter::MakeMatrixFilterRowMajor255(invert_colors));
} else if (uint_data[kColorFilterIndex]) {
SkColor color = uint_data[kColorFilterColorIndex];
SkBlendMode blend_mode =
static_cast<SkBlendMode>(uint_data[kColorFilterBlendModeIndex]);
Expand Down

0 comments on commit e75f793

Please sign in to comment.