#[cfg(feature = "render")]
extern crate alloc;
mod archive_resource;
mod archive_tail;
mod binary;
#[cfg(feature = "render")]
mod composition;
mod container;
mod decode;
mod end_tag;
mod error;
mod formula;
mod frame;
mod image;
#[cfg(feature = "render")]
mod ink;
mod integrity;
mod layer;
mod layout;
mod math;
mod media;
mod note;
mod note_metadata;
mod object;
mod object_flexible;
mod page;
mod page_background;
mod page_objects;
mod page_selection;
#[cfg(feature = "pdf")]
pub mod pdf;
mod progress;
#[cfg(feature = "render")]
mod render;
mod report;
mod shape;
mod shape_paint_source;
mod storage;
mod stroke_metadata;
mod table;
mod text_index;
mod types;
pub use archive_resource::{
ArchiveResource, ArchiveResourceContent, ArchiveResourceError, ArchiveResourceResolver,
ResolvedArchiveResource,
};
pub use end_tag::{
EndTagDisplayTimestamps, EndTagEncryption, EndTagFixedStyle, EndTagSource, StoredEndTag,
parse_end_tag_bytes, parse_end_tag_bytes_with_limits,
};
pub use error::{Error, Result};
pub use formula::{
FormulaLabel, FormulaLabelGraph, FormulaLabelRelation, FormulaLabelRelationKind,
FormulaMetadata, FormulaStroke,
};
#[cfg(feature = "render")]
pub use ink::{InkSupport, PEN_PROFILES, PenProfile, PreparedStroke, RectStamp, prepare_stroke};
pub use integrity::{IntegrityCounts, IntegrityReport};
pub use layer::LayerMetadata;
pub use layout::{
BodyTextCaptureWindow, BodyTextReflow, BodyTextSlice, LayoutDocument, LayoutPage,
layout_document, layout_document_with_progress,
};
pub use math::{MathAngleType, MathMargins, MathMetadata, PlotGraph, PlotMetadata};
pub use media::{
MediaManifest, MediaManifestEntry, parse_media_manifest_bytes,
parse_media_manifest_bytes_with_limits,
};
pub use note::{StoredNote, StoredNoteHeader, parse_note_bytes, parse_note_bytes_with_limits};
pub use note_metadata::{
NoteApplicationVersion, NoteAttachment, NoteAuthor, NoteLocation, NoteMetadata, NotePageEdit,
NotePenExtension, NotePenSettings, NoteStringId, NoteStringTable, NoteVoice, NoteVoiceEvent,
};
pub use object::{ObjectMetadata, ObjectResizeMode};
pub use object_flexible::{
ObjectBundle, ObjectBundleEntry, ObjectBundleValue, ObjectFlexibleMetadata, ObjectLayoutType,
ObjectPageSize, ObjectRenderLayer, ObjectSize, ObjectSpanSnapshot,
};
pub use page_objects::{PageObject, PageObjectContent};
pub use page_selection::{PageSelectionError, parse_page_selection};
#[cfg(feature = "pdf")]
pub use pdf::{
PdfError, PdfOptions, PdfOutput, PdfPageDiagnostics, render_document_pdf,
render_layout_pages_pdf_detailed_with_cache,
render_layout_pages_pdf_detailed_with_cache_and_progress,
render_layout_pages_pdf_detailed_with_fonts, render_layout_pages_pdf_with_fonts,
render_svg_pages_pdf,
};
pub use progress::{Progress, ProgressStage};
#[cfg(feature = "render")]
pub use render::{
DocumentTextCache, GeometryDiagnostic, GeometryDiagnosticKind, ObjectDiagnostic,
ObjectDiagnosticKind, PaintDiagnostic, PaintDiagnosticKind, PaintRole, PointMarkerTarget,
RenderColorMode, RenderOptions, RenderTheme, RenderedPage, StrokePaint, TextDiagnostic,
TextDiagnosticKind, fonts, render_document_svg, render_document_svg_with_fonts,
render_layout_page_replay_svg, render_layout_page_replay_svg_with_fonts,
render_layout_page_svg, render_layout_page_svg_with_fonts, render_page_svg, stroke_paint,
};
pub use report::{DiagnosticCode, DiagnosticSeverity, ParseDiagnostic, ParseReport};
pub use shape::{
LineLegacyPenSource, NativeLine, NativeShape, ShapeBaseSource, ShapePaint, ShapeStyle,
};
pub use shape_paint_source::{
ColorPaintSource, GradientStopSource, ImagePaintSource, NinePatchSource, PaintFloat32,
PatternPaintSource, ShapePaintSource,
};
pub use storage::{
PageManifest, PageManifestEntry, ParsedDocument, StoredArchivePage, StoredLayer, StoredObject,
StoredPage, StoredPageHeader, StoredPageLayers, parse_page_manifest_bytes,
parse_page_manifest_bytes_with_limits, parse_stored_page_bytes,
parse_stored_page_bytes_with_limits,
};
pub use stroke_metadata::{
StrokeMetadata, StrokeProperties, StrokeRendering, StrokeResources, StrokeStyle,
};
pub use table::{TableAutoFit, TableBorder, TableEdgeStyle, TableRecordMetadata, TableStyle};
pub use types::*;
use std::fs::File;
use std::io::Cursor;
use std::path::Path;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParseLimits {
pub max_archive_entries: usize,
pub max_entry_size: u64,
pub max_total_uncompressed_size: u64,
pub max_pages: usize,
pub max_strokes_per_page: usize,
pub max_points_per_stroke: usize,
pub max_objects_per_page: usize,
pub max_layers_per_page: usize,
pub max_object_nesting_depth: usize,
pub max_text_characters: usize,
pub max_text_spans: usize,
pub max_text_paragraphs: usize,
pub max_text_object_spans: usize,
pub max_note_metadata_entries: usize,
pub max_object_metadata_entries: usize,
}
impl Default for ParseLimits {
fn default() -> Self {
Self {
max_archive_entries: 65_536,
max_entry_size: 512 * 1024 * 1024,
max_total_uncompressed_size: 2 * 1024 * 1024 * 1024,
max_pages: 10_000,
max_strokes_per_page: 100_000,
max_points_per_stroke: u16::MAX as usize,
max_objects_per_page: 100_000,
max_layers_per_page: 64,
max_object_nesting_depth: 64,
max_text_characters: 250_000,
max_text_spans: 10_000,
max_text_paragraphs: 10_000,
max_text_object_spans: 10_000,
max_note_metadata_entries: 10_000,
max_object_metadata_entries: 10_000,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ParseOptions {
pub verify_integrity: bool,
pub retain_page_sources: bool,
pub retain_note_source: bool,
pub limits: ParseLimits,
}
pub fn parse(path: impl AsRef<Path>) -> Result<Document> {
parse_with_options(path, &ParseOptions::default())
}
pub fn parse_with_options(path: impl AsRef<Path>, options: &ParseOptions) -> Result<Document> {
let file = File::open(path)?;
container::parse_from_reader(file, options)
}
pub fn parse_detailed(path: impl AsRef<Path>) -> Result<ParsedDocument> {
parse_detailed_with_options(path, &ParseOptions::default())
}
pub fn parse_detailed_with_options(
path: impl AsRef<Path>,
options: &ParseOptions,
) -> Result<ParsedDocument> {
let file = File::open(path)?;
container::parse_detailed_from_reader(file, options)
}
pub fn parse_bytes(bytes: &[u8]) -> Result<Document> {
parse_bytes_with_options(bytes, &ParseOptions::default())
}
pub fn parse_bytes_with_options(bytes: &[u8], options: &ParseOptions) -> Result<Document> {
let cursor = Cursor::new(bytes);
container::parse_from_reader(cursor, options)
}
pub fn parse_bytes_detailed(bytes: &[u8]) -> Result<ParsedDocument> {
parse_bytes_detailed_with_options(bytes, &ParseOptions::default())
}
pub fn parse_bytes_detailed_with_options(
bytes: &[u8],
options: &ParseOptions,
) -> Result<ParsedDocument> {
let cursor = Cursor::new(bytes);
container::parse_detailed_from_reader(cursor, options)
}
pub fn parse_bytes_detailed_with_progress(
bytes: &[u8],
options: &ParseOptions,
observer: &mut dyn FnMut(Progress),
) -> Result<ParsedDocument> {
container::parse_detailed_from_reader_with_progress(Cursor::new(bytes), options, observer)
}
pub fn archive_zip_length(bytes: &[u8]) -> Result<u64> {
Ok(archive_tail::ArchiveTail::read(&mut std::io::Cursor::new(bytes))?.archive_length)
}