33// found in the LICENSE file.
44
55import 'dart:io' ;
6- import 'dart:typed_data' ;
76
87import 'package:args/args.dart' ;
9- import 'package:vector_graphics_compiler/vector_graphics_compiler .dart' ;
8+ import 'package:vector_graphics_compiler/src/isolate_processor .dart' ;
109
1110final ArgParser argParser = ArgParser ()
1211 ..addOption (
@@ -41,29 +40,39 @@ final ArgParser argParser = ArgParser()
4140 help: 'Allows for overdraw optimizer to be enabled or disabled' ,
4241 defaultsTo: true ,
4342 )
44- ..addOption ('input' ,
45- abbr: 'i' ,
46- help: 'The path to a file containing a single SVG' ,
47- mandatory: true )
43+ ..addOption (
44+ 'input-dir' ,
45+ help: 'The path to a directory containing one or more SVGs. '
46+ 'Only includes files that end with .svg. '
47+ 'Cannot be combined with --input or --output.' ,
48+ )
49+ ..addOption (
50+ 'input' ,
51+ abbr: 'i' ,
52+ help: 'The path to a file containing a single SVG' ,
53+ )
54+ ..addOption ('concurrency' ,
55+ abbr: 'k' ,
56+ help: 'The maximum number of SVG processing isolates to spawn at once. '
57+ 'If not provided, defaults to the number of cores.' )
4858 ..addOption (
4959 'output' ,
5060 abbr: 'o' ,
5161 help:
5262 'The path to a file where the resulting vector_graphic will be written.\n '
53- 'If not provided, defaults to <input-file>.vg ' ,
63+ 'If not provided, defaults to <input-file>.vec ' ,
5464 );
5565
56- void loadPathOpsIfNeeded (ArgResults results) {
57- if (results['optimize-masks' ] == true ||
58- results['optimize-clips' ] == true ||
59- results['optimize-overdraw' ] == true ) {
60- if (results.wasParsed ('libpathops' )) {
61- initializeLibPathOps (results['libpathops' ] as String );
62- } else {
63- if (! initializePathOpsFromFlutterCache ()) {
64- exit (1 );
65- }
66- }
66+ void validateOptions (ArgResults results) {
67+ if (results.wasParsed ('input-dir' ) &&
68+ (results.wasParsed ('input' ) || results.wasParsed ('output' ))) {
69+ print (
70+ '--input-dir cannot be combined with --input and/or --output options.' );
71+ exit (1 );
72+ }
73+ if (! results.wasParsed ('input' ) && ! results.wasParsed ('input-dir' )) {
74+ print ('One of --input or --input-dir must be specified.' );
75+ exit (1 );
6776 }
6877}
6978
@@ -76,46 +85,53 @@ Future<void> main(List<String> args) async {
7685 print (argParser.usage);
7786 exit (1 );
7887 }
88+ validateOptions (results);
7989
80- if (results['tessellate' ] == true ) {
81- if (results.wasParsed ('libtessellator' )) {
82- initializeLibTesselator (results['libtessellator' ] as String );
83- } else {
84- if (! initializeTessellatorFromFlutterCache ()) {
85- exit (1 );
90+ final List <Pair > pairs = < Pair > [];
91+ if (results.wasParsed ('input-dir' )) {
92+ final Directory directory = Directory (results['input-dir' ] as String );
93+ if (! directory.existsSync ()) {
94+ print ('input-dir ${directory .path } does not exist.' );
95+ exit (1 );
96+ }
97+ for (final File file
98+ in directory.listSync (recursive: true ).whereType <File >()) {
99+ if (! file.path.endsWith ('.svg' )) {
100+ continue ;
86101 }
102+ final String outputPath = '${file .path }.vec' ;
103+ pairs.add (Pair (file.path, outputPath));
87104 }
105+ } else {
106+ final String inputFilePath = results['input' ] as String ;
107+ final String outputFilePath =
108+ results['output' ] as String ? ?? '$inputFilePath .vec' ;
109+ pairs.add (Pair (inputFilePath, outputFilePath));
88110 }
89111
90- loadPathOpsIfNeeded (results);
91-
92- final String inputFilePath = results['input' ] as String ;
93- final String xml = File (inputFilePath).readAsStringSync ();
94- final File outputFile =
95- File (results['output' ] as String ? ?? '$inputFilePath .vg' );
96-
97- bool maskingOptimizerEnabled = true ;
98- bool clippingOptimizerEnabled = true ;
99- bool overdrawOptimizerEnabled = true ;
100-
101- if (results['optimize-masks' ] == false ) {
102- maskingOptimizerEnabled = false ;
103- }
104-
105- if (results['optimize-clips' ] == false ) {
106- clippingOptimizerEnabled = false ;
112+ final bool maskingOptimizerEnabled = results['optimize-masks' ] == true ;
113+ final bool clippingOptimizerEnabled = results['optimize-clips' ] == true ;
114+ final bool overdrawOptimizerEnabled = results['optimize-overdraw' ] == true ;
115+ final bool tessellate = results['tessellate' ] == true ;
116+ final int concurrency;
117+ if (results.wasParsed ('concurrency' )) {
118+ concurrency = int .parse (results['concurrency' ] as String );
119+ } else {
120+ concurrency = Platform .numberOfProcessors;
107121 }
108122
109- if (results['optimize-overdraw' ] == false ) {
110- overdrawOptimizerEnabled = false ;
123+ final IsolateProcessor processor = IsolateProcessor (
124+ results['libpathops' ] as String ? ,
125+ results['libtessellator' ] as String ? ,
126+ concurrency,
127+ );
128+ if (! await processor.process (
129+ pairs,
130+ maskingOptimizerEnabled: maskingOptimizerEnabled,
131+ clippingOptimizerEnabled: clippingOptimizerEnabled,
132+ overdrawOptimizerEnabled: overdrawOptimizerEnabled,
133+ tessellate: tessellate,
134+ )) {
135+ exit (1 );
111136 }
112-
113- final Uint8List bytes = await encodeSvg (
114- xml: xml,
115- debugName: args[0 ],
116- enableMaskingOptimizer: maskingOptimizerEnabled,
117- enableClippingOptimizer: clippingOptimizerEnabled,
118- enableOverdrawOptimizer: overdrawOptimizerEnabled);
119-
120- outputFile.writeAsBytesSync (bytes);
121137}
0 commit comments