Showing
2 changed files
with
72 additions
and
6 deletions
@@ -20,6 +20,7 @@ import 'dart:typed_data'; | @@ -20,6 +20,7 @@ import 'dart:typed_data'; | ||
20 | 20 | ||
21 | import 'package:meta/meta.dart'; | 21 | import 'package:meta/meta.dart'; |
22 | 22 | ||
23 | +import 'ascii85.dart'; | ||
23 | import 'color.dart'; | 24 | import 'color.dart'; |
24 | import 'object.dart'; | 25 | import 'object.dart'; |
25 | import 'stream.dart'; | 26 | import 'stream.dart'; |
@@ -113,7 +114,7 @@ class PdfNum extends PdfDataType { | @@ -113,7 +114,7 @@ class PdfNum extends PdfDataType { | ||
113 | } | 114 | } |
114 | 115 | ||
115 | class PdfNumList extends PdfDataType { | 116 | class PdfNumList extends PdfDataType { |
116 | - PdfNumList(this.values); | 117 | + const PdfNumList(this.values); |
117 | 118 | ||
118 | final List<num> values; | 119 | final List<num> values; |
119 | 120 | ||
@@ -511,12 +512,16 @@ class PdfArray<T extends PdfDataType> extends PdfDataType { | @@ -511,12 +512,16 @@ class PdfArray<T extends PdfDataType> extends PdfDataType { | ||
511 | } | 512 | } |
512 | 513 | ||
513 | class PdfDict<T extends PdfDataType> extends PdfDataType { | 514 | class PdfDict<T extends PdfDataType> extends PdfDataType { |
514 | - PdfDict([Map<String, T>? values]) { | 515 | + factory PdfDict([Map<String, T>? values]) { |
516 | + final _values = <String, T>{}; | ||
515 | if (values != null) { | 517 | if (values != null) { |
516 | - this.values.addAll(values); | 518 | + _values.addAll(values); |
517 | } | 519 | } |
520 | + return PdfDict.values(_values); | ||
518 | } | 521 | } |
519 | 522 | ||
523 | + const PdfDict.values([this.values = const {}]); | ||
524 | + | ||
520 | static PdfDict<PdfIndirect> fromObjectMap(Map<String, PdfObject> objects) { | 525 | static PdfDict<PdfIndirect> fromObjectMap(Map<String, PdfObject> objects) { |
521 | return PdfDict( | 526 | return PdfDict( |
522 | objects.map<String, PdfIndirect>( | 527 | objects.map<String, PdfIndirect>( |
@@ -526,7 +531,7 @@ class PdfDict<T extends PdfDataType> extends PdfDataType { | @@ -526,7 +531,7 @@ class PdfDict<T extends PdfDataType> extends PdfDataType { | ||
526 | ); | 531 | ); |
527 | } | 532 | } |
528 | 533 | ||
529 | - final values = <String, T>{}; | 534 | + final Map<String, T> values; |
530 | 535 | ||
531 | bool get isNotEmpty => values.isNotEmpty; | 536 | bool get isNotEmpty => values.isNotEmpty; |
532 | 537 | ||
@@ -589,6 +594,63 @@ class PdfDict<T extends PdfDataType> extends PdfDataType { | @@ -589,6 +594,63 @@ class PdfDict<T extends PdfDataType> extends PdfDataType { | ||
589 | int get hashCode => values.hashCode; | 594 | int get hashCode => values.hashCode; |
590 | } | 595 | } |
591 | 596 | ||
597 | +class PdfDictStream extends PdfDict<PdfDataType> { | ||
598 | + const PdfDictStream({ | ||
599 | + required this.object, | ||
600 | + Map<String, PdfDataType> values = const <String, PdfDataType>{}, | ||
601 | + required this.data, | ||
602 | + this.isBinary = false, | ||
603 | + }) : super.values(values); | ||
604 | + | ||
605 | + final Uint8List data; | ||
606 | + | ||
607 | + final PdfObject object; | ||
608 | + | ||
609 | + final bool isBinary; | ||
610 | + | ||
611 | + @override | ||
612 | + void output(PdfStream s) { | ||
613 | + final _values = PdfDict(values); | ||
614 | + | ||
615 | + Uint8List? _data; | ||
616 | + | ||
617 | + if (_values.containsKey('/Filter')) { | ||
618 | + // The data is already in the right format | ||
619 | + _data = data; | ||
620 | + } else if (object.pdfDocument.deflate != null) { | ||
621 | + // Compress the data | ||
622 | + final newData = Uint8List.fromList(object.pdfDocument.deflate!(data)); | ||
623 | + if (newData.lengthInBytes < data.lengthInBytes) { | ||
624 | + _values['/Filter'] = const PdfName('/FlateDecode'); | ||
625 | + _data = newData; | ||
626 | + } | ||
627 | + } | ||
628 | + | ||
629 | + if (_data == null) { | ||
630 | + if (isBinary) { | ||
631 | + // This is an Ascii85 stream | ||
632 | + final e = Ascii85Encoder(); | ||
633 | + _data = e.convert(data); | ||
634 | + _values['/Filter'] = const PdfName('/ASCII85Decode'); | ||
635 | + } else { | ||
636 | + // This is a non-deflated stream | ||
637 | + _data = data; | ||
638 | + } | ||
639 | + } | ||
640 | + | ||
641 | + if (object.pdfDocument.encryption != null) { | ||
642 | + _data = object.pdfDocument.encryption!.encrypt(_data, object); | ||
643 | + } | ||
644 | + | ||
645 | + _values['/Length'] = PdfNum(_data.length); | ||
646 | + | ||
647 | + _values.output(s); | ||
648 | + s.putString('stream\n'); | ||
649 | + s.putBytes(_data); | ||
650 | + s.putString('\nendstream\n'); | ||
651 | + } | ||
652 | +} | ||
653 | + | ||
592 | class PdfColorType extends PdfDataType { | 654 | class PdfColorType extends PdfDataType { |
593 | const PdfColorType(this.color); | 655 | const PdfColorType(this.color); |
594 | 656 |
@@ -38,6 +38,10 @@ void main() { | @@ -38,6 +38,10 @@ void main() { | ||
38 | expect(const PdfNum(50.1).toString(), '50.1'); | 38 | expect(const PdfNum(50.1).toString(), '50.1'); |
39 | }); | 39 | }); |
40 | 40 | ||
41 | + test('PdfDataTypes NumList', () { | ||
42 | + expect(const PdfNumList([0, 1, 2, 3]).toString(), '0 1 2 3'); | ||
43 | + }); | ||
44 | + | ||
41 | test('PdfDataTypes String', () { | 45 | test('PdfDataTypes String', () { |
42 | expect(PdfString.fromString('test').toString(), '(test)'); | 46 | expect(PdfString.fromString('test').toString(), '(test)'); |
43 | expect(PdfString.fromString('Zoé').toString(), '(Zoé)'); | 47 | expect(PdfString.fromString('Zoé').toString(), '(Zoé)'); |
@@ -105,8 +109,8 @@ void main() { | @@ -105,8 +109,8 @@ void main() { | ||
105 | '/String': PdfString.fromString('hello'), | 109 | '/String': PdfString.fromString('hello'), |
106 | '/Null': const PdfNull(), | 110 | '/Null': const PdfNull(), |
107 | '/Indirect': const PdfIndirect(55, 0), | 111 | '/Indirect': const PdfIndirect(55, 0), |
108 | - '/Array': PdfArray<PdfDataType>([]), | ||
109 | - '/Dict': PdfDict<PdfDataType>({}), | 112 | + '/Array': PdfArray(), |
113 | + '/Dict': PdfDict(), | ||
110 | }).toString(), | 114 | }).toString(), |
111 | '<</Name/Value/Bool true/Num 42/String(hello)/Null null/Indirect 55 0 R/Array[]/Dict<<>>>>', | 115 | '<</Name/Value/Bool true/Num 42/String(hello)/Null null/Indirect 55 0 R/Array[]/Dict<<>>>>', |
112 | ); | 116 | ); |
-
Please register or login to post a comment