Skip to content

Criação de anotações

O PDF Oxide suporta a criação de todos os tipos padrão de anotação PDF. As anotações podem ser adicionadas via FluentPageBuilder (API DocumentBuilder) ou PageBuilder (API PdfWriter).

Cobertura de bindings (v0.3.38). Os 15 métodos de anotação do DocumentBuilder / FluentPageBuilderlink_url / link_page / link_named, highlight, underline, strikeout, squiggly, nota adesiva, carimbo (14 tipos padrão + personalizado), texto livre e marca d’água (personalizada / DRAFT / CONFIDENTIAL) — estão disponíveis em Rust, Python, Node/TypeScript, C#, Go e WASM. A superfície de mais baixo nível no PdfWriter, com formas específicas por método (ink, polygon, polyline, caret, popup, anexo de arquivo, redact), é exclusiva do Rust; use DocumentBuilder nos outros bindings ou edite PDFs existentes via Edição de anotações.

Exemplo rápido

Rust (DocumentBuilder)

use pdf_oxide::writer::{DocumentBuilder, PageSize, StampType};

let mut builder = DocumentBuilder::new();
builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .text("Click here for details")
    .link_url("https://example.com")
    .text("Important finding")
    .highlight((1.0, 1.0, 0.0))  // Yellow highlight
    .sticky_note("Review this section carefully")
    .stamp(StampType::Approved)
    .done();

builder.save("annotated.pdf")?;

Rust (PdfWriter)

use pdf_oxide::writer::PdfWriter;
use pdf_oxide::geometry::Rect;

let mut writer = PdfWriter::new();
{
    let mut page = writer.add_letter_page();
    page.add_text("Document text", 72.0, 720.0, "Helvetica", 12.0);
    page.link(Rect::new(72.0, 720.0, 100.0, 12.0), "https://example.com");
    page.highlight_rect(Rect::new(72.0, 700.0, 200.0, 12.0));
    page.sticky_note(Rect::new(300.0, 720.0, 24.0, 24.0), "A note");
    page.finish();
}
writer.save("annotated.pdf")?;

Python

from pdf_oxide import DocumentBuilder, StampType

pdf = (DocumentBuilder()
    .letter_page()
        .at(72, 720).text("Click here for details")
        .link_url("https://example.com")
        .text("Important finding")
        .highlight((1.0, 1.0, 0.0))
        .sticky_note("Review this section carefully")
        .stamp(StampType.APPROVED)
    .done()
    .save("annotated.pdf"))

Node / TypeScript

import { DocumentBuilder, StampType } from "pdf-oxide";

await new DocumentBuilder()
  .letterPage()
    .at(72, 720).text("Click here for details")
    .linkUrl("https://example.com")
    .text("Important finding")
    .highlight([1.0, 1.0, 0.0])
    .stickyNote("Review this section carefully")
    .stamp(StampType.Approved)
  .done()
  .save("annotated.pdf");

C#

using PdfOxide;

DocumentBuilder.Create()
    .LetterPage()
        .At(72, 720).Text("Click here for details")
        .LinkUrl("https://example.com")
        .Text("Important finding")
        .Highlight(1.0, 1.0, 0.0)
        .StickyNote("Review this section carefully")
        .Stamp(StampType.Approved)
    .Done()
    .Save("annotated.pdf");

Go

builder := pdfoxide.NewDocumentBuilder()
builder.LetterPage().
    At(72, 720).Text("Click here for details").
    LinkUrl("https://example.com").
    Text("Important finding").
    Highlight(1.0, 1.0, 0.0).
    StickyNote("Review this section carefully").
    Stamp(pdfoxide.StampApproved).
    Done()
_ = builder.Save("annotated.pdf")

JavaScript (WASM) — atalhos de anotação em PDFs existentes

Os helpers legados addLink / addHighlight / addNote continuam funcionando para editar PDFs já existentes:

import init, { WasmPdfDocument } from "pdf-oxide-wasm/web";
await init();

const doc = new WasmPdfDocument(bytes);
doc.addLink(0, 100, 200, 300, 50, "https://oxide.fyi");
doc.addHighlight(0, 100, 700, 400, 20);
doc.addNote(0, 50, 750, "Review this section");
const saved = doc.save();
doc.free();

Para anotações na hora da criação a partir do WASM, use DocumentBuilder (mesma API do exemplo Node/TS acima).

Tipos de anotação

Anotações de Texto (Notas Adesivas)

Notas pop-up com vários ícones.

use pdf_oxide::writer::PdfWriter;
use pdf_oxide::annotation_types::TextAnnotationIcon;
use pdf_oxide::geometry::Rect;

let mut writer = PdfWriter::new();
{
    let mut page = writer.add_letter_page();

    // Default note icon
    page.sticky_note(Rect::new(72.0, 720.0, 24.0, 24.0), "Review this section");

    // Comment icon
    page.comment(Rect::new(72.0, 690.0, 24.0, 24.0), "Needs clarification");

    // Custom icon
    page.text_note_with_icon(
        Rect::new(72.0, 660.0, 24.0, 24.0),
        "Important",
        TextAnnotationIcon::Key,
    );

    page.finish();
}

Ícones disponíveis: Note, Comment, Key, Help, NewParagraph, Paragraph, Insert

Equivalente FluentPageBuilder:

builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .sticky_note("Review this")
    .sticky_note_with_icon("Important", TextAnnotationIcon::Key)
    .sticky_note_at(300.0, 720.0, "Positioned note")
    .done();

Links URL e navegação interna de páginas.

// URL link
page.link(Rect::new(72.0, 720.0, 150.0, 12.0), "https://example.com");

// Internal page link (0-indexed page number)
page.internal_link(Rect::new(72.0, 700.0, 100.0, 12.0), 2);

FluentPageBuilder:

builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .text("Visit website")
    .link_url("https://example.com")
    .text("Go to appendix")
    .link_page(5)
    .text("Jump to glossary")
    .link_named("glossary")
    .done();

Anotações de Texto Livre

Texto exibido diretamente na superfície da página.

use pdf_oxide::geometry::Rect;

// Basic text box
page.textbox(Rect::new(72.0, 650.0, 200.0, 50.0), "Annotation text");

// Styled text box
page.textbox_styled(
    Rect::new(72.0, 580.0, 200.0, 50.0),
    "Styled text",
    "Courier",
    14.0,
);

// Centered text
page.textbox_centered(Rect::new(72.0, 520.0, 200.0, 30.0), "Centered");

// Callout with leader line
page.callout(
    Rect::new(200.0, 450.0, 150.0, 50.0),
    "Callout text",
    vec![150.0, 430.0, 200.0, 475.0],
);

// Typewriter (borderless text)
page.typewriter(Rect::new(72.0, 400.0, 300.0, 20.0), "Typewriter text");

FluentPageBuilder:

builder.page(PageSize::Letter)
    .freetext(Rect::new(100.0, 600.0, 200.0, 50.0), "Comment text")
    .freetext_styled(Rect::new(100.0, 530.0, 200.0, 50.0), "Styled", "Courier", 14.0)
    .done();

Destaque, Sublinhado, Tachado, Ondulado

Anotações de marcação de texto para revisão.

use pdf_oxide::geometry::Rect;

page.highlight_rect(Rect::new(72.0, 720.0, 200.0, 12.0));
page.underline_rect(Rect::new(72.0, 700.0, 200.0, 12.0));
page.strikeout_rect(Rect::new(72.0, 680.0, 200.0, 12.0));
page.squiggly_rect(Rect::new(72.0, 660.0, 200.0, 12.0));

Com QuadPoints explícitos para posicionamento preciso:

page.highlight(
    Rect::new(72.0, 720.0, 200.0, 12.0),
    vec![[72.0, 732.0, 272.0, 732.0, 72.0, 720.0, 272.0, 720.0]],
);

FluentPageBuilder (color is RGB 0.0-1.0):

builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .text("Highlighted text")
    .highlight((1.0, 1.0, 0.0))    // Yellow
    .text("Underlined text")
    .underline((0.0, 0.0, 1.0))    // Blue
    .text("Deleted text")
    .strikeout((1.0, 0.0, 0.0))    // Red
    .text("Questionable text")
    .squiggly((1.0, 0.5, 0.0))     // Orange
    .done();

Anotações de Linha

Linhas e setas entre dois pontos.

// Simple line
page.line((100.0, 500.0), (300.0, 500.0));

// Arrow
page.arrow((100.0, 470.0), (300.0, 470.0));

// Double-headed arrow
page.double_arrow((100.0, 440.0), (300.0, 440.0));

Anotações de Forma (Quadrado, Círculo)

Retângulos e elipses.

use pdf_oxide::geometry::Rect;

// Rectangle outline
page.rectangle(Rect::new(72.0, 400.0, 150.0, 80.0));

// Filled rectangle
page.rectangle_filled(
    Rect::new(250.0, 400.0, 150.0, 80.0),
    (0.0, 0.0, 1.0),  // Blue stroke
    (0.8, 0.8, 1.0),  // Light blue fill
);

// Circle outline
page.circle(Rect::new(72.0, 300.0, 80.0, 80.0));

// Filled circle
page.circle_filled(
    Rect::new(180.0, 300.0, 80.0, 80.0),
    (1.0, 0.0, 0.0),  // Red stroke
    (1.0, 0.9, 0.9),  // Light red fill
);

Anotações de Polígono e Polilinha

Polígonos fechados e polilinhas abertas.

// Closed triangle
page.polygon(vec![(200.0, 250.0), (250.0, 300.0), (150.0, 300.0)]);

// Filled polygon
page.polygon_filled(
    vec![(300.0, 250.0), (350.0, 300.0), (250.0, 300.0)],
    (0.0, 0.5, 0.0),  // Green stroke
    (0.8, 1.0, 0.8),  // Light green fill
);

// Open polyline (zigzag)
page.polyline(vec![
    (72.0, 200.0), (150.0, 230.0), (220.0, 200.0), (300.0, 230.0),
]);

Anotações a Tinta (Desenho à Mão Livre)

Traços e desenhos à mão livre.

// Single stroke
page.ink(vec![(100.0, 150.0), (120.0, 170.0), (140.0, 150.0), (160.0, 170.0)]);

// Multiple strokes
page.freehand(vec![
    vec![(100.0, 100.0), (200.0, 100.0)],  // Horizontal line
    vec![(150.0, 50.0), (150.0, 150.0)],    // Vertical line
]);

// Styled ink
page.ink_styled(
    vec![(200.0, 150.0), (250.0, 180.0), (300.0, 150.0)],
    (1.0, 0.0, 0.0),  // Red
    3.0,               // 3pt line width
);

Anotações de Carimbo

Anotações padrão tipo carimbo.

use pdf_oxide::writer::StampType;
use pdf_oxide::geometry::Rect;

page.stamp(Rect::new(400.0, 700.0, 150.0, 50.0), StampType::Approved);
page.stamp_approved(Rect::new(400.0, 640.0, 150.0, 50.0));
page.stamp_draft(Rect::new(400.0, 580.0, 120.0, 40.0));
page.stamp_confidential(Rect::new(400.0, 520.0, 150.0, 50.0));
page.stamp_final(Rect::new(400.0, 460.0, 100.0, 40.0));
page.stamp_not_approved(Rect::new(400.0, 400.0, 150.0, 50.0));
page.stamp_for_comment(Rect::new(400.0, 340.0, 150.0, 50.0));
page.stamp_custom(Rect::new(400.0, 280.0, 150.0, 50.0), "ReviewPending");

