Showing
3 changed files
with
65 additions
and
44 deletions
@@ -42,69 +42,76 @@ class Anchor extends SingleChildWidget { | @@ -42,69 +42,76 @@ class Anchor extends SingleChildWidget { | ||
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | ||
45 | -class _Annotation extends SingleChildWidget { | ||
46 | - _Annotation({Widget child}) : super(child: child); | ||
47 | - | ||
48 | - @override | ||
49 | - void debugPaint(Context context) { | ||
50 | - context.canvas | ||
51 | - ..setFillColor(PdfColors.pink) | ||
52 | - ..drawRect(box.x, box.y, box.width, box.height) | ||
53 | - ..fillPath(); | 45 | +abstract class AnnotationBuilder { |
46 | + PdfRect localToGlobal(Context context, PdfRect box) { | ||
47 | + final Matrix4 mat = context.canvas.getTransform(); | ||
48 | + final Vector3 lt = mat.transform3(Vector3(box.left, box.bottom, 0)); | ||
49 | + final Vector3 rb = mat.transform3(Vector3(box.right, box.top, 0)); | ||
50 | + return PdfRect.fromLTRB(lt.x, lt.y, rb.x, rb.y); | ||
54 | } | 51 | } |
55 | 52 | ||
56 | - @override | ||
57 | - void paint(Context context) { | ||
58 | - super.paint(context); | ||
59 | - paintChild(context); | ||
60 | - } | 53 | + void build(Context context, PdfRect box); |
61 | } | 54 | } |
62 | 55 | ||
63 | -class Link extends _Annotation { | ||
64 | - Link({@required Widget child, this.destination}) | ||
65 | - : assert(child != null), | ||
66 | - super(child: child); | 56 | +class AnnotationLink extends AnnotationBuilder { |
57 | + AnnotationLink(this.destination) : assert(destination != null); | ||
67 | 58 | ||
68 | final String destination; | 59 | final String destination; |
69 | 60 | ||
70 | @override | 61 | @override |
71 | - void paint(Context context) { | ||
72 | - super.paint(context); | ||
73 | - | ||
74 | - if (destination != null) { | ||
75 | - final Matrix4 mat = context.canvas.getTransform(); | ||
76 | - final Vector3 lt = mat.transform3(Vector3(box.left, box.bottom, 0)); | ||
77 | - final Vector3 rb = mat.transform3(Vector3(box.right, box.top, 0)); | ||
78 | - final PdfRect ibox = PdfRect.fromLTRB(lt.x, lt.y, rb.x, rb.y); | 62 | + void build(Context context, PdfRect box) { |
79 | PdfAnnot.namedLink( | 63 | PdfAnnot.namedLink( |
80 | context.page, | 64 | context.page, |
81 | - rect: ibox, | 65 | + rect: localToGlobal(context, box), |
82 | dest: destination, | 66 | dest: destination, |
83 | ); | 67 | ); |
84 | } | 68 | } |
85 | - } | ||
86 | } | 69 | } |
87 | 70 | ||
88 | -class UrlLink extends _Annotation { | ||
89 | - UrlLink({@required Widget child, @required this.destination}) | ||
90 | - : assert(child != null), | ||
91 | - assert(destination != null), | ||
92 | - super(child: child); | 71 | +class AnnotationUrl extends AnnotationBuilder { |
72 | + AnnotationUrl(this.destination) : assert(destination != null); | ||
93 | 73 | ||
94 | final String destination; | 74 | final String destination; |
95 | 75 | ||
96 | @override | 76 | @override |
97 | - void paint(Context context) { | ||
98 | - super.paint(context); | ||
99 | - | ||
100 | - final Matrix4 mat = context.canvas.getTransform(); | ||
101 | - final Vector3 lt = mat.transform3(Vector3(box.left, box.bottom, 0)); | ||
102 | - final Vector3 rb = mat.transform3(Vector3(box.right, box.top, 0)); | ||
103 | - final PdfRect ibox = PdfRect.fromLTRB(lt.x, lt.y, rb.x, rb.y); | 77 | + void build(Context context, PdfRect box) { |
104 | PdfAnnot.urlLink( | 78 | PdfAnnot.urlLink( |
105 | context.page, | 79 | context.page, |
106 | - rect: ibox, | 80 | + rect: localToGlobal(context, box), |
107 | dest: destination, | 81 | dest: destination, |
108 | ); | 82 | ); |
109 | } | 83 | } |
110 | } | 84 | } |
85 | + | ||
86 | +class Annotation extends SingleChildWidget { | ||
87 | + Annotation({Widget child, this.builder}) : super(child: child); | ||
88 | + | ||
89 | + final AnnotationBuilder builder; | ||
90 | + | ||
91 | + @override | ||
92 | + void debugPaint(Context context) { | ||
93 | + context.canvas | ||
94 | + ..setFillColor(PdfColors.pink) | ||
95 | + ..drawRect(box.x, box.y, box.width, box.height) | ||
96 | + ..fillPath(); | ||
97 | + } | ||
98 | + | ||
99 | + @override | ||
100 | + void paint(Context context) { | ||
101 | + super.paint(context); | ||
102 | + paintChild(context); | ||
103 | + builder?.build(context, box); | ||
104 | + } | ||
105 | +} | ||
106 | + | ||
107 | +class Link extends Annotation { | ||
108 | + Link({@required Widget child, String destination}) | ||
109 | + : assert(child != null), | ||
110 | + super(child: child, builder: AnnotationLink(destination)); | ||
111 | +} | ||
112 | + | ||
113 | +class UrlLink extends Annotation { | ||
114 | + UrlLink({@required Widget child, String destination}) | ||
115 | + : assert(child != null), | ||
116 | + super(child: child, builder: AnnotationUrl(destination)); | ||
117 | +} |
@@ -19,7 +19,7 @@ part of widget; | @@ -19,7 +19,7 @@ part of widget; | ||
19 | enum TextAlign { left, right, center, justify } | 19 | enum TextAlign { left, right, center, justify } |
20 | 20 | ||
21 | class _Word { | 21 | class _Word { |
22 | - _Word(this.text, this.style, this.metrics); | 22 | + _Word(this.text, this.style, this.metrics, this.annotation); |
23 | 23 | ||
24 | final String text; | 24 | final String text; |
25 | 25 | ||
@@ -29,6 +29,8 @@ class _Word { | @@ -29,6 +29,8 @@ class _Word { | ||
29 | 29 | ||
30 | PdfPoint offset = PdfPoint.zero; | 30 | PdfPoint offset = PdfPoint.zero; |
31 | 31 | ||
32 | + final AnnotationBuilder annotation; | ||
33 | + | ||
32 | @override | 34 | @override |
33 | String toString() { | 35 | String toString() { |
34 | return 'Word "$text" offset:$offset metrics:$metrics style:$style'; | 36 | return 'Word "$text" offset:$offset metrics:$metrics style:$style'; |
@@ -53,7 +55,7 @@ class _Word { | @@ -53,7 +55,7 @@ class _Word { | ||
53 | } | 55 | } |
54 | 56 | ||
55 | class TextSpan { | 57 | class TextSpan { |
56 | - const TextSpan({this.style, this.text, this.children}); | 58 | + const TextSpan({this.style, this.text, this.children, this.annotation}); |
57 | 59 | ||
58 | final TextStyle style; | 60 | final TextStyle style; |
59 | 61 | ||
@@ -61,6 +63,8 @@ class TextSpan { | @@ -61,6 +63,8 @@ class TextSpan { | ||
61 | 63 | ||
62 | final List<TextSpan> children; | 64 | final List<TextSpan> children; |
63 | 65 | ||
66 | + final AnnotationBuilder annotation; | ||
67 | + | ||
64 | String toPlainText() { | 68 | String toPlainText() { |
65 | final StringBuffer buffer = StringBuffer(); | 69 | final StringBuffer buffer = StringBuffer(); |
66 | visitTextSpan((TextSpan span) { | 70 | visitTextSpan((TextSpan span) { |
@@ -210,7 +214,7 @@ class RichText extends Widget { | @@ -210,7 +214,7 @@ class RichText extends Widget { | ||
210 | top = math.min(top ?? metrics.top, metrics.top); | 214 | top = math.min(top ?? metrics.top, metrics.top); |
211 | bottom = math.max(bottom ?? metrics.bottom, metrics.bottom); | 215 | bottom = math.max(bottom ?? metrics.bottom, metrics.bottom); |
212 | 216 | ||
213 | - final _Word wd = _Word(word, style, metrics); | 217 | + final _Word wd = _Word(word, style, metrics, span.annotation); |
214 | wd.offset = PdfPoint(offsetX, -offsetY); | 218 | wd.offset = PdfPoint(offsetX, -offsetY); |
215 | 219 | ||
216 | _words.add(wd); | 220 | _words.add(wd); |
@@ -264,6 +268,15 @@ class RichText extends Widget { | @@ -264,6 +268,15 @@ class RichText extends Widget { | ||
264 | } | 268 | } |
265 | } | 269 | } |
266 | 270 | ||
271 | + if (word.annotation != null) { | ||
272 | + final PdfRect wordBox = PdfRect( | ||
273 | + box.x + word.offset.x + word.metrics.left, | ||
274 | + box.top + word.offset.y + word.metrics.top, | ||
275 | + word.metrics.width, | ||
276 | + word.metrics.height); | ||
277 | + word.annotation.build(context, wordBox); | ||
278 | + } | ||
279 | + | ||
267 | context.canvas.drawString( | 280 | context.canvas.drawString( |
268 | currentStyle.font.getFont(context), | 281 | currentStyle.font.getFont(context), |
269 | currentStyle.fontSize * textScaleFactor, | 282 | currentStyle.fontSize * textScaleFactor, |
-
Please register or login to post a comment