Skip to content
getnextpdf.com

Enterprise edition

Branding — Deep Reference

This page is the deep reference for the NextPDF\Enterprise\Branding module. The module marks evaluation output and leaves paid output untouched. A license-resolved BrandingMode selects a strategy; BrandingApplicator applies the resolved strategy to rendered PDF bytes. Under a paid license the transform is the identity: output is byte-for-byte unchanged, with no code change required. For the evaluation workflow, read the Branding capability page first.

This capability ships in NextPDF Enterprise (nextpdf/enterprise) and activates with an Enterprise-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

The subsystem carries the dedicated enterprise.branding capability code because it governs evaluation behavior across all editions. The branding mode is resolved from the signed license envelope at runtime; no application flag selects it. A paid license resolves the mode to None and never produces branded output. There is no production build to switch.

SymbolParametersDefault behaviorReturnsThrows or fails withNotes
BrandingModeNone ('none'): no modificationString-backed enum; EvaluationWatermark ('evaluation') activates evaluation branding.
BrandingStrategyContract consumed by integration pointsInterface; callers never branch on BrandingMode directly.
BrandingStrategy::isActivefalse for null strategy, true for evaluation strategyboolfalse means every other method returns identity values.
BrandingStrategy::buildPageWatermarkfloat $pageWidth, float $pageHeight (points)Empty string when inactive; diagonal watermark operators when activestringStream assumes a /helvetica font resource on the page.
BrandingStrategy::decorateProducerstring $producerIdentity when inactive; appends the evaluation suffix when activestringDefault suffix: [EVALUATION].
BrandingStrategy::decorateSubjectstring $subjectIdentity when inactive; prepends the evaluation prefix when activestringEmpty subject yields the trimmed marker.
BrandingStrategyFactory::createBrandingMode $mode, ?EvaluationBrandingConfig $config = nullMaps None to NullBrandingStrategy, EvaluationWatermark to EvaluationBrandingStrategyBrandingStrategyStatic; null config uses the defaults.
EvaluationBrandingConfig::__constructSix optional named parameters (text, suffix, prefix, size, gray, angle)Defaults: 48 pt, gray 0.85, 45 degreesInstanceInvalidArgumentException on empty text, non-positive font size, or gray outside 0.0–1.0final readonly; immutable.
EvaluationBrandingStrategyOptional EvaluationBrandingConfigApplies watermark and metadata decorationfinal readonly; implements BrandingStrategy.
NullBrandingStrategyIdentity on every methodSelected under a paid license.
BrandingApplicator::applystring $pdfBytes, BrandingStrategy $strategyInactive strategy: input returned byte-for-byte; active: one incremental update appendedstringBrandingApplicationException when active branding cannot be applied safelyPure, deterministic byte transform.
BrandingApplicationExceptionTerminal, fail-closed failure signalCarries SPEC_CODE (SPEC-BRANDING-UNAPPLICABLE); factory unsupportedStructure().
enum BrandingMode: string
{
case None = 'none';
case EvaluationWatermark = 'evaluation';
}
public static function create(
BrandingMode $mode,
?EvaluationBrandingConfig $config = null,
): BrandingStrategy
public function __construct(
public string $watermarkText = 'EVALUATION COPY — Not for Production Use',
public string $producerSuffix = ' [EVALUATION]',
public string $subjectPrefix = '[EVALUATION] ',
public float $watermarkFontSize = 48.0,
public float $watermarkGray = 0.85,
public float $watermarkAngle = 45.0,
)
public function apply(string $pdfBytes, BrandingStrategy $strategy): string

Mode and strategy resolution. The license state — not application code — selects the BrandingMode. BrandingStrategyFactory::create maps None to NullBrandingStrategy and EvaluationWatermark to EvaluationBrandingStrategy. Integration points consume the BrandingStrategy interface and never inspect the mode directly, so branding logic stays centralized. Under a paid license the null strategy is selected and output is identical to output produced with no branding subsystem at all.

Watermark generation. buildPageWatermark emits PDF content-stream operators for one page: an isolated graphics state (q/Q), the standard-14 Helvetica font via the /helvetica resource name, fill text rendering mode, and a rotation matrix that places the text diagonally through the page center. The default style is 48 pt text at gray level 0.85, rotated 45 degrees. Centering approximates text width by glyph count — grapheme clusters when intl is loaded, Unicode code points via mbstring otherwise, byte length as the final fallback. No per-glyph advance widths are consulted by design. The watermark text is escaped as a PDF literal string per ISO 32000-2:2020 §7.3.4.2 (backslash and parentheses).

