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