Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ onenote-core = { path = "crates/onenote-core" }
onenote-index = { path = "crates/onenote-index" }
onenote-render = { path = "crates/onenote-render" }
onenote-render-gtk = { path = "crates/onenote-render-gtk" }
onenote_parser = { git = "https://github.com/msiemens/onenote.rs", tag = "v2.0.0" }
onenote_parser = { git = "https://github.com/emsi/onenote.rs", rev = "57694b1ca128d4a6c1fb222f31049be3e6830599" }
rusqlite = { version = "0.32.1", features = ["bundled"] }
sanitize-filename = "0.6.0"
serde = { version = "1.0.219", features = ["derive", "rc"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/onenote-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub use resource::{
};

/// The crate API version during the pre-1.0 implementation phase.
pub const API_VERSION: u32 = 6;
pub const API_VERSION: u32 = 7;

/// Logical display pixels per `OneNote` half-inch layout unit at 96 DPI.
pub const PIXELS_PER_HALF_INCH: f32 = 48.0;
6 changes: 6 additions & 0 deletions crates/onenote-core/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,9 @@ pub struct TableCell {
pub struct Image {
/// Lazy binary payload.
pub resource: ResourceRef,
/// Optional browser-compatible representation stored by `OneNote`.
#[serde(default)]
pub web_fallback: Option<ResourceRef>,
/// Display width in logical pixels.
pub width: Option<f32>,
/// Display height in logical pixels.
Expand All @@ -662,6 +665,9 @@ pub struct Image {
pub struct Attachment {
/// Lazy binary payload.
pub resource: ResourceRef,
/// Optional icon stored by `OneNote` for this embedded file.
#[serde(default)]
pub icon: Option<ResourceRef>,
/// Display width in logical pixels.
pub width: Option<f32>,
/// Display height in logical pixels.
Expand Down
31 changes: 28 additions & 3 deletions crates/onenote-core/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{Error, ResourceStore, Result, PIXELS_PER_HALF_INCH};
use linkify::{LinkFinder, LinkKind};
use onenote_parser::contents::{
Content, EmbeddedFile, Image as ParserImage, Ink as ParserInk, List, Outline as ParserOutline,
OutlineElement as ParserOutlineElement, OutlineItem, ParagraphStyling, RichText,
OutlineElement as ParserOutlineElement, OutlineItem, ParagraphStyling, Picture, RichText,
Table as ParserTable,
};
use onenote_parser::notebook::Notebook as ParserNotebook;
Expand Down Expand Up @@ -538,8 +538,9 @@ impl Projector {
}

fn image(&mut self, image: &ParserImage, key: &str) -> Result<Image> {
let required_resources = 1 + usize::from(image.web_picture().is_some());
self.enforce(
self.resources.len() < self.limits.max_resources,
self.resources.len().saturating_add(required_resources) <= self.limits.max_resources,
"resource limit exceeded",
)?;
let id = ResourceId::new(self.id("resource", key));
Expand All @@ -556,8 +557,12 @@ impl Projector {
};
self.resources
.insert(id, ResourceLoader::Image(image.clone()));
let web_fallback = image.web_picture().map(|picture| {
self.picture_resource(picture, &format!("{key}/web-fallback"), "image-fallback")
});
Ok(Image {
resource,
web_fallback,
width: image
.layout_max_width()
.or_else(|| image.picture_width())
Expand Down Expand Up @@ -597,8 +602,9 @@ impl Projector {
}

fn attachment(&mut self, file: &EmbeddedFile, key: &str) -> Result<Attachment> {
let required_resources = 1 + usize::from(file.icon().is_some());
self.enforce(
self.resources.len() < self.limits.max_resources,
self.resources.len().saturating_add(required_resources) <= self.limits.max_resources,
"resource limit exceeded",
)?;
let id = ResourceId::new(self.id("resource", key));
Expand All @@ -616,13 +622,32 @@ impl Projector {
};
self.resources
.insert(id, ResourceLoader::Attachment(file.clone()));
let icon = file
.icon()
.map(|picture| self.picture_resource(picture, &format!("{key}/icon"), "file-icon"));
Ok(Attachment {
resource,
icon,
width: file.layout_max_width().map(half_inches),
height: file.layout_max_height().map(half_inches),
})
}

fn picture_resource(&mut self, picture: &Picture, key: &str, stem: &str) -> ResourceRef {
let id = ResourceId::new(self.id("resource", key));
let extension = picture.extension().unwrap_or("bin").trim_start_matches('.');
let resource = ResourceRef {
id: id.clone(),
name: format!("{stem}.{extension}"),
media_type: image_media_type(extension).to_owned(),
size: picture.size(),
status: resource_status(picture.data_status()),
};
self.resources
.insert(id, ResourceLoader::Picture(picture.clone()));
resource
}

fn ink_object(
&mut self,
ink: &ParserInk,
Expand Down
7 changes: 6 additions & 1 deletion crates/onenote-core/src/resource.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{Error, ResourceId, ResourceStatus, Result};
use onenote_parser::contents::{EmbeddedFile, FileDataStatus, Image};
use onenote_parser::contents::{EmbeddedFile, FileDataStatus, Image, Picture};
use std::collections::HashMap;
use std::io::{Read, Write};
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -65,20 +65,23 @@ impl ResourceCopyControl {
#[derive(Clone, Debug)]
pub(crate) enum ResourceLoader {
Image(Image),
Picture(Picture),
Attachment(EmbeddedFile),
}

impl ResourceLoader {
fn size(&self) -> u64 {
match self {
Self::Image(image) => image.size().unwrap_or(0),
Self::Picture(picture) => picture.size(),
Self::Attachment(file) => file.size(),
}
}

fn status(&self) -> ResourceStatus {
let status = match self {
Self::Image(image) => image.data_status(),
Self::Picture(picture) => picture.data_status(),
Self::Attachment(file) => file.data_status(),
};
resource_status(status)
Expand All @@ -87,13 +90,15 @@ impl ResourceLoader {
fn reader(&self) -> Option<Box<dyn Read>> {
match self {
Self::Image(image) => image.read(),
Self::Picture(picture) => Some(picture.read()),
Self::Attachment(file) => Some(file.read()),
}
}

fn verified_size(&self) -> Option<u64> {
match self {
Self::Image(image) => image.size(),
Self::Picture(picture) => Some(picture.size()),
Self::Attachment(file) => Some(file.size()),
}
}
Expand Down
16 changes: 13 additions & 3 deletions crates/onenote-core/tests/private_corpus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,13 @@ fn resource_refs(entries: &[NotebookEntry]) -> Vec<&ResourceRef> {
for page in &section.pages {
for object in &page.objects {
match &object.kind {
ObjectKind::Image(image) => resources.push(&image.resource),
ObjectKind::Image(image) => {
resources.push(&image.resource);
resources.extend(image.web_fallback.iter());
}
ObjectKind::Attachment(attachment) => {
resources.push(&attachment.resource);
resources.extend(attachment.icon.iter());
}
ObjectKind::Outline(outline) => {
for element in &outline.elements {
Expand All @@ -521,8 +525,14 @@ fn element_resource_refs<'a>(
) {
for content in &element.content {
match content {
ElementContent::Image(image) => output.push(&image.resource),
ElementContent::Attachment(attachment) => output.push(&attachment.resource),
ElementContent::Image(image) => {
output.push(&image.resource);
output.extend(image.web_fallback.iter());
}
ElementContent::Attachment(attachment) => {
output.push(&attachment.resource);
output.extend(attachment.icon.iter());
}
ElementContent::Table(table) => {
for row in &table.rows {
for cell in row {
Expand Down
Loading
Loading