8. Namespace `fix::` — normalização
19 operações que modificam o PDF e salvam um arquivo novo. O original nunca é alterado.
8.1 Como usar
Seção intitulada “8.1 Como usar”fix:: é o único namespace que escreve, por isso roda em comando próprio:
pdfl fix entrada.pdf script.pdfl --output corrigido.pdfOpções:
| Opção | O que faz |
|---|---|
--output <arquivo> |
PDF de saída (obrigatório) |
--dry-run |
Lista as operações sem salvar nada |
--report json|csv|html|pdf |
Formato do relatório |
--report-file <arquivo> |
Grava o relatório em arquivo |
Em pdfl run, qualquer chamada fix:: gera erro orientando a usar o comando
certo — assim ninguém aplica correções achando que está só validando.
Como as operações funcionam
Seção intitulada “Como as operações funcionam”// Este script NÃO precisa de checks: são comandos, executados na ordem.fix::set_trim_box(8.5, 8.5, 586.5, 833.5)fix::add_page_numbers()fix::add_watermark("RASCUNHO")Cada chamada é validada na hora (página inexistente, rotação inválida,
arquivo ausente) e só depois aplicada. O relatório traz o campo fixes com o
que foi feito:
"fixes": [ "TrimBox set to [8.5, 8.5, 586.5, 833.5]", "page numbering added", "watermark \"RASCUNHO\" added"]Nada impede misturar validação e correção no mesmo script:
// Valida antes de corrigir — se a pré-condição falhar, aparece no relatóriocheck "Pré-condições" { require doc.page_count > 0 assert !struct::check_encryption(), "arquivo criptografado, não dá para corrigir"}
fix::add_page_numbers()8.2 Caixas de página
Seção intitulada “8.2 Caixas de página”fix::set_page_size(largura, altura)
Seção intitulada “fix::set_page_size(largura, altura)”Define a MediaBox de todas as páginas.
// A4 em pontos — ou use unidades e deixe a conversão por conta da linguagemfix::set_page_size(595, 842)fix::set_page_size(210mm, 297mm) // idêntico, e mais legívelfix::set_crop_box(x0, y0, x1, y1), set_trim_box, set_bleed_box
Seção intitulada “fix::set_crop_box(x0, y0, x1, y1), set_trim_box, set_bleed_box”Definem a caixa correspondente em todas as páginas. Coordenadas em pontos, do canto inferior esquerdo ao superior direito.
// Arquivo veio da editora sem as caixas de produção:// TrimBox = área final; BleedBox = com 3 mm de sangria em voltafix::set_trim_box(8.5, 8.5, 586.5, 833.5)fix::set_bleed_box(0, 0, 595, 842)8.3 Páginas
Seção intitulada “8.3 Páginas”fix::rotate_page([pagina,] graus)
Seção intitulada “fix::rotate_page([pagina,] graus)”Rotaciona em 90, 180 ou 270 graus. Sem o número da página, rotaciona todas.
fix::rotate_page(90) // todas as páginasfix::rotate_page(3, 180) // só a página 3fix::delete_page(n) e fix::duplicate_page(n)
Seção intitulada “fix::delete_page(n) e fix::duplicate_page(n)”fix::delete_page(1) // remove a capa de rascunhofix::duplicate_page(1) // duplica a capa (a cópia entra logo depois)Remover a única página do documento é recusado com mensagem clara.
fix::reorder_pages([nova, ordem])
Seção intitulada “fix::reorder_pages([nova, ordem])”Nova ordem das páginas. A lista deve usar cada página exatamente uma vez.
// Documento de 4 páginas com a capa no fim: traz para o começofix::reorder_pages([4, 1, 2, 3])fix::split_document(de, ate, "saida.pdf")
Seção intitulada “fix::split_document(de, ate, "saida.pdf")”Salva um intervalo de páginas em outro arquivo. O documento em edição continua intacto.
// Separa o miolo da capa para envio a fornecedores diferentesfix::split_document(1, 2, "capa.pdf")fix::split_document(3, 50, "miolo.pdf")fix::merge_documents("outro.pdf")
Seção intitulada “fix::merge_documents("outro.pdf")”Anexa as páginas de outro PDF ao final.
fix::merge_documents("anexos/termo_de_garantia.pdf")fix::merge_documents("anexos/tabela_de_medidas.pdf")8.4 Conteúdo
Seção intitulada “8.4 Conteúdo”fix::add_watermark("texto")
Seção intitulada “fix::add_watermark("texto")”Marca d’água diagonal cinza, em todas as páginas.
fix::add_watermark("RASCUNHO — NÃO IMPRIMIR")fix::add_stamps("texto")
Seção intitulada “fix::add_stamps("texto")”Selo em vermelho no canto superior direito de cada página.
fix::add_stamps("APROVADO 02/08/2026")fix::add_page_numbers()
Seção intitulada “fix::add_page_numbers()”Numeração n / total no rodapé de cada página.
fix::add_page_numbers()fix::remove_annotations() e fix::remove_attachments()
Seção intitulada “fix::remove_annotations() e fix::remove_attachments()”Removem anotações (comentários, marcações de revisão) e arquivos anexados.
// Antes de enviar para a gráfica: comentários de revisão não podem// aparecer, e anexos só aumentam o arquivofix::remove_annotations()fix::remove_attachments()fix::flatten_layers()
Seção intitulada “fix::flatten_layers()”Remove a estrutura de camadas opcionais (OCG), deixando todo o conteúdo permanentemente visível.
// Camadas com "versão inglês" desligada podem ser reativadas por engano// na gráfica — achatar elimina o riscofix::flatten_layers()8.5 Otimização
Seção intitulada “8.5 Otimização”As operações desta seção só gravam se o arquivo encolher. Se a reescrita resultar em arquivo maior, o original é mantido.
fix::remove_unused_resources()
Seção intitulada “fix::remove_unused_resources()”Descarta objetos que não são alcançáveis a partir do trailer.
fix::remove_unused_resources()fix::downsample_images([dpi])
Seção intitulada “fix::downsample_images([dpi])”Reamostra imagens acima do DPI alvo (padrão 300). O DPI é calculado pelo tamanho impresso real da imagem na página.
// Versão para aprovação por e-mail não precisa de 300 DPIfix::downsample_images(96)
// Versão para impressão digitalfix::downsample_images(200)Imagens CMYK são preservadas. Reamostrá-las exigiria converter para RGB, o que destruiria as separações de pré-impressão. Em arquivos de gráfica, o ganho vem das imagens RGB.
fix::compress_images([qualidade])
Seção intitulada “fix::compress_images([qualidade])”Recodifica as imagens em JPEG na qualidade informada (1 a 100, padrão 85).
fix::compress_images(70)Não disponíveis
Seção intitulada “Não disponíveis”subset_fonts e linearize_document não existem como operações de fix:: e
geram erro de função desconhecida:
- subset_fonts: foi implementado e medido. Geradores profissionais já
embutem apenas os glifos usados, então o ganho medido foi de 0,5% no melhor
caso e nulo nos demais — não compensa o risco de corromper fontes. Para
verificar se as fontes estão em subset, use
prepress::subset_fonts(). - linearize_document: exige gerar hint tables (§7.14 da especificação PDF). Nenhuma biblioteca Rust faz isso, e uma versão parcial não seria reconhecida como “Fast Web View” pelos leitores.
8.6 Exemplos completos
Seção intitulada “8.6 Exemplos completos”Preparar arquivo da editora para a gráfica
Seção intitulada “Preparar arquivo da editora para a gráfica”// Uso: pdfl fix editora.pdf preparar_para_grafica.pdfl --output grafica.pdf
check "Pré-condições" { require doc.page_count > 0 assert !struct::check_encryption(), "arquivo criptografado — peça a versão aberta à editora"}
// Caixas de produção que a editora não definiufix::set_trim_box(8.5, 8.5, 586.5, 833.5)fix::set_bleed_box(0, 0, 595, 842)
// Limpeza: comentários de revisão e anexos não vão para a impressãofix::remove_annotations()fix::remove_attachments()fix::flatten_layers()fix::remove_unused_resources()Versão leve para aprovação por e-mail
Seção intitulada “Versão leve para aprovação por e-mail”// Uso: pdfl fix final.pdf versao_email.pdfl --output aprovacao.pdf
fix::downsample_images(96)fix::compress_images(70)fix::add_watermark("PROVA — NÃO É VERSÃO FINAL")fix::add_page_numbers()Conferindo o resultado com o próprio pdfl:
pdfl fix final.pdf versao_email.pdfl --output aprovacao.pdfpdfl inspect aprovacao.pdf # tamanho, DPI e avisos do arquivo geradoSeparar um livro em capa e miolo
Seção intitulada “Separar um livro em capa e miolo”// Uso: pdfl fix livro.pdf separar.pdfl --output livro_processado.pdf
check "Estrutura esperada" { assert doc.page_count > 4, "livro com apenas #{doc.page_count} páginas — estrutura inesperada"}
fix::split_document(1, 2, "saida/capa.pdf")fix::split_document(3, doc.page_count, "saida/miolo.pdf")