Skip to content

Commit

Permalink
make orientation toggle usable with custom doc format
Browse files Browse the repository at this point in the history
  • Loading branch information
flxzt committed Sep 10, 2023
1 parent f65efa1 commit e827934
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 192 deletions.
60 changes: 54 additions & 6 deletions crates/rnote-engine/src/document/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ impl TryFrom<u32> for PredefinedFormat {
}

impl PredefinedFormat {
pub fn size_portrait_mm(&self) -> Option<(f64, f64)> {
match self {
pub fn size_mm(&self, orientation: Orientation) -> Option<na::Vector2<f64>> {
let mut size_portrait = match self {
PredefinedFormat::A6 => Some((105.0, 148.0)),
PredefinedFormat::A5 => Some((148.0, 210.0)),
PredefinedFormat::A4 => Some((210.0, 297.0)),
Expand All @@ -63,7 +63,13 @@ impl PredefinedFormat {
PredefinedFormat::UsLetter => Some((215.9, 279.4)),
PredefinedFormat::UsLegal => Some((215.9, 355.6)),
PredefinedFormat::Custom => None,
};
if let Some(size_portrait) = &mut size_portrait {
if orientation == Orientation::Landscape {
std::mem::swap(&mut size_portrait.0, &mut size_portrait.1);
}
}
size_portrait.map(|s| na::vector![s.0, s.1])
}
}

Expand Down Expand Up @@ -147,13 +153,13 @@ impl Default for Orientation {
#[serde(default, rename = "format")]
pub struct Format {
#[serde(rename = "width", with = "rnote_compose::serialize::f64_dp3")]
pub width: f64,
width: f64,
#[serde(rename = "height", with = "rnote_compose::serialize::f64_dp3")]
pub height: f64,
height: f64,
#[serde(rename = "dpi", with = "rnote_compose::serialize::f64_dp3")]
pub dpi: f64,
dpi: f64,
#[serde(rename = "orientation")]
pub orientation: Orientation,
orientation: Orientation,
#[serde(rename = "border_color")]
pub border_color: Color,
#[serde(rename = "show_borders")]
Expand Down Expand Up @@ -187,4 +193,46 @@ impl Format {
pub const DPI_DEFAULT: f64 = 96.0;

pub const BORDER_COLOR_DEFAULT: piet::Color = color::GNOME_BRIGHTS[2];

pub fn width(&self) -> f64 {
self.width
}

pub fn set_width(&mut self, width: f64) {
self.width = width.clamp(Self::WIDTH_MIN, Self::WIDTH_MAX);
self.orientation = self.determine_orientation();
}

pub fn height(&self) -> f64 {
self.height
}

pub fn set_height(&mut self, height: f64) {
self.height = height.clamp(Self::HEIGHT_MIN, Self::HEIGHT_MAX);
self.orientation = self.determine_orientation();
}

pub fn dpi(&self) -> f64 {
self.dpi
}

pub fn set_dpi(&mut self, dpi: f64) {
self.dpi = dpi.clamp(Self::DPI_MIN, Self::DPI_MAX);
}

pub fn orientation(&self) -> Orientation {
self.orientation
}

pub fn size(&self) -> na::Vector2<f64> {
na::vector![self.width, self.height]
}

fn determine_orientation(&self) -> Orientation {
if self.width <= self.height {
Orientation::Portrait
} else {
Orientation::Landscape
}
}
}
58 changes: 26 additions & 32 deletions crates/rnote-engine/src/document/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ impl Default for Document {
Self {
x: 0.0,
y: 0.0,
width: Format::default().width,
height: Format::default().height,
width: Format::default().width(),
height: Format::default().height(),
format: Format::default(),
background: Background::default(),
layout: Layout::default(),
Expand Down Expand Up @@ -137,9 +137,9 @@ impl Document {
pub(crate) fn pages_bounds(&self, split_order: SplitOrder) -> Vec<Aabb> {
let doc_bounds = self.bounds();

if self.format.height > 0.0 && self.format.width > 0.0 {
if self.format.height() > 0.0 && self.format.width() > 0.0 {
doc_bounds.split_extended_origin_aligned(
na::vector![self.format.width, self.format.height],
na::vector![self.format.width(), self.format.height()],
split_order,
)
} else {
Expand All @@ -150,9 +150,9 @@ impl Document {
#[allow(unused)]
pub(crate) fn calc_n_pages(&self) -> u32 {
// Avoid div by 0
if self.format.height > 0.0 && self.format.width > 0.0 {
(self.width / self.format.width).ceil() as u32
* (self.height / self.format.height).ceil() as u32
if self.format.height() > 0.0 && self.format.width() > 0.0 {
(self.width / self.format.width()).ceil() as u32
* (self.height / self.format.height()).ceil() as u32
} else {
0
}
Expand Down Expand Up @@ -239,7 +239,7 @@ impl Document {
if self.layout != Layout::FixedSize {
return false;
}
let format_height = self.format.height;
let format_height = self.format.height();
let new_doc_height = self.height + format_height;
self.height = new_doc_height;
true
Expand All @@ -249,17 +249,17 @@ impl Document {
///
/// Returns false when not in fixed-size layout.
pub(crate) fn remove_page_fixed_size(&mut self) -> bool {
if self.layout != Layout::FixedSize || self.height <= self.format.height {
if self.layout != Layout::FixedSize || self.height <= self.format.height() {
return false;
}
self.height -= self.format.height;
self.height -= self.format.height();
true
}

fn resize_doc_fixed_size_layout(&mut self, store: &StrokeStore) {
let format_height = self.format.height;
let format_height = self.format.height();

let new_width = self.format.width;
let new_width = self.format.width();
// max(1.0) because then 'fraction'.ceil() is at least 1
let new_height = ((store.calc_height().max(1.0)) / format_height).ceil() * format_height;

Expand All @@ -270,9 +270,9 @@ impl Document {
}

fn resize_doc_continuous_vertical_layout(&mut self, store: &StrokeStore) {
let padding_bottom = self.format.height;
let padding_bottom = self.format.height();
let new_height = store.calc_height() + padding_bottom;
let new_width = self.format.width;
let new_width = self.format.width();

self.x = 0.0;
self.y = 0.0;
Expand All @@ -281,8 +281,8 @@ impl Document {
}

fn expand_doc_semi_infinite_layout(&mut self, viewport: Aabb) {
let padding_horizontal = self.format.width * 2.0;
let padding_vertical = self.format.height * 2.0;
let padding_horizontal = self.format.width() * 2.0;
let padding_vertical = self.format.height() * 2.0;

let new_bounds = self.bounds().merged(
&viewport.extend_right_and_bottom_by(na::vector![padding_horizontal, padding_vertical]),
Expand All @@ -295,8 +295,8 @@ impl Document {
}

fn expand_doc_infinite_layout(&mut self, viewport: Aabb) {
let padding_horizontal = self.format.width * 2.0;
let padding_vertical = self.format.height * 2.0;
let padding_horizontal = self.format.width() * 2.0;
let padding_vertical = self.format.height() * 2.0;

let new_bounds = self
.bounds()
Expand All @@ -309,20 +309,17 @@ impl Document {
}

fn resize_doc_semi_infinite_layout_to_fit_content(&mut self, store: &StrokeStore) {
let padding_horizontal = self.format.width * 2.0;
let padding_vertical = self.format.height * 2.0;
let padding_horizontal = self.format.width() * 2.0;
let padding_vertical = self.format.height() * 2.0;

let keys = store.stroke_keys_as_rendered();

let new_bounds = if let Some(new_bounds) = store.bounds_for_strokes(&keys) {
new_bounds.extend_right_and_bottom_by(na::vector![padding_horizontal, padding_vertical])
} else {
// If doc is empty, resize to one page with the format size
Aabb::new(
na::point![0.0, 0.0],
na::point![self.format.width, self.format.height],
)
.extend_right_and_bottom_by(na::vector![padding_horizontal, padding_vertical])
Aabb::new(na::point![0.0, 0.0], self.format.size().into())
.extend_right_and_bottom_by(na::vector![padding_horizontal, padding_vertical])
};
self.x = 0.0;
self.y = 0.0;
Expand All @@ -331,20 +328,17 @@ impl Document {
}

fn resize_doc_infinite_layout_to_fit_content(&mut self, store: &StrokeStore) {
let padding_horizontal = self.format.width * 2.0;
let padding_vertical = self.format.height * 2.0;
let padding_horizontal = self.format.width() * 2.0;
let padding_vertical = self.format.height() * 2.0;

let keys = store.stroke_keys_as_rendered();

let new_bounds = if let Some(new_bounds) = store.bounds_for_strokes(&keys) {
new_bounds.extend_by(na::vector![padding_horizontal, padding_vertical])
} else {
// If doc is empty, resize to one page with the format size
Aabb::new(
na::point![0.0, 0.0],
na::point![self.format.width, self.format.height],
)
.extend_by(na::vector![padding_horizontal, padding_vertical])
Aabb::new(na::point![0.0, 0.0], self.format.size().into())
.extend_by(na::vector![padding_horizontal, padding_vertical])
};
self.x = new_bounds.mins[0];
self.y = new_bounds.mins[1];
Expand Down
6 changes: 3 additions & 3 deletions crates/rnote-engine/src/engine/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ impl Engine {
let doc_export_prefs =
doc_export_prefs_override.unwrap_or(self.export_prefs.doc_export_prefs);
let pages_content = self.extract_pages_content(doc_export_prefs.page_order);
let format_size = na::vector![self.document.format.width, self.document.format.height];
let format_size = self.document.format.size();

rayon::spawn(move || {
let result = || -> anyhow::Result<Vec<u8>> {
Expand Down Expand Up @@ -570,7 +570,7 @@ impl Engine {
.filter_map(|mut stroke| {
let mut stroke = Arc::make_mut(&mut stroke).clone();
stroke.translate(-page_bounds.mins.coords);
stroke.into_xopp(document.format.dpi)
stroke.into_xopp(document.format.dpi())
})
.collect::<Vec<xoppformat::XoppStrokeType>>();

Expand Down Expand Up @@ -628,7 +628,7 @@ impl Engine {

let page_dimensions = crate::utils::convert_coord_dpi(
page_bounds.extents(),
document.format.dpi,
document.format.dpi(),
xoppformat::XoppFile::DPI,
);

Expand Down
11 changes: 4 additions & 7 deletions crates/rnote-engine/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,10 +574,7 @@ impl Engine {
let strokes_bounds = self.store.strokes_bounds(&keys);

let pages_bounds = doc_bounds
.split_extended_origin_aligned(
na::vector![self.document.format.width, self.document.format.height],
split_order,
)
.split_extended_origin_aligned(self.document.format.size(), split_order)
.into_iter()
.filter(|page_bounds| {
// Filter the pages out that don't intersect with any stroke
Expand All @@ -591,7 +588,7 @@ impl Engine {
// If no page has content, return the origin page
vec![Aabb::new(
na::point![0.0, 0.0],
na::point![self.document.format.width, self.document.format.height],
self.document.format.size().into(),
)]
} else {
pages_bounds
Expand Down Expand Up @@ -640,9 +637,9 @@ impl Engine {
pub fn return_to_origin(&mut self, parent_width: Option<f64>) -> WidgetFlags {
let zoom = self.camera.zoom();
let new_offset = if let Some(parent_width) = parent_width {
if self.document.format.width * zoom <= parent_width {
if self.document.format.width() * zoom <= parent_width {
na::vector![
(self.document.format.width * 0.5 * zoom) - parent_width * 0.5,
(self.document.format.width() * 0.5 * zoom) - parent_width * 0.5,
-Document::SHADOW_WIDTH * zoom
]
} else {
Expand Down
7 changes: 3 additions & 4 deletions crates/rnote-engine/src/engine/rendering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,9 @@ impl Engine {

snapshot.push_clip(&graphene::Rect::from_p2d_aabb(doc_bounds.loosened(2.0)));

for page_bounds in doc_bounds.split_extended_origin_aligned(
na::vector![self.document.format.width, self.document.format.height],
SplitOrder::default(),
) {
for page_bounds in doc_bounds
.split_extended_origin_aligned(self.document.format.size(), SplitOrder::default())
{
if !page_bounds.intersects(&viewport) {
continue;
}
Expand Down
28 changes: 17 additions & 11 deletions crates/rnote-engine/src/engine/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl EngineSnapshot {
let mut engine = Engine::default();

// We convert all values from the hardcoded 72 DPI of Xopp files to the preferred dpi
engine.document.format.dpi = xopp_import_prefs.dpi;
engine.document.format.set_dpi(xopp_import_prefs.dpi);

engine.document.x = 0.0;
engine.document.y = 0.0;
Expand All @@ -100,16 +100,22 @@ impl EngineSnapshot {
xopp_import_prefs.dpi,
);

engine.document.format.width = crate::utils::convert_value_dpi(
doc_width,
xoppformat::XoppFile::DPI,
xopp_import_prefs.dpi,
);
engine.document.format.height = crate::utils::convert_value_dpi(
doc_height / (no_pages as f64),
xoppformat::XoppFile::DPI,
xopp_import_prefs.dpi,
);
engine
.document
.format
.set_width(crate::utils::convert_value_dpi(
doc_width,
xoppformat::XoppFile::DPI,
xopp_import_prefs.dpi,
));
engine
.document
.format
.set_height(crate::utils::convert_value_dpi(
doc_height / (no_pages as f64),
xoppformat::XoppFile::DPI,
xopp_import_prefs.dpi,
));

if let Some(first_page) = xopp_file.xopp_root.pages.get(0) {
if let xoppformat::XoppBackgroundType::Solid {
Expand Down
4 changes: 2 additions & 2 deletions crates/rnote-engine/src/strokes/bitmapimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl BitmapImage {
) -> Result<Vec<Self>, anyhow::Error> {
let doc = poppler::Document::from_bytes(&glib::Bytes::from(to_be_read), None)?;
let page_range = page_range.unwrap_or(0..doc.n_pages() as u32);
let page_width = format.width * (pdf_import_prefs.page_width_perc / 100.0);
let page_width = 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) = doc.page(0) {
page_width / first_page.size().0
Expand Down Expand Up @@ -194,7 +194,7 @@ impl BitmapImage {
PdfImportPageSpacing::Continuous => {
height + Stroke::IMPORT_OFFSET_DEFAULT[1] * 0.5
}
PdfImportPageSpacing::OnePerDocumentPage => format.height,
PdfImportPageSpacing::OnePerDocumentPage => format.height(),
};

Ok((png_data, image_pos, image_size))
Expand Down
4 changes: 2 additions & 2 deletions crates/rnote-engine/src/strokes/vectorimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl VectorImage {
let doc = poppler::Document::from_bytes(&glib::Bytes::from(to_be_read), None)?;
let page_range = page_range.unwrap_or(0..doc.n_pages() as u32);

let page_width = format.width * (pdf_import_prefs.page_width_perc / 100.0);
let page_width = 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) = doc.page(0) {
page_width / first_page.size().0
Expand Down Expand Up @@ -276,7 +276,7 @@ impl VectorImage {
PdfImportPageSpacing::Continuous => {
height + Stroke::IMPORT_OFFSET_DEFAULT[1] * 0.5
}
PdfImportPageSpacing::OnePerDocumentPage => format.height,
PdfImportPageSpacing::OnePerDocumentPage => format.height(),
};

match res() {
Expand Down
Loading

0 comments on commit e827934

Please sign in to comment.