Коммит e87898c2 создал по автору Красавин Никита Сергеевич's avatar Красавин Никита Сергеевич
Просмотр файлов

Merge branch 'create-plugin' into 'master'

[feature] Create pdfrx

See merge request oss/flutter/flutter-community-plugins/pdfrx!1
владельцы 5487c5ed 70fc8b79
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/pubspec.lock
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Aurora generated
/aurora/flutter
# Authors
* Daniil Girenko, <a.fedchenko@omp.ru>
* Developer, 2024
* Maintainer, 2024
* Takashi Kawasaki, <@espresso3389>
* Developer, 2018
* Noname_1111788
* Developer, 2024
* Nikita Krasavin, <n.krasavin@omp.ru>
* Product owner, 2024
* Maintainer, 2024
* Reviewer, 2024
* Vitaly Zarubin, <v.zarubin@omp.ru>
* Reviewer, 2024
* Egor Popov, <e.popov@omp.ru>
* Reviewer, 2024
The MIT License (MIT)
===============
Copyright (c) 2024 Open Mobile Platform LLC <community@omp.ru>
Copyright (c) 2024 Noname_1111788
Copyright (c) 2018 @espresso3389 (Takashi Kawasaki)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# pdfrx
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://os-git.omprussia.ru/oss/flutter/flutter-community-plugins/pdfrx.git
git branch -M master
git push -uf origin master
```
## Integrate with your tools
- [ ] [Set up project integrations](https://os-git.omprussia.ru/oss/flutter/flutter-community-plugins/pdfrx/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
# pdfrx
[Pdfrx](https://pub.dartlang.org/packages/pdfrx) plugin with Aurora support.
The plugin supports Aurora, Android, iOS, Windows, macOS, Linux.
Web support will be added after the release of flutter-aurora 3.24.
## Interactive Demo
A [demo site](https://espresso3389.github.io/pdfrx/) using Flutter Web
![pdfrx](https://github.com/espresso3389/pdfrx/assets/1311400/b076ac0b-e2cb-48f0-8772-9891537ade7b)
## Main Features
- [Zoomable and scrollable PDF document viewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html)
- [PDF Link Handling](#pdf-link-handling) support
- [Document Outline (a.k.a Bookmarks)](#document-outline-aka-bookmarks) support
- [Text Selection (still experimental)](#text-selection) support
- [Text Search](#text-search) support
- Viewer decoration support
- Scroll bar by [PdfScrollThumb](#showing-scroll-thumbs)
- More viewer customizations by [PdfViewerParams.viewerOverlayBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/viewerOverlayBuilder.html)
- Page decoration support
- Overlay widgets on page by [PdfViewerParams.pageOverlaysBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/pageOverlaysBuilder.html)
- Canvas based paint on page by [PdfViewerParams.pagePaintCallbacks](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/pagePaintCallbacks.html)
- Multi-platform support
- Aurora
- Android
- iOS
- Windows
- macOS
- Linux (even on Raspberry PI)
- Web (\*using [PDF.js](https://mozilla.github.io/pdf.js/))
- Three layers of APIs:
- Easy to use Flutter widgets
- [PdfViewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html)
- [PdfDocumentViewBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocumentViewBuilder-class.html)
- [PdfPageView](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfPageView-class.html)
- Easy to use PDF APIs
- [PdfDocument](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocument-class.html)
- PDFium bindings
- Not encouraged but you can import [package:pdfrx/src/pdfium/pdfium_bindings.dart](https://github.com/espresso3389/pdfrx/blob/master/lib/src/pdfium/pdfium_bindings.dart)
## Example Code
The following fragment illustrates the easiest way to show a PDF file in assets:
```dart
import 'package:pdfrx/pdfrx.dart';
...
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Pdfrx example'),
),
body: PdfViewer.asset('assets/hello.pdf'),
),
);
}
}
```
Anyway, please follow the instructions below to install on your environment.
## Getting Started
This package is a fork of the original `pdfrx`.
It supports all the features of `pdfrx-1.0.82` and includes support for Aurora platform.
> Supports only OS Aurora 5+!
**pubspec.yaml**
```yaml
dependencies:
pdfrx:
git:
url: https://gitlab.com/omprussia/flutter/flutter-plugins.git
ref: pdfrx-1.0.82
path: packages/pdfrx_aurora
```
***.spec**
```spec
BuildRequires: pkgconfig(runtime-manager-qt5)
```
***.desktop**
```desktop
Permissions=Internet;UserDirs
```
### Note for Windows
Ensure your Windows installation enables _Developer Mode_.
The build process internally uses symbolic link and it requires Developer Mode to be enabled.
Without this, you may encounter errors [like this](https://github.com/espresso3389/pdfrx/issues/34).
## Open PDF File
[PdfViewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html) supports following functions to open PDF file on specific medium:
- [PdfViewer.asset](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer/PdfViewer.asset.html)
- Open PDF of Flutter's asset
- [PdfViewer.file](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer/PdfViewer.file.html)
- Open PDF from file
- macOS: may be blocked by [App Sandbox](https://github.com/espresso3389/pdfrx/wiki/macOS:-Deal-with-App-Sandbox)
- [PdfViewer.uri](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer/PdfViewer.uri.html)
- Open PDF from URI (`https://...` or relative path)
- Flutter Web: may be blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
- macOS: may be blocked by [App Sandbox](https://github.com/espresso3389/pdfrx/wiki/macOS:-Deal-with-App-Sandbox)
### Deal with Password Protected PDF Files
To support password protected PDF files, use [passwordProvider](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfPasswordProvider.html) to supply passwords interactively:
```dart
PdfViewer.asset(
'assets/test.pdf',
// Set password provider to show password dialog
passwordProvider: _passwordDialog,
...
),
```
And, `_passwordDialog` function is defined like this:
```dart
Future<String?> _passwordDialog() async {
final textController = TextEditingController();
return await showDialog<String?>(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text('Enter password'),
content: TextField(
controller: textController,
autofocus: true,
keyboardType: TextInputType.visiblePassword,
obscureText: true,
onSubmitted: (value) => Navigator.of(context).pop(value),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(null),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(textController.text),
child: const Text('OK'),
),
],
);
},
);
}
```
When [PdfViewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html) tries to open a password protected document, it calls the function passed to `passwordProvider` (except the first attempt; see below) repeatedly to get a new password until the document is successfully opened. And if the function returns null, the viewer will give up the password trials and the function is no longer called.
### `firstAttemptByEmptyPassword`
By default, the first password attempt uses empty password. This is because encrypted PDF files frequently use empty password for viewing purpose. It's _normally_ useful but if you want to use authoring password, it can be disabled by setting `firstAttemptByEmptyPassword` to false.
## Customizations
You can customize the behaviour and visual by configuring [PdfViewerParams](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams-class.html).
### Text Selection
Text selection feature is still experimental but you can easily enable it like the following fragment:
```dart
PdfViewer.asset(
'assets/test.pdf',
enableTextSelection: true,
...
),
```
There are still several limitations and issues on text selection feature:
- Pan-to-scroll does not work on Desktop ([#8](https://github.com/espresso3389/pdfrx/issues/8))
- Pan-to-scroll does not work on Flutter Web on mobile devices ([#180](https://github.com/espresso3389/pdfrx/issues/180))
- Selecting text sometimes throws exception ([#185](https://github.com/espresso3389/pdfrx/issues/185))
- Text selection suddenly gets cleared in certain situation
### PDF Link Handling
To enable Link in PDF file, you should set [PdfViewerParams.linkHandlerParams](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/linkHandlerParams.html).
The following fragment handles user's tap on link:
```dart
linkHandlerParams: PdfLinkHandlerParams(
onLinkTap: (link) {
// handle URL or Dest
if (link.url != null) {
// TODO: implement your own isSecureUrl by yourself...
if (await isSecureUrl(link.url!)) {
launchUrl(link.url!);
}
} else if (link.dest != null) {
controller.goToDest(link.dest);
}
},
),
```
#### Note for Link Validation
For URIs, you should check the validity of the URIs before opening the URI; [the example code](https://github.com/espresso3389/pdfrx/blob/7462532645311754a048c62e62a4a32bf9eae32a/example/viewer/lib/main.dart#L410) just show dialog to ask whether to open the URL or not.
For destinations, you can use [PdfViewerController.goToDest](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerController/goToDest.html) to go to the destination. Or you can use [PdfViewerController.calcMatrixForDest](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerController/calcMatrixForDest.html) to get the matrix for it.
#### Link Appearance
For link appearance, you can change its color using [PdfLinkHandlerParams.linkColor](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfLinkHandlerParams/linkColor.html).
For more further customization, you can use [PdfLinkHandlerParams.customPainter](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfLinkHandlerParams/customPainter.html):
```dart
customPainter: (canvas, pageRect, page, links) {
final paint = Paint()
..color = Colors.red.withOpacity(0.2)
..style = PaintingStyle.fill;
for (final link in links) {
// you can customize here to make your own link appearance
final rect = link.rect.toRectInPageRect(page: page, pageRect: pageRect);
canvas.drawRect(rect, paint);
}
}
```
### Document Outline (a.k.a Bookmarks)
PDF defines document outline ([PdfOutlineNode](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfOutlineNode-class.html)), which is sometimes called as bookmarks or index. And you can access it by [PdfDocument.loadOutline](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocument/loadOutline.html).
The following fragment obtains it on [PdfViewerParams.onViewerReady](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/onViewerReady.html):
```dart
onViewerReady: (document, controller) async {
outline.value = await document.loadOutline();
},
```
[PdfOutlineNode](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfOutlineNode-class.html) is tree structured data and for more information, see the usage on [example code](https://github.com/espresso3389/pdfrx/blob/master/example/viewer/lib/outline_view.dart).
### Horizontal Scroll View
By default, the pages are layed out vertically.
You can customize the layout logic by [PdfViewerParams.layoutPages](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/layoutPages.html):
```dart
layoutPages: (pages, params) {
final height =
pages.fold(0.0, (prev, page) => max(prev, page.height)) +
params.margin * 2;
final pageLayouts = <Rect>[];
double x = params.margin;
for (var page in pages) {
pageLayouts.add(
Rect.fromLTWH(
x,
(height - page.height) / 2, // center vertically
page.width,
page.height,
),
);
x += page.width + params.margin;
}
return PdfPageLayout(
pageLayouts: pageLayouts,
documentSize: Size(x, height),
);
},
```
### Facing Pages
The following code will show pages in "facing-sequential-layout" that is often used in PDF viewer apps:
```dart
/// Page reading order; true to L-to-R that is commonly used by books like manga or such
var isRightToLeftReadingOrder = false;
/// Use the first page as cover page
var needCoverPage = true;
...
layoutPages: (pages, params) {
final width = pages.fold(
0.0, (prev, page) => max(prev, page.width));
final pageLayouts = <Rect>[];
final offset = needCoverPage ? 1 : 0;
double y = params.margin;
for (int i = 0; i < pages.length; i++) {
final page = pages[i];
final pos = i + offset;
final isLeft = isRightToLeftReadingOrder
? (pos & 1) == 1
: (pos & 1) == 0;
final otherSide = (pos ^ 1) - offset;
final h = 0 <= otherSide && otherSide < pages.length
? max(page.height, pages[otherSide].height)
: page.height;
pageLayouts.add(
Rect.fromLTWH(
isLeft
? width + params.margin - page.width
: params.margin * 2 + width,
y + (h - page.height) / 2,
page.width,
page.height,
),
);
if (pos & 1 == 1 || i + 1 == pages.length) {
y += h + params.margin;
}
}
return PdfPageLayout(
pageLayouts: pageLayouts,
documentSize: Size(
(params.margin + width) * 2 + params.margin,
y,
),
);
},
```
### Showing Scroll Thumbs
By default, the viewer does never show any scroll bars nor scroll thumbs.
You can add scroll thumbs by using [PdfViewerParams.viewerOverlayBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/viewerOverlayBuilder.html):
```dart
viewerOverlayBuilder: (context, size, handleLinkTap) => [
// Add vertical scroll thumb on viewer's right side
PdfViewerScrollThumb(
controller: controller,
orientation: ScrollbarOrientation.right,
thumbSize: const Size(40, 25),
thumbBuilder:
(context, thumbSize, pageNumber, controller) =>
Container(
color: Colors.black,
// Show page number on the thumb
child: Center(
child: Text(
pageNumber.toString(),
style: const TextStyle(color: Colors.white),
),
),
),
),
// Add horizontal scroll thumb on viewer's bottom
PdfViewerScrollThumb(
controller: controller,
orientation: ScrollbarOrientation.bottom,
thumbSize: const Size(80, 30),
thumbBuilder:
(context, thumbSize, pageNumber, controller) =>
Container(
color: Colors.red,
),
),
],
```
Basically, [PdfViewerParams.viewerOverlayBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/viewerOverlayBuilder.html) can be used to insert any widgets under viewer's internal [Stack](https://api.flutter.dev/flutter/widgets/Stack-class.html).
But if you want to place many visual objects that does not interact with user, you'd better use [PdfViewerParams.pagePaintCallback](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/pagePaintCallbacks.html).
### Double-tap to Zoom
You can implement double-tap-to-zoom feature using [PdfViewerParams.viewerOverlayBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/viewerOverlayBuilder.html) with [PdfViewerScrollThumb](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerScrollThumb-class.html):
```dart
viewerOverlayBuilder: (context, size, handleLinkTap) => [
GestureDetector(
behavior: HitTestBehavior.translucent,
// Your code here:
onDoubleTap: () {
controller.zoomUp(loop: true);
},
// If you use GestureDetector on viewerOverlayBuilder, it breaks link-tap handling
// and you should manually handle it using onTapUp callback
onTapUp: (details) {
handleLinkTap(details.localPosition);
},
// Make the GestureDetector covers all the viewer widget's area
// but also make the event go through to the viewer.
child: IgnorePointer(
child:
SizedBox(width: size.width, height: size.height),
),
),
...
],
```
If you want to use [PdfViewerScrollThumb](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerScrollThumb-class.html) with double-tap-to-zoom enabled, place the double-tap-to-zoom code before [PdfViewerScrollThumb](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerScrollThumb-class.html).
### Adding Page Number on Page Bottom
If you want to add page number on each page, you can do that by [PdfViewerParams.pageOverlaysBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/pageOverlaysBuilder.html):
```dart
pageOverlaysBuilder: (context, pageRect, page) {
return Align(
alignment: Alignment.bottomCenter,
child: Text(page.pageNumber.toString(),
style: const TextStyle(color: Colors.red)));33
},
```
### Loading Indicator
[PdfViewer.uri](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer/PdfViewer.uri.html) may take long time to download PDF file and you want to show some loading indicator. You can do that by [PdfViewerParams.loadingBannerBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/loadingBannerBuilder.html):
```dart
loadingBannerBuilder: (context, bytesDownloaded, totalBytes) {
return Center(
child: CircularProgressIndicator(
// totalBytes may not be available on certain case
value: totalBytes != null ? bytesDownloaded / totalBytes : null,
backgroundColor: Colors.grey,
),
);
}
```
## Dark/Night Mode Support
[PdfViewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html) does not have any native dark (or night) mode support but it can be easily implemented using [ColorFiltered](https://api.flutter.dev/flutter/widgets/ColorFiltered-class.html) widget:
```dart
ColorFiltered(
colorFilter: ColorFilter.mode(Colors.white, darkMode ? BlendMode.difference : BlendMode.dst),
child: PdfViewer.file(filePath, ...),
),
```
The trick is originally introduced by [pckimlong](https://github.com/pckimlong).
## Other Features
### Text Search
[TextSearcher](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher-class.html) is just a helper class that helps you to implement text searching feature on your app.
The following fragment illustrates the overall structure of the [TextSearcher](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher-class.html):
```dart
class _MainPageState extends State<MainPage> {
final controller = PdfViewerController();
// create a PdfTextSearcher and add a listener to update the GUI on search result changes
late final textSearcher = PdfTextSearcher(controller)..addListener(_update);
void _update() {
if (mounted) {
setState(() {});
}
}
@override
void dispose() {
// dispose the PdfTextSearcher
textSearcher.removeListener(_update);
textSearcher.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pdfrx example'),
),
body: PdfViewer.asset(
'assets/hello.pdf',
controller: controller,
params: PdfViewerParams(
// add pageTextMatchPaintCallback that paints search hit highlights
pagePaintCallbacks: [
textSearcher.pageTextMatchPaintCallback
],
),
)
);
}
...
}
```
On the fragment above, it does:
- Create [TextSearcher](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher-class.html) instance
- Add a listener (Using [PdfTextSearcher.addListener](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/addListener.html)) to update UI on search result change
- Add [TextSearcher.pageTextMatchPaintCallback](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/pageTextMatchPaintCallback.html) to [PdfViewerParams.pagePaintCallbacks](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewerParams/pagePaintCallbacks.html) to show search matches
Then, you can use [TextSearcher.startTextSearch](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/startTextSearch.html) to search text in the PDF document:
```dart
textSearcher.startTextSearch('hello', caseInsensitive: true);
```
The search starts running in background and the search progress is notified by the listener.
There are several functions that helps you to navigate user to the search matches:
- [TextSearcher.goToMatchOfIndex](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/goToMatchOfIndex.html) to go to the match of the specified index
- [TextSearcher.goToNextMatch](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/goToNextMatch.html) to go to the next match
- [TextSearcher.goToPrevMatch](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/goToPrevMatch.html) to go to the previous match
You can get the search result (even during the search running) in the list of [PdfTextRange](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextRange-class.html) by [PdfTextSearcher.matches](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfTextSearcher/matches.html):
```dart
for (final match in textSearcher.matches) {
print(match.pageNumber);
...
}
```
You can also cancel the background search:
```dart
textSearcher.resetTextSearch();
```
### PdfDocumentViewBuilder/PdfPageView
[PdfPageView](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfPageView-class.html) is just another PDF widget that shows only one page. It accepts [PdfDocument](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocument-class.html) and page number to show a page within the document.
[PdfDocumentViewBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocumentViewBuilder-class.html) is used to safely manage [PdfDocument](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocument-class.html) inside widget tree and it accepts `builder` parameter that creates child widgets.
The following fragment is a typical use of these widgets:
```dart
PdfDocumentViewBuilder.asset(
'asset/test.pdf',
builder: (context, document) => ListView.builder(
itemCount: document?.pages.length ?? 0,
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(8),
height: 240,
child: Column(
children: [
SizedBox(
height: 220,
child: PdfPageView(
document: document,
pageNumber: index + 1,
alignment: Alignment.center,
),
),
Text(
'${index + 1}',
),
],
),
);
},
),
),
```
## PdfDocument Management
[PdfDocumentViewBuilder](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocumentViewBuilder-class.html) can accept [PdfDocumentRef](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocumentRef-class.html) from [PdfViewer](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfViewer-class.html) to safely share the same [PdfDocument](https://pub.dev/documentation/pdfrx/latest/pdfrx/PdfDocument-class.html) instance. For more information, see [example/viewer/lib/thumbnails_view.dart](example/viewer/lib/thumbnails_view.dart).
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
prefer_single_quotes: true
comment_references: true
prefer_relative_imports: true
use_key_in_widget_constructors: true
avoid_return_types_on_setters: true
avoid_types_on_closure_parameters: true
eol_at_end_of_file: true
sort_child_properties_last: true
sort_unnamed_constructors_first: true
sort_constructors_first: true
always_put_required_named_parameters_first: true
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
exclude:
- lib/src/pdfium/pdfium_bindings.dart
cmake_minimum_required(VERSION 3.18.1)
# Project-level configuration.
set(PROJECT_NAME "pdfrx")
project(${PROJECT_NAME} LANGUAGES CXX)
# Invoke the build for native code shared with the other target platforms.
# This can be changed to accommodate different builds.
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(VERSION 3.14...3.25)
set(PDFIUM_RELEASE chromium%2F6555)
set(PDFIUM_DIR ${CMAKE_BINARY_DIR}/pdfium)
set(PDFIUM_RELEASE_DIR ${PDFIUM_DIR}/${PDFIUM_RELEASE})
file(MAKE_DIRECTORY ${PDFIUM_RELEASE_DIR})
set(PDFIUM_PLATFORM "android")
set(PDFIUM_LIB_FILENAME "libpdfium.so")
set(PDFIUM_LIB_DIR "lib")
set(PDFIUM_ABI2SUF_arm64-v8a "android-arm64")
set(PDFIUM_ABI2SUF_armeabi-v7a "android-arm")
set(PDFIUM_ABI2SUF_x86 "android-x86")
set(PDFIUM_ABI2SUF_x86_64 "android-x64")
set(PDFIUM_ARCHIVE_NAME pdfium-${PDFIUM_ABI2SUF_${ANDROID_ABI}})
set(PDFIUM_SRC_LIB_FILENAME ${PDFIUM_RELEASE_DIR}/${PDFIUM_LIB_DIR}/${PDFIUM_LIB_FILENAME})
set(PDFIUM_LIBS_DIR ${CMAKE_SOURCE_DIR}/.lib/${PDFIUM_RELEASE})
set(PDFIUM_LIBS_ARCH_DIR ${PDFIUM_LIBS_DIR}/${ANDROID_ABI})
set(PDFIUM_DEST_LIB_FILENAME ${PDFIUM_LIBS_ARCH_DIR}/${PDFIUM_LIB_FILENAME})
set(PDFIUM_LATEST_DIR ${CMAKE_SOURCE_DIR}/.lib/latest)
set(PDFIUM_LATEST_LIBS_ARCH_DIR ${PDFIUM_LATEST_DIR}/${ANDROID_ABI})
set(PDFIUM_LASTEST_LIB_FILENAME ${PDFIUM_LATEST_LIBS_ARCH_DIR}/${PDFIUM_LIB_FILENAME})
if(NOT EXISTS ${PDFIUM_SRC_LIB_FILENAME})
message(STATUS "Download precompiled PDFium...")
file(DOWNLOAD https://github.com/bblanchon/pdfium-binaries/releases/download/${PDFIUM_RELEASE}/${PDFIUM_ARCHIVE_NAME}.tgz ${PDFIUM_RELEASE_DIR}/${PDFIUM_ARCHIVE_NAME}.tgz)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar zxf ${PDFIUM_RELEASE_DIR}/${PDFIUM_ARCHIVE_NAME}.tgz
WORKING_DIRECTORY ${PDFIUM_RELEASE_DIR}
ERROR_QUIET
)
if(STATUS AND NOT STATUS EQUAL 0)
message(FATAL_ERROR "Could not obtain PDFium binary for ${ANDROID_ABI}")
endif()
else()
message(STATUS "Use existing precompiled PDFium." )
endif()
if (NOT EXISTS ${PDFIUM_DEST_LIB_FILENAME})
file(MAKE_DIRECTORY ${PDFIUM_LIBS_ARCH_DIR})
file(COPY ${PDFIUM_SRC_LIB_FILENAME} DESTINATION ${PDFIUM_LIBS_ARCH_DIR})
endif()
# also copy header files for dev use
if (NOT EXISTS ${PDFIUM_LIBS_DIR}/include)
file(COPY ${PDFIUM_RELEASE_DIR}/include DESTINATION ${PDFIUM_LIBS_DIR})
endif()
file(REMOVE ${PDFIUM_LATEST_DIR})
file(CREATE_LINK ${PDFIUM_LIBS_DIR} ${PDFIUM_LATEST_DIR} SYMBOLIC)
find_library(libc++ libc++_static.a)
set(pdfrx_bundled_libraries
# Defined in ../src/CMakeLists.txt.
# This can be changed to accommodate different builds.
$<TARGET_FILE:pdfrx>
${PDFIUM_LASTEST_LIB_FILENAME}
PARENT_SCOPE
)
target_include_directories(pdfrx PRIVATE ${PDFIUM_LATEST_DIR}/include)
target_link_libraries(pdfrx PRIVATE ${PDFIUM_LASTEST_LIB_FILENAME} ${libc++})
// The Android Gradle Plugin builds the native code with the Android NDK.
group 'jp.espresso3389.pdfrx'
version '1.0'
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
// The Android Gradle Plugin knows how to build native code with the NDK.
classpath 'com.android.tools.build:gradle:7.3.0'
}
}
rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
android {
if (project.android.hasProperty("namespace")) {
namespace 'jp.espresso3389.pdfrx'
}
// Bumping the plugin compileSdkVersion requires all clients of this plugin
// to bump the version in their app.
compileSdkVersion 33
// Use the NDK version
// declared in /android/app/build.gradle file of the Flutter project.
// Replace it with a version number if this plugin requires a specfic NDK version.
// (e.g. ndkVersion "23.1.7779620")
ndkVersion android.ndkVersion
// Invoke the shared CMake build with the Android Gradle Plugin.
externalNativeBuild {
cmake {
version "3.18.1+"
path "CMakeLists.txt"
}
}
sourceSets {
main.jniLibs.srcDirs += '.lib/latest'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 21
}
packagingOptions {
pickFirst 'lib/x86/libpdfium.so'
pickFirst 'lib/x86_64/libpdfium.so'
pickFirst 'lib/armeabi-v7a/libpdfium.so'
pickFirst 'lib/arm64-v8a/libpdfium.so'
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.espresso3389.pdfrx">
</manifest>
# SPDX-FileCopyrightText: Copyright 2018 @espresso3389 (Takashi Kawasaki)
# SPDX-FileCopyrightText: Copyright 2024 Noname_1111788
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-License-Identifier: BSD-3-Clause
# The Flutter tooling requires that developers have CMake 3.10 or later
# installed. You should not increase this version, as doing so will cause
# the plugin to fail to compile for some customers of the plugin.
cmake_minimum_required(VERSION 3.10)
# Project-level configuration.
set(PROJECT_NAME "pdfrx")
project(${PROJECT_NAME} LANGUAGES CXX)
if(${PSDK_MAJOR} LESS 5)
message( FATAL_ERROR "Сannot build this project on Aurora version less than 5" )
endif()
# Determine target processor name
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x64|x86_64)")
SET(CPU_NAME "x64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86)")
SET(CPU_NAME "x86")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64|ARM64EC|arm64ec|ARM64E|arm64e)")
SET(CPU_NAME "arm64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM|armv7hl|armv7l|armv7)")
SET(CPU_NAME "arm")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported architecture \"${CMAKE_SYSTEM_PROCESSOR}\"")
ENDIF()
message( STATUS "Target CPU Name: ${CPU_NAME}" )
# Invoke the build for native code shared with the other target platforms.
# This can be changed to accommodate different builds.
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(VERSION 3.14...3.25)
set(PDFIUM_RELEASE chromium%2F6555)
set(PDFIUM_DIR ${CMAKE_BINARY_DIR}/pdfium)
set(PDFIUM_RELEASE_DIR ${PDFIUM_DIR}/${PDFIUM_RELEASE})
file(MAKE_DIRECTORY ${PDFIUM_RELEASE_DIR})
set(PDFIUM_PLATFORM "linux")
set(PDFIUM_LIB_FILENAME "libpdfium.so")
set(PDFIUM_LIB_DIR "lib")
set(PDFIUM_LINUX_ABI ${CPU_NAME})
set(PDFIUM_ARCHIVE_NAME pdfium-${PDFIUM_PLATFORM}-${PDFIUM_LINUX_ABI})
set(PDFIUM_SRC_LIB_FILENAME ${PDFIUM_RELEASE_DIR}/${PDFIUM_LIB_DIR}/${PDFIUM_LIB_FILENAME})
set(PDFIUM_SRC_IMPLIB_FILENAME ${PDFIUM_RELEASE_DIR}/lib/${PDFIUM_LIB_FILENAME}.lib)
set(PDFIUM_LIBS_DIR ${CMAKE_BINARY_DIR}/.lib/${PDFIUM_RELEASE})
set(PDFIUM_LIBS_ARCH_DIR ${PDFIUM_LIBS_DIR}/${PDFIUM_LINUX_ABI})
set(PDFIUM_DEST_LIB_FILENAME ${PDFIUM_LIBS_ARCH_DIR}/${PDFIUM_LIB_FILENAME})
set(PDFIUM_LATEST_DIR ${CMAKE_BINARY_DIR}/.lib/latest)
set(PDFIUM_LATEST_LIBS_ARCH_DIR ${PDFIUM_LATEST_DIR}/${PDFIUM_LINUX_ABI})
set(PDFIUM_LATEST_LIB_FILENAME ${PDFIUM_LATEST_LIBS_ARCH_DIR}/${PDFIUM_LIB_FILENAME})
if(NOT EXISTS ${PDFIUM_SRC_LIB_FILENAME})
message(STATUS "Download precompiled PDFium...")
file(DOWNLOAD https://github.com/bblanchon/pdfium-binaries/releases/download/${PDFIUM_RELEASE}/${PDFIUM_ARCHIVE_NAME}.tgz ${PDFIUM_RELEASE_DIR}/${PDFIUM_ARCHIVE_NAME}.tgz)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar zxf ${PDFIUM_RELEASE_DIR}/${PDFIUM_ARCHIVE_NAME}.tgz
WORKING_DIRECTORY ${PDFIUM_RELEASE_DIR}
ERROR_QUIET
)
if(STATUS AND NOT STATUS EQUAL 0)
message(FATAL_ERROR "Could not obtain PDFium binary for ${PDFIUM_LINUX_ABI}")
endif()
else()
message(STATUS "Use existing precompiled PDFium." )
endif()
if (NOT EXISTS ${PDFIUM_DEST_LIB_FILENAME})
file(MAKE_DIRECTORY ${PDFIUM_LIBS_ARCH_DIR})
file(COPY ${PDFIUM_SRC_LIB_FILENAME} DESTINATION ${PDFIUM_LIBS_ARCH_DIR})
endif()
# also copy header files for dev use
if (NOT EXISTS ${PDFIUM_LIBS_DIR}/include)
file(COPY ${PDFIUM_RELEASE_DIR}/include DESTINATION ${PDFIUM_LIBS_DIR})
endif()
file(REMOVE ${PDFIUM_LATEST_DIR})
file(CREATE_LINK ${PDFIUM_LIBS_DIR} ${PDFIUM_LATEST_DIR} SYMBOLIC)
# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(pdfrx_bundled_libraries
# Defined in ../src/CMakeLists.txt.
# This can be changed to accommodate different builds.
$<TARGET_FILE:pdfrx>
${PDFIUM_LATEST_LIB_FILENAME}
PARENT_SCOPE
)
target_include_directories(pdfrx INTERFACE PRIVATE ${PDFIUM_LATEST_DIR}/include)
target_link_libraries(pdfrx PRIVATE ${PDFIUM_LATEST_LIB_FILENAME})
// Relative import to be able to reuse the C sources.
// See the comment in ../{projectName}}.podspec for more information.
#include "../../src/pdfium_interop.cpp"
#!/bin/zsh -e
SCRIPT_DIR=$(cd $(dirname $0) && pwd)
cd $SCRIPT_DIR
# for iOS/iPhoneSimulator
if [[ ! -d ios/pdfium.xcframework ]]; then
./build-config.sh ios arm64
./build-config.sh iossim arm64
./build-config.sh iossim x64
mkdir -p .tmp/out/lib/iossim-release
lipo -create .tmp/out/lib/iossim-arm64-release/libpdfium.a .tmp/out/lib/iossim-x64-release/libpdfium.a -output .tmp/out/lib/iossim-release/libpdfium.a
mkdir -p ios/
xcodebuild -create-xcframework -library .tmp/out/lib/ios-arm64-release/libpdfium.a -headers .tmp/out/include -library .tmp/out/lib/iossim-release/libpdfium.a -headers .tmp/out/include -output ios/pdfium.xcframework
tar -czvf pdfium-ios.tgz ios
fi
# for macOS
if [[ ! -d macos/pdfium.xcframework ]]; then
./build-config.sh macos arm64
./build-config.sh macos x64
mkdir -p .tmp/out/lib/macos-release
lipo -create .tmp/out/lib/macos-arm64-release/libpdfium.a .tmp/out/lib/macos-x64-release/libpdfium.a -output .tmp/out/lib/macos-release/libpdfium.a
mkdir -p macos/
rm -rf macos/pdfium.xcframework
xcodebuild -create-xcframework -library .tmp/out/lib/macos-release/libpdfium.a -headers .tmp/out/include -output macos/pdfium.xcframework
tar -czvf pdfium-macos.tgz macos
fi
#!/bin/zsh -e
if [ "$2" = "" ]; then
echo "Usage: $0 linux|android|macos|ios|iossim x86|x64|arm|arm64"
exit 1
fi
# https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/6555
LAST_KNOWN_GOOD_COMMIT=5a6a8741b0e111a6b5bd9ab4e1036377c98885dc
SCRIPT_DIR=$(cd $(dirname $0) && pwd)
# linux, android, macos, ios
TARGET_OS_ORIG=$1
# x64, x86, arm64, ...
TARGET_ARCH=$2
# static or dll
STATIC_OR_DLL=static
# release or debug
REL_OR_DBG=release
if [[ "$TARGET_OS_ORIG" == "iossim" ]]; then
TARGET_OS=ios
TARGET_ENVIRONMENT=simulator
elif [[ "$TARGET_OS_ORIG" == "macos" ]]; then
TARGET_OS=mac
else
TARGET_OS=$TARGET_OS_ORIG
# only for ios; simulator or device
TARGET_ENVIRONMENT=device
fi
WORK_ROOT_DIR=$SCRIPT_DIR/.tmp
DIST_DIR=$WORK_ROOT_DIR/out
DEPOT_DIR=$WORK_ROOT_DIR/depot_tools
WORK_DIR=$WORK_ROOT_DIR/work
mkdir -p $WORK_ROOT_DIR $WORK_DIR $DIST_DIR
if [[ ! -d $DEPOT_DIR ]]; then
pushd $WORK_ROOT_DIR
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
popd
fi
export PATH=$DEPOT_DIR:$PATH
IS_SHAREDLIB=false
if [[ "$REL_OR_DBG" = "release" ]]; then
IS_DEBUG=false
DEBUG_DIR_SUFFIX=
else
IS_DEBUG=true
DEBUG_DIR_SUFFIX=/debug
fi
if [[ "$TARGET_OS" == "macos" || "$TARGET_OS" == "ios" || "$TARGET_OS" == "android" ]]; then
IS_CLANG=true
else
IS_CLANG=false
fi
cd $WORK_DIR
if [[ ! -e pdfium/.git/index ]]; then
fetch pdfium
fi
PDFIUM_SRCDIR=$WORK_DIR/pdfium
BUILDDIR=$PDFIUM_SRCDIR/out/$TARGET_OS_ORIG-$TARGET_ARCH-$REL_OR_DBG
mkdir -p $BUILDDIR
if [[ "$LAST_KNOWN_GOOD_COMMIT" != "" ]]; then
pushd $PDFIUM_SRCDIR
git reset --hard
git checkout $LAST_KNOWN_GOOD_COMMIT
cd $PDFIUM_SRCDIR/build
git reset --hard
cd $PDFIUM_SRCDIR/third_party/libjpeg_turbo
git reset --hard
popd
fi
INCLUDE_DIR=$DIST_DIR/include
if [[ ! -d $INCLUDE_DIR ]]; then
mkdir -p $INCLUDE_DIR
cp -r $PDFIUM_SRCDIR/public/* $INCLUDE_DIR
fi
if [[ "$TARGET_OS" == "ios" ]]; then
# (cd $PDFIUM_SRCDIR && git diff > ../../../patches/ios/pdfium.patch)
pushd $PDFIUM_SRCDIR
git apply --reject --whitespace=fix $SCRIPT_DIR/patches/ios/pdfium.patch
popd
# (cd $PDFIUM_SRCDIR/third_party/libjpeg_turbo && git diff > ../../../../../patches/ios/libjpeg_turbo.patch)
pushd $PDFIUM_SRCDIR/third_party/libjpeg_turbo/
git apply --reject --whitespace=fix $SCRIPT_DIR/patches/ios/libjpeg_turbo.patch
popd
fi
if [[ "$TARGET_OS" == "mac" ]]; then
# (cd $PDFIUM_SRCDIR && git diff > ../../../patches/macos/pdfium.patch)
pushd $PDFIUM_SRCDIR
git apply --reject --whitespace=fix $SCRIPT_DIR/patches/macos/pdfium.patch
popd
# (cd $PDFIUM_SRCDIR/build && git diff > ../../../../patches/macos/build-config.patch)
pushd $PDFIUM_SRCDIR/build
git apply --reject --whitespace=fix $SCRIPT_DIR/patches/macos/build-config.patch
popd
fi
cat <<EOF > $BUILDDIR/args.gn
is_clang = $IS_CLANG
target_os = "$TARGET_OS"
target_cpu = "$TARGET_ARCH"
pdf_is_complete_lib = true
pdf_is_standalone = true
is_component_build = $IS_SHAREDLIB
is_debug = $IS_DEBUG
enable_iterator_debugging = $IS_DEBUG
pdf_enable_xfa = false
pdf_enable_v8 = false
EOF
if [[ "$TARGET_OS" == "ios" ]]; then
# See ios/pdfium/.tmp/work/pdfium/build/config/ios/rules.gni
cat <<EOF >> $BUILDDIR/args.gn
ios_enable_code_signing = false
ios_deployment_target = "12.0"
use_custom_libcxx = false
pdf_use_partition_alloc = false
target_environment = "$TARGET_ENVIRONMENT"
EOF
fi
if [[ "$TARGET_OS" == "mac" ]]; then
cat <<EOF >> $BUILDDIR/args.gn
use_custom_libcxx = false
pdf_use_partition_alloc = false
EOF
fi
pushd $BUILDDIR
gn gen .
popd
ninja -C $BUILDDIR pdfium
LIB_DIR=$DIST_DIR/lib/$TARGET_OS_ORIG-$TARGET_ARCH-$REL_OR_DBG
rm -rf $LIB_DIR
mkdir -p $LIB_DIR
cp $BUILDDIR/obj/libpdfium.a $LIB_DIR
cd $SCRIPT_DIR
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint pdfrx.podspec` to validate before publishing.
#
lib_tag = 'pdfium-apple-v9'
Pod::Spec.new do |s|
s.name = 'pdfrx'
s.version = '0.0.3'
s.summary = 'Yet another PDF renderer for Flutter using PDFium.'
s.description = <<-DESC
Yet another PDF renderer for Flutter using PDFium.
DESC
s.homepage = 'https://github.com/espresso3389/pdfrx'
s.license = { :type => 'BSD', :file => '../LICENSE' }
s.author = { 'Takashi Kawasaki' => 'espresso3389@gmail.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.ios.deployment_target = '12.0'
s.ios.dependency 'Flutter'
s.ios.private_header_files = "pdfium/.lib/#{lib_tag}/ios/pdfium.xcframework/ios-arm64/Headers/*.h"
s.ios.vendored_frameworks = "pdfium/.lib/#{lib_tag}/ios/pdfium.xcframework"
# Flutter.framework does not contain a i386 slice.
s.ios.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES',
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
}
s.osx.deployment_target = '10.11'
s.osx.dependency 'FlutterMacOS'
s.osx.private_header_files = "pdfium/.lib/#{lib_tag}/macos/pdfium.xcframework/macos-arm64_x86_64/Headers/*.h"
s.osx.vendored_frameworks = "pdfium/.lib/#{lib_tag}/macos/pdfium.xcframework"
s.osx.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
s.prepare_command = <<-CMD
mkdir -p pdfium/.lib/#{lib_tag}
cd pdfium/.lib/#{lib_tag}
if [ ! -f ios.tgz ]; then
curl -Lo ios.tgz https://github.com/espresso3389/pdfrx/releases/download/#{lib_tag}/pdfium-ios.tgz
fi
if [ ! -d ios ]; then
tar xzf ios.tgz
fi
if [ ! -f macos.tgz ]; then
curl -Lo macos.tgz https://github.com/espresso3389/pdfrx/releases/download/#{lib_tag}/pdfium-macos.tgz
fi
if [ ! -d macos ]; then
tar xzf macos.tgz
fi
CMD
s.swift_version = '5.0'
end
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/pubspec.lock
/windows/flutter
/linux/flutter
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
/android/local.properties
# Aurora generated
/aurora/flutter
/windows/flutter
/macos/Flutter
/linux/flutter
/android/local.properties
/macos/Podfile.lock
# pdfrx_example
Demonstrates how to use the pdfrx plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
package jp.espresso3389.pdfrx_example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "jp.espresso3389.pdfrx_example"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "jp.espresso3389.pdfrx_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {}
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать