Skip to content

Commit

Permalink
0.4.25
Browse files Browse the repository at this point in the history
  • Loading branch information
espresso3389 committed Jan 26, 2024
1 parent f3b3a9e commit ee3494c
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 77 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.4.25

- FIXED: Able to scroll outside document area

# 0.4.24

- Huge refactoring on PdfViewerController; it's no longer TransformationController but just a ValueListenable<Matrix4>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Add this to your package's `pubspec.yaml` file and execute `flutter pub get`:

```yaml
dependencies:
pdfrx: ^0.4.24
pdfrx: ^0.4.25
```
### Windows
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.4.24"
version: "0.4.25"
platform:
dependency: transitive
description:
Expand Down
71 changes: 71 additions & 0 deletions lib/src/pdf_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,14 @@ abstract class PdfPageText {
/// Find text fragment index for the specified text index.
int getFragmentIndexForTextIndex(int textIndex) => fragments.lowerBound(
_PdfPageTextFragmentForSearch(textIndex), (a, b) => a.index - b.index);

/// Search text with [pattern].
Stream<PdfTextSearchResult> search(Pattern pattern) async* {
final matches = pattern.allMatches(fullText);
for (final match in matches) {
yield PdfTextSearchResult.fromTextRange(this, match.start, match.end);
}
}
}

/// Text fragment in PDF page.
Expand Down Expand Up @@ -417,6 +425,69 @@ class _PdfPageTextFragmentForSearch extends PdfPageTextFragment {
List<PdfRect>? get charRects => null;
}

class PdfTextSearchResult {
PdfTextSearchResult(this.fragments, this.start, this.end, this.bounds);

final List<PdfPageTextFragment> fragments;
final int start;
final int end;
final PdfRect bounds;

static PdfTextSearchResult fromTextRange(PdfPageText pageText, int a, int b) {
// basically a should be less than or equal to b, but we anyway swap them if not
if (a > b) {
final temp = a;
a = b;
b = temp;
}
final s = pageText.getFragmentIndexForTextIndex(a);
final e = pageText.getFragmentIndexForTextIndex(b);
final sf = pageText.fragments[s];
if (s == e) {
if (sf.charRects == null) {
return PdfTextSearchResult(
pageText.fragments.sublist(s, e),
a - sf.index,
b - sf.index,
sf.bounds,
);
} else {
return PdfTextSearchResult(
pageText.fragments.sublist(s, e),
a - sf.index,
b - sf.index,
sf.charRects!.skip(a - sf.index).take(b - a).boundingRect(),
);
}
}

var bounds = sf.charRects != null
? sf.charRects!.skip(a - sf.index).boundingRect()
: sf.bounds;
for (int i = s + 1; i < e; i++) {
bounds = bounds.merge(pageText.fragments[i].bounds);
}
final ef = pageText.fragments[e];
bounds = bounds.merge(ef.charRects != null
? ef.charRects!.take(b - ef.index).boundingRect()
: ef.bounds);

return PdfTextSearchResult(
pageText.fragments.sublist(s, e), s - sf.index, e - ef.index, bounds);
}
}

/// Extension to provide search over document feature.
extension PdfDocumentSearchExt on PdfDocument {
/// Search text with [pattern].
Stream<PdfTextSearchResult> search(Pattern pattern) async* {
for (final page in pages) {
final text = await page.loadText();
yield* text.search(pattern);
}
}
}

/// Rectangle in PDF page coordinates.
///
/// Please note that PDF page coordinates is different from Flutter's coordinate.
Expand Down
91 changes: 17 additions & 74 deletions lib/src/widgets/pdf_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ class PdfViewer extends StatefulWidget {
class _PdfViewerState extends State<PdfViewer>
with SingleTickerProviderStateMixin {
PdfViewerController? _controller;
final TransformationController _txController = TransformationController();
late final TransformationController _txController =
_PdfViewerTransformationController(this);
late final AnimationController _animController;
Animation<Matrix4>? _animGoTo;
int _animationResettingGuard = 0;
Expand Down Expand Up @@ -1149,6 +1150,17 @@ class _PdfViewerState extends State<PdfViewer>
.translate(_txController.value.xZoomed, _txController.value.yZoomed));
}

