Arrière-plans de page (eso-pic)

Une page LaTeX est assemblée sous forme de liste verticale, puis expédiée (shipout) d'un seul bloc une fois terminée : il ne reste donc aucun interstice où glisser un arrière-plan en dessous. Les arrière-plans de page — un aplat de couleur, une photo à fond perdu, un filigrane DRAFT en diagonale — existent malgré tout, parce que tous les paquets concernés jouent le même tour : ils s'intercalent juste avant l'expédition et déposent leur encre avant le texte. Le texte s'imprime ensuite par-dessus, et le résultat ressemble à un fond. Cette page suit cette idée unique à travers \pagecolor, eso-pic, le paquet background et draftwatermark, jusqu'à l'endroit où la plupart des gens se brûlent : l'imprimante et la taille du fichier.

\pagecolor face à une vraie couche d'arrière-plan

Si un aplat d'une seule couleur derrière toute la page suffit, la réponse tient en une ligne, \pagecolor{couleur}, et aucun paquet d'arrière-plan n'intervient. La commande vient de color/xcolor et non du noyau LaTeX : écrire \pagecolor{yellow} sans \usepackage{xcolor} produit ! Undefined control sequence. \nopagecolor annule l'effet. Deux de ses propriétés surprennent. D'abord, elle est globale et ignore les groupes : placée dans un environnement ou entre accolades, la teinte court malgré tout de cette page jusqu'à la fin du document (la notation des couleurs elle-même relève de la page consacrée aux couleurs). Ensuite, elle ne peut peindre qu'un rectangle uni : ni photographie, ni logo, ni texte incliné. Presque tout le reste de cette page découle de cette seconde limite.

document.tex
\documentclass{article}
\usepackage{xcolor}     % \pagecolor lives here, not in the kernel

\begin{document}
\pagecolor{yellow!10}   % tints this page and every page after it
Text on tinted paper.
\clearpage
\nopagecolor            % back to plain paper
Text on plain paper.
\end{document}

Que se passe-t-il donc lorsqu'il faut placer sous le texte autre chose qu'une couleur ? Au moment où LaTeX connaît le contenu d'une page, celle-ci est déjà terminée : la routine de sortie a assemblé une grande boîte verticale et il ne reste qu'à l'écrire. Aucune couche ne peut être glissée dessous. Le noyau propose à la place deux crochets, shipout/background et shipout/foreground, dont le mécanisme est d'une franchise presque comique. shipout/background insère une boîte de taille nulle comme tout premier élément de la boîte de sortie : son contenu est donc imprimé en premier et le reste de la page vient simplement par-dessus. shipout/foreground en ajoute une comme tout dernier élément, relevée jusqu'au coin, de sorte qu'elle s'imprime en dernier et recouvre le texte. Le PDF n'a pas de coordonnée z : l'ordre de dépôt de l'encre est la seule profondeur disponible. Les deux crochets ouvrent un environnement picture dont l'origine (0,0) se trouve au coin supérieur gauche de la page, avec \unitlength à 1 pt ; c'est pourquoi les coordonnées verticales des \put y sont normalement négatives.

Le plus curieux est que ces deux crochets sont bien plus jeunes que les paquets qui les utilisent. Ils sont apparus avec la version de LaTeX du 2020-10-01 ; auparavant, chaque paquet d'arrière-plan rapiéçait lui-même la routine de sortie, d'où l'accumulation de atbegshi, everyshi et everypage. Ces paquets fonctionnent encore, mais ne sont plus que de minces couches de compatibilité : \AddEverypageHook{...} de everypage s'écrit désormais littéralement \AddToHook{shipout/background}{\put(1in,-1in){...}}, le 1in,-1in déplaçant l'origine d'un pouce vers l'intérieur et d'un pouce vers le bas depuis le coin de la feuille, c'est-à-dire jusqu'au point de référence traditionnel de TeX. La conséquence pratique est simple : eso-pic, background et draftwatermark déposent tous leur matériau dans le même crochet du noyau. C'est ce qui permet de les combiner — et ce qui les fait aussi se disputer l'ordre d'impression.

