Showing
28 changed files
with
578 additions
and
309 deletions
@@ -38,6 +38,7 @@ part 'src/catalog.dart'; | @@ -38,6 +38,7 @@ part 'src/catalog.dart'; | ||
38 | part 'src/color.dart'; | 38 | part 'src/color.dart'; |
39 | part 'src/colors.dart'; | 39 | part 'src/colors.dart'; |
40 | part 'src/compatibility.dart'; | 40 | part 'src/compatibility.dart'; |
41 | +part 'src/data_types.dart'; | ||
41 | part 'src/document.dart'; | 42 | part 'src/document.dart'; |
42 | part 'src/encryption.dart'; | 43 | part 'src/encryption.dart'; |
43 | part 'src/exif.dart'; | 44 | part 'src/exif.dart'; |
@@ -86,7 +86,7 @@ class PdfAnnot extends PdfObject { | @@ -86,7 +86,7 @@ class PdfAnnot extends PdfObject { | ||
86 | @override | 86 | @override |
87 | void _prepare() { | 87 | void _prepare() { |
88 | super._prepare(); | 88 | super._prepare(); |
89 | - annot.build(pdfPage, params); | 89 | + annot.build(pdfPage, this, params); |
90 | } | 90 | } |
91 | } | 91 | } |
92 | 92 | ||
@@ -145,44 +145,44 @@ abstract class PdfAnnotBase { | @@ -145,44 +145,44 @@ abstract class PdfAnnotBase { | ||
145 | 145 | ||
146 | @protected | 146 | @protected |
147 | @mustCallSuper | 147 | @mustCallSuper |
148 | - void build(PdfPage page, Map<String, PdfStream> params) { | ||
149 | - params['/Subtype'] = PdfStream.string(subtype); | ||
150 | - params['/Rect'] = PdfStream() | ||
151 | - ..putNumArray(<double>[rect.left, rect.bottom, rect.right, rect.top]); | 148 | + void build(PdfPage page, PdfObject object, PdfDict params) { |
149 | + params['/Subtype'] = PdfName(subtype); | ||
150 | + params['/Rect'] = PdfArray.fromNum( | ||
151 | + <double>[rect.left, rect.bottom, rect.right, rect.top]); | ||
152 | 152 | ||
153 | params['/P'] = page.ref(); | 153 | params['/P'] = page.ref(); |
154 | 154 | ||
155 | // handle the border | 155 | // handle the border |
156 | if (border == null) { | 156 | if (border == null) { |
157 | - params['/Border'] = PdfStream.string('[0 0 0]'); | 157 | + params['/Border'] = PdfArray.fromNum(const <int>[0, 0, 0]); |
158 | } else { | 158 | } else { |
159 | params['/BS'] = border.ref(); | 159 | params['/BS'] = border.ref(); |
160 | } | 160 | } |
161 | 161 | ||
162 | if (content != null) { | 162 | if (content != null) { |
163 | - params['/Contents'] = PdfStream()..putLiteral(content); | 163 | + params['/Contents'] = PdfSecString.fromString(object, content); |
164 | } | 164 | } |
165 | 165 | ||
166 | if (name != null) { | 166 | if (name != null) { |
167 | - params['/NM'] = PdfStream()..putLiteral(name); | 167 | + params['/NM'] = PdfSecString.fromString(object, name); |
168 | } | 168 | } |
169 | 169 | ||
170 | if (flags != null) { | 170 | if (flags != null) { |
171 | - params['/F'] = PdfStream.intNum(flagValue); | 171 | + params['/F'] = PdfNum(flagValue); |
172 | } | 172 | } |
173 | 173 | ||
174 | if (date != null) { | 174 | if (date != null) { |
175 | - params['/M'] = PdfStream()..putDate(date); | 175 | + params['/M'] = PdfSecString.fromDate(object, date); |
176 | } | 176 | } |
177 | 177 | ||
178 | if (color != null) { | 178 | if (color != null) { |
179 | if (color is PdfColorCmyk) { | 179 | if (color is PdfColorCmyk) { |
180 | final PdfColorCmyk k = color; | 180 | final PdfColorCmyk k = color; |
181 | - params['/C'] = PdfStream() | ||
182 | - ..putNumList(<double>[k.cyan, k.magenta, k.yellow, k.black]); | 181 | + params['/C'] = |
182 | + PdfArray.fromNum(<double>[k.cyan, k.magenta, k.yellow, k.black]); | ||
183 | } else { | 183 | } else { |
184 | - params['/C'] = PdfStream() | ||
185 | - ..putNumList(<double>[color.red, color.green, color.blue]); | 184 | + params['/C'] = |
185 | + PdfArray.fromNum(<double>[color.red, color.green, color.blue]); | ||
186 | } | 186 | } |
187 | } | 187 | } |
188 | } | 188 | } |
@@ -231,13 +231,12 @@ class PdfAnnotNamedLink extends PdfAnnotBase { | @@ -231,13 +231,12 @@ class PdfAnnotNamedLink extends PdfAnnotBase { | ||
231 | final String dest; | 231 | final String dest; |
232 | 232 | ||
233 | @override | 233 | @override |
234 | - void build(PdfPage page, Map<String, PdfStream> params) { | ||
235 | - super.build(page, params); | ||
236 | - params['/A'] = PdfStream() | ||
237 | - ..putDictionary( | ||
238 | - <String, PdfStream>{ | ||
239 | - '/S': PdfStream()..putString('/GoTo'), | ||
240 | - '/D': PdfStream()..putText(dest), | 234 | + void build(PdfPage page, PdfObject object, PdfDict params) { |
235 | + super.build(page, object, params); | ||
236 | + params['/A'] = PdfDict( | ||
237 | + <String, PdfDataType>{ | ||
238 | + '/S': const PdfName('/GoTo'), | ||
239 | + '/D': PdfSecString.fromString(object, dest), | ||
241 | }, | 240 | }, |
242 | ); | 241 | ); |
243 | } | 242 | } |
@@ -264,13 +263,12 @@ class PdfAnnotUrlLink extends PdfAnnotBase { | @@ -264,13 +263,12 @@ class PdfAnnotUrlLink extends PdfAnnotBase { | ||
264 | final String url; | 263 | final String url; |
265 | 264 | ||
266 | @override | 265 | @override |
267 | - void build(PdfPage page, Map<String, PdfStream> params) { | ||
268 | - super.build(page, params); | ||
269 | - params['/A'] = PdfStream() | ||
270 | - ..putDictionary( | ||
271 | - <String, PdfStream>{ | ||
272 | - '/S': PdfStream()..putString('/URI'), | ||
273 | - '/URI': PdfStream()..putText(url), | 266 | + void build(PdfPage page, PdfObject object, PdfDict params) { |
267 | + super.build(page, object, params); | ||
268 | + params['/A'] = PdfDict( | ||
269 | + <String, PdfDataType>{ | ||
270 | + '/S': const PdfName('/URI'), | ||
271 | + '/URI': PdfSecString.fromString(object, url), | ||
274 | }, | 272 | }, |
275 | ); | 273 | ); |
276 | } | 274 | } |
@@ -289,7 +287,6 @@ abstract class PdfAnnotWidget extends PdfAnnotBase { | @@ -289,7 +287,6 @@ abstract class PdfAnnotWidget extends PdfAnnotBase { | ||
289 | DateTime date, | 287 | DateTime date, |
290 | PdfColor color, | 288 | PdfColor color, |
291 | this.highlighting, | 289 | this.highlighting, |
292 | - this.value, | ||
293 | }) : super( | 290 | }) : super( |
294 | subtype: '/Widget', | 291 | subtype: '/Widget', |
295 | rect: rect, | 292 | rect: rect, |
@@ -305,20 +302,14 @@ abstract class PdfAnnotWidget extends PdfAnnotBase { | @@ -305,20 +302,14 @@ abstract class PdfAnnotWidget extends PdfAnnotBase { | ||
305 | 302 | ||
306 | final PdfAnnotHighlighting highlighting; | 303 | final PdfAnnotHighlighting highlighting; |
307 | 304 | ||
308 | - final PdfStream value; | ||
309 | - | ||
310 | @override | 305 | @override |
311 | - void build(PdfPage page, Map<String, PdfStream> params) { | ||
312 | - super.build(page, params); | 306 | + void build(PdfPage page, PdfObject object, PdfDict params) { |
307 | + super.build(page, object, params); | ||
313 | 308 | ||
314 | - params['/FT'] = PdfStream.string(fieldType); | 309 | + params['/FT'] = PdfName(fieldType); |
315 | 310 | ||
316 | if (fieldName != null) { | 311 | if (fieldName != null) { |
317 | - params['/T'] = PdfStream()..putLiteral(fieldName); | ||
318 | - } | ||
319 | - | ||
320 | - if (value != null) { | ||
321 | - params['/V'] = value; | 312 | + params['/T'] = PdfSecString.fromString(object, fieldName); |
322 | } | 313 | } |
323 | } | 314 | } |
324 | } | 315 | } |
@@ -344,8 +335,8 @@ class PdfAnnotSign extends PdfAnnotWidget { | @@ -344,8 +335,8 @@ class PdfAnnotSign extends PdfAnnotWidget { | ||
344 | ); | 335 | ); |
345 | 336 | ||
346 | @override | 337 | @override |
347 | - void build(PdfPage page, Map<String, PdfStream> params) { | ||
348 | - super.build(page, params); | 338 | + void build(PdfPage page, PdfObject object, PdfDict params) { |
339 | + super.build(page, object, params); | ||
349 | assert(page.pdfDocument.sign != null); | 340 | assert(page.pdfDocument.sign != null); |
350 | params['/V'] = page.pdfDocument.sign.ref(); | 341 | params['/V'] = page.pdfDocument.sign.ref(); |
351 | } | 342 | } |
@@ -19,17 +19,17 @@ part of pdf; | @@ -19,17 +19,17 @@ part of pdf; | ||
19 | class PdfArrayObject extends PdfObject { | 19 | class PdfArrayObject extends PdfObject { |
20 | PdfArrayObject( | 20 | PdfArrayObject( |
21 | PdfDocument pdfDocument, | 21 | PdfDocument pdfDocument, |
22 | - this.values, | ||
23 | - ) : assert(values != null), | 22 | + this.array, |
23 | + ) : assert(array != null), | ||
24 | super(pdfDocument); | 24 | super(pdfDocument); |
25 | 25 | ||
26 | - final List<String> values; | 26 | + final PdfArray array; |
27 | 27 | ||
28 | @override | 28 | @override |
29 | void _writeContent(PdfStream os) { | 29 | void _writeContent(PdfStream os) { |
30 | super._writeContent(os); | 30 | super._writeContent(os); |
31 | 31 | ||
32 | - os.putStringArray(values); | 32 | + array.output(os); |
33 | os.putBytes(<int>[0x0a]); | 33 | os.putBytes(<int>[0x0a]); |
34 | } | 34 | } |
35 | } | 35 | } |
@@ -66,18 +66,15 @@ class PdfBorder extends PdfObject { | @@ -66,18 +66,15 @@ class PdfBorder extends PdfObject { | ||
66 | 66 | ||
67 | /// @param os OutputStream to send the object to | 67 | /// @param os OutputStream to send the object to |
68 | @override | 68 | @override |
69 | - void _writeContent(PdfStream os) { | ||
70 | - super._writeContent(os); | 69 | + void _prepare() { |
70 | + super._prepare(); | ||
71 | + | ||
72 | + params['/S'] = | ||
73 | + PdfName('/' + 'SDBIU'.substring(style.index, style.index + 1)); | ||
74 | + params['/W'] = PdfNum(width); | ||
71 | 75 | ||
72 | - final List<PdfStream> data = <PdfStream>[]; | ||
73 | - data.add(PdfStream.string('/S')); | ||
74 | - data.add(PdfStream.string( | ||
75 | - '/' + 'SDBIU'.substring(style.index, style.index + 1))); | ||
76 | - data.add(PdfStream.string('/W $width')); | ||
77 | if (dash != null) { | 76 | if (dash != null) { |
78 | - data.add(PdfStream.string('/D')); | ||
79 | - data.add(PdfStream.array(dash.map((double d) => PdfStream.num(d)))); | 77 | + params['/D'] = PdfArray.fromNum(dash); |
80 | } | 78 | } |
81 | - os.putArray(data); | ||
82 | } | 79 | } |
83 | } | 80 | } |
@@ -52,7 +52,7 @@ class PdfCatalog extends PdfObject { | @@ -52,7 +52,7 @@ class PdfCatalog extends PdfObject { | ||
52 | super._prepare(); | 52 | super._prepare(); |
53 | 53 | ||
54 | /// the PDF specification version, overrides the header version starting from 1.4 | 54 | /// the PDF specification version, overrides the header version starting from 1.4 |
55 | - params['/Version'] = PdfStream.string('/${pdfDocument.version}'); | 55 | + params['/Version'] = PdfName('/${pdfDocument.version}'); |
56 | 56 | ||
57 | params['/Pages'] = pdfPageList.ref(); | 57 | params['/Pages'] = pdfPageList.ref(); |
58 | 58 | ||
@@ -65,11 +65,10 @@ class PdfCatalog extends PdfObject { | @@ -65,11 +65,10 @@ class PdfCatalog extends PdfObject { | ||
65 | params['/Names'] = names.ref(); | 65 | params['/Names'] = names.ref(); |
66 | 66 | ||
67 | // the /PageMode setting | 67 | // the /PageMode setting |
68 | - params['/PageMode'] = | ||
69 | - PdfStream.string(PdfDocument._PdfPageModes[pageMode.index]); | 68 | + params['/PageMode'] = PdfName(PdfDocument._PdfPageModes[pageMode.index]); |
70 | 69 | ||
71 | if (pdfDocument.sign != null) { | 70 | if (pdfDocument.sign != null) { |
72 | - params['/Perms'] = PdfStream.dictionary(<String, PdfStream>{ | 71 | + params['/Perms'] = PdfDict(<String, PdfDataType>{ |
73 | '/DocMDP': pdfDocument.sign.ref(), | 72 | '/DocMDP': pdfDocument.sign.ref(), |
74 | }); | 73 | }); |
75 | } | 74 | } |
@@ -84,9 +83,9 @@ class PdfCatalog extends PdfObject { | @@ -84,9 +83,9 @@ class PdfCatalog extends PdfObject { | ||
84 | } | 83 | } |
85 | 84 | ||
86 | if (widgets.isNotEmpty) { | 85 | if (widgets.isNotEmpty) { |
87 | - params['/AcroForm'] = PdfStream.dictionary(<String, PdfStream>{ | ||
88 | - '/SigFlags': PdfStream.intNum(pdfDocument.sign?.flagsValue ?? 0), | ||
89 | - '/Fields': PdfStream()..putObjectArray(widgets), | 86 | + params['/AcroForm'] = PdfDict(<String, PdfDataType>{ |
87 | + '/SigFlags': PdfNum(pdfDocument.sign?.flagsValue ?? 0), | ||
88 | + '/Fields': PdfArray.fromObjects(widgets), | ||
90 | }); | 89 | }); |
91 | } | 90 | } |
92 | } | 91 | } |
@@ -73,7 +73,7 @@ class PDFAnnot extends PdfAnnot { | @@ -73,7 +73,7 @@ class PDFAnnot extends PdfAnnot { | ||
73 | @deprecated | 73 | @deprecated |
74 | class PDFArrayObject extends PdfArrayObject { | 74 | class PDFArrayObject extends PdfArrayObject { |
75 | PDFArrayObject(PdfDocument pdfDocument, List<String> values) | 75 | PDFArrayObject(PdfDocument pdfDocument, List<String> values) |
76 | - : super(pdfDocument, values); | 76 | + : super(pdfDocument, null); |
77 | } | 77 | } |
78 | 78 | ||
79 | @deprecated | 79 | @deprecated |
pdf/lib/src/data_types.dart
0 → 100644
1 | +/* | ||
2 | + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com> | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +// ignore_for_file: omit_local_variable_types | ||
18 | +// ignore_for_file: avoid_unused_constructor_parameters | ||
19 | + | ||
20 | +part of pdf; | ||
21 | + | ||
22 | +abstract class PdfDataType { | ||
23 | + const PdfDataType(); | ||
24 | + | ||
25 | + void output(PdfStream s); | ||
26 | + | ||
27 | + PdfStream toStream() { | ||
28 | + final PdfStream s = PdfStream(); | ||
29 | + output(s); | ||
30 | + return s; | ||
31 | + } | ||
32 | + | ||
33 | + @override | ||
34 | + String toString() { | ||
35 | + return String.fromCharCodes(toStream().output()); | ||
36 | + } | ||
37 | + | ||
38 | + List<int> toList() { | ||
39 | + return toStream().output(); | ||
40 | + } | ||
41 | +} | ||
42 | + | ||
43 | +class PdfBool extends PdfDataType { | ||
44 | + const PdfBool(this.value); | ||
45 | + | ||
46 | + final bool value; | ||
47 | + | ||
48 | + @override | ||
49 | + void output(PdfStream s) { | ||
50 | + s.putString(value ? 'true' : 'false'); | ||
51 | + } | ||
52 | +} | ||
53 | + | ||
54 | +class PdfNum extends PdfDataType { | ||
55 | + const PdfNum(this.value); | ||
56 | + | ||
57 | + final num value; | ||
58 | + | ||
59 | + @override | ||
60 | + void output(PdfStream s) { | ||
61 | + if (value is int) { | ||
62 | + s.putString(value.toInt().toString()); | ||
63 | + } else { | ||
64 | + s.putNum(value); | ||
65 | + } | ||
66 | + } | ||
67 | +} | ||
68 | + | ||
69 | +enum PdfStringFormat { binary, litteral } | ||
70 | + | ||
71 | +class PdfString extends PdfDataType { | ||
72 | + const PdfString(this.value, [this.format = PdfStringFormat.litteral]); | ||
73 | + | ||
74 | + factory PdfString.fromString(String value) { | ||
75 | + try { | ||
76 | + return PdfString(latin1.encode(value), PdfStringFormat.litteral); | ||
77 | + } catch (e) { | ||
78 | + return PdfString( | ||
79 | + Uint8List.fromList(<int>[0xfe, 0xff] + encodeUtf16be(value)), | ||
80 | + PdfStringFormat.litteral, | ||
81 | + ); | ||
82 | + } | ||
83 | + } | ||
84 | + | ||
85 | + factory PdfString.fromDate(DateTime date) { | ||
86 | + final DateTime utcDate = date.toUtc(); | ||
87 | + final String year = utcDate.year.toString().padLeft(4, '0'); | ||
88 | + final String month = utcDate.month.toString().padLeft(2, '0'); | ||
89 | + final String day = utcDate.day.toString().padLeft(2, '0'); | ||
90 | + final String hour = utcDate.hour.toString().padLeft(2, '0'); | ||
91 | + final String minute = utcDate.minute.toString().padLeft(2, '0'); | ||
92 | + final String second = utcDate.second.toString().padLeft(2, '0'); | ||
93 | + return PdfString.fromString('D:$year$month$day$hour$minute${second}Z'); | ||
94 | + } | ||
95 | + | ||
96 | + final Uint8List value; | ||
97 | + | ||
98 | + final PdfStringFormat format; | ||
99 | + | ||
100 | + /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit | ||
101 | + /// [digit]. | ||
102 | + int _codeUnitForDigit(int digit) => | ||
103 | + digit < 10 ? digit + 0x30 : digit + 0x61 - 10; | ||
104 | + | ||
105 | + @override | ||
106 | + void output(PdfStream s) { | ||
107 | + switch (format) { | ||
108 | + case PdfStringFormat.binary: | ||
109 | + s.putByte(0x3c); | ||
110 | + for (int byte in value) { | ||
111 | + s.putByte(_codeUnitForDigit((byte & 0xF0) >> 4)); | ||
112 | + s.putByte(_codeUnitForDigit(byte & 0x0F)); | ||
113 | + } | ||
114 | + s.putByte(0x3e); | ||
115 | + | ||
116 | + break; | ||
117 | + case PdfStringFormat.litteral: | ||
118 | + s.putByte(40); | ||
119 | + s.putTextBytes(value); | ||
120 | + s.putByte(41); | ||
121 | + break; | ||
122 | + } | ||
123 | + } | ||
124 | +} | ||
125 | + | ||
126 | +class PdfSecString extends PdfString { | ||
127 | + const PdfSecString(this.object, Uint8List value, | ||
128 | + [PdfStringFormat format = PdfStringFormat.binary]) | ||
129 | + : super(value, format); | ||
130 | + | ||
131 | + factory PdfSecString.fromString(PdfObject object, String value) { | ||
132 | + try { | ||
133 | + return PdfSecString( | ||
134 | + object, latin1.encode(value), PdfStringFormat.litteral); | ||
135 | + } catch (e) { | ||
136 | + return PdfSecString( | ||
137 | + object, | ||
138 | + Uint8List.fromList(<int>[0xfe, 0xff] + encodeUtf16be(value)), | ||
139 | + PdfStringFormat.litteral, | ||
140 | + ); | ||
141 | + } | ||
142 | + } | ||
143 | + | ||
144 | + factory PdfSecString.fromDate(PdfObject object, DateTime date) { | ||
145 | + final DateTime utcDate = date.toUtc(); | ||
146 | + final String year = utcDate.year.toString().padLeft(4, '0'); | ||
147 | + final String month = utcDate.month.toString().padLeft(2, '0'); | ||
148 | + final String day = utcDate.day.toString().padLeft(2, '0'); | ||
149 | + final String hour = utcDate.hour.toString().padLeft(2, '0'); | ||
150 | + final String minute = utcDate.minute.toString().padLeft(2, '0'); | ||
151 | + final String second = utcDate.second.toString().padLeft(2, '0'); | ||
152 | + return PdfSecString.fromString( | ||
153 | + object, 'D:$year$month$day$hour$minute${second}Z'); | ||
154 | + } | ||
155 | + | ||
156 | + final PdfObject object; | ||
157 | + | ||
158 | + @override | ||
159 | + void output(PdfStream s) { | ||
160 | + if (object.pdfDocument.encryption == null) { | ||
161 | + return super.output(s); | ||
162 | + } | ||
163 | + | ||
164 | + final List<int> enc = object.pdfDocument.encryption.encrypt(value, object); | ||
165 | + switch (format) { | ||
166 | + case PdfStringFormat.binary: | ||
167 | + s.putByte(0x3c); | ||
168 | + for (int byte in enc) { | ||
169 | + s.putByte(_codeUnitForDigit((byte & 0xF0) >> 4)); | ||
170 | + s.putByte(_codeUnitForDigit(byte & 0x0F)); | ||
171 | + } | ||
172 | + s.putByte(0x3e); | ||
173 | + | ||
174 | + break; | ||
175 | + case PdfStringFormat.litteral: | ||
176 | + s.putByte(40); | ||
177 | + s.putTextBytes(enc); | ||
178 | + s.putByte(41); | ||
179 | + break; | ||
180 | + } | ||
181 | + } | ||
182 | +} | ||
183 | + | ||
184 | +class PdfName extends PdfDataType { | ||
185 | + const PdfName(this.value); | ||
186 | + | ||
187 | + final String value; | ||
188 | + | ||
189 | + @override | ||
190 | + void output(PdfStream s) { | ||
191 | + assert(value[0] == '/'); | ||
192 | + s.putString(value); | ||
193 | + } | ||
194 | +} | ||
195 | + | ||
196 | +class PdfNull extends PdfDataType { | ||
197 | + const PdfNull(); | ||
198 | + | ||
199 | + @override | ||
200 | + void output(PdfStream s) { | ||
201 | + s.putString('null'); | ||
202 | + } | ||
203 | +} | ||
204 | + | ||
205 | +class PdfIndirect extends PdfDataType { | ||
206 | + const PdfIndirect(this.ser, this.gen); | ||
207 | + | ||
208 | + final int ser; | ||
209 | + | ||
210 | + final int gen; | ||
211 | + | ||
212 | + @override | ||
213 | + void output(PdfStream s) { | ||
214 | + s.putString('$ser $gen R'); | ||
215 | + } | ||
216 | +} | ||
217 | + | ||
218 | +class PdfArray extends PdfDataType { | ||
219 | + PdfArray([Iterable<PdfDataType> values]) { | ||
220 | + if (values != null) { | ||
221 | + this.values.addAll(values); | ||
222 | + } | ||
223 | + } | ||
224 | + | ||
225 | + factory PdfArray.fromObjects(List<PdfObject> objects) { | ||
226 | + return PdfArray( | ||
227 | + objects.map<PdfIndirect>((PdfObject e) => e.ref()).toList()); | ||
228 | + } | ||
229 | + | ||
230 | + factory PdfArray.fromNum(List<num> list) { | ||
231 | + return PdfArray(list.map<PdfNum>((num e) => PdfNum(e)).toList()); | ||
232 | + } | ||
233 | + | ||
234 | + // factory PdfArray.fromStrings(List<String> list) { | ||
235 | + // return PdfArray( | ||
236 | + // list.map<PdfString>((String e) => PdfString.fromString(e)).toList()); | ||
237 | + // } | ||
238 | + | ||
239 | + final List<PdfDataType> values = <PdfDataType>[]; | ||
240 | + | ||
241 | + void add(PdfDataType v) { | ||
242 | + values.add(v); | ||
243 | + } | ||
244 | + | ||
245 | + @override | ||
246 | + void output(PdfStream s) { | ||
247 | + s.putString('['); | ||
248 | + if (values.isNotEmpty) { | ||
249 | + for (int n = 0; n < values.length - 1; n++) { | ||
250 | + final PdfDataType val = values[n]; | ||
251 | + val.output(s); | ||
252 | + s.putString(' '); | ||
253 | + } | ||
254 | + values.last.output(s); | ||
255 | + } | ||
256 | + s.putString(']'); | ||
257 | + } | ||
258 | +} | ||
259 | + | ||
260 | +class PdfDict extends PdfDataType { | ||
261 | + PdfDict([Map<String, PdfDataType> values]) { | ||
262 | + if (values != null) { | ||
263 | + this.values.addAll(values); | ||
264 | + } | ||
265 | + } | ||
266 | + | ||
267 | + factory PdfDict.fromObjectMap(Map<String, PdfObject> objects) { | ||
268 | + return PdfDict( | ||
269 | + objects.map<String, PdfIndirect>( | ||
270 | + (String key, PdfObject value) => | ||
271 | + MapEntry<String, PdfIndirect>(key, value.ref()), | ||
272 | + ), | ||
273 | + ); | ||
274 | + } | ||
275 | + | ||
276 | + final Map<String, PdfDataType> values = <String, PdfDataType>{}; | ||
277 | + | ||
278 | + bool get isNotEmpty => values.isNotEmpty; | ||
279 | + | ||
280 | + operator []=(String k, PdfDataType v) { | ||
281 | + values[k] = v; | ||
282 | + } | ||
283 | + | ||
284 | + @override | ||
285 | + void output(PdfStream s) { | ||
286 | + s.putString('<< '); | ||
287 | + values.forEach((String k, PdfDataType v) { | ||
288 | + s.putString('$k '); | ||
289 | + v.output(s); | ||
290 | + s.putString('\n'); | ||
291 | + }); | ||
292 | + s.putString('>>'); | ||
293 | + } | ||
294 | + | ||
295 | + bool containsKey(String key) { | ||
296 | + return values.containsKey(key); | ||
297 | + } | ||
298 | +} |
@@ -119,9 +119,9 @@ abstract class PdfFont extends PdfObject { | @@ -119,9 +119,9 @@ abstract class PdfFont extends PdfObject { | ||
119 | void _prepare() { | 119 | void _prepare() { |
120 | super._prepare(); | 120 | super._prepare(); |
121 | 121 | ||
122 | - params['/Subtype'] = PdfStream.string(subtype); | ||
123 | - params['/Name'] = PdfStream.string(name); | ||
124 | - params['/Encoding'] = PdfStream.string('/WinAnsiEncoding'); | 122 | + params['/Subtype'] = PdfName(subtype); |
123 | + params['/Name'] = PdfName(name); | ||
124 | + params['/Encoding'] = const PdfName('/WinAnsiEncoding'); | ||
125 | } | 125 | } |
126 | 126 | ||
127 | @Deprecated('Use `glyphMetrics` instead') | 127 | @Deprecated('Use `glyphMetrics` instead') |
@@ -166,9 +166,9 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management | @@ -166,9 +166,9 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management | ||
166 | PdfStream putText(String text) { | 166 | PdfStream putText(String text) { |
167 | try { | 167 | try { |
168 | return PdfStream() | 168 | return PdfStream() |
169 | - ..putBytes(latin1.encode('(')) | 169 | + ..putByte(40) |
170 | ..putTextBytes(latin1.encode(text)) | 170 | ..putTextBytes(latin1.encode(text)) |
171 | - ..putBytes(latin1.encode(')')); | 171 | + ..putByte(41); |
172 | } catch (e) { | 172 | } catch (e) { |
173 | assert(false, '''\n--------------------------------------------- | 173 | assert(false, '''\n--------------------------------------------- |
174 | Can not decode the string to Latin1. | 174 | Can not decode the string to Latin1. |
@@ -32,20 +32,19 @@ class PdfFontDescriptor extends PdfObject { | @@ -32,20 +32,19 @@ class PdfFontDescriptor extends PdfObject { | ||
32 | void _prepare() { | 32 | void _prepare() { |
33 | super._prepare(); | 33 | super._prepare(); |
34 | 34 | ||
35 | - params['/FontName'] = PdfStream.string('/' + ttfFont.fontName); | 35 | + params['/FontName'] = PdfName('/' + ttfFont.fontName); |
36 | params['/FontFile2'] = file.ref(); | 36 | params['/FontFile2'] = file.ref(); |
37 | - params['/Flags'] = PdfStream.intNum(ttfFont.font.unicode ? 4 : 32); | ||
38 | - params['/FontBBox'] = PdfStream() | ||
39 | - ..putIntArray(<int>[ | 37 | + params['/Flags'] = PdfNum(ttfFont.font.unicode ? 4 : 32); |
38 | + params['/FontBBox'] = PdfArray.fromNum(<int>[ | ||
40 | (ttfFont.font.xMin / ttfFont.font.unitsPerEm * 1000).toInt(), | 39 | (ttfFont.font.xMin / ttfFont.font.unitsPerEm * 1000).toInt(), |
41 | (ttfFont.font.yMin / ttfFont.font.unitsPerEm * 1000).toInt(), | 40 | (ttfFont.font.yMin / ttfFont.font.unitsPerEm * 1000).toInt(), |
42 | (ttfFont.font.xMax / ttfFont.font.unitsPerEm * 1000).toInt(), | 41 | (ttfFont.font.xMax / ttfFont.font.unitsPerEm * 1000).toInt(), |
43 | (ttfFont.font.yMax / ttfFont.font.unitsPerEm * 1000).toInt() | 42 | (ttfFont.font.yMax / ttfFont.font.unitsPerEm * 1000).toInt() |
44 | ]); | 43 | ]); |
45 | - params['/Ascent'] = PdfStream.intNum((ttfFont.ascent * 1000).toInt()); | ||
46 | - params['/Descent'] = PdfStream.intNum((ttfFont.descent * 1000).toInt()); | ||
47 | - params['/ItalicAngle'] = PdfStream.intNum(0); | ||
48 | - params['/CapHeight'] = PdfStream.intNum(10); | ||
49 | - params['/StemV'] = PdfStream.intNum(79); | 44 | + params['/Ascent'] = PdfNum((ttfFont.ascent * 1000).toInt()); |
45 | + params['/Descent'] = PdfNum((ttfFont.descent * 1000).toInt()); | ||
46 | + params['/ItalicAngle'] = const PdfNum(0); | ||
47 | + params['/CapHeight'] = const PdfNum(10); | ||
48 | + params['/StemV'] = const PdfNum(79); | ||
50 | } | 49 | } |
51 | } | 50 | } |
@@ -20,8 +20,8 @@ part of pdf; | @@ -20,8 +20,8 @@ part of pdf; | ||
20 | 20 | ||
21 | class PdfFormXObject extends PdfXObject { | 21 | class PdfFormXObject extends PdfXObject { |
22 | PdfFormXObject(PdfDocument pdfDocument) : super(pdfDocument, '/Form') { | 22 | PdfFormXObject(PdfDocument pdfDocument) : super(pdfDocument, '/Form') { |
23 | - params['/FormType'] = PdfStream.string('1'); | ||
24 | - params['/BBox'] = PdfStream.string('[0 0 1000 1000]'); | 23 | + params['/FormType'] = const PdfNum(1); |
24 | + params['/BBox'] = PdfArray.fromNum(const <int>[0, 0, 1000, 1000]); | ||
25 | } | 25 | } |
26 | 26 | ||
27 | /// The fonts associated with this page | 27 | /// The fonts associated with this page |
@@ -34,7 +34,7 @@ class PdfFormXObject extends PdfXObject { | @@ -34,7 +34,7 @@ class PdfFormXObject extends PdfXObject { | ||
34 | void setMatrix(Matrix4 t) { | 34 | void setMatrix(Matrix4 t) { |
35 | final Float64List s = t.storage; | 35 | final Float64List s = t.storage; |
36 | params['/Matrix'] = | 36 | params['/Matrix'] = |
37 | - PdfStream.string('[${s[0]} ${s[1]} ${s[4]} ${s[5]} ${s[12]} ${s[13]}]'); | 37 | + PdfArray.fromNum(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]); |
38 | } | 38 | } |
39 | 39 | ||
40 | @override | 40 | @override |
@@ -43,20 +43,20 @@ class PdfFormXObject extends PdfXObject { | @@ -43,20 +43,20 @@ class PdfFormXObject extends PdfXObject { | ||
43 | 43 | ||
44 | // Now the resources | 44 | // Now the resources |
45 | /// This holds any resources for this FormXObject | 45 | /// This holds any resources for this FormXObject |
46 | - final Map<String, PdfStream> resources = <String, PdfStream>{}; | 46 | + final PdfDict resources = PdfDict(); |
47 | 47 | ||
48 | // fonts | 48 | // fonts |
49 | if (fonts.isNotEmpty) { | 49 | if (fonts.isNotEmpty) { |
50 | - resources['/Font'] = PdfStream()..putObjectDictionary(fonts); | 50 | + resources['/Font'] = PdfDict.fromObjectMap(fonts); |
51 | } | 51 | } |
52 | 52 | ||
53 | // Now the XObjects | 53 | // Now the XObjects |
54 | if (xobjects.isNotEmpty) { | 54 | if (xobjects.isNotEmpty) { |
55 | - resources['/XObject'] = PdfStream()..putObjectDictionary(xobjects); | 55 | + resources['/XObject'] = PdfDict.fromObjectMap(xobjects); |
56 | } | 56 | } |
57 | 57 | ||
58 | if (resources.isNotEmpty) { | 58 | if (resources.isNotEmpty) { |
59 | - params['/Resources'] = PdfStream.dictionary(resources); | 59 | + params['/Resources'] = resources; |
60 | } | 60 | } |
61 | } | 61 | } |
62 | } | 62 | } |
@@ -27,15 +27,15 @@ class PdfGraphicState { | @@ -27,15 +27,15 @@ class PdfGraphicState { | ||
27 | final double opacity; | 27 | final double opacity; |
28 | 28 | ||
29 | @protected | 29 | @protected |
30 | - PdfStream _output() { | ||
31 | - final Map<String, PdfStream> params = <String, PdfStream>{}; | 30 | + PdfDict _output() { |
31 | + final PdfDict params = PdfDict(); | ||
32 | 32 | ||
33 | if (opacity != null) { | 33 | if (opacity != null) { |
34 | - params['/CA'] = PdfStream.num(opacity); | ||
35 | - params['/ca'] = PdfStream.num(opacity); | 34 | + params['/CA'] = PdfNum(opacity); |
35 | + params['/ca'] = PdfNum(opacity); | ||
36 | } | 36 | } |
37 | 37 | ||
38 | - return PdfStream.dictionary(params); | 38 | + return params; |
39 | } | 39 | } |
40 | 40 | ||
41 | @override | 41 | @override |
@@ -78,10 +78,10 @@ class PdfImage extends PdfXObject { | @@ -78,10 +78,10 @@ class PdfImage extends PdfXObject { | ||
78 | _height = height, | 78 | _height = height, |
79 | super(pdfDocument, '/Image', isBinary: true) { | 79 | super(pdfDocument, '/Image', isBinary: true) { |
80 | _name = '/Image$objser'; | 80 | _name = '/Image$objser'; |
81 | - params['/Width'] = PdfStream.string(width.toString()); | ||
82 | - params['/Height'] = PdfStream.string(height.toString()); | ||
83 | - params['/BitsPerComponent'] = PdfStream.intNum(8); | ||
84 | - params['/Name'] = PdfStream.string(_name); | 81 | + params['/Width'] = PdfNum(width); |
82 | + params['/Height'] = PdfNum(height); | ||
83 | + params['/BitsPerComponent'] = const PdfNum(8); | ||
84 | + params['/Name'] = PdfName(_name); | ||
85 | 85 | ||
86 | if (alphaChannel == false && alpha) { | 86 | if (alphaChannel == false && alpha) { |
87 | final PdfImage _sMask = PdfImage._( | 87 | final PdfImage _sMask = PdfImage._( |
@@ -95,17 +95,17 @@ class PdfImage extends PdfXObject { | @@ -95,17 +95,17 @@ class PdfImage extends PdfXObject { | ||
95 | jpeg: jpeg, | 95 | jpeg: jpeg, |
96 | orientation: orientation, | 96 | orientation: orientation, |
97 | ); | 97 | ); |
98 | - params['/SMask'] = PdfStream.string('${_sMask.objser} 0 R'); | 98 | + params['/SMask'] = PdfIndirect(_sMask.objser, 0); |
99 | } | 99 | } |
100 | 100 | ||
101 | if (isRGB) { | 101 | if (isRGB) { |
102 | - params['/ColorSpace'] = PdfStream.string('/DeviceRGB'); | 102 | + params['/ColorSpace'] = const PdfName('/DeviceRGB'); |
103 | } else { | 103 | } else { |
104 | - params['/ColorSpace'] = PdfStream.string('/DeviceGray'); | 104 | + params['/ColorSpace'] = const PdfName('/DeviceGray'); |
105 | } | 105 | } |
106 | 106 | ||
107 | if (jpeg) { | 107 | if (jpeg) { |
108 | - params['/Intent'] = PdfStream.string('/RelativeColorimetric'); | 108 | + params['/Intent'] = const PdfName('/RelativeColorimetric'); |
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
@@ -163,7 +163,7 @@ class PdfImage extends PdfXObject { | @@ -163,7 +163,7 @@ class PdfImage extends PdfXObject { | ||
163 | void _prepare() { | 163 | void _prepare() { |
164 | if (jpeg) { | 164 | if (jpeg) { |
165 | buf.putBytes(image); | 165 | buf.putBytes(image); |
166 | - params['/Filter'] = PdfStream.string('/DCTDecode'); | 166 | + params['/Filter'] = const PdfName('/DCTDecode'); |
167 | super._prepare(); | 167 | super._prepare(); |
168 | return; | 168 | return; |
169 | } | 169 | } |
@@ -27,28 +27,28 @@ class PdfInfo extends PdfObject { | @@ -27,28 +27,28 @@ class PdfInfo extends PdfObject { | ||
27 | this.producer}) | 27 | this.producer}) |
28 | : super(pdfDocument, null) { | 28 | : super(pdfDocument, null) { |
29 | if (author != null) { | 29 | if (author != null) { |
30 | - params['/Author'] = PdfStream()..putLiteral(author); | 30 | + params['/Author'] = PdfSecString.fromString(this, author); |
31 | } | 31 | } |
32 | if (creator != null) { | 32 | if (creator != null) { |
33 | - params['/Creator'] = PdfStream()..putLiteral(creator); | 33 | + params['/Creator'] = PdfSecString.fromString(this, creator); |
34 | } | 34 | } |
35 | if (title != null) { | 35 | if (title != null) { |
36 | - params['/Title'] = PdfStream()..putLiteral(title); | 36 | + params['/Title'] = PdfSecString.fromString(this, title); |
37 | } | 37 | } |
38 | if (subject != null) { | 38 | if (subject != null) { |
39 | - params['/Subject'] = PdfStream()..putLiteral(subject); | 39 | + params['/Subject'] = PdfSecString.fromString(this, subject); |
40 | } | 40 | } |
41 | if (keywords != null) { | 41 | if (keywords != null) { |
42 | - params['/Keywords'] = PdfStream()..putLiteral(keywords); | 42 | + params['/Keywords'] = PdfSecString.fromString(this, keywords); |
43 | } | 43 | } |
44 | if (producer != null) { | 44 | if (producer != null) { |
45 | - params['/Producer'] = PdfStream() | ||
46 | - ..putLiteral('$producer ($_libraryName)'); | 45 | + params['/Producer'] = |
46 | + PdfSecString.fromString(this, '$producer ($_libraryName)'); | ||
47 | } else { | 47 | } else { |
48 | - params['/Producer'] = PdfStream()..putLiteral(_libraryName); | 48 | + params['/Producer'] = PdfSecString.fromString(this, _libraryName); |
49 | } | 49 | } |
50 | 50 | ||
51 | - params['/CreationDate'] = PdfStream()..putDate(DateTime.now()); | 51 | + params['/CreationDate'] = PdfSecString.fromDate(this, DateTime.now()); |
52 | } | 52 | } |
53 | 53 | ||
54 | static const String _libraryName = 'https://github.com/DavBfr/dart_pdf'; | 54 | static const String _libraryName = 'https://github.com/DavBfr/dart_pdf'; |
@@ -20,7 +20,7 @@ class PdfNames extends PdfObject { | @@ -20,7 +20,7 @@ class PdfNames extends PdfObject { | ||
20 | /// This constructs a Pdf Name object | 20 | /// This constructs a Pdf Name object |
21 | PdfNames(PdfDocument pdfDocument) : super(pdfDocument); | 21 | PdfNames(PdfDocument pdfDocument) : super(pdfDocument); |
22 | 22 | ||
23 | - final List<PdfStream> _dests = <PdfStream>[]; | 23 | + final PdfArray _dests = PdfArray(); |
24 | 24 | ||
25 | void addDest( | 25 | void addDest( |
26 | String name, | 26 | String name, |
@@ -32,16 +32,14 @@ class PdfNames extends PdfObject { | @@ -32,16 +32,14 @@ class PdfNames extends PdfObject { | ||
32 | assert(page.pdfDocument == pdfDocument); | 32 | assert(page.pdfDocument == pdfDocument); |
33 | assert(name != null); | 33 | assert(name != null); |
34 | 34 | ||
35 | - _dests.add(PdfStream()..putText(name)); | ||
36 | - _dests.add(PdfStream() | ||
37 | - ..putDictionary(<String, PdfStream>{ | ||
38 | - '/D': PdfStream() | ||
39 | - ..putArray(<PdfStream>[ | 35 | + _dests.add(PdfSecString.fromString(this, name)); |
36 | + _dests.add(PdfDict(<String, PdfDataType>{ | ||
37 | + '/D': PdfArray(<PdfDataType>[ | ||
40 | page.ref(), | 38 | page.ref(), |
41 | - PdfStream.string('/XYZ'), | ||
42 | - if (posX == null) PdfStream.string('null') else PdfStream.num(posX), | ||
43 | - if (posY == null) PdfStream.string('null') else PdfStream.num(posY), | ||
44 | - if (posZ == null) PdfStream.string('null') else PdfStream.num(posZ), | 39 | + const PdfName('/XYZ'), |
40 | + if (posX == null) const PdfNull() else PdfNum(posX), | ||
41 | + if (posY == null) const PdfNull() else PdfNum(posY), | ||
42 | + if (posZ == null) const PdfNull() else PdfNum(posZ), | ||
45 | ]), | 43 | ]), |
46 | })); | 44 | })); |
47 | } | 45 | } |
@@ -50,9 +48,6 @@ class PdfNames extends PdfObject { | @@ -50,9 +48,6 @@ class PdfNames extends PdfObject { | ||
50 | void _prepare() { | 48 | void _prepare() { |
51 | super._prepare(); | 49 | super._prepare(); |
52 | 50 | ||
53 | - params['/Dests'] = PdfStream() | ||
54 | - ..putDictionary(<String, PdfStream>{ | ||
55 | - '/Names': PdfStream()..putArray(_dests), | ||
56 | - }); | 51 | + params['/Dests'] = PdfDict(<String, PdfDataType>{'/Names': _dests}); |
57 | } | 52 | } |
58 | } | 53 | } |
@@ -24,14 +24,14 @@ class PdfObject { | @@ -24,14 +24,14 @@ class PdfObject { | ||
24 | : assert(pdfDocument != null), | 24 | : assert(pdfDocument != null), |
25 | objser = pdfDocument._genSerial() { | 25 | objser = pdfDocument._genSerial() { |
26 | if (type != null) { | 26 | if (type != null) { |
27 | - params['/Type'] = PdfStream.string(type); | 27 | + params['/Type'] = PdfName(type); |
28 | } | 28 | } |
29 | 29 | ||
30 | pdfDocument.objects.add(this); | 30 | pdfDocument.objects.add(this); |
31 | } | 31 | } |
32 | 32 | ||
33 | /// This is the object parameters. | 33 | /// This is the object parameters. |
34 | - final Map<String, PdfStream> params = <String, PdfStream>{}; | 34 | + final PdfDict params = PdfDict(); |
35 | 35 | ||
36 | /// This is the unique serial number for this object. | 36 | /// This is the unique serial number for this object. |
37 | final int objser; | 37 | final int objser; |
@@ -72,7 +72,7 @@ class PdfObject { | @@ -72,7 +72,7 @@ class PdfObject { | ||
72 | 72 | ||
73 | void _writeContent(PdfStream os) { | 73 | void _writeContent(PdfStream os) { |
74 | if (params.isNotEmpty) { | 74 | if (params.isNotEmpty) { |
75 | - os.putDictionary(params); | 75 | + params.output(os); |
76 | os.putString('\n'); | 76 | os.putString('\n'); |
77 | } | 77 | } |
78 | } | 78 | } |
@@ -89,5 +89,5 @@ class PdfObject { | @@ -89,5 +89,5 @@ class PdfObject { | ||
89 | 89 | ||
90 | /// Returns the unique serial number in Pdf format | 90 | /// Returns the unique serial number in Pdf format |
91 | /// @return the serial number in Pdf format | 91 | /// @return the serial number in Pdf format |
92 | - PdfStream ref() => PdfStream.string('$objser $objgen R'); | 92 | + PdfIndirect ref() => PdfIndirect(objser, objgen); |
93 | } | 93 | } |
@@ -46,12 +46,12 @@ class PdfObjectStream extends PdfObject { | @@ -46,12 +46,12 @@ class PdfObjectStream extends PdfObject { | ||
46 | _data = buf.output(); | 46 | _data = buf.output(); |
47 | } else if (pdfDocument.deflate != null) { | 47 | } else if (pdfDocument.deflate != null) { |
48 | _data = pdfDocument.deflate(buf.output()); | 48 | _data = pdfDocument.deflate(buf.output()); |
49 | - params['/Filter'] = PdfStream.string('/FlateDecode'); | 49 | + params['/Filter'] = const PdfName('/FlateDecode'); |
50 | } else if (isBinary) { | 50 | } else if (isBinary) { |
51 | // This is a Ascii85 stream | 51 | // This is a Ascii85 stream |
52 | final Ascii85Encoder e = Ascii85Encoder(); | 52 | final Ascii85Encoder e = Ascii85Encoder(); |
53 | _data = e.convert(buf.output()); | 53 | _data = e.convert(buf.output()); |
54 | - params['/Filter'] = PdfStream.string('/ASCII85Decode'); | 54 | + params['/Filter'] = const PdfName('/ASCII85Decode'); |
55 | } else { | 55 | } else { |
56 | // This is a non-deflated stream | 56 | // This is a non-deflated stream |
57 | _data = buf.output(); | 57 | _data = buf.output(); |
@@ -59,7 +59,7 @@ class PdfObjectStream extends PdfObject { | @@ -59,7 +59,7 @@ class PdfObjectStream extends PdfObject { | ||
59 | if (pdfDocument.encryption != null) { | 59 | if (pdfDocument.encryption != null) { |
60 | _data = pdfDocument.encryption.encrypt(_data, this); | 60 | _data = pdfDocument.encryption.encrypt(_data, this); |
61 | } | 61 | } |
62 | - params['/Length'] = PdfStream.intNum(_data.length); | 62 | + params['/Length'] = PdfNum(_data.length); |
63 | } | 63 | } |
64 | 64 | ||
65 | @override | 65 | @override |
@@ -87,24 +87,27 @@ class PdfOutline extends PdfObject { | @@ -87,24 +87,27 @@ class PdfOutline extends PdfObject { | ||
87 | 87 | ||
88 | // These are for kids only | 88 | // These are for kids only |
89 | if (parent != null) { | 89 | if (parent != null) { |
90 | - params['/Title'] = PdfStream.string(title); | ||
91 | - final List<PdfStream> dests = <PdfStream>[]; | 90 | + params['/Title'] = PdfSecString.fromString(this, title); |
91 | + final PdfArray dests = PdfArray(); | ||
92 | dests.add(dest.ref()); | 92 | dests.add(dest.ref()); |
93 | 93 | ||
94 | if (destMode == PdfOutlineMode.fitpage) { | 94 | if (destMode == PdfOutlineMode.fitpage) { |
95 | - dests.add(PdfStream.string('/Fit')); | 95 | + dests.add(const PdfName('/Fit')); |
96 | } else { | 96 | } else { |
97 | - dests.add(PdfStream.string( | ||
98 | - '/FitR ${rect.left} ${rect.bottom} ${rect.right} ${rect.top}')); | 97 | + dests.add(const PdfName('/FitR')); |
98 | + dests.add(PdfNum(rect.left)); | ||
99 | + dests.add(PdfNum(rect.bottom)); | ||
100 | + dests.add(PdfNum(rect.right)); | ||
101 | + dests.add(PdfNum(rect.top)); | ||
99 | } | 102 | } |
100 | params['/Parent'] = parent.ref(); | 103 | params['/Parent'] = parent.ref(); |
101 | - params['/Dest'] = PdfStream.array(dests); | 104 | + params['/Dest'] = dests; |
102 | 105 | ||
103 | // were a descendent, so by default we are closed. Find out how many | 106 | // were a descendent, so by default we are closed. Find out how many |
104 | // entries are below us | 107 | // entries are below us |
105 | final int c = descendants(); | 108 | final int c = descendants(); |
106 | if (c > 0) { | 109 | if (c > 0) { |
107 | - params['/Count'] = PdfStream.intNum(-c); | 110 | + params['/Count'] = PdfNum(-c); |
108 | } | 111 | } |
109 | 112 | ||
110 | final int index = parent.getIndex(this); | 113 | final int index = parent.getIndex(this); |
@@ -120,7 +123,7 @@ class PdfOutline extends PdfObject { | @@ -120,7 +123,7 @@ class PdfOutline extends PdfObject { | ||
120 | } else { | 123 | } else { |
121 | // the number of outlines in this document | 124 | // the number of outlines in this document |
122 | // were the top level node, so all are open by default | 125 | // were the top level node, so all are open by default |
123 | - params['/Count'] = PdfStream.intNum(outlines.length); | 126 | + params['/Count'] = PdfNum(outlines.length); |
124 | } | 127 | } |
125 | 128 | ||
126 | // These only valid if we have children | 129 | // These only valid if we have children |
@@ -113,16 +113,17 @@ class PdfOutput { | @@ -113,16 +113,17 @@ class PdfOutput { | ||
113 | // now the trailer object | 113 | // now the trailer object |
114 | os.putString('trailer\n'); | 114 | os.putString('trailer\n'); |
115 | 115 | ||
116 | - final Map<String, PdfStream> params = <String, PdfStream>{}; | 116 | + final PdfDict params = PdfDict(); |
117 | 117 | ||
118 | // the number of entries (REQUIRED) | 118 | // the number of entries (REQUIRED) |
119 | - params['/Size'] = PdfStream.intNum(offsets.length + 1); | 119 | + params['/Size'] = PdfNum(offsets.length + 1); |
120 | 120 | ||
121 | // the /Root catalog indirect reference (REQUIRED) | 121 | // the /Root catalog indirect reference (REQUIRED) |
122 | if (rootID != null) { | 122 | if (rootID != null) { |
123 | params['/Root'] = rootID.ref(); | 123 | params['/Root'] = rootID.ref(); |
124 | - final PdfStream id = PdfStream.binary(rootID.pdfDocument.documentID); | ||
125 | - params['/ID'] = PdfStream.array(<PdfStream>[id, id]); | 124 | + final PdfString id = |
125 | + PdfString(rootID.pdfDocument.documentID, PdfStringFormat.binary); | ||
126 | + params['/ID'] = PdfArray(<PdfDataType>[id, id]); | ||
126 | } else { | 127 | } else { |
127 | throw Exception('Root object is not present in document'); | 128 | throw Exception('Root object is not present in document'); |
128 | } | 129 | } |
@@ -138,7 +139,7 @@ class PdfOutput { | @@ -138,7 +139,7 @@ class PdfOutput { | ||
138 | } | 139 | } |
139 | 140 | ||
140 | // end the trailer object | 141 | // end the trailer object |
141 | - os.putDictionary(params); | 142 | + params.output(os); |
142 | os.putString('\nstartxref\n$xref\n%%EOF\n'); | 143 | os.putString('\nstartxref\n$xref\n%%EOF\n'); |
143 | 144 | ||
144 | if (signatureID != null) { | 145 | if (signatureID != null) { |
@@ -94,8 +94,8 @@ class PdfPage extends PdfObject { | @@ -94,8 +94,8 @@ class PdfPage extends PdfObject { | ||
94 | params['/Parent'] = pdfDocument.pdfPageList.ref(); | 94 | params['/Parent'] = pdfDocument.pdfPageList.ref(); |
95 | 95 | ||
96 | // the /MediaBox for the page size | 96 | // the /MediaBox for the page size |
97 | - params['/MediaBox'] = PdfStream() | ||
98 | - ..putNumArray(<double>[0, 0, pageFormat.width, pageFormat.height]); | 97 | + params['/MediaBox'] = |
98 | + PdfArray.fromNum(<double>[0, 0, pageFormat.width, pageFormat.height]); | ||
99 | 99 | ||
100 | // Rotation (if not zero) | 100 | // Rotation (if not zero) |
101 | // if(rotate!=0) { | 101 | // if(rotate!=0) { |
@@ -109,39 +109,38 @@ class PdfPage extends PdfObject { | @@ -109,39 +109,38 @@ class PdfPage extends PdfObject { | ||
109 | if (contents.length == 1) { | 109 | if (contents.length == 1) { |
110 | params['/Contents'] = contents.first.ref(); | 110 | params['/Contents'] = contents.first.ref(); |
111 | } else { | 111 | } else { |
112 | - params['/Contents'] = PdfStream()..putObjectArray(contents); | 112 | + params['/Contents'] = PdfArray.fromObjects(contents); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | // Now the resources | 116 | // Now the resources |
117 | /// This holds any resources for this page | 117 | /// This holds any resources for this page |
118 | - final Map<String, PdfStream> resources = <String, PdfStream>{}; | 118 | + final PdfDict resources = PdfDict(); |
119 | 119 | ||
120 | // fonts | 120 | // fonts |
121 | if (fonts.isNotEmpty) { | 121 | if (fonts.isNotEmpty) { |
122 | - resources['/Font'] = PdfStream()..putObjectDictionary(fonts); | 122 | + resources['/Font'] = PdfDict.fromObjectMap(fonts); |
123 | } | 123 | } |
124 | 124 | ||
125 | // Now the XObjects | 125 | // Now the XObjects |
126 | if (xObjects.isNotEmpty) { | 126 | if (xObjects.isNotEmpty) { |
127 | - resources['/XObject'] = PdfStream()..putObjectDictionary(xObjects); | 127 | + resources['/XObject'] = PdfDict.fromObjectMap(xObjects); |
128 | } | 128 | } |
129 | 129 | ||
130 | if (pdfDocument.hasGraphicStates) { | 130 | if (pdfDocument.hasGraphicStates) { |
131 | // Declare Transparency Group settings | 131 | // Declare Transparency Group settings |
132 | - params['/Group'] = PdfStream() | ||
133 | - ..putDictionary(<String, PdfStream>{ | ||
134 | - '/Type': PdfStream.string('/Group'), | ||
135 | - '/S': PdfStream.string('/Transparency'), | ||
136 | - '/CS': PdfStream.string('/DeviceRGB'), | ||
137 | - '/I': PdfStream()..putBool(isolatedTransparency), | ||
138 | - '/K': PdfStream()..putBool(knockoutTransparency), | 132 | + params['/Group'] = PdfDict(<String, PdfDataType>{ |
133 | + '/Type': const PdfName('/Group'), | ||
134 | + '/S': const PdfName('/Transparency'), | ||
135 | + '/CS': const PdfName('/DeviceRGB'), | ||
136 | + '/I': PdfBool(isolatedTransparency), | ||
137 | + '/K': PdfBool(knockoutTransparency), | ||
139 | }); | 138 | }); |
140 | 139 | ||
141 | resources['/ExtGState'] = pdfDocument.graphicStates.ref(); | 140 | resources['/ExtGState'] = pdfDocument.graphicStates.ref(); |
142 | } | 141 | } |
143 | 142 | ||
144 | - params['/Resources'] = PdfStream.dictionary(resources); | 143 | + params['/Resources'] = resources; |
145 | 144 | ||
146 | // The thumbnail | 145 | // The thumbnail |
147 | if (thumbnail != null) { | 146 | if (thumbnail != null) { |
@@ -150,7 +149,7 @@ class PdfPage extends PdfObject { | @@ -150,7 +149,7 @@ class PdfPage extends PdfObject { | ||
150 | 149 | ||
151 | // The /Annots object | 150 | // The /Annots object |
152 | if (annotations.isNotEmpty) { | 151 | if (annotations.isNotEmpty) { |
153 | - params['/Annots'] = PdfStream()..putObjectArray(annotations); | 152 | + params['/Annots'] = PdfArray.fromObjects(annotations); |
154 | } | 153 | } |
155 | } | 154 | } |
156 | } | 155 | } |
@@ -32,7 +32,7 @@ class PdfPageList extends PdfObject { | @@ -32,7 +32,7 @@ class PdfPageList extends PdfObject { | ||
32 | void _prepare() { | 32 | void _prepare() { |
33 | super._prepare(); | 33 | super._prepare(); |
34 | 34 | ||
35 | - params['/Kids'] = PdfStream()..putObjectArray(pages); | ||
36 | - params['/Count'] = PdfStream.intNum(pages.length); | 35 | + params['/Kids'] = PdfArray.fromObjects(pages); |
36 | + params['/Count'] = PdfNum(pages.length); | ||
37 | } | 37 | } |
38 | } | 38 | } |
@@ -42,7 +42,7 @@ class PdfSignature extends PdfObject { | @@ -42,7 +42,7 @@ class PdfSignature extends PdfObject { | ||
42 | 42 | ||
43 | @override | 43 | @override |
44 | void _write(PdfStream os) { | 44 | void _write(PdfStream os) { |
45 | - crypto.preSign(params); | 45 | + crypto.preSign(this, params); |
46 | 46 | ||
47 | _offsetStart = os.offset + '$objser $objgen obj\n'.length; | 47 | _offsetStart = os.offset + '$objser $objgen obj\n'.length; |
48 | super._write(os); | 48 | super._write(os); |
@@ -53,13 +53,13 @@ class PdfSignature extends PdfObject { | @@ -53,13 +53,13 @@ class PdfSignature extends PdfObject { | ||
53 | assert(_offsetStart != null && _offsetEnd != null, | 53 | assert(_offsetStart != null && _offsetEnd != null, |
54 | 'Must reserve the object space before signing the document'); | 54 | 'Must reserve the object space before signing the document'); |
55 | 55 | ||
56 | - crypto.sign(os, params, _offsetStart, _offsetEnd); | 56 | + crypto.sign(this, os, params, _offsetStart, _offsetEnd); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
60 | abstract class PdfSignatureBase { | 60 | abstract class PdfSignatureBase { |
61 | - void preSign(Map<String, PdfStream> params); | 61 | + void preSign(PdfObject object, PdfDict params); |
62 | 62 | ||
63 | - void sign(PdfStream os, Map<String, PdfStream> params, int offsetStart, | 63 | + void sign(PdfObject object, PdfStream os, PdfDict params, int offsetStart, |
64 | int offsetEnd); | 64 | int offsetEnd); |
65 | } | 65 | } |
@@ -36,13 +36,8 @@ class PdfStream { | @@ -36,13 +36,8 @@ class PdfStream { | ||
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | - static PdfStream string(String s) => PdfStream()..putString(s); | ||
40 | - | ||
41 | - void putStringUtf16(String s) { | ||
42 | - for (int codeUnit in s.codeUnits) { | ||
43 | - _stream.add(codeUnit & 0xff); | ||
44 | - _stream.add((codeUnit >> 8) & 0xff); | ||
45 | - } | 39 | + void putByte(int s) { |
40 | + _stream.add(s); | ||
46 | } | 41 | } |
47 | 42 | ||
48 | void putBytes(List<int> s) { | 43 | void putBytes(List<int> s) { |
@@ -61,13 +56,6 @@ class PdfStream { | @@ -61,13 +56,6 @@ class PdfStream { | ||
61 | }).join(' ')); | 56 | }).join(' ')); |
62 | } | 57 | } |
63 | 58 | ||
64 | - void putIntList(List<int> d) { | ||
65 | - putString(d.map((int v) => v.toString()).join(' ')); | ||
66 | - } | ||
67 | - | ||
68 | - static PdfStream num(double d) => PdfStream()..putNum(d); | ||
69 | - static PdfStream intNum(int i) => PdfStream()..putString(i.toString()); | ||
70 | - | ||
71 | /// Escape special characters | 59 | /// Escape special characters |
72 | /// \ddd Character code ddd (octal) | 60 | /// \ddd Character code ddd (octal) |
73 | void putTextBytes(List<int> s) { | 61 | void putTextBytes(List<int> s) { |
@@ -111,105 +99,6 @@ class PdfStream { | @@ -111,105 +99,6 @@ class PdfStream { | ||
111 | } | 99 | } |
112 | } | 100 | } |
113 | 101 | ||
114 | - void putText(String s) { | ||
115 | - putBytes(latin1.encode('(')); | ||
116 | - putTextBytes(latin1.encode(s)); | ||
117 | - putBytes(latin1.encode(')')); | ||
118 | - } | ||
119 | - | ||
120 | - void putLiteral(String s) { | ||
121 | - putBytes(latin1.encode('(')); | ||
122 | - putBytes(<int>[0xfe, 0xff]); | ||
123 | - putTextBytes(encodeUtf16be(s)); | ||
124 | - putBytes(latin1.encode(')')); | ||
125 | - } | ||
126 | - | ||
127 | - void putBool(bool value) { | ||
128 | - putString(value ? 'true' : 'false'); | ||
129 | - } | ||
130 | - | ||
131 | - /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit | ||
132 | - /// [digit]. | ||
133 | - int _codeUnitForDigit(int digit) => | ||
134 | - digit < 10 ? digit + 0x30 : digit + 0x61 - 10; | ||
135 | - | ||
136 | - void putBinary(List<int> s) { | ||
137 | - _stream.add(0x3c); | ||
138 | - for (int byte in s) { | ||
139 | - _stream.add(_codeUnitForDigit((byte & 0xF0) >> 4)); | ||
140 | - _stream.add(_codeUnitForDigit(byte & 0x0F)); | ||
141 | - } | ||
142 | - _stream.add(0x3e); | ||
143 | - } | ||
144 | - | ||
145 | - static PdfStream binary(List<int> s) => PdfStream()..putBinary(s); | ||
146 | - | ||
147 | - void putArray(List<PdfStream> values) { | ||
148 | - putString('['); | ||
149 | - for (PdfStream val in values) { | ||
150 | - putStream(val); | ||
151 | - putString(' '); | ||
152 | - } | ||
153 | - putString(']'); | ||
154 | - } | ||
155 | - | ||
156 | - void putObjectArray(List<PdfObject> values) { | ||
157 | - putString('['); | ||
158 | - for (PdfObject val in values) { | ||
159 | - putStream(val.ref()); | ||
160 | - putString(' '); | ||
161 | - } | ||
162 | - putString(']'); | ||
163 | - } | ||
164 | - | ||
165 | - void putStringArray(List<String> values) { | ||
166 | - putString('[' + values.join(' ') + ']'); | ||
167 | - } | ||
168 | - | ||
169 | - void putDate(DateTime date) { | ||
170 | - final DateTime utcDate = date.toUtc(); | ||
171 | - final String year = utcDate.year.toString().padLeft(4, '0'); | ||
172 | - final String month = utcDate.month.toString().padLeft(2, '0'); | ||
173 | - final String day = utcDate.day.toString().padLeft(2, '0'); | ||
174 | - final String hour = utcDate.hour.toString().padLeft(2, '0'); | ||
175 | - final String minute = utcDate.minute.toString().padLeft(2, '0'); | ||
176 | - final String second = utcDate.second.toString().padLeft(2, '0'); | ||
177 | - putText('D:$year$month$day$hour$minute${second}Z'); | ||
178 | - } | ||
179 | - | ||
180 | - void putNumArray(List<double> values) { | ||
181 | - putString('['); | ||
182 | - putNumList(values); | ||
183 | - putString(']'); | ||
184 | - } | ||
185 | - | ||
186 | - void putIntArray(List<int> values) { | ||
187 | - putString('['); | ||
188 | - putIntList(values); | ||
189 | - putString(']'); | ||
190 | - } | ||
191 | - | ||
192 | - static PdfStream array(List<PdfStream> values) => | ||
193 | - PdfStream()..putArray(values); | ||
194 | - | ||
195 | - void putDictionary(Map<String, PdfStream> values) { | ||
196 | - putString('<< '); | ||
197 | - values.forEach((String k, PdfStream v) { | ||
198 | - putString('$k '); | ||
199 | - putStream(v); | ||
200 | - putString('\n'); | ||
201 | - }); | ||
202 | - putString('>>'); | ||
203 | - } | ||
204 | - | ||
205 | - static PdfStream dictionary(Map<String, PdfStream> values) => | ||
206 | - PdfStream()..putDictionary(values); | ||
207 | - | ||
208 | - void putObjectDictionary(Map<String, PdfObject> values) { | ||
209 | - putDictionary(values.map((String string, PdfObject object) => | ||
210 | - MapEntry<String, PdfStream>(string, object.ref()))); | ||
211 | - } | ||
212 | - | ||
213 | int get offset => _stream.length; | 102 | int get offset => _stream.length; |
214 | 103 | ||
215 | List<int> output() => _stream; | 104 | List<int> output() => _stream; |
@@ -26,7 +26,7 @@ class PdfTtfFont extends PdfFont { | @@ -26,7 +26,7 @@ class PdfTtfFont extends PdfFont { | ||
26 | file = PdfObjectStream(pdfDocument, isBinary: true); | 26 | file = PdfObjectStream(pdfDocument, isBinary: true); |
27 | unicodeCMap = PdfUnicodeCmap(pdfDocument, protect); | 27 | unicodeCMap = PdfUnicodeCmap(pdfDocument, protect); |
28 | descriptor = PdfFontDescriptor(this, file); | 28 | descriptor = PdfFontDescriptor(this, file); |
29 | - widthsObject = PdfArrayObject(pdfDocument, <String>[]); | 29 | + widthsObject = PdfArrayObject(pdfDocument, PdfArray()); |
30 | } | 30 | } |
31 | 31 | ||
32 | @override | 32 | @override |
@@ -62,67 +62,64 @@ class PdfTtfFont extends PdfFont { | @@ -62,67 +62,64 @@ class PdfTtfFont extends PdfFont { | ||
62 | return font.glyphInfoMap[g] ?? PdfFontMetrics.zero; | 62 | return font.glyphInfoMap[g] ?? PdfFontMetrics.zero; |
63 | } | 63 | } |
64 | 64 | ||
65 | - void _buildTrueType(Map<String, PdfStream> params) { | 65 | + void _buildTrueType(PdfDict params) { |
66 | int charMin; | 66 | int charMin; |
67 | int charMax; | 67 | int charMax; |
68 | 68 | ||
69 | file.buf.putBytes(font.bytes.buffer.asUint8List()); | 69 | file.buf.putBytes(font.bytes.buffer.asUint8List()); |
70 | - file.params['/Length1'] = PdfStream.intNum(font.bytes.lengthInBytes); | 70 | + file.params['/Length1'] = PdfNum(font.bytes.lengthInBytes); |
71 | 71 | ||
72 | - params['/BaseFont'] = PdfStream.string('/' + fontName); | 72 | + params['/BaseFont'] = PdfName('/' + fontName); |
73 | params['/FontDescriptor'] = descriptor.ref(); | 73 | params['/FontDescriptor'] = descriptor.ref(); |
74 | charMin = 32; | 74 | charMin = 32; |
75 | charMax = 255; | 75 | charMax = 255; |
76 | for (int i = charMin; i <= charMax; i++) { | 76 | for (int i = charMin; i <= charMax; i++) { |
77 | - widthsObject.values | ||
78 | - .add((glyphMetrics(i).advanceWidth * 1000.0).toInt().toString()); | 77 | + widthsObject.array |
78 | + .add(PdfNum((glyphMetrics(i).advanceWidth * 1000.0).toInt())); | ||
79 | } | 79 | } |
80 | - params['/FirstChar'] = PdfStream.intNum(charMin); | ||
81 | - params['/LastChar'] = PdfStream.intNum(charMax); | 80 | + params['/FirstChar'] = PdfNum(charMin); |
81 | + params['/LastChar'] = PdfNum(charMax); | ||
82 | params['/Widths'] = widthsObject.ref(); | 82 | params['/Widths'] = widthsObject.ref(); |
83 | } | 83 | } |
84 | 84 | ||
85 | - void _buildType0(Map<String, PdfStream> params) { | 85 | + void _buildType0(PdfDict params) { |
86 | int charMin; | 86 | int charMin; |
87 | int charMax; | 87 | int charMax; |
88 | 88 | ||
89 | final TtfWriter ttfWriter = TtfWriter(font); | 89 | final TtfWriter ttfWriter = TtfWriter(font); |
90 | final Uint8List data = ttfWriter.withChars(unicodeCMap.cmap); | 90 | final Uint8List data = ttfWriter.withChars(unicodeCMap.cmap); |
91 | file.buf.putBytes(data); | 91 | file.buf.putBytes(data); |
92 | - file.params['/Length1'] = PdfStream.intNum(data.length); | 92 | + file.params['/Length1'] = PdfNum(data.length); |
93 | 93 | ||
94 | - final PdfStream descendantFont = PdfStream.dictionary(<String, PdfStream>{ | ||
95 | - '/Type': PdfStream.string('/Font'), | ||
96 | - '/BaseFont': PdfStream.string('/' + fontName), | 94 | + final PdfDict descendantFont = PdfDict(<String, PdfDataType>{ |
95 | + '/Type': const PdfName('/Font'), | ||
96 | + '/BaseFont': PdfName('/' + fontName), | ||
97 | '/FontFile2': file.ref(), | 97 | '/FontFile2': file.ref(), |
98 | '/FontDescriptor': descriptor.ref(), | 98 | '/FontDescriptor': descriptor.ref(), |
99 | - '/W': PdfStream.array(<PdfStream>[ | ||
100 | - PdfStream.intNum(0), | 99 | + '/W': PdfArray(<PdfDataType>[ |
100 | + const PdfNum(0), | ||
101 | widthsObject.ref(), | 101 | widthsObject.ref(), |
102 | ]), | 102 | ]), |
103 | - '/CIDToGIDMap': PdfStream.string('/Identity'), | ||
104 | - '/DW': PdfStream.string('1000'), | ||
105 | - '/Subtype': PdfStream.string('/CIDFontType2'), | ||
106 | - '/CIDSystemInfo': PdfStream.dictionary(<String, PdfStream>{ | ||
107 | - '/Supplement': PdfStream.intNum(0), | ||
108 | - '/Registry': PdfStream()..putText('Adobe'), | ||
109 | - '/Ordering': PdfStream()..putText('Identity-H'), | 103 | + '/CIDToGIDMap': const PdfName('/Identity'), |
104 | + '/DW': const PdfNum(1000), | ||
105 | + '/Subtype': const PdfName('/CIDFontType2'), | ||
106 | + '/CIDSystemInfo': PdfDict(<String, PdfDataType>{ | ||
107 | + '/Supplement': const PdfNum(0), | ||
108 | + '/Registry': PdfSecString.fromString(this, 'Adobe'), | ||
109 | + '/Ordering': PdfSecString.fromString(this, 'Identity-H'), | ||
110 | }) | 110 | }) |
111 | }); | 111 | }); |
112 | 112 | ||
113 | - params['/BaseFont'] = PdfStream.string('/' + fontName); | ||
114 | - params['/Encoding'] = PdfStream.string('/Identity-H'); | ||
115 | - params['/DescendantFonts'] = PdfStream() | ||
116 | - ..putArray(<PdfStream>[descendantFont]); | 113 | + params['/BaseFont'] = PdfName('/' + fontName); |
114 | + params['/Encoding'] = const PdfName('/Identity-H'); | ||
115 | + params['/DescendantFonts'] = PdfArray(<PdfDataType>[descendantFont]); | ||
117 | params['/ToUnicode'] = unicodeCMap.ref(); | 116 | params['/ToUnicode'] = unicodeCMap.ref(); |
118 | 117 | ||
119 | charMin = 0; | 118 | charMin = 0; |
120 | charMax = unicodeCMap.cmap.length - 1; | 119 | charMax = unicodeCMap.cmap.length - 1; |
121 | for (int i = charMin; i <= charMax; i++) { | 120 | for (int i = charMin; i <= charMax; i++) { |
122 | - widthsObject.values.add( | ||
123 | - (glyphMetrics(unicodeCMap.cmap[i]).advanceWidth * 1000.0) | ||
124 | - .toInt() | ||
125 | - .toString()); | 121 | + widthsObject.array.add(PdfNum( |
122 | + (glyphMetrics(unicodeCMap.cmap[i]).advanceWidth * 1000.0).toInt())); | ||
126 | } | 123 | } |
127 | } | 124 | } |
128 | 125 | ||
@@ -145,7 +142,7 @@ class PdfTtfFont extends PdfFont { | @@ -145,7 +142,7 @@ class PdfTtfFont extends PdfFont { | ||
145 | 142 | ||
146 | final Runes runes = text.runes; | 143 | final Runes runes = text.runes; |
147 | final PdfStream stream = PdfStream(); | 144 | final PdfStream stream = PdfStream(); |
148 | - stream.putBytes(latin1.encode('<')); | 145 | + stream.putByte(0x3c); |
149 | for (int rune in runes) { | 146 | for (int rune in runes) { |
150 | int char = unicodeCMap.cmap.indexOf(rune); | 147 | int char = unicodeCMap.cmap.indexOf(rune); |
151 | if (char == -1) { | 148 | if (char == -1) { |
@@ -155,7 +152,7 @@ class PdfTtfFont extends PdfFont { | @@ -155,7 +152,7 @@ class PdfTtfFont extends PdfFont { | ||
155 | 152 | ||
156 | stream.putBytes(latin1.encode(char.toRadixString(16).padLeft(4, '0'))); | 153 | stream.putBytes(latin1.encode(char.toRadixString(16).padLeft(4, '0'))); |
157 | } | 154 | } |
158 | - stream.putBytes(latin1.encode('>')); | 155 | + stream.putByte(0x3e); |
159 | return stream; | 156 | return stream; |
160 | } | 157 | } |
161 | 158 |
@@ -44,7 +44,7 @@ class PdfType1Font extends PdfFont { | @@ -44,7 +44,7 @@ class PdfType1Font extends PdfFont { | ||
44 | void _prepare() { | 44 | void _prepare() { |
45 | super._prepare(); | 45 | super._prepare(); |
46 | 46 | ||
47 | - params['/BaseFont'] = PdfStream.string('/' + fontName); | 47 | + params['/BaseFont'] = PdfName('/' + fontName); |
48 | } | 48 | } |
49 | 49 | ||
50 | @override | 50 | @override |
@@ -19,6 +19,6 @@ part of pdf; | @@ -19,6 +19,6 @@ part of pdf; | ||
19 | class PdfXObject extends PdfObjectStream { | 19 | class PdfXObject extends PdfObjectStream { |
20 | PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false}) | 20 | PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false}) |
21 | : super(pdfDocument, type: '/XObject', isBinary: isBinary) { | 21 | : super(pdfDocument, type: '/XObject', isBinary: isBinary) { |
22 | - params['/Subtype'] = PdfStream.string(subtype); | 22 | + params['/Subtype'] = PdfName(subtype); |
23 | } | 23 | } |
24 | } | 24 | } |
@@ -20,6 +20,7 @@ import '../example/main.dart' as example; | @@ -20,6 +20,7 @@ import '../example/main.dart' as example; | ||
20 | import 'annotations_test.dart' as annotations; | 20 | import 'annotations_test.dart' as annotations; |
21 | import 'colors_test.dart' as colors; | 21 | import 'colors_test.dart' as colors; |
22 | import 'complex_test.dart' as complex; | 22 | import 'complex_test.dart' as complex; |
23 | +import 'data_types_test.dart' as data_types; | ||
23 | import 'isolate_test.dart' as isolate; | 24 | import 'isolate_test.dart' as isolate; |
24 | import 'jpeg_test.dart' as jpeg; | 25 | import 'jpeg_test.dart' as jpeg; |
25 | import 'metrics_test.dart' as metrics; | 26 | import 'metrics_test.dart' as metrics; |
@@ -47,6 +48,7 @@ void main() { | @@ -47,6 +48,7 @@ void main() { | ||
47 | annotations.main(); | 48 | annotations.main(); |
48 | colors.main(); | 49 | colors.main(); |
49 | complex.main(); | 50 | complex.main(); |
51 | + data_types.main(); | ||
50 | example.main(); | 52 | example.main(); |
51 | isolate.main(); | 53 | isolate.main(); |
52 | jpeg.main(); | 54 | jpeg.main(); |
pdf/test/data_types_test.dart
0 → 100644
1 | +/* | ||
2 | + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com> | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +// ignore_for_file: omit_local_variable_types | ||
18 | + | ||
19 | +import 'dart:typed_data'; | ||
20 | + | ||
21 | +import 'package:pdf/pdf.dart'; | ||
22 | +import 'package:test/test.dart'; | ||
23 | + | ||
24 | +void main() { | ||
25 | + test('PdfDataTypes Bool ', () { | ||
26 | + expect(const PdfBool(true).toString(), 'true'); | ||
27 | + expect(const PdfBool(false).toString(), 'false'); | ||
28 | + }); | ||
29 | + | ||
30 | + test('PdfDataTypes Num', () { | ||
31 | + expect(const PdfNum(0).toString(), '0'); | ||
32 | + expect(const PdfNum(.5).toString(), '0.50000'); | ||
33 | + expect(const PdfNum(50).toString(), '50'); | ||
34 | + expect(const PdfNum(50.1).toString(), '50.10000'); | ||
35 | + }); | ||
36 | + | ||
37 | + test('PdfDataTypes String', () { | ||
38 | + expect(PdfString.fromString('test').toString(), '(test)'); | ||
39 | + expect(PdfString.fromString('Zoé').toString(), '(Zoé)'); | ||
40 | + expect(PdfString.fromString('\r\n\t\b\f)()(\\').toString(), | ||
41 | + r'(\r\n\t\b\f\)\(\)\(\\)'); | ||
42 | + expect( | ||
43 | + PdfString.fromString('你好').toList(), | ||
44 | + <int>[40, 254, 255, 79, 96, 89, 125, 41], | ||
45 | + ); | ||
46 | + expect( | ||
47 | + PdfString.fromDate(DateTime.fromMillisecondsSinceEpoch(1583606302000)) | ||
48 | + .toString(), | ||
49 | + '(D:20200307183822Z)', | ||
50 | + ); | ||
51 | + expect( | ||
52 | + PdfString( | ||
53 | + Uint8List.fromList(const <int>[0, 1, 2, 3, 4, 5, 6]), | ||
54 | + PdfStringFormat.binary, | ||
55 | + ).toString(), | ||
56 | + '<00010203040506>', | ||
57 | + ); | ||
58 | + }); | ||
59 | + | ||
60 | + test('PdfDataTypes Name', () { | ||
61 | + expect(const PdfName('/Hello').toString(), '/Hello'); | ||
62 | + }); | ||
63 | + | ||
64 | + test('PdfDataTypes Null', () { | ||
65 | + expect(const PdfNull().toString(), 'null'); | ||
66 | + }); | ||
67 | + | ||
68 | + test('PdfDataTypes Indirect', () { | ||
69 | + expect(const PdfIndirect(30, 4).toString(), '30 4 R'); | ||
70 | + }); | ||
71 | + | ||
72 | + test('PdfDataTypes Array', () { | ||
73 | + expect(PdfArray(<PdfDataType>[]).toString(), '[]'); | ||
74 | + expect( | ||
75 | + PdfArray(<PdfDataType>[const PdfNum(1), const PdfNum(2)]).toString(), | ||
76 | + '[1 2]', | ||
77 | + ); | ||
78 | + }); | ||
79 | + | ||
80 | + test('PdfDataTypes Dict', () { | ||
81 | + expect(PdfDict(<String, PdfDataType>{}).toString(), '<< >>'); | ||
82 | + | ||
83 | + expect( | ||
84 | + PdfDict(<String, PdfDataType>{ | ||
85 | + '/Name': const PdfName('/Value'), | ||
86 | + '/Bool': const PdfBool(true), | ||
87 | + '/Num': const PdfNum(42), | ||
88 | + '/String': PdfString.fromString('hello'), | ||
89 | + '/Null': const PdfNull(), | ||
90 | + '/Indirect': const PdfIndirect(55, 0), | ||
91 | + '/Array': PdfArray(<PdfDataType>[]), | ||
92 | + '/Dict': PdfDict(<String, PdfDataType>{}), | ||
93 | + }).toString(), | ||
94 | + '<< /Name /Value\n/Bool true\n/Num 42\n/String (hello)\n/Null null\n/Indirect 55 0 R\n/Array []\n/Dict << >>\n>>', | ||
95 | + ); | ||
96 | + }); | ||
97 | +} |
-
Please register or login to post a comment