Browse Source

aqui va los pdfs y eso. editar gitignore pa coger esto

parent
commit
e93fc5458e
100 changed files with 25658 additions and 4 deletions
  1. 10
    4
      .gitignore
  2. 208
    0
      app/config/app.php
  3. BIN
      app/storage/annual_pdfs/05-04-2022-for-15.pdf
  4. BIN
      app/storage/annual_pdfs/07-04-2022-for-15.pdf
  5. BIN
      app/storage/annual_pdfs/plan-on-07-04-2022-for-15.pdf
  6. 4
    0
      vendor/barryvdh/laravel-dompdf/.gitignore
  7. 28
    0
      vendor/barryvdh/laravel-dompdf/composer.json
  8. 47
    0
      vendor/barryvdh/laravel-dompdf/readme.md
  9. 45
    0
      vendor/barryvdh/laravel-dompdf/src/Facade.php
  10. 255
    0
      vendor/barryvdh/laravel-dompdf/src/PDF.php
  11. 77
    0
      vendor/barryvdh/laravel-dompdf/src/ServiceProvider.php
  12. 266
    0
      vendor/barryvdh/laravel-dompdf/src/config/config.php
  13. 3
    0
      vendor/barryvdh/laravel-ide-helper/.gitignore
  14. 36
    0
      vendor/barryvdh/laravel-ide-helper/composer.json
  15. 5
    0
      vendor/barryvdh/laravel-ide-helper/provides.json
  16. 97
    0
      vendor/barryvdh/laravel-ide-helper/readme.md
  17. 276
    0
      vendor/barryvdh/laravel-ide-helper/src/Alias.php
  18. 158
    0
      vendor/barryvdh/laravel-ide-helper/src/Console/GeneratorCommand.php
  19. 510
    0
      vendor/barryvdh/laravel-ide-helper/src/Console/ModelsCommand.php
  20. 196
    0
      vendor/barryvdh/laravel-ide-helper/src/Generator.php
  21. 70
    0
      vendor/barryvdh/laravel-ide-helper/src/IdeHelperServiceProvider.php
  22. 300
    0
      vendor/barryvdh/laravel-ide-helper/src/Method.php
  23. 78
    0
      vendor/barryvdh/laravel-ide-helper/src/config/config.php
  24. 39
    0
      vendor/barryvdh/laravel-ide-helper/src/views/ide-helper.php
  25. 13
    0
      vendor/dompdf/dompdf/.gitattributes
  26. 8
    0
      vendor/dompdf/dompdf/.gitignore
  27. 3
    0
      vendor/dompdf/dompdf/.gitmodules
  28. 76
    0
      vendor/dompdf/dompdf/CONTRIBUTING.md
  29. 456
    0
      vendor/dompdf/dompdf/LICENSE.LGPL
  30. 133
    0
      vendor/dompdf/dompdf/README.md
  31. 23
    0
      vendor/dompdf/dompdf/composer.json
  32. 279
    0
      vendor/dompdf/dompdf/dompdf.php
  33. 41
    0
      vendor/dompdf/dompdf/dompdf_config.custom.inc.php
  34. 398
    0
      vendor/dompdf/dompdf/dompdf_config.inc.php
  35. 125
    0
      vendor/dompdf/dompdf/include/absolute_positioner.cls.php
  36. 759
    0
      vendor/dompdf/dompdf/include/abstract_renderer.cls.php
  37. 592
    0
      vendor/dompdf/dompdf/include/attribute_translator.cls.php
  38. 86
    0
      vendor/dompdf/dompdf/include/autoload.inc.php
  39. 234
    0
      vendor/dompdf/dompdf/include/block_frame_decorator.cls.php
  40. 805
    0
      vendor/dompdf/dompdf/include/block_frame_reflower.cls.php
  41. 57
    0
      vendor/dompdf/dompdf/include/block_positioner.cls.php
  42. 230
    0
      vendor/dompdf/dompdf/include/block_renderer.cls.php
  43. 164
    0
      vendor/dompdf/dompdf/include/cached_pdf_decorator.cls.php
  44. 385
    0
      vendor/dompdf/dompdf/include/canvas.cls.php
  45. 63
    0
      vendor/dompdf/dompdf/include/canvas_factory.cls.php
  46. 790
    0
      vendor/dompdf/dompdf/include/cellmap.cls.php
  47. 877
    0
      vendor/dompdf/dompdf/include/cpdf_adapter.cls.php
  48. 287
    0
      vendor/dompdf/dompdf/include/css_color.cls.php
  49. 1101
    0
      vendor/dompdf/dompdf/include/dompdf.cls.php
  50. 26
    0
      vendor/dompdf/dompdf/include/dompdf_exception.cls.php
  51. 26
    0
      vendor/dompdf/dompdf/include/dompdf_image_exception.cls.php
  52. 8
    0
      vendor/dompdf/dompdf/include/file.skel
  53. 88
    0
      vendor/dompdf/dompdf/include/fixed_positioner.cls.php
  54. 382
    0
      vendor/dompdf/dompdf/include/font_metrics.cls.php
  55. 1191
    0
      vendor/dompdf/dompdf/include/frame.cls.php
  56. 717
    0
      vendor/dompdf/dompdf/include/frame_decorator.cls.php
  57. 252
    0
      vendor/dompdf/dompdf/include/frame_factory.cls.php
  58. 458
    0
      vendor/dompdf/dompdf/include/frame_reflower.cls.php
  59. 241
    0
      vendor/dompdf/dompdf/include/frame_tree.cls.php
  60. 1036
    0
      vendor/dompdf/dompdf/include/functions.inc.php
  61. 840
    0
      vendor/dompdf/dompdf/include/gd_adapter.cls.php
  62. 185
    0
      vendor/dompdf/dompdf/include/image_cache.cls.php
  63. 80
    0
      vendor/dompdf/dompdf/include/image_frame_decorator.cls.php
  64. 186
    0
      vendor/dompdf/dompdf/include/image_frame_reflower.cls.php
  65. 119
    0
      vendor/dompdf/dompdf/include/image_renderer.cls.php
  66. 74
    0
      vendor/dompdf/dompdf/include/inline_frame_decorator.cls.php
  67. 66
    0
      vendor/dompdf/dompdf/include/inline_frame_reflower.cls.php
  68. 70
    0
      vendor/dompdf/dompdf/include/inline_positioner.cls.php
  69. 190
    0
      vendor/dompdf/dompdf/include/inline_renderer.cls.php
  70. 37
    0
      vendor/dompdf/dompdf/include/javascript_embedder.cls.php
  71. 252
    0
      vendor/dompdf/dompdf/include/line_box.cls.php
  72. 65
    0
      vendor/dompdf/dompdf/include/list_bullet_frame_decorator.cls.php
  73. 33
    0
      vendor/dompdf/dompdf/include/list_bullet_frame_reflower.cls.php
  74. 143
    0
      vendor/dompdf/dompdf/include/list_bullet_image_frame_decorator.cls.php
  75. 73
    0
      vendor/dompdf/dompdf/include/list_bullet_positioner.cls.php
  76. 236
    0
      vendor/dompdf/dompdf/include/list_bullet_renderer.cls.php
  77. 26
    0
      vendor/dompdf/dompdf/include/null_frame_decorator.cls.php
  78. 21
    0
      vendor/dompdf/dompdf/include/null_frame_reflower.cls.php
  79. 23
    0
      vendor/dompdf/dompdf/include/null_positioner.cls.php
  80. 126
    0
      vendor/dompdf/dompdf/include/page_cache.cls.php
  81. 592
    0
      vendor/dompdf/dompdf/include/page_frame_decorator.cls.php
  82. 186
    0
      vendor/dompdf/dompdf/include/page_frame_reflower.cls.php
  83. 1085
    0
      vendor/dompdf/dompdf/include/pdflib_adapter.cls.php
  84. 48
    0
      vendor/dompdf/dompdf/include/php_evaluator.cls.php
  85. 51
    0
      vendor/dompdf/dompdf/include/positioner.cls.php
  86. 290
    0
      vendor/dompdf/dompdf/include/renderer.cls.php
  87. 2435
    0
      vendor/dompdf/dompdf/include/style.cls.php
  88. 1418
    0
      vendor/dompdf/dompdf/include/stylesheet.cls.php
  89. 102
    0
      vendor/dompdf/dompdf/include/table_cell_frame_decorator.cls.php
  90. 119
    0
      vendor/dompdf/dompdf/include/table_cell_frame_reflower.cls.php
  91. 28
    0
      vendor/dompdf/dompdf/include/table_cell_positioner.cls.php
  92. 155
    0
      vendor/dompdf/dompdf/include/table_cell_renderer.cls.php
  93. 334
    0
      vendor/dompdf/dompdf/include/table_frame_decorator.cls.php
  94. 578
    0
      vendor/dompdf/dompdf/include/table_frame_reflower.cls.php
  95. 48
    0
      vendor/dompdf/dompdf/include/table_row_frame_decorator.cls.php
  96. 61
    0
      vendor/dompdf/dompdf/include/table_row_frame_reflower.cls.php
  97. 66
    0
      vendor/dompdf/dompdf/include/table_row_group_frame_decorator.cls.php
  98. 59
    0
      vendor/dompdf/dompdf/include/table_row_group_frame_reflower.cls.php
  99. 40
    0
      vendor/dompdf/dompdf/include/table_row_group_renderer.cls.php
  100. 0
    0
      vendor/dompdf/dompdf/include/table_row_positioner.cls.php

+ 10
- 4
.gitignore View File

@@ -1,5 +1,5 @@
1 1
 /bootstrap/compiled.php
2
-/vendor
2
+
3 3
 composer.phar
4 4
 composer.lock
5 5
 .env.*.php
@@ -7,11 +7,17 @@ composer.lock
7 7
 .DS_Store
8 8
 Thumbs.db
9 9
 app/database/csv/*
10
-app/config/local/*
11
-app/config/app.php
10
+app/config/packages/*
11
+app/config/testing/*
12 12
 app/config/database.php
13
+app/config/*
14
+
15
+!app/config/app.php
13 16
 node_modules/
14
-app/config/
17
+vendor/*
18
+!vendor/barryvdh/
19
+!vendor/dompdf/
20
+
15 21
 app/controllers/AuthController.php
16 22
 app/controllers/AuthController.php
17 23
 bootstrap/start.php

+ 208
- 0
app/config/app.php View File

@@ -0,0 +1,208 @@
1
+<?php
2
+error_reporting(error_reporting() & ~E_DEPRECATED);
3
+return array(
4
+
5
+	/*
6
+	|--------------------------------------------------------------------------
7
+	| Application Debug Mode
8
+	|--------------------------------------------------------------------------
9
+	|
10
+	| When your application is in debug mode, detailed error messages with
11
+	| stack traces will be shown on every error that occurs within your
12
+	| application. If disabled, a simple generic error page is shown.
13
+	|
14
+	*/
15
+
16
+	//'debug' => $_ENV['APP_DEBUG'] ?: false,
17
+
18
+	'debug' => true,
19
+	/*
20
+	|--------------------------------------------------------------------------
21
+	| Application URL
22
+	|--------------------------------------------------------------------------
23
+	|
24
+	| This URL is used by the console to properly generate URLs when using
25
+	| the Artisan command line tool. You should set this to the root of
26
+	| your application so that it is used when running Artisan tasks.
27
+	|
28
+	*/ //$_ENV['APP_URL'] ?:
29
+
30
+	'url' =>  'http://localhost',
31
+
32
+	/*
33
+	|--------------------------------------------------------------------------
34
+	| Application Timezone
35
+	|--------------------------------------------------------------------------
36
+	|
37
+	| Here you may specify the default timezone for your application, which
38
+	| will be used by the PHP date and date-time functions. We have gone
39
+	| ahead and set this to a sensible default for you out of the box.
40
+	|
41
+	*/
42
+
43
+	'timezone' => 'America/Puerto_Rico',
44
+
45
+	/*
46
+	|--------------------------------------------------------------------------
47
+	| Application Locale Configuration
48
+	|--------------------------------------------------------------------------
49
+	|
50
+	| The application locale determines the default locale that will be used
51
+	| by the translation service provider. You are free to set this value
52
+	| to any of the locales which will be supported by the application.
53
+	|
54
+	*/
55
+
56
+	'locale' => 'en',
57
+
58
+	/*
59
+	|--------------------------------------------------------------------------
60
+	| Application Fallback Locale
61
+	|--------------------------------------------------------------------------
62
+	|
63
+	| The fallback locale determines the locale to use when the current one
64
+	| is not available. You may change the value to correspond to any of
65
+	| the language folders that are provided through your application.
66
+	|
67
+	*/
68
+
69
+	'fallback_locale' => 'en',
70
+
71
+	/*
72
+	|--------------------------------------------------------------------------
73
+	| Encryption Key
74
+	|--------------------------------------------------------------------------
75
+	|
76
+	| This key is used by the Illuminate encrypter service and should be set
77
+	| to a random, 32 character string, otherwise these encrypted strings
78
+	| will not be safe. Please do this before deploying an application!
79
+	|
80
+	*/
81
+
82
+	// 'key' => 'YourSecretKey!!!',
83
+	'key' => 'JozBz0yQBrZ5kEcPvgxch3RR3E3INSGs',
84
+
85
+	'cipher' => MCRYPT_RIJNDAEL_256,
86
+
87
+	/*
88
+	|--------------------------------------------------------------------------
89
+	| Autoloaded Service Providers
90
+	|--------------------------------------------------------------------------
91
+	|
92
+	| The service providers listed here will be automatically loaded on the
93
+	| request to your application. Feel free to add your own services to
94
+	| this array to grant expanded functionality to your applications.
95
+	|
96
+	*/
97
+
98
+	'providers' => array(
99
+
100
+		'Illuminate\Foundation\Providers\ArtisanServiceProvider',
101
+		'Illuminate\Auth\AuthServiceProvider',
102
+		'Illuminate\Cache\CacheServiceProvider',
103
+		'Illuminate\Session\CommandsServiceProvider',
104
+		'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
105
+		'Illuminate\Routing\ControllerServiceProvider',
106
+		'Illuminate\Cookie\CookieServiceProvider',
107
+		'Illuminate\Database\DatabaseServiceProvider',
108
+		'Illuminate\Encryption\EncryptionServiceProvider',
109
+		'Illuminate\Filesystem\FilesystemServiceProvider',
110
+		'Illuminate\Hashing\HashServiceProvider',
111
+		'Illuminate\Html\HtmlServiceProvider',
112
+		'Illuminate\Log\LogServiceProvider',
113
+		'Illuminate\Mail\MailServiceProvider',
114
+		'Illuminate\Database\MigrationServiceProvider',
115
+		'Illuminate\Pagination\PaginationServiceProvider',
116
+		'Illuminate\Queue\QueueServiceProvider',
117
+		'Illuminate\Redis\RedisServiceProvider',
118
+		'Illuminate\Remote\RemoteServiceProvider',
119
+		'Illuminate\Auth\Reminders\ReminderServiceProvider',
120
+		'Illuminate\Database\SeedServiceProvider',
121
+		'Illuminate\Session\SessionServiceProvider',
122
+		'Illuminate\Translation\TranslationServiceProvider',
123
+		'Illuminate\Validation\ValidationServiceProvider',
124
+		'Illuminate\View\ViewServiceProvider',
125
+		'Illuminate\Workbench\WorkbenchServiceProvider',
126
+		'Way\Generators\GeneratorsServiceProvider',
127
+		'Barryvdh\DomPDF\ServiceProvider',
128
+		// 'Cornford\Backup\Providers\BackupServiceProvider',
129
+		'Zizaco\Entrust\EntrustServiceProvider',
130
+		//To be able to use PDF
131
+		//'Thujohn\Pdf\PdfServiceProvider',
132
+
133
+	),
134
+
135
+	/*
136
+	|--------------------------------------------------------------------------
137
+	| Service Provider Manifest
138
+	|--------------------------------------------------------------------------
139
+	|
140
+	| The service provider manifest is used by Laravel to lazy load service
141
+	| providers which are not needed for each request, as well to keep a
142
+	| list of all of the services. Here, you may set its storage spot.
143
+	|
144
+	*/
145
+
146
+	'manifest' => storage_path() . '/meta',
147
+
148
+	/*
149
+	|--------------------------------------------------------------------------
150
+	| Class Aliases
151
+	|--------------------------------------------------------------------------
152
+	|
153
+	| This array of class aliases will be registered when this application
154
+	| is started. However, feel free to register as many as you wish as
155
+	| the aliases are "lazy" loaded so they don't hinder performance.
156
+	|
157
+	*/
158
+
159
+	'aliases' => array(
160
+
161
+		'App'               => 'Illuminate\Support\Facades\App',
162
+		'Artisan'           => 'Illuminate\Support\Facades\Artisan',
163
+		'Auth'              => 'Illuminate\Support\Facades\Auth',
164
+		//'Backup'	        => 'Cornford\Backup\Facades\Backup',
165
+		'Filesystem'        => 'Illuminate\Filesystem\Filesystem',
166
+		'Blade'             => 'Illuminate\Support\Facades\Blade',
167
+		'Cache'             => 'Illuminate\Support\Facades\Cache',
168
+		'ClassLoader'       => 'Illuminate\Support\ClassLoader',
169
+		'Config'            => 'Illuminate\Support\Facades\Config',
170
+		'Controller'        => 'Illuminate\Routing\Controller',
171
+		'Cookie'            => 'Illuminate\Support\Facades\Cookie',
172
+		'Crypt'             => 'Illuminate\Support\Facades\Crypt',
173
+		'DB'                => 'Illuminate\Support\Facades\DB',
174
+		'Eloquent'          => 'Illuminate\Database\Eloquent\Model',
175
+		'Event'             => 'Illuminate\Support\Facades\Event',
176
+		'File'              => 'Illuminate\Support\Facades\File',
177
+		'Form'              => 'Illuminate\Support\Facades\Form',
178
+		'Hash'              => 'Illuminate\Support\Facades\Hash',
179
+		'HTML'              => 'Illuminate\Support\Facades\HTML',
180
+		'Input'             => 'Illuminate\Support\Facades\Input',
181
+		'Lang'              => 'Illuminate\Support\Facades\Lang',
182
+		'Log'               => 'Illuminate\Support\Facades\Log',
183
+		'Mail'              => 'Illuminate\Support\Facades\Mail',
184
+		'Paginator'         => 'Illuminate\Support\Facades\Paginator',
185
+		'Password'          => 'Illuminate\Support\Facades\Password',
186
+		'Queue'             => 'Illuminate\Support\Facades\Queue',
187
+		'Redirect'          => 'Illuminate\Support\Facades\Redirect',
188
+		'Redis'             => 'Illuminate\Support\Facades\Redis',
189
+		'Request'           => 'Illuminate\Support\Facades\Request',
190
+		'Response'          => 'Illuminate\Support\Facades\Response',
191
+		'Route'             => 'Illuminate\Support\Facades\Route',
192
+		'Schema'            => 'Illuminate\Support\Facades\Schema',
193
+		'Seeder'            => 'Illuminate\Database\Seeder',
194
+		'Session'           => 'Illuminate\Support\Facades\Session',
195
+		'SoftDeletingTrait' => 'Illuminate\Database\Eloquent\SoftDeletingTrait',
196
+		'SSH'               => 'Illuminate\Support\Facades\SSH',
197
+		'Str'               => 'Illuminate\Support\Str',
198
+		'URL'               => 'Illuminate\Support\Facades\URL',
199
+		'Validator'         => 'Illuminate\Support\Facades\Validator',
200
+		'View'              => 'Illuminate\Support\Facades\View',
201
+		'PDF'				=> 'Barryvdh\DomPDF\Facade',
202
+		//'PDF' 				=> 'Thujohn\Pdf\PdfFacade',
203
+		'Entrust' => 'Zizaco\Entrust\EntrustFacade'
204
+
205
+
206
+	),
207
+
208
+);

BIN
app/storage/annual_pdfs/05-04-2022-for-15.pdf View File


BIN
app/storage/annual_pdfs/07-04-2022-for-15.pdf View File


BIN
app/storage/annual_pdfs/plan-on-07-04-2022-for-15.pdf View File


+ 4
- 0
vendor/barryvdh/laravel-dompdf/.gitignore View File

@@ -0,0 +1,4 @@
1
+/vendor
2
+composer.phar
3
+composer.lock
4
+.DS_Store

+ 28
- 0
vendor/barryvdh/laravel-dompdf/composer.json View File

@@ -0,0 +1,28 @@
1
+{
2
+    "name": "barryvdh/laravel-dompdf",
3
+    "description": "A DOMPDF Wrapper for Laravel",
4
+    "license": "MIT",
5
+    "keywords": ["laravel", "dompdf", "pdf"],
6
+    "authors": [
7
+        {
8
+            "name": "Barry vd. Heuvel",
9
+            "email": "barryvdh@gmail.com"
10
+        }
11
+    ],
12
+    "require": {
13
+        "php": ">=5.3.0",
14
+        "illuminate/support": "~4.0",
15
+        "dompdf/dompdf": "0.6.*"
16
+    },
17
+
18
+    "autoload": {
19
+        "psr-4": {
20
+            "Barryvdh\\DomPDF\\": "src"
21
+        }
22
+    },
23
+    "extra": {
24
+        "branch-alias": {
25
+            "dev-master": "0.4-dev"
26
+        }
27
+    }
28
+}

+ 47
- 0
vendor/barryvdh/laravel-dompdf/readme.md View File

@@ -0,0 +1,47 @@
1
+## DOMPDF Wrapper for Laravel 4
2
+
3
+Require this package in your composer.json and update composer. This will download the package and the dompdf + fontlib libraries also.
4
+
5
+    "barryvdh/laravel-dompdf": "0.4.*"
6
+
7
+After updating composer, add the ServiceProvider to the providers array in app/config/app.php
8
+
9
+    'Barryvdh\DomPDF\ServiceProvider',
10
+
11
+You can optionally use the facade for shorter code. Add this to your facades:
12
+
13
+    'PDF' => 'Barryvdh\DomPDF\Facade',
14
+
15
+You can create a new DOMPDF instance and load a HTML string, file or view name. You can save it to a file, or stream (show in browser) or download.
16
+
17
+    $pdf = App::make('dompdf');
18
+    $pdf->loadHTML('<h1>Test</h1>');
19
+    return $pdf->stream();
20
+
21
+Or use the facade:
22
+
23
+    $pdf = PDF::loadView('pdf.invoice', $data);
24
+    return $pdf->download('invoice.pdf');
25
+
26
+You can chain the methods:
27
+
28
+    return PDF::loadFile(public_path().'/myfile.html')->save('/path-to/my_stored_file.pdf')->stream('download.pdf');
29
+
30
+You can change the orientation and paper size, and hide or show errors (by default, errors are shown when debug is on)
31
+
32
+    PDF::loadHTML($html)->setPaper('a4')->setOrientation('landscape')->setWarnings(false)->save('myfile.pdf')
33
+
34
+If you need the output as a string, you can get the rendered PDF with the output() function, so you can save/output it yourself.
35
+
36
+You can  publish the config-file to change some settings (default paper etc).
37
+
38
+    php artisan config:publish barryvdh/laravel-dompdf
39
+
40
+### Tip: UTF-8 support
41
+In your templates, set the UTF-8 Metatag:
42
+
43
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
44
+
45
+### License
46
+
47
+This DOMPDF Wrapper for Laravel4 is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

+ 45
- 0
vendor/barryvdh/laravel-dompdf/src/Facade.php View File

@@ -0,0 +1,45 @@
1
+<?php
2
+namespace Barryvdh\DomPDF;
3
+
4
+use Illuminate\Support\Facades\Facade as IlluminateFacade;
5
+
6
+class Facade extends IlluminateFacade {
7
+
8
+    /**
9
+     * Get the registered name of the component.
10
+     *
11
+     * @return string
12
+     */
13
+    protected static function getFacadeAccessor() { return 'dompdf'; }
14
+
15
+    /**
16
+     * Resolve a new instance
17
+     */
18
+    public static function __callStatic($method, $args)
19
+    {
20
+        $instance = static::$app->make(static::getFacadeAccessor());
21
+
22
+        switch (count($args))
23
+        {
24
+            case 0:
25
+                return $instance->$method();
26
+
27
+            case 1:
28
+                return $instance->$method($args[0]);
29
+
30
+            case 2:
31
+                return $instance->$method($args[0], $args[1]);
32
+
33
+            case 3:
34
+                return $instance->$method($args[0], $args[1], $args[2]);
35
+
36
+            case 4:
37
+                return $instance->$method($args[0], $args[1], $args[2], $args[3]);
38
+
39
+            default:
40
+                return call_user_func_array(array($instance, $method), $args);
41
+        }
42
+    }
43
+
44
+
45
+}

+ 255
- 0
vendor/barryvdh/laravel-dompdf/src/PDF.php View File

@@ -0,0 +1,255 @@
1
+<?php
2
+
3
+namespace Barryvdh\DomPDF;
4
+
5
+use Exception;
6
+use Illuminate\Config\Repository as ConfigRepository;
7
+use Illuminate\Filesystem\Filesystem;
8
+use Illuminate\Http\Response;
9
+
10
+/**
11
+ * A Laravel wrapper for DOMPDF
12
+ *
13
+ * @package laravel-dompdf
14
+ * @author Barry vd. Heuvel
15
+ */
16
+class PDF
17
+{
18
+
19
+    /** @var \DOMPDF  */
20
+    protected $dompdf;
21
+
22
+    /** @var \Illuminate\Config\Repository  */
23
+    protected $config;
24
+
25
+    /** @var \Illuminate\Filesystem\Filesystem  */
26
+    protected $files;
27
+
28
+    /** @var \Illuminate\View\Factory  */
29
+    protected $view;
30
+
31
+    protected $rendered = false;
32
+    protected $orientation;
33
+    protected $paper;
34
+    protected $showWarnings;
35
+    protected $public_path;
36
+
37
+    /**
38
+     *
39
+     * @param \Illuminate\Config\Repository $config
40
+     * @param \Illuminate\Filesystem\Filesystem $files
41
+     * @param \Illuminate\View\Factory $view
42
+     * @param string $publicPath
43
+     */
44
+    public function __construct(ConfigRepository $config, Filesystem $files, /* Illuminate\View\Factory */ $view, $publicPath)
45
+    {
46
+        $this->config = $config;
47
+        $this->files = $files;
48
+        $this->view = $view;
49
+        $this->public_path = $publicPath;
50
+
51
+        $this->showWarnings = $this->config->get('laravel-dompdf::show_warnings', false);
52
+
53
+        //To prevent old configs from not working..
54
+        if ($this->config->has('laravel-dompdf::paper')) {
55
+            $this->paper = $this->config->get('laravel-dompdf::paper');
56
+        } else {
57
+            $this->paper = 'portrait';
58
+        }
59
+
60
+        $this->orientation = $this->config->get('laravel-dompdf::orientation') ?: 'portrait';
61
+
62
+        $this->dompdf = new \DOMPDF();
63
+        $this->dompdf->set_base_path(realpath($publicPath));
64
+    }
65
+
66
+    /**
67
+     * Get the DomPDF instance
68
+     *
69
+     * @return \DOMPDF
70
+     */
71
+    public function getDomPDF()
72
+    {
73
+        return $this->dompdf;
74
+    }
75
+
76
+    /**
77
+     * Set the paper size (default A4)
78
+     *
79
+     * @param string $paper
80
+     * @param string $orientation
81
+     * @return $this
82
+     */
83
+    public function setPaper($paper, $orientation = null)
84
+    {
85
+        $this->paper = $paper;
86
+        if ($orientation) {
87
+            $this->orientation = $orientation;
88
+        }
89
+        return $this;
90
+    }
91
+
92
+    /**
93
+     * Set the orientation (default portrait)
94
+     *
95
+     * @param string $orientation
96
+     * @return static
97
+     */
98
+    public function setOrientation($orientation)
99
+    {
100
+        $this->orientation = $orientation;
101
+        return $this;
102
+    }
103
+
104
+    /**
105
+     * Show or hide warnings
106
+     *
107
+     * @param bool $warnings
108
+     * @return $this
109
+     */
110
+    public function setWarnings($warnings)
111
+    {
112
+        $this->showWarnings = $warnings;
113
+        return $this;
114
+    }
115
+
116
+    /**
117
+     * Load a HTML string
118
+     *
119
+     * @param string $string
120
+     * @param string $encoding Not used yet
121
+     * @return static
122
+     */
123
+    public function loadHTML($string, $encoding = null)
124
+    {
125
+        $string = $this->convertEntities($string);
126
+        $this->dompdf->load_html($string, $encoding);
127
+        $this->rendered = false;
128
+        return $this;
129
+    }
130
+
131
+    /**
132
+     * Load a HTML file
133
+     *
134
+     * @param string $file
135
+     * @return static
136
+     */
137
+    public function loadFile($file)
138
+    {
139
+        $this->dompdf->load_html_file($file);
140
+        $this->rendered = false;
141
+        return $this;
142
+    }
143
+
144
+    /**
145
+     * Load a View and convert to HTML
146
+     *
147
+     * @param string $view
148
+     * @param array $data
149
+     * @param array $mergeData
150
+     * @param string $encoding Not used yet
151
+     * @return static
152
+     */
153
+    public function loadView($view, $data = array(), $mergeData = array(), $encoding = null)
154
+    {
155
+        $html = $this->view->make($view, $data, $mergeData)->render();
156
+        return $this->loadHTML($html, $encoding);
157
+    }
158
+
159
+    /**
160
+     * Output the PDF as a string.
161
+     *
162
+     * @return string The rendered PDF as string
163
+     */
164
+    public function output()
165
+    {
166
+        if (!$this->rendered) {
167
+            $this->render();
168
+        }
169
+        return $this->dompdf->output();
170
+    }
171
+
172
+    /**
173
+     * Save the PDF to a file
174
+     *
175
+     * @param $filename
176
+     * @return static
177
+     */
178
+    public function save($filename)
179
+    {
180
+        $this->files->put($filename, $this->output());
181
+        return $this;
182
+    }
183
+
184
+    /**
185
+     * Make the PDF downloadable by the user
186
+     *
187
+     * @param string $filename
188
+     * @return \Illuminate\Http\Response
189
+     */
190
+    public function download($filename = 'document.pdf')
191
+    {
192
+        $output = $this->output();
193
+        return new Response($output, 200, array(
194
+            'Content-Type' => 'application/pdf',
195
+            'Content-Disposition' =>  'attachment; filename="' . $filename . '"'
196
+        ));
197
+    }
198
+
199
+    /**
200
+     * Return a response with the PDF to show in the browser
201
+     *
202
+     * @param string $filename
203
+     * @return \Illuminate\Http\Response
204
+     */
205
+    public function stream($filename = 'document.pdf')
206
+    {
207
+        $output = $this->output();
208
+        return new Response($output, 200, array(
209
+            'Content-Type' => 'application/pdf',
210
+            'Content-Disposition' =>  'inline; filename="' . $filename . '"',
211
+        ));
212
+    }
213
+
214
+    /**
215
+     * Render the PDF
216
+     */
217
+    protected function render()
218
+    {
219
+        if (!$this->dompdf) {
220
+            throw new Exception('DOMPDF not created yet');
221
+        }
222
+
223
+        $this->dompdf->set_paper($this->paper, $this->orientation);
224
+
225
+        $this->dompdf->render();
226
+
227
+        if ($this->showWarnings) {
228
+            global $_dompdf_warnings;
229
+            if (count($_dompdf_warnings)) {
230
+                $warnings = '';
231
+                foreach ($_dompdf_warnings as $msg) {
232
+                    $warnings .= $msg . "\n";
233
+                }
234
+                // $warnings .= $this->dompdf->get_canvas()->get_cpdf()->messages;
235
+                if (!empty($warnings)) {
236
+                    throw new Exception($warnings);
237
+                }
238
+            }
239
+        }
240
+        $this->rendered = true;
241
+    }
242
+
243
+
244
+    protected function convertEntities($subject)
245
+    {
246
+        $entities = array(
247
+            '€' => '&#0128;',
248
+        );
249
+
250
+        foreach ($entities as $search => $replace) {
251
+            $subject = str_replace($search, $replace, $subject);
252
+        }
253
+        return $subject;
254
+    }
255
+}

+ 77
- 0
vendor/barryvdh/laravel-dompdf/src/ServiceProvider.php View File

@@ -0,0 +1,77 @@
1
+<?php
2
+namespace Barryvdh\DomPDF;
3
+
4
+use Exception;
5
+use Illuminate\Support\ServiceProvider as IlluminateServiceProvider;
6
+
7
+class ServiceProvider extends IlluminateServiceProvider {
8
+
9
+    /**
10
+     * Indicates if loading of the provider is deferred.
11
+     *
12
+     * @var bool
13
+     */
14
+    protected $defer = true;
15
+
16
+    /**
17
+     * Register the service provider.
18
+     *
19
+     * @throws \Exception
20
+     * @return void
21
+     */
22
+    public function register()
23
+    {
24
+        $this->app['config']->package('barryvdh/laravel-dompdf', __DIR__ . '/config');
25
+
26
+        $defines = $this->app['config']->get('laravel-dompdf::defines') ?: array();
27
+        foreach ($defines as $key => $value) {
28
+            $this->define($key, $value);
29
+        }
30
+
31
+        //Still load these values, in case config is not used.
32
+        $this->define("DOMPDF_ENABLE_REMOTE", true);
33
+        $this->define("DOMPDF_ENABLE_AUTOLOAD", false);
34
+        $this->define("DOMPDF_CHROOT", $this->app['path.base']);
35
+        $this->define("DOMPDF_LOG_OUTPUT_FILE", $this->app['path.storage'] . '/logs/dompdf.html');
36
+
37
+        $config_file = $this->app['config']->get(
38
+            'laravel-dompdf::config_file'
39
+        ) ?: $this->app['path.base'] . '/vendor/dompdf/dompdf/dompdf_config.inc.php';
40
+
41
+        if (file_exists($config_file)) {
42
+            require_once $config_file;
43
+        } else {
44
+            throw new Exception(
45
+                "$config_file cannot be loaded, please configure correct config file (config.php: config_file)"
46
+            );
47
+        }
48
+        
49
+        $this->app->bind('dompdf', function ($app) {
50
+                return new PDF($app['config'], $app['files'], $app['view'], $app['path.public']);
51
+            });
52
+    }
53
+
54
+    /**
55
+     * Get the services provided by the provider.
56
+     *
57
+     * @return array
58
+     */
59
+    public function provides()
60
+    {
61
+        return array('dompdf');
62
+    }
63
+
64
+    /**
65
+     * Define a value, if not already defined
66
+     * 
67
+     * @param string $name
68
+     * @param string $value
69
+     */
70
+    protected function define($name, $value)
71
+    {
72
+        if (!defined($name)) {
73
+            define($name, $value);
74
+        }
75
+    }
76
+
77
+}

+ 266
- 0
vendor/barryvdh/laravel-dompdf/src/config/config.php View File

@@ -0,0 +1,266 @@
1
+<?php
2
+
3
+return array(
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Settings
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Set some default values. It is possible to add all defines that can be set
11
+    | in dompdf_config.inc.php. You can also override the entire config file.
12
+    |
13
+    */
14
+    'show_warnings' => false,   // Throw an Exception on warnings from dompdf
15
+    'orientation' => 'portrait',
16
+    'defines' => array(
17
+        /**
18
+         * The location of the DOMPDF font directory
19
+         *
20
+         * The location of the directory where DOMPDF will store fonts and font metrics
21
+         * Note: This directory must exist and be writable by the webserver process.
22
+         * *Please note the trailing slash.*
23
+         *
24
+         * Notes regarding fonts:
25
+         * Additional .afm font metrics can be added by executing load_font.php from command line.
26
+         *
27
+         * Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must
28
+         * be embedded in the pdf file or the PDF may not display correctly. This can significantly
29
+         * increase file size unless font subsetting is enabled. Before embedding a font please
30
+         * review your rights under the font license.
31
+         *
32
+         * Any font specification in the source HTML is translated to the closest font available
33
+         * in the font directory.
34
+         *
35
+         * The pdf standard "Base 14 fonts" are:
36
+         * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
37
+         * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
38
+         * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
39
+         * Symbol, ZapfDingbats.
40
+         */
41
+        "DOMPDF_FONT_DIR" => storage_path('fonts/'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
42
+
43
+        /**
44
+         * The location of the DOMPDF font cache directory
45
+         *
46
+         * This directory contains the cached font metrics for the fonts used by DOMPDF.
47
+         * This directory can be the same as DOMPDF_FONT_DIR
48
+         *
49
+         * Note: This directory must exist and be writable by the webserver process.
50
+         */
51
+        "DOMPDF_FONT_CACHE" => storage_path('fonts/'),
52
+
53
+        /**
54
+         * The location of a temporary directory.
55
+         *
56
+         * The directory specified must be writeable by the webserver process.
57
+         * The temporary directory is required to download remote images and when
58
+         * using the PFDLib back end.
59
+         */
60
+        "DOMPDF_TEMP_DIR" => sys_get_temp_dir(),
61
+
62
+        /**
63
+         * ==== IMPORTANT ====
64
+         *
65
+         * dompdf's "chroot": Prevents dompdf from accessing system files or other
66
+         * files on the webserver.  All local files opened by dompdf must be in a
67
+         * subdirectory of this directory.  DO NOT set it to '/' since this could
68
+         * allow an attacker to use dompdf to read any files on the server.  This
69
+         * should be an absolute path.
70
+         * This is only checked on command line call by dompdf.php, but not by
71
+         * direct class use like:
72
+         * $dompdf = new DOMPDF();	$dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();
73
+         */
74
+        "DOMPDF_CHROOT" => realpath(base_path()),
75
+
76
+        /**
77
+         * Whether to use Unicode fonts or not.
78
+         *
79
+         * When set to true the PDF backend must be set to "CPDF" and fonts must be
80
+         * loaded via load_font.php.
81
+         *
82
+         * When enabled, dompdf can support all Unicode glyphs. Any glyphs used in a
83
+         * document must be present in your fonts, however.
84
+         */
85
+        "DOMPDF_UNICODE_ENABLED" => true,
86
+
87
+        /**
88
+         * Whether to enable font subsetting or not.
89
+         */
90
+        "DOMPDF_ENABLE_FONTSUBSETTING" => false,
91
+
92
+        /**
93
+         * The PDF rendering backend to use
94
+         *
95
+         * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and
96
+         * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will
97
+         * fall back on CPDF. 'GD' renders PDFs to graphic files. {@link
98
+         * Canvas_Factory} ultimately determines which rendering class to instantiate
99
+         * based on this setting.
100
+         *
101
+         * Both PDFLib & CPDF rendering backends provide sufficient rendering
102
+         * capabilities for dompdf, however additional features (e.g. object,
103
+         * image and font support, etc.) differ between backends.  Please see
104
+         * {@link PDFLib_Adapter} for more information on the PDFLib backend
105
+         * and {@link CPDF_Adapter} and lib/class.pdf.php for more information
106
+         * on CPDF. Also see the documentation for each backend at the links
107
+         * below.
108
+         *
109
+         * The GD rendering backend is a little different than PDFLib and
110
+         * CPDF. Several features of CPDF and PDFLib are not supported or do
111
+         * not make any sense when creating image files.  For example,
112
+         * multiple pages are not supported, nor are PDF 'objects'.  Have a
113
+         * look at {@link GD_Adapter} for more information.  GD support is
114
+         * experimental, so use it at your own risk.
115
+         *
116
+         * @link http://www.pdflib.com
117
+         * @link http://www.ros.co.nz/pdf
118
+         * @link http://www.php.net/image
119
+         */
120
+        "DOMPDF_PDF_BACKEND" => "CPDF",
121
+
122
+        /**
123
+         * PDFlib license key
124
+         *
125
+         * If you are using a licensed, commercial version of PDFlib, specify
126
+         * your license key here.  If you are using PDFlib-Lite or are evaluating
127
+         * the commercial version of PDFlib, comment out this setting.
128
+         *
129
+         * @link http://www.pdflib.com
130
+         *
131
+         * If pdflib present in web server and auto or selected explicitely above,
132
+         * a real license code must exist!
133
+         */
134
+        //"DOMPDF_PDFLIB_LICENSE" => "your license key here",
135
+
136
+        /**
137
+         * html target media view which should be rendered into pdf.
138
+         * List of types and parsing rules for future extensions:
139
+         * http://www.w3.org/TR/REC-html40/types.html
140
+         *   screen, tty, tv, projection, handheld, print, braille, aural, all
141
+         * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
142
+         * Note, even though the generated pdf file is intended for print output,
143
+         * the desired content might be different (e.g. screen or projection view of html file).
144
+         * Therefore allow specification of content here.
145
+         */
146
+        "DOMPDF_DEFAULT_MEDIA_TYPE" => "screen",
147
+
148
+        /**
149
+         * The default paper size.
150
+         *
151
+         * North America standard is "letter"; other countries generally "a4"
152
+         *
153
+         * @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.)
154
+         */
155
+        "DOMPDF_DEFAULT_PAPER_SIZE" => "a4",
156
+
157
+        /**
158
+         * The default font family
159
+         *
160
+         * Used if no suitable fonts can be found. This must exist in the font folder.
161
+         * @var string
162
+         */
163
+        "DOMPDF_DEFAULT_FONT" => "serif",
164
+
165
+        /**
166
+         * Image DPI setting
167
+         *
168
+         * This setting determines the default DPI setting for images and fonts.  The
169
+         * DPI may be overridden for inline images by explictly setting the
170
+         * image's width & height style attributes (i.e. if the image's native
171
+         * width is 600 pixels and you specify the image's width as 72 points,
172
+         * the image will have a DPI of 600 in the rendered PDF.  The DPI of
173
+         * background images can not be overridden and is controlled entirely
174
+         * via this parameter.
175
+         *
176
+         * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
177
+         * If a size in html is given as px (or without unit as image size),
178
+         * this tells the corresponding size in pt.
179
+         * This adjusts the relative sizes to be similar to the rendering of the
180
+         * html page in a reference browser.
181
+         *
182
+         * In pdf, always 1 pt = 1/72 inch
183
+         *
184
+         * Rendering resolution of various browsers in px per inch:
185
+         * Windows Firefox and Internet Explorer:
186
+         *   SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?
187
+         * Linux Firefox:
188
+         *   about:config *resolution: Default:96
189
+         *   (xorg screen dimension in mm and Desktop font dpi settings are ignored)
190
+         *
191
+         * Take care about extra font/image zoom factor of browser.
192
+         *
193
+         * In images, <img> size in pixel attribute, img css style, are overriding
194
+         * the real image dimension in px for rendering.
195
+         *
196
+         * @var int
197
+         */
198
+        "DOMPDF_DPI" => 96,
199
+
200
+        /**
201
+         * Enable inline PHP
202
+         *
203
+         * If this setting is set to true then DOMPDF will automatically evaluate
204
+         * inline PHP contained within <script type="text/php"> ... </script> tags.
205
+         *
206
+         * Enabling this for documents you do not trust (e.g. arbitrary remote html
207
+         * pages) is a security risk.  Set this option to false if you wish to process
208
+         * untrusted documents.
209
+         *
210
+         * @var bool
211
+         */
212
+        "DOMPDF_ENABLE_PHP" => false,
213
+
214
+        /**
215
+         * Enable inline Javascript
216
+         *
217
+         * If this setting is set to true then DOMPDF will automatically insert
218
+         * JavaScript code contained within <script type="text/javascript"> ... </script> tags.
219
+         *
220
+         * @var bool
221
+         */
222
+        "DOMPDF_ENABLE_JAVASCRIPT" => true,
223
+
224
+        /**
225
+         * Enable remote file access
226
+         *
227
+         * If this setting is set to true, DOMPDF will access remote sites for
228
+         * images and CSS files as required.
229
+         * This is required for part of test case www/test/image_variants.html through www/examples.php
230
+         *
231
+         * Attention!
232
+         * This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and
233
+         * allowing remote access to dompdf.php or on allowing remote html code to be passed to
234
+         * $dompdf = new DOMPDF(, $dompdf->load_html(...,
235
+         * This allows anonymous users to download legally doubtful internet content which on
236
+         * tracing back appears to being downloaded by your server, or allows malicious php code
237
+         * in remote html pages to be executed by your server with your account privileges.
238
+         *
239
+         * @var bool
240
+         */
241
+        "DOMPDF_ENABLE_REMOTE" => true,
242
+
243
+        /**
244
+         * A ratio applied to the fonts height to be more like browsers' line height
245
+         */
246
+        "DOMPDF_FONT_HEIGHT_RATIO" => 1.1,
247
+
248
+        /**
249
+         * Enable CSS float
250
+         *
251
+         * Allows people to disabled CSS float support
252
+         * @var bool
253
+         */
254
+        "DOMPDF_ENABLE_CSS_FLOAT" => false,
255
+
256
+
257
+        /**
258
+         * Use the more-than-experimental HTML5 Lib parser
259
+         */
260
+        "DOMPDF_ENABLE_HTML5PARSER" => false,
261
+
262
+
263
+    ),
264
+
265
+
266
+);

+ 3
- 0
vendor/barryvdh/laravel-ide-helper/.gitignore View File

@@ -0,0 +1,3 @@
1
+/vendor
2
+composer.lock
3
+.idea

+ 36
- 0
vendor/barryvdh/laravel-ide-helper/composer.json View File

@@ -0,0 +1,36 @@
1
+{
2
+    "name": "barryvdh/laravel-ide-helper",
3
+    "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.",
4
+    "keywords": ["laravel", "autocomplete", "ide", "helper", "phpstorm", "netbeans", "sublime", "codeintel", "phpdoc"],
5
+    "license": "MIT",
6
+    "authors": [
7
+        {
8
+            "name": "Barry vd. Heuvel",
9
+            "email": "barryvdh@gmail.com"
10
+        }
11
+    ],
12
+    "require": {
13
+        "php": ">=5.3.0",
14
+        "illuminate/support": "4.x",
15
+        "illuminate/console": "4.x",
16
+        "illuminate/filesystem": "4.x",
17
+        "phpdocumentor/reflection-docblock": "2.0.x",
18
+        "symfony/class-loader": "~2.3"
19
+    },
20
+    "require-dev": {
21
+        "doctrine/dbal": "~2.3"
22
+    },
23
+    "suggest": {
24
+        "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)"
25
+    },
26
+    "autoload": {
27
+        "psr-4": {
28
+            "Barryvdh\\LaravelIdeHelper\\": "src"
29
+        }
30
+    },
31
+    "extra": {
32
+        "branch-alias": {
33
+            "dev-master": "1.11-dev"
34
+        }
35
+    }
36
+}

+ 5
- 0
vendor/barryvdh/laravel-ide-helper/provides.json View File

@@ -0,0 +1,5 @@
1
+{
2
+  "providers": [
3
+    "Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider"
4
+  ]
5
+}

+ 97
- 0
vendor/barryvdh/laravel-ide-helper/readme.md View File

@@ -0,0 +1,97 @@
1
+## Laravel IDE Helper Generator
2
+[![Latest Stable Version](https://poser.pugx.org/barryvdh/laravel-ide-helper/version.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper) [![Total Downloads](https://poser.pugx.org/barryvdh/laravel-ide-helper/d/total.png)](https://packagist.org/packages/barryvdh/laravel-ide-helper)
3
+
4
+### Complete phpDocs, directly from the source
5
+
6
+_Checkout [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
7
+
8
+This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are alway up-to-date.
9
+If you don't want to generate it, you can add a pre-generated file to the root folder of your laravel project. (But this isn't as up-to-date as self generated files)
10
+
11
+* Generated version: https://gist.github.com/barryvdh/5227822
12
+
13
+Note: You do need CodeIntel for Sublime Text: https://github.com/SublimeCodeIntel/SublimeCodeIntel
14
+
15
+### Automatic phpDoc generation for Laravel Facades
16
+
17
+Require this package in your composer.json and run composer update (or run `composer require barryvdh/laravel-ide-helper:1.*` directly):
18
+
19
+    "barryvdh/laravel-ide-helper": "1.*"
20
+
21
+After updating composer, add the ServiceProvider to the providers array in app/config/app.php
22
+
23
+    'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
24
+
25
+You can now re-generate the docs yourself (for future updates) in artisan
26
+
27
+    php artisan ide-helper:generate
28
+
29
+Note: bootstrap/compiled.php has to be cleared first, so run `php artisan clear-compiled` before generating (and `php artisan optimize` after..)
30
+
31
+You can configure your composer.json to do this after each commit:
32
+
33
+    "scripts":{
34
+        "post-update-cmd":[
35
+            "php artisan clear-compiled",
36
+            "php artisan ide-helper:generate",
37
+            "php artisan optimize",
38
+        ]
39
+    },
40
+
41
+You can also publish the config-file to change implementations (ie. interface to specific class) or set defaults for --helpers or --sublime.
42
+
43
+    php artisan config:publish barryvdh/laravel-ide-helper
44
+
45
+The generator tries to identify the real class, but if it cannot be found, you can define it in the config file.
46
+
47
+Some classes need a working database connection. If you do not have a working default connection, some facades will not be included.
48
+You can use a in-memory sqlite driver, using the -M option.
49
+
50
+You can choose to include helper files. This is not enabled by default, but you can override this with the --helpers (-H) option.
51
+The Illuminate/Support/helpers.php is already set-up, but you can add/remove your own files in the config file.
52
+
53
+
54
+### Automatic phpDocs for Models
55
+
56
+> **Note:** Since v1.10 you need to require `doctrine/dbal: ~2.3` in your own composer.json. 
57
+
58
+If you don't want to write your properties yourself, you can use the command `ide-helper:models` to generate
59
+phpDocs, based on table columns, relations and getters/setters. You can write the comments directly to your Model file, using the `--write (-W)` option. By default, you are asked to overwrite or write to a separate file (\_ide\_helper\_models.php) (You can force No with `--nowrite (-N)`).
60
+Please make sure to backup your models, before writing the info.
61
+It should keep the existing comments and only append new properties/methods. The existing phpdoc is replaced, or added if not found.
62
+With the `--reset (-R)` option, the existing phpdocs are ignored, only the newly found columns/relations are saved as phpdocs.
63
+
64
+    php artisan ide-helper:models Post
65
+
66
+    /**
67
+     * An Eloquent Model: 'Post'
68
+     *
69
+     * @property integer $id
70
+     * @property integer $author_id
71
+     * @property string $title
72
+     * @property string $text
73
+     * @property \Carbon\Carbon $created_at
74
+     * @property \Carbon\Carbon $updated_at
75
+     * @property-read \User $author
76
+     * @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
77
+     */
78
+
79
+By default, models in app/models are scanned. The optional argument tells what models to use (also outside app/models).
80
+
81
+    php artisan ide-helper:models Post User
82
+
83
+You can also scan a different directory, using the --dir option (relative from the base path):
84
+
85
+    php artisan ide-helper:models --dir="app/workbench/name/package/models" --dir="app/src/Model"
86
+   
87
+You can publish the config file (`php artisan config:publish barryvdh/laravel-ide-helper`) and set the default directories.
88
+
89
+Models can be ignored using the --ignore (-I) option
90
+
91
+    php artisan ide-helper:models --ignore="Post,User"
92
+
93
+Note: With namespaces, wrap your model name in " signs: `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`)
94
+
95
+### License
96
+
97
+The Laravel IDE Helper Generator is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)

+ 276
- 0
vendor/barryvdh/laravel-ide-helper/src/Alias.php View File

@@ -0,0 +1,276 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper;
12
+
13
+class Alias
14
+{
15
+
16
+    protected $alias;
17
+    protected $facade;
18
+    protected $extends = null;
19
+    protected $classType = 'class';
20
+    protected $namespace = '__root';
21
+    protected $root = null;
22
+    protected $classes = array();
23
+    protected $methods = array();
24
+    protected $usedMethods = array();
25
+    protected $valid = false;
26
+    protected $magicMethods = array();
27
+    protected $interfaces = array();
28
+
29
+    /**
30
+     * @param string $alias
31
+     * @param string $facade
32
+     * @param array $magicMethods
33
+     * @param array $interfaces
34
+     */
35
+    public function __construct($alias, $facade, $magicMethods = array(), $interfaces = array())
36
+    {
37
+        $this->alias = $alias;
38
+        $this->magicMethods = $magicMethods;
39
+        $this->interfaces = $interfaces;
40
+
41
+        // Make the class absolute
42
+        $facade = '\\' . ltrim($facade, '\\');
43
+        $this->facade = $facade;
44
+
45
+
46
+        $this->detectRoot();
47
+
48
+        if ((!$this->isTrait() && $this->root)) {
49
+            $this->valid = true;
50
+        } else {
51
+            return;
52
+        }
53
+
54
+        $this->addClass($this->root);
55
+        $this->detectNamespace();
56
+        $this->detectClassType();
57
+
58
+
59
+    }
60
+
61
+    /**
62
+     * Add one or more classes to analyze
63
+     *
64
+     * @param array|string $classes
65
+     */
66
+    public function addClass($classes)
67
+    {
68
+        $classes = (array)$classes;
69
+        foreach ($classes as $class) {
70
+            if (class_exists($class) || interface_exists($class)) {
71
+                $this->classes[] = $class;
72
+            }else{
73
+                echo "Class not exists: $class\r\n";
74
+            }
75
+        }
76
+    }
77
+
78
+    /**
79
+     * Check if this class is valid to process.
80
+     * @return bool
81
+     */
82
+    public function isValid()
83
+    {
84
+        return $this->valid;
85
+    }
86
+
87
+    /**
88
+     * Get the classtype, 'interface' or 'class'
89
+     *
90
+     * @return string
91
+     */
92
+    public function getClasstype()
93
+    {
94
+        return $this->classType;
95
+    }
96
+
97
+    /**
98
+     * Get the class which this alias extends
99
+     *
100
+     * @return null|string
101
+     */
102
+    public function getExtends()
103
+    {
104
+        return $this->extends;
105
+    }
106
+
107
+    /**
108
+     * Get the Alias by which this class is called
109
+     *
110
+     * @return string
111
+     */
112
+    public function getAlias()
113
+    {
114
+        return $this->alias;
115
+    }
116
+
117
+    /**
118
+     * Get the namespace from the alias
119
+     *
120
+     * @return string
121
+     */
122
+    public function getNamespace()
123
+    {
124
+        return $this->namespace;
125
+    }
126
+
127
+    /**
128
+     * Get the methods found by this Alias
129
+     *
130
+     * @return array
131
+     */
132
+    public function getMethods()
133
+    {
134
+        $this->addMagicMethods();
135
+        $this->detectMethods();
136
+        return $this->methods;
137
+    }
138
+
139
+    /**
140
+     * Detect the namespace
141
+     */
142
+    protected function detectNamespace()
143
+    {
144
+        if (strpos($this->alias, '\\')) {
145
+            $nsParts = explode('\\', $this->alias);
146
+            $this->short = array_pop($nsParts);
147
+            $this->namespace = implode('\\', $nsParts);
148
+        }
149
+    }
150
+
151
+    /**
152
+     * Detect the class type
153
+     */
154
+    protected function detectClassType()
155
+    {
156
+        //Some classes extend the facade
157
+        if (interface_exists($this->facade)) {
158
+            $this->classType = 'interface';
159
+            $this->extends = $this->facade;
160
+        } else {
161
+            $this->classType = 'class';
162
+            if (class_exists($this->facade)) {
163
+                $this->extends = $this->facade;
164
+            }
165
+        }
166
+    }
167
+
168
+    /**
169
+     * Get the real root of a facade
170
+     *
171
+     * @return bool|string
172
+     */
173
+    protected function detectRoot()
174
+    {
175
+        $facade = $this->facade;
176
+
177
+        try {
178
+            //If possible, get the facade root
179
+            if (method_exists($facade, 'getFacadeRoot')) {
180
+                $root = get_class($facade::getFacadeRoot());
181
+            } else {
182
+                $root = $facade;
183
+            }
184
+
185
+            //If it doesn't exist, skip it
186
+            if (!class_exists($root) && !interface_exists($root)) {
187
+                $this->error("Class $root is not found.");
188
+                return;
189
+            }
190
+
191
+            $this->root = $root;
192
+
193
+            //When the database connection is not set, some classes will be skipped
194
+        } catch (\PDOException $e) {
195
+            $this->error(
196
+                "PDOException: " . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
197
+            );
198
+        } catch (\Exception $e) {
199
+            $this->error("Exception: " . $e->getMessage() . "\nSkipping $facade.");
200
+        }
201
+    }
202
+
203
+    /**
204
+     * Detect if this class is a trait or not.
205
+     *
206
+     * @return bool
207
+     */
208
+    protected function isTrait()
209
+    {
210
+        // Check if the facade is not a Trait
211
+        if (function_exists('trait_exists') && trait_exists($this->facade)) {
212
+            return true;
213
+        }
214
+        return false;
215
+    }
216
+
217
+    /**
218
+     * Add magic methods, as defined in the configuration files
219
+     */
220
+    protected function addMagicMethods()
221
+    {
222
+        foreach($this->magicMethods as $magic => $real){
223
+            list($className, $name) = explode('::', $real);
224
+            if(!class_exists($className) && !interface_exists($className)){
225
+                continue;
226
+            }
227
+            $method = new \ReflectionMethod($className, $name);
228
+            $class = new \ReflectionClass($className);
229
+
230
+            if(!in_array($method->name, $this->usedMethods)){
231
+                if($class !== $this->root){
232
+                    $this->methods[] = new Method($method, $this->alias, $class, $magic, $this->interfaces);
233
+                }
234
+                $this->usedMethods[] = $magic;
235
+            }
236
+        }
237
+    }
238
+
239
+    /**
240
+     * Get the methods for one or multiple classes.
241
+     *
242
+     * @return string
243
+     */
244
+    protected function detectMethods()
245
+    {
246
+
247
+        foreach ($this->classes as $class) {
248
+            $reflection = new \ReflectionClass($class);
249
+
250
+            $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
251
+            if ($methods) {
252
+                foreach ($methods as $method) {
253
+                    if (!in_array($method->name, $this->usedMethods)) {
254
+                        // Only add the methods to the output when the root is not the same as the class.
255
+                        // And don't add the __*() methods
256
+                        if ($this->extends !== $class && $method->name !== '__clone') {
257
+                            $this->methods[] = new Method($method, $this->alias, $reflection, $method->name, $this->interfaces);
258
+                        }
259
+                        $this->usedMethods[] = $method->name;
260
+                    }
261
+                }
262
+            }
263
+        }
264
+    }
265
+
266
+    /**
267
+     * Output an error.
268
+     *
269
+     * @param  string  $string
270
+     * @return void
271
+     */
272
+    protected function error($string)
273
+    {
274
+        echo $string . "\r\n";
275
+    }
276
+}

+ 158
- 0
vendor/barryvdh/laravel-ide-helper/src/Console/GeneratorCommand.php View File

@@ -0,0 +1,158 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper\Console;
12
+
13
+use Barryvdh\LaravelIdeHelper\Generator;
14
+use Illuminate\Config\Repository as ConfigRepository;
15
+use Illuminate\Console\Command;
16
+use Illuminate\Filesystem\Filesystem;
17
+use Symfony\Component\Console\Input\InputOption;
18
+use Symfony\Component\Console\Input\InputArgument;
19
+
20
+
21
+/**
22
+ * A command to generate autocomplete information for your IDE
23
+ *
24
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
25
+ */
26
+class GeneratorCommand extends Command
27
+{
28
+
29
+    /**
30
+     * The console command name.
31
+     *
32
+     * @var string
33
+     */
34
+    protected $name = 'ide-helper:generate';
35
+
36
+    /**
37
+     * The console command description.
38
+     *
39
+     * @var string
40
+     */
41
+    protected $description = 'Generate a new IDE Helper file.';
42
+
43
+    /** @var \Illuminate\Config\Repository */
44
+    protected $config;
45
+
46
+    /** @var \Illuminate\Filesystem\Filesystem */
47
+    protected $files;
48
+
49
+    /** @var \Illuminate\View\Factory */
50
+    protected $view;
51
+
52
+    protected $onlyExtend;
53
+
54
+
55
+    /**
56
+     *
57
+     * @param \Illuminate\Config\Repository $config
58
+     * @param \Illuminate\Filesystem\Filesystem $files
59
+     * @param \Illuminate\View\Factory $view
60
+     */
61
+    public function __construct(
62
+        ConfigRepository $config,
63
+        Filesystem $files, /* Illuminate\View\Factory */
64
+        $view
65
+    ) {
66
+        $this->config = $config;
67
+        $this->files = $files;
68
+        $this->view = $view;
69
+        parent::__construct();
70
+    }
71
+
72
+    /**
73
+     * Execute the console command.
74
+     *
75
+     * @return void
76
+     */
77
+    public function fire()
78
+    {
79
+        if (file_exists($compiled = base_path() . '/bootstrap/compiled.php')) {
80
+            $this->error(
81
+                'Error generating IDE Helper: first delete bootstrap/compiled.php (php artisan clear-compiled)'
82
+            );
83
+        } else {
84
+            $filename = $this->argument('filename');
85
+
86
+            if ($this->option('memory')) {
87
+                $this->useMemoryDriver();
88
+            }
89
+
90
+
91
+            $helpers = '';
92
+            if ($this->option('helpers') || ($this->config->get('laravel-ide-helper::include_helpers'))) {
93
+                foreach ($this->config->get('laravel-ide-helper::helper_files', array()) as $helper) {
94
+                    if (file_exists($helper)) {
95
+                        $helpers .= str_replace(array('<?php', '?>'), '', $this->files->get($helper));
96
+                    }
97
+                }
98
+            } else {
99
+                $helpers = '';
100
+            }
101
+
102
+            $generator = new Generator($this->config, $this->view, $this->getOutput(), $helpers);
103
+            $content = $generator->generate();
104
+            $written = $this->files->put($filename, $content);
105
+
106
+            if ($written !== false) {
107
+                $this->info("A new helper file was written to $filename");
108
+            } else {
109
+                $this->error("The helper file could not be created at $filename");
110
+            }
111
+        }
112
+    }
113
+
114
+    protected function useMemoryDriver()
115
+    {
116
+        //Use a sqlite database in memory, to avoid connection errors on Database facades
117
+        $this->config->set(
118
+            'database.connections.sqlite',
119
+            array(
120
+                'driver' => 'sqlite',
121
+                'database' => ':memory:',
122
+            )
123
+        );
124
+        $this->config->set('database.default', 'sqlite');
125
+    }
126
+
127
+    /**
128
+     * Get the console command arguments.
129
+     *
130
+     * @return array
131
+     */
132
+    protected function getArguments()
133
+    {
134
+        return array(
135
+            array(
136
+                'filename',
137
+                InputArgument::OPTIONAL,
138
+                'The path to the helper file',
139
+                $this->config->get('laravel-ide-helper::filename')
140
+            ),
141
+        );
142
+    }
143
+
144
+    /**
145
+     * Get the console command options.
146
+     *
147
+     * @return array
148
+     */
149
+    protected function getOptions()
150
+    {
151
+        return array(
152
+            array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'),
153
+            array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'),
154
+            array('sublime', "S", InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
155
+        );
156
+    }
157
+
158
+}

+ 510
- 0
vendor/barryvdh/laravel-ide-helper/src/Console/ModelsCommand.php View File

@@ -0,0 +1,510 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper\Console;
12
+
13
+use Illuminate\Console\Command;
14
+use Illuminate\Support\Str;
15
+use Symfony\Component\Console\Input\InputOption;
16
+use Symfony\Component\Console\Input\InputArgument;
17
+use Symfony\Component\ClassLoader\ClassMapGenerator;
18
+use phpDocumentor\Reflection\DocBlock;
19
+use phpDocumentor\Reflection\DocBlock\Context;
20
+use phpDocumentor\Reflection\DocBlock\Tag;
21
+use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
22
+
23
+/**
24
+ * A command to generate autocomplete information for your IDE
25
+ *
26
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
27
+ */
28
+class ModelsCommand extends Command
29
+{
30
+
31
+    /**
32
+     * The console command name.
33
+     *
34
+     * @var string
35
+     */
36
+    protected $name = 'ide-helper:models';
37
+    protected $filename = '_ide_helper_models.php';
38
+
39
+    /**
40
+     * The console command description.
41
+     *
42
+     * @var string
43
+     */
44
+    protected $description = 'Generate autocompletion for models';
45
+
46
+    protected $properties = array();
47
+    protected $methods = array();
48
+    protected $write = false;
49
+    protected $dirs = array();
50
+    protected $reset;
51
+
52
+
53
+    /**
54
+     * Execute the console command.
55
+     *
56
+     * @return void
57
+     */
58
+    public function fire()
59
+    {
60
+        $filename = $this->option('filename');
61
+        $this->write = $this->option('write');
62
+        $this->dirs = array_merge(
63
+            $this->laravel['config']->get('laravel-ide-helper::model_locations'),
64
+            $this->option('dir')
65
+        );
66
+        $model = $this->argument('model');
67
+        $ignore = $this->option('ignore');
68
+        $this->reset = $this->option('reset');
69
+
70
+        //If filename is default and Write is not specified, ask what to do
71
+        if (!$this->write && $filename === $this->filename && !$this->option('nowrite')) {
72
+            if ($this->confirm(
73
+                "Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): "
74
+            )
75
+            ) {
76
+                $this->write = true;
77
+            }
78
+        }
79
+
80
+        $content = $this->generateDocs($model, $ignore);
81
+
82
+        if (!$this->write) {
83
+            $written = \File::put($filename, $content);
84
+            if ($written !== false) {
85
+                $this->info("Model information was written to $filename");
86
+            } else {
87
+                $this->error("Failed to write model information to $filename");
88
+            }
89
+        }
90
+    }
91
+
92
+
93
+    /**
94
+     * Get the console command arguments.
95
+     *
96
+     * @return array
97
+     */
98
+    protected function getArguments()
99
+    {
100
+        return array(
101
+            array('model', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Which models to include', array()),
102
+        );
103
+    }
104
+
105
+    /**
106
+     * Get the console command options.
107
+     *
108
+     * @return array
109
+     */
110
+    protected function getOptions()
111
+    {
112
+        return array(
113
+            array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the helper file', $this->filename),
114
+            array('dir', 'D', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The model dir', array()),
115
+            array('write', 'W', InputOption::VALUE_NONE, 'Write to Model file'),
116
+            array('nowrite', 'N', InputOption::VALUE_NONE, 'Don\'t write to Model file'),
117
+            array('reset', 'R', InputOption::VALUE_NONE, 'Remove the original phpdocs instead of appending'),
118
+            array('ignore', 'I', InputOption::VALUE_OPTIONAL, 'Which models to ignore', ''),
119
+        );
120
+    }
121
+
122
+    protected function generateDocs($loadModels, $ignore = '')
123
+    {
124
+
125
+
126
+        $output = "<?php
127
+/**
128
+ * An helper file for your Eloquent Models
129
+ * Copy the phpDocs from this file to the correct Model,
130
+ * And remove them from this file, to prevent double declarations.
131
+ *
132
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
133
+ */
134
+\n\n";
135
+
136
+        $hasDoctrine = interface_exists('Doctrine\DBAL\Driver');
137
+
138
+        if (empty($loadModels)) {
139
+            $models = $this->loadModels();
140
+        } else {
141
+            $models = array();
142
+            foreach ($loadModels as $model) {
143
+                $models = array_merge($models, explode(',', $model));
144
+            }
145
+        }
146
+
147
+        $ignore = explode(',', $ignore);
148
+
149
+        foreach ($models as $name) {
150
+            if (in_array($name, $ignore)) {
151
+                $this->comment("Ignoring model '$name'");
152
+                continue;
153
+            } else {
154
+                $this->comment("Loading model '$name'");
155
+            }
156
+            $this->properties = array();
157
+            $this->methods = array();
158
+            if (class_exists($name)) {
159
+                try {
160
+                    // handle abstract classes, interfaces, ...
161
+                    $reflectionClass = new \ReflectionClass($name);
162
+                    if (!$reflectionClass->IsInstantiable()) {
163
+                        throw new \Exception($name . ' is not instanciable.');
164
+                    } elseif (!$reflectionClass->isSubclassOf('Illuminate\Database\Eloquent\Model')) {
165
+                        $this->comment("Class '$name' is not a model");
166
+                        continue;
167
+                    }
168
+
169
+                    $model = new $name();
170
+                    if ($hasDoctrine) {
171
+                        $this->getPropertiesFromTable($model);
172
+                    }
173
+                    $this->getPropertiesFromMethods($model);
174
+                    $output .= $this->createPhpDocs($name);
175
+                } catch (\Exception $e) {
176
+                    $this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name.");
177
+                }
178
+            } else {
179
+                $this->error("Class $name does not exist");
180
+            }
181
+
182
+        }
183
+
184
+        if (!$hasDoctrine) {
185
+            $this->error(
186
+                "Warning: 'doctrine/dbal: ~2.3' is required to load database information. Please require that in your composer.json and run 'composer update'."
187
+            );
188
+        }
189
+
190
+        return $output;
191
+
192
+    }
193
+
194
+
195
+    protected function loadModels()
196
+    {
197
+        $models = array();
198
+        foreach ($this->dirs as $dir) {
199
+            $dir = base_path() . '/' . $dir;
200
+            if (file_exists($dir)) {
201
+                foreach (ClassMapGenerator::createMap($dir) as $model => $path) {
202
+                    $models[] = $model;
203
+                }
204
+            }
205
+        }
206
+        return $models;
207
+    }
208
+
209
+    /**
210
+     * Load the properties from the database table.
211
+     *
212
+     * @param \Illuminate\Database\Eloquent\Model $model
213
+     */
214
+    protected function getPropertiesFromTable($model)
215
+    {
216
+        $table = $model->getConnection()->getTablePrefix() . $model->getTable();
217
+        $schema = $model->getConnection()->getDoctrineSchemaManager($table);
218
+        $schema->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
219
+
220
+        $columns = $schema->listTableColumns($table);
221
+
222
+        if ($columns) {
223
+            foreach ($columns as $column) {
224
+                $name = $column->getName();
225
+                if (in_array($name, $model->getDates())) {
226
+                    $type = '\Carbon\Carbon';
227
+                } else {
228
+                    $type = $column->getType()->getName();
229
+                    switch ($type) {
230
+                        case 'string':
231
+                        case 'text':
232
+                        case 'date':
233
+                        case 'time':
234
+                        case 'guid':
235
+                        case 'datetimetz':
236
+                        case 'datetime':
237
+                            $type = 'string';
238
+                            break;
239
+                        case 'integer':
240
+                        case 'bigint':
241
+                        case 'smallint':
242
+                            $type = 'integer';
243
+                            break;
244
+                        case 'decimal':
245
+                        case 'float':
246
+                            $type = 'float';
247
+                            break;
248
+                        case 'boolean':
249
+                            $type = 'boolean';
250
+                            break;
251
+                        default:
252
+                            $type = 'mixed';
253
+                            break;
254
+                    }
255
+                }
256
+
257
+
258
+                $this->setProperty($name, $type, true, true);
259
+                $this->setMethod(
260
+                    Str::camel("where_" . $name),
261
+                    '\Illuminate\Database\Query\Builder|\\' . get_class($model),
262
+                    array('$value')
263
+                );
264
+            }
265
+        }
266
+    }
267
+
268
+    /**
269
+     * @param \Illuminate\Database\Eloquent\Model $model
270
+     */
271
+    protected function getPropertiesFromMethods($model)
272
+    {
273
+        $methods = get_class_methods($model);
274
+        if ($methods) {
275
+            foreach ($methods as $method) {
276
+                if (Str::startsWith($method, 'get') && Str::endsWith(
277
+                        $method,
278
+                        'Attribute'
279
+                    ) && $method !== 'getAttribute'
280
+                ) {
281
+                    //Magic get<name>Attribute
282
+                    $name = Str::snake(substr($method, 3, -9));
283
+                    if (!empty($name)) {
284
+                        $this->setProperty($name, null, true, null);
285
+                    }
286
+                } elseif (Str::startsWith($method, 'set') && Str::endsWith(
287
+                        $method,
288
+                        'Attribute'
289
+                    ) && $method !== 'setAttribute'
290
+                ) {
291
+                    //Magic set<name>Attribute
292
+                    $name = Str::snake(substr($method, 3, -9));
293
+                    if (!empty($name)) {
294
+                        $this->setProperty($name, null, null, true);
295
+                    }
296
+                } elseif (Str::startsWith($method, 'scope') && $method !== 'scopeQuery') {
297
+                    //Magic set<name>Attribute
298
+                    $name = Str::camel(substr($method, 5));
299
+                    if (!empty($name)) {
300
+                        $reflection = new \ReflectionMethod($model, $method);
301
+                        $args = $this->getParameters($reflection);
302
+                        //Remove the first ($query) argument
303
+                        array_shift($args);
304
+                        $this->setMethod($name, '\\' . $reflection->class, $args);
305
+                    }
306
+                } elseif (!method_exists('Eloquent', $method) && !Str::startsWith($method, 'get')) {
307
+
308
+                    //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
309
+                    $reflection = new \ReflectionMethod($model, $method);
310
+
311
+                    $file = new \SplFileObject($reflection->getFileName());
312
+                    $file->seek($reflection->getStartLine() - 1);
313
+
314
+                    $code = '';
315
+                    while ($file->key() < $reflection->getEndLine()) {
316
+                        $code .= $file->current();
317
+                        $file->next();
318
+                    }
319
+                    $begin = strpos($code, 'function(');
320
+                    $code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
321
+
322
+                    foreach (array(
323
+                                 'hasMany',
324
+                                 'belongsToMany',
325
+                                 'hasOne',
326
+                                 'belongsTo',
327
+                                 'morphTo',
328
+                                 'morphMany',
329
+                                 'morphToMany'
330
+                             ) as $relation) {
331
+                        $search = '$this->' . $relation . '(';
332
+                        if ($pos = stripos($code, $search)) {
333
+                            $code = substr($code, $pos + strlen($search));
334
+                            $arguments = explode(',', substr($code, 0, stripos($code, ')')));
335
+                            //Remove quotes, ensure 1 \ in front of the model
336
+                            $returnModel = "\\" . ltrim(trim($arguments[0], " \"'"), "\\");
337
+                            if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
338
+                                //Collection or array of models (because Collection is Arrayable)
339
+                                $this->setProperty(
340
+                                    $method,
341
+                                    '\Illuminate\Database\Eloquent\Collection|' . $returnModel . '[]',
342
+                                    true,
343
+                                    null
344
+                                );
345
+                            } else {
346
+                                //Single model is returned
347
+                                $this->setProperty($method, $returnModel, true, null);
348
+                            }
349
+                        }
350
+                    }
351
+
352
+                }
353
+            }
354
+        }
355
+    }
356
+
357
+    /**
358
+     * @param string $name
359
+     * @param string|null $type
360
+     * @param bool|null $read
361
+     * @param bool|null $write
362
+     */
363
+    protected function setProperty($name, $type = null, $read = null, $write = null)
364
+    {
365
+        if (!isset($this->properties[$name])) {
366
+            $this->properties[$name] = array();
367
+            $this->properties[$name]['type'] = 'mixed';
368
+            $this->properties[$name]['read'] = false;
369
+            $this->properties[$name]['write'] = false;
370
+        }
371
+        if ($type !== null) {
372
+            $this->properties[$name]['type'] = $type;
373
+        }
374
+        if ($read !== null) {
375
+            $this->properties[$name]['read'] = $read;
376
+        }
377
+        if ($write !== null) {
378
+            $this->properties[$name]['write'] = $write;
379
+        }
380
+    }
381
+
382
+    protected function setMethod($name, $type = '', $arguments = array())
383
+    {
384
+        if (!isset($this->methods[$name])) {
385
+            $this->methods[$name] = array();
386
+            $this->methods[$name]['type'] = $type;
387
+            $this->methods[$name]['arguments'] = $arguments;
388
+        }
389
+    }
390
+
391
+    /**
392
+     * @param string $class
393
+     * @return string
394
+     */
395
+    protected function createPhpDocs($class)
396
+    {
397
+
398
+        $reflection = new \ReflectionClass($class);
399
+        $namespace = $reflection->getNamespaceName();
400
+        $classname = $reflection->getShortName();
401
+        $originalDoc = $reflection->getDocComment();
402
+
403
+        if ($this->reset) {
404
+            $phpdoc = new DocBlock('', new Context($namespace));
405
+        } else {
406
+            $phpdoc = new DocBlock($reflection, new Context($namespace));
407
+        }
408
+
409
+        if (!$phpdoc->getText()) {
410
+            $phpdoc->setText($class);
411
+        }
412
+
413
+        $properties = array();
414
+        $methods = array();
415
+        foreach ($phpdoc->getTags() as $tag) {
416
+            $name = $tag->getName();
417
+            if ($name == "property" || $name == "property-read" || $name == "property-write") {
418
+                $properties[] = $tag->getVariableName();
419
+            } elseif ($name == "method") {
420
+                $methods[] = $tag->getMethodName();
421
+            }
422
+        }
423
+
424
+        foreach ($this->properties as $name => $property) {
425
+            $name = "\$$name";
426
+            if (in_array($name, $properties)) {
427
+                continue;
428
+            }
429
+            if ($property['read'] && $property['write']) {
430
+                $attr = 'property';
431
+            } elseif ($property['write']) {
432
+                $attr = 'property-write';
433
+            } else {
434
+                $attr = 'property-read';
435
+            }
436
+            $tag = Tag::createInstance("@{$attr} {$property['type']} {$name}", $phpdoc);
437
+            $phpdoc->appendTag($tag);
438
+        }
439
+
440
+        foreach ($this->methods as $name => $method) {
441
+            if (in_array($name, $methods)) {
442
+                continue;
443
+            }
444
+            $arguments = implode(', ', $method['arguments']);
445
+            $tag = Tag::createInstance("@method static {$method['type']} {$name}({$arguments}) ", $phpdoc);
446
+            $phpdoc->appendTag($tag);
447
+        }
448
+
449
+        $serializer = new DocBlockSerializer();
450
+        $serializer->getDocComment($phpdoc);
451
+        $docComment = $serializer->getDocComment($phpdoc);
452
+
453
+
454
+        if ($this->write) {
455
+            $filename = $reflection->getFileName();
456
+            $contents = \File::get($filename);
457
+            if ($originalDoc) {
458
+                $contents = str_replace($originalDoc, $docComment, $contents);
459
+            } else {
460
+                $needle = "class {$classname}";
461
+                $replace = "{$docComment}\nclass {$classname}";
462
+                $pos = strpos($contents, $needle);
463
+                if ($pos !== false) {
464
+                    $contents = substr_replace($contents, $replace, $pos, strlen($needle));
465
+                }
466
+            }
467
+            if (\File::put($filename, $contents)) {
468
+                $this->info('Written new phpDocBlock to ' . $filename);
469
+            }
470
+        }
471
+
472
+        $output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n";
473
+        return $output;
474
+    }
475
+
476
+    /**
477
+     * Get the parameters and format them correctly
478
+     *
479
+     * @param $method
480
+     * @return array
481
+     */
482
+    public function getParameters($method)
483
+    {
484
+        //Loop through the default values for paremeters, and make the correct output string
485
+        $params = array();
486
+        $paramsWithDefault = array();
487
+        foreach ($method->getParameters() as $param) {
488
+            $paramStr = '$' . $param->getName();
489
+            $params[] = $paramStr;
490
+            if ($param->isOptional()) {
491
+                $default = $param->getDefaultValue();
492
+                if (is_bool($default)) {
493
+                    $default = $default ? 'true' : 'false';
494
+                } elseif (is_array($default)) {
495
+                    $default = 'array()';
496
+                } elseif (is_null($default)) {
497
+                    $default = 'null';
498
+                } elseif (is_int($default)) {
499
+                    //$default = $default;
500
+                } else {
501
+                    $default = "'" . trim($default) . "'";
502
+                }
503
+                $paramStr .= " = $default";
504
+            }
505
+            $paramsWithDefault[] = $paramStr;
506
+        }
507
+        return $paramsWithDefault;
508
+    }
509
+
510
+}

+ 196
- 0
vendor/barryvdh/laravel-ide-helper/src/Generator.php View File

@@ -0,0 +1,196 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper;
12
+
13
+use Illuminate\Foundation\AliasLoader;
14
+use Illuminate\Config\Repository as ConfigRepository;
15
+use Symfony\Component\Console\Output\OutputInterface;
16
+
17
+class Generator
18
+{
19
+    /** @var \Illuminate\Config\Repository */
20
+    protected $config;
21
+
22
+    /** @var \Illuminate\View\Factory */
23
+    protected $view;
24
+
25
+    /** @var \Symfony\Component\Console\Output\OutputInterface */
26
+    protected $output;
27
+
28
+    protected $extra = array();
29
+    protected $magic = array();
30
+    protected $interfaces = array();
31
+    protected $helpers;
32
+
33
+    /**
34
+     * @param \Illuminate\Config\Repository $config
35
+     * @param \Illuminate\View\Factory $view
36
+     * @param \Symfony\Component\Console\Output\OutputInterface $output
37
+     * @param string $helpers
38
+     */
39
+    public function __construct(ConfigRepository $config,
40
+        /* Illuminate\View\Factory */ $view,
41
+        OutputInterface $output = null,
42
+        $helpers = ''
43
+    ) {
44
+        $this->config = $config;
45
+        $this->view = $view;
46
+
47
+        // Find the drivers to add to the extra/interfaces
48
+        $this->detectDrivers();
49
+
50
+        $this->extra = array_merge($this->extra, $this->config->get('laravel-ide-helper::extra'));
51
+        $this->magic = array_merge($this->magic, $this->config->get('laravel-ide-helper::magic'));
52
+        $this->interfaces = array_merge($this->interfaces, $this->config->get('laravel-ide-helper::interfaces'));
53
+        $this->helpers = $helpers;
54
+    }
55
+
56
+    /**
57
+     * Generate the helper file contents;
58
+     *
59
+     * @return string;
60
+     */
61
+    public function generate()
62
+    {
63
+        $app = app();
64
+        return $this->view->make('laravel-ide-helper::ide-helper')
65
+            ->with('namespaces', $this->getNamespaces())
66
+            ->with('helpers', $this->helpers)
67
+            ->with('version', $app::VERSION)
68
+            ->render();
69
+    }
70
+
71
+    protected function detectDrivers()
72
+    {
73
+        try{
74
+            if (class_exists('Cache')) {
75
+                $class = get_class(\Auth::driver());
76
+                $this->extra['Auth'] = array($class);
77
+                $this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
78
+            }
79
+        }catch (\Exception $e) {}
80
+
81
+        try{
82
+            if (class_exists('DB')) {
83
+                $class = get_class(\DB::connection());
84
+                $this->extra['DB'] = array($class);
85
+                $this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
86
+            }
87
+        }catch (\Exception $e) {}
88
+
89
+        try{
90
+            if (class_exists('Cache')) {
91
+                $driver = get_class(\Cache::driver());
92
+                $store = get_class(\Cache::getStore());
93
+                $this->extra['Cache'] = array($driver, $store);
94
+                $this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
95
+            }
96
+        }catch (\Exception $e) {}
97
+
98
+        try{
99
+            if (class_exists('Queue')) {
100
+                $class = get_class(\Queue::connection());
101
+                $this->extra['Queue'] = array($class);
102
+                $this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
103
+            }
104
+        }catch (\Exception $e) {}
105
+
106
+        try{
107
+            if (class_exists('SSH')){
108
+                $class = get_class(\SSH::connection());
109
+                $this->extra['SSH'] = array($class);
110
+                $this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
111
+            }
112
+        }catch (\Exception $e) {}
113
+
114
+        // Make all interface classes absolute
115
+        foreach ($this->interfaces as &$interface) {
116
+            $interface = '\\' . ltrim($interface, '\\');
117
+        }
118
+    }
119
+
120
+    /**
121
+     * Find all namespaces/aliases that are valid for us to render
122
+     *
123
+     * @return array
124
+     */
125
+    protected function getNamespaces()
126
+    {
127
+        $namespaces = array();
128
+
129
+        // Get all aliases
130
+        foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) {
131
+            $magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
132
+            $alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
133
+            if ($alias->isValid()) {
134
+
135
+                //Add extra methods, from other classes (magic static calls)
136
+                if (array_key_exists($name, $this->extra)) {
137
+                    $alias->addClass($this->extra[$name]);
138
+                }
139
+
140
+                $namespace = $alias->getNamespace();
141
+                if (!isset($namespaces[$namespace])) {
142
+                    $namespaces[$namespace] = array();
143
+                }
144
+                $namespaces[$namespace][] = $alias;
145
+            }
146
+
147
+        }
148
+
149
+        return $namespaces;
150
+    }
151
+
152
+    /**
153
+     * Get the driver/connection/store from the managers
154
+     *
155
+     * @param $alias
156
+     * @return array|bool|string
157
+     */
158
+    public function getDriver($alias)
159
+    {
160
+        try {
161
+            if ($alias == "Auth") {
162
+                $driver = \Auth::driver();
163
+            } elseif ($alias == "DB") {
164
+                $driver = \DB::connection();
165
+            } elseif ($alias == "Cache") {
166
+                $driver = get_class(\Cache::driver());
167
+                $store = get_class(\Cache::getStore());
168
+                return array($driver, $store);
169
+            } elseif ($alias == "Queue") {
170
+                $driver = \Queue::connection();
171
+            } else {
172
+                return false;
173
+            }
174
+
175
+            return get_class($driver);
176
+        } catch (\Exception $e) {
177
+            $this->error("Could not determine driver/connection for $alias.");
178
+            return false;
179
+        }
180
+    }
181
+
182
+    /**
183
+     * Write a string as error output.
184
+     *
185
+     * @param  string  $string
186
+     * @return void
187
+     */
188
+    protected function error($string)
189
+    {
190
+        if($this->output){
191
+            $this->output->writeln("<error>$string</error>");
192
+        }else{
193
+            echo $string . "\r\n";
194
+        }
195
+    }
196
+}

+ 70
- 0
vendor/barryvdh/laravel-ide-helper/src/IdeHelperServiceProvider.php View File

@@ -0,0 +1,70 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper;
12
+
13
+use Illuminate\Support\ServiceProvider;
14
+use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand;
15
+use Barryvdh\LaravelIdeHelper\Console\Generator2Command;
16
+Use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
17
+
18
+class IdeHelperServiceProvider extends ServiceProvider
19
+{
20
+
21
+    /**
22
+     * Indicates if loading of the provider is deferred.
23
+     *
24
+     * @var bool
25
+     */
26
+    protected $defer = true;
27
+
28
+    /**
29
+     * Bootstrap the application events.
30
+     *
31
+     * @return void
32
+     */
33
+    public function boot()
34
+    {
35
+        $this->package('barryvdh/laravel-ide-helper', 'laravel-ide-helper', __DIR__);
36
+    }
37
+
38
+    /**
39
+     * Register the service provider.
40
+     *
41
+     * @return void
42
+     */
43
+    public function register()
44
+    {
45
+        $this->app['command.ide-helper.generate'] = $this->app->share(
46
+            function ($app) {
47
+                return new GeneratorCommand($app['config'], $app['files'], $app['view']);
48
+            }
49
+        );
50
+
51
+        $this->app['command.ide-helper.models'] = $this->app->share(
52
+            function () {
53
+                return new ModelsCommand();
54
+            }
55
+        );
56
+
57
+        $this->commands('command.ide-helper.generate', 'command.ide-helper.models');
58
+    }
59
+
60
+    /**
61
+     * Get the services provided by the provider.
62
+     *
63
+     * @return array
64
+     */
65
+    public function provides()
66
+    {
67
+        return array('command.ide-helper.generate', 'command.ide-helper.models');
68
+    }
69
+
70
+}

+ 300
- 0
vendor/barryvdh/laravel-ide-helper/src/Method.php View File

@@ -0,0 +1,300 @@
1
+<?php
2
+/**
3
+ * Laravel IDE Helper Generator
4
+ *
5
+ * @author    Barry vd. Heuvel <barryvdh@gmail.com>
6
+ * @copyright 2014 Barry vd. Heuvel / Fruitcake Studio (http://www.fruitcakestudio.nl)
7
+ * @license   http://www.opensource.org/licenses/mit-license.php MIT
8
+ * @link      https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+namespace Barryvdh\LaravelIdeHelper;
12
+
13
+use phpDocumentor\Reflection\DocBlock;
14
+use phpDocumentor\Reflection\DocBlock\Context;
15
+use phpDocumentor\Reflection\DocBlock\Tag;
16
+use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
17
+use phpDocumentor\Reflection\DocBlock\Tag\ParamTag;
18
+use phpDocumentor\Reflection\DocBlock\Serializer as DocBlockSerializer;
19
+
20
+class Method
21
+{
22
+    /** @var \phpDocumentor\Reflection\DocBlock  */
23
+    protected $phpdoc;
24
+
25
+    /** @var \ReflectionMethod  */
26
+    protected $method;
27
+
28
+    protected $output = '';
29
+    protected $name;
30
+    protected $namespace;
31
+    protected $params = array();
32
+    protected $params_with_default = array();
33
+    protected $interfaces = array();
34
+    protected $return = null;
35
+
36
+    /**
37
+     * @param \ReflectionMethod $method
38
+     * @param string $alias
39
+     * @param string $class
40
+     * @param string|null $methodName
41
+     * @param array $interfaces
42
+     */
43
+    public function __construct(\ReflectionMethod $method, $alias, $class, $methodName = null, $interfaces = array())
44
+    {
45
+        $this->method = $method;
46
+        $this->interfaces = $interfaces;
47
+        $this->name = $methodName ?: $method->name;
48
+        $this->namespace = $method->getDeclaringClass()->getNamespaceName();
49
+
50
+        //Create a DocBlock and serializer instance
51
+        $this->phpdoc = new DocBlock($method, new Context($this->namespace));
52
+
53
+        //Normalize the description and inherit the docs from parents/interfaces
54
+        try {
55
+            $this->normalizeDescription();
56
+            $this->normalizeParams();
57
+            $this->normalizeReturn();
58
+        } catch (\Exception $e) {}
59
+
60
+        //Get the parameters, including formatted default values
61
+        $this->getParameters($method);
62
+
63
+        //Make the method static
64
+        $this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
65
+
66
+        //Reference the 'real' function in the declaringclass
67
+        $declaringClass = $method->getDeclaringClass();
68
+        $this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
69
+        $this->root = '\\' . ltrim($class->getName(), '\\');
70
+    }
71
+
72
+    /**
73
+     * Get the class wherein the function resides
74
+     *
75
+     * @return string
76
+     */
77
+    public function getDeclaringClass()
78
+    {
79
+        return $this->declaringClassName;
80
+    }
81
+
82
+    /**
83
+     * Return the class from which this function would be called
84
+     *
85
+     * @return string
86
+     */
87
+    public function getRoot()
88
+    {
89
+        return $this->root;
90
+    }
91
+
92
+    /**
93
+     * Get the docblock for this method
94
+     *
95
+     * @param string $prefix
96
+     * @return mixed
97
+     */
98
+    public function getDocComment($prefix = "\t\t")
99
+    {
100
+        $serializer = new DocBlockSerializer(1, $prefix);
101
+        return $serializer->getDocComment($this->phpdoc);
102
+    }
103
+
104
+    /**
105
+     * Get the method name
106
+     *
107
+     * @return string
108
+     */
109
+    public function getName()
110
+    {
111
+        return $this->name;
112
+    }
113
+
114
+    /**
115
+     * Get the parameters for this method
116
+     *
117
+     * @param bool $implode Wether to implode the array or not
118
+     * @return string
119
+     */
120
+    public function getParams($implode = true)
121
+    {
122
+        return $implode ? implode(', ', $this->params) : $this->params;
123
+    }
124
+
125
+    /**
126
+     * Get the parameters for this method including default values
127
+     *
128
+     * @param bool $implode Wether to implode the array or not
129
+     * @return string
130
+     */
131
+    public function getParamsWithDefault($implode = true)
132
+    {
133
+        return $implode ? implode(', ', $this->params_with_default) : $this->params_with_default;
134
+    }
135
+
136
+    /**
137
+     * Get the description and get the inherited docs.
138
+     *
139
+     */
140
+    protected function normalizeDescription()
141
+    {
142
+        //Get the short + long description from the DocBlock
143
+        $description = $this->phpdoc->getText();
144
+
145
+        //Loop through parents/interfaces, to fill in {@inheritdoc}
146
+        if (strpos($description, '{@inheritdoc}') !== false) {
147
+            $inheritdoc = $this->getInheritDoc($this->method);
148
+            $inheritDescription = $inheritdoc->getText();
149
+
150
+            $description = str_replace('{@inheritdoc}', $inheritDescription, $description);
151
+            $this->phpdoc->setText($description);
152
+
153
+            //Add the tags that are inherited
154
+            $inheritTags = $inheritdoc->getTags();
155
+            if ($inheritTags) {
156
+                foreach ($inheritTags as $tag) {
157
+                    $tag->setDocBlock();
158
+                    $this->phpdoc->appendTag($tag);
159
+                }
160
+            }
161
+        }
162
+    }
163
+
164
+    /**
165
+     * Normalize the parameters
166
+     */
167
+    protected function normalizeParams()
168
+    {
169
+        //Get the return type and adjust them for beter autocomplete
170
+        $paramTags = $this->phpdoc->getTagsByName('param');
171
+        if ($paramTags) {
172
+            /** @var ParamTag $tag */
173
+            foreach($paramTags as $tag){
174
+                // Convert the keywords
175
+                $content = $this->convertKeywords($tag->getContent());
176
+                $tag->setContent($content);
177
+
178
+                // Get the expanded type and re-set the content
179
+                $content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
180
+                $tag->setContent(trim($content));
181
+            }
182
+        }
183
+    }
184
+
185
+    /**
186
+     * Normalize the return tag (make full namespace, replace interfaces)
187
+     */
188
+    protected function normalizeReturn()
189
+    {
190
+        //Get the return type and adjust them for beter autocomplete
191
+        $returnTags = $this->phpdoc->getTagsByName('return');
192
+        if ($returnTags) {
193
+            /** @var ReturnTag $tag */
194
+            $tag = reset($returnTags);
195
+            // Get the expanded type
196
+            $returnValue = $tag->getType();
197
+
198
+            // Replace the interfaces
199
+            foreach($this->interfaces as $interface => $real){
200
+                $returnValue = str_replace($interface, $real, $returnValue);
201
+            }
202
+
203
+            // Set the changed content
204
+            $tag->setContent($returnValue . ' ' . $tag->getDescription());
205
+            $this->return = $returnValue;
206
+        }else{
207
+            $this->return = null;
208
+        }
209
+    }
210
+
211
+    /**
212
+     * Convert keywwords that are incorrect.
213
+     *
214
+     * @param  string $string
215
+     * @return string
216
+     */
217
+    protected function convertKeywords($string)
218
+    {
219
+        $string = str_replace('\Closure', 'Closure', $string);
220
+        $string = str_replace('Closure', '\Closure', $string);
221
+        $string = str_replace('dynamic', 'mixed', $string);
222
+
223
+        return $string;
224
+    }
225
+
226
+    /**
227
+     * Should the function return a value?
228
+     *
229
+     * @return bool
230
+     */
231
+    public function shouldReturn()
232
+    {
233
+        if($this->return !== "void" && $this->method->name !== "__construct"){
234
+            return true;
235
+        }
236
+
237
+        return false;
238
+    }
239
+
240
+    /**
241
+     * Get the parameters and format them correctly
242
+     *
243
+     * @param $method
244
+     * @return array
245
+     */
246
+    public function getParameters($method)
247
+    {
248
+        //Loop through the default values for paremeters, and make the correct output string
249
+        $params = array();
250
+        $paramsWithDefault = array();
251
+        foreach ($method->getParameters() as $param) {
252
+            $paramStr = '$' . $param->getName();
253
+            $params[] = $paramStr;
254
+            if ($param->isOptional()) {
255
+                $default = $param->getDefaultValue();
256
+                if (is_bool($default)) {
257
+                    $default = $default ? 'true' : 'false';
258
+                } elseif (is_array($default)) {
259
+                    $default = 'array()';
260
+                } elseif (is_null($default)) {
261
+                    $default = 'null';
262
+                } elseif (is_int($default)) {
263
+                    //$default = $default;
264
+                } else {
265
+                    $default = "'" . trim($default) . "'";
266
+                }
267
+                $paramStr .= " = $default";
268
+            }
269
+            $paramsWithDefault[] = $paramStr;
270
+        }
271
+
272
+        $this->params = $params;
273
+        $this->params_with_default = $paramsWithDefault;
274
+    }
275
+
276
+    /**
277
+     * @param \ReflectionMethod $reflectionMethod
278
+     * @return string
279
+     */
280
+    protected function getInheritDoc($reflectionMethod)
281
+    {
282
+        $parentClass = $reflectionMethod->getDeclaringClass()->getParentClass();
283
+
284
+        //Get either a parent or the interface
285
+        if ($parentClass) {
286
+            $method = $parentClass->getMethod($reflectionMethod->getName());
287
+        } else {
288
+            $method = $reflectionMethod->getPrototype();
289
+        }
290
+        if ($method) {
291
+            $phpdoc = new DocBlock($method);
292
+            if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
293
+                //Not at the end yet, try another parent/interface..
294
+                return $this->getInheritDoc($method);
295
+            } else {
296
+                return $phpdoc;
297
+            }
298
+        }
299
+    }
300
+}

+ 78
- 0
vendor/barryvdh/laravel-ide-helper/src/config/config.php View File

@@ -0,0 +1,78 @@
1
+<?php
2
+
3
+return array(
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Filename
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | The default path to the helper file
11
+    |
12
+    */
13
+
14
+    'filename' => '_ide_helper.php',
15
+
16
+    /*
17
+    |--------------------------------------------------------------------------
18
+    | Helper files to include
19
+    |--------------------------------------------------------------------------
20
+    |
21
+    | Include helper files. By default not included, but can be toggled with the
22
+    | -- helpers (-H) option. Extra helper files can be included.
23
+    |
24
+    */
25
+
26
+    'include_helpers' => false,
27
+
28
+    'helper_files' => array(
29
+        base_path().'/vendor/laravel/framework/src/Illuminate/Support/helpers.php',
30
+    ),
31
+
32
+    /*
33
+    |--------------------------------------------------------------------------
34
+    | Model locations to include
35
+    |--------------------------------------------------------------------------
36
+    |
37
+    | Define in which directories the ide-helper:models command should look
38
+    | for models.
39
+    |
40
+    */
41
+
42
+    'model_locations' => array(
43
+        'app/models',
44
+    ),
45
+
46
+
47
+    /*
48
+    |--------------------------------------------------------------------------
49
+    | Extra classes
50
+    |--------------------------------------------------------------------------
51
+    |
52
+    | These implementations are not really extended, but called with magic functions
53
+    |
54
+    */
55
+
56
+    'extra' => array(
57
+        'Artisan' => array('Illuminate\Foundation\Artisan'),
58
+        'Eloquent' => array('Illuminate\Database\Eloquent\Builder', 'Illuminate\Database\Query\Builder'),
59
+        'Session' => array('Illuminate\Session\Store'),
60
+    ),
61
+
62
+    'magic' => array(
63
+        'Log' => array(
64
+            'debug'     => 'Monolog\Logger::addDebug',
65
+            'info'      => 'Monolog\Logger::addInfo',
66
+            'notice'    => 'Monolog\Logger::addNotice',
67
+            'warning'   => 'Monolog\Logger::addWarning',
68
+            'error'     => 'Monolog\Logger::addError',
69
+            'critical'  => 'Monolog\Logger::addCritical',
70
+            'alert'     => 'Monolog\Logger::addAlert',
71
+            'emergency' => 'Monolog\Logger::addEmergency',
72
+        )
73
+    ),
74
+    'interfaces' => array(
75
+        '\Illuminate\Auth\UserInterface' => '\User',
76
+    )
77
+
78
+);

+ 39
- 0
vendor/barryvdh/laravel-ide-helper/src/views/ide-helper.php View File

@@ -0,0 +1,39 @@
1
+<?= '<?php' ?>
2
+
3
+/**
4
+ * An helper file for Laravel 4, to provide autocomplete information to your IDE
5
+ * Generated for Laravel <?= $version ?> on <?= date("Y-m-d") ?>.
6
+ *
7
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
8
+ * @see https://github.com/barryvdh/laravel-ide-helper
9
+ */
10
+
11
+<?php foreach($namespaces as $namespace => $aliases): ?>
12
+namespace <?= $namespace == '__root' ? '' : $namespace ?>{
13
+<?php if($namespace == '__root'): ?>
14
+    exit("This file should not be included, only analyzed by your IDE");
15
+<?= $helpers ?>
16
+<?php endif; ?>
17
+<?php foreach($aliases as $alias): ?>
18
+
19
+    <?= $alias->getClassType() ?> <?= $alias->getAlias() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{
20
+        <?php foreach($alias->getMethods() as $method): ?>
21
+
22
+        <?= trim($method->getDocComment()) ?>
23
+
24
+        public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>){<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
25
+
26
+            //Method inherited from <?= $method->getDeclaringClass() ?>
27
+            <?php endif; ?>
28
+
29
+            <?= $method->shouldReturn() ? 'return ': '' ?><?= $method->getRoot() ?>::<?= $method->getName() ?>(<?= $method->getParams() ?>);
30
+        }
31
+        <?php endforeach; ?>
32
+
33
+    }
34
+
35
+<?php endforeach; ?>
36
+
37
+}
38
+
39
+<?php endforeach; ?>

+ 13
- 0
vendor/dompdf/dompdf/.gitattributes View File

@@ -0,0 +1,13 @@
1
+*.json  text
2
+*.xml		text
3
+*.php		text
4
+*.LGPL	text
5
+*.md    text
6
+*.skel 	text
7
+*.css   text
8
+*.inc		text
9
+*.js    text
10
+*.html  text
11
+*.txt   text
12
+*.svg   text
13
+

+ 8
- 0
vendor/dompdf/dompdf/.gitignore View File

@@ -0,0 +1,8 @@
1
+.DS_Store
2
+composer.lock
3
+vendor
4
+.idea
5
+.project
6
+lib/fonts/*.afm.php
7
+lib/fonts/*.ufm.php
8
+lib/fonts/log.htm

+ 3
- 0
vendor/dompdf/dompdf/.gitmodules View File

@@ -0,0 +1,3 @@
1
+[submodule "lib/php-font-lib"]
2
+	path = lib/php-font-lib
3
+	url = https://github.com/PhenX/php-font-lib.git

+ 76
- 0
vendor/dompdf/dompdf/CONTRIBUTING.md View File

@@ -0,0 +1,76 @@
1
+# How to contribute
2
+
3
+- [Getting help](#getting-help)
4
+- [Submitting bug reports](#submitting-bug-reports)
5
+- [Contributing code](#contributing-code)
6
+
7
+## Getting help
8
+
9
+Community discussion, questions, and informal bug reporting is done on the
10
+[dompdf Google group](http://groups.google.com/group/dompdf). You may also 
11
+seek help on
12
+[StackOverflow](http://stackoverflow.com/questions/tagged/dompdf).
13
+
14
+## Submitting bug reports
15
+
16
+The preferred way to report bugs is to use the
17
+[GitHub issue tracker](http://github.com/dompdf/dompdf/issues). Before 
18
+reporting a bug, read these pointers.
19
+
20
+**Please search inside the bug tracker to see if the bug you found is not already reported.**
21
+
22
+**Note:** The issue tracker is for *bugs* and *feature requests*, not requests for help.
23
+Questions should be asked on the
24
+[dompdf Google group](http://groups.google.com/group/dompdf) instead.
25
+
26
+### Reporting bugs effectively
27
+
28
+- dompdf is maintained by volunteers. They don't owe you anything, so be
29
+  polite. Reports with an indignant or belligerent tone tend to be moved to the
30
+  bottom of the pile.
31
+
32
+- Include information about **the PHP version on which the problem occurred**. Even
33
+  if you tested several PHP version on different servers, and the problem occurred
34
+  in all of them, mention this fact in the bug report.
35
+  Also include the operating system it's installed on. PHP configuration can also help,
36
+  and server error logs (like Apache logs)
37
+
38
+- Mention which release of dompdf you're using (the zip, the master branch, etc).
39
+  Preferably, try also with the current development snapshot, to ensure the
40
+  problem has not already been fixed.
41
+
42
+- Mention very precisely what went wrong. "X is broken" is not a good bug
43
+  report. What did you expect to happen? What happened instead? Describe the
44
+  exact steps a maintainer has to take to make the problem occur. We can not
45
+  fix something that we can not observe.
46
+
47
+- If the problem can not be reproduced in any of the demos included in the
48
+  dompdf distribution, please provide an HTML document that demonstrates
49
+  the problem. There are a few options to show us your code:
50
+   - [JS Fiddle](http://jsfiddle.net/)
51
+   - [dompdf debug helper](http://eclecticgeek.com/dompdf/debug.php) (provided by @bsweeney)
52
+   - Include the HTML/CSS inside the bug report, with
53
+   [code highlighting](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-code).
54
+
55
+## Contributing code
56
+
57
+- Make sure you have a [GitHub Account](https://github.com/signup/free)
58
+- Fork [dompdf](https://github.com/dompdf/dompdf/)
59
+  ([how to fork a repo](https://help.github.com/articles/fork-a-repo))
60
+- *Make your changes on the dev branch* or the most appropriate feature branch. Please only patch 
61
+  the master branch if you are attempting to address an urgent bug in the released code.
62
+- Add a simple test file in `www/test/`, with a comprehensive name.
63
+- Submit a pull request
64
+([how to create a pull request](https://help.github.com/articles/fork-a-repo))
65
+
66
+### Coding standards
67
+
68
+- 2 spaces per indentation level, no tabs.
69
+- spaces inside `if` like this:
70
+```php
71
+if ( $foo == "bar" ) {
72
+  //
73
+}
74
+```
75
+- booleans in lowercase
76
+- opening braces *always* on the same line

+ 456
- 0
vendor/dompdf/dompdf/LICENSE.LGPL View File

@@ -0,0 +1,456 @@
1
+		  GNU LESSER GENERAL PUBLIC LICENSE
2
+		       Version 2.1, February 1999
3
+
4
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+[This is the first released version of the Lesser GPL.  It also counts
10
+ as the successor of the GNU Library Public License, version 2, hence
11
+ the version number 2.1.]
12
+
13
+			    Preamble
14
+
15
+  The licenses for most software are designed to take away your
16
+freedom to share and change it.  By contrast, the GNU General Public
17
+Licenses are intended to guarantee your freedom to share and change
18
+free software--to make sure the software is free for all its users.
19
+
20
+  This license, the Lesser General Public License, applies to some
21
+specially designated software packages--typically libraries--of the
22
+Free Software Foundation and other authors who decide to use it.  You
23
+can use it too, but we suggest you first think carefully about whether
24
+this license or the ordinary General Public License is the better
25
+strategy to use in any particular case, based on the explanations below.
26
+
27
+  When we speak of free software, we are referring to freedom of use,
28
+not price.  Our General Public Licenses are designed to make sure that
29
+you have the freedom to distribute copies of free software (and charge
30
+for this service if you wish); that you receive source code or can get
31
+it if you want it; that you can change the software and use pieces of
32
+it in new free programs; and that you are informed that you can do
33
+these things.
34
+
35
+  To protect your rights, we need to make restrictions that forbid
36
+distributors to deny you these rights or to ask you to surrender these
37
+rights.  These restrictions translate to certain responsibilities for
38
+you if you distribute copies of the library or if you modify it.
39
+
40
+  For example, if you distribute copies of the library, whether gratis
41
+or for a fee, you must give the recipients all the rights that we gave
42
+you.  You must make sure that they, too, receive or can get the source
43
+code.  If you link other code with the library, you must provide
44
+complete object files to the recipients, so that they can relink them
45
+with the library after making changes to the library and recompiling
46
+it.  And you must show them these terms so they know their rights.
47
+
48
+  We protect your rights with a two-step method: (1) we copyright the
49
+library, and (2) we offer you this license, which gives you legal
50
+permission to copy, distribute and/or modify the library.
51
+
52
+  To protect each distributor, we want to make it very clear that
53
+there is no warranty for the free library.  Also, if the library is
54
+modified by someone else and passed on, the recipients should know
55
+that what they have is not the original version, so that the original
56
+author's reputation will not be affected by problems that might be
57
+introduced by others.
58
+
59
+  Finally, software patents pose a constant threat to the existence of
60
+any free program.  We wish to make sure that a company cannot
61
+effectively restrict the users of a free program by obtaining a
62
+restrictive license from a patent holder.  Therefore, we insist that
63
+any patent license obtained for a version of the library must be
64
+consistent with the full freedom of use specified in this license.
65
+
66
+  Most GNU software, including some libraries, is covered by the
67
+ordinary GNU General Public License.  This license, the GNU Lesser
68
+General Public License, applies to certain designated libraries, and
69
+is quite different from the ordinary General Public License.  We use
70
+this license for certain libraries in order to permit linking those
71
+libraries into non-free programs.
72
+
73
+  When a program is linked with a library, whether statically or using
74
+a shared library, the combination of the two is legally speaking a
75
+combined work, a derivative of the original library.  The ordinary
76
+General Public License therefore permits such linking only if the
77
+entire combination fits its criteria of freedom.  The Lesser General
78
+Public License permits more lax criteria for linking other code with
79
+the library.
80
+
81
+  We call this license the "Lesser" General Public License because it
82
+does Less to protect the user's freedom than the ordinary General
83
+Public License.  It also provides other free software developers Less
84
+of an advantage over competing non-free programs.  These disadvantages
85
+are the reason we use the ordinary General Public License for many
86
+libraries.  However, the Lesser license provides advantages in certain
87
+special circumstances.
88
+
89
+  For example, on rare occasions, there may be a special need to
90
+encourage the widest possible use of a certain library, so that it becomes
91
+a de-facto standard.  To achieve this, non-free programs must be
92
+allowed to use the library.  A more frequent case is that a free
93
+library does the same job as widely used non-free libraries.  In this
94
+case, there is little to gain by limiting the free library to free
95
+software only, so we use the Lesser General Public License.
96
+
97
+  In other cases, permission to use a particular library in non-free
98
+programs enables a greater number of people to use a large body of
99
+free software.  For example, permission to use the GNU C Library in
100
+non-free programs enables many more people to use the whole GNU
101
+operating system, as well as its variant, the GNU/Linux operating
102
+system.
103
+
104
+  Although the Lesser General Public License is Less protective of the
105
+users' freedom, it does ensure that the user of a program that is
106
+linked with the Library has the freedom and the wherewithal to run
107
+that program using a modified version of the Library.
108
+
109
+  The precise terms and conditions for copying, distribution and
110
+modification follow.  Pay close attention to the difference between a
111
+"work based on the library" and a "work that uses the library".  The
112
+former contains code derived from the library, whereas the latter must
113
+be combined with the library in order to run.
114
+
115
+		  GNU LESSER GENERAL PUBLIC LICENSE
116
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
+
118
+  0. This License Agreement applies to any software library or other
119
+program which contains a notice placed by the copyright holder or
120
+other authorized party saying it may be distributed under the terms of
121
+this Lesser General Public License (also called "this License").
122
+Each licensee is addressed as "you".
123
+
124
+  A "library" means a collection of software functions and/or data
125
+prepared so as to be conveniently linked with application programs
126
+(which use some of those functions and data) to form executables.
127
+
128
+  The "Library", below, refers to any such software library or work
129
+which has been distributed under these terms.  A "work based on the
130
+Library" means either the Library or any derivative work under
131
+copyright law: that is to say, a work containing the Library or a
132
+portion of it, either verbatim or with modifications and/or translated
133
+straightforwardly into another language.  (Hereinafter, translation is
134
+included without limitation in the term "modification".)
135
+
136
+  "Source code" for a work means the preferred form of the work for
137
+making modifications to it.  For a library, complete source code means
138
+all the source code for all modules it contains, plus any associated
139
+interface definition files, plus the scripts used to control compilation
140
+and installation of the library.
141
+
142
+  Activities other than copying, distribution and modification are not
143
+covered by this License; they are outside its scope.  The act of
144
+running a program using the Library is not restricted, and output from
145
+such a program is covered only if its contents constitute a work based
146
+on the Library (independent of the use of the Library in a tool for
147
+writing it).  Whether that is true depends on what the Library does
148
+and what the program that uses the Library does.
149
+  
150
+  1. You may copy and distribute verbatim copies of the Library's
151
+complete source code as you receive it, in any medium, provided that
152
+you conspicuously and appropriately publish on each copy an
153
+appropriate copyright notice and disclaimer of warranty; keep intact
154
+all the notices that refer to this License and to the absence of any
155
+warranty; and distribute a copy of this License along with the
156
+Library.
157
+
158
+  You may charge a fee for the physical act of transferring a copy,
159
+and you may at your option offer warranty protection in exchange for a
160
+fee.
161
+
162
+  2. You may modify your copy or copies of the Library or any portion
163
+of it, thus forming a work based on the Library, and copy and
164
+distribute such modifications or work under the terms of Section 1
165
+above, provided that you also meet all of these conditions:
166
+
167
+    a) The modified work must itself be a software library.
168
+
169
+    b) You must cause the files modified to carry prominent notices
170
+    stating that you changed the files and the date of any change.
171
+
172
+    c) You must cause the whole of the work to be licensed at no
173
+    charge to all third parties under the terms of this License.
174
+
175
+    d) If a facility in the modified Library refers to a function or a
176
+    table of data to be supplied by an application program that uses
177
+    the facility, other than as an argument passed when the facility
178
+    is invoked, then you must make a good faith effort to ensure that,
179
+    in the event an application does not supply such function or
180
+    table, the facility still operates, and performs whatever part of
181
+    its purpose remains meaningful.
182
+
183
+    (For example, a function in a library to compute square roots has
184
+    a purpose that is entirely well-defined independent of the
185
+    application.  Therefore, Subsection 2d requires that any
186
+    application-supplied function or table used by this function must
187
+    be optional: if the application does not supply it, the square
188
+    root function must still compute square roots.)
189
+
190
+These requirements apply to the modified work as a whole.  If
191
+identifiable sections of that work are not derived from the Library,
192
+and can be reasonably considered independent and separate works in
193
+themselves, then this License, and its terms, do not apply to those
194
+sections when you distribute them as separate works.  But when you
195
+distribute the same sections as part of a whole which is a work based
196
+on the Library, the distribution of the whole must be on the terms of
197
+this License, whose permissions for other licensees extend to the
198
+entire whole, and thus to each and every part regardless of who wrote
199
+it.
200
+
201
+Thus, it is not the intent of this section to claim rights or contest
202
+your rights to work written entirely by you; rather, the intent is to
203
+exercise the right to control the distribution of derivative or
204
+collective works based on the Library.
205
+
206
+In addition, mere aggregation of another work not based on the Library
207
+with the Library (or with a work based on the Library) on a volume of
208
+a storage or distribution medium does not bring the other work under
209
+the scope of this License.
210
+
211
+  3. You may opt to apply the terms of the ordinary GNU General Public
212
+License instead of this License to a given copy of the Library.  To do
213
+this, you must alter all the notices that refer to this License, so
214
+that they refer to the ordinary GNU General Public License, version 2,
215
+instead of to this License.  (If a newer version than version 2 of the
216
+ordinary GNU General Public License has appeared, then you can specify
217
+that version instead if you wish.)  Do not make any other change in
218
+these notices.
219
+
220
+  Once this change is made in a given copy, it is irreversible for
221
+that copy, so the ordinary GNU General Public License applies to all
222
+subsequent copies and derivative works made from that copy.
223
+
224
+  This option is useful when you wish to copy part of the code of
225
+the Library into a program that is not a library.
226
+
227
+  4. You may copy and distribute the Library (or a portion or
228
+derivative of it, under Section 2) in object code or executable form
229
+under the terms of Sections 1 and 2 above provided that you accompany
230
+it with the complete corresponding machine-readable source code, which
231
+must be distributed under the terms of Sections 1 and 2 above on a
232
+medium customarily used for software interchange.
233
+
234
+  If distribution of object code is made by offering access to copy
235
+from a designated place, then offering equivalent access to copy the
236
+source code from the same place satisfies the requirement to
237
+distribute the source code, even though third parties are not
238
+compelled to copy the source along with the object code.
239
+
240
+  5. A program that contains no derivative of any portion of the
241
+Library, but is designed to work with the Library by being compiled or
242
+linked with it, is called a "work that uses the Library".  Such a
243
+work, in isolation, is not a derivative work of the Library, and
244
+therefore falls outside the scope of this License.
245
+
246
+  However, linking a "work that uses the Library" with the Library
247
+creates an executable that is a derivative of the Library (because it
248
+contains portions of the Library), rather than a "work that uses the
249
+library".  The executable is therefore covered by this License.
250
+Section 6 states terms for distribution of such executables.
251
+
252
+  When a "work that uses the Library" uses material from a header file
253
+that is part of the Library, the object code for the work may be a
254
+derivative work of the Library even though the source code is not.
255
+Whether this is true is especially significant if the work can be
256
+linked without the Library, or if the work is itself a library.  The
257
+threshold for this to be true is not precisely defined by law.
258
+
259
+  If such an object file uses only numerical parameters, data
260
+structure layouts and accessors, and small macros and small inline
261
+functions (ten lines or less in length), then the use of the object
262
+file is unrestricted, regardless of whether it is legally a derivative
263
+work.  (Executables containing this object code plus portions of the
264
+Library will still fall under Section 6.)
265
+
266
+  Otherwise, if the work is a derivative of the Library, you may
267
+distribute the object code for the work under the terms of Section 6.
268
+Any executables containing that work also fall under Section 6,
269
+whether or not they are linked directly with the Library itself.
270
+
271
+  6. As an exception to the Sections above, you may also combine or
272
+link a "work that uses the Library" with the Library to produce a
273
+work containing portions of the Library, and distribute that work
274
+under terms of your choice, provided that the terms permit
275
+modification of the work for the customer's own use and reverse
276
+engineering for debugging such modifications.
277
+
278
+  You must give prominent notice with each copy of the work that the
279
+Library is used in it and that the Library and its use are covered by
280
+this License.  You must supply a copy of this License.  If the work
281
+during execution displays copyright notices, you must include the
282
+copyright notice for the Library among them, as well as a reference
283
+directing the user to the copy of this License.  Also, you must do one
284
+of these things:
285
+
286
+    a) Accompany the work with the complete corresponding
287
+    machine-readable source code for the Library including whatever
288
+    changes were used in the work (which must be distributed under
289
+    Sections 1 and 2 above); and, if the work is an executable linked
290
+    with the Library, with the complete machine-readable "work that
291
+    uses the Library", as object code and/or source code, so that the
292
+    user can modify the Library and then relink to produce a modified
293
+    executable containing the modified Library.  (It is understood
294
+    that the user who changes the contents of definitions files in the
295
+    Library will not necessarily be able to recompile the application
296
+    to use the modified definitions.)
297
+
298
+    b) Use a suitable shared library mechanism for linking with the
299
+    Library.  A suitable mechanism is one that (1) uses at run time a
300
+    copy of the library already present on the user's computer system,
301
+    rather than copying library functions into the executable, and (2)
302
+    will operate properly with a modified version of the library, if
303
+    the user installs one, as long as the modified version is
304
+    interface-compatible with the version that the work was made with.
305
+
306
+    c) Accompany the work with a written offer, valid for at
307
+    least three years, to give the same user the materials
308
+    specified in Subsection 6a, above, for a charge no more
309
+    than the cost of performing this distribution.
310
+
311
+    d) If distribution of the work is made by offering access to copy
312
+    from a designated place, offer equivalent access to copy the above
313
+    specified materials from the same place.
314
+
315
+    e) Verify that the user has already received a copy of these
316
+    materials or that you have already sent this user a copy.
317
+
318
+  For an executable, the required form of the "work that uses the
319
+Library" must include any data and utility programs needed for
320
+reproducing the executable from it.  However, as a special exception,
321
+the materials to be distributed need not include anything that is
322
+normally distributed (in either source or binary form) with the major
323
+components (compiler, kernel, and so on) of the operating system on
324
+which the executable runs, unless that component itself accompanies
325
+the executable.
326
+
327
+  It may happen that this requirement contradicts the license
328
+restrictions of other proprietary libraries that do not normally
329
+accompany the operating system.  Such a contradiction means you cannot
330
+use both them and the Library together in an executable that you
331
+distribute.
332
+
333
+  7. You may place library facilities that are a work based on the
334
+Library side-by-side in a single library together with other library
335
+facilities not covered by this License, and distribute such a combined
336
+library, provided that the separate distribution of the work based on
337
+the Library and of the other library facilities is otherwise
338
+permitted, and provided that you do these two things:
339
+
340
+    a) Accompany the combined library with a copy of the same work
341
+    based on the Library, uncombined with any other library
342
+    facilities.  This must be distributed under the terms of the
343
+    Sections above.
344
+
345
+    b) Give prominent notice with the combined library of the fact
346
+    that part of it is a work based on the Library, and explaining
347
+    where to find the accompanying uncombined form of the same work.
348
+
349
+  8. You may not copy, modify, sublicense, link with, or distribute
350
+the Library except as expressly provided under this License.  Any
351
+attempt otherwise to copy, modify, sublicense, link with, or
352
+distribute the Library is void, and will automatically terminate your
353
+rights under this License.  However, parties who have received copies,
354
+or rights, from you under this License will not have their licenses
355
+terminated so long as such parties remain in full compliance.
356
+
357
+  9. You are not required to accept this License, since you have not
358
+signed it.  However, nothing else grants you permission to modify or
359
+distribute the Library or its derivative works.  These actions are
360
+prohibited by law if you do not accept this License.  Therefore, by
361
+modifying or distributing the Library (or any work based on the
362
+Library), you indicate your acceptance of this License to do so, and
363
+all its terms and conditions for copying, distributing or modifying
364
+the Library or works based on it.
365
+
366
+  10. Each time you redistribute the Library (or any work based on the
367
+Library), the recipient automatically receives a license from the
368
+original licensor to copy, distribute, link with or modify the Library
369
+subject to these terms and conditions.  You may not impose any further
370
+restrictions on the recipients' exercise of the rights granted herein.
371
+You are not responsible for enforcing compliance by third parties with
372
+this License.
373
+
374
+  11. If, as a consequence of a court judgment or allegation of patent
375
+infringement or for any other reason (not limited to patent issues),
376
+conditions are imposed on you (whether by court order, agreement or
377
+otherwise) that contradict the conditions of this License, they do not
378
+excuse you from the conditions of this License.  If you cannot
379
+distribute so as to satisfy simultaneously your obligations under this
380
+License and any other pertinent obligations, then as a consequence you
381
+may not distribute the Library at all.  For example, if a patent
382
+license would not permit royalty-free redistribution of the Library by
383
+all those who receive copies directly or indirectly through you, then
384
+the only way you could satisfy both it and this License would be to
385
+refrain entirely from distribution of the Library.
386
+
387
+If any portion of this section is held invalid or unenforceable under any
388
+particular circumstance, the balance of the section is intended to apply,
389
+and the section as a whole is intended to apply in other circumstances.
390
+
391
+It is not the purpose of this section to induce you to infringe any
392
+patents or other property right claims or to contest validity of any
393
+such claims; this section has the sole purpose of protecting the
394
+integrity of the free software distribution system which is
395
+implemented by public license practices.  Many people have made
396
+generous contributions to the wide range of software distributed
397
+through that system in reliance on consistent application of that
398
+system; it is up to the author/donor to decide if he or she is willing
399
+to distribute software through any other system and a licensee cannot
400
+impose that choice.
401
+
402
+This section is intended to make thoroughly clear what is believed to
403
+be a consequence of the rest of this License.
404
+
405
+  12. If the distribution and/or use of the Library is restricted in
406
+certain countries either by patents or by copyrighted interfaces, the
407
+original copyright holder who places the Library under this License may add
408
+an explicit geographical distribution limitation excluding those countries,
409
+so that distribution is permitted only in or among countries not thus
410
+excluded.  In such case, this License incorporates the limitation as if
411
+written in the body of this License.
412
+
413
+  13. The Free Software Foundation may publish revised and/or new
414
+versions of the Lesser General Public License from time to time.
415
+Such new versions will be similar in spirit to the present version,
416
+but may differ in detail to address new problems or concerns.
417
+
418
+Each version is given a distinguishing version number.  If the Library
419
+specifies a version number of this License which applies to it and
420
+"any later version", you have the option of following the terms and
421
+conditions either of that version or of any later version published by
422
+the Free Software Foundation.  If the Library does not specify a
423
+license version number, you may choose any version ever published by
424
+the Free Software Foundation.
425
+
426
+  14. If you wish to incorporate parts of the Library into other free
427
+programs whose distribution conditions are incompatible with these,
428
+write to the author to ask for permission.  For software which is
429
+copyrighted by the Free Software Foundation, write to the Free
430
+Software Foundation; we sometimes make exceptions for this.  Our
431
+decision will be guided by the two goals of preserving the free status
432
+of all derivatives of our free software and of promoting the sharing
433
+and reuse of software generally.
434
+
435
+			    NO WARRANTY
436
+
437
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
+
447
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456
+DAMAGES.

+ 133
- 0
vendor/dompdf/dompdf/README.md View File

@@ -0,0 +1,133 @@
1
+[![Latest Stable Version](https://poser.pugx.org/dompdf/dompdf/v/stable.png)](https://packagist.org/packages/dompdf/dompdf) [![Total Downloads](https://poser.pugx.org/dompdf/dompdf/downloads.png)](https://packagist.org/packages/dompdf/dompdf) [![Latest Unstable Version](https://poser.pugx.org/dompdf/dompdf/v/unstable.png)](https://packagist.org/packages/dompdf/dompdf) [![License](https://poser.pugx.org/dompdf/dompdf/license.png)](https://packagist.org/packages/dompdf/dompdf)
2
+
3
+**dompdf is an HTML to PDF converter**.
4
+At its heart, dompdf is (mostly) [CSS 2.1](http://www.w3.org/TR/CSS2/) compliant
5
+HTML layout and rendering engine written in PHP. It is a style-driven renderer:
6
+it will download and read external stylesheets, inline style tags, and the style
7
+attributes of individual HTML elements. It also supports most presentational
8
+HTML attributes.
9
+
10
+----
11
+
12
+**Check out the [Demo](http://pxd.me/dompdf/www/examples.php) and ask any
13
+question on [StackOverflow](http://stackoverflow.com/questions/tagged/dompdf) or
14
+on the [Google Groups](http://groups.google.com/group/dompdf)**
15
+
16
+----
17
+
18
+[![Follow us on Twitter](http://twitter-badges.s3.amazonaws.com/twitter-a.png)](http://www.twitter.com/dompdf)
19
+[![Follow us on Google+](https://ssl.gstatic.com/images/icons/gplus-32.png)](https://plus.google.com/108710008521858993320?prsrc=3)
20
+
21
+Features
22
+========
23
+ * handles most CSS 2.1 and a few CSS3 properties, including @import, @media &
24
+   @page rules
25
+ * supports most presentational HTML 4.0 attributes
26
+ * supports external stylesheets, either local or through http/ftp (via
27
+   fopen-wrappers)
28
+ * supports complex tables, including row & column spans, separate & collapsed
29
+   border models, individual cell styling
30
+ * image support (gif, png (8, 24 and 32 bit with alpha channel), bmp & jpeg)
31
+ * no dependencies on external PDF libraries, thanks to the R&OS PDF class
32
+ * inline PHP support
33
+ 
34
+Requirements
35
+============
36
+ * PHP 5.0+ (5.3+ recommended)
37
+ * DOM extension
38
+ * GD extension
39
+
40
+Recommendations
41
+============
42
+ * MBString extension: provides internationalization support. This extension is
43
+   *not* enabled by default. dompdf has limited internationalization support
44
+   when this extension is not enabled.
45
+ * opcache (OPcache, XCache, APC, etc.): improves performance
46
+
47
+About Fonts & Character Encoding
48
+============
49
+PDF documents internally support the following fonts: Helvetica, Times-Roman,
50
+Courier, Zapf-Dingbats, & Symbol. These fonts only support Windows ANSI
51
+encoding. In order for a PDF to display characters that are not available in
52
+Windows ANSI you must supply an external font. dompdf will embed any referenced
53
+font in the PDF so long as it has been pre-loaded or is accessible to dompdf and
54
+reference in CSS @font-face rules. See the
55
+[font overview](https://github.com/dompdf/dompdf/wiki/About-Fonts-and-Character-Encoding)
56
+for more information on how to use fonts.
57
+
58
+The [DejaVu TrueType fonts](http://dejavu-fonts.org) have been pre-installed to
59
+give dompdf decent Unicode character coverage by default. To use the DejaVu
60
+fonts reference the font in your stylesheet, e.g. `body { font-family: DejaVu
61
+Sans; }` (for DejaVu Sans).
62
+
63
+Easy Installation
64
+============
65
+Install with git
66
+---
67
+From the command line switch to the directory where dompdf will reside and run
68
+the following commands:
69
+
70
+```sh
71
+git clone https://github.com/dompdf/dompdf.git .
72
+git submodule init
73
+git submodule update
74
+```
75
+
76
+Install with composer
77
+---
78
+To install with Composer, simply add the requirement to your `composer.json`
79
+file:
80
+
81
+```json
82
+{
83
+  "require" : {
84
+    "dompdf/dompdf" : "0.6.*"
85
+  }
86
+}
87
+```
88
+
89
+And run Composer to update your dependencies:
90
+
91
+```bash
92
+$ curl -sS http://getcomposer.org/installer | php
93
+$ php composer.phar update
94
+```
95
+    
96
+Before you can use the Composer installation of DOMPDF in your application you
97
+must disable dompdf's default auto-loader, include the Composer autoloader, and
98
+load the dompdf configuration file:
99
+
100
+```php
101
+// somewhere early in your project's loading, require the Composer autoloader
102
+// see: http://getcomposer.org/doc/00-intro.md
103
+require 'vendor/autoload.php';
104
+
105
+// disable DOMPDF's internal autoloader if you are using Composer
106
+define('DOMPDF_ENABLE_AUTOLOAD', false);
107
+
108
+// include DOMPDF's default configuration
109
+require_once '/path/to/vendor/dompdf/dompdf/dompdf_config.inc.php';
110
+```
111
+
112
+Download and install
113
+---
114
+Download an archive of dompdf and extract it into the directory where dompdf
115
+will reside
116
+ * You can download stable copies of dompdf from
117
+   https://github.com/dompdf/dompdf/tags
118
+ * Or download a nightly (the latest, unreleased code) from
119
+   http://eclecticgeek.com/dompdf
120
+
121
+Limitations (Known Issues)
122
+==========================
123
+ * not particularly tolerant to poorly-formed HTML input. To avoid any
124
+   unexpected rendering issues you should either enable the built-in HTML5
125
+   parser (via the `DOMPDF_ENABLE_HTML5PARSER` configuration constant) or run
126
+   your HTML through a HTML validator/cleaner (such as Tidy).
127
+ * large files or large tables can take a while to render
128
+ * CSS float is not supported (but is in the works, enable it through the
129
+   `DOMPDF_ENABLE_CSS_FLOAT` configuration constant).
130
+ 
131
+If you find this project useful, please consider making a donation.
132
+(Any funds donated will be used to help further development on this project.)	
133
+[![Donate button](https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](http://goo.gl/DSvWf)

+ 23
- 0
vendor/dompdf/dompdf/composer.json View File

@@ -0,0 +1,23 @@
1
+{
2
+    "name": "dompdf/dompdf",
3
+    "type": "library",
4
+    "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
5
+    "homepage": "https://github.com/dompdf/dompdf",
6
+    "license": "LGPL",
7
+    "authors": [
8
+        {
9
+            "name": "Fabien Ménager",
10
+            "email": "fabien.menager@gmail.com"
11
+        },
12
+        {
13
+            "name": "Brian Sweeney",
14
+            "email": "eclecticgeek@gmail.com"
15
+        }
16
+    ],
17
+    "autoload": {
18
+        "classmap": ["include/"]
19
+    },
20
+    "require": {
21
+        "phenx/php-font-lib": "0.2.*"
22
+    }
23
+}

+ 279
- 0
vendor/dompdf/dompdf/dompdf.php View File

@@ -0,0 +1,279 @@
1
+<?php
2
+/**
3
+ * Command line utility to use dompdf.
4
+ * Can also be used with HTTP GET parameters
5
+ * 
6
+ * @package dompdf
7
+ * @link    http://dompdf.github.com/
8
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
9
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
+ */
11
+
12
+/**
13
+ * Display command line usage
14
+ */
15
+function dompdf_usage() {
16
+  $default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE;
17
+  
18
+  echo <<<EOD
19
+  
20
+Usage: {$_SERVER["argv"][0]} [options] html_file
21
+
22
+html_file can be a filename, a url if fopen_wrappers are enabled, or the '-' character to read from standard input.
23
+
24
+Options:
25
+ -h             Show this message
26
+ -l             List available paper sizes
27
+ -p size        Paper size; something like 'letter', 'A4', 'legal', etc.  
28
+                  The default is '$default_paper_size'
29
+ -o orientation Either 'portrait' or 'landscape'.  Default is 'portrait'
30
+ -b path        Set the 'document root' of the html_file.  
31
+                  Relative urls (for stylesheets) are resolved using this directory.  
32
+                  Default is the directory of html_file.
33
+ -f file        The output filename.  Default is the input [html_file].pdf
34
+ -v             Verbose: display html parsing warnings and file not found errors.
35
+ -d             Very verbose: display oodles of debugging output: every frame 
36
+                  in the tree printed to stdout.
37
+ -t             Comma separated list of debugging types (page-break,reflow,split)
38
+ 
39
+EOD;
40
+exit;
41
+}
42
+
43
+/**
44
+ * Parses command line options
45
+ * 
46
+ * @return array The command line options
47
+ */
48
+function getoptions() {
49
+
50
+  $opts = array();
51
+
52
+  if ( $_SERVER["argc"] == 1 )
53
+    return $opts;
54
+
55
+  $i = 1;
56
+  while ($i < $_SERVER["argc"]) {
57
+
58
+    switch ($_SERVER["argv"][$i]) {
59
+
60
+    case "--help":
61
+    case "-h":
62
+      $opts["h"] = true;
63
+      $i++;
64
+      break;
65
+
66
+    case "-l":
67
+      $opts["l"] = true;
68
+      $i++;
69
+      break;
70
+
71
+    case "-p":
72
+      if ( !isset($_SERVER["argv"][$i+1]) )
73
+        die("-p switch requires a size parameter\n");
74
+      $opts["p"] = $_SERVER["argv"][$i+1];
75
+      $i += 2;
76
+      break;
77
+
78
+    case "-o":
79
+      if ( !isset($_SERVER["argv"][$i+1]) )
80
+        die("-o switch requires an orientation parameter\n");
81
+      $opts["o"] = $_SERVER["argv"][$i+1];
82
+      $i += 2;
83
+      break;
84
+
85
+    case "-b":
86
+      if ( !isset($_SERVER["argv"][$i+1]) )
87
+        die("-b switch requires a path parameter\n");
88
+      $opts["b"] = $_SERVER["argv"][$i+1];
89
+      $i += 2;
90
+      break;
91
+
92
+    case "-f":
93
+      if ( !isset($_SERVER["argv"][$i+1]) )
94
+        die("-f switch requires a filename parameter\n");
95
+      $opts["f"] = $_SERVER["argv"][$i+1];
96
+      $i += 2;
97
+      break;
98
+
99
+    case "-v":
100
+      $opts["v"] = true;
101
+      $i++;
102
+      break;
103
+
104
+    case "-d":
105
+      $opts["d"] = true;
106
+      $i++;
107
+      break;
108
+
109
+    case "-t":
110
+      if ( !isset($_SERVER['argv'][$i + 1]) )
111
+        die("-t switch requires a comma separated list of types\n");
112
+      $opts["t"] = $_SERVER['argv'][$i+1];
113
+      $i += 2;
114
+      break;
115
+
116
+   default:
117
+      $opts["filename"] = $_SERVER["argv"][$i];
118
+      $i++;
119
+      break;
120
+    }
121
+
122
+  }
123
+  return $opts;
124
+}
125
+
126
+require_once("dompdf_config.inc.php");
127
+global $_dompdf_show_warnings, $_dompdf_debug, $_DOMPDF_DEBUG_TYPES;
128
+
129
+$sapi = php_sapi_name();
130
+$options = array();
131
+
132
+$dompdf = new DOMPDF();
133
+
134
+switch ( $sapi ) {
135
+
136
+ case "cli":
137
+
138
+  $opts = getoptions();
139
+
140
+  if ( isset($opts["h"]) || (!isset($opts["filename"]) && !isset($opts["l"])) ) {
141
+    dompdf_usage();
142
+    exit;
143
+  }
144
+
145
+  if ( isset($opts["l"]) ) {
146
+    echo "\nUnderstood paper sizes:\n";
147
+
148
+    foreach (array_keys(CPDF_Adapter::$PAPER_SIZES) as $size)
149
+      echo "  " . mb_strtoupper($size) . "\n";
150
+    exit;
151
+  }
152
+  $file = $opts["filename"];
153
+
154
+  if ( isset($opts["p"]) )
155
+    $paper = $opts["p"];
156
+  else
157
+    $paper = DOMPDF_DEFAULT_PAPER_SIZE;
158
+
159
+  if ( isset($opts["o"]) )
160
+    $orientation = $opts["o"];
161
+  else
162
+    $orientation = "portrait";
163
+
164
+  if ( isset($opts["b"]) )
165
+    $base_path = $opts["b"];
166
+
167
+  if ( isset($opts["f"]) )
168
+    $outfile = $opts["f"];
169
+  else {
170
+    if ( $file === "-" )
171
+      $outfile = "dompdf_out.pdf";
172
+    else
173
+      $outfile = str_ireplace(array(".html", ".htm"), "", $file) . ".pdf";
174
+  }
175
+
176
+  if ( isset($opts["v"]) )
177
+    $_dompdf_show_warnings = true;
178
+
179
+  if ( isset($opts["d"]) ) {
180
+    $_dompdf_show_warnings = true;
181
+    $_dompdf_debug = true;
182
+  }
183
+
184
+  if ( isset($opts['t']) ) {
185
+    $arr = split(',',$opts['t']);
186
+    $types = array();
187
+    foreach ($arr as $type)
188
+      $types[ trim($type) ] = 1;
189
+    $_DOMPDF_DEBUG_TYPES = $types;
190
+  }
191
+  
192
+  $save_file = true;
193
+
194
+  break;
195
+
196
+ default:
197
+
198
+  $dompdf->set_option('enable_php', false);
199
+  
200
+  if ( isset($_GET["input_file"]) )
201
+    $file = rawurldecode($_GET["input_file"]);
202
+  else
203
+    throw new DOMPDF_Exception("An input file is required (i.e. input_file _GET variable).");
204
+  
205
+  if ( isset($_GET["paper"]) )
206
+    $paper = rawurldecode($_GET["paper"]);
207
+  else
208
+    $paper = DOMPDF_DEFAULT_PAPER_SIZE;
209
+  
210
+  if ( isset($_GET["orientation"]) )
211
+    $orientation = rawurldecode($_GET["orientation"]);
212
+  else
213
+    $orientation = "portrait";
214
+  
215
+  if ( isset($_GET["base_path"]) ) {
216
+    $base_path = rawurldecode($_GET["base_path"]);
217
+    $file = $base_path . $file; # Set the input file
218
+  }  
219
+  
220
+  if ( isset($_GET["options"]) ) {
221
+    $options = $_GET["options"];
222
+  }
223
+  
224
+  $file_parts = explode_url($file);
225
+  
226
+  $outfile = "dompdf_out.pdf"; # Don't allow them to set the output file
227
+  $save_file = false; # Don't save the file
228
+  
229
+  break;
230
+}
231
+
232
+if ( $file === "-" ) {
233
+  $str = "";
234
+  while ( !feof(STDIN) )
235
+    $str .= fread(STDIN, 4096);
236
+
237
+  $dompdf->load_html($str);
238
+
239
+} else
240
+  $dompdf->load_html_file($file);
241
+
242
+if ( isset($base_path) ) {
243
+  $dompdf->set_base_path($base_path);
244
+}
245
+
246
+$dompdf->set_paper($paper, $orientation);
247
+
248
+$dompdf->render();
249
+
250
+if ( $_dompdf_show_warnings ) {
251
+  global $_dompdf_warnings;
252
+  foreach ($_dompdf_warnings as $msg)
253
+    echo $msg . "\n";
254
+  echo $dompdf->get_canvas()->get_cpdf()->messages;
255
+  flush();
256
+}
257
+
258
+if ( $save_file ) {
259
+//   if ( !is_writable($outfile) )
260
+//     throw new DOMPDF_Exception("'$outfile' is not writable.");
261
+  if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" )
262
+    $outfile = str_replace(".pdf", ".png", $outfile);
263
+
264
+  list($proto, $host, $path, $file) = explode_url($outfile);
265
+  if ( $proto != "" ) // i.e. not file://
266
+    $outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file
267
+
268
+  $outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile);
269
+
270
+  if ( strpos($outfile, DOMPDF_CHROOT) !== 0 )
271
+    throw new DOMPDF_Exception("Permission denied.");
272
+
273
+  file_put_contents($outfile, $dompdf->output( array("compress" => 0) ));
274
+  exit(0);
275
+}
276
+
277
+if ( !headers_sent() ) {
278
+  $dompdf->stream($outfile, $options);
279
+}

+ 41
- 0
vendor/dompdf/dompdf/dompdf_config.custom.inc.php View File

@@ -0,0 +1,41 @@
1
+<?php
2
+// Please refer to dompdf_config.inc.php for details on each configuration option.
3
+
4
+//define("DOMPDF_TEMP_DIR", "/tmp");
5
+//define("DOMPDF_FONT_DIR", DOMPDF_DIR."/lib/fonts/");
6
+//define("DOMPDF_FONT_CACHE", DOMPDF_DIR."/lib/fonts/");
7
+//define("DOMPDF_UNICODE_ENABLED", true);
8
+//define("DOMPDF_PDF_BACKEND", "PDFLib");
9
+//define("DOMPDF_DEFAULT_MEDIA_TYPE", "print");
10
+//define("DOMPDF_DEFAULT_PAPER_SIZE", "letter");
11
+//define("DOMPDF_DEFAULT_FONT", "serif");
12
+//define("DOMPDF_DPI", 72);
13
+//define("DOMPDF_ENABLE_CSS_FLOAT", true);
14
+//define("DOMPDF_ENABLE_JAVASCRIPT", false);
15
+//define("DEBUGPNG", true);
16
+//define("DEBUGKEEPTEMP", true);
17
+//define("DEBUGCSS", true);
18
+//define("DEBUG_LAYOUT", true);
19
+//define("DEBUG_LAYOUT_LINES", false);
20
+//define("DEBUG_LAYOUT_BLOCKS", false);
21
+//define("DEBUG_LAYOUT_INLINE", false);
22
+//define("DOMPDF_FONT_HEIGHT_RATIO", 1.0);
23
+//define("DEBUG_LAYOUT_PADDINGBOX", false);
24
+//define("DOMPDF_LOG_OUTPUT_FILE", DOMPDF_FONT_DIR."log.htm");
25
+//define("DOMPDF_ENABLE_HTML5PARSER", true);
26
+//define("DOMPDF_ENABLE_FONTSUBSETTING", true);
27
+
28
+// Authentication for the dompdf/www
29
+//define("DOMPDF_ADMIN_USERNAME", "user");
30
+//define("DOMPDF_ADMIN_PASSWORD", "password");
31
+
32
+/**
33
+ * Attention!
34
+ * The following settings may increase the risk of system exploit.
35
+ * Do not change these settings without understanding the consequences.
36
+ * Additional documentation is available on the dompdf wiki at:
37
+ * https://github.com/dompdf/dompdf/wiki
38
+ */
39
+//define("DOMPDF_CHROOT", DOMPDF_DIR);
40
+//define("DOMPDF_ENABLE_PHP", false);
41
+//define("DOMPDF_ENABLE_REMOTE", false);

+ 398
- 0
vendor/dompdf/dompdf/dompdf_config.inc.php View File

@@ -0,0 +1,398 @@
1
+<?php
2
+
3
+/**
4
+ * @package dompdf
5
+ * @link    http://dompdf.github.com/
6
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
7
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
8
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
9
+ * @author   Brian Sweeney <eclecticgeek@gmail.com>
10
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
11
+ */
12
+
13
+if (class_exists('DOMPDF', false)) {
14
+  return;
15
+}
16
+
17
+PHP_VERSION >= 5.0 or die("DOMPDF requires PHP 5.0+");
18
+
19
+/**
20
+ * The root of your DOMPDF installation
21
+ */
22
+define("DOMPDF_DIR", str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname(__FILE__))));
23
+
24
+/**
25
+ * The location of the DOMPDF include directory
26
+ */
27
+define("DOMPDF_INC_DIR", DOMPDF_DIR . "/include");
28
+
29
+/**
30
+ * The location of the DOMPDF lib directory
31
+ */
32
+define("DOMPDF_LIB_DIR", DOMPDF_DIR . "/lib");
33
+
34
+/**
35
+ * Some installations don't have $_SERVER['DOCUMENT_ROOT']
36
+ * http://fyneworks.blogspot.com/2007/08/php-documentroot-in-iis-windows-servers.html
37
+ */
38
+if (!isset($_SERVER['DOCUMENT_ROOT'])) {
39
+  $path = "";
40
+
41
+  if (isset($_SERVER['SCRIPT_FILENAME']))
42
+    $path = $_SERVER['SCRIPT_FILENAME'];
43
+  elseif (isset($_SERVER['PATH_TRANSLATED']))
44
+    $path = str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']);
45
+
46
+  $_SERVER['DOCUMENT_ROOT'] = str_replace('\\', '/', substr($path, 0, 0 - strlen($_SERVER['PHP_SELF'])));
47
+}
48
+
49
+/** Include the custom config file if it exists */
50
+if (file_exists(DOMPDF_DIR . "/dompdf_config.custom.inc.php")) {
51
+  require_once(DOMPDF_DIR . "/dompdf_config.custom.inc.php");
52
+}
53
+
54
+//FIXME: Some function definitions rely on the constants defined by DOMPDF. However, might this location prove problematic?
55
+require_once(DOMPDF_INC_DIR . "/functions.inc.php");
56
+
57
+/**
58
+ * Username and password used by the configuration utility in www/
59
+ */
60
+def("DOMPDF_ADMIN_USERNAME", "user");
61
+def("DOMPDF_ADMIN_PASSWORD", "password");
62
+
63
+/**
64
+ * The location of the DOMPDF font directory
65
+ *
66
+ * The location of the directory where DOMPDF will store fonts and font metrics
67
+ * Note: This directory must exist and be writable by the webserver process.
68
+ * *Please note the trailing slash.*
69
+ *
70
+ * Notes regarding fonts:
71
+ * Additional .afm font metrics can be added by executing load_font.php from command line.
72
+ *
73
+ * Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must
74
+ * be embedded in the pdf file or the PDF may not display correctly. This can significantly
75
+ * increase file size unless font subsetting is enabled. Before embedding a font please
76
+ * review your rights under the font license.
77
+ *
78
+ * Any font specification in the source HTML is translated to the closest font available
79
+ * in the font directory.
80
+ *
81
+ * The pdf standard "Base 14 fonts" are:
82
+ * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
83
+ * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
84
+ * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
85
+ * Symbol, ZapfDingbats.
86
+ */
87
+def("DOMPDF_FONT_DIR", DOMPDF_DIR . "/lib/fonts/");
88
+
89
+/**
90
+ * The location of the DOMPDF font cache directory
91
+ *
92
+ * This directory contains the cached font metrics for the fonts used by DOMPDF.
93
+ * This directory can be the same as DOMPDF_FONT_DIR
94
+ * 
95
+ * Note: This directory must exist and be writable by the webserver process.
96
+ */
97
+def("DOMPDF_FONT_CACHE", DOMPDF_FONT_DIR);
98
+
99
+/**
100
+ * The location of a temporary directory.
101
+ *
102
+ * The directory specified must be writeable by the webserver process.
103
+ * The temporary directory is required to download remote images and when
104
+ * using the PFDLib back end.
105
+ */
106
+def("DOMPDF_TEMP_DIR", sys_get_temp_dir());
107
+
108
+/**
109
+ * ==== IMPORTANT ====
110
+ *
111
+ * dompdf's "chroot": Prevents dompdf from accessing system files or other
112
+ * files on the webserver.  All local files opened by dompdf must be in a
113
+ * subdirectory of this directory.  DO NOT set it to '/' since this could
114
+ * allow an attacker to use dompdf to read any files on the server.  This
115
+ * should be an absolute path.
116
+ * This is only checked on command line call by dompdf.php, but not by
117
+ * direct class use like:
118
+ * $dompdf = new DOMPDF();	$dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();
119
+ */
120
+def("DOMPDF_CHROOT", realpath(DOMPDF_DIR));
121
+
122
+/**
123
+ * Whether to use Unicode fonts or not.
124
+ *
125
+ * When set to true the PDF backend must be set to "CPDF" and fonts must be
126
+ * loaded via load_font.php.
127
+ *
128
+ * When enabled, dompdf can support all Unicode glyphs. Any glyphs used in a
129
+ * document must be present in your fonts, however.
130
+ */
131
+def("DOMPDF_UNICODE_ENABLED", true);
132
+
133
+/**
134
+ * Whether to enable font subsetting or not.
135
+ */
136
+def("DOMPDF_ENABLE_FONTSUBSETTING", false);
137
+
138
+/**
139
+ * The PDF rendering backend to use
140
+ *
141
+ * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and
142
+ * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will
143
+ * fall back on CPDF. 'GD' renders PDFs to graphic files. {@link
144
+ * Canvas_Factory} ultimately determines which rendering class to instantiate
145
+ * based on this setting.
146
+ *
147
+ * Both PDFLib & CPDF rendering backends provide sufficient rendering
148
+ * capabilities for dompdf, however additional features (e.g. object,
149
+ * image and font support, etc.) differ between backends.  Please see
150
+ * {@link PDFLib_Adapter} for more information on the PDFLib backend
151
+ * and {@link CPDF_Adapter} and lib/class.pdf.php for more information
152
+ * on CPDF. Also see the documentation for each backend at the links
153
+ * below.
154
+ *
155
+ * The GD rendering backend is a little different than PDFLib and
156
+ * CPDF. Several features of CPDF and PDFLib are not supported or do
157
+ * not make any sense when creating image files.  For example,
158
+ * multiple pages are not supported, nor are PDF 'objects'.  Have a
159
+ * look at {@link GD_Adapter} for more information.  GD support is
160
+ * experimental, so use it at your own risk.
161
+ *
162
+ * @link http://www.pdflib.com
163
+ * @link http://www.ros.co.nz/pdf
164
+ * @link http://www.php.net/image
165
+ */
166
+def("DOMPDF_PDF_BACKEND", "CPDF");
167
+
168
+/**
169
+ * PDFlib license key
170
+ *
171
+ * If you are using a licensed, commercial version of PDFlib, specify
172
+ * your license key here.  If you are using PDFlib-Lite or are evaluating
173
+ * the commercial version of PDFlib, comment out this setting.
174
+ *
175
+ * @link http://www.pdflib.com
176
+ *
177
+ * If pdflib present in web server and auto or selected explicitely above,
178
+ * a real license code must exist!
179
+ */
180
+//def("DOMPDF_PDFLIB_LICENSE", "your license key here");
181
+
182
+/**
183
+ * html target media view which should be rendered into pdf.
184
+ * List of types and parsing rules for future extensions:
185
+ * http://www.w3.org/TR/REC-html40/types.html
186
+ *   screen, tty, tv, projection, handheld, print, braille, aural, all
187
+ * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
188
+ * Note, even though the generated pdf file is intended for print output,
189
+ * the desired content might be different (e.g. screen or projection view of html file).
190
+ * Therefore allow specification of content here.
191
+ */
192
+def("DOMPDF_DEFAULT_MEDIA_TYPE", "screen");
193
+
194
+/**
195
+ * The default paper size.
196
+ *
197
+ * North America standard is "letter"; other countries generally "a4"
198
+ *
199
+ * @see CPDF_Adapter::PAPER_SIZES for valid sizes
200
+ */
201
+def("DOMPDF_DEFAULT_PAPER_SIZE", "letter");
202
+
203
+/**
204
+ * The default font family
205
+ *
206
+ * Used if no suitable fonts can be found. This must exist in the font folder.
207
+ * @var string
208
+ */
209
+def("DOMPDF_DEFAULT_FONT", "serif");
210
+
211
+/**
212
+ * Image DPI setting
213
+ *
214
+ * This setting determines the default DPI setting for images and fonts.  The
215
+ * DPI may be overridden for inline images by explictly setting the
216
+ * image's width & height style attributes (i.e. if the image's native
217
+ * width is 600 pixels and you specify the image's width as 72 points,
218
+ * the image will have a DPI of 600 in the rendered PDF.  The DPI of
219
+ * background images can not be overridden and is controlled entirely
220
+ * via this parameter.
221
+ *
222
+ * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
223
+ * If a size in html is given as px (or without unit as image size),
224
+ * this tells the corresponding size in pt at 72 DPI.
225
+ * This adjusts the relative sizes to be similar to the rendering of the
226
+ * html page in a reference browser.
227
+ *
228
+ * In pdf, always 1 pt = 1/72 inch
229
+ *
230
+ * Rendering resolution of various browsers in px per inch:
231
+ * Windows Firefox and Internet Explorer:
232
+ *   SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?
233
+ * Linux Firefox:
234
+ *   about:config *resolution: Default:96
235
+ *   (xorg screen dimension in mm and Desktop font dpi settings are ignored)
236
+ *
237
+ * Take care about extra font/image zoom factor of browser.
238
+ *
239
+ * In images, <img> size in pixel attribute, img css style, are overriding
240
+ * the real image dimension in px for rendering.
241
+ *
242
+ * @var int
243
+ */
244
+def("DOMPDF_DPI", 96);
245
+
246
+/**
247
+ * Enable inline PHP
248
+ *
249
+ * If this setting is set to true then DOMPDF will automatically evaluate
250
+ * inline PHP contained within <script type="text/php"> ... </script> tags.
251
+ *
252
+ * Attention!
253
+ * Enabling this for documents you do not trust (e.g. arbitrary remote html
254
+ * pages) is a security risk. Inline scripts are run with the same level of
255
+ * system access available to dompdf. Set this option to false (recommended)
256
+ * if you wish to process untrusted documents.
257
+ *
258
+ * @var bool
259
+ */
260
+def("DOMPDF_ENABLE_PHP", false);
261
+
262
+/**
263
+ * Enable inline Javascript
264
+ *
265
+ * If this setting is set to true then DOMPDF will automatically insert
266
+ * JavaScript code contained within <script type="text/javascript"> ... </script> tags.
267
+ *
268
+ * @var bool
269
+ */
270
+def("DOMPDF_ENABLE_JAVASCRIPT", true);
271
+
272
+/**
273
+ * Enable remote file access
274
+ *
275
+ * If this setting is set to true, DOMPDF will access remote sites for
276
+ * images and CSS files as required.
277
+ * This is required for part of test case www/test/image_variants.html through www/examples.php
278
+ *
279
+ * Attention!
280
+ * This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and
281
+ * allowing remote access to dompdf.php or on allowing remote html code to be passed to
282
+ * $dompdf = new DOMPDF(); $dompdf->load_html(...);
283
+ * This allows anonymous users to download legally doubtful internet content which on
284
+ * tracing back appears to being downloaded by your server, or allows malicious php code
285
+ * in remote html pages to be executed by your server with your account privileges.
286
+ *
287
+ * @var bool
288
+ */
289
+def("DOMPDF_ENABLE_REMOTE", false);
290
+
291
+/**
292
+ * The debug output log
293
+ * @var string
294
+ */
295
+def("DOMPDF_LOG_OUTPUT_FILE", DOMPDF_FONT_DIR . "log.htm");
296
+
297
+/**
298
+ * A ratio applied to the fonts height to be more like browsers' line height
299
+ */
300
+def("DOMPDF_FONT_HEIGHT_RATIO", 1.1);
301
+
302
+/**
303
+ * Enable CSS float
304
+ *
305
+ * Allows people to disabled CSS float support
306
+ * @var bool
307
+ */
308
+def("DOMPDF_ENABLE_CSS_FLOAT", false);
309
+
310
+/**
311
+ * Enable the built in DOMPDF autoloader
312
+ *
313
+ * @var bool
314
+ */
315
+def("DOMPDF_ENABLE_AUTOLOAD", false);
316
+
317
+/**
318
+ * Prepend the DOMPDF autoload function to the spl_autoload stack
319
+ *
320
+ * @var bool
321
+ */
322
+def("DOMPDF_AUTOLOAD_PREPEND", false);
323
+
324
+/**
325
+ * Use the more-than-experimental HTML5 Lib parser
326
+ */
327
+def("DOMPDF_ENABLE_HTML5PARSER", false);
328
+require_once(DOMPDF_LIB_DIR . "/html5lib/Parser.php");
329
+
330
+// ### End of user-configurable options ###
331
+
332
+/**
333
+ * Load autoloader
334
+ */
335
+if (DOMPDF_ENABLE_AUTOLOAD) {
336
+  require_once(DOMPDF_INC_DIR . "/autoload.inc.php");
337
+  require_once(DOMPDF_LIB_DIR . "/php-font-lib/classes/Font.php");
338
+}
339
+
340
+/**
341
+ * Ensure that PHP is working with text internally using UTF8 character encoding.
342
+ */
343
+mb_internal_encoding('UTF-8');
344
+
345
+/**
346
+ * Global array of warnings generated by DomDocument parser and
347
+ * stylesheet class
348
+ *
349
+ * @var array
350
+ */
351
+global $_dompdf_warnings;
352
+$_dompdf_warnings = array();
353
+
354
+/**
355
+ * If true, $_dompdf_warnings is dumped on script termination when using
356
+ * dompdf/dompdf.php or after rendering when using the DOMPDF class.
357
+ * When using the class, setting this value to true will prevent you from
358
+ * streaming the PDF.
359
+ *
360
+ * @var bool
361
+ */
362
+global $_dompdf_show_warnings;
363
+$_dompdf_show_warnings = false;
364
+
365
+/**
366
+ * If true, the entire tree is dumped to stdout in dompdf.cls.php.
367
+ * Setting this value to true will prevent you from streaming the PDF.
368
+ *
369
+ * @var bool
370
+ */
371
+global $_dompdf_debug;
372
+$_dompdf_debug = false;
373
+
374
+/**
375
+ * Array of enabled debug message types
376
+ *
377
+ * @var array
378
+ */
379
+global $_DOMPDF_DEBUG_TYPES;
380
+$_DOMPDF_DEBUG_TYPES = array(); //array("page-break" => 1);
381
+
382
+/* Optionally enable different classes of debug output before the pdf content.
383
+ * Visible if displaying pdf as text,
384
+ * E.g. on repeated display of same pdf in browser when pdf is not taken out of
385
+ * the browser cache and the premature output prevents setting of the mime type.
386
+ */
387
+def('DEBUGPNG', false);
388
+def('DEBUGKEEPTEMP', false);
389
+def('DEBUGCSS', false);
390
+
391
+/* Layout debugging. Will display rectangles around different block levels.
392
+ * Visible in the PDF itself.
393
+ */
394
+def('DEBUG_LAYOUT', false);
395
+def('DEBUG_LAYOUT_LINES', true);
396
+def('DEBUG_LAYOUT_BLOCKS', true);
397
+def('DEBUG_LAYOUT_INLINE', true);
398
+def('DEBUG_LAYOUT_PADDINGBOX', true);

+ 125
- 0
vendor/dompdf/dompdf/include/absolute_positioner.cls.php View File

@@ -0,0 +1,125 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Positions absolutely positioned frames
11
+ */
12
+class Absolute_Positioner extends Positioner {
13
+
14
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
15
+
16
+  function position() {
17
+
18
+    $frame = $this->_frame;
19
+    $style = $frame->get_style();
20
+    
21
+    $p = $frame->find_positionned_parent();
22
+    
23
+    list($x, $y, $w, $h) = $frame->get_containing_block();
24
+
25
+    $top    = $style->length_in_pt($style->top,    $h);
26
+    $right  = $style->length_in_pt($style->right,  $w);
27
+    $bottom = $style->length_in_pt($style->bottom, $h);
28
+    $left   = $style->length_in_pt($style->left,   $w);
29
+    
30
+    if ( $p && !($left === "auto" && $right === "auto") ) {
31
+      // Get the parent's padding box (see http://www.w3.org/TR/CSS21/visuren.html#propdef-top)
32
+      list($x, $y, $w, $h) = $p->get_padding_box();
33
+    }
34
+    
35
+    list($width, $height) = array($frame->get_margin_width(), $frame->get_margin_height());
36
+    
37
+    $orig_style = $this->_frame->get_original_style();
38
+    $orig_width = $orig_style->width;
39
+    $orig_height = $orig_style->height;
40
+    
41
+    /****************************
42
+    
43
+    Width auto: 
44
+    ____________| left=auto | left=fixed |
45
+    right=auto  |     A     |     B      |
46
+    right=fixed |     C     |     D      |
47
+    
48
+    Width fixed: 
49
+    ____________| left=auto | left=fixed |
50
+    right=auto  |     E     |     F      |
51
+    right=fixed |     G     |     H      |
52
+    
53
+    *****************************/
54
+    
55
+    if ( $left === "auto" ) {
56
+      if ( $right === "auto" ) {
57
+        // A or E - Keep the frame at the same position
58
+        $x = $x + $frame->find_block_parent()->get_current_line_box()->w;
59
+      }
60
+      else {
61
+        if ( $orig_width === "auto" ) {
62
+          // C
63
+          $x += $w - $width - $right;
64
+        }
65
+        else {
66
+          // G
67
+          $x += $w - $width - $right;
68
+        }
69
+      }
70
+    }
71
+    else {
72
+      if ( $right === "auto" ) {
73
+        // B or F
74
+        $x += $left;
75
+      }
76
+      else {
77
+        if ( $orig_width === "auto" ) {
78
+          // D - TODO change width
79
+          $x += $left;
80
+        }
81
+        else {
82
+          // H - Everything is fixed: left + width win
83
+          $x += $left;
84
+        }
85
+      }
86
+    }
87
+    
88
+    // The same vertically
89
+    if ( $top === "auto" ) {
90
+      if ( $bottom === "auto" ) {
91
+        // A or E - Keep the frame at the same position
92
+        $y = $frame->find_block_parent()->get_current_line_box()->y;
93
+      }
94
+      else {
95
+        if ( $orig_height === "auto" ) {
96
+          // C
97
+          $y += $h - $height - $bottom;
98
+        }
99
+        else {
100
+          // G
101
+          $y += $h - $height - $bottom;
102
+        }
103
+      }
104
+    }
105
+    else {
106
+      if ( $bottom === "auto" ) {
107
+        // B or F
108
+        $y += $top;
109
+      }
110
+      else {
111
+        if ( $orig_height === "auto" ) {
112
+          // D - TODO change height
113
+          $y += $top;
114
+        }
115
+        else {
116
+          // H - Everything is fixed: top + height win
117
+          $y += $top;
118
+        }
119
+      }
120
+    }
121
+    
122
+    $frame->set_position($x, $y);
123
+
124
+  }
125
+}

+ 759
- 0
vendor/dompdf/dompdf/include/abstract_renderer.cls.php View File

@@ -0,0 +1,759 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
8
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
+ */
10
+
11
+/**
12
+ * Base renderer class
13
+ *
14
+ * @access private
15
+ * @package dompdf
16
+ */
17
+abstract class Abstract_Renderer {
18
+
19
+  /**
20
+   * Rendering backend
21
+   *
22
+   * @var Canvas
23
+   */
24
+  protected $_canvas;
25
+
26
+  /**
27
+   * Current dompdf instance
28
+   *
29
+   * @var DOMPDF
30
+   */
31
+  protected $_dompdf;
32
+  
33
+  /**
34
+   * Class constructor
35
+   *
36
+   * @param DOMPDF $dompdf The current dompdf instance
37
+   */
38
+  function __construct(DOMPDF $dompdf) {
39
+    $this->_dompdf = $dompdf;
40
+    $this->_canvas = $dompdf->get_canvas();
41
+  }
42
+  
43
+  /**
44
+   * Render a frame.
45
+   *
46
+   * Specialized in child classes
47
+   *
48
+   * @param Frame $frame The frame to render
49
+   */
50
+  abstract function render(Frame $frame);
51
+
52
+  //........................................................................
53
+
54
+  /**
55
+   * Render a background image over a rectangular area
56
+   *
57
+   * @param string $url      The background image to load
58
+   * @param float  $x        The left edge of the rectangular area
59
+   * @param float  $y        The top edge of the rectangular area
60
+   * @param float  $width    The width of the rectangular area
61
+   * @param float  $height   The height of the rectangular area
62
+   * @param Style  $style    The associated Style object
63
+   *
64
+   * @throws Exception
65
+   */
66
+  protected function _background_image($url, $x, $y, $width, $height, $style) {
67
+    if ( !function_exists("imagecreatetruecolor") ) {
68
+      throw new Exception("The PHP GD extension is required, but is not installed.");
69
+    }
70
+
71
+    $sheet = $style->get_stylesheet();
72
+
73
+    // Skip degenerate cases
74
+    if ( $width == 0 || $height == 0 ) {
75
+      return;
76
+    }
77
+    
78
+    $box_width = $width;
79
+    $box_height = $height;
80
+
81
+    //debugpng
82
+    if (DEBUGPNG) print '[_background_image '.$url.']';
83
+
84
+    list($img, $type, /*$msg*/) = Image_Cache::resolve_url(
85
+      $url,
86
+      $sheet->get_protocol(),
87
+      $sheet->get_host(),
88
+      $sheet->get_base_path(),
89
+      $this->_dompdf
90
+    );
91
+
92
+    // Bail if the image is no good
93
+    if ( Image_Cache::is_broken($img) ) {
94
+      return;
95
+    }
96
+
97
+    //Try to optimize away reading and composing of same background multiple times
98
+    //Postponing read with imagecreatefrom   ...()
99
+    //final composition parameters and name not known yet
100
+    //Therefore read dimension directly from file, instead of creating gd object first.
101
+    //$img_w = imagesx($src); $img_h = imagesy($src);
102
+
103
+    list($img_w, $img_h) = dompdf_getimagesize($img, $this->_dompdf->get_http_context());
104
+    if (!isset($img_w) || $img_w == 0 || !isset($img_h) || $img_h == 0) {
105
+      return;
106
+    }
107
+
108
+    $repeat = $style->background_repeat;
109
+    $dpi = $this->_dompdf->get_option("dpi");
110
+
111
+    //Increase background resolution and dependent box size according to image resolution to be placed in
112
+    //Then image can be copied in without resize
113
+    $bg_width = round((float)($width * $dpi) / 72);
114
+    $bg_height = round((float)($height * $dpi) / 72);
115
+
116
+    //Need %bg_x, $bg_y as background pos, where img starts, converted to pixel
117
+
118
+    list($bg_x, $bg_y) = $style->background_position;
119
+
120
+    if ( is_percent($bg_x) ) {
121
+      // The point $bg_x % from the left edge of the image is placed
122
+      // $bg_x % from the left edge of the background rectangle
123
+      $p = ((float)$bg_x)/100.0;
124
+      $x1 = $p * $img_w;
125
+      $x2 = $p * $bg_width;
126
+
127
+      $bg_x = $x2 - $x1;
128
+    }
129
+    else {
130
+      $bg_x = (float)($style->length_in_pt($bg_x)*$dpi) / 72;
131
+    }
132
+    
133
+    $bg_x = round($bg_x + $style->length_in_pt($style->border_left_width)*$dpi / 72);
134
+
135
+    if ( is_percent($bg_y) ) {
136
+      // The point $bg_y % from the left edge of the image is placed
137
+      // $bg_y % from the left edge of the background rectangle
138
+      $p = ((float)$bg_y)/100.0;
139
+      $y1 = $p * $img_h;
140
+      $y2 = $p * $bg_height;
141
+
142
+      $bg_y = $y2 - $y1;
143
+    }
144
+    else {
145
+      $bg_y = (float)($style->length_in_pt($bg_y)*$dpi) / 72;
146
+    }
147
+    
148
+    $bg_y = round($bg_y + $style->length_in_pt($style->border_top_width)*$dpi / 72);
149
+
150
+    //clip background to the image area on partial repeat. Nothing to do if img off area
151
+    //On repeat, normalize start position to the tile at immediate left/top or 0/0 of area
152
+    //On no repeat with positive offset: move size/start to have offset==0
153
+    //Handle x/y Dimensions separately
154
+
155
+    if ( $repeat !== "repeat" && $repeat !== "repeat-x" ) {
156
+      //No repeat x
157
+      if ($bg_x < 0) {
158
+        $bg_width = $img_w + $bg_x;
159
+      }
160
+      else {
161
+        $x += ($bg_x * 72)/$dpi;
162
+        $bg_width = $bg_width - $bg_x;
163
+        if ($bg_width > $img_w) {
164
+          $bg_width = $img_w;
165
+        }
166
+        $bg_x = 0;
167
+      }
168
+      
169
+      if ($bg_width <= 0) {
170
+        return;
171
+      }
172
+      
173
+      $width = (float)($bg_width * 72)/$dpi;
174
+    }
175
+    else {
176
+      //repeat x
177
+      if ($bg_x < 0) {
178
+        $bg_x = - ((-$bg_x) % $img_w);
179
+      }
180
+      else {
181
+        $bg_x = $bg_x % $img_w;
182
+        if ($bg_x > 0) {
183
+          $bg_x -= $img_w;
184
+        }
185
+      }
186
+    }
187
+
188
+    if ( $repeat !== "repeat" && $repeat !== "repeat-y" ) {
189
+      //no repeat y
190
+      if ($bg_y < 0) {
191
+        $bg_height = $img_h + $bg_y;
192
+      }
193
+      else {
194
+        $y += ($bg_y * 72)/$dpi;
195
+        $bg_height = $bg_height - $bg_y;
196
+        if ($bg_height > $img_h) {
197
+          $bg_height = $img_h;
198
+        }
199
+        $bg_y = 0;
200
+      }
201
+      if ($bg_height <= 0) {
202
+        return;
203
+      }
204
+      $height = (float)($bg_height * 72)/$dpi;
205
+    }
206
+    else {
207
+      //repeat y
208
+      if ($bg_y < 0) {
209
+        $bg_y = - ((-$bg_y) % $img_h);
210
+      }
211
+      else {
212
+        $bg_y = $bg_y % $img_h;
213
+        if ($bg_y > 0) {
214
+          $bg_y -= $img_h;
215
+        }
216
+      }
217
+    }
218
+
219
+    //Optimization, if repeat has no effect
220
+    if ( $repeat === "repeat" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height ) {
221
+      $repeat = "repeat-x";
222
+    }
223
+    
224
+    if ( $repeat === "repeat" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width ) {
225
+      $repeat = "repeat-y";
226
+    }
227
+    
228
+    if ( ($repeat === "repeat-x" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width) ||
229
+         ($repeat === "repeat-y" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height) ) {
230
+      $repeat = "no-repeat";
231
+    }
232
+
233
+    //Use filename as indicator only
234
+    //different names for different variants to have different copies in the pdf
235
+    //This is not dependent of background color of box! .'_'.(is_array($bg_color) ? $bg_color["hex"] : $bg_color)
236
+    //Note: Here, bg_* are the start values, not end values after going through the tile loops!
237
+
238
+    $filedummy = $img;
239
+    
240
+    $is_png = false;
241
+    $filedummy .= '_'.$bg_width.'_'.$bg_height.'_'.$bg_x.'_'.$bg_y.'_'.$repeat;
242
+
243
+    //Optimization to avoid multiple times rendering the same image.
244
+    //If check functions are existing and identical image already cached,
245
+    //then skip creation of duplicate, because it is not needed by addImagePng
246
+    if ( $this->_canvas instanceof CPDF_Adapter &&
247
+         $this->_canvas->get_cpdf()->image_iscached($filedummy) ) {
248
+      $bg = null;
249
+    }
250
+    
251
+    else {
252
+  
253
+      // Create a new image to fit over the background rectangle
254
+      $bg = imagecreatetruecolor($bg_width, $bg_height);
255
+      
256
+      switch (strtolower($type)) {
257
+        case IMAGETYPE_PNG:
258
+          $is_png = true;
259
+          imagesavealpha($bg, true);
260
+          imagealphablending($bg, false);
261
+          $src = imagecreatefrompng($img);
262
+          break;
263
+    
264
+        case IMAGETYPE_JPEG:
265
+          $src = imagecreatefromjpeg($img);
266
+          break;
267
+    
268
+        case IMAGETYPE_GIF:
269
+          $src = imagecreatefromgif($img);
270
+          break;
271
+          
272
+        case IMAGETYPE_BMP:
273
+          $src = imagecreatefrombmp($img);
274
+          break;
275
+    
276
+        default:
277
+          return; // Unsupported image type
278
+      }
279
+  
280
+      if ( $src == null ) {
281
+        return;
282
+      }
283
+  
284
+      //Background color if box is not relevant here
285
+      //Non transparent image: box clipped to real size. Background non relevant.
286
+      //Transparent image: The image controls the transparency and lets shine through whatever background.
287
+      //However on transparent image preset the composed image with the transparency color,
288
+      //to keep the transparency when copying over the non transparent parts of the tiles.
289
+      $ti = imagecolortransparent($src);
290
+      
291
+      if ( $ti >= 0 ) {
292
+        $tc = imagecolorsforindex($src, $ti);
293
+        $ti = imagecolorallocate($bg, $tc['red'], $tc['green'], $tc['blue']);
294
+        imagefill($bg, 0, 0, $ti);
295
+        imagecolortransparent($bg, $ti);
296
+      }
297
+  
298
+      //This has only an effect for the non repeatable dimension.
299
+      //compute start of src and dest coordinates of the single copy
300
+      if ( $bg_x < 0 ) {
301
+        $dst_x = 0;
302
+        $src_x = -$bg_x;
303
+      }
304
+      else {
305
+        $src_x = 0;
306
+        $dst_x = $bg_x;
307
+      }
308
+  
309
+      if ( $bg_y < 0 ) {
310
+        $dst_y = 0;
311
+        $src_y = -$bg_y;
312
+      }
313
+      else {
314
+        $src_y = 0;
315
+        $dst_y = $bg_y;
316
+      }
317
+  
318
+      //For historical reasons exchange meanings of variables:
319
+      //start_* will be the start values, while bg_* will be the temporary start values in the loops
320
+      $start_x = $bg_x;
321
+      $start_y = $bg_y;
322
+  
323
+      // Copy regions from the source image to the background
324
+      if ( $repeat === "no-repeat" ) {
325
+  
326
+        // Simply place the image on the background
327
+        imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $img_h);
328
+  
329
+      }
330
+      else if ( $repeat === "repeat-x" ) {
331
+  
332
+        for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) {
333
+          if ( $bg_x < 0 ) {
334
+            $dst_x = 0;
335
+            $src_x = -$bg_x;
336
+            $w = $img_w + $bg_x;
337
+          }
338
+          else {
339
+            $dst_x = $bg_x;
340
+            $src_x = 0;
341
+            $w = $img_w;
342
+          }
343
+          imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $img_h);
344
+        }
345
+  
346
+      }
347
+      else if ( $repeat === "repeat-y" ) {
348
+  
349
+        for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) {
350
+          if ( $bg_y < 0 ) {
351
+            $dst_y = 0;
352
+            $src_y = -$bg_y;
353
+            $h = $img_h + $bg_y;
354
+          }
355
+          else {
356
+            $dst_y = $bg_y;
357
+            $src_y = 0;
358
+            $h = $img_h;
359
+          }
360
+          imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $h);
361
+  
362
+        }
363
+  
364
+      }
365
+      else if ( $repeat === "repeat" ) {
366
+  
367
+        for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) {
368
+          for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) {
369
+  
370
+            if ( $bg_x < 0 ) {
371
+              $dst_x = 0;
372
+              $src_x = -$bg_x;
373
+              $w = $img_w + $bg_x;
374
+            }
375
+            else {
376
+              $dst_x = $bg_x;
377
+              $src_x = 0;
378
+              $w = $img_w;
379
+            }
380
+  
381
+            if ( $bg_y < 0 ) {
382
+              $dst_y = 0;
383
+              $src_y = -$bg_y;
384
+              $h = $img_h + $bg_y;
385
+            }
386
+            else {
387
+              $dst_y = $bg_y;
388
+              $src_y = 0;
389
+              $h = $img_h;
390
+            }
391
+            imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $h);
392
+          }
393
+        }
394
+      }
395
+      
396
+      else {
397
+        print 'Unknown repeat!';
398
+      }
399
+      
400
+      imagedestroy($src);
401
+
402
+    } /* End optimize away creation of duplicates */
403
+
404
+    $this->_canvas->clipping_rectangle($x, $y, $box_width, $box_height);
405
+    
406
+    //img: image url string
407
+    //img_w, img_h: original image size in px
408
+    //width, height: box size in pt
409
+    //bg_width, bg_height: box size in px
410
+    //x, y: left/top edge of box on page in pt
411
+    //start_x, start_y: placement of image relative to pattern
412
+    //$repeat: repeat mode
413
+    //$bg: GD object of result image
414
+    //$src: GD object of original image
415
+    //When using cpdf and optimization to direct png creation from gd object is available,
416
+    //don't create temp file, but place gd object directly into the pdf
417
+    if ( !$is_png && $this->_canvas instanceof CPDF_Adapter ) {
418
+      // Note: CPDF_Adapter image converts y position
419
+      $this->_canvas->get_cpdf()->addImagePng($filedummy, $x, $this->_canvas->get_height() - $y - $height, $width, $height, $bg);
420
+    } 
421
+    
422
+    else {
423
+      $tmp_dir = $this->_dompdf->get_option("temp_dir");
424
+      $tmp_name = tempnam($tmp_dir, "bg_dompdf_img_");
425
+      @unlink($tmp_name);
426
+      $tmp_file = "$tmp_name.png";
427
+      
428
+      //debugpng
429
+      if (DEBUGPNG) print '[_background_image '.$tmp_file.']';
430
+
431
+      imagepng($bg, $tmp_file);
432
+      $this->_canvas->image($tmp_file, $x, $y, $width, $height);
433
+      imagedestroy($bg);
434
+
435
+      //debugpng
436
+      if (DEBUGPNG) print '[_background_image unlink '.$tmp_file.']';
437
+
438
+      if (!DEBUGKEEPTEMP) {
439
+        unlink($tmp_file);
440
+      }
441
+    }
442
+    
443
+    $this->_canvas->clipping_end();
444
+  }
445
+  
446
+  protected function _get_dash_pattern($style, $width) {
447
+    $pattern = array();
448
+    
449
+    switch ($style) {
450
+      default:
451
+      /*case "solid":
452
+      case "double":
453
+      case "groove":
454
+      case "inset":
455
+      case "outset":
456
+      case "ridge":*/
457
+      case "none": break;
458
+      
459
+      case "dotted": 
460
+        if ( $width <= 1 )
461
+          $pattern = array($width, $width*2);
462
+        else
463
+          $pattern = array($width);
464
+      break;
465
+      
466
+      case "dashed": 
467
+        $pattern = array(3 * $width);
468
+      break;
469
+    }
470
+    
471
+    return $pattern;
472
+  }
473
+
474
+  protected function _border_none($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
475
+    return;
476
+  }
477
+  
478
+  protected function _border_hidden($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
479
+    return;
480
+  }
481
+  
482
+  // Border rendering functions
483
+
484
+  protected function _border_dotted($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
485
+    $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dotted", $r1, $r2);
486
+  }
487
+
488
+
489
+  protected function _border_dashed($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
490
+    $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dashed", $r1, $r2);
491
+  }
492
+
493
+
494
+  protected function _border_solid($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
495
+    // TODO: Solve rendering where one corner is beveled (radius == 0), one corner isn't.
496
+    if ( $corner_style !== "bevel" || $r1 > 0 || $r2 > 0 ) {
497
+      // do it the simple way
498
+      $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "solid", $r1, $r2);
499
+      return;
500
+    }
501
+
502
+    list($top, $right, $bottom, $left) = $widths;
503
+
504
+    // All this polygon business is for beveled corners...
505
+    switch ($side) {
506
+      case "top":
507
+        $points = array($x, $y,
508
+                        $x + $length, $y,
509
+                        $x + $length - $right, $y + $top,
510
+                        $x + $left, $y + $top);
511
+        $this->_canvas->polygon($points, $color, null, null, true);
512
+        break;
513
+  
514
+      case "bottom":
515
+        $points = array($x, $y,
516
+                        $x + $length, $y,
517
+                        $x + $length - $right, $y - $bottom,
518
+                        $x + $left, $y - $bottom);
519
+        $this->_canvas->polygon($points, $color, null, null, true);
520
+        break;
521
+  
522
+      case "left":
523
+        $points = array($x, $y,
524
+                        $x, $y + $length,
525
+                        $x + $left, $y + $length - $bottom,
526
+                        $x + $left, $y + $top);
527
+        $this->_canvas->polygon($points, $color, null, null, true);
528
+        break;
529
+  
530
+      case "right":
531
+        $points = array($x, $y,
532
+                        $x, $y + $length,
533
+                        $x - $right, $y + $length - $bottom,
534
+                        $x - $right, $y + $top);
535
+        $this->_canvas->polygon($points, $color, null, null, true);
536
+        break;
537
+  
538
+      default:
539
+        return;
540
+    }
541
+  }
542
+
543
+  protected function _apply_ratio($side, $ratio, $top, $right, $bottom, $left, &$x, &$y, &$length, &$r1, &$r2) {
544
+    switch ($side) {
545
+
546
+    case "top":
547
+      $r1 -= $left * $ratio;
548
+      $r2 -= $right * $ratio;
549
+      $x += $left * $ratio;
550
+      $y += $top * $ratio;
551
+      $length -= $left * $ratio + $right * $ratio;
552
+      break;
553
+
554
+    case "bottom":
555
+      $r1 -= $right * $ratio;
556
+      $r2 -= $left * $ratio;
557
+      $x += $left * $ratio;
558
+      $y -= $bottom * $ratio;
559
+      $length -= $left * $ratio + $right * $ratio;
560
+      break;
561
+
562
+    case "left":
563
+      $r1 -= $top * $ratio;
564
+      $r2 -= $bottom * $ratio;
565
+      $x += $left * $ratio;
566
+      $y += $top * $ratio;
567
+      $length -= $top * $ratio + $bottom * $ratio;
568
+      break;
569
+
570
+    case "right":
571
+      $r1 -= $bottom * $ratio;
572
+      $r2 -= $top * $ratio;
573
+      $x -= $right * $ratio;
574
+      $y += $top * $ratio;
575
+      $length -= $top * $ratio + $bottom * $ratio;
576
+      break;
577
+
578
+    default:
579
+      return;
580
+
581
+    }
582
+  }
583
+
584
+  protected function _border_double($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
585
+    list($top, $right, $bottom, $left) = $widths;
586
+
587
+    $third_widths = array($top / 3, $right / 3, $bottom / 3, $left / 3);
588
+
589
+    // draw the outer border
590
+    $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2);
591
+
592
+    $this->_apply_ratio($side, 2/3, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
593
+
594
+    $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2);
595
+  }
596
+
597
+  protected function _border_groove($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
598
+    list($top, $right, $bottom, $left) = $widths;
599
+
600
+    $half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2);
601
+
602
+    $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
603
+    
604
+    $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
605
+
606
+    $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
607
+
608
+  }
609
+
610
+  protected function _border_ridge($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
611
+    list($top, $right, $bottom, $left) = $widths;
612
+
613
+    $half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2);
614
+
615
+    $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
616
+    
617
+    $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
618
+
619
+    $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
620
+
621
+  }
622
+
623
+  protected function _tint($c) {
624
+    if ( !is_numeric($c) )
625
+      return $c;
626
+
627
+    return min(1, $c + 0.16);
628
+  }
629
+
630
+  protected function _shade($c) {
631
+    if ( !is_numeric($c) )
632
+      return $c;
633
+
634
+    return max(0, $c - 0.33);
635
+  }
636
+
637
+  protected function _border_inset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
638
+    switch ($side) {
639
+      case "top":
640
+      case "left":
641
+        $shade = array_map(array($this, "_shade"), $color);
642
+        $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2);
643
+        break;
644
+  
645
+      case "bottom":
646
+      case "right":
647
+        $tint = array_map(array($this, "_tint"), $color);
648
+        $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2);
649
+        break;
650
+  
651
+      default:
652
+        return;
653
+    }
654
+  }
655
+
656
+  protected function _border_outset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
657
+    switch ($side) {
658
+      case "top":
659
+      case "left":
660
+        $tint = array_map(array($this, "_tint"), $color);
661
+        $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2);
662
+        break;
663
+  
664
+      case "bottom":
665
+      case "right":
666
+        $shade = array_map(array($this, "_shade"), $color);
667
+        $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2);
668
+        break;
669
+  
670
+      default:
671
+        return;
672
+    }
673
+  }
674
+  // Draws a solid, dotted, or dashed line, observing the border radius
675
+  protected function _border_line($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $pattern_name, $r1 = 0, $r2 = 0) {
676
+    list($top, $right, $bottom, $left) = $widths;
677
+    
678
+    $width = $$side;
679
+    $pattern = $this->_get_dash_pattern($pattern_name, $width);
680
+
681
+    $half_width = $width/2;
682
+    $r1 -= $half_width;
683
+    $r2 -= $half_width;
684
+    $adjust = $r1/80;
685
+    $length -= $width; 
686
+    
687
+    switch ($side) {
688
+      case "top":
689
+        $x += $half_width; 
690
+        $y += $half_width;
691
+  
692
+        if ( $r1 > 0 ) {
693
+          $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 90-$adjust, 135+$adjust, $color, $width, $pattern);
694
+        }
695
+  
696
+        $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern);
697
+  
698
+        if ( $r2 > 0 ) {
699
+          $this->_canvas->arc($x + $length - $r2, $y + $r2, $r2, $r2, 45-$adjust, 90+$adjust, $color, $width, $pattern);
700
+        }
701
+        break;
702
+        
703
+      case "bottom":
704
+        $x += $half_width; 
705
+        $y -= $half_width;
706
+        
707
+        if ( $r1 > 0 ) {
708
+          $this->_canvas->arc($x + $r1, $y - $r1, $r1, $r1, 225-$adjust, 270+$adjust, $color, $width, $pattern);
709
+        }
710
+        
711
+        $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern);
712
+        
713
+        if ( $r2 > 0 ) {
714
+          $this->_canvas->arc($x + $length - $r2, $y - $r2, $r2, $r2, 270-$adjust, 315+$adjust, $color, $width, $pattern);
715
+        }
716
+        break;
717
+        
718
+      case "left":
719
+        $y += $half_width; 
720
+        $x += $half_width;
721
+        
722
+        if ( $r1 > 0 ) {
723
+          $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 135-$adjust, 180+$adjust, $color, $width, $pattern);
724
+        }
725
+        
726
+        $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern);
727
+        
728
+        if ( $r2 > 0 ) {
729
+          $this->_canvas->arc($x + $r2, $y + $length - $r2, $r2, $r2, 180-$adjust, 225+$adjust, $color, $width, $pattern);
730
+        }
731
+        break;
732
+        
733
+      case "right":
734
+        $y += $half_width; 
735
+        $x -= $half_width;
736
+        
737
+        if ( $r1 > 0 ) {
738
+          $this->_canvas->arc($x - $r1, $y + $r1, $r1, $r1, 0-$adjust, 45+$adjust, $color, $width, $pattern);
739
+        }
740
+        
741
+        $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern);
742
+        
743
+        if ( $r2 > 0 ) {
744
+          $this->_canvas->arc($x - $r2, $y + $length - $r2, $r2, $r2, 315-$adjust, 360+$adjust, $color, $width, $pattern);
745
+        }
746
+        break;
747
+    }
748
+  }
749
+
750
+  protected function _set_opacity($opacity) {
751
+    if ( is_numeric($opacity) && $opacity <= 1.0 && $opacity >= 0.0 ) {
752
+      $this->_canvas->set_opacity( $opacity );
753
+    }
754
+  }
755
+
756
+  protected function _debug_layout($box, $color = "red", $style = array()) {
757
+    $this->_canvas->rectangle($box[0], $box[1], $box[2], $box[3], CSS_Color::parse($color), 0.1, $style);
758
+  }
759
+}

+ 592
- 0
vendor/dompdf/dompdf/include/attribute_translator.cls.php View File

@@ -0,0 +1,592 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Translates HTML 4.0 attributes into CSS rules
12
+ *
13
+ * @package dompdf
14
+ */
15
+class Attribute_Translator {
16
+  static $_style_attr = "_html_style_attribute";
17
+  
18
+  // Munged data originally from
19
+  // http://www.w3.org/TR/REC-html40/index/attributes.html
20
+  // http://www.cs.tut.fi/~jkorpela/html2css.html
21
+  static private $__ATTRIBUTE_LOOKUP = array(
22
+    //'caption' => array ( 'align' => '', ),
23
+    'img' => array(
24
+      'align' => array(
25
+        'bottom' => 'vertical-align: baseline;',
26
+        'middle' => 'vertical-align: middle;',
27
+        'top'    => 'vertical-align: top;',
28
+        'left'   => 'float: left;',
29
+        'right'  => 'float: right;'
30
+      ),
31
+      'border' => 'border: %0.2F px solid;',
32
+      'height' => 'height: %s px;',
33
+      'hspace' => 'padding-left: %1$0.2F px; padding-right: %1$0.2F px;',
34
+      'vspace' => 'padding-top: %1$0.2F px; padding-bottom: %1$0.2F px;',
35
+      'width'  => 'width: %s px;',
36
+    ),
37
+    'table' => array(
38
+      'align' => array(
39
+        'left'   => 'margin-left: 0; margin-right: auto;',
40
+        'center' => 'margin-left: auto; margin-right: auto;',
41
+        'right'  => 'margin-left: auto; margin-right: 0;'
42
+      ),
43
+      'bgcolor' => 'background-color: %s;',
44
+      'border' => '!set_table_border',
45
+      'cellpadding' => '!set_table_cellpadding',//'border-spacing: %0.2F; border-collapse: separate;',
46
+      'cellspacing' => '!set_table_cellspacing',
47
+      'frame' => array(
48
+        'void'   => 'border-style: none;',
49
+        'above'  => 'border-top-style: solid;',
50
+        'below'  => 'border-bottom-style: solid;',
51
+        'hsides' => 'border-left-style: solid; border-right-style: solid;',
52
+        'vsides' => 'border-top-style: solid; border-bottom-style: solid;',
53
+        'lhs'    => 'border-left-style: solid;',
54
+        'rhs'    => 'border-right-style: solid;',
55
+        'box'    => 'border-style: solid;',
56
+        'border' => 'border-style: solid;'
57
+      ),
58
+      'rules' => '!set_table_rules',
59
+      'width' => 'width: %s;',
60
+    ),
61
+    'hr' => array(
62
+      'align'   => '!set_hr_align', // Need to grab width to set 'left' & 'right' correctly
63
+      'noshade' => 'border-style: solid;',
64
+      'size'    => '!set_hr_size', //'border-width: %0.2F px;',
65
+      'width'   => 'width: %s;',
66
+    ),
67
+    'div' => array(
68
+      'align' => 'text-align: %s;',
69
+    ),
70
+    'h1' => array(
71
+      'align' => 'text-align: %s;',
72
+    ),
73
+    'h2' => array(
74
+      'align' => 'text-align: %s;',
75
+    ),
76
+    'h3' => array(
77
+      'align' => 'text-align: %s;',
78
+    ),
79
+    'h4' => array(
80
+      'align' => 'text-align: %s;',
81
+    ),
82
+    'h5' => array(
83
+      'align' => 'text-align: %s;',
84
+    ),
85
+    'h6' => array(
86
+      'align' => 'text-align: %s;',
87
+    ),
88
+    'p' => array(
89
+      'align' => 'text-align: %s;',
90
+    ),
91
+//    'col' => array(
92
+//      'align'  => '',
93
+//      'valign' => '',
94
+//    ),
95
+//    'colgroup' => array(
96
+//      'align'  => '',
97
+//      'valign' => '',
98
+//    ),
99
+    'tbody' => array(
100
+      'align'  => '!set_table_row_align',
101
+      'valign' => '!set_table_row_valign',
102
+    ),
103
+    'td' => array(
104
+      'align'   => 'text-align: %s;',
105
+      'bgcolor' => '!set_background_color',
106
+      'height'  => 'height: %s;',
107
+      'nowrap'  => 'white-space: nowrap;',
108
+      'valign'  => 'vertical-align: %s;',
109
+      'width'   => 'width: %s;',
110
+    ),
111
+    'tfoot' => array(
112
+      'align'   => '!set_table_row_align',
113
+      'valign'  => '!set_table_row_valign',
114
+    ),
115
+    'th' => array(
116
+      'align'   => 'text-align: %s;',
117
+      'bgcolor' => '!set_background_color',
118
+      'height'  => 'height: %s;',
119
+      'nowrap'  => 'white-space: nowrap;',
120
+      'valign'  => 'vertical-align: %s;',
121
+      'width'   => 'width: %s;',
122
+    ),
123
+    'thead' => array(
124
+      'align'   => '!set_table_row_align',
125
+      'valign'  => '!set_table_row_valign',
126
+    ),
127
+    'tr' => array(
128
+      'align'   => '!set_table_row_align',
129
+      'bgcolor' => '!set_table_row_bgcolor',
130
+      'valign'  => '!set_table_row_valign',
131
+    ),
132
+    'body' => array(
133
+      'background' => 'background-image: url(%s);',
134
+      'bgcolor'    => '!set_background_color',
135
+      'link'       => '!set_body_link',
136
+      'text'       => '!set_color',
137
+    ),
138
+    'br' => array(
139
+      'clear' => 'clear: %s;',
140
+    ),
141
+    'basefont' => array(
142
+      'color' => '!set_color',
143
+      'face'  => 'font-family: %s;',
144
+      'size'  => '!set_basefont_size',
145
+    ),
146
+    'font' => array(
147
+      'color' => '!set_color',
148
+      'face'  => 'font-family: %s;',
149
+      'size'  => '!set_font_size',
150
+    ),
151
+    'dir' => array(
152
+      'compact' => 'margin: 0.5em 0;',
153
+    ),
154
+    'dl' => array(
155
+      'compact' => 'margin: 0.5em 0;',
156
+    ),
157
+    'menu' => array(
158
+      'compact' => 'margin: 0.5em 0;',
159
+    ),
160
+    'ol' => array(
161
+      'compact' => 'margin: 0.5em 0;',
162
+      'start'   => 'counter-reset: -dompdf-default-counter %d;',
163
+      'type'    => 'list-style-type: %s;',
164
+    ),
165
+    'ul' => array(
166
+      'compact' => 'margin: 0.5em 0;',
167
+      'type'    => 'list-style-type: %s;',
168
+    ),
169
+    'li' => array(
170
+      'type'    => 'list-style-type: %s;',
171
+      'value'   => 'counter-reset: -dompdf-default-counter %d;',
172
+    ),
173
+    'pre' => array(
174
+      'width' => 'width: %s;',
175
+    ),
176
+  );
177
+  
178
+  static protected $_last_basefont_size = 3;
179
+  static protected $_font_size_lookup = array(
180
+    // For basefont support
181
+    -3 => "4pt", 
182
+    -2 => "5pt", 
183
+    -1 => "6pt", 
184
+     0 => "7pt", 
185
+    
186
+     1 => "8pt",
187
+     2 => "10pt",
188
+     3 => "12pt",
189
+     4 => "14pt",
190
+     5 => "18pt",
191
+     6 => "24pt",
192
+     7 => "34pt",
193
+     
194
+    // For basefont support
195
+     8 => "48pt", 
196
+     9 => "44pt", 
197
+    10 => "52pt", 
198
+    11 => "60pt", 
199
+  );
200
+
201
+  /**
202
+   * @param Frame $frame
203
+   */
204
+  static function translate_attributes(Frame $frame) {
205
+    $node = $frame->get_node();
206
+    $tag = $node->nodeName;
207
+
208
+    if ( !isset(self::$__ATTRIBUTE_LOOKUP[$tag]) ) {
209
+      return;
210
+    }
211
+
212
+    $valid_attrs = self::$__ATTRIBUTE_LOOKUP[$tag];
213
+    $attrs = $node->attributes;
214
+    $style = rtrim($node->getAttribute(self::$_style_attr), "; ");
215
+    if ( $style != "" ) {
216
+      $style .= ";";
217
+    }
218
+
219
+    foreach ($attrs as $attr => $attr_node ) {
220
+      if ( !isset($valid_attrs[$attr]) ) {
221
+        continue;
222
+      }
223
+
224
+      $value = $attr_node->value;
225
+
226
+      $target = $valid_attrs[$attr];
227
+      
228
+      // Look up $value in $target, if $target is an array:
229
+      if ( is_array($target) ) {
230
+        if ( isset($target[$value]) ) {
231
+          $style .= " " . self::_resolve_target($node, $target[$value], $value);
232
+        }
233
+      }
234
+      else {
235
+        // otherwise use target directly
236
+        $style .= " " . self::_resolve_target($node, $target, $value);
237
+      }
238
+    }
239
+    
240
+    if ( !is_null($style) ) {
241
+      $style = ltrim($style);
242
+      $node->setAttribute(self::$_style_attr, $style);
243
+    }
244
+    
245
+  }
246
+
247
+  /**
248
+   * @param DOMNode $node
249
+   * @param string  $target
250
+   * @param string      $value
251
+   *
252
+   * @return string
253
+   */
254
+  static protected function _resolve_target(DOMNode $node, $target, $value) {
255
+    if ( $target[0] === "!" ) {
256
+      // Function call
257
+      $func = "_" . mb_substr($target, 1);
258
+      return self::$func($node, $value);
259
+    }
260
+    
261
+    return $value ? sprintf($target, $value) : "";
262
+  }
263
+
264
+  /**
265
+   * @param DOMElement $node
266
+   * @param string     $new_style
267
+   */
268
+  static function append_style(DOMElement $node, $new_style) {
269
+    $style = rtrim($node->getAttribute(self::$_style_attr), ";");
270
+    $style .= $new_style;
271
+    $style = ltrim($style, ";");
272
+    $node->setAttribute(self::$_style_attr, $style);
273
+  }
274
+
275
+  /**
276
+   * @param DOMNode $node
277
+   *
278
+   * @return DOMNodeList|DOMElement[]
279
+   */
280
+  static protected function get_cell_list(DOMNode $node) {
281
+    $xpath = new DOMXpath($node->ownerDocument);
282
+    
283
+    switch($node->nodeName) {
284
+      default:
285
+      case "table":
286
+        $query = "tr/td | thead/tr/td | tbody/tr/td | tfoot/tr/td | tr/th | thead/tr/th | tbody/tr/th | tfoot/tr/th";
287
+        break;
288
+        
289
+      case "tbody":
290
+      case "tfoot":
291
+      case "thead":
292
+        $query = "tr/td | tr/th";
293
+        break;
294
+        
295
+      case "tr":
296
+        $query = "td | th";
297
+        break;
298
+    }
299
+    
300
+    return $xpath->query($query, $node);
301
+  }
302
+
303
+  /**
304
+   * @param string $value
305
+   *
306
+   * @return string
307
+   */
308
+  static protected function _get_valid_color($value) {
309
+    if ( preg_match('/^#?([0-9A-F]{6})$/i', $value, $matches) ) {
310
+      $value = "#$matches[1]";
311
+    }
312
+    
313
+    return $value;
314
+  }
315
+
316
+  /**
317
+   * @param DOMElement $node
318
+   * @param string     $value
319
+   *
320
+   * @return string
321
+   */
322
+  static protected function _set_color(DOMElement $node, $value) {
323
+    $value = self::_get_valid_color($value);
324
+    return "color: $value;";
325
+  }
326
+
327
+  /**
328
+   * @param DOMElement $node
329
+   * @param string     $value
330
+   *
331
+   * @return string
332
+   */
333
+  static protected function _set_background_color(DOMElement $node, $value) {
334
+    $value = self::_get_valid_color($value);
335
+    return "background-color: $value;";
336
+  }
337
+
338
+  /**
339
+   * @param DOMElement $node
340
+   * @param string     $value
341
+   *
342
+   * @return null
343
+   */
344
+  static protected function _set_table_cellpadding(DOMElement $node, $value) {
345
+    $cell_list = self::get_cell_list($node);
346
+    
347
+    foreach ($cell_list as $cell) {
348
+      self::append_style($cell, "; padding: {$value}px;");
349
+    }
350
+    
351
+    return null;
352
+  }
353
+
354
+  /**
355
+   * @param DOMElement $node
356
+   * @param string     $value
357
+   *
358
+   * @return string
359
+   */
360
+  static protected function _set_table_border(DOMElement $node, $value) {
361
+    $cell_list = self::get_cell_list($node);
362
+
363
+    foreach ($cell_list as $cell) {
364
+      $style = rtrim($cell->getAttribute(self::$_style_attr));
365
+      $style .= "; border-width: " . ($value > 0 ? 1 : 0) . "pt; border-style: inset;";
366
+      $style = ltrim($style, ";");
367
+      $cell->setAttribute(self::$_style_attr, $style);
368
+    }
369
+    
370
+    $style = rtrim($node->getAttribute(self::$_style_attr), ";");
371
+    $style .= "; border-width: $value" . "px; ";
372
+    return ltrim($style, "; ");
373
+  }
374
+
375
+  /**
376
+   * @param DOMElement $node
377
+   * @param string     $value
378
+   *
379
+   * @return string
380
+   */
381
+  static protected function _set_table_cellspacing(DOMElement $node, $value) {
382
+    $style = rtrim($node->getAttribute(self::$_style_attr), ";");
383
+
384
+    if ( $value == 0 ) {
385
+      $style .= "; border-collapse: collapse;";
386
+    }
387
+    else {
388
+      $style .= "; border-spacing: {$value}px; border-collapse: separate;";
389
+    }
390
+    
391
+    return ltrim($style, ";");
392
+  }
393
+
394
+  /**
395
+   * @param DOMElement $node
396
+   * @param string     $value
397
+   *
398
+   * @return null|string
399
+   */
400
+  static protected function _set_table_rules(DOMElement $node, $value) {
401
+    $new_style = "; border-collapse: collapse;";
402
+    
403
+    switch ($value) {
404
+    case "none":
405
+      $new_style .= "border-style: none;";
406
+      break;
407
+
408
+    case "groups":
409
+      // FIXME: unsupported
410
+      return null;
411
+
412
+    case "rows":
413
+      $new_style .= "border-style: solid none solid none; border-width: 1px; ";
414
+      break;
415
+
416
+    case "cols":
417
+      $new_style .= "border-style: none solid none solid; border-width: 1px; ";
418
+      break;
419
+
420
+    case "all":
421
+      $new_style .= "border-style: solid; border-width: 1px; ";
422
+      break;
423
+      
424
+    default:
425
+      // Invalid value
426
+      return null;
427
+    }
428
+
429
+    $cell_list = self::get_cell_list($node);
430
+    
431
+    foreach ($cell_list as $cell) {
432
+      $style = $cell->getAttribute(self::$_style_attr);
433
+      $style .= $new_style;
434
+      $cell->setAttribute(self::$_style_attr, $style);
435
+    }
436
+    
437
+    $style = rtrim($node->getAttribute(self::$_style_attr), ";");
438
+    $style .= "; border-collapse: collapse; ";
439
+    
440
+    return ltrim($style, "; ");
441
+  }
442
+
443
+  /**
444
+   * @param DOMElement $node
445
+   * @param string     $value
446
+   *
447
+   * @return string
448
+   */
449
+  static protected function _set_hr_size(DOMElement $node, $value) {
450
+    $style = rtrim($node->getAttribute(self::$_style_attr), ";");
451
+    $style .= "; border-width: ".max(0, $value-2)."; ";
452
+    return ltrim($style, "; ");
453
+  }
454
+
455
+  /**
456
+   * @param DOMElement $node
457
+   * @param string     $value
458
+   *
459
+   * @return null|string
460
+   */
461
+  static protected function _set_hr_align(DOMElement $node, $value) {
462
+    $style = rtrim($node->getAttribute(self::$_style_attr),";");
463
+    $width = $node->getAttribute("width");
464
+    
465
+    if ( $width == "" ) {
466
+      $width = "100%";
467
+    }
468
+
469
+    $remainder = 100 - (double)rtrim($width, "% ");
470
+    
471
+    switch ($value) {
472
+      case "left":
473
+        $style .= "; margin-right: $remainder %;";
474
+        break;
475
+  
476
+      case "right":
477
+        $style .= "; margin-left: $remainder %;";
478
+        break;
479
+  
480
+      case "center":
481
+        $style .= "; margin-left: auto; margin-right: auto;";
482
+        break;
483
+  
484
+      default:
485
+        return null;
486
+    }
487
+    
488
+    return ltrim($style, "; ");
489
+  }
490
+
491
+  /**
492
+   * @param DOMElement $node
493
+   * @param string     $value
494
+   *
495
+   * @return null
496
+   */
497
+  static protected function _set_table_row_align(DOMElement $node, $value) {
498
+    $cell_list = self::get_cell_list($node);
499
+
500
+    foreach ($cell_list as $cell) {
501
+      self::append_style($cell, "; text-align: $value;");
502
+    }
503
+
504
+    return null;
505
+  }
506
+
507
+  /**
508
+   * @param DOMElement $node
509
+   * @param string     $value
510
+   *
511
+   * @return null
512
+   */
513
+  static protected function _set_table_row_valign(DOMElement $node, $value) {
514
+    $cell_list = self::get_cell_list($node);
515
+
516
+    foreach ($cell_list as $cell) {
517
+      self::append_style($cell, "; vertical-align: $value;");
518
+    }
519
+
520
+    return null;
521
+  }
522
+
523
+  /**
524
+   * @param DOMElement $node
525
+   * @param string     $value
526
+   *
527
+   * @return null
528
+   */
529
+  static protected function _set_table_row_bgcolor(DOMElement $node, $value) {
530
+    $cell_list = self::get_cell_list($node);
531
+    $value = self::_get_valid_color($value);
532
+    
533
+    foreach ($cell_list as $cell) {
534
+      self::append_style($cell, "; background-color: $value;");
535
+    }
536
+
537
+    return null;
538
+  }
539
+
540
+  /**
541
+   * @param DOMElement $node
542
+   * @param string     $value
543
+   *
544
+   * @return null
545
+   */
546
+  static protected function _set_body_link(DOMElement $node, $value) {
547
+    $a_list = $node->getElementsByTagName("a");
548
+    $value = self::_get_valid_color($value);
549
+    
550
+    foreach ($a_list as $a) {
551
+      self::append_style($a, "; color: $value;");
552
+    }
553
+
554
+    return null;
555
+  }
556
+
557
+  /**
558
+   * @param DOMElement $node
559
+   * @param string     $value
560
+   *
561
+   * @return null
562
+   */
563
+  static protected function _set_basefont_size(DOMElement $node, $value) {
564
+    // FIXME: ? we don't actually set the font size of anything here, just
565
+    // the base size for later modification by <font> tags.
566
+    self::$_last_basefont_size = $value;
567
+    return null;
568
+  }
569
+
570
+  /**
571
+   * @param DOMElement $node
572
+   * @param string     $value
573
+   *
574
+   * @return string
575
+   */
576
+  static protected function _set_font_size(DOMElement $node, $value) {
577
+    $style = $node->getAttribute(self::$_style_attr);
578
+
579
+    if ( $value[0] === "-" || $value[0] === "+" ) {
580
+      $value = self::$_last_basefont_size + (int)$value;
581
+    }
582
+    
583
+    if ( isset(self::$_font_size_lookup[$value]) ) {
584
+      $style .= "; font-size: " . self::$_font_size_lookup[$value] . ";";
585
+    }
586
+    else {
587
+      $style .= "; font-size: $value;";
588
+    }
589
+    
590
+    return ltrim($style, "; ");
591
+  }
592
+}

+ 86
- 0
vendor/dompdf/dompdf/include/autoload.inc.php View File

@@ -0,0 +1,86 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+ 
10
+/**
11
+ * DOMPDF autoload function
12
+ *
13
+ * If you have an existing autoload function, add a call to this function
14
+ * from your existing __autoload() implementation.
15
+ *
16
+ * @param string $class
17
+ */
18
+function DOMPDF_autoload($class) {
19
+  $filename = DOMPDF_INC_DIR . "/" . mb_strtolower($class) . ".cls.php";
20
+  
21
+  if ( is_file($filename) ) {
22
+    include_once $filename;
23
+  }
24
+}
25
+
26
+// If SPL autoload functions are available (PHP >= 5.1.2)
27
+if ( function_exists("spl_autoload_register") ) {
28
+  $autoload = "DOMPDF_autoload";
29
+  $funcs = spl_autoload_functions();
30
+  
31
+  // No functions currently in the stack. 
32
+  if ( !DOMPDF_AUTOLOAD_PREPEND || $funcs === false ) {
33
+    spl_autoload_register($autoload); 
34
+  }
35
+  
36
+  // If PHP >= 5.3 the $prepend argument is available
37
+  else if ( PHP_VERSION_ID >= 50300 ) {
38
+    spl_autoload_register($autoload, true, true); 
39
+  }
40
+  
41
+  else {
42
+    // Unregister existing autoloaders... 
43
+    $compat = (PHP_VERSION_ID <= 50102 && PHP_VERSION_ID >= 50100);
44
+              
45
+    foreach ($funcs as $func) { 
46
+      if (is_array($func)) { 
47
+        // :TRICKY: There are some compatibility issues and some 
48
+        // places where we need to error out 
49
+        $reflector = new ReflectionMethod($func[0], $func[1]); 
50
+        if (!$reflector->isStatic()) { 
51
+          throw new Exception('This function is not compatible with non-static object methods due to PHP Bug #44144.'); 
52
+        }
53
+        
54
+        // Suprisingly, spl_autoload_register supports the 
55
+        // Class::staticMethod callback format, although call_user_func doesn't 
56
+        if ($compat) $func = implode('::', $func); 
57
+      }
58
+      
59
+      spl_autoload_unregister($func); 
60
+    }
61
+    
62
+    // Register the new one, thus putting it at the front of the stack... 
63
+    spl_autoload_register($autoload); 
64
+    
65
+    // Now, go back and re-register all of our old ones. 
66
+    foreach ($funcs as $func) { 
67
+      spl_autoload_register($func); 
68
+    }
69
+    
70
+    // Be polite and ensure that userland autoload gets retained
71
+    if ( function_exists("__autoload") ) {
72
+      spl_autoload_register("__autoload");
73
+    }
74
+  }
75
+}
76
+
77
+else if ( !function_exists("__autoload") ) {
78
+  /**
79
+   * Default __autoload() function
80
+   *
81
+   * @param string $class
82
+   */
83
+  function __autoload($class) {
84
+    DOMPDF_autoload($class);
85
+  }
86
+}

+ 234
- 0
vendor/dompdf/dompdf/include/block_frame_decorator.cls.php View File

@@ -0,0 +1,234 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Decorates frames for block layout
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Block_Frame_Decorator extends Frame_Decorator {
16
+  /**
17
+   * Current line index
18
+   *
19
+   * @var int
20
+   */
21
+  protected $_cl;
22
+  
23
+  /**
24
+   * The block's line boxes
25
+   * 
26
+   * @var Line_Box[]
27
+   */
28
+  protected $_line_boxes;
29
+
30
+  function __construct(Frame $frame, DOMPDF $dompdf) {
31
+    parent::__construct($frame, $dompdf);
32
+    
33
+    $this->_line_boxes = array(new Line_Box($this));
34
+    $this->_cl = 0;
35
+  }
36
+
37
+  function reset() {
38
+    parent::reset();
39
+    
40
+    $this->_line_boxes = array(new Line_Box($this));
41
+    $this->_cl = 0;
42
+  }
43
+
44
+  /**
45
+   * @return Line_Box
46
+   */
47
+  function get_current_line_box() {
48
+    return $this->_line_boxes[$this->_cl];
49
+  }
50
+
51
+  /**
52
+   * @return integer
53
+   */
54
+  function get_current_line_number() {
55
+    return $this->_cl;
56
+  }
57
+
58
+  /**
59
+   * @return Line_Box[]
60
+   */
61
+  function get_line_boxes() { 
62
+    return $this->_line_boxes; 
63
+  }
64
+
65
+  /**
66
+   * @param integer $i
67
+   */
68
+  function clear_line($i) {
69
+    if ( isset($this->_line_boxes[$i]) ) {
70
+      unset($this->_line_boxes[$i]);
71
+    }
72
+  }
73
+
74
+  /**
75
+   * @param Frame $frame
76
+   */
77
+  function add_frame_to_line(Frame $frame) {
78
+    if ( !$frame->is_in_flow() ) {
79
+      return;
80
+    }
81
+    
82
+    $style = $frame->get_style();
83
+    
84
+    $frame->set_containing_line($this->_line_boxes[$this->_cl]);
85
+    
86
+    /*
87
+    // Adds a new line after a block, only if certain conditions are met
88
+    if ((($frame instanceof Inline_Frame_Decorator && $frame->get_node()->nodeName !== "br") || 
89
+          $frame instanceof Text_Frame_Decorator && trim($frame->get_text())) && 
90
+        ($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" && 
91
+         $this->_line_boxes[$this->_cl]->w > 0 )) {
92
+           
93
+           $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame );
94
+           $this->add_line();
95
+         
96
+           // Add each child of the inline frame to the line individually
97
+           foreach ($frame->get_children() as $child)
98
+             $this->add_frame_to_line( $child );     
99
+    }
100
+    else*/
101
+
102
+    // Handle inline frames (which are effectively wrappers)
103
+    if ( $frame instanceof Inline_Frame_Decorator ) {
104
+
105
+      // Handle line breaks
106
+      if ( $frame->get_node()->nodeName === "br" ) {
107
+        $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame );
108
+        $this->add_line(true);
109
+      }
110
+
111
+      return;
112
+    }
113
+
114
+    // Trim leading text if this is an empty line.  Kinda a hack to put it here,
115
+    // but what can you do...
116
+    if ( $this->get_current_line_box()->w == 0 &&
117
+         $frame->is_text_node() &&
118
+        !$frame->is_pre() ) {
119
+
120
+      $frame->set_text( ltrim($frame->get_text()) );
121
+      $frame->recalculate_width();
122
+    }
123
+
124
+    $w = $frame->get_margin_width();
125
+
126
+    if ( $w == 0 ) {
127
+      return;
128
+    }
129
+
130
+    // Debugging code:
131
+    /*
132
+    pre_r("\n<h3>Adding frame to line:</h3>");
133
+
134
+    //    pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")");
135
+    //    pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")");
136
+    if ( $frame->is_text_node() )
137
+      pre_r('"'.$frame->get_node()->nodeValue.'"');
138
+
139
+    pre_r("Line width: " . $this->_line_boxes[$this->_cl]->w);
140
+    pre_r("Frame: " . get_class($frame));
141
+    pre_r("Frame width: "  . $w);
142
+    pre_r("Frame height: " . $frame->get_margin_height());
143
+    pre_r("Containing block width: " . $this->get_containing_block("w"));
144
+    */
145
+    // End debugging
146
+
147
+    $line = $this->_line_boxes[$this->_cl];
148
+    if ( $line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) {
149
+      $this->add_line();
150
+    }
151
+
152
+    $frame->position();
153
+
154
+    $current_line = $this->_line_boxes[$this->_cl];
155
+    $current_line->add_frame($frame);
156
+
157
+    if ( $frame->is_text_node() ) {
158
+      $current_line->wc += count(preg_split("/\s+/", trim($frame->get_text())));
159
+    }
160
+
161
+    $this->increase_line_width($w);
162
+    
163
+    $this->maximize_line_height($frame->get_margin_height(), $frame);
164
+  }
165
+
166
+  function remove_frames_from_line(Frame $frame) {
167
+    // Search backwards through the lines for $frame
168
+    $i = $this->_cl;
169
+    $j = null;
170
+
171
+    while ($i >= 0) {
172
+      if ( ($j = in_array($frame, $this->_line_boxes[$i]->get_frames(), true)) !== false ) {
173
+        break;
174
+      }
175
+      
176
+      $i--;
177
+    }
178
+
179
+    if ( $j === false ) {
180
+      return;
181
+    }
182
+
183
+    // Remove $frame and all frames that follow
184
+    while ($j < count($this->_line_boxes[$i]->get_frames())) {
185
+      $frames = $this->_line_boxes[$i]->get_frames();
186
+      $f = $frames[$j];
187
+      $frames[$j] = null;
188
+      unset($frames[$j]);
189
+      $j++;
190
+      $this->_line_boxes[$i]->w -= $f->get_margin_width();
191
+    }
192
+
193
+    // Recalculate the height of the line
194
+    $h = 0;
195
+    foreach ($this->_line_boxes[$i]->get_frames() as $f) {
196
+      $h = max( $h, $f->get_margin_height() );
197
+    }
198
+
199
+    $this->_line_boxes[$i]->h = $h;
200
+
201
+    // Remove all lines that follow
202
+    while ($this->_cl > $i) {
203
+      $this->_line_boxes[ $this->_cl ] = null;
204
+      unset($this->_line_boxes[ $this->_cl ]);
205
+      $this->_cl--;
206
+    }
207
+  }
208
+
209
+  function increase_line_width($w) {
210
+    $this->_line_boxes[ $this->_cl ]->w += $w;
211
+  }
212
+
213
+  function maximize_line_height($val, Frame $frame) {
214
+    if ( $val > $this->_line_boxes[ $this->_cl ]->h ) {
215
+      $this->_line_boxes[ $this->_cl ]->tallest_frame = $frame;
216
+      $this->_line_boxes[ $this->_cl ]->h = $val;
217
+    }
218
+  }
219
+
220
+  function add_line($br = false) {
221
+
222
+//     if ( $this->_line_boxes[$this->_cl]["h"] == 0 ) //count($this->_line_boxes[$i]["frames"]) == 0 ||
223
+//       return;
224
+
225
+    $this->_line_boxes[$this->_cl]->br = $br;
226
+    $y = $this->_line_boxes[$this->_cl]->y + $this->_line_boxes[$this->_cl]->h;
227
+
228
+    $new_line = new Line_Box($this, $y);
229
+    
230
+    $this->_line_boxes[ ++$this->_cl ] = $new_line;
231
+  }
232
+
233
+  //........................................................................
234
+}

+ 805
- 0
vendor/dompdf/dompdf/include/block_frame_reflower.cls.php View File

@@ -0,0 +1,805 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Reflows block frames
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Block_Frame_Reflower extends Frame_Reflower {
17
+  // Minimum line width to justify, as fraction of available width
18
+  const MIN_JUSTIFY_WIDTH = 0.80;
19
+
20
+  /**
21
+   * @var Block_Frame_Decorator
22
+   */
23
+  protected $_frame;
24
+  
25
+  function __construct(Block_Frame_Decorator $frame) { parent::__construct($frame); }
26
+
27
+  /**
28
+   *  Calculate the ideal used value for the width property as per:
29
+   *  http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins
30
+   *  
31
+   *  @param float $width
32
+   *  @return array
33
+   */
34
+  protected function _calculate_width($width) {
35
+    $frame = $this->_frame;
36
+    $style = $frame->get_style();
37
+    $w = $frame->get_containing_block("w");
38
+
39
+    if ( $style->position === "fixed" ) {
40
+      $w = $frame->get_parent()->get_containing_block("w");
41
+    }
42
+
43
+    $rm = $style->length_in_pt($style->margin_right, $w);
44
+    $lm = $style->length_in_pt($style->margin_left, $w);
45
+
46
+    $left = $style->length_in_pt($style->left, $w);
47
+    $right = $style->length_in_pt($style->right, $w);
48
+    
49
+    // Handle 'auto' values
50
+    $dims = array($style->border_left_width,
51
+                  $style->border_right_width,
52
+                  $style->padding_left,
53
+                  $style->padding_right,
54
+                  $width !== "auto" ? $width : 0,
55
+                  $rm !== "auto" ? $rm : 0,
56
+                  $lm !== "auto" ? $lm : 0);
57
+
58
+    // absolutely positioned boxes take the 'left' and 'right' properties into account
59
+    if ( $frame->is_absolute() ) {
60
+      $absolute = true;
61
+      $dims[] = $left !== "auto" ? $left : 0;
62
+      $dims[] = $right !== "auto" ? $right : 0;
63
+    }
64
+    else {
65
+      $absolute = false;
66
+    }
67
+
68
+    $sum = $style->length_in_pt($dims, $w);
69
+
70
+    // Compare to the containing block
71
+    $diff = $w - $sum;
72
+
73
+    if ( $diff > 0 ) {
74
+
75
+      if ( $absolute ) {
76
+
77
+        // resolve auto properties: see
78
+        // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
79
+
80
+        if ( $width === "auto" && $left === "auto" && $right === "auto" ) {
81
+
82
+          if ( $lm === "auto" ) $lm = 0;
83
+          if ( $rm === "auto" ) $rm = 0;
84
+
85
+          // Technically, the width should be "shrink-to-fit" i.e. based on the
86
+          // preferred width of the content...  a little too costly here as a
87
+          // special case.  Just get the width to take up the slack:
88
+          $left = 0;
89
+          $right = 0;
90
+          $width = $diff;
91
+        }
92
+        else if ( $width === "auto" ) {
93
+
94
+          if ( $lm    === "auto" ) $lm = 0;
95
+          if ( $rm    === "auto" ) $rm = 0;
96
+          if ( $left  === "auto" ) $left = 0;
97
+          if ( $right === "auto" ) $right = 0;
98
+
99
+          $width = $diff;
100
+        }
101
+        else if ( $left === "auto" ) {
102
+          
103
+          if ( $lm    === "auto" ) $lm = 0;
104
+          if ( $rm    === "auto" ) $rm = 0;
105
+          if ( $right === "auto" ) $right = 0;
106
+
107
+          $left = $diff;
108
+        }
109
+        else if ( $right === "auto" ) {
110
+
111
+          if ( $lm === "auto" ) $lm = 0;
112
+          if ( $rm === "auto" ) $rm = 0;
113
+
114
+          $right = $diff;
115
+        }
116
+
117
+      }
118
+      else {
119
+
120
+        // Find auto properties and get them to take up the slack
121
+        if ( $width === "auto" ) {
122
+          $width = $diff;
123
+        }
124
+        else if ( $lm === "auto" && $rm === "auto" ) {
125
+          $lm = $rm = round($diff / 2);
126
+        }
127
+        else if ( $lm === "auto" ) {
128
+          $lm = $diff;
129
+        }
130
+        else if ( $rm === "auto" ) {
131
+          $rm = $diff;
132
+        }
133
+      }
134
+
135
+    }
136
+    else if ($diff < 0) {
137
+
138
+      // We are over constrained--set margin-right to the difference
139
+      $rm = $diff;
140
+
141
+    }
142
+
143
+    return array(
144
+      "width"        => $width,
145
+      "margin_left"  => $lm,
146
+      "margin_right" => $rm,
147
+      "left"         => $left,
148
+      "right"        => $right,
149
+    );
150
+  }
151
+
152
+  /**
153
+   * Call the above function, but resolve max/min widths
154
+   *
155
+   * @throws DOMPDF_Exception
156
+   * @return array
157
+   */
158
+  protected function _calculate_restricted_width() {
159
+    $frame = $this->_frame;
160
+    $style = $frame->get_style();
161
+    $cb = $frame->get_containing_block();
162
+    
163
+    if ( $style->position === "fixed" ) {
164
+      $cb = $frame->get_root()->get_containing_block();
165
+    }
166
+    
167
+    //if ( $style->position === "absolute" )
168
+    //  $cb = $frame->find_positionned_parent()->get_containing_block();
169
+
170
+    if ( !isset($cb["w"]) ) {
171
+      throw new DOMPDF_Exception("Box property calculation requires containing block width");
172
+    }
173
+    
174
+    // Treat width 100% as auto
175
+    if ( $style->width === "100%" ) {
176
+      $width = "auto";
177
+    }
178
+    else {
179
+      $width = $style->length_in_pt($style->width, $cb["w"]);
180
+    }
181
+    
182
+    extract($this->_calculate_width($width));
183
+
184
+    // Handle min/max width
185
+    $min_width = $style->length_in_pt($style->min_width, $cb["w"]);
186
+    $max_width = $style->length_in_pt($style->max_width, $cb["w"]);
187
+
188
+    if ( $max_width !== "none" && $min_width > $max_width ) {
189
+      list($max_width, $min_width) = array($min_width, $max_width);
190
+    }
191
+    
192
+    if ( $max_width !== "none" && $width > $max_width ) {
193
+      extract($this->_calculate_width($max_width));
194
+    }
195
+
196
+    if ( $width < $min_width ) {
197
+      extract($this->_calculate_width($min_width));
198
+    }
199
+
200
+    return array($width, $margin_left, $margin_right, $left, $right);
201
+  }
202
+  
203
+  /** 
204
+   * Determine the unrestricted height of content within the block
205
+   * not by adding each line's height, but by getting the last line's position. 
206
+   * This because lines could have been pushed lower by a clearing element.
207
+   *
208
+   * @return float
209
+   */
210
+  protected function _calculate_content_height() {
211
+    $lines = $this->_frame->get_line_boxes();
212
+    $height = 0;
213
+
214
+    foreach ($lines as $line) {
215
+      $height += $line->h;
216
+    }
217
+    
218
+    /*
219
+    $first_line = reset($lines);
220
+    $last_line  = end($lines);
221
+    $height2 = $last_line->y + $last_line->h - $first_line->y;
222
+    */
223
+    
224
+    return $height;
225
+  }
226
+
227
+  /** 
228
+   * Determine the frame's restricted height
229
+   *
230
+   * @return array
231
+   */
232
+  protected function _calculate_restricted_height() {
233
+    $frame = $this->_frame;
234
+    $style = $frame->get_style();
235
+    $content_height = $this->_calculate_content_height();
236
+    $cb = $frame->get_containing_block();
237
+    
238
+    $height = $style->length_in_pt($style->height, $cb["h"]);
239
+
240
+    $top    = $style->length_in_pt($style->top, $cb["h"]);
241
+    $bottom = $style->length_in_pt($style->bottom, $cb["h"]);
242
+
243
+    $margin_top    = $style->length_in_pt($style->margin_top, $cb["h"]);
244
+    $margin_bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]);
245
+
246
+    if ( $frame->is_absolute() ) {
247
+
248
+      // see http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
249
+
250
+      $dims = array($top !== "auto" ? $top : 0,
251
+                    $style->margin_top !== "auto" ? $style->margin_top : 0,
252
+                    $style->padding_top,
253
+                    $style->border_top_width,
254
+                    $height !== "auto" ? $height : 0,
255
+                    $style->border_bottom_width,
256
+                    $style->padding_bottom,
257
+                    $style->margin_bottom !== "auto" ? $style->margin_bottom : 0,
258
+                    $bottom !== "auto" ? $bottom : 0);
259
+
260
+      $sum = $style->length_in_pt($dims, $cb["h"]);
261
+
262
+      $diff = $cb["h"] - $sum; 
263
+
264
+      if ( $diff > 0 ) {
265
+
266
+        if ( $height === "auto" && $top === "auto" && $bottom === "auto" ) {
267
+
268
+          if ( $margin_top    === "auto" ) $margin_top = 0;
269
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
270
+
271
+          $height = $diff;
272
+        }
273
+        else if ( $height === "auto" && $top === "auto" ) {
274
+
275
+          if ( $margin_top    === "auto" ) $margin_top = 0;
276
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
277
+
278
+          $height = $content_height;
279
+          $top = $diff - $content_height;
280
+        }
281
+        else if ( $height === "auto" && $bottom === "auto" ) {
282
+
283
+          if ( $margin_top    === "auto" ) $margin_top = 0;
284
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
285
+
286
+          $height = $content_height;
287
+          $bottom = $diff - $content_height;
288
+        }
289
+        else if ( $top === "auto" && $bottom === "auto" ) {
290
+
291
+          if ( $margin_top    === "auto" ) $margin_top = 0;
292
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
293
+
294
+          $bottom = $diff;
295
+        }
296
+        else if ( $top === "auto" ) {
297
+
298
+          if ( $margin_top    === "auto" ) $margin_top = 0;
299
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
300
+
301
+          $top = $diff;
302
+        }
303
+        else if ( $height === "auto" ) {
304
+
305
+          if ( $margin_top    === "auto" ) $margin_top = 0;
306
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
307
+
308
+          $height = $diff;
309
+        }
310
+        else if ( $bottom === "auto" ) {
311
+
312
+          if ( $margin_top    === "auto" ) $margin_top = 0;
313
+          if ( $margin_bottom === "auto" ) $margin_bottom = 0;
314
+
315
+          $bottom = $diff;
316
+        }
317
+        else {
318
+
319
+          if ( $style->overflow === "visible" ) {
320
+            // set all autos to zero
321
+            if ( $margin_top    === "auto" ) $margin_top = 0;
322
+            if ( $margin_bottom === "auto" ) $margin_bottom = 0;
323
+            if ( $top           === "auto" ) $top = 0;
324
+            if ( $bottom        === "auto" ) $bottom = 0;
325
+            if ( $height        === "auto" ) $height = $content_height;
326
+          }
327
+
328
+          // FIXME: overflow hidden
329
+        }
330
+
331
+      }
332
+
333
+    }
334
+    else {
335
+
336
+      // Expand the height if overflow is visible 
337
+      if ( $height === "auto" && $content_height > $height /* && $style->overflow === "visible" */) {
338
+        $height = $content_height;
339
+      }
340
+
341
+      // FIXME: this should probably be moved to a seperate function as per
342
+      // _calculate_restricted_width
343
+      
344
+      // Only handle min/max height if the height is independent of the frame's content
345
+      if ( !($style->overflow === "visible" ||
346
+             ($style->overflow === "hidden" && $height === "auto")) ) {
347
+
348
+        $min_height = $style->min_height;
349
+        $max_height = $style->max_height;
350
+
351
+        if ( isset($cb["h"]) ) {
352
+          $min_height = $style->length_in_pt($min_height, $cb["h"]);
353
+          $max_height = $style->length_in_pt($max_height, $cb["h"]);
354
+
355
+        }
356
+        else if ( isset($cb["w"]) ) {
357
+
358
+          if ( mb_strpos($min_height, "%") !== false ) {
359
+            $min_height = 0;
360
+          }
361
+          else {
362
+            $min_height = $style->length_in_pt($min_height, $cb["w"]);
363
+          }
364
+
365
+          if ( mb_strpos($max_height, "%") !== false ) {
366
+            $max_height = "none";
367
+          }
368
+          else {
369
+            $max_height = $style->length_in_pt($max_height, $cb["w"]);
370
+          }
371
+        }
372
+
373
+        if ( $max_height !== "none" && $min_height > $max_height ) {
374
+          // Swap 'em
375
+          list($max_height, $min_height) = array($min_height, $max_height);
376
+        }
377
+        
378
+        if ( $max_height !== "none" && $height > $max_height ) {
379
+          $height = $max_height;
380
+        }
381
+
382
+        if ( $height < $min_height ) {
383
+          $height = $min_height;
384
+        }
385
+      }
386
+
387
+    }
388
+
389
+    return array($height, $margin_top, $margin_bottom, $top, $bottom);
390
+
391
+  }
392
+
393
+  /**
394
+   * Adjust the justification of each of our lines.
395
+   * http://www.w3.org/TR/CSS21/text.html#propdef-text-align
396
+   */
397
+  protected function _text_align() {
398
+    $style = $this->_frame->get_style();
399
+    $w = $this->_frame->get_containing_block("w");
400
+    $width = $style->length_in_pt($style->width, $w);
401
+    
402
+    switch ($style->text_align) {
403
+      default:
404
+      case "left":
405
+        foreach ($this->_frame->get_line_boxes() as $line) {
406
+          if ( !$line->left ) {
407
+            continue;
408
+          }
409
+          
410
+          foreach($line->get_frames() as $frame) {
411
+            if ( $frame instanceof Block_Frame_Decorator) {
412
+              continue;
413
+            }
414
+            $frame->set_position( $frame->get_position("x") + $line->left );
415
+          }
416
+        }
417
+        return;
418
+  
419
+      case "right":
420
+        foreach ($this->_frame->get_line_boxes() as $line) {
421
+          // Move each child over by $dx
422
+          $dx = $width - $line->w - $line->right;
423
+          
424
+          foreach($line->get_frames() as $frame) {
425
+            // Block frames are not aligned by text-align
426
+            if ($frame instanceof Block_Frame_Decorator) {
427
+              continue;
428
+            }
429
+            
430
+            $frame->set_position( $frame->get_position("x") + $dx );
431
+          }
432
+        }
433
+        break;
434
+  
435
+  
436
+      case "justify":
437
+        // We justify all lines except the last one
438
+        $lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards)
439
+        array_pop($lines);
440
+        
441
+        foreach($lines as $i => $line) {
442
+          if ( $line->br ) {
443
+            unset($lines[$i]);
444
+          }
445
+        }
446
+        
447
+        // One space character's width. Will be used to get a more accurate spacing
448
+        $space_width = Font_Metrics::get_text_width(" ", $style->font_family, $style->font_size);
449
+        
450
+        foreach ($lines as $line) {
451
+          if ( $line->left ) {
452
+            foreach ( $line->get_frames() as $frame ) {
453
+              if ( !$frame instanceof Text_Frame_Decorator ) {
454
+                continue;
455
+              }
456
+    
457
+              $frame->set_position( $frame->get_position("x") + $line->left );
458
+            }
459
+          }
460
+            
461
+          // Only set the spacing if the line is long enough.  This is really
462
+          // just an aesthetic choice ;)
463
+          //if ( $line["left"] + $line["w"] + $line["right"] > self::MIN_JUSTIFY_WIDTH * $width ) {
464
+            
465
+            // Set the spacing for each child
466
+            if ( $line->wc > 1 ) {
467
+              $spacing = ($width - ($line->left + $line->w + $line->right) + $space_width) / ($line->wc - 1);
468
+            }
469
+            else {
470
+              $spacing = 0;
471
+            }
472
+  
473
+            $dx = 0;
474
+            foreach($line->get_frames() as $frame) {
475
+              if ( !$frame instanceof Text_Frame_Decorator ) {
476
+                continue;
477
+              }
478
+                
479
+              $text = $frame->get_text();
480
+              $spaces = mb_substr_count($text, " ");
481
+              
482
+              $char_spacing = $style->length_in_pt($style->letter_spacing);
483
+              $_spacing = $spacing + $char_spacing;
484
+              
485
+              $frame->set_position( $frame->get_position("x") + $dx );
486
+              $frame->set_text_spacing($_spacing);
487
+              
488
+              $dx += $spaces * $_spacing;
489
+            }
490
+  
491
+            // The line (should) now occupy the entire width
492
+            $line->w = $width;
493
+  
494
+          //}
495
+        }
496
+        break;
497
+  
498
+      case "center":
499
+      case "centre":
500
+        foreach ($this->_frame->get_line_boxes() as $line) {
501
+          // Centre each line by moving each frame in the line by:
502
+          $dx = ($width + $line->left - $line->w - $line->right ) / 2;
503
+          
504
+          foreach ($line->get_frames() as $frame) {
505
+            // Block frames are not aligned by text-align
506
+            if ($frame instanceof Block_Frame_Decorator) {
507
+              continue;
508
+            }
509
+            
510
+            $frame->set_position( $frame->get_position("x") + $dx );
511
+          }
512
+        }
513
+        break;
514
+    }
515
+  }
516
+  
517
+  /**
518
+   * Align inline children vertically.
519
+   * Aligns each child vertically after each line is reflowed
520
+   */
521
+  function vertical_align() {
522
+    
523
+    $canvas = null;
524
+    
525
+    foreach ( $this->_frame->get_line_boxes() as $line ) {
526
+
527
+      $height = $line->h;
528
+    
529
+      foreach ( $line->get_frames() as $frame ) {
530
+        $style = $frame->get_style();
531
+
532
+        if ( $style->display !== "inline" ) {
533
+          continue;
534
+        }
535
+
536
+        $align = $frame->get_parent()->get_style()->vertical_align;
537
+        
538
+        if ( !isset($canvas) ) {
539
+          $canvas = $frame->get_root()->get_dompdf()->get_canvas();
540
+        }
541
+        
542
+        $baseline = $canvas->get_font_baseline($style->font_family, $style->font_size);
543
+        $y_offset = 0;
544
+        
545
+        switch ($align) {
546
+          case "baseline":
547
+            $y_offset = $height*0.8 - $baseline; // The 0.8 ratio is arbitrary until we find it's meaning
548
+            break;
549
+    
550
+          case "middle":
551
+            $y_offset = ($height*0.8 - $baseline) / 2;
552
+            break;
553
+    
554
+          case "sub":
555
+            $y_offset = 0.3 * $height;
556
+            break;
557
+    
558
+          case "super":
559
+            $y_offset = -0.2 * $height;
560
+            break;
561
+    
562
+          case "text-top":
563
+          case "top": // Not strictly accurate, but good enough for now
564
+            break;
565
+    
566
+          case "text-bottom":
567
+          case "bottom":
568
+            $y_offset = $height*0.8 - $baseline;
569
+            break;
570
+        }
571
+         
572
+        if ( $y_offset ) {
573
+          $frame->move(0, $y_offset);
574
+        }
575
+      }
576
+    }
577
+  }
578
+
579
+  /**
580
+   * @param Frame $child
581
+   */
582
+  function process_clear(Frame $child){
583
+    $enable_css_float = $this->get_dompdf()->get_option("enable_css_float");
584
+    if ( !$enable_css_float ) {
585
+      return;
586
+    }
587
+    
588
+    $child_style = $child->get_style();
589
+    $root = $this->_frame->get_root();
590
+    
591
+    // Handle "clear"
592
+    if ( $child_style->clear !== "none" ) {
593
+      $lowest_y = $root->get_lowest_float_offset($child);
594
+      
595
+      // If a float is still applying, we handle it
596
+      if ( $lowest_y ) {
597
+        if ( $child->is_in_flow() ) {
598
+          $line_box = $this->_frame->get_current_line_box();
599
+          $line_box->y = $lowest_y + $child->get_margin_height();
600
+          $line_box->left = 0;
601
+          $line_box->right = 0;
602
+        }
603
+        
604
+        $child->move(0, $lowest_y - $child->get_position("y"));
605
+      }
606
+    }
607
+  }
608
+
609
+  /**
610
+   * @param Frame $child
611
+   * @param float $cb_x
612
+   * @param float $cb_w
613
+   */
614
+  function process_float(Frame $child, $cb_x, $cb_w){
615
+    $enable_css_float = $this->_frame->get_dompdf()->get_option("enable_css_float");
616
+    if ( !$enable_css_float ) {
617
+      return;
618
+    }
619
+    
620
+    $child_style = $child->get_style();
621
+    $root = $this->_frame->get_root();
622
+    
623
+    // Handle "float"
624
+    if ( $child_style->float !== "none" ) {
625
+      $root->add_floating_frame($child);
626
+      
627
+      // Remove next frame's beginning whitespace
628
+      $next = $child->get_next_sibling();
629
+      if ( $next && $next instanceof Text_Frame_Decorator) {
630
+        $next->set_text(ltrim($next->get_text()));
631
+      }
632
+      
633
+      $line_box = $this->_frame->get_current_line_box();
634
+      list($old_x, $old_y) = $child->get_position();
635
+      
636
+      $float_x = $cb_x;
637
+      $float_y = $old_y;
638
+      $float_w = $child->get_margin_width();
639
+      
640
+      if ( $child_style->clear === "none" ) {
641
+        switch( $child_style->float ) {
642
+          case "left": 
643
+            $float_x += $line_box->left;
644
+            break;
645
+          case "right": 
646
+            $float_x += ($cb_w - $line_box->right - $float_w);
647
+            break;
648
+        }
649
+      }
650
+      else {
651
+        if ( $child_style->float === "right" ) {
652
+          $float_x += ($cb_w - $float_w);
653
+        }
654
+      }
655
+      
656
+      if ( $cb_w < $float_x + $float_w - $old_x ) {
657
+        // TODO handle when floating elements don't fit
658
+      }
659
+      
660
+      $line_box->get_float_offsets();
661
+      
662
+      if ( $child->_float_next_line ) {
663
+        $float_y += $line_box->h;
664
+      }
665
+      
666
+      $child->set_position($float_x, $float_y);
667
+      $child->move($float_x - $old_x, $float_y - $old_y, true);
668
+    }
669
+  }
670
+
671
+  /**
672
+   * @param Frame_Decorator $block
673
+   */
674
+  function reflow(Block_Frame_Decorator $block = null) {
675
+
676
+    // Check if a page break is forced
677
+    $page = $this->_frame->get_root();
678
+    $page->check_forced_page_break($this->_frame);
679
+
680
+    // Bail if the page is full
681
+    if ( $page->is_full() ) {
682
+      return;
683
+    }
684
+      
685
+    // Generated content
686
+    $this->_set_content();
687
+
688
+    // Collapse margins if required
689
+    $this->_collapse_margins();
690
+
691
+    $style = $this->_frame->get_style();
692
+    $cb = $this->_frame->get_containing_block();
693
+    
694
+    if ( $style->position === "fixed" ) {
695
+      $cb = $this->_frame->get_root()->get_containing_block();
696
+    }
697
+    
698
+    // Determine the constraints imposed by this frame: calculate the width
699
+    // of the content area:
700
+    list($w, $left_margin, $right_margin, $left, $right) = $this->_calculate_restricted_width();
701
+
702
+    // Store the calculated properties
703
+    $style->width = $w . "pt";
704
+    $style->margin_left = $left_margin."pt";
705
+    $style->margin_right = $right_margin."pt";
706
+    $style->left = $left ."pt";
707
+    $style->right = $right . "pt";
708
+    
709
+    // Update the position
710
+    $this->_frame->position();
711
+    list($x, $y) = $this->_frame->get_position();
712
+
713
+    // Adjust the first line based on the text-indent property
714
+    $indent = $style->length_in_pt($style->text_indent, $cb["w"]);
715
+    $this->_frame->increase_line_width($indent);
716
+
717
+    // Determine the content edge
718
+    $top = $style->length_in_pt(array($style->margin_top,
719
+                                      $style->padding_top,
720
+                                      $style->border_top_width), $cb["h"]);
721
+
722
+    $bottom = $style->length_in_pt(array($style->border_bottom_width,
723
+                                         $style->margin_bottom,
724
+                                         $style->padding_bottom), $cb["h"]);
725
+
726
+    $cb_x = $x + $left_margin + $style->length_in_pt(array($style->border_left_width, 
727
+                                                           $style->padding_left), $cb["w"]);
728
+
729
+    $cb_y = $y + $top;
730
+
731
+    $cb_h = ($cb["h"] + $cb["y"]) - $bottom - $cb_y;
732
+
733
+    // Set the y position of the first line in this block
734
+    $line_box = $this->_frame->get_current_line_box();
735
+    $line_box->y = $cb_y;
736
+    $line_box->get_float_offsets();
737
+    
738
+    // Set the containing blocks and reflow each child
739
+    foreach ( $this->_frame->get_children() as $child ) {
740
+      
741
+      // Bail out if the page is full
742
+      if ( $page->is_full() ) {
743
+        break;
744
+      }
745
+      
746
+      $child->set_containing_block($cb_x, $cb_y, $w, $cb_h);
747
+      
748
+      $this->process_clear($child);
749
+      
750
+      $child->reflow($this->_frame);
751
+      
752
+      // Don't add the child to the line if a page break has occurred
753
+      if ( $page->check_page_break($child) ) {
754
+        break;
755
+      }
756
+      
757
+      $this->process_float($child, $cb_x, $w);
758
+    }
759
+
760
+    // Determine our height
761
+    list($height, $margin_top, $margin_bottom, $top, $bottom) = $this->_calculate_restricted_height();
762
+    $style->height = $height;
763
+    $style->margin_top = $margin_top;
764
+    $style->margin_bottom = $margin_bottom;
765
+    $style->top = $top;
766
+    $style->bottom = $bottom;
767
+    
768
+    $needs_reposition = ($style->position === "absolute" && ($style->right !== "auto" || $style->bottom !== "auto"));
769
+    
770
+    // Absolute positioning measurement
771
+    if ( $needs_reposition ) {
772
+      $orig_style = $this->_frame->get_original_style();
773
+      if ( $orig_style->width === "auto" && ($orig_style->left === "auto" || $orig_style->right === "auto") ) {
774
+        $width = 0;
775
+        foreach ($this->_frame->get_line_boxes() as $line) {
776
+          $width = max($line->w, $width);
777
+        }
778
+        $style->width = $width;
779
+      }
780
+      
781
+      $style->left = $orig_style->left;
782
+      $style->right = $orig_style->right;
783
+    }
784
+
785
+    $this->_text_align();
786
+    $this->vertical_align();
787
+    
788
+    // Absolute positioning
789
+    if ( $needs_reposition ) {
790
+      list($x, $y) = $this->_frame->get_position();
791
+      $this->_frame->position();
792
+      list($new_x, $new_y) = $this->_frame->get_position();
793
+      $this->_frame->move($new_x-$x, $new_y-$y, true);
794
+    }
795
+    
796
+    if ( $block && $this->_frame->is_in_flow() ) {
797
+      $block->add_frame_to_line($this->_frame);
798
+      
799
+      // May be inline-block
800
+      if ( $style->display === "block" ) {
801
+        $block->add_line();
802
+      }
803
+    }
804
+  }
805
+}

+ 57
- 0
vendor/dompdf/dompdf/include/block_positioner.cls.php View File

@@ -0,0 +1,57 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Positions block frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Block_Positioner extends Positioner {
16
+
17
+
18
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
19
+  
20
+  //........................................................................
21
+
22
+  function position() {
23
+    $frame = $this->_frame;
24
+    $style = $frame->get_style();
25
+    $cb = $frame->get_containing_block();
26
+    $p = $frame->find_block_parent();
27
+    
28
+    if ( $p ) {
29
+      $float = $style->float;
30
+
31
+      $enable_css_float = $frame->get_dompdf()->get_option("enable_css_float");
32
+      if ( !$enable_css_float || !$float || $float === "none" ) {
33
+        $p->add_line(true);
34
+      }
35
+      $y = $p->get_current_line_box()->y;
36
+      
37
+    }
38
+    else {
39
+      $y = $cb["y"];
40
+    }
41
+
42
+    $x = $cb["x"];
43
+
44
+    // Relative positionning
45
+    if ( $style->position === "relative" ) {
46
+      $top =    $style->length_in_pt($style->top,    $cb["h"]);
47
+      //$right =  $style->length_in_pt($style->right,  $cb["w"]);
48
+      //$bottom = $style->length_in_pt($style->bottom, $cb["h"]);
49
+      $left =   $style->length_in_pt($style->left,   $cb["w"]);
50
+      
51
+      $x += $left;
52
+      $y += $top;
53
+    }
54
+    
55
+    $frame->set_position($x, $y);
56
+  }
57
+}

+ 230
- 0
vendor/dompdf/dompdf/include/block_renderer.cls.php View File

@@ -0,0 +1,230 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Renders block frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Block_Renderer extends Abstract_Renderer {
16
+
17
+  //........................................................................
18
+
19
+  function render(Frame $frame) {
20
+    $style = $frame->get_style();
21
+    $node = $frame->get_node();
22
+
23
+    list($x, $y, $w, $h) = $frame->get_border_box();
24
+    
25
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
26
+
27
+    if ( $node->nodeName === "body" ) {
28
+      $h = $frame->get_containing_block("h") - $style->length_in_pt(array(
29
+        $style->margin_top,
30
+        $style->border_top_width,
31
+        $style->border_bottom_width,
32
+        $style->margin_bottom),
33
+      $style->width);
34
+    }
35
+
36
+    // Handle anchors & links
37
+    if ( $node->nodeName === "a" && $href = $node->getAttribute("href") ) {
38
+      $this->_canvas->add_link($href, $x, $y, $w, $h);
39
+    }
40
+    
41
+    // Draw our background, border and content
42
+    list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h);
43
+    
44
+    if ( $tl + $tr + $br + $bl > 0 ) {
45
+      $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl );
46
+    }
47
+      
48
+    if ( ($bg = $style->background_color) !== "transparent" ) {
49
+      $this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg );
50
+    }
51
+
52
+    if ( ($url = $style->background_image) && $url !== "none" ) {
53
+      $this->_background_image($url, $x, $y, $w, $h, $style);
54
+    }
55
+    
56
+    if ( $tl + $tr + $br + $bl > 0 ) {
57
+      $this->_canvas->clipping_end();
58
+    }
59
+
60
+    $border_box = array($x, $y, $w, $h);
61
+    $this->_render_border($frame, $border_box);
62
+    $this->_render_outline($frame, $border_box);
63
+    
64
+    if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) {
65
+      $this->_debug_layout($frame->get_border_box(), "red");
66
+      if (DEBUG_LAYOUT_PADDINGBOX) {
67
+        $this->_debug_layout($frame->get_padding_box(), "red", array(0.5, 0.5));
68
+      }
69
+    }
70
+    
71
+    if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES && $frame->get_decorator()) {
72
+      foreach ($frame->get_decorator()->get_line_boxes() as $line) {
73
+        $frame->_debug_layout(array($line->x, $line->y, $line->w, $line->h), "orange");
74
+      }
75
+    }
76
+  }
77
+
78
+  protected function _render_border(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") {
79
+    $style = $frame->get_style();
80
+    $bp = $style->get_border_properties();
81
+
82
+    if ( empty($border_box) ) {
83
+      $border_box = $frame->get_border_box();
84
+    }
85
+    
86
+    // find the radius
87
+    $radius = $style->get_computed_border_radius($border_box[2], $border_box[3]); // w, h
88
+
89
+    // Short-cut: If all the borders are "solid" with the same color and style, and no radius, we'd better draw a rectangle
90
+    if (
91
+        in_array($bp["top"]["style"], array("solid", "dashed", "dotted")) && 
92
+        $bp["top"]    == $bp["right"] &&
93
+        $bp["right"]  == $bp["bottom"] &&
94
+        $bp["bottom"] == $bp["left"] &&
95
+        array_sum($radius) == 0
96
+    ) {
97
+      $props = $bp["top"];
98
+      if ( $props["color"] === "transparent" || $props["width"] <= 0 ) return;
99
+      
100
+      list($x, $y, $w, $h) = $border_box;
101
+      $width = $style->length_in_pt($props["width"]);
102
+      $pattern = $this->_get_dash_pattern($props["style"], $width);
103
+      $this->_canvas->rectangle($x + $width / 2, $y + $width / 2, $w - $width, $h - $width, $props["color"], $width, $pattern);
104
+      return;
105
+    }
106
+
107
+    // Do it the long way
108
+    $widths = array($style->length_in_pt($bp["top"]["width"]),
109
+                    $style->length_in_pt($bp["right"]["width"]),
110
+                    $style->length_in_pt($bp["bottom"]["width"]),
111
+                    $style->length_in_pt($bp["left"]["width"]));
112
+    
113
+    foreach ($bp as $side => $props) {
114
+      list($x, $y, $w, $h) = $border_box;
115
+      $length = 0;
116
+      $r1 = 0;
117
+      $r2 = 0;
118
+
119
+      if ( !$props["style"] || 
120
+            $props["style"] === "none" || 
121
+            $props["width"] <= 0 || 
122
+            $props["color"] == "transparent" )
123
+        continue;
124
+
125
+      switch($side) {
126
+      case "top":
127
+        $length = $w;
128
+        $r1 = $radius["top-left"];
129
+        $r2 = $radius["top-right"];
130
+        break;
131
+
132
+      case "bottom":
133
+        $length = $w;
134
+        $y += $h;
135
+        $r1 = $radius["bottom-left"];
136
+        $r2 = $radius["bottom-right"];
137
+        break;
138
+
139
+      case "left":
140
+        $length = $h;
141
+        $r1 = $radius["top-left"];
142
+        $r2 = $radius["bottom-left"];
143
+        break;
144
+
145
+      case "right":
146
+        $length = $h;
147
+        $x += $w;
148
+        $r1 = $radius["top-right"];
149
+        $r2 = $radius["bottom-right"];
150
+        break;
151
+      default:
152
+        break;
153
+      }
154
+      $method = "_border_" . $props["style"];
155
+    
156
+      // draw rounded corners
157
+      $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style, $r1, $r2);
158
+    }
159
+  }
160
+
161
+  protected function _render_outline(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") {
162
+    $style = $frame->get_style();
163
+    
164
+    $props = array(
165
+      "width" => $style->outline_width,
166
+      "style" => $style->outline_style,
167
+      "color" => $style->outline_color,
168
+    );
169
+    
170
+    if ( !$props["style"] || $props["style"] === "none" || $props["width"] <= 0 )
171
+      return;
172
+
173
+    if ( empty($border_box) ) {
174
+      $border_box = $frame->get_border_box();
175
+    }
176
+
177
+    $offset = $style->length_in_pt($props["width"]);
178
+    $pattern = $this->_get_dash_pattern($props["style"], $offset);
179
+
180
+    // If the outline style is "solid" we'd better draw a rectangle
181
+    if ( in_array($props["style"], array("solid", "dashed", "dotted")) ) {
182
+      $border_box[0] -= $offset / 2;
183
+      $border_box[1] -= $offset / 2;
184
+      $border_box[2] += $offset;
185
+      $border_box[3] += $offset;
186
+    
187
+      list($x, $y, $w, $h) = $border_box;
188
+      $this->_canvas->rectangle($x, $y, $w, $h, $props["color"], $offset, $pattern);
189
+      return;
190
+    }
191
+
192
+    $border_box[0] -= $offset;
193
+    $border_box[1] -= $offset;
194
+    $border_box[2] += $offset * 2;
195
+    $border_box[3] += $offset * 2;
196
+    
197
+    $method = "_border_" . $props["style"];
198
+    $widths = array_fill(0, 4, $props["width"]);
199
+    $sides = array("top", "right", "left", "bottom");
200
+    $length = 0;
201
+    
202
+    foreach ($sides as $side) {
203
+      list($x, $y, $w, $h) = $border_box;
204
+
205
+      switch($side) {
206
+      case "top":
207
+        $length = $w;
208
+        break;
209
+
210
+      case "bottom":
211
+        $length = $w;
212
+        $y += $h;
213
+        break;
214
+
215
+      case "left":
216
+        $length = $h;
217
+        break;
218
+
219
+      case "right":
220
+        $length = $h;
221
+        $x += $w;
222
+        break;
223
+      default:
224
+        break;
225
+      }
226
+
227
+      $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style);
228
+    }
229
+  }
230
+}

+ 164
- 0
vendor/dompdf/dompdf/include/cached_pdf_decorator.cls.php View File

@@ -0,0 +1,164 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Caching canvas implementation
11
+ *
12
+ * Each rendered page is serialized and stored in the {@link Page_Cache}.
13
+ * This is useful for static forms/pages that do not need to be re-rendered
14
+ * all the time.
15
+ *
16
+ * This class decorates normal CPDF_Adapters.  It is currently completely
17
+ * experimental.
18
+ *
19
+ * @access private
20
+ * @package dompdf
21
+ */
22
+class Cached_PDF_Decorator extends CPDF_Adapter implements Canvas {
23
+  /**
24
+   * @var CPDF_Adapter
25
+   */
26
+  protected $_pdf;
27
+  protected $_cache_id;
28
+  protected $_current_page_id;
29
+  protected $_fonts;  // fonts used in this document
30
+  
31
+  function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) {
32
+    $this->_fonts = array();
33
+  }
34
+
35
+  /**
36
+   * Must be called after constructor
37
+   *
38
+   * @param int          $cache_id
39
+   * @param CPDF_Adapter $pdf
40
+   */
41
+  function init($cache_id, CPDF_Adapter $pdf) {
42
+    $this->_cache_id = $cache_id;
43
+    $this->_pdf = $pdf;
44
+    $this->_current_page_id = $this->_pdf->open_object();
45
+  }
46
+
47
+  //........................................................................
48
+
49
+  function get_cpdf() { return $this->_pdf->get_cpdf(); }
50
+
51
+  function open_object() { $this->_pdf->open_object(); }
52
+  function reopen_object($object) { $this->_pdf->reopen_object($object); }
53
+  
54
+  function close_object() { $this->_pdf->close_object(); }
55
+
56
+  function add_object($object, $where = 'all') { $this->_pdf->add_object($object, $where); }
57
+
58
+  function serialize_object($id) { $this->_pdf->serialize_object($id); }
59
+
60
+  function reopen_serialized_object($obj) { $this->_pdf->reopen_serialized_object($obj); }
61
+    
62
+  //........................................................................
63
+
64
+  function get_width() { return $this->_pdf->get_width(); }
65
+  function get_height() {  return $this->_pdf->get_height(); }
66
+  function get_page_number() { return $this->_pdf->get_page_number(); }
67
+  function get_page_count() { return $this->_pdf->get_page_count(); }
68
+
69
+  function set_page_number($num) { $this->_pdf->set_page_number($num); }
70
+  function set_page_count($count) { $this->_pdf->set_page_count($count); }
71
+
72
+  function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) {
73
+    $this->_pdf->line($x1, $y1, $x2, $y2, $color, $width, $style);
74
+  }
75
+                              
76
+  function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) {
77
+    $this->_pdf->rectangle($x1, $y1, $w, $h, $color, $width, $style);
78
+  }
79
+ 
80
+  function filled_rectangle($x1, $y1, $w, $h, $color) {
81
+    $this->_pdf->filled_rectangle($x1, $y1, $w, $h, $color);
82
+  }
83
+    
84
+  function polygon($points, $color, $width = null, $style = array(), $fill = false) {
85
+    $this->_pdf->polygon($points, $color, $width, $style, $fill);
86
+  }
87
+
88
+  function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) {
89
+    $this->_pdf->circle($x, $y, $r1, $color, $width, $style, $fill);
90
+  }
91
+
92
+  function image($img_url, $x, $y, $w, $h, $resolution = "normal") {
93
+    $this->_pdf->image($img_url, $x, $y, $w, $h, $resolution);
94
+  }
95
+  
96
+  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
97
+    $this->_fonts[$font] = true;
98
+    $this->_pdf->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
99
+  }
100
+
101
+  function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
102
+    
103
+    // We want to remove this from cached pages since it may not be correct
104
+    $this->_pdf->close_object();
105
+    $this->_pdf->page_text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
106
+    $this->_pdf->reopen_object($this->_current_page_id);
107
+  }
108
+  
109
+  function page_script($script, $type = 'text/php') {
110
+    
111
+    // We want to remove this from cached pages since it may not be correct
112
+    $this->_pdf->close_object();
113
+    $this->_pdf->page_script($script, $type);
114
+    $this->_pdf->reopen_object($this->_current_page_id);
115
+  }
116
+  
117
+  function new_page() {
118
+    $this->_pdf->close_object();
119
+
120
+    // Add the object to the current page
121
+    $this->_pdf->add_object($this->_current_page_id, "add");
122
+    $this->_pdf->new_page();    
123
+
124
+    Page_Cache::store_page($this->_cache_id,
125
+                           $this->_pdf->get_page_number() - 1,
126
+                           $this->_pdf->serialize_object($this->_current_page_id));
127
+
128
+    $this->_current_page_id = $this->_pdf->open_object();
129
+    return $this->_current_page_id;
130
+  }
131
+  
132
+  function stream($filename, $options = null) {
133
+    // Store the last page in the page cache
134
+    if ( !is_null($this->_current_page_id) ) {
135
+      $this->_pdf->close_object();
136
+      $this->_pdf->add_object($this->_current_page_id, "add");
137
+      Page_Cache::store_page($this->_cache_id,
138
+                             $this->_pdf->get_page_number(),
139
+                             $this->_pdf->serialize_object($this->_current_page_id));
140
+      Page_Cache::store_fonts($this->_cache_id, $this->_fonts);
141
+      $this->_current_page_id = null;
142
+    }
143
+    
144
+    $this->_pdf->stream($filename);
145
+    
146
+  }
147
+  
148
+  function output($options = null) {
149
+    // Store the last page in the page cache
150
+    if ( !is_null($this->_current_page_id) ) {
151
+      $this->_pdf->close_object();
152
+      $this->_pdf->add_object($this->_current_page_id, "add");
153
+      Page_Cache::store_page($this->_cache_id,
154
+                             $this->_pdf->get_page_number(),
155
+                             $this->_pdf->serialize_object($this->_current_page_id));
156
+      $this->_current_page_id = null;
157
+    }
158
+    
159
+    return $this->_pdf->output();
160
+  }
161
+  
162
+  function get_messages() { return $this->_pdf->get_messages(); }
163
+  
164
+}

+ 385
- 0
vendor/dompdf/dompdf/include/canvas.cls.php View File

@@ -0,0 +1,385 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Main rendering interface
12
+ *
13
+ * Currently {@link CPDF_Adapter}, {@link PDFLib_Adapter}, {@link TCPDF_Adapter}, and {@link GD_Adapter}
14
+ * implement this interface.
15
+ *
16
+ * Implementations should measure x and y increasing to the left and down,
17
+ * respectively, with the origin in the top left corner.  Implementations
18
+ * are free to use a unit other than points for length, but I can't
19
+ * guarantee that the results will look any good.
20
+ *
21
+ * @package dompdf
22
+ */
23
+interface Canvas {
24
+  function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf);
25
+
26
+  /**
27
+   * @return DOMPDF
28
+   */
29
+  function get_dompdf();
30
+
31
+  /**
32
+   * Returns the current page number
33
+   *
34
+   * @return int
35
+   */
36
+  function get_page_number();
37
+
38
+  /**
39
+   * Returns the total number of pages
40
+   *
41
+   * @return int
42
+   */
43
+  function get_page_count();
44
+
45
+  /**
46
+   * Sets the total number of pages
47
+   *
48
+   * @param int $count
49
+   */
50
+  function set_page_count($count);
51
+
52
+  /**
53
+   * Draws a line from x1,y1 to x2,y2
54
+   *
55
+   * See {@link Style::munge_color()} for the format of the color array.
56
+   * See {@link Cpdf::setLineStyle()} for a description of the format of the
57
+   * $style parameter (aka dash).
58
+   *
59
+   * @param float $x1
60
+   * @param float $y1
61
+   * @param float $x2
62
+   * @param float $y2
63
+   * @param array $color
64
+   * @param float $width
65
+   * @param array $style
66
+   */
67
+  function line($x1, $y1, $x2, $y2, $color, $width, $style = null);
68
+
69
+  /**
70
+   * Draws a rectangle at x1,y1 with width w and height h
71
+   *
72
+   * See {@link Style::munge_color()} for the format of the color array.
73
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
74
+   * parameter (aka dash)
75
+   *
76
+   * @param float $x1
77
+   * @param float $y1
78
+   * @param float $w
79
+   * @param float $h
80
+   * @param array $color
81
+   * @param float $width
82
+   * @param array $style
83
+   */   
84
+  function rectangle($x1, $y1, $w, $h, $color, $width, $style = null);
85
+
86
+  /**
87
+   * Draws a filled rectangle at x1,y1 with width w and height h
88
+   *
89
+   * See {@link Style::munge_color()} for the format of the color array.
90
+   *
91
+   * @param float $x1
92
+   * @param float $y1
93
+   * @param float $w
94
+   * @param float $h
95
+   * @param array $color
96
+   */   
97
+  function filled_rectangle($x1, $y1, $w, $h, $color);
98
+
99
+  /**
100
+   * Starts a clipping rectangle at x1,y1 with width w and height h
101
+   *
102
+   * @param float $x1
103
+   * @param float $y1
104
+   * @param float $w
105
+   * @param float $h
106
+   */   
107
+  function clipping_rectangle($x1, $y1, $w, $h);
108
+
109
+  /**
110
+   * Starts a rounded clipping rectangle at x1,y1 with width w and height h
111
+   *
112
+   * @param float $x1
113
+   * @param float $y1
114
+   * @param float $w
115
+   * @param float $h
116
+   * @param float $tl
117
+   * @param float $tr
118
+   * @param float $br
119
+   * @param float $bl
120
+   *
121
+   * @return
122
+   */
123
+  function clipping_roundrectangle($x1, $y1, $w, $h, $tl, $tr, $br, $bl);
124
+  
125
+  /**
126
+   * Ends the last clipping shape
127
+   */  
128
+  function clipping_end();
129
+  
130
+  /**
131
+   * Save current state
132
+   */
133
+  function save();
134
+  
135
+  /**
136
+   * Restore last state
137
+   */
138
+  function restore();
139
+  
140
+  /**
141
+   * Rotate
142
+   */
143
+  function rotate($angle, $x, $y);
144
+  
145
+  /**
146
+   * Skew
147
+   */
148
+  function skew($angle_x, $angle_y, $x, $y);
149
+  
150
+  /**
151
+   * Scale
152
+   */
153
+  function scale($s_x, $s_y, $x, $y);
154
+  
155
+  /**
156
+   * Translate
157
+   */
158
+  function translate($t_x, $t_y);
159
+  
160
+  /**
161
+   * Transform
162
+   */
163
+  function transform($a, $b, $c, $d, $e, $f);
164
+  
165
+  /**
166
+   * Draws a polygon
167
+   *
168
+   * The polygon is formed by joining all the points stored in the $points
169
+   * array.  $points has the following structure:
170
+   * <code>
171
+   * array(0 => x1,
172
+   *       1 => y1,
173
+   *       2 => x2,
174
+   *       3 => y2,
175
+   *       ...
176
+   *       );
177
+   * </code>
178
+   *
179
+   * See {@link Style::munge_color()} for the format of the color array.
180
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
181
+   * parameter (aka dash)   
182
+   *
183
+   * @param array $points
184
+   * @param array $color
185
+   * @param float $width
186
+   * @param array $style
187
+   * @param bool  $fill  Fills the polygon if true
188
+   */
189
+  function polygon($points, $color, $width = null, $style = null, $fill = false);
190
+
191
+  /**
192
+   * Draws a circle at $x,$y with radius $r
193
+   *
194
+   * See {@link Style::munge_color()} for the format of the color array.
195
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
196
+   * parameter (aka dash)
197
+   *
198
+   * @param float $x
199
+   * @param float $y
200
+   * @param float $r
201
+   * @param array $color
202
+   * @param float $width
203
+   * @param array $style
204
+   * @param bool $fill Fills the circle if true   
205
+   */   
206
+  function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false);
207
+
208
+  /**
209
+   * Add an image to the pdf.
210
+   *
211
+   * The image is placed at the specified x and y coordinates with the
212
+   * given width and height.
213
+   *
214
+   * @param string $img_url the path to the image
215
+   * @param float $x x position
216
+   * @param float $y y position
217
+   * @param int $w width (in pixels)
218
+   * @param int $h height (in pixels)
219
+   * @param string $resolution The resolution of the image
220
+   */
221
+  function image($img_url, $x, $y, $w, $h, $resolution = "normal");
222
+
223
+  /**
224
+   * Add an arc to the PDF
225
+   * See {@link Style::munge_color()} for the format of the color array.
226
+   *
227
+   * @param float $x      X coordinate of the arc
228
+   * @param float $y      Y coordinate of the arc
229
+   * @param float $r1     Radius 1
230
+   * @param float $r2     Radius 2
231
+   * @param float $astart Start angle in degrees
232
+   * @param float $aend   End angle in degrees
233
+   * @param array $color  Color
234
+   * @param float $width
235
+   * @param array $style
236
+   *
237
+   * @return void
238
+   */
239
+  function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array());
240
+
241
+  /**
242
+   * Writes text at the specified x and y coordinates
243
+   * See {@link Style::munge_color()} for the format of the color array.
244
+   *
245
+   * @param float  $x
246
+   * @param float  $y
247
+   * @param string $text       the text to write
248
+   * @param string $font       the font file to use
249
+   * @param float  $size       the font size, in points
250
+   * @param array  $color
251
+   * @param float  $word_space word spacing adjustment
252
+   * @param float  $char_space char spacing adjustment
253
+   * @param float  $angle      angle
254
+   *
255
+   * @return void
256
+   */
257
+  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0);
258
+
259
+  /**
260
+   * Add a named destination (similar to <a name="foo">...</a> in html)
261
+   *
262
+   * @param string $anchorname The name of the named destination
263
+   */
264
+  function add_named_dest($anchorname);
265
+
266
+  /**
267
+   * Add a link to the pdf
268
+   *
269
+   * @param string $url    The url to link to
270
+   * @param float  $x      The x position of the link
271
+   * @param float  $y      The y position of the link
272
+   * @param float  $width  The width of the link
273
+   * @param float  $height The height of the link
274
+   *
275
+   * @return void
276
+   */
277
+  function add_link($url, $x, $y, $width, $height);
278
+
279
+  /**
280
+   * Add meta information to the pdf
281
+   *
282
+   * @param string $name  Label of the value (Creator, Producer, etc.)
283
+   * @param string $value The text to set
284
+   */
285
+  function add_info($name, $value);
286
+  
287
+  /**
288
+   * Calculates text size, in points
289
+   *
290
+   * @param string $text the text to be sized
291
+   * @param string $font the desired font
292
+   * @param float  $size the desired font size
293
+   * @param float  $word_spacing word spacing, if any
294
+   * @param float  $char_spacing
295
+   *
296
+   * @return float
297
+   */
298
+  function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0);
299
+
300
+  /**
301
+   * Calculates font height, in points
302
+   *
303
+   * @param string $font
304
+   * @param float  $size
305
+   *
306
+   * @return float
307
+   */
308
+  function get_font_height($font, $size);
309
+
310
+  /**
311
+   * Calculates font baseline, in points
312
+   *
313
+   * @param string $font
314
+   * @param float  $size
315
+   *
316
+   * @return float
317
+   */
318
+  function get_font_baseline($font, $size);
319
+  
320
+  /**
321
+   * Returns the font x-height, in points
322
+   *
323
+   * @param string $font
324
+   * @param float  $size
325
+   *
326
+   * @return float
327
+   */
328
+  //function get_font_x_height($font, $size);
329
+  
330
+  /**
331
+   * Sets the opacity
332
+   *
333
+   * @param float  $opacity
334
+   * @param string $mode
335
+   */
336
+  function set_opacity($opacity, $mode = "Normal");
337
+
338
+  /**
339
+   * Sets the default view
340
+   *
341
+   * @param string $view
342
+   * 'XYZ'  left, top, zoom
343
+   * 'Fit'
344
+   * 'FitH' top
345
+   * 'FitV' left
346
+   * 'FitR' left,bottom,right
347
+   * 'FitB'
348
+   * 'FitBH' top
349
+   * 'FitBV' left
350
+   * @param array  $options
351
+   *
352
+   * @return void
353
+   */
354
+  function set_default_view($view, $options = array());
355
+
356
+  /**
357
+   * @param string $script
358
+   *
359
+   * @return void
360
+   */
361
+  function javascript($script);
362
+
363
+  /**
364
+   * Starts a new page
365
+   *
366
+   * Subsequent drawing operations will appear on the new page.
367
+   */
368
+  function new_page();
369
+
370
+  /**
371
+   * Streams the PDF directly to the browser
372
+   *
373
+   * @param string $filename the name of the PDF file
374
+   * @param array  $options associative array, 'Attachment' => 0 or 1, 'compress' => 1 or 0
375
+   */
376
+  function stream($filename, $options = null);
377
+
378
+  /**
379
+   * Returns the PDF as a string
380
+   *
381
+   * @param array  $options associative array: 'compress' => 1 or 0
382
+   * @return string
383
+   */
384
+  function output($options = null);
385
+}

+ 63
- 0
vendor/dompdf/dompdf/include/canvas_factory.cls.php View File

@@ -0,0 +1,63 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Create canvas instances
11
+ *
12
+ * The canvas factory creates canvas instances based on the
13
+ * availability of rendering backends and config options.
14
+ *
15
+ * @package dompdf
16
+ */
17
+class Canvas_Factory {
18
+
19
+  /**
20
+   * Constructor is private: this is a static class
21
+   */
22
+  private function __construct() { }
23
+
24
+  /**
25
+   * @param DOMPDF       $dompdf
26
+   * @param string|array $paper
27
+   * @param string       $orientation
28
+   * @param string       $class
29
+   *
30
+   * @return Canvas
31
+   */
32
+  static function get_instance(DOMPDF $dompdf, $paper = null, $orientation = null, $class = null) {
33
+
34
+    $backend = strtolower(DOMPDF_PDF_BACKEND);
35
+    
36
+    if ( isset($class) && class_exists($class, false) ) {
37
+      $class .= "_Adapter";
38
+    }
39
+    
40
+    else if ( (DOMPDF_PDF_BACKEND === "auto" || $backend === "pdflib" ) &&
41
+              class_exists("PDFLib", false) ) {
42
+      $class = "PDFLib_Adapter";
43
+    }
44
+
45
+    // FIXME The TCPDF adapter is not ready yet
46
+    //else if ( (DOMPDF_PDF_BACKEND === "auto" || $backend === "cpdf") )
47
+    //  $class = "CPDF_Adapter";
48
+
49
+    else if ( $backend === "tcpdf" ) {
50
+      $class = "TCPDF_Adapter";
51
+    }
52
+      
53
+    else if ( $backend === "gd" ) {
54
+      $class = "GD_Adapter";
55
+    }
56
+    
57
+    else {
58
+      $class = "CPDF_Adapter";
59
+    }
60
+
61
+    return new $class($paper, $orientation, $dompdf);
62
+  }
63
+}

+ 790
- 0
vendor/dompdf/dompdf/include/cellmap.cls.php View File

@@ -0,0 +1,790 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Maps table cells to the table grid.
11
+ *
12
+ * This class resolves borders in tables with collapsed borders and helps
13
+ * place row & column spanned table cells.
14
+ *
15
+ * @access private
16
+ * @package dompdf
17
+ */
18
+class Cellmap {
19
+
20
+  /**
21
+   * Border style weight lookup for collapsed border resolution.
22
+   *
23
+   * @var array
24
+   */
25
+  static protected $_BORDER_STYLE_SCORE = array(
26
+    "inset"  => 1,
27
+    "groove" => 2,
28
+    "outset" => 3,
29
+    "ridge"  => 4,
30
+    "dotted" => 5,
31
+    "dashed" => 6,
32
+    "solid"  => 7,
33
+    "double" => 8,
34
+    "hidden" => 9,
35
+    "none"   => 0,
36
+   );
37
+
38
+  /**
39
+   * The table object this cellmap is attached to.
40
+   *
41
+   * @var Table_Frame_Decorator
42
+   */
43
+  protected $_table;
44
+
45
+  /**
46
+   * The total number of rows in the table
47
+   *
48
+   * @var int
49
+   */
50
+  protected $_num_rows;
51
+
52
+  /**
53
+   * The total number of columns in the table
54
+   *
55
+   * @var int
56
+   */
57
+  protected $_num_cols;
58
+
59
+  /**
60
+   * 2D array mapping <row,column> to frames
61
+   *
62
+   * @var Frame[][]
63
+   */
64
+  protected $_cells;
65
+
66
+  /**
67
+   * 1D array of column dimensions
68
+   *
69
+   * @var array
70
+   */
71
+  protected $_columns;
72
+
73
+  /**
74
+   * 1D array of row dimensions
75
+   *
76
+   * @var array
77
+   */
78
+  protected $_rows;
79
+
80
+  /**
81
+   * 2D array of border specs
82
+   *
83
+   * @var array
84
+   */
85
+  protected $_borders;
86
+
87
+  /**
88
+   * 1D Array mapping frames to (multiple) <row, col> pairs, keyed on frame_id.
89
+   *
90
+   * @var Frame[]
91
+   */
92
+  protected $_frames;
93
+
94
+  /**
95
+   * Current column when adding cells, 0-based
96
+   *
97
+   * @var int
98
+   */
99
+  private $__col;
100
+
101
+  /**
102
+   * Current row when adding cells, 0-based
103
+   *
104
+   * @var int
105
+   */
106
+  private $__row;
107
+  
108
+  /**
109
+   * Tells wether the columns' width can be modified
110
+   *
111
+   * @var bool
112
+   */
113
+  private $_columns_locked = false;
114
+  
115
+  /**
116
+   * Tells wether the table has table-layout:fixed
117
+   *
118
+   * @var bool
119
+   */
120
+  private $_fixed_layout = false;
121
+
122
+  //........................................................................
123
+
124
+  function __construct(Table_Frame_Decorator $table) {
125
+    $this->_table = $table;
126
+    $this->reset();
127
+  }
128
+  
129
+  function __destruct() {
130
+    clear_object($this);
131
+  }
132
+  //........................................................................
133
+
134
+  function reset() {
135
+    $this->_num_rows = 0;
136
+    $this->_num_cols = 0;
137
+
138
+    $this->_cells  = array();
139
+    $this->_frames = array();
140
+
141
+    if ( !$this->_columns_locked ) {
142
+      $this->_columns = array();
143
+    }
144
+    
145
+    $this->_rows = array();
146
+
147
+    $this->_borders = array();
148
+
149
+    $this->__col = $this->__row = 0;
150
+  }
151
+
152
+  //........................................................................
153
+
154
+  function lock_columns() { 
155
+    $this->_columns_locked = true; 
156
+  }
157
+
158
+  function is_columns_locked() {
159
+    return $this->_columns_locked;
160
+  }
161
+  
162
+  function set_layout_fixed($fixed) { 
163
+    $this->_fixed_layout = $fixed; 
164
+  }
165
+
166
+  function is_layout_fixed() {
167
+    return $this->_fixed_layout;
168
+  }
169
+  
170
+  function get_num_rows() { return $this->_num_rows; }
171
+  function get_num_cols() { return $this->_num_cols; }
172
+
173
+  function &get_columns() {
174
+    return $this->_columns;
175
+  }
176
+
177
+  function set_columns($columns) {
178
+    $this->_columns = $columns;
179
+  }
180
+
181
+  function &get_column($i) {
182
+    if ( !isset($this->_columns[$i]) ) {
183
+      $this->_columns[$i] = array(
184
+        "x" => 0,
185
+        "min-width" => 0,
186
+        "max-width" => 0,
187
+        "used-width" => null,
188
+        "absolute" => 0,
189
+        "percent" => 0,
190
+        "auto" => true,
191
+      );
192
+    }
193
+    
194
+    return $this->_columns[$i];
195
+  }
196
+
197
+  function &get_rows() {
198
+    return $this->_rows;
199
+  }
200
+
201
+  function &get_row($j) {
202
+    if ( !isset($this->_rows[$j]) ) {
203
+      $this->_rows[$j] = array(
204
+        "y" => 0,
205
+        "first-column" => 0,
206
+        "height" => null,
207
+      );
208
+    }
209
+    
210
+    return $this->_rows[$j];
211
+  }
212
+
213
+  function get_border($i, $j, $h_v, $prop = null) {
214
+    if ( !isset($this->_borders[$i][$j][$h_v]) ) {
215
+      $this->_borders[$i][$j][$h_v] = array(
216
+        "width" => 0,
217
+        "style" => "solid",
218
+        "color" => "black",
219
+      );
220
+    }
221
+    
222
+    if ( isset($prop) ) {
223
+      return $this->_borders[$i][$j][$h_v][$prop];
224
+    }
225
+    
226
+    return $this->_borders[$i][$j][$h_v];
227
+  }
228
+
229
+  function get_border_properties($i, $j) {
230
+    return array(
231
+      "top"    => $this->get_border($i,   $j,   "horizontal"), 
232
+      "right"  => $this->get_border($i,   $j+1, "vertical"),
233
+      "bottom" => $this->get_border($i+1, $j,   "horizontal"), 
234
+      "left"   => $this->get_border($i,   $j,   "vertical"),
235
+    );
236
+  }
237
+
238
+  //........................................................................
239
+
240
+  function get_spanned_cells(Frame $frame) {
241
+    $key = $frame->get_id();
242
+
243
+    if ( !isset($this->_frames[$key]) ) {
244
+      throw new DOMPDF_Exception("Frame not found in cellmap");
245
+    }
246
+
247
+    return $this->_frames[$key];
248
+
249
+  }
250
+
251
+  function frame_exists_in_cellmap(Frame $frame) {
252
+    $key = $frame->get_id();
253
+    return isset($this->_frames[$key]);
254
+  }
255
+  
256
+  function get_frame_position(Frame $frame) {
257
+    global $_dompdf_warnings;
258
+
259
+    $key = $frame->get_id();
260
+
261
+    if ( !isset($this->_frames[$key]) ) {
262
+      throw new DOMPDF_Exception("Frame not found in cellmap");
263
+    }
264
+
265
+    $col = $this->_frames[$key]["columns"][0];
266
+    $row = $this->_frames[$key]["rows"][0];
267
+
268
+    if ( !isset($this->_columns[$col])) {
269
+      $_dompdf_warnings[] = "Frame not found in columns array.  Check your table layout for missing or extra TDs.";
270
+      $x = 0;
271
+    }
272
+    else {
273
+      $x = $this->_columns[$col]["x"];
274
+    }
275
+
276
+    if ( !isset($this->_rows[$row])) {
277
+      $_dompdf_warnings[] = "Frame not found in row array.  Check your table layout for missing or extra TDs.";
278
+      $y = 0;
279
+    }
280
+    else {
281
+      $y = $this->_rows[$row]["y"];
282
+    }
283
+
284
+    return array($x, $y, "x" => $x, "y" => $y);
285
+  }
286
+
287
+  function get_frame_width(Frame $frame) {
288
+    $key = $frame->get_id();
289
+
290
+    if ( !isset($this->_frames[$key]) ) {
291
+      throw new DOMPDF_Exception("Frame not found in cellmap");
292
+    }
293
+
294
+    $cols = $this->_frames[$key]["columns"];
295
+    $w = 0;
296
+    foreach ($cols as $i) {
297
+      $w += $this->_columns[$i]["used-width"];
298
+    }
299
+    
300
+    return $w;
301
+  }
302
+
303
+  function get_frame_height(Frame $frame) {
304
+    $key = $frame->get_id();
305
+
306
+    if ( !isset($this->_frames[$key]) ) {
307
+      throw new DOMPDF_Exception("Frame not found in cellmap");
308
+    }
309
+
310
+    $rows = $this->_frames[$key]["rows"];
311
+    $h = 0;
312
+    foreach ($rows as $i) {
313
+      if ( !isset($this->_rows[$i]) )  {
314
+        throw new Exception("The row #$i could not be found, please file an issue in the tracker with the HTML code");
315
+      }
316
+      
317
+      $h += $this->_rows[$i]["height"];
318
+    }
319
+    
320
+    return $h;
321
+  }
322
+
323
+
324
+  //........................................................................
325
+
326
+  function set_column_width($j, $width) {
327
+    if ( $this->_columns_locked ) {
328
+      return;
329
+    }
330
+    
331
+    $col =& $this->get_column($j);
332
+    $col["used-width"] = $width;
333
+    $next_col =& $this->get_column($j+1);
334
+    $next_col["x"] = $next_col["x"] + $width;
335
+  }
336
+
337
+  function set_row_height($i, $height) {
338
+    $row =& $this->get_row($i);
339
+    
340
+    if ( $row["height"] !== null && $height <= $row["height"] ) {
341
+      return;
342
+    }
343
+
344
+    $row["height"] = $height;
345
+    $next_row =& $this->get_row($i+1);
346
+    $next_row["y"] = $row["y"] + $height;
347
+
348
+  }
349
+
350
+  //........................................................................
351
+
352
+
353
+  protected function _resolve_border($i, $j, $h_v, $border_spec) {
354
+    $n_width = $border_spec["width"];
355
+    $n_style = $border_spec["style"];
356
+
357
+    if ( !isset($this->_borders[$i][$j][$h_v]) ) {
358
+      $this->_borders[$i][$j][$h_v] = $border_spec;
359
+      return $this->_borders[$i][$j][$h_v]["width"];
360
+    }
361
+    
362
+    $border = &$this->_borders[$i][$j][$h_v];
363
+    
364
+    $o_width = $border["width"];
365
+    $o_style = $border["style"];
366
+
367
+    if ( ($n_style === "hidden" ||
368
+          $n_width  >  $o_width ||
369
+          $o_style === "none")
370
+
371
+         or
372
+
373
+         ($o_width == $n_width &&
374
+          in_array($n_style, self::$_BORDER_STYLE_SCORE) &&
375
+          self::$_BORDER_STYLE_SCORE[ $n_style ] > self::$_BORDER_STYLE_SCORE[ $o_style ]) ) {
376
+      $border = $border_spec;
377
+    }
378
+
379
+    return $border["width"];
380
+  }
381
+
382
+  //........................................................................
383
+
384
+  function add_frame(Frame $frame) {
385
+    
386
+    $style = $frame->get_style();
387
+    $display = $style->display;
388
+
389
+    $collapse = $this->_table->get_style()->border_collapse == "collapse";
390
+
391
+    // Recursively add the frames within tables, table-row-groups and table-rows
392
+    if ( $display === "table-row" ||
393
+         $display === "table" ||
394
+         $display === "inline-table" ||
395
+         in_array($display, Table_Frame_Decorator::$ROW_GROUPS) ) {
396
+
397
+      $start_row = $this->__row;
398
+      foreach ( $frame->get_children() as $child ) {
399
+        $this->add_frame( $child );
400
+      }
401
+
402
+      if ( $display === "table-row" ) {
403
+        $this->add_row();
404
+      }
405
+
406
+      $num_rows = $this->__row - $start_row - 1;
407
+      $key = $frame->get_id();
408
+
409
+      // Row groups always span across the entire table
410
+      $this->_frames[$key]["columns"] = range(0,max(0,$this->_num_cols-1));
411
+      $this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1));
412
+      $this->_frames[$key]["frame"] = $frame;
413
+
414
+      if ( $display !== "table-row" && $collapse ) {
415
+
416
+        $bp = $style->get_border_properties();
417
+
418
+        // Resolve the borders
419
+        for ( $i = 0; $i < $num_rows+1; $i++) {
420
+          $this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]);
421
+          $this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]);
422
+        }
423
+
424
+        for ( $j = 0; $j < $this->_num_cols; $j++) {
425
+          $this->_resolve_border($start_row, $j, "horizontal", $bp["top"]);
426
+          $this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]);
427
+        }
428
+      }
429
+
430
+
431
+      return;
432
+    }
433
+    
434
+    $node = $frame->get_node();
435
+    
436
+    // Determine where this cell is going
437
+    $colspan = $node->getAttribute("colspan");
438
+    $rowspan = $node->getAttribute("rowspan");
439
+
440
+    if ( !$colspan ) {
441
+      $colspan = 1;
442
+      $node->setAttribute("colspan",1);
443
+    }
444
+
445
+    if ( !$rowspan ) {
446
+      $rowspan = 1;
447
+      $node->setAttribute("rowspan",1);
448
+    }
449
+    $key = $frame->get_id();
450
+
451
+    $bp = $style->get_border_properties();
452
+
453
+
454
+    // Add the frame to the cellmap
455
+    $max_left = $max_right = 0;
456
+
457
+    // Find the next available column (fix by Ciro Mondueri)
458
+    $ac = $this->__col;
459
+    while ( isset($this->_cells[$this->__row][$ac]) ) {
460
+       $ac++;
461
+    }
462
+    
463
+    $this->__col = $ac;
464
+
465
+    // Rows:
466
+    for ( $i = 0; $i < $rowspan; $i++ ) {
467
+      $row = $this->__row + $i;
468
+
469
+      $this->_frames[$key]["rows"][] = $row;
470
+
471
+      for ( $j = 0; $j < $colspan; $j++) {
472
+        $this->_cells[$row][$this->__col + $j] = $frame;
473
+      }
474
+
475
+      if ( $collapse ) {
476
+        // Resolve vertical borders
477
+        $max_left = max($max_left, $this->_resolve_border($row, $this->__col, "vertical", $bp["left"]));
478
+        $max_right = max($max_right, $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"]));
479
+      }
480
+    }
481
+
482
+    $max_top = $max_bottom = 0;
483
+
484
+    // Columns:
485
+    for ( $j = 0; $j < $colspan; $j++ ) {
486
+      $col = $this->__col + $j;
487
+      $this->_frames[$key]["columns"][] = $col;
488
+
489
+      if ( $collapse ) {
490
+        // Resolve horizontal borders
491
+        $max_top = max($max_top, $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"]));
492
+        $max_bottom = max($max_bottom, $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"]));
493
+      }
494
+    }
495
+
496
+    $this->_frames[$key]["frame"] = $frame;
497
+
498
+    // Handle seperated border model
499
+    if ( !$collapse ) {
500
+      list($h, $v) = $this->_table->get_style()->border_spacing;
501
+
502
+      // Border spacing is effectively a margin between cells
503
+      $v = $style->length_in_pt($v) / 2;
504
+      $h = $style->length_in_pt($h) / 2;
505
+      $style->margin = "$v $h";
506
+
507
+      // The additional 1/2 width gets added to the table proper
508
+    }
509
+    else {
510
+      // Drop the frame's actual border
511
+      $style->border_left_width = $max_left / 2;
512
+      $style->border_right_width = $max_right / 2;
513
+      $style->border_top_width = $max_top / 2;
514
+      $style->border_bottom_width = $max_bottom / 2;
515
+      $style->margin = "none";
516
+    }
517
+
518
+    if ( !$this->_columns_locked ) {
519
+      // Resolve the frame's width
520
+      if ( $this->_fixed_layout ) {
521
+        list($frame_min, $frame_max) = array(0, 10e-10);
522
+      }
523
+      else {
524
+        list($frame_min, $frame_max) = $frame->get_min_max_width();
525
+      }
526
+  
527
+      $width = $style->width;
528
+
529
+      $val = null;
530
+      if ( is_percent($width) ) {
531
+        $var = "percent";
532
+        $val = (float)rtrim($width, "% ") / $colspan;
533
+      }
534
+      else if ( $width !== "auto" ) {
535
+        $var = "absolute";
536
+        $val = $style->length_in_pt($frame_min) / $colspan;
537
+      }
538
+      
539
+      $min = 0;
540
+      $max = 0;
541
+      for ( $cs = 0; $cs < $colspan; $cs++ ) {
542
+  
543
+        // Resolve the frame's width(s) with other cells
544
+        $col =& $this->get_column( $this->__col + $cs );
545
+  
546
+        // Note: $var is either 'percent' or 'absolute'.  We compare the
547
+        // requested percentage or absolute values with the existing widths
548
+        // and adjust accordingly.
549
+        if ( isset($var) && $val > $col[$var] ) {
550
+          $col[$var] = $val;
551
+          $col["auto"] = false;
552
+        }
553
+  
554
+        $min += $col["min-width"];
555
+        $max += $col["max-width"];
556
+      }
557
+  
558
+      if ( $frame_min > $min ) {
559
+        // The frame needs more space.  Expand each sub-column
560
+        // FIXME try to avoid putting this dummy value when table-layout:fixed
561
+        $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_min - $min) / $colspan);
562
+        for ($c = 0; $c < $colspan; $c++) {
563
+          $col =& $this->get_column($this->__col + $c);
564
+          $col["min-width"] += $inc;
565
+        }
566
+      }
567
+  
568
+      if ( $frame_max > $max ) {
569
+        // FIXME try to avoid putting this dummy value when table-layout:fixed
570
+        $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_max - $max) / $colspan);
571
+        for ($c = 0; $c < $colspan; $c++) {
572
+          $col =& $this->get_column($this->__col + $c);
573
+          $col["max-width"] += $inc;
574
+        }
575
+      }
576
+    }
577
+
578
+    $this->__col += $colspan;
579
+    if ( $this->__col > $this->_num_cols )
580
+      $this->_num_cols = $this->__col;
581
+
582
+  }
583
+
584
+  //........................................................................
585
+
586
+  function add_row() {
587
+
588
+    $this->__row++;
589
+    $this->_num_rows++;
590
+
591
+    // Find the next available column
592
+    $i = 0;
593
+    while ( isset($this->_cells[$this->__row][$i]) ) {
594
+      $i++;
595
+    }
596
+
597
+    $this->__col = $i;
598
+
599
+  }
600
+
601
+  //........................................................................
602
+
603
+  /**
604
+   * Remove a row from the cellmap.
605
+   *
606
+   * @param Frame
607
+   */
608
+  function remove_row(Frame $row) {
609
+
610
+    $key = $row->get_id();
611
+    if ( !isset($this->_frames[$key]) ) {
612
+      return;  // Presumably this row has alredy been removed
613
+    }
614
+
615
+    $this->_row = $this->_num_rows--;
616
+
617
+    $rows = $this->_frames[$key]["rows"];
618
+    $columns = $this->_frames[$key]["columns"];
619
+
620
+    // Remove all frames from this row
621
+    foreach ( $rows as $r ) {
622
+      foreach ( $columns as $c ) {
623
+        if ( isset($this->_cells[$r][$c]) ) {
624
+          $id = $this->_cells[$r][$c]->get_id();
625
+          
626
+          $this->_frames[$id] = null;
627
+          unset($this->_frames[$id]);
628
+          
629
+          $this->_cells[$r][$c] = null;
630
+          unset($this->_cells[$r][$c]);
631
+        }
632
+      }
633
+      
634
+      $this->_rows[$r] = null;
635
+      unset($this->_rows[$r]);
636
+    }
637
+
638
+    $this->_frames[$key] = null;
639
+    unset($this->_frames[$key]);
640
+
641
+  }
642
+
643
+  /**
644
+   * Remove a row group from the cellmap.
645
+   *
646
+   * @param Frame $group  The group to remove
647
+   */
648
+  function remove_row_group(Frame $group) {
649
+
650
+    $key = $group->get_id();
651
+    if ( !isset($this->_frames[$key]) ) {
652
+      return;  // Presumably this row has alredy been removed
653
+    }
654
+    
655
+    $iter = $group->get_first_child();
656
+    while ($iter) {
657
+      $this->remove_row($iter);
658
+      $iter = $iter->get_next_sibling();
659
+    }
660
+
661
+    $this->_frames[$key] = null;
662
+    unset($this->_frames[$key]);
663
+  }
664
+
665
+  /**
666
+   * Update a row group after rows have been removed
667
+   *
668
+   * @param Frame $group    The group to update
669
+   * @param Frame $last_row The last row in the row group
670
+   */
671
+  function update_row_group(Frame $group, Frame $last_row) {
672
+
673
+    $g_key = $group->get_id();
674
+    $r_key = $last_row->get_id();
675
+
676
+    $r_rows = $this->_frames[$r_key]["rows"];
677
+    $this->_frames[$g_key]["rows"] = range( $this->_frames[$g_key]["rows"][0], end($r_rows) );
678
+
679
+  }
680
+
681
+  //........................................................................
682
+
683
+  function assign_x_positions() {
684
+    // Pre-condition: widths must be resolved and assigned to columns and
685
+    // column[0]["x"] must be set.
686
+
687
+    if ( $this->_columns_locked ) {
688
+      return;
689
+    }
690
+    
691
+    $x = $this->_columns[0]["x"];
692
+    foreach ( array_keys($this->_columns) as $j ) {
693
+      $this->_columns[$j]["x"] = $x;
694
+      $x += $this->_columns[$j]["used-width"];
695
+    }
696
+
697
+  }
698
+
699
+  function assign_frame_heights() {
700
+    // Pre-condition: widths and heights of each column & row must be
701
+    // calcluated
702
+
703
+    foreach ( $this->_frames as $arr ) {
704
+      $frame = $arr["frame"];
705
+
706
+      $h = 0;
707
+      foreach( $arr["rows"] as $row ) {
708
+        if ( !isset($this->_rows[$row]) ) {
709
+          // The row has been removed because of a page split, so skip it.
710
+          continue;
711
+        }
712
+        
713
+        $h += $this->_rows[$row]["height"];
714
+      }
715
+
716
+      if ( $frame instanceof Table_Cell_Frame_Decorator ) {
717
+        $frame->set_cell_height($h);
718
+      }
719
+      else {
720
+        $frame->get_style()->height = $h;
721
+      }
722
+    }
723
+
724
+  }
725
+
726
+  //........................................................................
727
+
728
+  /**
729
+   * Re-adjust frame height if the table height is larger than its content
730
+   */
731
+  function set_frame_heights($table_height, $content_height) {
732
+
733
+
734
+    // Distribute the increased height proportionally amongst each row
735
+    foreach ( $this->_frames as $arr ) {
736
+      $frame = $arr["frame"];
737
+
738
+      $h = 0;
739
+      foreach ($arr["rows"] as $row ) {
740
+        if ( !isset($this->_rows[$row]) ) {
741
+          continue;
742
+        }
743
+
744
+        $h += $this->_rows[$row]["height"];
745
+      }
746
+      
747
+      if ( $content_height > 0 ) {
748
+        $new_height = ($h / $content_height) * $table_height;
749
+      }
750
+      else {
751
+        $new_height = 0;
752
+      }
753
+
754
+      if ( $frame instanceof Table_Cell_Frame_Decorator ) {
755
+        $frame->set_cell_height($new_height);
756
+      }
757
+      else {
758
+        $frame->get_style()->height = $new_height;
759
+      }
760
+    }
761
+
762
+  }
763
+
764
+  //........................................................................
765
+
766
+  // Used for debugging:
767
+  function __toString() {
768
+    $str = "";
769
+    $str .= "Columns:<br/>";
770
+    $str .= pre_r($this->_columns, true);
771
+    $str .=  "Rows:<br/>";
772
+    $str .= pre_r($this->_rows, true);
773
+
774
+    $str .=  "Frames:<br/>";
775
+    $arr = array();
776
+    foreach ( $this->_frames as $key => $val ) {
777
+      $arr[$key] = array("columns" => $val["columns"], "rows" => $val["rows"]);
778
+    }
779
+    
780
+    $str .= pre_r($arr, true);
781
+
782
+    if ( php_sapi_name() == "cli" ) {
783
+      $str = strip_tags(str_replace(array("<br/>","<b>","</b>"),
784
+                                    array("\n",chr(27)."[01;33m", chr(27)."[0m"),
785
+                                    $str));
786
+    }
787
+    
788
+    return $str;
789
+  }
790
+}

+ 877
- 0
vendor/dompdf/dompdf/include/cpdf_adapter.cls.php View File

@@ -0,0 +1,877 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Orion Richardson <orionr@yahoo.com>
7
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
8
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
9
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
+ */
11
+
12
+// FIXME: Need to sanity check inputs to this class
13
+require_once(DOMPDF_LIB_DIR . "/class.pdf.php");
14
+
15
+/**
16
+ * PDF rendering interface
17
+ *
18
+ * CPDF_Adapter provides a simple stateless interface to the stateful one
19
+ * provided by the Cpdf class.
20
+ *
21
+ * Unless otherwise mentioned, all dimensions are in points (1/72 in).  The
22
+ * coordinate origin is in the top left corner, and y values increase
23
+ * downwards.
24
+ *
25
+ * See {@link http://www.ros.co.nz/pdf/} for more complete documentation
26
+ * on the underlying {@link Cpdf} class.
27
+ *
28
+ * @package dompdf
29
+ */
30
+class CPDF_Adapter implements Canvas {
31
+
32
+  /**
33
+   * Dimensions of paper sizes in points
34
+   *
35
+   * @var array;
36
+   */
37
+  static $PAPER_SIZES = array(
38
+    "4a0" => array(0,0,4767.87,6740.79),
39
+    "2a0" => array(0,0,3370.39,4767.87),
40
+    "a0" => array(0,0,2383.94,3370.39),
41
+    "a1" => array(0,0,1683.78,2383.94),
42
+    "a2" => array(0,0,1190.55,1683.78),
43
+    "a3" => array(0,0,841.89,1190.55),
44
+    "a4" => array(0,0,595.28,841.89),
45
+    "a5" => array(0,0,419.53,595.28),
46
+    "a6" => array(0,0,297.64,419.53),
47
+    "a7" => array(0,0,209.76,297.64),
48
+    "a8" => array(0,0,147.40,209.76),
49
+    "a9" => array(0,0,104.88,147.40),
50
+    "a10" => array(0,0,73.70,104.88),
51
+    "b0" => array(0,0,2834.65,4008.19),
52
+    "b1" => array(0,0,2004.09,2834.65),
53
+    "b2" => array(0,0,1417.32,2004.09),
54
+    "b3" => array(0,0,1000.63,1417.32),
55
+    "b4" => array(0,0,708.66,1000.63),
56
+    "b5" => array(0,0,498.90,708.66),
57
+    "b6" => array(0,0,354.33,498.90),
58
+    "b7" => array(0,0,249.45,354.33),
59
+    "b8" => array(0,0,175.75,249.45),
60
+    "b9" => array(0,0,124.72,175.75),
61
+    "b10" => array(0,0,87.87,124.72),
62
+    "c0" => array(0,0,2599.37,3676.54),
63
+    "c1" => array(0,0,1836.85,2599.37),
64
+    "c2" => array(0,0,1298.27,1836.85),
65
+    "c3" => array(0,0,918.43,1298.27),
66
+    "c4" => array(0,0,649.13,918.43),
67
+    "c5" => array(0,0,459.21,649.13),
68
+    "c6" => array(0,0,323.15,459.21),
69
+    "c7" => array(0,0,229.61,323.15),
70
+    "c8" => array(0,0,161.57,229.61),
71
+    "c9" => array(0,0,113.39,161.57),
72
+    "c10" => array(0,0,79.37,113.39),
73
+    "ra0" => array(0,0,2437.80,3458.27),
74
+    "ra1" => array(0,0,1729.13,2437.80),
75
+    "ra2" => array(0,0,1218.90,1729.13),
76
+    "ra3" => array(0,0,864.57,1218.90),
77
+    "ra4" => array(0,0,609.45,864.57),
78
+    "sra0" => array(0,0,2551.18,3628.35),
79
+    "sra1" => array(0,0,1814.17,2551.18),
80
+    "sra2" => array(0,0,1275.59,1814.17),
81
+    "sra3" => array(0,0,907.09,1275.59),
82
+    "sra4" => array(0,0,637.80,907.09),
83
+    "letter" => array(0,0,612.00,792.00),
84
+    "legal" => array(0,0,612.00,1008.00),
85
+    "ledger" => array(0,0,1224.00, 792.00),
86
+    "tabloid" => array(0,0,792.00, 1224.00),
87
+    "executive" => array(0,0,521.86,756.00),
88
+    "folio" => array(0,0,612.00,936.00),
89
+    "commercial #10 envelope" => array(0,0,684,297),
90
+    "catalog #10 1/2 envelope" => array(0,0,648,864),
91
+    "8.5x11" => array(0,0,612.00,792.00),
92
+    "8.5x14" => array(0,0,612.00,1008.0),
93
+    "11x17"  => array(0,0,792.00, 1224.00),
94
+  );
95
+
96
+  /**
97
+   * The DOMPDF object
98
+   *
99
+   * @var DOMPDF
100
+   */
101
+  private $_dompdf;
102
+
103
+  /**
104
+   * Instance of Cpdf class
105
+   *
106
+   * @var Cpdf
107
+   */
108
+  private $_pdf;
109
+
110
+  /**
111
+   * PDF width, in points
112
+   *
113
+   * @var float
114
+   */
115
+  private $_width;
116
+
117
+  /**
118
+   * PDF height, in points
119
+   *
120
+   * @var float;
121
+   */
122
+  private $_height;
123
+
124
+  /**
125
+   * Current page number
126
+   *
127
+   * @var int
128
+   */
129
+  private $_page_number;
130
+
131
+  /**
132
+   * Total number of pages
133
+   *
134
+   * @var int
135
+   */
136
+  private $_page_count;
137
+
138
+  /**
139
+   * Text to display on every page
140
+   *
141
+   * @var array
142
+   */
143
+  private $_page_text;
144
+
145
+  /**
146
+   * Array of pages for accesing after rendering is initially complete
147
+   *
148
+   * @var array
149
+   */
150
+  private $_pages;
151
+
152
+  /**
153
+   * Array of temporary cached images to be deleted when processing is complete
154
+   *
155
+   * @var array
156
+   */
157
+  private $_image_cache;
158
+
159
+  /**
160
+   * Class constructor
161
+   *
162
+   * @param mixed  $paper       The size of paper to use in this PDF ({@link CPDF_Adapter::$PAPER_SIZES})
163
+   * @param string $orientation The orientation of the document (either 'landscape' or 'portrait')
164
+   * @param DOMPDF $dompdf      The DOMPDF instance
165
+   */
166
+  function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) {
167
+    if ( is_array($paper) ) {
168
+      $size = $paper;
169
+    }
170
+    else if ( isset(self::$PAPER_SIZES[mb_strtolower($paper)]) ) {
171
+      $size = self::$PAPER_SIZES[mb_strtolower($paper)];
172
+    }
173
+    else {
174
+      $size = self::$PAPER_SIZES["letter"];
175
+    }
176
+
177
+    if ( mb_strtolower($orientation) === "landscape" ) {
178
+      list($size[2], $size[3]) = array($size[3], $size[2]);
179
+    }
180
+
181
+    $this->_dompdf = $dompdf;
182
+    
183
+    $this->_pdf = new Cpdf(
184
+      $size,
185
+      $dompdf->get_option("enable_unicode"),
186
+      $dompdf->get_option("font_cache"),
187
+      $dompdf->get_option("temp_dir")
188
+    );
189
+
190
+    $this->_pdf->addInfo("Creator", "DOMPDF");
191
+    $time = substr_replace(date('YmdHisO'), '\'', -2, 0).'\'';
192
+    $this->_pdf->addInfo("CreationDate", "D:$time");
193
+    $this->_pdf->addInfo("ModDate", "D:$time");
194
+
195
+    $this->_width = $size[2] - $size[0];
196
+    $this->_height= $size[3] - $size[1];
197
+    
198
+    $this->_page_number = $this->_page_count = 1;
199
+    $this->_page_text = array();
200
+
201
+    $this->_pages = array($this->_pdf->getFirstPageId());
202
+
203
+    $this->_image_cache = array();
204
+  }
205
+
206
+  function get_dompdf(){
207
+    return $this->_dompdf;
208
+  }
209
+
210
+  /**
211
+   * Class destructor
212
+   *
213
+   * Deletes all temporary image files
214
+   */
215
+  function __destruct() {
216
+    foreach ($this->_image_cache as $img) {
217
+      // The file might be already deleted by 3rd party tmp cleaner,
218
+      // the file might not have been created at all
219
+      // (if image outputting commands failed)
220
+      // or because the destructor was called twice accidentally.
221
+      if (!file_exists($img)) {
222
+        continue;
223
+      }
224
+
225
+      if (DEBUGPNG) print '[__destruct unlink '.$img.']';
226
+      if (!DEBUGKEEPTEMP) unlink($img);
227
+    }
228
+  }
229
+  
230
+  /**
231
+   * Returns the Cpdf instance
232
+   *
233
+   * @return Cpdf
234
+   */
235
+  function get_cpdf() {
236
+    return $this->_pdf;
237
+  }
238
+
239
+  /**
240
+   * Add meta information to the PDF
241
+   *
242
+   * @param string $label  label of the value (Creator, Producer, etc.)
243
+   * @param string $value  the text to set
244
+   */
245
+  function add_info($label, $value) {
246
+    $this->_pdf->addInfo($label, $value);
247
+  }
248
+
249
+  /**
250
+   * Opens a new 'object'
251
+   *
252
+   * While an object is open, all drawing actions are recored in the object,
253
+   * as opposed to being drawn on the current page.  Objects can be added
254
+   * later to a specific page or to several pages.
255
+   *
256
+   * The return value is an integer ID for the new object.
257
+   *
258
+   * @see CPDF_Adapter::close_object()
259
+   * @see CPDF_Adapter::add_object()
260
+   *
261
+   * @return int
262
+   */
263
+  function open_object() {
264
+    $ret = $this->_pdf->openObject();
265
+    $this->_pdf->saveState();
266
+    return $ret;
267
+  }
268
+
269
+  /**
270
+   * Reopens an existing 'object'
271
+   *
272
+   * @see CPDF_Adapter::open_object()
273
+   * @param int $object  the ID of a previously opened object
274
+   */
275
+  function reopen_object($object) {
276
+    $this->_pdf->reopenObject($object);
277
+    $this->_pdf->saveState();
278
+  }
279
+
280
+  /**
281
+   * Closes the current 'object'
282
+   *
283
+   * @see CPDF_Adapter::open_object()
284
+   */
285
+  function close_object() {
286
+    $this->_pdf->restoreState();
287
+    $this->_pdf->closeObject();
288
+  }
289
+
290
+  /**
291
+   * Adds a specified 'object' to the document
292
+   *
293
+   * $object int specifying an object created with {@link
294
+   * CPDF_Adapter::open_object()}.  $where can be one of:
295
+   * - 'add' add to current page only
296
+   * - 'all' add to every page from the current one onwards
297
+   * - 'odd' add to all odd numbered pages from now on
298
+   * - 'even' add to all even numbered pages from now on
299
+   * - 'next' add the object to the next page only
300
+   * - 'nextodd' add to all odd numbered pages from the next one
301
+   * - 'nexteven' add to all even numbered pages from the next one
302
+   *
303
+   * @see Cpdf::addObject()
304
+   *
305
+   * @param int $object
306
+   * @param string $where
307
+   */
308
+  function add_object($object, $where = 'all') {
309
+    $this->_pdf->addObject($object, $where);
310
+  }
311
+
312
+  /**
313
+   * Stops the specified 'object' from appearing in the document.
314
+   *
315
+   * The object will stop being displayed on the page following the current
316
+   * one.
317
+   *
318
+   * @param int $object
319
+   */
320
+  function stop_object($object) {
321
+    $this->_pdf->stopObject($object);
322
+  }
323
+
324
+  /**
325
+   * @access private
326
+   */
327
+  function serialize_object($id) {
328
+    // Serialize the pdf object's current state for retrieval later
329
+    return $this->_pdf->serializeObject($id);
330
+  }
331
+
332
+  /**
333
+   * @access private
334
+   */
335
+  function reopen_serialized_object($obj) {
336
+    return $this->_pdf->restoreSerializedObject($obj);
337
+  }
338
+    
339
+  //........................................................................
340
+
341
+  /**
342
+   * Returns the PDF's width in points
343
+   * @return float
344
+   */
345
+  function get_width() { return $this->_width; }
346
+
347
+  /**
348
+   * Returns the PDF's height in points
349
+   * @return float
350
+   */
351
+  function get_height() { return $this->_height; }
352
+
353
+  /**
354
+   * Returns the current page number
355
+   * @return int
356
+   */
357
+  function get_page_number() { return $this->_page_number; }
358
+
359
+  /**
360
+   * Returns the total number of pages in the document
361
+   * @return int
362
+   */
363
+  function get_page_count() { return $this->_page_count; }
364
+
365
+  /**
366
+   * Sets the current page number
367
+   *
368
+   * @param int $num
369
+   */
370
+  function set_page_number($num) { $this->_page_number = $num; }
371
+
372
+  /**
373
+   * Sets the page count
374
+   *
375
+   * @param int $count
376
+   */
377
+  function set_page_count($count) {  $this->_page_count = $count; }
378
+    
379
+  /**
380
+   * Sets the stroke color
381
+   *
382
+   * See {@link Style::set_color()} for the format of the color array.
383
+   * @param array $color
384
+   */
385
+  protected function _set_stroke_color($color) {
386
+    $this->_pdf->setStrokeColor($color);
387
+  }
388
+  
389
+  /**
390
+   * Sets the fill colour
391
+   *
392
+   * See {@link Style::set_color()} for the format of the colour array.
393
+   * @param array $color
394
+   */
395
+  protected function _set_fill_color($color) {
396
+    $this->_pdf->setColor($color);
397
+  }
398
+
399
+  /**
400
+   * Sets line transparency
401
+   * @see Cpdf::setLineTransparency()
402
+   *
403
+   * Valid blend modes are (case-sensitive):
404
+   *
405
+   * Normal, Multiply, Screen, Overlay, Darken, Lighten,
406
+   * ColorDodge, ColorBurn, HardLight, SoftLight, Difference,
407
+   * Exclusion
408
+   *
409
+   * @param string $mode the blending mode to use
410
+   * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
411
+   */
412
+  protected function _set_line_transparency($mode, $opacity) {
413
+    $this->_pdf->setLineTransparency($mode, $opacity);
414
+  }
415
+  
416
+  /**
417
+   * Sets fill transparency
418
+   * @see Cpdf::setFillTransparency()
419
+   *
420
+   * Valid blend modes are (case-sensitive):
421
+   *
422
+   * Normal, Multiply, Screen, Overlay, Darken, Lighten,
423
+   * ColorDogde, ColorBurn, HardLight, SoftLight, Difference,
424
+   * Exclusion
425
+   *
426
+   * @param string $mode the blending mode to use
427
+   * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
428
+   */
429
+  protected function _set_fill_transparency($mode, $opacity) {
430
+    $this->_pdf->setFillTransparency($mode, $opacity);
431
+  }
432
+
433
+  /**
434
+   * Sets the line style
435
+   *
436
+   * @see Cpdf::setLineStyle()
437
+   *
438
+   * @param float  $width
439
+   * @param string $cap
440
+   * @param string $join
441
+   * @param array  $dash
442
+   */
443
+  protected function _set_line_style($width, $cap, $join, $dash) {
444
+    $this->_pdf->setLineStyle($width, $cap, $join, $dash);
445
+  }
446
+  
447
+  /**
448
+   * Sets the opacity 
449
+   * 
450
+   * @param $opacity
451
+   * @param $mode
452
+   */
453
+  function set_opacity($opacity, $mode = "Normal") {
454
+    $this->_set_line_transparency($mode, $opacity);
455
+    $this->_set_fill_transparency($mode, $opacity);
456
+  }
457
+  
458
+  function set_default_view($view, $options = array()) {
459
+    array_unshift($options, $view);
460
+    call_user_func_array(array($this->_pdf, "openHere"), $options);
461
+  }
462
+
463
+  /**
464
+   * Remaps y coords from 4th to 1st quadrant
465
+   *
466
+   * @param float $y
467
+   * @return float
468
+   */
469
+  protected function y($y) {
470
+    return $this->_height - $y;
471
+  }
472
+
473
+  // Canvas implementation
474
+  function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) {
475
+    $this->_set_stroke_color($color);
476
+    $this->_set_line_style($width, "butt", "", $style);
477
+    
478
+    $this->_pdf->line($x1, $this->y($y1),
479
+                      $x2, $this->y($y2));
480
+  }
481
+  
482
+  function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array()) {
483
+    $this->_set_stroke_color($color);
484
+    $this->_set_line_style($width, "butt", "", $style);
485
+    
486
+    $this->_pdf->ellipse($x, $this->y($y), $r1, $r2, 0, 8, $astart, $aend, false, false, true, false);
487
+  }
488
+                              
489
+  //........................................................................
490
+
491
+  /**
492
+   * Convert a GIF or BMP image to a PNG image
493
+   *
494
+   * @param string  $image_url
495
+   * @param integer $type
496
+   *
497
+   * @throws DOMPDF_Exception
498
+   * @return string The url of the newly converted image
499
+   */
500
+  protected function _convert_gif_bmp_to_png($image_url, $type) {
501
+    $image_type = Image_Cache::type_to_ext($type);
502
+    $func_name = "imagecreatefrom$image_type";
503
+    
504
+    if ( !function_exists($func_name) ) {
505
+      throw new DOMPDF_Exception("Function $func_name() not found.  Cannot convert $image_type image: $image_url.  Please install the image PHP extension.");
506
+    }
507
+
508
+    set_error_handler("record_warnings");
509
+    $im = $func_name($image_url);
510
+
511
+    if ( $im ) {
512
+      imageinterlace($im, false);
513
+
514
+      $tmp_dir = $this->_dompdf->get_option("temp_dir");
515
+      $tmp_name = tempnam($tmp_dir, "{$image_type}dompdf_img_");
516
+      @unlink($tmp_name);
517
+      $filename = "$tmp_name.png";
518
+      $this->_image_cache[] = $filename;
519
+
520
+      imagepng($im, $filename);
521
+      imagedestroy($im);
522
+    } 
523
+    else {
524
+      $filename = Image_Cache::$broken_image;
525
+    }
526
+
527
+    restore_error_handler();
528
+    
529
+    return $filename;
530
+  }
531
+
532
+  function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) {
533
+    $this->_set_stroke_color($color);
534
+    $this->_set_line_style($width, "butt", "", $style);
535
+    $this->_pdf->rectangle($x1, $this->y($y1) - $h, $w, $h);
536
+  }
537
+  
538
+  function filled_rectangle($x1, $y1, $w, $h, $color) {
539
+    $this->_set_fill_color($color);
540
+    $this->_pdf->filledRectangle($x1, $this->y($y1) - $h, $w, $h);
541
+  }
542
+  
543
+  function clipping_rectangle($x1, $y1, $w, $h) {
544
+    $this->_pdf->clippingRectangle($x1, $this->y($y1) - $h, $w, $h);
545
+  }
546
+  
547
+  function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) {
548
+    $this->_pdf->clippingRectangleRounded($x1, $this->y($y1) - $h, $w, $h, $rTL, $rTR, $rBR, $rBL);
549
+  }
550
+  
551
+  function clipping_end() {
552
+    $this->_pdf->clippingEnd();
553
+  }
554
+  
555
+  function save() {
556
+    $this->_pdf->saveState();
557
+  }
558
+  
559
+  function restore() {
560
+    $this->_pdf->restoreState();
561
+  }
562
+  
563
+  function rotate($angle, $x, $y) {
564
+    $this->_pdf->rotate($angle, $x, $y);
565
+  }
566
+  
567
+  function skew($angle_x, $angle_y, $x, $y) {
568
+    $this->_pdf->skew($angle_x, $angle_y, $x, $y);
569
+  }
570
+  
571
+  function scale($s_x, $s_y, $x, $y) {
572
+    $this->_pdf->scale($s_x, $s_y, $x, $y);
573
+  }
574
+  
575
+  function translate($t_x, $t_y) {
576
+    $this->_pdf->translate($t_x, $t_y);
577
+  }
578
+  
579
+  function transform($a, $b, $c, $d, $e, $f) {
580
+    $this->_pdf->transform(array($a, $b, $c, $d, $e, $f));
581
+  }
582
+
583
+  function polygon($points, $color, $width = null, $style = array(), $fill = false) {
584
+    $this->_set_fill_color($color);
585
+    $this->_set_stroke_color($color);
586
+    
587
+    // Adjust y values
588
+    for ( $i = 1; $i < count($points); $i += 2) {
589
+      $points[$i] = $this->y($points[$i]);
590
+    }
591
+    
592
+    $this->_pdf->polygon($points, count($points) / 2, $fill);
593
+  }
594
+
595
+  function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) {
596
+    $this->_set_fill_color($color);
597
+    $this->_set_stroke_color($color);
598
+
599
+    if ( !$fill && isset($width) ) {
600
+      $this->_set_line_style($width, "round", "round", $style);
601
+    }
602
+
603
+    $this->_pdf->ellipse($x, $this->y($y), $r1, 0, 0, 8, 0, 360, 1, $fill);
604
+  }
605
+
606
+  function image($img, $x, $y, $w, $h, $resolution = "normal") {
607
+    list($width, $height, $type) = dompdf_getimagesize($img, $this->_dompdf->get_http_context());
608
+    
609
+    $debug_png = $this->_dompdf->get_option("debug_png");
610
+
611
+    if ($debug_png) print "[image:$img|$width|$height|$type]";
612
+
613
+    switch ($type) {
614
+    case IMAGETYPE_JPEG:
615
+      if ($debug_png) print '!!!jpg!!!';
616
+      $this->_pdf->addJpegFromFile($img, $x, $this->y($y) - $h, $w, $h);
617
+      break;
618
+      
619
+    case IMAGETYPE_GIF:
620
+    case IMAGETYPE_BMP:
621
+      if ($debug_png) print '!!!bmp or gif!!!';
622
+      // @todo use cache for BMP and GIF
623
+      $img = $this->_convert_gif_bmp_to_png($img, $type);
624
+
625
+    case IMAGETYPE_PNG:
626
+      if ($debug_png) print '!!!png!!!';
627
+
628
+      $this->_pdf->addPngFromFile($img, $x, $this->y($y) - $h, $w, $h);
629
+      break;
630
+
631
+    default:
632
+      if ($debug_png) print '!!!unknown!!!';
633
+    }
634
+  }
635
+
636
+  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
637
+    $pdf = $this->_pdf;
638
+    
639
+    $pdf->setColor($color);
640
+    
641
+    $font .= ".afm";
642
+    $pdf->selectFont($font);
643
+    
644
+    //Font_Metrics::get_font_height($font, $size) ==
645
+    //$this->get_font_height($font, $size) ==
646
+    //$this->_pdf->selectFont($font),$this->_pdf->getFontHeight($size)
647
+    //- FontBBoxheight+FontHeightOffset, scaled to $size, in pt
648
+    //$this->_pdf->getFontDescender($size)
649
+    //- Descender scaled to size
650
+    //
651
+    //$this->_pdf->fonts[$this->_pdf->currentFont] sizes:
652
+    //['FontBBox'][0] left, ['FontBBox'][1] bottom, ['FontBBox'][2] right, ['FontBBox'][3] top
653
+    //Maximum extent of all glyphs of the font from the baseline point
654
+    //['Ascender'] maximum height above baseline except accents
655
+    //['Descender'] maximum depth below baseline, negative number means below baseline
656
+    //['FontHeightOffset'] manual enhancement of .afm files to trim windows fonts. currently not used.
657
+    //Values are in 1/1000 pt for a font size of 1 pt
658
+    //
659
+    //['FontBBox'][1] should be close to ['Descender']
660
+    //['FontBBox'][3] should be close to ['Ascender']+Accents
661
+    //in practice, FontBBox values are a little bigger
662
+    //
663
+    //The text position is referenced to the baseline, not to the lower corner of the FontBBox,
664
+    //for what the left,top corner is given.
665
+    //FontBBox spans also the background box for the text.
666
+    //If the lower corner would be used as reference point, the Descents of the glyphs would
667
+    //hang over the background box border.
668
+    //Therefore compensate only the extent above the Baseline.
669
+    //
670
+    //print '<pre>['.$font.','.$size.','.$pdf->getFontHeight($size).','.$pdf->getFontDescender($size).','.$pdf->fonts[$pdf->currentFont]['FontBBox'][3].','.$pdf->fonts[$pdf->currentFont]['FontBBox'][1].','.$pdf->fonts[$pdf->currentFont]['FontHeightOffset'].','.$pdf->fonts[$pdf->currentFont]['Ascender'].','.$pdf->fonts[$pdf->currentFont]['Descender'].']</pre>';
671
+    //
672
+    //$pdf->addText($x, $this->y($y) - ($pdf->fonts[$pdf->currentFont]['FontBBox'][3]*$size)/1000, $size, $text, $angle, $word_space, $char_space);
673
+    $pdf->addText($x, $this->y($y) - $pdf->getFontHeight($size), $size, $text, $angle, $word_space, $char_space);
674
+  }
675
+
676
+  //........................................................................
677
+
678
+  function javascript($code) {
679
+    $this->_pdf->addJavascript($code);
680
+  }
681
+
682
+  //........................................................................
683
+
684
+  /**
685
+   * Add a named destination (similar to <a name="foo">...</a> in html)
686
+   *
687
+   * @param string $anchorname The name of the named destination
688
+   */
689
+  function add_named_dest($anchorname) {
690
+    $this->_pdf->addDestination($anchorname, "Fit");
691
+  }
692
+
693
+  //........................................................................
694
+
695
+  /**
696
+   * Add a link to the pdf
697
+   *
698
+   * @param string $url The url to link to
699
+   * @param float  $x   The x position of the link
700
+   * @param float  $y   The y position of the link
701
+   * @param float  $width   The width of the link
702
+   * @param float  $height   The height of the link
703
+   */
704
+  function add_link($url, $x, $y, $width, $height) {
705
+
706
+    $y = $this->y($y) - $height;
707
+
708
+    if ( strpos($url, '#') === 0 ) {
709
+      // Local link
710
+      $name = substr($url,1);
711
+      if ( $name ) {
712
+        $this->_pdf->addInternalLink($name, $x, $y, $x + $width, $y + $height);
713
+      }
714
+      
715
+    }
716
+    else {
717
+      $this->_pdf->addLink(rawurldecode($url), $x, $y, $x + $width, $y + $height);
718
+    }
719
+  }
720
+
721
+  function get_text_width($text, $font, $size, $word_spacing = 0, $char_spacing = 0) {
722
+    $this->_pdf->selectFont($font);
723
+
724
+    $unicode = $this->_dompdf->get_option("enable_unicode");
725
+    if (!$unicode) {
726
+      $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8');
727
+    }
728
+
729
+    return $this->_pdf->getTextWidth($size, $text, $word_spacing, $char_spacing);
730
+  }
731
+  
732
+  function register_string_subset($font, $string) {
733
+    $this->_pdf->registerText($font, $string);
734
+  }
735
+
736
+  function get_font_height($font, $size) {
737
+    $this->_pdf->selectFont($font);
738
+
739
+    $ratio = $this->_dompdf->get_option("font_height_ratio");
740
+    return $this->_pdf->getFontHeight($size) * $ratio;
741
+  }
742
+  
743
+  /*function get_font_x_height($font, $size) {
744
+    $this->_pdf->selectFont($font);
745
+    $ratio = $this->_dompdf->get_option("font_height_ratio");
746
+    return $this->_pdf->getFontXHeight($size) * $ratio;
747
+  }*/
748
+  
749
+  function get_font_baseline($font, $size) {
750
+    $ratio = $this->_dompdf->get_option("font_height_ratio");
751
+    return $this->get_font_height($font, $size) / $ratio;
752
+  }
753
+  
754
+  /**
755
+   * Writes text at the specified x and y coordinates on every page
756
+   *
757
+   * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
758
+   * with their current values.
759
+   *
760
+   * See {@link Style::munge_color()} for the format of the colour array.
761
+   *
762
+   * @param float $x
763
+   * @param float $y
764
+   * @param string $text the text to write
765
+   * @param string $font the font file to use
766
+   * @param float $size the font size, in points
767
+   * @param array $color
768
+   * @param float $word_space word spacing adjustment
769
+   * @param float $char_space char spacing adjustment
770
+   * @param float $angle angle to write the text at, measured CW starting from the x-axis
771
+   */
772
+  function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
773
+    $_t = "text";
774
+    $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle");
775
+  }
776
+    
777
+  /**
778
+   * Processes a script on every page
779
+   *
780
+   * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available.
781
+   *
782
+   * This function can be used to add page numbers to all pages
783
+   * after the first one, for example.
784
+   *
785
+   * @param string $code the script code
786
+   * @param string $type the language type for script
787
+   */
788
+  function page_script($code, $type = "text/php") {
789
+    $_t = "script";
790
+    $this->_page_text[] = compact("_t", "code", "type");
791
+  }
792
+
793
+  function new_page() {
794
+    $this->_page_number++;
795
+    $this->_page_count++;
796
+
797
+    $ret = $this->_pdf->newPage();
798
+    $this->_pages[] = $ret;
799
+    return $ret;
800
+  }
801
+
802
+  /**
803
+   * Add text to each page after rendering is complete
804
+   */
805
+  protected function _add_page_text() {
806
+    
807
+    if ( !count($this->_page_text) ) {
808
+      return;
809
+    }
810
+
811
+    $page_number = 1;
812
+    $eval = null;
813
+
814
+    foreach ($this->_pages as $pid) {
815
+      $this->reopen_object($pid);
816
+
817
+      foreach ($this->_page_text as $pt) {
818
+        extract($pt);
819
+
820
+        switch ($_t) {
821
+          case "text":
822
+            $text = str_replace(array("{PAGE_NUM}","{PAGE_COUNT}"),
823
+                                array($page_number, $this->_page_count), $text);
824
+            $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
825
+            break;
826
+            
827
+          case "script":
828
+            if ( !$eval ) {
829
+              $eval = new PHP_Evaluator($this);
830
+            }
831
+            $eval->evaluate($code, array('PAGE_NUM' => $page_number, 'PAGE_COUNT' => $this->_page_count));
832
+            break;
833
+        }
834
+      }
835
+
836
+      $this->close_object();
837
+      $page_number++;
838
+    }
839
+  }
840
+  
841
+  /**
842
+   * Streams the PDF directly to the browser
843
+   *
844
+   * @param string $filename the name of the PDF file
845
+   * @param array  $options associative array, 'Attachment' => 0 or 1, 'compress' => 1 or 0
846
+   */
847
+  function stream($filename, $options = null) {
848
+    // Add page text
849
+    $this->_add_page_text();
850
+    
851
+    $options["Content-Disposition"] = $filename;
852
+    $this->_pdf->stream($options);
853
+  }
854
+
855
+  /**
856
+   * Returns the PDF as a string
857
+   * 
858
+   * @param array $options Output options
859
+   * @return string
860
+   */
861
+  function output($options = null) {
862
+    $this->_add_page_text();
863
+
864
+    $debug = isset($options["compress"]) && $options["compress"] != 1;
865
+    
866
+    return $this->_pdf->output($debug);
867
+  }
868
+
869
+  /**
870
+   * Returns logging messages generated by the Cpdf class
871
+   *
872
+   * @return string
873
+   */
874
+  function get_messages() {
875
+    return $this->_pdf->messages;
876
+  }
877
+}

+ 287
- 0
vendor/dompdf/dompdf/include/css_color.cls.php View File

@@ -0,0 +1,287 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+class CSS_Color {
11
+  static $cssColorNames = array(
12
+    "aliceblue" => "F0F8FF",
13
+    "antiquewhite" => "FAEBD7",
14
+    "aqua" => "00FFFF",
15
+    "aquamarine" => "7FFFD4",
16
+    "azure" => "F0FFFF",
17
+    "beige" => "F5F5DC",
18
+    "bisque" => "FFE4C4",
19
+    "black" => "000000",
20
+    "blanchedalmond" => "FFEBCD",
21
+    "blue" => "0000FF",
22
+    "blueviolet" => "8A2BE2",
23
+    "brown" => "A52A2A",
24
+    "burlywood" => "DEB887",
25
+    "cadetblue" => "5F9EA0",
26
+    "chartreuse" => "7FFF00",
27
+    "chocolate" => "D2691E",
28
+    "coral" => "FF7F50",
29
+    "cornflowerblue" => "6495ED",
30
+    "cornsilk" => "FFF8DC",
31
+    "crimson" => "DC143C",
32
+    "cyan" => "00FFFF",
33
+    "darkblue" => "00008B",
34
+    "darkcyan" => "008B8B",
35
+    "darkgoldenrod" => "B8860B",
36
+    "darkgray" => "A9A9A9",
37
+    "darkgreen" => "006400",
38
+    "darkgrey" => "A9A9A9",
39
+    "darkkhaki" => "BDB76B",
40
+    "darkmagenta" => "8B008B",
41
+    "darkolivegreen" => "556B2F",
42
+    "darkorange" => "FF8C00",
43
+    "darkorchid" => "9932CC",
44
+    "darkred" => "8B0000",
45
+    "darksalmon" => "E9967A",
46
+    "darkseagreen" => "8FBC8F",
47
+    "darkslateblue" => "483D8B",
48
+    "darkslategray" => "2F4F4F",
49
+    "darkslategrey" => "2F4F4F",
50
+    "darkturquoise" => "00CED1",
51
+    "darkviolet" => "9400D3",
52
+    "deeppink" => "FF1493",
53
+    "deepskyblue" => "00BFFF",
54
+    "dimgray" => "696969",
55
+    "dimgrey" => "696969",
56
+    "dodgerblue" => "1E90FF",
57
+    "firebrick" => "B22222",
58
+    "floralwhite" => "FFFAF0",
59
+    "forestgreen" => "228B22",
60
+    "fuchsia" => "FF00FF",
61
+    "gainsboro" => "DCDCDC",
62
+    "ghostwhite" => "F8F8FF",
63
+    "gold" => "FFD700",
64
+    "goldenrod" => "DAA520",
65
+    "gray" => "808080",
66
+    "green" => "008000",
67
+    "greenyellow" => "ADFF2F",
68
+    "grey" => "808080",
69
+    "honeydew" => "F0FFF0",
70
+    "hotpink" => "FF69B4",
71
+    "indianred" => "CD5C5C",
72
+    "indigo" => "4B0082",
73
+    "ivory" => "FFFFF0",
74
+    "khaki" => "F0E68C",
75
+    "lavender" => "E6E6FA",
76
+    "lavenderblush" => "FFF0F5",
77
+    "lawngreen" => "7CFC00",
78
+    "lemonchiffon" => "FFFACD",
79
+    "lightblue" => "ADD8E6",
80
+    "lightcoral" => "F08080",
81
+    "lightcyan" => "E0FFFF",
82
+    "lightgoldenrodyellow" => "FAFAD2",
83
+    "lightgray" => "D3D3D3",
84
+    "lightgreen" => "90EE90",
85
+    "lightgrey" => "D3D3D3",
86
+    "lightpink" => "FFB6C1",
87
+    "lightsalmon" => "FFA07A",
88
+    "lightseagreen" => "20B2AA",
89
+    "lightskyblue" => "87CEFA",
90
+    "lightslategray" => "778899",
91
+    "lightslategrey" => "778899",
92
+    "lightsteelblue" => "B0C4DE",
93
+    "lightyellow" => "FFFFE0",
94
+    "lime" => "00FF00",
95
+    "limegreen" => "32CD32",
96
+    "linen" => "FAF0E6",
97
+    "magenta" => "FF00FF",
98
+    "maroon" => "800000",
99
+    "mediumaquamarine" => "66CDAA",
100
+    "mediumblue" => "0000CD",
101
+    "mediumorchid" => "BA55D3",
102
+    "mediumpurple" => "9370DB",
103
+    "mediumseagreen" => "3CB371",
104
+    "mediumslateblue" => "7B68EE",
105
+    "mediumspringgreen" => "00FA9A",
106
+    "mediumturquoise" => "48D1CC",
107
+    "mediumvioletred" => "C71585",
108
+    "midnightblue" => "191970",
109
+    "mintcream" => "F5FFFA",
110
+    "mistyrose" => "FFE4E1",
111
+    "moccasin" => "FFE4B5",
112
+    "navajowhite" => "FFDEAD",
113
+    "navy" => "000080",
114
+    "oldlace" => "FDF5E6",
115
+    "olive" => "808000",
116
+    "olivedrab" => "6B8E23",
117
+    "orange" => "FFA500",
118
+    "orangered" => "FF4500",
119
+    "orchid" => "DA70D6",
120
+    "palegoldenrod" => "EEE8AA",
121
+    "palegreen" => "98FB98",
122
+    "paleturquoise" => "AFEEEE",
123
+    "palevioletred" => "DB7093",
124
+    "papayawhip" => "FFEFD5",
125
+    "peachpuff" => "FFDAB9",
126
+    "peru" => "CD853F",
127
+    "pink" => "FFC0CB",
128
+    "plum" => "DDA0DD",
129
+    "powderblue" => "B0E0E6",
130
+    "purple" => "800080",
131
+    "red" => "FF0000",
132
+    "rosybrown" => "BC8F8F",
133
+    "royalblue" => "4169E1",
134
+    "saddlebrown" => "8B4513",
135
+    "salmon" => "FA8072",
136
+    "sandybrown" => "F4A460",
137
+    "seagreen" => "2E8B57",
138
+    "seashell" => "FFF5EE",
139
+    "sienna" => "A0522D",
140
+    "silver" => "C0C0C0",
141
+    "skyblue" => "87CEEB",
142
+    "slateblue" => "6A5ACD",
143
+    "slategray" => "708090",
144
+    "slategrey" => "708090",
145
+    "snow" => "FFFAFA",
146
+    "springgreen" => "00FF7F",
147
+    "steelblue" => "4682B4",
148
+    "tan" => "D2B48C",
149
+    "teal" => "008080",
150
+    "thistle" => "D8BFD8",
151
+    "tomato" => "FF6347",
152
+    "turquoise" => "40E0D0",
153
+    "violet" => "EE82EE",
154
+    "wheat" => "F5DEB3",
155
+    "white" => "FFFFFF",
156
+    "whitesmoke" => "F5F5F5",
157
+    "yellow" => "FFFF00",
158
+    "yellowgreen" => "9ACD32",
159
+  );
160
+
161
+  static function parse($color) {
162
+    if ( is_array($color) ) {
163
+      // Assume the array has the right format...
164
+      // FIXME: should/could verify this.
165
+      return $color;
166
+    }
167
+    
168
+    static $cache = array();
169
+    
170
+    $color = strtolower($color);
171
+    
172
+    if ( isset($cache[$color]) ) {
173
+      return $cache[$color];
174
+    }
175
+      
176
+    if ( in_array($color, array("transparent", "inherit")) ) {
177
+      return $cache[$color] = $color;
178
+    }
179
+    
180
+    if ( isset(self::$cssColorNames[$color]) ) {
181
+      return $cache[$color] = self::getArray(self::$cssColorNames[$color]);
182
+    }
183
+    
184
+    $length = mb_strlen($color);
185
+    
186
+    // #rgb format
187
+    if ( $length == 4 && $color[0] === "#" ) {
188
+      return $cache[$color] = self::getArray($color[1].$color[1].$color[2].$color[2].$color[3].$color[3]);
189
+    }
190
+
191
+    // #rrggbb format
192
+    else if ( $length == 7 && $color[0] === "#" ) {
193
+      return $cache[$color] = self::getArray(mb_substr($color, 1, 6));
194
+    }
195
+    
196
+    // rgb( r,g,b ) / rgbaa( r,g,b,α ) format
197
+    else if ( mb_strpos($color, "rgb") !== false ) {
198
+      $i = mb_strpos($color, "(");
199
+      $j = mb_strpos($color, ")");
200
+      
201
+      // Bad color value
202
+      if ( $i === false || $j === false ) {
203
+        return null;
204
+      }
205
+      
206
+      $triplet = explode(",", mb_substr($color, $i+1, $j-$i-1));
207
+      
208
+      // alpha transparency
209
+      // FIXME: not currently using transparency
210
+      $alpha = 1;
211
+      if ( count( $triplet ) == 4 ) {
212
+        $alpha = (float) ( trim( array_pop( $triplet ) ) );
213
+        // bad value, set to fully opaque
214
+        if ( $alpha > 1 || $alpha < 0 ) {
215
+          $alpha = 1;
216
+        }
217
+      }
218
+      
219
+      if ( count($triplet) != 3 ) {
220
+        return null;
221
+      }
222
+      
223
+      foreach (array_keys($triplet) as $c) {
224
+        $triplet[$c] = trim($triplet[$c]);
225
+        
226
+        if ( $triplet[$c][mb_strlen($triplet[$c]) - 1] === "%" ) {
227
+          $triplet[$c] = round($triplet[$c] * 2.55);
228
+        }
229
+      }
230
+      
231
+      return $cache[$color] = self::getArray(vsprintf("%02X%02X%02X", $triplet));
232
+    
233
+    }
234
+    
235
+    // cmyk( c,m,y,k ) format
236
+    // http://www.w3.org/TR/css3-gcpm/#cmyk-colors
237
+    else if ( mb_strpos($color, "cmyk") !== false ) {
238
+      $i = mb_strpos($color, "(");
239
+      $j = mb_strpos($color, ")");
240
+      
241
+      // Bad color value
242
+      if ( $i === false || $j === false ) {
243
+        return null;
244
+      }
245
+
246
+      $values = explode(",", mb_substr($color, $i+1, $j-$i-1));
247
+
248
+      if ( count($values) != 4 ) {
249
+        return null;
250
+      }
251
+      
252
+      foreach ($values as &$c) {
253
+        $c = floatval(trim($c));
254
+        if ($c > 1.0) $c = 1.0;
255
+        if ($c < 0.0) $c = 0.0;
256
+      }
257
+      
258
+      return $cache[$color] = self::getArray($values);
259
+    }
260
+
261
+    return null;
262
+  }
263
+  
264
+  static function getArray($color) {
265
+    $c = array(null, null, null, null, "hex" => null);
266
+    
267
+    if (is_array($color)) {
268
+      $c = $color;
269
+      $c["c"] = $c[0];
270
+      $c["m"] = $c[1];
271
+      $c["y"] = $c[2];
272
+      $c["k"] = $c[3];
273
+      $c["hex"] = "cmyk($c[0],$c[1],$c[2],$c[3])";
274
+    }
275
+    else {
276
+      $c[0] = hexdec(mb_substr($color, 0, 2)) / 0xff;
277
+      $c[1] = hexdec(mb_substr($color, 2, 2)) / 0xff;
278
+      $c[2] = hexdec(mb_substr($color, 4, 2)) / 0xff;
279
+      $c["r"] = $c[0];
280
+      $c["g"] = $c[1];
281
+      $c["b"] = $c[2];
282
+      $c["hex"] = "#$color";
283
+    }
284
+    
285
+    return $c;
286
+  }
287
+}

+ 1101
- 0
vendor/dompdf/dompdf/include/dompdf.cls.php
File diff suppressed because it is too large
View File


+ 26
- 0
vendor/dompdf/dompdf/include/dompdf_exception.cls.php View File

@@ -0,0 +1,26 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Standard exception thrown by DOMPDF classes
11
+ *
12
+ * @package dompdf
13
+ */
14
+class DOMPDF_Exception extends Exception {
15
+
16
+  /**
17
+   * Class constructor
18
+   *
19
+   * @param string $message Error message
20
+   * @param int $code Error code
21
+   */
22
+  function __construct($message = null, $code = 0) {
23
+    parent::__construct($message, $code);
24
+  }
25
+
26
+}

+ 26
- 0
vendor/dompdf/dompdf/include/dompdf_image_exception.cls.php View File

@@ -0,0 +1,26 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Image exception thrown by DOMPDF
11
+ *
12
+ * @package dompdf
13
+ */
14
+class DOMPDF_Image_Exception extends DOMPDF_Exception {
15
+
16
+  /**
17
+   * Class constructor
18
+   *
19
+   * @param string $message Error message
20
+   * @param int $code Error code
21
+   */
22
+  function __construct($message = null, $code = 0) {
23
+    parent::__construct($message, $code);
24
+  }
25
+
26
+}

+ 8
- 0
vendor/dompdf/dompdf/include/file.skel View File

@@ -0,0 +1,8 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  ...
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */

+ 88
- 0
vendor/dompdf/dompdf/include/fixed_positioner.cls.php View File

@@ -0,0 +1,88 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Positions fixely positioned frames
12
+ */
13
+class Fixed_Positioner extends Positioner {
14
+
15
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
16
+
17
+  function position() {
18
+
19
+    $frame = $this->_frame;
20
+    $style = $frame->get_original_style();
21
+    $root = $frame->get_root();
22
+    $initialcb = $root->get_containing_block();
23
+    $initialcb_style = $root->get_style();
24
+
25
+    $p = $frame->find_block_parent();
26
+    if ( $p ) {
27
+      $p->add_line();
28
+    }
29
+
30
+    // Compute the margins of the @page style
31
+    $margin_top    = $initialcb_style->length_in_pt($initialcb_style->margin_top,    $initialcb["h"]);
32
+    $margin_right  = $initialcb_style->length_in_pt($initialcb_style->margin_right,  $initialcb["w"]);
33
+    $margin_bottom = $initialcb_style->length_in_pt($initialcb_style->margin_bottom, $initialcb["h"]);
34
+    $margin_left   = $initialcb_style->length_in_pt($initialcb_style->margin_left,   $initialcb["w"]);
35
+    
36
+    // The needed computed style of the element
37
+    $height = $style->length_in_pt($style->height, $initialcb["h"]);
38
+    $width  = $style->length_in_pt($style->width,  $initialcb["w"]);
39
+    
40
+    $top    = $style->length_in_pt($style->top,    $initialcb["h"]);
41
+    $right  = $style->length_in_pt($style->right,  $initialcb["w"]);
42
+    $bottom = $style->length_in_pt($style->bottom, $initialcb["h"]);
43
+    $left   = $style->length_in_pt($style->left,   $initialcb["w"]);
44
+
45
+    $y = $margin_top;
46
+    if ( isset($top) ) {
47
+      $y = $top + $margin_top;
48
+      if ( $top === "auto" ) {
49
+        $y = $margin_top;
50
+        if ( isset($bottom) && $bottom !== "auto" ) {
51
+          $y = $initialcb["h"] - $bottom - $margin_bottom;
52
+          $margin_height = $this->_frame->get_margin_height();
53
+          if ( $margin_height !== "auto" ) {
54
+            $y -= $margin_height;
55
+          }
56
+          else {
57
+            $y -= $height;
58
+          }
59
+        }
60
+      }
61
+    }
62
+
63
+    $x = $margin_left;
64
+    if ( isset($left) ) {
65
+      $x = $left + $margin_left;
66
+      if ( $left === "auto" ) {
67
+        $x = $margin_left;
68
+        if ( isset($right) && $right !== "auto" ) {
69
+          $x = $initialcb["w"] - $right - $margin_right;
70
+          $margin_width = $this->_frame->get_margin_width();
71
+          if ( $margin_width !== "auto" ) {
72
+            $x -= $margin_width;
73
+          }
74
+          else {
75
+            $x -= $width;
76
+          }
77
+        }
78
+      }
79
+    }
80
+    
81
+    $frame->set_position($x, $y);
82
+
83
+    $children = $frame->get_children();
84
+    foreach($children as $child) {
85
+      $child->set_position($x, $y);
86
+    }
87
+  }
88
+}

+ 382
- 0
vendor/dompdf/dompdf/include/font_metrics.cls.php View File

@@ -0,0 +1,382 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
8
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
+ */
10
+
11
+require_once DOMPDF_LIB_DIR . "/class.pdf.php";
12
+
13
+/**
14
+ * Name of the font cache file
15
+ *
16
+ * This file must be writable by the webserver process only to update it
17
+ * with save_font_families() after adding the .afm file references of a new font family
18
+ * with Font_Metrics::save_font_families().
19
+ * This is typically done only from command line with load_font.php on converting
20
+ * ttf fonts to ufm with php-font-lib.
21
+ *
22
+ * Declared here because PHP5 prevents constants from being declared with expressions
23
+ */
24
+define('__DOMPDF_FONT_CACHE_FILE', DOMPDF_FONT_DIR . "dompdf_font_family_cache.php");
25
+
26
+/**
27
+ * The font metrics class
28
+ *
29
+ * This class provides information about fonts and text.  It can resolve
30
+ * font names into actual installed font files, as well as determine the
31
+ * size of text in a particular font and size.
32
+ *
33
+ * @static
34
+ * @package dompdf
35
+ */
36
+class Font_Metrics {
37
+
38
+  /**
39
+   * @see __DOMPDF_FONT_CACHE_FILE
40
+   */
41
+  const CACHE_FILE = __DOMPDF_FONT_CACHE_FILE;
42
+  
43
+  /**
44
+   * Underlying {@link Canvas} object to perform text size calculations
45
+   *
46
+   * @var Canvas
47
+   */
48
+  static protected $_pdf = null;
49
+
50
+  /**
51
+   * Array of font family names to font files
52
+   *
53
+   * Usually cached by the {@link load_font.php} script
54
+   *
55
+   * @var array
56
+   */
57
+  static protected $_font_lookup = array();
58
+  
59
+  
60
+  /**
61
+   * Class initialization
62
+   *
63
+   */
64
+  static function init(Canvas $canvas = null) {
65
+    if (!self::$_pdf) {
66
+      if (!$canvas) {
67
+        $canvas = Canvas_Factory::get_instance(new DOMPDF());
68
+      }
69
+      
70
+      self::$_pdf = $canvas;
71
+    }
72
+  }
73
+
74
+  /**
75
+   * Calculates text size, in points
76
+   *
77
+   * @param string $text the text to be sized
78
+   * @param string $font the desired font
79
+   * @param float  $size the desired font size
80
+   * @param float  $word_spacing
81
+   * @param float  $char_spacing
82
+   *
83
+   * @internal param float $spacing word spacing, if any
84
+   * @return float
85
+   */
86
+  static function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) {
87
+    //return self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing);
88
+    
89
+    // @todo Make sure this cache is efficient before enabling it
90
+    static $cache = array();
91
+    
92
+    if ( $text === "" ) {
93
+      return 0;
94
+    }
95
+    
96
+    // Don't cache long strings
97
+    $use_cache = !isset($text[50]); // Faster than strlen
98
+    
99
+    $key = "$font/$size/$word_spacing/$char_spacing";
100
+    
101
+    if ( $use_cache && isset($cache[$key][$text]) ) {
102
+      return $cache[$key]["$text"];
103
+    }
104
+    
105
+    $width = self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing);
106
+    
107
+    if ( $use_cache ) {
108
+      $cache[$key][$text] = $width;
109
+    }
110
+    
111
+    return $width;
112
+  }
113
+
114
+  /**
115
+   * Calculates font height
116
+   *
117
+   * @param string $font
118
+   * @param float $size
119
+   * @return float
120
+   */
121
+  static function get_font_height($font, $size) {
122
+    return self::$_pdf->get_font_height($font, $size);
123
+  }
124
+
125
+  /**
126
+   * Resolves a font family & subtype into an actual font file
127
+   * Subtype can be one of 'normal', 'bold', 'italic' or 'bold_italic'.  If
128
+   * the particular font family has no suitable font file, the default font
129
+   * ({@link DOMPDF_DEFAULT_FONT}) is used.  The font file returned
130
+   * is the absolute pathname to the font file on the system.
131
+   *
132
+   * @param string $family_raw
133
+   * @param string $subtype_raw
134
+   *
135
+   * @return string
136
+   */
137
+  static function get_font($family_raw, $subtype_raw = "normal") {
138
+    static $cache = array();
139
+    
140
+    if ( isset($cache[$family_raw][$subtype_raw]) ) {
141
+      return $cache[$family_raw][$subtype_raw];
142
+    }
143
+    
144
+    /* Allow calling for various fonts in search path. Therefore not immediately
145
+     * return replacement on non match.
146
+     * Only when called with NULL try replacement.
147
+     * When this is also missing there is really trouble.
148
+     * If only the subtype fails, nevertheless return failure.
149
+     * Only on checking the fallback font, check various subtypes on same font.
150
+     */
151
+    
152
+    $subtype = strtolower($subtype_raw);
153
+    
154
+    if ( $family_raw ) {
155
+      $family = str_replace( array("'", '"'), "", strtolower($family_raw));
156
+      
157
+      if ( isset(self::$_font_lookup[$family][$subtype]) ) {
158
+        return $cache[$family_raw][$subtype_raw] = self::$_font_lookup[$family][$subtype];
159
+      }
160
+      
161
+      return null;
162
+    }
163
+
164
+    $family = "serif";
165
+
166
+    if ( isset(self::$_font_lookup[$family][$subtype]) ) {
167
+      return $cache[$family_raw][$subtype_raw] = self::$_font_lookup[$family][$subtype];
168
+    }
169
+    
170
+    if ( !isset(self::$_font_lookup[$family]) ) {
171
+      return null;
172
+    }
173
+    
174
+    $family = self::$_font_lookup[$family];
175
+
176
+    foreach ( $family as $sub => $font ) {
177
+      if (strpos($subtype, $sub) !== false) {
178
+        return $cache[$family_raw][$subtype_raw] = $font;
179
+      }
180
+    }
181
+
182
+    if ($subtype !== "normal") {
183
+      foreach ( $family as $sub => $font ) {
184
+        if ($sub !== "normal") {
185
+          return $cache[$family_raw][$subtype_raw] = $font;
186
+        }
187
+      }
188
+    }
189
+
190
+    $subtype = "normal";
191
+
192
+    if ( isset($family[$subtype]) ) {
193
+      return $cache[$family_raw][$subtype_raw] = $family[$subtype];
194
+    }
195
+    
196
+    return null;
197
+  }
198
+  
199
+  static function get_family($family) {
200
+    $family = str_replace( array("'", '"'), "", mb_strtolower($family));
201
+    
202
+    if ( isset(self::$_font_lookup[$family]) ) {
203
+      return self::$_font_lookup[$family];
204
+    }
205
+    
206
+    return null;
207
+  }
208
+
209
+  /**
210
+   * Saves the stored font family cache
211
+   *
212
+   * The name and location of the cache file are determined by {@link
213
+   * Font_Metrics::CACHE_FILE}.  This file should be writable by the
214
+   * webserver process.
215
+   *
216
+   * @see Font_Metrics::load_font_families()
217
+   */
218
+  static function save_font_families() {
219
+    // replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability)
220
+    $cache_data = sprintf("<?php return array (%s", PHP_EOL);
221
+    foreach (self::$_font_lookup as $family => $variants) {
222
+      $cache_data .= sprintf("  '%s' => array(%s", addslashes($family), PHP_EOL);
223
+      foreach ($variants as $variant => $path) {
224
+        $path = sprintf("'%s'", $path);
225
+        $path = str_replace('\'' . DOMPDF_FONT_DIR , 'DOMPDF_FONT_DIR . \'' , $path);
226
+        $path = str_replace('\'' . DOMPDF_DIR , 'DOMPDF_DIR . \'' , $path);
227
+        $cache_data .= sprintf("    '%s' => %s,%s", $variant, $path, PHP_EOL);
228
+      }
229
+      $cache_data .= sprintf("  ),%s", PHP_EOL);
230
+    }
231
+    $cache_data .= ") ?>";
232
+    file_put_contents(self::CACHE_FILE, $cache_data);
233
+  }
234
+
235
+  /**
236
+   * Loads the stored font family cache
237
+   *
238
+   * @see save_font_families()
239
+   */
240
+  static function load_font_families() {
241
+    $dist_fonts = require_once DOMPDF_DIR . "/lib/fonts/dompdf_font_family_cache.dist.php";
242
+    
243
+    // FIXME: temporary step for font cache created before the font cache fix
244
+    if ( is_readable( DOMPDF_FONT_DIR . "dompdf_font_family_cache" ) ) {
245
+      $old_fonts = require_once DOMPDF_FONT_DIR . "dompdf_font_family_cache";
246
+      // If the font family cache is still in the old format
247
+      if ( $old_fonts === 1 ) {
248
+        $cache_data = file_get_contents(DOMPDF_FONT_DIR . "dompdf_font_family_cache");
249
+        file_put_contents(DOMPDF_FONT_DIR . "dompdf_font_family_cache", "<"."?php return $cache_data ?".">");
250
+        $old_fonts = require_once DOMPDF_FONT_DIR . "dompdf_font_family_cache";
251
+      }
252
+      $dist_fonts += $old_fonts;
253
+    }
254
+    
255
+    if ( !is_readable(self::CACHE_FILE) ) {
256
+      self::$_font_lookup = $dist_fonts;
257
+      return;
258
+    }
259
+    
260
+    $cache_data = require_once self::CACHE_FILE;
261
+    
262
+    // If the font family cache is still in the old format
263
+    if ( self::$_font_lookup === 1 ) {
264
+      $cache_data = file_get_contents(self::CACHE_FILE);
265
+      file_put_contents(self::CACHE_FILE, "<"."?php return $cache_data ?".">");
266
+      $cache_data = require_once self::CACHE_FILE;
267
+    }
268
+    
269
+    self::$_font_lookup = array();
270
+    foreach ($cache_data as $key => $value) {
271
+      self::$_font_lookup[stripslashes($key)] = $value;
272
+    }
273
+    
274
+    // Merge provided fonts
275
+    self::$_font_lookup += $dist_fonts;
276
+  }
277
+  
278
+  static function get_type($type) {
279
+    if (preg_match("/bold/i", $type)) {
280
+      if (preg_match("/italic|oblique/i", $type)) {
281
+        $type = "bold_italic";
282
+      }
283
+      else {
284
+        $type = "bold";
285
+      }
286
+    }
287
+    elseif (preg_match("/italic|oblique/i", $type)) {
288
+      $type = "italic";
289
+    }
290
+    else {
291
+      $type = "normal";
292
+    }
293
+      
294
+    return $type;
295
+  }
296
+  
297
+  static function install_fonts($files) {
298
+    $names = array();
299
+    
300
+    foreach($files as $file) {
301
+      $font = Font::load($file);
302
+      $records = $font->getData("name", "records");
303
+      $type = self::get_type($records[2]);
304
+      $names[mb_strtolower($records[1])][$type] = $file;
305
+    }
306
+    
307
+    return $names;
308
+  }
309
+  
310
+  static function get_system_fonts() {
311
+    $files = glob("/usr/share/fonts/truetype/*.ttf") +
312
+             glob("/usr/share/fonts/truetype/*/*.ttf") +
313
+             glob("/usr/share/fonts/truetype/*/*/*.ttf") +
314
+             glob("C:\\Windows\\fonts\\*.ttf") + 
315
+             glob("C:\\WinNT\\fonts\\*.ttf") + 
316
+             glob("/mnt/c_drive/WINDOWS/Fonts/");
317
+    
318
+    return self::install_fonts($files);
319
+  }
320
+
321
+  /**
322
+   * Returns the current font lookup table
323
+   *
324
+   * @return array
325
+   */
326
+  static function get_font_families() {
327
+    return self::$_font_lookup;
328
+  }
329
+
330
+  static function set_font_family($fontname, $entry) {
331
+    self::$_font_lookup[mb_strtolower($fontname)] = $entry;
332
+  }
333
+  
334
+  static function register_font($style, $remote_file, $context = null) {
335
+    $fontname = mb_strtolower($style["family"]);
336
+    $families = Font_Metrics::get_font_families();
337
+    
338
+    $entry = array();
339
+    if ( isset($families[$fontname]) ) {
340
+      $entry = $families[$fontname];
341
+    }
342
+    
343
+    $local_file = DOMPDF_FONT_DIR . md5($remote_file);
344
+    $local_temp_file = DOMPDF_TEMP_DIR . "/" . md5($remote_file);
345
+    $cache_entry = $local_file;
346
+    $local_file .= ".ttf";
347
+    
348
+    $style_string = Font_Metrics::get_type("{$style['weight']} {$style['style']}");
349
+    
350
+    if ( !isset($entry[$style_string]) ) {
351
+      $entry[$style_string] = $cache_entry;
352
+      
353
+      // Download the remote file
354
+      file_put_contents($local_temp_file, file_get_contents($remote_file, null, $context));
355
+      
356
+      $font = Font::load($local_temp_file);
357
+      
358
+      if (!$font) {
359
+        unlink($local_temp_file);
360
+        return false;
361
+      }
362
+      
363
+      $font->parse();
364
+      $font->saveAdobeFontMetrics("$cache_entry.ufm");
365
+      
366
+      unlink($local_temp_file);
367
+      
368
+      if ( !file_exists("$cache_entry.ufm") ) {
369
+        return false;
370
+      }
371
+      
372
+      // Save the changes
373
+      file_put_contents($local_file, file_get_contents($remote_file, null, $context));
374
+      Font_Metrics::set_font_family($fontname, $entry);
375
+      Font_Metrics::save_font_families();
376
+    }
377
+    
378
+    return true;
379
+  }
380
+}
381
+
382
+Font_Metrics::load_font_families();

+ 1191
- 0
vendor/dompdf/dompdf/include/frame.cls.php
File diff suppressed because it is too large
View File


+ 717
- 0
vendor/dompdf/dompdf/include/frame_decorator.cls.php View File

@@ -0,0 +1,717 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Base Frame_Decorator class
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+abstract class Frame_Decorator extends Frame {
16
+  const DEFAULT_COUNTER = "-dompdf-default-counter";
17
+  
18
+  public $_counters = array(); // array([id] => counter_value) (for generated content)
19
+  
20
+  /**
21
+   * The root node of the DOM tree
22
+   *
23
+   * @var Frame
24
+   */
25
+  protected $_root;
26
+
27
+  /**
28
+   * The decorated frame
29
+   *
30
+   * @var Frame
31
+   */
32
+  protected $_frame;
33
+
34
+  /**
35
+   * Positioner object used to position this frame (Strategy pattern)
36
+   *
37
+   * @var Positioner
38
+   */
39
+  protected $_positioner;
40
+
41
+  /**
42
+   * Reflower object used to calculate frame dimensions (Strategy pattern)
43
+   *
44
+   * @var Frame_Reflower
45
+   */
46
+  protected $_reflower;
47
+  
48
+  /**
49
+   * Reference to the current dompdf instance
50
+   *
51
+   * @var DOMPDF
52
+   */
53
+  protected $_dompdf;
54
+  
55
+  /**
56
+   * First block parent
57
+   * 
58
+   * @var Block_Frame_Decorator
59
+   */
60
+  private $_block_parent;
61
+  
62
+  /**
63
+   * First positionned parent (position: relative | absolute | fixed)
64
+   * 
65
+   * @var Frame_Decorator
66
+   */
67
+  private $_positionned_parent;
68
+
69
+  /**
70
+   * Class constructor
71
+   *
72
+   * @param Frame  $frame  The decoration target
73
+   * @param DOMPDF $dompdf The DOMPDF object
74
+   */
75
+  function __construct(Frame $frame, DOMPDF $dompdf) {
76
+    $this->_frame = $frame;
77
+    $this->_root = null;
78
+    $this->_dompdf = $dompdf;
79
+    $frame->set_decorator($this);
80
+  }
81
+
82
+  /**
83
+   * "Destructor": foribly free all references held by this object
84
+   *
85
+   * @param bool $recursive if true, call dispose on all children
86
+   */
87
+  function dispose($recursive = false) {
88
+    if ( $recursive ) {
89
+      while ( $child = $this->get_first_child() ) {
90
+        $child->dispose(true);
91
+      }
92
+    }
93
+    
94
+    $this->_root = null;
95
+    unset($this->_root);
96
+    
97
+    $this->_frame->dispose(true);
98
+    $this->_frame = null;
99
+    unset($this->_frame);
100
+    
101
+    $this->_positioner = null;
102
+    unset($this->_positioner);
103
+    
104
+    $this->_reflower = null;
105
+    unset($this->_reflower);
106
+  }
107
+
108
+  /**
109
+   * Return a copy of this frame with $node as its node
110
+   * 
111
+   * @param DOMNode $node
112
+   *
113
+   * @return Frame
114
+   */ 
115
+  function copy(DOMNode $node) {
116
+    $frame = new Frame($node);
117
+    $frame->set_style(clone $this->_frame->get_original_style());
118
+    
119
+    return Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
120
+  }
121
+
122
+  /**
123
+   * Create a deep copy: copy this node and all children
124
+   *
125
+   * @return Frame
126
+   */
127
+  function deep_copy() {
128
+    $frame = new Frame($this->get_node()->cloneNode());
129
+    $frame->set_style(clone $this->_frame->get_original_style());
130
+    
131
+    $deco = Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
132
+    
133
+    foreach ($this->get_children() as $child) {
134
+      $deco->append_child($child->deep_copy());
135
+    }
136
+    
137
+    return $deco;
138
+  }
139
+  
140
+  /**
141
+   * Delegate calls to decorated frame object
142
+   */
143
+  function reset() {
144
+    $this->_frame->reset();
145
+    
146
+    $this->_counters = array();
147
+    
148
+    // Reset all children
149
+    foreach ($this->get_children() as $child) {
150
+      $child->reset();
151
+    }
152
+  }
153
+  
154
+  // Getters -----------
155
+  function get_id() {
156
+    return $this->_frame->get_id();
157
+  }
158
+  
159
+  /**
160
+   * @return Frame
161
+   */
162
+  function get_frame() {
163
+    return $this->_frame;
164
+  }
165
+  
166
+  /**
167
+   * @return DOMElement|DOMText
168
+   */
169
+  function get_node() {
170
+    return $this->_frame->get_node();
171
+  }
172
+  
173
+  /**
174
+   * @return Style
175
+   */
176
+  function get_style() {
177
+    return $this->_frame->get_style();
178
+  }
179
+  
180
+  /**
181
+   * @return Style
182
+   */
183
+  function get_original_style() {
184
+    return $this->_frame->get_original_style();
185
+  }
186
+
187
+  /**
188
+   * @param integer $i
189
+   *
190
+   * @return array|float
191
+   */
192
+  function get_containing_block($i = null) {
193
+    return $this->_frame->get_containing_block($i);
194
+  }
195
+
196
+  /**
197
+   * @param integer $i
198
+   *
199
+   * @return array|float
200
+   */
201
+  function get_position($i = null) {
202
+    return $this->_frame->get_position($i);
203
+  }
204
+  
205
+  /**
206
+   * @return DOMPDF
207
+   */
208
+  function get_dompdf() {
209
+    return $this->_dompdf;
210
+  }
211
+
212
+  /**
213
+   * @return float
214
+   */
215
+  function get_margin_height() {
216
+    return $this->_frame->get_margin_height();
217
+  }
218
+
219
+  /**
220
+   * @return float
221
+   */
222
+  function get_margin_width() {
223
+    return $this->_frame->get_margin_width();
224
+  }
225
+
226
+  /**
227
+   * @return array
228
+   */
229
+  function get_padding_box() {
230
+    return $this->_frame->get_padding_box();
231
+  }
232
+
233
+  /**
234
+   * @return array
235
+   */
236
+  function get_border_box() {
237
+    return $this->_frame->get_border_box();
238
+  }
239
+
240
+  /**
241
+   * @param integer $id
242
+   */
243
+  function set_id($id) {
244
+    $this->_frame->set_id($id);
245
+  }
246
+
247
+  /**
248
+   * @param Style $style
249
+   */
250
+  function set_style(Style $style) {
251
+    $this->_frame->set_style($style);
252
+  }
253
+
254
+  /**
255
+   * @param float $x
256
+   * @param float $y
257
+   * @param float $w
258
+   * @param float $h
259
+   */
260
+  function set_containing_block($x = null, $y = null, $w = null, $h = null) {
261
+    $this->_frame->set_containing_block($x, $y, $w, $h);
262
+  }
263
+
264
+  /**
265
+   * @param float $x
266
+   * @param float $y
267
+   */
268
+  function set_position($x = null, $y = null) {
269
+    $this->_frame->set_position($x, $y);
270
+  }
271
+
272
+  /**
273
+   * @return string
274
+   */
275
+  function __toString() {
276
+    return $this->_frame->__toString();
277
+  }
278
+
279
+  /**
280
+   * @param Frame $child
281
+   * @param bool  $update_node
282
+   */
283
+  function prepend_child(Frame $child, $update_node = true) {
284
+    while ( $child instanceof Frame_Decorator ) {
285
+      $child = $child->_frame;
286
+    }
287
+    
288
+    $this->_frame->prepend_child($child, $update_node);
289
+  }
290
+
291
+  /**
292
+   * @param Frame $child
293
+   * @param bool  $update_node
294
+   */
295
+  function append_child(Frame $child, $update_node = true) {
296
+    while ( $child instanceof Frame_Decorator ) {
297
+      $child = $child->_frame;
298
+    }
299
+
300
+    $this->_frame->append_child($child, $update_node);
301
+  }
302
+
303
+  /**
304
+   * @param Frame $new_child
305
+   * @param Frame $ref
306
+   * @param bool  $update_node
307
+   */
308
+  function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) {
309
+    while ( $new_child instanceof Frame_Decorator ) {
310
+      $new_child = $new_child->_frame;
311
+    }
312
+
313
+    if ( $ref instanceof Frame_Decorator ) {
314
+      $ref = $ref->_frame;
315
+    }
316
+
317
+    $this->_frame->insert_child_before($new_child, $ref, $update_node);
318
+  }
319
+
320
+  /**
321
+   * @param Frame $new_child
322
+   * @param Frame $ref
323
+   * @param bool  $update_node
324
+   */
325
+  function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) {
326
+    while ( $new_child instanceof Frame_Decorator ) {
327
+      $new_child = $new_child->_frame;
328
+    }
329
+
330
+    while ( $ref instanceof Frame_Decorator ) {
331
+      $ref = $ref->_frame;
332
+    }
333
+    
334
+    $this->_frame->insert_child_after($new_child, $ref, $update_node);
335
+  }
336
+
337
+  /**
338
+   * @param Frame $child
339
+   * @param bool  $update_node
340
+   *
341
+   * @return Frame
342
+   */
343
+  function remove_child(Frame $child, $update_node = true) {
344
+    while  ( $child instanceof Frame_Decorator ) {
345
+      $child = $child->_frame;
346
+    }
347
+
348
+    return $this->_frame->remove_child($child, $update_node);
349
+  }
350
+
351
+  /**
352
+   * @return Frame_Decorator
353
+   */
354
+  function get_parent() {
355
+    $p = $this->_frame->get_parent();
356
+    if ( $p && $deco = $p->get_decorator() ) {
357
+      while ( $tmp = $deco->get_decorator() ) {
358
+        $deco = $tmp;
359
+      }
360
+      
361
+      return $deco;
362
+    }
363
+    else if ( $p ) {
364
+      return $p;
365
+    }
366
+    
367
+    return null;
368
+  }
369
+
370
+  /**
371
+   * @return Frame_Decorator
372
+   */
373
+  function get_first_child() {
374
+    $c = $this->_frame->get_first_child();
375
+    if ( $c && $deco = $c->get_decorator() ) {
376
+      while ( $tmp = $deco->get_decorator() ) {
377
+        $deco = $tmp;
378
+      }
379
+      
380
+      return $deco;
381
+    }
382
+    else if ( $c ) {
383
+      return $c;
384
+    }
385
+    
386
+    return null;
387
+  }
388
+
389
+  /**
390
+   * @return Frame_Decorator
391
+   */
392
+  function get_last_child() {
393
+    $c = $this->_frame->get_last_child();
394
+    if ( $c && $deco = $c->get_decorator() ) {
395
+      while ( $tmp = $deco->get_decorator() ) {
396
+        $deco = $tmp;
397
+      }
398
+      
399
+      return $deco;
400
+    }
401
+    else if ( $c ) {
402
+      return $c;
403
+    }
404
+    
405
+    return null;
406
+  }
407
+
408
+  /**
409
+   * @return Frame_Decorator
410
+   */
411
+  function get_prev_sibling() {
412
+    $s = $this->_frame->get_prev_sibling();
413
+    if ( $s && $deco = $s->get_decorator() ) {
414
+      while ( $tmp = $deco->get_decorator() ) {
415
+        $deco = $tmp;
416
+      }
417
+      return $deco;
418
+    }
419
+    else if ( $s ) {
420
+      return $s;
421
+    }
422
+    
423
+    return null;
424
+  }
425
+  
426
+  /**
427
+   * @return Frame_Decorator
428
+   */
429
+  function get_next_sibling() {
430
+    $s = $this->_frame->get_next_sibling();
431
+    if ( $s && $deco = $s->get_decorator() ) {
432
+      while ( $tmp = $deco->get_decorator() ) {
433
+        $deco = $tmp;
434
+      }
435
+      
436
+      return $deco;
437
+    }
438
+    else if ( $s ) {
439
+      return $s;
440
+    }
441
+    
442
+    return null;
443
+  }
444
+
445
+  /**
446
+   * @return FrameTreeList
447
+   */
448
+  function get_subtree() {
449
+    return new FrameTreeList($this);
450
+  }
451
+
452
+  function set_positioner(Positioner $posn) {
453
+    $this->_positioner = $posn;
454
+    if ( $this->_frame instanceof Frame_Decorator ) {
455
+      $this->_frame->set_positioner($posn);
456
+    }
457
+  }
458
+
459
+  function set_reflower(Frame_Reflower $reflower) {
460
+    $this->_reflower = $reflower;
461
+    if ( $this->_frame instanceof Frame_Decorator ) {
462
+      $this->_frame->set_reflower( $reflower );
463
+    }
464
+  }
465
+  
466
+  /**
467
+   * @return Frame_Reflower
468
+   */
469
+  function get_reflower() {
470
+    return $this->_reflower;
471
+  }
472
+
473
+  /**
474
+   * @param Frame $root
475
+   */
476
+  function set_root(Frame $root) {
477
+    $this->_root = $root;
478
+    
479
+    if ( $this->_frame instanceof Frame_Decorator ) {
480
+      $this->_frame->set_root($root);
481
+    }
482
+  }
483
+  
484
+  /**
485
+   * @return Page_Frame_Decorator
486
+   */
487
+  function get_root() {
488
+    return $this->_root;
489
+  }
490
+
491
+  /**
492
+   * @return Block_Frame_Decorator
493
+   */
494
+  function find_block_parent() {
495
+    // Find our nearest block level parent
496
+    $p = $this->get_parent();
497
+    
498
+    while ( $p ) {
499
+      if ( $p->is_block() ) {
500
+        break;
501
+      }
502
+      
503
+      $p = $p->get_parent();
504
+    }
505
+
506
+    return $this->_block_parent = $p;
507
+  }
508
+  
509
+  /**
510
+   * @return Frame_Decorator
511
+   */
512
+  function find_positionned_parent() {
513
+    // Find our nearest relative positionned parent
514
+    $p = $this->get_parent();
515
+    while ( $p ) {
516
+      if ( $p->is_positionned() ) {
517
+        break;
518
+      }
519
+      
520
+      $p = $p->get_parent();
521
+    }
522
+    
523
+    if ( !$p ) {
524
+      $p = $this->_root->get_first_child(); // <body>
525
+    }
526
+
527
+    return $this->_positionned_parent = $p;
528
+  }
529
+
530
+  /**
531
+   * split this frame at $child.
532
+   * The current frame is cloned and $child and all children following
533
+   * $child are added to the clone.  The clone is then passed to the
534
+   * current frame's parent->split() method.
535
+   *
536
+   * @param Frame   $child
537
+   * @param boolean $force_pagebreak
538
+   *
539
+   * @throws DOMPDF_Exception
540
+   * @return void
541
+   */
542
+  function split(Frame $child = null, $force_pagebreak = false) {
543
+    // decrement any counters that were incremented on the current node, unless that node is the body
544
+    $style = $this->_frame->get_style();
545
+    if ( $this->_frame->get_node()->nodeName !== "body" && $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) {
546
+      $this->decrement_counters($decrement);
547
+    }
548
+    
549
+    if ( is_null( $child ) ) {
550
+      // check for counter increment on :before content (always a child of the selected element @link Frame_Reflower::_set_content)
551
+      // this can push the current node to the next page before counter rules have bubbled up (but only if
552
+      // it's been rendered, thus the position check)
553
+      if ( !$this->is_text_node() && $this->get_node()->hasAttribute("dompdf_before_frame_id") ) {
554
+        foreach($this->_frame->get_children() as $child) {
555
+          if ( $this->get_node()->getAttribute("dompdf_before_frame_id") == $child->get_id() && $child->get_position('x') !== NULL ) {
556
+            $style = $child->get_style();
557
+            if ( $style->counter_increment && ($decrement = $style->counter_increment) !== "none" ) {
558
+              $this->decrement_counters($decrement);
559
+            }
560
+          }
561
+        }
562
+      }
563
+      $this->get_parent()->split($this, $force_pagebreak);
564
+      return;
565
+    }
566
+    
567
+    if ( $child->get_parent() !== $this ) {
568
+      throw new DOMPDF_Exception("Unable to split: frame is not a child of this one.");
569
+    }
570
+    
571
+    $node = $this->_frame->get_node();
572
+    
573
+    $split = $this->copy( $node->cloneNode() );
574
+    $split->reset();
575
+    $split->get_original_style()->text_indent = 0;
576
+    $split->_splitted = true;
577
+    
578
+    // The body's properties must be kept
579
+    if ( $node->nodeName !== "body" ) {
580
+      // Style reset on the first and second parts
581
+      $style = $this->_frame->get_style();
582
+      $style->margin_bottom = 0;
583
+      $style->padding_bottom = 0;
584
+      $style->border_bottom = 0;
585
+      
586
+      // second
587
+      $orig_style = $split->get_original_style();
588
+      $orig_style->text_indent = 0;
589
+      $orig_style->margin_top = 0;
590
+      $orig_style->padding_top = 0;
591
+      $orig_style->border_top = 0;
592
+    }
593
+    
594
+    $this->get_parent()->insert_child_after($split, $this);
595
+    
596
+    // Add $frame and all following siblings to the new split node
597
+    $iter = $child;
598
+    while ($iter) {
599
+      $frame = $iter;
600
+      $iter = $iter->get_next_sibling();
601
+      $frame->reset();
602
+      $split->append_child($frame);
603
+    }
604
+    
605
+    $this->get_parent()->split($split, $force_pagebreak);
606
+    
607
+    // If this node resets a counter save the current value to use when rendering on the next page
608
+    if ( $style->counter_reset && ( $reset = $style->counter_reset ) !== "none" ) {
609
+      $vars = preg_split( '/\s+/' , trim( $reset ) , 2 );
610
+      $split->_counters[ '__' . $vars[0] ] = $this->lookup_counter_frame( $vars[0] )->_counters[$vars[0]];
611
+    }
612
+  }
613
+
614
+  function reset_counter($id = self::DEFAULT_COUNTER, $value = 0) {
615
+    $this->get_parent()->_counters[$id] = intval($value);
616
+  }
617
+  
618
+  function decrement_counters($counters) {
619
+    foreach($counters as $id => $increment) {
620
+      $this->increment_counter($id, intval($increment) * -1);
621
+    }
622
+  }
623
+  
624
+  function increment_counters($counters) {
625
+    foreach($counters as $id => $increment) {
626
+      $this->increment_counter($id, intval($increment));
627
+    }
628
+  }
629
+
630
+  function increment_counter($id = self::DEFAULT_COUNTER, $increment = 1) {
631
+    $counter_frame = $this->lookup_counter_frame($id);
632
+
633
+    if ( $counter_frame ) {
634
+      if ( !isset($counter_frame->_counters[$id]) ) {
635
+        $counter_frame->_counters[$id] = 0;
636
+      }
637
+      
638
+      $counter_frame->_counters[$id] += $increment;
639
+    }
640
+  }
641
+  
642
+  function lookup_counter_frame($id = self::DEFAULT_COUNTER) {
643
+    $f = $this->get_parent();
644
+    
645
+    while( $f ) {
646
+      if( isset($f->_counters[$id]) ) {
647
+        return $f;
648
+      }
649
+      $fp = $f->get_parent();
650
+      
651
+      if ( !$fp ) {
652
+        return $f;
653
+      }
654
+      
655
+      $f = $fp;
656
+    }
657
+  }
658
+
659
+  // TODO: What version is the best : this one or the one in List_Bullet_Renderer ?
660
+  function counter_value($id = self::DEFAULT_COUNTER, $type = "decimal") {
661
+    $type = mb_strtolower($type);
662
+    
663
+    if ( !isset($this->_counters[$id]) ) {
664
+      $this->_counters[$id] = 0;
665
+    }
666
+
667
+    $value = $this->_counters[$id];
668
+    
669
+    switch ($type) {
670
+      default:
671
+      case "decimal":
672
+        return $value;
673
+  
674
+      case "decimal-leading-zero":
675
+        return str_pad($value, 2, "0");
676
+  
677
+      case "lower-roman":
678
+        return dec2roman($value);
679
+  
680
+      case "upper-roman":
681
+        return mb_strtoupper(dec2roman($value));
682
+  
683
+      case "lower-latin":
684
+      case "lower-alpha":
685
+        return chr( ($value % 26) + ord('a') - 1);
686
+  
687
+      case "upper-latin":
688
+      case "upper-alpha":
689
+        return chr( ($value % 26) + ord('A') - 1);
690
+  
691
+      case "lower-greek":
692
+        return unichr($value + 944);
693
+  
694
+      case "upper-greek":
695
+        return unichr($value + 912);
696
+    }
697
+  }
698
+
699
+  final function position() {
700
+    $this->_positioner->position();
701
+  }
702
+  
703
+  final function move($offset_x, $offset_y, $ignore_self = false) {
704
+    $this->_positioner->move($offset_x, $offset_y, $ignore_self); 
705
+  }
706
+  
707
+  final function reflow(Block_Frame_Decorator $block = null) {
708
+    // Uncomment this to see the frames before they're laid out, instead of
709
+    // during rendering.
710
+    //echo $this->_frame; flush();
711
+    $this->_reflower->reflow($block);
712
+  }
713
+
714
+  final function get_min_max_width() {
715
+    return $this->_reflower->get_min_max_width();
716
+  }
717
+}

+ 252
- 0
vendor/dompdf/dompdf/include/frame_factory.cls.php View File

@@ -0,0 +1,252 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Contains frame decorating logic
11
+ *
12
+ * This class is responsible for assigning the correct {@link Frame_Decorator},
13
+ * {@link Positioner}, and {@link Frame_Reflower} objects to {@link Frame}
14
+ * objects.  This is determined primarily by the Frame's display type, but
15
+ * also by the Frame's node's type (e.g. DomElement vs. #text)
16
+ *
17
+ * @access private
18
+ * @package dompdf
19
+ */
20
+class Frame_Factory {
21
+
22
+  /**
23
+   * Decorate the root Frame
24
+   * 
25
+   * @param $root Frame The frame to decorate
26
+   * @param $dompdf DOMPDF The dompdf instance
27
+   * @return Page_Frame_Decorator
28
+   */
29
+  static function decorate_root(Frame $root, DOMPDF $dompdf) {
30
+    $frame = new Page_Frame_Decorator($root, $dompdf);
31
+    $frame->set_reflower( new Page_Frame_Reflower($frame) );
32
+    $root->set_decorator($frame);
33
+    return $frame;
34
+  }
35
+
36
+  /**
37
+   * Decorate a Frame
38
+   *
39
+   * @param Frame  $frame  The frame to decorate
40
+   * @param DOMPDF $dompdf The dompdf instance
41
+   * @param Frame  $root   The frame to decorate
42
+   *
43
+   * @throws DOMPDF_Exception
44
+   * @return Frame_Decorator
45
+   * FIXME: this is admittedly a little smelly...
46
+   */
47
+  static function decorate_frame(Frame $frame, DOMPDF $dompdf, Frame $root = null) {
48
+    if ( is_null($dompdf) ) {
49
+      throw new DOMPDF_Exception("The DOMPDF argument is required");
50
+    }
51
+    
52
+    $style = $frame->get_style();
53
+    
54
+    // Floating (and more generally out-of-flow) elements are blocks 
55
+    // http://coding.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/
56
+    if ( !$frame->is_in_flow() && in_array($style->display, Style::$INLINE_TYPES)) {
57
+      $style->display = "block";
58
+    }
59
+      
60
+    $display = $style->display;
61
+    
62
+    switch ($display) {
63
+      
64
+    case "block":
65
+      $positioner = "Block";        
66
+      $decorator = "Block";
67
+      $reflower = "Block";
68
+      break;
69
+    
70
+    case "inline-block":
71
+      $positioner = "Inline";
72
+      $decorator = "Block";
73
+      $reflower = "Block";
74
+      break;
75
+
76
+    case "inline":
77
+      $positioner = "Inline";
78
+      if ( $frame->is_text_node() ) {
79
+        $decorator = "Text";
80
+        $reflower = "Text";
81
+      } 
82
+      else {
83
+        $enable_css_float = $dompdf->get_option("enable_css_float");
84
+        if ( $enable_css_float && $style->float !== "none" ) {
85
+          $decorator = "Block";
86
+          $reflower = "Block";
87
+        }
88
+        else {
89
+          $decorator = "Inline";
90
+          $reflower = "Inline";
91
+        }
92
+      }
93
+      break;   
94
+
95
+    case "table":
96
+      $positioner = "Block";
97
+      $decorator = "Table";
98
+      $reflower = "Table";
99
+      break;
100
+      
101
+    case "inline-table":
102
+      $positioner = "Inline";
103
+      $decorator = "Table";
104
+      $reflower = "Table";
105
+      break;
106
+
107
+    case "table-row-group":
108
+    case "table-header-group":
109
+    case "table-footer-group":
110
+      $positioner = "Null";
111
+      $decorator = "Table_Row_Group";
112
+      $reflower = "Table_Row_Group";
113
+      break;
114
+      
115
+    case "table-row":
116
+      $positioner = "Null";
117
+      $decorator = "Table_Row";
118
+      $reflower = "Table_Row";
119
+      break;
120
+
121
+    case "table-cell":
122
+      $positioner = "Table_Cell";
123
+      $decorator = "Table_Cell";
124
+      $reflower = "Table_Cell";
125
+      break;
126
+        
127
+    case "list-item":
128
+      $positioner = "Block";
129
+      $decorator  = "Block";
130
+      $reflower   = "Block";
131
+      break;
132
+
133
+    case "-dompdf-list-bullet":
134
+      if ( $style->list_style_position === "inside" ) {
135
+        $positioner = "Inline";
136
+      }
137
+      else {        
138
+        $positioner = "List_Bullet";
139
+      }
140
+
141
+      if ( $style->list_style_image !== "none" ) {
142
+        $decorator = "List_Bullet_Image";
143
+      }
144
+      else {
145
+        $decorator = "List_Bullet";
146
+      }
147
+      
148
+      $reflower = "List_Bullet";
149
+      break;
150
+
151
+    case "-dompdf-image":
152
+      $positioner = "Inline";
153
+      $decorator = "Image";
154
+      $reflower = "Image";
155
+      break;
156
+      
157
+    case "-dompdf-br":
158
+      $positioner = "Inline";
159
+      $decorator = "Inline";
160
+      $reflower = "Inline";
161
+      break;
162
+
163
+    default:
164
+      // FIXME: should throw some sort of warning or something?
165
+    case "none":
166
+      if ( $style->_dompdf_keep !== "yes" ) {
167
+        // Remove the node and the frame
168
+        $frame->get_parent()->remove_child($frame);
169
+        return;
170
+      }
171
+
172
+      $positioner = "Null";
173
+      $decorator = "Null";
174
+      $reflower = "Null";
175
+      break;
176
+    }
177
+
178
+    // Handle CSS position
179
+    $position = $style->position;
180
+    
181
+    if ( $position === "absolute" ) {
182
+      $positioner = "Absolute";
183
+    }
184
+    else if ( $position === "fixed" ) {
185
+      $positioner = "Fixed";
186
+    }
187
+      
188
+    $node = $frame->get_node();
189
+    
190
+    // Handle nodeName
191
+    if ( $node->nodeName === "img" ) {
192
+      $style->display = "-dompdf-image";
193
+      $decorator = "Image";
194
+      $reflower = "Image";
195
+    }
196
+  
197
+    $positioner .= "_Positioner";
198
+    $decorator .= "_Frame_Decorator";
199
+    $reflower .= "_Frame_Reflower";
200
+
201
+    $deco = new $decorator($frame, $dompdf);
202
+    
203
+    $deco->set_positioner( new $positioner($deco) );
204
+    $deco->set_reflower( new $reflower($deco) );
205
+    
206
+    if ( $root ) {
207
+      $deco->set_root($root);
208
+    }
209
+    
210
+    if ( $display === "list-item" ) {
211
+      // Insert a list-bullet frame
212
+      $xml = $dompdf->get_dom();
213
+      $bullet_node = $xml->createElement("bullet"); // arbitrary choice
214
+      $b_f = new Frame($bullet_node);
215
+
216
+      $node = $frame->get_node();
217
+      $parent_node = $node->parentNode;
218
+      
219
+      if ( $parent_node ) {
220
+        if ( !$parent_node->hasAttribute("dompdf-children-count") ) {
221
+          $xpath = new DOMXPath($xml);
222
+          $count = $xpath->query("li", $parent_node)->length;
223
+          $parent_node->setAttribute("dompdf-children-count", $count);
224
+        }
225
+        
226
+        if ( is_numeric($node->getAttribute("value")) ) {
227
+          $index = intval($node->getAttribute("value"));
228
+        }
229
+        else {
230
+          if ( !$parent_node->hasAttribute("dompdf-counter") ) {
231
+            $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1);
232
+          }
233
+          else {
234
+            $index = $parent_node->getAttribute("dompdf-counter")+1;
235
+          }
236
+        }
237
+        
238
+        $parent_node->setAttribute("dompdf-counter", $index);
239
+        $bullet_node->setAttribute("dompdf-counter", $index);
240
+      }
241
+      
242
+      $new_style = $dompdf->get_css()->create_style();
243
+      $new_style->display = "-dompdf-list-bullet";
244
+      $new_style->inherit($style);
245
+      $b_f->set_style($new_style);
246
+      
247
+      $deco->prepend_child( Frame_Factory::decorate_frame($b_f, $dompdf, $root) );
248
+    }
249
+    
250
+    return $deco;
251
+  }
252
+}

+ 458
- 0
vendor/dompdf/dompdf/include/frame_reflower.cls.php View File

@@ -0,0 +1,458 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Base reflower class
11
+ *
12
+ * Reflower objects are responsible for determining the width and height of
13
+ * individual frames.  They also create line and page breaks as necessary.
14
+ *
15
+ * @access private
16
+ * @package dompdf
17
+ */
18
+abstract class Frame_Reflower {
19
+
20
+  /**
21
+   * Frame for this reflower
22
+   *
23
+   * @var Frame
24
+   */
25
+  protected $_frame;
26
+
27
+  /**
28
+   * Cached min/max size
29
+   *
30
+   * @var array
31
+   */
32
+  protected $_min_max_cache;
33
+  
34
+  function __construct(Frame $frame) {
35
+    $this->_frame = $frame;
36
+    $this->_min_max_cache = null;
37
+  }
38
+
39
+  function dispose() {
40
+    clear_object($this);
41
+  }
42
+
43
+  /**
44
+   * @return DOMPDF
45
+   */
46
+  function get_dompdf() {
47
+    return $this->_frame->get_dompdf();
48
+  }
49
+
50
+  /**
51
+   * Collapse frames margins
52
+   * http://www.w3.org/TR/CSS2/box.html#collapsing-margins
53
+   */
54
+  protected function _collapse_margins() {
55
+    $frame = $this->_frame;
56
+    $cb = $frame->get_containing_block();
57
+    $style = $frame->get_style();
58
+    
59
+    if ( !$frame->is_in_flow() ) {
60
+      return;
61
+    }
62
+
63
+    $t = $style->length_in_pt($style->margin_top, $cb["h"]);
64
+    $b = $style->length_in_pt($style->margin_bottom, $cb["h"]);
65
+
66
+    // Handle 'auto' values
67
+    if ( $t === "auto" ) {
68
+      $style->margin_top = "0pt";
69
+      $t = 0;
70
+    }
71
+
72
+    if ( $b === "auto" ) {
73
+      $style->margin_bottom = "0pt";
74
+      $b = 0;
75
+    }
76
+
77
+    // Collapse vertical margins:
78
+    $n = $frame->get_next_sibling();
79
+    if ( $n && !$n->is_block() ) {
80
+      while ( $n = $n->get_next_sibling() ) {
81
+        if ( $n->is_block() ) {
82
+          break;
83
+        }
84
+        
85
+        if ( !$n->get_first_child() ) {
86
+          $n = null;
87
+          break;
88
+        }
89
+      }
90
+    }
91
+    
92
+    if ( $n ) {
93
+      $n_style = $n->get_style();
94
+      $b = max($b, $n_style->length_in_pt($n_style->margin_top, $cb["h"]));
95
+      $n_style->margin_top = "0pt";
96
+      $style->margin_bottom = $b."pt";
97
+    }
98
+
99
+    // Collapse our first child's margin
100
+    /*$f = $this->_frame->get_first_child();
101
+    if ( $f && !$f->is_block() ) {
102
+      while ( $f = $f->get_next_sibling() ) {
103
+        if ( $f->is_block() ) {
104
+          break;
105
+        }
106
+        
107
+        if ( !$f->get_first_child() ) {
108
+          $f = null;
109
+          break;
110
+        }
111
+      }
112
+    }
113
+
114
+    // Margin are collapsed only between block elements
115
+    if ( $f ) {
116
+      $f_style = $f->get_style();
117
+      $t = max($t, $f_style->length_in_pt($f_style->margin_top, $cb["h"]));
118
+      $style->margin_top = $t."pt";
119
+      $f_style->margin_bottom = "0pt";
120
+    }*/
121
+  }
122
+
123
+  //........................................................................
124
+
125
+  abstract function reflow(Block_Frame_Decorator $block = null);
126
+
127
+  //........................................................................
128
+
129
+  // Required for table layout: Returns an array(0 => min, 1 => max, "min"
130
+  // => min, "max" => max) of the minimum and maximum widths of this frame.
131
+  // This provides a basic implementation.  Child classes should override
132
+  // this if necessary.
133
+  function get_min_max_width() {
134
+    if ( !is_null($this->_min_max_cache) ) {
135
+      return $this->_min_max_cache;
136
+    }
137
+    
138
+    $style = $this->_frame->get_style();
139
+
140
+    // Account for margins & padding
141
+    $dims = array($style->padding_left,
142
+                  $style->padding_right,
143
+                  $style->border_left_width,
144
+                  $style->border_right_width,
145
+                  $style->margin_left,
146
+                  $style->margin_right);
147
+
148
+    $cb_w = $this->_frame->get_containing_block("w");
149
+    $delta = $style->length_in_pt($dims, $cb_w);
150
+
151
+    // Handle degenerate case
152
+    if ( !$this->_frame->get_first_child() ) {
153
+      return $this->_min_max_cache = array(
154
+        $delta, $delta,
155
+        "min" => $delta, 
156
+        "max" => $delta,
157
+      );
158
+    }
159
+
160
+    $low = array();
161
+    $high = array();
162
+
163
+    for ( $iter = $this->_frame->get_children()->getIterator();
164
+          $iter->valid();
165
+          $iter->next() ) {
166
+
167
+      $inline_min = 0;
168
+      $inline_max = 0;
169
+
170
+      // Add all adjacent inline widths together to calculate max width
171
+      while ( $iter->valid() && in_array( $iter->current()->get_style()->display, Style::$INLINE_TYPES ) ) {
172
+
173
+        $child = $iter->current();
174
+
175
+        $minmax = $child->get_min_max_width();
176
+
177
+        if ( in_array( $iter->current()->get_style()->white_space, array("pre", "nowrap") ) ) {
178
+          $inline_min += $minmax["min"];
179
+        }
180
+        else {
181
+          $low[] = $minmax["min"];
182
+        }
183
+
184
+        $inline_max += $minmax["max"];
185
+        $iter->next();
186
+
187
+      }
188
+
189
+      if ( $inline_max > 0 ) $high[] = $inline_max;
190
+      if ( $inline_min > 0 ) $low[]  = $inline_min;
191
+
192
+      if ( $iter->valid() ) {
193
+        list($low[], $high[]) = $iter->current()->get_min_max_width();
194
+        continue;
195
+      }
196
+
197
+    }
198
+    $min = count($low) ? max($low) : 0;
199
+    $max = count($high) ? max($high) : 0;
200
+
201
+    // Use specified width if it is greater than the minimum defined by the
202
+    // content.  If the width is a percentage ignore it for now.
203
+    $width = $style->width;
204
+    if ( $width !== "auto" && !is_percent($width) ) {
205
+      $width = $style->length_in_pt($width, $cb_w);
206
+      if ( $min < $width ) $min = $width;
207
+      if ( $max < $width ) $max = $width;
208
+    }
209
+
210
+    $min += $delta;
211
+    $max += $delta;
212
+    return $this->_min_max_cache = array($min, $max, "min"=>$min, "max"=>$max);
213
+  }
214
+
215
+  /**
216
+   * Parses a CSS string containing quotes and escaped hex characters
217
+   * 
218
+   * @param $string string The CSS string to parse
219
+   * @param $single_trim
220
+   * @return string
221
+   */
222
+  protected function _parse_string($string, $single_trim = false) {
223
+    if ( $single_trim ) {
224
+      $string = preg_replace('/^[\"\']/', "", $string);
225
+      $string = preg_replace('/[\"\']$/', "", $string);
226
+    }
227
+    else {
228
+      $string = trim($string, "'\"");
229
+    }
230
+    
231
+    $string = str_replace(array("\\\n",'\\"',"\\'"),
232
+                          array("",'"',"'"), $string);
233
+
234
+    // Convert escaped hex characters into ascii characters (e.g. \A => newline)
235
+    $string = preg_replace_callback("/\\\\([0-9a-fA-F]{0,6})/",
236
+                                    create_function('$matches',
237
+                                                    'return unichr(hexdec($matches[1]));'),
238
+                                    $string);
239
+    return $string;
240
+  }
241
+  
242
+  /**
243
+   * Parses a CSS "quotes" property
244
+   * 
245
+   * @return array|null An array of pairs of quotes
246
+   */
247
+  protected function _parse_quotes() {
248
+    
249
+    // Matches quote types
250
+    $re = '/(\'[^\']*\')|(\"[^\"]*\")/';
251
+    
252
+    $quotes = $this->_frame->get_style()->quotes;
253
+      
254
+    // split on spaces, except within quotes
255
+    if ( !preg_match_all($re, "$quotes", $matches, PREG_SET_ORDER) ) {
256
+      return null;
257
+    }
258
+      
259
+    $quotes_array = array();
260
+    foreach($matches as &$_quote){
261
+      $quotes_array[] = $this->_parse_string($_quote[0], true);
262
+    }
263
+    
264
+    if ( empty($quotes_array) ) {
265
+      $quotes_array = array('"', '"');
266
+    }
267
+    
268
+    return array_chunk($quotes_array, 2);
269
+  }
270
+
271
+  /**
272
+   * Parses the CSS "content" property
273
+   * 
274
+   * @return string|null The resulting string
275
+   */
276
+  protected function _parse_content() {
277
+
278
+    // Matches generated content
279
+    $re = "/\n".
280
+      "\s(counters?\\([^)]*\\))|\n".
281
+      "\A(counters?\\([^)]*\\))|\n".
282
+      "\s([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\3|\n".
283
+      "\A([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?<!\\\\)\\5|\n" .
284
+      "\s([^\s\"']+)|\n" .
285
+      "\A([^\s\"']+)\n".
286
+      "/xi";
287
+    
288
+    $content = $this->_frame->get_style()->content;
289
+
290
+    $quotes = $this->_parse_quotes();
291
+    
292
+    // split on spaces, except within quotes
293
+    if ( !preg_match_all($re, $content, $matches, PREG_SET_ORDER) ) {
294
+      return null;
295
+    }
296
+      
297
+    $text = "";
298
+
299
+    foreach ($matches as $match) {
300
+      
301
+      if ( isset($match[2]) && $match[2] !== "" ) {
302
+        $match[1] = $match[2];
303
+      }
304
+      
305
+      if ( isset($match[6]) && $match[6] !== "" ) {
306
+        $match[4] = $match[6];
307
+      }
308
+
309
+      if ( isset($match[8]) && $match[8] !== "" ) {
310
+        $match[7] = $match[8];
311
+      }
312
+
313
+      if ( isset($match[1]) && $match[1] !== "" ) {
314
+        
315
+        // counters?(...)
316
+        $match[1] = mb_strtolower(trim($match[1]));
317
+
318
+        // Handle counter() references:
319
+        // http://www.w3.org/TR/CSS21/generate.html#content
320
+
321
+        $i = mb_strpos($match[1], ")");
322
+        if ( $i === false ) {
323
+          continue;
324
+        }
325
+
326
+        preg_match( '/(counters?)(^\()*?\(\s*([^\s,]+)\s*(,\s*["\']?([^"\'\)]+)["\']?\s*(,\s*([^\s)]+)\s*)?)?\)/i' , $match[1] , $args );
327
+        $counter_id = $args[3];
328
+        if ( strtolower( $args[1] ) == 'counter' ) {
329
+          // counter(name [,style])
330
+          if ( isset( $args[5] ) ) {
331
+            $type = trim( $args[5] );
332
+          }
333
+          else {
334
+            $type = null;
335
+          }
336
+          $p = $this->_frame->lookup_counter_frame( $counter_id );
337
+          
338
+          $text .= $p->counter_value($counter_id, $type);
339
+          
340
+        }
341
+        else if ( strtolower( $args[1] ) == 'counters' ) {
342
+          // counters(name, string [,style])
343
+          if ( isset($args[5]) ) {
344
+            $string = $this->_parse_string( $args[5] );
345
+          }
346
+          else {
347
+            $string = "";
348
+          }
349
+          
350
+          if ( isset( $args[7] ) ) {
351
+            $type = trim( $args[7] );
352
+          }
353
+          else {
354
+            $type = null;
355
+          }
356
+          
357
+          $p = $this->_frame->lookup_counter_frame($counter_id);
358
+          $tmp = array();
359
+          while ($p) {
360
+            // We only want to use the counter values when they actually increment the counter
361
+            if ( array_key_exists( $counter_id , $p->_counters ) ) {
362
+              array_unshift( $tmp , $p->counter_value($counter_id, $type) );
363
+            }
364
+            $p = $p->lookup_counter_frame($counter_id);
365
+            
366
+          }
367
+          $text .= implode( $string , $tmp );
368
+          
369
+        }
370
+        else {
371
+          // countertops?
372
+          continue;
373
+        }
374
+        
375
+      }
376
+      else if ( isset($match[4]) && $match[4] !== "" ) {
377
+        // String match
378
+        $text .= $this->_parse_string($match[4]);
379
+      }
380
+      else if ( isset($match[7]) && $match[7] !== "" ) {
381
+        // Directive match
382
+
383
+        if ( $match[7] === "open-quote" ) {
384
+          // FIXME: do something here
385
+          $text .= $quotes[0][0];
386
+        }
387
+        else if ( $match[7] === "close-quote" ) {
388
+          // FIXME: do something else here
389
+          $text .= $quotes[0][1];
390
+        }
391
+        else if ( $match[7] === "no-open-quote" ) {
392
+          // FIXME:
393
+        }
394
+        else if ( $match[7] === "no-close-quote" ) {
395
+          // FIXME:
396
+        }
397
+        else if ( mb_strpos($match[7],"attr(") === 0 ) {
398
+
399
+          $i = mb_strpos($match[7],")");
400
+          if ( $i === false ) {
401
+            continue;
402
+          }
403
+
404
+          $attr = mb_substr($match[7], 5, $i - 5);
405
+          if ( $attr == "" ) {
406
+            continue;
407
+          }
408
+            
409
+          $text .= $this->_frame->get_parent()->get_node()->getAttribute($attr);
410
+        }
411
+        else {
412
+          continue;
413
+        }
414
+      }
415
+    }
416
+    
417
+    return $text;
418
+  }
419
+  
420
+  /**
421
+   * Sets the generated content of a generated frame
422
+   */
423
+  protected function _set_content(){
424
+    $frame = $this->_frame;
425
+    $style = $frame->get_style();
426
+    
427
+    // if the element was pushed to a new page use the saved counter value, otherwise use the CSS reset value
428
+    if ( $style->counter_reset && ($reset = $style->counter_reset) !== "none" ) {
429
+      $vars = preg_split('/\s+/', trim($reset), 2);
430
+      $frame->reset_counter( $vars[0] , ( isset($frame->_counters['__'.$vars[0]]) ? $frame->_counters['__'.$vars[0]] : ( isset($vars[1]) ? $vars[1] : 0 ) ) );
431
+    }
432
+    
433
+    if ( $style->counter_increment && ($increment = $style->counter_increment) !== "none" ) {
434
+      $frame->increment_counters($increment);
435
+    }
436
+  
437
+    if ( $style->content && !$frame->get_first_child() && $frame->get_node()->nodeName === "dompdf_generated" ) {
438
+      $content = $this->_parse_content();
439
+      // add generated content to the font subset
440
+      // FIXME: This is currently too late because the font subset has already been generated.
441
+      //        See notes in issue #750.
442
+      if ( $frame->get_dompdf()->get_option("enable_font_subsetting") && $frame->get_dompdf()->get_canvas() instanceof CPDF_Adapter ) {
443
+        $frame->get_dompdf()->get_canvas()->register_string_subset($style->font_family, $content);
444
+      }
445
+      
446
+      $node = $frame->get_node()->ownerDocument->createTextNode($content);
447
+      
448
+      $new_style = $style->get_stylesheet()->create_style();
449
+      $new_style->inherit($style);
450
+      
451
+      $new_frame = new Frame($node);
452
+      $new_frame->set_style($new_style);
453
+      
454
+      Frame_Factory::decorate_frame($new_frame, $frame->get_dompdf(), $frame->get_root());
455
+      $frame->append_child($new_frame);
456
+    }
457
+  }
458
+}

+ 241
- 0
vendor/dompdf/dompdf/include/frame_tree.cls.php View File

@@ -0,0 +1,241 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Represents an entire document as a tree of frames
11
+ *
12
+ * The Frame_Tree consists of {@link Frame} objects each tied to specific
13
+ * DOMNode objects in a specific DomDocument.  The Frame_Tree has the same
14
+ * structure as the DomDocument, but adds additional capabalities for
15
+ * styling and layout.
16
+ *
17
+ * @package dompdf
18
+ * @access protected
19
+ */
20
+class Frame_Tree {
21
+    
22
+  /**
23
+   * Tags to ignore while parsing the tree
24
+   *
25
+   * @var array
26
+   */
27
+  static protected $_HIDDEN_TAGS = array("area", "base", "basefont", "head", "style",
28
+                                         "meta", "title", "colgroup",
29
+                                         "noembed", "noscript", "param", "#comment");  
30
+  /**
31
+   * The main DomDocument
32
+   *
33
+   * @see http://ca2.php.net/manual/en/ref.dom.php
34
+   * @var DomDocument
35
+   */
36
+  protected $_dom;
37
+
38
+  /**
39
+   * The root node of the FrameTree.
40
+   *
41
+   * @var Frame
42
+   */
43
+  protected $_root;
44
+
45
+  /**
46
+   * Subtrees of absolutely positioned elements
47
+   *
48
+   * @var array of Frames
49
+   */
50
+  protected $_absolute_frames;
51
+
52
+  /**
53
+   * A mapping of {@link Frame} objects to DOMNode objects
54
+   *
55
+   * @var array
56
+   */
57
+  protected $_registry;
58
+  
59
+
60
+  /**
61
+   * Class constructor
62
+   *
63
+   * @param DomDocument $dom the main DomDocument object representing the current html document
64
+   */
65
+  function __construct(DomDocument $dom) {
66
+    $this->_dom = $dom;
67
+    $this->_root = null;
68
+    $this->_registry = array();
69
+  }
70
+  
71
+  function __destruct() {
72
+    clear_object($this);
73
+  }
74
+
75
+  /**
76
+   * Returns the DomDocument object representing the curent html document
77
+   *
78
+   * @return DOMDocument
79
+   */
80
+  function get_dom() {
81
+    return $this->_dom;
82
+  }
83
+
84
+  /**
85
+   * Returns the root frame of the tree
86
+   * 
87
+   * @return Page_Frame_Decorator
88
+   */
89
+  function get_root() {
90
+    return $this->_root;
91
+  }
92
+
93
+  /**
94
+   * Returns a specific frame given its id
95
+   *
96
+   * @param string $id
97
+   * @return Frame
98
+   */
99
+  function get_frame($id) {
100
+    return isset($this->_registry[$id]) ? $this->_registry[$id] : null;
101
+  }
102
+
103
+  /**
104
+   * Returns a post-order iterator for all frames in the tree
105
+   *
106
+   * @return FrameTreeList|Frame[]
107
+   */
108
+  function get_frames() {
109
+    return new FrameTreeList($this->_root);
110
+  }
111
+      
112
+  /**
113
+   * Builds the tree
114
+   */
115
+  function build_tree() {
116
+    $html = $this->_dom->getElementsByTagName("html")->item(0);
117
+    if ( is_null($html) ) {
118
+      $html = $this->_dom->firstChild;
119
+    }
120
+
121
+    if ( is_null($html) ) {
122
+      throw new DOMPDF_Exception("Requested HTML document contains no data.");
123
+    }
124
+
125
+    $this->fix_tables();
126
+    
127
+    $this->_root = $this->_build_tree_r($html);
128
+  }
129
+  
130
+  /**
131
+   * Adds missing TBODYs around TR
132
+   */
133
+  protected function fix_tables(){
134
+    $xp = new DOMXPath($this->_dom);
135
+    
136
+    // Move table caption before the table
137
+    // FIXME find a better way to deal with it...
138
+    $captions = $xp->query("//table/caption");
139
+    foreach($captions as $caption) {
140
+      $table = $caption->parentNode;
141
+      $table->parentNode->insertBefore($caption, $table);
142
+    }
143
+    
144
+    $rows = $xp->query("//table/tr");
145
+    foreach($rows as $row) {
146
+      $tbody = $this->_dom->createElement("tbody");
147
+      $tbody = $row->parentNode->insertBefore($tbody, $row);
148
+      $tbody->appendChild($row);
149
+    }
150
+  }
151
+
152
+  /**
153
+   * Recursively adds {@link Frame} objects to the tree
154
+   *
155
+   * Recursively build a tree of Frame objects based on a dom tree.
156
+   * No layout information is calculated at this time, although the
157
+   * tree may be adjusted (i.e. nodes and frames for generated content
158
+   * and images may be created).
159
+   *
160
+   * @param DOMNode $node the current DOMNode being considered
161
+   * @return Frame
162
+   */
163
+  protected function _build_tree_r(DOMNode $node) {
164
+    
165
+    $frame = new Frame($node);
166
+    $id = $frame->get_id();
167
+    $this->_registry[ $id ] = $frame;
168
+    
169
+    if ( !$node->hasChildNodes() ) {
170
+      return $frame;
171
+    }
172
+
173
+    // Fixes 'cannot access undefined property for object with
174
+    // overloaded access', fix by Stefan radulian
175
+    // <stefan.radulian@symbion.at>    
176
+    //foreach ($node->childNodes as $child) {
177
+
178
+    // Store the children in an array so that the tree can be modified
179
+    $children = array();
180
+    for ($i = 0; $i < $node->childNodes->length; $i++) {
181
+      $children[] = $node->childNodes->item($i);
182
+    }
183
+
184
+    foreach ($children as $child) {
185
+      $node_name = mb_strtolower($child->nodeName);
186
+      
187
+      // Skip non-displaying nodes
188
+      if ( in_array($node_name, self::$_HIDDEN_TAGS) )  {
189
+        if ( $node_name !== "head" && $node_name !== "style" ) {
190
+          $child->parentNode->removeChild($child);
191
+        }
192
+        
193
+        continue;
194
+      }
195
+
196
+      // Skip empty text nodes
197
+      if ( $node_name === "#text" && $child->nodeValue == "" ) {
198
+        $child->parentNode->removeChild($child);
199
+        continue;
200
+      }
201
+
202
+      // Skip empty image nodes
203
+      if ( $node_name === "img" && $child->getAttribute("src") == "" ) {
204
+        $child->parentNode->removeChild($child);
205
+        continue;
206
+      }
207
+      
208
+      $frame->append_child($this->_build_tree_r($child), false);
209
+    }
210
+    
211
+    return $frame;
212
+  }
213
+  
214
+  public function insert_node(DOMNode $node, DOMNode $new_node, $pos) {
215
+    if ( $pos === "after" || !$node->firstChild ) {
216
+      $node->appendChild($new_node);
217
+    }
218
+    else {
219
+      $node->insertBefore($new_node, $node->firstChild);
220
+    }
221
+    
222
+    $this->_build_tree_r($new_node);
223
+    
224
+    $frame_id = $new_node->getAttribute("frame_id");
225
+    $frame = $this->get_frame($frame_id);
226
+    
227
+    $parent_id = $node->getAttribute("frame_id");
228
+    $parent = $this->get_frame($parent_id);
229
+    
230
+    if ( $parent ) {
231
+      if ( $pos === "before" ) {
232
+        $parent->prepend_child($frame, false);
233
+      }
234
+      else {
235
+        $parent->append_child($frame, false);
236
+      }
237
+    }
238
+    
239
+    return $frame_id;
240
+  }
241
+}

+ 1036
- 0
vendor/dompdf/dompdf/include/functions.inc.php
File diff suppressed because it is too large
View File


+ 840
- 0
vendor/dompdf/dompdf/include/gd_adapter.cls.php View File

@@ -0,0 +1,840 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Image rendering interface
12
+ *
13
+ * Renders to an image format supported by GD (jpeg, gif, png, xpm).
14
+ * Not super-useful day-to-day but handy nonetheless
15
+ *
16
+ * @package dompdf
17
+ */
18
+class GD_Adapter implements Canvas {
19
+  /**
20
+   * @var DOMPDF
21
+   */
22
+  private $_dompdf;
23
+
24
+  /**
25
+   * Resource handle for the image
26
+   *
27
+   * @var resource
28
+   */
29
+  private $_img;
30
+
31
+  /**
32
+   * Image width in pixels
33
+   *
34
+   * @var int
35
+   */
36
+  private $_width;
37
+
38
+  /**
39
+   * Image height in pixels
40
+   *
41
+   * @var int
42
+   */
43
+  private $_height;
44
+
45
+  /**
46
+   * Current page number
47
+   *
48
+   * @var int
49
+   */
50
+  private $_page_number;
51
+
52
+  /**
53
+   * Total number of pages
54
+   *
55
+   * @var int
56
+   */
57
+  private $_page_count;
58
+
59
+  /**
60
+   * Image antialias factor
61
+   *
62
+   * @var float
63
+   */
64
+  private $_aa_factor;
65
+
66
+  /**
67
+   * Allocated colors
68
+   *
69
+   * @var array
70
+   */
71
+  private $_colors;
72
+
73
+  /**
74
+   * Background color
75
+   *
76
+   * @var int
77
+   */
78
+  private $_bg_color;
79
+
80
+  /**
81
+   * Class constructor
82
+   *
83
+   * @param mixed  $size         The size of image to create: array(x1,y1,x2,y2) or "letter", "legal", etc.
84
+   * @param string $orientation  The orientation of the document (either 'landscape' or 'portrait')
85
+   * @param DOMPDF $dompdf
86
+   * @param float  $aa_factor    Anti-aliasing factor, 1 for no AA
87
+   * @param array  $bg_color     Image background color: array(r,g,b,a), 0 <= r,g,b,a <= 1
88
+   */
89
+  function __construct($size, $orientation = "portrait", DOMPDF $dompdf, $aa_factor = 1.0, $bg_color = array(1,1,1,0) ) {
90
+
91
+    if ( !is_array($size) ) {
92
+      $size = strtolower($size);
93
+      
94
+      if ( isset(CPDF_Adapter::$PAPER_SIZES[$size]) ) {
95
+        $size = CPDF_Adapter::$PAPER_SIZES[$size];
96
+      }
97
+      else {
98
+        $size = CPDF_Adapter::$PAPER_SIZES["letter"];
99
+      }
100
+    }
101
+
102
+    if ( strtolower($orientation) === "landscape" ) {
103
+      list($size[2],$size[3]) = array($size[3],$size[2]);
104
+    }
105
+
106
+    $this->_dompdf = $dompdf;
107
+
108
+    if ( $aa_factor < 1 ) {
109
+      $aa_factor = 1;
110
+    }
111
+
112
+    $this->_aa_factor = $aa_factor;
113
+    
114
+    $size[2] *= $aa_factor;
115
+    $size[3] *= $aa_factor;
116
+    
117
+    $this->_width = $size[2] - $size[0];
118
+    $this->_height = $size[3] - $size[1];
119
+
120
+    $this->_img = imagecreatetruecolor($this->_width, $this->_height);
121
+
122
+    if ( is_null($bg_color) || !is_array($bg_color) ) {
123
+      // Pure white bg
124
+      $bg_color = array(1,1,1,0);
125
+    }
126
+
127
+    $this->_bg_color = $this->_allocate_color($bg_color);
128
+    imagealphablending($this->_img, true);
129
+    imagesavealpha($this->_img, true);
130
+    imagefill($this->_img, 0, 0, $this->_bg_color);
131
+    
132
+  }
133
+
134
+  function get_dompdf(){
135
+    return $this->_dompdf;
136
+  }
137
+
138
+  /**
139
+   * Return the GF image resource
140
+   *
141
+   * @return resource
142
+   */
143
+  function get_image() { return $this->_img; }
144
+
145
+  /**
146
+   * Return the image's width in pixels
147
+   *
148
+   * @return float
149
+   */
150
+  function get_width() { return $this->_width / $this->_aa_factor; }
151
+
152
+  /**
153
+   * Return the image's height in pixels
154
+   *
155
+   * @return float
156
+   */
157
+  function get_height() { return $this->_height / $this->_aa_factor; }
158
+
159
+  /**
160
+   * Returns the current page number
161
+   * @return int
162
+   */
163
+  function get_page_number() { return $this->_page_number; }
164
+
165
+  /**
166
+   * Returns the total number of pages in the document
167
+   * @return int
168
+   */
169
+  function get_page_count() { return $this->_page_count; }
170
+
171
+  /**
172
+   * Sets the current page number
173
+   *
174
+   * @param int $num
175
+   */
176
+  function set_page_number($num) { $this->_page_number = $num; }
177
+
178
+  /**
179
+   * Sets the page count
180
+   *
181
+   * @param int $count
182
+   */
183
+  function set_page_count($count) {  $this->_page_count = $count; }
184
+  
185
+  /**
186
+   * Sets the opacity 
187
+   * 
188
+   * @param $opacity
189
+   * @param $mode
190
+   */
191
+  function set_opacity($opacity, $mode = "Normal") {
192
+    // FIXME
193
+  }
194
+
195
+  /**
196
+   * Allocate a new color.  Allocate with GD as needed and store
197
+   * previously allocated colors in $this->_colors.
198
+   *
199
+   * @param array $color  The new current color
200
+   * @return int           The allocated color
201
+   */
202
+  private function _allocate_color($color) {
203
+    
204
+    if ( isset($color["c"]) ) {
205
+      $color = cmyk_to_rgb($color);
206
+    }
207
+    
208
+    // Full opacity if no alpha set
209
+    if ( !isset($color[3]) ) 
210
+      $color[3] = 0;
211
+    
212
+    list($r,$g,$b,$a) = $color;
213
+    
214
+    $r *= 255;
215
+    $g *= 255;
216
+    $b *= 255;
217
+    $a *= 127;
218
+    
219
+    // Clip values
220
+    $r = $r > 255 ? 255 : $r;
221
+    $g = $g > 255 ? 255 : $g;
222
+    $b = $b > 255 ? 255 : $b;
223
+    $a = $a > 127 ? 127 : $a;
224
+      
225
+    $r = $r < 0 ? 0 : $r;
226
+    $g = $g < 0 ? 0 : $g;
227
+    $b = $b < 0 ? 0 : $b;
228
+    $a = $a < 0 ? 0 : $a;
229
+      
230
+    $key = sprintf("#%02X%02X%02X%02X", $r, $g, $b, $a);
231
+      
232
+    if ( isset($this->_colors[$key]) )
233
+      return $this->_colors[$key];
234
+
235
+    if ( $a != 0 ) 
236
+      $this->_colors[$key] = imagecolorallocatealpha($this->_img, $r, $g, $b, $a);
237
+    else
238
+      $this->_colors[$key] = imagecolorallocate($this->_img, $r, $g, $b);
239
+      
240
+    return $this->_colors[$key];
241
+    
242
+  }
243
+  
244
+  /**
245
+   * Draws a line from x1,y1 to x2,y2
246
+   *
247
+   * See {@link Style::munge_color()} for the format of the color array.
248
+   * See {@link Cpdf::setLineStyle()} for a description of the format of the
249
+   * $style parameter (aka dash).
250
+   *
251
+   * @param float $x1
252
+   * @param float $y1
253
+   * @param float $x2
254
+   * @param float $y2
255
+   * @param array $color
256
+   * @param float $width
257
+   * @param array $style
258
+   */
259
+  function line($x1, $y1, $x2, $y2, $color, $width, $style = null) {
260
+
261
+    // Scale by the AA factor
262
+    $x1 *= $this->_aa_factor;
263
+    $y1 *= $this->_aa_factor;
264
+    $x2 *= $this->_aa_factor;
265
+    $y2 *= $this->_aa_factor;
266
+    $width *= $this->_aa_factor;
267
+
268
+    $c = $this->_allocate_color($color);
269
+
270
+    // Convert the style array if required
271
+    if ( !is_null($style) ) {
272
+      $gd_style = array();
273
+
274
+      if ( count($style) == 1 ) {
275
+        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
276
+          $gd_style[] = $c;
277
+        }
278
+
279
+        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
280
+          $gd_style[] = $this->_bg_color;
281
+        }
282
+
283
+      } else {
284
+
285
+        $i = 0;
286
+        foreach ($style as $length) {
287
+
288
+          if ( $i % 2 == 0 ) {
289
+            // 'On' pattern
290
+            for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) 
291
+              $gd_style[] = $c;
292
+            
293
+          } else {
294
+            // Off pattern
295
+            for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) 
296
+              $gd_style[] = $this->_bg_color;
297
+            
298
+          }
299
+          $i++;
300
+        }
301
+      }
302
+      
303
+      imagesetstyle($this->_img, $gd_style);
304
+      $c = IMG_COLOR_STYLED;
305
+    }
306
+    
307
+    imagesetthickness($this->_img, $width);
308
+
309
+    imageline($this->_img, $x1, $y1, $x2, $y2, $c);
310
+    
311
+  }
312
+
313
+  function arc($x1, $y1, $r1, $r2, $astart, $aend, $color, $width, $style = array()) {
314
+    // @todo
315
+  }
316
+
317
+  /**
318
+   * Draws a rectangle at x1,y1 with width w and height h
319
+   *
320
+   * See {@link Style::munge_color()} for the format of the color array.
321
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
322
+   * parameter (aka dash)
323
+   *
324
+   * @param float $x1
325
+   * @param float $y1
326
+   * @param float $w
327
+   * @param float $h
328
+   * @param array $color
329
+   * @param float $width
330
+   * @param array $style
331
+   */   
332
+  function rectangle($x1, $y1, $w, $h, $color, $width, $style = null) {
333
+
334
+    // Scale by the AA factor
335
+    $x1 *= $this->_aa_factor;
336
+    $y1 *= $this->_aa_factor;
337
+    $w *= $this->_aa_factor;
338
+    $h *= $this->_aa_factor;
339
+
340
+    $c = $this->_allocate_color($color);
341
+
342
+    // Convert the style array if required
343
+    if ( !is_null($style) ) {
344
+      $gd_style = array();
345
+
346
+      foreach ($style as $length) {
347
+        for ($i = 0; $i < $length; $i++) {
348
+          $gd_style[] = $c;
349
+        }
350
+      }
351
+
352
+      imagesetstyle($this->_img, $gd_style);
353
+      $c = IMG_COLOR_STYLED;
354
+    }
355
+
356
+    imagesetthickness($this->_img, $width);
357
+
358
+    imagerectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c);
359
+    
360
+  }
361
+
362
+  /**
363
+   * Draws a filled rectangle at x1,y1 with width w and height h
364
+   *
365
+   * See {@link Style::munge_color()} for the format of the color array.
366
+   *
367
+   * @param float $x1
368
+   * @param float $y1
369
+   * @param float $w
370
+   * @param float $h
371
+   * @param array $color
372
+   */   
373
+  function filled_rectangle($x1, $y1, $w, $h, $color) {
374
+
375
+    // Scale by the AA factor
376
+    $x1 *= $this->_aa_factor;
377
+    $y1 *= $this->_aa_factor;
378
+    $w *= $this->_aa_factor;
379
+    $h *= $this->_aa_factor;
380
+
381
+    $c = $this->_allocate_color($color);
382
+
383
+    imagefilledrectangle($this->_img, $x1, $y1, $x1 + $w, $y1 + $h, $c);
384
+
385
+  }
386
+  
387
+  /**
388
+   * Starts a clipping rectangle at x1,y1 with width w and height h
389
+   *
390
+   * @param float $x1
391
+   * @param float $y1
392
+   * @param float $w
393
+   * @param float $h
394
+   */
395
+  function clipping_rectangle($x1, $y1, $w, $h) {
396
+    // @todo
397
+  }
398
+  
399
+  function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) {
400
+    // @todo
401
+  }
402
+  
403
+  /**
404
+   * Ends the last clipping shape
405
+   */  
406
+  function clipping_end() {
407
+    // @todo
408
+  }
409
+  
410
+  function save() {
411
+    // @todo
412
+  }
413
+  
414
+  function restore() {
415
+    // @todo
416
+  }
417
+  
418
+  function rotate($angle, $x, $y) {
419
+    // @todo
420
+  }
421
+  
422
+  function skew($angle_x, $angle_y, $x, $y) {
423
+    // @todo
424
+  }
425
+  
426
+  function scale($s_x, $s_y, $x, $y) {
427
+    // @todo
428
+  }
429
+  
430
+  function translate($t_x, $t_y) {
431
+    // @todo
432
+  }
433
+  
434
+  function transform($a, $b, $c, $d, $e, $f) {
435
+    // @todo
436
+  }
437
+
438
+  /**
439
+   * Draws a polygon
440
+   *
441
+   * The polygon is formed by joining all the points stored in the $points
442
+   * array.  $points has the following structure:
443
+   * <code>
444
+   * array(0 => x1,
445
+   *       1 => y1,
446
+   *       2 => x2,
447
+   *       3 => y2,
448
+   *       ...
449
+   *       );
450
+   * </code>
451
+   *
452
+   * See {@link Style::munge_color()} for the format of the color array.
453
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
454
+   * parameter (aka dash)   
455
+   *
456
+   * @param array $points
457
+   * @param array $color
458
+   * @param float $width
459
+   * @param array $style
460
+   * @param bool  $fill  Fills the polygon if true
461
+   */
462
+  function polygon($points, $color, $width = null, $style = null, $fill = false) {
463
+
464
+    // Scale each point by the AA factor
465
+    foreach (array_keys($points) as $i)
466
+      $points[$i] *= $this->_aa_factor;
467
+
468
+    $c = $this->_allocate_color($color);
469
+
470
+    // Convert the style array if required
471
+    if ( !is_null($style) && !$fill ) {
472
+      $gd_style = array();
473
+
474
+      foreach ($style as $length) {
475
+        for ($i = 0; $i < $length; $i++) {
476
+          $gd_style[] = $c;
477
+        }
478
+      }
479
+
480
+      imagesetstyle($this->_img, $gd_style);
481
+      $c = IMG_COLOR_STYLED;
482
+    }
483
+
484
+    imagesetthickness($this->_img, $width);
485
+
486
+    if ( $fill ) 
487
+      imagefilledpolygon($this->_img, $points, count($points) / 2, $c);
488
+    else
489
+      imagepolygon($this->_img, $points, count($points) / 2, $c);
490
+        
491
+  }
492
+
493
+  /**
494
+   * Draws a circle at $x,$y with radius $r
495
+   *
496
+   * See {@link Style::munge_color()} for the format of the color array.
497
+   * See {@link Cpdf::setLineStyle()} for a description of the $style
498
+   * parameter (aka dash)
499
+   *
500
+   * @param float $x
501
+   * @param float $y
502
+   * @param float $r
503
+   * @param array $color
504
+   * @param float $width
505
+   * @param array $style
506
+   * @param bool $fill Fills the circle if true   
507
+   */   
508
+  function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false) {
509
+
510
+    // Scale by the AA factor
511
+    $x *= $this->_aa_factor;
512
+    $y *= $this->_aa_factor;
513
+    $r *= $this->_aa_factor;
514
+
515
+    $c = $this->_allocate_color($color);
516
+
517
+    // Convert the style array if required
518
+    if ( !is_null($style) && !$fill ) {
519
+      $gd_style = array();
520
+
521
+      foreach ($style as $length) {
522
+        for ($i = 0; $i < $length; $i++) {
523
+          $gd_style[] = $c;
524
+        }
525
+      }
526
+
527
+      imagesetstyle($this->_img, $gd_style);
528
+      $c = IMG_COLOR_STYLED;
529
+    }
530
+
531
+    imagesetthickness($this->_img, $width);
532
+
533
+    if ( $fill )
534
+      imagefilledellipse($this->_img, $x, $y, $r, $r, $c);
535
+    else
536
+      imageellipse($this->_img, $x, $y, $r, $r, $c);
537
+        
538
+  }
539
+
540
+  /**
541
+   * Add an image to the pdf.
542
+   * The image is placed at the specified x and y coordinates with the
543
+   * given width and height.
544
+   *
545
+   * @param string $img_url the path to the image
546
+   * @param float  $x       x position
547
+   * @param float  $y       y position
548
+   * @param int    $w       width (in pixels)
549
+   * @param int    $h       height (in pixels)
550
+   * @param string $resolution
551
+   *
552
+   * @return void
553
+   * @internal param string $img_type the type (e.g. extension) of the image
554
+   */
555
+  function image($img_url, $x, $y, $w, $h, $resolution = "normal") {
556
+    $img_type = Image_Cache::detect_type($img_url, $this->_dompdf->get_http_context());
557
+    $img_ext  = Image_Cache::type_to_ext($img_type);
558
+
559
+    if ( !$img_ext ) {
560
+      return;
561
+    }
562
+    
563
+    $func = "imagecreatefrom$img_ext";
564
+    $src = @$func($img_url);
565
+
566
+    if ( !$src ) {
567
+      return; // Probably should add to $_dompdf_errors or whatever here
568
+    }
569
+    
570
+    // Scale by the AA factor
571
+    $x *= $this->_aa_factor;
572
+    $y *= $this->_aa_factor;
573
+
574
+    $w *= $this->_aa_factor;
575
+    $h *= $this->_aa_factor;
576
+    
577
+    $img_w = imagesx($src);
578
+    $img_h = imagesy($src);
579
+    
580
+    imagecopyresampled($this->_img, $src, $x, $y, 0, 0, $w, $h, $img_w, $img_h);
581
+    
582
+  }
583
+
584
+  /**
585
+   * Writes text at the specified x and y coordinates
586
+   * See {@link Style::munge_color()} for the format of the color array.
587
+   *
588
+   * @param float  $x
589
+   * @param float  $y
590
+   * @param string $text  the text to write
591
+   * @param string $font  the font file to use
592
+   * @param float  $size  the font size, in points
593
+   * @param array  $color
594
+   * @param float  $word_spacing word spacing adjustment
595
+   * @param float  $char_spacing
596
+   * @param float  $angle Text angle
597
+   *
598
+   * @return void
599
+   */
600
+  function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_spacing = 0.0, $char_spacing = 0.0, $angle = 0.0) {
601
+
602
+    // Scale by the AA factor
603
+    $x *= $this->_aa_factor;
604
+    $y *= $this->_aa_factor;
605
+    $size *= $this->_aa_factor;
606
+    
607
+    $h = $this->get_font_height($font, $size);
608
+    $c = $this->_allocate_color($color);
609
+    
610
+    $text = mb_encode_numericentity($text, array(0x0080, 0xff, 0, 0xff), 'UTF-8');
611
+
612
+    $font = $this->get_ttf_file($font);
613
+
614
+    // FIXME: word spacing
615
+    @imagettftext($this->_img, $size, $angle, $x, $y + $h, $c, $font, $text);
616
+    
617
+  }
618
+  
619
+  function javascript($code) {
620
+    // Not implemented
621
+  }
622
+
623
+  /**
624
+   * Add a named destination (similar to <a name="foo">...</a> in html)
625
+   *
626
+   * @param string $anchorname The name of the named destination
627
+   */
628
+  function add_named_dest($anchorname) {
629
+    // Not implemented
630
+  }
631
+
632
+  /**
633
+   * Add a link to the pdf
634
+   *
635
+   * @param string $url    The url to link to
636
+   * @param float  $x      The x position of the link
637
+   * @param float  $y      The y position of the link
638
+   * @param float  $width  The width of the link
639
+   * @param float  $height The height of the link
640
+   */
641
+  function add_link($url, $x, $y, $width, $height) {
642
+    // Not implemented
643
+  }
644
+
645
+  /**
646
+   * Add meta information to the PDF
647
+   *
648
+   * @param string $label  label of the value (Creator, Producer, etc.)
649
+   * @param string $value  the text to set
650
+   */
651
+  function add_info($label, $value) {
652
+    // N/A
653
+  }
654
+  
655
+  function set_default_view($view, $options = array()) {
656
+    // N/A
657
+  }
658
+
659
+  /**
660
+   * Calculates text size, in points
661
+   *
662
+   * @param string $text the text to be sized
663
+   * @param string $font the desired font
664
+   * @param float  $size the desired font size
665
+   * @param float  $word_spacing word spacing, if any
666
+   * @param float  $char_spacing char spacing, if any
667
+   *
668
+   * @return float
669
+   */
670
+  function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) {
671
+    $font = $this->get_ttf_file($font);
672
+      
673
+    $text = mb_encode_numericentity($text, array(0x0080, 0xffff, 0, 0xffff), 'UTF-8');
674
+
675
+    // FIXME: word spacing
676
+    list($x1,,$x2) = @imagettfbbox($size, 0, $font, $text);
677
+    return $x2 - $x1;
678
+  }
679
+  
680
+  function get_ttf_file($font) {
681
+    if ( strpos($font, '.ttf') === false )
682
+      $font .= ".ttf";
683
+    
684
+    /*$filename = substr(strtolower(basename($font)), 0, -4);
685
+    
686
+    if ( in_array($filename, DOMPDF::$native_fonts) ) {
687
+      return "arial.ttf";
688
+    }*/
689
+    
690
+    return $font;
691
+  }
692
+
693
+  /**
694
+   * Calculates font height, in points
695
+   *
696
+   * @param string $font
697
+   * @param float $size
698
+   * @return float
699
+   */
700
+  function get_font_height($font, $size) {
701
+    $font = $this->get_ttf_file($font);
702
+    $ratio = $this->_dompdf->get_option("font_height_ratio");
703
+
704
+    // FIXME: word spacing
705
+    list(,$y2,,,,$y1) = imagettfbbox($size, 0, $font, "MXjpqytfhl");  // Test string with ascenders, descenders and caps
706
+    return ($y2 - $y1) * $ratio;
707
+  }
708
+  
709
+  function get_font_baseline($font, $size) {
710
+    $ratio = $this->_dompdf->get_option("font_height_ratio");
711
+    return $this->get_font_height($font, $size) / $ratio;
712
+  }
713
+  
714
+  /**
715
+   * Starts a new page
716
+   *
717
+   * Subsequent drawing operations will appear on the new page.
718
+   */
719
+  function new_page() {
720
+    $this->_page_number++;
721
+    $this->_page_count++;
722
+  }    
723
+
724
+  function open_object(){
725
+    // N/A
726
+  }
727
+
728
+  function close_object(){
729
+    // N/A
730
+  }
731
+
732
+  function add_object(){
733
+    // N/A
734
+  }
735
+
736
+  function page_text(){
737
+    // N/A
738
+  }
739
+  
740
+  /**
741
+   * Streams the image directly to the browser
742
+   *
743
+   * @param string $filename the name of the image file (ignored)
744
+   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
745
+   */
746
+  function stream($filename, $options = null) {
747
+
748
+    // Perform any antialiasing
749
+    if ( $this->_aa_factor != 1 ) {
750
+      $dst_w = $this->_width / $this->_aa_factor;
751
+      $dst_h = $this->_height / $this->_aa_factor;
752
+      $dst = imagecreatetruecolor($dst_w, $dst_h);
753
+      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
754
+                         $dst_w, $dst_h,
755
+                         $this->_width, $this->_height);
756
+    } else {
757
+      $dst = $this->_img;
758
+    }
759
+
760
+    if ( !isset($options["type"]) )
761
+      $options["type"] = "png";
762
+
763
+    $type = strtolower($options["type"]);
764
+    
765
+    header("Cache-Control: private");
766
+    
767
+    switch ($type) {
768
+
769
+    case "jpg":
770
+    case "jpeg":
771
+      if ( !isset($options["quality"]) )
772
+        $options["quality"] = 75;
773
+      
774
+      header("Content-type: image/jpeg");
775
+      imagejpeg($dst, '', $options["quality"]);
776
+      break;
777
+
778
+    case "png":
779
+    default:
780
+      header("Content-type: image/png");
781
+      imagepng($dst);
782
+      break;
783
+    }
784
+
785
+    if ( $this->_aa_factor != 1 ) 
786
+      imagedestroy($dst);
787
+  }
788
+
789
+  /**
790
+   * Returns the PNG as a string
791
+   *
792
+   * @param array  $options associative array, 'type' => jpeg|jpg|png, 'quality' => 0 - 100 (jpeg only)
793
+   * @return string
794
+   */
795
+  function output($options = null) {
796
+
797
+    if ( $this->_aa_factor != 1 ) {
798
+      $dst_w = $this->_width / $this->_aa_factor;
799
+      $dst_h = $this->_height / $this->_aa_factor;
800
+      $dst = imagecreatetruecolor($dst_w, $dst_h);
801
+      imagecopyresampled($dst, $this->_img, 0, 0, 0, 0,
802
+                         $dst_w, $dst_h,
803
+                         $this->_width, $this->_height);
804
+    } else {
805
+      $dst = $this->_img;
806
+    }
807
+    
808
+    if ( !isset($options["type"]) )
809
+      $options["type"] = "png";
810
+
811
+    $type = $options["type"];
812
+    
813
+    ob_start();
814
+
815
+    switch ($type) {
816
+
817
+    case "jpg":
818
+    case "jpeg":
819
+      if ( !isset($options["quality"]) )
820
+        $options["quality"] = 75;
821
+      
822
+      imagejpeg($dst, '', $options["quality"]);
823
+      break;
824
+
825
+    case "png":
826
+    default:
827
+      imagepng($dst);
828
+      break;
829
+    }
830
+
831
+    $image = ob_get_clean();
832
+
833
+    if ( $this->_aa_factor != 1 )
834
+      imagedestroy($dst);
835
+    
836
+    return $image;
837
+  }
838
+  
839
+  
840
+}

+ 185
- 0
vendor/dompdf/dompdf/include/image_cache.cls.php View File

@@ -0,0 +1,185 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
8
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
+ */
10
+
11
+/**
12
+ * Static class that resolves image urls and downloads and caches
13
+ * remote images if required.
14
+ *
15
+ * @access private
16
+ * @package dompdf
17
+ */
18
+class Image_Cache {
19
+
20
+  /**
21
+   * Array of downloaded images.  Cached so that identical images are
22
+   * not needlessly downloaded.
23
+   *
24
+   * @var array
25
+   */
26
+  static protected $_cache = array();
27
+  
28
+  /**
29
+   * The url to the "broken image" used when images can't be loade
30
+   * 
31
+   * @var string
32
+   */
33
+  public static $broken_image;
34
+
35
+  /**
36
+   * Resolve and fetch an image for use.
37
+   *
38
+   * @param string $url        The url of the image
39
+   * @param string $protocol   Default protocol if none specified in $url
40
+   * @param string $host       Default host if none specified in $url
41
+   * @param string $base_path  Default path if none specified in $url
42
+   * @param DOMPDF $dompdf     The DOMPDF instance
43
+   *
44
+   * @throws DOMPDF_Image_Exception
45
+   * @return array             An array with two elements: The local path to the image and the image extension
46
+   */
47
+  static function resolve_url($url, $protocol, $host, $base_path, DOMPDF $dompdf) {
48
+    $protocol = mb_strtolower($protocol);
49
+    $parsed_url = explode_url($url);
50
+    $message = null;
51
+
52
+    $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != "");
53
+    
54
+    $data_uri = strpos($parsed_url['protocol'], "data:") === 0;
55
+    $full_url = null;
56
+    $enable_remote = $dompdf->get_option("enable_remote");
57
+
58
+    try {
59
+      
60
+      // Remote not allowed and is not DataURI
61
+      if ( !$enable_remote && $remote && !$data_uri ) {
62
+        throw new DOMPDF_Image_Exception("DOMPDF_ENABLE_REMOTE is set to FALSE");
63
+      } 
64
+      
65
+      // Remote allowed or DataURI
66
+      else if ( $enable_remote && $remote || $data_uri ) {
67
+        // Download remote files to a temporary directory
68
+        $full_url = build_url($protocol, $host, $base_path, $url);
69
+  
70
+        // From cache
71
+        if ( isset(self::$_cache[$full_url]) ) {
72
+          $resolved_url = self::$_cache[$full_url];
73
+        }
74
+        
75
+        // From remote
76
+        else {
77
+          $tmp_dir = $dompdf->get_option("temp_dir");
78
+          $resolved_url = tempnam($tmp_dir, "ca_dompdf_img_");
79
+          $image = "";
80
+
81
+          if ($data_uri) {
82
+            if ($parsed_data_uri = parse_data_uri($url)) {
83
+              $image = $parsed_data_uri['data'];
84
+            }
85
+          }
86
+          else {
87
+            set_error_handler("record_warnings");
88
+            $image = file_get_contents($full_url, null, $dompdf->get_http_context());
89
+            restore_error_handler();
90
+          }
91
+  
92
+          // Image not found or invalid
93
+          if ( strlen($image) == 0 ) {
94
+            $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found");
95
+            throw new DOMPDF_Image_Exception($msg);
96
+          }
97
+          
98
+          // Image found, put in cache and process
99
+          else {
100
+            //e.g. fetch.php?media=url.jpg&cache=1
101
+            //- Image file name might be one of the dynamic parts of the url, don't strip off!
102
+            //- a remote url does not need to have a file extension at all
103
+            //- local cached file does not have a matching file extension
104
+            //Therefore get image type from the content
105
+            file_put_contents($resolved_url, $image);
106
+          }
107
+        }
108
+      }
109
+      
110
+      // Not remote, local image
111
+      else {
112
+        $resolved_url = build_url($protocol, $host, $base_path, $url);
113
+      }
114
+  
115
+      // Check if the local file is readable
116
+      if ( !is_readable($resolved_url) || !filesize($resolved_url) ) {
117
+        throw new DOMPDF_Image_Exception("Image not readable or empty");
118
+      }
119
+      
120
+      // Check is the file is an image
121
+      else {
122
+        list($width, $height, $type) = dompdf_getimagesize($resolved_url, $dompdf->get_http_context());
123
+        
124
+        // Known image type
125
+        if ( $width && $height && in_array($type, array(IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_BMP)) ) {
126
+          //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup.
127
+          //Only execute on successful caching of remote image.
128
+          if ( $enable_remote && $remote || $data_uri ) {
129
+            self::$_cache[$full_url] = $resolved_url;
130
+          }
131
+        }
132
+        
133
+        // Unknown image type
134
+        else {
135
+          throw new DOMPDF_Image_Exception("Image type unknown");
136
+        }
137
+      }
138
+    }
139
+    catch(DOMPDF_Image_Exception $e) {
140
+      $resolved_url = self::$broken_image;
141
+      $type = IMAGETYPE_PNG;
142
+      $message = "Image not found or type unknown";
143
+      $_dompdf_warnings[] = $e->getMessage()." :: $url";
144
+    }
145
+
146
+    return array($resolved_url, $type, $message);
147
+  }
148
+
149
+  /**
150
+   * Unlink all cached images (i.e. temporary images either downloaded
151
+   * or converted)
152
+   */
153
+  static function clear() {
154
+    if ( empty(self::$_cache) || DEBUGKEEPTEMP ) return;
155
+    
156
+    foreach ( self::$_cache as $file ) {
157
+      if (DEBUGPNG) print "[clear unlink $file]";
158
+      unlink($file);
159
+    }
160
+    
161
+    self::$_cache = array();
162
+  }
163
+  
164
+  static function detect_type($file, $context = null) {
165
+    list(, , $type) = dompdf_getimagesize($file, $context);
166
+    return $type;
167
+  }
168
+  
169
+  static function type_to_ext($type) {
170
+    $image_types = array(
171
+      IMAGETYPE_GIF  => "gif",
172
+      IMAGETYPE_PNG  => "png",
173
+      IMAGETYPE_JPEG => "jpeg",
174
+      IMAGETYPE_BMP  => "bmp",
175
+    );
176
+    
177
+    return (isset($image_types[$type]) ? $image_types[$type] : null);
178
+  }
179
+  
180
+  static function is_broken($url) {
181
+    return $url === self::$broken_image;
182
+  }
183
+}
184
+
185
+Image_Cache::$broken_image = DOMPDF_LIB_DIR . "/res/broken_image.png";

+ 80
- 0
vendor/dompdf/dompdf/include/image_frame_decorator.cls.php View File

@@ -0,0 +1,80 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Decorates frames for image layout and rendering
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Image_Frame_Decorator extends Frame_Decorator {
17
+
18
+  /**
19
+   * The path to the image file (note that remote images are
20
+   * downloaded locally to DOMPDF_TEMP_DIR).
21
+   *
22
+   * @var string
23
+   */
24
+  protected $_image_url;
25
+  
26
+  /**
27
+   * The image's file error message
28
+   *
29
+   * @var string
30
+   */
31
+  protected $_image_msg;
32
+
33
+  /**
34
+   * Class constructor
35
+   *
36
+   * @param Frame $frame the frame to decorate
37
+   * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls)
38
+   */
39
+  function __construct(Frame $frame, DOMPDF $dompdf) {
40
+    parent::__construct($frame, $dompdf);
41
+    $url = $frame->get_node()->getAttribute("src");
42
+
43
+    $debug_png = $dompdf->get_option("debug_png");
44
+    if ($debug_png) print '[__construct '.$url.']';
45
+
46
+    list($this->_image_url, /*$type*/, $this->_image_msg) = Image_Cache::resolve_url(
47
+      $url,
48
+      $dompdf->get_protocol(),
49
+      $dompdf->get_host(),
50
+      $dompdf->get_base_path(),
51
+      $dompdf
52
+    );
53
+
54
+    if ( Image_Cache::is_broken($this->_image_url) &&
55
+         $alt = $frame->get_node()->getAttribute("alt") ) {
56
+      $style = $frame->get_style();
57
+      $style->width  = (4/3)*Font_Metrics::get_text_width($alt, $style->font_family, $style->font_size, $style->word_spacing);
58
+      $style->height = Font_Metrics::get_font_height($style->font_family, $style->font_size);
59
+    }
60
+  }
61
+
62
+  /**
63
+   * Return the image's url
64
+   *
65
+   * @return string The url of this image
66
+   */
67
+  function get_image_url() {
68
+    return $this->_image_url;
69
+  }
70
+
71
+  /**
72
+   * Return the image's error message
73
+   *
74
+   * @return string The image's error message
75
+   */
76
+  function get_image_msg() {
77
+    return $this->_image_msg;
78
+  }
79
+  
80
+}

+ 186
- 0
vendor/dompdf/dompdf/include/image_frame_reflower.cls.php View File

@@ -0,0 +1,186 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Image reflower class
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Image_Frame_Reflower extends Frame_Reflower {
17
+
18
+  function __construct(Image_Frame_Decorator $frame) {
19
+    parent::__construct($frame);
20
+  }
21
+
22
+  function reflow(Block_Frame_Decorator $block = null) {
23
+    $this->_frame->position();
24
+    
25
+    //FLOAT
26
+    //$frame = $this->_frame;
27
+    //$page = $frame->get_root();
28
+
29
+    //$enable_css_float = $this->get_dompdf()->get_option("enable_css_float");
30
+    //if ($enable_css_float && $frame->get_style()->float !== "none" ) {
31
+    //  $page->add_floating_frame($this);
32
+    //}
33
+    // Set the frame's width
34
+    $this->get_min_max_width();
35
+    
36
+    if ( $block ) {
37
+      $block->add_frame_to_line($this->_frame);
38
+    }
39
+  }
40
+
41
+  function get_min_max_width() {
42
+    if (DEBUGPNG) {
43
+      // Determine the image's size. Time consuming. Only when really needed?
44
+      list($img_width, $img_height) = dompdf_getimagesize($this->_frame->get_image_url(), $this->get_dompdf()->get_http_context());
45
+      print "get_min_max_width() ".
46
+        $this->_frame->get_style()->width.' '.
47
+        $this->_frame->get_style()->height.';'.
48
+        $this->_frame->get_parent()->get_style()->width." ".
49
+        $this->_frame->get_parent()->get_style()->height.";".
50
+        $this->_frame->get_parent()->get_parent()->get_style()->width.' '.
51
+        $this->_frame->get_parent()->get_parent()->get_style()->height.';'.
52
+        $img_width. ' '.
53
+        $img_height.'|' ;
54
+    }
55
+
56
+    $style = $this->_frame->get_style();
57
+    
58
+    $width_forced = true;
59
+    $height_forced = true;
60
+
61
+    //own style auto or invalid value: use natural size in px
62
+    //own style value: ignore suffix text including unit, use given number as px
63
+    //own style %: walk up parent chain until found available space in pt; fill available space
64
+    //
65
+    //special ignored unit: e.g. 10ex: e treated as exponent; x ignored; 10e completely invalid ->like auto
66
+
67
+    $width = ($style->width > 0 ? $style->width : 0);
68
+    if ( is_percent($width) ) {
69
+      $t = 0.0;
70
+      for ($f = $this->_frame->get_parent(); $f; $f = $f->get_parent()) {
71
+        $f_style = $f->get_style();
72
+        $t = $f_style->length_in_pt($f_style->width);
73
+        if ($t != 0) {
74
+          break;
75
+        }
76
+      }
77
+      $width = ((float)rtrim($width,"%") * $t)/100; //maybe 0
78
+    } elseif ( !mb_strpos($width, 'pt') ) {
79
+      // Don't set image original size if "%" branch was 0 or size not given.
80
+      // Otherwise aspect changed on %/auto combination for width/height
81
+      // Resample according to px per inch
82
+      // See also List_Bullet_Image_Frame_Decorator::__construct
83
+      $width = $style->length_in_pt($width);
84
+    }
85
+
86
+    $height = ($style->height > 0 ? $style->height : 0);
87
+    if ( is_percent($height) ) {
88
+      $t = 0.0;
89
+      for ($f = $this->_frame->get_parent(); $f; $f = $f->get_parent()) {
90
+        $f_style = $f->get_style();
91
+        $t = $f_style->length_in_pt($f_style->height);
92
+        if ($t != 0) {
93
+          break;
94
+        }
95
+      }
96
+      $height = ((float)rtrim($height,"%") * $t)/100; //maybe 0
97
+    } elseif ( !mb_strpos($height, 'pt') ) {
98
+      // Don't set image original size if "%" branch was 0 or size not given.
99
+      // Otherwise aspect changed on %/auto combination for width/height
100
+      // Resample according to px per inch
101
+      // See also List_Bullet_Image_Frame_Decorator::__construct
102
+      $height = $style->length_in_pt($height);
103
+    }
104
+
105
+    if ($width == 0 || $height == 0) {
106
+      // Determine the image's size. Time consuming. Only when really needed!
107
+      list($img_width, $img_height) = dompdf_getimagesize($this->_frame->get_image_url(), $this->get_dompdf()->get_http_context());
108
+      
109
+      // don't treat 0 as error. Can be downscaled or can be catched elsewhere if image not readable.
110
+      // Resample according to px per inch
111
+      // See also List_Bullet_Image_Frame_Decorator::__construct
112
+      if ($width == 0 && $height == 0) {
113
+        $dpi = $this->_frame->get_dompdf()->get_option("dpi");
114
+        $width = (float)($img_width * 72) / $dpi;
115
+        $height = (float)($img_height * 72) / $dpi;
116
+        $width_forced = false;
117
+        $height_forced = false;
118
+      } elseif ($height == 0 && $width != 0) {
119
+        $height_forced = false;
120
+        $height = ($width / $img_width) * $img_height; //keep aspect ratio
121
+      } elseif ($width == 0 && $height != 0) {
122
+        $width_forced = false;
123
+        $width = ($height / $img_height) * $img_width; //keep aspect ratio
124
+      }
125
+    }
126
+    
127
+    // Handle min/max width/height
128
+    if ( $style->min_width  !== "none" || 
129
+         $style->max_width  !== "none" || 
130
+         $style->min_height !== "none" || 
131
+         $style->max_height !== "none" ) {
132
+           
133
+      list(/*$x*/, /*$y*/, $w, $h) = $this->_frame->get_containing_block();
134
+      
135
+      $min_width = $style->length_in_pt($style->min_width, $w);
136
+      $max_width = $style->length_in_pt($style->max_width, $w);
137
+      $min_height = $style->length_in_pt($style->min_height, $h);
138
+      $max_height = $style->length_in_pt($style->max_height, $h);
139
+  
140
+      if ( $max_width !== "none" && $width > $max_width ) {
141
+        if ( !$height_forced ) {
142
+          $height *= $max_width / $width;
143
+        }
144
+        
145
+        $width = $max_width;
146
+      }
147
+  
148
+      if ( $min_width !== "none" && $width < $min_width ) {
149
+        if ( !$height_forced ) {
150
+          $height *= $min_width / $width;
151
+        }
152
+        
153
+        $width = $min_width;
154
+      }
155
+      
156
+      if ( $max_height !== "none" && $height > $max_height ) {
157
+        if ( !$width_forced ) {
158
+          $width *= $max_height / $height;
159
+        }
160
+        
161
+        $height = $max_height;
162
+      }
163
+      
164
+      if ( $min_height !== "none" && $height < $min_height ) {
165
+        if ( !$width_forced ) {
166
+          $width *= $min_height / $height;
167
+        }
168
+        
169
+        $height = $min_height;
170
+      }
171
+    }
172
+    
173
+    if (DEBUGPNG) print $width.' '.$height.';';
174
+
175
+    $style->width = $width . "pt";
176
+    $style->height = $height . "pt";
177
+    
178
+    $style->min_width = "none";
179
+    $style->max_width = "none";
180
+    $style->min_height = "none";
181
+    $style->max_height = "none";
182
+
183
+    return array( $width, $width, "min" => $width, "max" => $width);
184
+    
185
+  }
186
+}

+ 119
- 0
vendor/dompdf/dompdf/include/image_renderer.cls.php View File

@@ -0,0 +1,119 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Image renderer
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Image_Renderer extends Block_Renderer {
17
+
18
+  function render(Frame $frame) {
19
+    // Render background & borders
20
+    $style = $frame->get_style();
21
+    $cb = $frame->get_containing_block();
22
+    list($x, $y, $w, $h) = $frame->get_border_box();
23
+  
24
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
25
+    
26
+    list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h);
27
+    
28
+    $has_border_radius = $tl + $tr + $br + $bl > 0;
29
+    
30
+    if ( $has_border_radius ) {
31
+      $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl );
32
+    }
33
+
34
+    if ( ($bg = $style->background_color) !== "transparent" ) {
35
+      $this->_canvas->filled_rectangle($x, $y, $w, $h, $bg);
36
+    }
37
+
38
+    if ( ($url = $style->background_image) && $url !== "none" ) {
39
+      $this->_background_image($url, $x, $y, $w, $h, $style);
40
+    }
41
+    
42
+    if ( $has_border_radius ) {
43
+      $this->_canvas->clipping_end();
44
+    }
45
+         
46
+    $this->_render_border($frame);
47
+    $this->_render_outline($frame);
48
+    
49
+    list($x, $y) = $frame->get_padding_box();
50
+    
51
+    $x += $style->length_in_pt($style->padding_left, $cb["w"]);
52
+    $y += $style->length_in_pt($style->padding_top, $cb["h"]);
53
+    
54
+    $w = $style->length_in_pt($style->width, $cb["w"]);
55
+    $h = $style->length_in_pt($style->height, $cb["h"]);
56
+    
57
+    if ( $has_border_radius ) {
58
+      list($wt, $wr, $wb, $wl) = array(
59
+        $style->border_top_width,
60
+        $style->border_right_width,
61
+        $style->border_bottom_width,
62
+        $style->border_left_width,
63
+      );
64
+      
65
+      // we have to get the "inner" radius
66
+      if ( $tl > 0 ) {
67
+        $tl -= ($wt + $wl) / 2;
68
+      }
69
+      if ( $tr > 0 ) {
70
+        $tr -= ($wt + $wr) / 2;
71
+      }
72
+      if ( $br > 0 ) {
73
+        $br -= ($wb + $wr) / 2;
74
+      }
75
+      if ( $bl > 0 ) {
76
+        $bl -= ($wb + $wl) / 2;
77
+      }
78
+      
79
+      $this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl );
80
+    }
81
+    
82
+    $src = $frame->get_image_url();
83
+    $alt = null;
84
+
85
+    if ( Image_Cache::is_broken($src) &&
86
+      $alt = $frame->get_node()->getAttribute("alt") ) {
87
+      $font = $style->font_family;
88
+      $size = $style->font_size;
89
+      $spacing = $style->word_spacing;
90
+      $this->_canvas->text($x, $y, $alt,
91
+                           $font, $size,
92
+                           $style->color, $spacing);
93
+    }
94
+    else {
95
+      $this->_canvas->image( $src, $x, $y, $w, $h, $style->image_resolution);
96
+    }
97
+    
98
+    if ( $has_border_radius ) {
99
+      $this->_canvas->clipping_end();
100
+    }
101
+    
102
+    if ( $msg = $frame->get_image_msg() ) {
103
+      $parts = preg_split("/\s*\n\s*/", $msg);
104
+      $height = 10;
105
+      $_y = $alt ? $y+$h-count($parts)*$height : $y;
106
+      
107
+      foreach($parts as $i => $_part) {
108
+        $this->_canvas->text($x, $_y + $i*$height, $_part, "times", $height*0.8, array(0.5, 0.5, 0.5));
109
+      }
110
+    }
111
+    
112
+    if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) {
113
+      $this->_debug_layout($frame->get_border_box(), "blue");
114
+      if (DEBUG_LAYOUT_PADDINGBOX) {
115
+        $this->_debug_layout($frame->get_padding_box(), "blue", array(0.5, 0.5));
116
+      }
117
+    }
118
+  }
119
+}

+ 74
- 0
vendor/dompdf/dompdf/include/inline_frame_decorator.cls.php View File

@@ -0,0 +1,74 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Decorates frames for inline layout
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Inline_Frame_Decorator extends Frame_Decorator {
17
+  
18
+  function __construct(Frame $frame, DOMPDF $dompdf) { parent::__construct($frame, $dompdf); }
19
+
20
+  function split(Frame $frame = null, $force_pagebreak = false) {
21
+
22
+    if ( is_null($frame) ) {
23
+      $this->get_parent()->split($this, $force_pagebreak);
24
+      return;
25
+    }
26
+
27
+    if ( $frame->get_parent() !== $this )
28
+      throw new DOMPDF_Exception("Unable to split: frame is not a child of this one.");
29
+        
30
+    $split = $this->copy( $this->_frame->get_node()->cloneNode() ); 
31
+    $this->get_parent()->insert_child_after($split, $this);
32
+
33
+    // Unset the current node's right style properties
34
+    $style = $this->_frame->get_style();
35
+    $style->margin_right = 0;
36
+    $style->padding_right = 0;
37
+    $style->border_right_width = 0;
38
+
39
+    // Unset the split node's left style properties since we don't want them
40
+    // to propagate
41
+    $style = $split->get_style();
42
+    $style->margin_left = 0;
43
+    $style->padding_left = 0;
44
+    $style->border_left_width = 0;
45
+
46
+    //On continuation of inline element on next line,
47
+    //don't repeat non-vertically repeatble background images
48
+    //See e.g. in testcase image_variants, long desriptions
49
+    if ( ($url = $style->background_image) && $url !== "none"
50
+         && ($repeat = $style->background_repeat) && $repeat !== "repeat" &&  $repeat !== "repeat-y"
51
+       ) {
52
+      $style->background_image = "none";
53
+    }           
54
+
55
+    // Add $frame and all following siblings to the new split node
56
+    $iter = $frame;
57
+    while ($iter) {
58
+      $frame = $iter;      
59
+      $iter = $iter->get_next_sibling();
60
+      $frame->reset();
61
+      $split->append_child($frame);
62
+    }
63
+    
64
+    $page_breaks = array("always", "left", "right");
65
+    $frame_style = $frame->get_style();
66
+    if( $force_pagebreak ||
67
+      in_array($frame_style->page_break_before, $page_breaks) ||
68
+      in_array($frame_style->page_break_after, $page_breaks) ) {
69
+
70
+      $this->get_parent()->split($split, true);
71
+    }
72
+  }
73
+  
74
+} 

+ 66
- 0
vendor/dompdf/dompdf/include/inline_frame_reflower.cls.php View File

@@ -0,0 +1,66 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows inline frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Inline_Frame_Reflower extends Frame_Reflower {
16
+
17
+  function __construct(Frame $frame) { parent::__construct($frame); }
18
+  
19
+  //........................................................................
20
+
21
+  function reflow(Block_Frame_Decorator $block = null) {
22
+    $frame = $this->_frame;
23
+    
24
+    // Check if a page break is forced
25
+    $page = $frame->get_root();
26
+    $page->check_forced_page_break($frame);
27
+    
28
+    if ( $page->is_full() )
29
+      return;
30
+      
31
+    $style = $frame->get_style();
32
+    
33
+    // Generated content
34
+    $this->_set_content();
35
+    
36
+    $frame->position();
37
+
38
+    $cb = $frame->get_containing_block();
39
+
40
+    // Add our margin, padding & border to the first and last children
41
+    if ( ($f = $frame->get_first_child()) && $f instanceof Text_Frame_Decorator ) {
42
+      $f_style = $f->get_style();
43
+      $f_style->margin_left  = $style->margin_left;
44
+      $f_style->padding_left = $style->padding_left;
45
+      $f_style->border_left  = $style->border_left;
46
+    }
47
+
48
+    if ( ($l = $frame->get_last_child()) && $l instanceof Text_Frame_Decorator ) {
49
+      $l_style = $l->get_style();
50
+      $l_style->margin_right  = $style->margin_right;
51
+      $l_style->padding_right = $style->padding_right;
52
+      $l_style->border_right  = $style->border_right;
53
+    }
54
+    
55
+    if ( $block ) {
56
+      $block->add_frame_to_line($this->_frame);
57
+    }
58
+
59
+    // Set the containing blocks and reflow each child.  The containing
60
+    // block is not changed by line boxes.
61
+    foreach ( $frame->get_children() as $child ) {
62
+      $child->set_containing_block($cb);
63
+      $child->reflow($block);
64
+    }
65
+  }
66
+}

+ 70
- 0
vendor/dompdf/dompdf/include/inline_positioner.cls.php View File

@@ -0,0 +1,70 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Positions inline frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Inline_Positioner extends Positioner {
16
+
17
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
18
+
19
+  //........................................................................
20
+
21
+  function position() {
22
+    /**
23
+     * Find our nearest block level parent and access its lines property.
24
+     * @var Block_Frame_Decorator
25
+     */ 
26
+    $p = $this->_frame->find_block_parent();
27
+
28
+    // Debugging code:
29
+
30
+//     pre_r("\nPositioning:");
31
+//     pre_r("Me: " . $this->_frame->get_node()->nodeName . " (" . spl_object_hash($this->_frame->get_node()) . ")");
32
+//     pre_r("Parent: " . $p->get_node()->nodeName . " (" . spl_object_hash($p->get_node()) . ")");
33
+
34
+    // End debugging
35
+
36
+    if ( !$p )
37
+      throw new DOMPDF_Exception("No block-level parent found.  Not good.");
38
+
39
+    $f = $this->_frame;
40
+    
41
+    $cb = $f->get_containing_block();
42
+    $line = $p->get_current_line_box();
43
+
44
+    // Skip the page break if in a fixed position element
45
+    $is_fixed = false;
46
+    while($f = $f->get_parent()) {
47
+      if($f->get_style()->position === "fixed") {
48
+        $is_fixed = true;
49
+        break;
50
+      }
51
+    }
52
+
53
+    $f = $this->_frame;
54
+
55
+    if ( !$is_fixed && $f->get_parent() &&
56
+         $f->get_parent() instanceof Inline_Frame_Decorator &&
57
+         $f->is_text_node() ) {
58
+      
59
+      $min_max = $f->get_reflower()->get_min_max_width();
60
+      
61
+      // If the frame doesn't fit in the current line, a line break occurs
62
+      if ( $min_max["min"] > ($cb["w"] - $line->left - $line->w - $line->right) ) {
63
+        $p->add_line();
64
+      }
65
+    }
66
+    
67
+    $f->set_position($cb["x"] + $line->w, $line->y);
68
+
69
+  }
70
+}

+ 190
- 0
vendor/dompdf/dompdf/include/inline_renderer.cls.php View File

@@ -0,0 +1,190 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Renders inline frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Inline_Renderer extends Abstract_Renderer {
16
+  
17
+  //........................................................................
18
+
19
+  function render(Frame $frame) {
20
+    $style = $frame->get_style();
21
+
22
+    if ( !$frame->get_first_child() )
23
+      return; // No children, no service
24
+    
25
+    // Draw the left border if applicable
26
+    $bp = $style->get_border_properties();
27
+    $widths = array($style->length_in_pt($bp["top"]["width"]),
28
+                    $style->length_in_pt($bp["right"]["width"]),
29
+                    $style->length_in_pt($bp["bottom"]["width"]),
30
+                    $style->length_in_pt($bp["left"]["width"]));
31
+
32
+    // Draw the background & border behind each child.  To do this we need
33
+    // to figure out just how much space each child takes:
34
+    list($x, $y) = $frame->get_first_child()->get_position();
35
+    $w = null;
36
+    $h = 0;
37
+//     $x += $widths[3];
38
+//     $y += $widths[0];
39
+    
40
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
41
+    
42
+    $first_row = true;
43
+
44
+    foreach ($frame->get_children() as $child) {
45
+      list($child_x, $child_y, $child_w, $child_h) = $child->get_padding_box();
46
+      
47
+      if ( !is_null($w) && $child_x < $x + $w ) {
48
+        //This branch seems to be supposed to being called on the first part
49
+        //of an inline html element, and the part after the if clause for the
50
+        //parts after a line break.
51
+        //But because $w initially mostly is 0, and gets updated only on the next
52
+        //round, this seem to be never executed and the common close always.
53
+
54
+        // The next child is on another line.  Draw the background &
55
+        // borders on this line.
56
+
57
+        // Background:
58
+        if ( ($bg = $style->background_color) !== "transparent" )
59
+          $this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg);
60
+
61
+        if ( ($url = $style->background_image) && $url !== "none" ) {
62
+          $this->_background_image($url, $x, $y, $w, $h, $style);
63
+        }
64
+
65
+        // If this is the first row, draw the left border
66
+        if ( $first_row ) {
67
+
68
+          if ( $bp["left"]["style"] !== "none" && $bp["left"]["color"] !== "transparent" && $bp["left"]["width"] > 0 ) {
69
+            $method = "_border_" . $bp["left"]["style"];            
70
+            $this->$method($x, $y, $h + $widths[0] + $widths[2], $bp["left"]["color"], $widths, "left");
71
+          }
72
+          $first_row = false;
73
+        }
74
+
75
+        // Draw the top & bottom borders
76
+        if ( $bp["top"]["style"] !== "none" && $bp["top"]["color"] !== "transparent" && $bp["top"]["width"] > 0 ) {
77
+          $method = "_border_" . $bp["top"]["style"];
78
+          $this->$method($x, $y, $w + $widths[1] + $widths[3], $bp["top"]["color"], $widths, "top");
79
+        }
80
+        
81
+        if ( $bp["bottom"]["style"] !== "none" && $bp["bottom"]["color"] !== "transparent" && $bp["bottom"]["width"] > 0 ) {
82
+          $method = "_border_" . $bp["bottom"]["style"];
83
+          $this->$method($x, $y + $h + $widths[0] + $widths[2], $w + $widths[1] + $widths[3], $bp["bottom"]["color"], $widths, "bottom");
84
+        }
85
+
86
+        // Handle anchors & links
87
+        $link_node = null;
88
+        if ( $frame->get_node()->nodeName === "a" ) {
89
+          $link_node = $frame->get_node();
90
+        }
91
+        else if ( $frame->get_parent()->get_node()->nodeName === "a" ){
92
+          $link_node = $frame->get_parent()->get_node();
93
+        }
94
+        
95
+        if ( $link_node && $href = $link_node->getAttribute("href") ) {
96
+          $this->_canvas->add_link($href, $x, $y, $w, $h);
97
+        }
98
+
99
+        $x = $child_x;
100
+        $y = $child_y;
101
+        $w = $child_w;
102
+        $h = $child_h;
103
+        continue;
104
+      }
105
+
106
+      if ( is_null($w) )
107
+        $w = $child_w;
108
+      else
109
+        $w += $child_w;
110
+      
111
+      $h = max($h, $child_h);
112
+
113
+      if (DEBUG_LAYOUT && DEBUG_LAYOUT_INLINE) {
114
+        $this->_debug_layout($child->get_border_box(), "blue");
115
+        if (DEBUG_LAYOUT_PADDINGBOX) {
116
+          $this->_debug_layout($child->get_padding_box(), "blue", array(0.5, 0.5));
117
+        }
118
+      }
119
+    }
120
+
121
+    
122
+    // Handle the last child
123
+    if ( ($bg = $style->background_color) !== "transparent" ) 
124
+      $this->_canvas->filled_rectangle( $x + $widths[3], $y + $widths[0], $w, $h, $bg);
125
+
126
+    //On continuation lines (after line break) of inline elements, the style got copied.
127
+    //But a non repeatable background image should not be repeated on the next line.
128
+    //But removing the background image above has never an effect, and removing it below
129
+    //removes it always, even on the initial line.
130
+    //Need to handle it elsewhere, e.g. on certain ...clone()... usages.    
131
+    // Repeat not given: default is Style::__construct
132
+    // ... && (!($repeat = $style->background_repeat) || $repeat === "repeat" ...
133
+    //different position? $this->_background_image($url, $x, $y, $w, $h, $style);
134
+    if ( ($url = $style->background_image) && $url !== "none" )           
135
+      $this->_background_image($url, $x + $widths[3], $y + $widths[0], $w, $h, $style);
136
+        
137
+    // Add the border widths
138
+    $w += $widths[1] + $widths[3];
139
+    $h += $widths[0] + $widths[2];
140
+
141
+    // make sure the border and background start inside the left margin
142
+    $left_margin = $style->length_in_pt($style->margin_left);
143
+    $x += $left_margin;
144
+
145
+    // If this is the first row, draw the left border too
146
+    if ( $first_row && $bp["left"]["style"] !== "none" && $bp["left"]["color"] !== "transparent" && $widths[3] > 0 ) {
147
+      $method = "_border_" . $bp["left"]["style"];
148
+      $this->$method($x, $y, $h, $bp["left"]["color"], $widths, "left");
149
+    }
150
+    
151
+    // Draw the top & bottom borders
152
+    if ( $bp["top"]["style"] !== "none" && $bp["top"]["color"] !== "transparent" && $widths[0] > 0 ) {
153
+      $method = "_border_" . $bp["top"]["style"];
154
+      $this->$method($x, $y, $w, $bp["top"]["color"], $widths, "top");
155
+    }
156
+    
157
+    if ( $bp["bottom"]["style"] !== "none" && $bp["bottom"]["color"] !== "transparent" && $widths[2] > 0 ) {
158
+      $method = "_border_" . $bp["bottom"]["style"];
159
+      $this->$method($x, $y + $h, $w, $bp["bottom"]["color"], $widths, "bottom");
160
+    }
161
+
162
+    //    pre_var_dump(get_class($frame->get_next_sibling()));
163
+    //    $last_row = get_class($frame->get_next_sibling()) !== 'Inline_Frame_Decorator';
164
+    // Draw the right border if this is the last row
165
+    if ( $bp["right"]["style"] !== "none" && $bp["right"]["color"] !== "transparent" && $widths[1] > 0 ) {
166
+      $method = "_border_" . $bp["right"]["style"];
167
+      $this->$method($x + $w, $y, $h, $bp["right"]["color"], $widths, "right");
168
+    }
169
+
170
+    // Only two levels of links frames
171
+    $link_node = null;
172
+    if ( $frame->get_node()->nodeName === "a" ) {
173
+      $link_node = $frame->get_node();
174
+      
175
+      if ( ($name = $link_node->getAttribute("name")) || ($name = $link_node->getAttribute("id")) ) {
176
+        $this->_canvas->add_named_dest($name);
177
+      }
178
+    }
179
+    
180
+    if ( $frame->get_parent() && $frame->get_parent()->get_node()->nodeName === "a" ){
181
+      $link_node = $frame->get_parent()->get_node();
182
+    }
183
+    
184
+    // Handle anchors & links
185
+    if ( $link_node ) {
186
+      if ( $href = $link_node->getAttribute("href") )
187
+        $this->_canvas->add_link($href, $x, $y, $w, $h);
188
+    }
189
+  }
190
+}

+ 37
- 0
vendor/dompdf/dompdf/include/javascript_embedder.cls.php View File

@@ -0,0 +1,37 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Embeds Javascript into the PDF document
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Javascript_Embedder {
16
+  
17
+  /**
18
+   * @var DOMPDF
19
+   */
20
+  protected $_dompdf;
21
+
22
+  function __construct(DOMPDF $dompdf) {
23
+    $this->_dompdf = $dompdf;
24
+  }
25
+
26
+  function insert($script) {
27
+    $this->_dompdf->get_canvas()->javascript($script);
28
+  }
29
+
30
+  function render(Frame $frame) {
31
+    if ( !$this->_dompdf->get_option("enable_javascript") ) {
32
+      return;
33
+    }
34
+      
35
+    $this->insert($frame->get_node()->nodeValue);
36
+  }
37
+}

+ 252
- 0
vendor/dompdf/dompdf/include/line_box.cls.php View File

@@ -0,0 +1,252 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * The line box class
11
+ *
12
+ * This class represents a line box
13
+ * http://www.w3.org/TR/CSS2/visuren.html#line-box
14
+ *
15
+ * @access protected
16
+ * @package dompdf
17
+ */
18
+class Line_Box {
19
+
20
+  /**
21
+   * @var Block_Frame_Decorator
22
+   */
23
+  protected $_block_frame;
24
+
25
+  /**
26
+   * @var Frame[]
27
+   */
28
+  protected $_frames = array();
29
+  
30
+  /**
31
+   * @var integer
32
+   */
33
+  public $wc = 0;
34
+  
35
+  /**
36
+   * @var float
37
+   */
38
+  public $y = null;
39
+  
40
+  /**
41
+   * @var float
42
+   */
43
+  public $w = 0.0;
44
+  
45
+  /**
46
+   * @var float
47
+   */
48
+  public $h = 0.0;
49
+  
50
+  /**
51
+   * @var float
52
+   */
53
+  public $left = 0.0;
54
+  
55
+  /**
56
+   * @var float
57
+   */
58
+  public $right = 0.0;
59
+  
60
+  /**
61
+   * @var Frame
62
+   */
63
+  public $tallest_frame = null;
64
+
65
+  /**
66
+   * @var bool[]
67
+   */
68
+  public $floating_blocks = array();
69
+  
70
+  /**
71
+   * @var bool
72
+   */
73
+  public $br = false;
74
+  
75
+  /**
76
+   * Class constructor
77
+   *
78
+   * @param Block_Frame_Decorator $frame the Block_Frame_Decorator containing this line
79
+   */
80
+  function __construct(Block_Frame_Decorator $frame, $y = 0) {
81
+    $this->_block_frame = $frame;
82
+    $this->_frames = array();
83
+    $this->y = $y;
84
+    
85
+    $this->get_float_offsets();
86
+  }
87
+  
88
+  /**
89
+   * Returns the floating elements inside the first floating parent
90
+   *
91
+   * @param Page_Frame_Decorator $root
92
+   *
93
+   * @return Frame[]
94
+   */
95
+  function get_floats_inside(Page_Frame_Decorator $root) {
96
+    $floating_frames = $root->get_floating_frames();
97
+    
98
+    if ( count($floating_frames) == 0 ) {
99
+      return $floating_frames;
100
+    }
101
+    
102
+    // Find nearest floating element
103
+    $p = $this->_block_frame;
104
+    while( $p->get_style()->float === "none" ) {
105
+      $parent = $p->get_parent();
106
+      
107
+      if ( !$parent ) {
108
+        break;
109
+      }
110
+      
111
+      $p = $parent;
112
+    }
113
+    
114
+    if ( $p == $root ) {
115
+      return $floating_frames;
116
+    }
117
+    
118
+    $parent = $p;
119
+    
120
+    $childs = array();
121
+    
122
+    foreach ($floating_frames as $_floating) {
123
+      $p = $_floating->get_parent();
124
+      
125
+      while (($p = $p->get_parent()) && $p !== $parent);
126
+      
127
+      if ( $p ) {
128
+        $childs[] = $p;
129
+      }
130
+    }
131
+    
132
+    return $childs;
133
+  }
134
+  
135
+  function get_float_offsets() {
136
+    $enable_css_float = $this->_block_frame->get_dompdf()->get_option("enable_css_float");
137
+    if ( !$enable_css_float ) {
138
+      return;
139
+    }
140
+      
141
+    static $anti_infinite_loop = 500; // FIXME smelly hack
142
+    
143
+    $reflower = $this->_block_frame->get_reflower();
144
+    
145
+    if ( !$reflower ) {
146
+      return;
147
+    }
148
+    
149
+    $cb_w = null;
150
+  
151
+    $block = $this->_block_frame;
152
+    $root = $block->get_root();
153
+    
154
+    if ( !$root ) {
155
+      return;
156
+    }
157
+    
158
+    $floating_frames = $this->get_floats_inside($root);
159
+    
160
+    foreach ( $floating_frames as $child_key => $floating_frame ) {
161
+      $id = $floating_frame->get_id();
162
+      
163
+      if ( isset($this->floating_blocks[$id]) ) {
164
+        continue;
165
+      }
166
+      
167
+      $floating_style = $floating_frame->get_style();
168
+      $float = $floating_style->float;
169
+      
170
+      $floating_width = $floating_frame->get_margin_width();
171
+      
172
+      if (!$cb_w) {
173
+        $cb_w = $floating_frame->get_containing_block("w");
174
+      }
175
+      
176
+      $line_w = $this->get_width();
177
+      
178
+      if ( !$floating_frame->_float_next_line && ($cb_w <= $line_w + $floating_width) && ($cb_w > $line_w) ) {
179
+        $floating_frame->_float_next_line = true;
180
+        continue;
181
+      }
182
+      
183
+      // If the child is still shifted by the floating element
184
+      if ( $anti_infinite_loop-- > 0 &&
185
+           $floating_frame->get_position("y") + $floating_frame->get_margin_height() > $this->y && 
186
+           $block->get_position("x") + $block->get_margin_width() > $floating_frame->get_position("x")
187
+           ) {
188
+        if ( $float === "left" )
189
+          $this->left  += $floating_width;
190
+        else
191
+          $this->right += $floating_width;
192
+        
193
+        $this->floating_blocks[$id] = true;
194
+      }
195
+      
196
+      // else, the floating element won't shift anymore
197
+      else {
198
+        $root->remove_floating_frame($child_key);
199
+      }
200
+    }
201
+  }
202
+
203
+  /**
204
+   * @return float
205
+   */
206
+  function get_width(){
207
+    return $this->left + $this->w + $this->right;
208
+  }
209
+
210
+  /**
211
+   * @return Block_Frame_Decorator
212
+   */
213
+  function get_block_frame() {
214
+    return $this->_block_frame;
215
+  }
216
+
217
+  /**
218
+   * @return Frame[]
219
+   */
220
+  function &get_frames() {
221
+    return $this->_frames;
222
+  }
223
+
224
+  /**
225
+   * @param Frame $frame
226
+   */
227
+  function add_frame(Frame $frame) {
228
+    $this->_frames[] = $frame;
229
+  }
230
+  
231
+  function __toString(){
232
+    $props = array("wc", "y", "w", "h", "left", "right", "br");
233
+    $s = "";
234
+    foreach($props as $prop) {
235
+      $s .= "$prop: ".$this->$prop."\n";
236
+    }
237
+    $s .= count($this->_frames)." frames\n";
238
+    return $s;
239
+  }
240
+  /*function __get($prop) {
241
+    if (!isset($this->{"_$prop"})) return;
242
+    return $this->{"_$prop"};
243
+  }*/
244
+}
245
+
246
+/*
247
+class LineBoxList implements Iterator {
248
+  private $_p = 0;
249
+  private $_lines = array();
250
+  
251
+}
252
+*/

+ 65
- 0
vendor/dompdf/dompdf/include/list_bullet_frame_decorator.cls.php View File

@@ -0,0 +1,65 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Decorates frames for list bullet rendering
12
+ *
13
+ * @access private
14
+ * @package dompdf 
15
+ */
16
+class List_Bullet_Frame_Decorator extends Frame_Decorator {
17
+
18
+  const BULLET_PADDING = 1; // Distance from bullet to text in pt
19
+  // As fraction of font size (including descent). See also DECO_THICKNESS.
20
+  const BULLET_THICKNESS = 0.04;   // Thickness of bullet outline. Screen: 0.08, print: better less, e.g. 0.04
21
+  const BULLET_DESCENT = 0.3;  //descent of font below baseline. Todo: Guessed for now.
22
+  const BULLET_SIZE = 0.35;   // bullet diameter. For now 0.5 of font_size without descent.
23
+  
24
+  static $BULLET_TYPES = array("disc", "circle", "square");
25
+  
26
+  //........................................................................
27
+
28
+  function __construct(Frame $frame, DOMPDF $dompdf) {
29
+    parent::__construct($frame, $dompdf);
30
+  }
31
+  
32
+  function get_margin_width() {
33
+    $style = $this->_frame->get_style();
34
+    
35
+    // Small hack to prevent extra indenting of list text on list_style_position === "inside"
36
+    // and on suppressed bullet
37
+    if ( $style->list_style_position === "outside" ||
38
+         $style->list_style_type === "none" ) {
39
+      return 0;
40
+    }
41
+    
42
+    return $style->get_font_size() * self::BULLET_SIZE + 2 * self::BULLET_PADDING;
43
+  }
44
+
45
+  //hits only on "inset" lists items, to increase height of box
46
+  function get_margin_height() {
47
+    $style = $this->_frame->get_style();
48
+    
49
+    if ( $style->list_style_type === "none" ) {
50
+      return 0;
51
+    }
52
+    
53
+    return $style->get_font_size() * self::BULLET_SIZE + 2 * self::BULLET_PADDING;
54
+  }
55
+
56
+  function get_width() {
57
+    return $this->get_margin_height();
58
+  }
59
+  
60
+  function get_height() {
61
+    return $this->get_margin_height();
62
+  }
63
+  
64
+  //........................................................................
65
+}

+ 33
- 0
vendor/dompdf/dompdf/include/list_bullet_frame_reflower.cls.php View File

@@ -0,0 +1,33 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows list bullets
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class List_Bullet_Frame_Reflower extends Frame_Reflower {
16
+
17
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
18
+    
19
+  //........................................................................
20
+
21
+  function reflow(Block_Frame_Decorator $block = null) {
22
+    $style = $this->_frame->get_style();
23
+
24
+    $style->width = $this->_frame->get_width();
25
+    $this->_frame->position();
26
+
27
+    if ( $style->list_style_position === "inside" ) {
28
+      $p = $this->_frame->find_block_parent();
29
+      $p->add_frame_to_line($this->_frame);
30
+    }
31
+
32
+  }
33
+}

+ 143
- 0
vendor/dompdf/dompdf/include/list_bullet_image_frame_decorator.cls.php View File

@@ -0,0 +1,143 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Decorates frames for list bullets with custom images
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class List_Bullet_Image_Frame_Decorator extends Frame_Decorator {
17
+
18
+  /**
19
+   * The underlying image frame
20
+   * 
21
+   * @var Image_Frame_Decorator
22
+   */
23
+  protected $_img;
24
+
25
+  /**
26
+   * The image's width in pixels
27
+   *
28
+   * @var int
29
+   */
30
+  protected $_width;
31
+  
32
+  /**
33
+   * The image's height in pixels
34
+   *
35
+   * @var int
36
+   */
37
+  protected $_height;
38
+
39
+  /**
40
+   * Class constructor
41
+   *
42
+   * @param Frame $frame the bullet frame to decorate
43
+   * @param DOMPDF $dompdf the document's dompdf object
44
+   */
45
+  function __construct(Frame $frame, DOMPDF $dompdf) {
46
+    $style = $frame->get_style();
47
+    $url = $style->list_style_image;
48
+    $frame->get_node()->setAttribute("src", $url);
49
+    $this->_img = new Image_Frame_Decorator($frame, $dompdf);
50
+    parent::__construct($this->_img, $dompdf);
51
+    list($width, $height) = dompdf_getimagesize($this->_img->get_image_url(), $dompdf->get_http_context());
52
+
53
+    // Resample the bullet image to be consistent with 'auto' sized images
54
+    // See also Image_Frame_Reflower::get_min_max_width
55
+    // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary.
56
+    $dpi = $this->_dompdf->get_option("dpi");
57
+    $this->_width = ((float)rtrim($width, "px") * 72) / $dpi;
58
+    $this->_height = ((float)rtrim($height, "px") * 72) / $dpi;
59
+ 
60
+    //If an image is taller as the containing block/box, the box should be extended.
61
+    //Neighbour elements are overwriting the overlapping image areas.
62
+    //Todo: Where can the box size be extended?   
63
+    //Code below has no effect.
64
+    //See block_frame_reflower _calculate_restricted_height
65
+    //See generated_frame_reflower, Dompdf:render() "list-item", "-dompdf-list-bullet"S.
66
+    //Leave for now    
67
+    //if ($style->min_height < $this->_height ) {
68
+    //  $style->min_height = $this->_height;
69
+    //}
70
+    //$style->height = "auto";   
71
+  }
72
+
73
+  /**
74
+   * Return the bullet's width
75
+   *
76
+   * @return int
77
+   */
78
+  function get_width() {
79
+    //ignore image width, use same width as on predefined bullet List_Bullet_Frame_Decorator
80
+    //for proper alignment of bullet image and text. Allow image to not fitting on left border.
81
+    //This controls the distance between bullet image and text 
82
+    //return $this->_width;
83
+    return $this->_frame->get_style()->get_font_size()*List_Bullet_Frame_Decorator::BULLET_SIZE + 
84
+      2 * List_Bullet_Frame_Decorator::BULLET_PADDING;
85
+  }
86
+
87
+  /**
88
+   * Return the bullet's height
89
+   *
90
+   * @return int
91
+   */
92
+  function get_height() {
93
+    //based on image height
94
+    return $this->_height;
95
+  }
96
+  
97
+  /**
98
+   * Override get_margin_width
99
+   *
100
+   * @return int
101
+   */
102
+  function get_margin_width() {
103
+    //ignore image width, use same width as on predefined bullet List_Bullet_Frame_Decorator
104
+    //for proper alignment of bullet image and text. Allow image to not fitting on left border.
105
+    //This controls the extra indentation of text to make room for the bullet image.
106
+    //Here use actual image size, not predefined bullet size 
107
+    //return $this->_frame->get_style()->get_font_size()*List_Bullet_Frame_Decorator::BULLET_SIZE + 
108
+    //  2 * List_Bullet_Frame_Decorator::BULLET_PADDING;
109
+
110
+    // Small hack to prevent indenting of list text
111
+    // Image Might not exist, then position like on list_bullet_frame_decorator fallback to none. 
112
+    if ( $this->_frame->get_style()->list_style_position === "outside" ||
113
+         $this->_width == 0) 
114
+      return 0;
115
+    //This aligns the "inside" image position with the text.
116
+    //The text starts to the right of the image.
117
+    //Between the image and the text there is an added margin of image width.
118
+    //Where this comes from is unknown.
119
+    //The corresponding List_Bullet_Frame_Decorator sets a smaller margin. bullet size?
120
+    return $this->_width + 2 * List_Bullet_Frame_Decorator::BULLET_PADDING;
121
+  }
122
+
123
+  /**
124
+   * Override get_margin_height()
125
+   *
126
+   * @return int
127
+   */
128
+  function get_margin_height() {
129
+    //Hits only on "inset" lists items, to increase height of box
130
+    //based on image height
131
+    return $this->_height + 2 * List_Bullet_Frame_Decorator::BULLET_PADDING;
132
+  }
133
+
134
+  /**
135
+   * Return image url
136
+   *
137
+   * @return string
138
+   */
139
+  function get_image_url() {
140
+    return $this->_img->get_image_url();
141
+  }
142
+  
143
+}

+ 73
- 0
vendor/dompdf/dompdf/include/list_bullet_positioner.cls.php View File

@@ -0,0 +1,73 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Positions list bullets
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class List_Bullet_Positioner extends Positioner {
17
+
18
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
19
+  
20
+  //........................................................................
21
+
22
+  function position() {
23
+    
24
+    // Bullets & friends are positioned an absolute distance to the left of
25
+    // the content edge of their parent element
26
+    $cb = $this->_frame->get_containing_block();
27
+    
28
+    // Note: this differs from most frames in that we must position
29
+    // ourselves after determining our width
30
+    $x = $cb["x"] - $this->_frame->get_width();
31
+
32
+    $p = $this->_frame->find_block_parent();
33
+
34
+    $y = $p->get_current_line_box()->y;
35
+
36
+    // This is a bit of a hack...
37
+    $n = $this->_frame->get_next_sibling();
38
+    if ( $n ) {
39
+      $style = $n->get_style();
40
+      $line_height = $style->length_in_pt($style->line_height, $style->get_font_size());
41
+      $offset = $style->length_in_pt($line_height, $n->get_containing_block("h")) - $this->_frame->get_height();             
42
+      $y += $offset / 2;
43
+    }
44
+
45
+  // Now the position is the left top of the block which should be marked with the bullet.
46
+  // We tried to find out the y of the start of the first text character within the block.
47
+  // But the top margin/padding does not fit, neither from this nor from the next sibling
48
+  // The "bit of a hack" above does not work also.
49
+  
50
+  // Instead let's position the bullet vertically centered to the block which should be marked.
51
+  // But for get_next_sibling() the get_containing_block is all zero, and for find_block_parent()
52
+  // the get_containing_block is paper width and the entire list as height.
53
+  
54
+    // if ($p) {
55
+    //   //$cb = $n->get_containing_block();
56
+    //   $cb = $p->get_containing_block();
57
+    //   $y += $cb["h"]/2;
58
+    // print 'cb:'.$cb["x"].':'.$cb["y"].':'.$cb["w"].':'.$cb["h"].':';
59
+    // }   
60
+
61
+  // Todo:
62
+  // For now give up on the above. Use Guesswork with font y-pos in the middle of the line spacing
63
+
64
+    /*$style = $p->get_style();
65
+    $font_size = $style->get_font_size();
66
+    $line_height = $style->length_in_pt($style->line_height, $font_size);
67
+    $y += ($line_height - $font_size) / 2;    */
68
+   
69
+    //Position is x-end y-top of character position of the bullet.    
70
+    $this->_frame->set_position($x, $y);
71
+    
72
+  }
73
+}

+ 236
- 0
vendor/dompdf/dompdf/include/list_bullet_renderer.cls.php View File

@@ -0,0 +1,236 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Helmut Tischer <htischer@weihenstephan.org>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Renders list bullets
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class List_Bullet_Renderer extends Abstract_Renderer {
17
+  static function get_counter_chars($type) {
18
+    static $cache = array();
19
+    
20
+    if ( isset($cache[$type]) ) {
21
+      return $cache[$type];
22
+    }
23
+    
24
+    $uppercase = false;
25
+    $text = "";
26
+    
27
+    switch ($type) {
28
+      case "decimal-leading-zero":
29
+      case "decimal":
30
+      case "1":
31
+        return "0123456789";
32
+      
33
+      case "upper-alpha":
34
+      case "upper-latin":
35
+      case "A":
36
+        $uppercase = true;
37
+      case "lower-alpha":
38
+      case "lower-latin":
39
+      case "a":
40
+        $text = "abcdefghijklmnopqrstuvwxyz";
41
+        break;
42
+        
43
+      case "upper-roman":
44
+      case "I":
45
+        $uppercase = true;
46
+      case "lower-roman":
47
+      case "i":
48
+        $text = "ivxlcdm";
49
+        break;
50
+      
51
+      case "lower-greek":
52
+        for($i = 0; $i < 24; $i++) {
53
+          $text .= unichr($i+944);
54
+        }
55
+        break;
56
+    }
57
+    
58
+    if ( $uppercase ) {
59
+      $text = strtoupper($text);
60
+    }
61
+    
62
+    return $cache[$type] = "$text.";
63
+  }
64
+
65
+  /**
66
+   * @param integer $n
67
+   * @param string  $type
68
+   * @param integer $pad
69
+   *
70
+   * @return string
71
+   */
72
+  private function make_counter($n, $type, $pad = null){
73
+    $n = intval($n);
74
+    $text = "";
75
+    $uppercase = false;
76
+    
77
+    switch ($type) {
78
+      case "decimal-leading-zero":
79
+      case "decimal":
80
+      case "1":
81
+        if ($pad) 
82
+          $text = str_pad($n, $pad, "0", STR_PAD_LEFT);
83
+        else 
84
+          $text = $n;
85
+        break;
86
+      
87
+      case "upper-alpha":
88
+      case "upper-latin":
89
+      case "A":
90
+        $uppercase = true;
91
+      case "lower-alpha":
92
+      case "lower-latin":
93
+      case "a":
94
+        $text = chr( ($n % 26) + ord('a') - 1);
95
+        break;
96
+        
97
+      case "upper-roman":
98
+      case "I":
99
+        $uppercase = true;
100
+      case "lower-roman":
101
+      case "i":
102
+        $text = dec2roman($n);
103
+        break;
104
+      
105
+      case "lower-greek":
106
+        $text = unichr($n + 944);
107
+        break;
108
+    }
109
+    
110
+    if ( $uppercase ) {
111
+      $text = strtoupper($text);
112
+    }
113
+    
114
+    return "$text.";
115
+  }
116
+  
117
+  function render(Frame $frame) {
118
+    $style = $frame->get_style();
119
+    $font_size = $style->get_font_size();
120
+    $line_height = $style->length_in_pt($style->line_height, $frame->get_containing_block("w"));
121
+
122
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
123
+
124
+    $li = $frame->get_parent();
125
+
126
+    // Don't render bullets twice if if was split
127
+    if ($li->_splitted) {
128
+      return;
129
+    }
130
+
131
+    // Handle list-style-image
132
+    // If list style image is requested but missing, fall back to predefined types
133
+    if ( $style->list_style_image !== "none" &&
134
+         !Image_Cache::is_broken($img = $frame->get_image_url())) {
135
+
136
+      list($x,$y) = $frame->get_position();
137
+      
138
+      //For expected size and aspect, instead of box size, use image natural size scaled to DPI.
139
+      // Resample the bullet image to be consistent with 'auto' sized images
140
+      // See also Image_Frame_Reflower::get_min_max_width
141
+      // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary.
142
+      //$w = $frame->get_width();
143
+      //$h = $frame->get_height();
144
+      list($width, $height) = dompdf_getimagesize($img, $this->_dompdf->get_http_context());
145
+      $dpi = $this->_dompdf->get_option("dpi");
146
+      $w = ((float)rtrim($width, "px") * 72) / $dpi;
147
+      $h = ((float)rtrim($height, "px") * 72) / $dpi;
148
+      
149
+      $x -= $w;
150
+      $y -= ($line_height - $font_size)/2; //Reverse hinting of list_bullet_positioner
151
+
152
+      $this->_canvas->image( $img, $x, $y, $w, $h);
153
+
154
+    } else {
155
+
156
+      $bullet_style = $style->list_style_type;
157
+
158
+      $fill = false;
159
+
160
+      switch ($bullet_style) {
161
+
162
+      default:
163
+      case "disc":
164
+        $fill = true;
165
+
166
+      case "circle":
167
+        list($x,$y) = $frame->get_position();
168
+        $r = ($font_size*(List_Bullet_Frame_Decorator::BULLET_SIZE /*-List_Bullet_Frame_Decorator::BULLET_THICKNESS*/ ))/2;
169
+        $x -= $font_size*(List_Bullet_Frame_Decorator::BULLET_SIZE/2);
170
+        $y += ($font_size*(1-List_Bullet_Frame_Decorator::BULLET_DESCENT))/2;
171
+        $o = $font_size*List_Bullet_Frame_Decorator::BULLET_THICKNESS;
172
+        $this->_canvas->circle($x, $y, $r, $style->color, $o, null, $fill);
173
+        break;
174
+
175
+      case "square":
176
+        list($x, $y) = $frame->get_position();
177
+        $w = $font_size*List_Bullet_Frame_Decorator::BULLET_SIZE;
178
+        $x -= $w;
179
+        $y += ($font_size*(1-List_Bullet_Frame_Decorator::BULLET_DESCENT-List_Bullet_Frame_Decorator::BULLET_SIZE))/2;
180
+        $this->_canvas->filled_rectangle($x, $y, $w, $w, $style->color);
181
+        break;
182
+    
183
+      case "decimal-leading-zero":
184
+      case "decimal":
185
+      case "lower-alpha":
186
+      case "lower-latin":
187
+      case "lower-roman":
188
+      case "lower-greek":
189
+      case "upper-alpha":
190
+      case "upper-latin":
191
+      case "upper-roman":
192
+      case "1": // HTML 4.0 compatibility
193
+      case "a":
194
+      case "i":
195
+      case "A":
196
+      case "I":
197
+        $pad = null;
198
+        if ( $bullet_style === "decimal-leading-zero" ) {
199
+          $pad = strlen($li->get_parent()->get_node()->getAttribute("dompdf-children-count"));
200
+        }
201
+
202
+        $node = $frame->get_node();
203
+
204
+        if ( !$node->hasAttribute("dompdf-counter") ) {
205
+          return;
206
+        }
207
+
208
+        $index = $node->getAttribute("dompdf-counter");
209
+        $text = $this->make_counter($index, $bullet_style, $pad);
210
+
211
+        if ( trim($text) == "" ) {
212
+          return;
213
+        }
214
+        
215
+        $spacing = 0;
216
+        $font_family = $style->font_family;
217
+        
218
+        $line = $li->get_containing_line();
219
+        list($x, $y) = array($frame->get_position("x"), $line->y);
220
+
221
+        $x -= Font_Metrics::get_text_width($text, $font_family, $font_size, $spacing);
222
+        
223
+        // Take line-height into account
224
+        $line_height = $style->line_height;
225
+        $y += ($line_height - $font_size) / 4; // FIXME I thought it should be 2, but 4 gives better results
226
+        
227
+        $this->_canvas->text($x, $y, $text,
228
+                             $font_family, $font_size,
229
+                             $style->color, $spacing);
230
+      
231
+      case "none":
232
+        break;
233
+      }
234
+    }
235
+  }
236
+}

+ 26
- 0
vendor/dompdf/dompdf/include/null_frame_decorator.cls.php View File

@@ -0,0 +1,26 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Dummy decorator
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Null_Frame_Decorator extends Frame_Decorator {
16
+
17
+  function __construct(Frame $frame, DOMPDF $dompdf) {
18
+    parent::__construct($frame, $dompdf);
19
+    $style = $this->_frame->get_style();
20
+    $style->width = 0;
21
+    $style->height = 0;
22
+    $style->margin = 0;
23
+    $style->padding = 0;
24
+  }
25
+
26
+}

+ 21
- 0
vendor/dompdf/dompdf/include/null_frame_reflower.cls.php View File

@@ -0,0 +1,21 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Dummy reflower
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Null_Frame_Reflower extends Frame_Reflower {
16
+
17
+  function __construct(Frame $frame) { parent::__construct($frame); }
18
+
19
+  function reflow(Block_Frame_Decorator $block = null) { return; }
20
+  
21
+}

+ 23
- 0
vendor/dompdf/dompdf/include/null_positioner.cls.php View File

@@ -0,0 +1,23 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Dummy positioner
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Null_Positioner extends Positioner {
16
+
17
+  function __construct(Frame_Decorator $frame) {
18
+    parent::__construct($frame);
19
+  }
20
+
21
+  function position() { return; }
22
+  
23
+}

+ 126
- 0
vendor/dompdf/dompdf/include/page_cache.cls.php View File

@@ -0,0 +1,126 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Caches individual rendered PDF pages
11
+ *
12
+ * Not totally implemented yet.  Use at your own risk ;)
13
+ * 
14
+ * @access private
15
+ * @package dompdf
16
+ * @static
17
+ */
18
+class Page_Cache {
19
+
20
+  const DB_USER = "dompdf_page_cache";
21
+  const DB_PASS = "some meaningful password";
22
+  const DB_NAME = "dompdf_page_cache";
23
+  
24
+  static private $__connection = null;
25
+  
26
+  static function init() {
27
+    if ( is_null(self::$__connection) ) {
28
+      $con_str = "host=" . DB_HOST .
29
+        " dbname=" . self::DB_NAME .
30
+        " user=" . self::DB_USER .
31
+        " password=" . self::DB_PASS;
32
+      
33
+      if ( !self::$__connection = pg_connect($con_str) )
34
+        throw new Exception("Database connection failed.");
35
+    }
36
+  }
37
+  
38
+  function __construct() { throw new Exception("Can not create instance of Page_Class.  Class is static."); }
39
+
40
+  private static function __query($sql) {
41
+    if ( !($res = pg_query(self::$__connection, $sql)) )
42
+      throw new Exception(pg_last_error(self::$__connection));
43
+    return $res;
44
+  }
45
+  
46
+  static function store_page($id, $page_num, $data) {
47
+    $where = "WHERE id='" . pg_escape_string($id) . "' AND ".
48
+      "page_num=". pg_escape_string($page_num);
49
+
50
+    $res = self::__query("SELECT timestamp FROM page_cache ". $where);
51
+
52
+    $row = pg_fetch_assoc($res);
53
+    
54
+    if ( $row ) 
55
+      self::__query("UPDATE page_cache SET data='" . pg_escape_string($data) . "' " . $where);
56
+    else 
57
+      self::__query("INSERT INTO page_cache (id, page_num, data) VALUES ('" . pg_escape_string($id) . "', ".
58
+                     pg_escape_string($page_num) . ", ".
59
+                     "'". pg_escape_string($data) . "')");
60
+
61
+  }
62
+
63
+  static function store_fonts($id, $fonts) {
64
+    self::__query("BEGIN");
65
+    // Update the font information
66
+    self::__query("DELETE FROM page_fonts WHERE id='" . pg_escape_string($id) . "'");
67
+
68
+    foreach (array_keys($fonts) as $font)
69
+      self::__query("INSERT INTO page_fonts (id, font_name) VALUES ('" .
70
+                    pg_escape_string($id) . "', '" . pg_escape_string($font) . "')");
71
+    self::__query("COMMIT");
72
+  }
73
+  
74
+//   static function retrieve_page($id, $page_num) {
75
+
76
+//     $res = self::__query("SELECT data FROM page_cache WHERE id='" . pg_escape_string($id) . "' AND ".
77
+//                           "page_num=". pg_escape_string($page_num));
78
+
79
+//     $row = pg_fetch_assoc($res);
80
+
81
+//     return pg_unescape_bytea($row["data"]);
82
+    
83
+//   }
84
+
85
+  static function get_page_timestamp($id, $page_num) {
86
+    $res = self::__query("SELECT timestamp FROM page_cache WHERE id='" . pg_escape_string($id) . "' AND ".
87
+                          "page_num=". pg_escape_string($page_num));
88
+
89
+    $row = pg_fetch_assoc($res);
90
+
91
+    return $row["timestamp"];
92
+    
93
+  }
94
+
95
+  // Adds the cached document referenced by $id to the provided pdf
96
+  static function insert_cached_document(CPDF_Adapter $pdf, $id, $new_page = true) {
97
+    $res = self::__query("SELECT font_name FROM page_fonts WHERE id='" . pg_escape_string($id) . "'");
98
+
99
+    // Ensure that the fonts needed by the cached document are loaded into
100
+    // the pdf
101
+    while ($row = pg_fetch_assoc($res)) 
102
+      $pdf->get_cpdf()->selectFont($row["font_name"]);
103
+    
104
+    $res = self::__query("SELECT data FROM page_cache WHERE id='" . pg_escape_string($id) . "'");
105
+
106
+    if ( $new_page )
107
+      $pdf->new_page();
108
+
109
+    $first = true;
110
+    while ($row = pg_fetch_assoc($res)) {
111
+
112
+      if ( !$first ) 
113
+        $pdf->new_page();
114
+      else 
115
+        $first = false;        
116
+      
117
+      $page = $pdf->reopen_serialized_object($row["data"]);
118
+      //$pdf->close_object();
119
+      $pdf->add_object($page, "add");
120
+
121
+    }
122
+      
123
+  }
124
+}
125
+
126
+Page_Cache::init();

+ 592
- 0
vendor/dompdf/dompdf/include/page_frame_decorator.cls.php View File

@@ -0,0 +1,592 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Decorates frames for page layout
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Page_Frame_Decorator extends Frame_Decorator {
16
+
17
+  /**
18
+   * y value of bottom page margin
19
+   *
20
+   * @var float
21
+   */
22
+  protected $_bottom_page_margin;
23
+
24
+  /**
25
+   * Flag indicating page is full.
26
+   *
27
+   * @var bool
28
+   */
29
+  protected $_page_full;
30
+
31
+  /**
32
+   * Number of tables currently being reflowed
33
+   *
34
+   * @var int
35
+   */
36
+  protected $_in_table;
37
+
38
+  /**
39
+   * The pdf renderer
40
+   *
41
+   * @var Renderer
42
+   */
43
+  protected $_renderer;
44
+  
45
+  /**
46
+   * This page's floating frames
47
+   * 
48
+   * @var array
49
+   */
50
+  protected $_floating_frames = array();
51
+
52
+  //........................................................................
53
+
54
+  /**
55
+   * Class constructor
56
+   *
57
+   * @param Frame  $frame the frame to decorate
58
+   * @param DOMPDF $dompdf
59
+   */
60
+  function __construct(Frame $frame, DOMPDF $dompdf) {
61
+    parent::__construct($frame, $dompdf);
62
+    $this->_page_full = false;
63
+    $this->_in_table = 0;
64
+    $this->_bottom_page_margin = null;
65
+  }
66
+
67
+  /**
68
+   * Set the renderer used for this pdf
69
+   *
70
+   * @param Renderer $renderer the renderer to use
71
+   */
72
+  function set_renderer($renderer) {
73
+    $this->_renderer = $renderer;
74
+  }
75
+
76
+  /**
77
+   * Return the renderer used for this pdf
78
+   *
79
+   * @return Renderer
80
+   */
81
+  function get_renderer() {
82
+    return $this->_renderer;
83
+  }
84
+
85
+  /**
86
+   * Set the frame's containing block.  Overridden to set $this->_bottom_page_margin.
87
+   *
88
+   * @param float $x
89
+   * @param float $y
90
+   * @param float $w
91
+   * @param float $h
92
+   */
93
+  function set_containing_block($x = null, $y = null, $w = null, $h = null) {
94
+    parent::set_containing_block($x,$y,$w,$h);
95
+    //$w = $this->get_containing_block("w");
96
+    if ( isset($h) )
97
+      $this->_bottom_page_margin = $h; // - $this->_frame->get_style()->length_in_pt($this->_frame->get_style()->margin_bottom, $w);
98
+  }
99
+
100
+  /**
101
+   * Returns true if the page is full and is no longer accepting frames.
102
+   *
103
+   * @return bool
104
+   */
105
+  function is_full() {
106
+    return $this->_page_full;
107
+  }
108
+
109
+  /**
110
+   * Start a new page by resetting the full flag.
111
+   */
112
+  function next_page() {
113
+    $this->_floating_frames = array();
114
+    $this->_renderer->new_page();
115
+    $this->_page_full = false;
116
+  }
117
+
118
+  /**
119
+   * Indicate to the page that a table is currently being reflowed.
120
+   */
121
+  function table_reflow_start() {
122
+    $this->_in_table++;
123
+  }
124
+
125
+  /**
126
+   * Indicate to the page that table reflow is finished.
127
+   */
128
+  function table_reflow_end() {
129
+    $this->_in_table--;
130
+  }
131
+
132
+  /**
133
+   * Return whether we are currently in a nested table or not
134
+   *
135
+   * @return bool
136
+   */
137
+  function in_nested_table() {
138
+    return $this->_in_table > 1;
139
+  }
140
+  
141
+  /**
142
+   * Check if a forced page break is required before $frame.  This uses the
143
+   * frame's page_break_before property as well as the preceeding frame's
144
+   * page_break_after property.
145
+   *
146
+   * @link http://www.w3.org/TR/CSS21/page.html#forced
147
+   *
148
+   * @param Frame $frame the frame to check
149
+   * @return bool true if a page break occured
150
+   */
151
+  function check_forced_page_break(Frame $frame) {
152
+      
153
+    // Skip check if page is already split
154
+    if ( $this->_page_full )
155
+      return null;
156
+
157
+    $block_types = array("block", "list-item", "table", "inline");
158
+    $page_breaks = array("always", "left", "right");
159
+
160
+    $style = $frame->get_style();
161
+
162
+    if ( !in_array($style->display, $block_types) )
163
+      return false;
164
+
165
+    // Find the previous block-level sibling
166
+    $prev = $frame->get_prev_sibling();
167
+
168
+    while ( $prev && !in_array($prev->get_style()->display, $block_types) )
169
+      $prev = $prev->get_prev_sibling();
170
+
171
+
172
+    if ( in_array($style->page_break_before, $page_breaks) ) {
173
+
174
+      // Prevent cascading splits
175
+      $frame->split(null, true);
176
+      // We have to grab the style again here because split() resets
177
+      // $frame->style to the frame's orignal style.
178
+      $frame->get_style()->page_break_before = "auto";
179
+      $this->_page_full = true;
180
+      
181
+      return true;
182
+    }
183
+
184
+    if ( $prev && in_array($prev->get_style()->page_break_after, $page_breaks) ) {
185
+      // Prevent cascading splits
186
+      $frame->split(null, true);
187
+      $prev->get_style()->page_break_after = "auto";
188
+      $this->_page_full = true;
189
+      return true;
190
+    }
191
+    
192
+    if( $prev && $prev->get_last_child() && $frame->get_node()->nodeName != "body" ) {
193
+      $prev_last_child = $prev->get_last_child();
194
+      if ( in_array($prev_last_child->get_style()->page_break_after, $page_breaks) ) {
195
+        $frame->split(null, true);
196
+        $prev_last_child->get_style()->page_break_after = "auto";
197
+        $this->_page_full = true;
198
+        return true;
199
+      }
200
+    }
201
+
202
+
203
+    return false;
204
+  }
205
+
206
+  /**
207
+   * Determine if a page break is allowed before $frame
208
+   * http://www.w3.org/TR/CSS21/page.html#allowed-page-breaks
209
+   * 
210
+   * In the normal flow, page breaks can occur at the following places:
211
+   * 
212
+   *    1. In the vertical margin between block boxes. When a page
213
+   *    break occurs here, the used values of the relevant
214
+   *    'margin-top' and 'margin-bottom' properties are set to '0'.
215
+   *    2. Between line boxes inside a block box.
216
+   *
217
+   * These breaks are subject to the following rules:
218
+   * 
219
+   *   * Rule A: Breaking at (1) is allowed only if the
220
+   *     'page-break-after' and 'page-break-before' properties of
221
+   *     all the elements generating boxes that meet at this margin
222
+   *     allow it, which is when at least one of them has the value
223
+   *     'always', 'left', or 'right', or when all of them are
224
+   *     'auto'.
225
+   *
226
+   *   * Rule B: However, if all of them are 'auto' and the
227
+   *     nearest common ancestor of all the elements has a
228
+   *     'page-break-inside' value of 'avoid', then breaking here is
229
+   *     not allowed.
230
+   *
231
+   *   * Rule C: Breaking at (2) is allowed only if the number of
232
+   *     line boxes between the break and the start of the enclosing
233
+   *     block box is the value of 'orphans' or more, and the number
234
+   *     of line boxes between the break and the end of the box is
235
+   *     the value of 'widows' or more.
236
+   *
237
+   *   * Rule D: In addition, breaking at (2) is allowed only if
238
+   *     the 'page-break-inside' property is 'auto'.
239
+   *
240
+   * If the above doesn't provide enough break points to keep
241
+   * content from overflowing the page boxes, then rules B and D are
242
+   * dropped in order to find additional breakpoints.
243
+   *
244
+   * If that still does not lead to sufficient break points, rules A
245
+   * and C are dropped as well, to find still more break points.
246
+   *
247
+   * We will also allow breaks between table rows.  However, when
248
+   * splitting a table, the table headers should carry over to the
249
+   * next page (but they don't yet).
250
+   * 
251
+   * @param Frame $frame the frame to check
252
+   * @return bool true if a break is allowed, false otherwise
253
+   */
254
+  protected function _page_break_allowed(Frame $frame) {
255
+
256
+    $block_types = array("block", "list-item", "table", "-dompdf-image");
257
+    dompdf_debug("page-break", "_page_break_allowed(" . $frame->get_node()->nodeName. ")");
258
+    $display = $frame->get_style()->display;
259
+
260
+    // Block Frames (1):
261
+    if ( in_array($display, $block_types) ) {
262
+
263
+      // Avoid breaks within table-cells
264
+      if ( $this->_in_table ) {
265
+        dompdf_debug("page-break", "In table: " . $this->_in_table);
266
+        return false;
267
+      }
268
+
269
+      // Rules A & B
270
+
271
+      if ( $frame->get_style()->page_break_before === "avoid" ) {
272
+        dompdf_debug("page-break", "before: avoid");
273
+        return false;
274
+      }
275
+
276
+      // Find the preceeding block-level sibling
277
+      $prev = $frame->get_prev_sibling();
278
+      while ( $prev && !in_array($prev->get_style()->display, $block_types) )
279
+        $prev = $prev->get_prev_sibling();
280
+
281
+      // Does the previous element allow a page break after?
282
+      if ( $prev && $prev->get_style()->page_break_after === "avoid" ) {
283
+        dompdf_debug("page-break", "after: avoid");
284
+        return false;
285
+      }
286
+
287
+      // If both $prev & $frame have the same parent, check the parent's
288
+      // page_break_inside property.
289
+      $parent = $frame->get_parent();
290
+      if ( $prev && $parent && $parent->get_style()->page_break_inside === "avoid" ) {
291
+          dompdf_debug("page-break", "parent inside: avoid");
292
+        return false;
293
+      }
294
+
295
+      // To prevent cascading page breaks when a top-level element has
296
+      // page-break-inside: avoid, ensure that at least one frame is
297
+      // on the page before splitting.
298
+      if ( $parent->get_node()->nodeName === "body" && !$prev ) {
299
+        // We are the body's first child
300
+          dompdf_debug("page-break", "Body's first child.");
301
+        return false;
302
+      }
303
+
304
+      // If the frame is the first block-level frame, use the value from
305
+      // $frame's parent instead.
306
+      if ( !$prev && $parent )
307
+        return $this->_page_break_allowed( $parent );
308
+
309
+      dompdf_debug("page-break", "block: break allowed");
310
+      return true;
311
+
312
+    }
313
+
314
+    // Inline frames (2):
315
+    else if ( in_array($display, Style::$INLINE_TYPES) ) {
316
+
317
+      // Avoid breaks within table-cells
318
+      if ( $this->_in_table ) {
319
+          dompdf_debug("page-break", "In table: " . $this->_in_table);
320
+        return false;
321
+      }
322
+
323
+      // Rule C
324
+      $block_parent = $frame->find_block_parent();
325
+      if ( count($block_parent->get_line_boxes() ) < $frame->get_style()->orphans ) {
326
+          dompdf_debug("page-break", "orphans");
327
+        return false;
328
+      }
329
+
330
+      // FIXME: Checking widows is tricky without having laid out the
331
+      // remaining line boxes.  Just ignore it for now...
332
+
333
+      // Rule D
334
+      $p = $block_parent;
335
+      while ($p) {
336
+        if ( $p->get_style()->page_break_inside === "avoid" ) {
337
+          dompdf_debug("page-break", "parent->inside: avoid");
338
+          return false;
339
+        }
340
+        $p = $p->find_block_parent();
341
+      }
342
+
343
+      // To prevent cascading page breaks when a top-level element has
344
+      // page-break-inside: avoid, ensure that at least one frame with
345
+      // some content is on the page before splitting.
346
+      $prev = $frame->get_prev_sibling();
347
+      while ( $prev && ($prev->is_text_node() && trim($prev->get_node()->nodeValue) == "") )
348
+        $prev = $prev->get_prev_sibling();
349
+
350
+      if ( $block_parent->get_node()->nodeName === "body" && !$prev ) {
351
+        // We are the body's first child
352
+          dompdf_debug("page-break", "Body's first child.");
353
+        return false;
354
+      }
355
+
356
+      // Skip breaks on empty text nodes
357
+      if ( $frame->is_text_node() &&
358
+           $frame->get_node()->nodeValue == "" )
359
+        return false;
360
+
361
+      dompdf_debug("page-break", "inline: break allowed");
362
+      return true;
363
+
364
+    // Table-rows
365
+    } else if ( $display === "table-row" ) {
366
+
367
+      // Simply check if the parent table's page_break_inside property is
368
+      // not 'avoid'
369
+      $p = Table_Frame_Decorator::find_parent_table($frame);
370
+
371
+      while ($p) {
372
+        if ( $p->get_style()->page_break_inside === "avoid" ) {
373
+          dompdf_debug("page-break", "parent->inside: avoid");
374
+          return false;
375
+        }
376
+        $p = $p->find_block_parent();
377
+      }
378
+
379
+      // Avoid breaking after the first row of a table
380
+      if ( $p && $p->get_first_child() === $frame) {
381
+         dompdf_debug("page-break", "table: first-row");
382
+        return false;
383
+      }
384
+
385
+      // If this is a nested table, prevent the page from breaking
386
+      if ( $this->_in_table > 1 ) {
387
+        dompdf_debug("page-break", "table: nested table");
388
+        return false;
389
+      }
390
+
391
+      dompdf_debug("page-break","table-row/row-groups: break allowed");
392
+      return true;
393
+
394
+    } else if ( in_array($display, Table_Frame_Decorator::$ROW_GROUPS) ) {
395
+
396
+      // Disallow breaks at row-groups: only split at row boundaries
397
+      return false;
398
+
399
+    } else {
400
+
401
+      dompdf_debug("page-break", "? " . $frame->get_style()->display . "");
402
+      return false;
403
+    }
404
+
405
+  }
406
+
407
+  /**
408
+   * Check if $frame will fit on the page.  If the frame does not fit,
409
+   * the frame tree is modified so that a page break occurs in the
410
+   * correct location.
411
+   *
412
+   * @param Frame $frame the frame to check
413
+   * @return Frame the frame following the page break
414
+   */
415
+  function check_page_break(Frame $frame) {
416
+    // Do not split if we have already or if the frame was already 
417
+    // pushed to the next page (prevents infinite loops)
418
+    if ( $this->_page_full || $frame->_already_pushed ) {
419
+      return false;
420
+    }
421
+    
422
+    // If the frame is absolute of fixed it shouldn't break
423
+    $p = $frame;
424
+    do {
425
+      if ( $p->is_absolute() )
426
+        return false;
427
+    } while ( $p = $p->get_parent() );
428
+    
429
+    $margin_height = $frame->get_margin_height();
430
+    
431
+    // FIXME If the row is taller than the page and 
432
+    // if it the first of the page, we don't break
433
+    if ( $frame->get_style()->display === "table-row" &&
434
+         !$frame->get_prev_sibling() && 
435
+         $margin_height > $this->get_margin_height() )
436
+      return false;
437
+
438
+    // Determine the frame's maximum y value
439
+    $max_y = $frame->get_position("y") + $margin_height;
440
+
441
+    // If a split is to occur here, then the bottom margins & paddings of all
442
+    // parents of $frame must fit on the page as well:
443
+    $p = $frame->get_parent();
444
+    while ( $p ) {
445
+      $style = $p->get_style();
446
+      $max_y += $style->length_in_pt(array($style->margin_bottom,
447
+                                           $style->padding_bottom,
448
+                                           $style->border_bottom_width));
449
+      $p = $p->get_parent();
450
+    }
451
+
452
+
453
+    // Check if $frame flows off the page
454
+    if ( $max_y <= $this->_bottom_page_margin )
455
+      // no: do nothing
456
+      return false;
457
+
458
+    dompdf_debug("page-break", "check_page_break");
459
+    dompdf_debug("page-break", "in_table: " . $this->_in_table);
460
+
461
+    // yes: determine page break location
462
+    $iter = $frame;
463
+    $flg = false;
464
+
465
+    $in_table = $this->_in_table;
466
+
467
+    dompdf_debug("page-break","Starting search");
468
+    while ( $iter ) {
469
+      // echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). "";
470
+      if ( $iter === $this ) {
471
+         dompdf_debug("page-break", "reached root.");
472
+        // We've reached the root in our search.  Just split at $frame.
473
+        break;
474
+      }
475
+
476
+      if ( $this->_page_break_allowed($iter) ) {
477
+        dompdf_debug("page-break","break allowed, splitting.");
478
+        $iter->split(null, true);
479
+        $this->_page_full = true;
480
+        $this->_in_table = $in_table;
481
+        $frame->_already_pushed = true;
482
+        return true;
483
+      }
484
+
485
+      if ( !$flg && $next = $iter->get_last_child() ) {
486
+         dompdf_debug("page-break", "following last child.");
487
+
488
+        if ( $next->is_table() )
489
+          $this->_in_table++;
490
+
491
+        $iter = $next;
492
+        continue;
493
+      }
494
+
495
+      if ( $next = $iter->get_prev_sibling() ) {
496
+         dompdf_debug("page-break", "following prev sibling.");
497
+
498
+        if ( $next->is_table() && !$iter->is_table() )
499
+          $this->_in_table++;
500
+
501
+        else if ( !$next->is_table() && $iter->is_table() )
502
+          $this->_in_table--;
503
+
504
+        $iter = $next;
505
+        $flg = false;
506
+        continue;
507
+      }
508
+
509
+      if ( $next = $iter->get_parent() ) {
510
+         dompdf_debug("page-break", "following parent.");
511
+
512
+        if ( $iter->is_table() )
513
+          $this->_in_table--;
514
+
515
+        $iter = $next;
516
+        $flg = true;
517
+        continue;
518
+      }
519
+
520
+      break;
521
+    }
522
+
523
+    $this->_in_table = $in_table;
524
+
525
+    // No valid page break found.  Just break at $frame.
526
+    dompdf_debug("page-break", "no valid break found, just splitting.");
527
+    
528
+    // If we are in a table, backtrack to the nearest top-level table row
529
+    if ( $this->_in_table ) {
530
+      $iter = $frame;
531
+      while ($iter && $iter->get_style()->display !== "table-row")
532
+        $iter = $iter->get_parent();
533
+      
534
+      $iter->split(null, true);
535
+    } else {
536
+      $frame->split(null, true);
537
+    }
538
+    
539
+    $this->_page_full = true;
540
+    $frame->_already_pushed = true;
541
+    return true;
542
+  }
543
+
544
+  //........................................................................
545
+
546
+  function split(Frame $frame = null, $force_pagebreak = false) {
547
+    // Do nothing
548
+  }
549
+
550
+  /**
551
+   * Add a floating frame
552
+   *
553
+   * @param Frame $frame
554
+   *
555
+   * @return void
556
+   */
557
+  function add_floating_frame(Frame $frame) {
558
+    array_unshift($this->_floating_frames, $frame);
559
+  }
560
+  
561
+  /**
562
+   * @return Frame[]
563
+   */
564
+  function get_floating_frames() { 
565
+    return $this->_floating_frames; 
566
+  }
567
+
568
+  public function remove_floating_frame($key) {
569
+    unset($this->_floating_frames[$key]);
570
+  }
571
+
572
+  public function get_lowest_float_offset(Frame $child) {
573
+    $style = $child->get_style();
574
+    $side = $style->clear;
575
+    $float = $style->float;
576
+    
577
+    $y = 0;
578
+    
579
+    foreach($this->_floating_frames as $key => $frame) {
580
+      if ( $side === "both" || $frame->get_style()->float === $side ) {
581
+        $y = max($y, $frame->get_position("y") + $frame->get_margin_height());
582
+        
583
+        if ( $float !== "none" ) {
584
+          $this->remove_floating_frame($key);
585
+        }
586
+      }
587
+    }
588
+    
589
+    return $y;
590
+  }
591
+
592
+}

+ 186
- 0
vendor/dompdf/dompdf/include/page_frame_reflower.cls.php View File

@@ -0,0 +1,186 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @author  Fabien Ménager <fabien.menager@gmail.com>
7
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
8
+ */
9
+
10
+/**
11
+ * Reflows pages
12
+ *
13
+ * @access private
14
+ * @package dompdf
15
+ */
16
+class Page_Frame_Reflower extends Frame_Reflower {
17
+
18
+  /**
19
+   * Cache of the callbacks array
20
+   * 
21
+   * @var array
22
+   */
23
+  private $_callbacks;
24
+  
25
+  /**
26
+   * Cache of the canvas
27
+   *
28
+   * @var Canvas
29
+   */
30
+  private $_canvas;
31
+
32
+  function __construct(Page_Frame_Decorator $frame) { parent::__construct($frame); }
33
+  
34
+  function apply_page_style(Frame $frame, $page_number){
35
+    $style = $frame->get_style();
36
+    $page_styles = $style->get_stylesheet()->get_page_styles();
37
+    
38
+    // http://www.w3.org/TR/CSS21/page.html#page-selectors
39
+    if ( count($page_styles) > 1 ) {
40
+      $odd   = $page_number % 2 == 1;
41
+      $first = $page_number == 1;
42
+      
43
+      $style = clone $page_styles["base"];
44
+    
45
+      // FIXME RTL
46
+      if ( $odd && isset($page_styles[":right"]) ) {
47
+        $style->merge($page_styles[":right"]);
48
+      }
49
+      
50
+      if ( $odd && isset($page_styles[":odd"]) ) {
51
+        $style->merge($page_styles[":odd"]);
52
+      }
53
+  
54
+      // FIXME RTL
55
+      if ( !$odd && isset($page_styles[":left"]) ) {
56
+        $style->merge($page_styles[":left"]);
57
+      }
58
+  
59
+      if ( !$odd && isset($page_styles[":even"]) ) {
60
+        $style->merge($page_styles[":even"]);
61
+      }
62
+      
63
+      if ( $first && isset($page_styles[":first"]) ) {
64
+        $style->merge($page_styles[":first"]);
65
+      }
66
+      
67
+      $frame->set_style($style);
68
+    }
69
+  }
70
+  
71
+  //........................................................................
72
+
73
+  /**
74
+   * Paged layout:
75
+   * http://www.w3.org/TR/CSS21/page.html
76
+   */
77
+  function reflow(Block_Frame_Decorator $block = null) {
78
+    $fixed_children = array();
79
+    $prev_child = null;
80
+    $child = $this->_frame->get_first_child();
81
+    $current_page = 0;
82
+    
83
+    while ($child) {
84
+      $this->apply_page_style($this->_frame, $current_page + 1);
85
+      
86
+      $style = $this->_frame->get_style();
87
+  
88
+      // Pages are only concerned with margins
89
+      $cb = $this->_frame->get_containing_block();
90
+      $left   = $style->length_in_pt($style->margin_left,   $cb["w"]);
91
+      $right  = $style->length_in_pt($style->margin_right,  $cb["w"]);
92
+      $top    = $style->length_in_pt($style->margin_top,    $cb["h"]);
93
+      $bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]);
94
+      
95
+      $content_x = $cb["x"] + $left;
96
+      $content_y = $cb["y"] + $top;
97
+      $content_width = $cb["w"] - $left - $right;
98
+      $content_height = $cb["h"] - $top - $bottom;
99
+      
100
+      // Only if it's the first page, we save the nodes with a fixed position
101
+      if ($current_page == 0) {
102
+        $children = $child->get_children();
103
+        foreach ($children as $onechild) {
104
+          if ($onechild->get_style()->position === "fixed") {
105
+            $fixed_children[] = $onechild->deep_copy();
106
+          }
107
+        }
108
+        $fixed_children = array_reverse($fixed_children);
109
+      }
110
+      
111
+      $child->set_containing_block($content_x, $content_y, $content_width, $content_height);
112
+      
113
+      // Check for begin reflow callback
114
+      $this->_check_callbacks("begin_page_reflow", $child);
115
+    
116
+      //Insert a copy of each node which have a fixed position
117
+      if ($current_page >= 1) {
118
+        foreach ($fixed_children as $fixed_child) {
119
+          $child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child());
120
+        }
121
+      }
122
+      
123
+      $child->reflow();
124
+      $next_child = $child->get_next_sibling();
125
+      
126
+      // Check for begin render callback
127
+      $this->_check_callbacks("begin_page_render", $child);
128
+      
129
+      // Render the page
130
+      $this->_frame->get_renderer()->render($child);
131
+      
132
+      // Check for end render callback
133
+      $this->_check_callbacks("end_page_render", $child);
134
+      
135
+      if ( $next_child ) {
136
+        $this->_frame->next_page();
137
+      }
138
+
139
+      // Wait to dispose of all frames on the previous page
140
+      // so callback will have access to them
141
+      if ( $prev_child ) {
142
+        $prev_child->dispose(true);
143
+      }
144
+      $prev_child = $child;
145
+      $child = $next_child;
146
+      $current_page++;
147
+    }
148
+
149
+    // Dispose of previous page if it still exists
150
+    if ( $prev_child ) {
151
+      $prev_child->dispose(true);
152
+    }
153
+  }  
154
+  
155
+  //........................................................................
156
+  
157
+  /**
158
+   * Check for callbacks that need to be performed when a given event
159
+   * gets triggered on a page
160
+   *
161
+   * @param string $event the type of event
162
+   * @param Frame $frame the frame that event is triggered on
163
+   */
164
+  protected function _check_callbacks($event, $frame) {
165
+    if (!isset($this->_callbacks)) {
166
+      $dompdf = $this->_frame->get_dompdf();
167
+      $this->_callbacks = $dompdf->get_callbacks();
168
+      $this->_canvas = $dompdf->get_canvas();
169
+    }
170
+    
171
+    if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
172
+      $info = array(0 => $this->_canvas, "canvas" => $this->_canvas,
173
+                    1 => $frame, "frame" => $frame);
174
+      $fs = $this->_callbacks[$event];
175
+      foreach ($fs as $f) {
176
+        if (is_callable($f)) {
177
+          if (is_array($f)) {
178
+            $f[0]->$f[1]($info);
179
+          } else {
180
+            $f($info);
181
+          }
182
+        }
183
+      }
184
+    }
185
+  }  
186
+}

+ 1085
- 0
vendor/dompdf/dompdf/include/pdflib_adapter.cls.php
File diff suppressed because it is too large
View File


+ 48
- 0
vendor/dompdf/dompdf/include/php_evaluator.cls.php View File

@@ -0,0 +1,48 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Executes inline PHP code during the rendering process
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class PHP_Evaluator {
16
+  
17
+  /**
18
+   * @var Canvas
19
+   */
20
+  protected $_canvas;
21
+
22
+  function __construct(Canvas $canvas) {
23
+    $this->_canvas = $canvas;
24
+  }
25
+
26
+  function evaluate($code, $vars = array()) {
27
+    if ( !$this->_canvas->get_dompdf()->get_option("enable_php") ) {
28
+      return;
29
+    }
30
+    
31
+    // Set up some variables for the inline code
32
+    $pdf = $this->_canvas;
33
+    $PAGE_NUM = $pdf->get_page_number();
34
+    $PAGE_COUNT = $pdf->get_page_count();
35
+    
36
+    // Override those variables if passed in
37
+    foreach ($vars as $k => $v) {
38
+      $$k = $v;
39
+    }
40
+
41
+    //$code = html_entity_decode($code); // @todo uncomment this when tested
42
+    eval($code); 
43
+  }
44
+
45
+  function render(Frame $frame) {
46
+    $this->evaluate($frame->get_node()->nodeValue);
47
+  }
48
+}

+ 51
- 0
vendor/dompdf/dompdf/include/positioner.cls.php View File

@@ -0,0 +1,51 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Base Positioner class
11
+ *
12
+ * Defines postioner interface
13
+ *
14
+ * @access private
15
+ * @package dompdf
16
+ */
17
+abstract class Positioner {
18
+  
19
+  /**
20
+   * @var Frame_Decorator
21
+   */
22
+  protected $_frame;
23
+  
24
+  //........................................................................
25
+
26
+  function __construct(Frame_Decorator $frame) {
27
+    $this->_frame = $frame;
28
+  }
29
+  
30
+  /**
31
+   * Class destructor
32
+   */
33
+  function __destruct() {
34
+    clear_object($this);
35
+  }
36
+  //........................................................................
37
+
38
+  abstract function position();
39
+  
40
+  function move($offset_x, $offset_y, $ignore_self = false) {
41
+    list($x, $y) = $this->_frame->get_position();
42
+    
43
+    if ( !$ignore_self ) {
44
+      $this->_frame->set_position($x + $offset_x, $y + $offset_y);
45
+    }
46
+    
47
+    foreach($this->_frame->get_children() as $child) {
48
+      $child->move($offset_x, $offset_y);
49
+    }
50
+  }
51
+}

+ 290
- 0
vendor/dompdf/dompdf/include/renderer.cls.php View File

@@ -0,0 +1,290 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Concrete renderer
11
+ *
12
+ * Instantiates several specific renderers in order to render any given
13
+ * frame.
14
+ *
15
+ * @access private
16
+ * @package dompdf
17
+ */
18
+class Renderer extends Abstract_Renderer {
19
+
20
+  /**
21
+   * Array of renderers for specific frame types
22
+   *
23
+   * @var Abstract_Renderer[]
24
+   */
25
+  protected $_renderers;
26
+    
27
+  /**
28
+   * Cache of the callbacks array
29
+   * 
30
+   * @var array
31
+   */
32
+  private $_callbacks;
33
+  
34
+  /**
35
+   * Class destructor
36
+   */
37
+  function __destruct() {
38
+    clear_object($this);
39
+  }
40
+  
41
+  /**
42
+   * Advance the canvas to the next page
43
+   */  
44
+  function new_page() {
45
+    $this->_canvas->new_page();
46
+  }
47
+
48
+  /**
49
+   * Render frames recursively
50
+   *
51
+   * @param Frame $frame the frame to render
52
+   */
53
+  function render(Frame $frame) {
54
+    global $_dompdf_debug;
55
+
56
+    if ( $_dompdf_debug ) {
57
+      echo $frame;
58
+      flush();
59
+    }
60
+    
61
+    $style = $frame->get_style();
62
+    
63
+    if ( in_array($style->visibility, array("hidden", "collapse")) ) {
64
+      return;
65
+    }
66
+    
67
+    $display = $style->display;
68
+    
69
+    // Starts the CSS transformation
70
+    if ( $style->transform && is_array($style->transform) ) {
71
+      $this->_canvas->save();
72
+      list($x, $y) = $frame->get_padding_box();
73
+      $origin = $style->transform_origin;
74
+      
75
+      foreach($style->transform as $transform) {
76
+        list($function, $values) = $transform;
77
+        if ( $function === "matrix" ) {
78
+          $function = "transform";
79
+        }
80
+        
81
+        $values = array_map("floatval", $values);
82
+        $values[] = $x + $style->length_in_pt($origin[0], $style->width);
83
+        $values[] = $y + $style->length_in_pt($origin[1], $style->height);
84
+        
85
+        call_user_func_array(array($this->_canvas, $function), $values);
86
+      }
87
+    }
88
+    
89
+    switch ($display) {
90
+      
91
+    case "block":
92
+    case "list-item":
93
+    case "inline-block":
94
+    case "table":
95
+    case "inline-table":
96
+      $this->_render_frame("block", $frame);
97
+      break;
98
+
99
+    case "inline":
100
+      if ( $frame->is_text_node() )
101
+        $this->_render_frame("text", $frame);
102
+      else
103
+        $this->_render_frame("inline", $frame);
104
+      break;
105
+
106
+    case "table-cell":
107
+      $this->_render_frame("table-cell", $frame);
108
+      break;
109
+
110
+    case "table-row-group":
111
+    case "table-header-group":
112
+    case "table-footer-group":
113
+      $this->_render_frame("table-row-group", $frame);
114
+      break;
115
+
116
+    case "-dompdf-list-bullet":
117
+      $this->_render_frame("list-bullet", $frame);
118
+      break;
119
+
120
+    case "-dompdf-image":
121
+      $this->_render_frame("image", $frame);
122
+      break;
123
+      
124
+    case "none":
125
+      $node = $frame->get_node();
126
+          
127
+      if ( $node->nodeName === "script" ) {
128
+        if ( $node->getAttribute("type") === "text/php" ||
129
+             $node->getAttribute("language") === "php" ) {
130
+          // Evaluate embedded php scripts
131
+          $this->_render_frame("php", $frame);
132
+        }
133
+        
134
+        elseif ( $node->getAttribute("type") === "text/javascript" ||
135
+             $node->getAttribute("language") === "javascript" ) {
136
+          // Insert JavaScript
137
+          $this->_render_frame("javascript", $frame);
138
+        }
139
+      }
140
+
141
+      // Don't render children, so skip to next iter
142
+      return;
143
+      
144
+    default:
145
+      break;
146
+
147
+    }
148
+
149
+    // Starts the overflow: hidden box
150
+    if ( $style->overflow === "hidden" ) {
151
+      list($x, $y, $w, $h) = $frame->get_padding_box();
152
+      
153
+      // get border radii
154
+      $style = $frame->get_style();
155
+      list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h);
156
+      
157
+      if ( $tl + $tr + $br + $bl > 0 ) {
158
+        $this->_canvas->clipping_roundrectangle($x, $y, $w, $h, $tl, $tr, $br, $bl);
159
+      }
160
+      else {
161
+        $this->_canvas->clipping_rectangle($x, $y, $w, $h);
162
+      }
163
+    }
164
+
165
+    $stack = array();
166
+    
167
+    foreach ($frame->get_children() as $child) {
168
+      // < 0 : nagative z-index
169
+      // = 0 : no z-index, no stacking context
170
+      // = 1 : stacking context without z-index
171
+      // > 1 : z-index
172
+      $child_style = $child->get_style();
173
+      $child_z_index = $child_style->z_index;
174
+      $z_index = 0;
175
+      
176
+      if ( $child_z_index !== "auto" ) {
177
+        $z_index = intval($child_z_index) + 1;
178
+      } 
179
+      elseif ( $child_style->float !== "none" || $child->is_positionned()) {
180
+        $z_index = 1;
181
+      }
182
+      
183
+      $stack[$z_index][] = $child;
184
+    }
185
+    
186
+    ksort($stack);
187
+    
188
+    foreach ($stack as $by_index) {
189
+      foreach($by_index as $child) {
190
+        $this->render($child);
191
+      }
192
+    }
193
+     
194
+    // Ends the overflow: hidden box
195
+    if ( $style->overflow === "hidden" ) {
196
+      $this->_canvas->clipping_end();
197
+    }
198
+
199
+    if ( $style->transform && is_array($style->transform) ) {
200
+      $this->_canvas->restore();
201
+    }
202
+
203
+    // Check for end frame callback
204
+    $this->_check_callbacks("end_frame", $frame);
205
+  }
206
+  
207
+  /**
208
+   * Check for callbacks that need to be performed when a given event
209
+   * gets triggered on a frame
210
+   *
211
+   * @param string $event the type of event
212
+   * @param Frame $frame the frame that event is triggered on
213
+   */
214
+  protected function _check_callbacks($event, $frame) {
215
+    if (!isset($this->_callbacks)) {
216
+      $this->_callbacks = $this->_dompdf->get_callbacks();
217
+    }
218
+    
219
+    if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) {
220
+      $info = array(0 => $this->_canvas, "canvas" => $this->_canvas,
221
+                    1 => $frame, "frame" => $frame);
222
+      $fs = $this->_callbacks[$event];
223
+      foreach ($fs as $f) {
224
+        if (is_callable($f)) {
225
+          if (is_array($f)) {
226
+            $f[0]->$f[1]($info);
227
+          } else {
228
+            $f($info);
229
+          }
230
+        }
231
+      }
232
+    }
233
+  }
234
+
235
+  /**
236
+   * Render a single frame
237
+   *
238
+   * Creates Renderer objects on demand
239
+   *
240
+   * @param string $type type of renderer to use
241
+   * @param Frame $frame the frame to render
242
+   */
243
+  protected function _render_frame($type, $frame) {
244
+
245
+    if ( !isset($this->_renderers[$type]) ) {
246
+      
247
+      switch ($type) {
248
+      case "block":
249
+        $this->_renderers[$type] = new Block_Renderer($this->_dompdf);
250
+        break;
251
+
252
+      case "inline":
253
+        $this->_renderers[$type] = new Inline_Renderer($this->_dompdf);
254
+        break;
255
+
256
+      case "text":
257
+        $this->_renderers[$type] = new Text_Renderer($this->_dompdf);
258
+        break;
259
+
260
+      case "image":
261
+        $this->_renderers[$type] = new Image_Renderer($this->_dompdf);
262
+        break;
263
+      
264
+      case "table-cell":
265
+        $this->_renderers[$type] = new Table_Cell_Renderer($this->_dompdf);
266
+        break;
267
+      
268
+      case "table-row-group":
269
+        $this->_renderers[$type] = new Table_Row_Group_Renderer($this->_dompdf);
270
+        break;
271
+
272
+      case "list-bullet":
273
+        $this->_renderers[$type] = new List_Bullet_Renderer($this->_dompdf);
274
+        break;
275
+
276
+      case "php":
277
+        $this->_renderers[$type] = new PHP_Evaluator($this->_canvas);
278
+        break;
279
+
280
+      case "javascript":
281
+        $this->_renderers[$type] = new Javascript_Embedder($this->_dompdf);
282
+        break;
283
+        
284
+      }
285
+    }
286
+    
287
+    $this->_renderers[$type]->render($frame);
288
+
289
+  }
290
+}

+ 2435
- 0
vendor/dompdf/dompdf/include/style.cls.php
File diff suppressed because it is too large
View File


+ 1418
- 0
vendor/dompdf/dompdf/include/stylesheet.cls.php
File diff suppressed because it is too large
View File


+ 102
- 0
vendor/dompdf/dompdf/include/table_cell_frame_decorator.cls.php View File

@@ -0,0 +1,102 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Decorates table cells for layout
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Cell_Frame_Decorator extends Block_Frame_Decorator {
16
+  
17
+  protected $_resolved_borders;
18
+  protected $_content_height;
19
+  
20
+  //........................................................................
21
+
22
+  function __construct(Frame $frame, DOMPDF $dompdf) {
23
+    parent::__construct($frame, $dompdf);
24
+    $this->_resolved_borders = array();
25
+    $this->_content_height = 0;    
26
+  }
27
+
28
+  //........................................................................
29
+
30
+  function reset() {
31
+    parent::reset();
32
+    $this->_resolved_borders = array();
33
+    $this->_content_height = 0;
34
+    $this->_frame->reset();    
35
+  }
36
+  
37
+  function get_content_height() {
38
+    return $this->_content_height;
39
+  }
40
+
41
+  function set_content_height($height) {
42
+    $this->_content_height = $height;
43
+  }
44
+  
45
+  function set_cell_height($height) {
46
+    $style = $this->get_style();
47
+    $v_space = $style->length_in_pt(array($style->margin_top,
48
+                                          $style->padding_top,
49
+                                          $style->border_top_width,
50
+                                          $style->border_bottom_width,
51
+                                          $style->padding_bottom,
52
+                                          $style->margin_bottom),
53
+                                    $style->width);
54
+
55
+    $new_height = $height - $v_space;    
56
+    $style->height = $new_height;
57
+
58
+    if ( $new_height > $this->_content_height ) {
59
+      $y_offset = 0;
60
+      
61
+      // Adjust our vertical alignment
62
+      switch ($style->vertical_align) {
63
+        default:
64
+        case "baseline":
65
+          // FIXME: this isn't right
66
+          
67
+        case "top":
68
+          // Don't need to do anything
69
+          return;
70
+  
71
+        case "middle":
72
+          $y_offset = ($new_height - $this->_content_height) / 2;
73
+          break;
74
+  
75
+        case "bottom":
76
+          $y_offset = $new_height - $this->_content_height;
77
+          break;
78
+      }
79
+   
80
+      if ( $y_offset ) {
81
+        // Move our children
82
+        foreach ( $this->get_line_boxes() as $line ) {
83
+          foreach ( $line->get_frames() as $frame )
84
+            $frame->move( 0, $y_offset );
85
+        }
86
+      }
87
+   }
88
+        
89
+  }
90
+
91
+  function set_resolved_border($side, $border_spec) {    
92
+    $this->_resolved_borders[$side] = $border_spec;
93
+  }
94
+
95
+  //........................................................................
96
+
97
+  function get_resolved_border($side) {
98
+    return $this->_resolved_borders[$side];
99
+  }
100
+
101
+  function get_resolved_borders() { return $this->_resolved_borders; }
102
+}

+ 119
- 0
vendor/dompdf/dompdf/include/table_cell_frame_reflower.cls.php View File

@@ -0,0 +1,119 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows table cells
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Cell_Frame_Reflower extends Block_Frame_Reflower {
16
+
17
+  //........................................................................
18
+
19
+  function __construct(Block_Frame_Decorator $frame) {
20
+    parent::__construct($frame);
21
+  }
22
+
23
+  //........................................................................
24
+
25
+  function reflow(Block_Frame_Decorator $block = null) {
26
+
27
+    $style = $this->_frame->get_style();
28
+
29
+    $table = Table_Frame_Decorator::find_parent_table($this->_frame);
30
+    $cellmap = $table->get_cellmap();
31
+
32
+    list($x, $y) = $cellmap->get_frame_position($this->_frame);
33
+    $this->_frame->set_position($x, $y);
34
+
35
+    $cells = $cellmap->get_spanned_cells($this->_frame);
36
+
37
+    $w = 0;
38
+    foreach ( $cells["columns"] as $i ) {
39
+      $col = $cellmap->get_column( $i );
40
+      $w += $col["used-width"];
41
+    }
42
+
43
+    //FIXME?
44
+    $h = $this->_frame->get_containing_block("h");
45
+
46
+    $left_space = $style->length_in_pt(array($style->margin_left,
47
+                                             $style->padding_left,
48
+                                             $style->border_left_width),
49
+                                       $w);
50
+
51
+    $right_space = $style->length_in_pt(array($style->padding_right,
52
+                                              $style->margin_right,
53
+                                              $style->border_right_width),
54
+                                        $w);
55
+
56
+    $top_space = $style->length_in_pt(array($style->margin_top,
57
+                                            $style->padding_top,
58
+                                            $style->border_top_width),
59
+                                      $h);
60
+    $bottom_space = $style->length_in_pt(array($style->margin_bottom,
61
+                                               $style->padding_bottom,
62
+                                               $style->border_bottom_width),
63
+                                      $h);
64
+
65
+    $style->width = $cb_w = $w - $left_space - $right_space;
66
+
67
+    $content_x = $x + $left_space;
68
+    $content_y = $line_y = $y + $top_space;
69
+
70
+    // Adjust the first line based on the text-indent property
71
+    $indent = $style->length_in_pt($style->text_indent, $w);
72
+    $this->_frame->increase_line_width($indent);
73
+
74
+    $page = $this->_frame->get_root();
75
+    
76
+    // Set the y position of the first line in the cell
77
+    $line_box = $this->_frame->get_current_line_box();
78
+    $line_box->y = $line_y;
79
+    
80
+    // Set the containing blocks and reflow each child
81
+    foreach ( $this->_frame->get_children() as $child ) {
82
+      
83
+      if ( $page->is_full() )
84
+        break;
85
+    
86
+      $child->set_containing_block($content_x, $content_y, $cb_w, $h);
87
+      
88
+      $this->process_clear($child);
89
+      
90
+      $child->reflow($this->_frame);
91
+    
92
+      $this->process_float($child, $x + $left_space, $w - $right_space - $left_space);
93
+    }
94
+
95
+    // Determine our height
96
+    $style_height = $style->length_in_pt($style->height, $h);
97
+
98
+    $this->_frame->set_content_height($this->_calculate_content_height());
99
+
100
+    $height = max($style_height, $this->_frame->get_content_height());
101
+
102
+    // Let the cellmap know our height
103
+    $cell_height = $height / count($cells["rows"]);
104
+
105
+    if ($style_height <= $height)
106
+      $cell_height += $top_space + $bottom_space;
107
+
108
+    foreach ($cells["rows"] as $i)
109
+      $cellmap->set_row_height($i, $cell_height);
110
+
111
+    $style->height = $height;
112
+
113
+    $this->_text_align();
114
+
115
+    $this->vertical_align();
116
+
117
+  }
118
+
119
+}

+ 28
- 0
vendor/dompdf/dompdf/include/table_cell_positioner.cls.php View File

@@ -0,0 +1,28 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Positions table cells
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Cell_Positioner extends Positioner {
16
+
17
+  function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
18
+  
19
+  //........................................................................
20
+
21
+  function position() {
22
+
23
+    $table = Table_Frame_Decorator::find_parent_table($this->_frame);
24
+    $cellmap = $table->get_cellmap();
25
+    $this->_frame->set_position($cellmap->get_frame_position($this->_frame));
26
+
27
+  }
28
+}

+ 155
- 0
vendor/dompdf/dompdf/include/table_cell_renderer.cls.php View File

@@ -0,0 +1,155 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Renders table cells
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Cell_Renderer extends Block_Renderer {
16
+
17
+  //........................................................................
18
+
19
+  function render(Frame $frame) {
20
+    $style = $frame->get_style();
21
+    
22
+    if ( trim($frame->get_node()->nodeValue) === "" && $style->empty_cells === "hide" ) {
23
+      return;
24
+    }
25
+
26
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
27
+    list($x, $y, $w, $h) = $frame->get_border_box();
28
+    
29
+    // Draw our background, border and content
30
+    if ( ($bg = $style->background_color) !== "transparent" ) {
31
+      $this->_canvas->filled_rectangle($x, $y, $w, $h, $bg);
32
+    }
33
+
34
+    if ( ($url = $style->background_image) && $url !== "none" ) {
35
+      $this->_background_image($url, $x, $y, $w, $h, $style);
36
+    }
37
+    
38
+    $table = Table_Frame_Decorator::find_parent_table($frame);
39
+
40
+    if ( $table->get_style()->border_collapse !== "collapse" ) {
41
+      $this->_render_border($frame);
42
+      $this->_render_outline($frame);
43
+      return;
44
+    }
45
+
46
+    // The collapsed case is slightly complicated...
47
+    // @todo Add support for outlines here
48
+
49
+    $cellmap  = $table->get_cellmap();
50
+    $cells    = $cellmap->get_spanned_cells($frame);
51
+    $num_rows = $cellmap->get_num_rows();
52
+    $num_cols = $cellmap->get_num_cols();
53
+
54
+    // Determine the top row spanned by this cell
55
+    $i = $cells["rows"][0];
56
+    $top_row = $cellmap->get_row($i);
57
+
58
+    // Determine if this cell borders on the bottom of the table.  If so,
59
+    // then we draw its bottom border.  Otherwise the next row down will
60
+    // draw its top border instead.
61
+    if (in_array( $num_rows - 1, $cells["rows"])) {
62
+      $draw_bottom = true;
63
+      $bottom_row = $cellmap->get_row($num_rows - 1);
64
+    } else
65
+      $draw_bottom = false;
66
+
67
+
68
+    // Draw the horizontal borders
69
+    foreach ( $cells["columns"] as $j ) {
70
+      $bp = $cellmap->get_border_properties($i, $j);
71
+
72
+      $y = $top_row["y"] - $bp["top"]["width"] / 2;
73
+
74
+      $col = $cellmap->get_column($j);
75
+      $x = $col["x"] - $bp["left"]["width"] / 2;
76
+      $w = $col["used-width"] + ($bp["left"]["width"] + $bp["right"]["width"] ) / 2;
77
+
78
+      if ( $bp["top"]["style"] !== "none" && $bp["top"]["width"] > 0 ) {
79
+        $widths = array($bp["top"]["width"],
80
+                        $bp["right"]["width"],
81
+                        $bp["bottom"]["width"],
82
+                        $bp["left"]["width"]);
83
+        $method = "_border_". $bp["top"]["style"];
84
+        $this->$method($x, $y, $w, $bp["top"]["color"], $widths, "top", "square");
85
+      }
86
+
87
+      if ( $draw_bottom ) {
88
+        $bp = $cellmap->get_border_properties($num_rows - 1, $j);
89
+        if ( $bp["bottom"]["style"] === "none" || $bp["bottom"]["width"] <= 0 )
90
+          continue;
91
+
92
+        $y = $bottom_row["y"] + $bottom_row["height"] + $bp["bottom"]["width"] / 2;
93
+
94
+        $widths = array($bp["top"]["width"],
95
+                        $bp["right"]["width"],
96
+                        $bp["bottom"]["width"],
97
+                        $bp["left"]["width"]);
98
+        $method = "_border_". $bp["bottom"]["style"];
99
+        $this->$method($x, $y, $w, $bp["bottom"]["color"], $widths, "bottom", "square");
100
+
101
+      }
102
+    }
103
+
104
+    $j = $cells["columns"][0];
105
+
106
+    $left_col = $cellmap->get_column($j);
107
+
108
+    if (in_array($num_cols - 1, $cells["columns"])) {
109
+      $draw_right = true;
110
+      $right_col = $cellmap->get_column($num_cols - 1);
111
+    } else
112
+      $draw_right = false;
113
+
114
+    // Draw the vertical borders
115
+    foreach ( $cells["rows"] as $i ) {
116
+      $bp = $cellmap->get_border_properties($i, $j);
117
+
118
+      $x = $left_col["x"] - $bp["left"]["width"] / 2;
119
+
120
+      $row = $cellmap->get_row($i);
121
+
122
+      $y = $row["y"] - $bp["top"]["width"] / 2;
123
+      $h = $row["height"] + ($bp["top"]["width"] + $bp["bottom"]["width"])/ 2;
124
+
125
+      if ( $bp["left"]["style"] !== "none" && $bp["left"]["width"] > 0 ) {
126
+
127
+        $widths = array($bp["top"]["width"],
128
+                        $bp["right"]["width"],
129
+                        $bp["bottom"]["width"],
130
+                        $bp["left"]["width"]);
131
+
132
+        $method = "_border_" . $bp["left"]["style"];
133
+        $this->$method($x, $y, $h, $bp["left"]["color"], $widths, "left", "square");
134
+      }
135
+
136
+      if ( $draw_right ) {
137
+        $bp = $cellmap->get_border_properties($i, $num_cols - 1);
138
+        if ( $bp["right"]["style"] === "none" || $bp["right"]["width"] <= 0 )
139
+          continue;
140
+
141
+        $x = $right_col["x"] + $right_col["used-width"] + $bp["right"]["width"] / 2;
142
+
143
+        $widths = array($bp["top"]["width"],
144
+                        $bp["right"]["width"],
145
+                        $bp["bottom"]["width"],
146
+                        $bp["left"]["width"]);
147
+
148
+        $method = "_border_" . $bp["right"]["style"];
149
+        $this->$method($x, $y, $h, $bp["right"]["color"], $widths, "right", "square");
150
+
151
+      }
152
+    }
153
+
154
+  }
155
+}

+ 334
- 0
vendor/dompdf/dompdf/include/table_frame_decorator.cls.php View File

@@ -0,0 +1,334 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Decorates Frames for table layout
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Frame_Decorator extends Frame_Decorator {
16
+  static $VALID_CHILDREN = array("table-row-group",
17
+                                 "table-row",
18
+                                 "table-header-group",
19
+                                 "table-footer-group",
20
+                                 "table-column",
21
+                                 "table-column-group",
22
+                                 "table-caption",
23
+                                 "table-cell");
24
+
25
+  static $ROW_GROUPS = array('table-row-group',
26
+                             'table-header-group',
27
+                             'table-footer-group');
28
+
29
+  /**
30
+   * The Cellmap object for this table.  The cellmap maps table cells
31
+   * to rows and columns, and aids in calculating column widths.
32
+   *
33
+   * @var Cellmap
34
+   */
35
+  protected $_cellmap;
36
+
37
+  /**
38
+   * The minimum width of the table, in pt
39
+   *
40
+   * @var float
41
+   */
42
+  protected $_min_width;
43
+
44
+  /**
45
+   * The maximum width of the table, in pt
46
+   *
47
+   * @var float
48
+   */
49
+  protected $_max_width;
50
+
51
+  /**
52
+   * Table header rows.  Each table header is duplicated when a table
53
+   * spans pages.
54
+   *
55
+   * @var array
56
+   */
57
+  protected $_headers;
58
+
59
+  /**
60
+   * Table footer rows.  Each table footer is duplicated when a table
61
+   * spans pages.
62
+   *
63
+   * @var array
64
+   */
65
+  protected $_footers;
66
+
67
+  /**
68
+   * Class constructor
69
+   *
70
+   * @param Frame  $frame the frame to decorate
71
+   * @param DOMPDF $dompdf
72
+   */
73
+  function __construct(Frame $frame, DOMPDF $dompdf) {
74
+    parent::__construct($frame, $dompdf);
75
+    $this->_cellmap = new Cellmap($this);
76
+    
77
+    if ( $frame->get_style()->table_layout === "fixed" ) {
78
+      $this->_cellmap->set_layout_fixed(true);
79
+    }
80
+    
81
+    $this->_min_width = null;
82
+    $this->_max_width = null;
83
+    $this->_headers = array();
84
+    $this->_footers = array();
85
+  }
86
+
87
+
88
+  function reset() {
89
+    parent::reset();
90
+    $this->_cellmap->reset();
91
+    $this->_min_width = null;
92
+    $this->_max_width = null;
93
+    $this->_headers = array();
94
+    $this->_footers = array();
95
+    $this->_reflower->reset();
96
+  }
97
+
98
+  //........................................................................
99
+
100
+  /**
101
+   * split the table at $row.  $row and all subsequent rows will be
102
+   * added to the clone.  This method is overidden in order to remove
103
+   * frames from the cellmap properly.
104
+   *
105
+   * @param Frame $child
106
+   * @param bool  $force_pagebreak
107
+   *
108
+   * @return void
109
+   */
110
+  function split(Frame $child = null, $force_pagebreak = false) {
111
+
112
+    if ( is_null($child) ) {
113
+      parent::split();
114
+      return;
115
+    }
116
+
117
+    // If $child is a header or if it is the first non-header row, do
118
+    // not duplicate headers, simply move the table to the next page.
119
+    if ( count($this->_headers) && !in_array($child, $this->_headers, true) &&
120
+         !in_array($child->get_prev_sibling(), $this->_headers, true) ) {
121
+
122
+      $first_header = null;
123
+
124
+      // Insert copies of the table headers before $child
125
+      foreach ($this->_headers as $header) {
126
+
127
+        $new_header = $header->deep_copy();
128
+
129
+        if ( is_null($first_header) )
130
+          $first_header = $new_header;
131
+
132
+        $this->insert_child_before($new_header, $child);
133
+      }
134
+
135
+      parent::split($first_header);
136
+
137
+    } else if ( in_array($child->get_style()->display, self::$ROW_GROUPS) ) {
138
+
139
+      // Individual rows should have already been handled
140
+      parent::split($child);
141
+
142
+    } else {
143
+
144
+      $iter = $child;
145
+
146
+      while ($iter) {
147
+        $this->_cellmap->remove_row($iter);
148
+        $iter = $iter->get_next_sibling();
149
+      }
150
+
151
+      parent::split($child);
152
+    }
153
+  }
154
+
155
+  /**
156
+   * Return a copy of this frame with $node as its node
157
+   * 
158
+   * @param DOMNode $node
159
+   * @return Frame
160
+   */ 
161
+  function copy(DOMNode $node) {
162
+    $deco = parent::copy($node);
163
+    
164
+    // In order to keep columns' widths through pages
165
+    $deco->_cellmap->set_columns($this->_cellmap->get_columns());
166
+    $deco->_cellmap->lock_columns();
167
+
168
+    return $deco;
169
+  }
170
+
171
+  /**
172
+   * Static function to locate the parent table of a frame
173
+   *
174
+   * @param Frame $frame
175
+   * @return Table_Frame_Decorator the table that is an ancestor of $frame
176
+   */
177
+  static function find_parent_table(Frame $frame) {
178
+
179
+    while ( $frame = $frame->get_parent() )
180
+      if ( $frame->is_table() )
181
+        break;
182
+
183
+    return $frame;
184
+  }
185
+
186
+  /**
187
+   * Return this table's Cellmap
188
+   *
189
+   * @return Cellmap
190
+   */
191
+  function get_cellmap() { return $this->_cellmap; }
192
+
193
+  /**
194
+   * Return the minimum width of this table
195
+   *
196
+   * @return float
197
+   */
198
+  function get_min_width() { return $this->_min_width; }
199
+
200
+  /**
201
+   * Return the maximum width of this table
202
+   *
203
+   * @return float
204
+   */
205
+  function get_max_width() { return $this->_max_width; }
206
+
207
+  /**
208
+   * Set the minimum width of the table
209
+   *
210
+   * @param float $width the new minimum width
211
+   */
212
+  function set_min_width($width) { $this->_min_width = $width; }
213
+
214
+  /**
215
+   * Set the maximum width of the table
216
+   *
217
+   * @param float $width the new maximum width
218
+   */
219
+  function set_max_width($width) { $this->_max_width = $width; }
220
+
221
+  /**
222
+   * Restructure tree so that the table has the correct structure.
223
+   * Invalid children (i.e. all non-table-rows) are moved below the
224
+   * table.
225
+   */
226
+  function normalise() {
227
+
228
+    // Store frames generated by invalid tags and move them outside the table
229
+    $erroneous_frames = array();
230
+    $anon_row = false;
231
+    $iter = $this->get_first_child();
232
+    while ( $iter ) {
233
+      $child = $iter;
234
+      $iter = $iter->get_next_sibling();
235
+
236
+      $display = $child->get_style()->display;
237
+
238
+      if ( $anon_row ) {
239
+
240
+        if ( $display === "table-row" ) {
241
+          // Add the previous anonymous row
242
+          $this->insert_child_before($table_row, $child);
243
+
244
+          $table_row->normalise();
245
+          $child->normalise();
246
+          $anon_row = false;
247
+          continue;
248
+        }
249
+
250
+        // add the child to the anonymous row
251
+        $table_row->append_child($child);
252
+        continue;
253
+
254
+      } else {
255
+
256
+        if ( $display === "table-row" ) {
257
+          $child->normalise();
258
+          continue;
259
+        }
260
+
261
+        if ( $display === "table-cell" ) {
262
+          // Create an anonymous table row
263
+          $tr = $this->get_node()->ownerDocument->createElement("tr");
264
+
265
+          $frame = new Frame($tr);
266
+
267
+          $css = $this->get_style()->get_stylesheet();
268
+          $style = $css->create_style();
269
+          $style->inherit($this->get_style());
270
+
271
+          // Lookup styles for tr tags.  If the user wants styles to work
272
+          // better, they should make the tr explicit... I'm not going to
273
+          // try to guess what they intended.
274
+          if ( $tr_style = $css->lookup("tr") )
275
+            $style->merge($tr_style);
276
+
277
+          // Okay, I have absolutely no idea why I need this clone here, but
278
+          // if it's omitted, php (as of 2004-07-28) segfaults.
279
+          $frame->set_style(clone $style);
280
+          $table_row = Frame_Factory::decorate_frame($frame, $this->_dompdf, $this->_root);
281
+
282
+          // Add the cell to the row
283
+          $table_row->append_child($child);
284
+
285
+          $anon_row = true;
286
+          continue;
287
+        }
288
+
289
+        if ( !in_array($display, self::$VALID_CHILDREN) ) {
290
+          $erroneous_frames[] = $child;
291
+          continue;
292
+        }
293
+
294
+        // Normalise other table parts (i.e. row groups)
295
+        foreach ($child->get_children() as $grandchild) {
296
+          if ( $grandchild->get_style()->display === "table-row" ) {
297
+            $grandchild->normalise();
298
+          }
299
+        }
300
+
301
+        // Add headers and footers
302
+        if ( $display === "table-header-group" )
303
+          $this->_headers[] = $child;
304
+
305
+        else if ( $display === "table-footer-group" )
306
+          $this->_footers[] = $child;
307
+      }
308
+    }
309
+
310
+    if ( $anon_row ) {
311
+      // Add the row to the table
312
+      $this->_frame->append_child($table_row);
313
+      $table_row->normalise();
314
+      $this->_cellmap->add_row();
315
+    }
316
+
317
+    foreach ($erroneous_frames as $frame)
318
+      $this->move_after($frame);
319
+
320
+  }
321
+
322
+  //........................................................................
323
+
324
+  /**
325
+   * Moves the specified frame and it's corresponding node outside of
326
+   * the table.
327
+   *
328
+   * @param Frame $frame the frame to move
329
+   */
330
+  function move_after(Frame $frame) {
331
+    $this->get_parent()->insert_child_after($frame, $this);
332
+  }
333
+
334
+}

+ 578
- 0
vendor/dompdf/dompdf/include/table_frame_reflower.cls.php View File

@@ -0,0 +1,578 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows tables
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Frame_Reflower extends Frame_Reflower {
16
+  /**
17
+   * Frame for this reflower
18
+   *
19
+   * @var Table_Frame_Decorator
20
+   */
21
+  protected $_frame;
22
+
23
+  /**
24
+   * Cache of results between call to get_min_max_width and assign_widths
25
+   *
26
+   * @var array
27
+   */
28
+  protected $_state;
29
+
30
+  function __construct(Table_Frame_Decorator $frame) {
31
+    $this->_state = null;
32
+    parent::__construct($frame);
33
+  }
34
+
35
+  /**
36
+   * State is held here so it needs to be reset along with the decorator
37
+   */
38
+  function reset() {
39
+    $this->_state = null;
40
+    $this->_min_max_cache = null;
41
+  }
42
+
43
+  //........................................................................
44
+
45
+  protected function _assign_widths() {
46
+    $style = $this->_frame->get_style();
47
+
48
+    // Find the min/max width of the table and sort the columns into
49
+    // absolute/percent/auto arrays
50
+    $min_width = $this->_state["min_width"];
51
+    $max_width = $this->_state["max_width"];
52
+    $percent_used = $this->_state["percent_used"];
53
+    $absolute_used = $this->_state["absolute_used"];
54
+    $auto_min = $this->_state["auto_min"];
55
+
56
+    $absolute =& $this->_state["absolute"];
57
+    $percent =& $this->_state["percent"];
58
+    $auto =& $this->_state["auto"];
59
+
60
+    // Determine the actual width of the table
61
+    $cb = $this->_frame->get_containing_block();
62
+    $columns =& $this->_frame->get_cellmap()->get_columns();
63
+
64
+    $width = $style->width;
65
+
66
+    // Calculate padding & border fudge factor
67
+    $left = $style->margin_left;
68
+    $right = $style->margin_right;
69
+    
70
+    $centered = ( $left === "auto" && $right === "auto" );
71
+
72
+    $left  = $left  === "auto" ? 0 : $style->length_in_pt($left, $cb["w"]);
73
+    $right = $right === "auto" ? 0 : $style->length_in_pt($right, $cb["w"]);
74
+
75
+    $delta = $left + $right;
76
+    
77
+    if ( !$centered ) {
78
+      $delta += $style->length_in_pt(array(
79
+        $style->padding_left,
80
+        $style->border_left_width,
81
+        $style->border_right_width,
82
+        $style->padding_right), 
83
+      $cb["w"]);
84
+    }
85
+    
86
+    $min_table_width = $style->length_in_pt( $style->min_width, $cb["w"] - $delta );
87
+
88
+    // min & max widths already include borders & padding
89
+    $min_width -= $delta;
90
+    $max_width -= $delta;
91
+    
92
+    if ( $width !== "auto" ) {
93
+
94
+      $preferred_width = $style->length_in_pt($width, $cb["w"]) - $delta;
95
+
96
+      if ( $preferred_width < $min_table_width )
97
+        $preferred_width = $min_table_width;
98
+
99
+      if ( $preferred_width > $min_width )
100
+        $width = $preferred_width;
101
+      else
102
+        $width = $min_width;
103
+
104
+    } else {
105
+
106
+      if ( $max_width + $delta < $cb["w"] )
107
+        $width = $max_width;
108
+      else if ( $cb["w"] - $delta > $min_width )
109
+        $width = $cb["w"] - $delta;
110
+      else
111
+        $width = $min_width;
112
+
113
+      if ( $width < $min_table_width )
114
+        $width = $min_table_width;
115
+
116
+    }
117
+
118
+    // Store our resolved width
119
+    $style->width = $width;
120
+
121
+    $cellmap = $this->_frame->get_cellmap();
122
+    
123
+    if ( $cellmap->is_columns_locked() ) {
124
+      return;
125
+    }
126
+
127
+    // If the whole table fits on the page, then assign each column it's max width
128
+    if ( $width == $max_width ) {
129
+
130
+      foreach (array_keys($columns) as $i)
131
+        $cellmap->set_column_width($i, $columns[$i]["max-width"]);
132
+
133
+      return;
134
+    }
135
+
136
+    // Determine leftover and assign it evenly to all columns
137
+    if ( $width > $min_width ) {
138
+
139
+      // We have four cases to deal with:
140
+      //
141
+      // 1. All columns are auto--no widths have been specified.  In this
142
+      // case we distribute extra space across all columns weighted by max-width.
143
+      //
144
+      // 2. Only absolute widths have been specified.  In this case we
145
+      // distribute any extra space equally among 'width: auto' columns, or all
146
+      // columns if no auto columns have been specified.
147
+      //
148
+      // 3. Only percentage widths have been specified.  In this case we
149
+      // normalize the percentage values and distribute any remaining % to
150
+      // width: auto columns.  We then proceed to assign widths as fractions
151
+      // of the table width.
152
+      //
153
+      // 4. Both absolute and percentage widths have been specified.
154
+
155
+      $increment = 0;
156
+
157
+      // Case 1:
158
+      if ( $absolute_used == 0 && $percent_used == 0 ) {
159
+        $increment = $width - $min_width;
160
+
161
+        foreach (array_keys($columns) as $i) {
162
+          $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment * ($columns[$i]["max-width"] / $max_width));
163
+        }
164
+        return;
165
+      }
166
+
167
+
168
+      // Case 2
169
+      if ( $absolute_used > 0 && $percent_used == 0 ) {
170
+
171
+        if ( count($auto) > 0 )
172
+          $increment = ($width - $auto_min - $absolute_used) / count($auto);
173
+
174
+        // Use the absolutely specified width or the increment
175
+        foreach (array_keys($columns) as $i) {
176
+
177
+          if ( $columns[$i]["absolute"] > 0 && count($auto) )
178
+            $cellmap->set_column_width($i, $columns[$i]["min-width"]);
179
+          else if ( count($auto) ) 
180
+            $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment);
181
+          else {
182
+            // All absolute columns
183
+            $increment = ($width - $absolute_used) * $columns[$i]["absolute"] / $absolute_used;
184
+
185
+            $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment);
186
+          }
187
+
188
+        }
189
+        return;
190
+      }
191
+
192
+
193
+      // Case 3:
194
+      if ( $absolute_used == 0 && $percent_used > 0 ) {
195
+
196
+        $scale = null;
197
+        $remaining = null;
198
+
199
+        // Scale percent values if the total percentage is > 100, or if all
200
+        // values are specified as percentages.
201
+        if ( $percent_used > 100 || count($auto) == 0)
202
+          $scale = 100 / $percent_used;
203
+        else
204
+          $scale = 1;
205
+
206
+        // Account for the minimum space used by the unassigned auto columns
207
+        $used_width = $auto_min;
208
+
209
+        foreach ($percent as $i) {
210
+          $columns[$i]["percent"] *= $scale;
211
+
212
+          $slack = $width - $used_width;
213
+
214
+          $w = min($columns[$i]["percent"] * $width/100, $slack);
215
+
216
+          if ( $w < $columns[$i]["min-width"] )
217
+            $w = $columns[$i]["min-width"];
218
+
219
+          $cellmap->set_column_width($i, $w);
220
+          $used_width += $w;
221
+
222
+        }
223
+
224
+        // This works because $used_width includes the min-width of each
225
+        // unassigned column
226
+        if ( count($auto) > 0 ) {
227
+          $increment = ($width - $used_width) / count($auto);
228
+
229
+          foreach ($auto as $i)
230
+            $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment);
231
+
232
+        }
233
+        return;
234
+      }
235
+
236
+      // Case 4:
237
+
238
+      // First-come, first served
239
+      if ( $absolute_used > 0 && $percent_used > 0 ) {
240
+
241
+        $used_width = $auto_min;
242
+
243
+        foreach ($absolute as $i) {
244
+          $cellmap->set_column_width($i, $columns[$i]["min-width"]);
245
+          $used_width +=  $columns[$i]["min-width"];
246
+        }
247
+
248
+        // Scale percent values if the total percentage is > 100 or there
249
+        // are no auto values to take up slack
250
+        if ( $percent_used > 100 || count($auto) == 0 )
251
+          $scale = 100 / $percent_used;
252
+        else
253
+          $scale = 1;
254
+
255
+        $remaining_width = $width - $used_width;
256
+
257
+        foreach ($percent as $i) {
258
+          $slack = $remaining_width - $used_width;
259
+
260
+          $columns[$i]["percent"] *= $scale;
261
+          $w = min($columns[$i]["percent"] * $remaining_width / 100, $slack);
262
+
263
+          if ( $w < $columns[$i]["min-width"] )
264
+            $w = $columns[$i]["min-width"];
265
+
266
+          $columns[$i]["used-width"] = $w;
267
+          $used_width += $w;
268
+        }
269
+
270
+        if ( count($auto) > 0 ) {
271
+          $increment = ($width - $used_width) / count($auto);
272
+
273
+          foreach ($auto as $i)
274
+            $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment);
275
+
276
+        }
277
+
278
+        return;
279
+      }
280
+
281
+
282
+    } else { // we are over constrained
283
+
284
+      // Each column gets its minimum width
285
+      foreach (array_keys($columns) as $i)
286
+        $cellmap->set_column_width($i, $columns[$i]["min-width"]);
287
+
288
+    }
289
+  }
290
+
291
+  //........................................................................
292
+
293
+  // Determine the frame's height based on min/max height
294
+  protected function _calculate_height() {
295
+
296
+    $style = $this->_frame->get_style();
297
+    $height = $style->height;
298
+
299
+    $cellmap = $this->_frame->get_cellmap();
300
+    $cellmap->assign_frame_heights();
301
+    $rows = $cellmap->get_rows();
302
+
303
+    // Determine our content height
304
+    $content_height = 0;
305
+    foreach ( $rows as $r )
306
+      $content_height += $r["height"];
307
+
308
+    $cb = $this->_frame->get_containing_block();
309
+
310
+    if ( !($style->overflow === "visible" ||
311
+           ($style->overflow === "hidden" && $height === "auto")) ) {
312
+
313
+      // Only handle min/max height if the height is independent of the frame's content
314
+
315
+      $min_height = $style->min_height;
316
+      $max_height = $style->max_height;
317
+
318
+      if ( isset($cb["h"]) ) {
319
+        $min_height = $style->length_in_pt($min_height, $cb["h"]);
320
+        $max_height = $style->length_in_pt($max_height, $cb["h"]);
321
+
322
+      } else if ( isset($cb["w"]) ) {
323
+
324
+        if ( mb_strpos($min_height, "%") !== false )
325
+          $min_height = 0;
326
+        else
327
+          $min_height = $style->length_in_pt($min_height, $cb["w"]);
328
+
329
+        if ( mb_strpos($max_height, "%") !== false )
330
+          $max_height = "none";
331
+        else
332
+          $max_height = $style->length_in_pt($max_height, $cb["w"]);
333
+      }
334
+
335
+      if ( $max_height !== "none" && $min_height > $max_height )
336
+        // Swap 'em
337
+        list($max_height, $min_height) = array($min_height, $max_height);
338
+
339
+      if ( $max_height !== "none" && $height > $max_height )
340
+        $height = $max_height;
341
+
342
+      if ( $height < $min_height )
343
+        $height = $min_height;
344
+
345
+    } else {
346
+
347
+      // Use the content height or the height value, whichever is greater
348
+      if ( $height !== "auto" ) {
349
+        $height = $style->length_in_pt($height, $cb["h"]);
350
+
351
+        if ( $height <= $content_height )
352
+          $height = $content_height;
353
+        else
354
+          $cellmap->set_frame_heights($height,$content_height);
355
+
356
+      } else
357
+        $height = $content_height;
358
+
359
+    }
360
+
361
+    return $height;
362
+
363
+  }
364
+  //........................................................................
365
+
366
+  /**
367
+   * @param Block_Frame_Decorator $block
368
+   */
369
+  function reflow(Block_Frame_Decorator $block = null) {
370
+    /**
371
+     * @var Table_Frame_Decorator
372
+     */
373
+    $frame = $this->_frame;
374
+    
375
+    // Check if a page break is forced
376
+    $page = $frame->get_root();
377
+    $page->check_forced_page_break($frame);
378
+
379
+    // Bail if the page is full
380
+    if ( $page->is_full() )
381
+      return;
382
+    
383
+    // Let the page know that we're reflowing a table so that splits
384
+    // are suppressed (simply setting page-break-inside: avoid won't
385
+    // work because we may have an arbitrary number of block elements
386
+    // inside tds.)
387
+    $page->table_reflow_start();
388
+    
389
+    // Collapse vertical margins, if required
390
+    $this->_collapse_margins();
391
+
392
+    $frame->position();
393
+
394
+    // Table layout algorithm:
395
+    // http://www.w3.org/TR/CSS21/tables.html#auto-table-layout
396
+
397
+    if ( is_null($this->_state) )
398
+      $this->get_min_max_width();
399
+
400
+    $cb = $frame->get_containing_block();
401
+    $style = $frame->get_style();
402
+
403
+    // This is slightly inexact, but should be okay.  Add half the
404
+    // border-spacing to the table as padding.  The other half is added to
405
+    // the cells themselves.
406
+    if ( $style->border_collapse === "separate" ) {
407
+      list($h, $v) = $style->border_spacing;
408
+
409
+      $v = $style->length_in_pt($v) / 2;
410
+      $h = $style->length_in_pt($h) / 2;
411
+
412
+      $style->padding_left   = $style->length_in_pt($style->padding_left,   $cb["w"]) + $h;
413
+      $style->padding_right  = $style->length_in_pt($style->padding_right,  $cb["w"]) + $h;
414
+      $style->padding_top    = $style->length_in_pt($style->padding_top,    $cb["h"]) + $v;
415
+      $style->padding_bottom = $style->length_in_pt($style->padding_bottom, $cb["h"]) + $v;
416
+
417
+    }
418
+
419
+    $this->_assign_widths();
420
+
421
+    // Adjust left & right margins, if they are auto
422
+    $width = $style->width;
423
+    $left = $style->margin_left;
424
+    $right = $style->margin_right;
425
+
426
+    $diff = $cb["w"] - $width;
427
+
428
+    if ( $left === "auto" && $right === "auto" ) {
429
+      if ( $diff < 0 ) {
430
+        $left = 0;
431
+        $right = $diff;
432
+      }
433
+      else {
434
+        $left = $right = $diff / 2;
435
+      }
436
+      
437
+      $style->margin_left = "$left pt";
438
+      $style->margin_right = "$right pt";
439
+
440
+    } else {
441
+      if ( $left === "auto" ) {
442
+        $left = $style->length_in_pt($cb["w"] - $right - $width, $cb["w"]);
443
+      }
444
+      if ( $right === "auto" ) {
445
+        $left = $style->length_in_pt($left, $cb["w"]);
446
+      }
447
+    }
448
+
449
+    list($x, $y) = $frame->get_position();
450
+
451
+    // Determine the content edge
452
+    $content_x = $x + $left + $style->length_in_pt(array($style->padding_left,
453
+                                                         $style->border_left_width), $cb["w"]);
454
+    $content_y = $y + $style->length_in_pt(array($style->margin_top,
455
+                                                 $style->border_top_width,
456
+                                                 $style->padding_top), $cb["h"]);
457
+
458
+    if ( isset($cb["h"]) )
459
+      $h = $cb["h"];
460
+    else
461
+      $h = null;
462
+
463
+    $cellmap = $frame->get_cellmap();
464
+    $col =& $cellmap->get_column(0);
465
+    $col["x"] = $content_x;
466
+
467
+    $row =& $cellmap->get_row(0);
468
+    $row["y"] = $content_y;
469
+
470
+    $cellmap->assign_x_positions();
471
+
472
+    // Set the containing block of each child & reflow
473
+    foreach ( $frame->get_children() as $child ) {
474
+
475
+      // Bail if the page is full
476
+      if ( !$page->in_nested_table() && $page->is_full() )
477
+        break;
478
+
479
+      $child->set_containing_block($content_x, $content_y, $width, $h);
480
+      $child->reflow();
481
+
482
+      if ( !$page->in_nested_table() )
483
+        // Check if a split has occured
484
+        $page->check_page_break($child);
485
+
486
+    }
487
+
488
+    // Assign heights to our cells:
489
+    $style->height = $this->_calculate_height();
490
+
491
+    if ( $style->border_collapse === "collapse" ) {
492
+      // Unset our borders because our cells are now using them
493
+      $style->border_style = "none";
494
+    }
495
+
496
+    $page->table_reflow_end();
497
+
498
+    // Debugging:
499
+    //echo ($this->_frame->get_cellmap());
500
+    
501
+    if ( $block && $style->float === "none" && $frame->is_in_flow() ) {
502
+      $block->add_frame_to_line($frame);
503
+      $block->add_line();
504
+    }
505
+  }
506
+
507
+  //........................................................................
508
+
509
+  function get_min_max_width() {
510
+
511
+    if ( !is_null($this->_min_max_cache)  )
512
+      return $this->_min_max_cache;
513
+
514
+    $style = $this->_frame->get_style();
515
+
516
+    $this->_frame->normalise();
517
+
518
+    // Add the cells to the cellmap (this will calcluate column widths as
519
+    // frames are added)
520
+    $this->_frame->get_cellmap()->add_frame($this->_frame);
521
+
522
+    // Find the min/max width of the table and sort the columns into
523
+    // absolute/percent/auto arrays
524
+    $this->_state = array();
525
+    $this->_state["min_width"] = 0;
526
+    $this->_state["max_width"] = 0;
527
+
528
+    $this->_state["percent_used"] = 0;
529
+    $this->_state["absolute_used"] = 0;
530
+    $this->_state["auto_min"] = 0;
531
+
532
+    $this->_state["absolute"] = array();
533
+    $this->_state["percent"] = array();
534
+    $this->_state["auto"] = array();
535
+
536
+    $columns =& $this->_frame->get_cellmap()->get_columns();
537
+    foreach (array_keys($columns) as $i) {
538
+      $this->_state["min_width"] += $columns[$i]["min-width"];
539
+      $this->_state["max_width"] += $columns[$i]["max-width"];
540
+
541
+      if ( $columns[$i]["absolute"] > 0 ) {
542
+        $this->_state["absolute"][] = $i;
543
+        $this->_state["absolute_used"] += $columns[$i]["absolute"];
544
+
545
+      } else if ( $columns[$i]["percent"] > 0 ) {
546
+        $this->_state["percent"][] = $i;
547
+        $this->_state["percent_used"] += $columns[$i]["percent"];
548
+
549
+      } else {
550
+        $this->_state["auto"][] = $i;
551
+        $this->_state["auto_min"] += $columns[$i]["min-width"];
552
+      }
553
+    }
554
+
555
+    // Account for margins & padding
556
+    $dims = array($style->border_left_width,
557
+                  $style->border_right_width,
558
+                  $style->padding_left,
559
+                  $style->padding_right,
560
+                  $style->margin_left,
561
+                  $style->margin_right);
562
+
563
+    if ( $style->border_collapse !== "collapse" ) 
564
+      list($dims[]) = $style->border_spacing;
565
+
566
+    $delta = $style->length_in_pt($dims, $this->_frame->get_containing_block("w"));
567
+
568
+    $this->_state["min_width"] += $delta;
569
+    $this->_state["max_width"] += $delta;
570
+
571
+    return $this->_min_max_cache = array(
572
+      $this->_state["min_width"], 
573
+      $this->_state["max_width"],
574
+      "min" => $this->_state["min_width"], 
575
+      "max" => $this->_state["max_width"],
576
+    );
577
+  }
578
+}

+ 48
- 0
vendor/dompdf/dompdf/include/table_row_frame_decorator.cls.php View File

@@ -0,0 +1,48 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Decorates Frames for table row layout
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Row_Frame_Decorator extends Frame_Decorator {
16
+
17
+  // protected members
18
+  
19
+  function __construct(Frame $frame, DOMPDF $dompdf) {
20
+    parent::__construct($frame, $dompdf);
21
+  }
22
+  
23
+  //........................................................................ 
24
+
25
+  /**
26
+   * Remove all non table-cell frames from this row and move them after
27
+   * the table.
28
+   */
29
+  function normalise() {
30
+
31
+    // Find our table parent
32
+    $p = Table_Frame_Decorator::find_parent_table($this);
33
+    
34
+    $erroneous_frames = array();
35
+    foreach ($this->get_children() as $child) {      
36
+      $display = $child->get_style()->display;
37
+
38
+      if ( $display !== "table-cell" )
39
+        $erroneous_frames[] = $child;
40
+    }
41
+    
42
+    //  dump the extra nodes after the table.
43
+    foreach ($erroneous_frames as $frame) 
44
+      $p->move_after($frame);
45
+  }
46
+  
47
+  
48
+}

+ 61
- 0
vendor/dompdf/dompdf/include/table_row_frame_reflower.cls.php View File

@@ -0,0 +1,61 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows table rows
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Row_Frame_Reflower extends Frame_Reflower {
16
+
17
+
18
+  function __construct(Table_Row_Frame_Decorator $frame) {
19
+    parent::__construct($frame);
20
+  }
21
+
22
+  //........................................................................
23
+
24
+  function reflow(Block_Frame_Decorator $block = null) {
25
+    $page = $this->_frame->get_root();
26
+
27
+    if ( $page->is_full() )
28
+      return;
29
+
30
+    $this->_frame->position();
31
+    $style = $this->_frame->get_style();
32
+    $cb = $this->_frame->get_containing_block();
33
+
34
+    foreach ($this->_frame->get_children() as $child) {
35
+
36
+      if ( $page->is_full() )
37
+        return;
38
+
39
+      $child->set_containing_block($cb);
40
+      $child->reflow();
41
+
42
+    }
43
+
44
+    if ( $page->is_full() )
45
+      return;
46
+
47
+    $table = Table_Frame_Decorator::find_parent_table($this->_frame);
48
+    $cellmap = $table->get_cellmap();
49
+    $style->width = $cellmap->get_frame_width($this->_frame);
50
+    $style->height = $cellmap->get_frame_height($this->_frame);
51
+
52
+    $this->_frame->set_position($cellmap->get_frame_position($this->_frame));
53
+
54
+  }
55
+
56
+  //........................................................................
57
+
58
+  function get_min_max_width() {
59
+    throw new DOMPDF_Exception("Min/max width is undefined for table rows");
60
+  }
61
+}

+ 66
- 0
vendor/dompdf/dompdf/include/table_row_group_frame_decorator.cls.php View File

@@ -0,0 +1,66 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Table row group decorator
11
+ *
12
+ * Overrides split() method for tbody, thead & tfoot elements
13
+ *
14
+ * @access private
15
+ * @package dompdf
16
+ */
17
+class Table_Row_Group_Frame_Decorator extends Frame_Decorator {
18
+
19
+  /**
20
+   * Class constructor
21
+   *
22
+   * @param Frame $frame   Frame to decorate
23
+   * @param DOMPDF $dompdf Current dompdf instance
24
+   */
25
+  function __construct(Frame $frame, DOMPDF $dompdf) {
26
+    parent::__construct($frame, $dompdf);
27
+  }
28
+
29
+  /**
30
+   * Override split() to remove all child rows and this element from the cellmap
31
+   *
32
+   * @param Frame $child
33
+   * @param bool  $force_pagebreak
34
+   *
35
+   * @return void
36
+   */
37
+  function split(Frame $child = null, $force_pagebreak = false) {
38
+
39
+    if ( is_null($child) ) {
40
+      parent::split();
41
+      return;
42
+    }
43
+
44
+    // Remove child & all subsequent rows from the cellmap
45
+    $cellmap = $this->get_parent()->get_cellmap();
46
+    $iter = $child;
47
+
48
+    while ( $iter ) {
49
+      $cellmap->remove_row($iter);
50
+      $iter = $iter->get_next_sibling();
51
+    }
52
+
53
+    // If we are splitting at the first child remove the
54
+    // table-row-group from the cellmap as well
55
+    if ( $child === $this->get_first_child() ) {
56
+      $cellmap->remove_row_group($this);
57
+      parent::split();
58
+      return;
59
+    }
60
+    
61
+    $cellmap->update_row_group($this, $child->get_prev_sibling());
62
+    parent::split($child);
63
+    
64
+  }
65
+}
66
+ 

+ 59
- 0
vendor/dompdf/dompdf/include/table_row_group_frame_reflower.cls.php View File

@@ -0,0 +1,59 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Reflows table row groups (e.g. tbody tags)
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Row_Group_Frame_Reflower extends Frame_Reflower {
16
+
17
+  function __construct($frame) {
18
+    parent::__construct($frame);
19
+  }
20
+
21
+  function reflow(Block_Frame_Decorator $block = null) {
22
+    $page = $this->_frame->get_root();
23
+
24
+    $style = $this->_frame->get_style();
25
+    
26
+    // Our width is equal to the width of our parent table
27
+    $table = Table_Frame_Decorator::find_parent_table($this->_frame);
28
+    
29
+    $cb = $this->_frame->get_containing_block();
30
+    
31
+    foreach ( $this->_frame->get_children() as $child) {
32
+      // Bail if the page is full
33
+      if ( $page->is_full() )
34
+        return;
35
+
36
+      $child->set_containing_block($cb["x"], $cb["y"], $cb["w"], $cb["h"]);
37
+      $child->reflow();
38
+
39
+      // Check if a split has occured
40
+      $page->check_page_break($child);
41
+
42
+    }
43
+
44
+    if ( $page->is_full() )
45
+      return;
46
+
47
+    $cellmap = $table->get_cellmap();
48
+    $style->width = $cellmap->get_frame_width($this->_frame);
49
+    $style->height = $cellmap->get_frame_height($this->_frame);
50
+
51
+    $this->_frame->set_position($cellmap->get_frame_position($this->_frame));
52
+    
53
+    if ( $table->get_style()->border_collapse === "collapse" ) 
54
+      // Unset our borders because our cells are now using them
55
+      $style->border_style = "none";
56
+ 
57
+  }
58
+
59
+}

+ 40
- 0
vendor/dompdf/dompdf/include/table_row_group_renderer.cls.php View File

@@ -0,0 +1,40 @@
1
+<?php
2
+/**
3
+ * @package dompdf
4
+ * @link    http://dompdf.github.com/
5
+ * @author  Benj Carson <benjcarson@digitaljunkies.ca>
6
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
7
+ */
8
+
9
+/**
10
+ * Renders block frames
11
+ *
12
+ * @access private
13
+ * @package dompdf
14
+ */
15
+class Table_Row_Group_Renderer extends Block_Renderer {
16
+
17
+  //........................................................................
18
+
19
+  function render(Frame $frame) {
20
+    $style = $frame->get_style(); 
21
+    
22
+    $this->_set_opacity( $frame->get_opacity( $style->opacity ) );
23
+
24
+    $this->_render_border($frame);
25
+    $this->_render_outline($frame);
26
+    
27
+    if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) {
28
+      $this->_debug_layout($frame->get_border_box(), "red");
29
+      if (DEBUG_LAYOUT_PADDINGBOX) {
30
+        $this->_debug_layout($frame->get_padding_box(), "red", array(0.5, 0.5));
31
+      }
32
+    }
33
+    
34
+    if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES && $frame->get_decorator()) {
35
+      foreach ($frame->get_decorator()->get_line_boxes() as $line) {
36
+        $frame->_debug_layout(array($line->x, $line->y, $line->w, $line->h), "orange");
37
+      }
38
+    }
39
+  }
40
+}

+ 0
- 0
vendor/dompdf/dompdf/include/table_row_positioner.cls.php View File


Some files were not shown because too many files changed in this diff