summaryrefslogtreecommitdiff
path: root/crates/typst-pdf
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-02-14 15:41:46 +0100
committerGitHub <noreply@github.com>2024-02-14 14:41:46 +0000
commit601118652de5b3151e96eba3c0c8c285f3fab8fd (patch)
tree2327ecc5020d9a9c410cf6ae0f03964af8d05ac9 /crates/typst-pdf
parentb89348b92a9c1ae67a4bb69a6db69d14f881384d (diff)
Share resource dictionary via indirect object instead of inheritance (#3414)
Diffstat (limited to 'crates/typst-pdf')
-rw-r--r--crates/typst-pdf/src/page.rs27
1 files changed, 20 insertions, 7 deletions
diff --git a/crates/typst-pdf/src/page.rs b/crates/typst-pdf/src/page.rs
index ddcfe50f..41381777 100644
--- a/crates/typst-pdf/src/page.rs
+++ b/crates/typst-pdf/src/page.rs
@@ -6,7 +6,7 @@ use pdf_writer::types::{
ActionType, AnnotationFlags, AnnotationType, ColorSpaceOperand, LineCapStyle,
LineJoinStyle, NumberingStyle,
};
-use pdf_writer::writers::PageLabel;
+use pdf_writer::writers::{PageLabel, Resources};
use pdf_writer::{Content, Filter, Finish, Name, Rect, Ref, Str, TextStr};
use typst::introspection::Meta;
use typst::layout::{
@@ -85,16 +85,27 @@ pub(crate) fn construct_page(ctx: &mut PdfContext, frame: &Frame) -> (Ref, Encod
/// Write the page tree.
pub(crate) fn write_page_tree(ctx: &mut PdfContext) {
+ let resources_ref = write_global_resources(ctx);
+
for i in 0..ctx.pages.len() {
- write_page(ctx, i);
+ write_page(ctx, i, resources_ref);
}
- let mut pages = ctx.pdf.pages(ctx.page_tree_ref);
- pages
+ ctx.pdf
+ .pages(ctx.page_tree_ref)
.count(ctx.page_refs.len() as i32)
.kids(ctx.page_refs.iter().copied());
+}
- let mut resources = pages.resources();
+/// Write the global resource dictionary that will be referenced by all pages.
+///
+/// We add a reference to this dictionary to each page individually instead of
+/// to the root node of the page tree because using the resource inheritance
+/// feature breaks PDF merging with Apple Preview.
+fn write_global_resources(ctx: &mut PdfContext) -> Ref {
+ let resource_ref = ctx.alloc.bump();
+
+ let mut resources = ctx.pdf.indirect(resource_ref).start::<Resources>();
ctx.colors
.write_color_spaces(resources.color_spaces(), &mut ctx.alloc);
@@ -135,14 +146,15 @@ pub(crate) fn write_page_tree(ctx: &mut PdfContext) {
ext_gs_states.finish();
resources.finish();
- pages.finish();
// Write all of the functions used by the document.
ctx.colors.write_functions(&mut ctx.pdf);
+
+ resource_ref
}
/// Write a page tree node.
-fn write_page(ctx: &mut PdfContext, i: usize) {
+fn write_page(ctx: &mut PdfContext, i: usize, resources_ref: Ref) {
let page = &ctx.pages[i];
let content_id = ctx.alloc.bump();
@@ -153,6 +165,7 @@ fn write_page(ctx: &mut PdfContext, i: usize) {
let h = page.size.y.to_f32();
page_writer.media_box(Rect::new(0.0, 0.0, w, h));
page_writer.contents(content_id);
+ page_writer.pair(Name(b"Resources"), resources_ref);
if page.uses_opacities {
page_writer