Skip to content

Commit

Permalink
Resolves #140
Browse files Browse the repository at this point in the history
  • Loading branch information
Alastair Carey committed Mar 9, 2024
1 parent 213c029 commit 8a69fc7
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pdfium-render"
version = "0.8.18"
version = "0.8.19"
edition = "2018"
publish = true
description = "A high-level idiomatic Rust wrapper around Pdfium, the C++ PDF library used by the Google Chromium project."
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,14 @@ available at <https://github.com/ajrcarey/pdfium-render/tree/master/examples>. T
_Note: upcoming release 0.9.0 will remove all deprecated items. For a complete list of deprecated
items, see <https://github.com/ajrcarey/pdfium-render/issues/36>._

Release 0.8.19 adds support for creating new annotations, positioning those annotations,
Release 0.8.20 adds support for creating new annotations, positioning those annotations,
associating them with page objects, and retrieving and setting more annotation properties for each
annotation type. A new `examples/create_annotations.rs` example demonstrates the extended functionality.

Release 0.8.19 fixes a bug in `PdfPage::flatten()` that prevented the effect of the flatten operation
from taking effect until the page was dropped and reloaded. The effect of the flatten operation
is now immediately available.

Releases 0.8.17 and 0.8.18 adjust the WASM implementation of `pdfium-render` to account for some small packaging
changes in the upstream releases of Pdfium published at <https://github.com/paulocoutinhox/pdfium-lib/releases>;
release 0.8.17 also fixes a potential segmentation fault that could occur when dropping a `PdfDocument`
Expand Down Expand Up @@ -345,7 +349,7 @@ functions specific to interactive scripting, user interaction, and printing.
* Releases numbered 0.8.x aim to progressively add support for all remaining Pdfium editing functions to `pdfium-render`.
* Releases numbered 0.9.x aim to fill any remaining gaps in the high-level interface prior to 1.0.

There are 368 `FPDF_*` functions in the Pdfium API. As of version 0.8.18, 325 (88%) have
There are 368 `FPDF_*` functions in the Pdfium API. As of version 0.8.19, 325 (88%) have
bindings available in `PdfiumLibraryBindings`, with the functionality of the majority of these
available via the `pdfium-render` high-level interface.

Expand All @@ -358,7 +362,7 @@ at <https://github.com/ajrcarey/pdfium-render/issues>.

## Version history

* 0.8.19: adds `PdfPageAnnotationAttachmentPoints` struct and matching iterator; adds new annotation functions
* 0.8.20: adds `PdfPageAnnotationAttachmentPoints` struct and matching iterator; adds new annotation functions
to `PdfPageAnnotationCommon` along with their matching implementations in `PdfPageAnnotationPrivate`,
including `PdfPageAnnotationCommon::set_bounds()`, `PdfPageAnnotationCommon::set_position()`,
`PdfPageAnnotationCommon::set_width()`, `PdfPageAnnotationCommon::set_height()`,
Expand All @@ -369,7 +373,11 @@ at <https://github.com/ajrcarey/pdfium-render/issues>.
`chrono::DateTime` types to PDF date strings in `utils::dates`; adds mutability and annotation
creation functions to `PdfPageAnnotations` collection; adds new `create_annotations.rs` example;
adds `PdfPageTextSegment::chars()` convenience function.
* 0.8.18: Adjusts `PdfiumRenderWasmState::bind_to_pdfium()` to fall back to
* 0.8.19: adjusts the behaviour of `PdfPage::flatten()` so that the page is reloaded after the
call to `FPDFPage_Flatten()`. This ensures that the effect of the flatten operation is immediately
visible to the caller; previously, it was necessary for the caller to drop and reload the page
themselves. For more details, see <https://github.com/ajrcarey/pdfium-render/issues/140>.
* 0.8.18: adjusts `PdfiumRenderWasmState::bind_to_pdfium()` to fall back to
`Module["wasmExports"]["__indirect_function_table"]` if `Window.wasmTable` global variable is
not available, in response to upstream packaging changes at
<https://github.com/paulocoutinhox/pdfium-lib/releases>. For more details, see
Expand Down
50 changes: 32 additions & 18 deletions src/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,22 +849,7 @@ impl<'a> PdfPage<'a> {
// transformation to take effect. For more information, see:
// https://github.com/ajrcarey/pdfium-render/issues/93

if let Some(page_index) =
PdfPageIndexCache::get_index_for_page(self.document_handle, self.page_handle)
{
self.drop_impl();

self.page_handle = self
.bindings
.FPDF_LoadPage(self.document_handle, page_index as c_int);

PdfPageIndexCache::set_index_for_page(
self.document_handle,
self.page_handle,
page_index,
);
}

self.reload_in_place();
Ok(())
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
Expand Down Expand Up @@ -915,9 +900,16 @@ impl<'a> PdfPage<'a> {
.FPDFPage_Flatten(self.page_handle, flag as c_int) as u32
{
FLATTEN_SUCCESS => {
self.is_content_regeneration_required = true;
self.regenerate_content()?;

self.regenerate_content()
// As noted at https://bugs.chromium.org/p/pdfium/issues/detail?id=2055,
// FPDFPage_Flatten() updates the underlying dictionaries and content streams for
// the page, but does not update the FPDF_Page structure. We must reload the
// page for the effects of the flatten operation to be visible. For more information, see:
// https://github.com/ajrcarey/pdfium-render/issues/140

self.reload_in_place();
Ok(())
}
FLATTEN_NOTHINGTODO => Ok(()),
FLATTEN_FAIL => Err(PdfiumError::PageFlattenFailure),
Expand Down Expand Up @@ -1025,6 +1017,28 @@ impl<'a> PdfPage<'a> {
}
}

/// Reloads the page transparently to any caller, forcing a refresh of all page data structures.
/// This will replace this page's `FPDF_PAGE` handle. The page index cache will be updated.
fn reload_in_place(&mut self) {
if let Some(page_index) =
PdfPageIndexCache::get_index_for_page(self.document_handle, self.page_handle)
{
self.drop_impl();

self.page_handle = self
.bindings
.FPDF_LoadPage(self.document_handle, page_index as c_int);

PdfPageIndexCache::set_index_for_page(
self.document_handle,
self.page_handle,
page_index,
);
}
}

/// Drops the page by calling `FPDF_ClosePage()`, freeing held memory. This will invalidate
/// this page's `FPDF_PAGE` handle. The page index cache will be updated.
fn drop_impl(&mut self) {
if self.regeneration_strategy != PdfPageContentRegenerationStrategy::Manual
&& self.is_content_regeneration_required
Expand Down

0 comments on commit 8a69fc7

Please # to comment.