Formats9 min de leitura

Como funciona a edição de texto em um PDF: fluxos de conteúdo, codificações de fonte e por que só se edita uma linha por vez

Uma página PDF não tem parágrafos nem caixas de texto, só instruções para desenhar glifos com uma fonte em uma posição. Editar uma linha apaga as instruções antigas e escreve novas no mesmo lugar, e isso define o que pode ou não ser editado.

PDF123 · Updated 2026-10-14
Como funciona a edição de texto em um PDF: fluxos de conteúdo, codificações de fonte e por que só se edita uma linha por vez

Uma página PDF não tem parágrafos nem caixas de texto. Ela tem uma lista de instruções: nesta posição, com esta fonte e este tamanho, desenhe estes glifos. Mudar o texto significa apagar as instruções que desenham aquela linha e escrever novas na mesma posição, com a mesma fonte, tamanho e cor. Por isso o Editar PDF edita uma linha por vez e não consegue quebrar o texto automaticamente: isso decorre da forma como o texto é armazenado.

Como é uma linha de texto dentro do arquivo

O conteúdo de uma página fica em um fluxo de conteúdo, um pequeno programa feito de operadores. Quatro operadores fazem a maior parte do trabalho com texto: BT e ET delimitam um bloco de texto, Tf escolhe a fonte e o tamanho, Td move para a posição seguinte e Tj desenha uma string. Com uma fonte padrão, o caso mais simples é este:

BT /F1 18 Tf 20 150 Td (Hello World) Tj ET

Isso significa: escolha a fonte F1 a 18 pontos, vá para x 20, y 150 e desenhe Hello World. Um PDF impresso pelo Chrome costuma ser diferente: os parênteses deixam de conter caracteres e passam a conter números de glifo da fonte, e o Tm define a posição uma única vez. Abaixo está a linha Hello World from Georgia de uma página exportada pelo Chrome, em que cada quatro dígitos hexadecimais são um número de glifo:

BT /F4 24 Tf 1 0 0 -1 30 52 Tm <002b0048004f004f00520003003a00520055004f0047000300490055005200500003002a004800520055004a004c0044> Tj ET

002b é H, 0048 é e, 004f é l, 0003 é um espaço, 003a é W, e assim por diante. Esses números só significam algo dentro dessa fonte específica; não são Unicode. Quando você copia o texto, o visualizador converte os números de volta em caracteres com uma tabela de consulta guardada em outra parte do arquivo.

Daí decorrem duas coisas. Primeiro, nada no fluxo de conteúdo diz "isto é um parágrafo": uma quebra de linha é só outro Td ou Tm que move a posição para a linha seguinte, e quantas linhas um parágrafo tem precisa ser deduzido a partir das posições. Segundo, para escrever um caractere novo em uma linha você precisa do número desse caractere nessa fonte, e a fonte muitas vezes contém apenas os glifos que foram usados quando o arquivo foi escrito. Esse é o resultado do subsetting de fontes.

Você pode expandir os fluxos com o qpdf:

qpdf --qdf --object-streams=disable in.pdf out.pdf

Abra out.pdf em um editor de texto e procure por Tj para ver todas as strings desenhadas na página. Para saber o que mais um PDF contém, veja O que há dentro de um PDF: objetos, streams e a tabela de referência cruzada.

Como o editor reconstrói uma "linha" a partir de glifos

O editor precisa primeiro agrupar glifos soltos em uma linha em que o usuário possa clicar. Glifos com a mesma fonte, tamanho e cor, cuja distância até o glifo anterior não passa de um tamanho de fonte, formam um mesmo trecho (um grupo de glifos vizinhos); uma quebra de linha, uma fonte nova ou uma cor nova encerra o trecho. O texto que corre da direita para a esquerda, ou na vertical, não é agrupado e não pode ser aberto para edição.

Há duas consequências que dá para observar diretamente. Uma linha que mistura duas fontes, como uma linha em chinês com uma palavra em inglês, é dividida em dois trechos vizinhos, nos quais se clica separadamente. Depois de uma edição acontece o mesmo: se o texto novo usa outra fonte, a linha vira dois trechos, e editar um deles deixa o outro como estava.

Editando uma linha: apagar o texto antigo e escrever o novo

A exclusão usa a tarja só de texto: os glifos dentro da área da linha são removidos do fluxo de conteúdo, imagens e linhas ficam como estão e nenhuma caixa colorida é desenhada sobre o texto antigo, de modo que copiar e buscar já não o encontram. Isso muda apenas o conteúdo da página; se o mesmo texto também aparece em uma anotação ou nas propriedades do documento, elas não são afetadas.

A escrita acrescenta uma instrução de texto nova no fim do fluxo de conteúdo da página, a partir da posição da linha de base da linha original e reaproveitando o tamanho e a cor dela. Depois de mudar a linha acima para Hello World 2, o que é acrescentado no fim da página é:

q 1 0 0 1 22.5 148.92 cm 0 0 0 rg
/Span <</ActualText <feff00480065006c006c006f00200057006f0072006c006400200032>>> BDC
BT /F4 18 Tf 0 0 Td <002b0048004f004f00520003003a00520055004f00470003> Tj ET
BT /F9 18 Tf 102.18 0 Td (2) Tj ET
EMC
Q

