Utility and Helper Classes
Utility and Helper Classes
This guide shows how to use the small, focused helper classes that Aspose.PDF FOSS for .NET ships for common low-level tasks: integer math used by security primitives, regex search configuration, PostScript function evaluation, external font discovery, vector sub-path extraction, physical text measurement, buffered content-stream edits, large in-memory streams, and library version reporting. These classes are not entry points on their own, but they back higher-level document, text, and rendering operations throughout the API.
Integer math helpers
MathExtensions is a small static helper used internally by the library’s
security primitives, but it is available for general use whenever you need
a modulo operation that always returns a non-negative result.
// Unlike the C# % operator, Mod never returns a negative value.
int wrapped = MathExtensions.Mod(-3, 5); // 2Regex search configuration
RegexManager is a static class that configures the regular-expression
engine used by text search operations such as TextFragmentAbsorber. Set
MatchTimeout to bound how long a pattern is allowed to run, and enable
NonBacktracking to use the non-backtracking regex engine for
performance-sensitive searches.
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);Evaluating PostScript functions
PostScriptEvaluator is a static class that evaluates Type 4 PDF functions
(PDF32000 §7.10.5) — PostScript calculator programs embedded in a PDF, such
as those used in some color-space and shading definitions.
double[] inputs = { 0.5 };
// Evaluate a PostScript calculator program against the input array.
var outputs = PostScriptEvaluator.Evaluate("{ 2 mul }", inputs);External font search paths
ExternalFontCache manages the folders searched for external (non-embedded)
TrueType/OpenType faces during rendering and conversion. Use Instance to
reach the singleton, GetDefaultFontsFolders to inspect the built-in search
locations, and SetFontsFolders to add or replace them.
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);Extracting vector sub-paths
GraphicsAbsorber visits a page and extracts its painted vector sub-paths as
SubPath elements, each carrying its own page-space bounding Rectangle.
This is useful for inspecting or measuring vector artwork without parsing
the content stream by hand.
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}]");
}
}Physical text segment measurement
PhysicalTextSegment is the page-space projection of an absorbed
TextSegment. Reach it through TextSegment.PhysicalSegment to measure a
run of characters or read its resolved TextState.
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;
}
}Buffering content-stream edits
ContentsAppender, reached through Page.ContentsAppender, buffers
operators to prepend or append to a page’s content stream and commits them
in one pass with 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();Large in-memory streams
OptimizedMemoryStream is a growable in-memory stream that can exceed the
2 GB single-array limit of MemoryStream by storing data in fixed-size
chunks. It derives from Stream, so it supports the usual read, write, and
seek operations.
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();Library version information
BuildVersionInfo is a static class exposing the library’s product name and
version numbers at runtime — useful for diagnostics and support requests.
Console.WriteLine(BuildVersionInfo.Product);
Console.WriteLine(BuildVersionInfo.AssemblyVersion);
Console.WriteLine(BuildVersionInfo.FileVersion);Tips and Best Practices
- Set
RegexManager.MatchTimeoutbefore running searches over untrusted or user-supplied patterns to avoid catastrophic backtracking. - Call
ExternalFontCache.SetFontsFolderswithreset: truewhen you want to fully replace the default search paths rather than append to them. - Prefer
OptimizedMemoryStreamoverMemoryStreamwhen buffering very large documents or image data that may exceed 2 GB. - Always finish a batch of
ContentsAppenderedits withUpdateData()— buffered operators are not committed to the content stream until then. GraphicsAbsorber.Elementsmay containGraphicElementinstances other thanSubPath; check the type before casting.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
| Regex search hangs on complex patterns | No timeout configured on RegexManager | Set RegexManager.MatchTimeout before running TextFragmentAbsorber searches |
Content-stream edits from ContentsAppender don’t appear in the saved file | UpdateData() was never called | Call UpdateData() after the last AppendToBegin/AppendToEnd call |
| Custom fonts aren’t picked up during rendering | Font folder wasn’t registered, or reset: true cleared expected defaults | Call ExternalFontCache.SetFontsFolders with the correct folder list and reset value |
OutOfMemoryException when buffering very large output | MemoryStream hit its 2 GB single-array limit | Use OptimizedMemoryStream, which stores data in fixed-size chunks |
FAQ
Why does MathExtensions.Mod differ from the C# % operator?
MathExtensions.Mod always returns a non-negative remainder, whereas the
built-in % operator can return a negative value when the dividend is
negative.
How do I stop a regex-based text search from running too long?
Set RegexManager.MatchTimeout to a TimeSpan before constructing or
running a TextFragmentAbsorber that uses a regex pattern.
Does SetFontsFolders replace or add to the existing search paths?
It depends on the reset argument: pass true to replace the current
folder list, or false to append the new folders to it.
What does GraphicsAbsorber actually extract?
It extracts the painted vector sub-paths of a page as SubPath elements,
each with a page-space bounding Rectangle, via GraphicsAbsorber.Visit.
When should I use OptimizedMemoryStream instead of MemoryStream?
When the buffered data may approach or exceed 2 GB, since MemoryStream is
backed by a single array with that hard limit.
API Reference Summary
| Class / Method | Description |
|---|---|
MathExtensions.Mod | Non-negative integer modulo helper used by security primitives |
RegexManager.MatchTimeout | Timeout applied to regex-based text searches |
RegexManager.NonBacktracking | Enables the non-backtracking regex engine |
PostScriptEvaluator.Evaluate | Evaluates a Type 4 PDF PostScript calculator function |
ExternalFontCache.Instance | Singleton access to the external font cache |
ExternalFontCache.GetDefaultFontsFolders | Returns the default external font search folders |
ExternalFontCache.SetFontsFolders | Adds or replaces external font search folders |
GraphicsAbsorber.Visit | Extracts vector graphics elements from a page |
GraphicsAbsorber.Elements | Collection of extracted GraphicElement/SubPath items |
SubPath.Rectangle | Page-space bounding rectangle of an extracted sub-path |
PhysicalTextSegment.MeasureSegment | Measures a character range of a physical text segment |
PhysicalTextSegment.TextState | Resolved formatting state of a physical text segment |
ContentsAppender.AppendToBegin | Buffers an operator to prepend to a page’s content stream |
ContentsAppender.AppendToEnd | Buffers an operator to append to a page’s content stream |
ContentsAppender.UpdateData | Commits buffered operators to the content stream |
OptimizedMemoryStream | Growable in-memory stream beyond the 2 GB MemoryStream limit |
BuildVersionInfo.Product | Product name of the running library |
BuildVersionInfo.AssemblyVersion | Assembly version of the running library |
BuildVersionInfo.FileVersion | File version of the running library |