Skip to content
Add Text Watermark

Add Text Watermark

PdfPage.AddWatermarkText stamps a line of text across a page at a chosen angle and opacity. It’s the shortest route to a “DRAFT” or “CONFIDENTIAL” overlay: one call per page, no layout work, and the existing page content is left untouched underneath.

The text is rasterized, not typeset. UniPDF renders it into a PNG with FreeType and embeds that as an image, so the watermark is a bitmap on the page. That has real consequences, covered under limitations.

Doing it

options := model.WatermarkTextOptions{
    Alpha:     0.3,
    FontSize:  40,
    FontPath:  "Roboto-Regular.ttf",
    FontColor: color.RGBA{R: 255, G: 0, B: 0, A: 255},
    Angle:     30,
}

if err := page.AddWatermarkText("CONFIDENTIAL", options); err != nil {
    return err
}

The call modifies the page in place and writes nothing. Collect the watermarked pages with a creator’s AddPage and call c.WriteToFile, or convert the reader with pdfReader.ToWriter(nil).

The options

FieldDefaultEffect
FontPathnone, requiredPath to a .ttf file, loaded and parsed by FreeType.
Alpha0.5Opacity, written to the graphics state as both ca and CA.
FontSize20Rasterization size in points, at 72 DPI.
FontColorblackA color.Color. Its alpha channel is ignored.
Angle0Rotation in degrees, applied to the image as a whole.

FontPath is the only mandatory field, and it is a TrueType file path rather than a UniPDF PdfFont. The standard 14 fonts, a font already embedded in the document and a composite font are all unavailable here; you need a .ttf on disk.

Alpha cannot be set to 0. A zero value is treated as unset and replaced with 0.5, so the smallest opacity you can ask for is a small nonzero number like 0.01.

FontColor’s alpha channel is discarded during rasterization, which is why color.RGBA{R: 255, A: 1} still comes out solid red rather than nearly invisible. Control transparency with Alpha.

The watermark is always centered and always scaled with its aspect ratio preserved. AddWatermarkText calls AddWatermarkImage with FitToWidth: false and PreserveAspectRatio: true hard-coded, so those two knobs are not reachable from here.

Limitations

Because the text is rasterized, it isn’t selectable, isn’t found by search, isn’t extracted by the text extractor, and doesn’t scale cleanly when the page is zoomed or printed at high resolution. A larger FontSize produces a larger bitmap, which is the only lever on quality.

The canvas the text is drawn on is sized by estimate: character count times font size, clamped to the media box width. The estimate is generous, so short text sits in a wide mostly-empty bitmap, which is why a watermark often looks smaller and further right than the font size suggests. Once the estimate exceeds the page width the clamp takes over and glyphs past that edge are cut off rather than the text being shrunk to fit. Fewer characters at a larger FontSize is the way to fill a page.

Newlines in the text produce multiple lines, spaced at 1.5 times the font size. Tabs become four spaces and carriage returns are dropped.

An empty string returns “no text set” and an empty FontPath returns “no font path set”. Anything wrong with the font file itself, missing or not parseable as TrueType, surfaces as an error from the same call.

Calling AddWatermarkText twice on the same page adds two watermarks. Nothing detects or replaces an existing one.

Run the example

The example watermarks every page of an input document with a string given on the command line and writes the result through a creator. Everything happens in main. The Roboto-Regular.ttf shipped in the watermarks folder is what FontPath points at, so run it from that directory.

git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/watermarks
go run pdf_add_text_watermark.go <input.pdf> <watermark text> <output.pdf>

If this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.

View the full source

Sample output

Text watermark across a page

Last updated on