Showing
3 changed files
with
149 additions
and
16 deletions
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | * Fix annotations | 5 | * Fix annotations |
6 | * Implement default fonts bounding box | 6 | * Implement default fonts bounding box |
7 | * Add Bézier Curve primitive | 7 | * Add Bézier Curve primitive |
8 | +* Implement drawShape | ||
8 | 9 | ||
9 | # 1.0.8 | 10 | # 1.0.8 |
10 | * Fix monospace TTF font loading | 11 | * Fix monospace TTF font loading |
@@ -206,26 +206,151 @@ class PdfGraphics { | @@ -206,26 +206,151 @@ class PdfGraphics { | ||
206 | buf.putString("$x1 $y1 $x2 $y2 $x3 $y3 c\n"); | 206 | buf.putString("$x1 $y1 $x2 $y2 $x3 $y3 c\n"); |
207 | } | 207 | } |
208 | 208 | ||
209 | - void drawShape(String d) { | ||
210 | - var sb = StringBuffer(); | ||
211 | - | ||
212 | - RegExp exp = RegExp(r"([MmZzLlHhVvCcSsQqTtAa])|(-[\.0-9]+)|([\.0-9]+)"); | ||
213 | - var matches = exp.allMatches(d); | ||
214 | - var action; | 209 | + /// https://github.com/deeplook/svglib/blob/master/svglib/svglib.py#L911 |
210 | + void drawShape(String d, {stroke = true}) { | ||
211 | + final sb = StringBuffer(); | ||
212 | + final exp = RegExp(r"([MmZzLlHhVvCcSsQqTtAaE])|(-[\.0-9]+)|([\.0-9]+)"); | ||
213 | + final matches = exp.allMatches(d + " E"); | ||
214 | + String action; | ||
215 | + String lastAction; | ||
216 | + List<double> points; | ||
217 | + PdfPoint lastControl = PdfPoint(0.0, 0.0); | ||
218 | + PdfPoint lastPoint = PdfPoint(0.0, 0.0); | ||
215 | for (var m in matches) { | 219 | for (var m in matches) { |
216 | var a = m.group(1); | 220 | var a = m.group(1); |
217 | var b = m.group(0); | 221 | var b = m.group(0); |
218 | - print("$a, $b"); | ||
219 | - if (a != null) { | ||
220 | - if (action != null) { | ||
221 | - sb.write("$action "); | 222 | + |
223 | + if (a == null) { | ||
224 | + points.add(double.parse(b)); | ||
225 | + continue; | ||
226 | + } | ||
227 | + | ||
228 | + if (action != null) { | ||
229 | + switch (action) { | ||
230 | + case 'm': // moveto relative | ||
231 | + lastPoint = | ||
232 | + PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
233 | + sb.write("${lastPoint.x} ${lastPoint.y} m "); | ||
234 | + break; | ||
235 | + case 'M': // moveto absolute | ||
236 | + lastPoint = PdfPoint(points[0], points[1]); | ||
237 | + sb.write("${lastPoint.x} ${lastPoint.y} m "); | ||
238 | + break; | ||
239 | + case 'l': // lineto relative | ||
240 | + lastPoint = | ||
241 | + PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
242 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
243 | + break; | ||
244 | + case 'L': // lineto absolute | ||
245 | + lastPoint = PdfPoint(points[0], points[1]); | ||
246 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
247 | + break; | ||
248 | + case 'H': // horizontal line absolute | ||
249 | + lastPoint = PdfPoint(points[0], lastPoint.y); | ||
250 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
251 | + break; | ||
252 | + case 'V': // vertical line absolute | ||
253 | + lastPoint = PdfPoint(lastPoint.x, points[0]); | ||
254 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
255 | + break; | ||
256 | + case 'h': // horizontal line relative | ||
257 | + lastPoint = PdfPoint(lastPoint.x + points[0], lastPoint.y); | ||
258 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
259 | + break; | ||
260 | + case 'v': // vertical line relative | ||
261 | + lastPoint = PdfPoint(lastPoint.x, lastPoint.y + points[0]); | ||
262 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
263 | + break; | ||
264 | + case 'C': // cubic bezier, absolute | ||
265 | + var len = 0; | ||
266 | + while ((len + 1) * 6 <= points.length) { | ||
267 | + sb.write( | ||
268 | + points.sublist(len * 6, (len + 1) * 6).join(" ") + " c "); | ||
269 | + len += 1; | ||
270 | + } | ||
271 | + lastPoint = | ||
272 | + PdfPoint(points[points.length - 2], points[points.length - 1]); | ||
273 | + lastControl = | ||
274 | + PdfPoint(points[points.length - 4], points[points.length - 3]); | ||
275 | + break; | ||
276 | + case 'S': // smooth cubic bézier, absolute | ||
277 | + while (points.length >= 4) { | ||
278 | + PdfPoint c1; | ||
279 | + if ('cCsS'.indexOf(lastAction) >= 0) { | ||
280 | + c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
281 | + lastPoint.y + (lastPoint.y - lastControl.y)); | ||
282 | + } else { | ||
283 | + c1 = lastPoint; | ||
284 | + } | ||
285 | + lastControl = PdfPoint(points[0], points[1]); | ||
286 | + lastPoint = PdfPoint(points[2], points[3]); | ||
287 | + sb.write( | ||
288 | + "${c1.x} ${c1.y} ${lastControl.x} ${lastControl.y} ${lastPoint.x} ${lastPoint.y} c "); | ||
289 | + points = points.sublist(4); | ||
290 | + lastAction = 'C'; | ||
291 | + } | ||
292 | + break; | ||
293 | + case 'c': // cubic bezier, relative | ||
294 | + var len = 0; | ||
295 | + while ((len + 1) * 6 <= points.length) { | ||
296 | + points[len + 0] += lastPoint.x; | ||
297 | + points[len + 1] += lastPoint.y; | ||
298 | + points[len + 2] += lastPoint.x; | ||
299 | + points[len + 3] += lastPoint.y; | ||
300 | + points[len + 4] += lastPoint.x; | ||
301 | + points[len + 5] += lastPoint.y; | ||
302 | + sb.write( | ||
303 | + points.sublist(len * 6, (len + 1) * 6).join(" ") + " c "); | ||
304 | + len += 1; | ||
305 | + } | ||
306 | + lastPoint = | ||
307 | + PdfPoint(points[points.length - 2], points[points.length - 1]); | ||
308 | + lastControl = | ||
309 | + PdfPoint(points[points.length - 4], points[points.length - 3]); | ||
310 | + break; | ||
311 | + case 's': // smooth cubic bézier, relative | ||
312 | + while (points.length >= 4) { | ||
313 | + PdfPoint c1; | ||
314 | + if ('cCsS'.indexOf(lastAction) >= 0) { | ||
315 | + c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
316 | + lastPoint.y + (lastPoint.y - lastControl.y)); | ||
317 | + } else { | ||
318 | + c1 = lastPoint; | ||
319 | + } | ||
320 | + lastControl = | ||
321 | + PdfPoint(points[0] + lastPoint.x, points[1] + lastPoint.y); | ||
322 | + lastPoint = | ||
323 | + PdfPoint(points[2] + lastPoint.x, points[3] + lastPoint.y); | ||
324 | + sb.write( | ||
325 | + "${c1.x} ${c1.y} ${lastControl.x} ${lastControl.y} ${lastPoint.x} ${lastPoint.y} c "); | ||
326 | + points = points.sublist(4); | ||
327 | + lastAction = 'c'; | ||
328 | + } | ||
329 | + break; | ||
330 | + // case 'Q': // quadratic bezier, absolute | ||
331 | + // break; | ||
332 | + // case 'T': // quadratic bezier, absolute | ||
333 | + // break; | ||
334 | + // case 'q': // quadratic bezier, relative | ||
335 | + // break; | ||
336 | + // case 't': // quadratic bezier, relative | ||
337 | + // break; | ||
338 | + // case 'A': // elliptical arc, absolute | ||
339 | + // break; | ||
340 | + // case 'a': // elliptical arc, relative | ||
341 | + // break; | ||
342 | + case 'Z': // close path | ||
343 | + case 'z': // close path | ||
344 | + if (stroke) sb.write("s "); | ||
345 | + break; | ||
346 | + default: | ||
347 | + print("Unknown path action: $action"); | ||
222 | } | 348 | } |
223 | - action = a; | ||
224 | - } else { | ||
225 | - sb.write("$b "); | ||
226 | } | 349 | } |
350 | + lastAction = action; | ||
351 | + action = a; | ||
352 | + points = List<double>(); | ||
227 | } | 353 | } |
228 | - print(sb); | ||
229 | buf.putString(sb.toString()); | 354 | buf.putString(sb.toString()); |
230 | } | 355 | } |
231 | 356 |
@@ -20,12 +20,19 @@ void main() { | @@ -20,12 +20,19 @@ void main() { | ||
20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); | 20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); |
21 | 21 | ||
22 | var g = page.getGraphics(); | 22 | var g = page.getGraphics(); |
23 | + | ||
23 | g.saveContext(); | 24 | g.saveContext(); |
24 | var tm = Matrix4.identity(); | 25 | var tm = Matrix4.identity(); |
25 | - tm.translate(100.0, 700.0); | 26 | + tm.translate(50.0, 290.0); |
27 | + tm.rotateZ(pi); | ||
26 | g.setTransform(tm); | 28 | g.setTransform(tm); |
27 | -// g.drawShape("M37 0H9C6.24 0 4 2.24 4 5v38c0 2.76 2.24 5 5 5h28c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM23 46c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm15-8H8V6h30v32z"); | 29 | + g.setColor(PdfColor(0.0, 0.0, 0.0)); |
30 | + g.drawShape( | ||
31 | + "M37 0H9C6.24 0 4 2.24 4 5v38c0 2.76 2.24 5 5 5h28c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM23 46c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm15-8H8V6h30v32z", | ||
32 | + stroke: false); | ||
33 | + g.fillPath(); | ||
28 | g.restoreContext(); | 34 | g.restoreContext(); |
35 | + | ||
29 | var font1 = g.defaultFont; | 36 | var font1 = g.defaultFont; |
30 | 37 | ||
31 | var font2 = PdfTtfFont( | 38 | var font2 = PdfTtfFont( |
-
Please register or login to post a comment