Un dessin sur chaque page avec eso-pic — \AddToShipoutPictureBG

eso-pic est l'outil polyvalent. \AddToShipoutPictureBG{...} dessine son argument derrière le texte sur chaque page à partir de ce point, et \AddToShipoutPictureFG{...} le dessine devant. Le paquet de Rolf Niepraschk est plus ancien que les crochets du noyau et a déménagé dessus dans sa version 3 ; il survit parce qu'il ne présuppose rien de ce que l'on souhaite dessiner. Les formes étoilées \AddToShipoutPictureBG* et \AddToShipoutPictureFG* n'agissent que sur la page courante : en interne, le matériau étoilé est vidé dès que cette page est expédiée. Pour arrêter un fond plus tard, on appelle \ClearShipoutPictureBG (ou \ClearShipoutPictureFG pour le premier plan). \AddToShipoutPicture et \AddToShipoutPicture* sont d'anciens alias des formes BG et se comportent à l'identique.

À l'intérieur du crochet, on se trouve dans un environnement picture : le placement se fait donc avec \put(x,y){...}. Par défaut, eso-pic déplace l'origine dans le coin inférieur gauche de la feuille (option pscoord, active par défaut). Chargé comme \usepackage[texcoord]{eso-pic}, l'origine passe en haut à gauche et y croît vers le bas. Compter depuis un coin à chaque fois étant pénible, le paquet fournit des aides : \AtPageLowerLeft, \AtPageUpperLeft et \AtPageCenter par rapport à la feuille, \AtTextUpperLeft, \AtTextLowerLeft et \AtTextCenter par rapport à la zone de texte, ainsi que \AtStockLowerLeft et consorts lorsque la classe memoir est en jeu. LaTeX actuel accepte de vraies dimensions dans \put, si bien que \put(0,-\paperheight) est valide et que l'ancien enrobage \LenToUnit, prévu pour cela, n'est plus qu'un passe-plat conservé par compatibilité. En cas de coordonnées incertaines, \usepackage[grid]{eso-pic} trace une grille graduée sur chaque page — gridunit=mm par défaut, avec aussi bp, in et pt.

document.tex
\documentclass{article}
\usepackage{eso-pic}
\usepackage{graphicx}

% one image stretched over the whole sheet, on every page
\AddToShipoutPictureBG{%
  \AtPageLowerLeft{%
    \includegraphics[width=\paperwidth,height=\paperheight]{background.jpg}}%
}

\begin{document}
The text sits on top of the full-bleed image.
\end{document}

Pour un motif dessiné plutôt qu'une photographie, on place un tikzpicture dans le crochet. L'ancrage commode est ici \AtPageCenter, car les coordonnées propres de TikZ rayonnent alors depuis le milieu de la feuille et tout se raisonne par rapport à (0,0). En pratique, la méthode consiste à garder l'option grid active pendant le positionnement, puis à la retirer.

document.tex
\documentclass{article}
\usepackage[grid,gridunit=mm]{eso-pic}  % drop "grid" once the position is right
\usepackage{tikz}

\AddToShipoutPictureBG{%
  \AtPageCenter{%
    \begin{tikzpicture}
      \fill[blue!8] (0,0) circle (6cm);
    \end{tikzpicture}}%
}

\begin{document}
A soft tinted disc sits behind the text on every page.
\end{document}

Limiter un fond à une seule page ou à la page de titre

La réponse : utiliser la forme étoilée et l'écrire là où la page commence. \AddToShipoutPictureBG*{...} ne s'applique qu'à la page en cours d'assemblage au moment où LaTeX lit la ligne. Un fond de couverture se place donc dans le préambule ou juste avant \maketitle ; plus loin, il atterrit sur la page qui se trouvait ouverte. Le même raisonnement révèle un piège dans \ClearShipoutPictureBG : la commande est globale et prend effet immédiatement, si bien qu'un appel au milieu d'une page supprime le fond de cette page-là, et pas seulement de la suivante. Si la page courante doit garder son fond, il faut d'abord l'expédier par \clearpage, puis effacer. Pour un fond couvrant plusieurs pages, la forme habituelle est donc : commencer sans étoile, puis \clearpage suivi de \ClearShipoutPictureBG.

document.tex
\documentclass{article}
\usepackage{eso-pic}
\usepackage{graphicx}

\title{Annual Report}
\author{A. Author}

\begin{document}
% starred form: the cover art lands on this page only
\AddToShipoutPictureBG*{%
  \AtPageLowerLeft{%
    \includegraphics[width=\paperwidth,height=\paperheight]{cover.pdf}}%
}
\maketitle
\clearpage
No background from here on.
\end{document}

Les paquets spécialisés proposent le même raccourci dans leur propre langage. background dispose de firstpage=true pour la seule première page, et de la combinaison pages=some avec \BgThispage pour des pages choisies. draftwatermark se limite à la page un avec \usepackage[firstpageonly]{draftwatermark} et peut être désactivé puis réactivé en cours de document par \DraftwatermarkOptions{stamp=false} et {stamp=true}. S'il ne s'agit que de poser une image, le paquet wallpaper — une fine couche au-dessus de eso-pic — est commode : \CenterWallPaper{facteur}{fichier} centre une image, \TileWallPaper{largeur}{hauteur}{fichier} la répète en mosaïque, et \ULCornerWallPaper et ses variantes l'ancrent dans un coin. Mieux encore pour cette section : chacune de ces commandes possède un jumeau limité à la page courante dont le nom contient This, par exemple \ThisCenterWallPaper.

Le paquet background : des filigranes déclarés avec \backgroundsetup

Pour éviter de calculer soi-même les coordonnées, le paquet background de Gonzalo Medina est la réponse. Toute la configuration se rassemble dans \backgroundsetup{clé=valeur, ...} et le tracé est confié à TikZ. Un simple \usepackage{background} produit déjà les valeurs par défaut : un grand Draft rougeâtre (color=red!45, contents=Draft) traversant le centre de chaque page à 60 degrés avec opacity=0.5. Les clés principales sont contents= (le matériau : texte, \includegraphics ou dessin), color= (tout l'éventail xcolor), opacity= (0 totalement transparent, 1 totalement opaque), angle= (sens antihoraire, de −360 à 360), scale=, position= (syntaxe de placement de nœud TikZ telle que current page.center ; les coordonnées nues ne doivent pas être mises entre parenthèses), placement= (les trois préréglages center, top et bottom), nodeanchor= et anchor=, plus hshift= et vshift= pour ajuster. \backgroundsetup s'appelle dans le préambule comme dans le corps, autant de fois que voulu : le dessin peut donc changer en cours de route.

document.tex
\documentclass{article}
\usepackage{background}

\backgroundsetup{
  contents={DRAFT},
  color=red,
  opacity=0.25,
  angle=45,
  scale=8,
  position=current page.center,
}

\begin{document}
Every page carries a diagonal DRAFT watermark. Compile twice.
\end{document}

Trois pièges. D'abord, toujours compiler deux fois. Le matériau est un tikzpicture avec remember picture, overlay ancré au nœud current page : sa position absolue sur la feuille dépend donc de ce que la compilation précédente a écrit dans le fichier .aux. Au premier passage apparaît LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right. et le filigrane est mal placé ou absent. Ensuite, si le matériau de contents= contient des commandes LaTeX, il faut le déclarer via \backgroundsetup et non comme option de \usepackage : la chaîne d'options est analysée d'une manière qui les casse. Enfin, pages=some avec \BgThispage fonctionne sans souci, mais la commande inverse \NoBgThispage ne doit pas être employée dans un document en deux colonnes : son implémentation repose sur afterpage, qui ne coopère pas avec le mode deux colonnes. Sur deux colonnes, mieux vaut inverser la logique : passer à pages=some et appeler \BgThispage sur les pages qui doivent porter le fond.

draftwatermark : un filigrane DRAFT en une ligne

Si un filigrane textuel suffit, draftwatermark de Sergio Callegari est le chemin le plus court. Un \usepackage{draftwatermark} place un grand DRAFT gris au centre de chaque page — les valeurs par défaut sont text=DRAFT, angle=45, scale=1, fontsize=0.25\paperwidth, et une couleur colorspec=0.8 dans le modèle colormodel=gray. La configuration réside dans \DraftwatermarkOptions{clé=valeur} : text=, angle=, scale=, fontsize=, color= (qui peut porter un modèle, comme {[gray]{0.85}}), hpos=/vpos= (ou les deux d'un coup avec pos={x,y}), hanchor=/vanchor= (ou les lettres accolées, comme anchor=lt), et alignment= pour un texte sur plusieurs lignes. Il existe exactement une exception : firstpageonly n'est utilisable qu'en option de paquet ; écrire \DraftwatermarkOptions{firstpageonly} produit ! Package keyval Error: firstpageonly undefined. Pour ne marquer que la première page, il faut charger \usepackage[firstpageonly]{draftwatermark}.

document.tex
\documentclass{article}
% firstpageonly works only here, as a package option
\usepackage[firstpageonly]{draftwatermark}

\DraftwatermarkOptions{
  text=CONFIDENTIAL,
  color={[gray]{0.85}},
  angle=45,
  fontsize=1.5cm,
}

\begin{document}
Only the first page is marked CONFIDENTIAL.
\end{document}

La raison même de l'existence de ce paquet est un morceau d'histoire. Son prédécesseur draftcopy, de Jürgen Vollmer, dessinait son filigrane à l'aide de \special PostScript, que pdfLaTeX ne sait pas interpréter ; d'après le manuel, cette incompatibilité avec les moteurs produisant directement du PDF fut la première motivation pour écrire draftwatermark. Le paquet actuel n'emploie donc aucune astuce dépendante du pilote et se comporte de la même façon sous pdfLaTeX, XeLaTeX et LuaLaTeX. Les anciennes commandes \SetWatermarkText{...}, \SetWatermarkScale{...}, \SetWatermarkColor{...}, \SetWatermarkAngle{...} et \SetWatermarkLightness{...} (0 pour le noir, 1 pour le blanc) subsistent par compatibilité, mais chacune se contente de relayer vers \DraftwatermarkOptions : les nouveaux documents utiliseront la forme clé-valeur. Ce qui rend vraiment service en fin de projet, c'est la famille stamp : \usepackage[final]{draftwatermark}nostamp est un synonyme — supprime le filigrane sans toucher au réglage, et comme final est une option de classe très répandue, un \documentclass[final]{article} l'atteint aussi. La limite est tout aussi nette : draftwatermark ne dépose de matériau que dans shipout/background et ne peut donc pas tamponner par-dessus le texte. Pour une superposition, ou un contrôle strict de l'empilement, il faut \AddToShipoutPictureFG de eso-pic, scrlayer de KOMA-Script, ou directement le crochet shipout/foreground. draftwatermark déclare même son rang dans le crochet : il demande à être dessiné avant eso-pic, si bien qu'en combinant les deux, le dessin de eso-pic se pose sur le filigrane.

Quel paquet choisir, et les pièges courants

En pratique, on remonte depuis l'outil le plus modeste : \pagecolor pour une couleur, draftwatermark pour un filigrane textuel, background pour une configuration déclarative propre, et seulement si rien de tout cela ne se plie à la demande, on descend vers eso-pic pour placer directement avec \put. Dès qu'il faut quelque chose devant le texte, le choix se réduit à eso-pic (ou scrlayer, ou le crochet brut).

OutilUsage adaptéPeut-il passer devant ?À surveiller
\pagecolorUn aplat de couleur derrière toutNon — c'est la couleur du papierExige xcolor ; global, ignore les groupes
eso-picUn dessin quelconque à une position absolueOui — \AddToShipoutPictureFGPlacement manuel avec \put ; formes étoilées limitées à la page courante
backgroundFiligranes diagonaux déclaratifs ; angle et opacité aisésNon — fond seulementDeux compilations ; \NoBgThispage échoue en deux colonnes
draftwatermarkUne marque DRAFT ou CONFIDENTIAL en une ligneNon — fond seulementfirstpageonly n'existe qu'en option de paquet
wallpaperFonds image centrés, en mosaïque ou ancrés dans un coinNon — fond seulementFine couche au-dessus de eso-pic ; les variantes \This... ne valent que pour la page courante
shipout/backgroundContrôle total sans aucun paquetOui — via shipout/foregroundOrigine au coin supérieur gauche, y négatif ; enregistrement par \AddToHook
  • Rien n'apparaît, ou tout est mal placé → compiler background deux fois. Avec eso-pic, suspecter le signe de la coordonnée y (origine en bas à gauche par défaut) et des espaces parasites hors du \put.
  • Le fond ne devait être que sur la couverture mais apparaît partout → la forme sans étoile a été employée. Passer à \AddToShipoutPictureBG* et le placer juste avant \maketitle.
  • L'effacement a aussi vidé la page courante\ClearShipoutPictureBG agit immédiatement ; insérer un \clearpage avant.
  • Le filigrane doit passer par-dessus le texte\AddToShipoutPictureFG. Ni draftwatermark ni background ne le peuvent : tous deux sont limités au fond.
  • Retirer le filigrane de la version rendue\usepackage[final]{draftwatermark} ou \DraftwatermarkOptions{stamp=false} : le réglage reste, la marque disparaît.
  • Compilation par DVI (dvipdfmx / dvips) → tout fonctionne, mais couleur, opacité et inclusion d'images dépendent du pilote ; eso-pic possède en outre une option dvips.

Impression et taille du fichier : ce que coûte vraiment un fond pleine page

Un fond magnifique à l'écran devient souvent tout autre chose sur le papier. D'abord la contrainte physique : les imprimantes laser et jet d'encre de bureau ne savent pas déposer d'encre jusqu'au bord de la feuille. Une image étirée à \paperwidth dans l'idée qu'elle sera à fond perdu revient avec un liseré blanc de quelques millimètres sur les quatre côtés. S'il faut vraiment du fond perdu, la feuille doit être plus grande que la page finie, puis rognée : le bon geste consiste donc à demander à la classe ou à geometry un papier avec débord, non à étirer davantage l'image. Le second coût est plus terre à terre : une teinte qui paraît douce sur un écran rétroéclairé devient sur papier un aplat d'encre couvrant toute la page. C'est lent, c'est cher, et cela ressort presque toujours plus sombre que prévu. La lisibilité paie aussi, car tout fond réduit le contraste avec le texte ; la cible prudente pour l'opacity d'un filigrane est donc « juste perceptible ».

La taille du fichier se comporte très différemment selon la matière du fond. Une image chargée par \includegraphics est intégrée une seule fois dans le PDF et simplement référencée par chaque page : un rapport de cent pages doté d'un fond photographique ne pèse guère plus que le rapport augmenté d'une copie de la photo. Un fond dessiné avec TikZ n'a pas cette propriété : les commandes de tracé sont réexécutées pour chaque page et les formes atterrissent dans le flux de contenu de chacune, si bien que le fichier grossit à peu près proportionnellement au nombre de pages. Si un fond vectoriel élaboré a fait passer le PDF à plusieurs mégaoctets, le remède est simple : compiler ce dessin séparément en un PDF autonome et l'inclure avec \includegraphics. La qualité vectorielle est préservée et l'intégration n'a lieu qu'une fois.