From 900cf5e427e6441ceab030cfe6aa5bba94a208f3 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Mon, 11 Jan 2021 17:20:45 +0900 Subject: [PATCH] packages upgrade, fixed printing for multipage --- .../fullscreen/entry_action_delegate.dart | 49 +---------- lib/widgets/fullscreen/printing.dart | 84 +++++++++++++++++++ pubspec.lock | 16 ++-- 3 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 lib/widgets/fullscreen/printing.dart diff --git a/lib/widgets/fullscreen/entry_action_delegate.dart b/lib/widgets/fullscreen/entry_action_delegate.dart index 16e736901..75b818390 100644 --- a/lib/widgets/fullscreen/entry_action_delegate.dart +++ b/lib/widgets/fullscreen/entry_action_delegate.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -import 'package:aves/image_providers/uri_image_provider.dart'; import 'package:aves/model/actions/entry_actions.dart'; import 'package:aves/model/image_entry.dart'; import 'package:aves/model/source/collection_lens.dart'; @@ -11,13 +10,12 @@ import 'package:aves/widgets/common/action_mixins/permission_aware.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/rename_entry_dialog.dart'; import 'package:aves/widgets/fullscreen/fullscreen_debug_page.dart'; +import 'package:aves/widgets/fullscreen/printing.dart'; import 'package:aves/widgets/fullscreen/source_viewer_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -import 'package:pdf/widgets.dart' as pdf; import 'package:pedantic/pedantic.dart'; -import 'package:printing/printing.dart'; class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin { final CollectionLens collection; @@ -45,7 +43,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin { _showRenameDialog(context, entry); break; case EntryAction.print: - _print(entry); + EntryPrinter(entry).print(); break; case EntryAction.rotateCCW: _rotate(context, entry, clockwise: false); @@ -90,49 +88,6 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin { } } - Future _print(ImageEntry entry) async { - final uri = entry.uri; - final mimeType = entry.mimeType; - final rotationDegrees = entry.rotationDegrees; - final isFlipped = entry.isFlipped; - final documentName = entry.bestTitle ?? 'Aves'; - final doc = pdf.Document(title: documentName); - - pdf.Widget pdfChild; - if (entry.isSvg) { - final bytes = await ImageFileService.getImage(uri, mimeType, entry.rotationDegrees, entry.isFlipped); - if (bytes != null && bytes.isNotEmpty) { - pdfChild = pdf.SvgImage(svg: utf8.decode(bytes)); - } - } else { - pdfChild = pdf.Image.provider(await flutterImageProvider( - UriImage( - uri: uri, - mimeType: mimeType, - // TODO TLAD multipage print - page: 0, - rotationDegrees: rotationDegrees, - isFlipped: isFlipped, - ), - )); - } - if (pdfChild != null) { - doc.addPage(pdf.Page( - orientation: entry.isPortrait ? pdf.PageOrientation.portrait : pdf.PageOrientation.landscape, - build: (context) => pdf.FullPage( - ignoreMargins: true, - child: pdf.Center( - child: pdfChild, - ), - ), - )); // Page - unawaited(Printing.layoutPdf( - onLayout: (format) => doc.save(), - name: documentName, - )); - } - } - Future _flip(BuildContext context, ImageEntry entry) async { if (!await checkStoragePermission(context, {entry})) return; diff --git a/lib/widgets/fullscreen/printing.dart b/lib/widgets/fullscreen/printing.dart new file mode 100644 index 000000000..00824a099 --- /dev/null +++ b/lib/widgets/fullscreen/printing.dart @@ -0,0 +1,84 @@ +import 'dart:convert'; + +import 'package:aves/image_providers/uri_image_provider.dart'; +import 'package:aves/model/image_entry.dart'; +import 'package:aves/services/image_file_service.dart'; +import 'package:aves/services/metadata_service.dart'; +import 'package:pdf/widgets.dart' as pdf; +import 'package:pedantic/pedantic.dart'; +import 'package:printing/printing.dart'; + +class EntryPrinter { + final ImageEntry entry; + + const EntryPrinter(this.entry); + + Future print() async { + final documentName = entry.bestTitle ?? 'Aves'; + final doc = pdf.Document(title: documentName); + + final pages = await _buildPages(); + if (pages.isNotEmpty) { + pages.forEach(doc.addPage); // Page + unawaited(Printing.layoutPdf( + onLayout: (format) => doc.save(), + name: documentName, + )); + } + } + + Future> _buildPages() async { + final pages = []; + + void _addPdfPage(pdf.Widget pdfChild) { + if (pdfChild == null) return; + pages.add(pdf.Page( + orientation: entry.isPortrait ? pdf.PageOrientation.portrait : pdf.PageOrientation.landscape, + build: (context) => pdf.FullPage( + ignoreMargins: true, + child: pdf.Center( + child: pdfChild, + ), + ), + )); + } + + if (entry.isMultipage) { + final multiPageInfo = await MetadataService.getMultiPageInfo(entry); + if (multiPageInfo.pageCount > 1) { + for (final kv in multiPageInfo.pages.entries) { + _addPdfPage(await _buildPageImage(page: kv.key)); + } + } + } + if (pages.isEmpty) { + _addPdfPage(await _buildPageImage()); + } + return pages; + } + + Future _buildPageImage({page = 0}) async { + final uri = entry.uri; + final mimeType = entry.mimeType; + final rotationDegrees = entry.rotationDegrees; + final isFlipped = entry.isFlipped; + + if (entry.isSvg) { + final bytes = await ImageFileService.getImage(uri, mimeType, rotationDegrees, isFlipped); + if (bytes != null && bytes.isNotEmpty) { + return pdf.SvgImage(svg: utf8.decode(bytes)); + } + } else { + return pdf.Image(await flutterImageProvider( + UriImage( + uri: uri, + mimeType: mimeType, + page: page, + rotationDegrees: rotationDegrees, + isFlipped: isFlipped, + ), + )); + } + return null; + } +} diff --git a/pubspec.lock b/pubspec.lock index b3090e230..fbb1a555d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -331,7 +331,7 @@ packages: name: flutter_markdown url: "https://pub.dartlang.org" source: hosted - version: "0.5.1" + version: "0.5.2" flutter_native_timezone: dependency: "direct main" description: @@ -395,7 +395,7 @@ packages: name: google_maps_flutter url: "https://pub.dartlang.org" source: hosted - version: "1.0.6" + version: "1.0.10" google_maps_flutter_platform_interface: dependency: transitive description: @@ -535,7 +535,7 @@ packages: name: motion_sensors url: "https://pub.dartlang.org" source: hosted - version: "0.0.4" + version: "0.0.5" nested: dependency: transitive description: @@ -605,7 +605,7 @@ packages: name: panorama url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.3.1" path: dependency: transitive description: @@ -633,7 +633,7 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.24" + version: "1.6.27" path_provider_linux: dependency: transitive description: @@ -647,7 +647,7 @@ packages: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+6" + version: "0.0.4+8" path_provider_platform_interface: dependency: transitive description: @@ -668,7 +668,7 @@ packages: name: pdf url: "https://pub.dartlang.org" source: hosted - version: "1.13.0" + version: "2.0.0" pedantic: dependency: "direct main" description: @@ -738,7 +738,7 @@ packages: name: printing url: "https://pub.dartlang.org" source: hosted - version: "3.7.2" + version: "4.0.0" process: dependency: transitive description: