David PHAM-VAN

Improve PdfXrefTable output

@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 - Improve Documents conformity 15 - Improve Documents conformity
16 - Make PdfXref a PdfIndirect descendent 16 - Make PdfXref a PdfIndirect descendent
17 - Move Pdf generation settings to PdfSettings 17 - Move Pdf generation settings to PdfSettings
  18 +- Improve PdfXrefTable output
18 19
19 ## 3.9.0 20 ## 3.9.0
20 21
@@ -99,9 +99,6 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -99,9 +99,6 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
99 /// List of objects to write 99 /// List of objects to write
100 final objects = <PdfObjectBase>{}; 100 final objects = <PdfObjectBase>{};
101 101
102 - /// Contains the offset of each objects  
103 - final _offsets = <PdfXref>[];  
104 -  
105 /// Writes a block of references to the Pdf file 102 /// Writes a block of references to the Pdf file
106 void _writeBlock(PdfStream s, int firstId, List<PdfXref> block) { 103 void _writeBlock(PdfStream s, int firstId, List<PdfXref> block) {
107 s.putString('$firstId ${block.length}\n'); 104 s.putString('$firstId ${block.length}\n');
@@ -137,21 +134,34 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -137,21 +134,34 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
137 return true; 134 return true;
138 }()); 135 }());
139 136
  137 + final xrefList = <PdfXref>[];
140 for (final ob in objects) { 138 for (final ob in objects) {
141 final offset = ob.output(s); 139 final offset = ob.output(s);
142 - _offsets.add(PdfXref(ob.objser, offset, gen: ob.objgen)); 140 + xrefList.add(PdfXref(ob.objser, offset, gen: ob.objgen));
143 } 141 }
144 142
  143 + assert(() {
  144 + if (o.settings.verbose) {
  145 + s.putComment('');
  146 + s.putComment('-' * 78);
  147 + s.putComment('$runtimeType ${o.settings.version.name}');
  148 + for (final x in xrefList) {
  149 + s.putComment(' $x');
  150 + }
  151 + }
  152 + return true;
  153 + }());
  154 +
