From 03ea40328a563dad2863a1ebc476f3801a77bae7 Mon Sep 17 00:00:00 2001 From: Doublonmousse <115779707+Doublonmousse@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:27:31 +0200 Subject: [PATCH 1/2] text import for `xopp` files --- crates/rnote-engine/src/engine/snapshot.rs | 14 +++++++++++++ crates/rnote-engine/src/strokes/stroke.rs | 24 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/crates/rnote-engine/src/engine/snapshot.rs b/crates/rnote-engine/src/engine/snapshot.rs index 18c5ce4da1..59cb3d7324 100644 --- a/crates/rnote-engine/src/engine/snapshot.rs +++ b/crates/rnote-engine/src/engine/snapshot.rs @@ -183,6 +183,20 @@ impl EngineSnapshot { } } } + + for new_xopptext in layers.texts.into_iter() { + match Stroke::from_xopptext(new_xopptext, offset, xopp_import_prefs.dpi) + { + Ok(new_text) => { + engine.store.insert_stroke(new_text, None); + } + Err(e) => { + error!( + "Creating Stroke from XoppText failed while loading Xopp bytes, Err: {e:?}", + ); + } + } + } } // Only add to y offset, results in vertical pages diff --git a/crates/rnote-engine/src/strokes/stroke.rs b/crates/rnote-engine/src/strokes/stroke.rs index d426421554..e3cec8d009 100644 --- a/crates/rnote-engine/src/strokes/stroke.rs +++ b/crates/rnote-engine/src/strokes/stroke.rs @@ -7,6 +7,7 @@ use super::vectorimage::VectorImage; use super::{Content, TextStroke}; use crate::fileformats::xoppformat::{self, XoppColor}; use crate::store::chrono_comp::StrokeLayer; +use crate::strokes::textstroke::TextStyle; use crate::{Drawable, utils}; use crate::{Engine, render}; use p2d::bounding_volume::Aabb; @@ -427,6 +428,29 @@ impl Stroke { Ok(Stroke::BitmapImage(BitmapImage { image, rectangle })) } + pub fn from_xopptext( + xopp_text: xoppformat::XoppText, + offset: na::Vector2, + target_dpi: f64, + ) -> Result { + let pos: na::Vector2 = na::Vector2::::new( + crate::utils::convert_value_dpi(xopp_text.x, xoppformat::XoppFile::DPI, target_dpi), + crate::utils::convert_value_dpi(xopp_text.y, xoppformat::XoppFile::DPI, target_dpi), + ); + + let mut textstyle = TextStyle::default(); + textstyle.color = crate::utils::color_from_xopp(xopp_text.color); + textstyle.font_size = + crate::utils::convert_value_dpi(xopp_text.size, xoppformat::XoppFile::DPI, target_dpi); + textstyle.font_family = xopp_text.font; + + Ok(Stroke::TextStroke(TextStroke::new( + xopp_text.text, + pos + offset, + textstyle, + ))) + } + pub fn into_xopp(self, current_dpi: f64) -> Option { match self { Stroke::BrushStroke(brushstroke) => { From a29842b97e949d64abfaa42dd4d9d71912913119 Mon Sep 17 00:00:00 2001 From: Doublonmousse <115779707+Doublonmousse@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:27:51 +0200 Subject: [PATCH 2/2] notes on `xopp` import --- crates/rnote-engine/src/strokes/stroke.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/rnote-engine/src/strokes/stroke.rs b/crates/rnote-engine/src/strokes/stroke.rs index e3cec8d009..a533d05a0f 100644 --- a/crates/rnote-engine/src/strokes/stroke.rs +++ b/crates/rnote-engine/src/strokes/stroke.rs @@ -520,6 +520,12 @@ impl Stroke { )) } Stroke::ShapeStroke(shapestroke) => { + // Remark + // We can transform shapes to a xopp brushstroke + // under the following conditions + // - if the stroke color is not none + // - if the fill color is transparent + // - if the style is not rough let png_data = match shapestroke.export_to_bitmap_image_bytes( image::ImageFormat::Png, Engine::STROKE_EXPORT_IMAGE_SCALE, @@ -564,6 +570,14 @@ impl Stroke { Stroke::TextStroke(textstroke) => { // Xournal++ text strokes do not support affine transformations, so we have to convert on best effort here. // The best solution for now seems to be to export them as a bitmap image. + // + // We _could_ try to retain the text more but + // the hard part is a xopp text element is + // - a single font + // - a single emphasis mode (bold,italic ...) on all text + // - a single color + // So we'd have to cut the text into smaller xopp text elements + // to retain it ... let png_data = match textstroke.export_to_bitmap_image_bytes( image::ImageFormat::Png, Engine::STROKE_EXPORT_IMAGE_SCALE, @@ -606,6 +620,7 @@ impl Stroke { )) } Stroke::VectorImage(vectorimage) => { + // no svg support in xournalpp let png_data = match vectorimage.export_to_bitmap_image_bytes( image::ImageFormat::Png, Engine::STROKE_EXPORT_IMAGE_SCALE,