summaryrefslogtreecommitdiff
path: root/src/export/pdf
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2023-05-02 13:53:20 +0200
committerGitHub <noreply@github.com>2023-05-02 13:53:20 +0200
commit17cef8dcee022ca89ccef62eaec23ff6c0e4cdf9 (patch)
tree253ea22f94ac90f0df91d6e20758ecc9d7271ce8 /src/export/pdf
parent021694de239ca5d6d799dde98423036bb1da405e (diff)
Add ICC profiles to images in PDF and update `usvg`, `svg2pdf` (#822)
Diffstat (limited to 'src/export/pdf')
-rw-r--r--src/export/pdf/image.rs22
-rw-r--r--src/export/pdf/outline.rs2
-rw-r--r--src/export/pdf/page.rs4
3 files changed, 23 insertions, 5 deletions
diff --git a/src/export/pdf/image.rs b/src/export/pdf/image.rs
index 04d4dcc3..dcd5a45a 100644
--- a/src/export/pdf/image.rs
+++ b/src/export/pdf/image.rs
@@ -11,6 +11,7 @@ use crate::image::{DecodedImage, RasterFormat};
pub fn write_images(ctx: &mut PdfContext) {
for image in ctx.image_map.items() {
let image_ref = ctx.alloc.bump();
+ let icc_ref = ctx.alloc.bump();
ctx.image_refs.push(image_ref);
let width = image.width();
@@ -19,7 +20,7 @@ pub fn write_images(ctx: &mut PdfContext) {
// Add the primary image.
// TODO: Error if image could not be encoded.
match image.decoded() {
- DecodedImage::Raster(dynamic, format) => {
+ DecodedImage::Raster(dynamic, icc, format) => {
// TODO: Error if image could not be encoded.
let (data, filter, has_color) = encode_image(*format, dynamic).unwrap();
let mut image = ctx.writer.image_xobject(image_ref, &data);
@@ -29,7 +30,9 @@ pub fn write_images(ctx: &mut PdfContext) {
image.bits_per_component(8);
let space = image.color_space();
- if has_color {
+ if icc.is_some() {
+ space.icc_based(icc_ref);
+ } else if has_color {
space.device_rgb();
} else {
space.device_gray();
@@ -49,6 +52,21 @@ pub fn write_images(ctx: &mut PdfContext) {
mask.height(height as i32);
mask.color_space().device_gray();
mask.bits_per_component(8);
+ } else {
+ image.finish();
+ }
+
+ if let Some(icc) = icc {
+ let compressed = deflate(&icc.0);
+ let mut stream = ctx.writer.icc_profile(icc_ref, &compressed);
+ stream.filter(Filter::FlateDecode);
+ if has_color {
+ stream.n(3);
+ stream.alternate().srgb();
+ } else {
+ stream.n(1);
+ stream.alternate().d65_gray();
+ }
}
}
DecodedImage::Svg(svg) => {
diff --git a/src/export/pdf/outline.rs b/src/export/pdf/outline.rs
index f8f12d71..c156ecaf 100644
--- a/src/export/pdf/outline.rs
+++ b/src/export/pdf/outline.rs
@@ -118,7 +118,7 @@ fn write_outline_item(
let index = pos.page.get() - 1;
if let Some(&height) = ctx.page_heights.get(index) {
let y = (pos.point.y - Abs::pt(10.0)).max(Abs::zero());
- outline.dest_direct().page(ctx.page_refs[index]).xyz(
+ outline.dest().page(ctx.page_refs[index]).xyz(
pos.point.x.to_f32(),
height - y.to_f32(),
None,
diff --git a/src/export/pdf/page.rs b/src/export/pdf/page.rs
index acf5062e..35a4f5dc 100644
--- a/src/export/pdf/page.rs
+++ b/src/export/pdf/page.rs
@@ -139,7 +139,7 @@ fn write_page(ctx: &mut PdfContext, page: Page) {
annotation
.action()
.action_type(ActionType::GoTo)
- .destination_direct()
+ .destination()
.page(ctx.page_refs[index])
.xyz(pos.point.x.to_f32(), height - y.to_f32(), None);
}
@@ -499,7 +499,7 @@ fn write_image(ctx: &mut PageContext, x: f32, y: f32, image: &Image, size: Size)
if let Some(alt) = image.alt() {
let mut image_span =
ctx.content.begin_marked_content_with_properties(Name(b"Span"));
- let mut image_alt = image_span.properties_direct();
+ let mut image_alt = image_span.properties();
image_alt.pair(Name(b"Alt"), pdf_writer::Str(alt.as_bytes()));
image_alt.finish();
image_span.finish();