O primeiro BT usa a fonte original F4 e os números de glifo originais, então Hello World é reaproveitado exatamente como estava. O "2" não está no subconjunto da fonte original, por isso o segundo BT inicia uma nova fonte Helvetica padrão (F9) para desenhá-lo. q e Q restringem a transformação de coordenadas e a cor deste bloco a ele mesmo; o editor também envolve o conteúdo original em um par q/Q, para que um estado deixado desbalanceado no fim da página original não afete o texto novo. Esse é o aspecto de um trecho; os números variam conforme o arquivo.

Acrescentar no fim tem três consequências:

  • O texto novo é pintado por último, por cima de todo o resto da página. O texto que ficava sob uma imagem ou um bloco colorido aparece acima dele depois de uma edição.
  • Uma ferramenta que extrai texto na ordem do fluxo de conteúdo (como pdftotext -raw) lê a linha editada por último naquela página, enquanto a extração por posição (pdftotext -layout) não mostra mudança. A página parece a mesma, mas a ordem de leitura mudou.
  • O editor anexa um ActualText ao texto novo, que informa ao visualizador quais caracteres reais os glifos representam. Um glifo pode corresponder a vários caracteres, e procurá-lo só pelo número do glifo às vezes devolve um caractere de compatibilidade (por exemplo, ler 文 como o radical Kangxi ⽂); o ActualText garante que o que você copia é o que você digitou.

Qual fonte desenha o texto novo

Reaproveitar a fonte original é a opção mais segura, porque o formato dos glifos, o peso e a largura combinam com o que está ao lado. Poder reaproveitá-la depende de o editor conseguir saber qual código um caractere tem nessa fonte:

  • Uma fonte composta como a de cima (Type0, números de glifo de dois bytes, codificação Identity-H): procura-se o caractere na fonte para obter o número do glifo e, se ele for encontrado, usa-se esse número. Se não for encontrado, o caractere não está no subconjunto.
  • Uma fonte simples de um byte (TrueType, Type1) com codificação WinAnsi ou MacRoman: o mapeamento entre caractere e byte é fixo, e as larguras vêm da tabela de larguras do arquivo.
  • Uma fonte com codificação personalizada (Differences) ou que depende da codificação embutida da fonte: não há mapeamento confiável, então o editor não adivinha e recorre a uma fonte alternativa; do contrário o texto sairia ilegível.

Quando um caractere não está na fonte original, usa-se uma fonte alternativa. Letras latinas simples usam a mais próxima entre Helvetica, Times e Courier, fontes padrão que todo visualizador tem, então não é preciso embutir nada. Todo o resto, como caracteres chineses, kana, hangul, tailandês, letras latinas acentuadas, cirílico e grego, usa uma fonte Noto de código aberto: o servidor pega os caracteres da requisição e recorta só esses glifos da fonte completa com a biblioteca de subsetting de código aberto HarfBuzz, geralmente alguns KB, e o navegador os embute no seu arquivo. A forma regional de um caractere chinês segue o idioma da interface: chinês simplificado, tradicional, japonês ou coreano.

Os glifos são embutidos em vez de se escrever apenas o nome de uma fonte porque uma fonte referenciada só pelo nome é trocada por qualquer alternativa que cada visualizador escolha, e o peso pode diferir de um visualizador para outro; depois de embutidos, todos os visualizadores mostram os mesmos formatos.

Por que só uma linha por vez

O editor não tem mecanismo de layout. Cada posição de glifo é fixa no arquivo; o texto novo é apenas disposto para a direita a partir do ponto inicial, usando as larguras da fonte, sem lógica de "quebrar na margem", e nada depois dele é movido. Se você alonga uma linha, os caracteres excedentes seguem para a direita, e o que passar da borda da página não pode ser visto. Reescrever um parágrafo ou acrescentar linhas a uma tabela exige um layout novo, o que significa voltar ao arquivo de origem a partir do qual o PDF foi feito.

As larguras também são apenas as larguras de avanço da própria fonte (quanto a posição de escrita avança depois de cada glifo), sem kerning nem substituição de glifos. O texto que não precisa de shaping (a escolha e o posicionamento dos glifos conforme o contexto: latino, cirílico, grego e caracteres chineses) é disposto corretamente. As marcas de tom do tailandês precisam de posicionamento de glifos para ficar no lugar certo, o que o editor não faz, então podem ficar deslocadas. O árabe precisa de formas de glifo que dependem do contexto e de layout da direita para a esquerda, o hebraico precisa de layout da direita para a esquerda e as escritas índicas precisam que consoantes e sinais vocálicos se combinem em glifos; tudo isso exige shaping de texto completo, que o editor não faz hoje, então digitá-los é recusado em vez de produzir caracteres errados.

Dois outros limites vêm do próprio arquivo. O conteúdo de uma página digitalizada é uma única imagem sem operadores de texto, então não há nada para apagar ou mudar. Depois que um arquivo com assinatura digital é editado, o conteúdo original que a assinatura protegia mudou, e a assinatura deixa de ser válida.

Confira você mesmo

Você pode ver as mudanças descritas acima em um arquivo baixado com três comandos:

pdftotext -raw edited.pdf -      # extrai na ordem do fluxo de conteúdo: o texto antigo sumiu, a linha editada vem por último
pdffonts edited.pdf              # lista de fontes: as fontes originais que foram reaproveitadas e o subconjunto de fonte recém-embutido
qpdf --qdf --object-streams=disable edited.pdf edited.qdf   # expande o fluxo de conteúdo; o bloco BT ... ET acrescentado está no fim

Continue lendo

Open tool
Process in the browser — no watermark, files removed after the job.
Open tool