class _PdfViewerTransformationController extends TransformationController {
_PdfViewerTransformationController(this._state);

final _PdfViewerState _state;

@override
set value(Matrix4 newValue) {
super.value = _state._makeMatrixInSafeRange(newValue);
}
}

/// Defines page layout.
class PdfPageLayout {
PdfPageLayout({required this.pageLayouts, required this.documentSize});
Expand Down Expand Up @@ -1375,7 +1387,7 @@ class PdfViewerController extends ValueListenable<Matrix4> {
}
}

extension Matrix4Ext on Matrix4 {
extension PdfMatrix4Ext on Matrix4 {
/// Zoom ratio of the matrix.
double get zoom => storage[0];

Expand Down Expand Up @@ -1409,14 +1421,15 @@ extension Matrix4Ext on Matrix4 {
height: (viewSize.height - margin * 2) / zoom);
}

extension RangeDouble<T extends num> on T {
extension _RangeDouble<T extends num> on T {
/// Identical to [num.clamp] but it does nothing if [a] is larger or equal to [b].
T range(T a, T b) => a < b ? clamp(a, b) as T : (a + b) / 2 as T;
}

extension RectExt on Rect {
Rect operator *(double operand) => Rect.fromLTRB(
left * operand, top * operand, right * operand, bottom * operand);

Rect operator /(double operand) => Rect.fromLTRB(
left / operand, top / operand, right / operand, bottom / operand);

Expand Down Expand Up @@ -1444,77 +1457,7 @@ class _CustomPainter extends CustomPainter {
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

class PdfPageTextSearcher {
PdfPageTextSearcher._(this._state);
final _PdfViewerState _state;

Stream<PdfTextSearchResult> search(RegExp pattern) async* {
final pages = _state._document!.pages;
for (int i = 0; i < pages.length; i++) {
final page = pages[i];
final pageText = await page.loadText();
final matches = pattern.allMatches(pageText.fullText);
for (final match in matches) {
yield PdfTextSearchResult.fromTextRange(
pageText, match.start, match.end);
}
}
}
}

class PdfTextSearchResult {
PdfTextSearchResult(this.fragments, this.start, this.end, this.bounds);

final List<PdfPageTextFragment> fragments;
final int start;
final int end;
final PdfRect bounds;

static PdfTextSearchResult fromTextRange(PdfPageText pageText, int a, int b) {
// basically a should be less than or equal to b, but we anyway swap them if not
if (a > b) {
final temp = a;
a = b;
b = temp;
}
final s = pageText.getFragmentIndexForTextIndex(a);
final e = pageText.getFragmentIndexForTextIndex(b);
final sf = pageText.fragments[s];
if (s == e) {
if (sf.charRects == null) {
return PdfTextSearchResult(
pageText.fragments.sublist(s, e),
a - sf.index,
b - sf.index,
sf.bounds,
);
} else {
return PdfTextSearchResult(
pageText.fragments.sublist(s, e),
a - sf.index,
b - sf.index,
sf.charRects!.skip(a - sf.index).take(b - a).boundingRect(),
);
}
}

var bounds = sf.charRects != null
? sf.charRects!.skip(a - sf.index).boundingRect()
: sf.bounds;
for (int i = s + 1; i < e; i++) {
bounds = bounds.merge(pageText.fragments[i].bounds);
}
final ef = pageText.fragments[e];
bounds = bounds.merge(ef.charRects != null
? ef.charRects!.take(b - ef.index).boundingRect()
: ef.bounds);

return PdfTextSearchResult(
pageText.fragments.sublist(s, e), s - sf.index, e - ef.index, bounds);
}
}

extension RawKeyEventExt on RawKeyEvent {
extension _RawKeyEventExt on RawKeyEvent {
/// Key pressing state of ⌘ or Control depending on the platform.
bool get isCommandKeyPressed =>
Platform.isMacOS || Platform.isIOS ? isMetaPressed : isControlPressed;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: pdfrx
description: High speed zooming/scrolling PDF viewer implementation that supports mobile, desktop, and Web.
version: 0.4.24
version: 0.4.25
homepage: https://github.com/espresso3389/pdfrx

environment:
Expand Down

0 comments on commit ee3494c

Please sign in to comment.