145 final int xrefOffset; 155 final int xrefOffset;
146 156
147 params['/Root'] = o.ref(); 157 params['/Root'] = o.ref();
148 158
149 switch (o.settings.version) { 159 switch (o.settings.version) {
150 case PdfVersion.pdf_1_4: 160 case PdfVersion.pdf_1_4:
151 - xrefOffset = outputLegacy(o, s); 161 + xrefOffset = _outputLegacy(o, s, xrefList);
152 break; 162 break;
153 case PdfVersion.pdf_1_5: 163 case PdfVersion.pdf_1_5:
154 - xrefOffset = outputCompressed(o, s); 164 + xrefOffset = _outputCompressed(o, s, xrefList);
155 break; 165 break;
156 } 166 }
157 167
@@ -159,7 +169,6 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -159,7 +169,6 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
159 if (o.settings.verbose) { 169 if (o.settings.verbose) {
160 s.putComment(''); 170 s.putComment('');
161 s.putComment('-' * 78); 171 s.putComment('-' * 78);
162 - s.putComment('$runtimeType');  
163 } 172 }
164 return true; 173 return true;
165 }()); 174 }());
@@ -180,28 +189,10 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -180,28 +189,10 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
180 }()); 189 }());
181 } 190 }
182 191
183 - @override  
184 - String toString() {  
185 - final s = StringBuffer();  
186 - for (final x in _offsets) {  
187 - s.writeln(' $x');  
188 - }  
189 - return s.toString();  
190 - }  
191 -  
192 - int outputLegacy(PdfObjectBase o, PdfStream s) { 192 + int _outputLegacy(PdfObjectBase o, PdfStream s, List<PdfXref> xrefList) {
193 // Now scan through the offsets list. They should be in sequence. 193 // Now scan through the offsets list. They should be in sequence.
194 - _offsets.sort((a, b) => a.ser.compareTo(b.ser));  
195 - final size = _offsets.last.ser + 1;  
196 -  
197 - assert(() {  
198 - if (o.settings.verbose) {  
199 - s.putComment('');  
200 - s.putComment('-' * 78);  
201 - s.putComment('$runtimeType ${o.settings.version.name}\n$this');  
202 - }  
203 - return true;  
204 - }()); 194 + xrefList.sort((a, b) => a.ser.compareTo(b.ser));
  195 + final size = xrefList.last.ser + 1;
205 196
206 var firstId = 0; // First id in block 197 var firstId = 0; // First id in block
207 var lastId = 0; // The last id used 198 var lastId = 0; // The last id used
@@ -218,7 +209,7 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -218,7 +209,7 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
218 final objOffset = s.offset; 209 final objOffset = s.offset;
219 s.putString('xref\n'); 210 s.putString('xref\n');
220 211
221 - for (final x in _offsets) { 212 + for (final x in xrefList) {
222 // check to see if block is in range 213 // check to see if block is in range
223 if (x.ser != (lastId + 1)) { 214 if (x.ser != (lastId + 1)) {
224 // no, so write this block, and reset 215 // no, so write this block, and reset
@@ -251,16 +242,16 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -251,16 +242,16 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
251 } 242 }
252 243
253 /// Output a compressed cross-reference table 244 /// Output a compressed cross-reference table
254 - int outputCompressed(PdfObjectBase o, PdfStream s) { 245 + int _outputCompressed(PdfObjectBase o, PdfStream s, List<PdfXref> xrefList) {
255 final offset = s.offset; 246 final offset = s.offset;
256 247
257 // Sort all references 248 // Sort all references
258 - _offsets.sort((a, b) => a.ser.compareTo(b.ser)); 249 + xrefList.sort((a, b) => a.ser.compareTo(b.ser));
259 250
260 // Write this object too 251 // Write this object too
261 - final id = _offsets.last.ser + 1; 252 + final id = xrefList.last.ser + 1;
262 final size = id + 1; 253 final size = id + 1;
263 - _offsets.add(PdfXref(id, offset)); 254 + xrefList.add(PdfXref(id, offset));
264 255
265 params['/Type'] = const PdfName('/XRef'); 256 params['/Type'] = const PdfName('/XRef');
266 params['/Size'] = PdfNum(size); 257 params['/Size'] = PdfNum(size);
@@ -272,7 +263,7 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -272,7 +263,7 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
272 // We need block 0 to exist 263 // We need block 0 to exist
273 blocks.add(firstId); 264 blocks.add(firstId);
274 265
275 - for (final x in _offsets) { 266 + for (final x in xrefList) {
276 // check to see if block is in range 267 // check to see if block is in range
277 if (x.ser != (lastId + 1)) { 268 if (x.ser != (lastId + 1)) {
278 // no, so store this block, and reset 269 // no, so store this block, and reset
@@ -293,25 +284,15 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic { @@ -293,25 +284,15 @@ class PdfXrefTable extends PdfDataType with PdfDiagnostic {
293 params['/W'] = PdfArray.fromNum(w); 284 params['/W'] = PdfArray.fromNum(w);
294 final wl = w.reduce((a, b) => a + b); 285 final wl = w.reduce((a, b) => a + b);
295 286
296 - final binOffsets = ByteData((_offsets.length + 1) * wl); 287 + final binOffsets = ByteData((xrefList.length + 1) * wl);
297 var ofs = 0; 288 var ofs = 0;
298 // Write offset zero, all zeros 289 // Write offset zero, all zeros
299 ofs += wl; 290 ofs += wl;
300 291
301 - for (final x in _offsets) { 292 + for (final x in xrefList) {
302 ofs = x._compressedRef(binOffsets, ofs, w); 293 ofs = x._compressedRef(binOffsets, ofs, w);
303 } 294 }
304 295
305 - // Write the object  
306 - assert(() {  
307 - if (o.settings.verbose) {  
308 - s.putComment('');  
309 - s.putComment('-' * 78);  
310 - s.putComment('$runtimeType ${o.settings.version.name}\n$this');  
311 - }  
312 - return true;  
313 - }());  
314 -  
315 final objOffset = s.offset; 296 final objOffset = s.offset;
316 297
317 PdfObjectBase( 298 PdfObjectBase(