TX Text Control supports the insertion of SVG images. In combination with the ability to add images to headers and footers that overlap the main text, SVGs can be used to add watermarks to documents.

Watermarks are a common way to protect documents from being copied or to indicate that a document is confidential. This article introduces the WatermarkGenerator class, which is used to create SVG watermark images with various options, including text, rotation, and font.

The following code shows how to create a watermark image with the text CONFIDENTIAL and a rotation of 20 degrees:

var watermark = WatermarkGenerator.CreateSVGWatermark(
"CONFIDENTIAL", 20, Color.LightGray, new Font("Arial", 90));
AddWatermark(textControl1, watermark);
view raw test.cs hosted with ❤ by GitHub

Watermarks in TX Text Control

The next code uses a different font and a different rotation.

var watermark = WatermarkGenerator.CreateSVGWatermark(
"DRAFT", -20, Color.LightGreen, new Font("Verdana", 180));
AddWatermark(textControl1, watermark);
view raw test.cs hosted with ❤ by GitHub

Watermarks in TX Text Control

The WatermarkGenerator class measures the size of the image based on the font that is being used and dynamically generates the SVG.

using System.Drawing;
using System.Text;
public static class WatermarkGenerator
{
// Create an SVG watermark with centered text and rotation
public static byte[] CreateSVGWatermark(string text, int rotation, Color color, Font font)
{
// Guess the size of the SVG image including rotation
SizeF size = MeasureTextSize(text, font);
// Convert font to CSS style
string fontCssStyle = GetFontCssStyle(font);
// Convert color to hex
string colorHex = ColorToHex(color);
// Generate SVG markup
string svgMarkup = GenerateSvgMarkup(text, rotation, size, fontCssStyle, colorHex);
return Encoding.ASCII.GetBytes(svgMarkup);
}
private static SizeF MeasureTextSize(string text, Font font)
{
using (Graphics graphics = Graphics.FromImage(new Bitmap(1, 1)))
{
return graphics.MeasureString(text, font);
}
}
private static string GetFontCssStyle(Font font)
{
return $"font-family: {font.FontFamily.Name}; font-size: {font.Size}px; font-weight: {(font.Bold ? "bold" : "normal")};";
}
private static string ColorToHex(Color color)
{
return $"#{color.R:X2}{color.G:X2}{color.B:X2}";
}
private static string GenerateSvgMarkup(string text, int rotation, SizeF size, string fontCssStyle, string colorHex)
{
return $@"<svg xmlns='http://www.w3.org/2000/svg' width='{size.Width}' height='{size.Width}' viewBox='0 0 {size.Width} {size.Width}' preserveAspectRatio='none'>
<text x='{size.Width / 2}' y='{size.Width / 2}' text-anchor='middle' alignment-baseline='middle' transform='rotate({rotation} {size.Width / 2} {size.Width / 2})' style='{fontCssStyle} fill: {colorHex};'>{text}</text>
</svg>";
}
}
view raw test.cs hosted with ❤ by GitHub

The position of the image to be inserted in the center is calculated by the AddWatermark method. The image must be centered vertically and horizontally on each page of each section if there are different page sizes and orientations.

The following formula is used to calculate the location of the background images:

([Page width] - [image width] - [both page margins]) / 2

The following illustration shows the various values that must be taken into account when calculating the exact horizontal position:

Watermarks in TX Text Control

Learn More

This article shows how to add SVG images to document section headers that are automatically repeated on each page. This watermark is centered vertically and horizontally on each section page.

Adding SVG Watermarks to Documents

public void AddWatermark(TXTextControl.TextControl tx, byte[] watermark)
{
tx.PageUnit = TXTextControl.MeasuringUnit.Twips;
foreach (TXTextControl.Section section in tx.Sections)
{
// remove existing headers for demo purposes
section.HeadersAndFooters.Remove(TXTextControl.HeaderFooterType.All);
// add new header for each section
section.HeadersAndFooters.Add(TXTextControl.HeaderFooterType.Header);
TXTextControl.HeaderFooter hf =
(section.HeadersAndFooters.GetItem(TXTextControl.HeaderFooterType.Header));
// add the watermark
TXTextControl.Image image;
using (MemoryStream ms = new MemoryStream(watermark, 0, watermark.Length, writable: false, publiclyVisible: true))
{
image = new TXTextControl.Image(ms);
hf.Images.Add(
image,
1,
new System.Drawing.Point(0, 0),
TXTextControl.ImageInsertionMode.FixedOnPage |
TXTextControl.ImageInsertionMode.BelowTheText);
}
// Calculate the horizontal center location
int locationX = (int)((section.Format.PageSize.Width - image.Size.Width -
(section.Format.PageMargins.Left + section.Format.PageMargins.Right)) / 2);
// Calculate the vertical center location
int locationY = (int)((section.Format.PageSize.Height - image.Size.Height -
(section.Format.PageMargins.Top + section.Format.PageMargins.Bottom)) / 2);
// set the location
image.Location = new System.Drawing.Point(locationX, locationY);
}
}
view raw test.cs hosted with ❤ by GitHub