@@ -246,6 +246,36 @@ export async function makeNoisePdf(): Promise<Uint8Array> {
246246 return doc . save ( ) ;
247247}
248248
249+ /**
250+ * Document à signer : `pages` pages A4 blanches portant du texte (couche
251+ * texte) et des métadonnées marquées SECRET, pour vérifier que la copie
252+ * signée n'en garde rien.
253+ */
254+ export async function makeSignablePdf ( pages : number ) : Promise < Uint8Array > {
255+ const doc = await PDFDocument . create ( ) ;
256+ doc . setAuthor ( SECRET ) ;
257+ doc . setTitle ( SECRET ) ;
258+ const font = await doc . embedFont ( StandardFonts . Helvetica ) ;
259+ for ( let i = 0 ; i < pages ; i ++ ) {
260+ const page = doc . addPage ( [ 595 , 842 ] ) ;
261+ page . drawText ( `Contrat — page ${ i + 1 } — ${ SECRET } ` , { x : 50 , y : 790 , size : 11 , font, color : rgb ( 0.1 , 0.1 , 0.1 ) } ) ;
262+ }
263+ return doc . save ( ) ;
264+ }
265+
266+ /** Octets JPEG de l'image qui couvre la page `index` d'une sortie Cachety (une image par page). */
267+ export async function pageJpeg ( bytes : Uint8Array , index : number ) : Promise < Uint8Array > {
268+ const doc = await PDFDocument . load ( bytes ) ;
269+ const page = doc . getPage ( index ) ;
270+ const resources = page . node . Resources ( ) ;
271+ const xobjects = resources ?. lookup ( PDFName . of ( "XObject" ) , PDFDict ) ;
272+ for ( const [ , ref ] of xobjects ?. entries ( ) ?? [ ] ) {
273+ const stream = doc . context . lookup ( ref ) ;
274+ if ( stream instanceof PDFRawStream ) return stream . contents ;
275+ }
276+ throw new Error ( `page ${ index } : aucune image` ) ;
277+ }
278+
249279/** PDF d'une page entièrement bleue (#2040c0) : repère pour vérifier un masque. */
250280export async function makeBluePdf ( ) : Promise < Uint8Array > {
251281 const doc = await PDFDocument . create ( ) ;
0 commit comments