Classes de Utilidade e Auxiliares
Classes de Utilitários e Auxiliares
Este guia mostra como usar as pequenas e focadas classes auxiliares que Aspose.PDF FOSS para .NET oferece para tarefas de baixo nível comuns: matemática inteira usada por primitivas de segurança, configuração de busca por regex, avaliação de funções PostScript, descoberta de fontes externas, extração de subcaminhos vetoriais, medição física de texto, edições de fluxos de conteúdo em buffer, fluxos grandes em memória e relatório de versão da biblioteca. Essas classes não são pontos de entrada por si só, mas dão suporte a operações de documento, texto e renderização de alto nível em todo o API.
Auxiliares de matemática inteira
MathExtensions é um pequeno auxiliar estático usado internamente pelas primitivas de segurança da biblioteca, mas está disponível para uso geral sempre que você precisar de uma operação de módulo que sempre retorne um resultado não negativo.
// Unlike the C# % operator, Mod never returns a negative value.
int wrapped = MathExtensions.Mod(-3, 5); // 2Configuração de busca por regex
RegexManager é uma classe estática que configura o mecanismo de expressões regulares usado pelas operações de busca de texto, como TextFragmentAbsorber. Defina MatchTimeout para limitar o tempo que um padrão pode ser executado e habilite NonBacktracking para usar o mecanismo de regex sem retrocessos em buscas sensíveis a desempenho.
using var doc = Document.Open(pdfBytes);
// Guard against runaway regex patterns.
RegexManager.MatchTimeout = TimeSpan.FromSeconds(5);
RegexManager.NonBacktracking = true;
var absorber = new TextFragmentAbsorber(@"\d{3}-\d{4}", true);
doc.Pages[1].Accept(absorber);Avaliando funções PostScript
PostScriptEvaluator é uma classe estática que avalia funções PDF Tipo 4 (PDF32000 §7.10.5) — programas de calculadora PostScript incorporados em um PDF, como os usados em algumas definições de espaço de cor e sombreamento.
double[] inputs = { 0.5 };
// Evaluate a PostScript calculator program against the input array.
var outputs = PostScriptEvaluator.Evaluate("{ 2 mul }", inputs);Caminhos de pesquisa de fontes externas
ExternalFontCache gerencia as pastas pesquisadas para faces TrueType/OpenType externas (não incorporadas) durante a renderização e conversão. Use Instance para acessar o singleton, GetDefaultFontsFolders para inspecionar os locais de pesquisa incorporados e SetFontsFolders para adicioná-los ou substituí-los.
var cache = ExternalFontCache.Instance;
var defaultFolders = cache.GetDefaultFontsFolders();
// reset: false appends to the existing search paths instead of replacing them.
cache.SetFontsFolders(new[] { @"C:\Fonts\Custom" }, reset: false);Extraindo subcaminhos vetoriais
GraphicsAbsorber visita uma página e extrai seus subcaminhos vetoriais pintados como elementos SubPath, cada um contendo seu próprio limite Rectangle no espaço da página. Isso é útil para inspecionar ou medir arte vetorial sem analisar manualmente o fluxo de conteúdo.
using var doc = Document.Open(pdfBytes);
var absorber = new GraphicsAbsorber();
absorber.Visit(doc.Pages[1]);
Console.WriteLine($"Elements found: {absorber.Elements.Count}");
foreach (var element in absorber.Elements)
{
if (element is SubPath subPath)
{
Rectangle bounds = subPath.Rectangle;
Console.WriteLine($"Sub-path bounds: [{bounds.LLX}, {bounds.LLY}, {bounds.URX}, {bounds.URY}]");
}
}Medição física de segmento de texto
PhysicalTextSegment é a projeção no espaço da página de um TextSegment absorvido. Acesse-a através de TextSegment.PhysicalSegment para medir uma sequência de caracteres ou ler seu TextState resolvido.
using var doc = Document.Open(pdfBytes);
var absorber = new TextFragmentAbsorber();
doc.Pages[1].Accept(absorber);
foreach (TextFragment fragment in absorber.TextFragments)
{
foreach (TextSegment segment in fragment.Segments)
{
PhysicalTextSegment physical = segment.PhysicalSegment;
var width = physical.MeasureSegment(segment.StartCharIndex, segment.EndCharIndex, true);
TextState state = physical.TextState;
}
}Bufferizando edições de fluxo de conteúdo
ContentsAppender, acessado através de Page.ContentsAppender, armazena em buffer os operadores para prefixar ou anexar ao fluxo de conteúdo de uma página e os confirma em uma única passagem com UpdateData.
using var doc = Document.Open(pdfBytes);
Page page = doc.Pages[1];
page.ContentsAppender.AppendToBegin(new GSave());
page.ContentsAppender.AppendToEnd(new GRestore());
page.ContentsAppender.UpdateData();Grandes fluxos em memória
OptimizedMemoryStream é um fluxo em memória expansível que pode exceder o limite de 2 GB de array único do MemoryStream armazenando dados em blocos de tamanho fixo. Ele deriva de Stream, portanto suporta as operações habituais de leitura, gravação e busca.
using var stream = new OptimizedMemoryStream();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes("large payload");
stream.Write(buffer, 0, buffer.Length);
bool canSeek = stream.CanSeek;
byte[] allBytes = stream.ToArray();Informações da versão da biblioteca
BuildVersionInfo é uma classe estática que expõe o nome do produto da biblioteca e os números de versão em tempo de execução — útil para diagnósticos e solicitações de suporte.
Console.WriteLine(BuildVersionInfo.Product);
Console.WriteLine(BuildVersionInfo.AssemblyVersion);
Console.WriteLine(BuildVersionInfo.FileVersion);Dicas e Melhores Práticas
- Defina
RegexManager.MatchTimeoutantes de executar pesquisas em padrões não confiáveis ou fornecidos pelo usuário para evitar retrocessos catastróficos. - Chame
ExternalFontCache.SetFontsFolderscomreset: truequando quiser substituir totalmente os caminhos de pesquisa padrão em vez de acrescentá-los. - Prefira
OptimizedMemoryStreamaMemoryStreamao fazer buffer de documentos muito grandes ou dados de imagem que podem exceder 2 GB. - Sempre finalize um lote de edições
ContentsAppendercomUpdateData()— os operadores em buffer não são confirmados no fluxo de conteúdo até então. GraphicsAbsorber.Elementspode conter instânciasGraphicElementdiferentes deSubPath; verifique o tipo antes de converter.
Problemas Comuns
| Problema | Causa | Correção |
|---|---|---|
| A busca regex trava em padrões complexos | Nenhum timeout configurado em RegexManager | Defina RegexManager.MatchTimeout antes de executar pesquisas TextFragmentAbsorber |
As edições de fluxo de conteúdo de ContentsAppender não aparecem no arquivo salvo | UpdateData() nunca foi chamado | Chame UpdateData() após a última chamada de AppendToBegin/AppendToEnd |
| Fontes personalizadas não são detectadas durante a renderização | A pasta de fontes não foi registrada, ou reset: true limpou os padrões esperados | Chame ExternalFontCache.SetFontsFolders com a lista de pastas correta e o valor reset |
OutOfMemoryException ao fazer buffer de saída muito grande | MemoryStream atingiu seu limite de 2 GB para array único | Use OptimizedMemoryStream, que armazena dados em blocos de tamanho fixo |
FAQ
Por que MathExtensions.Mod difere do operador % C#?
MathExtensions.Mod sempre retorna um resto não negativo, enquanto o operador interno % pode retornar um valor negativo quando o dividendo é negativo.
Como impedir que uma busca de texto baseada em regex seja executada por muito tempo?
Defina RegexManager.MatchTimeout como um TimeSpan antes de construir ou executar um TextFragmentAbsorber que use um padrão regex.
O SetFontsFolders substitui ou adiciona aos caminhos de pesquisa existentes?
Depende do argumento reset: passe true para substituir a lista atual de pastas, ou false para acrescentar as novas pastas a ela.
O que o GraphicsAbsorber realmente extrai?
Ele extrai os subcaminhos vetoriais pintados de uma página como elementos SubPath, cada um com um Rectangle delimitador no espaço da página, via GraphicsAbsorber.Visit.
Quando devo usar OptimizedMemoryStream em vez de MemoryStream?
Quando os dados em buffer podem se aproximar ou exceder 2 GB, já que MemoryStream é suportado por um único array com esse limite rígido.
API Reference Resumo
| Classe / Método | Descrição |
|---|---|
MathExtensions.Mod | Auxiliar de módulo de inteiro não-negativo usado por primitivas de segurança |
RegexManager.MatchTimeout | Tempo limite aplicado a buscas de texto baseadas em regex |
RegexManager.NonBacktracking | Habilita o motor de regex sem retrocesso |
PostScriptEvaluator.Evaluate | Avalia uma função de calculadora PostScript do PDF Tipo 4 |
ExternalFontCache.Instance | Acesso singleton ao cache externo de fontes |
ExternalFontCache.GetDefaultFontsFolders | Retorna as pastas padrão de pesquisa de fontes externas |
ExternalFontCache.SetFontsFolders | Adiciona ou substitui pastas de pesquisa de fontes externas |
GraphicsAbsorber.Visit | Extrai elementos de gráficos vetoriais de uma página |
GraphicsAbsorber.Elements | Coleção de itens extraídos GraphicElement/SubPath |
SubPath.Rectangle | Retângulo delimitador no espaço da página de um subcaminho extraído |
PhysicalTextSegment.MeasureSegment | Mede um intervalo de caracteres de um segmento de texto físico |
PhysicalTextSegment.TextState | Estado de formatação resolvido de um segmento de texto físico |
ContentsAppender.AppendToBegin | Armazena em buffer um operador para prefixar ao fluxo de conteúdo da página |
ContentsAppender.AppendToEnd | Armazena em buffer um operador para anexar ao fluxo de conteúdo da página |
ContentsAppender.UpdateData | Confirma os operadores em buffer no fluxo de conteúdo |
OptimizedMemoryStream | Fluxo em memória expansível além do limite de 2 GB MemoryStream |
BuildVersionInfo.Product | Nome do produto da biblioteca em execução |
BuildVersionInfo.AssemblyVersion | Versão da assembly da biblioteca em execução |
BuildVersionInfo.FileVersion | Versão de arquivo da biblioteca em execução |