Showing
3 changed files
with
69 additions
and
48 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); | ||
| 79 | - PdfAnnot.namedLink( | ||
| 80 | - context.page, | ||
| 81 | - rect: ibox, | ||
| 82 | - dest: destination, | ||
| 83 | - ); | ||
| 84 | - } | 62 | + void build(Context context, PdfRect box) { |
| 63 | + PdfAnnot.namedLink( | ||
| 64 | + context.page, | ||
| 65 | + rect: localToGlobal(context, box), | ||
| 66 | + dest: destination, | ||
| 67 | + ); | ||
| 85 | } | 68 | } |
| 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