David PHAM-VAN

Automatic pdf.js library loading

... ... @@ -6,6 +6,7 @@
- Fix parsing TTF fonts with zero-length glyphs
- Fix PdfPreview page format and orientation updates
- Update Pdfium version to 4929
- Automatic pdf.js library loading
## 5.7.2
... ...
... ... @@ -36,8 +36,9 @@ for documentation.
```
4. For MacOS add printing capability by opening macos directory in XCode
5. For the web, a javascript library and a small script has to be added to
your `web/index.html` file, just before `</head>`:
5. If you want to manually set the PdfJs library version for the web, a javascript
library and a small script has to be added to your `web/index.html` file, just
before `</head>`. Otherwise it is loaded automatically:
```html
<script src="//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.8.335/pdf.min.js"></script>
... ...
... ... @@ -8,8 +8,6 @@ analyzer:
missing_return: warning
public_member_api_docs: ignore
todo: ignore
constant_identifier_names: ignore
avoid_print: ignore
linter:
rules:
... ...
... ... @@ -29,12 +29,13 @@ import 'package:pdf/pdf.dart';
import 'src/callback.dart';
import 'src/interface.dart';
import 'src/mutex.dart';
import 'src/pdfjs.dart';
import 'src/printer.dart';
import 'src/printing_info.dart';
import 'src/raster.dart';
/// Print plugin targetting Flutter on the Web
/// Print plugin targeting Flutter on the Web
class PrintingPlugin extends PrintingPlatform {
/// Registers this class as the default instance of [PrintingPlugin].
static void registerWith(Registrar registrar) {
... ... @@ -45,16 +46,67 @@ class PrintingPlugin extends PrintingPlatform {
static const String _frameId = '__net_nfet_printing__';
@override
Future<PrintingInfo> info() async {
final dynamic workerSrc = js.context.callMethod('eval', <String>[
static const _pdfJsVersion =
'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.13.216';
final _loading = Mutex();
bool get _hasPdfJsLib => js.context.callMethod('eval', <String>[
'typeof pdfjsLib !== "undefined" && pdfjsLib.GlobalWorkerOptions.workerSrc!="";'
]);
Future<void> _initPlugin() async {
await _loading.acquire();
if (!_hasPdfJsLib) {
final script = ScriptElement()
..type = 'text/javascript'
..async = true
..src = '$_pdfJsVersion/pdf.min.js';
assert(document.head != null);
document.head!.append(script);
await script.onLoad.first;
if (js.context['pdfjsLib'] == null) {
// In dev, requireJs is loaded in
final require = js.JsObject.fromBrowserObject(js.context['require']);
require.callMethod('config', <dynamic>[
js.JsObject.jsify({
'paths': {
'pdfjs-dist/build/pdf': '$_pdfJsVersion/pdf.min',
'pdfjs-dist/build/pdf.worker': '$_pdfJsVersion/pdf.worker.min',
}
})
]);
final completer = Completer<void>();
js.context.callMethod('require', <dynamic>[
js.JsObject.jsify(
['pdfjs-dist/build/pdf', 'pdfjs-dist/build/pdf.worker']),
(dynamic app) {
js.context['pdfjsLib'] = app;
completer.complete();
}
]);
await completer.future;
}
js.context['pdfjsLib']['GlobalWorkerOptions']['workerSrc'] =
'$_pdfJsVersion/pdf.worker.min.js';
}
_loading.release();
}
@override
Future<PrintingInfo> info() async {
await _initPlugin();
return PrintingInfo(
canPrint: true,
canShare: true,
canRaster: workerSrc,
canRaster: _hasPdfJsLib,
);
}
... ... @@ -235,6 +287,8 @@ class PrintingPlugin extends PrintingPlatform {
List<int>? pages,
double dpi,
) async* {
await _initPlugin();
final t = PdfJs.getDocument(Settings()..data = document);
final d = await promiseToFuture<PdfJsDoc>(t.promise);
... ...
... ... @@ -19,6 +19,8 @@ import 'dart:convert';
import 'package:flutter/services.dart';
import '../mutex.dart';
/// Application asset manifest.
mixin AssetManifest {
static final _assets = <String>[];
... ... @@ -63,29 +65,3 @@ mixin AssetManifest {
return _assets.contains(key);
}
}
/// Simple Mutex
class Mutex {
final _waiting = <Completer>[];
bool _locked = false;
/// Lock the mutex
Future<void> acquire() async {
if (_locked) {
final c = Completer<void>();
_waiting.add(c);
await c.future;
}
_locked = true;
}
/// Release the mutex
void release() {
_locked = false;
for (final e in _waiting) {
e.complete();
}
_waiting.clear();
}
}
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'dart:async';
/// Simple Mutex
class Mutex {
final _waiting = <Completer>[];
bool _locked = false;
bool get locked => _locked;
/// Wait for the mutex to be available
Future<void> wait() async {
await acquire();
release();
}
/// Lock the mutex
Future<void> acquire() async {
if (_locked) {
final c = Completer<void>();
_waiting.add(c);
await c.future;
}
_locked = true;
}
/// Release the mutex
void release() {
_locked = false;
for (final e in _waiting) {
e.complete();
}
_waiting.clear();
}
}
... ...