Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Mpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -9497,7 +9497,7 @@ function SetDash($black = false, $white = false)

function SetDisplayPreferences($preferences)
{
// String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow
// String containing any or none of /HideMenubar/HideToolbar/HideWindowUI/DisplayDocTitle/CenterWindow/FitWindow/NoPrintScaling/FullScreen/UseAttachments

$this->DisplayPreferences .= $preferences;
}
Expand Down
39 changes: 31 additions & 8 deletions src/Writer/MetadataWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,11 @@ public function writeCatalog() //_putcatalog
// Bookmarks
if (count($this->mpdf->BMoutlines) > 0) {
$this->writer->write('/Outlines ' . $this->mpdf->OutlineRoot . ' 0 R');
$this->writer->write('/PageMode /UseOutlines');
}

// Fullscreen
if (is_int(strpos($this->mpdf->DisplayPreferences, 'FullScreen'))) {
$this->writer->write('/PageMode /FullScreen');
$pageMode = $this->getPageMode();
if ($pageMode !== null) {
$this->writer->write('/PageMode /' . $pageMode);
}

// Metadata
Expand Down Expand Up @@ -463,10 +462,6 @@ public function writeCatalog() //_putcatalog
$this->writer->write('>>');
}

if ($this->mpdf->open_layer_pane && ($this->mpdf->hasOC || count($this->mpdf->layers))) {
$this->writer->write('/PageMode /UseOC');
}

if ($this->mpdf->hasOC || count($this->mpdf->layers)) {

$p = $v = $h = $l = $loff = $lall = $as = '';
Expand Down Expand Up @@ -510,6 +505,34 @@ public function writeCatalog() //_putcatalog
}
}

/**
* A catalog carries a single /PageMode, so the modes the document asks for explicitly take
* precedence over the outline pane implied by simply having bookmarks.
*
* @return string|null
*/
private function getPageMode()
{
if ($this->mpdf->open_layer_pane && ($this->mpdf->hasOC || count($this->mpdf->layers))) {
return 'UseOC';
}

if (is_int(strpos($this->mpdf->DisplayPreferences, 'FullScreen'))) {
return 'FullScreen';
}

// UseAttachments is PDF 1.6 spec.
if (is_int(strpos($this->mpdf->DisplayPreferences, 'UseAttachments'))) {
return 'UseAttachments';
}

if (count($this->mpdf->BMoutlines) > 0) {
return 'UseOutlines';
}

return null;
}

/**
* @since 5.7.2
*/
Expand Down
94 changes: 94 additions & 0 deletions tests/Mpdf/PageModeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace Mpdf;

class PageModeTest extends \Yoast\PHPUnitPolyfills\TestCases\TestCase
{

public function testNoPageModeByDefault()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->WriteHTML('<p>Hello</p>');
});

$this->assertStringNotContainsString('/PageMode', $output);
}

public function testBookmarksOpenTheOutlinePane()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->WriteHTML('<p>Hello</p>');
$mpdf->Bookmark('Chapter one');
});

$this->assertSame(1, substr_count($output, '/PageMode'));
$this->assertStringContainsString('/PageMode /UseOutlines', $output);
}

public function testUseAttachmentsDisplayPreference()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->SetDisplayPreferences('UseAttachments');
$mpdf->WriteHTML('<p>Hello</p>');
});

$this->assertSame(1, substr_count($output, '/PageMode'));
$this->assertStringContainsString('/PageMode /UseAttachments', $output);
}

/**
* A dictionary cannot hold the same key twice, so an explicit request has to beat the
* outline pane that bookmarks would otherwise ask for.
*/
public function testExplicitPreferenceWinsOverBookmarks()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->SetDisplayPreferences('UseAttachments');
$mpdf->WriteHTML('<p>Hello</p>');
$mpdf->Bookmark('Chapter one');
});

$this->assertSame(1, substr_count($output, '/PageMode'));
$this->assertStringContainsString('/PageMode /UseAttachments', $output);
}

public function testFullScreenWinsOverUseAttachments()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->SetDisplayPreferences('FullScreenUseAttachments');
$mpdf->WriteHTML('<p>Hello</p>');
});

$this->assertSame(1, substr_count($output, '/PageMode'));
$this->assertStringContainsString('/PageMode /FullScreen', $output);
}

public function testLayerPaneWinsOverEverythingElse()
{
$output = $this->render(function (Mpdf $mpdf) {
$mpdf->open_layer_pane = true;
$mpdf->SetDisplayPreferences('FullScreen');
$mpdf->SetVisibility('screenonly');
$mpdf->WriteHTML('<p>Hello</p>');
$mpdf->SetVisibility('visible');
$mpdf->Bookmark('Chapter one');
});

$this->assertSame(1, substr_count($output, '/PageMode'));
$this->assertStringContainsString('/PageMode /UseOC', $output);
}

private function render(callable $write)
{
$mpdf = new Mpdf();
$mpdf->compress = false;

$write($mpdf);

$output = $mpdf->OutputBinaryData();
$mpdf->cleanup();

return $output;
}

}
Loading