Skip to main content

Module model

Module model 

Source
Expand description

Shared PDF-editor wire/model types (Dispatch A, lane A1).

Owns every Rust type other PDF-editor lanes compile against, per docs/PDF-EDITOR-NOW.md §5.1 (wire models), §5.2 (inspection state types), §7.2 (font catalog API), and §11 (typed errors), plus the digest helpers those sections describe and the shared PdfEditCommand/ComposedCandidate types the frozen composer signature depends on (docs/PDF-EDITOR-DISPATCH.md, “Frozen cross-lane seams”):

pub fn compose_candidate(
    source: &[u8],
    commands: &[PdfEditCommand],
    fonts: &dyn PdfFontResolver,
) -> Result<ComposedCandidate, PdfEditError>;

That function itself is defined by pdf_compose.rs (Dispatch C, lane C1) — this module only provides the types its signature depends on, so downstream lanes can build and test against a stable contract before the real implementation lands. Likewise inspect_pdf_page’s stateful content walker (§5.2’s visit_text_show, §5.3’s may_join/painted-bounds inventory) is pdf_inspect.rs (lane B1); this module owns only the Matrix/TextState/PositionedGlyph family of types that walker is built from.

This file makes no filesystem or Tauri-state assumptions and defines no #[tauri::command] — every command in this effort (inspect_pdf_page, list_pdf_fonts, compose_pdf_preview, prepare_pdf_save, commit_pdf_save) belongs to a later lane’s file.

Structs§

ComposedCandidate
Result of composing a source-command batch against fresh source bytes — the frozen compose_candidate’s success type (PDF-EDITOR-DISPATCH.md). pdf_compose.rs (lane C1) produces this; pdf_save.rs (lane C2) and the compose_pdf_preview command (§9.4) consume it — bytes becomes candidate/preview bytes, affected_pages becomes PreparedPdfSave.affected_pages (§10.1) and the pages compose_pdf_preview tells the frontend to re-render.
DecodedGlyph
One decoded glyph from a Tj/TJ show operand. source_range is the glyph’s byte range within the decoded operand string (start inclusive, end exclusive) and feeds SourceAddress::with_glyph for later island-span grouping (§5.3). bbox, when the font decoder can supply it, is the glyph’s font-unit bounding box (x_min, y_min, x_max, y_max, scaled to /1000 em units) used by TextState::glyph_quad for exact geometry; when absent, glyph_quad falls back to an advance-width approximation.
GlyphId
One glyph identifier within a resolved font’s own glyph index space, matching ttf_parser::GlyphId’s representation (a 16-bit glyph index) so pdf_font.rs (lane B2) and pdf_compose.rs (lane C1) can convert between the two without an extra newtype hop.
GlyphSourceAddress
One glyph’s source address — the same shape as PdfSourceSpan minus the fields (expected_text, expected_digest) that only become knowable once island grouping has concatenated a run of glyphs’ decoded text.
Matrix
2D affine transform in PDF row-vector convention: (x' y' 1) = (x y 1) x M. Used for both the graphics-state CTM (cm/q/Q) and the text matrix/text-line matrix (Tm/Td/TD/T*).
PaintState
Paint identity of a run of text, used by §5.3’s compatible_paint to decide whether two adjacent glyphs may join into the same island.
PaintedBounds
Conservative axis-aligned device-space bounding box for path paint (S, s, f, F, f*, B, B*, b, b*) or XObject Do placement, per §5.3’s coarse painted-bounds inventory. B1 records these while walking; unrelated flags an entry as belonging to content other than the island/run currently being evaluated, matching §8’s validate_layout collision check (item.unrelated && item.bounds.intersects(run.bounds)).
PdfColor
RGBA color for text-fill appearance. Mirrors frontend PdfTextAppearance["color"] (§6).
PdfDocumentRevision
PdfFontCatalogEntry
PdfPageGraph
PdfPoint
One point in unrotated PDF user-space (or device space, depending on call site — callers document which). Mirrors frontend PdfPoint (§6, owned by pdfEditModel.ts).
PdfRect
Axis-aligned rectangle in PDF user-space points. Mirrors frontend PdfRect (§6/§8, owned by pdfEditModel.ts). Used for §8 layout validation (available.contains(run.bounds)) and §5.3’s painted-bounds inventory.
PdfSourceLocator
PdfSourceSpan
PdfTextAppearance
Requested/applied text appearance for an edit. Mirrors frontend PdfTextAppearance (§6) verbatim (field order/names), used by PdfTextIsland::appearance and by PdfEditCommand.
PdfTextEditState
Rust mirror of frontend PdfSourceEdit/PdfAddText’s shared { text, appearance } shape (§6). Used for both before/after on a replace-source-text command.
PdfTextGap
A word gap the walker synthesised as a space in PdfTextIsland::text: PDF text from TeX and similar producers has no space glyphs, only TJ adjustments or position moves.
PdfTextIsland
PositionedGlyph
One glyph positioned in both PDF user-space (via text_matrix/ctm) and device space (via quad), as produced by visit_text_show (§5.2) and consumed by §5.3’s may_join grouping and painted-bounds inventory.
ResolvedPdfFont
A catalog font resolved to its actual font-program bytes, ready for glyph mapping (§7.3) and subsetting/embedding (§7.4). id matches PdfFontCatalogEntry::id — the font ID, not the family label, is what crosses the Save boundary (§7.2).
SourceAddress
Address of one show-operand (Tj, or one string item inside a TJ array) before any glyph index is known — built once per operator, then narrowed per glyph via SourceAddress::with_glyph.
TextState
Running text-object state for one page’s content-stream scan: the CTM, text matrix/text-line matrix, and the spacing/scale/leading/rise/render-mode parameters §5.2 requires tracking across q/Q/cm; BT/ET; Tm/Td/TD/T*; Tf/Tz/Tc/Tw/TL/Ts/Tr.

