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
11 changes: 6 additions & 5 deletions crates/pdf-annotation-core/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
pdf_data::AnnotationAction,
style::ResolvedStyle,
};
use pdf_graphics::{point::Point, rect::Rect, size::Size, transform::Transform};
use serde::{Deserialize, Serialize};

/// Host element family presenting a widget's field value.
Expand Down Expand Up @@ -115,14 +116,14 @@ pub struct AnnotationEntry {
/// Why the host should show a placeholder instead of `annotation.content`.
pub unsupported: Option<String>,
/// Device-space interaction rectangles.
pub bounds: Vec<[f64; 4]>,
pub bounds: Vec<Rect>,
/// Page-space bottom-left corner of the `size` box; local coordinates are
/// `[x - origin[0], origin[1] + size[1] - y]`.
pub origin: [f64; 2],
/// `[x - origin.x, origin.y + size.height - y]`.
pub origin: Point,
/// Local page-unit width and height.
pub size: [f64; 2],
pub size: Size,
/// Local top-left to device affine matrix.
pub transform: [f64; 6],
pub transform: Transform,
/// Preserve physical size under zoom.
pub no_zoom: bool,
/// Preserve orientation under rotation.
Expand Down
28 changes: 20 additions & 8 deletions crates/pdf-annotation-core/src/free_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ use pdf_graphics::{color::Color, polyline::Polyline, rect::Rect};
use serde::{Deserialize, Serialize};

/// Left, top, right, and bottom text insets used when the source supplies none.
const DEFAULT_INSETS: [f64; 4] = [2.0; 4];
const DEFAULT_INSETS: Rect = Rect {
left: 2.0,
top: 2.0,
right: 2.0,
bottom: 2.0,
};

/// Solid free-text border in page units.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
Expand All @@ -19,7 +24,7 @@ pub struct FreeTextBorder {
/// Unquantized opaque sRGB color.
pub color: Color,
/// Nonnegative border width.
pub width: f64,
pub width: f32,
}

/// Explicit native free-text style, independent of retained PDF source metadata.
Expand All @@ -30,13 +35,13 @@ pub struct FreeTextStyle {
/// Plain PDF font resource name; no slash or PDF delimiters.
pub font_name: Vec<u8>,
/// Strictly positive font size in page units.
pub font_size: f64,
pub font_size: f32,
/// Unquantized opaque text sRGB color.
pub text_color: Color,
/// Optional solid border.
pub border: Option<FreeTextBorder>,
/// Nonnegative left, top, right, bottom text insets, in that order.
pub insets: [f64; 4],
pub insets: Rect,
/// Horizontal text alignment.
pub alignment: Alignment,
}
Expand All @@ -59,7 +64,7 @@ impl FreeTextStyle {
///
/// The border is present only when the style has a border color; `insets`
/// default to two page units per side. Does not validate the result.
pub fn from_resolved(style: &ResolvedStyle, insets: Option<[f64; 4]>) -> Self {
pub fn from_resolved(style: &ResolvedStyle, insets: Option<Rect>) -> Self {
Self {
font_name: style.font_resource_name().to_vec(),
font_size: style.font_size,
Expand Down Expand Up @@ -102,7 +107,14 @@ impl FreeTextStyle {
|| [self.text_color.r, self.text_color.g, self.text_color.b]
.iter()
.any(|v| !v.is_finite() || *v < 0.0)
|| self.insets.iter().any(|v| !v.is_finite() || *v < 0.0)
|| [
self.insets.left,
self.insets.top,
self.insets.right,
self.insets.bottom,
]
.iter()
.any(|v| !v.is_finite() || *v < 0.0)
|| self.border.as_ref().is_some_and(|b| {
!b.width.is_finite()
|| b.width < 0.0
Expand All @@ -123,15 +135,15 @@ impl FreeTextStyle {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct FreeText {
/// Page-space placement.
pub bounds: Rect<f64>,
pub bounds: Rect,
/// Current Unicode text.
pub text: String,
/// Current text and border style.
pub style: FreeTextStyle,
/// Rich text retained without claiming a rich-text editor or renderer.
pub rich_contents: Option<Vec<u8>>,
/// Optional open two- or three-point callout, translated with the annotation.
pub callout: Option<Polyline<f64>>,
pub callout: Option<Polyline>,
/// Retained border effect, unsupported by the plain-text editor.
pub border_effect: Option<BorderEffect>,
}
Expand Down
14 changes: 7 additions & 7 deletions crates/pdf-annotation-core/src/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use pdf_graphics::rect::Rect;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SourceLayout {
/// Normalized copy of the source rectangle.
pub rect: Rect<f64>,
pub rect: Rect,
/// Page point `rect` was measured against: the first ink point, else its origin.
pub anchor: Point,
}
Expand Down Expand Up @@ -67,7 +67,7 @@ pub enum AnnotationKind {
}

/// Union of every quad's bounds; markup without quads has no geometry.
fn quads_bounds(quads: &[Quad]) -> Result<Rect<f64>, ValidationError> {
fn quads_bounds(quads: &[Quad]) -> Result<Rect, ValidationError> {
quads
.iter()
.map(Quad::bounds)
Expand All @@ -85,7 +85,7 @@ impl AnnotationKind {
/// # Errors
/// Returns `InvalidHighlight` for markup without quads, `InvalidInk` for ink without
/// strokes, and `InvalidBounds` when the result is not a finite, positive rectangle.
pub fn bounds(&self, layout: Option<&SourceLayout>) -> Result<Rect<f64>, ValidationError> {
pub fn bounds(&self, layout: Option<&SourceLayout>) -> Result<Rect, ValidationError> {
let result = match self {
Self::FreeText(v) => v.bounds,
Self::Link(v) => v.bounds,
Expand Down Expand Up @@ -122,7 +122,7 @@ impl AnnotationKind {
let b = v
.strokes
.iter()
.filter_map(|stroke| stroke.bounds())
.filter_map(|stroke| stroke.vertex_bounds())
.reduce(|a, b| a.union(&b))
.ok_or(ValidationError::InvalidInk)?;
Rect {
Expand Down Expand Up @@ -337,7 +337,7 @@ impl AnnotationKind {
return Err(ValidationError::InvalidBounds);
}
if v.insets
.is_some_and(|values| values.iter().any(|value| *value < 0.0))
.is_some_and(|r| [r.left, r.top, r.right, r.bottom].iter().any(|v| *v < 0.0))
{
return Err(ValidationError::InvalidStyle {
field: "shape insets",
Expand Down Expand Up @@ -409,14 +409,14 @@ impl AnnotationKind {
Self::TextNote(value) => value.anchor.translate(delta.x, delta.y),
Self::Ink(value) => {
for line in value.strokes.iter_mut() {
line.translate(delta.x, delta.y);
line.translate(delta);
}
}
Self::Widget(value) => value.bounds.translate(delta.x, delta.y),
Self::FreeText(v) => v.translate(delta),
Self::Line(v) | Self::Polygon(v) | Self::PolyLine(v) => {
v.bounds.translate(delta.x, delta.y);
v.vertices.translate(delta.x, delta.y);
v.vertices.translate(delta);
}
Self::Square(v) | Self::Circle(v) => v.bounds.translate(delta.x, delta.y),
Self::Underline(v) | Self::Squiggly(v) | Self::StrikeOut(v) => {
Expand Down
8 changes: 4 additions & 4 deletions crates/pdf-annotation-core/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ pub struct Revision(
);

/// Position in unrotated PDF page user space, before any viewport transform.
pub type Point = pdf_graphics::point::Point<f64>;
pub type Point = pdf_graphics::point::Point<f32>;

/// Convex highlight region with four distinct corners in perimeter order.
pub type Quad = pdf_graphics::quad::Quad<f64>;
pub type Quad = pdf_graphics::quad::Quad<f32>;

/// Selected regions supplied by the host's text-selection system.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -94,9 +94,9 @@ pub struct Ink {
#[serde(default)]
pub style: Option<crate::style::ResolvedStyle>,
/// Nonempty open strokes, each containing at least two points.
pub strokes: Vec<Polyline<f64>>,
pub strokes: Vec<Polyline>,
/// Finite, strictly positive stroke width in page user-space units.
pub width: f64,
pub width: f32,
/// Stroke color; alpha is the annotation opacity.
pub color: Color,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/pdf-annotation-core/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl AnnotationOverlay {
&mut self,
mut command: AnnotationCommandRequest,
viewport_revision: Option<u32>,
page_bounds: Option<Rect<f64>>,
page_bounds: Option<Rect>,
) -> AnnotationLayerResult<AnnotationReceipt> {
if let Some(target) = &command.target {
let annotation = self.mounted_annotation(target, viewport_revision)?;
Expand Down Expand Up @@ -357,7 +357,7 @@ impl AnnotationOverlay {
&self,
annotation: &Annotation,
delta: Point,
page_bounds: Option<Rect<f64>>,
page_bounds: Option<Rect>,
) -> AnnotationLayerResult<Point> {
let page = page_bounds.ok_or(AnnotationLayerError::InvalidInput("drag page bounds"))?;
let layout = self
Expand Down
42 changes: 21 additions & 21 deletions crates/pdf-annotation-core/src/pdf_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ impl<'de> serde::Deserialize<'de> for WidgetFieldFlags {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct AnnotationBorder {
/// Horizontal corner radius.
pub horizontal_radius: f64,
pub horizontal_radius: f32,
/// Vertical corner radius.
pub vertical_radius: f64,
pub vertical_radius: f32,
/// Border width.
pub width: f64,
pub width: f32,
/// Optional validated dash pattern; `None` is a solid border.
pub dash_pattern: Option<DashPattern>,
}
Expand All @@ -73,11 +73,11 @@ pub struct AnnotationBorder {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct BorderStyle {
/// Border width.
pub width: Option<f64>,
pub width: Option<f32>,
/// Border style name.
pub style: Option<BorderStyleName>,
/// Optional dash pattern.
pub dash_pattern: Option<Vec<f64>>,
pub dash_pattern: Option<Vec<f32>>,
}

/// Owned BorderStyleName data retained from the source PDF.
Expand Down Expand Up @@ -463,16 +463,16 @@ impl AnnotationAction {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct InkList {
/// The parsed stroke lists.
pub strokes: Vec<Polyline<f64>>,
pub strokes: Vec<Polyline>,
}

/// Owned CaretAnnotation data retained from the source PDF.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct CaretAnnotation {
/// The difference rectangle.
pub difference_rect: Option<[f64; 4]>,
/// The `/RD` difference rectangle: left, top, right, and bottom insets from `/Rect`.
pub difference_rect: Option<Rect>,
/// The caret style.
pub style: Option<CaretSymbolStyle>,
}
Expand All @@ -488,8 +488,8 @@ pub struct CircleAnnotation {
pub interior_color: Option<Color>,
/// The border effect.
pub border_effect: Option<BorderEffect>,
/// The difference rectangle.
pub difference_rect: Option<[f64; 4]>,
/// The `/RD` difference rectangle: left, top, right, and bottom insets from `/Rect`.
pub difference_rect: Option<Rect>,
}

/// Owned FreeTextAlignment data retained from the source PDF.
Expand Down Expand Up @@ -519,11 +519,11 @@ pub struct FreeTextAnnotation {
/// The default style string.
pub default_style: Option<Vec<u8>>,
/// The open callout line, from its starting point to its attachment point.
pub callout_line: Option<Polyline<f64>>,
pub callout_line: Option<Polyline>,
/// The border effect.
pub border_effect: Option<BorderEffect>,
/// The difference rectangle.
pub difference_rect: Option<[f64; 4]>,
/// The `/RD` difference rectangle: left, top, right, and bottom insets from `/Rect`.
pub difference_rect: Option<Rect>,
/// The intent.
pub intent: Option<Vec<u8>>,
}
Expand Down Expand Up @@ -560,17 +560,17 @@ pub struct InkAnnotation {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct LineAnnotation {
/// The required line endpoints.
pub line: [f64; 4],
pub line: [f32; 4],
/// The line ending styles.
pub line_endings: Option<[LineEndingStyle; 2]>,
/// The border style.
pub border_style: Option<BorderStyle>,
/// The interior color.
pub interior_color: Option<Color>,
/// The leader line length.
pub leader_line_length: Option<f64>,
pub leader_line_length: Option<f32>,
/// The leader line extension length.
pub leader_line_extension: Option<f64>,
pub leader_line_extension: Option<f32>,
/// Whether the caption is positioned at the line's end.
pub caption: Option<bool>,
/// The intent.
Expand Down Expand Up @@ -602,7 +602,7 @@ pub struct LinkAnnotation {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct PolygonAnnotation {
/// The required polygon vertices.
pub vertices: Polyline<f64>,
pub vertices: Polyline,
/// The line ending styles.
pub line_endings: Option<[LineEndingStyle; 2]>,
/// The interior color.
Expand All @@ -619,7 +619,7 @@ pub struct PolygonAnnotation {
#[cfg_attr(feature = "typescript", ts(export_to = "annotation_contract.ts"))]
pub struct PolyLineAnnotation {
/// The required polyline vertices.
pub vertices: Polyline<f64>,
pub vertices: Polyline,
/// The line ending styles.
pub line_endings: Option<[LineEndingStyle; 2]>,
/// The interior color.
Expand Down Expand Up @@ -654,8 +654,8 @@ pub struct SquareAnnotation {
pub interior_color: Option<Color>,
/// The border effect.
pub border_effect: Option<BorderEffect>,
/// The difference rectangle.
pub difference_rect: Option<[f64; 4]>,
/// The `/RD` difference rectangle: left, top, right, and bottom insets from `/Rect`.
pub difference_rect: Option<Rect>,
}

/// Owned SquigglyAnnotation data retained from the source PDF.
Expand Down Expand Up @@ -868,7 +868,7 @@ pub struct SourceAnnotation {
/// The optional annotation rectangle from `/Rect`, in PDF page user space
/// where `bottom` is the lower `y` edge. Edges keep their source values and
/// order, so inverted rectangles are preserved rather than normalized.
pub rect: Option<Rect<f64>>,
pub rect: Option<Rect>,
/// The optional annotation contents.
pub contents: Option<Vec<u8>>,
/// The optional annotation name from `/NM`.
Expand Down
Loading
Loading