StampType variants: Approved, Experimental, NotApproved, AsIs, Expired, NotForPublicRelease, Confidential, Final, Sold, Departmental, ForComment, TopSecret, Draft, ForPublicRelease, Custom(String)

Anotações de Marca d’Água

Marcas d’água em nível de página que aparecem atrás do conteúdo.

// FluentPageBuilder API
builder.page(PageSize::Letter)
    .watermark("DRAFT")
    .done();

builder.page(PageSize::Letter)
    .watermark_confidential()
    .done();

builder.page(PageSize::Letter)
    .watermark_draft()
    .done();

Anotações de Redação

Marcar regiões para redação.

use pdf_oxide::geometry::Rect;

page.redact(Rect::new(72.0, 600.0, 200.0, 20.0));
page.redact_with_text(Rect::new(72.0, 570.0, 200.0, 20.0), "REDACTED");

Tipos de Anotação Adicionais

use pdf_oxide::geometry::Rect;

// Popup window
page.popup(Rect::new(200.0, 500.0, 200.0, 100.0), true);

// Caret (text insertion marker)
page.caret(Rect::new(72.0, 450.0, 20.0, 20.0));
page.caret_paragraph(Rect::new(72.0, 420.0, 20.0, 20.0));
page.caret_with_comment(Rect::new(72.0, 390.0, 20.0, 20.0), "Insert paragraph here");

// File attachment
page.file_attachment(Rect::new(72.0, 350.0, 24.0, 24.0), "report.xlsx");
page.file_attachment_paperclip(Rect::new(72.0, 320.0, 24.0, 24.0), "notes.txt");

Método de Anotação Genérico

Adicionar qualquer tipo de anotação usando o método genérico add_annotation():

use pdf_oxide::writer::{LinkAnnotation, Annotation};
use pdf_oxide::geometry::Rect;

let link = LinkAnnotation::uri(
    Rect::new(72.0, 720.0, 100.0, 12.0),
    "https://example.com",
);

page.add_annotation(link);

Exemplo Avançado

Demonstração Completa de Anotações

use pdf_oxide::writer::{PdfWriter, StampType};
use pdf_oxide::geometry::Rect;

let mut writer = PdfWriter::new();
{
    let mut page = writer.add_letter_page();

    // Links
    page.add_text("Visit Rust", 72.0, 750.0, "Helvetica", 12.0);
    page.link(Rect::new(72.0, 750.0, 70.0, 12.0), "https://rust-lang.org");

    // Text markup
    page.highlight_rect(Rect::new(72.0, 720.0, 150.0, 12.0));
    page.underline_rect(Rect::new(72.0, 700.0, 150.0, 12.0));
    page.strikeout_rect(Rect::new(72.0, 680.0, 150.0, 12.0));
    page.squiggly_rect(Rect::new(72.0, 660.0, 150.0, 12.0));

    // Notes
    page.sticky_note(Rect::new(300.0, 720.0, 24.0, 24.0), "Important");
    page.comment(Rect::new(340.0, 720.0, 24.0, 24.0), "Review needed");

    // Shapes
    page.line((72.0, 620.0), (250.0, 620.0));
    page.arrow((72.0, 600.0), (250.0, 600.0));
    page.rectangle(Rect::new(72.0, 540.0, 100.0, 50.0));
    page.circle(Rect::new(200.0, 540.0, 50.0, 50.0));

    // Ink
    page.ink(vec![(72.0, 500.0), (120.0, 520.0), (170.0, 500.0)]);

    // Stamp
    page.stamp_approved(Rect::new(400.0, 720.0, 150.0, 50.0));

    // Redact
    page.redact(Rect::new(72.0, 450.0, 200.0, 15.0));

    page.finish();
}
writer.save("annotation_showcase.pdf")?;

Páginas Relacionadas