bytes, new FlateDecode()); $repertoire = new UnicodeText(implode('', array_map(static fn (UnicodeText $line): string => $line->utf8, $lines))); $map = (new CharacterMapFactory($program))->create($fontFile, $repertoire); $encoder = new TextEncoder($map); $descriptor = (new FontDescriptorFactory($program))->create($fontFile, new FontDescriptorFlags(4), new NumericType(80)); $descendant = new CIDFontType2($descriptor, new CIDToGIDMap($map, new FlateDecode()), new CIDWidths($map)); $font = new Type0Font($descendant, new ToUnicodeCMap($map, new FlateDecode())); // MCAF associates a content sequence through a named property dictionary. $resources = new ResourceDictionary( new Font(new DictionaryType(new Entry(new NameType('F1'), new IndirectReference($font)))), new Properties(new DictionaryType(new Entry(new NameType('AFData'), new AssociatedFilesPropertyList($files)))), ); $operators = [new BeginAssociatedFilesMarkedContent(new NameType('AFData')), new Op\BeginTextObject(), new Op\SetTextFontAndSize(new NameType('F1'), new NumericType(20)), new Op\MoveTextPosition(new NumericType(48), new NumericType(748))]; foreach ($lines as $index => $line) { if ($index !== 0) { $operators[] = new Op\SetTextFontAndSize(new NameType('F1'), new NumericType(12)); $operators[] = new Op\MoveTextPosition(new NumericType(0), new NumericType($index === 1 ? -42 : -28)); } $operators[] = new Op\ShowText($encoder->encode($line)); } $operators[] = new Op\EndTextObject(); $operators[] = new Op\EndMarkedContent(); $page = new PageObject( new Rectangle(new NumericType(0), new NumericType(0), new NumericType(595), new NumericType(842)), $resources, new StreamObject(new ContentStreams(...$operators)), new Entry(new NameType('AF'), $files), ); $pages = (new PageTreeNode())->addKid($page); // This definition belongs to ISO32000-2 Table29, separately from ISO32000-1 Table28. $catalog = new CatalogDictionaryTable29(new TypeEntry(new NameType('Catalog')), new PagesEntry(new IndirectReference($pages)), new AFEntry($files)); // Info is retained for a simple UTF8 string demonstration. It is deprecated in // PDF2.0; this example does not claim complete PDF2.0 or archival-profile conformance. $info = new DictionaryType(new Entry(new NameType('Title'), $title)); $file = new FileStructure(new FileHeader(PdfVersion::PDF20), new FileBody($catalog), trailerEntries: new DictionaryType(new Entry(new NameType('Info'), new IndirectReference($info)))); $path = $argv[1] ?? __DIR__ . '/pdf20-associated-files.pdf'; $file->writeTo($path); echo $path . PHP_EOL;