David PHAM-VAN

Remove num functions from stream object

@@ -24,7 +24,7 @@ abstract class PdfDataType { @@ -24,7 +24,7 @@ abstract class PdfDataType {
24 24
25 void output(PdfStream s); 25 void output(PdfStream s);
26 26
27 - PdfStream toStream() { 27 + PdfStream _toStream() {
28 final PdfStream s = PdfStream(); 28 final PdfStream s = PdfStream();
29 output(s); 29 output(s);
30 return s; 30 return s;
@@ -32,11 +32,12 @@ abstract class PdfDataType { @@ -32,11 +32,12 @@ abstract class PdfDataType {
32 32
33 @override 33 @override
34 String toString() { 34 String toString() {
35 - return String.fromCharCodes(toStream().output()); 35 + return String.fromCharCodes(_toStream().output());
36 } 36 }
37 37
  38 + @visibleForTesting
38 Uint8List toList() { 39 Uint8List toList() {
39 - return toStream().output(); 40 + return _toStream().output();
40 } 41 }
41 } 42 }
42 43
@@ -52,7 +53,13 @@ class PdfBool extends PdfDataType { @@ -52,7 +53,13 @@ class PdfBool extends PdfDataType {
52 } 53 }
53 54
54 class PdfNum extends PdfDataType { 55 class PdfNum extends PdfDataType {
55 - const PdfNum(this.value); 56 + const PdfNum(this.value)
  57 + : assert(value != null),
  58 + assert(value != double.infinity),
  59 + assert(value != double.nan),
  60 + assert(value != double.negativeInfinity);
  61 +
  62 + static const int precision = 5;
56 63
57 final num value; 64 final num value;
58 65
@@ -61,7 +68,23 @@ class PdfNum extends PdfDataType { @@ -61,7 +68,23 @@ class PdfNum extends PdfDataType {
61 if (value is int) { 68 if (value is int) {
62 s.putString(value.toInt().toString()); 69 s.putString(value.toInt().toString());
63 } else { 70 } else {
64 - s.putNum(value); 71 + s.putString(value.toStringAsFixed(precision));
  72 + }
  73 + }
  74 +}
  75 +
  76 +class PdfNumList extends PdfDataType {
  77 + PdfNumList(this.values) : assert(values != null);
  78 +
  79 + final List<num> values;
  80 +
  81 + @override
  82 + void output(PdfStream s) {
  83 + for (int n = 0; n < values.length; n++) {
  84 + if (n > 0) {
  85 + s.putByte(0x20);
  86 + }
  87 + PdfNum(values[n]).output(s);
65 } 88 }
66 } 89 }
67 } 90 }
@@ -102,6 +125,49 @@ class PdfString extends PdfDataType { @@ -102,6 +125,49 @@ class PdfString extends PdfDataType {
102 return _string('D:$year$month$day$hour$minute${second}Z'); 125 return _string('D:$year$month$day$hour$minute${second}Z');
103 } 126 }
104 127
  128 + /// Escape special characters
  129 + /// \ddd Character code ddd (octal)
  130 + void _putTextBytes(PdfStream s, List<int> b) {
  131 + for (int c in b) {
  132 + switch (c) {
  133 + case 0x0a: // \n Line feed (LF)
  134 + s.putByte(0x5c);
  135 + s.putByte(0x6e);
  136 + break;
  137 + case 0x0d: // \r Carriage return (CR)
  138 + s.putByte(0x5c);
  139 + s.putByte(0x72);
  140 + break;
  141 + case 0x09: // \t Horizontal tab (HT)
  142 + s.putByte(0x5c);
  143 + s.putByte(0x74);
  144 + break;
  145 + case 0x08: // \b Backspace (BS)
  146 + s.putByte(0x5c);
  147 + s.putByte(0x62);
  148 + break;
  149 + case 0x0c: // \f Form feed (FF)
  150 + s.putByte(0x5c);
  151 + s.putByte(0x66);
  152 + break;
  153 + case 0x28: // \( Left parenthesis
  154 + s.putByte(0x5c);
  155 + s.putByte(0x28);
  156 + break;
  157 + case 0x29: // \) Right parenthesis
  158 + s.putByte(0x5c);
  159 + s.putByte(0x29);
  160 + break;
  161 + case 0x5c: // \\ Backslash
  162 + s.putByte(0x5c);
  163 + s.putByte(0x5c);
  164 + break;
  165 + default:
  166 + s.putByte(c);
  167 + }
  168 + }
  169 + }
  170 +
105 /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit 171 /// Returns the ASCII/Unicode code unit corresponding to the hexadecimal digit
106 /// [digit]. 172 /// [digit].
107 int _codeUnitForDigit(int digit) => 173 int _codeUnitForDigit(int digit) =>
@@ -116,11 +182,10 @@ class PdfString extends PdfDataType { @@ -116,11 +182,10 @@ class PdfString extends PdfDataType {
116 s.putByte(_codeUnitForDigit(byte & 0x0F)); 182 s.putByte(_codeUnitForDigit(byte & 0x0F));
117 } 183 }
118 s.putByte(0x3e); 184 s.putByte(0x3e);
119 -  
120 break; 185 break;
121 case PdfStringFormat.litteral: 186 case PdfStringFormat.litteral:
122 s.putByte(40); 187 s.putByte(40);
123 - s.putTextBytes(value); 188 + _putTextBytes(s, value);
124 s.putByte(41); 189 s.putByte(41);
125 break; 190 break;
126 } 191 }
@@ -172,10 +172,7 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management @@ -172,10 +172,7 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management
172 172
173 void putText(PdfStream stream, String text) { 173 void putText(PdfStream stream, String text) {
174 try { 174 try {
175 - stream  
176 - ..putByte(40)  
177 - ..putTextBytes(latin1.encode(text))  
178 - ..putByte(41); 175 + PdfString(latin1.encode(text), PdfStringFormat.litteral).output(stream);
179 } catch (_) { 176 } catch (_) {
180 assert(() { 177 assert(() {
181 print(_cannotDecodeMessage); 178 print(_cannotDecodeMessage);
@@ -138,28 +138,28 @@ class PdfGraphics { @@ -138,28 +138,28 @@ class PdfGraphics {
138 buf.putString('q '); 138 buf.putString('q ');
139 switch (img.orientation) { 139 switch (img.orientation) {
140 case PdfImageOrientation.topLeft: 140 case PdfImageOrientation.topLeft:
141 - buf.putNumList(<double>[w, 0, 0, h, x, y]); 141 + PdfNumList(<double>[w, 0, 0, h, x, y]).output(buf);
142 break; 142 break;
143 case PdfImageOrientation.topRight: 143 case PdfImageOrientation.topRight:
144 - buf.putNumList(<double>[-w, 0, 0, h, w + x, y]); 144 + PdfNumList(<double>[-w, 0, 0, h, w + x, y]).output(buf);
145 break; 145 break;
146 case PdfImageOrientation.bottomRight: 146 case PdfImageOrientation.bottomRight:
147 - buf.putNumList(<double>[-w, 0, 0, -h, w + x, h + y]); 147 + PdfNumList(<double>[-w, 0, 0, -h, w + x, h + y]).output(buf);
148 break; 148 break;
149 case PdfImageOrientation.bottomLeft: 149 case PdfImageOrientation.bottomLeft:
150 - buf.putNumList(<double>[w, 0, 0, -h, x, h + y]); 150 + PdfNumList(<double>[w, 0, 0, -h, x, h + y]).output(buf);
151 break; 151 break;
152 case PdfImageOrientation.leftTop: 152 case PdfImageOrientation.leftTop:
153 - buf.putNumList(<double>[0, -h, -w, 0, w + x, h + y]); 153 + PdfNumList(<double>[0, -h, -w, 0, w + x, h + y]).output(buf);
154 break; 154 break;
155 case PdfImageOrientation.rightTop: 155 case PdfImageOrientation.rightTop:
156 - buf.putNumList(<double>[0, -h, w, 0, x, h + y]); 156 + PdfNumList(<double>[0, -h, w, 0, x, h + y]).output(buf);
157 break; 157 break;
158 case PdfImageOrientation.rightBottom: 158 case PdfImageOrientation.rightBottom:
159 - buf.putNumList(<double>[0, h, w, 0, x, y]); 159 + PdfNumList(<double>[0, h, w, 0, x, y]).output(buf);
160 break; 160 break;
161 case PdfImageOrientation.leftBottom: 161 case PdfImageOrientation.leftBottom:
162 - buf.putNumList(<double>[0, h, -w, 0, w + x, y]); 162 + PdfNumList(<double>[0, h, -w, 0, w + x, y]).output(buf);
163 break; 163 break;
164 } 164 }
165 165
@@ -200,7 +200,7 @@ class PdfGraphics { @@ -200,7 +200,7 @@ class PdfGraphics {
200 double w, 200 double w,
201 double h, 201 double h,
202 ) { 202 ) {
203 - buf.putNumList(<double>[x, y, w, h]); 203 + PdfNumList(<double>[x, y, w, h]).output(buf);
204 buf.putString(' re\n'); 204 buf.putString(' re\n');
205 } 205 }
206 206
@@ -247,24 +247,24 @@ class PdfGraphics { @@ -247,24 +247,24 @@ class PdfGraphics {
247 } 247 }
248 248
249 buf.putString('BT '); 249 buf.putString('BT ');
250 - buf.putNumList(<double>[x, y]); 250 + PdfNumList(<double>[x, y]).output(buf);
251 buf.putString(' Td ${font.name} '); 251 buf.putString(' Td ${font.name} ');
252 - buf.putNum(size); 252 + PdfNum(size).output(buf);
253 buf.putString(' Tf '); 253 buf.putString(' Tf ');
254 if (charSpace != 0) { 254 if (charSpace != 0) {
255 - buf.putNum(charSpace); 255 + PdfNum(charSpace).output(buf);
256 buf.putString(' Tc '); 256 buf.putString(' Tc ');
257 } 257 }
258 if (wordSpace != 0) { 258 if (wordSpace != 0) {
259 - buf.putNum(wordSpace); 259 + PdfNum(wordSpace).output(buf);
260 buf.putString(' Tw '); 260 buf.putString(' Tw ');
261 } 261 }
262 if (scale != 1) { 262 if (scale != 1) {
263 - buf.putNum(scale * 100); 263 + PdfNum(scale * 100).output(buf);
264 buf.putString(' Tz '); 264 buf.putString(' Tz ');
265 } 265 }
266 if (rise != 0) { 266 if (rise != 0) {
267 - buf.putNum(rise); 267 + PdfNum(rise).output(buf);
268 buf.putString(' Ts '); 268 buf.putString(' Ts ');
269 } 269 }
270 if (mode != PdfTextRenderingMode.fill) { 270 if (mode != PdfTextRenderingMode.fill) {
@@ -288,11 +288,11 @@ class PdfGraphics { @@ -288,11 +288,11 @@ class PdfGraphics {
288 /// @param c Color to use 288 /// @param c Color to use
289 void setFillColor(PdfColor color) { 289 void setFillColor(PdfColor color) {
290 if (color is PdfColorCmyk) { 290 if (color is PdfColorCmyk) {
291 - buf.putNumList(  
292 - <double>[color.cyan, color.magenta, color.yellow, color.black]); 291 + PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black])
  292 + .output(buf);
293 buf.putString(' k\n'); 293 buf.putString(' k\n');
294 } else { 294 } else {
295 - buf.putNumList(<double>[color.red, color.green, color.blue]); 295 + PdfNumList(<double>[color.red, color.green, color.blue]).output(buf);
296 buf.putString(' rg\n'); 296 buf.putString(' rg\n');
297 } 297 }
298 } 298 }
@@ -302,11 +302,11 @@ class PdfGraphics { @@ -302,11 +302,11 @@ class PdfGraphics {
302 /// @param c Color to use 302 /// @param c Color to use
303 void setStrokeColor(PdfColor color) { 303 void setStrokeColor(PdfColor color) {
304 if (color is PdfColorCmyk) { 304 if (color is PdfColorCmyk) {
305 - buf.putNumList(  
306 - <double>[color.cyan, color.magenta, color.yellow, color.black]); 305 + PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black])
  306 + .output(buf);
307 buf.putString(' K\n'); 307 buf.putString(' K\n');
308 } else { 308 } else {
309 - buf.putNumList(<double>[color.red, color.green, color.blue]); 309 + PdfNumList(<double>[color.red, color.green, color.blue]).output(buf);
310 buf.putString(' RG\n'); 310 buf.putString(' RG\n');
311 } 311 }
312 } 312 }
@@ -320,7 +320,7 @@ class PdfGraphics { @@ -320,7 +320,7 @@ class PdfGraphics {
320 /// Set the transformation Matrix 320 /// Set the transformation Matrix
321 void setTransform(Matrix4 t) { 321 void setTransform(Matrix4 t) {
322 final Float64List s = t.storage; 322 final Float64List s = t.storage;
323 - buf.putNumList(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]); 323 + PdfNumList(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]).output(buf);
324 buf.putString(' cm\n'); 324 buf.putString(' cm\n');
325 _context.ctm.multiply(t); 325 _context.ctm.multiply(t);
326 } 326 }
@@ -335,7 +335,7 @@ class PdfGraphics { @@ -335,7 +335,7 @@ class PdfGraphics {
335 /// @param x coordinate 335 /// @param x coordinate
336 /// @param y coordinate 336 /// @param y coordinate
337 void lineTo(double x, double y) { 337 void lineTo(double x, double y) {
338 - buf.putNumList(<double>[x, y]); 338 + PdfNumList(<double>[x, y]).output(buf);
339 buf.putString(' l\n'); 339 buf.putString(' l\n');
340 } 340 }
341 341
@@ -344,7 +344,7 @@ class PdfGraphics { @@ -344,7 +344,7 @@ class PdfGraphics {
344 /// @param x coordinate 344 /// @param x coordinate
345 /// @param y coordinate 345 /// @param y coordinate
346 void moveTo(double x, double y) { 346 void moveTo(double x, double y) {
347 - buf.putNumList(<double>[x, y]); 347 + PdfNumList(<double>[x, y]).output(buf);
348 buf.putString(' m\n'); 348 buf.putString(' m\n');
349 } 349 }
350 350
@@ -360,7 +360,7 @@ class PdfGraphics { @@ -360,7 +360,7 @@ class PdfGraphics {
360 /// @param y3 end point 360 /// @param y3 end point
361 void curveTo( 361 void curveTo(
362 double x1, double y1, double x2, double y2, double x3, double y3) { 362 double x1, double y1, double x2, double y2, double x3, double y3) {
363 - buf.putNumList(<double>[x1, y1, x2, y2, x3, y3]); 363 + PdfNumList(<double>[x1, y1, x2, y2, x3, y3]).output(buf);
364 buf.putString(' c\n'); 364 buf.putString(' c\n');
365 } 365 }
366 366
@@ -685,12 +685,12 @@ class PdfGraphics { @@ -685,12 +685,12 @@ class PdfGraphics {
685 } 685 }
686 686
687 void setLineWidth(double width) { 687 void setLineWidth(double width) {
688 - buf.putNum(width); 688 + PdfNum(width).output(buf);
689 buf.putString(' w\n'); 689 buf.putString(' w\n');
690 } 690 }
691 691
692 void setMiterLimit(double limit) { 692 void setMiterLimit(double limit) {
693 - buf.putNum(limit); 693 + PdfNum(limit).output(buf);
694 buf.putString(' M\n'); 694 buf.putString(' M\n');
695 } 695 }
696 } 696 }
@@ -19,8 +19,6 @@ @@ -19,8 +19,6 @@
19 part of pdf; 19 part of pdf;
20 20
21 class PdfStream { 21 class PdfStream {
22 - static const int precision = 5;  
23 -  
24 static const int _grow = 65536; 22 static const int _grow = 65536;
25 23
26 Uint8List _stream = Uint8List(_grow); 24 Uint8List _stream = Uint8List(_grow);
@@ -62,67 +60,14 @@ class PdfStream { @@ -62,67 +60,14 @@ class PdfStream {
62 Uint8List output() => _stream.sublist(0, _offset); 60 Uint8List output() => _stream.sublist(0, _offset);
63 61
64 void putString(String s) { 62 void putString(String s) {
65 - for (int codeUnit in s.codeUnits) {  
66 - if (codeUnit <= 0x7f) {  
67 - putByte(codeUnit);  
68 - } else {  
69 - putByte(0x20);  
70 - }  
71 - }  
72 - }  
73 -  
74 - void putNum(double d) {  
75 - assert(d != double.infinity);  
76 - putString(d.toStringAsFixed(precision));  
77 - }  
78 -  
79 - void putNumList(List<double> d) {  
80 - putString(d.map((double v) {  
81 - assert(v != double.infinity);  
82 - return v.toStringAsFixed(precision);  
83 - }).join(' '));  
84 - }  
85 -  
86 - /// Escape special characters  
87 - /// \ddd Character code ddd (octal)  
88 - void putTextBytes(List<int> s) {  
89 - for (int c in s) {  
90 - switch (c) {  
91 - case 0x0a: // \n Line feed (LF)  
92 - putByte(0x5c);  
93 - putByte(0x6e);  
94 - break;  
95 - case 0x0d: // \r Carriage return (CR)  
96 - putByte(0x5c);  
97 - putByte(0x72);  
98 - break;  
99 - case 0x09: // \t Horizontal tab (HT)  
100 - putByte(0x5c);  
101 - putByte(0x74);  
102 - break;  
103 - case 0x08: // \b Backspace (BS)  
104 - putByte(0x5c);  
105 - putByte(0x62);  
106 - break;  
107 - case 0x0c: // \f Form feed (FF)  
108 - putByte(0x5c);  
109 - putByte(0x66);  
110 - break;  
111 - case 0x28: // \( Left parenthesis  
112 - putByte(0x5c);  
113 - putByte(0x28);  
114 - break;  
115 - case 0x29: // \) Right parenthesis  
116 - putByte(0x5c);  
117 - putByte(0x29);  
118 - break;  
119 - case 0x5c: // \\ Backslash  
120 - putByte(0x5c);  
121 - putByte(0x5c);  
122 - break;  
123 - default:  
124 - putByte(c); 63 + assert(() {
  64 + for (final int codeUnit in s.codeUnits) {
  65 + if (codeUnit > 0x7f) {
  66 + return false;
125 } 67 }
126 } 68 }
  69 + return true;
  70 + }());
  71 + putBytes(s.codeUnits);
127 } 72 }
128 } 73 }