Skip to content

Added new kb article radwordsprocessing-correctly-render-non-breaking-spaces-in-pdf #540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: Correctly Rendering Non-Breaking Spaces in PDF from HTML with RadWordsProcessing
description: This article demonstrates how to properly handle non-breaking spaces in HTML when converting to PDF using RadWordsProcessing libraries.
type: how-to
page_title: How to Ensure Non-Breaking Spaces Are Rendered Correctly in PDFs Generated from HTML
slug: radwordsprocessing-correctly-render-non-breaking-spaces-in-pdf
tags: radwordsprocessing, document, processing, html,formatprovider, pdf, fontsprovider, nonbreaking,spaces
res_type: kb
ticketid: 1683368
---

## Environment

| Version | Product | Author |
| ---- | ---- | ---- |
| 2025.1.205| RadWordsProcessing |[Desislava Yordanova](https://www.telerik.com/blogs/author/desislava-yordanova)|

## Description

When converting HTML content to PDF format using [RadWordsProcessing]({%slug radwordsprocessing-overview%}), non-breaking spaces (` `) within and surrounding HTML tags are not rendered correctly in the generated PDF document, although they appear as expected in the DOCX output. This issue occurs due to the .NET Standard version of RadWordsProcessing lacking a default mechanism for reading font data, which is required for accurate space rendering in PDFs.
Copy link
Contributor

@YoanKar YoanKar May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

".NET Standard version of RadPdfProcessing (not WordsProcessing) lacking a default mechanism for reading font data..."

Also specify that this is not the default behavior, but only when exporting to PDF. Because currently it seems that the WordsProcessing library cannot handle fonts in .NET Standard in general, which also happens to cover the PDF export.


This knowledge base article shows how to ensure that non-breaking spaces in HTML are correctly rendered in the exported PDF documents using RadWordsProcessing.

![HTML to PDF with Non-Breaking Spaces](images/non-breaking-spaces-in-exported-pdf.png)

## Solution

To resolve the issue of non-breaking spaces not being rendered correctly in PDF documents generated from HTML content, it is necessary to implement a custom [FontsProvider]({%slug pdfprocessing-implement-fontsprovider%}). This ensures [RadPdfProcessing]({%slug radpdfprocessing-overview%}) has access to font data for accurately rendering spaces and other font-related features in the PDF output.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" necessary to implement a custom FontsProvider..."

There is also the option of manually registering the fonts (https://docs.telerik.com/devtools/document-processing/knowledge-base/load-fonts-with-net-standard), so the provider is not exactly necessary.

1 - If the article will only focus on the FontsProvider, then no changes are requried.
2 - Alternatively the second option (https://docs.telerik.com/devtools/document-processing/knowledge-base/load-fonts-with-net-standard) can also mentioned and added with an example.


1. **Implement a Custom FontsProvider**

Create a class that extends `FontsProviderBase` and override the `GetFontData` method to provide the necessary font data. This method should return the font data as a byte array for the specified font properties.

```csharp
public class FontsProvider : Telerik.Windows.Documents.Extensibility.FontsProviderBase
{
public override byte[] GetFontData(Telerik.Windows.Documents.Core.Fonts.FontProperties fontProperties)
{
string fontFileName = fontProperties.FontFamilyName + ".ttf";
string fontFolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);

//The fonts can differ depending on the file
if (fontProperties.FontFamilyName == "Segoe UI")
{
if (fontProperties.FontStyle == FontStyles.Italic && fontProperties.FontWeight == FontWeights.Bold)
{
fontFileName = $"segoeuiz.ttf";
}
else if (fontProperties.FontStyle == FontStyles.Italic)
{
fontFileName = $"segoeuii.ttf";
}
else if (fontProperties.FontWeight == FontWeights.Normal)
{
fontFileName = "segoeui.ttf";
}
else if (fontProperties.FontWeight == FontWeights.Bold)
{
fontFileName = $"segoeuib.ttf";
}
}
else if (fontProperties.FontFamilyName == "Times New Roman")
{
if (fontProperties.FontStyle == FontStyles.Italic && fontProperties.FontWeight == FontWeights.Bold)
{
fontFileName = $"timesbi.ttf";
}
else if (fontProperties.FontStyle == FontStyles.Italic)
{
fontFileName = $"timesi.ttf";
}
else if (fontProperties.FontWeight == FontWeights.Normal)
{
fontFileName = "times.ttf";
}
else if (fontProperties.FontWeight == FontWeights.Bold)
{
fontFileName = $"timesbd.ttf";
}
}

//...add more fonts if needed...
DirectoryInfo directory = new DirectoryInfo(fontFolder);
FileInfo[] fontFiles = directory.GetFiles();

var fontFile = fontFiles.FirstOrDefault(f => f.Name.Equals(fontFileName, StringComparison.InvariantCultureIgnoreCase));
if (fontFile != null)
{
var targetPath = fontFile.FullName;
using (FileStream fileStream = File.OpenRead(targetPath))
{
using (MemoryStream memoryStream = new MemoryStream())
{
fileStream.CopyTo(memoryStream);
Debug.WriteLine("Found "+ fontFileName);
return memoryStream.ToArray();
}
}
}
Debug.WriteLine("NOT Found " + fontFileName);
return null;
}
}
```

2. **Set the Custom FontsProvider to the FixedExtensibilityManager**

Before generating the PDF document, assign an instance of the custom `FontsProvider` to the `FontsProvider` property of `FixedExtensibilityManager`.

```csharp
Telerik.Windows.Documents.Extensibility.FontsProviderBase fontsProvider = new FontsProvider();
Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.FontsProvider = fontsProvider;
```

3. **Generate PDF Document from HTML Content**

Utilize the [HtmlFormatProvider]({%slug radwordsprocessing-formats-and-conversion-html-htmlformatprovider%}) to import HTML content and convert it to a [RadFlowDocument]({%slug radwordsprocessing-model-radflowdocument%}). Then, use the [PdfFormatProvider]({%slug radwordsprocessing-formats-and-conversion-pdf-pdfformatprovider
tags: using,pdfformatprovider%}) to export the document to PDF, ensuring non-breaking spaces and other font-related elements are rendered correctly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect PdfFormatProvider slug


```csharp
// Example method implementation for converting HTML to PDF
public static byte[] CreateDocumentFromHtml(string html, bool pdf = false)
{
// Conversion logic...
}
```

For a detailed guide on implementing a `FontsProvider`, refer to the [How to implement a FontsProvider]({%slug pdfprocessing-implement-fontsprovider%}) article. This implementation ensures that non-breaking spaces and other font-related elements are accurately rendered in PDF documents generated from HTML content using RadWordsProcessing.

## See Also

- [How to Implement a FontsProvider for RadPdfProcessing]({%slug pdfprocessing-implement-fontsprovider%})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference kb in another article