├── .editorconfig
├── .github
├── dependabot.yaml
└── workflows
│ └── ci.yaml
├── .gitignore
├── .idea
├── .name
├── Ghostscript.iml
├── composerJson.xml
├── copyright
│ └── profiles_settings.xml
├── dictionaries
│ └── daniel.xml
├── encodings.xml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── modules.xml
├── phing.xml
├── php.xml
├── scopes
│ └── scope_settings.xml
└── vcs.xml
├── .scrutinizer.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── build.xml
├── composer.json
├── phpunit.xml.dist
├── src
├── Device
│ ├── AbstractDevice.php
│ ├── BoundingBoxInfo.php
│ ├── CommandLineParameters
│ │ ├── EpsTrait.php
│ │ ├── FontTrait.php
│ │ ├── IccColorTrait.php
│ │ ├── InteractionTrait.php
│ │ ├── OtherTrait.php
│ │ ├── OutputSelectionTrait.php
│ │ ├── PageTrait.php
│ │ ├── RenderingTrait.php
│ │ └── ResourceTrait.php
│ ├── CommandLineParametersTrait.php
│ ├── DistillerParameters
│ │ ├── AdvancedTrait.php
│ │ ├── ColorConversionTrait.php
│ │ ├── ColorImageCompressionTrait.php
│ │ ├── FontTrait.php
│ │ ├── GrayImageCompressionTrait.php
│ │ ├── MonoImageCompressionTrait.php
│ │ └── PageCompressionTrait.php
│ ├── DistillerParametersTrait.php
│ ├── Inkcov.php
│ ├── NoDisplay.php
│ ├── PdfInfo.php
│ └── PdfWrite.php
├── Enum
│ ├── AutoRotatePages.php
│ ├── Binding.php
│ ├── CannotEmbedFontPolicy.php
│ ├── ColorAndGrayImageFilter.php
│ ├── ColorConversionStrategy.php
│ ├── DefaultRenderingIntent.php
│ ├── ImageDownsampleType.php
│ ├── MonoImageFilter.php
│ ├── PdfSettings.php
│ ├── ProcessColorModel.php
│ ├── TransferFunctionInfo.php
│ └── UcrAndBgInfo.php
├── Ghostscript.php
├── GhostscriptInterface.php
├── Input.php
└── Process
│ ├── Argument.php
│ └── Arguments.php
└── tests
├── data
├── input.pdf
└── pdf_info.ps
└── src
├── Device
├── AbstractDeviceTest.php
├── BoundingBoxInfoTest.php
├── CommandLineParameters
│ ├── FontTraitTest.php
│ ├── InteractionTraitTest.php
│ ├── OtherTraitTest.php
│ └── PageTraitTest.php
├── DeviceTestCase.php
├── DistillerParameters
│ ├── AdvancedTraitTest.php
│ ├── ColorConversionTraitTest.php
│ ├── ColorImageCompressionTraitTest.php
│ ├── FontTraitTest.php
│ ├── GrayImageCompressionTraitTest.php
│ ├── MonoImageCompressionTraitTest.php
│ └── PageCompressionTraitTest.php
├── DistillerParametersTraitTest.php
├── InkcovTest.php
├── NoDisplayTest.php
├── PdfInfoTest.php
└── PdfWriteTest.php
├── Enum
├── AutoRotatePagesTest.php
├── BindingTest.php
├── CannotEmbedFontPolicyTest.php
├── ColorAndGrayImageFilterTest.php
├── ColorConversionStrategyTest.php
├── DefaultRenderingIntentTest.php
├── ImageDownsampleTypeTest.php
├── MonoImageFilterTest.php
├── PdfSettingsTest.php
├── ProcessColorModelTest.php
├── TransferFunctionInfoTest.php
└── UcrAndBgInfoTest.php
├── GhostscriptTest.php
├── InputTest.php
└── Process
├── ArgumentTest.php
└── ArgumentsTest.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Default settings
7 | [*]
8 | end_of_line = lf
9 | indent_size = 4
10 | indent_style = space
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
14 | # Markdown file settings
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
18 | # YAML file settings
19 | [*.yaml]
20 | indent_size = 2
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | updates:
4 | - package-ecosystem: 'composer'
5 | directory: '/'
6 | schedule:
7 | interval: 'weekly'
8 |
9 | - package-ecosystem: 'github-actions'
10 | directory: '/'
11 | schedule:
12 | interval: 'weekly'
13 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | pull_request:
3 | branches:
4 | - master
5 | push:
6 | branches:
7 | - master
8 |
9 | env:
10 | PHP_EXTENSIONS: intl, pcov
11 | PHP_VERSION: 8.3
12 |
13 | jobs:
14 | tests:
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - name: Checkout code
19 | uses: actions/checkout@v4
20 | with:
21 | fetch-depth: 0
22 |
23 | - name: Install packages
24 | uses: awalsh128/cache-apt-pkgs-action@latest
25 | with:
26 | packages: ghostscript
27 | version: 1
28 |
29 | - name: Setup PHP extensions cache
30 | id: php-extensions-cache
31 | uses: shivammathur/cache-extensions@v1
32 | with:
33 | php-version: ${{ env.PHP_VERSION }}
34 | extensions: ${{ env.PHP_EXTENSIONS }}
35 | key: ${{ runner.os }}-PHP-Extensions-V1
36 |
37 | - name: Cache PHP extensions
38 | uses: actions/cache@v4
39 | with:
40 | path: ${{ steps.php-extensions-cache.outputs.dir }}
41 | key: ${{ steps.php-extensions-cache.outputs.key }}
42 | restore-keys: ${{ steps.php-extensions-cache.outputs.key }}
43 |
44 | - name: Setup PHP
45 | uses: shivammathur/setup-php@v2
46 | with:
47 | php-version: ${{ env.PHP_VERSION }}
48 | extensions: ${{ env.PHP_EXTENSIONS }}
49 |
50 | - name: Get Composer cache directory
51 | id: composer-cache
52 | run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
53 |
54 | - name: Cache Composer dependencies
55 | uses: actions/cache@v4
56 | with:
57 | path: ${{ steps.composer-cache.outputs.dir }}
58 | key: ${{ runner.os }}-Composer-V1-${{ hashFiles('**/composer.lock') }}
59 | restore-keys: ${{ runner.os }}-Composer-V1-
60 |
61 | - name: Install Composer dependencies
62 | run: composer update --prefer-dist --prefer-stable --no-progress
63 |
64 | - name: Run PHPUnit tests
65 | run: vendor/bin/phpunit --coverage-clover=coverage.clover --coverage-text
66 |
67 | - name: Upload coverage to Scrutinizer
68 | run: vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | build/
3 | cache/
4 | vendor/
5 | .phpunit.cache/
6 | .phpunit.result.cache
7 | composer.phar
8 | composer.lock
9 | coverage.clover
10 | phpunit.xml
11 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | Ghostscript
--------------------------------------------------------------------------------
/.idea/Ghostscript.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/composerJson.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/dictionaries/daniel.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ghostscript
5 | joboptions
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/phing.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $USER_HOME$/.composer/vendor/bin/phing
5 |
6 |
--------------------------------------------------------------------------------
/.idea/php.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | filter:
2 | excluded_paths:
3 | - "tests/*"
4 |
5 | checks:
6 | php:
7 | remove_extra_empty_lines: true
8 | remove_php_closing_tag: true
9 | remove_trailing_whitespace: true
10 | fix_use_statements:
11 | remove_unused: true
12 | preserve_multiple: false
13 | preserve_blanklines: true
14 | order_alphabetically: true
15 | fix_php_opening_tag: true
16 | fix_linefeed: true
17 | fix_line_ending: true
18 | fix_identation_4spaces: true
19 | fix_doc_comments: true
20 |
21 | tools:
22 | external_code_coverage:
23 | timeout: 600
24 | runs: 2
25 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All Notable changes to `gravitymedia/ghostscript` will be documented in this file.
4 | This project adheres to [Semantic Versioning](http://semver.org/).
5 |
6 | ## NEXT - YYYY-MM-DD
7 |
8 | ### Added
9 | - Nothing
10 |
11 | ### Changed
12 | - Nothing
13 |
14 | ### Deprecated
15 | - Nothing
16 |
17 | ### Removed
18 | - Nothing
19 |
20 | ### Fixed
21 | - Nothing
22 |
23 | ### Security
24 | - Nothing
25 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | We accept contributions via Pull Requests on [Github](https://github.com/GravityMedia/Ghostscript).
6 |
7 | ## Pull Requests
8 |
9 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
10 |
11 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
12 |
13 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
14 |
15 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
16 |
17 | - **Create feature branches** - Don't ask us to pull from your master branch.
18 |
19 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
20 |
21 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
22 |
23 | ## Running Tests
24 |
25 | ``` bash
26 | $ php vendor/bin/phpunit --coverage-text --verbose
27 | ```
28 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Daniel Schröder
4 |
5 | > Permission is hereby granted, free of charge, to any person obtaining a copy
6 | > of this software and associated documentation files (the "Software"), to deal
7 | > in the Software without restriction, including without limitation the rights
8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | > copies of the Software, and to permit persons to whom the Software is
10 | > furnished to do so, subject to the following conditions:
11 | >
12 | > The above copyright notice and this permission notice shall be included in
13 | > all copies or substantial portions of the Software.
14 | >
15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | > THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ghostscript
2 |
3 | [](https://packagist.org/packages/gravitymedia/ghostscript)
4 | [](LICENSE.md)
5 | [](https://github.com/GravityMedia/Ghostscript/actions/workflows/ci.yaml)
6 | [](https://scrutinizer-ci.com/g/GravityMedia/Ghostscript/code-structure)
7 | [](https://scrutinizer-ci.com/g/GravityMedia/Ghostscript)
8 | [](https://packagist.org/packages/gravitymedia/ghostscript)
9 |
10 | Ghostscript is an object oriented Ghostscript binary wrapper for PHP.
11 |
12 | ## Requirements
13 |
14 | This library has the following requirements:
15 |
16 | - PHP 8.0+
17 | - Ghostscript 9.00+
18 |
19 | ## Installation
20 |
21 | Install Composer in your project:
22 |
23 | ```bash
24 | $ curl -s https://getcomposer.org/installer | php
25 | ```
26 |
27 | Require the package via Composer:
28 |
29 | ```bash
30 | $ php composer.phar require gravitymedia/ghostscript:v2.4
31 | ```
32 |
33 | ## Usage
34 |
35 | This is a simple usage example how to convert an input PDF to an output PDF.
36 |
37 | ```php
38 | // Initialize autoloader
39 | require_once __DIR__ . '/vendor/autoload.php';
40 |
41 | // Import classes
42 | use GravityMedia\Ghostscript\Ghostscript;
43 | use Symfony\Component\Process\Process;
44 |
45 | // Define input and output files
46 | $inputFile = '/path/to/input/file.pdf';
47 | $outputFile = '/path/to/output/file.pdf';
48 |
49 | // Create Ghostscript object
50 | $ghostscript = new Ghostscript([
51 | 'quiet' => false
52 | ]);
53 |
54 | // Create and configure the device
55 | $device = $ghostscript->createPdfDevice($outputFile);
56 | $device->setCompatibilityLevel(1.4);
57 |
58 | // Create process
59 | $process = $device->createProcess($inputFile);
60 |
61 | // Print the command line
62 | print '$ ' . $process->getCommandLine() . PHP_EOL;
63 |
64 | // Run process
65 | $process->run(function ($type, $buffer) {
66 | if ($type === Process::ERR) {
67 | throw new \RuntimeException($buffer);
68 | }
69 |
70 | print $buffer;
71 | });
72 | ```
73 |
74 | ## Testing
75 |
76 | Clone this repository, install Composer and all dependencies:
77 |
78 | ```bash
79 | $ php composer.phar install
80 | ```
81 |
82 | Run the test suite:
83 |
84 | ```bash
85 | $ php composer.phar test
86 | ```
87 |
88 | ## Generating documentation
89 |
90 | Clone this repository, install Composer and all dependencies:
91 |
92 | ```bash
93 | $ php composer.phar install
94 | ```
95 |
96 | Generate the documentation to the `build/docs` directory:
97 |
98 | ```bash
99 | $ php composer.phar doc
100 | ```
101 |
102 | ## Contributing
103 |
104 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
105 |
106 | ## Credits
107 |
108 | - [Daniel Schröder](https://github.com/pCoLaSD)
109 | - [All Contributors](../../contributors)
110 |
111 | ## License
112 |
113 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
114 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gravitymedia/ghostscript",
3 | "description": "Ghostscript is an object oriented Ghostscript binary wrapper for PHP.",
4 | "keywords": [
5 | "gravitymedia",
6 | "ghostscript"
7 | ],
8 | "homepage": "https://github.com/GravityMedia/Ghostscript",
9 | "license": "MIT",
10 | "authors": [
11 | {
12 | "name": "Daniel Schröder",
13 | "email": "daniel.schroeder@gravitymedia.de",
14 | "homepage": "https://github.com/pCoLaSD",
15 | "role": "Developer"
16 | }
17 | ],
18 | "require": {
19 | "php": "^8.0",
20 | "symfony/process": "^5.0|^6.0|^7.0"
21 | },
22 | "require-dev": {
23 | "phing/phing": "^2.14",
24 | "phpunit/phpunit": "^9.5|^10.0|^11.0",
25 | "scrutinizer/ocular": "^1.3",
26 | "symfony/finder": "^5.0|^6.0|^7.0",
27 | "sebastian/comparator": ">=1.2.3"
28 | },
29 | "autoload": {
30 | "psr-4": {
31 | "GravityMedia\\Ghostscript\\": "src/"
32 | }
33 | },
34 | "autoload-dev": {
35 | "psr-4": {
36 | "GravityMedia\\GhostscriptTest\\": "tests/src/"
37 | }
38 | },
39 | "scripts": {
40 | "test": "php vendor/bin/phing test",
41 | "doc": "php vendor/bin/phing doc"
42 | },
43 | "extra": {
44 | "branch-alias": {
45 | "dev-master": "2.0-dev"
46 | }
47 | },
48 | "archive": {
49 | "exclude": [
50 | "/.*",
51 | "/*.php",
52 | "/build.*",
53 | "/composer.*",
54 | "/phpunit.*",
55 | "/tests"
56 | ]
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | src
27 |
28 |
29 |
30 |
31 | tests/src
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/Device/AbstractDevice.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | use GravityMedia\Ghostscript\Ghostscript;
11 | use GravityMedia\Ghostscript\GhostscriptInterface;
12 | use GravityMedia\Ghostscript\Input;
13 | use GravityMedia\Ghostscript\Process\Argument;
14 | use GravityMedia\Ghostscript\Process\Arguments;
15 | use Symfony\Component\Process\Process;
16 |
17 | /**
18 | * The abstract device class.
19 | *
20 | * @package GravityMedia\Ghostscript\Devices
21 | */
22 | abstract class AbstractDevice
23 | {
24 | /**
25 | * Use command line options.
26 | */
27 | use CommandLineParametersTrait;
28 |
29 | /**
30 | * Use rendering parameters.
31 | */
32 | use CommandLineParameters\RenderingTrait;
33 |
34 | /**
35 | * Use page parameters.
36 | */
37 | use CommandLineParameters\PageTrait;
38 |
39 | /**
40 | * Use font-related parameters.
41 | */
42 | use CommandLineParameters\FontTrait;
43 |
44 | /**
45 | * Use resource-related parameters.
46 | */
47 | use CommandLineParameters\ResourceTrait;
48 |
49 | /**
50 | * Use interaction parameters.
51 | */
52 | use CommandLineParameters\InteractionTrait;
53 |
54 | /**
55 | * Use device and output selection parameters.
56 | */
57 | use CommandLineParameters\OutputSelectionTrait;
58 |
59 | /**
60 | * Use EPS parameters.
61 | */
62 | use CommandLineParameters\EpsTrait;
63 |
64 | /**
65 | * Use ICC color parameters.
66 | */
67 | use CommandLineParameters\IccColorTrait;
68 |
69 | /**
70 | * Use other parameters.
71 | */
72 | use CommandLineParameters\OtherTrait;
73 |
74 | /**
75 | * The Ghostscript object.
76 | */
77 | protected GhostscriptInterface $ghostscript;
78 |
79 | /**
80 | * The arguments object.
81 | */
82 | private Arguments $arguments;
83 |
84 | /**
85 | * Create abstract device object.
86 | */
87 | public function __construct(GhostscriptInterface $ghostscript, Arguments $arguments)
88 | {
89 | $this->ghostscript = $ghostscript;
90 | $this->arguments = $arguments;
91 | }
92 |
93 | /**
94 | * Get argument.
95 | *
96 | * @param string $name
97 | *
98 | * @return null|Argument
99 | */
100 | protected function getArgument($name)
101 | {
102 | return $this->arguments->getArgument($name);
103 | }
104 |
105 | /**
106 | * Whether argument is set.
107 | *
108 | * @param string $name
109 | *
110 | * @return bool
111 | */
112 | protected function hasArgument($name)
113 | {
114 | return null !== $this->getArgument($name);
115 | }
116 |
117 | /**
118 | * Get argument value.
119 | *
120 | * @param string $name
121 | *
122 | * @return null|string
123 | */
124 | protected function getArgumentValue($name)
125 | {
126 | $argument = $this->getArgument($name);
127 | if (null === $argument) {
128 | return null;
129 | }
130 |
131 | return $argument->getValue();
132 | }
133 |
134 | /**
135 | * Set argument.
136 | *
137 | * @param string $argument
138 | *
139 | * @return $this
140 | */
141 | protected function setArgument($argument)
142 | {
143 | $this->arguments->setArgument($argument);
144 |
145 | return $this;
146 | }
147 |
148 | /**
149 | * Sanitize input.
150 | *
151 | * @param null|string|resource|Input $input
152 | *
153 | * @return Input
154 | */
155 | protected function sanitizeInput($input)
156 | {
157 | if (null === $input) {
158 | $input = $this->ghostscript->getOption('input', new Input());
159 | }
160 |
161 | if ($input instanceof Input) {
162 | return $input;
163 | }
164 |
165 | $instance = new Input();
166 |
167 | if (is_resource($input)) {
168 | return $instance->setProcessInput($input);
169 | }
170 |
171 | if (file_exists($input)) {
172 | return $instance->addFile($input);
173 | }
174 |
175 | return $instance->setPostScriptCode((string)$input);
176 | }
177 |
178 | /**
179 | * Create process arguments.
180 | *
181 | * @param Input $input
182 | *
183 | * @throws \RuntimeException
184 | *
185 | * @return array
186 | */
187 | protected function createProcessArguments(Input $input)
188 | {
189 | $arguments = array_values($this->arguments->toArray());
190 |
191 | if (null !== $input->getPostScriptCode()) {
192 | array_push($arguments, '-c', $input->getPostScriptCode());
193 | }
194 |
195 | if (count($input->getFiles()) > 0) {
196 | array_push($arguments, '-f');
197 | foreach ($input->getFiles() as $file) {
198 | if (!is_file($file)) {
199 | throw new \RuntimeException('Input file does not exist');
200 | }
201 |
202 | array_push($arguments, $file);
203 | }
204 | }
205 |
206 | if (null !== $input->getProcessInput()) {
207 | array_push($arguments, '-');
208 | }
209 |
210 | return $arguments;
211 | }
212 |
213 | /**
214 | * Create process object.
215 | *
216 | * @param null|string|resource|Input $input
217 | *
218 | * @throws \RuntimeException
219 | *
220 | * @return Process
221 | */
222 | public function createProcess($input = null)
223 | {
224 | $requiredVersion = $this->getRequiredVersion();
225 | $version = $this->ghostscript->getVersion();
226 | if (version_compare($requiredVersion, $version) > 0) {
227 | throw new \RuntimeException("Ghostscript version {$requiredVersion} or higher is required");
228 | }
229 |
230 | $input = $this->sanitizeInput($input);
231 |
232 | $arguments = $this->createProcessArguments($input);
233 | array_unshift(
234 | $arguments,
235 | $this->ghostscript->getOption('bin', Ghostscript::DEFAULT_BINARY)
236 | );
237 |
238 | return new Process(
239 | $arguments,
240 | $this->ghostscript->getOption('cwd'),
241 | $this->ghostscript->getOption('env', []),
242 | $input->getProcessInput(),
243 | $this->ghostscript->getOption('timeout', 60)
244 | );
245 | }
246 |
247 | protected function getRequiredVersion(): string
248 | {
249 | return '9.00';
250 | }
251 | }
252 |
--------------------------------------------------------------------------------
/src/Device/BoundingBoxInfo.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | use GravityMedia\Ghostscript\Ghostscript;
11 | use GravityMedia\Ghostscript\GhostscriptInterface;
12 | use GravityMedia\Ghostscript\Process\Arguments;
13 |
14 | /**
15 | * The bounding box info device class.
16 | *
17 | * @link http://ghostscript.com/doc/current/Devices.htm#Bounding_box_output
18 | *
19 | * @package GravityMedia\Ghostscript\Devices
20 | */
21 | class BoundingBoxInfo extends AbstractDevice
22 | {
23 | /**
24 | * Create bounding box info device object.
25 | *
26 | * @param Ghostscript $ghostscript
27 | * @param Arguments $arguments
28 | */
29 | public function __construct(GhostscriptInterface $ghostscript, Arguments $arguments)
30 | {
31 | parent::__construct($ghostscript, $arguments->setArgument('-sDEVICE=bbox'));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/EpsTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The EPS parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#EPS_parameters
16 | */
17 | trait EpsTrait
18 | {
19 | /**
20 | * TODO
21 | *
22 | * -dEPSCrop
23 | * Crop an EPS file to the bounding box. This is useful when converting an EPS file to a bitmap.
24 | *
25 | * -dEPSFitPage
26 | * Resize an EPS file to fit the page. This is useful for shrinking or enlarging an EPS file to fit the paper
27 | * size when printing.
28 | *
29 | * This option is also set by the -dFitPage option.
30 | *
31 | * -dNOEPS
32 | * Prevent special processing of EPS files. This is useful when EPS files have incorrect Document Structuring
33 | * Convention comments.
34 | */
35 | }
36 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/FontTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The font-related parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Font_related_parameters
16 | */
17 | trait FontTrait
18 | {
19 | /**
20 | * Get argument value.
21 | *
22 | * @param string $name
23 | *
24 | * @return null|string
25 | */
26 | abstract protected function getArgumentValue($name);
27 |
28 | /**
29 | * Set argument.
30 | *
31 | * @param string $argument
32 | *
33 | * @return $this
34 | */
35 | abstract protected function setArgument($argument);
36 |
37 | /**
38 | * TODO
39 | *
40 | * -dDISKFONTS
41 | * Causes individual character outlines to be loaded from the disk the first time they are encountered.
42 | * (Normally Ghostscript loads all the character outlines when it loads a font.) This may allow loading more
43 | * fonts into memory at the expense of slower rendering. DISKFONTS is effective only if the diskfont feature
44 | * was built into the executable; otherwise it is ignored.
45 | *
46 | * -dLOCALFONTS
47 | * Causes Type 1 fonts to be loaded into the current VM -- normally local VM -- instead of always being loaded
48 | * into global VM. Useful only for compatibility with Adobe printers for loading some obsolete fonts.
49 | *
50 | * -dNOCCFONTS
51 | * Suppresses the use of fonts precompiled into the Ghostscript executable. See "Precompiling fonts" in the
52 | * documentation on fonts for details. This is probably useful only for debugging.
53 | *
54 | * -dNOFONTMAP
55 | * Suppresses the normal loading of the Fontmap file. This may be useful in environments without a file system.
56 | *
57 | * -dNOFONTPATH
58 | * Suppresses consultation of GS_FONTPATH. This may be useful for debugging.
59 | *
60 | * -dNOPLATFONTS
61 | * Disables the use of fonts supplied by the underlying platform (X Windows or Microsoft Windows). This may be
62 | * needed if the platform fonts look undesirably different from the scalable fonts.
63 | *
64 | * -dNONATIVEFONTMAP
65 | * Disables the use of font map and corresponding fonts supplied by the underlying platform. This may be needed
66 | * to ensure consistent rendering on the platforms with different fonts, for instance, during regression
67 | * testing.
68 | *
69 | * -sFONTMAP=filename1;filename2;...
70 | * Specifies alternate name or names for the Fontmap file. Note that the names are separated by ":" on Unix
71 | * systems, by ";" on MS Windows systems, and by "," on VMS systems, just as for search paths.
72 | */
73 |
74 | /**
75 | * Get FONTPATH parameter value
76 | *
77 | * @return string|null
78 | */
79 | public function getFontPath()
80 | {
81 | return $this->getArgumentValue('-sFONTPATH');
82 | }
83 |
84 | /**
85 | * Set FONTPATH parameter
86 | *
87 | * @param string $fontPath Specifies a list of directories that will be scanned when looking for fonts not found on
88 | * the search path, overriding the environment variable GS_FONTPATH.
89 | *
90 | * @return $this
91 | */
92 | public function setFontPath($fontPath)
93 | {
94 | $this->setArgument(sprintf('-sFONTPATH=%s', $fontPath));
95 |
96 | return $this;
97 | }
98 |
99 | /**
100 | * TODO
101 | *
102 | * -sSUBSTFONT=fontname
103 | * Causes the given font to be substituted for all unknown fonts, instead of using the normal intelligent
104 | * substitution algorithm. Also, in this case, the font returned by findfont is the actual font named fontname,
105 | * not a copy of the font with its FontName changed to the requested one. THIS OPTION SHOULD NOT BE USED WITH
106 | * HIGH LEVEL DEVICES, such as pdfwrite, because it prevents such devices from providing the original font
107 | * names in the output document. The font specified (fontname) will be embedded instead, limiting all future
108 | * users of the document to the same approximate rendering.
109 | *
110 | * -dOLDCFF
111 | * Reverts to using the old, sequential, PostScript CFF parser. New CFF parser is coded in C and uses direct
112 | * access to the font data. This option and the old parser will be removed when the new parser proves its
113 | * reliability.
114 | */
115 | }
116 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/InteractionTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The interaction-related parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Interaction_related_parameters
16 | */
17 | trait InteractionTrait
18 | {
19 | /**
20 | * Whether argument is set
21 | *
22 | * @param string $name
23 | *
24 | * @return bool
25 | */
26 | abstract protected function hasArgument($name);
27 |
28 | /**
29 | * Get argument value
30 | *
31 | * @param string $name
32 | *
33 | * @return null|string
34 | */
35 | abstract protected function getArgumentValue($name);
36 |
37 | /**
38 | * Set argument
39 | *
40 | * @param string $argument
41 | *
42 | * @return $this
43 | */
44 | abstract protected function setArgument($argument);
45 |
46 | /**
47 | * Whether BATCH flag is set
48 | *
49 | * @return bool
50 | */
51 | public function isBatch()
52 | {
53 | return $this->hasArgument('-dBATCH');
54 | }
55 |
56 | /**
57 | * Set BATCH flag
58 | *
59 | * Causes Ghostscript to exit after processing all files named on the command line, rather than going into an
60 | * interactive loop reading PostScript commands. Equivalent to putting -c quit at the end of the command line.
61 | *
62 | * @return $this
63 | */
64 | public function setBatch()
65 | {
66 | $this->setArgument('-dBATCH');
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * Whether NOPAGEPROMPT flag is set
73 | *
74 | * @return bool
75 | */
76 | public function isNoPagePrompt()
77 | {
78 | return $this->hasArgument('-dNOPAGEPROMPT');
79 | }
80 |
81 | /**
82 | * Set NOPAGEPROMPT flag
83 | *
84 | * Disables only the prompt, but not the pause, at the end of each page. This may be useful on PC displays that get
85 | * confused if a program attempts to write text to the console while the display is in a graphics mode.
86 | *
87 | * @return $this
88 | */
89 | public function setNoPagePrompt()
90 | {
91 | $this->setArgument('-dNOPAGEPROMPT');
92 |
93 | return $this;
94 | }
95 |
96 | /**
97 | * Whether NOPAUSE flag is set
98 | *
99 | * @return bool
100 | */
101 | public function isNoPause()
102 | {
103 | return $this->hasArgument('-dNOPAUSE');
104 | }
105 |
106 | /**
107 | * Set NOPAUSE flag
108 | *
109 | * Disables the prompt and pause at the end of each page. Normally one should use this (along with -dBATCH) when
110 | * producing output on a printer or to a file; it also may be desirable for applications where another program is
111 | * "driving" Ghostscript.
112 | *
113 | * @return $this
114 | */
115 | public function setNoPause()
116 | {
117 | $this->setArgument('-dNOPAUSE');
118 |
119 | return $this;
120 | }
121 |
122 | /**
123 | * Whether NOPROMPT flag is set
124 | *
125 | * @return bool
126 | */
127 | public function isNoPrompt()
128 | {
129 | return $this->hasArgument('-dNOPROMPT');
130 | }
131 |
132 | /**
133 | * Set NOPROMPT flag
134 | *
135 | * Disables the prompt printed by Ghostscript when it expects interactive input, as well as the end-of-page prompt
136 | * (-dNOPAGEPROMPT). This allows piping input directly into Ghostscript, as long as the data doesn't refer to
137 | * currentfile.
138 | *
139 | * @return $this
140 | */
141 | public function setNoPrompt()
142 | {
143 | $this->setArgument('-dNOPROMPT');
144 |
145 | return $this;
146 | }
147 |
148 | /**
149 | * Whether QUIET flag is set
150 | *
151 | * @return bool
152 | */
153 | public function isQuiet()
154 | {
155 | return $this->hasArgument('-dQUIET');
156 | }
157 |
158 | /**
159 | * Set QUIET flag
160 | *
161 | * Suppresses routine information comments on standard output. This is currently necessary when redirecting device
162 | * output to standard output.
163 | *
164 | * @return $this
165 | */
166 | public function setQuiet()
167 | {
168 | $this->setArgument('-dQUIET');
169 |
170 | return $this;
171 | }
172 |
173 | /**
174 | * Whether SHORTERRORS flag is set
175 | *
176 | * @return bool
177 | */
178 | public function isShortErrors()
179 | {
180 | return $this->hasArgument('-dSHORTERRORS');
181 | }
182 |
183 | /**
184 | * Set SHORTERRORS flag
185 | *
186 | * Makes certain error and information messages more Adobe-compatible.
187 | *
188 | * @return $this
189 | */
190 | public function setShortErrors()
191 | {
192 | $this->setArgument('-dSHORTERRORS');
193 |
194 | return $this;
195 | }
196 |
197 | /**
198 | * Get value of stdout parameter if set
199 | *
200 | * @return string|null
201 | */
202 | public function getStdout()
203 | {
204 | return $this->getArgumentValue('-sstdout');
205 | }
206 |
207 | /**
208 | * Set stdout parameter
209 | *
210 | * Redirect PostScript %stdout to a file or stderr, to avoid it being mixed with device stdout. To redirect stdout
211 | * to stderr use -sstdout=%stderr. To cancel redirection of stdout use -sstdout=%stdout or -sstdout=-.
212 | *
213 | * Note that this redirects PostScript output to %stdout but does not change the destination FILE of device output
214 | * as with -sOutputFile=- or even -sOutputFile=%stdout since devices write directly using the stdout FILE * pointer
215 | * with C function calls such as fwrite or fputs.
216 | *
217 | * @param string $filename file to redirect PostScript %stdout to
218 | *
219 | * @return $this
220 | */
221 | public function setStdout($filename)
222 | {
223 | $this->setArgument(sprintf('-sstdout=%s', $filename));
224 |
225 | return $this;
226 | }
227 |
228 | /**
229 | * Whether TTYPAUSE flag is set
230 | *
231 | * @return bool
232 | */
233 | public function isTtyPause()
234 | {
235 | return $this->hasArgument('-dTTYPAUSE');
236 | }
237 |
238 | /**
239 | * Set TTYPAUSE flag
240 | *
241 | * Causes Ghostscript to read a character from /dev/tty, rather than standard input, at the end of each page. This
242 | * may be useful if input is coming from a pipe. Note that -dTTYPAUSE overrides -dNOPAUSE. Also note that -dTTYPAUSE
243 | * requires opening the terminal device directly, and may cause problems in combination with -dSAFER. Permission
244 | * errors can be avoided by adding the device to the permitted reading list before invoking safer mode. For example:
245 | * gs -dTTYPAUSE -dDELAYSAFER -c '<< /PermitFileReading [ (/dev/tty)] >> setuserparams .locksafe' -dSAFER
246 | *
247 | * @return $this
248 | */
249 | public function setTtyPause()
250 | {
251 | $this->setArgument('-dTTYPAUSE');
252 |
253 | return $this;
254 | }
255 | }
256 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/OutputSelectionTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The device and output selection parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Output_selection_parameters
16 | */
17 | trait OutputSelectionTrait
18 | {
19 | /**
20 | * TODO
21 | *
22 | * -dNODISPLAY
23 | * Initializes Ghostscript with a null device (a device that discards the output image) rather than the default
24 | * device or the device selected with -sDEVICE=. This is usually useful only when running PostScript code whose
25 | * purpose is to compute something rather than to produce an output image.
26 | *
27 | * -sDEVICE=device
28 | * Selects an alternate initial output device.
29 | *
30 | * -sOutputFile=filename
31 | * Selects an alternate output file (or pipe) for the initial output device, as described above.
32 | *
33 | * -d.IgnoreNumCopies=true
34 | * Some devices implement support for "printing" multiple copies of the input document and some do not, usually
35 | * based on whether it makes sense for a particular output format. This switch instructs all devices to ignore
36 | * a request to print multiple copies, giving more consistent behaviour.
37 | */
38 | }
39 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/PageTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The page parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Page_parameters
16 | */
17 | trait PageTrait
18 | {
19 | /**
20 | * Get argument value.
21 | *
22 | * @param string $name
23 | *
24 | * @return null|string
25 | */
26 | abstract protected function getArgumentValue($name);
27 |
28 | /**
29 | * Set argument.
30 | *
31 | * @param string $argument
32 | *
33 | * @return $this
34 | */
35 | abstract protected function setArgument($argument);
36 |
37 | /**
38 | * Get FirstPage parameter value
39 | *
40 | * @return string|null
41 | */
42 | public function getFirstPage()
43 | {
44 | return $this->getArgumentValue('-dFirstPage');
45 | }
46 |
47 | /**
48 | * Set FirstPage parameter
49 | * Begins processing on the designated page of the document.
50 | *
51 | * @param int $firstPage.
52 | *
53 | * @return $this
54 | */
55 | public function setFirstPage($firstPage)
56 | {
57 | $this->setArgument(sprintf('-dFirstPage=%d', $firstPage));
58 |
59 | return $this;
60 | }
61 |
62 | /**
63 | * Get LastPage parameter value
64 | *
65 | * @return string|null
66 | */
67 | public function getLastPage()
68 | {
69 | return $this->getArgumentValue('-dLastPage');
70 | }
71 |
72 | /**
73 | * Set LastPage parameter
74 | * Stops processing after the designated page of the document.
75 | *
76 | * @param int $lastPage.
77 | *
78 | * @return $this
79 | */
80 | public function setLastPage($lastPage)
81 | {
82 | $this->setArgument(sprintf('-dLastPage=%d', $lastPage));
83 |
84 | return $this;
85 | }
86 |
87 | /**
88 | * -dFIXEDMEDIA
89 | * Causes the media size to be fixed after initialization, forcing pages of other sizes or orientations to be
90 | * clipped. This may be useful when printing documents on a printer that can handle their requested paper size
91 | * but whose default is some other size. Note that -g automatically sets -dFIXEDMEDIA, but -sPAPERSIZE= does
92 | * not.
93 | *
94 | * @return $this
95 | */
96 | public function setFixedMedia()
97 | {
98 | $this->setArgument('-dFIXEDMEDIA');
99 |
100 | return $this;
101 | }
102 |
103 | public function getFixedMedia()
104 | {
105 | return $this->getArgumentValue('-dFIXEDMEDIA');
106 | }
107 |
108 | /**
109 | * The PDF file will be scaled to fit the current device page size (usually the default page size).
110 | * This is useful for creating fixed size images of PDF files that may have a variety of page sizes,
111 | * for example thumbnail images.
112 | *
113 | * @return $this
114 | */
115 | public function setPDFFitPage()
116 | {
117 | $this->setArgument('-dPDFFitPage');
118 |
119 | return $this;
120 | }
121 |
122 | public function getPDFFitPage()
123 | {
124 | return $this->getArgumentValue('-dPDFFitPage');
125 | }
126 |
127 | /**
128 | * TODO
129 | *
130 | * -dFIXEDRESOLUTION
131 | * Causes the media resolution to be fixed similarly. -r automatically sets -dFIXEDRESOLUTION.
132 | *
133 | * -dPSFitPage
134 | * The page size from the PostScript file setpagedevice operator, or one of the older statusdict page size
135 | * operators (such as letter or a4) will be rotated, scaled and centered on the "best fit" page size from those
136 | * availiable in the InputAttributes list. The -dPSFitPage is most easily used to fit pages when used with the
137 | * -dFIXEDMEDIA option.
138 | *
139 | * This option is also set by the -dFitPage option.
140 | *
141 | * -dORIENT1=true
142 | * -dORIENT1=false
143 | * Defines the meaning of the 0 and 1 orientation values for the setpage[params] compatibility operators. The
144 | * default value of ORIENT1 is true (set in gs_init.ps), which is the correct value for most files that use
145 | * setpage[params] at all, namely, files produced by badly designed applications that "know" that the output
146 | * will be printed on certain roll-media printers: these applications use 0 to mean landscape and 1 to mean
147 | * portrait. -dORIENT1=false declares that 0 means portrait and 1 means landscape, which is the convention used
148 | * by a smaller number of files produced by properly written applications.
149 | *
150 | * -dDEVICEWIDTHPOINTS=w
151 | * -dDEVICEHEIGHTPOINTS=h
152 | * Sets the initial page width to w or initial page height to h respectively, specified in 1/72" units.
153 | *
154 | * -sDEFAULTPAPERSIZE=a4
155 | * This value will be used to replace the device default papersize ONLY if the default papersize for the device
156 | * is 'letter' or 'a4' serving to insulate users of A4 or 8.5x11 from particular device defaults (the
157 | * collection of contributed drivers in Ghostscript vary as to the default size).
158 | *
159 | * -dFitPage
160 | * This is a "convenience" operator that sets the various options to perform page fitting for specific file
161 | * types.
162 | *
163 | * This option sets the -dEPSFitPage, -dPDFFitPage, and the -dFitPage options.
164 | */
165 | }
166 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/RenderingTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The rendering parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Rendering_parameters
16 | */
17 | trait RenderingTrait
18 | {
19 | /**
20 | * TODO
21 | *
22 | * -dCOLORSCREEN
23 | * -dCOLORSCREEN=0
24 | * -dCOLORSCREEN=false
25 | * On high-resolution devices (at least 150 dpi resolution, or -dDITHERPPI specified), -dCOLORSCREEN forces the
26 | * use of separate halftone screens with different angles for CMYK or RGB if halftones are needed (this
27 | * produces the best-quality output); -dCOLORSCREEN=0 uses separate screens with the same frequency and angle;
28 | * -dCOLORSCREEN=false forces the use of a single binary screen. The default if COLORSCREEN is not specified is
29 | * to use separate screens with different angles if the device has fewer than 5 bits per color, and a single
30 | * binary screen (which is never actually used under normal circumstances) on all other devices.
31 | *
32 | * -dDITHERPPI=lpi
33 | * Forces all devices to be considered high-resolution, and forces use of a halftone screen or screens with lpi
34 | * lines per inch, disregarding the actual device resolution. Reasonable values for lpi are N/5 to N/20, where
35 | * N is the resolution in dots per inch.
36 | *
37 | * -dDOINTERPOLATE
38 | * Turns on image interpolation for all images, improving image quality for scaled images at the expense of
39 | * speed. Note that -dNOINTERPOLATE overrides -dDOINTERPOLATE if both are specified.
40 | *
41 | * -dNOINTERPOLATE does nearest neighbour scaling (Bresenham's line algorithm through the image, plotting the
42 | * closest texture coord at each pixel). If we are downscaling this results in some source pixels not appearing
43 | * at all in the destination. If we are upscaling, at least some source pixels cover more than one destination
44 | * pixel.
45 | *
46 | * In all but special cases -dDOINTERPOLATE uses a Mitchell filter function to scale the contributions for each
47 | * output pixel; upscaling, every output pixel ends up being the weighted sum of 16 input pixels, downscaling
48 | * more. Every source pixel has an effect on the output pixels.
49 | *
50 | * Computationally, -dDOINTERPOLATE is much heavier work than -dNOINTERPOLATE (lots of floating point muliplies
51 | * and adds for every output pixel vs simple integer additions, subtractions, and shifts).
52 | *
53 | * The exact algorithm used is from Graphics Gems 3, Chapter I.2 General Filtered Image Rescaling.
54 | *
55 | * -dTextAlphaBits=n
56 | * -dGraphicsAlphaBits=n
57 | * These options control the use of subsample antialiasing. Their use is highly recommended for producing high
58 | * quality rasterizations. The subsampling box size n should be 4 for optimum output, but smaller values can be
59 | * used for faster rendering. Antialiasing is enabled separately for text and graphics content. Allowed values
60 | * are 1, 2 or 4.
61 | *
62 | * Note that because of the way antialiasing blends the edges of shapes into the background when they are drawn
63 | * some files that rely on joining separate filled polygons together to cover an area may not render as
64 | * expected with GraphicsAlphaBits at 2 or 4. If you encounter strange lines within solid areas, try rendering
65 | * that file again with -dGraphicsAlphaBits=1.
66 | *
67 | * -dAlignToPixels=n
68 | * Chooses glyph alignent to integral pixel boundaries (if set to the value 1) or to subpixels (value 0).
69 | * Subpixels are a smaller raster grid which is used internally for text antialiasing. The number of subpixels
70 | * in a pixel usually is 2^TextAlphaBits, but this may be automatically reduced for big characters to save
71 | * space in character cache.
72 | *
73 | * The parameter has no effect if -dTextAlphaBits=1. Default value is 0.
74 | *
75 | * Setting -dAlignToPixels=0 can improve rendering of poorly hinted fonts, but may impair the appearance of
76 | * well-hinted fonts.
77 | *
78 | * -dGridFitTT=n
79 | * This specifies the initial value for the implementation specific user parameter GridFitTT. It controls grid
80 | * fitting of True Type fonts (Sometimes referred to as "hinting", but strictly speaking the latter is a
81 | * feature of Type 1 fonts). Setting this to 2 enables automatic grid fitting for True Type glyphs. The value 0
82 | * disables grid fitting. The default value is 2. For more information see the description of the user
83 | * parameter GridFitTT.
84 | *
85 | * -dUseCIEColor
86 | * Set UseCIEColor in the page device dictionary, remapping device-dependent color values through a Postscript
87 | * defined CIE color space. Document DeviceGray, DeviceRGB and DeviceCMYK source colors will be substituted
88 | * respectively by Postscript CIEA, CIEABC and CIEDEFG color spaces. See the document GS9 Color Management for
89 | * details on how this option will interact with Ghostscript's ICC-based color workflow. If accurate colors are
90 | * desired, it is recommended that an ICC workflow be used.
91 | *
92 | * -dNOCIE
93 | * Substitutes DeviceGray for CIEBasedA, DeviceRGB for CIEBasedABC and CIEBasedDEF spaces and DeviceCMYK fpr
94 | * CIEBasedDEFG color spaces. Useful only on very slow systems where color accuracy is less important.
95 | *
96 | * -dNOSUBSTDEVICECOLORS
97 | * This switch prevents the substitution of the ColorSpace resources (DefaultGray, DefaultRGB, and DefaultCMYK)
98 | * for the DeviceGray, DeviceRGB, and DeviceCMYK color spaces. This switch is primarily useful for PDF creation
99 | * using the pdfwrite device when retaining the color spaces from the original document is important.
100 | *
101 | * -dNOPSICC
102 | * Disables the automatic loading and use of an input color space that is contained in a PostScript file as DSC
103 | * comments starting with the %%BeginICCProfile: comment. ICC profiles are sometimes embedded by applications
104 | * to convey the exact input color space allowing better color fidelity. Since the embedded ICC profiles often
105 | * use multidimensional RenderTables, color conversion may be slower than using the Default color conversion
106 | * invoked when the -dUseCIEColor option is specified, therefore the -dNOPSICC option may result in improved
107 | * performance at slightly reduced color fidelity.
108 | *
109 | * -dNOINTERPOLATE
110 | * Turns off image interpolation, improving performance on interpolated images at the expense of image quality.
111 | * -dNOINTERPOLATE overrides -dDOINTERPOLATE.
112 | *
113 | * -dNOTRANSPARENCY
114 | * Turns off PDF 1.4 transparency, resulting in faster (but possibly incorrect) rendering of pages containing
115 | * PDF 1.4 transparency and blending.
116 | *
117 | * -dNO_TN5044
118 | * Turns off the TN 5044 psuedo operators. These psuedo operators are not a part of the official Postscript
119 | * specification. However they are defined in Technical Note #5044 Color Separation Conventions for PostScript
120 | * Language Programs. These psuedo operators are required for some files from QuarkXPress. However some files
121 | * from Corel 9 and Illustrator 88 do not operate properly if these operators are present.
122 | *
123 | * -dDOPS
124 | * Enables processing of DoPS directives in PDF files. DoPS has in fact been deprecated for some time. Use of
125 | * this option is not recommended in security-conscious applications, as it increases the scope for malicious
126 | * code. -dDOPS has no effect on processing of PostScript source files. Note: in releases 7.30 and earlier,
127 | * processing of DoPS was always enabled.
128 | */
129 | }
130 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParameters/ResourceTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\CommandLineParameters;
9 |
10 | /**
11 | * The resource-related parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\CommandLineParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#Resource_related_parameters
16 | */
17 | trait ResourceTrait
18 | {
19 | /**
20 | * TODO
21 | *
22 | * -sGenericResourceDir=path
23 | * Specifies a path to resource files. The value is platform dependent. It must end with a directory separator.
24 | *
25 | * A note for Windows users, Artifex recommends the use of the forward slash delimiter due to the special
26 | * interpretation of \" by the Microsoft C startup code. See Parsing C Command-Line Arguments for more
27 | * information.
28 | *
29 | * Adobe specifies GenericResourceDir to be an absolute path to a single resource directory. Ghostscript
30 | * instead maintains multiple resource directories and uses an extended method for finding resources, which is
31 | * explained in "Finding PostScript Level 2 resources".
32 | *
33 | * Due to the extended search method, Ghostscript uses GenericResourceDir only as a default directory for
34 | * resources being not installed. Therefore GenericResourceDir may be considered as a place where new resources
35 | * to be installed. The default implementation of the function ResourceFileName uses GenericResourceDir when
36 | * (1) it is an absolute path, or (2) the resource file is absent. The extended search method does not call
37 | * ResourceFileName .
38 | *
39 | * Default value is (./Resource/) for Unix, and an equivalent one on other platforms.
40 | *
41 | * -sFontResourceDir=path
42 | * Specifies a path where font files are installed. It's meaning is similar to GenericResourceDir.
43 | *
44 | * Default value is (./Font/) for Unix, and an equivalent one on other platforms.
45 | */
46 | }
47 |
--------------------------------------------------------------------------------
/src/Device/CommandLineParametersTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | /**
11 | * The general Ghostscript command line parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript
14 | *
15 | * @link http://ghostscript.com/doc/current/Use.htm#General_switches
16 | */
17 | trait CommandLineParametersTrait
18 | {
19 | /**
20 | * TODO
21 | *
22 | * Input control
23 | *
24 | * @filename
25 | * Causes Ghostscript to read filename and treat its contents the same as the command line. (This was intended
26 | * primarily for getting around DOS's 128-character limit on the length of a command line.) Switches or file
27 | * names in the file may be separated by any amount of white space (space, tab, line break); there is no limit
28 | * on the size of the file.
29 | *
30 | * -- filename arg1 ...
31 | * -+ filename arg1 ...
32 | * Takes the next argument as a file name as usual, but takes all remaining arguments (even if they have the
33 | * syntactic form of switches) and defines the name ARGUMENTS in userdict (not systemdict) as an array of those
34 | * strings, before running the file. When Ghostscript finishes executing the file, it exits back to the shell.
35 | *
36 | * -@ filename arg1 ...
37 | * Does the same thing as -- and -+, but expands @filename arguments.
38 | *
39 | * -
40 | * -_
41 | * These are not really switches: they tell Ghostscript to read from standard input, which is coming from a
42 | * file
43 | * or a pipe, with or without buffering. On some systems, Ghostscript may read the input one character at a
44 | * time, which is useful for programs such as ghostview that generate input for Ghostscript dynamically and
45 | * watch for some response, but can slow processing. If performance is significantly slower than with a named
46 | * file, try '-_' which always reads the input in blocks. However, '-' is equivalent on most systems.
47 | *
48 | * -c token ...
49 | * -c string ...
50 | * Interprets arguments as PostScript code up to the next argument that begins with "-" followed by a
51 | * non-digit,
52 | * or with "@". For example, if the file quit.ps contains just the word "quit", then -c quit on the command
53 | * line
54 | * is equivalent to quit.ps there. Each argument must be valid PostScript, either individual tokens as defined
55 | * by the token operator, or a string containing valid PostScript.
56 | *
57 | * -f
58 | * Interprets following non-switch arguments as file names to be executed using the normal run command. Since
59 | * this is the default behavior, -f is useful only for terminating the list of tokens for the -c switch.
60 | *
61 | * -ffilename
62 | * Execute the given file, even if its name begins with a "-" or "@".
63 | *
64 | * File searching
65 | *
66 | * Note that by "library files" here we mean all the files identified using the search rule under "How Ghostscript
67 | * finds files" above: Ghostscript's own initialization files, fonts, and files named on the command line.
68 | *
69 | * -Idirectories
70 | * -I directories
71 | * Adds the designated list of directories at the head of the search path for library files.
72 | *
73 | * -P
74 | * Makes Ghostscript look first in the current directory for library files.
75 | *
76 | * -P-
77 | * Makes Ghostscript not look first in the current directory for library files (unless, of course, the first
78 | * explicitly supplied directory is "."). This is now the default.
79 | *
80 | * Setting parameters
81 | *
82 | * -Dname
83 | * -dname
84 | * Define a name in systemdict with value=true.
85 | *
86 | * -Dname=token
87 | * -dname=token
88 | * Define a name in systemdict with the given value. The value must be a valid PostScript token (as defined by
89 | * the token operator). If the token is a non-literal name, it must be true, false, or null. It is recommeded
90 | * that this is used only for simple values -- use -c (above) for complex values such as procedures, arrays or
91 | * dictionaries. Note that these values are defined before other names in systemdict, so any name that that
92 | * conflicts with one usually in systemdict will be replaced by the normal definition during the interpreter
93 | * initialization.
94 | *
95 | * -Sname=string
96 | * -sname=string
97 | * Define a name in systemdict with a given string as value. This is different from -d. For example, -dXYZ=35
98 | * on
99 | * the command line is equivalent to the program fragment
100 | *
101 | * /XYZ 35 def
102 | *
103 | * whereas -sXYZ=35 is equivalent to
104 | *
105 | * /XYZ (35) def
106 | *
107 | * -uname
108 | * Un-define a name, cancelling -d or -s.
109 | *
110 | * Note that the initialization file gs_init.ps makes systemdict read-only, so the values of names defined with -D,
111 | * -d, -S, and -s cannot be changed -- although, of course, they can be superseded by definitions in userdict or
112 | * other dictionaries. However, device parameters set this way (PageSize, Margins, etc.) are not read-only, and can
113 | * be changed by code in PostScript files.
114 | *
115 | * -gnumber1xnumber2
116 | * Equivalent to -dDEVICEWIDTH=number1 and -dDEVICEHEIGHT=number2, specifying the device width and height in
117 | * pixels for the benefit of devices such as X11 windows and VESA displays that require (or allow) you to
118 | * specify width and height. Note that this causes documents of other sizes to be clipped, not scaled: see
119 | * -dFIXEDMEDIA below.
120 | *
121 | * -rnumber (same as -rnumberxnumber)
122 | * -rnumber1xnumber2
123 | * Equivalent to -dDEVICEXRESOLUTION=number1 and -dDEVICEYRESOLUTION=number2, specifying the device horizontal
124 | * and vertical resolution in pixels per inch for the benefit of devices such as printers that support multiple
125 | * X and Y resolutions.
126 | */
127 | }
128 |
--------------------------------------------------------------------------------
/src/Device/DistillerParameters/FontTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Enum\CannotEmbedFontPolicy;
11 | use GravityMedia\Ghostscript\Enum\PdfSettings;
12 |
13 | /**
14 | * The font distiller parameters trait.
15 | *
16 | * @package GravityMedia\Ghostscript\Device\DistillerParameters
17 | *
18 | * @link http://ghostscript.com/doc/current/Ps2pdf.htm
19 | */
20 | trait FontTrait
21 | {
22 | /**
23 | * Get argument value
24 | *
25 | * @param string $name
26 | *
27 | * @return null|string
28 | */
29 | abstract protected function getArgumentValue($name);
30 |
31 | /**
32 | * Set argument
33 | *
34 | * @param string $argument
35 | *
36 | * @return $this
37 | */
38 | abstract protected function setArgument($argument);
39 |
40 | /**
41 | * Get PDF settings
42 | *
43 | * @return string
44 | */
45 | abstract public function getPdfSettings();
46 |
47 | /**
48 | * Get cannot embed font policy
49 | *
50 | * @return string
51 | */
52 | public function getCannotEmbedFontPolicy()
53 | {
54 | $value = $this->getArgumentValue('-dCannotEmbedFontPolicy');
55 | if (null === $value) {
56 | switch ($this->getPdfSettings()) {
57 | case PdfSettings::PREPRESS:
58 | return CannotEmbedFontPolicy::ERROR;
59 | default:
60 | return CannotEmbedFontPolicy::WARNING;
61 | }
62 | }
63 |
64 | return ltrim($value, '/');
65 | }
66 |
67 | /**
68 | * Set cannot embed font policy
69 | *
70 | * @param string $cannotEmbedFontPolicy
71 | *
72 | * @param \InvalidArgumentException
73 | *
74 | * @return $this
75 | */
76 | public function setCannotEmbedFontPolicy($cannotEmbedFontPolicy)
77 | {
78 | $cannotEmbedFontPolicy = ltrim($cannotEmbedFontPolicy, '/');
79 | if (!in_array($cannotEmbedFontPolicy, CannotEmbedFontPolicy::values())) {
80 | throw new \InvalidArgumentException('Invalid cannot embed font policy argument');
81 | }
82 |
83 | $this->setArgument(sprintf('-dCannotEmbedFontPolicy=/%s', $cannotEmbedFontPolicy));
84 |
85 | return $this;
86 | }
87 |
88 | /**
89 | * Whether to embed all fonts
90 | *
91 | * @return bool
92 | */
93 | public function isEmbedAllFonts()
94 | {
95 | $value = $this->getArgumentValue('-dEmbedAllFonts');
96 | if (null === $value) {
97 | switch ($this->getPdfSettings()) {
98 | case PdfSettings::SCREEN:
99 | return false;
100 | default:
101 | return true;
102 | }
103 | }
104 |
105 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
106 | }
107 |
108 | /**
109 | * Set embed all fonts flag
110 | *
111 | * @param string $embedAllFonts
112 | *
113 | * @return $this
114 | */
115 | public function setEmbedAllFonts($embedAllFonts)
116 | {
117 | $this->setArgument(sprintf('-dEmbedAllFonts=%s', $embedAllFonts ? 'true' : 'false'));
118 |
119 | return $this;
120 | }
121 |
122 | /**
123 | * Get max subset pct
124 | *
125 | * @return int
126 | */
127 | public function getMaxSubsetPct()
128 | {
129 | $value = $this->getArgumentValue('-dMaxSubsetPct');
130 | if (null === $value) {
131 | return 100;
132 | }
133 |
134 | return intval($value);
135 | }
136 |
137 | /**
138 | * Set max subset pct
139 | *
140 | * @param int $maxSubsetPct
141 | *
142 | * @return $this
143 | */
144 | public function setMaxSubsetPct($maxSubsetPct)
145 | {
146 | $this->setArgument(sprintf('-dMaxSubsetPct=%s', $maxSubsetPct));
147 |
148 | return $this;
149 | }
150 |
151 | /**
152 | * Whether to subset fonts
153 | *
154 | * @return bool
155 | */
156 | public function isSubsetFonts()
157 | {
158 | $value = $this->getArgumentValue('-dSubsetFonts');
159 | if (null === $value) {
160 | return true;
161 | }
162 |
163 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
164 | }
165 |
166 | /**
167 | * Set subset fonts flag
168 | *
169 | * @param bool $subsetFonts
170 | *
171 | * @return $this
172 | */
173 | public function setSubsetFonts($subsetFonts)
174 | {
175 | $this->setArgument(sprintf('-dSubsetFonts=%s', $subsetFonts ? 'true' : 'false'));
176 |
177 | return $this;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/src/Device/DistillerParameters/MonoImageCompressionTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Enum\ImageDownsampleType;
11 | use GravityMedia\Ghostscript\Enum\MonoImageFilter;
12 | use GravityMedia\Ghostscript\Enum\PdfSettings;
13 |
14 | /**
15 | * The monochrome image compression distiller parameters trait.
16 | *
17 | * @package GravityMedia\Ghostscript\Device\DistillerParameters
18 | *
19 | * @link http://ghostscript.com/doc/current/Ps2pdf.htm
20 | */
21 | trait MonoImageCompressionTrait
22 | {
23 | /**
24 | * Get argument value
25 | *
26 | * @param string $name
27 | *
28 | * @return null|string
29 | */
30 | abstract protected function getArgumentValue($name);
31 |
32 | /**
33 | * Set argument
34 | *
35 | * @param string $argument
36 | *
37 | * @return $this
38 | */
39 | abstract protected function setArgument($argument);
40 |
41 | /**
42 | * Get PDF settings
43 | *
44 | * @return string
45 | */
46 | abstract public function getPdfSettings();
47 |
48 | /**
49 | * Whether to anti alias monochrome images
50 | *
51 | * @return bool
52 | */
53 | public function isAntiAliasMonoImages()
54 | {
55 | $value = $this->getArgumentValue('-dAntiAliasMonoImages');
56 | if (null === $value) {
57 | return false;
58 | }
59 |
60 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
61 | }
62 |
63 | /**
64 | * Set anti alias monochrome images flag
65 | *
66 | * @param bool $antiAliasMonoImages
67 | *
68 | * @return $this
69 | */
70 | public function setAntiAliasMonoImages($antiAliasMonoImages)
71 | {
72 | $this->setArgument(sprintf('-dAntiAliasMonoImages=%s', $antiAliasMonoImages ? 'true' : 'false'));
73 |
74 | return $this;
75 | }
76 |
77 | /**
78 | * Whether to downsample monochrome images
79 | *
80 | * @return bool
81 | */
82 | public function isDownsampleMonoImages()
83 | {
84 | $value = $this->getArgumentValue('-dDownsampleMonoImages');
85 | if (null === $value) {
86 | switch ($this->getPdfSettings()) {
87 | case PdfSettings::SCREEN:
88 | case PdfSettings::EBOOK:
89 | return true;
90 | default:
91 | return false;
92 | }
93 | }
94 |
95 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
96 | }
97 |
98 | /**
99 | * Set downsample monochrome images flag
100 | *
101 | * @param bool $downsampleMonoImages
102 | *
103 | * @return $this
104 | */
105 | public function setDownsampleMonoImages($downsampleMonoImages)
106 | {
107 | $this->setArgument(sprintf('-dDownsampleMonoImages=%s', $downsampleMonoImages ? 'true' : 'false'));
108 |
109 | return $this;
110 | }
111 |
112 | /**
113 | * Whether to encode monochrome images
114 | *
115 | * @return bool
116 | */
117 | public function isEncodeMonoImages()
118 | {
119 | $value = $this->getArgumentValue('-dEncodeMonoImages');
120 | if (null === $value) {
121 | return true;
122 | }
123 |
124 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
125 | }
126 |
127 | /**
128 | * Set encode monochrome images flag
129 | *
130 | * @param bool $encodeMonoImages
131 | *
132 | * @return $this
133 | */
134 | public function setEncodeMonoImages($encodeMonoImages)
135 | {
136 | $this->setArgument(sprintf('-dEncodeMonoImages=%s', $encodeMonoImages ? 'true' : 'false'));
137 |
138 | return $this;
139 | }
140 |
141 | /**
142 | * Get monochrome image depth
143 | *
144 | * @return int
145 | */
146 | public function getMonoImageDepth()
147 | {
148 | $value = $this->getArgumentValue('-dMonoImageDepth');
149 | if (null === $value) {
150 | return -1;
151 | }
152 |
153 | return intval($value);
154 | }
155 |
156 | /**
157 | * Set monochrome image depth
158 | *
159 | * @param int $monoImageDepth
160 | *
161 | * @return $this
162 | */
163 | public function setMonoImageDepth($monoImageDepth)
164 | {
165 | $this->setArgument(sprintf('-dMonoImageDepth=%s', $monoImageDepth));
166 |
167 | return $this;
168 | }
169 |
170 | /**
171 | * Get monochrome image downsample threshold
172 | *
173 | * @return float
174 | */
175 | public function getMonoImageDownsampleThreshold()
176 | {
177 | $value = $this->getArgumentValue('-dMonoImageDownsampleThreshold');
178 | if (null === $value) {
179 | return 1.5;
180 | }
181 |
182 | return floatval($value);
183 | }
184 |
185 | /**
186 | * Set monochrome image downsample threshold
187 | *
188 | * @param float $monoImageDownsampleThreshold
189 | *
190 | * @return $this
191 | */
192 | public function setMonoImageDownsampleThreshold($monoImageDownsampleThreshold)
193 | {
194 | $this->setArgument(sprintf('-dMonoImageDownsampleThreshold=%s', $monoImageDownsampleThreshold));
195 |
196 | return $this;
197 | }
198 |
199 | /**
200 | * Get monochrome image downsample type
201 | *
202 | * @return string
203 | */
204 | public function getMonoImageDownsampleType()
205 | {
206 | $value = $this->getArgumentValue('-dMonoImageDownsampleType');
207 | if (null === $value) {
208 | switch ($this->getPdfSettings()) {
209 | case PdfSettings::PREPRESS:
210 | return ImageDownsampleType::BICUBIC;
211 | default:
212 | return ImageDownsampleType::SUBSAMPLE;
213 | }
214 | }
215 |
216 | return ltrim($value, '/');
217 | }
218 |
219 | /**
220 | * Set monochrome image downsample type
221 | *
222 | * @param string $monoImageDownsampleType
223 | *
224 | * @throws \InvalidArgumentException
225 | *
226 | * @return $this
227 | */
228 | public function setMonoImageDownsampleType($monoImageDownsampleType)
229 | {
230 | $monoImageDownsampleType = ltrim($monoImageDownsampleType, '/');
231 | if (!in_array($monoImageDownsampleType, ImageDownsampleType::values())) {
232 | throw new \InvalidArgumentException('Invalid monochrome image downsample type argument');
233 | }
234 |
235 | $this->setArgument(sprintf('-dMonoImageDownsampleType=/%s', $monoImageDownsampleType));
236 |
237 | return $this;
238 | }
239 |
240 | /**
241 | * Get monochrome image filter
242 | *
243 | * @return string
244 | */
245 | public function getMonoImageFilter()
246 | {
247 | $value = $this->getArgumentValue('-dMonoImageFilter');
248 | if (null === $value) {
249 | return MonoImageFilter::CCITT_FAX_ENCODE;
250 | }
251 |
252 | return ltrim($value, '/');
253 | }
254 |
255 | /**
256 | * Set monochrome image filter
257 | *
258 | * @param string $monoImageFilter
259 | *
260 | * @throws \InvalidArgumentException
261 | *
262 | * @return $this
263 | */
264 | public function setMonoImageFilter($monoImageFilter)
265 | {
266 | $monoImageFilter = ltrim($monoImageFilter, '/');
267 | if (!in_array($monoImageFilter, MonoImageFilter::values())) {
268 | throw new \InvalidArgumentException('Invalid monochrome image filter argument');
269 | }
270 |
271 | $this->setArgument(sprintf('-dMonoImageFilter=/%s', $monoImageFilter));
272 |
273 | return $this;
274 | }
275 |
276 | /**
277 | * Get monochrome image resolution
278 | *
279 | * @return int
280 | */
281 | public function getMonoImageResolution()
282 | {
283 | $value = $this->getArgumentValue('-dMonoImageResolution');
284 | if (null === $value) {
285 | switch ($this->getPdfSettings()) {
286 | case PdfSettings::PRINTER:
287 | case PdfSettings::PREPRESS:
288 | return 1200;
289 | default:
290 | return 300;
291 | }
292 | }
293 |
294 | return intval($value);
295 | }
296 |
297 | /**
298 | * Set monochrome image resolution
299 | *
300 | * @param int $monoImageResolution
301 | *
302 | * @return $this
303 | */
304 | public function setMonoImageResolution($monoImageResolution)
305 | {
306 | $this->setArgument(sprintf('-dMonoImageResolution=%s', $monoImageResolution));
307 |
308 | return $this;
309 | }
310 | }
311 |
--------------------------------------------------------------------------------
/src/Device/DistillerParameters/PageCompressionTrait.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device\DistillerParameters;
9 |
10 | /**
11 | * The page compression distiller parameters trait.
12 | *
13 | * @package GravityMedia\Ghostscript\Device\DistillerParameters
14 | *
15 | * @link http://ghostscript.com/doc/current/Ps2pdf.htm
16 | */
17 | trait PageCompressionTrait
18 | {
19 | /**
20 | * Get argument value
21 | *
22 | * @param string $name
23 | *
24 | * @return null|string
25 | */
26 | abstract protected function getArgumentValue($name);
27 |
28 | /**
29 | * Set argument
30 | *
31 | * @param string $argument
32 | *
33 | * @return $this
34 | */
35 | abstract protected function setArgument($argument);
36 |
37 | /**
38 | * Whether to compress pages
39 | *
40 | * @return bool
41 | */
42 | public function isCompressPages()
43 | {
44 | $value = $this->getArgumentValue('-dCompressPages');
45 | if (null === $value) {
46 | return true;
47 | }
48 |
49 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
50 | }
51 |
52 | /**
53 | * Set compress pages flag
54 | *
55 | * @param true $compressPages
56 | *
57 | * @return $this
58 | */
59 | public function setCompressPages($compressPages)
60 | {
61 | $this->setArgument(sprintf('-dCompressPages=%s', $compressPages ? 'true' : 'false'));
62 |
63 | return $this;
64 | }
65 |
66 | /**
67 | * Whether to LZW encode pages
68 | *
69 | * @return bool
70 | */
71 | public function isLzwEncodePages()
72 | {
73 | $value = $this->getArgumentValue('-dLZWEncodePages');
74 | if (null === $value) {
75 | return false;
76 | }
77 |
78 | return filter_var($value, FILTER_VALIDATE_BOOLEAN);
79 | }
80 |
81 | /**
82 | * Set LZW encode pages flag
83 | *
84 | * @param string $lzwEncodePages
85 | *
86 | * @return $this
87 | */
88 | public function setLzwEncodePages($lzwEncodePages)
89 | {
90 | $this->setArgument(sprintf('-dLZWEncodePages=%s', $lzwEncodePages ? 'true' : 'false'));
91 |
92 | return $this;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Device/Inkcov.php:
--------------------------------------------------------------------------------
1 | setArgument('-sDEVICE=inkcov'));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Device/NoDisplay.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | use GravityMedia\Ghostscript\Ghostscript;
11 | use GravityMedia\Ghostscript\GhostscriptInterface;
12 | use GravityMedia\Ghostscript\Process\Arguments;
13 |
14 | /**
15 | * The no display device class.
16 | *
17 | * @package GravityMedia\Ghostscript\Devices
18 | */
19 | class NoDisplay extends AbstractDevice
20 | {
21 | /**
22 | * Create no display device object.
23 | *
24 | * @param Ghostscript $ghostscript
25 | * @param Arguments $arguments
26 | */
27 | public function __construct(GhostscriptInterface $ghostscript, Arguments $arguments)
28 | {
29 | parent::__construct($ghostscript, $arguments->setArgument('-dNODISPLAY'));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Device/PdfInfo.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | use GravityMedia\Ghostscript\Ghostscript;
11 | use GravityMedia\Ghostscript\GhostscriptInterface;
12 | use GravityMedia\Ghostscript\Process\Arguments;
13 |
14 | /**
15 | * The PDF info device class.
16 | *
17 | * This class supports the pdf_info.ps script that is contained in Ghostscript toolbin.
18 | *
19 | * @link http://svn.ghostscript.com/ghostscript/trunk/gs/toolbin/
20 | *
21 | * @package GravityMedia\Ghostscript\Devices
22 | */
23 | class PdfInfo extends NoDisplay
24 | {
25 | /**
26 | * The PDF info path.
27 | */
28 | private string $pdfInfoPath;
29 |
30 | /**
31 | * Create PDF info device object.
32 | *
33 | * @param Ghostscript $ghostscript
34 | * @param Arguments $arguments
35 | * @param string $pdfInfoPath Path to toolbin/pdf_info.ps
36 | */
37 | public function __construct(GhostscriptInterface $ghostscript, Arguments $arguments, $pdfInfoPath)
38 | {
39 | parent::__construct($ghostscript, $arguments);
40 |
41 | $this->pdfInfoPath = $pdfInfoPath;
42 | }
43 |
44 | /**
45 | * Create process object.
46 | *
47 | * @param string $input Path to PDF file to be examined
48 | *
49 | * @throws \RuntimeException
50 | *
51 | * @return \Symfony\Component\Process\Process
52 | */
53 | public function createProcess($input = null)
54 | {
55 | if (!is_string($input) || !file_exists($input)) {
56 | throw new \RuntimeException('Input file does not exist');
57 | }
58 |
59 | $this->setArgument(sprintf('-sFile=%s', $input));
60 |
61 | return parent::createProcess($this->pdfInfoPath);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Device/PdfWrite.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Device;
9 |
10 | use GravityMedia\Ghostscript\Enum\PdfSettings;
11 | use GravityMedia\Ghostscript\Enum\ProcessColorModel;
12 | use GravityMedia\Ghostscript\Ghostscript;
13 | use GravityMedia\Ghostscript\GhostscriptInterface;
14 | use GravityMedia\Ghostscript\Input;
15 | use GravityMedia\Ghostscript\Process\Arguments;
16 |
17 | /**
18 | * The PDF write device class.
19 | *
20 | * @package GravityMedia\Ghostscript\Devices
21 | */
22 | class PdfWrite extends AbstractDevice
23 | {
24 | /**
25 | * Use distiller parameters.
26 | */
27 | use DistillerParametersTrait;
28 |
29 | /**
30 | * Use color image compression distiller parameters.
31 | */
32 | use DistillerParameters\ColorImageCompressionTrait;
33 |
34 | /**
35 | * Use grayscale image compression distiller parameters.
36 | */
37 | use DistillerParameters\GrayImageCompressionTrait;
38 |
39 | /**
40 | * Use monochrome image compression distiller parameters.
41 | */
42 | use DistillerParameters\MonoImageCompressionTrait;
43 |
44 | /**
45 | * Use page compression distiller parameters.
46 | */
47 | use DistillerParameters\PageCompressionTrait;
48 |
49 | /**
50 | * Use font distiller parameters.
51 | */
52 | use DistillerParameters\FontTrait;
53 |
54 | /**
55 | * Use color conversion distiller parameters.
56 | */
57 | use DistillerParameters\ColorConversionTrait;
58 |
59 | /**
60 | * Use advanced distiller parameters.
61 | */
62 | use DistillerParameters\AdvancedTrait;
63 |
64 | /**
65 | * Create PDF write device object.
66 | *
67 | * @param Ghostscript $ghostscript
68 | * @param Arguments $arguments
69 | */
70 | public function __construct(GhostscriptInterface $ghostscript, Arguments $arguments)
71 | {
72 | parent::__construct($ghostscript, $arguments->setArgument('-sDEVICE=pdfwrite'));
73 |
74 | $this->setPdfSettings(PdfSettings::__DEFAULT);
75 | }
76 |
77 | /**
78 | * Get output file.
79 | *
80 | * @return null|string
81 | */
82 | public function getOutputFile()
83 | {
84 | return $this->getArgumentValue('-sOutputFile');
85 | }
86 |
87 | /**
88 | * Set output file.
89 | *
90 | * @param string $outputFile
91 | *
92 | * @return $this
93 | */
94 | public function setOutputFile($outputFile)
95 | {
96 | $this->setArgument('-sOutputFile=' . $outputFile);
97 |
98 | return $this;
99 | }
100 |
101 | /**
102 | * Get PDF settings.
103 | *
104 | * @return string
105 | */
106 | public function getPdfSettings()
107 | {
108 | return ltrim($this->getArgumentValue('-dPDFSETTINGS'), '/');
109 | }
110 |
111 | /**
112 | * Set PDF settings.
113 | *
114 | * @param string $pdfSettings
115 | *
116 | * @throws \InvalidArgumentException
117 | *
118 | * @return $this
119 | */
120 | public function setPdfSettings($pdfSettings)
121 | {
122 | $pdfSettings = ltrim($pdfSettings, '/');
123 | if (!in_array($pdfSettings, PdfSettings::values())) {
124 | throw new \InvalidArgumentException('Invalid PDF settings argument');
125 | }
126 |
127 | $this->setArgument(sprintf('-dPDFSETTINGS=/%s', $pdfSettings));
128 |
129 | return $this;
130 | }
131 |
132 | /**
133 | * Get process color model.
134 | *
135 | * @return string
136 | */
137 | public function getProcessColorModel()
138 | {
139 | return ltrim($this->getArgumentValue('-dProcessColorModel'), '/');
140 | }
141 |
142 | /**
143 | * Set process color model.
144 | *
145 | * @param string $processColorModel
146 | *
147 | * @throws \InvalidArgumentException
148 | *
149 | * @return $this
150 | */
151 | public function setProcessColorModel($processColorModel)
152 | {
153 | $processColorModel = ltrim($processColorModel, '/');
154 | if (!in_array($processColorModel, ProcessColorModel::values())) {
155 | throw new \InvalidArgumentException('Invalid process color model argument');
156 | }
157 |
158 | $this->setArgument(sprintf('-dProcessColorModel=/%s', $processColorModel));
159 |
160 | return $this;
161 | }
162 |
163 | /**
164 | * {@inheritdoc}
165 | */
166 | protected function createProcessArguments(Input $input)
167 | {
168 | $code = $input->getPostScriptCode();
169 | if (null === $code) {
170 | $code = '';
171 | }
172 |
173 | /**
174 | * Make sure .setpdfwrite gets called when using Ghostscript version less than 9.50:
175 | * This operator conditions the environment for the pdfwrite output device. It is a shorthand for setting parameters
176 | * that have been deemed benificial. While not strictly necessary, it is usually helpful to set call this when using
177 | * the pdfwrite device.
178 | * @link https://ghostscript.com/doc/current/Language.htm#.setpdfwrite
179 | */
180 | if (version_compare($this->ghostscript->getVersion(), '9.50', '<') && false === strstr($code, '.setpdfwrite')) {
181 | $input->setPostScriptCode(ltrim($code . ' .setpdfwrite', ' '));
182 | }
183 |
184 | return parent::createProcessArguments($input);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/src/Enum/AutoRotatePages.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The auto rotate pages enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class AutoRotatePages
16 | {
17 | /**
18 | * Do not auto rotate pages
19 | */
20 | const NONE = 'None';
21 |
22 | /**
23 | * Auto rotate all pages
24 | */
25 | const ALL = 'All';
26 |
27 | /**
28 | * Auto rotate page by page
29 | */
30 | const PAGE_BY_PAGE = 'PageByPage';
31 |
32 | /**
33 | * Available auto rotate pages values
34 | *
35 | * @var string[] $values
36 | */
37 | private static $values = [
38 | self::NONE,
39 | self::ALL,
40 | self::PAGE_BY_PAGE
41 | ];
42 |
43 | /**
44 | * Get available auto rotate pages values
45 | *
46 | * @return string[]
47 | */
48 | public static function values()
49 | {
50 | return self::$values;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Enum/Binding.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The binding enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class Binding
16 | {
17 | /**
18 | * Left binding
19 | */
20 | const LEFT = 'Left';
21 |
22 | /**
23 | * Right binding
24 | */
25 | const RIGHT = 'Right';
26 |
27 | /**
28 | * Available binding values
29 | *
30 | * @var string[] $values
31 | */
32 | private static $values = [
33 | self::LEFT,
34 | self::RIGHT
35 | ];
36 |
37 | /**
38 | * Get available binding values
39 | *
40 | * @return string[]
41 | */
42 | public static function values()
43 | {
44 | return self::$values;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Enum/CannotEmbedFontPolicy.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The cannot embed font policy enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class CannotEmbedFontPolicy
16 | {
17 | /**
18 | * Ignore non embeddable fonts and continue
19 | */
20 | const OK = 'OK';
21 |
22 | /**
23 | * Display a warning for non embeddable fonts
24 | */
25 | const WARNING = 'Warning';
26 |
27 | /**
28 | * Quit current job for non embeddable fonts
29 | */
30 | const ERROR = 'Error';
31 |
32 | /**
33 | * Available cannot embed font policy values
34 | *
35 | * @var string[]
36 | */
37 | private static $values = [
38 | self::OK,
39 | self::WARNING,
40 | self::ERROR
41 | ];
42 |
43 | /**
44 | * Get available cannot embed font policy values
45 | *
46 | * @return string[]
47 | */
48 | public static function values()
49 | {
50 | return self::$values;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Enum/ColorAndGrayImageFilter.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The color and grayscale image filter enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class ColorAndGrayImageFilter
16 | {
17 | /**
18 | * Select JPEG compression
19 | */
20 | const DCT_ENCODE = 'DCTEncode';
21 |
22 | /**
23 | * Select Flate (ZIP) compression
24 | */
25 | const FLATE_ENCODE = 'FlateEncode';
26 |
27 | /**
28 | * Available color and grayscale image filter values
29 | *
30 | * @var string[]
31 | */
32 | private static $values = [
33 | self::DCT_ENCODE,
34 | self::FLATE_ENCODE
35 | ];
36 |
37 | /**
38 | * Get available color and grayscale image filter values
39 | *
40 | * @return string[]
41 | */
42 | public static function values()
43 | {
44 | return self::$values;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Enum/ColorConversionStrategy.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The color conversion strategy enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class ColorConversionStrategy
16 | {
17 | /**
18 | * Leave color unchanged
19 | */
20 | const LEAVE_COLOR_UNCHANGED = 'LeaveColorUnchanged';
21 |
22 | /**
23 | * Tag everything for color management
24 | */
25 | const USE_DEVICE_INDEPENDENT_COLOR = 'UseDeviceIndependentColor';
26 |
27 | /**
28 | * Convert all colors to gray
29 | */
30 | const GRAY = 'Gray';
31 |
32 | /**
33 | * Convert all colors to sRGB
34 | */
35 | const SRGB = 'sRGB';
36 |
37 | /**
38 | * Convert all colors to CMYK
39 | */
40 | const CMYK = 'CMYK';
41 |
42 | /**
43 | * Available color conversion strategy values
44 | *
45 | * @var string[]
46 | */
47 | private static $values = [
48 | self::LEAVE_COLOR_UNCHANGED,
49 | self::USE_DEVICE_INDEPENDENT_COLOR,
50 | self::GRAY,
51 | self::SRGB,
52 | self::CMYK
53 | ];
54 |
55 | /**
56 | * Get available color conversion strategy values
57 | *
58 | * @return string[]
59 | */
60 | public static function values()
61 | {
62 | return self::$values;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Enum/DefaultRenderingIntent.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The default rendering intent enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class DefaultRenderingIntent
16 | {
17 | /**
18 | * Write no rendering intent to the PDF
19 | */
20 | const __DEFAULT = 'Default';
21 |
22 | /**
23 | * Perceptual rendering intent
24 | */
25 | const PERCEPTUAL = 'Perceptual';
26 |
27 | /**
28 | * Saturation rendering intent
29 | */
30 | const SATURATION = 'Saturation';
31 |
32 | /**
33 | * Relative colorimetric rendering intent
34 | */
35 | const RELATIVE_COLORIMETRIC = 'RelativeColorimetric';
36 |
37 | /**
38 | * Absolute colorimetric rendering intent
39 | */
40 | const ABSOLUTE_COLORIMETRIC = 'AbsoluteColorimetric';
41 |
42 | /**
43 | * Available default rendering intent values
44 | *
45 | * @var string[]
46 | */
47 | private static $values = [
48 | self::__DEFAULT,
49 | self::PERCEPTUAL,
50 | self::SATURATION,
51 | self::RELATIVE_COLORIMETRIC,
52 | self::ABSOLUTE_COLORIMETRIC
53 | ];
54 |
55 | /**
56 | * Get available default rendering intent values
57 | *
58 | * @return string[]
59 | */
60 | public static function values()
61 | {
62 | return self::$values;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Enum/ImageDownsampleType.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The image downsample type enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class ImageDownsampleType
16 | {
17 | /**
18 | * Average groups of samples to get the downsampled value
19 | */
20 | const AVERAGE = 'Average';
21 |
22 | /**
23 | * Use bicubic interpolation on a group of samples to get the downsampled value
24 | */
25 | const BICUBIC = 'Bicubic';
26 |
27 | /**
28 | * Pick the center sample from a group of samples to get the downsampled value
29 | */
30 | const SUBSAMPLE = 'Subsample';
31 |
32 | /**
33 | * Do not downsample images
34 | */
35 | const NONE = 'None';
36 |
37 | /**
38 | * Available image downsample type values
39 | *
40 | * @var string[]
41 | */
42 | private static $values = [
43 | self::AVERAGE,
44 | self::BICUBIC,
45 | self::SUBSAMPLE,
46 | self::NONE,
47 | ];
48 |
49 | /**
50 | * Get available image downsample type values
51 | *
52 | * @return string[]
53 | */
54 | public static function values()
55 | {
56 | return self::$values;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Enum/MonoImageFilter.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The monochrome image filter enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class MonoImageFilter
16 | {
17 | /**
18 | * Select CCITT Group 3 or 4 facsimile encoding
19 | */
20 | const CCITT_FAX_ENCODE = 'CCITTFaxEncode';
21 |
22 | /**
23 | * Select Flate (ZIP) compression
24 | */
25 | const FLATE_ENCODE = 'FlateEncode';
26 |
27 | /**
28 | * Select run length encoding
29 | */
30 | const RUN_LENGTH_ENCODE = 'RunLengthEncode';
31 |
32 | /**
33 | * Available monochrome image filter values
34 | *
35 | * @var string[]
36 | */
37 | private static $values = [
38 | self::CCITT_FAX_ENCODE,
39 | self::FLATE_ENCODE,
40 | self::RUN_LENGTH_ENCODE
41 | ];
42 |
43 | /**
44 | * Get available monochrome image filter values
45 | *
46 | * @return string[]
47 | */
48 | public static function values()
49 | {
50 | return self::$values;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Enum/PdfSettings.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The PDF settings enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class PdfSettings
16 | {
17 | /**
18 | * Output intended to be useful across a wide variety of uses, possibly at the expense of a larger output file
19 | */
20 | const __DEFAULT = 'default';
21 |
22 | /**
23 | * Low-resolution output similar to the Acrobat Distiller "Screen Optimized" setting
24 | */
25 | const SCREEN = 'screen';
26 |
27 | /**
28 | * Medium-resolution output similar to the Acrobat Distiller "eBook" setting
29 | */
30 | const EBOOK = 'ebook';
31 |
32 | /**
33 | * Output similar to the Acrobat Distiller "Print Optimized" setting
34 | */
35 | const PRINTER = 'printer';
36 |
37 | /**
38 | * Output similar to Acrobat Distiller "Prepress Optimized" setting
39 | */
40 | const PREPRESS = 'prepress';
41 |
42 | /**
43 | * Available PDF settings values
44 | *
45 | * @var string[] $values
46 | */
47 | private static $values = [
48 | self::__DEFAULT,
49 | self::SCREEN,
50 | self::EBOOK,
51 | self::PRINTER,
52 | self::PREPRESS
53 | ];
54 |
55 | /**
56 | * Get available PDF settings values
57 | *
58 | * @return string[]
59 | */
60 | public static function values()
61 | {
62 | return self::$values;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Enum/ProcessColorModel.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The process color model enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class ProcessColorModel
16 | {
17 | const DEVICE_RGB = 'DeviceRGB';
18 | const DEVICE_CMYK = 'DeviceCMYK';
19 | const DEVICE_GRAY = 'DeviceGray';
20 |
21 |
22 | /**
23 | * Available process color model values
24 | *
25 | * @var string[] $values
26 | */
27 | private static $values = [
28 | self::DEVICE_RGB,
29 | self::DEVICE_CMYK,
30 | self::DEVICE_GRAY
31 | ];
32 |
33 | /**
34 | * Get available process color model values
35 | *
36 | * @return string[]
37 | */
38 | public static function values()
39 | {
40 | return self::$values;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Enum/TransferFunctionInfo.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The transfer function info enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class TransferFunctionInfo
16 | {
17 | /**
18 | * Preserve transfer functions (pass into the PDF file)
19 | */
20 | const PRESERVE = 'Preserve';
21 |
22 | /**
23 | * Ignore transfer functions (do not pass into the PDF file)
24 | */
25 | const REMOVE = 'Remove';
26 |
27 | /**
28 | * Apply transfer functions to color values
29 | */
30 | const APPLY = 'Apply';
31 |
32 | /**
33 | * Available transfer function info values
34 | *
35 | * @var string[]
36 | */
37 | private static $values = [
38 | self::PRESERVE,
39 | self::REMOVE,
40 | self::APPLY
41 | ];
42 |
43 | /**
44 | * Get available transfer function info values
45 | *
46 | * @return string[]
47 | */
48 | public static function values()
49 | {
50 | return self::$values;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Enum/UcrAndBgInfo.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Enum;
9 |
10 | /**
11 | * The UCR and BG info enum
12 | *
13 | * @package GravityMedia\Ghostscript\Enum
14 | */
15 | class UcrAndBgInfo
16 | {
17 | /**
18 | * Preserve under color removal and black generation arguments
19 | */
20 | const PRESERVE = 'Preserve';
21 |
22 | /**
23 | * Ignore under color removal and black generation arguments
24 | */
25 | const REMOVE = 'Remove';
26 |
27 | /**
28 | * Available UCR and BG info values
29 | *
30 | * @var string[]
31 | */
32 | private static $values = [
33 | self::PRESERVE,
34 | self::REMOVE
35 | ];
36 |
37 | /**
38 | * Get available UCR and BG info values
39 | *
40 | * @return string[]
41 | */
42 | public static function values()
43 | {
44 | return self::$values;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Ghostscript.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript;
9 |
10 | use GravityMedia\Ghostscript\Device\BoundingBoxInfo;
11 | use GravityMedia\Ghostscript\Device\Inkcov;
12 | use GravityMedia\Ghostscript\Device\NoDisplay;
13 | use GravityMedia\Ghostscript\Device\PdfInfo;
14 | use GravityMedia\Ghostscript\Device\PdfWrite;
15 | use GravityMedia\Ghostscript\Process\Arguments;
16 | use Symfony\Component\Process\Process;
17 |
18 | /**
19 | * The Ghostscript class.
20 | *
21 | * @package GravityMedia\Ghostscript
22 | */
23 | class Ghostscript implements GhostscriptInterface
24 | {
25 | /**
26 | * The default binary.
27 | */
28 | const DEFAULT_BINARY = 'gs';
29 |
30 | /**
31 | * The versions.
32 | *
33 | * @var string[]
34 | */
35 | protected static $versions = [];
36 |
37 | /**
38 | * The options.
39 | *
40 | * @var array
41 | */
42 | protected $options = [];
43 |
44 |
45 | /**
46 | * Create Ghostscript object.
47 | *
48 | * @param array $options
49 | *
50 | * @throws \RuntimeException
51 | */
52 | public function __construct(array $options = [])
53 | {
54 | $this->options = $options;
55 | }
56 |
57 | /**
58 | * Get option.
59 | *
60 | * @param string $name
61 | * @param mixed $default
62 | *
63 | * @return mixed
64 | */
65 | public function getOption($name, $default = null)
66 | {
67 | if (array_key_exists($name, $this->options)) {
68 | return $this->options[$name];
69 | }
70 |
71 | return $default;
72 | }
73 |
74 | /**
75 | * Get process to identify version.
76 | *
77 | * @param string $binary
78 | *
79 | * @return Process
80 | */
81 | protected function createProcessToIdentifyVersion($binary)
82 | {
83 | return new Process([$binary, '--version']);
84 | }
85 |
86 | /**
87 | * Get version.
88 | *
89 | * @throws \RuntimeException
90 | *
91 | * @return string
92 | */
93 | public function getVersion()
94 | {
95 | $binary = $this->getOption('bin', static::DEFAULT_BINARY);
96 |
97 | if (!isset(static::$versions[$binary])) {
98 | $process = $this->createProcessToIdentifyVersion($binary);
99 | $process->run();
100 |
101 | if (!$process->isSuccessful()) {
102 | throw new \RuntimeException($process->getErrorOutput());
103 | }
104 |
105 | static::$versions[$binary] = $process->getOutput();
106 | }
107 |
108 | return static::$versions[$binary];
109 | }
110 |
111 | /**
112 | * Create arguments object.
113 | *
114 | * @return Arguments
115 | */
116 | protected function createArguments()
117 | {
118 | $arguments = new Arguments();
119 |
120 | if ($this->getOption('quiet', true)) {
121 | $arguments->addArgument('-q');
122 | }
123 |
124 | return $arguments;
125 | }
126 |
127 | /**
128 | * Create PDF device object.
129 | *
130 | * @param null|string $outputFile
131 | *
132 | * @return PdfWrite
133 | */
134 | public function createPdfDevice($outputFile = null)
135 | {
136 | $device = new PdfWrite($this, $this->createArguments());
137 | $device
138 | ->setSafer()
139 | ->setBatch()
140 | ->setNoPause();
141 |
142 | if (null === $outputFile) {
143 | $outputFile = '-';
144 | }
145 |
146 | $device->setOutputFile($outputFile);
147 |
148 | return $device;
149 | }
150 |
151 | /**
152 | * Create no display device object.
153 | *
154 | * @return NoDisplay
155 | */
156 | public function createNoDisplayDevice()
157 | {
158 | return new NoDisplay($this, $this->createArguments());
159 | }
160 |
161 | /**
162 | * Create PDF info device object.
163 | *
164 | * @param string $pdfInfoPath Path to toolbin/pdf_info.ps
165 | *
166 | * @return PdfInfo
167 | */
168 | public function createPdfInfoDevice($pdfInfoPath)
169 | {
170 | return new PdfInfo($this, $this->createArguments(), $pdfInfoPath);
171 | }
172 |
173 | /**
174 | * Create bounding box info device object.
175 | *
176 | * @return BoundingBoxInfo
177 | */
178 | public function createBoundingBoxInfoDevice()
179 | {
180 | $device = new BoundingBoxInfo($this, $this->createArguments());
181 | $device
182 | ->setSafer()
183 | ->setBatch()
184 | ->setNoPause();
185 |
186 | return $device;
187 | }
188 |
189 | /**
190 | * Create inkcov device object
191 | *
192 | * @return Inkcov
193 | */
194 | public function createInkcovDevice()
195 | {
196 | $this->options['quiet'] = false;
197 |
198 | $arguments = $this->createArguments();
199 | $arguments->addArgument('-o');
200 | $arguments->addArgument('-');
201 |
202 | $device = new Inkcov($this, $arguments);
203 |
204 | return $device;
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/src/GhostscriptInterface.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript;
9 |
10 | use GravityMedia\Ghostscript\Device\BoundingBoxInfo;
11 | use GravityMedia\Ghostscript\Device\Inkcov;
12 | use GravityMedia\Ghostscript\Device\NoDisplay;
13 | use GravityMedia\Ghostscript\Device\PdfInfo;
14 | use GravityMedia\Ghostscript\Device\PdfWrite;
15 |
16 | /**
17 | * @package GravityMedia\Ghostscript
18 | */
19 | interface GhostscriptInterface
20 | {
21 | /**
22 | * Get option.
23 | *
24 | * @param string $name
25 | * @param mixed $default
26 | *
27 | * @return mixed
28 | */
29 | public function getOption($name, $default = null);
30 |
31 | /**
32 | * Get version.
33 | *
34 | * @return string
35 | * @throws \RuntimeException
36 | *
37 | */
38 | public function getVersion();
39 |
40 | /**
41 | * Create PDF device object.
42 | *
43 | * @param null|string $outputFile
44 | *
45 | * @return PdfWrite
46 | */
47 | public function createPdfDevice($outputFile = null);
48 |
49 | /**
50 | * Create no display device object.
51 | *
52 | * @return NoDisplay
53 | */
54 | public function createNoDisplayDevice();
55 |
56 | /**
57 | * Create PDF info device object.
58 | *
59 | * @param string $pdfInfoPath Path to toolbin/pdf_info.ps
60 | *
61 | * @return PdfInfo
62 | */
63 | public function createPdfInfoDevice($pdfInfoPath);
64 |
65 | /**
66 | * Create bounding box info device object.
67 | *
68 | * @return BoundingBoxInfo
69 | */
70 | public function createBoundingBoxInfoDevice();
71 |
72 | /**
73 | * Create inkcov device object
74 | *
75 | * @return Inkcov
76 | */
77 | public function createInkcovDevice();
78 | }
79 |
--------------------------------------------------------------------------------
/src/Input.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript;
9 |
10 | use Symfony\Component\Process\ProcessUtils;
11 |
12 | /**
13 | * The input class.
14 | *
15 | * @package GravityMedia\Ghostscript
16 | */
17 | class Input
18 | {
19 | /**
20 | * The process input.
21 | *
22 | * @var null|string|resource
23 | */
24 | private $processInput;
25 |
26 | /**
27 | * The PostScript code.
28 | *
29 | * @var null|string
30 | */
31 | private $postScriptCode;
32 |
33 | /**
34 | * The files.
35 | *
36 | * @var null|string[]
37 | */
38 | private $files;
39 |
40 | /**
41 | * Get process input.
42 | *
43 | * @return null|string|resource
44 | */
45 | public function getProcessInput()
46 | {
47 | return $this->processInput;
48 | }
49 |
50 | /**
51 | * Set process input.
52 | *
53 | * @param mixed $processInput
54 | *
55 | * @throws \InvalidArgumentException
56 | *
57 | * @return $this
58 | */
59 | public function setProcessInput($processInput)
60 | {
61 | $this->processInput = ProcessUtils::validateInput(__METHOD__, $processInput);
62 |
63 | return $this;
64 | }
65 |
66 | /**
67 | * Get PostScript code.
68 | *
69 | * @return null|string
70 | */
71 | public function getPostScriptCode()
72 | {
73 | return $this->postScriptCode;
74 | }
75 |
76 | /**
77 | * Set PostScript code.
78 | *
79 | * @param null|string $postScriptCode
80 | *
81 | * @return $this
82 | */
83 | public function setPostScriptCode($postScriptCode)
84 | {
85 | $this->postScriptCode = $postScriptCode;
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * Get files.
92 | *
93 | * @return string[]
94 | */
95 | public function getFiles()
96 | {
97 | if (null === $this->files) {
98 | return [];
99 | }
100 |
101 | return $this->files;
102 | }
103 |
104 | /**
105 | * Add file.
106 | *
107 | * @param string $file
108 | *
109 | * @return $this
110 | */
111 | public function addFile($file)
112 | {
113 | if (null === $this->files) {
114 | $this->files = [];
115 | }
116 |
117 | $this->files[] = $file;
118 |
119 | return $this;
120 | }
121 |
122 | /**
123 | * Set files.
124 | *
125 | * @param string[] $files
126 | *
127 | * @return $this
128 | */
129 | public function setFiles(array $files)
130 | {
131 | $this->files = $files;
132 |
133 | return $this;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/Process/Argument.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Process;
9 |
10 | /**
11 | * The argument class.
12 | *
13 | * @package GravityMedia\Ghostscript\Process
14 | */
15 | class Argument
16 | {
17 | /**
18 | * The name.
19 | *
20 | * @var string
21 | */
22 | protected $name;
23 |
24 | /**
25 | * The value.
26 | *
27 | * @var mixed
28 | */
29 | protected $value;
30 |
31 | /**
32 | * Create argument object.
33 | *
34 | * @param string $name
35 | * @param mixed $value
36 | */
37 | public function __construct($name, $value = null)
38 | {
39 | $this->name = $name;
40 | $this->value = $value;
41 | }
42 |
43 | /**
44 | * Create argument object from string.
45 | *
46 | * @param string $argument
47 | *
48 | * @return $this
49 | */
50 | public static function fromString($argument)
51 | {
52 | $argument = explode('=', $argument, 2);
53 | $instance = new static(array_shift($argument));
54 |
55 | if (count($argument) > 0) {
56 | $instance->setValue(array_shift($argument));
57 | }
58 |
59 | return $instance;
60 | }
61 |
62 | /**
63 | * Return argument object as string.
64 | *
65 | * @return string
66 | */
67 | public function toString()
68 | {
69 | if (!$this->hasValue()) {
70 | return $this->getName();
71 | }
72 |
73 | return sprintf('%s=%s', $this->getName(), $this->getValue());
74 | }
75 |
76 | /**
77 | * Get name.
78 | *
79 | * @return string
80 | */
81 | public function getName()
82 | {
83 | return $this->name;
84 | }
85 |
86 | /**
87 | * Return whether the argument has a value.
88 | *
89 | * @return bool
90 | */
91 | public function hasValue()
92 | {
93 | return null !== $this->value;
94 | }
95 |
96 | /**
97 | * Get value.
98 | *
99 | * @return mixed
100 | */
101 | public function getValue()
102 | {
103 | return $this->value;
104 | }
105 |
106 | /**
107 | * Set value.
108 | *
109 | * @param mixed $value
110 | *
111 | * @return $this
112 | */
113 | public function setValue($value)
114 | {
115 | $this->value = $value;
116 |
117 | return $this;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/Process/Arguments.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\Ghostscript\Process;
9 |
10 | /**
11 | * The arguments class.
12 | *
13 | * @package GravityMedia\Ghostscript\Process
14 | */
15 | class Arguments
16 | {
17 | /**
18 | * The argument objects.
19 | *
20 | * @var Argument[]
21 | */
22 | protected $arguments;
23 |
24 | /**
25 | * Create arguments object.
26 | */
27 | public function __construct()
28 | {
29 | $this->arguments = [];
30 | }
31 |
32 | /**
33 | * Return arguments as array of strings.
34 | *
35 | * @return string[]
36 | */
37 | public function toArray()
38 | {
39 | return array_values(array_map(function (Argument $argument) {
40 | return $argument->toString();
41 | }, $this->arguments));
42 | }
43 |
44 | /**
45 | * Convert argument to argument object.
46 | *
47 | * @param string|Argument $argument
48 | *
49 | * @throws \InvalidArgumentException
50 | *
51 | * @return Argument
52 | */
53 | protected function convertArgument($argument)
54 | {
55 | if (is_string($argument)) {
56 | $argument = Argument::fromString($argument);
57 | }
58 |
59 | if (!$argument instanceof Argument) {
60 | throw new \InvalidArgumentException('Invalid argument');
61 | }
62 |
63 | return $argument;
64 | }
65 |
66 | /**
67 | * Get argument object.
68 | *
69 | * @param string $name
70 | *
71 | * @return Argument|null
72 | */
73 | public function getArgument($name)
74 | {
75 | $hash = $this->hashName($name);
76 |
77 | if (isset($this->arguments[$hash])) {
78 | return $this->arguments[$hash];
79 | }
80 |
81 | return null;
82 | }
83 |
84 | /**
85 | * Add argument.
86 | *
87 | * @param string|Argument $argument
88 | *
89 | * @throws \InvalidArgumentException
90 | *
91 | * @return $this
92 | */
93 | public function addArgument($argument)
94 | {
95 | $this->arguments[] = $this->convertArgument($argument);
96 |
97 | return $this;
98 | }
99 |
100 | /**
101 | * Add all arguments.
102 | *
103 | * @param array $arguments
104 | *
105 | * @throws \InvalidArgumentException
106 | *
107 | * @return $this
108 | */
109 | public function addArguments(array $arguments)
110 | {
111 | foreach ($arguments as $argument) {
112 | $this->addArgument($argument);
113 | }
114 |
115 | return $this;
116 | }
117 |
118 | /**
119 | * Hash the name.
120 | *
121 | * @param string $name
122 | *
123 | * @return string
124 | */
125 | protected function hashName($name)
126 | {
127 | return strtolower(ltrim($name, '-'));
128 | }
129 |
130 | /**
131 | * Set argument.
132 | *
133 | * @param string|Argument $argument
134 | *
135 | * @throws \InvalidArgumentException
136 | *
137 | * @return $this
138 | */
139 | public function setArgument($argument)
140 | {
141 | $argument = $this->convertArgument($argument);
142 |
143 | $hash = $this->hashName($argument->getName());
144 |
145 | $this->arguments[$hash] = $argument;
146 |
147 | return $this;
148 | }
149 |
150 | /**
151 | * Set all arguments.
152 | *
153 | * @param array $arguments
154 | *
155 | * @throws \InvalidArgumentException
156 | *
157 | * @return $this
158 | */
159 | public function setArguments(array $arguments)
160 | {
161 | foreach ($arguments as $argument) {
162 | $this->setArgument($argument);
163 | }
164 |
165 | return $this;
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/tests/data/input.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GravityMedia/Ghostscript/156a3da121624ea1057d6732d3f09ceed01aba81/tests/data/input.pdf
--------------------------------------------------------------------------------
/tests/data/pdf_info.ps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GravityMedia/Ghostscript/156a3da121624ea1057d6732d3f09ceed01aba81/tests/data/pdf_info.ps
--------------------------------------------------------------------------------
/tests/src/Device/AbstractDeviceTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device;
9 |
10 | use GravityMedia\Ghostscript\Device\AbstractDevice;
11 | use GravityMedia\Ghostscript\Ghostscript;
12 | use GravityMedia\Ghostscript\Input;
13 | use GravityMedia\Ghostscript\Process\Argument;
14 | use GravityMedia\Ghostscript\Process\Arguments;
15 | use PHPUnit\Framework\Attributes\CoversClass;
16 | use PHPUnit\Framework\Attributes\UsesClass;
17 | use PHPUnit\Framework\TestCase;
18 |
19 | /**
20 | * The abstract device test class.
21 | *
22 | * @package GravityMedia\GhostscriptTest\Devices
23 | */
24 | #[CoversClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Ghostscript::class)]
26 | #[UsesClass(\GravityMedia\Ghostscript\Input::class)]
27 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\EpsTrait::class)]
28 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\FontTrait::class)]
29 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\IccColorTrait::class)]
30 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\InteractionTrait::class)]
31 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\OtherTrait::class)]
32 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\OutputSelectionTrait::class)]
33 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\PageTrait::class)]
34 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\RenderingTrait::class)]
35 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\ResourceTrait::class)]
36 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
37 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
38 | class AbstractDeviceTest extends TestCase
39 | {
40 | /**
41 | * Returns an OS independent representation of the commandline.
42 | *
43 | * @param string $commandline
44 | *
45 | * @return mixed
46 | */
47 | protected function quoteCommandLine($commandline)
48 | {
49 | if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
50 | return str_replace('"', '\'', $commandline);
51 |
52 | }
53 |
54 | return $commandline;
55 | }
56 |
57 | /**
58 | * @param array $args
59 | *
60 | * @return AbstractDevice
61 | */
62 | protected function createDevice(array $args = [])
63 | {
64 | $ghostscript = new Ghostscript();
65 | $arguments = new Arguments();
66 | $arguments->setArguments($args);
67 |
68 | return $this->getMockForAbstractClass(AbstractDevice::class, [$ghostscript, $arguments]);
69 | }
70 |
71 | public function testArgumentGetter()
72 | {
73 | $device = $this->createDevice(['-dFoo=/Bar']);
74 | $method = new \ReflectionMethod(AbstractDevice::class, 'getArgument');
75 | $method->setAccessible(true);
76 |
77 | $this->assertNull($method->invoke($device, '-dBaz'));
78 |
79 | /** @var \GravityMedia\Ghostscript\Process\Argument $argument */
80 | $argument = $method->invoke($device, '-dFoo');
81 | $this->assertInstanceOf(Argument::class, $argument);
82 | $this->assertSame('/Bar', $argument->getValue());
83 | }
84 |
85 | public function testArgumentTester()
86 | {
87 | $device = $this->createDevice(['-dFoo=/Bar']);
88 | $method = new \ReflectionMethod(AbstractDevice::class, 'hasArgument');
89 | $method->setAccessible(true);
90 |
91 | $this->assertFalse($method->invoke($device, '-dBar'));
92 | $this->assertTrue($method->invoke($device, '-dFoo'));
93 | }
94 |
95 | public function testArgumentValueGetter()
96 | {
97 | $device = $this->createDevice(['-dFoo=/Bar']);
98 | $method = new \ReflectionMethod(AbstractDevice::class, 'getArgumentValue');
99 | $method->setAccessible(true);
100 |
101 | $this->assertNull($method->invoke($device, '-dBaz'));
102 | $this->assertSame('/Bar', $method->invoke($device, '-dFoo'));
103 | }
104 |
105 | public function testArgumentSetter()
106 | {
107 | $ghostscript = new Ghostscript();
108 | $arguments = new Arguments();
109 |
110 | /** @var AbstractDevice $device */
111 | $device = $this->getMockForAbstractClass(AbstractDevice::class, [$ghostscript, $arguments]);
112 |
113 | $method = new \ReflectionMethod(AbstractDevice::class, 'setArgument');
114 | $method->setAccessible(true);
115 | $method->invoke($device, '-dFoo=/Bar');
116 |
117 | $argument = $arguments->getArgument('-dFoo');
118 | $this->assertInstanceOf(Argument::class, $argument);
119 | $this->assertSame('/Bar', $argument->getValue());
120 | }
121 |
122 | public function testProcessCreation()
123 | {
124 | $process = $this->createDevice()->createProcess();
125 |
126 | $this->assertEquals("'gs'", $this->quoteCommandLine($process->getCommandLine()));
127 | }
128 |
129 | public function testProcessCreationWithInput()
130 | {
131 | $file = __DIR__ . '/../../data/input.pdf';
132 | $processInput = fopen($file, 'r');
133 | $code = '.setpdfwrite';
134 |
135 | $input = new Input();
136 | $input->addFile($file);
137 | $input->setProcessInput($processInput);
138 | $input->setPostScriptCode($code);
139 |
140 | $process = $this->createDevice()->createProcess($input);
141 |
142 | $this->assertEquals("'gs' '-c' '$code' '-f' '$file' '-'", $this->quoteCommandLine($process->getCommandLine()));
143 | $this->assertEquals($processInput, $process->getInput());
144 |
145 | fclose($processInput);
146 | }
147 |
148 | public function testProcessCreationWithPostScriptInput()
149 | {
150 | $input = '.setpdfwrite';
151 |
152 | $process = $this->createDevice()->createProcess($input);
153 |
154 | $this->assertEquals("'gs' '-c' '$input'", $this->quoteCommandLine($process->getCommandLine()));
155 | }
156 |
157 | public function testProcessCreationWithFileInput()
158 | {
159 | $input = __DIR__ . '/../../data/input.pdf';
160 |
161 | $process = $this->createDevice()->createProcess($input);
162 |
163 | $this->assertEquals("'gs' '-f' '$input'", $this->quoteCommandLine($process->getCommandLine()));
164 | }
165 |
166 | public function testProcessCreationWithResourceInput()
167 | {
168 | $input = fopen(__DIR__ . '/../../data/input.pdf', 'r');
169 |
170 | $process = $this->createDevice()->createProcess($input);
171 |
172 | $this->assertEquals("'gs' '-'", $this->quoteCommandLine($process->getCommandLine()));
173 | $this->assertEquals($input, $process->getInput());
174 |
175 | fclose($input);
176 | }
177 |
178 | /**
179 | * @expectedException \RuntimeException
180 | */
181 | public function testProcessCreationThrowsExceptionOnMissingInputFile()
182 | {
183 | $this->expectExceptionMessage('Input file does not exist');
184 |
185 | $input = new Input();
186 | $input->addFile('/path/to/input/file.pdf');
187 |
188 | $this->createDevice()->createProcess($input);
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/tests/src/Device/BoundingBoxInfoTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device;
9 |
10 | use GravityMedia\Ghostscript\Device\AbstractDevice;
11 | use GravityMedia\Ghostscript\Device\BoundingBoxInfo;
12 | use GravityMedia\Ghostscript\Ghostscript;
13 | use GravityMedia\Ghostscript\Process\Argument;
14 | use GravityMedia\Ghostscript\Process\Arguments;
15 | use PHPUnit\Framework\Attributes\CoversClass;
16 | use PHPUnit\Framework\Attributes\UsesClass;
17 | use PHPUnit\Framework\TestCase;
18 |
19 | /**
20 | * The bounding box info device test class.
21 | *
22 | * @package GravityMedia\GhostscriptTest\Devices
23 | */
24 | #[CoversClass(\GravityMedia\Ghostscript\Device\BoundingBoxInfo::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Ghostscript::class)]
26 | #[UsesClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
27 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
28 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
29 | class BoundingBoxInfoTest extends DeviceTestCase
30 | {
31 | protected function createDevice(?string $version = null): AbstractDevice
32 | {
33 | return new BoundingBoxInfo($this->getGhostscript($version), $this->arguments);
34 | }
35 |
36 | public function testDeviceCreation()
37 | {
38 | $device = $this->createDevice();
39 |
40 | $this->assertInstanceOf(BoundingBoxInfo::class, $device);
41 |
42 | $argument = $this->arguments->getArgument('-sDEVICE');
43 |
44 | $this->assertInstanceOf(Argument::class, $argument);
45 | $this->assertEquals('bbox', $argument->getValue());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tests/src/Device/CommandLineParameters/FontTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\CommandLineParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\CommandLineParameters\FontTrait;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The font-related parameters trait test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Device\CommandLineParameters
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\FontTrait::class)]
20 | class FontTraitTest extends TestCase
21 | {
22 | public function testFontPath()
23 | {
24 | /** @var FontTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
25 | $trait = $this->getMockForTrait(FontTrait::class);
26 | $trait->expects($this->once())->method('getArgumentValue')->with('-sFONTPATH')->willReturn(null);
27 | $this->assertNull($trait->getFontPath());
28 |
29 | $trait->expects($this->once())->method('setArgument')->with('-sFONTPATH=some/path')->willReturnSelf();
30 | $this->assertSame($trait, $trait->setFontPath('some/path'));
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/tests/src/Device/CommandLineParameters/InteractionTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\CommandLineParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\CommandLineParameters\InteractionTrait;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The interaction-related parameters trait test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Device\CommandLineParameters
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\InteractionTrait::class)]
20 | class InteractionTraitTest extends TestCase
21 | {
22 | public function testBatch()
23 | {
24 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
25 | $trait = $this->getMockForTrait(InteractionTrait::class);
26 | $trait->expects($this->once())->method('hasArgument')->with('-dBATCH')->willReturn(false);
27 | $this->assertFalse($trait->isBatch());
28 |
29 | $trait->expects($this->once())->method('setArgument')->with('-dBATCH')->willReturnSelf();
30 | $this->assertSame($trait, $trait->setBatch());
31 | }
32 |
33 | public function testNoPagePrompt()
34 | {
35 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
36 | $trait = $this->getMockForTrait(InteractionTrait::class);
37 | $trait->expects($this->once())->method('hasArgument')->with('-dNOPAGEPROMPT')->willReturn(false);
38 | $this->assertFalse($trait->isNoPagePrompt());
39 |
40 | $trait->expects($this->once())->method('setArgument')->with('-dNOPAGEPROMPT')->willReturnSelf();
41 | $this->assertSame($trait, $trait->setNoPagePrompt());
42 | }
43 |
44 | public function testNoPause()
45 | {
46 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
47 | $trait = $this->getMockForTrait(InteractionTrait::class);
48 | $trait->expects($this->once())->method('hasArgument')->with('-dNOPAUSE')->willReturn(false);
49 | $this->assertFalse($trait->isNoPause());
50 |
51 | $trait->expects($this->once())->method('setArgument')->with('-dNOPAUSE')->willReturnSelf();
52 | $this->assertSame($trait, $trait->setNoPause());
53 | }
54 |
55 | public function testNoPromt()
56 | {
57 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
58 | $trait = $this->getMockForTrait(InteractionTrait::class);
59 | $trait->expects($this->once())->method('hasArgument')->with('-dNOPROMPT')->willReturn(false);
60 | $this->assertFalse($trait->isNoPrompt());
61 |
62 | $trait->expects($this->once())->method('setArgument')->with('-dNOPROMPT')->willReturnSelf();
63 | $this->assertSame($trait, $trait->setNoPrompt());
64 | }
65 |
66 | public function testQuiet()
67 | {
68 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
69 | $trait = $this->getMockForTrait(InteractionTrait::class);
70 | $trait->expects($this->once())->method('hasArgument')->with('-dQUIET')->willReturn(false);
71 | $this->assertFalse($trait->isQuiet());
72 |
73 | $trait->expects($this->once())->method('setArgument')->with('-dQUIET')->willReturnSelf();
74 | $this->assertSame($trait, $trait->setQuiet());
75 | }
76 |
77 | public function testShortErrors()
78 | {
79 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
80 | $trait = $this->getMockForTrait(InteractionTrait::class);
81 | $trait->expects($this->once())->method('hasArgument')->with('-dSHORTERRORS')->willReturn(false);
82 | $this->assertFalse($trait->isShortErrors());
83 |
84 | $trait->expects($this->once())->method('setArgument')->with('-dSHORTERRORS')->willReturnSelf();
85 | $this->assertSame($trait, $trait->setShortErrors());
86 | }
87 |
88 | public function testStdout()
89 | {
90 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
91 | $trait = $this->getMockForTrait(InteractionTrait::class);
92 | $trait->expects($this->once())->method('getArgumentValue')->with('-sstdout')->willReturn(null);
93 | $this->assertNull($trait->getStdout());
94 |
95 | $trait->expects($this->once())->method('setArgument')->with('-sstdout=some file')->willReturnSelf();
96 | $this->assertSame($trait, $trait->setStdout('some file'));
97 | }
98 |
99 | public function testTtyPause()
100 | {
101 | /** @var InteractionTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
102 | $trait = $this->getMockForTrait(InteractionTrait::class);
103 | $trait->expects($this->once())->method('hasArgument')->with('-dTTYPAUSE')->willReturn(false);
104 | $this->assertFalse($trait->isTtyPause());
105 |
106 | $trait->expects($this->once())->method('setArgument')->with('-dTTYPAUSE')->willReturnSelf();
107 | $this->assertSame($trait, $trait->setTtyPause());
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/tests/src/Device/CommandLineParameters/OtherTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\CommandLineParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\CommandLineParameters\OtherTrait;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The other parameters trait test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Device\CommandLineParameters
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\OtherTrait::class)]
20 | class OtherTraitTest extends TestCase
21 | {
22 | public function testFilterImage()
23 | {
24 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
25 | $trait = $this->getMockForTrait(OtherTrait::class);
26 | $trait->expects($this->once())->method('hasArgument')->with('-dFILTERIMAGE')->willReturn(false);
27 | $this->assertFalse($trait->isFilterImage());
28 |
29 | $trait->expects($this->once())->method('setArgument')->with('-dFILTERIMAGE')->willReturnSelf();
30 | $this->assertSame($trait, $trait->setFilterImage());
31 | }
32 |
33 | public function testFilterText()
34 | {
35 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
36 | $trait = $this->getMockForTrait(OtherTrait::class);
37 | $trait->expects($this->once())->method('hasArgument')->with('-dFILTERTEXT')->willReturn(false);
38 | $this->assertFalse($trait->isFilterText());
39 |
40 | $trait->expects($this->once())->method('setArgument')->with('-dFILTERTEXT')->willReturnSelf();
41 | $this->assertSame($trait, $trait->setFilterText());
42 | }
43 |
44 | public function testFilterVector()
45 | {
46 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
47 | $trait = $this->getMockForTrait(OtherTrait::class);
48 | $trait->expects($this->once())->method('hasArgument')->with('-dFILTERVECTOR')->willReturn(false);
49 | $this->assertFalse($trait->isFilterVector());
50 |
51 | $trait->expects($this->once())->method('setArgument')->with('-dFILTERVECTOR')->willReturnSelf();
52 | $this->assertSame($trait, $trait->setFilterVector());
53 | }
54 |
55 | public function testDelayBind()
56 | {
57 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
58 | $trait = $this->getMockForTrait(OtherTrait::class);
59 | $trait->expects($this->once())->method('hasArgument')->with('-dDELAYBIND')->willReturn(false);
60 | $this->assertFalse($trait->isDelayBind());
61 |
62 | $trait->expects($this->once())->method('setArgument')->with('-dDELAYBIND')->willReturnSelf();
63 | $this->assertSame($trait, $trait->setDelayBind());
64 | }
65 |
66 | public function testDoPdfMarks()
67 | {
68 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
69 | $trait = $this->getMockForTrait(OtherTrait::class);
70 | $trait->expects($this->once())->method('hasArgument')->with('-dDOPDFMARKS')->willReturn(false);
71 | $this->assertFalse($trait->isDoPdfMarks());
72 |
73 | $trait->expects($this->once())->method('setArgument')->with('-dDOPDFMARKS')->willReturnSelf();
74 | $this->assertSame($trait, $trait->setDoPdfMarks());
75 | }
76 |
77 | public function testJobServer()
78 | {
79 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
80 | $trait = $this->getMockForTrait(OtherTrait::class);
81 | $trait->expects($this->once())->method('hasArgument')->with('-dJOBSERVER')->willReturn(false);
82 | $this->assertFalse($trait->isJobServer());
83 |
84 | $trait->expects($this->once())->method('setArgument')->with('-dJOBSERVER')->willReturnSelf();
85 | $this->assertSame($trait, $trait->setJobServer());
86 | }
87 |
88 | public function testNoBind()
89 | {
90 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
91 | $trait = $this->getMockForTrait(OtherTrait::class);
92 | $trait->expects($this->once())->method('hasArgument')->with('-dNOBIND')->willReturn(false);
93 | $this->assertFalse($trait->isNoBind());
94 |
95 | $trait->expects($this->once())->method('setArgument')->with('-dNOBIND')->willReturnSelf();
96 | $this->assertSame($trait, $trait->setNoBind());
97 | }
98 |
99 | public function testNoCache()
100 | {
101 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
102 | $trait = $this->getMockForTrait(OtherTrait::class);
103 | $trait->expects($this->once())->method('hasArgument')->with('-dNOCACHE')->willReturn(false);
104 | $this->assertFalse($trait->isNoCache());
105 |
106 | $trait->expects($this->once())->method('setArgument')->with('-dNOCACHE')->willReturnSelf();
107 | $this->assertSame($trait, $trait->setNoCache());
108 | }
109 |
110 | public function testNoGc()
111 | {
112 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
113 | $trait = $this->getMockForTrait(OtherTrait::class);
114 | $trait->expects($this->once())->method('hasArgument')->with('-dNOGC')->willReturn(false);
115 | $this->assertFalse($trait->isNoGc());
116 |
117 | $trait->expects($this->once())->method('setArgument')->with('-dNOGC')->willReturnSelf();
118 | $this->assertSame($trait, $trait->setNoGc());
119 | }
120 |
121 | public function testNoOuterSave()
122 | {
123 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
124 | $trait = $this->getMockForTrait(OtherTrait::class);
125 | $trait->expects($this->once())->method('hasArgument')->with('-dNOOUTERSAVE')->willReturn(false);
126 | $this->assertFalse($trait->isNoOuterSave());
127 |
128 | $trait->expects($this->once())->method('setArgument')->with('-dNOOUTERSAVE')->willReturnSelf();
129 | $this->assertSame($trait, $trait->setNoOuterSave());
130 | }
131 |
132 | public function testNoSafer()
133 | {
134 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
135 | $trait = $this->getMockForTrait(OtherTrait::class);
136 | $trait->expects($this->once())->method('hasArgument')->with('-dNOSAFER')->willReturn(false);
137 | $this->assertFalse($trait->isNoSafer());
138 |
139 | $trait->expects($this->once())->method('setArgument')->with('-dNOSAFER')->willReturnSelf();
140 | $this->assertSame($trait, $trait->setNoSafer());
141 | }
142 |
143 | public function testSafer()
144 | {
145 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
146 | $trait = $this->getMockForTrait(OtherTrait::class);
147 | $trait->expects($this->once())->method('hasArgument')->with('-dSAFER')->willReturn(false);
148 | $this->assertFalse($trait->isSafer());
149 |
150 | $trait->expects($this->once())->method('setArgument')->with('-dSAFER')->willReturnSelf();
151 | $this->assertSame($trait, $trait->setSafer());
152 | }
153 |
154 | public function testPreBandThresholdTrue()
155 | {
156 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
157 | $trait = $this->getMockForTrait(OtherTrait::class);
158 | $trait->expects($this->exactly(2))->method('getArgumentValue')
159 | ->with('-dPreBandThreshold')->willReturnOnConsecutiveCalls(null, true);
160 | $trait->expects($this->exactly(1))->method('setArgument')
161 | ->with('-dPreBandThreshold=true')->willReturnSelf();
162 | $this->assertFalse($trait->isPreBandThreshold());
163 | $this->assertSame($trait, $trait->setPreBandThreshold(true));
164 | $this->assertTrue($trait->isPreBandThreshold());
165 | }
166 |
167 | public function testPreBandThresholdFalse()
168 | {
169 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
170 | $trait = $this->getMockForTrait(OtherTrait::class);
171 | $trait->expects($this->exactly(2))->method('getArgumentValue')
172 | ->with('-dPreBandThreshold')->willReturnOnConsecutiveCalls(null, false);
173 | $trait->expects($this->exactly(1))->method('setArgument')
174 | ->with('-dPreBandThreshold=false')->willReturnSelf();
175 | $this->assertFalse($trait->isPreBandThreshold());
176 | $this->assertSame($trait, $trait->setPreBandThreshold(false));
177 | $this->assertFalse($trait->isPreBandThreshold());
178 | }
179 |
180 | public function testStrict()
181 | {
182 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
183 | $trait = $this->getMockForTrait(OtherTrait::class);
184 | $trait->expects($this->once())->method('hasArgument')->with('-dSTRICT')->willReturn(false);
185 | $this->assertFalse($trait->isStrict());
186 |
187 | $trait->expects($this->once())->method('setArgument')->with('-dSTRICT')->willReturnSelf();
188 | $this->assertSame($trait, $trait->setStrict());
189 | }
190 |
191 | public function testWriteSystemDict()
192 | {
193 | /** @var OtherTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
194 | $trait = $this->getMockForTrait(OtherTrait::class);
195 | $trait->expects($this->once())->method('hasArgument')->with('-dWRITESYSTEMDICT')->willReturn(false);
196 | $this->assertFalse($trait->isWriteSystemDict());
197 |
198 | $trait->expects($this->once())->method('setArgument')->with('-dWRITESYSTEMDICT')->willReturnSelf();
199 | $this->assertSame($trait, $trait->setWriteSystemDict());
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/tests/src/Device/CommandLineParameters/PageTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\CommandLineParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\CommandLineParameters\PageTrait;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The page parameters trait test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Device\CommandLineParameters
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\PageTrait::class)]
20 | class PageTraitTest extends TestCase
21 | {
22 | public function testFirstPage()
23 | {
24 | /** @var PageTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
25 | $trait = $this->getMockForTrait(PageTrait::class);
26 | $trait->expects($this->once())->method('getArgumentValue')->with('-dFirstPage')->willReturn(null);
27 | $this->assertNull($trait->getFirstPage());
28 |
29 | $trait->expects($this->once())->method('setArgument')->with('-dFirstPage=42')->willReturnSelf();
30 | $this->assertSame($trait, $trait->setFirstPage(42));
31 | }
32 |
33 | public function testLastPage()
34 | {
35 | /** @var PageTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
36 | $trait = $this->getMockForTrait(PageTrait::class);
37 | $trait->expects($this->once())->method('getArgumentValue')->with('-dLastPage')->willReturn(null);
38 | $this->assertNull($trait->getLastPage());
39 |
40 | $trait->expects($this->once())->method('setArgument')->with('-dLastPage=42')->willReturnSelf();
41 | $this->assertSame($trait, $trait->setLastPage(42));
42 | }
43 |
44 | public function testFixedMedia()
45 | {
46 | /** @var PageTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
47 | $trait = $this->getMockForTrait(PageTrait::class);
48 | $trait->expects($this->once())->method('getArgumentValue')->with('-dFIXEDMEDIA')->willReturn(null);
49 | $this->assertNull($trait->getFixedMedia());
50 |
51 | $trait->expects($this->once())->method('setArgument')->with('-dFIXEDMEDIA')->willReturnSelf();
52 | $this->assertSame($trait, $trait->setFixedMedia());
53 | }
54 |
55 | public function testPDFFitPage()
56 | {
57 | /** @var PageTrait|\PHPUnit_Framework_MockObject_MockObject $trait */
58 | $trait = $this->getMockForTrait(PageTrait::class);
59 | $trait->expects($this->once())->method('getArgumentValue')->with('-dPDFFitPage')->willReturn(null);
60 | $this->assertNull($trait->getPDFFitPage());
61 |
62 | $trait->expects($this->once())->method('setArgument')->with('-dPDFFitPage')->willReturnSelf();
63 | $this->assertSame($trait, $trait->setPDFFitPage());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/src/Device/DeviceTestCase.php:
--------------------------------------------------------------------------------
1 | arguments = new Arguments();
23 | }
24 |
25 | abstract protected function createDevice(?string $version = null): AbstractDevice;
26 |
27 | protected function getGhostscript(?string $version): Ghostscript|MockObject
28 | {
29 | if ($version === null) {
30 | $ghostscript = new Ghostscript();
31 | } else {
32 | $ghostscript = $this->createPartialMock(Ghostscript::class, ['getVersion']);
33 |
34 | $ghostscript->expects($this->atLeastOnce())
35 | ->method('getVersion')
36 | ->willReturn($version);
37 | }
38 | return $ghostscript;
39 | }
40 |
41 | public static function dataVersionsChecks(): array
42 | {
43 | $minVersion = static::getExpectedMinimumVersion();
44 | return [
45 | '8.50' => [fn (self $self) => $self->assertVersionCheck(
46 | version: '8.50',
47 | expectedFailure: true,
48 | )],
49 | $minVersion => [fn (self $self) => $self->assertVersionCheck(
50 | version: $minVersion,
51 | expectedFailure: false,
52 | )],
53 | '9.10' => [fn (self $self) => $self->assertVersionCheck(
54 | version: '9.10',
55 | expectedFailure: false,
56 | )],
57 | '9.50' => [fn (self $self) => $self->assertVersionCheck(
58 | version: '9.50',
59 | expectedFailure: false,
60 | )],
61 | '10.00.0' => [fn (self $self) => $self->assertVersionCheck(
62 | version: '10.00.0', // Version from brew (Mac)
63 | expectedFailure: false,
64 | )]
65 | ];
66 | }
67 |
68 | /**
69 | * @dataProvider dataVersionsChecks
70 | */
71 | public function testVersionCheck(callable $closure): void
72 | {
73 | $closure($this);
74 | }
75 |
76 | protected function assertVersionCheck(
77 | string $version,
78 | bool $expectedFailure,
79 | ): void
80 | {
81 | if ($expectedFailure) {
82 | $expectedMinimumVersion = static::getExpectedMinimumVersion();
83 | $this->expectExceptionMessage('Ghostscript version ' . $expectedMinimumVersion . ' or higher is required');
84 | }
85 |
86 | $device = $this->createDevice($version);
87 | $this->createProcessForVersionTest($device);
88 | }
89 |
90 | protected static function getExpectedMinimumVersion(): string
91 | {
92 | return '9.00';
93 | }
94 |
95 | protected function createProcessForVersionTest(AbstractDevice $device): Process
96 | {
97 | return $device->createProcess();
98 | }
99 |
100 | /**
101 | * Returns an OS independent representation of the commandline.
102 | */
103 | protected function quoteCommandLine(string $commandline): string
104 | {
105 | if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
106 | return str_replace('"', '\'', $commandline);
107 | }
108 |
109 | return $commandline;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/tests/src/Device/DistillerParameters/AdvancedTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\DistillerParameters\AdvancedTrait;
11 | use GravityMedia\Ghostscript\Enum\PdfSettings;
12 | use PHPUnit\Framework\Attributes\CoversClass;
13 | use PHPUnit\Framework\TestCase;
14 |
15 | /**
16 | * The advanced distiller parameters test class.
17 | *
18 | * @package GravityMedia\GhostscriptTest\Devices\DistillerParameters
19 | */
20 | #[CoversClass(\GravityMedia\Ghostscript\Device\DistillerParameters\AdvancedTrait::class)]
21 | class AdvancedTraitTest extends TestCase
22 | {
23 | /**
24 | * @param string $pdfSettings
25 | *
26 | * @return AdvancedTrait
27 | */
28 | protected function createTraitForDefaultValue($pdfSettings)
29 | {
30 | $trait = $this->getMockForTrait(AdvancedTrait::class);
31 |
32 | $trait->expects($this->once())
33 | ->method('getArgumentValue')
34 | ->willReturn(null);
35 |
36 | $trait->expects($this->once())
37 | ->method('getPdfSettings')
38 | ->willReturn($pdfSettings);
39 |
40 | return $trait;
41 | }
42 |
43 | /**
44 | * @param null|string $argumentValue
45 | *
46 | * @return AdvancedTrait
47 | */
48 | protected function createTraitForArgumentValue($argumentValue)
49 | {
50 | $trait = $this->getMockForTrait(AdvancedTrait::class);
51 |
52 | $trait->expects($this->once())
53 | ->method('getArgumentValue')
54 | ->willReturn($argumentValue);
55 |
56 | // expect the method `setArgument` to be called when the argument value is not null
57 | if (null !== $argumentValue) {
58 | $trait->expects($this->once())
59 | ->method('setArgument');
60 | }
61 |
62 | return $trait;
63 | }
64 |
65 | public function testAscii85EncodePagesArgument()
66 | {
67 | $trait = $this->createTraitForArgumentValue(null);
68 | $this->assertFalse($trait->isAscii85EncodePages());
69 |
70 | $trait = $this->createTraitForArgumentValue(true);
71 | $this->assertTrue($trait->setAscii85EncodePages(true)->isAscii85EncodePages());
72 | }
73 |
74 | public function testAutoPositionEpsFilesArgument()
75 | {
76 | $trait = $this->createTraitForArgumentValue(null);
77 | $this->assertFalse($trait->isAutoPositionEpsFiles());
78 |
79 | $trait = $this->createTraitForArgumentValue(true);
80 | $this->assertTrue($trait->setAutoPositionEpsFiles(true)->isAutoPositionEpsFiles());
81 | }
82 |
83 | /**
84 | * @dataProvider providePdfSettingsForCreateJobTicket
85 | *
86 | * @param bool $createJobTicket
87 | * @param string $pdfSettings
88 | */
89 | public function testCreateJobTicketArgument($createJobTicket, $pdfSettings)
90 | {
91 | $trait = $this->createTraitForDefaultValue($pdfSettings);
92 | $this->assertSame($createJobTicket, $trait->isCreateJobTicket());
93 |
94 | $trait = $this->createTraitForArgumentValue($createJobTicket);
95 | $this->assertSame($createJobTicket, $trait->setCreateJobTicket($createJobTicket)->isCreateJobTicket());
96 | }
97 |
98 | /**
99 | * @return array
100 | */
101 | public static function providePdfSettingsForCreateJobTicket()
102 | {
103 | return [
104 | [false, PdfSettings::__DEFAULT],
105 | [false, PdfSettings::SCREEN],
106 | [false, PdfSettings::EBOOK],
107 | [true, PdfSettings::PRINTER],
108 | [true, PdfSettings::PREPRESS]
109 | ];
110 | }
111 |
112 | public function testDetectBlendsArgument()
113 | {
114 | $trait = $this->createTraitForArgumentValue(null);
115 | $this->assertTrue($trait->isDetectBlends());
116 |
117 | $trait = $this->createTraitForArgumentValue(false);
118 | $this->assertFalse($trait->setDetectBlends(false)->isDetectBlends());
119 | }
120 |
121 | public function testEmitDscWarningsArgument()
122 | {
123 | $trait = $this->createTraitForArgumentValue(null);
124 | $this->assertFalse($trait->isEmitDscWarnings());
125 |
126 | $trait = $this->createTraitForArgumentValue(true);
127 | $this->assertTrue($trait->setEmitDscWarnings(true)->isEmitDscWarnings());
128 | }
129 |
130 | public function testLockDistillerParamsArgument()
131 | {
132 | $trait = $this->createTraitForArgumentValue(null);
133 | $this->assertFalse($trait->isLockDistillerParams());
134 |
135 | $trait = $this->createTraitForArgumentValue(true);
136 | $this->assertTrue($trait->setLockDistillerParams(true)->isLockDistillerParams());
137 | }
138 |
139 | public function testOpmArgument()
140 | {
141 | $trait = $this->createTraitForArgumentValue(null);
142 | $this->assertSame(1, $trait->getOpm());
143 |
144 | $trait = $this->createTraitForArgumentValue(2);
145 | $this->assertSame(2, $trait->setOpm(2)->getOpm());
146 | }
147 |
148 | public function testParseDscCommentsArgument()
149 | {
150 | $trait = $this->createTraitForArgumentValue(null);
151 | $this->assertTrue($trait->isParseDscComments());
152 |
153 | $trait = $this->createTraitForArgumentValue(false);
154 | $this->assertFalse($trait->setParseDscComments(false)->isParseDscComments());
155 | }
156 |
157 | public function testParseDscCommentsForDocInfoArgument()
158 | {
159 | $trait = $this->createTraitForArgumentValue(null);
160 | $this->assertTrue($trait->isParseDscCommentsForDocInfo());
161 |
162 | $trait = $this->createTraitForArgumentValue(false);
163 | $this->assertFalse($trait->setParseDscCommentsForDocInfo(false)->isParseDscCommentsForDocInfo());
164 | }
165 |
166 | public function testPreserveCopyPageArgument()
167 | {
168 | $trait = $this->createTraitForArgumentValue(null);
169 | $this->assertTrue($trait->isPreserveCopyPage());
170 |
171 | $trait = $this->createTraitForArgumentValue(false);
172 | $this->assertFalse($trait->setPreserveCopyPage(false)->isPreserveCopyPage());
173 | }
174 |
175 | public function testPreserveEpsInfoArgument()
176 | {
177 | $trait = $this->createTraitForArgumentValue(null);
178 | $this->assertTrue($trait->isPreserveEpsInfo());
179 |
180 | $trait = $this->createTraitForArgumentValue(false);
181 | $this->assertFalse($trait->setPreserveEpsInfo(false)->isPreserveEpsInfo());
182 | }
183 |
184 | /**
185 | * @dataProvider providePdfSettingsForPreserveOpiComments
186 | *
187 | * @param bool $preserveOpiComments
188 | * @param string $pdfSettings
189 | */
190 | public function testPreserveOpiCommentsArgument($preserveOpiComments, $pdfSettings)
191 | {
192 | $trait = $this->createTraitForDefaultValue($pdfSettings);
193 | $this->assertSame($preserveOpiComments, $trait->isPreserveOpiComments());
194 |
195 | $trait = $this->createTraitForArgumentValue($preserveOpiComments);
196 | $this->assertSame(
197 | $preserveOpiComments,
198 | $trait->setPreserveOpiComments($preserveOpiComments)->isPreserveOpiComments()
199 | );
200 | }
201 |
202 | /**
203 | * @return array
204 | */
205 | public static function providePdfSettingsForPreserveOpiComments()
206 | {
207 | return [
208 | [false, PdfSettings::__DEFAULT],
209 | [false, PdfSettings::SCREEN],
210 | [false, PdfSettings::EBOOK],
211 | [true, PdfSettings::PRINTER],
212 | [true, PdfSettings::PREPRESS]
213 | ];
214 | }
215 |
216 | public function testUsePrologueArgument()
217 | {
218 | $trait = $this->createTraitForArgumentValue(null);
219 | $this->assertFalse($trait->isUsePrologue());
220 |
221 | $trait = $this->createTraitForArgumentValue(true);
222 | $this->assertTrue($trait->setUsePrologue(true)->isUsePrologue());
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/tests/src/Device/DistillerParameters/FontTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\DistillerParameters\FontTrait;
11 | use GravityMedia\Ghostscript\Enum\CannotEmbedFontPolicy;
12 | use GravityMedia\Ghostscript\Enum\PdfSettings;
13 | use PHPUnit\Framework\Attributes\CoversClass;
14 | use PHPUnit\Framework\Attributes\UsesClass;
15 | use PHPUnit\Framework\TestCase;
16 |
17 | /**
18 | * The font distiller parameters test class.
19 | *
20 | * @package GravityMedia\GhostscriptTest\Devices\DistillerParameters
21 | */
22 | #[CoversClass(\GravityMedia\Ghostscript\Device\DistillerParameters\FontTrait::class)]
23 | #[UsesClass(\GravityMedia\Ghostscript\Enum\CannotEmbedFontPolicy::class)]
24 | class FontTraitTest extends TestCase
25 | {
26 | /**
27 | * @param string $pdfSettings
28 | *
29 | * @return FontTrait
30 | */
31 | protected function createTraitForDefaultValue($pdfSettings)
32 | {
33 | $trait = $this->getMockForTrait(FontTrait::class);
34 |
35 | $trait->expects($this->once())
36 | ->method('getArgumentValue')
37 | ->willReturn(null);
38 |
39 | $trait->expects($this->once())
40 | ->method('getPdfSettings')
41 | ->willReturn($pdfSettings);
42 |
43 | return $trait;
44 | }
45 |
46 | /**
47 | * @param null|string $argumentValue
48 | *
49 | * @return FontTrait
50 | */
51 | protected function createTraitForArgumentValue($argumentValue)
52 | {
53 | $trait = $this->getMockForTrait(FontTrait::class);
54 |
55 | $trait->expects($this->once())
56 | ->method('getArgumentValue')
57 | ->willReturn($argumentValue);
58 |
59 | // expect the method `setArgument` to be called when the argument value is not null
60 | if (null !== $argumentValue) {
61 | $trait->expects($this->once())
62 | ->method('setArgument');
63 | }
64 |
65 | return $trait;
66 | }
67 |
68 | /**
69 | * @dataProvider providePdfSettingsForCannotEmbedFontPolicy
70 | *
71 | * @param string $cannotEmbedFontPolicy
72 | * @param string $pdfSettings
73 | */
74 | public function testCannotEmbedFontPolicyArgument($cannotEmbedFontPolicy, $pdfSettings)
75 | {
76 | $trait = $this->createTraitForDefaultValue($pdfSettings);
77 | $this->assertSame($cannotEmbedFontPolicy, $trait->getCannotEmbedFontPolicy());
78 |
79 | $trait = $this->createTraitForArgumentValue('/' . $cannotEmbedFontPolicy);
80 | $this->assertSame(
81 | $cannotEmbedFontPolicy,
82 | $trait->setCannotEmbedFontPolicy($cannotEmbedFontPolicy)->getCannotEmbedFontPolicy()
83 | );
84 | }
85 |
86 | /**
87 | * @return array
88 | */
89 | public static function providePdfSettingsForCannotEmbedFontPolicy()
90 | {
91 | return [
92 | [CannotEmbedFontPolicy::WARNING, PdfSettings::__DEFAULT],
93 | [CannotEmbedFontPolicy::WARNING, PdfSettings::SCREEN],
94 | [CannotEmbedFontPolicy::WARNING, PdfSettings::EBOOK],
95 | [CannotEmbedFontPolicy::WARNING, PdfSettings::PRINTER],
96 | [CannotEmbedFontPolicy::ERROR, PdfSettings::PREPRESS]
97 | ];
98 | }
99 |
100 | /**
101 | * @expectedException \InvalidArgumentException
102 | */
103 | public function testCannotEmbedFontPolicyArgumentThrowsException()
104 | {
105 | $this->expectExceptionMessage('Invalid cannot embed font policy argument');
106 |
107 | /** @var FontTrait $trait */
108 | $trait = $this->getMockForTrait(FontTrait::class);
109 |
110 | $trait->setCannotEmbedFontPolicy('/Foo');
111 | }
112 |
113 | /**
114 | * @dataProvider providePdfSettingsForEmbedAllFonts
115 | *
116 | * @param bool $embedAllFonts
117 | * @param string $pdfSettings
118 | */
119 | public function testEmbedAllFontsArgument($embedAllFonts, $pdfSettings)
120 | {
121 | $trait = $this->createTraitForDefaultValue($pdfSettings);
122 | $this->assertSame($embedAllFonts, $trait->isEmbedAllFonts());
123 |
124 | $trait = $this->createTraitForArgumentValue($embedAllFonts);
125 | $this->assertSame($embedAllFonts, $trait->setEmbedAllFonts($embedAllFonts)->isEmbedAllFonts());
126 | }
127 |
128 | /**
129 | * @return array
130 | */
131 | public static function providePdfSettingsForEmbedAllFonts()
132 | {
133 | return [
134 | [true, PdfSettings::__DEFAULT],
135 | [false, PdfSettings::SCREEN],
136 | [true, PdfSettings::EBOOK],
137 | [true, PdfSettings::PRINTER],
138 | [true, PdfSettings::PREPRESS]
139 | ];
140 | }
141 |
142 | public function testMaxSubsetPctArgument()
143 | {
144 | $trait = $this->createTraitForArgumentValue(null);
145 | $this->assertSame(100, $trait->getMaxSubsetPct());
146 |
147 | $trait = $this->createTraitForArgumentValue(66);
148 | $this->assertSame(66, $trait->setMaxSubsetPct(66)->getMaxSubsetPct());
149 | }
150 |
151 | public function testSubsetFontsArgument()
152 | {
153 | $trait = $this->createTraitForArgumentValue(null);
154 | $this->assertTrue($trait->isSubsetFonts());
155 |
156 | $trait = $this->createTraitForArgumentValue(false);
157 | $this->assertFalse($trait->setSubsetFonts(false)->isSubsetFonts());
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/tests/src/Device/DistillerParameters/MonoImageCompressionTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\DistillerParameters\MonoImageCompressionTrait;
11 | use GravityMedia\Ghostscript\Enum\ImageDownsampleType;
12 | use GravityMedia\Ghostscript\Enum\MonoImageFilter;
13 | use GravityMedia\Ghostscript\Enum\PdfSettings;
14 | use PHPUnit\Framework\Attributes\CoversClass;
15 | use PHPUnit\Framework\Attributes\UsesClass;
16 | use PHPUnit\Framework\TestCase;
17 |
18 | /**
19 | * The monochrome image compression distiller parameters test class.
20 | *
21 | * @package GravityMedia\GhostscriptTest\Devices\DistillerParameters
22 | */
23 | #[CoversClass(\GravityMedia\Ghostscript\Device\DistillerParameters\MonoImageCompressionTrait::class)]
24 | #[UsesClass(\GravityMedia\Ghostscript\Enum\MonoImageFilter::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Enum\ImageDownsampleType::class)]
26 | class MonoImageCompressionTraitTest extends TestCase
27 | {
28 | /**
29 | * @param string $pdfSettings
30 | *
31 | * @return MonoImageCompressionTrait
32 | */
33 | protected function createTraitForDefaultValue($pdfSettings)
34 | {
35 | $trait = $this->getMockForTrait(MonoImageCompressionTrait::class);
36 |
37 | $trait->expects($this->once())
38 | ->method('getArgumentValue')
39 | ->willReturn(null);
40 |
41 | $trait->expects($this->once())
42 | ->method('getPdfSettings')
43 | ->willReturn($pdfSettings);
44 |
45 | return $trait;
46 | }
47 |
48 | /**
49 | * @param null|string $argumentValue
50 | *
51 | * @return MonoImageCompressionTrait
52 | */
53 | protected function createTraitForArgumentValue($argumentValue)
54 | {
55 | $trait = $this->getMockForTrait(MonoImageCompressionTrait::class);
56 |
57 | $trait->expects($this->once())
58 | ->method('getArgumentValue')
59 | ->willReturn($argumentValue);
60 |
61 | // expect the method `setArgument` to be called when the argument value is not null
62 | if (null !== $argumentValue) {
63 | $trait->expects($this->once())
64 | ->method('setArgument');
65 | }
66 |
67 | return $trait;
68 | }
69 |
70 | public function testAntiAliasMonoImagesArgument()
71 | {
72 | $trait = $this->createTraitForArgumentValue(null);
73 | $this->assertFalse($trait->isAntiAliasMonoImages());
74 |
75 | $trait = $this->createTraitForArgumentValue(true);
76 | $this->assertTrue($trait->setAntiAliasMonoImages(true)->isAntiAliasMonoImages());
77 | }
78 |
79 | public function testMonoImageDepthArgument()
80 | {
81 | $trait = $this->createTraitForArgumentValue(null);
82 | $this->assertSame(-1, $trait->getMonoImageDepth());
83 |
84 | $trait = $this->createTraitForArgumentValue(8);
85 | $this->assertSame(8, $trait->setMonoImageDepth(8)->getMonoImageDepth());
86 | }
87 |
88 | public function testMonoImageDownsampleThresholdArgument()
89 | {
90 | $trait = $this->createTraitForArgumentValue(null);
91 | $this->assertSame(1.5, $trait->getMonoImageDownsampleThreshold());
92 |
93 | $trait = $this->createTraitForArgumentValue(1.0);
94 | $this->assertSame(1.0, $trait->setMonoImageDownsampleThreshold(1.0)->getMonoImageDownsampleThreshold());
95 | }
96 |
97 | /**
98 | * @dataProvider providePdfSettingsForMonoImageDownsampleType
99 | *
100 | * @param string $monoImageDownsampleType
101 | * @param string $pdfSettings
102 | */
103 | public function testMonoImageDownsampleTypeArgument($monoImageDownsampleType, $pdfSettings)
104 | {
105 | $trait = $this->createTraitForDefaultValue($pdfSettings);
106 | $this->assertSame($monoImageDownsampleType, $trait->getMonoImageDownsampleType());
107 |
108 | $trait = $this->createTraitForArgumentValue('/' . $monoImageDownsampleType);
109 | $this->assertSame(
110 | $monoImageDownsampleType,
111 | $trait->setMonoImageDownsampleType($monoImageDownsampleType)->getMonoImageDownsampleType()
112 | );
113 | }
114 |
115 | /**
116 | * @return array
117 | */
118 | public static function providePdfSettingsForMonoImageDownsampleType()
119 | {
120 | return [
121 | [ImageDownsampleType::SUBSAMPLE, PdfSettings::__DEFAULT],
122 | [ImageDownsampleType::SUBSAMPLE, PdfSettings::SCREEN],
123 | [ImageDownsampleType::SUBSAMPLE, PdfSettings::EBOOK],
124 | [ImageDownsampleType::SUBSAMPLE, PdfSettings::PRINTER],
125 | [ImageDownsampleType::BICUBIC, PdfSettings::PREPRESS]
126 | ];
127 | }
128 |
129 | /**
130 | * @expectedException \InvalidArgumentException
131 | */
132 | public function testMonoImageDownsampleTypeArgumentThrowsException()
133 | {
134 | $this->expectExceptionMessage('Invalid monochrome image downsample type argument');
135 |
136 | /** @var MonoImageCompressionTrait $trait */
137 | $trait = $this->getMockForTrait(MonoImageCompressionTrait::class);
138 |
139 | $trait->setMonoImageDownsampleType('/Foo');
140 | }
141 |
142 | public function testMonoImageFilterFallbackArgument()
143 | {
144 | $trait = $this->createTraitForArgumentValue(null);
145 | $this->assertSame(MonoImageFilter::CCITT_FAX_ENCODE, $trait->getMonoImageFilter());
146 | }
147 |
148 | /**
149 | * @dataProvider providePdfSettingsForMonoImageFilter
150 | *
151 | * @param string $transferFunctionInfo
152 | */
153 | public function testMonoImageFilterArgument($transferFunctionInfo)
154 | {
155 | $trait = $this->createTraitForArgumentValue('/' . $transferFunctionInfo);
156 | $this->assertSame(
157 | $transferFunctionInfo,
158 | $trait->setMonoImageFilter($transferFunctionInfo)->getMonoImageFilter()
159 | );
160 | }
161 |
162 | /**
163 | * @return array
164 | */
165 | public static function providePdfSettingsForMonoImageFilter()
166 | {
167 | return [
168 | [MonoImageFilter::CCITT_FAX_ENCODE],
169 | [MonoImageFilter::FLATE_ENCODE],
170 | [MonoImageFilter::RUN_LENGTH_ENCODE]
171 | ];
172 | }
173 |
174 | /**
175 | * @expectedException \InvalidArgumentException
176 | */
177 | public function testMonoImageFilterArgumentThrowsException()
178 | {
179 | $this->expectExceptionMessage('Invalid monochrome image filter argument');
180 |
181 | /** @var MonoImageCompressionTrait $trait */
182 | $trait = $this->getMockForTrait(MonoImageCompressionTrait::class);
183 |
184 | $trait->setMonoImageFilter('/Foo');
185 | }
186 |
187 | /**
188 | * @dataProvider providePdfSettingsForMonoImageResolution
189 | *
190 | * @param int $monoImageResolution
191 | * @param string $pdfSettings
192 | */
193 | public function testMonoImageResolutionArgument($monoImageResolution, $pdfSettings)
194 | {
195 | $trait = $this->createTraitForDefaultValue($pdfSettings);
196 | $this->assertSame($monoImageResolution, $trait->getMonoImageResolution());
197 |
198 | $trait = $this->createTraitForArgumentValue($monoImageResolution);
199 | $this->assertSame(
200 | $monoImageResolution,
201 | $trait->setMonoImageResolution($monoImageResolution)->getMonoImageResolution()
202 | );
203 | }
204 |
205 | /**
206 | * @return array
207 | */
208 | public static function providePdfSettingsForMonoImageResolution()
209 | {
210 | return [
211 | [300, PdfSettings::__DEFAULT],
212 | [300, PdfSettings::SCREEN],
213 | [300, PdfSettings::EBOOK],
214 | [1200, PdfSettings::PRINTER],
215 | [1200, PdfSettings::PREPRESS]
216 | ];
217 | }
218 |
219 | /**
220 | * @dataProvider providePdfSettingsForDownsampleMonoImages
221 | *
222 | * @param bool $downsampleMonoImages
223 | * @param string $pdfSettings
224 | */
225 | public function testDownsampleMonoImagesArgument($downsampleMonoImages, $pdfSettings)
226 | {
227 | $trait = $this->createTraitForDefaultValue($pdfSettings);
228 | $this->assertSame($downsampleMonoImages, $trait->isDownsampleMonoImages());
229 |
230 | $trait = $this->createTraitForArgumentValue($downsampleMonoImages);
231 | $this->assertSame(
232 | $downsampleMonoImages,
233 | $trait->setDownsampleMonoImages($downsampleMonoImages)->isDownsampleMonoImages()
234 | );
235 | }
236 |
237 | /**
238 | * @return array
239 | */
240 | public static function providePdfSettingsForDownsampleMonoImages()
241 | {
242 | return [
243 | [false, PdfSettings::__DEFAULT],
244 | [true, PdfSettings::SCREEN],
245 | [true, PdfSettings::EBOOK],
246 | [false, PdfSettings::PRINTER],
247 | [false, PdfSettings::PREPRESS]
248 | ];
249 | }
250 |
251 | public function testEncodeMonoImagesArgument()
252 | {
253 | $trait = $this->createTraitForArgumentValue(null);
254 | $this->assertTrue($trait->isEncodeMonoImages());
255 |
256 | $trait = $this->createTraitForArgumentValue(false);
257 | $this->assertFalse($trait->setEncodeMonoImages(false)->isEncodeMonoImages());
258 | }
259 | }
260 |
--------------------------------------------------------------------------------
/tests/src/Device/DistillerParameters/PageCompressionTraitTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device\DistillerParameters;
9 |
10 | use GravityMedia\Ghostscript\Device\DistillerParameters\PageCompressionTrait;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The page compression distiller parameters test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Devices\DistillerParameters
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Device\DistillerParameters\PageCompressionTrait::class)]
20 | class PageCompressionTraitTest extends TestCase
21 | {
22 | /**
23 | * @param null|string $argumentValue
24 | *
25 | * @return PageCompressionTrait
26 | */
27 | protected function createTraitForArgumentValue($argumentValue)
28 | {
29 | $trait = $this->getMockForTrait(PageCompressionTrait::class);
30 |
31 | $trait->expects($this->once())
32 | ->method('getArgumentValue')
33 | ->willReturn($argumentValue);
34 |
35 | // expect the method `setArgument` to be called when the argument value is not null
36 | if (null !== $argumentValue) {
37 | $trait->expects($this->once())
38 | ->method('setArgument');
39 | }
40 |
41 | return $trait;
42 | }
43 |
44 | public function testCompressPagesArgument()
45 | {
46 | $trait = $this->createTraitForArgumentValue(null);
47 | $this->assertTrue($trait->isCompressPages());
48 |
49 | $trait = $this->createTraitForArgumentValue(false);
50 | $this->assertFalse($trait->setCompressPages(false)->isCompressPages());
51 | }
52 |
53 | public function testLzwEncodePagesArgument()
54 | {
55 | $trait = $this->createTraitForArgumentValue(null);
56 | $this->assertFalse($trait->isLzwEncodePages());
57 |
58 | $trait = $this->createTraitForArgumentValue(true);
59 | $this->assertTrue($trait->setLzwEncodePages(true)->isLzwEncodePages());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/src/Device/InkcovTest.php:
--------------------------------------------------------------------------------
1 | getGhostscript($version), $this->arguments);
28 | }
29 |
30 | public function testDeviceCreation()
31 | {
32 | $device = $this->createDevice();
33 |
34 | $this->assertInstanceOf(Inkcov::class, $device);
35 | $this->assertInstanceOf(Argument::class, $this->arguments->getArgument('-sDEVICE'));
36 | $this->assertEquals('inkcov', $this->arguments->getArgument('-sDEVICE')->getValue());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/src/Device/NoDisplayTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device;
9 |
10 | use GravityMedia\Ghostscript\Device\AbstractDevice;
11 | use GravityMedia\Ghostscript\Device\NoDisplay;
12 | use GravityMedia\Ghostscript\Process\Argument;
13 | use PHPUnit\Framework\Attributes\CoversClass;
14 | use PHPUnit\Framework\Attributes\UsesClass;
15 |
16 | /**
17 | * The no display device test class.
18 | *
19 | * @package GravityMedia\GhostscriptTest\Devices
20 | */
21 | #[CoversClass(\GravityMedia\Ghostscript\Device\NoDisplay::class)]
22 | #[UsesClass(\GravityMedia\Ghostscript\Ghostscript::class)]
23 | #[UsesClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
24 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
26 | class NoDisplayTest extends DeviceTestCase
27 | {
28 | protected function createDevice(?string $version = null): AbstractDevice
29 | {
30 | $ghostscript = $this->getGhostscript($version);
31 |
32 | return new NoDisplay($ghostscript, $this->arguments);
33 | }
34 |
35 | public function testDeviceCreation()
36 | {
37 | $device = $this->createDevice();
38 |
39 | $this->assertInstanceOf(NoDisplay::class, $device);
40 | $this->assertInstanceOf(Argument::class, $this->arguments->getArgument('-dNODISPLAY'));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/src/Device/PdfInfoTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device;
9 |
10 | use GravityMedia\Ghostscript\Device\AbstractDevice;
11 | use GravityMedia\Ghostscript\Device\PdfInfo;
12 | use GravityMedia\Ghostscript\Process\Arguments;
13 | use Symfony\Component\Process\Process;
14 | use PHPUnit\Framework\Attributes\CoversClass;
15 | use PHPUnit\Framework\Attributes\UsesClass;
16 |
17 | /**
18 | * The pdf info device test class.
19 | *
20 | * @package GravityMedia\GhostscriptTest\Devices
21 | */
22 | #[CoversClass(\GravityMedia\Ghostscript\Device\PdfInfo::class)]
23 | #[UsesClass(\GravityMedia\Ghostscript\Ghostscript::class)]
24 | #[UsesClass(\GravityMedia\Ghostscript\Input::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
26 | #[UsesClass(\GravityMedia\Ghostscript\Device\NoDisplay::class)]
27 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
28 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
29 | class PdfInfoTest extends DeviceTestCase
30 | {
31 | const PDF_PATH = __DIR__ . '/../../data/pdf_info.ps';
32 |
33 | protected function createDevice(?string $version = null): PdfInfo
34 | {
35 | $ghostscript = $this->getGhostscript($version);
36 | $arguments = new Arguments();
37 |
38 | return new PdfInfo($ghostscript, $arguments, self::PDF_PATH);
39 | }
40 |
41 | public function testDeviceCreation()
42 | {
43 | $device = $this->createDevice();
44 | $field = new \ReflectionProperty(PdfInfo::class, 'pdfInfoPath');
45 | $field->setAccessible(true);
46 | $this->assertEquals(self::PDF_PATH, $field->getValue($device));
47 | }
48 |
49 | public function testProcessCreation()
50 | {
51 | $inputFile = __DIR__ . '/../../data/input.pdf';
52 | $pdfInfoPath = self::PDF_PATH;
53 | $device = $this->createDevice();
54 | $process = $device->createProcess($inputFile);
55 |
56 | $expectedCommandLine = "'gs' '-dNODISPLAY' '-sFile=$inputFile' '-f' '$pdfInfoPath'";
57 | $this->assertEquals($expectedCommandLine, $this->quoteCommandLine($process->getCommandLine()));
58 | }
59 |
60 | /**
61 | * @expectedException \RuntimeException
62 | */
63 | public function testProcessCreationThrowsExceptionOnMissingInputFile()
64 | {
65 | $this->expectExceptionMessage('Input file does not exist');
66 |
67 | $device = $this->createDevice();
68 | $device->createProcess();
69 | }
70 |
71 | protected function createProcessForVersionTest(AbstractDevice $device): Process
72 | {
73 | $inputFile = __DIR__ . '/../../data/input.pdf';
74 |
75 | return $device->createProcess($inputFile);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/src/Device/PdfWriteTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Device;
9 |
10 | use GravityMedia\Ghostscript\Device\PdfWrite;
11 | use GravityMedia\Ghostscript\Enum\PdfSettings;
12 | use GravityMedia\Ghostscript\Enum\ProcessColorModel;
13 | use PHPUnit\Framework\Attributes\CoversClass;
14 | use PHPUnit\Framework\Attributes\UsesClass;
15 |
16 | /**
17 | * The PDF write device test class.
18 | *
19 | * @package GravityMedia\GhostscriptTest\Devices
20 | */
21 | #[CoversClass(\GravityMedia\Ghostscript\Device\PdfWrite::class)]
22 | #[UsesClass(\GravityMedia\Ghostscript\Ghostscript::class)]
23 | #[UsesClass(\GravityMedia\Ghostscript\Input::class)]
24 | #[UsesClass(\GravityMedia\Ghostscript\Enum\PdfSettings::class)]
25 | #[UsesClass(\GravityMedia\Ghostscript\Enum\ProcessColorModel::class)]
26 | #[UsesClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
27 | #[UsesClass(\GravityMedia\Ghostscript\Device\DistillerParametersTrait::class)]
28 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
29 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
30 | class PdfWriteTest extends DeviceTestCase
31 | {
32 | protected function createDevice(?string $version = null): PdfWrite
33 | {
34 | return new PdfWrite($this->getGhostscript($version), $this->arguments);
35 | }
36 |
37 | public function testDeviceCreation()
38 | {
39 | $this->assertInstanceOf('GravityMedia\Ghostscript\Device\PdfWrite', $this->createDevice());
40 | }
41 |
42 | public function testOutputFileArgument()
43 | {
44 | $device = $this->createDevice();
45 | $outputFile = '/path/to/output/file.pdf';
46 |
47 | $this->assertNull($device->getOutputFile());
48 | $this->assertSame($outputFile, $device->setOutputFile($outputFile)->getOutputFile());
49 | }
50 |
51 | /**
52 | * @dataProvider providePdfSettings
53 | *
54 | * @param string $pdfSettings
55 | */
56 | public function testPdfSettingsArgument($pdfSettings)
57 | {
58 | $device = $this->createDevice();
59 |
60 | $this->assertSame(PdfSettings::__DEFAULT, $device->getPdfSettings());
61 | $this->assertSame($pdfSettings, $device->setPdfSettings($pdfSettings)->getPdfSettings());
62 | }
63 |
64 | /**
65 | * @return array
66 | */
67 | public static function providePdfSettings()
68 | {
69 | return [
70 | [PdfSettings::__DEFAULT],
71 | [PdfSettings::SCREEN],
72 | [PdfSettings::EBOOK],
73 | [PdfSettings::PRINTER],
74 | [PdfSettings::PREPRESS]
75 | ];
76 | }
77 |
78 | /**
79 | * @expectedException \InvalidArgumentException
80 | */
81 | public function testPdfSettingsSetterThrowsExceptionOnInvalidArgument()
82 | {
83 | $this->expectExceptionMessage('Invalid PDF settings argument');
84 |
85 | $this->createDevice()->setPdfSettings('/foo');
86 | }
87 |
88 | /**
89 | * @dataProvider provideProcessColorModel
90 | *
91 | * @param string $processColorModel
92 | */
93 | public function testProcessColorModelArgument($processColorModel)
94 | {
95 | $device = $this->createDevice();
96 | $this->assertSame($processColorModel, $device->setProcessColorModel($processColorModel)->getProcessColorModel());
97 | }
98 |
99 | /**
100 | * @return array
101 | */
102 | public static function provideProcessColorModel(): array
103 | {
104 | return [
105 | [ProcessColorModel::DEVICE_RGB],
106 | [ProcessColorModel::DEVICE_CMYK],
107 | [ProcessColorModel::DEVICE_GRAY]
108 | ];
109 | }
110 |
111 | /**
112 | * @expectedException \InvalidArgumentException
113 | */
114 | public function testProcessColorModelSetterThrowsExceptionOnInvalidArgument()
115 | {
116 | $this->expectExceptionMessage('Invalid process color model argument');
117 | $this->createDevice()->setProcessColorModel('/foo');
118 | }
119 |
120 | public static function dataProcessCreation(): array
121 | {
122 | return [
123 | [fn (self $self) => $self->assertProcessCreation(
124 | version: '9.00',
125 | expectSetPDFWrite: true,
126 | )],
127 | [fn (self $self) => $self->assertProcessCreation(
128 | version: '9.10',
129 | expectSetPDFWrite: true,
130 | )],
131 | [fn (self $self) => $self->assertProcessCreation(
132 | version: '9.50',
133 | expectSetPDFWrite: false,
134 | )],
135 | [fn (self $self) => $self->assertProcessCreation(
136 | version: '10.00.0',
137 | expectSetPDFWrite: false,
138 | )]
139 | ];
140 | }
141 |
142 | /**
143 | * @dataProvider dataProcessCreation
144 | */
145 | public function testProcessCreation(callable $closure): void
146 | {
147 | $closure($this);
148 | }
149 |
150 | protected function assertProcessCreation(
151 | string $version,
152 | bool $expectSetPDFWrite,
153 | ): void
154 | {
155 | $process = $this->createDevice($version)->createProcess();
156 |
157 | $command = "'gs' '-sDEVICE=pdfwrite' '-dPDFSETTINGS=/default'";
158 | $this->assertEquals(
159 | $expectSetPDFWrite ? "{$command} '-c' '.setpdfwrite'" : $command,
160 | $this->quoteCommandLine($process->getCommandLine())
161 | );
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/tests/src/Enum/AutoRotatePagesTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\AutoRotatePages;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The auto rotate pages enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\AutoRotatePages::class)]
20 | class AutoRotatePagesTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | AutoRotatePages::NONE,
26 | AutoRotatePages::ALL,
27 | AutoRotatePages::PAGE_BY_PAGE
28 | ];
29 |
30 | $this->assertEquals($values, AutoRotatePages::values());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/src/Enum/BindingTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\Binding;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The binding enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\Binding::class)]
20 | class BindingTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | Binding::LEFT,
26 | Binding::RIGHT
27 | ];
28 |
29 | $this->assertEquals($values, Binding::values());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/src/Enum/CannotEmbedFontPolicyTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\CannotEmbedFontPolicy;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The cannot embed font policy enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\CannotEmbedFontPolicy::class)]
20 | class CannotEmbedFontPolicyTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | CannotEmbedFontPolicy::OK,
26 | CannotEmbedFontPolicy::WARNING,
27 | CannotEmbedFontPolicy::ERROR
28 | ];
29 |
30 | $this->assertEquals($values, CannotEmbedFontPolicy::values());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/src/Enum/ColorAndGrayImageFilterTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\ColorAndGrayImageFilter;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The color and grayscale image filter enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\ColorAndGrayImageFilter::class)]
20 | class ColorAndGrayImageFilterTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | ColorAndGrayImageFilter::DCT_ENCODE,
26 | ColorAndGrayImageFilter::FLATE_ENCODE
27 | ];
28 |
29 | $this->assertEquals($values, ColorAndGrayImageFilter::values());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/src/Enum/ColorConversionStrategyTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\ColorConversionStrategy;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The color conversion strategy enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\ColorConversionStrategy::class)]
20 | class ColorConversionStrategyTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | ColorConversionStrategy::LEAVE_COLOR_UNCHANGED,
26 | ColorConversionStrategy::USE_DEVICE_INDEPENDENT_COLOR,
27 | ColorConversionStrategy::GRAY,
28 | ColorConversionStrategy::SRGB,
29 | ColorConversionStrategy::CMYK
30 | ];
31 |
32 | $this->assertEquals($values, ColorConversionStrategy::values());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/src/Enum/DefaultRenderingIntentTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\DefaultRenderingIntent;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The default rendering intent enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\DefaultRenderingIntent::class)]
20 | class DefaultRenderingIntentTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | DefaultRenderingIntent::__DEFAULT,
26 | DefaultRenderingIntent::PERCEPTUAL,
27 | DefaultRenderingIntent::SATURATION,
28 | DefaultRenderingIntent::RELATIVE_COLORIMETRIC,
29 | DefaultRenderingIntent::ABSOLUTE_COLORIMETRIC
30 | ];
31 |
32 | $this->assertEquals($values, DefaultRenderingIntent::values());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/src/Enum/ImageDownsampleTypeTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\ImageDownsampleType;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The image downsample type enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\ImageDownsampleType::class)]
20 | class ImageDownsampleTypeTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | ImageDownsampleType::AVERAGE,
26 | ImageDownsampleType::BICUBIC,
27 | ImageDownsampleType::SUBSAMPLE,
28 | ImageDownsampleType::NONE,
29 | ];
30 |
31 | $this->assertEquals($values, ImageDownsampleType::values());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/src/Enum/MonoImageFilterTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\MonoImageFilter;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The monochrome image filter enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\MonoImageFilter::class)]
20 | class MonoImageFilterTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | MonoImageFilter::CCITT_FAX_ENCODE,
26 | MonoImageFilter::FLATE_ENCODE,
27 | MonoImageFilter::RUN_LENGTH_ENCODE
28 | ];
29 |
30 | $this->assertEquals($values, MonoImageFilter::values());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/src/Enum/PdfSettingsTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\PdfSettings;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The PDF settings enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\PdfSettings::class)]
20 | class PdfSettingsTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | PdfSettings::__DEFAULT,
26 | PdfSettings::SCREEN,
27 | PdfSettings::EBOOK,
28 | PdfSettings::PRINTER,
29 | PdfSettings::PREPRESS
30 | ];
31 |
32 | $this->assertEquals($values, PdfSettings::values());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/src/Enum/ProcessColorModelTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\ProcessColorModel;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The binding enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\ProcessColorModel::class)]
20 | class ProcessColorModelTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | ProcessColorModel::DEVICE_RGB,
26 | ProcessColorModel::DEVICE_CMYK,
27 | ProcessColorModel::DEVICE_GRAY
28 | ];
29 |
30 | $this->assertEquals($values, ProcessColorModel::values());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/src/Enum/TransferFunctionInfoTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\TransferFunctionInfo;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The transfer function info enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\TransferFunctionInfo::class)]
20 | class TransferFunctionInfoTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | TransferFunctionInfo::PRESERVE,
26 | TransferFunctionInfo::REMOVE,
27 | TransferFunctionInfo::APPLY
28 | ];
29 |
30 | $this->assertEquals($values, TransferFunctionInfo::values());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/src/Enum/UcrAndBgInfoTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Enum;
9 |
10 | use GravityMedia\Ghostscript\Enum\UcrAndBgInfo;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The UCR and BG info enum test class
16 | *
17 | * @package GravityMedia\GhostscriptTest\Enum
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Enum\UcrAndBgInfo::class)]
20 | class UcrAndBgInfoTest extends TestCase
21 | {
22 | public function testValues()
23 | {
24 | $values = [
25 | UcrAndBgInfo::PRESERVE,
26 | UcrAndBgInfo::REMOVE
27 | ];
28 |
29 | $this->assertEquals($values, UcrAndBgInfo::values());
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/src/GhostscriptTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest;
9 |
10 | use GravityMedia\Ghostscript\Device\BoundingBoxInfo;
11 | use GravityMedia\Ghostscript\Device\Inkcov;
12 | use GravityMedia\Ghostscript\Device\NoDisplay;
13 | use GravityMedia\Ghostscript\Device\PdfInfo;
14 | use GravityMedia\Ghostscript\Device\PdfWrite;
15 | use GravityMedia\Ghostscript\Ghostscript;
16 | use GravityMedia\Ghostscript\Process\Arguments;
17 | use PHPUnit\Framework\Attributes\CoversClass;
18 | use PHPUnit\Framework\Attributes\UsesClass;
19 | use PHPUnit\Framework\TestCase;
20 |
21 | /**
22 | * The Ghostscript test class
23 | *
24 | * @package GravityMedia\GhostscriptTest
25 | */
26 | #[CoversClass(\GravityMedia\Ghostscript\Ghostscript::class)]
27 | #[UsesClass(\GravityMedia\Ghostscript\Input::class)]
28 | #[UsesClass(\GravityMedia\Ghostscript\Enum\PdfSettings::class)]
29 | #[UsesClass(\GravityMedia\Ghostscript\Device\AbstractDevice::class)]
30 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\EpsTrait::class)]
31 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\FontTrait::class)]
32 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\IccColorTrait::class)]
33 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\InteractionTrait::class)]
34 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\OtherTrait::class)]
35 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\OutputSelectionTrait::class)]
36 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\PageTrait::class)]
37 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\RenderingTrait::class)]
38 | #[UsesClass(\GravityMedia\Ghostscript\Device\CommandLineParameters\ResourceTrait::class)]
39 | #[UsesClass(\GravityMedia\Ghostscript\Device\DistillerParametersTrait::class)]
40 | #[UsesClass(\GravityMedia\Ghostscript\Device\BoundingBoxInfo::class)]
41 | #[UsesClass(\GravityMedia\Ghostscript\Device\Inkcov::class)]
42 | #[UsesClass(\GravityMedia\Ghostscript\Device\NoDisplay::class)]
43 | #[UsesClass(\GravityMedia\Ghostscript\Device\PdfInfo::class)]
44 | #[UsesClass(\GravityMedia\Ghostscript\Device\PdfWrite::class)]
45 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
46 | #[UsesClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
47 | class GhostscriptTest extends TestCase
48 | {
49 | public function testCreateGhostscriptObject()
50 | {
51 | $this->assertInstanceOf(Ghostscript::class, new Ghostscript());
52 | }
53 |
54 | /**
55 | * @dataProvider provideOptions
56 | *
57 | * @param array $options
58 | * @param string $name
59 | * @param mixed $value
60 | */
61 | public function testGetOption(array $options, $name, $value)
62 | {
63 | $instance = new Ghostscript($options);
64 |
65 | $this->assertSame($value, $instance->getOption($name));
66 | }
67 |
68 | /**
69 | * @return array
70 | */
71 | public static function provideOptions()
72 | {
73 | return [
74 | [[], 'foo', null],
75 | [['foo' => 'bar'], 'foo', 'bar']
76 | ];
77 | }
78 |
79 | public function testGetVersion()
80 | {
81 | $instance = new Ghostscript();
82 |
83 | $this->assertMatchesRegularExpression('/^[0-9]+\.[0-9\.]+$/', $instance->getVersion());
84 | }
85 |
86 | public function testGetVersionThrowsExceptionOnFailure()
87 | {
88 | $this->expectExceptionMessageMatches('/exec: \/foo\/bar\/baz/');
89 | $ghostscript = new Ghostscript(['bin' => '/foo/bar/baz']);
90 | $ghostscript->getVersion();
91 | }
92 |
93 | public function testProcessArgumentsCreation()
94 | {
95 | $method = new \ReflectionMethod(Ghostscript::class, 'createArguments');
96 | $method->setAccessible(true);
97 |
98 | $this->assertInstanceOf(Arguments::class, $method->invoke(new Ghostscript()));
99 | }
100 |
101 | public function testPdfDeviceCreation()
102 | {
103 | $instance = new Ghostscript();
104 |
105 | $this->assertInstanceOf(PdfWrite::class, $instance->createPdfDevice());
106 | }
107 |
108 | public function testNullDeviceCreation()
109 | {
110 | $instance = new Ghostscript();
111 |
112 | $this->assertInstanceOf(NoDisplay::class, $instance->createNoDisplayDevice());
113 | }
114 |
115 | public function testPdfInfoDeviceCreation()
116 | {
117 | $instance = new Ghostscript();
118 | $pdfInfoPath = 'path/to/pdf_info.ps';
119 | $pdfInfo = $instance->createPdfInfoDevice($pdfInfoPath);
120 |
121 | $this->assertInstanceOf(PdfInfo::class, $pdfInfo);
122 |
123 | $field = new \ReflectionProperty(PdfInfo::class, 'pdfInfoPath');
124 | $field->setAccessible(true);
125 | $this->assertEquals($pdfInfoPath, $field->getValue($pdfInfo));
126 | }
127 |
128 | public function testBoundingBoxInfoCreation()
129 | {
130 | $instance = new Ghostscript();
131 |
132 | $this->assertInstanceOf(BoundingBoxInfo::class, $instance->createBoundingBoxInfoDevice());
133 | }
134 |
135 | public function testInkcovDeviceCreation()
136 | {
137 | $instance = new Ghostscript();
138 | $device = $instance->createInkcovDevice();
139 |
140 | $this->assertInstanceOf(Inkcov::class, $device);
141 | $this->assertEquals("'gs' '-o' '-' '-sDEVICE=inkcov'", $device->createProcess()->getCommandLine());
142 | }
143 |
144 | /**
145 | * @dataProvider provideTimeout
146 | *
147 | * @param null|int $value
148 | * @param null|int $result
149 | */
150 | public function testTimeoutOption($value, $result)
151 | {
152 | $instance = new Ghostscript(['timeout' => $value]);
153 | $device = $instance->createPdfDevice('/path/to/output/file.pdf');
154 | $process = $device->createProcess(__DIR__ . '/../data/input.pdf');
155 |
156 | $this->assertEquals($result, $process->getTimeout());
157 | }
158 |
159 | /**
160 | * @return array
161 | */
162 | public static function provideTimeout()
163 | {
164 | return [
165 | [42, 42],
166 | [0, null],
167 | [null, null],
168 | ];
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/tests/src/InputTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest;
9 |
10 | use GravityMedia\Ghostscript\Input;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The input test class
16 | *
17 | * @package GravityMedia\GhostscriptTest
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Input::class)]
20 | class InputTest extends TestCase
21 | {
22 | public function testDefaultInput()
23 | {
24 | $input = new Input();
25 |
26 | $this->assertNull($input->getProcessInput());
27 | $this->assertNull($input->getPostScriptCode());
28 | $this->assertContainsOnly('array', $input->getFiles());
29 | $this->assertCount(0, $input->getFiles());
30 | }
31 |
32 | public function testInput()
33 | {
34 | $input = new Input();
35 | $input->setProcessInput('input');
36 | $input->setPostScriptCode('.setpdfwrite');
37 | $input->addFile('/path/to/output/file.pdf');
38 | $input->setFiles(['/path/to/output/file.pdf']);
39 |
40 | $this->assertSame('input', $input->getProcessInput());
41 | $this->assertSame('.setpdfwrite', $input->getPostScriptCode());
42 | $this->assertContainsOnly('string', $input->getFiles());
43 | $this->assertCount(1, $input->getFiles());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/src/Process/ArgumentTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Process;
9 |
10 | use GravityMedia\Ghostscript\Process\Argument;
11 | use PHPUnit\Framework\Attributes\CoversClass;
12 | use PHPUnit\Framework\TestCase;
13 |
14 | /**
15 | * The process argument test class.
16 | *
17 | * @package GravityMedia\GhostscriptTest\Process
18 | */
19 | #[CoversClass(\GravityMedia\Ghostscript\Process\Argument::class)]
20 | class ArgumentTest extends TestCase
21 | {
22 | /**
23 | * @dataProvider provideConstructorArguments
24 | *
25 | * @param string $name
26 | * @param mixed $value
27 | */
28 | public function testArgumentConstruction($name, $value)
29 | {
30 | $instance = new Argument($name, $value);
31 |
32 | $this->assertSame($name, $instance->getName());
33 | $this->assertSame($value, $instance->getValue());
34 | }
35 |
36 | /**
37 | * @return array
38 | */
39 | public static function provideConstructorArguments()
40 | {
41 | return [
42 | ['name', null],
43 | ['name', 'value']
44 | ];
45 | }
46 |
47 | /**
48 | * @dataProvider provideArgumentStrings
49 | *
50 | * @param string $string
51 | * @param string $name
52 | * @param mixed $value
53 | */
54 | public function testArgumentConstructionFromString($string, $name, $value)
55 | {
56 | $instance = Argument::fromString($string);
57 |
58 | $this->assertSame($name, $instance->getName());
59 | $this->assertSame($value, $instance->getValue());
60 | }
61 |
62 | /**
63 | * @dataProvider provideArgumentStrings
64 | *
65 | * @param string $string
66 | * @param string $name
67 | * @param mixed $value
68 | */
69 | public function testArgumentStringResult($string, $name, $value)
70 | {
71 | $instance = new Argument($name, $value);
72 |
73 | $this->assertSame($string, $instance->toString());
74 | }
75 |
76 | /**
77 | * @return array
78 | */
79 | public static function provideArgumentStrings()
80 | {
81 | return [
82 | ['name', 'name', null],
83 | ['name=value', 'name', 'value']
84 | ];
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tests/src/Process/ArgumentsTest.php:
--------------------------------------------------------------------------------
1 |
6 | */
7 |
8 | namespace GravityMedia\GhostscriptTest\Process;
9 |
10 | use GravityMedia\Ghostscript\Process\Argument;
11 | use GravityMedia\Ghostscript\Process\Arguments;
12 | use PHPUnit\Framework\Attributes\CoversClass;
13 | use PHPUnit\Framework\Attributes\UsesClass;
14 | use PHPUnit\Framework\TestCase;
15 |
16 | /**
17 | * The arguments test class.
18 | *
19 | * @package GravityMedia\GhostscriptTest\Process
20 | */
21 | #[CoversClass(\GravityMedia\Ghostscript\Process\Arguments::class)]
22 | #[UsesClass(\GravityMedia\Ghostscript\Process\Argument::class)]
23 | class ArgumentsTest extends TestCase
24 | {
25 | public function testArgumentsConstruction()
26 | {
27 | $instance = new Arguments();
28 |
29 | $this->assertEquals([], $instance->toArray());
30 | }
31 |
32 | /**
33 | * @expectedException \InvalidArgumentException
34 | */
35 | public function testArgumentConversionThrowsExceptionOnInvalidArgument()
36 | {
37 | $this->expectExceptionMessage('Invalid argument');
38 |
39 | $method = new \ReflectionMethod(Arguments::class, 'convertArgument');
40 | $method->setAccessible(true);
41 |
42 | $method->invoke(new Arguments(), 0);
43 | }
44 |
45 | /**
46 | * @dataProvider provideArgumentsForAddition
47 | *
48 | * @param array $arguments
49 | * @param array $expected
50 | */
51 | public function testAddingArguments($arguments, $expected)
52 | {
53 | $instance = new Arguments();
54 | $instance->addArguments($arguments);
55 |
56 | $this->assertEquals($expected, $instance->toArray());
57 | }
58 |
59 | /**
60 | * @return array
61 | */
62 | public static function provideArgumentsForAddition()
63 | {
64 | return [
65 | [['foo'], ['foo']],
66 | [['foo', 'foo'], ['foo', 'foo']],
67 | [['foo', 'foo=bar'], ['foo', 'foo=bar']]
68 | ];
69 | }
70 |
71 | /**
72 | * @dataProvider provideArgumentsForSetting
73 | *
74 | * @param array $arguments
75 | * @param array $expected
76 | */
77 | public function testSettingArguments($arguments, $expected)
78 | {
79 | $instance = new Arguments();
80 | $instance->setArguments($arguments);
81 |
82 | $this->assertEquals($expected, $instance->toArray());
83 | }
84 |
85 | /**
86 | * @return array
87 | */
88 | public static function provideArgumentsForSetting()
89 | {
90 | return [
91 | [['foo'], ['foo']],
92 | [['foo', 'foo'], ['foo']],
93 | [['foo', 'foo=bar'], ['foo=bar']]
94 | ];
95 | }
96 |
97 | public function testGetArgument()
98 | {
99 | $instance = new Arguments();
100 | $instance->setArgument('foo=bar');
101 |
102 | $this->assertInstanceOf(Argument::class, $instance->getArgument('foo'));
103 | $this->assertSame('bar', $instance->getArgument('foo')->getValue());
104 | $this->assertNull($instance->getArgument('bar'));
105 | }
106 | }
107 |
--------------------------------------------------------------------------------