Enums§

PdfEditBlocker
Why an island’s own font cannot be used to write replacement text. Serialized as a snake_case string in PdfTextIsland::edit_blocker. editable == false with one of these means “no replacement can be written through this island’s font at all”; a replacement that merely needs a glyph the font lacks is not a blocker (see PdfEditError::MissingGlyphs).
PdfEditCommand
Rust mirror of frontend PdfEditCommand (§6: PdfSourceEdit | PdfAddText). #[serde(tag = "kind", rename_all = "camelCase")] on a PascalCase variant name serializes/deserializes to exactly the same "replaceSourceText"/"addText" discriminant the frontend sends, so the two sides share one wire shape without a hand-written tag. This is the commands: &[PdfEditCommand] parameter of the frozen compose_candidate signature (PDF-EDITOR-DISPATCH.md) and the source_commands field of prepare_pdf_save/compose_pdf_preview requests (§9.4/§10.1).
PdfEditError
Stable, typed rejection reasons for PDF-editor commands. Crosses Tauri IPC as a JSON tag + message; thiserror::Error gives each variant the exact user-facing string from §11. Kept verbatim against the contract — do not add fields or reorder variants without updating §11 first, since every lane (B1 inspection, B2 fonts, C1 composition, C2 save) matches on these by name.
PdfFontSource
Where a catalog font’s data comes from — bundled with RightKit (e.g. Source Serif 4) or discovered on the host system via fontdb (§7.1).
PdfOcrBackgroundProof
Proof supplied by OCR/UI inspection that a line’s background is safe to cover with an opaque rectangle. Only near-uniform backgrounds are accepted by the sparse OCR correction composer.
TextRenderMode
Text-object render mode (Tr), per PDF spec 9.3.6. Only fill/stroke visibility matters for island grouping’s compatible_paint (§5.3); modes 4-7 (clipping variants) are represented but current scope treats any clipping mode as unsupported at the call site, not here.
WritingDirection
Text writing direction. Current scope supports left-to-right only (§7.3); the other variants exist so a walker can classify and then reject unsupported content with a typed error instead of silently misinterpreting it.

Traits§

PdfFontResolver
Resolves catalog font IDs to usable font data and maps text to glyphs (§7.2). Implemented by pdf_font.rs (lane B2); consumed by the frozen compose_candidate signature (PDF-EDITOR-DISPATCH.md) as fonts: &dyn PdfFontResolver, so pdf_compose.rs (lane C1) can build and test against this trait before B2’s real implementation lands.
TextStateFont
Per-page active font handle used while walking a content stream (§5.2’s visit_text_show). Implemented by whatever page-font resolver pdf_inspect.rs (lane B1) builds from a page’s /Resources/Font — distinct from PdfFontResolver (§7.2), which resolves catalog fonts for composition/embedding, not content-stream decoding.

Functions§

compute_island_digest
island_digest: binds an island’s ordered spans, decoded glyph sequence, font identity, active matrices, paint, and geometry into one digest (§5.1) — a stronger identity check than expected_digest alone, since two visibly-identical runs of text (e.g. repeated labels) can still be told apart by their distinct source spans and transforms. Field order below is significant and part of this function’s contract: callers on either side of a save must hash the same canonicalization to agree on a digest.
document_sha256
document_sha256: identifies the exact backing bytes a PdfDocumentRevision/ PdfSourceLocator was computed against, so a command carrying a stale locator can be rejected with PdfEditError::StaleSource before it touches content streams.
expected_text_digest
expected_digest: verifies one PdfSourceSpan’s operand text hasn’t changed since the locator was built, independent of the whole-document hash — lets a save distinguish “unrelated edit elsewhere in the document” (safe) from “this exact operand changed” (reject with PdfEditError::SourceDigestMismatch).
sha256_hex
Lowercase-hex SHA-256 of bytes. Backs every digest helper below and is directly usable for PdfDocumentRevision::document_sha256/PdfSourceLocator::document_sha256.