Skip to content

Commit

Permalink
fix color filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
dnfield committed Jan 24, 2020
1 parent 68ed538 commit 5c075e7
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 25 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -14,5 +14,7 @@ doc/api/
coverage/
.project

# golden failure diffs
test/failures
# Flutter crash logs
/flutter_*.log
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# CHANGES

## 0.17.0

- Make ColorFiltering apply to whole layer instead of per paint operation.
- **BREAKING** Remove `colorFilter` parameter from `VectorDrawable.draw`.
- Fix color filtering for text.

## 0.16.1

- Support `image` tags in `defs`.
Expand Down
40 changes: 22 additions & 18 deletions lib/src/vector_drawable.dart
Expand Up @@ -30,7 +30,7 @@ abstract class Drawable {
/// the `parentPaint` to optionally override the child's paint.
///
/// The `bounds` specify the area to draw in.
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds);
void draw(Canvas canvas, Rect bounds);
}

/// A [Drawable] that can have a [DrawableStyle] applied to it.
Expand Down Expand Up @@ -283,7 +283,7 @@ class DrawablePaint {
final double strokeWidth;

/// Creates a [Paint] object from this [DrawablePaint].
Paint toFlutterPaint([ColorFilter colorFilterOverride]) {
Paint toFlutterPaint() {
final Paint paint = Paint();

// Null chekcs are needed here because the setters assert.
Expand All @@ -293,8 +293,8 @@ class DrawablePaint {
if (color != null) {
paint.color = color;
}
if (colorFilterOverride != null || colorFilter != null) {
paint.colorFilter = colorFilterOverride ?? colorFilter;
if (colorFilter != null) {
paint.colorFilter = colorFilter;
}
if (filterQuality != null) {
paint.filterQuality = filterQuality;
Expand Down Expand Up @@ -507,7 +507,7 @@ class DrawableText implements Drawable {
(fill?.width ?? 0.0) + (stroke?.width ?? 0.0) > 0.0;

@override
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds) {
void draw(Canvas canvas, Rect bounds) {
if (!hasDrawableContent) {
return;
}
Expand Down Expand Up @@ -893,7 +893,7 @@ class DrawableRoot implements DrawableParent {
!viewport.viewBox.isEmpty;

@override
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds) {
void draw(Canvas canvas, Rect bounds) {
if (!hasDrawableContent) {
return;
}
Expand All @@ -907,7 +907,7 @@ class DrawableRoot implements DrawableParent {
canvas.translate(viewport.viewBoxOffset.dx, viewport.viewBoxOffset.dy);
}
for (Drawable child in children) {
child.draw(canvas, colorFilter, viewport.viewBoxRect);
child.draw(canvas, viewport.viewBoxRect);
}

if (transform != null) {
Expand All @@ -934,15 +934,19 @@ class DrawableRoot implements DrawableParent {

final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder, viewport.viewBoxRect);
canvas.save();
if (colorFilter != null) {
canvas.saveLayer(null, Paint()..colorFilter = colorFilter);
} else {
canvas.save();
}
if (size != null) {
scaleCanvasToViewBox(canvas, size);
}
if (clipToViewBox == true) {
clipCanvasToViewBox(canvas);
}

draw(canvas, colorFilter, viewport.viewBoxRect);
draw(canvas, viewport.viewBoxRect);
canvas.restore();
return recorder.endRecording();
}
Expand Down Expand Up @@ -988,7 +992,7 @@ class DrawableGroup implements DrawableStyleable, DrawableParent {
bool get hasDrawableContent => children != null && children.isNotEmpty;

@override
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds) {
void draw(Canvas canvas, Rect bounds) {
if (!hasDrawableContent) {
return;
}
Expand Down Expand Up @@ -1018,12 +1022,12 @@ class DrawableGroup implements DrawableStyleable, DrawableParent {
}

for (Drawable child in children) {
child.draw(canvas, colorFilter, bounds);
child.draw(canvas, bounds);
}

if (style.mask != null) {
canvas.saveLayer(null, _grayscaleDstInPaint);
style.mask.draw(canvas, colorFilter, bounds);
style.mask.draw(canvas, bounds);
canvas.restore();
}
if (needsSaveLayer) {
Expand Down Expand Up @@ -1103,7 +1107,7 @@ class DrawableRasterImage implements DrawableStyleable {
final DrawableStyle style;

@override
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds) {
void draw(Canvas canvas, Rect bounds) {
final Size imageSize = Size(
image.width.toDouble(),
image.height.toDouble(),
Expand Down Expand Up @@ -1190,7 +1194,7 @@ class DrawableShape implements DrawableStyleable {
bool get hasDrawableContent => bounds.width + bounds.height > 0;

@override
void draw(Canvas canvas, ColorFilter colorFilter, Rect bounds) {
void draw(Canvas canvas, Rect bounds) {
if (!hasDrawableContent || style == null) {
return;
}
Expand All @@ -1210,7 +1214,7 @@ class DrawableShape implements DrawableStyleable {
}
if (style.fill?.style != null) {
assert(style.fill.style == PaintingStyle.fill);
canvas.drawPath(path, style.fill.toFlutterPaint(colorFilter));
canvas.drawPath(path, style.fill.toFlutterPaint());
}

if (style.stroke?.style != null) {
Expand All @@ -1223,15 +1227,15 @@ class DrawableShape implements DrawableStyleable {
dashArray: style.dashArray,
dashOffset: style.dashOffset,
),
style.stroke.toFlutterPaint(colorFilter));
style.stroke.toFlutterPaint());
} else {
canvas.drawPath(path, style.stroke.toFlutterPaint(colorFilter));
canvas.drawPath(path, style.stroke.toFlutterPaint());
}
}

if (style.mask != null) {
canvas.saveLayer(null, _grayscaleDstInPaint);
style.mask.draw(canvas, colorFilter, bounds);
style.mask.draw(canvas, bounds);
canvas.restore();
canvas.restore();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/svg.dart
@@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:io' show File;
import 'dart:typed_data';
import 'dart:ui' show Picture;

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,7 +1,7 @@
name: flutter_svg
description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files.
homepage: https://github.com/dnfield/flutter_svg
version: 0.16.1
version: 0.17.0

dependencies:
path_drawing: ^0.4.1
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/golden_widget/text_color_filter.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 52 additions & 4 deletions test/widget_svg_test.dart
Expand Up @@ -13,10 +13,7 @@ import 'package:mockito/mockito.dart';
Future<void> _checkWidgetAndGolden(Key key, String filename) async {
final Finder widgetFinder = find.byKey(key);
expect(widgetFinder, findsOneWidget);
if (Platform.isLinux) {
await expectLater(
widgetFinder, matchesGoldenFile('golden_widget/$filename'));
}
await expectLater(widgetFinder, matchesGoldenFile('golden_widget/$filename'));
}

void main() {
Expand Down Expand Up @@ -388,6 +385,57 @@ void main() {

expect(find.byType(Semantics), findsNothing);
}, semanticsEnabled: true);

testWidgets('SvgPicture colorFilter - flutter logo',
(WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
RepaintBoundary(
key: key,
child: SvgPicture.string(
svgStr,
width: 100.0,
height: 100.0,
color: const Color(0xFF990000),
),
),
);

await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'flutter_logo.string.color_filter.png');
});

testWidgets('SvgPicture colorFilter with text', (WidgetTester tester) async {
const String svgData =
'''<svg font-family="arial" font-size="14" height="160" width="88" xmlns="http://www.w3.org/2000/svg">
<g stroke="#000" stroke-linecap="round" stroke-width="2" stroke-opacity="1" fill-opacity="1" stroke-linejoin="miter">
<g>
<line x1="60" x2="88" y1="136" y2="136"/>
</g>
<g>
<text stroke-width="1" x="9" y="28">2</text>
</g>
<g>
<text stroke-width="1" x="73" y="156">1</text>
</g>
</g>
</svg>''';
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
RepaintBoundary(
key: key,
child: SvgPicture.string(
svgData,
width: 100.0,
height: 100.0,
color: const Color(0xFF990000),
),
),
);

await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'text_color_filter.png');
});
}

class MockAssetBundle extends Mock implements AssetBundle {}
Expand Down
2 changes: 1 addition & 1 deletion tool/gen_golden.dart
Expand Up @@ -27,7 +27,7 @@ Future<Uint8List> getSvgPngBytes(String svgData) async {
svgRoot.clipCanvasToViewBox(canvas);

canvas.drawPaint(Paint()..color = const Color(0xFFFFFFFF));
svgRoot.draw(canvas, null, svgRoot.viewport.viewBoxRect);
svgRoot.draw(canvas, svgRoot.viewport.viewBoxRect);

final Picture pict = rec.endRecording();

Expand Down

0 comments on commit 5c075e7

Please sign in to comment.