Showing
4 changed files
with
35 additions
and
166 deletions
@@ -24,6 +24,7 @@ import 'dart:typed_data'; | @@ -24,6 +24,7 @@ import 'dart:typed_data'; | ||
24 | import 'package:crypto/crypto.dart'; | 24 | import 'package:crypto/crypto.dart'; |
25 | import 'package:image/image.dart' as im; | 25 | import 'package:image/image.dart' as im; |
26 | import 'package:meta/meta.dart'; | 26 | import 'package:meta/meta.dart'; |
27 | +import 'package:path_parsing/path_parsing.dart'; | ||
27 | import 'package:utf/utf.dart'; | 28 | import 'package:utf/utf.dart'; |
28 | import 'package:vector_math/vector_math_64.dart'; | 29 | import 'package:vector_math/vector_math_64.dart'; |
29 | 30 |
@@ -514,173 +514,9 @@ class PdfGraphics { | @@ -514,173 +514,9 @@ class PdfGraphics { | ||
514 | } | 514 | } |
515 | } | 515 | } |
516 | 516 | ||
517 | - /// https://github.com/deeplook/svglib/blob/master/svglib/svglib.py#L911 | ||
518 | void drawShape(String d, {bool stroke = true}) { | 517 | void drawShape(String d, {bool stroke = true}) { |
519 | - final RegExp exp = | ||
520 | - RegExp(r'([MmZzLlHhVvCcSsQqTtAaE])|(-[\.0-9]+)|([\.0-9]+)'); | ||
521 | - final Iterable<Match> matches = exp.allMatches(d + ' E'); | ||
522 | - String action; | ||
523 | - String lastAction; | ||
524 | - List<double> points; | ||
525 | - PdfPoint lastControl = const PdfPoint(0, 0); | ||
526 | - PdfPoint lastPoint = const PdfPoint(0, 0); | ||
527 | - for (Match m in matches) { | ||
528 | - final String a = m.group(1); | ||
529 | - final String b = m.group(0); | ||
530 | - | ||
531 | - if (a == null) { | ||
532 | - points.add(double.parse(b)); | ||
533 | - continue; | ||
534 | - } | ||
535 | - | ||
536 | - if (action != null) { | ||
537 | - switch (action) { | ||
538 | - case 'm': // moveto relative | ||
539 | - lastPoint = | ||
540 | - PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
541 | - moveTo(lastPoint.x, lastPoint.y); | ||
542 | - break; | ||
543 | - case 'M': // moveto absolute | ||
544 | - lastPoint = PdfPoint(points[0], points[1]); | ||
545 | - moveTo(lastPoint.x, lastPoint.y); | ||
546 | - break; | ||
547 | - case 'l': // lineto relative | ||
548 | - lastPoint = | ||
549 | - PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
550 | - lineTo(lastPoint.x, lastPoint.y); | ||
551 | - break; | ||
552 | - case 'L': // lineto absolute | ||
553 | - lastPoint = PdfPoint(points[0], points[1]); | ||
554 | - lineTo(lastPoint.x, lastPoint.y); | ||
555 | - break; | ||
556 | - case 'H': // horizontal line absolute | ||
557 | - lastPoint = PdfPoint(points[0], lastPoint.y); | ||
558 | - lineTo(lastPoint.x, lastPoint.y); | ||
559 | - break; | ||
560 | - case 'V': // vertical line absolute | ||
561 | - lastPoint = PdfPoint(lastPoint.x, points[0]); | ||
562 | - lineTo(lastPoint.x, lastPoint.y); | ||
563 | - break; | ||
564 | - case 'h': // horizontal line relative | ||
565 | - lastPoint = PdfPoint(lastPoint.x + points[0], lastPoint.y); | ||
566 | - lineTo(lastPoint.x, lastPoint.y); | ||
567 | - break; | ||
568 | - case 'v': // vertical line relative | ||
569 | - lastPoint = PdfPoint(lastPoint.x, lastPoint.y + points[0]); | ||
570 | - lineTo(lastPoint.x, lastPoint.y); | ||
571 | - break; | ||
572 | - case 'C': // cubic bezier, absolute | ||
573 | - int len = 0; | ||
574 | - while (len < points.length) { | ||
575 | - curveTo(points[len + 0], points[len + 1], points[len + 2], | ||
576 | - points[len + 3], points[len + 4], points[len + 5]); | ||
577 | - len += 6; | ||
578 | - } | ||
579 | - lastPoint = | ||
580 | - PdfPoint(points[points.length - 2], points[points.length - 1]); | ||
581 | - lastControl = | ||
582 | - PdfPoint(points[points.length - 4], points[points.length - 3]); | ||
583 | - break; | ||
584 | - case 'S': // smooth cubic bézier, absolute | ||
585 | - while (points.length >= 4) { | ||
586 | - PdfPoint c1; | ||
587 | - if ('cCsS'.contains(lastAction)) { | ||
588 | - c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
589 | - lastPoint.y + (lastPoint.y - lastControl.y)); | ||
590 | - } else { | ||
591 | - c1 = lastPoint; | ||
592 | - } | ||
593 | - lastControl = PdfPoint(points[0], points[1]); | ||
594 | - lastPoint = PdfPoint(points[2], points[3]); | ||
595 | - curveTo(c1.x, c1.y, lastControl.x, lastControl.y, lastPoint.x, | ||
596 | - lastPoint.y); | ||
597 | - points = points.sublist(4); | ||
598 | - lastAction = 'C'; | ||
599 | - } | ||
600 | - break; | ||
601 | - case 'c': // cubic bezier, relative | ||
602 | - int len = 0; | ||
603 | - while (len < points.length) { | ||
604 | - points[len + 0] += lastPoint.x; | ||
605 | - points[len + 1] += lastPoint.y; | ||
606 | - points[len + 2] += lastPoint.x; | ||
607 | - points[len + 3] += lastPoint.y; | ||
608 | - points[len + 4] += lastPoint.x; | ||
609 | - points[len + 5] += lastPoint.y; | ||
610 | - curveTo(points[len + 0], points[len + 1], points[len + 2], | ||
611 | - points[len + 3], points[len + 4], points[len + 5]); | ||
612 | - lastPoint = PdfPoint(points[len + 4], points[len + 5]); | ||
613 | - lastControl = PdfPoint(points[len + 2], points[len + 3]); | ||
614 | - len += 6; | ||
615 | - } | ||
616 | - break; | ||
617 | - case 's': // smooth cubic bézier, relative | ||
618 | - while (points.length >= 4) { | ||
619 | - PdfPoint c1; | ||
620 | - if ('cCsS'.contains(lastAction)) { | ||
621 | - c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
622 | - lastPoint.y + (lastPoint.y - lastControl.y)); | ||
623 | - } else { | ||
624 | - c1 = lastPoint; | ||
625 | - } | ||
626 | - lastControl = | ||
627 | - PdfPoint(points[0] + lastPoint.x, points[1] + lastPoint.y); | ||
628 | - lastPoint = | ||
629 | - PdfPoint(points[2] + lastPoint.x, points[3] + lastPoint.y); | ||
630 | - curveTo(c1.x, c1.y, lastControl.x, lastControl.y, lastPoint.x, | ||
631 | - lastPoint.y); | ||
632 | - points = points.sublist(4); | ||
633 | - lastAction = 'c'; | ||
634 | - } | ||
635 | - break; | ||
636 | - // case 'Q': // quadratic bezier, absolute | ||
637 | - // break; | ||
638 | - // case 'T': // quadratic bezier, absolute | ||
639 | - // break; | ||
640 | - // case 'q': // quadratic bezier, relative | ||
641 | - // break; | ||
642 | - // case 't': // quadratic bezier, relative | ||
643 | - // break; | ||
644 | - case 'A': // elliptical arc, absolute | ||
645 | - int len = 0; | ||
646 | - while (len < points.length) { | ||
647 | - bezierArc(lastPoint.x, lastPoint.y, points[len + 0], | ||
648 | - points[len + 1], points[len + 5], points[len + 6], | ||
649 | - phi: points[len + 2] * math.pi / 180.0, | ||
650 | - large: points[len + 3] != 0.0, | ||
651 | - sweep: points[len + 4] != 0.0); | ||
652 | - lastPoint = PdfPoint(points[len + 5], points[len + 6]); | ||
653 | - len += 7; | ||
654 | - } | ||
655 | - break; | ||
656 | - case 'a': // elliptical arc, relative | ||
657 | - int len = 0; | ||
658 | - while (len < points.length) { | ||
659 | - points[len + 5] += lastPoint.x; | ||
660 | - points[len + 6] += lastPoint.y; | ||
661 | - bezierArc(lastPoint.x, lastPoint.y, points[len + 0], | ||
662 | - points[len + 1], points[len + 5], points[len + 6], | ||
663 | - phi: points[len + 2] * math.pi / 180.0, | ||
664 | - large: points[len + 3] != 0.0, | ||
665 | - sweep: points[len + 4] != 0.0); | ||
666 | - lastPoint = PdfPoint(points[len + 5], points[len + 6]); | ||
667 | - len += 7; | ||
668 | - } | ||
669 | - break; | ||
670 | - case 'Z': // close path | ||
671 | - case 'z': // close path | ||
672 | - if (stroke) { | ||
673 | - closePath(); | ||
674 | - } | ||
675 | - break; | ||
676 | - default: | ||
677 | - print('Unknown path action: $action'); | ||
678 | - } | ||
679 | - } | ||
680 | - lastAction = action; | ||
681 | - action = a; | ||
682 | - points = <double>[]; | ||
683 | - } | 518 | + final proxy = _PathProxy(this, stroke); |
519 | + writeSvgPathDataToPath(d, proxy); | ||
684 | } | 520 | } |
685 | 521 | ||
686 | void setLineCap(PdfLineCap cap) { | 522 | void setLineCap(PdfLineCap cap) { |
@@ -706,3 +542,33 @@ class PdfGraphics { | @@ -706,3 +542,33 @@ class PdfGraphics { | ||
706 | buf.putString(' $phase d\n'); | 542 | buf.putString(' $phase d\n'); |
707 | } | 543 | } |
708 | } | 544 | } |
545 | + | ||
546 | +class _PathProxy extends PathProxy { | ||
547 | + _PathProxy(this.canvas, this.stroke); | ||
548 | + | ||
549 | + final PdfGraphics canvas; | ||
550 | + final bool stroke; | ||
551 | + | ||
552 | + @override | ||
553 | + void close() { | ||
554 | + if (stroke) { | ||
555 | + canvas.closePath(); | ||
556 | + } | ||
557 | + } | ||
558 | + | ||
559 | + @override | ||
560 | + void cubicTo( | ||
561 | + double x1, double y1, double x2, double y2, double x3, double y3) { | ||
562 | + canvas.curveTo(x1, y1, x2, y2, x3, y3); | ||
563 | + } | ||
564 | + | ||
565 | + @override | ||
566 | + void lineTo(double x, double y) { | ||
567 | + canvas.lineTo(x, y); | ||
568 | + } | ||
569 | + | ||
570 | + @override | ||
571 | + void moveTo(double x, double y) { | ||
572 | + canvas.moveTo(x, y); | ||
573 | + } | ||
574 | +} |
-
Please register or login to post a comment