David PHAM-VAN

Add PdfDictStream

... ... @@ -20,6 +20,7 @@ import 'dart:typed_data';
import 'package:meta/meta.dart';
import 'ascii85.dart';
import 'color.dart';
import 'object.dart';
import 'stream.dart';
... ... @@ -113,7 +114,7 @@ class PdfNum extends PdfDataType {
}
class PdfNumList extends PdfDataType {
PdfNumList(this.values);
const PdfNumList(this.values);
final List<num> values;
... ... @@ -511,12 +512,16 @@ class PdfArray<T extends PdfDataType> extends PdfDataType {
}
class PdfDict<T extends PdfDataType> extends PdfDataType {
PdfDict([Map<String, T>? values]) {
factory PdfDict([Map<String, T>? values]) {
final _values = <String, T>{};
if (values != null) {
this.values.addAll(values);
_values.addAll(values);
}
return PdfDict.values(_values);
}
const PdfDict.values([this.values = const {}]);
static PdfDict<PdfIndirect> fromObjectMap(Map<String, PdfObject> objects) {
return PdfDict(
objects.map<String, PdfIndirect>(
... ... @@ -526,7 +531,7 @@ class PdfDict<T extends PdfDataType> extends PdfDataType {
);
}
final values = <String, T>{};
final Map<String, T> values;
bool get isNotEmpty => values.isNotEmpty;
... ... @@ -589,6 +594,63 @@ class PdfDict<T extends PdfDataType> extends PdfDataType {
int get hashCode => values.hashCode;
}
class PdfDictStream extends PdfDict<PdfDataType> {
const PdfDictStream({
required this.object,
Map<String, PdfDataType> values = const <String, PdfDataType>{},
required this.data,
this.isBinary = false,
}) : super.values(values);
final Uint8List data;
final PdfObject object;
final bool isBinary;
@override
void output(PdfStream s) {
final _values = PdfDict(values);
Uint8List? _data;
if (_values.containsKey('/Filter')) {
// The data is already in the right format
_data = data;
} else if (object.pdfDocument.deflate != null) {
// Compress the data
final newData = Uint8List.fromList(object.pdfDocument.deflate!(data));
if (newData.lengthInBytes < data.lengthInBytes) {
_values['/Filter'] = const PdfName('/FlateDecode');
_data = newData;
}
}
if (_data == null) {
if (isBinary) {
// This is an Ascii85 stream
final e = Ascii85Encoder();
_data = e.convert(data);
_values['/Filter'] = const PdfName('/ASCII85Decode');
} else {
// This is a non-deflated stream
_data = data;
}
}
if (object.pdfDocument.encryption != null) {
_data = object.pdfDocument.encryption!.encrypt(_data, object);
}
_values['/Length'] = PdfNum(_data.length);
_values.output(s);
s.putString('stream\n');
s.putBytes(_data);
s.putString('\nendstream\n');
}
}
class PdfColorType extends PdfDataType {
const PdfColorType(this.color);
... ...
... ... @@ -38,6 +38,10 @@ void main() {
expect(const PdfNum(50.1).toString(), '50.1');
});
test('PdfDataTypes NumList', () {
expect(const PdfNumList([0, 1, 2, 3]).toString(), '0 1 2 3');
});
test('PdfDataTypes String', () {
expect(PdfString.fromString('test').toString(), '(test)');
expect(PdfString.fromString('Zoé').toString(), '(Zoé)');
... ... @@ -105,8 +109,8 @@ void main() {
'/String': PdfString.fromString('hello'),
'/Null': const PdfNull(),
'/Indirect': const PdfIndirect(55, 0),
'/Array': PdfArray<PdfDataType>([]),
'/Dict': PdfDict<PdfDataType>({}),
'/Array': PdfArray(),
'/Dict': PdfDict(),
}).toString(),
'<</Name/Value/Bool true/Num 42/String(hello)/Null null/Indirect 55 0 R/Array[]/Dict<<>>>>',
);
... ...