The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: set the desired family in the HTML/CSS, register the corresponding TTF or TTC file with an XMLWorkerFontProvider, and pass that same provider to the XML Worker conversion call. The file must contain the glyphs your text needs, and the HTML bytes must be decoded with the correct charset. Merely writing a new font-family name does not make iTextSharp find an arbitrary font file.
The working model: CSS name, registered file, and conversion provider
iTextSharp 5’s XML Worker has three separate jobs to connect:
- CSS chooses a family. Your HTML or stylesheet declares a name such as
My FontorNoto Naskh Arabic. - The font provider knows the file. Register the actual
.ttfor.ttcfile; XML Worker does not infer a disk path from a CSS string. - The parser uses that provider. Supply the configured provider to
ParseXHtml, or attach it to theHtmlPipelineContextin a manual pipeline.
The CSS family text and the font’s internal family name usually correspond, but they are not guaranteed to be the same string as the filename. If a family does not resolve, inspect the internal name and use the spelling exposed by the font.
Recommended Free Tools
These instructions apply to iTextSharp 5 with the XML Worker add-on. XML Worker is intended for predictable XHTML and CSS templates, not for rendering an arbitrary web page as a browser would. The older HTMLWorker class is deprecated and has more limited HTML/CSS support. iText 7’s pdfHTML uses a different API and should not be mixed with this code. See iText’s scope overview at the iText conversion guide.
A complete C# example
The following pattern explicitly registers the faces it uses and parses UTF-8 HTML. Adjust namespaces and overloads to the versions installed in your project.
using System.IO;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.pipeline.css;
var html = @"<html>
<head>
<style>
body { font-family: My Font; font-size: 11pt; }
h1 { font-family: My Font; font-weight: bold; }
</style>
</head>
<body><h1>Invoice</h1><p>Text rendered with the registered family.</p></body>
</html>";
using (var output = File.Create("result.pdf"))
using (var document = new Document())
{
var writer = PdfWriter.GetInstance(document, output);
document.Open();
var fontProvider = new XMLWorkerFontProvider(
XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.Register("resources/fonts/MyFont-Regular.ttf");
fontProvider.Register("resources/fonts/MyFont-Bold.ttf");
using (var htmlStream = new MemoryStream(Encoding.UTF8.GetBytes(html)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(
writer, document, htmlStream, null,
Encoding.UTF8, fontProvider);
}
document.Close();
}
The HTML can instead be read from a file or supplied as a separate CSS stream. The important part is that the provider passed to ParseXHtml is the one containing your registrations. Creating a provider but passing a different provider—or no provider—does not change font lookup.
For the documented helper signature and Arabic example, compare iText’s XML Worker instructions. The dependency example for iTextSharp 5.5.7 lists itextsharp.dll and itextsharp.xmlworker.dll; those names are specific to that package example, so verify the assemblies and versions in your own project at the package guide.
Register each style you actually use
Regular, bold, and italic faces
A regular file is not automatically a reliable source for every weight and style. Register the files your template requests:
fontProvider.Register("resources/fonts/Cardo-Regular.ttf");
fontProvider.Register("resources/fonts/Cardo-Bold.ttf");
fontProvider.Register("resources/fonts/Cardo-Italic.ttf");
Then use matching CSS declarations, for example font-weight: bold and font-style: italic. XML Worker can apply substitution rules, but substitution should be intentional: a synthetic or substituted face may not have the same metrics or appearance as the real face. The iText discussion of explicit registrations and substitutions is at Why is XMLWorker parsing slow?.
Rank #2
TrueType collections
If you use a .ttc collection, confirm which face index your installed XML Worker version expects and test every requested style. A deployment that works with a standalone TTF can fail when a collection path or face selection is interpreted differently.
Font licensing
Embedding a font in a PDF may be restricted by its license. Check the license for redistribution and embedding rights before placing the file in an application or shipping generated documents. Registration APIs do not grant those rights; the legacy FontFactory documentation is useful for understanding registration and embedding concepts.
Make the family declaration reach XML Worker
Put the declaration in inline CSS, a <style> block, or a stylesheet that you actually pass to the parser. For example:
<style>
body { font-family: My Font; }
.arabic { font-family: Noto Naskh Arabic; }
</style>
When using a separate stylesheet stream, pass it in the CSS-stream argument of ParseXHtml. A stylesheet sitting beside the HTML file is not automatically loaded unless your pipeline supplies it. Keep the HTML predictable and well-formed XHTML; malformed markup or browser-only CSS can prevent the rule from being applied even when the font is registered correctly.
Encoding, glyph coverage, and right-to-left scripts
Use the charset that matches the bytes
Encoding.UTF8 is appropriate when the source bytes are UTF-8. It cannot repair text that was already decoded incorrectly, nor can it compensate for a database or file saved in another encoding. Decode the source once with the correct charset, then pass matching bytes and encoding to XML Worker.
Verify glyph coverage
A successful registration does not mean the typeface contains every character. Test accented Latin, currency signs, punctuation, Cyrillic, Arabic, CJK, or any other scripts in your real documents. Missing glyphs can appear as empty boxes or omitted characters; choose a font with coverage for that script, or design an explicit fallback strategy.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Arabic and other RTL text
Font selection and text direction are separate. Arabic requires a font with Arabic glyphs and appropriate right-to-left handling in the document and pipeline. The official Arabic example demonstrates font-family: Noto Naskh Arabic, registers NotoNaskhArabic-Regular.ttf, and discusses direction separately at the XML Worker Arabic page.
Manual pipeline configuration
If the convenience helper does not fit your architecture, attach the provider to the HTML pipeline’s CSS appliers. The essential relationship is the same:
var fontProvider = new XMLWorkerFontProvider(
XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.Register("resources/fonts/MyFont-Regular.ttf");
var cssAppliers = new CssAppliersImpl(fontProvider);
var htmlContext = new HtmlPipelineContext(cssAppliers);
// Configure tag processors, image providers, and your CSS resolver here.
// Build the CSSResolver, HtmlPipeline, and PdfWriterPipeline,
// then run XMLWorker with this context.
Exact constructors vary between XML Worker releases, so use the signatures in the installed assembly. The critical point is that the CssAppliersImpl receives the same provider containing the registered files.
Predictable font loading in production
Use an explicit path strategy
Relative paths often resolve against the process working directory, which may differ between Visual Studio, IIS, a Windows service, a container, and a scheduled job. Resolve the font directory from a known application base path, verify the file exists at startup, and log the final path. Include the font files in deployment output rather than assuming they exist on the server.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #4
Avoid unnecessary directory scans
The default helper can search font directories. For a controlled set of fonts, DONTLOOKFORFONTS plus explicit Register calls removes that discovery work and makes the input deterministic. iText describes this as reducing lookup overhead, not as a guaranteed speed increase; benchmark your own workload and cache immutable registration data where your application design permits.
Embedding and output validation
Open a generated PDF in more than one viewer and inspect its font properties. Confirm that the intended family and styles are embedded or otherwise available according to your compliance requirements. A PDF that looks correct on the build machine can fail on a client machine if it depends on an unembedded system font.
Troubleshooting by symptom
| Symptom | Likely cause | Fix |
|---|---|---|
| PDF still uses a default font | The CSS rule is not loaded, the family name does not resolve, or the configured provider was not passed to XML Worker. | Confirm the stylesheet stream, internal family name, registration call, and the exact provider argument in the parse call. |
| Boxes or missing characters | The registered face lacks the glyphs. | Choose a typeface covering the required script and test representative characters. |
| Works locally, fails after deployment | The font path is relative, the file was not copied, or the process lacks permission. | Log an absolute path, check file existence and permissions in the deployed environment, and package the font explicitly. |
| Bold or italic looks like regular text | Only the regular face was registered or substitution produced an unexpected result. | Register the actual bold and italic files and verify CSS weight/style values. |
| Arabic is reversed or disconnected | Direction and shaping configuration are incomplete; changing the family alone is insufficient. | Follow the RTL guidance in the official Arabic example and test mixed-direction paragraphs. |
| Conversion is unexpectedly slow | Font-directory discovery or repeated registration is occurring for every document. | Use explicit registration with DONTLOOKFORFONTS, avoid rebuilding providers unnecessarily, and measure before and after. |
| Compilation errors around the helper | The project uses a different XML Worker/iTextSharp release or an iText 7 API. | Check the installed assembly’s overloads; do not copy pdfHTML or Java examples unchanged into iTextSharp 5. |
When iTextSharp 5 is the wrong conversion tool
If your input depends on modern browser layout, JavaScript execution, responsive breakpoints, or arbitrary remote pages, XML Worker’s controlled XHTML/CSS model may be a poor fit. It is appropriate for templates such as invoices and reports when you can control the markup and assets. HTMLWorker is a deprecated alternative for only small, simple snippets, while iText 7 pdfHTML is a separate product line and migration path. Compare the installed generation, input complexity, glyph requirements, licensing, and maintenance cost before changing APIs.
Or skip the browser setup
If your actual goal is a clean image or PDF of a live URL rather than converting your own HTML with iTextSharp, ScreenshotNeo provides a single website-screenshot API call. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. It also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
For a direct request, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Sign up for the free ScreenshotNeo plan.
Best Value
FAQ
Can I change the font with only CSS?
No. CSS requests a family, but XML Worker also needs a registered file that resolves to that family and contains the required glyphs.
Should I register fonts globally on the server?
Not necessarily. Explicit application-level registration is usually more predictable and avoids relying on machine-specific font directories; ensure your font license permits embedding.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchDoes this code work with iText 7?
No. iText 7 pdfHTML has different namespaces and configuration. Use documentation for the generation your application actually references.
Frequently Asked Questions
Can I change the font with only CSS?
No. CSS requests a family, but XML Worker also needs a registered file that resolves to that family and contains the required glyphs.
Should I register fonts globally on the server?
Not necessarily. Explicit application-level registration is usually more predictable and avoids relying on machine-specific font directories; ensure your font license permits embedding.
Does this code work with iText 7?
No. iText 7 pdfHTML has different namespaces and configuration. Use documentation for the generation your application actually references.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