Metadata decoration. decorateProducer appends the producer suffix to the /Producer value. decorateSubject prepends the subject prefix to the /Subject value; an empty subject yields the trimmed marker, so a document without subject metadata is still marked.

Byte application. BrandingApplicator::apply is the terminal consumer of the branding control. With an inactive strategy it returns the input byte-for-byte. With an active strategy it appends a single incremental update in the shape defined by ISO 32000-2:2020 §7.5.6: the original bytes stay intact, and the appended body holds a decorated Info object (reusing the existing object number), one watermark content stream plus one updated page object per page, and a new cross-reference stream (/Type /XRef, /W [1 4 2]) whose /Prev points back to the prior startxref. The transform is pure and deterministic for a given input and configuration.

Fail-closed contract. When the strategy is active, the input must be brandable: a %PDF- header, no /Encrypt entry, no object streams (/ObjStm), a cross-reference-stream tail, and a /helvetica font resource resolvable from every page. Any violation raises BrandingApplicationException instead of returning unbranded bytes. Callers must treat the exception as terminal and must not commit the original, unmarked bytes.

  • Branded output means the license state is evaluation-style. That reflects license state, not a defect.
  • The watermark is centered and diagonal by design. It is not tunable for production use; a paid license removes it entirely.
  • EvaluationBrandingConfig rejects empty watermark text, a non-positive font size, and a gray level outside 0.0–1.0 with InvalidArgumentException.
  • An active strategy that produces no Producer, Subject, or watermark change is refused with BrandingApplicationException rather than emitting bytes that look paid.
  • A page without a usable /MediaBox (absent or inherited) is watermarked at the ISO 216 A4 default of 595.276 × 841.890 points.
  • /Contents in single-reference and array forms are both supported; the watermark reference is appended last so it draws on top. A page with no /Contents receives one.
  • Info string values round-trip in their original representation: hexadecimal strings (UTF-16BE) stay hexadecimal, literal strings stay literal. An absent key is appended, hex-encoded when the value contains non-ASCII characters.
  • Encrypted documents are refused: rewriting string objects under /Encrypt would require the document encryption key.
  • Failures carry the stable code SPEC-BRANDING-UNAPPLICABLE (BrandingApplicationException::SPEC_CODE) so consuming pipelines can dead-letter and audit unbrandable output.
  • The module performs no cryptographic operations. License-envelope signature verification belongs to the licensing subsystem; see the Licensing deep reference.
ClaimStandardClause
Incremental updates append changes to the end of the file and leave the original contents intact.ISO 32000-2§7.5.6
The update’s cross-reference section covers only changed objects, and the added trailer carries a Prev entry locating the previous cross-reference section.ISO 32000-2§7.5.6
Literal strings are written in parentheses; unbalanced parentheses and the reverse solidus require escape treatment.ISO 32000-2§7.3.4.2

All clauses are paraphrased; NextPDF does not reproduce normative text. The applicator writes incremental updates in the cited ISO 32000-2 shape as a capability statement. This page describes runtime behavior only. It makes no warranty, no statement about eligibility or legal effect, and does not constitute legal advice; the terms of an evaluation or subscription are defined solely by the license agreement.

  • BrandingMode, BrandingStrategy, both strategies, and the config carry @since 3.0.0; BrandingApplicator and BrandingApplicationException carry @since 3.1.0.
  • The subsystem makes no network calls. The applicator reads only the structural fields it rewrites: the Info dictionary strings, page dictionaries, and the cross-reference tail.
  • The license envelope is a signed artifact whose issuer signature the runtime verifies. License provisioning, renewal, and secure storage are the operator’s responsibility.
  • All concrete types are final; the strategies and the config are also readonly. Construct a new config instance to change watermark style.
  • BrandingStrategy::isActive() returning false guarantees identity values from every other method; callers may short-circuit on it for performance.
  • The watermark stream references the /helvetica resource name. Core registers this resource for its own branding; an integration that disables Core branding must ensure the resource exists.
  • The applicator computes no digest; the caller re-digests the branded bytes before committing them.
  • Internal mechanism detail stays in the source repository’s internal documentation and is out of scope for this manual.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.