David PHAM-VAN

Optimize file size

@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 - Implement table row vertical alignment 6 - Implement table row vertical alignment
7 - Improve Internal data structure 7 - Improve Internal data structure
8 - Remove deprecated functions 8 - Remove deprecated functions
  9 +- Optimize file size
9 10
10 ## 1.5.0 11 ## 1.5.0
11 12
@@ -72,17 +72,26 @@ class PdfString extends PdfDataType { @@ -72,17 +72,26 @@ class PdfString extends PdfDataType {
72 const PdfString(this.value, [this.format = PdfStringFormat.litteral]); 72 const PdfString(this.value, [this.format = PdfStringFormat.litteral]);
73 73
74 factory PdfString.fromString(String value) { 74 factory PdfString.fromString(String value) {
  75 + return PdfString(_string(value), PdfStringFormat.litteral);
  76 + }
  77 +
  78 + factory PdfString.fromDate(DateTime date) {
  79 + return PdfString(_date(date));
  80 + }
  81 +
  82 + final Uint8List value;
  83 +
  84 + final PdfStringFormat format;
  85 +
  86 + static Uint8List _string(String value) {
75 try { 87 try {
76 - return PdfString(latin1.encode(value), PdfStringFormat.litteral); 88 + return latin1.encode(value);
77 } catch (e) { 89 } catch (e) {
78 - return PdfString(  
79 - Uint8List.fromList(<int>[0xfe, 0xff] + encodeUtf16be(value)),  
80 - PdfStringFormat.litteral,  
81 - ); 90 + return Uint8List.fromList(<int>[0xfe, 0xff] + encodeUtf16be(value));
82 } 91 }
83 } 92 }
84 93
85 - factory PdfString.fromDate(DateTime date) { 94 + static Uint8List _date(DateTime date) {
86 final DateTime utcDate = date.toUtc(); 95 final DateTime utcDate = date.toUtc();
87 final String year = utcDate.year.toString().padLeft(4, '0'); 96 final String year = utcDate.year.toString().padLeft(4, '0');
88 final String month = utcDate.month.toString().padLeft(2, '0'); 97 final String month = utcDate.month.toString().padLeft(2, '0');
@@ -90,20 +99,15 @@ class PdfString extends PdfDataType { @@ -90,20 +99,15 @@ class PdfString extends PdfDataType {
90 final String hour = utcDate.hour.toString().padLeft(2, '0'); 99 final String hour = utcDate.hour.toString().padLeft(2, '0');
91 final String minute = utcDate.minute.toString().padLeft(2, '0'); 100 final String minute = utcDate.minute.toString().padLeft(2, '0');
92 final String second = utcDate.second.toString().padLeft(2, '0'); 101 final String second = utcDate.second.toString().padLeft(2, '0');
93 - return PdfString.fromString('D:$year$month$day$hour$minute${second}Z'); 102 + return _string('D:$year$month$day$hour$minute${second}Z');
94 } 103 }
95 104
96 - final Uint8List value;  
97 -  
98 - final PdfStringFormat format;  
99 -  
100 /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit 105 /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit
101 /// [digit]. 106 /// [digit].
102 int _codeUnitForDigit(int digit) => 107 int _codeUnitForDigit(int digit) =>
103 digit < 10 ? digit + 0x30 : digit + 0x61 - 10; 108 digit < 10 ? digit + 0x30 : digit + 0x61 - 10;
104 109
105 - @override  
106 - void output(PdfStream s) { 110 + void _output(PdfStream s, Uint8List value) {
107 switch (format) { 111 switch (format) {
108 case PdfStringFormat.binary: 112 case PdfStringFormat.binary:
109 s.putByte(0x3c); 113 s.putByte(0x3c);
@@ -121,6 +125,11 @@ class PdfString extends PdfDataType { @@ -121,6 +125,11 @@ class PdfString extends PdfDataType {
121 break; 125 break;
122 } 126 }
123 } 127 }
  128 +
  129 + @override
  130 + void output(PdfStream s) {
  131 + _output(s, value);
  132 + }
124 } 133 }
125 134
126 class PdfSecString extends PdfString { 135 class PdfSecString extends PdfString {
@@ -129,28 +138,11 @@ class PdfSecString extends PdfString { @@ -129,28 +138,11 @@ class PdfSecString extends PdfString {
129 : super(value, format); 138 : super(value, format);
130 139
131 factory PdfSecString.fromString(PdfObject object, String value) { 140 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 - } 141 + return PdfSecString(object, PdfString._string(value));
142 } 142 }
143 143
144 factory PdfSecString.fromDate(PdfObject object, DateTime date) { 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'); 145 + return PdfSecString(object, PdfString._date(date));
154 } 146 }
155 147
156 final PdfObject object; 148 final PdfObject object;
@@ -162,22 +154,7 @@ class PdfSecString extends PdfString { @@ -162,22 +154,7 @@ class PdfSecString extends PdfString {
162 } 154 }
163 155
164 final List<int> enc = object.pdfDocument.encryption.encrypt(value, object); 156 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 - } 157 + _output(s, Uint8List.fromList(enc));
181 } 158 }
182 } 159 }
183 160
@@ -231,11 +208,6 @@ class PdfArray extends PdfDataType { @@ -231,11 +208,6 @@ class PdfArray extends PdfDataType {
231 return PdfArray(list.map<PdfNum>((num e) => PdfNum(e)).toList()); 208 return PdfArray(list.map<PdfNum>((num e) => PdfNum(e)).toList());
232 } 209 }
233 210
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>[]; 211 final List<PdfDataType> values = <PdfDataType>[];
240 212
241 void add(PdfDataType v) { 213 void add(PdfDataType v) {
@@ -246,12 +218,17 @@ class PdfArray extends PdfDataType { @@ -246,12 +218,17 @@ class PdfArray extends PdfDataType {
246 void output(PdfStream s) { 218 void output(PdfStream s) {
247 s.putString('['); 219 s.putString('[');
248 if (values.isNotEmpty) { 220 if (values.isNotEmpty) {
249 - for (int n = 0; n < values.length - 1; n++) { 221 + for (int n = 0; n < values.length; n++) {
250 final PdfDataType val = values[n]; 222 final PdfDataType val = values[n];
  223 + if (n > 0 &&
  224 + !(val is PdfName ||
  225 + val is PdfString ||
  226 + val is PdfArray ||
  227 + val is PdfDict)) {
  228 + s.putByte(0x20);
  229 + }
251 val.output(s); 230 val.output(s);
252 - s.putString(' ');  
253 } 231 }
254 - values.last.output(s);  
255 } 232 }
256 s.putString(']'); 233 s.putString(']');
257 } 234 }
@@ -283,13 +260,15 @@ class PdfDict extends PdfDataType { @@ -283,13 +260,15 @@ class PdfDict extends PdfDataType {
283 260
284 @override 261 @override
285 void output(PdfStream s) { 262 void output(PdfStream s) {
286 - s.putString('<< '); 263 + s.putBytes(const <int>[0x3c, 0x3c]);
287 values.forEach((String k, PdfDataType v) { 264 values.forEach((String k, PdfDataType v) {
288 - s.putString('$k '); 265 + s.putString(k);
  266 + if (v is PdfNum || v is PdfBool || v is PdfNull || v is PdfIndirect) {
  267 + s.putByte(0x20);
  268 + }
289 v.output(s); 269 v.output(s);
290 - s.putString('\n');  
291 }); 270 });
292 - s.putString('>>'); 271 + s.putBytes(const <int>[0x3e, 0x3e]);
293 } 272 }
294 273
295 bool containsKey(String key) { 274 bool containsKey(String key) {
@@ -163,9 +163,9 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management @@ -163,9 +163,9 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management
163 @override 163 @override
164 String toString() => 'Font($fontName)'; 164 String toString() => 'Font($fontName)';
165 165
166 - PdfStream putText(String text) { 166 + void putText(PdfStream stream, String text) {
167 try { 167 try {
168 - return PdfStream() 168 + stream
169 ..putByte(40) 169 ..putByte(40)
170 ..putTextBytes(latin1.encode(text)) 170 ..putTextBytes(latin1.encode(text))
171 ..putByte(41); 171 ..putByte(41);
@@ -280,7 +280,7 @@ class PdfGraphics { @@ -280,7 +280,7 @@ class PdfGraphics {
280 buf.putString('${mode.index} Tr '); 280 buf.putString('${mode.index} Tr ');
281 } 281 }
282 buf.putString('['); 282 buf.putString('[');
283 - buf.putStream(font.putText(s)); 283 + font.putText(buf, s);
284 buf.putString(']TJ ET\n'); 284 buf.putString(']TJ ET\n');
285 } 285 }
286 286
@@ -135,13 +135,13 @@ class PdfTtfFont extends PdfFont { @@ -135,13 +135,13 @@ class PdfTtfFont extends PdfFont {
135 } 135 }
136 136
137 @override 137 @override
138 - PdfStream putText(String text) { 138 + void putText(PdfStream stream, String text) {
139 if (!font.unicode) { 139 if (!font.unicode) {
140 - return super.putText(text); 140 + super.putText(stream, text);
141 } 141 }
142 142
143 final Runes runes = text.runes; 143 final Runes runes = text.runes;
144 - final PdfStream stream = PdfStream(); 144 +
145 stream.putByte(0x3c); 145 stream.putByte(0x3c);
146 for (int rune in runes) { 146 for (int rune in runes) {
147 int char = unicodeCMap.cmap.indexOf(rune); 147 int char = unicodeCMap.cmap.indexOf(rune);
@@ -153,7 +153,6 @@ class PdfTtfFont extends PdfFont { @@ -153,7 +153,6 @@ class PdfTtfFont extends PdfFont {
153 stream.putBytes(latin1.encode(char.toRadixString(16).padLeft(4, '0'))); 153 stream.putBytes(latin1.encode(char.toRadixString(16).padLeft(4, '0')));
154 } 154 }
155 stream.putByte(0x3e); 155 stream.putByte(0x3e);
156 - return stream;  
157 } 156 }
158 157
159 @override 158 @override
@@ -70,15 +70,28 @@ void main() { @@ -70,15 +70,28 @@ void main() {
70 }); 70 });
71 71
72 test('PdfDataTypes Array', () { 72 test('PdfDataTypes Array', () {
73 - expect(PdfArray(<PdfDataType>[]).toString(), '[]'); 73 + expect(PdfArray().toString(), '[]');
74 expect( 74 expect(
75 PdfArray(<PdfDataType>[const PdfNum(1), const PdfNum(2)]).toString(), 75 PdfArray(<PdfDataType>[const PdfNum(1), const PdfNum(2)]).toString(),
76 '[1 2]', 76 '[1 2]',
77 ); 77 );
  78 + expect(
  79 + PdfArray(<PdfDataType>[
  80 + const PdfName('/Name'),
  81 + const PdfName('/Other'),
  82 + const PdfBool(false),
  83 + const PdfNum(2.5),
  84 + const PdfNull(),
  85 + PdfString.fromString('helło'),
  86 + PdfArray(),
  87 + PdfDict(),
  88 + ]).toString(),
  89 + '[/Name/Other false 2.50000 null(þÿ\x00h\x00e\x00l\x01B\x00o)[]<<>>]',
  90 + );
78 }); 91 });
79 92
80 test('PdfDataTypes Dict', () { 93 test('PdfDataTypes Dict', () {
81 - expect(PdfDict(<String, PdfDataType>{}).toString(), '<< >>'); 94 + expect(PdfDict().toString(), '<<>>');
82 95
83 expect( 96 expect(
84 PdfDict(<String, PdfDataType>{ 97 PdfDict(<String, PdfDataType>{
@@ -91,7 +104,7 @@ void main() { @@ -91,7 +104,7 @@ void main() {
91 '/Array': PdfArray(<PdfDataType>[]), 104 '/Array': PdfArray(<PdfDataType>[]),
92 '/Dict': PdfDict(<String, PdfDataType>{}), 105 '/Dict': PdfDict(<String, PdfDataType>{}),
93 }).toString(), 106 }).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>>', 107 + '<</Name/Value/Bool true/Num 42/String(hello)/Null null/Indirect 55 0 R/Array[]/Dict<<>>>>',
95 ); 108 );
96 }); 109 });
97 } 110 }