Skip to content

Commit

Permalink
Transform parser bugs (#208)
Browse files Browse the repository at this point in the history
* Fix parsing bugs in transform parser
  • Loading branch information
dnfield committed Jun 15, 2023
1 parent ed58418 commit 2b8860b
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 39 deletions.
4 changes: 4 additions & 0 deletions packages/vector_graphics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.1.8

- Fix bugs in transform parsing.

## 1.1.7

- Support for matching the ambient text direction.
Expand Down
6 changes: 3 additions & 3 deletions packages/vector_graphics/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: vector_graphics
description: A vector graphics rendering package for Flutter.
version: 1.1.7
version: 1.1.8
homepage: https://github.com/dnfield/vector_graphics

environment:
Expand All @@ -10,13 +10,13 @@ environment:
dependencies:
flutter:
sdk: flutter
vector_graphics_codec: 1.1.7
vector_graphics_codec: 1.1.8

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0
vector_graphics_compiler: 1.1.7
vector_graphics_compiler: 1.1.8

# Comment out before publishing
dependency_overrides:
Expand Down
4 changes: 4 additions & 0 deletions packages/vector_graphics_codec/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.1.8

- Fix bugs in transform parsing.

## 1.1.7

- Support for matching the ambient text direction.
Expand Down
2 changes: 1 addition & 1 deletion packages/vector_graphics_codec/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: vector_graphics_codec
description: An encoding library for `package:vector_graphics`
version: 1.1.7
version: 1.1.8
homepage: https://github.com/dnfield/vector_graphics

environment:
Expand Down
4 changes: 4 additions & 0 deletions packages/vector_graphics_compiler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.1.8

- Fix bugs in transform parsing.

## 1.1.7

- Support for matching the ambient text direction.
Expand Down
88 changes: 56 additions & 32 deletions packages/vector_graphics_compiler/lib/src/svg/parsers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ final RegExp _transformValidator = RegExp('^($_transformCommandAtom)*\$');
final RegExp _transformCommand = RegExp(_transformCommandAtom);

typedef _MatrixParser = AffineMatrix Function(
String? paramsStr, AffineMatrix current);
List<double> params, AffineMatrix current);

