Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: scale imported pdf pages uniformly by the widest page
Also enable the "Page Spacing" option when "Adjust Document" is active.
  • Loading branch information
alberto-is committed Sep 11, 2026
commit c01b8db1e521c72546b970619d76e6cea3ae397b
52 changes: 35 additions & 17 deletions crates/rnote-engine/src/strokes/bitmapimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,24 @@ impl BitmapImage {
format.width() * (pdf_import_prefs.page_width_perc / 100.0)
};

// calculate the page zoom based on the width of the first page.
let page_zoom = if let Some(first_page) = pages.first() {
page_width / first_page.render_dimensions().0 as f64
} else {
// Uniform zoom based on the widest page, keeps relative page sizes.
let max_intrinsic_width = page_range
.clone()
.filter_map(|page_i| pages.get(page_i))
.map(|page| page.render_dimensions().0 as f64)
.fold(0.0f64, f64::max);
if max_intrinsic_width <= 0.0 {
return Ok(vec![]);
};
}
let page_zoom_fit = page_width / max_intrinsic_width;

// Stride for OnePerDocumentPage: start each page on a document page boundary.
let max_rendered_height = page_range
.clone()
.filter_map(|page_i| pages.get(page_i))
.map(|page| page.render_dimensions().1 as f64 * page_zoom_fit)
.fold(0.0f64, f64::max);

let x = insert_pos[0];
let mut y = insert_pos[1];

Expand All @@ -171,11 +183,11 @@ impl BitmapImage {
let dimensions = page.render_dimensions();
(dimensions.0 as f64, dimensions.1 as f64)
};
let width = intrinsic_width * page_zoom;
let height = intrinsic_height * page_zoom;
let width = intrinsic_width * page_zoom_fit;
let height = intrinsic_height * page_zoom_fit;
let render_settings = hayro::RenderSettings {
x_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom) as f32,
y_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom) as f32,
x_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom_fit) as f32,
y_scale: (pdf_import_prefs.bitmap_scalefactor * page_zoom_fit) as f32,
width: Some((pdf_import_prefs.bitmap_scalefactor * width).ceil() as u16),
height: Some((pdf_import_prefs.bitmap_scalefactor * height).ceil() as u16),
bg_color: vello_cpu::color::AlphaColor::WHITE,
Expand All @@ -189,16 +201,22 @@ impl BitmapImage {
let image_pos = Vector2::new(x, y);
let image_size = Vector2::new(width, height);

if pdf_import_prefs.adjust_document {
y += height
} else {
y += match pdf_import_prefs.page_spacing {
PdfImportPageSpacing::Continuous => {
y += match pdf_import_prefs.page_spacing {
PdfImportPageSpacing::Continuous => {
if pdf_import_prefs.adjust_document {
height
} else {
height + Stroke::IMPORT_OFFSET_DEFAULT[1] * 0.5
}
PdfImportPageSpacing::OnePerDocumentPage => format.height(),
};
}
}
PdfImportPageSpacing::OnePerDocumentPage => {
if pdf_import_prefs.adjust_document {
max_rendered_height
} else {
format.height()
}
}
};

Ok((png_data, image_pos, image_size))
})
Expand Down
48 changes: 33 additions & 15 deletions crates/rnote-engine/src/strokes/vectorimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,24 @@ impl VectorImage {
format.width() * (pdf_import_prefs.page_width_perc / 100.0)
};

// calculate the page zoom based on the width of the first page.
let page_zoom = if let Some(first_page) = pages.first() {
page_width / first_page.render_dimensions().0 as f64
} else {
// Uniform zoom based on the widest page, keeps relative page sizes.
let max_intrinsic_width = page_range
.clone()
.filter_map(|page_i| pages.get(page_i))
.map(|page| page.render_dimensions().0 as f64)
.fold(0.0f64, f64::max);
if max_intrinsic_width <= 0.0 {
return Ok(vec![]);
};
}
let page_zoom_fit = page_width / max_intrinsic_width;

// Stride for OnePerDocumentPage: start each page on a document page boundary.
let max_rendered_height = page_range
.clone()
.filter_map(|page_i| pages.get(page_i))
.map(|page| page.render_dimensions().1 as f64 * page_zoom_fit)
.fold(0.0f64, f64::max);

let x = insert_pos[0];
let mut y = insert_pos[1];

Expand All @@ -251,20 +263,26 @@ impl VectorImage {
let dimensions = page.render_dimensions();
(dimensions.0 as f64, dimensions.1 as f64)
};
let width = intrinsic_width * page_zoom;
let height = intrinsic_height * page_zoom;
let width = intrinsic_width * page_zoom_fit;
let height = intrinsic_height * page_zoom_fit;
let bounds = Aabb::new(Vector2::new(x, y), Vector2::new(x + width, y + height));

if pdf_import_prefs.adjust_document {
y += height
} else {
y += match pdf_import_prefs.page_spacing {
PdfImportPageSpacing::Continuous => {
y += match pdf_import_prefs.page_spacing {
PdfImportPageSpacing::Continuous => {
if pdf_import_prefs.adjust_document {
height
} else {
height + Stroke::IMPORT_OFFSET_DEFAULT[1] * 0.5
}
PdfImportPageSpacing::OnePerDocumentPage => format.height(),
};
}
}
PdfImportPageSpacing::OnePerDocumentPage => {
if pdf_import_prefs.adjust_document {
max_rendered_height
} else {
format.height()
}
}
};
let svg_data = hayro_svg::convert(page, &interpreter_settings, &render_settings);
let svg = Svg { svg_data, bounds };

Expand Down
5 changes: 0 additions & 5 deletions crates/rnote-ui/src/dialogs/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,6 @@ pub(crate) async fn dialog_import_pdf_w_prefs(
.invert_boolean()
.sync_create()
.build();
pdf_import_adjust_document_row
.bind_property("active", &pdf_import_page_spacing_row, "sensitive")
.invert_boolean()
.sync_create()
.build();

let pdf_import_prefs = appwindow
.engine_config()
Expand Down