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/FluentPageBuilder—link_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 noPdfWriter, com formas específicas por método (ink,polygon,polyline,caret,popup, anexo de arquivo,redact), é exclusiva do Rust; useDocumentBuildernos 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();
Anotações de Link
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
- API fluente DocumentBuilder — construção fluente de páginas com anotações
- Criação de campos de formulário — campos de formulário interativos
- Gráficos, padrões e sombreamentos — primitivas de desenho de baixo nível