const Map<String, _MatrixParser> _matrixParsers = <String, _MatrixParser>{
'matrix': _parseSvgMatrix,
Expand All @@ -25,6 +25,35 @@ const Map<String, _MatrixParser> _matrixParsers = <String, _MatrixParser>{
'skewY': _parseSvgSkewY,
};

List<double> _parseTransformParams(String params) {
final List<double> result = <double>[];
String current = '';
for (int i = 0; i < params.length; i += 1) {
if (params[i] == ' ' || params[i] == '-' || params[i] == ',') {
if (current != '') {
result.add(parseDouble(current)!);
}
if (params[i] == '-') {
current = '-';
} else {
current = '';
}
} else {
if (params[i] == '.') {
if (current.contains('.')) {
result.add(parseDouble(current)!);
current = '';
}
}
current += params[i];
}
}
if (current.isNotEmpty) {
result.add(parseDouble(current)!);
}
return result;
}

/// Parses a SVG transform attribute into a [AffineMatrix].
AffineMatrix? parseTransform(String? transform) {
if (transform == null || transform == '') {
Expand All @@ -39,7 +68,7 @@ AffineMatrix? parseTransform(String? transform) {
AffineMatrix result = AffineMatrix.identity;
for (Match m in matches) {
final String command = m.group(1)!.trim();
final String? params = m.group(2)!.trim();
final List<double> params = _parseTransformParams(m.group(2)!.trim());

final _MatrixParser? transformer = _matrixParsers[command];
if (transformer == null) {
Expand All @@ -51,60 +80,55 @@ AffineMatrix? parseTransform(String? transform) {
return result;
}

final RegExp _valueSeparator = RegExp('( *, *| +)');

AffineMatrix _parseSvgMatrix(String? paramsStr, AffineMatrix current) {
final List<String> params = paramsStr!.trim().split(_valueSeparator);
AffineMatrix _parseSvgMatrix(List<double> params, AffineMatrix current) {
assert(params.isNotEmpty);
assert(params.length == 6);
final double a = parseDouble(params[0])!;
final double b = parseDouble(params[1])!;
final double c = parseDouble(params[2])!;
final double d = parseDouble(params[3])!;
final double e = parseDouble(params[4])!;
final double f = parseDouble(params[5])!;
final double a = params[0];
final double b = params[1];
final double c = params[2];
final double d = params[3];
final double e = params[4];
final double f = params[5];

return AffineMatrix(a, b, c, d, e, f).multiplied(current);
}

AffineMatrix _parseSvgSkewX(String? paramsStr, AffineMatrix current) {
final double x = parseDouble(paramsStr)!;
return AffineMatrix(1.0, 0.0, tan(x), 1.0, 0.0, 0.0).multiplied(current);
AffineMatrix _parseSvgSkewX(List<double> params, AffineMatrix current) {
assert(params.isNotEmpty);
return AffineMatrix(1.0, 0.0, tan(params.first), 1.0, 0.0, 0.0)
.multiplied(current);
}

AffineMatrix _parseSvgSkewY(String? paramsStr, AffineMatrix current) {
final double y = parseDouble(paramsStr)!;
return AffineMatrix(1.0, tan(y), 0.0, 1.0, 0.0, 0.0).multiplied(current);
AffineMatrix _parseSvgSkewY(List<double> params, AffineMatrix current) {
assert(params.isNotEmpty);
return AffineMatrix(1.0, tan(params.first), 0.0, 1.0, 0.0, 0.0)
.multiplied(current);
}

AffineMatrix _parseSvgTranslate(String? paramsStr, AffineMatrix current) {
final List<String> params = paramsStr!.split(_valueSeparator);
AffineMatrix _parseSvgTranslate(List<double> params, AffineMatrix current) {
assert(params.isNotEmpty);
assert(params.length <= 2);
final double x = parseDouble(params[0])!;
final double y = params.length < 2 ? 0.0 : parseDouble(params[1])!;
return AffineMatrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current);
final double y = params.length < 2 ? 0.0 : params[1];
return AffineMatrix(1.0, 0.0, 0.0, 1.0, params.first, y).multiplied(current);
}

AffineMatrix _parseSvgScale(String? paramsStr, AffineMatrix current) {
final List<String> params = paramsStr!.split(_valueSeparator);
AffineMatrix _parseSvgScale(List<double> params, AffineMatrix current) {
assert(params.isNotEmpty);
assert(params.length <= 2);
final double x = parseDouble(params[0])!;
final double y = params.length < 2 ? x : parseDouble(params[1])!;
final double x = params[0];
final double y = params.length < 2 ? x : params[1];
return AffineMatrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current);
}

AffineMatrix _parseSvgRotate(String? paramsStr, AffineMatrix current) {
final List<String> params = paramsStr!.split(_valueSeparator);
AffineMatrix _parseSvgRotate(List<double> params, AffineMatrix current) {
assert(params.length <= 3);
final double a = radians(parseDouble(params[0])!);
final double a = radians(params[0]);

final AffineMatrix rotate = AffineMatrix.identity.rotated(a);

if (params.length > 1) {
final double x = parseDouble(params[1])!;
final double y = params.length == 3 ? parseDouble(params[2])! : x;
final double x = params[1];
final double y = params.length == 3 ? params[2] : x;
return AffineMatrix(1.0, 0.0, 0.0, 1.0, x, y)
.multiplied(rotate)
.translated(-x, -y)
Expand Down
6 changes: 3 additions & 3 deletions packages/vector_graphics_compiler/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: vector_graphics_compiler
description: A compiler for `package:vector_graphics`.
version: 1.1.7
version: 1.1.8
homepage: https://github.com/dnfield/vector_graphics

executables:
Expand All @@ -14,7 +14,7 @@ dependencies:
meta: ^1.7.0
path_parsing: ^1.0.1
xml: ^6.3.0
vector_graphics_codec: 1.1.7
vector_graphics_codec: 1.1.8

dev_dependencies:
flutter_lints: ^1.0.0
Expand All @@ -24,7 +24,7 @@ dev_dependencies:
sdk: flutter
flutter_test:
sdk: flutter
vector_graphics: 1.1.7
vector_graphics: 1.1.8

# Comment out before publishing
dependency_overrides:
Expand Down
11 changes: 11 additions & 0 deletions packages/vector_graphics_compiler/test/parsers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ void main() {
test('Point conversion', () {
expect(parseDoubleWithUnits('1pt', theme: const SvgTheme()), 1 + 1 / 3);
});

test('Parse a transform with a missing space', () {
expect(
parseTransform('translate(0-70)'),
AffineMatrix.identity.translated(0, -70),
);
});

test('Parse a transform with doubled periods', () {
print(parseTransform('matrix(.70711-.70711.70711.70711-640.89 452.68)'));
});
}

class TestColorMapper extends ColorMapper {
Expand Down

0 comments on commit 2b8860b

Please sign in to comment.