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); |
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); |
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>"; | |
} | |
} |
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:
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.
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); | |
} | |
} |