@@ -5,12 +5,93 @@ import 'package:flutter/services.dart';
5
5
import 'package:flutter/widgets.dart' ;
6
6
import 'package:flutter_svg/src/utilities/http.dart' ;
7
7
import 'package:vector_graphics/vector_graphics.dart' ;
8
- import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' ;
8
+ import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' as vg ;
9
9
10
10
import '../svg.dart' show svg;
11
11
import 'utilities/compute.dart' ;
12
12
import 'utilities/file.dart' ;
13
13
14
+ /// A theme used when decoding an SVG picture.
15
+ @immutable
16
+ class SvgTheme {
17
+ /// Instantiates an SVG theme with the [currentColor]
18
+ /// and [fontSize] .
19
+ ///
20
+ /// Defaults the [fontSize] to 14.
21
+ const SvgTheme ({
22
+ this .currentColor,
23
+ this .fontSize = 14 ,
24
+ double ? xHeight,
25
+ }) : xHeight = xHeight ?? fontSize / 2 ;
26
+
27
+ /// The default color applied to SVG elements that inherit the color property.
28
+ /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword
29
+ final Color ? currentColor;
30
+
31
+ /// The font size used when calculating em units of SVG elements.
32
+ /// See: https://www.w3.org/TR/SVG11/coords.html#Units
33
+ final double fontSize;
34
+
35
+ /// The x-height (corpus size) of the font used when calculating ex units of SVG elements.
36
+ /// Defaults to [fontSize] / 2 if not provided.
37
+ /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height
38
+ final double xHeight;
39
+
40
+ vg.SvgTheme _toVgTheme () {
41
+ return vg.SvgTheme (
42
+ currentColor: currentColor != null ? vg.Color (currentColor! .value) : null ,
43
+ fontSize: fontSize,
44
+ xHeight: xHeight,
45
+ );
46
+ }
47
+
48
+ @override
49
+ bool operator == (dynamic other) {
50
+ if (other.runtimeType != runtimeType) {
51
+ return false ;
52
+ }
53
+
54
+ return other is SvgTheme &&
55
+ currentColor == other.currentColor &&
56
+ fontSize == other.fontSize &&
57
+ xHeight == other.xHeight;
58
+ }
59
+
60
+ @override
61
+ int get hashCode => Object .hash (currentColor, fontSize, xHeight);
62
+
63
+ @override
64
+ String toString () =>
65
+ 'SvgTheme(currentColor: $currentColor , fontSize: $fontSize , xHeight: $xHeight )' ;
66
+ }
67
+
68
+ /// A class that transforms from one color to another during SVG parsing.
69
+ abstract class ColorMapper {
70
+ /// Returns a new color to use in place of [color] during SVG parsing.
71
+ ///
72
+ /// The SVG parser will call this method every time it parses a color
73
+ Color substitute (
74
+ String ? id,
75
+ String elementName,
76
+ String attributeName,
77
+ Color color,
78
+ );
79
+ }
80
+
81
+ class _DelegateVgColorMapper extends vg.ColorMapper {
82
+ _DelegateVgColorMapper (this .colorMapper);
83
+
84
+ final ColorMapper colorMapper;
85
+
86
+ @override
87
+ vg.Color substitute (
88
+ String ? id, String elementName, String attributeName, vg.Color color) {
89
+ final Color substituteColor = colorMapper.substitute (
90
+ id, elementName, attributeName, Color (color.value));
91
+ return vg.Color (substituteColor.value);
92
+ }
93
+ }
94
+
14
95
/// A [BytesLoader] that parses a SVG data in an isolate and creates a
15
96
/// vector_graphics binary representation.
16
97
abstract class SvgLoader <T > extends BytesLoader {
@@ -38,15 +119,20 @@ abstract class SvgLoader<T> extends BytesLoader {
38
119
Future <ByteData > _load (BuildContext ? context) {
39
120
return prepareMessage (context).then ((T ? message) {
40
121
return compute ((T ? message) {
41
- return encodeSvg (
42
- xml: provideSvg (message),
43
- theme: theme,
44
- colorMapper: colorMapper,
45
- debugName: 'Svg loader' ,
46
- enableClippingOptimizer: false ,
47
- enableMaskingOptimizer: false ,
48
- enableOverdrawOptimizer: false ,
49
- ).buffer.asByteData ();
122
+ return vg
123
+ .encodeSvg (
124
+ xml: provideSvg (message),
125
+ theme: theme._toVgTheme (),
126
+ colorMapper: colorMapper == null
127
+ ? null
128
+ : _DelegateVgColorMapper (colorMapper! ),
129
+ debugName: 'Svg loader' ,
130
+ enableClippingOptimizer: false ,
131
+ enableMaskingOptimizer: false ,
132
+ enableOverdrawOptimizer: false ,
133
+ )
134
+ .buffer
135
+ .asByteData ();
50
136
}, message, debugLabel: 'Load Bytes' );
51
137
});
52
138
}
0 commit comments