From b7b35ad35b7e2423b9584c86546f28fc189c02ec Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sat, 2 Nov 2019 22:41:54 +0100 Subject: [PATCH] Upload MPDF files --- lib/MPDF/composer.json | 5 + lib/MPDF/composer.lock | 288 + lib/MPDF/vendor/autoload.php | 7 + lib/MPDF/vendor/composer/ClassLoader.php | 445 + lib/MPDF/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + lib/MPDF/vendor/composer/autoload_files.php | 10 + .../vendor/composer/autoload_namespaces.php | 9 + lib/MPDF/vendor/composer/autoload_psr4.php | 13 + lib/MPDF/vendor/composer/autoload_real.php | 70 + lib/MPDF/vendor/composer/autoload_static.php | 59 + lib/MPDF/vendor/composer/installed.json | 282 + lib/MPDF/vendor/mpdf/mpdf/.gitignore | 2 + lib/MPDF/vendor/mpdf/mpdf/.travis.yml | 53 + lib/MPDF/vendor/mpdf/mpdf/CHANGELOG.md | 741 + lib/MPDF/vendor/mpdf/mpdf/CREDITS.txt | 91 + lib/MPDF/vendor/mpdf/mpdf/LICENSE.txt | 280 + lib/MPDF/vendor/mpdf/mpdf/README.md | 127 + lib/MPDF/vendor/mpdf/mpdf/composer.json | 99 + lib/MPDF/vendor/mpdf/mpdf/data/CJKdata.php | 99 + .../collations/Afrikaans_South_Africa.php | 104 + .../mpdf/data/collations/Albanian_Albania.php | 110 + .../mpdf/data/collations/Alsatian_France.php | 104 + .../mpdf/data/collations/Arabic_Algeria.php | 67 + .../mpdf/data/collations/Arabic_Bahrain.php | 67 + .../mpdf/data/collations/Arabic_Egypt.php | 67 + .../mpdf/mpdf/data/collations/Arabic_Iraq.php | 67 + .../mpdf/data/collations/Arabic_Jordan.php | 67 + .../mpdf/data/collations/Arabic_Kuwait.php | 67 + .../mpdf/data/collations/Arabic_Lebanon.php | 67 + .../mpdf/data/collations/Arabic_Libya.php | 67 + .../mpdf/data/collations/Arabic_Morocco.php | 67 + .../mpdf/mpdf/data/collations/Arabic_Oman.php | 67 + .../data/collations/Arabic_Pseudo_RTL.php | 67 + .../mpdf/data/collations/Arabic_Qatar.php | 67 + .../data/collations/Arabic_Saudi_Arabia.php | 67 + .../mpdf/data/collations/Arabic_Syria.php | 67 + .../mpdf/data/collations/Arabic_Tunisia.php | 67 + .../mpdf/data/collations/Arabic_Yemen.php | 67 + .../Azeri_(Cyrillic)_Azerbaijan.php | 79 + .../collations/Azeri_(Latin)_Azerbaijan.php | 97 + .../mpdf/data/collations/Bashkir_Russia.php | 79 + .../mpdf/data/collations/Basque_Spain.php | 104 + .../data/collations/Belarusian_Belarus.php | 79 + ...nian_(Cyrillic)_Bosnia_and_Herzegovina.php | 79 + ...Bosnian_(Latin)_Bosnia_and_Herzegovina.php | 106 + .../mpdf/data/collations/Breton_France.php | 104 + .../data/collations/Bulgarian_Bulgaria.php | 79 + .../mpdf/data/collations/Catalan_Spain.php | 104 + .../mpdf/data/collations/Corsican_France.php | 104 + ...roatian_(Latin)_Bosnia_and_Herzegovina.php | 106 + .../mpdf/data/collations/Croatian_Croatia.php | 106 + .../data/collations/Czech_Czech_Republic.php | 107 + .../mpdf/data/collations/Danish_Denmark.php | 101 + .../mpdf/data/collations/Dari_Afghanistan.php | 64 + .../mpdf/data/collations/Dutch_Belgium.php | 104 + .../data/collations/Dutch_Netherlands.php | 104 + .../data/collations/English_Australia.php | 104 + .../mpdf/data/collations/English_Belize.php | 104 + .../mpdf/data/collations/English_Canada.php | 104 + .../data/collations/English_Caribbean.php | 104 + .../mpdf/data/collations/English_India.php | 104 + .../mpdf/data/collations/English_Ireland.php | 104 + .../mpdf/data/collations/English_Jamaica.php | 104 + .../mpdf/data/collations/English_Malaysia.php | 104 + .../data/collations/English_New_Zealand.php | 104 + .../English_Republic_of_the_Philippines.php | 104 + .../data/collations/English_Singapore.php | 104 + .../data/collations/English_South_Africa.php | 104 + .../English_Trinidad_and_Tobago.php | 104 + .../collations/English_United_Kingdom.php | 103 + .../data/collations/English_United_States.php | 103 + .../mpdf/data/collations/English_Zimbabwe.php | 104 + .../mpdf/data/collations/Estonian_Estonia.php | 93 + .../data/collations/Faroese_Faroe_Islands.php | 104 + .../data/collations/Filipino_Philippines.php | 104 + .../mpdf/data/collations/Finnish_Finland.php | 102 + .../mpdf/data/collations/French_Belgium.php | 104 + .../mpdf/data/collations/French_Canada.php | 104 + .../mpdf/data/collations/French_France.php | 104 + .../data/collations/French_Luxembourg.php | 104 + .../French_Principality_of_Monaco.php | 104 + .../data/collations/French_Switzerland.php | 104 + .../data/collations/Frisian_Netherlands.php | 104 + .../mpdf/data/collations/Galician_Spain.php | 104 + .../mpdf/data/collations/German_Austria.php | 104 + .../mpdf/data/collations/German_Germany.php | 104 + .../data/collations/German_Liechtenstein.php | 104 + .../data/collations/German_Luxembourg.php | 104 + .../data/collations/German_Switzerland.php | 104 + .../mpdf/data/collations/Greek_Greece.php | 74 + .../data/collations/Greenlandic_Greenland.php | 101 + .../data/collations/Hausa_(Latin)_Nigeria.php | 104 + .../mpdf/data/collations/Hebrew_Israel.php | 59 + .../data/collations/Hungarian_Hungary.php | 70 + .../data/collations/Icelandic_Iceland.php | 94 + .../mpdf/data/collations/Igbo_Nigeria.php | 104 + .../data/collations/Indonesian_Indonesia.php | 104 + .../collations/Inuktitut_(Latin)_Canada.php | 104 + .../Invariant_Language_Invariant_Country.php | 104 + .../mpdf/data/collations/Irish_Ireland.php | 104 + .../mpdf/data/collations/Italian_Italy.php | 104 + .../data/collations/Italian_Switzerland.php | 104 + .../data/collations/Kinyarwanda_Rwanda.php | 104 + .../mpdf/data/collations/Kiswahili_Kenya.php | 104 + .../data/collations/Kyrgyz_Kyrgyzstan.php | 79 + .../mpdf/data/collations/Latvian_Latvia.php | 87 + .../data/collations/Lithuanian_Lithuania.php | 91 + .../data/collations/Lower_Sorbian_Germany.php | 104 + .../collations/Luxembourgish_Luxembourg.php | 104 + .../Macedonian_(FYROM)_Macedonia_(FYROM).php | 78 + .../collations/Malay_Brunei_Darussalam.php | 104 + .../mpdf/data/collations/Malay_Malaysia.php | 104 + .../mpdf/data/collations/Mapudungun_Chile.php | 102 + .../mpdf/data/collations/Mohawk_Canada.php | 104 + .../Mongolian_(Cyrillic)_Mongolia.php | 79 + .../collations/Norwegian_(Nynorsk)_Norway.php | 101 + .../mpdf/data/collations/Occitan_France.php | 104 + .../mpdf/data/collations/Persian_Iran.php | 65 + .../mpdf/data/collations/Polish_Poland.php | 102 + .../data/collations/Portuguese_Brazil.php | 104 + .../data/collations/Portuguese_Portugal.php | 104 + .../mpdf/data/collations/Quechua_Bolivia.php | 104 + .../mpdf/data/collations/Quechua_Ecuador.php | 104 + .../mpdf/data/collations/Quechua_Peru.php | 104 + .../mpdf/data/collations/Romanian_Romania.php | 107 + .../data/collations/Romansh_Switzerland.php | 86 + .../mpdf/data/collations/Russian_Russia.php | 79 + .../data/collations/Sami_(Inari)_Finland.php | 94 + .../data/collations/Sami_(Lule)_Norway.php | 94 + .../data/collations/Sami_(Lule)_Sweden.php | 94 + .../collations/Sami_(Northern)_Finland.php | 94 + .../collations/Sami_(Northern)_Norway.php | 94 + .../collations/Sami_(Northern)_Sweden.php | 94 + .../data/collations/Sami_(Skolt)_Finland.php | 94 + .../collations/Sami_(Southern)_Norway.php | 94 + .../collations/Sami_(Southern)_Sweden.php | 94 + ...bian_(Cyrillic)_Bosnia_and_Herzegovina.php | 79 + .../collations/Serbian_(Cyrillic)_Serbia.php | 79 + ...Serbian_(Latin)_Bosnia_and_Herzegovina.php | 106 + .../collations/Serbian_(Latin)_Serbia.php | 106 + .../Sesotho_sa_Leboa_South_Africa.php | 104 + .../data/collations/Setswana_South_Africa.php | 104 + .../mpdf/data/collations/Slovak_Slovakia.php | 105 + .../data/collations/Slovenian_Slovenia.php | 104 + .../data/collations/Spanish_Argentina.php | 103 + .../mpdf/data/collations/Spanish_Bolivia.php | 103 + .../mpdf/data/collations/Spanish_Chile.php | 103 + .../mpdf/data/collations/Spanish_Colombia.php | 103 + .../data/collations/Spanish_Costa_Rica.php | 103 + .../collations/Spanish_Dominican_Republic.php | 103 + .../mpdf/data/collations/Spanish_Ecuador.php | 103 + .../data/collations/Spanish_El_Salvador.php | 103 + .../data/collations/Spanish_Guatemala.php | 103 + .../mpdf/data/collations/Spanish_Honduras.php | 103 + .../mpdf/data/collations/Spanish_Mexico.php | 103 + .../data/collations/Spanish_Nicaragua.php | 103 + .../mpdf/data/collations/Spanish_Panama.php | 103 + .../mpdf/data/collations/Spanish_Paraguay.php | 103 + .../mpdf/data/collations/Spanish_Peru.php | 103 + .../data/collations/Spanish_Puerto_Rico.php | 103 + .../mpdf/data/collations/Spanish_Spain.php | 103 + .../data/collations/Spanish_United_States.php | 104 + .../mpdf/data/collations/Spanish_Uruguay.php | 103 + .../data/collations/Spanish_Venezuela.php | 103 + .../mpdf/data/collations/Swedish_Finland.php | 102 + .../mpdf/data/collations/Swedish_Sweden.php | 102 + .../Tajik_(Cyrillic)_Tajikistan.php | 79 + .../collations/Tamazight_(Latin)_Algeria.php | 104 + .../mpdf/data/collations/Tatar_Russia.php | 79 + .../mpdf/data/collations/Turkish_Turkey.php | 97 + .../data/collations/Turkmen_Turkmenistan.php | 104 + .../data/collations/Ukrainian_Ukraine.php | 78 + .../data/collations/Upper_Sorbian_Germany.php | 102 + .../Urdu_Islamic_Republic_of_Pakistan.php | 66 + .../Uzbek_(Cyrillic)_Uzbekistan.php | 79 + .../collations/Uzbek_(Latin)_Uzbekistan.php | 102 + .../data/collations/Vietnamese_Vietnam.php | 90 + .../data/collations/Welsh_United_Kingdom.php | 104 + .../mpdf/data/collations/Wolof_Senegal.php | 104 + .../mpdf/data/collations/Yakut_Russia.php | 78 + .../mpdf/data/collations/Yoruba_Nigeria.php | 104 + .../data/collations/isiXhosa_South_Africa.php | 104 + .../data/collations/isiZulu_South_Africa.php | 104 + .../mpdf/mpdf/data/entity_substitutions.php | 39 + .../vendor/mpdf/mpdf/data/font/ccourier.php | 9 + .../vendor/mpdf/mpdf/data/font/ccourierb.php | 9 + .../vendor/mpdf/mpdf/data/font/ccourierbi.php | 9 + .../vendor/mpdf/mpdf/data/font/ccourieri.php | 9 + .../vendor/mpdf/mpdf/data/font/chelvetica.php | 21 + .../mpdf/mpdf/data/font/chelveticab.php | 21 + .../mpdf/mpdf/data/font/chelveticabi.php | 21 + .../mpdf/mpdf/data/font/chelveticai.php | 21 + .../vendor/mpdf/mpdf/data/font/csymbol.php | 20 + .../vendor/mpdf/mpdf/data/font/ctimes.php | 21 + .../vendor/mpdf/mpdf/data/font/ctimesb.php | 21 + .../vendor/mpdf/mpdf/data/font/ctimesbi.php | 21 + .../vendor/mpdf/mpdf/data/font/ctimesi.php | 21 + .../mpdf/mpdf/data/font/czapfdingbats.php | 20 + .../data/iccprofiles/sRGB_IEC61966-2-1.icc | Bin 0 -> 3052 bytes lib/MPDF/vendor/mpdf/mpdf/data/lang2fonts.css | 394 + .../vendor/mpdf/mpdf/data/linebrdictK.dat | Bin 0 -> 1053144 bytes .../vendor/mpdf/mpdf/data/linebrdictL.dat | Bin 0 -> 126932 bytes .../vendor/mpdf/mpdf/data/linebrdictT.dat | Bin 0 -> 301751 bytes lib/MPDF/vendor/mpdf/mpdf/data/mpdf.css | 94 + lib/MPDF/vendor/mpdf/mpdf/data/no_image.jpg | Bin 0 -> 7888 bytes lib/MPDF/vendor/mpdf/mpdf/data/out.php | 68 + .../vendor/mpdf/mpdf/data/patterns/NOTES.txt | 5 + .../vendor/mpdf/mpdf/data/patterns/de.php | 8 + .../mpdf/mpdf/data/patterns/dictionary.txt | 1 + .../vendor/mpdf/mpdf/data/patterns/en.php | 8 + .../vendor/mpdf/mpdf/data/patterns/es.php | 10 + .../vendor/mpdf/mpdf/data/patterns/fi.php | 8 + .../vendor/mpdf/mpdf/data/patterns/fr.php | 11 + .../vendor/mpdf/mpdf/data/patterns/it.php | 10 + .../vendor/mpdf/mpdf/data/patterns/nl.php | 10 + .../vendor/mpdf/mpdf/data/patterns/pl.php | 8 + .../vendor/mpdf/mpdf/data/patterns/ru.php | 11 + .../vendor/mpdf/mpdf/data/patterns/sv.php | 11 + lib/MPDF/vendor/mpdf/mpdf/data/subs_core.php | 452 + .../vendor/mpdf/mpdf/data/subs_win-1252.php | 306 + lib/MPDF/vendor/mpdf/mpdf/data/upperCase.php | 3 + lib/MPDF/vendor/mpdf/mpdf/phpunit.xml | 22 + lib/MPDF/vendor/mpdf/mpdf/ruleset.xml | 43 + lib/MPDF/vendor/mpdf/mpdf/src/Barcode.php | 150 + .../mpdf/mpdf/src/Barcode/AbstractBarcode.php | 69 + .../mpdf/src/Barcode/BarcodeException.php | 8 + .../mpdf/src/Barcode/BarcodeInterface.php | 30 + .../vendor/mpdf/mpdf/src/Barcode/Codabar.php | 93 + .../vendor/mpdf/mpdf/src/Barcode/Code11.php | 143 + .../vendor/mpdf/mpdf/src/Barcode/Code128.php | 241 + .../vendor/mpdf/mpdf/src/Barcode/Code39.php | 235 + .../vendor/mpdf/mpdf/src/Barcode/Code93.php | 226 + .../vendor/mpdf/mpdf/src/Barcode/EanExt.php | 114 + .../vendor/mpdf/mpdf/src/Barcode/EanUpc.php | 270 + lib/MPDF/vendor/mpdf/mpdf/src/Barcode/I25.php | 137 + lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Imb.php | 366 + lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Msi.php | 98 + .../vendor/mpdf/mpdf/src/Barcode/Postnet.php | 124 + .../vendor/mpdf/mpdf/src/Barcode/Rm4Scc.php | 199 + lib/MPDF/vendor/mpdf/mpdf/src/Barcode/S25.php | 111 + lib/MPDF/vendor/mpdf/mpdf/src/Cache.php | 114 + .../mpdf/mpdf/src/Color/ColorConverter.php | 337 + .../mpdf/src/Color/ColorModeConverter.php | 199 + .../mpdf/src/Color/ColorSpaceRestrictor.php | 214 + .../mpdf/mpdf/src/Color/NamedColors.php | 158 + .../mpdf/mpdf/src/Config/ConfigVariables.php | 524 + .../mpdf/mpdf/src/Config/FontVariables.php | 332 + .../mpdf/mpdf/src/Conversion/DecToAlpha.php | 48 + .../mpdf/mpdf/src/Conversion/DecToCjk.php | 22 + .../mpdf/mpdf/src/Conversion/DecToHebrew.php | 68 + .../mpdf/mpdf/src/Conversion/DecToOther.php | 68 + .../mpdf/mpdf/src/Conversion/DecToRoman.php | 136 + lib/MPDF/vendor/mpdf/mpdf/src/Css/Border.php | 13 + .../vendor/mpdf/mpdf/src/Css/DefaultCss.php | 217 + .../vendor/mpdf/mpdf/src/Css/TextVars.php | 25 + lib/MPDF/vendor/mpdf/mpdf/src/CssManager.php | 2308 ++ lib/MPDF/vendor/mpdf/mpdf/src/DirectWrite.php | 515 + .../Exception/InvalidArgumentException.php | 8 + .../mpdf/src/File/StreamWrapperChecker.php | 46 + .../vendor/mpdf/mpdf/src/Fonts/FontCache.php | 79 + .../mpdf/mpdf/src/Fonts/FontFileFinder.php | 35 + .../mpdf/mpdf/src/Fonts/GlyphOperator.php | 17 + .../mpdf/mpdf/src/Fonts/MetricsGenerator.php | 110 + lib/MPDF/vendor/mpdf/mpdf/src/Form.php | 1828 ++ lib/MPDF/vendor/mpdf/mpdf/src/FpdiTrait.php | 412 + .../vendor/mpdf/mpdf/src/Gif/ColorTable.php | 82 + .../vendor/mpdf/mpdf/src/Gif/FileHeader.php | 94 + lib/MPDF/vendor/mpdf/mpdf/src/Gif/Gif.php | 70 + lib/MPDF/vendor/mpdf/mpdf/src/Gif/Image.php | 187 + .../vendor/mpdf/mpdf/src/Gif/ImageHeader.php | 87 + lib/MPDF/vendor/mpdf/mpdf/src/Gif/Lzw.php | 236 + lib/MPDF/vendor/mpdf/mpdf/src/Gradient.php | 975 + .../vendor/mpdf/mpdf/src/HTMLParserMode.php | 46 + lib/MPDF/vendor/mpdf/mpdf/src/Hyphenator.php | 207 + lib/MPDF/vendor/mpdf/mpdf/src/Image/Bmp.php | 297 + .../mpdf/mpdf/src/Image/ImageProcessor.php | 1435 + .../mpdf/mpdf/src/Image/ImageTypeGuesser.php | 42 + lib/MPDF/vendor/mpdf/mpdf/src/Image/Svg.php | 3933 +++ lib/MPDF/vendor/mpdf/mpdf/src/Image/Wmf.php | 290 + .../mpdf/mpdf/src/Language/LanguageToFont.php | 546 + .../src/Language/LanguageToFontInterface.php | 29 + .../mpdf/src/Language/ScriptToLanguage.php | 141 + .../Language/ScriptToLanguageInterface.php | 12 + lib/MPDF/vendor/mpdf/mpdf/src/Log/Context.php | 22 + lib/MPDF/vendor/mpdf/mpdf/src/Mpdf.php | 27206 ++++++++++++++++ .../vendor/mpdf/mpdf/src/MpdfException.php | 8 + .../mpdf/mpdf/src/MpdfImageException.php | 8 + lib/MPDF/vendor/mpdf/mpdf/src/Otl.php | 6211 ++++ lib/MPDF/vendor/mpdf/mpdf/src/OtlDump.php | 4369 +++ .../mpdf/mpdf/src/Output/Destination.php | 15 + lib/MPDF/vendor/mpdf/mpdf/src/PageFormat.php | 83 + .../vendor/mpdf/mpdf/src/Pdf/Protection.php | 360 + .../src/Pdf/Protection/UniqidGenerator.php | 32 + .../mpdf/mpdf/src/RemoteContentFetcher.php | 148 + .../vendor/mpdf/mpdf/src/ServiceFactory.php | 173 + .../vendor/mpdf/mpdf/src/Shaper/Indic.php | 1945 ++ .../vendor/mpdf/mpdf/src/Shaper/Myanmar.php | 543 + lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Sea.php | 397 + .../vendor/mpdf/mpdf/src/SizeConverter.php | 161 + lib/MPDF/vendor/mpdf/mpdf/src/Strict.php | 67 + lib/MPDF/vendor/mpdf/mpdf/src/TTFontFile.php | 4947 +++ .../mpdf/mpdf/src/TTFontFileAnalysis.php | 454 + .../vendor/mpdf/mpdf/src/TableOfContents.php | 908 + lib/MPDF/vendor/mpdf/mpdf/src/Tag.php | 253 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/A.php | 50 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Acronym.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Address.php | 9 + .../vendor/mpdf/mpdf/src/Tag/Annotation.php | 99 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Article.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Aside.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/B.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/BarCode.php | 256 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdi.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdo.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Big.php | 9 + .../vendor/mpdf/mpdf/src/Tag/BlockQuote.php | 9 + .../vendor/mpdf/mpdf/src/Tag/BlockTag.php | 1352 + .../vendor/mpdf/mpdf/src/Tag/Bookmark.php | 32 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Br.php | 88 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Caption.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Center.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Cite.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Code.php | 9 + .../vendor/mpdf/mpdf/src/Tag/ColumnBreak.php | 8 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Columns.php | 67 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dd.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Del.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Details.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Div.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dl.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/DotTab.php | 68 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dt.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Em.php | 9 + .../vendor/mpdf/mpdf/src/Tag/FieldSet.php | 9 + .../vendor/mpdf/mpdf/src/Tag/FigCaption.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Figure.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Font.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Footer.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Form.php | 9 + .../vendor/mpdf/mpdf/src/Tag/FormFeed.php | 293 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H1.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H2.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H3.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H4.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H5.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/H6.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/HGroup.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Header.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Hr.php | 126 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/I.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Img.php | 458 + .../vendor/mpdf/mpdf/src/Tag/IndexEntry.php | 32 + .../vendor/mpdf/mpdf/src/Tag/IndexInsert.php | 33 + .../vendor/mpdf/mpdf/src/Tag/InlineTag.php | 232 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Input.php | 425 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ins.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Kbd.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Legend.php | 35 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Li.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Main.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Mark.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Meter.php | 517 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Nav.php | 9 + .../vendor/mpdf/mpdf/src/Tag/NewColumn.php | 18 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewPage.php | 8 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ol.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Option.php | 38 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/P.php | 9 + .../vendor/mpdf/mpdf/src/Tag/PageBreak.php | 8 + .../vendor/mpdf/mpdf/src/Tag/PageFooter.php | 153 + .../vendor/mpdf/mpdf/src/Tag/PageHeader.php | 8 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Pre.php | 13 + .../vendor/mpdf/mpdf/src/Tag/Progress.php | 72 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Q.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/S.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Samp.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Section.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Select.php | 154 + .../mpdf/mpdf/src/Tag/SetHtmlPageFooter.php | 73 + .../mpdf/mpdf/src/Tag/SetHtmlPageHeader.php | 9 + .../mpdf/mpdf/src/Tag/SetPageFooter.php | 9 + .../mpdf/mpdf/src/Tag/SetPageHeader.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Small.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Span.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strike.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strong.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sub.php | 9 + .../mpdf/mpdf/src/Tag/SubstituteTag.php | 18 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Summary.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sup.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/TBody.php | 23 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/TFoot.php | 59 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/THead.php | 58 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Table.php | 1272 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tag.php | 121 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Td.php | 469 + .../vendor/mpdf/mpdf/src/Tag/TextArea.php | 162 + .../vendor/mpdf/mpdf/src/Tag/TextCircle.php | 250 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Th.php | 13 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Time.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Toc.php | 17 + .../vendor/mpdf/mpdf/src/Tag/TocEntry.php | 38 + .../vendor/mpdf/mpdf/src/Tag/TocPageBreak.php | 16 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tr.php | 102 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tt.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tta.php | 22 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tts.php | 15 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ttz.php | 15 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/U.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ul.php | 9 + lib/MPDF/vendor/mpdf/mpdf/src/Tag/VarTag.php | 9 + .../mpdf/mpdf/src/Tag/WatermarkImage.php | 41 + .../mpdf/mpdf/src/Tag/WatermarkText.php | 25 + lib/MPDF/vendor/mpdf/mpdf/src/Ucdn.php | 2921 ++ .../vendor/mpdf/mpdf/src/Utils/Arrays.php | 92 + .../mpdf/mpdf/src/Utils/NumericString.php | 18 + .../vendor/mpdf/mpdf/src/Utils/PdfDate.php | 30 + .../vendor/mpdf/mpdf/src/Utils/UtfString.php | 67 + .../mpdf/mpdf/src/Writer/BackgroundWriter.php | 451 + .../mpdf/mpdf/src/Writer/BaseWriter.php | 250 + .../mpdf/mpdf/src/Writer/BookmarkWriter.php | 138 + .../mpdf/mpdf/src/Writer/ColorWriter.php | 46 + .../mpdf/mpdf/src/Writer/FontWriter.php | 680 + .../mpdf/mpdf/src/Writer/FormWriter.php | 63 + .../mpdf/mpdf/src/Writer/ImageWriter.php | 119 + .../mpdf/mpdf/src/Writer/JavaScriptWriter.php | 46 + .../mpdf/mpdf/src/Writer/MetadataWriter.php | 821 + .../mpdf/mpdf/src/Writer/ObjectWriter.php | 64 + .../mpdf/src/Writer/OptionalContentWriter.php | 71 + .../mpdf/mpdf/src/Writer/PageWriter.php | 285 + .../mpdf/mpdf/src/Writer/ResourceWriter.php | 256 + .../vendor/mpdf/mpdf/src/functions-dev.php | 13 + .../mpdf/mpdf/ttfonts/DejaVuSans-Bold.ttf | Bin 0 -> 693876 bytes .../mpdf/ttfonts/DejaVuSans-BoldOblique.ttf | Bin 0 -> 632168 bytes .../mpdf/mpdf/ttfonts/DejaVuSans-Oblique.ttf | Bin 0 -> 632416 bytes .../vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf | Bin 0 -> 741536 bytes .../vendor/mpdf/mpdf/ttfonts/DejaVuinfo.txt | 99 + lib/MPDF/vendor/myclabs/deep-copy/LICENSE | 20 + lib/MPDF/vendor/myclabs/deep-copy/README.md | 376 + .../vendor/myclabs/deep-copy/composer.json | 38 + .../vendor/myclabs/deep-copy/doc/clone.png | Bin 0 -> 12380 bytes .../myclabs/deep-copy/doc/deep-clone.png | Bin 0 -> 14009 bytes .../myclabs/deep-copy/doc/deep-copy.png | Bin 0 -> 10895 bytes .../vendor/myclabs/deep-copy/doc/graph.png | Bin 0 -> 6436 bytes .../deep-copy/src/DeepCopy/DeepCopy.php | 289 + .../src/DeepCopy/Exception/CloneException.php | 9 + .../DeepCopy/Exception/PropertyException.php | 9 + .../Doctrine/DoctrineCollectionFilter.php | 33 + .../DoctrineEmptyCollectionFilter.php | 28 + .../Filter/Doctrine/DoctrineProxyFilter.php | 22 + .../deep-copy/src/DeepCopy/Filter/Filter.php | 18 + .../src/DeepCopy/Filter/KeepFilter.php | 16 + .../src/DeepCopy/Filter/ReplaceFilter.php | 39 + .../src/DeepCopy/Filter/SetNullFilter.php | 24 + .../Matcher/Doctrine/DoctrineProxyMatcher.php | 22 + .../src/DeepCopy/Matcher/Matcher.php | 14 + .../src/DeepCopy/Matcher/PropertyMatcher.php | 39 + .../DeepCopy/Matcher/PropertyNameMatcher.php | 32 + .../DeepCopy/Matcher/PropertyTypeMatcher.php | 46 + .../DeepCopy/Reflection/ReflectionHelper.php | 78 + .../TypeFilter/Date/DateIntervalFilter.php | 33 + .../src/DeepCopy/TypeFilter/ReplaceFilter.php | 30 + .../DeepCopy/TypeFilter/ShallowCopyFilter.php | 17 + .../TypeFilter/Spl/SplDoublyLinkedList.php | 10 + .../Spl/SplDoublyLinkedListFilter.php | 51 + .../src/DeepCopy/TypeFilter/TypeFilter.php | 13 + .../src/DeepCopy/TypeMatcher/TypeMatcher.php | 29 + .../deep-copy/src/DeepCopy/deep_copy.php | 20 + .../vendor/paragonie/random_compat/LICENSE | 22 + .../paragonie/random_compat/build-phar.sh | 5 + .../paragonie/random_compat/composer.json | 34 + .../dist/random_compat.phar.pubkey | 5 + .../dist/random_compat.phar.pubkey.asc | 11 + .../paragonie/random_compat/lib/random.php | 32 + .../random_compat/other/build_phar.php | 57 + .../random_compat/psalm-autoload.php | 9 + .../vendor/paragonie/random_compat/psalm.xml | 19 + lib/MPDF/vendor/psr/log/.gitignore | 1 + lib/MPDF/vendor/psr/log/LICENSE | 19 + .../vendor/psr/log/Psr/Log/AbstractLogger.php | 128 + .../log/Psr/Log/InvalidArgumentException.php | 7 + lib/MPDF/vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 18 + .../psr/log/Psr/Log/LoggerAwareTrait.php | 26 + .../psr/log/Psr/Log/LoggerInterface.php | 125 + .../vendor/psr/log/Psr/Log/LoggerTrait.php | 142 + .../vendor/psr/log/Psr/Log/NullLogger.php | 30 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 146 + .../psr/log/Psr/Log/Test/TestLogger.php | 147 + lib/MPDF/vendor/psr/log/README.md | 58 + lib/MPDF/vendor/psr/log/composer.json | 26 + lib/MPDF/vendor/setasign/fpdi/LICENSE.txt | 21 + lib/MPDF/vendor/setasign/fpdi/README.md | 168 + lib/MPDF/vendor/setasign/fpdi/composer.json | 50 + lib/MPDF/vendor/setasign/fpdi/src/FpdfTpl.php | 22 + .../vendor/setasign/fpdi/src/FpdfTplTrait.php | 466 + lib/MPDF/vendor/setasign/fpdi/src/Fpdi.php | 155 + .../setasign/fpdi/src/FpdiException.php | 19 + .../vendor/setasign/fpdi/src/FpdiTrait.php | 562 + .../CrossReference/AbstractReader.php | 96 + .../CrossReference/CrossReference.php | 320 + .../CrossReferenceException.php | 80 + .../PdfParser/CrossReference/FixedReader.php | 196 + .../PdfParser/CrossReference/LineReader.php | 173 + .../CrossReference/ReaderInterface.php | 35 + .../fpdi/src/PdfParser/Filter/Ascii85.php | 104 + .../src/PdfParser/Filter/Ascii85Exception.php | 28 + .../fpdi/src/PdfParser/Filter/AsciiHex.php | 48 + .../src/PdfParser/Filter/FilterException.php | 24 + .../src/PdfParser/Filter/FilterInterface.php | 26 + .../fpdi/src/PdfParser/Filter/Flate.php | 78 + .../src/PdfParser/Filter/FlateException.php | 28 + .../fpdi/src/PdfParser/Filter/Lzw.php | 189 + .../src/PdfParser/Filter/LzwException.php | 23 + .../setasign/fpdi/src/PdfParser/PdfParser.php | 378 + .../fpdi/src/PdfParser/PdfParserException.php | 50 + .../fpdi/src/PdfParser/StreamReader.php | 468 + .../setasign/fpdi/src/PdfParser/Tokenizer.php | 161 + .../fpdi/src/PdfParser/Type/PdfArray.php | 85 + .../fpdi/src/PdfParser/Type/PdfBoolean.php | 43 + .../fpdi/src/PdfParser/Type/PdfDictionary.php | 135 + .../fpdi/src/PdfParser/Type/PdfHexString.php | 82 + .../src/PdfParser/Type/PdfIndirectObject.php | 104 + .../Type/PdfIndirectObjectReference.php | 53 + .../fpdi/src/PdfParser/Type/PdfName.php | 82 + .../fpdi/src/PdfParser/Type/PdfNull.php | 20 + .../fpdi/src/PdfParser/Type/PdfNumeric.php | 44 + .../fpdi/src/PdfParser/Type/PdfStream.php | 320 + .../fpdi/src/PdfParser/Type/PdfString.php | 172 + .../fpdi/src/PdfParser/Type/PdfToken.php | 44 + .../fpdi/src/PdfParser/Type/PdfType.php | 79 + .../src/PdfParser/Type/PdfTypeException.php | 25 + .../src/PdfReader/DataStructure/Rectangle.php | 174 + .../setasign/fpdi/src/PdfReader/Page.php | 272 + .../fpdi/src/PdfReader/PageBoundaries.php | 95 + .../setasign/fpdi/src/PdfReader/PdfReader.php | 221 + .../fpdi/src/PdfReader/PdfReaderException.php | 35 + .../vendor/setasign/fpdi/src/Tcpdf/Fpdi.php | 266 + .../vendor/setasign/fpdi/src/TcpdfFpdi.php | 23 + .../setasign/fpdi/src/Tfpdf/FpdfTpl.php | 99 + .../vendor/setasign/fpdi/src/Tfpdf/Fpdi.php | 164 + .../vendor/setasign/fpdi/src/autoload.php | 20 + 543 files changed, 111174 insertions(+) create mode 100644 lib/MPDF/composer.json create mode 100644 lib/MPDF/composer.lock create mode 100644 lib/MPDF/vendor/autoload.php create mode 100644 lib/MPDF/vendor/composer/ClassLoader.php create mode 100644 lib/MPDF/vendor/composer/LICENSE create mode 100644 lib/MPDF/vendor/composer/autoload_classmap.php create mode 100644 lib/MPDF/vendor/composer/autoload_files.php create mode 100644 lib/MPDF/vendor/composer/autoload_namespaces.php create mode 100644 lib/MPDF/vendor/composer/autoload_psr4.php create mode 100644 lib/MPDF/vendor/composer/autoload_real.php create mode 100644 lib/MPDF/vendor/composer/autoload_static.php create mode 100644 lib/MPDF/vendor/composer/installed.json create mode 100644 lib/MPDF/vendor/mpdf/mpdf/.gitignore create mode 100644 lib/MPDF/vendor/mpdf/mpdf/.travis.yml create mode 100644 lib/MPDF/vendor/mpdf/mpdf/CHANGELOG.md create mode 100644 lib/MPDF/vendor/mpdf/mpdf/CREDITS.txt create mode 100644 lib/MPDF/vendor/mpdf/mpdf/LICENSE.txt create mode 100644 lib/MPDF/vendor/mpdf/mpdf/README.md create mode 100644 lib/MPDF/vendor/mpdf/mpdf/composer.json create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/CJKdata.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Afrikaans_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Albanian_Albania.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Alsatian_France.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Algeria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Bahrain.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Egypt.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Iraq.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Jordan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Kuwait.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Lebanon.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Libya.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Morocco.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Oman.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Pseudo_RTL.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Qatar.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Saudi_Arabia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Syria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Tunisia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Arabic_Yemen.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Azeri_(Cyrillic)_Azerbaijan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Azeri_(Latin)_Azerbaijan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Bashkir_Russia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Basque_Spain.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Belarusian_Belarus.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Bosnian_(Cyrillic)_Bosnia_and_Herzegovina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Bosnian_(Latin)_Bosnia_and_Herzegovina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Breton_France.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Bulgarian_Bulgaria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Catalan_Spain.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Corsican_France.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Croatian_(Latin)_Bosnia_and_Herzegovina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Croatian_Croatia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Czech_Czech_Republic.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Danish_Denmark.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Dari_Afghanistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Dutch_Belgium.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Dutch_Netherlands.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Australia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Belize.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Canada.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Caribbean.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_India.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Ireland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Jamaica.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Malaysia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_New_Zealand.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Republic_of_the_Philippines.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Singapore.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Trinidad_and_Tobago.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_United_Kingdom.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_United_States.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/English_Zimbabwe.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Estonian_Estonia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Faroese_Faroe_Islands.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Filipino_Philippines.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Finnish_Finland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_Belgium.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_Canada.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_France.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_Luxembourg.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_Principality_of_Monaco.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/French_Switzerland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Frisian_Netherlands.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Galician_Spain.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/German_Austria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/German_Germany.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/German_Liechtenstein.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/German_Luxembourg.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/German_Switzerland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Greek_Greece.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Greenlandic_Greenland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Hausa_(Latin)_Nigeria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Hebrew_Israel.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Hungarian_Hungary.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Icelandic_Iceland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Igbo_Nigeria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Indonesian_Indonesia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Inuktitut_(Latin)_Canada.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Invariant_Language_Invariant_Country.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Irish_Ireland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Italian_Italy.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Italian_Switzerland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Kinyarwanda_Rwanda.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Kiswahili_Kenya.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Kyrgyz_Kyrgyzstan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Latvian_Latvia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Lithuanian_Lithuania.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Lower_Sorbian_Germany.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Luxembourgish_Luxembourg.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Macedonian_(FYROM)_Macedonia_(FYROM).php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Malay_Brunei_Darussalam.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Malay_Malaysia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Mapudungun_Chile.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Mohawk_Canada.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Mongolian_(Cyrillic)_Mongolia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Norwegian_(Nynorsk)_Norway.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Occitan_France.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Persian_Iran.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Polish_Poland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Portuguese_Brazil.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Portuguese_Portugal.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Quechua_Bolivia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Quechua_Ecuador.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Quechua_Peru.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Romanian_Romania.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Romansh_Switzerland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Russian_Russia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Inari)_Finland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Lule)_Norway.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Lule)_Sweden.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Northern)_Finland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Northern)_Norway.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Northern)_Sweden.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Skolt)_Finland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Southern)_Norway.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sami_(Southern)_Sweden.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Serbian_(Cyrillic)_Bosnia_and_Herzegovina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Serbian_(Cyrillic)_Serbia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Serbian_(Latin)_Bosnia_and_Herzegovina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Serbian_(Latin)_Serbia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Sesotho_sa_Leboa_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Setswana_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Slovak_Slovakia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Slovenian_Slovenia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Argentina.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Bolivia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Chile.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Colombia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Costa_Rica.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Dominican_Republic.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Ecuador.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_El_Salvador.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Guatemala.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Honduras.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Mexico.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Nicaragua.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Panama.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Paraguay.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Peru.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Puerto_Rico.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Spain.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_United_States.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Uruguay.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Spanish_Venezuela.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Swedish_Finland.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Swedish_Sweden.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Tajik_(Cyrillic)_Tajikistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Tamazight_(Latin)_Algeria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Tatar_Russia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Turkish_Turkey.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Turkmen_Turkmenistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Ukrainian_Ukraine.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Upper_Sorbian_Germany.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Urdu_Islamic_Republic_of_Pakistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Uzbek_(Cyrillic)_Uzbekistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Uzbek_(Latin)_Uzbekistan.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Vietnamese_Vietnam.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Welsh_United_Kingdom.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Wolof_Senegal.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Yakut_Russia.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/Yoruba_Nigeria.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/isiXhosa_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/collations/isiZulu_South_Africa.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/entity_substitutions.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ccourier.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ccourierb.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ccourierbi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ccourieri.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/chelvetica.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/chelveticab.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/chelveticabi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/chelveticai.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/csymbol.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ctimes.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ctimesb.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ctimesbi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/ctimesi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/font/czapfdingbats.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/iccprofiles/sRGB_IEC61966-2-1.icc create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/lang2fonts.css create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/linebrdictK.dat create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/linebrdictL.dat create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/linebrdictT.dat create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/mpdf.css create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/no_image.jpg create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/out.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/NOTES.txt create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/de.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/dictionary.txt create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/en.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/es.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/fi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/fr.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/it.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/nl.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/pl.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/ru.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/patterns/sv.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/subs_core.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/subs_win-1252.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/data/upperCase.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/phpunit.xml create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ruleset.xml create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/AbstractBarcode.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/BarcodeException.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/BarcodeInterface.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Codabar.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Code11.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Code128.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Code39.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Code93.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/EanExt.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/EanUpc.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/I25.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Imb.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Msi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Postnet.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/Rm4Scc.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Barcode/S25.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Cache.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Color/ColorConverter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Color/ColorModeConverter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Color/ColorSpaceRestrictor.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Color/NamedColors.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Config/ConfigVariables.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Config/FontVariables.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Conversion/DecToAlpha.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Conversion/DecToCjk.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Conversion/DecToHebrew.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Conversion/DecToOther.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Conversion/DecToRoman.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Css/Border.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Css/DefaultCss.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Css/TextVars.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/CssManager.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/DirectWrite.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Exception/InvalidArgumentException.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/File/StreamWrapperChecker.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Fonts/FontCache.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Fonts/FontFileFinder.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Fonts/GlyphOperator.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Fonts/MetricsGenerator.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Form.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/FpdiTrait.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/ColorTable.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/FileHeader.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/Gif.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/Image.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/ImageHeader.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gif/Lzw.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Gradient.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/HTMLParserMode.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Hyphenator.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Image/Bmp.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Image/ImageProcessor.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Image/ImageTypeGuesser.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Image/Svg.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Image/Wmf.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Language/LanguageToFont.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Language/LanguageToFontInterface.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Language/ScriptToLanguage.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Language/ScriptToLanguageInterface.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Log/Context.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Mpdf.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/MpdfException.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/MpdfImageException.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Otl.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/OtlDump.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Output/Destination.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/PageFormat.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/RemoteContentFetcher.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/ServiceFactory.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Indic.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Myanmar.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Sea.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/SizeConverter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Strict.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/TTFontFile.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/TTFontFileAnalysis.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/TableOfContents.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/A.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Acronym.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Address.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Annotation.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Article.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Aside.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/B.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/BarCode.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdi.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdo.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Big.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockQuote.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockTag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bookmark.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Br.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Caption.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Center.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Cite.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Code.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/ColumnBreak.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Columns.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dd.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Del.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Details.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Div.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dl.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/DotTab.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dt.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Em.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/FieldSet.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/FigCaption.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Figure.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Font.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Footer.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Form.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/FormFeed.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H1.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H2.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H3.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H4.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H5.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/H6.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/HGroup.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Header.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Hr.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/I.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Img.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexEntry.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexInsert.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/InlineTag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Input.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ins.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Kbd.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Legend.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Li.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Main.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Mark.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Meter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Nav.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewColumn.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewPage.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ol.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Option.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/P.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageBreak.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageFooter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageHeader.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Pre.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Progress.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Q.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/S.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Samp.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Section.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Select.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageFooter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageHeader.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Small.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Span.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strike.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strong.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sub.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/SubstituteTag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Summary.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sup.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TBody.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TFoot.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/THead.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Table.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Td.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextArea.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextCircle.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Th.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Time.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Toc.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocEntry.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocPageBreak.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tr.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tt.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tta.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tts.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ttz.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/U.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ul.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/VarTag.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkImage.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkText.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Ucdn.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Utils/Arrays.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Utils/NumericString.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Utils/PdfDate.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Utils/UtfString.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/BackgroundWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/BaseWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/BookmarkWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/ColorWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/FontWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/FormWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/ImageWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/JavaScriptWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/MetadataWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/ObjectWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/OptionalContentWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/PageWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/Writer/ResourceWriter.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/src/functions-dev.php create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Bold.ttf create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-BoldOblique.ttf create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Oblique.ttf create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf create mode 100644 lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuinfo.txt create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/LICENSE create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/README.md create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/composer.json create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/doc/clone.png create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/doc/deep-clone.png create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/doc/deep-copy.png create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/doc/graph.png create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php create mode 100644 lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php create mode 100644 lib/MPDF/vendor/paragonie/random_compat/LICENSE create mode 100755 lib/MPDF/vendor/paragonie/random_compat/build-phar.sh create mode 100644 lib/MPDF/vendor/paragonie/random_compat/composer.json create mode 100644 lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey create mode 100644 lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc create mode 100644 lib/MPDF/vendor/paragonie/random_compat/lib/random.php create mode 100644 lib/MPDF/vendor/paragonie/random_compat/other/build_phar.php create mode 100644 lib/MPDF/vendor/paragonie/random_compat/psalm-autoload.php create mode 100644 lib/MPDF/vendor/paragonie/random_compat/psalm.xml create mode 100644 lib/MPDF/vendor/psr/log/.gitignore create mode 100644 lib/MPDF/vendor/psr/log/LICENSE create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 lib/MPDF/vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 lib/MPDF/vendor/psr/log/README.md create mode 100644 lib/MPDF/vendor/psr/log/composer.json create mode 100644 lib/MPDF/vendor/setasign/fpdi/LICENSE.txt create mode 100644 lib/MPDF/vendor/setasign/fpdi/README.md create mode 100644 lib/MPDF/vendor/setasign/fpdi/composer.json create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/FpdfTpl.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/FpdfTplTrait.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/Fpdi.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/FpdiException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/FpdiTrait.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/AbstractReader.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReferenceException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/FixedReader.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/LineReader.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/ReaderInterface.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Ascii85.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Ascii85Exception.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/AsciiHex.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FilterException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FilterInterface.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Flate.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FlateException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Lzw.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/LzwException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/PdfParser.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/PdfParserException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/StreamReader.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Tokenizer.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfNumeric.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfReader/DataStructure/Rectangle.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfReader/Page.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PageBoundaries.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PdfReader.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PdfReaderException.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/TcpdfFpdi.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/Tfpdf/FpdfTpl.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php create mode 100644 lib/MPDF/vendor/setasign/fpdi/src/autoload.php diff --git a/lib/MPDF/composer.json b/lib/MPDF/composer.json new file mode 100644 index 0000000..49fa66e --- /dev/null +++ b/lib/MPDF/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "mpdf/mpdf": "^8.0" + } +} diff --git a/lib/MPDF/composer.lock b/lib/MPDF/composer.lock new file mode 100644 index 0000000..52264c0 --- /dev/null +++ b/lib/MPDF/composer.lock @@ -0,0 +1,288 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "4eb8b6908db5ba53816b92c15345ed52", + "packages": [ + { + "name": "mpdf/mpdf", + "version": "v8.0.3", + "source": { + "type": "git", + "url": "https://github.com/mpdf/mpdf.git", + "reference": "6dd4285aff21f013554ff752046bb44ab1240f5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/mpdf/zipball/6dd4285aff21f013554ff752046bb44ab1240f5f", + "reference": "6dd4285aff21f013554ff752046bb44ab1240f5f", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "ext-mbstring": "*", + "myclabs/deep-copy": "^1.7", + "paragonie/random_compat": "^1.4|^2.0|9.99.99", + "php": "^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0", + "psr/log": "^1.0", + "setasign/fpdi": "^2.1" + }, + "require-dev": { + "mockery/mockery": "^0.9.5", + "mpdf/qrcode": "^1.0.0", + "phpunit/phpunit": "^5.0", + "squizlabs/php_codesniffer": "^3.5.0", + "tracy/tracy": "^2.4" + }, + "suggest": { + "ext-bcmath": "Needed for generation of some types of barcodes", + "ext-xml": "Needed mainly for SVG manipulation", + "ext-zlib": "Needed for compression of embedded resources, such as fonts" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-development": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Mpdf\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-only" + ], + "authors": [ + { + "name": "Matěj Humpál", + "role": "Developer, maintainer" + }, + { + "name": "Ian Back", + "role": "Developer (retired)" + } + ], + "description": "PHP library generating PDF files from UTF-8 encoded HTML", + "homepage": "https://mpdf.github.io", + "keywords": [ + "pdf", + "php", + "utf-8" + ], + "time": "2019-10-25T17:54:07+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.3", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2019-08-09T12:45:53+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "psr/log", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2019-11-01T11:05:21+00:00" + }, + { + "name": "setasign/fpdi", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/Setasign/FPDI.git", + "reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Setasign/FPDI/zipball/3c266002f8044f61b17329f7cd702d44d73f0f7f", + "reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f", + "shasum": "" + }, + "require": { + "ext-zlib": "*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7", + "setasign/fpdf": "~1.8", + "setasign/tfpdf": "1.25", + "tecnickcom/tcpdf": "~6.2" + }, + "suggest": { + "setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured.", + "setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.", + "setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF.", + "setasign/fpdi-tfpdf": "Use this package to automatically evaluate dependencies to tFPDF." + }, + "type": "library", + "autoload": { + "psr-4": { + "setasign\\Fpdi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Slabon", + "email": "jan.slabon@setasign.com", + "homepage": "https://www.setasign.com" + }, + { + "name": "Maximilian Kresse", + "email": "maximilian.kresse@setasign.com", + "homepage": "https://www.setasign.com" + } + ], + "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.", + "homepage": "https://www.setasign.com/fpdi", + "keywords": [ + "fpdf", + "fpdi", + "pdf" + ], + "time": "2019-01-30T14:11:19+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/lib/MPDF/vendor/autoload.php b/lib/MPDF/vendor/autoload.php new file mode 100644 index 0000000..5dab4cf --- /dev/null +++ b/lib/MPDF/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/lib/MPDF/vendor/composer/LICENSE b/lib/MPDF/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/lib/MPDF/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/lib/MPDF/vendor/composer/autoload_classmap.php b/lib/MPDF/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..7a91153 --- /dev/null +++ b/lib/MPDF/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', +); diff --git a/lib/MPDF/vendor/composer/autoload_namespaces.php b/lib/MPDF/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/lib/MPDF/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/setasign/fpdi/src'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Mpdf\\' => array($vendorDir . '/mpdf/mpdf/src'), + 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), +); diff --git a/lib/MPDF/vendor/composer/autoload_real.php b/lib/MPDF/vendor/composer/autoload_real.php new file mode 100644 index 0000000..78cb1ab --- /dev/null +++ b/lib/MPDF/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit464b8cc4726849d52f4325e9114ac125::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit464b8cc4726849d52f4325e9114ac125::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire464b8cc4726849d52f4325e9114ac125($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire464b8cc4726849d52f4325e9114ac125($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/lib/MPDF/vendor/composer/autoload_static.php b/lib/MPDF/vendor/composer/autoload_static.php new file mode 100644 index 0000000..d855abc --- /dev/null +++ b/lib/MPDF/vendor/composer/autoload_static.php @@ -0,0 +1,59 @@ + __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', + ); + + public static $prefixLengthsPsr4 = array ( + 's' => + array ( + 'setasign\\Fpdi\\' => 14, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + ), + 'M' => + array ( + 'Mpdf\\' => 5, + ), + 'D' => + array ( + 'DeepCopy\\' => 9, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'setasign\\Fpdi\\' => + array ( + 0 => __DIR__ . '/..' . '/setasign/fpdi/src', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Mpdf\\' => + array ( + 0 => __DIR__ . '/..' . '/mpdf/mpdf/src', + ), + 'DeepCopy\\' => + array ( + 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit464b8cc4726849d52f4325e9114ac125::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit464b8cc4726849d52f4325e9114ac125::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/lib/MPDF/vendor/composer/installed.json b/lib/MPDF/vendor/composer/installed.json new file mode 100644 index 0000000..25093fe --- /dev/null +++ b/lib/MPDF/vendor/composer/installed.json @@ -0,0 +1,282 @@ +[ + { + "name": "mpdf/mpdf", + "version": "v8.0.3", + "version_normalized": "8.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/mpdf/mpdf.git", + "reference": "6dd4285aff21f013554ff752046bb44ab1240f5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mpdf/mpdf/zipball/6dd4285aff21f013554ff752046bb44ab1240f5f", + "reference": "6dd4285aff21f013554ff752046bb44ab1240f5f", + "shasum": "" + }, + "require": { + "ext-gd": "*", + "ext-mbstring": "*", + "myclabs/deep-copy": "^1.7", + "paragonie/random_compat": "^1.4|^2.0|9.99.99", + "php": "^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0", + "psr/log": "^1.0", + "setasign/fpdi": "^2.1" + }, + "require-dev": { + "mockery/mockery": "^0.9.5", + "mpdf/qrcode": "^1.0.0", + "phpunit/phpunit": "^5.0", + "squizlabs/php_codesniffer": "^3.5.0", + "tracy/tracy": "^2.4" + }, + "suggest": { + "ext-bcmath": "Needed for generation of some types of barcodes", + "ext-xml": "Needed mainly for SVG manipulation", + "ext-zlib": "Needed for compression of embedded resources, such as fonts" + }, + "time": "2019-10-25T17:54:07+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-development": "7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Mpdf\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-only" + ], + "authors": [ + { + "name": "Matěj Humpál", + "role": "Developer, maintainer" + }, + { + "name": "Ian Back", + "role": "Developer (retired)" + } + ], + "description": "PHP library generating PDF files from UTF-8 encoded HTML", + "homepage": "https://mpdf.github.io", + "keywords": [ + "pdf", + "php", + "utf-8" + ] + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.3", + "version_normalized": "1.9.3.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "time": "2019-08-09T12:45:53+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ] + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "version_normalized": "9.99.99.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2018-07-02T15:55:56+00:00", + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ] + }, + { + "name": "psr/log", + "version": "1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", + "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2019-11-01T11:05:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "setasign/fpdi", + "version": "v2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/Setasign/FPDI.git", + "reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Setasign/FPDI/zipball/3c266002f8044f61b17329f7cd702d44d73f0f7f", + "reference": "3c266002f8044f61b17329f7cd702d44d73f0f7f", + "shasum": "" + }, + "require": { + "ext-zlib": "*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7", + "setasign/fpdf": "~1.8", + "setasign/tfpdf": "1.25", + "tecnickcom/tcpdf": "~6.2" + }, + "suggest": { + "setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured.", + "setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.", + "setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF.", + "setasign/fpdi-tfpdf": "Use this package to automatically evaluate dependencies to tFPDF." + }, + "time": "2019-01-30T14:11:19+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "setasign\\Fpdi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Slabon", + "email": "jan.slabon@setasign.com", + "homepage": "https://www.setasign.com" + }, + { + "name": "Maximilian Kresse", + "email": "maximilian.kresse@setasign.com", + "homepage": "https://www.setasign.com" + } + ], + "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.", + "homepage": "https://www.setasign.com/fpdi", + "keywords": [ + "fpdf", + "fpdi", + "pdf" + ] + } +] diff --git a/lib/MPDF/vendor/mpdf/mpdf/.gitignore b/lib/MPDF/vendor/mpdf/mpdf/.gitignore new file mode 100644 index 0000000..0bfe817 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/.gitignore @@ -0,0 +1,2 @@ +vendor/* +composer.lock diff --git a/lib/MPDF/vendor/mpdf/mpdf/.travis.yml b/lib/MPDF/vendor/mpdf/mpdf/.travis.yml new file mode 100644 index 0000000..7bac3e6 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/.travis.yml @@ -0,0 +1,53 @@ +language: php + +dist: xenial + +group: edge + +php: + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - 7.3 + - 7.4snapshot + - nightly + +matrix: + + include: + + - env: LINT=1 + php: 7.1 + #- env: COVERAGE=1 + # php: 7.1 + + allow_failures: + - php: nightly + +install: + - composer self-update + - echo "${TRAVIS_PHP_VERSION:0:3}" + - | + if [[ "${TRAVIS_PHP_VERSION:0:7}" == "nightly" ]]; then + composer install --ignore-platform-reqs + elif [[ "${TRAVIS_PHP_VERSION:0:11}" == "7.4snapshot" ]]; then + composer install --ignore-platform-reqs + else + composer install + fi + +script: + - | + if [[ "$LINT" == "1" ]]; then + composer cs + elif [[ "$COVERAGE" == "1" ]]; then + composer coverage + else + composer test + fi + +notifications: + email: + on_success: change + on_failure: always diff --git a/lib/MPDF/vendor/mpdf/mpdf/CHANGELOG.md b/lib/MPDF/vendor/mpdf/mpdf/CHANGELOG.md new file mode 100644 index 0000000..a31d16d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/CHANGELOG.md @@ -0,0 +1,741 @@ +mPDF 8.1.x +=========================== + +* Add proxy support to curl +* Fixed date and time format in the informations dictionary (#1083, @peterdevpl) +* Checking allowed stream wrappers in CssManager +* PHP 7.4 support (until final 7.4 release with composer --ignore-platform-reqs) +* Improve debugging of remote content issues (@ribeirobreno) + +mPDF 8.0.x +=========================== + +* Added the check for JPEG SOF header 0xFF 0xC1 (extended) (@jamiejones85) +* Allows setting `none` as zoom mode in `SetDisplayMode` method, so that OpenAction is not written (#602) +* Allowed image stream whitelist to be customised (#1005, thanks @jakejackson) +* Fixed parsing of top-left-bottom-right CSS rules with !important (#1009) +* Fixed skipping ordered list numbering with page-break-inside: avoid (#339) +* Compound classes selector support, like `.one.two` or `div.message.special` (#538, @peterdevpl) + +mPDF 8.0.0 +=========================== + +### 15/03/2019 + +* Updated FPDI dependency to version 2 (thanks a lot, @JanSlabon) + - removed `SetImportUse` method + - case of `ImportPage` method changed to `importPage` + - similarly, case of `setSourceFile` and `useTemplate` was changed to a lowercase first letter. + - signature of `importPage` changed + - returned value of `useTemplate` changed +* Moved QRCode generating code portions to external package _mpdf/qrcode_ + - This reduced package size considerably (ca 6MB) +* Fraction sizes without leading zeros allowed for font sizes (#973, thanks @peterdevpl) +* WriteHTML is now strict about used `$mode` parameter (#915, thanks, @tomtomau) +* Fixed regression in nested tables (#860, thanks, @machour) +* Scientific notation handling in CSS font sizes (#753, thanks, @peterdevpl) + + +mPDF 7.1.x +=========================== + +* PHAR security issue fixed (thanks, @jakejackson) +* Font temporary data saved as JSON instead of generating PHP files (thanks, @jakejackson) +* cURL handling enhancements (thanks, @jakejackson) +* SVG parsing fixes (thanks, @achretien) +* Write PDF content with *Writer service classes +* PHP 7.3 is supported +* Added myclabs/deepcopy dependency, fixed TOC page numbering (thanks, @jakejackson) +* Custom color for QR codes +* Added support for orientation config key +* Code and tests cleanups and enhancements + - PHPUnit dedicated assertions (thanks, @carusogabriel) + - WriteHTML part constants (thanks, @tomtomau) + - Various notice fixes (kudos to all respective authors) + +mPDF 7.0.x +=========================== + +* Allow passing file content or file path to `SetAssociatedFiles` (#558) +* Allowed ^1.4 and ^2.0 of paragon/random_compat to allow wider usage +* Fix of undefined _getImage function (#539) +* Code cleanup +* Better writable rights for temp dir validation (#534) +* Fix displaying dollar character in footer with core fonts (#520) +* Fixed missed code2utf call (#531) +* Refactored and cleaned-up classes and subnamespaces + + +mPDF 7.0.0 +=========================== + +### 19/10/2017 + +Backward incompatible changes +----------------------------- + +- PHP `^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0` is required. +- Entire project moved under `Mpdf` namespace + - Practically all classes renamed to use `PascalCase` and named to be more verbose + - Changed directory structure to comply to `PSR-4` +- Removed explicit require calls, replaced with Composer autoloading +- Removed configuration files + - All configuration now done via `__construct` parameter (see below) +- Changed `\Mpdf\Mpdf` constructor signature + - Class now accepts only single array `$config` parameter + - Array keys are former `config.php` and `config_fonts.php` properties + - Additionally, former constructor parameters can be used as keys +- `tempDir` directory now must be writable, otherwise an exception is thrown +- ICC profile is loaded as entire path to file (to prevent a need to write inside vendor directory) +- Moved examples to separate repository +- Moved `TextVars` constants to separate class +- Moved border constants to separate class +- `scriptToLang` and `langToFont` in separate interfaced class methods +- Will now throw an exception when `mbstring.func_overload` is set +- Moved Glyph operator `GF_` constants in separate `\Mpdf\Fonts\GlyphOperator` class +- All methods in Barcode class renamed to camelCase including public `dec_to_hex` and `hex_to_dec` +- Decimal conversion methods (to roman, cjk, etc.) were moved to classes in `\Mpdf\Conversion` namespace +- Images in PHP variables (``) were moved from direct Mpdf properties to `Mpdf::$imageVars` public property array +- Removed global `_SVG_AUTOFONT` and `_SVG_CLASSES` constants in favor of `svgAutoFont` and `svgClasses` configuration keys +- Moved global `_testIntersect`, `_testIntersectCircle` and `calc_bezier_bbox` fucntions inside `Svg` class as private methods. + - Changed names to camelCase without underscores and to `computeBezierBoundingBox` +- Security: Embedded files via `` custom tag must be explicitly allowed via `allowAnnotationFiles` configuration key +- `fontDir` property of Mpdf class is private and must be accessed via configuration variable with array of paths or `AddFontDirectory` method +- QR code `` element now treats `\r\n` and `\n` as actual line breaks +- cURL is prefered over socket when downloading images. +- Removed globally defined functions from `functions.php` in favor of `\Mpdf\Utils` classes `PdfDate` and `UtfString`. + - Unused global functions were removed entirely. + + +Removed features +---------------- + +- Progressbar support +- JpGraph support +- `error_reporting` changes +- Timezone changes +- `compress.php` utility +- `_MPDF_PATH` and `_MPDF_URI` constants +- `_MPDF_TEMP_PATH` constant in favor of `tempDir` configuration variable +- `_MPDF_TTFONTDATAPATH` in favor of `tempDir` configuration variable +- `_MPDFK` constant in favor of `\Mpdf\Mpdf::SCALE` class constant +- `FONT_DESCRIPTOR` constant in favor of `fontDescriptor` configuration variable +- `_MPDF_SYSTEM_TTFONTS` constant in favor of `fontDir` configuration variable with array of paths or `AddFontDirectory` method +- HTML output of error messages and debugs +- Formerly deprecated methods + + +Fixes and code enhancements +---------------------------- + +- Fixed joining arab letters +- Fixed redeclared `unicode_hex` function +- Converted arrays to short syntax +- Refactored and tested color handling with potential conversion fixes in `hsl*()` color definitions +- Refactored `Barcode` class with separate class in `Mpdf\Barcode` namespace for each barcode type +- Fixed colsum calculation for different locales (by @flow-control in #491) +- Image type guessing from content separated to its own class + + +New features +------------ + +- Refactored caching (custom `Cache` and `FontCache` classes) +- Implemented `Psr\Log\LoggerAware` interface + - All debug and additional messages are now sent to the logger + - Messages can be filtered based on `\Mpdf\Log\Context` class constants +- `FontFileFinder` class allowing to specify multiple paths to search for fonts +- `MpdfException` now extends `ErrorException` to allow specifying place in code where error occured +- Generating font metrics moved to separate class +- Added `\Mpdf\Output\Destination` class with verbose output destination constants +- Availability to set custom default CSS file +- Availability to set custom hyphenation dictionary file +- Refactored code portions to new "separate" classes: + - `Mpdf\Color\*` classes + - `ColorConvertor` + - `ColorModeConvertor` + - `ColorSpaceRestrictor` + - `Mpdf\SizeConvertor` + - `Mpdf\Hyphenator` + - `Mpdf\Image\ImageProcessor` + - `Mpdf\Image\ImageTypeGuesser` + - `Mpdf\Conversion\*` classes +- Custom watermark angle with `watermarkAngle` configuration variable +- Custom document properties (idea by @zarubik in #142) +- PDF/A-3 associated files + additional xmp rdf (by @chab in #130) +- Additional font directories can be added via `addFontDir` method +- Introduced `cleanup` method which restores original `mb_` encoding settings (see #421) +- QR code `` element now treats `\r\n` and `\n` as actual line breaks +- Customizable following of 3xx HTTP redirects, validation of SSL certificates, cURL timeout. + - `curlFollowLocation` + - `curlAllowUnsafeSslRequests` + - `curlTimeout` +- QR codes can be generated without a border using `disableborder="1"` HTML attribute in `` tag + + +Git repository enhancements +--------------------------- + +- Added contributing guidelines +- Added Issue template + + +mPDF 6.1.0 +=========================== + +### 26/04/2016 + +- Composer updates + - First release officially supporting Composer + - Updated license in composer.json + - Chmod 777 on dirs `ttfontdata`, `tmp`, `graph_cache` after composer install +- Requiring PHP 5.4.0+ with Composer +- Code style + - Reformated (almost) all PHP files to keep basic code style + - Removed trailing whitespaces + - Converted all txt, php, css, and htm files to utf8 + - Removed closing PHP tags + - Change all else if calls to elseif +- Added base PHPUnit tests +- Added Travis CI integration with unit tests +- Changed all `mPDF::Error` and `die()` calls to throwing `MpdfException` +- PDF Import changes + - FPDI updated to 1.6.0 to fix incompatible licenses + - FPDI loaded from Composer or manually only +- Removed iccprofiles/CMYK directory +- Renamed example files: change spaces to underscores to make scripting easier +- Fixed `LEDGER` and `TABLOID` paper sizes +- Implemented static cache for mpdf function `ConvertColor`. +- Removed PHP4 style constructors +- Work with HTML tags separated to `Tag` class +- Fixed most Strict standards PHP errors +- Add config constant so we can define custom font data +- HTML + - fax & tel support in href attribute + - Check $html in `$mpdf->WriteHTML()` to see if it is an integer, float, string, boolean or + a class with `__toString()` and cast to a string, otherwise throw exception. +- PHP 7 + - Fix getting image from internal variable in PHP7 (4dcc2b4) + - Fix PHP7 Fatal error: `'break' not in the 'loop' or 'switch' context` (002bb8a) +- Fixed output file name for `D` and `I` output modes (issue #105, f297546) + +mPDF 6.0 +=========================== + +### 20/12/2014 + +New features / Improvements +--------------------------- +- Support for OpenTypeLayout tables / features for complex scripts and Advances Typography. +- Improved bidirectional text handling. +- Improved line-breaking, including for complex scripts e.g. Lao, Thai and Khmer. +- Updated page-breaking options. +- Automatic language mark-up and font selection using autoScriptToLang and autoLangToFont. +- Kashida for text-justification in arabic scripts. +- Index collation for non-ASCII characters. +- Index mark-up allowing control over layout using CSS. +- `{PAGENO}` and `{nbpg}` can use any of the number types as in list-style e.g. set in `` using pagenumstyle. +- CSS support for lists. +- Default stylesheet - `mpdf.css` - updated. + +Added CSS support +----------------- +- lang attribute selector e.g. :lang(fr), [lang="fr"] +- font-variant-position +- font-variant-caps +- font-variant-ligatures +- font-variant-numeric +- font-variant-alternates - Only [normal | historical-forms] supported (i.e. most are NOT supported) +- font-variant - as above, and except for: east-asian-variant-values, east-asian-width-values, ruby +- font-language-override +- font-feature-settings +- text-outline is now supported on TD/TH tags +- hebrew, khmer, cambodian, lao, and cjk-decimal recognised as values for "list-style-type" in numbered lists and page numbering. +- list-style-image and list-style-position +- transform (on `` only) +- text-decoration:overline +- image-rendering +- unicode-bidi (also `` tag) +- vertical-align can use lengths e.g. 0.5em +- line-stacking-strategy +- line-stacking-shift + +mPDF 5.7.4 +================ + +### 15/12/2014 + +Bug Fixes & Minor Additions +--------------------------- +- SVG images now support embedded images e.g. `` +- SVG images now supports `` element e.g. ``, and also `` +- SVG images now can use Autofont (see top of `classes/svg.php` file) +- SVG images now has limited support for CSS classes (see top of `classes/svg.php` file) +- SVG images - style inheritance improved +- SVG images - improved handling of comments and other extraneous code +- SVG images - fix to ensure opacity is reset before another element +- SVG images - font-size not resetting after a `` element +- SVG radial gradients bug (if the focus [fx,fy] lies outside circle defined by [cx,cy] and r) cf. pservers-grad-15-b.svg +- SVG allows spaces in attribute definitions in `` or `` e.g. `` +- SVG text which contains a `<` sign, it will break the text - now processed as `<` (despite the fact that this does not conform to XML spec) +- SVG images - support automatic font selection and (minimal) use of CSS classes - cf. the defined constants at top of svg.php file +- SVG images - text-anchor now supported as a CSS style, as well as an HTML attribute +- CSS support for :nth-child() selector improved to fully support the draft CSS3 spec - http://www.w3.org/TR/selectors/#nth-child-pseudo + [NB only works on table columns or rows] +- text-indent when set as "em" - incorrectly calculated if last text in line in different font size than for block +- CSS not applying cascaded styles on `` elements - [changed MergeCSS() type to INLINE for 'A', LEGEND, METER and PROGRESS] +- fix for underline/strikethrough/overline so that line position(s) are based correctly on font-size/font in nested situations +- Error: Strict warning: Only variables should be passed by reference - in PHP5.5.9 +- bug accessing images from some servers (HTTP 403 Forbidden whn accessed using fopen etc.) +- Setting page format incorrectly set default twice and missed some options +- bug fixed in Overwrite() when specifying replacement as a string +- barcode C93 - updated C93 code from TCPDF because of bug - incorrect checksum character for "153-2-4" +- Tables - bug when using colspan across columns which may have a cell width specified + cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug +- Tables - cell height (when specified) is not resized when table is shrunk +- Tables - if table width specified, but narrower than minimum cell wdith, and less than page width - table will expand to + minimum cell width(s) as long as $keep_table_proportions = true +- Tables - if using packTableData, and borders-collapse, wider border is overwriting content of adjacent cell + Test case: + ``` + + + +
Hallo world
Hallo world
+ ``` +- Images - image height is reset proportional to original if width is set to maximum e.g. `` +- URL handling changed to work with special characters in path fragments; affects `
` links, `` images and + CSS url() e.g background-image + - also to ignore `../` included as a query value +- Barcodes with bottom numerals e.g. EAN-13 - incorrect numeral size when using core fonts + +-------------------------------- + +NB Spec. for embedded SVG images: +as per http://www.w3.org/TR/2003/REC-SVG11-20030114/struct.html#ImageElement +Attributes supported: +- x +- y +- xlink:href (required) - can be jpeg, png or gif image - not vector (SVG or WMF) image +- width (required) +- height (required) +- preserveAspectRatio + +Note: all attribute names and values are case-sensitive +width and height cannot be assigned by CSS - must be attributes + +mPDF 5.7.3 +================ + +### 24/8/2014 + +Bug Fixes & Minor Additions +--------------------------- + +- Tables - cellSpacing and cellPadding taking preference over CSS stylesheet +- Tables - background images in table inside HTML Footer incorrectly positioned +- Tables - cell in a nested table with a specified width, should determine width of parent table cell + (cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug-) +- Tables - colspan (on a row after first row) exceeds number of columns in table +- Gradients in Imported documents (mPDFI) causing error in some browsers +- Fatal error after page-break-after:always on root level block element +- Support for 'https/SSL' if file_get_contents_by_socket required (e.g. getting images with allow_url_fopen turned off) +- Improved support for specified ports when getting external CSS stylesheets e.g. www.domain.com:80 +- error accessing local .css files with dummy queries (cache-busting) e.g. mpdfstyleA4.css?v=2.0.18.9 +- start of end tag in PRE incorrectly changed to < +- error thrown when open.basedir restriction in effect (deleting temporary files) +- image which forces pagebreak incorrectly positioned at top of page +- [changes to avoid warning notices by checking if (isset(x)) before referencing it] +- text with letter-spacing set inside table which needs to be resixed (shrunk) - letter-spacing was not adjusted +- nested table incorrectly calculating width and unnecessarily wrapping text +- vertical-align:super|sub can be nested using `` elements +- inline elements can be nested e.g. text `text13text` text +- CSS vertical-align:0.5em (or %) now supported +- underline and strikethrough now use the parent inline block baseline/fontsize/color for child inline elements *** change in behaviour + (Adjusts line height to take account of superscript and subscript except in tables) +- nested table incorrectly calculating width and unnecessarily wrapping text +- tables - font size carrying over from one nested table to the next nested table +- tables - border set as attribute on `` overrides border set as CSS on `` not printing at all (since v5.7) +- list-style incorrectly overriding list-style-type in cascading CSS +- page-break-after:avoid not taking into account bottom padding and margin when estimating if next line can fit on page +- images not displayed when using "https://" if images are referenced by src="//domain.com/image" +- +aCJK incorrectly parsed when instantiating class e.g. new mpDF('ja+aCJK') +- line-breaking - zero-width object at end of line (e.g. index entry) causing a space left untrimmed at end of line +- ToC since v5.7 incorrectly handling non-ascii characters, entities or tags +- cell height miscalculated when using hard-hyphenate +- border colors set with transparency not working +- transparency settings for stroke and fill interfering with one another +- 'float' inside a HTML header/footer - not clearing the float before first line of text +- error if script run across date change at midnight +- temporary file name collisions (e.g. when processing images) if numerous users +- `` position attribute not working +- `<` (less-than sign) inside a PRE element, and NOT start of a valid tag, was incorrectly removed +- file attachments not opening in Reader XI +- JPG images not recognised if not containing JFIF or Exif markers +- instance of preg_replace with /e modifier causing error in PHP 5.5 +- correctly handle CSS URLs with no scheme +- Index entries causing errors when repeat entries are used within page-break-inside:avoid, rotated tables etc. +- table with fixed width column and long word in cell set to colspan across this column (adding spare width to all columns) +- incorrect hyphenation if multiple soft-hyphens on line before break +- SVG images - objects contained in `` being displayed +- SVG images - multiple, or quoted fonts e.g. style="font-family:'lucida grande', verdana" not recognised +- SVG images - line with opacity=0 still visible (only in some PDF viewers/browsers) +- text in an SVG image displaying with incorrect font in some PDF viewers/browsers +- SVG images - fill:RGB(0,0,0) not recognised when uppercase +- background images using data:image\/(jpeg|gif|png);base64 format - error when reading in stylesheet + +New CSS support +--------------- + +- added support for style="opacity:0.6;" in SVG images - previously only supported style="fill-opacity:0.6; stroke-opacity: 0.6;" +- improved PNG image handling for some cases of alpha channel transparency +- khmer, cambodian and lao recognised as list-style-type for numbered lists + +SVG Images +---------- + +- Limited support for `` and `` + +mPDF 5.7.1 +================ +## 01/09/2013 + +1) FILES: mpdf.php + +Bug fix; Dollar sign enclosed by `
` tag causing error.
+Test e.g.: `
Test $1.00 Test
Test $2.00 Test
Test $3.00 Test
Test $4.00 Test
` + +----------------------------- + +2) FILES: includes/functions.php AND mpdf.php + +Changes to `preg_replace` with `/e` modifier to use `preg_replace_callback` +(/e depracated from PHP 5.5) + +----------------------------- + +3) FILES: classes/barcode.php + +Small change to function `barcode_c128()` which allows ASCII 0 - 31 to be used in C128A e.g. chr(13) in: +`` + +----------------------------- + +4) FILES: mpdf.php + +Using $use_kwt ("keep-[heading]-with-table") if `

` before table is on 2 lines and pagebreak occurs after first line +the first line is displayed at the bottom of the 2nd page. +Edited so that $use_kwt only works if the HEADING is only one line. Else ignores (but prints correctly) + +----------------------------- + +5) FILES: mpdf.php + +Clearing old temporary files from `_MPDF_TEMP_PATH` will now ignore "hidden" files e.g. starting with a "`.`" `.htaccess`, `.gitignore` etc. +and also leave `dummy.txt` alone + + +mPDF 5.7 +=========================== + +### 14/07/2013 + +Files changed +------------- +- config.php +- mpdf.php +- classes/tocontents.php +- classes/cssmgr.php +- classes/svg.php +- includes/functions.php +- includes/out.php +- examples/formsubmit.php [Important - Security update] + +Updated Example Files in /examples/ +----------------------------------- + +- All example files +- mpdfstyleA4.css + +config.php +---------- + +Removed: +- $this->hyphenateTables +- $this->hyphenate +- $this->orphansAllowed +Edited: +- "hyphens: manual" - Added to $this->defaultCSS +- $this->allowedCSStags now includes '|TEXTCIRCLE|DOTTAB' +New: +- $this->decimal_align = array('DP'=>'.', 'DC'=>',', 'DM'=>"\xc2\xb7", 'DA'=>"\xd9\xab", 'DD'=>'-'); +- $this->h2toc = array('H1'=>0, 'H2'=>1, 'H3'=>2); +- $this->h2bookmarks = array('H1'=>0, 'H2'=>1, 'H3'=>2); +- $this->CJKforceend = false; // Forces overflowng punctuation to hang outside right margin (used with CJK script) + + +Backwards compatability +----------------------- + +Changes in mPDF 5.7 may cause some changes to the way your documents appear. There are two main differences: +1) Hyphenation. To retain appearance compatible with earlier versions, set the CSS property "hyphens: auto" whenever + you previously used $mpdf->hyphenate=true; +2) Table of Contents - appearance can now be controlled with CSS styles. By default, in mPDF 5.7, no styling is applied so you will get: + - No indent (previous default of 5mm) - ($tocindent is ignored) + - Any font, font-size set ($tocfont or $tocfontsize) will not work + - HyperLinks will appear with your default appearance - usually blue and underlined + - line spacing will be narrower (can use line-height or margin-top in CSS) + +New features / Improvements +--------------------------- +- Layout of Table of Content ToC now controlled using CSS styles +- Text alignment on decimal mark inside tables +- Automatically generated bookmarks and/or ToC entries from H1 - H6 tags +- Support for unit of "rem" as size e.g. font-size: 1rem; +- Origin and clipping for background images and gradients controlled by CSS i.e. background-origin, background-size, background-clip +- Text-outline controlled by CSS (compatible with CSS3 spec.) +- Use of `` enhanced by custom CSS "outdent" property +- Image HTML attributes `` added: max-height, max-width, min-height and min-width +- Spotcolor can now be defined as it is used e.g. color: spot(PANTONE 534 EC, 100%, 85, 65, 47, 9); +- Lists - added support for "start" attribute in `
    ` e.g. `
      ` +- Hyphenation controlled using CSS, consistent with CSS3 spec. +- Line breaking improved to avoid breaks within words where HTML tags are used e.g. H20 +- Line breaking in CJK scripts improved (and ability to force hanging punctuation) +- Numerals in a CJK script are kept together +- RTL improved support for phrases containing numerals and \ and / +- Bidi override codes supported - Right-to-Left Embedding [RLE] U+202B, Left-to-Right Embedding [LRE] U+202A, + U+202C POP DIRECTIONAL FORMATTING (PDF) +- Support for `` in HTML - uses it to SetBasePath for relative URLs. +- HTML tag - added support for `` or `` - converted to a soft-hyphen +- CSS now takes precedence over HTML attribute e.g. `
` +- tables - if table width set to 100% and one cell/column is empty with no padding/border, sizing incorrectly + (http://www.mpdf1.com/forum/discussion/1886/td-fontsize-in-nested-table-bug-#Item_5) +- `
` added as recognised tag +- CSS style transform supported on `` element (only) + All transform functions are supported except matrix() i.e. translate(), translateX(), translateY(), skew(), skewX(), skewY(), + scale(), scaleX(), scaleY(), rotate() + NB When using Columns or Keep-with-table (use_kwt), cannot use transform +- CSS background-color now supported on `` element +- @page :first not recognised unless @page {} has styles set +- left/right margins not allowed on @page :first + +mPDF 5.7.2 +================ + +### 28/12/2013 + +Bug Fixes +--------- + +- `
` + +Added CSS support +----------------- +- max-height, max-width, min-height and min-width for images `` +- "hyphens: none|manual|auto" as per CSS3 spec. +- Decimal mark alignment e.g. text-align: "." center; +- "rem" accepted as a valid (font)size in CSS e.g. font-size: 1.5rem +- text-outline, text-outline-width and text-outline-color supported everywhere except in tables (blur not supported) +- background-origin, background-size, background-clip are now supported everywhere except in tables +- "visibility: hidden|visible|printonly|screenonly" for inline elements e.g. `` +- Colors: device-cmyk(c,m,y,k) as per CSS3 spec. For consistency, device-cmyka also supported (not CSS3 spec) +- "z-index" can be used to utilise layers in the PDF document +- Custom CSS property added: "outdent" - opposite of indent + +The HTML elements `` and `` can now have CSS properties applied to them. + +Bug fixes +--------- +- SVG images - path including e.g. 1.234E-15 incorrectly parsed (not recognising capital E) +- Tables - if a table starts when the Y position on page is below bottom margin caused endless loop +- Float-ing DIVs - starting a float at bottom of page and it causes page break before anything output, second new page is forced +- Tables - Warning notice now given in Table footer or header if `` placed after `` and table spans page +- Columns - block with border-width wider than the length of the border line, line overflows +- Columns - block with no padding containing a block with borders but no backgound colour, borders not printed +- Table in Columns - when background color set by surrounding block element - colour missing for height of half bottom border. +- TOCpagebreakByArray() when called by function was not adding the pagebreak +- Border around block element - dashed not showing correctly (not resetting linewidth between different edges) +- Double border in table - when background colour set in surrounding block element - shows as black line between the 2 bits of double +- Borders around DIVs - "double" border problem if not all 4 sides equally - fixed +- Borders around DIVs - solid (and double) borders overlap as in tables - now fixed so mitred joins as in browser + [Inadvertently improves borders in Columns because of change in LineCap] +- Page numbering - $mpdf->pagenumSuffix etc not suppressed in HTML headers/footers if number suppressed +- Page numbering - Page number total {nbpg} incorrect - e.g. showing decreasing numbers through document, when ToC present +- RTL numerals - incorrectly reversing a number followed by a comma +- Transform to uppercase/lowercase not working for chars > ASCII 128 when using core fonts +- TOCpagebreak - Not setting TOC-FOOTER +- TOCpagebreak - toc-even-header-name etc. not working +- Parsing some relative URLs incorrectly +- Textcircle - when moved to next page by "page-break-inside: avoid" +- Bookmarks will now work if jump more than one level e.g. 0,2,1 Inserts a new blank entry at level 1 +- Paths to img or stylesheets - incorrectly reading "//www.domain.com" i.e. when starting with two / +- data:image as background url() - incorrectly adjusting path on server if MPDF_PATH not specified (included in release mPDF 5.6.1) +- Image problem if spaces or commas in path using http:// URL (included in release mPDF 5.6.1) +- Image URL parsing rewritten to handle both urlencoded URLs and not urlencoded (included in release mPDF 5.6.1) +- `` fixed to allow color, font-size and font-family to be correctly used, avoid dots being moved to new page, and to work in RTL +- Table {colsum} summed figures in table header +- list-style-type (custom) colour not working +- `` toc-preHTML and toc-postHTML can now contain quotes + +mPDF 5.6 +=========================== + +### 20/01/2013 + +Files changed +------------- +- mpdf.php +- config.php +- includes/functions.php +- classes/meter.php +- classes/directw.php + + +config.php changes +------------------ + +- $this->allowedCSStags - added HTML5 tags + textcircle AND +- $this->outerblocktags - added HTML5 tags +- $this->defaultCSS - added default CSS properties + +New features / Improvements +--------------------------- +CSS support added for for min-height, min-width, max-height and max-width in `` + +Images embedded in CSS +- `` improved to make it more robust, and background: `url(data:image...` now added to work + +HTML5 tags supported +- as generic block elements: `
must precede in a table"); + } else { + return; + } + } + + + // Advance down page by half width of top border + if ($horf == 'H') { // Only if header + if ($table['borders_separate']) { + $adv = $table['border_spacing_V'] / 2 + $table['border_details']['T']['w'] + $table['padding']['T']; + } else { + $adv = $table['max_cell_border_width']['T'] / 2; + } + if ($adv) { + if ($this->table_rotate) { + $this->y += ($adv); + } else { + $this->DivLn($adv, $this->blklvl, true); + } + } + } + + $topy = $content[$firstrow][0]['y'] - $this->y; + + for ($i = $firstrow; $i <= $lastrow; $i++) { + $y = $this->y; + + /* -- COLUMNS -- */ + // If outside columns, this is done in PaintDivBB + if ($this->ColActive) { + // OUTER FILL BGCOLOR of DIVS + if ($this->blklvl > 0) { + $firstblockfill = $this->GetFirstBlockFill(); + if ($firstblockfill && $this->blklvl >= $firstblockfill) { + $divh = $content[$i][0]['h']; + $bak_x = $this->x; + $this->DivLn($divh, -3, false); + // Reset current block fill + $bcor = $this->blk[$this->blklvl]['bgcolorarray']; + $this->SetFColor($bcor); + $this->x = $bak_x; + } + } + } + /* -- END COLUMNS -- */ + + $colctr = 0; + foreach ($content[$i] as $tablehf) { + $colctr++; + $y = Arrays::get($tablehf, 'y', null) - $topy; + $this->y = $y; + // Set some cell values + $x = Arrays::get($tablehf, 'x', null); + if (($this->mirrorMargins) && ($tablestartpage == 'ODD') && (($this->page) % 2 == 0)) { // EVEN + $x = $x + $this->MarginCorrection; + } elseif (($this->mirrorMargins) && ($tablestartpage == 'EVEN') && (($this->page) % 2 == 1)) { // ODD + $x = $x + $this->MarginCorrection; + } + /* -- COLUMNS -- */ + // Added to correct for Columns + if ($this->ColActive) { + if ($this->directionality == 'rtl') { // *OTL* + $x -= ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth + $this->ColGap); // *OTL* + } // *OTL* + else { // *OTL* + $x += ($this->CurrCol - $tablestartcolumn) * ($this->ColWidth + $this->ColGap); + } // *OTL* + } + /* -- END COLUMNS -- */ + + if ($colctr == 1) { + $x0 = $x; + } + + // mPDF ITERATION + if ($this->iterationCounter) { + foreach ($tablehf['textbuffer'] as $k => $t) { + if (!is_array($t[0]) && preg_match('/{iteration ([a-zA-Z0-9_]+)}/', $t[0], $m)) { + $vname = '__' . $m[1] . '_'; + if (!isset($this->$vname)) { + $this->$vname = 1; + } else { + $this->$vname++; + } + $tablehf['textbuffer'][$k][0] = preg_replace('/{iteration ' . $m[1] . '}/', $this->$vname, $tablehf['textbuffer'][$k][0]); + } + } + } + + $w = Arrays::get($tablehf, 'w', null); + $h = Arrays::get($tablehf, 'h', null); + $va = Arrays::get($tablehf, 'va', null); + $R = Arrays::get($tablehf, 'R', null); + $direction = Arrays::get($tablehf, 'direction', null); + $mih = Arrays::get($tablehf, 'mih', null); + $border = Arrays::get($tablehf, 'border', null); + $border_details = Arrays::get($tablehf, 'border_details', null); + $padding = Arrays::get($tablehf, 'padding', null); + $this->tabletheadjustfinished = true; + + $textbuffer = Arrays::get($tablehf, 'textbuffer', null); + + // Align + $align = Arrays::get($tablehf, 'a', null); + $this->cellTextAlign = $align; + + $this->cellLineHeight = Arrays::get($tablehf, 'cellLineHeight', null); + $this->cellLineStackingStrategy = Arrays::get($tablehf, 'cellLineStackingStrategy', null); + $this->cellLineStackingShift = Arrays::get($tablehf, 'cellLineStackingShift', null); + + $this->x = $x; + + if ($this->ColActive) { + if ($table['borders_separate']) { + $tablefill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0; + if ($tablefill) { + $color = $this->colorConverter->convert($tablefill, $this->PDFAXwarnings); + if ($color) { + $xadj = ($table['border_spacing_H'] / 2); + $yadj = ($table['border_spacing_V'] / 2); + $wadj = $table['border_spacing_H']; + $hadj = $table['border_spacing_V']; + if ($i == $firstrow && $horf == 'H') { // Top + $yadj += $table['padding']['T'] + $table['border_details']['T']['w']; + $hadj += $table['padding']['T'] + $table['border_details']['T']['w']; + } + if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i + $tablehf['rowspan']) == ($lastrow + 1)) || (!isset($tablehf['rowspan']) && ($i + 1) == ($lastrow + 1))) && $horf == 'F') { // Bottom + $hadj += $table['padding']['B'] + $table['border_details']['B']['w']; + } + if ($colctr == 1) { // Left + $xadj += $table['padding']['L'] + $table['border_details']['L']['w']; + $wadj += $table['padding']['L'] + $table['border_details']['L']['w']; + } + if ($colctr == count($content[$i])) { // Right + $wadj += $table['padding']['R'] + $table['border_details']['R']['w']; + } + $this->SetFColor($color); + $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F'); + } + } + } + } + + if ($table['empty_cells'] != 'hide' || !empty($textbuffer) || !$table['borders_separate']) { + $paintcell = true; + } else { + $paintcell = false; + } + + // Vertical align + if ($R && intval($R) > 0 && isset($va) && $va != 'B') { + $va = 'B'; + } + + if (!isset($va) || empty($va) || $va == 'M') { + $this->y += ($h - $mih) / 2; + } elseif (isset($va) && $va == 'B') { + $this->y += $h - $mih; + } + + + // TABLE ROW OR CELL FILL BGCOLOR + $fill = 0; + if (isset($tablehf['bgcolor']) && $tablehf['bgcolor'] && $tablehf['bgcolor'] != 'transparent') { + $fill = $tablehf['bgcolor']; + $leveladj = 6; + } elseif (isset($content[$i][0]['trbgcolor']) && $content[$i][0]['trbgcolor'] && $content[$i][0]['trbgcolor'] != 'transparent') { // Row color + $fill = $content[$i][0]['trbgcolor']; + $leveladj = 3; + } + if ($fill && $paintcell) { + $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings); + if ($color) { + if ($table['borders_separate']) { + if ($this->ColActive) { + $this->SetFColor($color); + $this->Rect($x + ($table['border_spacing_H'] / 2), $y + ($table['border_spacing_V'] / 2), $w - $table['border_spacing_H'], $h - $table['border_spacing_V'], 'F'); + } else { + $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => ($x + ($table['border_spacing_H'] / 2)), 'y' => ($y + ($table['border_spacing_V'] / 2)), 'w' => ($w - $table['border_spacing_H']), 'h' => ($h - $table['border_spacing_V']), 'col' => $color]; + } + } else { + if ($this->ColActive) { + $this->SetFColor($color); + $this->Rect($x, $y, $w, $h, 'F'); + } else { + $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'col' => $color]; + } + } + } + } + + + /* -- BACKGROUNDS -- */ + if (isset($tablehf['gradient']) && $tablehf['gradient'] && $paintcell) { + $g = $this->gradient->parseBackgroundGradient($tablehf['gradient']); + if ($g) { + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']); + } else { + $this->tableBackgrounds[$level * 9 + 7][] = ['gradient' => true, 'x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } + + if (isset($tablehf['background-image']) && $paintcell) { + if ($tablehf['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $tablehf['background-image']['gradient'])) { + $g = $this->gradient->parseMozGradient($tablehf['background-image']['gradient']); + if ($g) { + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']); + } else { + $this->tableBackgrounds[$level * 9 + 7][] = ['gradient' => true, 'x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } elseif ($tablehf['background-image']['image_id']) { // Background pattern + $n = count($this->patterns) + 1; + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($tablehf['background-image']['orig_w'], $tablehf['background-image']['orig_h'], $pw, $ph, $tablehf['background-image']['resize'], $tablehf['background-image']['x_repeat'], $tablehf['background-image']['y_repeat']); + $this->patterns[$n] = ['x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'pgh' => $this->h, 'image_id' => $tablehf['background-image']['image_id'], 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $tablehf['background-image']['x_pos'], 'y_pos' => $tablehf['background-image']['y_pos'], 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'itype' => $tablehf['background-image']['itype']]; + if ($tablehf['background-image']['opacity'] > 0 && $tablehf['background-image']['opacity'] < 1) { + $opac = $this->SetAlpha($tablehf['background-image']['opacity'], 'Normal', true); + } else { + $opac = ''; + } + $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px * Mpdf::SCALE, ($this->h - $py) * Mpdf::SCALE, $pw * Mpdf::SCALE, -$ph * Mpdf::SCALE)); + } else { + $this->tableBackgrounds[$level * 9 + 8][] = ['x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'image_id' => $tablehf['background-image']['image_id'], 'orig_w' => $tablehf['background-image']['orig_w'], 'orig_h' => $tablehf['background-image']['orig_h'], 'x_pos' => $tablehf['background-image']['x_pos'], 'y_pos' => $tablehf['background-image']['y_pos'], 'x_repeat' => $tablehf['background-image']['x_repeat'], 'y_repeat' => $tablehf['background-image']['y_repeat'], 'clippath' => '', 'resize' => $tablehf['background-image']['resize'], 'opacity' => $tablehf['background-image']['opacity'], 'itype' => $tablehf['background-image']['itype']]; + } + } + } + /* -- END BACKGROUNDS -- */ + + // Cell Border + if ($table['borders_separate'] && $paintcell && $border) { + $this->_tableRect($x + ($table['border_spacing_H'] / 2) + ($border_details['L']['w'] / 2), $y + ($table['border_spacing_V'] / 2) + ($border_details['T']['w'] / 2), $w - $table['border_spacing_H'] - ($border_details['L']['w'] / 2) - ($border_details['R']['w'] / 2), $h - $table['border_spacing_V'] - ($border_details['T']['w'] / 2) - ($border_details['B']['w'] / 2), $border, $border_details, false, $table['borders_separate']); + } elseif ($paintcell && $border) { + $this->_tableRect($x, $y, $w, $h, $border, $border_details, true, $table['borders_separate']); // true causes buffer + } + + // Print cell content + if (!empty($textbuffer)) { + if ($horf == 'F' && preg_match('/{colsum([0-9]*)[_]*}/', $textbuffer[0][0], $m)) { + $rep = sprintf("%01." . intval($m[1]) . "f", $this->colsums[$colctr - 1]); + $textbuffer[0][0] = preg_replace('/{colsum[0-9_]*}/', $rep, $textbuffer[0][0]); + } + + if ($R) { + $cellPtSize = $textbuffer[0][11] / $this->shrin_k; + if (!$cellPtSize) { + $cellPtSize = $this->default_font_size; + } + $cellFontHeight = ($cellPtSize / Mpdf::SCALE); + $opx = $this->x; + $opy = $this->y; + $angle = intval($R); + + // Only allow 45 - 90 degrees (when bottom-aligned) or -90 + if ($angle > 90) { + $angle = 90; + } elseif ($angle > 0 && (isset($va) && $va != 'B')) { + $angle = 90; + } elseif ($angle > 0 && $angle < 45) { + $angle = 45; + } elseif ($angle < 0) { + $angle = -90; + } + + $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight); + if (isset($align) && $align == 'R') { + $this->x += ($w) + ($offset) - ($cellFontHeight / 3) - ($padding['R'] + $border_details['R']['w']); + } elseif (!isset($align) || $align == 'C') { + $this->x += ($w / 2) + ($offset); + } else { + $this->x += ($offset) + ($cellFontHeight / 3) + ($padding['L'] + $border_details['L']['w']); + } + $str = ''; + foreach ($tablehf['textbuffer'] as $t) { + $str .= $t[0] . ' '; + } + $str = rtrim($str); + + if (!isset($va) || $va == 'M') { + $this->y -= ($h - $mih) / 2; // Undo what was added earlier VERTICAL ALIGN + if ($angle > 0) { + $this->y += (($h - $mih) / 2) + ($padding['T'] + $border_details['T']['w']) + ($mih - ($padding['T'] + $border_details['T']['w'] + $border_details['B']['w'] + $padding['B'])); + } elseif ($angle < 0) { + $this->y += (($h - $mih) / 2) + ($padding['T'] + $border_details['T']['w']); + } + } elseif (isset($va) && $va == 'B') { + $this->y -= $h - $mih; // Undo what was added earlier VERTICAL ALIGN + if ($angle > 0) { + $this->y += $h - ($border_details['B']['w'] + $padding['B']); + } elseif ($angle < 0) { + $this->y += $h - $mih + ($padding['T'] + $border_details['T']['w']); + } + } elseif (isset($va) && $va == 'T') { + if ($angle > 0) { + $this->y += $mih - ($border_details['B']['w'] + $padding['B']); + } elseif ($angle < 0) { + $this->y += ($padding['T'] + $border_details['T']['w']); + } + } + + $this->Rotate($angle, $this->x, $this->y); + $s_fs = $this->FontSizePt; + $s_f = $this->FontFamily; + $s_st = $this->FontStyle; + if (!empty($textbuffer[0][3])) { // Font Color + $cor = $textbuffer[0][3]; + $this->SetTColor($cor); + } + $this->SetFont($textbuffer[0][4], $textbuffer[0][2], $cellPtSize, true, true); + + $this->magic_reverse_dir($str, $this->directionality, $textbuffer[0][18]); + $this->Text($this->x, $this->y, $str, $textbuffer[0][18], $textbuffer[0][8]); // textvar + $this->Rotate(0); + $this->SetFont($s_f, $s_st, $s_fs, true, true); + $this->SetTColor(0); + $this->x = $opx; + $this->y = $opy; + } else { + if ($table['borders_separate']) { // NB twice border width + $xadj = $border_details['L']['w'] + $padding['L'] + ($table['border_spacing_H'] / 2); + $wadj = $border_details['L']['w'] + $border_details['R']['w'] + $padding['L'] + $padding['R'] + $table['border_spacing_H']; + $yadj = $border_details['T']['w'] + $padding['T'] + ($table['border_spacing_H'] / 2); + } else { + $xadj = $border_details['L']['w'] / 2 + $padding['L']; + $wadj = ($border_details['L']['w'] + $border_details['R']['w']) / 2 + $padding['L'] + $padding['R']; + $yadj = $border_details['T']['w'] / 2 + $padding['T']; + } + + $this->divwidth = $w - ($wadj); + $this->x += $xadj; + $this->y += $yadj; + $this->printbuffer($textbuffer, '', true, false, $direction); + } + } + $textbuffer = []; + + /* -- BACKGROUNDS -- */ + if (!$this->ColActive) { + if (isset($content[$i][0]['trgradients']) && ($colctr == 1 || $table['borders_separate'])) { + $g = $this->gradient->parseBackgroundGradient($content[$i][0]['trgradients']); + if ($g) { + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => $s]; + } else { + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } + + if (isset($content[$i][0]['trbackground-images']) && ($colctr == 1 || $table['borders_separate'])) { + if ($content[$i][0]['trbackground-images']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $content[$i][0]['trbackground-images']['gradient'])) { + $g = $this->gradient->parseMozGradient($content[$i][0]['trbackground-images']['gradient']); + if ($g) { + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => $s]; + } else { + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } else { + $image_id = $content[$i][0]['trbackground-images']['image_id']; + $orig_w = $content[$i][0]['trbackground-images']['orig_w']; + $orig_h = $content[$i][0]['trbackground-images']['orig_h']; + $x_pos = $content[$i][0]['trbackground-images']['x_pos']; + $y_pos = $content[$i][0]['trbackground-images']['y_pos']; + $x_repeat = $content[$i][0]['trbackground-images']['x_repeat']; + $y_repeat = $content[$i][0]['trbackground-images']['y_repeat']; + $resize = $content[$i][0]['trbackground-images']['resize']; + $opacity = $content[$i][0]['trbackground-images']['opacity']; + $itype = $content[$i][0]['trbackground-images']['itype']; + + $clippath = ''; + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 5][] = ['x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => $s, 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } else { + $this->tableBackgrounds[$level * 9 + 5][] = ['x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => '', 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } + } + } + } + /* -- END BACKGROUNDS -- */ + + // TABLE BORDER - if separate OR collapsed and only table border + if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) { + $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H'] / 2); + $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H'] / 2); + $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V'] / 2); + $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V'] / 2); + $tbx = $x; + $tby = $y; + $tbw = $w; + $tbh = $h; + $tab_bord = 0; + $corner = ''; + if ($i == $firstrow && $horf == 'H') { // Top + $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2); + $tbh += $halfspaceT + ($table['border_details']['T']['w'] / 2); + $this->setBorder($tab_bord, Border::TOP); + $corner .= 'T'; + } + if (($i == ($lastrow) || (isset($tablehf['rowspan']) && ($i + $tablehf['rowspan']) == ($lastrow + 1))) && $horf == 'F') { // Bottom + $tbh += $halfspaceB + ($table['border_details']['B']['w'] / 2); + $this->setBorder($tab_bord, Border::BOTTOM); + $corner .= 'B'; + } + if ($colctr == 1 && $firstSpread) { // Left + $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2); + $tbw += $halfspaceL + ($table['border_details']['L']['w'] / 2); + $this->setBorder($tab_bord, Border::LEFT); + $corner .= 'L'; + } + if ($colctr == count($content[$i]) && $finalSpread) { // Right + $tbw += $halfspaceR + ($table['border_details']['R']['w'] / 2); + $this->setBorder($tab_bord, Border::RIGHT); + $corner .= 'R'; + } + $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord, $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H']); + } + }// end column $content + $this->y = $y + $h; // Update y coordinate + }// end row $i + unset($table); + $this->colsums = []; + } + } + + /* -- END TABLES -- */ + + function SetHTMLHeader($header = '', $OE = '', $write = false) + { + + $height = 0; + if (is_array($header) && isset($header['html']) && $header['html']) { + $Hhtml = $header['html']; + if ($this->setAutoTopMargin) { + if (isset($header['h'])) { + $height = $header['h']; + } else { + $height = $this->_getHtmlHeight($Hhtml); + } + } + } elseif (!is_array($header) && $header) { + $Hhtml = $header; + if ($this->setAutoTopMargin) { + $height = $this->_getHtmlHeight($Hhtml); + } + } else { + $Hhtml = ''; + } + + if ($OE !== 'E') { + $OE = 'O'; + } + + if ($OE === 'E') { + if ($Hhtml) { + $this->HTMLHeaderE = []; + $this->HTMLHeaderE['html'] = $Hhtml; + $this->HTMLHeaderE['h'] = $height; + } else { + $this->HTMLHeaderE = ''; + } + } else { + if ($Hhtml) { + $this->HTMLHeader = []; + $this->HTMLHeader['html'] = $Hhtml; + $this->HTMLHeader['h'] = $height; + } else { + $this->HTMLHeader = ''; + } + } + + if (!$this->mirrorMargins && $OE == 'E') { + return; + } + if ($Hhtml == '') { + return; + } + + if ($this->setAutoTopMargin == 'pad') { + $this->tMargin = $this->margin_header + $height + $this->orig_tMargin; + if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { + $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; + } + } elseif ($this->setAutoTopMargin == 'stretch') { + $this->tMargin = max($this->orig_tMargin, $this->margin_header + $height + $this->autoMarginPadding); + if (isset($this->saveHTMLHeader[$this->page][$OE]['mt'])) { + $this->saveHTMLHeader[$this->page][$OE]['mt'] = $this->tMargin; + } + } + if ($write && $this->state != 0 && (($this->mirrorMargins && $OE == 'E' && ($this->page) % 2 == 0) || ($this->mirrorMargins && $OE != 'E' && ($this->page) % 2 == 1) || !$this->mirrorMargins)) { + $this->writeHTMLHeaders(); + } + } + + function SetHTMLFooter($footer = '', $OE = '') + { + $height = 0; + if (is_array($footer) && isset($footer['html']) && $footer['html']) { + $Fhtml = $footer['html']; + if ($this->setAutoBottomMargin) { + if (isset($footer['h'])) { + $height = $footer['h']; + } else { + $height = $this->_getHtmlHeight($Fhtml); + } + } + } elseif (!is_array($footer) && $footer) { + $Fhtml = $footer; + if ($this->setAutoBottomMargin) { + $height = $this->_getHtmlHeight($Fhtml); + } + } else { + $Fhtml = ''; + } + + if ($OE !== 'E') { + $OE = 'O'; + } + + if ($OE === 'E') { + if ($Fhtml) { + $this->HTMLFooterE = []; + $this->HTMLFooterE['html'] = $Fhtml; + $this->HTMLFooterE['h'] = $height; + } else { + $this->HTMLFooterE = ''; + } + } else { + if ($Fhtml) { + $this->HTMLFooter = []; + $this->HTMLFooter['html'] = $Fhtml; + $this->HTMLFooter['h'] = $height; + } else { + $this->HTMLFooter = ''; + } + } + + if (!$this->mirrorMargins && $OE == 'E') { + return; + } + + if ($Fhtml == '') { + return false; + } + + if ($this->setAutoBottomMargin == 'pad') { + $this->bMargin = $this->margin_footer + $height + $this->orig_bMargin; + $this->PageBreakTrigger = $this->h - $this->bMargin; + if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { + $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; + } + } elseif ($this->setAutoBottomMargin == 'stretch') { + $this->bMargin = max($this->orig_bMargin, $this->margin_footer + $height + $this->autoMarginPadding); + $this->PageBreakTrigger = $this->h - $this->bMargin; + if (isset($this->saveHTMLHeader[$this->page][$OE]['mb'])) { + $this->saveHTMLHeader[$this->page][$OE]['mb'] = $this->bMargin; + } + } + } + + function _getHtmlHeight($html) + { + $save_state = $this->state; + if ($this->state == 0) { + $this->AddPage($this->CurOrientation); + } + $this->state = 2; + $this->Reset(); + $this->pageoutput[$this->page] = []; + $save_x = $this->x; + $save_y = $this->y; + $this->x = $this->lMargin; + $this->y = $this->margin_header; + $html = str_replace('{PAGENO}', $this->pagenumPrefix . $this->docPageNum($this->page) . $this->pagenumSuffix, $html); + $html = str_replace($this->aliasNbPgGp, $this->nbpgPrefix . $this->docPageNumTotal($this->page) . $this->nbpgSuffix, $html); + $html = str_replace($this->aliasNbPg, $this->page, $html); + $html = preg_replace_callback('/\{DATE\s+(.*?)\}/', [$this, 'date_callback'], $html); // mPDF 5.7 + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + $savepb = $this->pageBackgrounds; + $this->writingHTMLheader = true; + $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER); + $this->writingHTMLheader = false; + $h = ($this->y - $this->margin_header); + $this->Reset(); + // mPDF 5.7.2 - Clear in case Float used in Header/Footer + $this->blk[0]['blockContext'] = 0; + $this->blk[0]['float_endpos'] = 0; + + $this->pageoutput[$this->page] = []; + $this->headerbuffer = ''; + $this->pageBackgrounds = $savepb; + $this->x = $save_x; + $this->y = $save_y; + $this->state = $save_state; + if ($save_state == 0) { + unset($this->pages[1]); + $this->page = 0; + } + return $h; + } + + // Called internally from Header + function writeHTMLHeaders() + { + + if ($this->mirrorMargins && ($this->page) % 2 == 0) { + $OE = 'E'; + } else { + $OE = 'O'; + } + + if ($OE === 'E') { + $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeaderE['html']; + } else { + $this->saveHTMLHeader[$this->page][$OE]['html'] = $this->HTMLHeader['html']; + } + + if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) { + $this->saveHTMLHeader[$this->page][$OE]['rotate'] = true; + $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->tMargin; + $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->bMargin; + $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header; + $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer; + $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->h; + $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->w; + } else { + $this->saveHTMLHeader[$this->page][$OE]['ml'] = $this->lMargin; + $this->saveHTMLHeader[$this->page][$OE]['mr'] = $this->rMargin; + $this->saveHTMLHeader[$this->page][$OE]['mh'] = $this->margin_header; + $this->saveHTMLHeader[$this->page][$OE]['mf'] = $this->margin_footer; + $this->saveHTMLHeader[$this->page][$OE]['pw'] = $this->w; + $this->saveHTMLHeader[$this->page][$OE]['ph'] = $this->h; + } + } + + function writeHTMLFooters() + { + + if ($this->mirrorMargins && ($this->page) % 2 == 0) { + $OE = 'E'; + } else { + $OE = 'O'; + } + + if ($OE === 'E') { + $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooterE['html']; + } else { + $this->saveHTMLFooter[$this->page][$OE]['html'] = $this->HTMLFooter['html']; + } + + if ($this->forcePortraitHeaders && $this->CurOrientation == 'L' && $this->CurOrientation != $this->DefOrientation) { + $this->saveHTMLFooter[$this->page][$OE]['rotate'] = true; + $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->tMargin; + $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->bMargin; + $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->rMargin; + $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->lMargin; + $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header; + $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer; + $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->h; + $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->w; + } else { + $this->saveHTMLFooter[$this->page][$OE]['ml'] = $this->lMargin; + $this->saveHTMLFooter[$this->page][$OE]['mr'] = $this->rMargin; + $this->saveHTMLFooter[$this->page][$OE]['mt'] = $this->tMargin; + $this->saveHTMLFooter[$this->page][$OE]['mb'] = $this->bMargin; + $this->saveHTMLFooter[$this->page][$OE]['mh'] = $this->margin_header; + $this->saveHTMLFooter[$this->page][$OE]['mf'] = $this->margin_footer; + $this->saveHTMLFooter[$this->page][$OE]['pw'] = $this->w; + $this->saveHTMLFooter[$this->page][$OE]['ph'] = $this->h; + } + } + + // mPDF 6 + function _shareHeaderFooterWidth($cl, $cc, $cr) + { + // mPDF 6 + $l = mb_strlen($cl, 'UTF-8'); + $c = mb_strlen($cc, 'UTF-8'); + $r = mb_strlen($cr, 'UTF-8'); + $s = max($l, $r); + $tw = $c + 2 * $s; + if ($tw > 0) { + return [intval($s * 100 / $tw), intval($c * 100 / $tw), intval($s * 100 / $tw)]; + } else { + return [33, 33, 33]; + } + } + + // mPDF 6 + // Create an HTML header/footer from array (non-HTML header/footer) + function _createHTMLheaderFooter($arr, $hf) + { + $lContent = (isset($arr['L']['content']) ? $arr['L']['content'] : ''); + $cContent = (isset($arr['C']['content']) ? $arr['C']['content'] : ''); + $rContent = (isset($arr['R']['content']) ? $arr['R']['content'] : ''); + list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($lContent, $cContent, $rContent); + if ($hf == 'H') { + $valign = 'bottom'; + $vpadding = '0 0 ' . $this->header_line_spacing . 'em 0'; + } else { + $valign = 'top'; + $vpadding = '' . $this->footer_line_spacing . 'em 0 0 0'; + } + if ($this->directionality == 'rtl') { // table columns get reversed so need different text-alignment + $talignL = 'right'; + $talignR = 'left'; + } else { + $talignL = 'left'; + $talignR = 'right'; + } + $html = '
'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= '
' . $lContent . '' . $cContent . '' . $rContent . '
'; + return $html; + } + + function DefHeaderByName($name, $arr) + { + if (!$name) { + $name = '_nonhtmldefault'; + } + $html = $this->_createHTMLheaderFooter($arr, 'H'); + + $this->pageHTMLheaders[$name]['html'] = $html; + $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html); + } + + function DefFooterByName($name, $arr) + { + if (!$name) { + $name = '_nonhtmldefault'; + } + $html = $this->_createHTMLheaderFooter($arr, 'F'); + + $this->pageHTMLfooters[$name]['html'] = $html; + $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html); + } + + function SetHeaderByName($name, $side = 'O', $write = false) + { + if (!$name) { + $name = '_nonhtmldefault'; + } + $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side, $write); + } + + function SetFooterByName($name, $side = 'O') + { + if (!$name) { + $name = '_nonhtmldefault'; + } + $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side); + } + + function DefHTMLHeaderByName($name, $html) + { + if (!$name) { + $name = '_default'; + } + + $this->pageHTMLheaders[$name]['html'] = $html; + $this->pageHTMLheaders[$name]['h'] = $this->_getHtmlHeight($html); + } + + function DefHTMLFooterByName($name, $html) + { + if (!$name) { + $name = '_default'; + } + + $this->pageHTMLfooters[$name]['html'] = $html; + $this->pageHTMLfooters[$name]['h'] = $this->_getHtmlHeight($html); + } + + function SetHTMLHeaderByName($name, $side = 'O', $write = false) + { + if (!$name) { + $name = '_default'; + } + $this->SetHTMLHeader($this->pageHTMLheaders[$name], $side, $write); + } + + function SetHTMLFooterByName($name, $side = 'O') + { + if (!$name) { + $name = '_default'; + } + $this->SetHTMLFooter($this->pageHTMLfooters[$name], $side); + } + + function SetHeader($Harray = [], $side = '', $write = false) + { + $oddhtml = ''; + $evenhtml = ''; + + if (is_string($Harray)) { + + if (strlen($Harray) === 0) { + + $oddhtml = ''; + $evenhtml = ''; + + } elseif (strpos($Harray, '|') !== false) { + + $hdet = explode('|', $Harray); + + list($lw, $cw, $rw) = $this->_shareHeaderFooterWidth($hdet[0], $hdet[1], $hdet[2]); + $oddhtml = ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= '
' . $hdet[0] . '' . $hdet[1] . '' . $hdet[2] . '
'; + + $evenhtml = ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= '
' . $hdet[2] . '' . $hdet[1] . '' . $hdet[0] . '
'; + + } else { + + $oddhtml = '
' . $Harray . '
'; + $evenhtml = '
' . $Harray . '
'; + } + + } elseif (is_array($Harray) && !empty($Harray)) { + + $odd = null; + $even = null; + + if ($side === 'O') { + $odd = $Harray; + } elseif ($side === 'E') { + $even = $Harray; + } else { + $odd = Arrays::get($Harray, 'odd', null); + $even = Arrays::get($Harray, 'even', null); + } + + $oddhtml = $this->_createHTMLheaderFooter($odd, 'H'); + $evenhtml = $this->_createHTMLheaderFooter($even, 'H'); + } + + if ($side === 'E') { + $this->SetHTMLHeader($evenhtml, 'E', $write); + } elseif ($side === 'O') { + $this->SetHTMLHeader($oddhtml, 'O', $write); + } else { + $this->SetHTMLHeader($oddhtml, 'O', $write); + $this->SetHTMLHeader($evenhtml, 'E', $write); + } + } + + function SetFooter($Farray = [], $side = '') + { + $oddhtml = ''; + $evenhtml = ''; + + if (is_string($Farray)) { + + if (strlen($Farray) == 0) { + + $oddhtml = ''; + $evenhtml = ''; + + } elseif (strpos($Farray, '|') !== false) { + + $hdet = explode('|', $Farray); + $oddhtml = ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= ''; + $oddhtml .= '
' . $hdet[0] . '' . $hdet[1] . '' . $hdet[2] . '
'; + + $evenhtml = ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= ''; + $evenhtml .= '
' . $hdet[2] . '' . $hdet[1] . '' . $hdet[0] . '
'; + + } else { + + $oddhtml = '
' . $Farray . '
'; + + $evenhtml = '
' . $Farray . '
'; + } + + } elseif (is_array($Farray)) { + + $odd = null; + $even = null; + + if ($side === 'O') { + $odd = $Farray; + } elseif ($side == 'E') { + $even = $Farray; + } else { + $odd = Arrays::get($Farray, 'odd', null); + $even = Arrays::get($Farray, 'even', null); + } + + $oddhtml = $this->_createHTMLheaderFooter($odd, 'F'); + $evenhtml = $this->_createHTMLheaderFooter($even, 'F'); + } + + if ($side === 'E') { + $this->SetHTMLFooter($evenhtml, 'E'); + } elseif ($side === 'O') { + $this->SetHTMLFooter($oddhtml, 'O'); + } else { + $this->SetHTMLFooter($oddhtml, 'O'); + $this->SetHTMLFooter($evenhtml, 'E'); + } + } + + /* -- WATERMARK -- */ + + function SetWatermarkText($txt = '', $alpha = -1) + { + if ($alpha >= 0) { + $this->watermarkTextAlpha = $alpha; + } + $this->watermarkText = $txt; + } + + function SetWatermarkImage($src, $alpha = -1, $size = 'D', $pos = 'F') + { + if ($alpha >= 0) { + $this->watermarkImageAlpha = $alpha; + } + $this->watermarkImage = $src; + $this->watermark_size = $size; + $this->watermark_pos = $pos; + } + + /* -- END WATERMARK -- */ + + // Page footer + function Footer() + { + /* -- CSS-PAGE -- */ + // PAGED MEDIA - CROP / CROSS MARKS from @PAGE + if ($this->show_marks == 'CROP' || $this->show_marks == 'CROPCROSS') { + // Show TICK MARKS + $this->SetLineWidth(0.1); // = 0.1 mm + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $l = $this->cropMarkLength; + $m = $this->cropMarkMargin; // Distance of crop mark from margin + $b = $this->nonPrintMargin; // Non-printable border at edge of paper sheet + $ax1 = $b; + $bx = $this->page_box['outer_width_LR'] - $m; + $ax = max($ax1, $bx - $l); + $cx1 = $this->w - $b; + $dx = $this->w - $this->page_box['outer_width_LR'] + $m; + $cx = min($cx1, $dx + $l); + $ay1 = $b; + $by = $this->page_box['outer_width_TB'] - $m; + $ay = max($ay1, $by - $l); + $cy1 = $this->h - $b; + $dy = $this->h - $this->page_box['outer_width_TB'] + $m; + $cy = min($cy1, $dy + $l); + + $this->Line($ax, $this->page_box['outer_width_TB'], $bx, $this->page_box['outer_width_TB']); + $this->Line($cx, $this->page_box['outer_width_TB'], $dx, $this->page_box['outer_width_TB']); + $this->Line($ax, $this->h - $this->page_box['outer_width_TB'], $bx, $this->h - $this->page_box['outer_width_TB']); + $this->Line($cx, $this->h - $this->page_box['outer_width_TB'], $dx, $this->h - $this->page_box['outer_width_TB']); + $this->Line($this->page_box['outer_width_LR'], $ay, $this->page_box['outer_width_LR'], $by); + $this->Line($this->page_box['outer_width_LR'], $cy, $this->page_box['outer_width_LR'], $dy); + $this->Line($this->w - $this->page_box['outer_width_LR'], $ay, $this->w - $this->page_box['outer_width_LR'], $by); + $this->Line($this->w - $this->page_box['outer_width_LR'], $cy, $this->w - $this->page_box['outer_width_LR'], $dy); + + if ($this->printers_info) { + $hd = date('Y-m-d H:i') . ' Page ' . $this->page . ' of {nb}'; + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetFont('arial', '', 7.5, true, true); + $this->x = $this->page_box['outer_width_LR'] + 1.5; + $this->y = 1; + $this->Cell($headerpgwidth, $this->FontSize, $hd, 0, 0, 'L', 0, '', 0, 0, 0, 'M'); + $this->SetFont($this->default_font, '', $this->original_default_font_size); + } + } + if ($this->show_marks == 'CROSS' || $this->show_marks == 'CROPCROSS') { + $this->SetLineWidth(0.1); // = 0.1 mm + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $l = 14 / 2; // longer length of the cross line (half) + $w = 6 / 2; // shorter width of the cross line (half) + $r = 1.2; // radius of circle + $m = $this->crossMarkMargin; // Distance of cross mark from margin + $x1 = $this->page_box['outer_width_LR'] - $m; + $x2 = $this->w - $this->page_box['outer_width_LR'] + $m; + $y1 = $this->page_box['outer_width_TB'] - $m; + $y2 = $this->h - $this->page_box['outer_width_TB'] + $m; + // Left + $this->Circle($x1, $this->h / 2, $r, 'S'); + $this->Line($x1 - $w, $this->h / 2, $x1 + $w, $this->h / 2); + $this->Line($x1, $this->h / 2 - $l, $x1, $this->h / 2 + $l); + // Right + $this->Circle($x2, $this->h / 2, $r, 'S'); + $this->Line($x2 - $w, $this->h / 2, $x2 + $w, $this->h / 2); + $this->Line($x2, $this->h / 2 - $l, $x2, $this->h / 2 + $l); + // Top + $this->Circle($this->w / 2, $y1, $r, 'S'); + $this->Line($this->w / 2, $y1 - $w, $this->w / 2, $y1 + $w); + $this->Line($this->w / 2 - $l, $y1, $this->w / 2 + $l, $y1); + // Bottom + $this->Circle($this->w / 2, $y2, $r, 'S'); + $this->Line($this->w / 2, $y2 - $w, $this->w / 2, $y2 + $w); + $this->Line($this->w / 2 - $l, $y2, $this->w / 2 + $l, $y2); + } + + /* -- END CSS-PAGE -- */ + + // mPDF 6 + // If @page set non-HTML headers/footers named, they were not read until later in the HTML code - so now set them + if ($this->page == 1) { + if ($this->firstPageBoxHeader) { + if (isset($this->pageHTMLheaders[$this->firstPageBoxHeader])) { + $this->HTMLHeader = $this->pageHTMLheaders[$this->firstPageBoxHeader]; + } + $this->Header(); + } + if ($this->firstPageBoxFooter) { + if (isset($this->pageHTMLfooters[$this->firstPageBoxFooter])) { + $this->HTMLFooter = $this->pageHTMLfooters[$this->firstPageBoxFooter]; + } + } + $this->firstPageBoxHeader = ''; + $this->firstPageBoxFooter = ''; + } + + + if (($this->mirrorMargins && ($this->page % 2 == 0) && $this->HTMLFooterE) || ($this->mirrorMargins && ($this->page % 2 == 1) && $this->HTMLFooter) || (!$this->mirrorMargins && $this->HTMLFooter)) { + $this->writeHTMLFooters(); + } + + /* -- WATERMARK -- */ + if (($this->watermarkText) && ($this->showWatermarkText)) { + $this->watermark($this->watermarkText, $this->watermarkAngle, 120, $this->watermarkTextAlpha); // Watermark text + } + if (($this->watermarkImage) && ($this->showWatermarkImage)) { + $this->watermarkImg($this->watermarkImage, $this->watermarkImageAlpha); // Watermark image + } + /* -- END WATERMARK -- */ + } + + /* -- HTML-CSS -- */ + + /** + * Write HTML code to the document + * + * Also used internally to parse HTML into buffers + * + * @param string $html + * @param int $mode Use HTMLParserMode constants. Controls what parts of the $html code is parsed. + * @param bool $init Clears and sets buffers to Top level block etc. + * @param bool $close If false leaves buffers etc. in current state, so that it can continue a block etc. + */ + function WriteHTML($html, $mode = HTMLParserMode::DEFAULT_MODE, $init = true, $close = true) + { + /* Check $html is an integer, float, string, boolean or class with __toString(), otherwise throw exception */ + if (is_scalar($html) === false) { + if (!is_object($html) || ! method_exists($html, '__toString')) { + throw new \Mpdf\MpdfException('WriteHTML() requires $html be an integer, float, string, boolean or an object with the __toString() magic method.'); + } + } + + // Check the mode is valid + if (in_array($mode, HTMLParserMode::getAllModes(), true) === false) { + throw new \Mpdf\MpdfException('WriteHTML() requires $mode to be one of the modes defined in HTMLParserMode'); + } + + /* Cast $html as a string */ + $html = (string) $html; + + // @log Parsing CSS & Headers + + if ($init) { + $this->headerbuffer = ''; + $this->textbuffer = []; + $this->fixedPosBlockSave = []; + } + if ($mode === HTMLParserMode::HEADER_CSS) { + $html = ''; + } // stylesheet only + + if ($this->allow_charset_conversion) { + if ($mode === HTMLParserMode::DEFAULT_MODE) { + $this->ReadCharset($html); + } + if ($this->charset_in && $mode !== HTMLParserMode::HTML_HEADER_BUFFER) { + $success = iconv($this->charset_in, 'UTF-8//TRANSLIT', $html); + if ($success) { + $html = $success; + } + } + } + + $html = $this->purify_utf8($html, false); + if ($init) { + $this->blklvl = 0; + $this->lastblocklevelchange = 0; + $this->blk = []; + $this->initialiseBlock($this->blk[0]); + $this->blk[0]['width'] = & $this->pgwidth; + $this->blk[0]['inner_width'] = & $this->pgwidth; + $this->blk[0]['blockContext'] = $this->blockContext; + } + + $zproperties = []; + if ($mode === HTMLParserMode::DEFAULT_MODE || $mode === HTMLParserMode::HEADER_CSS) { + $this->ReadMetaTags($html); + + if (preg_match('/]*href=["\']([^"\'>]*)["\']/i', $html, $m)) { + $this->SetBasePath($m[1]); + } + $html = $this->cssManager->ReadCSS($html); + + if ($this->autoLangToFont && !$this->usingCoreFont && preg_match('/]*lang=[\'\"](.*?)[\'\"]/ism', $html, $m)) { + $html_lang = $m[1]; + } + + if (preg_match('/]*dir=[\'\"]\s*rtl\s*[\'\"]/ism', $html)) { + $zproperties['DIRECTION'] = 'rtl'; + } + + // allow in-line CSS for body tag to be parsed // Get tag inline CSS + if (preg_match('/]*)>(.*?)<\/body>/ism', $html, $m) || preg_match('/]*)>(.*)$/ism', $html, $m)) { + $html = $m[2]; + // Changed to allow style="background: url('bg.jpg')" + if (preg_match('/style=[\"](.*?)[\"]/ism', $m[1], $mm) || preg_match('/style=[\'](.*?)[\']/ism', $m[1], $mm)) { + $zproperties = $this->cssManager->readInlineCSS($mm[1]); + } + if (preg_match('/dir=[\'\"]\s*rtl\s*[\'\"]/ism', $m[1])) { + $zproperties['DIRECTION'] = 'rtl'; + } + if (isset($html_lang) && $html_lang) { + $zproperties['LANG'] = $html_lang; + } + if ($this->autoLangToFont && !$this->onlyCoreFonts && preg_match('/lang=[\'\"](.*?)[\'\"]/ism', $m[1], $mm)) { + $zproperties['LANG'] = $mm[1]; + } + } + } + $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', ''); + if ($zproperties) { + $properties = $this->cssManager->array_merge_recursive_unique($properties, $zproperties); + } + + if (isset($properties['DIRECTION']) && $properties['DIRECTION']) { + $this->cssManager->CSS['BODY']['DIRECTION'] = $properties['DIRECTION']; + } + if (!isset($this->cssManager->CSS['BODY']['DIRECTION'])) { + $this->cssManager->CSS['BODY']['DIRECTION'] = $this->directionality; + } else { + $this->SetDirectionality($this->cssManager->CSS['BODY']['DIRECTION']); + } + + $this->setCSS($properties, '', 'BODY'); + + $this->blk[0]['InlineProperties'] = $this->saveInlineProperties(); + + if ($mode === HTMLParserMode::HEADER_CSS) { + return ''; + } + if (!isset($this->cssManager->CSS['BODY'])) { + $this->cssManager->CSS['BODY'] = []; + } + + /* -- BACKGROUNDS -- */ + if (isset($properties['BACKGROUND-GRADIENT'])) { + $this->bodyBackgroundGradient = $properties['BACKGROUND-GRADIENT']; + } + + if (isset($properties['BACKGROUND-IMAGE']) && $properties['BACKGROUND-IMAGE']) { + $ret = $this->SetBackground($properties, $this->pgwidth); + if ($ret) { + $this->bodyBackgroundImage = $ret; + } + } + /* -- END BACKGROUNDS -- */ + + /* -- CSS-PAGE -- */ + // If page-box is set + if ($this->state == 0 && ((isset($this->cssManager->CSS['@PAGE']) && $this->cssManager->CSS['@PAGE']) || (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']) && $this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']))) { // mPDF 5.7.3 + $this->page_box['current'] = ''; + $this->page_box['using'] = true; + list($pborientation, $pbmgl, $pbmgr, $pbmgt, $pbmgb, $pbmgh, $pbmgf, $hname, $fname, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat) = $this->SetPagedMediaCSS('', false, 'O'); + $this->DefOrientation = $this->CurOrientation = $pborientation; + $this->orig_lMargin = $this->DeflMargin = $pbmgl; + $this->orig_rMargin = $this->DefrMargin = $pbmgr; + $this->orig_tMargin = $this->tMargin = $pbmgt; + $this->orig_bMargin = $this->bMargin = $pbmgb; + $this->orig_hMargin = $this->margin_header = $pbmgh; + $this->orig_fMargin = $this->margin_footer = $pbmgf; + list($pborientation, $pbmgl, $pbmgr, $pbmgt, $pbmgb, $pbmgh, $pbmgf, $hname, $fname, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat) = $this->SetPagedMediaCSS('', true, 'O'); // first page + $this->show_marks = $marks; + if ($hname) { + $this->firstPageBoxHeader = $hname; + } + if ($fname) { + $this->firstPageBoxFooter = $fname; + } + } + /* -- END CSS-PAGE -- */ + + $parseonly = false; + $this->bufferoutput = false; + if ($mode == HTMLParserMode::HTML_PARSE_NO_WRITE) { + $parseonly = true; + // Close any open block tags + $arr = []; + $ai = 0; + for ($b = $this->blklvl; $b > 0; $b--) { + $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai); + } + // Output any text left in buffer + if (count($this->textbuffer)) { + $this->printbuffer($this->textbuffer); + } + $this->textbuffer = []; + } elseif ($mode === HTMLParserMode::HTML_HEADER_BUFFER) { + // Close any open block tags + $arr = []; + $ai = 0; + for ($b = $this->blklvl; $b > 0; $b--) { + $this->tag->CloseTag($this->blk[$b]['tag'], $arr, $ai); + } + // Output any text left in buffer + if (count($this->textbuffer)) { + $this->printbuffer($this->textbuffer); + } + $this->bufferoutput = true; + $this->textbuffer = []; + $this->headerbuffer = ''; + $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', ''); + $this->setCSS($properties, '', 'BODY'); + } + + mb_internal_encoding('UTF-8'); + + $html = $this->AdjustHTML($html, $this->tabSpaces); // Try to make HTML look more like XHTML + + if ($this->autoScriptToLang) { + $html = $this->markScriptToLang($html); + } + + preg_match_all('/]*)>(.*?)<\/htmlpageheader>/si', $html, $h); + for ($i = 0; $i < count($h[1]); $i++) { + if (preg_match('/name=[\'|\"](.*?)[\'|\"]/', $h[1][$i], $n)) { + $this->pageHTMLheaders[$n[1]]['html'] = $h[2][$i]; + $this->pageHTMLheaders[$n[1]]['h'] = $this->_getHtmlHeight($h[2][$i]); + } + } + preg_match_all('/]*)>(.*?)<\/htmlpagefooter>/si', $html, $f); + for ($i = 0; $i < count($f[1]); $i++) { + if (preg_match('/name=[\'|\"](.*?)[\'|\"]/', $f[1][$i], $n)) { + $this->pageHTMLfooters[$n[1]]['html'] = $f[2][$i]; + $this->pageHTMLfooters[$n[1]]['h'] = $this->_getHtmlHeight($f[2][$i]); + } + } + + $html = preg_replace('//si', '', $html); + $html = preg_replace('//si', '', $html); + + if ($this->state == 0 && ($mode === HTMLParserMode::DEFAULT_MODE || $mode === HTMLParserMode::HTML_BODY)) { + $this->AddPage($this->CurOrientation); + } + + + if (isset($hname) && preg_match('/^html_(.*)$/i', $hname, $n)) { + $this->SetHTMLHeader($this->pageHTMLheaders[$n[1]], 'O', true); + } + if (isset($fname) && preg_match('/^html_(.*)$/i', $fname, $n)) { + $this->SetHTMLFooter($this->pageHTMLfooters[$n[1]], 'O'); + } + + + + $html = str_replace('checkSIP = false; + $this->checkSMP = false; + $this->checkCJK = false; + if ($this->onlyCoreFonts) { + $html = $this->SubstituteChars($html); + } else { + if (preg_match("/([" . $this->pregRTLchars . "])/u", $html)) { + $this->biDirectional = true; + } // *OTL* + if (preg_match("/([\x{20000}-\x{2FFFF}])/u", $html)) { + $this->checkSIP = true; + } + if (preg_match("/([\x{10000}-\x{1FFFF}])/u", $html)) { + $this->checkSMP = true; + } + /* -- CJK-FONTS -- */ + if (preg_match("/([" . $this->pregCJKchars . "])/u", $html)) { + $this->checkCJK = true; + } + /* -- END CJK-FONTS -- */ + } + + // Don't allow non-breaking spaces that are converted to substituted chars or will break anyway and mess up table width calc. + $html = str_replace('160', chr(32), $html); + $html = str_replace('', '|', $html); + $html = str_replace('', '|', $html); + $html = str_replace('', '|', $html); + + // Add new supported tags in the DisableTags function + $html = strip_tags($html, $this->enabledtags); // remove all unsupported tags, but the ones inside the 'enabledtags' string + // Explode the string in order to parse the HTML code + $a = preg_split('/<(.*?)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE); + // ? more accurate regexp that allows e.g.
+ // if changing - also change in fn.SubstituteChars() + // $a = preg_split ('/<((?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE); + + if ($this->mb_enc) { + mb_internal_encoding($this->mb_enc); + } + $pbc = 0; + $this->subPos = -1; + $cnt = count($a); + for ($i = 0; $i < $cnt; $i++) { + $e = $a[$i]; + if ($i % 2 == 0) { + // TEXT + if ($this->blk[$this->blklvl]['hide']) { + continue; + } + if ($this->inlineDisplayOff) { + continue; + } + if ($this->inMeter) { + continue; + } + + if ($this->inFixedPosBlock) { + $this->fixedPosBlock .= $e; + continue; + } // *CSS-POSITION* + if (strlen($e) == 0) { + continue; + } + + if ($this->ignorefollowingspaces && !$this->ispre) { + if (strlen(ltrim($e)) == 0) { + continue; + } + if ($this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats' && substr($e, 0, 1) == ' ') { + $this->ignorefollowingspaces = false; + $e = ltrim($e); + } + } + + $this->OTLdata = null; // mPDF 5.7.1 + + $e = UtfString::strcode2utf($e); + $e = $this->lesser_entity_decode($e); + + if ($this->usingCoreFont) { + // If core font is selected in document which is not onlyCoreFonts - substitute with non-core font + if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->subPos < $i && !$this->specialcontent) { + $cnt += $this->SubstituteCharsNonCore($a, $i, $e); + } + // CONVERT ENCODING + $e = mb_convert_encoding($e, $this->mb_enc, 'UTF-8'); + if ($this->textvar & TextVars::FT_UPPERCASE) { + $e = mb_strtoupper($e, $this->mb_enc); + } // mPDF 5.7.1 + elseif ($this->textvar & TextVars::FT_LOWERCASE) { + $e = mb_strtolower($e, $this->mb_enc); + } // mPDF 5.7.1 + elseif ($this->textvar & TextVars::FT_CAPITALIZE) { + $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); + } // mPDF 5.7.1 + } else { + if ($this->checkSIP && $this->CurrentFont['sipext'] && $this->subPos < $i && (!$this->specialcontent || !$this->useActiveForms)) { + $cnt += $this->SubstituteCharsSIP($a, $i, $e); + } + + if ($this->useSubstitutions && !$this->onlyCoreFonts && $this->CurrentFont['type'] != 'Type0' && $this->subPos < $i && (!$this->specialcontent || !$this->useActiveForms)) { + $cnt += $this->SubstituteCharsMB($a, $i, $e); + } + + if ($this->textvar & TextVars::FT_UPPERCASE) { + $e = mb_strtoupper($e, $this->mb_enc); + } elseif ($this->textvar & TextVars::FT_LOWERCASE) { + $e = mb_strtolower($e, $this->mb_enc); + } elseif ($this->textvar & TextVars::FT_CAPITALIZE) { + $e = mb_convert_case($e, MB_CASE_TITLE, "UTF-8"); + } + + /* -- OTL -- */ + // Use OTL OpenType Table Layout - GSUB & GPOS + if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL'] && (!$this->specialcontent || !$this->useActiveForms)) { + if (!$this->otl) { + $this->otl = new Otl($this, $this->fontCache); + } + $e = $this->otl->applyOTL($e, $this->CurrentFont['useOTL']); + $this->OTLdata = $this->otl->OTLdata; + $this->otl->removeChar($e, $this->OTLdata, "\xef\xbb\xbf"); // Remove ZWNBSP (also Byte order mark FEFF) + } /* -- END OTL -- */ + else { + // removes U+200E/U+200F LTR and RTL mark and U+200C/U+200D Zero-width Joiner and Non-joiner + $e = preg_replace("/[\xe2\x80\x8c\xe2\x80\x8d\xe2\x80\x8e\xe2\x80\x8f]/u", '', $e); + $e = preg_replace("/[\xef\xbb\xbf]/u", '', $e); // Remove ZWNBSP (also Byte order mark FEFF) + } + } + + if (($this->tts) || ($this->ttz) || ($this->tta)) { + $es = explode('|', $e); + $e = ''; + foreach ($es as $val) { + $e .= chr($val); + } + } + + // FORM ELEMENTS + if ($this->specialcontent) { + /* -- FORMS -- */ + // SELECT tag (form element) + if ($this->specialcontent == "type=select") { + $e = ltrim($e); + if (!empty($this->OTLdata)) { + $this->otl->trimOTLdata($this->OTLdata, true, false); + } // *OTL* + $stringwidth = $this->GetStringWidth($e); + if (!isset($this->selectoption['MAXWIDTH']) || $stringwidth > $this->selectoption['MAXWIDTH']) { + $this->selectoption['MAXWIDTH'] = $stringwidth; + } + if (!isset($this->selectoption['SELECTED']) || $this->selectoption['SELECTED'] == '') { + $this->selectoption['SELECTED'] = $e; + if (!empty($this->OTLdata)) { + $this->selectoption['SELECTED-OTLDATA'] = $this->OTLdata; + } // *OTL* + } + // Active Forms + if (isset($this->selectoption['ACTIVE']) && $this->selectoption['ACTIVE']) { + $this->selectoption['ITEMS'][] = ['exportValue' => $this->selectoption['currentVAL'], 'content' => $e, 'selected' => $this->selectoption['currentSEL']]; + } + $this->OTLdata = []; + } // TEXTAREA + else { + $objattr = unserialize($this->specialcontent); + $objattr['text'] = $e; + $objattr['OTLdata'] = $this->OTLdata; + $this->OTLdata = []; + $te = "\xbb\xa4\xactype=textarea,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->tdbegin) { + $this->_saveCellTextBuffer($te, $this->HREF); + } else { + $this->_saveTextBuffer($te, $this->HREF); + } + } + /* -- END FORMS -- */ + } // TABLE + elseif ($this->tableLevel) { + /* -- TABLES -- */ + if ($this->tdbegin) { + if (($this->ignorefollowingspaces) && !$this->ispre) { + $e = ltrim($e); + if (!empty($this->OTLdata)) { + $this->otl->trimOTLdata($this->OTLdata, true, false); + } // *OTL* + } + if ($e || $e === '0') { + if ($this->blockjustfinished && $this->cell[$this->row][$this->col]['s'] > 0) { + $this->_saveCellTextBuffer("\n"); + if (!isset($this->cell[$this->row][$this->col]['maxs'])) { + $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s']; + } elseif ($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) { + $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s']; + } + $this->cell[$this->row][$this->col]['s'] = 0; // reset + } + $this->blockjustfinished = false; + + if (!isset($this->cell[$this->row][$this->col]['R']) || !$this->cell[$this->row][$this->col]['R']) { + if (isset($this->cell[$this->row][$this->col]['s'])) { + $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar); + } else { + $this->cell[$this->row][$this->col]['s'] = $this->GetStringWidth($e, false, $this->OTLdata, $this->textvar); + } + if (!empty($this->spanborddet)) { + $this->cell[$this->row][$this->col]['s'] += (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0) + (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0); + } + } + $this->_saveCellTextBuffer($e, $this->HREF); + if (substr($this->cell[$this->row][$this->col]['a'], 0, 1) == 'D') { + $dp = $this->decimal_align[substr($this->cell[$this->row][$this->col]['a'], 0, 2)]; + $s = preg_split('/' . preg_quote($dp, '/') . '/', $e, 2); // ? needs to be /u if not core + $s0 = $this->GetStringWidth($s[0], false); + if (isset($s[1]) && $s[1]) { + $s1 = $this->GetStringWidth(($s[1] . $dp), false); + } else { + $s1 = 0; + } + if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'])) { + $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = $s0; + } else { + $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0'] = max($s0, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs0']); + } + if (!isset($this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'])) { + $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = $s1; + } else { + $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1'] = max($s1, $this->table[$this->tableLevel][$this->tbctr[$this->tableLevel]]['decimal_align'][$this->col]['maxs1']); + } + } + + $this->nestedtablejustfinished = false; + $this->linebreakjustfinished = false; + } + } + /* -- END TABLES -- */ + } // ALL ELSE + else { + if ($this->ignorefollowingspaces && !$this->ispre) { + $e = ltrim($e); + if (!empty($this->OTLdata)) { + $this->otl->trimOTLdata($this->OTLdata, true, false); + } // *OTL* + } + if ($e || $e === '0') { + $this->_saveTextBuffer($e, $this->HREF); + } + } + if ($e || $e === '0') { + $this->ignorefollowingspaces = false; // mPDF 6 + } + if (substr($e, -1, 1) == ' ' && !$this->ispre && $this->FontFamily != 'csymbol' && $this->FontFamily != 'czapfdingbats') { + $this->ignorefollowingspaces = true; + } + } else { // TAG ** + if (isset($e[0]) && $e[0] == '/') { + $endtag = trim(strtoupper(substr($e, 1))); + + /* -- CSS-POSITION -- */ + // mPDF 6 + if ($this->inFixedPosBlock) { + if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { + $this->fixedPosBlockDepth--; + } + if ($this->fixedPosBlockDepth == 0) { + $this->fixedPosBlockSave[] = [$this->fixedPosBlock, $this->fixedPosBlockBBox, $this->page]; + $this->fixedPosBlock = ''; + $this->inFixedPosBlock = false; + continue; + } + $this->fixedPosBlock .= '<' . $e . '>'; + continue; + } + /* -- END CSS-POSITION -- */ + + // mPDF 6 + // Correct for tags where HTML5 specifies optional end tags (see also OpenTag() ) + if ($this->allow_html_optional_endtags && !$parseonly) { + if (isset($this->blk[$this->blklvl]['tag'])) { + $closed = false; + // li end tag may be omitted if there is no more content in the parent element + if (!$closed && $this->blk[$this->blklvl]['tag'] == 'LI' && $endtag != 'LI' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { + $this->tag->CloseTag('LI', $a, $i); + $closed = true; + } + // dd end tag may be omitted if there is no more content in the parent element + if (!$closed && $this->blk[$this->blklvl]['tag'] == 'DD' && $endtag != 'DD' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { + $this->tag->CloseTag('DD', $a, $i); + $closed = true; + } + // p end tag may be omitted if there is no more content in the parent element and the parent element is not an A element [??????] + if (!$closed && $this->blk[$this->blklvl]['tag'] == 'P' && $endtag != 'P' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { + $this->tag->CloseTag('P', $a, $i); + $closed = true; + } + // option end tag may be omitted if there is no more content in the parent element + if (!$closed && $this->blk[$this->blklvl]['tag'] == 'OPTION' && $endtag != 'OPTION' && (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags))) { + $this->tag->CloseTag('OPTION', $a, $i); + $closed = true; + } + } + /* -- TABLES -- */ + // Check for Table tags where HTML specifies optional end tags, + if ($endtag == 'TABLE') { + if ($this->lastoptionaltag == 'THEAD' || $this->lastoptionaltag == 'TBODY' || $this->lastoptionaltag == 'TFOOT') { + $this->tag->CloseTag($this->lastoptionaltag, $a, $i); + } + if ($this->lastoptionaltag == 'TR') { + $this->tag->CloseTag('TR', $a, $i); + } + if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { + $this->tag->CloseTag($this->lastoptionaltag, $a, $i); + $this->tag->CloseTag('TR', $a, $i); + } + } + if ($endtag == 'THEAD' || $endtag == 'TBODY' || $endtag == 'TFOOT') { + if ($this->lastoptionaltag == 'TR') { + $this->tag->CloseTag('TR', $a, $i); + } + if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { + $this->tag->CloseTag($this->lastoptionaltag, $a, $i); + $this->tag->CloseTag('TR', $a, $i); + } + } + if ($endtag == 'TR') { + if ($this->lastoptionaltag == 'TD' || $this->lastoptionaltag == 'TH') { + $this->tag->CloseTag($this->lastoptionaltag, $a, $i); + } + } + /* -- END TABLES -- */ + } + + + // mPDF 6 + if ($this->blk[$this->blklvl]['hide']) { + if (in_array($endtag, $this->outerblocktags) || in_array($endtag, $this->innerblocktags)) { + unset($this->blk[$this->blklvl]); + $this->blklvl--; + } + continue; + } + + // mPDF 6 + $this->tag->CloseTag($endtag, $a, $i); // mPDF 6 + } else { // OPENING TAG + if ($this->blk[$this->blklvl]['hide']) { + if (strpos($e, ' ')) { + $te = strtoupper(substr($e, 0, strpos($e, ' '))); + } else { + $te = strtoupper($e); + } + // mPDF 6 + if ($te == 'THEAD' || $te == 'TBODY' || $te == 'TFOOT' || $te == 'TR' || $te == 'TD' || $te == 'TH') { + $this->lastoptionaltag = $te; + } + if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { + $this->blklvl++; + $this->blk[$this->blklvl]['hide'] = true; + $this->blk[$this->blklvl]['tag'] = $te; // mPDF 6 + } + continue; + } + + /* -- CSS-POSITION -- */ + if ($this->inFixedPosBlock) { + if (strpos($e, ' ')) { + $te = strtoupper(substr($e, 0, strpos($e, ' '))); + } else { + $te = strtoupper($e); + } + $this->fixedPosBlock .= '<' . $e . '>'; + if (in_array($te, $this->outerblocktags) || in_array($te, $this->innerblocktags)) { + $this->fixedPosBlockDepth++; + } + continue; + } + /* -- END CSS-POSITION -- */ + $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any + $e = preg_replace($regexp, "=\"\$1\"", $e); + // changes anykey=anyvalue to anykey="anyvalue" (only do this inside [some] tags) + if (substr($e, 0, 10) != 'pageheader' && substr($e, 0, 10) != 'pagefooter' && substr($e, 0, 12) != 'tocpagebreak' && substr($e, 0, 10) != 'indexentry' && substr($e, 0, 8) != 'tocentry') { // mPDF 6 (ZZZ99H) + $regexp = '| (\\w+?)=([^\\s>"]+)|si'; + $e = preg_replace($regexp, " \$1=\"\$2\"", $e); + } + + $e = preg_replace('/ (\\S+?)\s*=\s*"/i', " \\1=\"", $e); + + // Fix path values, if needed + $orig_srcpath = ''; + if ((stristr($e, "href=") !== false) or ( stristr($e, "src=") !== false)) { + $regexp = '/ (href|src)\s*=\s*"(.*?)"/i'; + preg_match($regexp, $e, $auxiliararray); + if (isset($auxiliararray[2])) { + $path = $auxiliararray[2]; + } else { + $path = ''; + } + if (trim($path) != '' && !(stristr($e, "src=") !== false && substr($path, 0, 4) == 'var:') && substr($path, 0, 1) != '@') { + $path = htmlspecialchars_decode($path); // mPDF 5.7.4 URLs + $orig_srcpath = $path; + $this->GetFullPath($path); + $regexp = '/ (href|src)="(.*?)"/i'; + $e = preg_replace($regexp, ' \\1="' . $path . '"', $e); + } + }//END of Fix path values + // Extract attributes + $contents = []; + $contents1 = []; + $contents2 = []; + // Changed to allow style="background: url('bg.jpg')" + // Changed to improve performance; maximum length of \S (attribute) = 16 + // Increase allowed attribute name to 32 - cutting off "toc-even-header-name" etc. + preg_match_all('/\\S{1,32}=["][^"]*["]/', $e, $contents1); + preg_match_all('/\\S{1,32}=[\'][^\']*[\']/i', $e, $contents2); + + $contents = array_merge($contents1, $contents2); + preg_match('/\\S+/', $e, $a2); + $tag = (isset($a2[0]) ? strtoupper($a2[0]) : ''); + $attr = []; + if ($orig_srcpath) { + $attr['ORIG_SRC'] = $orig_srcpath; + } + if (!empty($contents)) { + foreach ($contents[0] as $v) { + // Changed to allow style="background: url('bg.jpg')" + if (preg_match('/^([^=]*)=["]?([^"]*)["]?$/', $v, $a3) || preg_match('/^([^=]*)=[\']?([^\']*)[\']?$/', $v, $a3)) { + if (strtoupper($a3[1]) == 'ID' || strtoupper($a3[1]) == 'CLASS') { // 4.2.013 Omits STYLE + $attr[strtoupper($a3[1])] = trim(strtoupper($a3[2])); + } // includes header-style-right etc. used for + elseif (preg_match('/^(HEADER|FOOTER)-STYLE/i', $a3[1])) { + $attr[strtoupper($a3[1])] = trim(strtoupper($a3[2])); + } else { + $attr[strtoupper($a3[1])] = trim($a3[2]); + } + } + } + } + $this->tag->OpenTag($tag, $attr, $a, $i); // mPDF 6 + /* -- CSS-POSITION -- */ + if ($this->inFixedPosBlock) { + $this->fixedPosBlockBBox = [$tag, $attr, $this->x, $this->y]; + $this->fixedPosBlock = ''; + $this->fixedPosBlockDepth = 1; + } + /* -- END CSS-POSITION -- */ + if (preg_match('/\/$/', $e)) { + $this->tag->CloseTag($tag, $a, $i); + } + } + } // end TAG + } // end of foreach($a as $i=>$e) + + if ($close) { + // Close any open block tags + for ($b = $this->blklvl; $b > 0; $b--) { + $this->tag->CloseTag($this->blk[$b]['tag'], $a, $i); + } + + // Output any text left in buffer + if (count($this->textbuffer) && !$parseonly) { + $this->printbuffer($this->textbuffer); + } + if (!$parseonly) { + $this->textbuffer = []; + } + + /* -- CSS-FLOAT -- */ + // If ended with a float, need to move to end page + $currpos = $this->page * 1000 + $this->y; + if (isset($this->blk[$this->blklvl]['float_endpos']) && $this->blk[$this->blklvl]['float_endpos'] > $currpos) { + $old_page = $this->page; + $new_page = intval($this->blk[$this->blklvl]['float_endpos'] / 1000); + if ($old_page != $new_page) { + $s = $this->PrintPageBackgrounds(); + // Writes after the marker so not overwritten later by page background etc. + $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]); + $this->pageBackgrounds = []; + $this->page = $new_page; + $this->ResetMargins(); + $this->Reset(); + $this->pageoutput[$this->page] = []; + } + $this->y = (($this->blk[$this->blklvl]['float_endpos'] * 1000) % 1000000) / 1000; // mod changes operands to integers before processing + } + /* -- END CSS-FLOAT -- */ + + /* -- CSS-IMAGE-FLOAT -- */ + $this->printfloatbuffer(); + /* -- END CSS-IMAGE-FLOAT -- */ + + // Create Internal Links, if needed + if (!empty($this->internallink)) { + + foreach ($this->internallink as $k => $v) { + + if (strpos($k, "#") !== false) { + continue; + } + + if (!is_array($v)) { + continue; + } + + $ypos = $v['Y']; + $pagenum = $v['PAGE']; + $sharp = "#"; + + while (array_key_exists($sharp . $k, $this->internallink)) { + $internallink = $this->internallink[$sharp . $k]; + $this->SetLink($internallink, $ypos, $pagenum); + $sharp .= "#"; + } + } + } + + $this->bufferoutput = false; + + /* -- CSS-POSITION -- */ + if (count($this->fixedPosBlockSave)) { + foreach ($this->fixedPosBlockSave as $fpbs) { + $old_page = $this->page; + $this->page = $fpbs[2]; + $this->WriteFixedPosHTML($fpbs[0], 0, 0, 100, 100, 'auto', $fpbs[1]); // 0,0,10,10 are overwritten by bbox + $this->page = $old_page; + } + $this->fixedPosBlockSave = []; + } + /* -- END CSS-POSITION -- */ + } + } + + /* -- CSS-POSITION -- */ + + function WriteFixedPosHTML($html, $x, $y, $w, $h, $overflow = 'visible', $bounding = []) + { + // $overflow can be 'hidden', 'visible' or 'auto' - 'auto' causes autofit to size + // Annotations disabled - enabled in mPDF 5.0 + // Links do work + // Will always go on current page (or start Page 1 if required) + // Probably INCOMPATIBLE WITH keep with table, columns etc. + // Called externally or interally via
+ // When used internally, $x $y $w $h and $overflow are all overridden by $bounding + + $overflow = strtolower($overflow); + if ($this->state == 0) { + $this->AddPage($this->CurOrientation); + } + $save_y = $this->y; + $save_x = $this->x; + $this->fullImageHeight = $this->h; + $save_cols = false; + /* -- COLUMNS -- */ + if ($this->ColActive) { + $save_cols = true; + $save_nbcol = $this->NbCol; // other values of gap and vAlign will not change by setting Columns off + $this->SetColumns(0); + } + /* -- END COLUMNS -- */ + $save_annots = $this->title2annots; // *ANNOTATIONS* + $this->writingHTMLheader = true; // a FIX to stop pagebreaks etc. + $this->writingHTMLfooter = true; + $this->InFooter = true; // suppresses autopagebreaks + $save_bgs = $this->pageBackgrounds; + $checkinnerhtml = preg_replace('/\s/', '', $html); + $rotate = 0; + + if ($w > $this->w) { + $x = 0; + $w = $this->w; + } + if ($h > $this->h) { + $y = 0; + $h = $this->h; + } + if ($x > $this->w) { + $x = $this->w - $w; + } + if ($y > $this->h) { + $y = $this->h - $h; + } + + if (!empty($bounding)) { + // $cont_ containing block = full physical page (position: absolute) or page inside margins (position: fixed) + // $bbox_ Bounding box is the
which is positioned absolutely/fixed + // top/left/right/bottom/width/height/background*/border*/padding*/margin* are taken from bounding + // font*[family/size/style/weight]/line-height/text*[align/decoration/transform/indent]/color are transferred to $inner + // as an enclosing
(after having checked ID/CLASS) + // $x, $y, $w, $h are inside of $bbox_ = containing box for $inner_ + // $inner_ InnerHTML is the contents of that block to be output + $tag = $bounding[0]; + $attr = $bounding[1]; + $orig_x0 = $bounding[2]; + $orig_y0 = $bounding[3]; + + // As in WriteHTML() initialising + $this->blklvl = 0; + $this->lastblocklevelchange = 0; + $this->blk = []; + $this->initialiseBlock($this->blk[0]); + + $this->blk[0]['width'] = & $this->pgwidth; + $this->blk[0]['inner_width'] = & $this->pgwidth; + + $this->blk[0]['blockContext'] = $this->blockContext; + + $properties = $this->cssManager->MergeCSS('BLOCK', 'BODY', ''); + $this->setCSS($properties, '', 'BODY'); + $this->blklvl = 1; + $this->initialiseBlock($this->blk[1]); + $this->blk[1]['tag'] = $tag; + $this->blk[1]['attr'] = $attr; + $this->Reset(); + $p = $this->cssManager->MergeCSS('BLOCK', $tag, $attr); + if (isset($p['ROTATE']) && ($p['ROTATE'] == 90 || $p['ROTATE'] == -90 || $p['ROTATE'] == 180)) { + $rotate = $p['ROTATE']; + } // mPDF 6 + if (isset($p['OVERFLOW'])) { + $overflow = strtolower($p['OVERFLOW']); + } + if (strtolower($p['POSITION']) == 'fixed') { + $cont_w = $this->pgwidth; // $this->blk[0]['inner_width']; + $cont_h = $this->h - $this->tMargin - $this->bMargin; + $cont_x = $this->lMargin; + $cont_y = $this->tMargin; + } else { + $cont_w = $this->w; // ABSOLUTE; + $cont_h = $this->h; + $cont_x = 0; + $cont_y = 0; + } + + // Pass on in-line properties to the innerhtml + $css = ''; + if (isset($p['TEXT-ALIGN'])) { + $css .= 'text-align: ' . strtolower($p['TEXT-ALIGN']) . '; '; + } + if (isset($p['TEXT-TRANSFORM'])) { + $css .= 'text-transform: ' . strtolower($p['TEXT-TRANSFORM']) . '; '; + } + if (isset($p['TEXT-INDENT'])) { + $css .= 'text-indent: ' . strtolower($p['TEXT-INDENT']) . '; '; + } + if (isset($p['TEXT-DECORATION'])) { + $css .= 'text-decoration: ' . strtolower($p['TEXT-DECORATION']) . '; '; + } + if (isset($p['FONT-FAMILY'])) { + $css .= 'font-family: ' . strtolower($p['FONT-FAMILY']) . '; '; + } + if (isset($p['FONT-STYLE'])) { + $css .= 'font-style: ' . strtolower($p['FONT-STYLE']) . '; '; + } + if (isset($p['FONT-WEIGHT'])) { + $css .= 'font-weight: ' . strtolower($p['FONT-WEIGHT']) . '; '; + } + if (isset($p['FONT-SIZE'])) { + $css .= 'font-size: ' . strtolower($p['FONT-SIZE']) . '; '; + } + if (isset($p['LINE-HEIGHT'])) { + $css .= 'line-height: ' . strtolower($p['LINE-HEIGHT']) . '; '; + } + if (isset($p['TEXT-SHADOW'])) { + $css .= 'text-shadow: ' . strtolower($p['TEXT-SHADOW']) . '; '; + } + if (isset($p['LETTER-SPACING'])) { + $css .= 'letter-spacing: ' . strtolower($p['LETTER-SPACING']) . '; '; + } + // mPDF 6 + if (isset($p['FONT-VARIANT-POSITION'])) { + $css .= 'font-variant-position: ' . strtolower($p['FONT-VARIANT-POSITION']) . '; '; + } + if (isset($p['FONT-VARIANT-CAPS'])) { + $css .= 'font-variant-caps: ' . strtolower($p['FONT-VARIANT-CAPS']) . '; '; + } + if (isset($p['FONT-VARIANT-LIGATURES'])) { + $css .= 'font-variant-ligatures: ' . strtolower($p['FONT-VARIANT-LIGATURES']) . '; '; + } + if (isset($p['FONT-VARIANT-NUMERIC'])) { + $css .= 'font-variant-numeric: ' . strtolower($p['FONT-VARIANT-NUMERIC']) . '; '; + } + if (isset($p['FONT-VARIANT-ALTERNATES'])) { + $css .= 'font-variant-alternates: ' . strtolower($p['FONT-VARIANT-ALTERNATES']) . '; '; + } + if (isset($p['FONT-FEATURE-SETTINGS'])) { + $css .= 'font-feature-settings: ' . strtolower($p['FONT-FEATURE-SETTINGS']) . '; '; + } + if (isset($p['FONT-LANGUAGE-OVERRIDE'])) { + $css .= 'font-language-override: ' . strtolower($p['FONT-LANGUAGE-OVERRIDE']) . '; '; + } + if (isset($p['FONT-KERNING'])) { + $css .= 'font-kerning: ' . strtolower($p['FONT-KERNING']) . '; '; + } + + if (isset($p['COLOR'])) { + $css .= 'color: ' . strtolower($p['COLOR']) . '; '; + } + if (isset($p['Z-INDEX'])) { + $css .= 'z-index: ' . $p['Z-INDEX'] . '; '; + } + if ($css) { + $html = '
' . $html . '
'; + } + // Copy over (only) the properties to set for border and background + $pb = []; + $pb['MARGIN-TOP'] = (isset($p['MARGIN-TOP']) ? $p['MARGIN-TOP'] : ''); + $pb['MARGIN-RIGHT'] = (isset($p['MARGIN-RIGHT']) ? $p['MARGIN-RIGHT'] : ''); + $pb['MARGIN-BOTTOM'] = (isset($p['MARGIN-BOTTOM']) ? $p['MARGIN-BOTTOM'] : ''); + $pb['MARGIN-LEFT'] = (isset($p['MARGIN-LEFT']) ? $p['MARGIN-LEFT'] : ''); + $pb['PADDING-TOP'] = (isset($p['PADDING-TOP']) ? $p['PADDING-TOP'] : ''); + $pb['PADDING-RIGHT'] = (isset($p['PADDING-RIGHT']) ? $p['PADDING-RIGHT'] : ''); + $pb['PADDING-BOTTOM'] = (isset($p['PADDING-BOTTOM']) ? $p['PADDING-BOTTOM'] : ''); + $pb['PADDING-LEFT'] = (isset($p['PADDING-LEFT']) ? $p['PADDING-LEFT'] : ''); + $pb['BORDER-TOP'] = (isset($p['BORDER-TOP']) ? $p['BORDER-TOP'] : ''); + $pb['BORDER-RIGHT'] = (isset($p['BORDER-RIGHT']) ? $p['BORDER-RIGHT'] : ''); + $pb['BORDER-BOTTOM'] = (isset($p['BORDER-BOTTOM']) ? $p['BORDER-BOTTOM'] : ''); + $pb['BORDER-LEFT'] = (isset($p['BORDER-LEFT']) ? $p['BORDER-LEFT'] : ''); + if (isset($p['BORDER-TOP-LEFT-RADIUS-H'])) { + $pb['BORDER-TOP-LEFT-RADIUS-H'] = $p['BORDER-TOP-LEFT-RADIUS-H']; + } + if (isset($p['BORDER-TOP-LEFT-RADIUS-V'])) { + $pb['BORDER-TOP-LEFT-RADIUS-V'] = $p['BORDER-TOP-LEFT-RADIUS-V']; + } + if (isset($p['BORDER-TOP-RIGHT-RADIUS-H'])) { + $pb['BORDER-TOP-RIGHT-RADIUS-H'] = $p['BORDER-TOP-RIGHT-RADIUS-H']; + } + if (isset($p['BORDER-TOP-RIGHT-RADIUS-V'])) { + $pb['BORDER-TOP-RIGHT-RADIUS-V'] = $p['BORDER-TOP-RIGHT-RADIUS-V']; + } + if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-H'])) { + $pb['BORDER-BOTTOM-LEFT-RADIUS-H'] = $p['BORDER-BOTTOM-LEFT-RADIUS-H']; + } + if (isset($p['BORDER-BOTTOM-LEFT-RADIUS-V'])) { + $pb['BORDER-BOTTOM-LEFT-RADIUS-V'] = $p['BORDER-BOTTOM-LEFT-RADIUS-V']; + } + if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-H'])) { + $pb['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-H']; + } + if (isset($p['BORDER-BOTTOM-RIGHT-RADIUS-V'])) { + $pb['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $p['BORDER-BOTTOM-RIGHT-RADIUS-V']; + } + if (isset($p['BACKGROUND-COLOR'])) { + $pb['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; + } + if (isset($p['BOX-SHADOW'])) { + $pb['BOX-SHADOW'] = $p['BOX-SHADOW']; + } + /* -- BACKGROUNDS -- */ + if (isset($p['BACKGROUND-IMAGE'])) { + $pb['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; + } + if (isset($p['BACKGROUND-IMAGE-RESIZE'])) { + $pb['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; + } + if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { + $pb['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; + } + if (isset($p['BACKGROUND-REPEAT'])) { + $pb['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; + } + if (isset($p['BACKGROUND-POSITION'])) { + $pb['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; + } + if (isset($p['BACKGROUND-GRADIENT'])) { + $pb['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; + } + if (isset($p['BACKGROUND-SIZE'])) { + $pb['BACKGROUND-SIZE'] = $p['BACKGROUND-SIZE']; + } + if (isset($p['BACKGROUND-ORIGIN'])) { + $pb['BACKGROUND-ORIGIN'] = $p['BACKGROUND-ORIGIN']; + } + if (isset($p['BACKGROUND-CLIP'])) { + $pb['BACKGROUND-CLIP'] = $p['BACKGROUND-CLIP']; + } + + /* -- END BACKGROUNDS -- */ + + $this->setCSS($pb, 'BLOCK', $tag); + + // ================================================================ + $bbox_br = $this->blk[1]['border_right']['w']; + $bbox_bl = $this->blk[1]['border_left']['w']; + $bbox_bt = $this->blk[1]['border_top']['w']; + $bbox_bb = $this->blk[1]['border_bottom']['w']; + $bbox_pr = $this->blk[1]['padding_right']; + $bbox_pl = $this->blk[1]['padding_left']; + $bbox_pt = $this->blk[1]['padding_top']; + $bbox_pb = $this->blk[1]['padding_bottom']; + $bbox_mr = $this->blk[1]['margin_right']; + if (isset($p['MARGIN-RIGHT']) && strtolower($p['MARGIN-RIGHT']) == 'auto') { + $bbox_mr = 'auto'; + } + $bbox_ml = $this->blk[1]['margin_left']; + if (isset($p['MARGIN-LEFT']) && strtolower($p['MARGIN-LEFT']) == 'auto') { + $bbox_ml = 'auto'; + } + $bbox_mt = $this->blk[1]['margin_top']; + if (isset($p['MARGIN-TOP']) && strtolower($p['MARGIN-TOP']) == 'auto') { + $bbox_mt = 'auto'; + } + $bbox_mb = $this->blk[1]['margin_bottom']; + if (isset($p['MARGIN-BOTTOM']) && strtolower($p['MARGIN-BOTTOM']) == 'auto') { + $bbox_mb = 'auto'; + } + if (isset($p['LEFT']) && strtolower($p['LEFT']) != 'auto') { + $bbox_left = $this->sizeConverter->convert($p['LEFT'], $cont_w, $this->FontSize, false); + } else { + $bbox_left = 'auto'; + } + if (isset($p['TOP']) && strtolower($p['TOP']) != 'auto') { + $bbox_top = $this->sizeConverter->convert($p['TOP'], $cont_h, $this->FontSize, false); + } else { + $bbox_top = 'auto'; + } + if (isset($p['RIGHT']) && strtolower($p['RIGHT']) != 'auto') { + $bbox_right = $this->sizeConverter->convert($p['RIGHT'], $cont_w, $this->FontSize, false); + } else { + $bbox_right = 'auto'; + } + if (isset($p['BOTTOM']) && strtolower($p['BOTTOM']) != 'auto') { + $bbox_bottom = $this->sizeConverter->convert($p['BOTTOM'], $cont_h, $this->FontSize, false); + } else { + $bbox_bottom = 'auto'; + } + if (isset($p['WIDTH']) && strtolower($p['WIDTH']) != 'auto') { + $inner_w = $this->sizeConverter->convert($p['WIDTH'], $cont_w, $this->FontSize, false); + } else { + $inner_w = 'auto'; + } + if (isset($p['HEIGHT']) && strtolower($p['HEIGHT']) != 'auto') { + $inner_h = $this->sizeConverter->convert($p['HEIGHT'], $cont_h, $this->FontSize, false); + } else { + $inner_h = 'auto'; + } + + // If bottom or right pos are set and not left / top - save this to adjust rotated block later + if ($rotate == 90 || $rotate == -90) { // mPDF 6 + if ($bbox_left === 'auto' && $bbox_right !== 'auto') { + $rot_rpos = $bbox_right; + } else { + $rot_rpos = false; + } + if ($bbox_top === 'auto' && $bbox_bottom !== 'auto') { + $rot_bpos = $bbox_bottom; + } else { + $rot_bpos = false; + } + } + + // ================================================================ + if ($checkinnerhtml == '' && $inner_h === 'auto') { + $inner_h = 0.0001; + } + if ($checkinnerhtml == '' && $inner_w === 'auto') { + $inner_w = 2 * $this->GetCharWidth('W', false); + } + // ================================================================ + // Algorithm from CSS2.1 See http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height + // mPD 5.3.14 + // Special case (not CSS) if all not specified, centre vertically on page + $bbox_top_orig = ''; + if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_mt === 'auto' && $bbox_mb === 'auto') { + $bbox_top_orig = $bbox_top; + if ($bbox_mt === 'auto') { + $bbox_mt = 0; + } + if ($bbox_mb === 'auto') { + $bbox_mb = 0; + } + $bbox_top = $orig_y0 - $bbox_mt - $cont_y; + // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto' + } // mPD 5.3.14 + elseif ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom === 'auto') { + $bbox_top_orig = $bbox_top = $orig_y0 - $cont_y; + if ($bbox_mt === 'auto') { + $bbox_mt = 0; + } + if ($bbox_mb === 'auto') { + $bbox_mb = 0; + } + // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto' + } elseif ($bbox_top !== 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') { + if ($bbox_mt === 'auto' && $bbox_mb === 'auto') { + $x = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom; + $bbox_mt = $bbox_mb = ($x / 2); + } elseif ($bbox_mt === 'auto') { + $bbox_mt = $cont_h - $bbox_top - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom; + } elseif ($bbox_mb === 'auto') { + $bbox_mb = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_bottom; + } else { + $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt; + } + } else { + if ($bbox_mt === 'auto') { + $bbox_mt = 0; + } + if ($bbox_mb === 'auto') { + $bbox_mb = 0; + } + if ($bbox_top === 'auto' && $inner_h === 'auto' && $bbox_bottom !== 'auto') { + // solve for $bbox_top when content_h known - $inner_h=='auto' && $bbox_top =='auto' + } elseif ($bbox_top === 'auto' && $bbox_bottom === 'auto' && $inner_h !== 'auto') { + $bbox_top = $orig_y0 - $bbox_mt - $cont_y; + $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt; + } elseif ($inner_h === 'auto' && $bbox_bottom === 'auto' && $bbox_top !== 'auto') { + // solve for $bbox_bottom when content_h known - $inner_h=='auto' && $bbox_bottom=='auto' + } elseif ($bbox_top === 'auto' && $inner_h !== 'auto' && $bbox_bottom !== 'auto') { + $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom; + } elseif ($inner_h === 'auto' && $bbox_top !== 'auto' && $bbox_bottom !== 'auto') { + $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mt - $bbox_bottom; + } elseif ($bbox_bottom === 'auto' && $bbox_top !== 'auto' && $inner_h !== 'auto') { + $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mt; + } + } + + // THEN DO SAME FOR WIDTH + // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width + if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right === 'auto') { + if ($bbox_ml === 'auto') { + $bbox_ml = 0; + } + if ($bbox_mr === 'auto') { + $bbox_mr = 0; + } + // IF containing element RTL, should set $bbox_right + $bbox_left = $orig_x0 - $bbox_ml - $cont_x; + // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto' + } elseif ($bbox_left !== 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') { + if ($bbox_ml === 'auto' && $bbox_mr === 'auto') { + $x = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right; + $bbox_ml = $bbox_mr = ($x / 2); + } elseif ($bbox_ml === 'auto') { + $bbox_ml = $cont_w - $bbox_left - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right; + } elseif ($bbox_mr === 'auto') { + $bbox_mr = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_right; + } else { + $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml; + } + } else { + if ($bbox_ml === 'auto') { + $bbox_ml = 0; + } + if ($bbox_mr === 'auto') { + $bbox_mr = 0; + } + if ($bbox_left === 'auto' && $inner_w === 'auto' && $bbox_right !== 'auto') { + // solve for $bbox_left when content_w known - $inner_w=='auto' && $bbox_left =='auto' + } elseif ($bbox_left === 'auto' && $bbox_right === 'auto' && $inner_w !== 'auto') { + // IF containing element RTL, should set $bbox_right + $bbox_left = $orig_x0 - $bbox_ml - $cont_x; + $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml; + } elseif ($inner_w === 'auto' && $bbox_right === 'auto' && $bbox_left !== 'auto') { + // solve for $bbox_right when content_w known - $inner_w=='auto' && $bbox_right=='auto' + } elseif ($bbox_left === 'auto' && $inner_w !== 'auto' && $bbox_right !== 'auto') { + $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right; + } elseif ($inner_w === 'auto' && $bbox_left !== 'auto' && $bbox_right !== 'auto') { + $inner_w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right; + } elseif ($bbox_right === 'auto' && $bbox_left !== 'auto' && $inner_w !== 'auto') { + $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml; + } + } + + // ================================================================ + // ================================================================ + /* -- BACKGROUNDS -- */ + if (isset($pb['BACKGROUND-IMAGE']) && $pb['BACKGROUND-IMAGE']) { + $ret = $this->SetBackground($pb, $this->blk[1]['inner_width']); + if ($ret) { + $this->blk[1]['background-image'] = $ret; + } + } + /* -- END BACKGROUNDS -- */ + + $bbox_top_auto = $bbox_top === 'auto'; + $bbox_left_auto = $bbox_left === 'auto'; + $bbox_right_auto = $bbox_right === 'auto'; + $bbox_bottom_auto = $bbox_bottom === 'auto'; + + $bbox_top = is_numeric($bbox_top) ? $bbox_top : 0; + $bbox_left = is_numeric($bbox_left) ? $bbox_left : 0; + $bbox_right = is_numeric($bbox_right) ? $bbox_right : 0; + $bbox_bottom = is_numeric($bbox_bottom) ? $bbox_bottom : 0; + + $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt; + $h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom; + + $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl; + $w = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $bbox_pr - $bbox_br - $bbox_mr - $bbox_right; + + // Set (temporary) values for x y w h to do first paint, if values are auto + if ($inner_h === 'auto' && $bbox_top_auto) { + $y = $cont_y + $bbox_mt + $bbox_bt + $bbox_pt; + $h = $cont_h - ($bbox_bottom + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb); + } elseif ($inner_h === 'auto' && $bbox_bottom_auto) { + $y = $cont_y + $bbox_top + $bbox_mt + $bbox_bt + $bbox_pt; + $h = $cont_h - ($bbox_top + $bbox_mt + $bbox_mb + $bbox_bt + $bbox_bb + $bbox_pt + $bbox_pb); + } + if ($inner_w === 'auto' && $bbox_left_auto) { + $x = $cont_x + $bbox_ml + $bbox_bl + $bbox_pl; + $w = $cont_w - ($bbox_right + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr); + } elseif ($inner_w === 'auto' && $bbox_right_auto) { + $x = $cont_x + $bbox_left + $bbox_ml + $bbox_bl + $bbox_pl; + $w = $cont_w - ($bbox_left + $bbox_ml + $bbox_mr + $bbox_bl + $bbox_br + $bbox_pl + $bbox_pr); + } + + $bbox_y = $cont_y + $bbox_top + $bbox_mt; + $bbox_x = $cont_x + $bbox_left + $bbox_ml; + + $saved_block1 = $this->blk[1]; + + unset($p); + unset($pb); + + // ================================================================ + if ($inner_w === 'auto') { // do a first write + $this->lMargin = $x; + $this->rMargin = $this->w - $w - $x; + + // SET POSITION & FONT VALUES + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->pageoutput[$this->page] = []; + $this->x = $x; + $this->y = $y; + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + $this->pageBackgrounds = []; + $this->maxPosR = 0; + $this->maxPosL = $this->w; // For RTL + $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER); + $inner_w = $this->maxPosR - $this->lMargin; + if ($bbox_right_auto) { + $bbox_right = $cont_w - $bbox_left - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml; + } elseif ($bbox_left_auto) { + $bbox_left = $cont_w - $bbox_ml - $bbox_bl - $bbox_pl - $inner_w - $bbox_pr - $bbox_br - $bbox_ml - $bbox_right; + $bbox_x = $cont_x + $bbox_left + $bbox_ml; + $inner_x = $bbox_x + $bbox_bl + $bbox_pl; + $x = $inner_x; + } + + $w = $inner_w; + $bbox_y = $cont_y + $bbox_top + $bbox_mt; + $bbox_x = $cont_x + $bbox_left + $bbox_ml; + } + + if ($inner_h === 'auto') { // do a first write + + $this->lMargin = $x; + $this->rMargin = $this->w - $w - $x; + + // SET POSITION & FONT VALUES + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->pageoutput[$this->page] = []; + $this->x = $x; + $this->y = $y; + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + $this->pageBackgrounds = []; + $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER); + $inner_h = $this->y - $y; + + if ($overflow != 'hidden' && $overflow != 'visible') { // constrained + if (($this->y + $bbox_pb + $bbox_bb) > ($cont_y + $cont_h)) { + $adj = ($this->y + $bbox_pb + $bbox_bb) - ($cont_y + $cont_h); + $inner_h -= $adj; + } + } + if ($bbox_bottom_auto && $bbox_top_orig === 'auto') { + $bbox_bottom = $bbox_top = ($cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb) / 2; + if ($overflow != 'hidden' && $overflow != 'visible') { // constrained + if ($bbox_top < 0) { + $bbox_top = 0; + $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom; + } + } + $bbox_y = $cont_y + $bbox_top + $bbox_mt; + $inner_y = $bbox_y + $bbox_bt + $bbox_pt; + $y = $inner_y; + } elseif ($bbox_bottom_auto) { + $bbox_bottom = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb; + } elseif ($bbox_top_auto) { + $bbox_top = $cont_h - $bbox_mt - $bbox_bt - $bbox_pt - $inner_h - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom; + if ($overflow != 'hidden' && $overflow != 'visible') { // constrained + if ($bbox_top < 0) { + $bbox_top = 0; + $inner_h = $cont_h - $bbox_top - $bbox_mt - $bbox_bt - $bbox_pt - $bbox_pb - $bbox_bb - $bbox_mb - $bbox_bottom; + } + } + $bbox_y = $cont_y + $bbox_top + $bbox_mt; + $inner_y = $bbox_y + $bbox_bt + $bbox_pt; + $y = $inner_y; + } + $h = $inner_h; + $bbox_y = $cont_y + $bbox_top + $bbox_mt; + $bbox_x = $cont_x + $bbox_left + $bbox_ml; + } + + $inner_w = $w; + $inner_h = $h; + } + + $this->lMargin = $x; + $this->rMargin = $this->w - $w - $x; + + // SET POSITION & FONT VALUES + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->pageoutput[$this->page] = []; + + $this->x = $x; + $this->y = $y; + + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + + $this->pageBackgrounds = []; + + $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER); + + $actual_h = $this->y - $y; + $use_w = $w; + $use_h = $h; + $ratio = $actual_h / $use_w; + + if ($overflow != 'hidden' && $overflow != 'visible') { + $target = $h / $w; + if ($target > 0) { + if (($ratio / $target) > 1) { + $nl = ceil($actual_h / $this->lineheight); + $l = $use_w * $nl; + $est_w = sqrt(($l * $this->lineheight) / $target) * 0.8; + $use_w += ($est_w - $use_w) - ($w / 100); + } + $bpcstart = ($ratio / $target); + $bpcctr = 1; + + while (($ratio / $target) > 1) { + // @log 'Auto-sizing fixed-position block $bpcctr++ + + $this->x = $x; + $this->y = $y; + + if (($ratio / $target) > 1.5 || ($ratio / $target) < 0.6) { + $use_w += ($w / $this->incrementFPR1); + } elseif (($ratio / $target) > 1.2 || ($ratio / $target) < 0.85) { + $use_w += ($w / $this->incrementFPR2); + } elseif (($ratio / $target) > 1.1 || ($ratio / $target) < 0.91) { + $use_w += ($w / $this->incrementFPR3); + } else { + $use_w += ($w / $this->incrementFPR4); + } + + $use_h = $use_w * $target; + $this->rMargin = $this->w - $use_w - $x; + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + $this->pageBackgrounds = []; + $this->WriteHTML($html, HTMLParserMode::HTML_HEADER_BUFFER); + $actual_h = $this->y - $y; + $ratio = $actual_h / $use_w; + } + } + } + + $shrink_f = $w / $use_w; + + // ================================================================ + + $this->pages[$this->page] .= '___BEFORE_BORDERS___'; + $block_s = $this->PrintPageBackgrounds(); // Save to print later inside clipping path + $this->pageBackgrounds = []; + + // ================================================================ + + if ($rotate == 90 || $rotate == -90) { // mPDF 6 + $prerotw = $bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br; + $preroth = $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb; + $rot_start = " q\n"; + if ($rotate == 90) { + if ($rot_rpos !== false) { + $adjw = $prerotw; + } // width before rotation + else { + $adjw = $preroth; + } // height before rotation + if ($rot_bpos !== false) { + $adjh = -$prerotw + $preroth; + } else { + $adjh = 0; + } + } else { + if ($rot_rpos !== false) { + $adjw = $prerotw - $preroth; + } else { + $adjw = 0; + } + if ($rot_bpos !== false) { + $adjh = $preroth; + } // height before rotation + else { + $adjh = $prerotw; + } // width before rotation + } + $rot_start .= $this->transformTranslate($adjw, $adjh, true) . "\n"; + $rot_start .= $this->transformRotate($rotate, $bbox_x, $bbox_y, true) . "\n"; + $rot_end = " Q\n"; + } elseif ($rotate == 180) { // mPDF 6 + $rot_start = " q\n"; + $rot_start .= $this->transformTranslate($bbox_bl + $bbox_pl + $inner_w + $bbox_pr + $bbox_br, $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb, true) . "\n"; + $rot_start .= $this->transformRotate(180, $bbox_x, $bbox_y, true) . "\n"; + $rot_end = " Q\n"; + } else { + $rot_start = ''; + $rot_end = ''; + } + + // ================================================================ + if (!empty($bounding)) { + // WHEN HEIGHT // BOTTOM EDGE IS KNOWN and $this->y is set to the bottom + // Re-instate saved $this->blk[1] + $this->blk[1] = $saved_block1; + + // These are only needed when painting border/background + $this->blk[1]['width'] = $bbox_w = $cont_w - $bbox_left - $bbox_ml - $bbox_mr - $bbox_right; + $this->blk[1]['x0'] = $bbox_x; + $this->blk[1]['y0'] = $bbox_y; + $this->blk[1]['startpage'] = $this->page; + $this->blk[1]['y1'] = $bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb; + $this->writer->write($rot_start); + $this->PaintDivBB('', 0, 1); // Prints borders and sets backgrounds in $this->pageBackgrounds + $this->writer->write($rot_end); + } + + $s = $this->PrintPageBackgrounds(); + $s = $rot_start . $s . $rot_end; + $this->pages[$this->page] = preg_replace('/___BEFORE_BORDERS___/', "\n" . $s . "\n", $this->pages[$this->page]); + $this->pageBackgrounds = []; + + $this->writer->write($rot_start); + + // Clipping Output + if ($overflow == 'hidden') { + // Bounding rectangle to clip + $clip_y1 = $this->y; + if (!empty($bounding) && ($this->y + $bbox_pb + $bbox_bb) > ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb )) { + $clip_y1 = ($bbox_y + $bbox_bt + $bbox_pt + $inner_h + $bbox_pb + $bbox_bb ) - ($bbox_pb + $bbox_bb); + } + // $op = 'W* n'; // Clipping + $op = 'W n'; // Clipping alternative mode + $this->writer->write("q"); + $ch = $clip_y1 - $y; + $this->writer->write(sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op)); + if (!empty($block_s)) { + $tmp = "q\n" . sprintf('%.3F %.3F %.3F %.3F re %s', $x * Mpdf::SCALE, ($this->h - $y) * Mpdf::SCALE, $w * Mpdf::SCALE, -$ch * Mpdf::SCALE, $op); + $tmp .= "\n" . $block_s . "\nQ"; + $block_s = $tmp; + } + } + + + if (!empty($block_s)) { + if ($shrink_f != 1) { // i.e. autofit has resized the box + $tmp = "q\n" . $this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y, true); + $tmp .= "\n" . $block_s . "\nQ"; + $block_s = $tmp; + } + $this->writer->write($block_s); + } + + + + if ($shrink_f != 1) { // i.e. autofit has resized the box + $this->StartTransform(); + $this->transformScale(($shrink_f * 100), ($shrink_f * 100), $x, $y); + } + + $this->writer->write($this->headerbuffer); + + if ($shrink_f != 1) { // i.e. autofit has resized the box + $this->StopTransform(); + } + + if ($overflow == 'hidden') { + // End clipping + $this->writer->write("Q"); + } + + $this->writer->write($rot_end); + + + // Page Links + foreach ($this->HTMLheaderPageLinks as $lk) { + if ($rotate) { + $tmp = $lk[2]; // Switch h - w + $lk[2] = $lk[3]; + $lk[3] = $tmp; + + $lx1 = (($lk[0] / Mpdf::SCALE)); + $ly1 = (($this->h - ($lk[1] / Mpdf::SCALE))); + if ($rotate == 90) { + $adjx = -($lx1 - $bbox_x) + ($preroth - ($ly1 - $bbox_y)); + $adjy = -($ly1 - $bbox_y) + ($lx1 - $bbox_x); + $lk[2] = -$lk[2]; + } elseif ($rotate == -90) { + $adjx = -($lx1 - $bbox_x) + ($ly1 - $bbox_y); + $adjy = -($ly1 - $bbox_y) - ($lx1 - $bbox_x) + $prerotw; + $lk[3] = -$lk[3]; + } + if ($rot_rpos !== false) { + $adjx += $prerotw - $preroth; + } + if ($rot_bpos !== false) { + $adjy += $preroth - $prerotw; + } + $lx1 += $adjx; + $ly1 += $adjy; + + $lk[0] = $lx1 * Mpdf::SCALE; + $lk[1] = ($this->h - $ly1) * Mpdf::SCALE; + } + if ($shrink_f != 1) { // i.e. autofit has resized the box + $lx1 = (($lk[0] / Mpdf::SCALE) - $x); + $lx2 = $x + ($lx1 * $shrink_f); + $lk[0] = $lx2 * Mpdf::SCALE; + $ly1 = (($this->h - ($lk[1] / Mpdf::SCALE)) - $y); + $ly2 = $y + ($ly1 * $shrink_f); + $lk[1] = ($this->h - $ly2) * Mpdf::SCALE; + $lk[2] *= $shrink_f; // width + $lk[3] *= $shrink_f; // height + } + $this->PageLinks[$this->page][] = $lk; + } + + foreach ($this->HTMLheaderPageForms as $n => $f) { + if ($shrink_f != 1) { // i.e. autofit has resized the box + $f['x'] = $x + (($f['x'] - $x) * $shrink_f); + $f['y'] = $y + (($f['y'] - $y) * $shrink_f); + $f['w'] *= $shrink_f; + $f['h'] *= $shrink_f; + $f['style']['fontsize'] *= $shrink_f; + } + $this->form->forms[$f['n']] = $f; + } + // Page Annotations + foreach ($this->HTMLheaderPageAnnots as $lk) { + if ($rotate) { + if ($rotate == 90) { + $adjx = -($lk['x'] - $bbox_x) + ($preroth - ($lk['y'] - $bbox_y)); + $adjy = -($lk['y'] - $bbox_y) + ($lk['x'] - $bbox_x); + } elseif ($rotate == -90) { + $adjx = -($lk['x'] - $bbox_x) + ($lk['y'] - $bbox_y); + $adjy = -($lk['y'] - $bbox_y) - ($lk['x'] - $bbox_x) + $prerotw; + } + if ($rot_rpos !== false) { + $adjx += $prerotw - $preroth; + } + if ($rot_bpos !== false) { + $adjy += $preroth - $prerotw; + } + $lk['x'] += $adjx; + $lk['y'] += $adjy; + } + if ($shrink_f != 1) { // i.e. autofit has resized the box + $lk['x'] = $x + (($lk['x'] - $x) * $shrink_f); + $lk['y'] = $y + (($lk['y'] - $y) * $shrink_f); + } + $this->PageAnnots[$this->page][] = $lk; + } + + // Restore + $this->headerbuffer = ''; + $this->HTMLheaderPageLinks = []; + $this->HTMLheaderPageAnnots = []; + $this->HTMLheaderPageForms = []; + $this->pageBackgrounds = $save_bgs; + $this->writingHTMLheader = false; + + $this->writingHTMLfooter = false; + $this->fullImageHeight = false; + $this->ResetMargins(); + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->SetXY($save_x, $save_y); + $this->title2annots = $save_annots; // *ANNOTATIONS* + $this->InFooter = false; // turns back on autopagebreaks + $this->pageoutput[$this->page] = []; + $this->pageoutput[$this->page]['Font'] = ''; + /* -- COLUMNS -- */ + if ($save_cols) { + $this->SetColumns($save_nbcol, $this->colvAlign, $this->ColGap); + } + /* -- END COLUMNS -- */ + } + + /* -- END CSS-POSITION -- */ + + function initialiseBlock(&$blk) + { + $blk['margin_top'] = 0; + $blk['margin_left'] = 0; + $blk['margin_bottom'] = 0; + $blk['margin_right'] = 0; + $blk['padding_top'] = 0; + $blk['padding_left'] = 0; + $blk['padding_bottom'] = 0; + $blk['padding_right'] = 0; + $blk['border_top']['w'] = 0; + $blk['border_left']['w'] = 0; + $blk['border_bottom']['w'] = 0; + $blk['border_right']['w'] = 0; + $blk['direction'] = 'ltr'; + $blk['hide'] = false; + $blk['outer_left_margin'] = 0; + $blk['outer_right_margin'] = 0; + $blk['cascadeCSS'] = []; + $blk['block-align'] = false; + $blk['bgcolor'] = false; + $blk['page_break_after_avoid'] = false; + $blk['keep_block_together'] = false; + $blk['float'] = false; + $blk['line_height'] = ''; + $blk['margin_collapse'] = false; + } + + function border_details($bd) + { + $prop = preg_split('/\s+/', trim($bd)); + + if (isset($this->blk[$this->blklvl]['inner_width'])) { + $refw = $this->blk[$this->blklvl]['inner_width']; + } elseif (isset($this->blk[$this->blklvl - 1]['inner_width'])) { + $refw = $this->blk[$this->blklvl - 1]['inner_width']; + } else { + $refw = $this->w; + } + if (count($prop) == 1) { + $bsize = $this->sizeConverter->convert($prop[0], $refw, $this->FontSize, false); + if ($bsize > 0) { + return ['s' => 1, 'w' => $bsize, 'c' => $this->colorConverter->convert(0, $this->PDFAXwarnings), 'style' => 'solid']; + } else { + return ['w' => 0, 's' => 0]; + } + } elseif (count($prop) == 2) { + // 1px solid + if (in_array($prop[1], $this->borderstyles) || $prop[1] == 'none' || $prop[1] == 'hidden') { + $prop[2] = ''; + } // solid #000000 + elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') { + $prop[0] = ''; + $prop[1] = $prop[0]; + $prop[2] = $prop[1]; + } // 1px #000000 + else { + $prop[1] = ''; + $prop[2] = $prop[1]; + } + } elseif (count($prop) == 3) { + // Change #000000 1px solid to 1px solid #000000 (proper) + if (substr($prop[0], 0, 1) == '#') { + $tmp = $prop[0]; + $prop[0] = $prop[1]; + $prop[1] = $prop[2]; + $prop[2] = $tmp; + } // Change solid #000000 1px to 1px solid #000000 (proper) + elseif (substr($prop[0], 1, 1) == '#') { + $tmp = $prop[1]; + $prop[0] = $prop[2]; + $prop[1] = $prop[0]; + $prop[2] = $tmp; + } // Change solid 1px #000000 to 1px solid #000000 (proper) + elseif (in_array($prop[0], $this->borderstyles) || $prop[0] == 'none' || $prop[0] == 'hidden') { + $tmp = $prop[0]; + $prop[0] = $prop[1]; + $prop[1] = $tmp; + } + } else { + return []; + } + // Size + $bsize = $this->sizeConverter->convert($prop[0], $refw, $this->FontSize, false); + // color + $coul = $this->colorConverter->convert($prop[2], $this->PDFAXwarnings); // returns array + // Style + $prop[1] = strtolower($prop[1]); + if (in_array($prop[1], $this->borderstyles) && $bsize > 0) { + $on = 1; + } elseif ($prop[1] == 'hidden') { + $on = 1; + $bsize = 0; + $coul = ''; + } elseif ($prop[1] == 'none') { + $on = 0; + $bsize = 0; + $coul = ''; + } else { + $on = 0; + $bsize = 0; + $coul = ''; + $prop[1] = ''; + } + return ['s' => $on, 'w' => $bsize, 'c' => $coul, 'style' => $prop[1], 'dom' => 0]; + } + + /* -- END HTML-CSS -- */ + + + /* -- BORDER-RADIUS -- */ + + function _borderPadding($a, $b, &$px, &$py) + { + // $px and py are padding long axis (x) and short axis (y) + $added = 0; // extra padding + + $x = $a - $px; + $y = $b - $py; + // Check if Falls within ellipse of border radius + if (( (($x + $added) * ($x + $added)) / ($a * $a) + (($y + $added) * ($y + $added)) / ($b * $b) ) <= 1) { + return false; + } + + $t = atan2($y, $x); + + $newx = $b / sqrt((($b * $b) / ($a * $a)) + ( tan($t) * tan($t) )); + $newy = $a / sqrt((($a * $a) / ($b * $b)) + ( (1 / tan($t)) * (1 / tan($t)) )); + $px = max($px, $a - $newx + $added); + $py = max($py, $b - $newy + $added); + } + + /* -- END BORDER-RADIUS -- */ + /* -- HTML-CSS -- */ + /* -- CSS-PAGE -- */ + + function SetPagedMediaCSS($name, $first, $oddEven) + { + if ($oddEven == 'E') { + if ($this->directionality == 'rtl') { + $side = 'R'; + } else { + $side = 'L'; + } + } else { + if ($this->directionality == 'rtl') { + $side = 'L'; + } else { + $side = 'R'; + } + } + $name = strtoupper($name); + $p = []; + $p['SIZE'] = 'AUTO'; + + // Uses mPDF original margins as default + $p['MARGIN-RIGHT'] = strval($this->orig_rMargin) . 'mm'; + $p['MARGIN-LEFT'] = strval($this->orig_lMargin) . 'mm'; + $p['MARGIN-TOP'] = strval($this->orig_tMargin) . 'mm'; + $p['MARGIN-BOTTOM'] = strval($this->orig_bMargin) . 'mm'; + $p['MARGIN-HEADER'] = strval($this->orig_hMargin) . 'mm'; + $p['MARGIN-FOOTER'] = strval($this->orig_fMargin) . 'mm'; + + // Basic page + selector + if (isset($this->cssManager->CSS['@PAGE'])) { + $zp = $this->cssManager->CSS['@PAGE']; + } else { + $zp = []; + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') { + $p['HEADER'] = $p['EVEN-HEADER-NAME']; + unset($p['EVEN-HEADER-NAME']); + } + if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') { + $p['HEADER'] = $p['ODD-HEADER-NAME']; + unset($p['ODD-HEADER-NAME']); + } + if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') { + $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; + unset($p['EVEN-FOOTER-NAME']); + } + if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') { + $p['FOOTER'] = $p['ODD-FOOTER-NAME']; + unset($p['ODD-FOOTER-NAME']); + } + + // If right/Odd page + if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT']) && $side == 'R') { + $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>RIGHT']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :LEFT or :RIGHT + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + // If left/Even page + if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT']) && $side == 'L') { + $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>LEFT']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :LEFT or :RIGHT + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + // If first page + if (isset($this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']) && $first) { + $zp = $this->cssManager->CSS['@PAGE>>PSEUDO>>FIRST']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :FIRST // mPDF 5.7.3 + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + // If named page + if ($name) { + if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name])) { + $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name]; + } else { + $zp = []; + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + if (isset($p['EVEN-HEADER-NAME']) && $oddEven == 'E') { + $p['HEADER'] = $p['EVEN-HEADER-NAME']; + unset($p['EVEN-HEADER-NAME']); + } + if (isset($p['ODD-HEADER-NAME']) && $oddEven != 'E') { + $p['HEADER'] = $p['ODD-HEADER-NAME']; + unset($p['ODD-HEADER-NAME']); + } + if (isset($p['EVEN-FOOTER-NAME']) && $oddEven == 'E') { + $p['FOOTER'] = $p['EVEN-FOOTER-NAME']; + unset($p['EVEN-FOOTER-NAME']); + } + if (isset($p['ODD-FOOTER-NAME']) && $oddEven != 'E') { + $p['FOOTER'] = $p['ODD-FOOTER-NAME']; + unset($p['ODD-FOOTER-NAME']); + } + + // If named right/Odd page + if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>RIGHT']) && $side == 'R') { + $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>RIGHT']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :LEFT or :RIGHT + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + // If named left/Even page + if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>LEFT']) && $side == 'L') { + $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>LEFT']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :LEFT or :RIGHT + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + + // If named first page + if (isset($this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>FIRST']) && $first) { + $zp = $this->cssManager->CSS['@PAGE>>NAMED>>' . $name . '>>PSEUDO>>FIRST']; + } else { + $zp = []; + } + if (isset($zp['SIZE'])) { + unset($zp['SIZE']); + } + if (isset($zp['SHEET-SIZE'])) { + unset($zp['SHEET-SIZE']); + } + // Disallow margin-left or -right on :FIRST // mPDF 5.7.3 + if (isset($zp['MARGIN-LEFT'])) { + unset($zp['MARGIN-LEFT']); + } + if (isset($zp['MARGIN-RIGHT'])) { + unset($zp['MARGIN-RIGHT']); + } + if (is_array($zp) && !empty($zp)) { + $p = array_merge($p, $zp); + } + } + + $orientation = $mgl = $mgr = $mgt = $mgb = $mgh = $mgf = ''; + $header = $footer = ''; + $resetpagenum = $pagenumstyle = $suppress = ''; + $marks = ''; + $bg = []; + + $newformat = ''; + + + if (isset($p['SHEET-SIZE']) && is_array($p['SHEET-SIZE'])) { + $newformat = $p['SHEET-SIZE']; + if ($newformat[0] > $newformat[1]) { // landscape + $newformat = array_reverse($newformat); + $p['ORIENTATION'] = 'L'; + } else { + $p['ORIENTATION'] = 'P'; + } + $this->_setPageSize($newformat, $p['ORIENTATION']); + } + + if (isset($p['SIZE']) && is_array($p['SIZE']) && !$newformat) { + if ($p['SIZE']['W'] > $p['SIZE']['H']) { + $p['ORIENTATION'] = 'L'; + } else { + $p['ORIENTATION'] = 'P'; + } + } + if (is_array($p['SIZE'])) { + if ($p['SIZE']['W'] > $this->fw) { + $p['SIZE']['W'] = $this->fw; + } // mPD 4.2 use fw not fPt + if ($p['SIZE']['H'] > $this->fh) { + $p['SIZE']['H'] = $this->fh; + } + if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) { + $outer_width_LR = ($this->fw - $p['SIZE']['W']) / 2; + $outer_width_TB = ($this->fh - $p['SIZE']['H']) / 2; + } else { + $outer_width_LR = ($this->fh - $p['SIZE']['W']) / 2; + $outer_width_TB = ($this->fw - $p['SIZE']['H']) / 2; + } + $pgw = $p['SIZE']['W']; + $pgh = $p['SIZE']['H']; + } else { // AUTO LANDSCAPE PORTRAIT + $outer_width_LR = 0; + $outer_width_TB = 0; + if (!$newformat) { + if (strtoupper($p['SIZE']) == 'AUTO') { + $p['ORIENTATION'] = $this->DefOrientation; + } elseif (strtoupper($p['SIZE']) == 'LANDSCAPE') { + $p['ORIENTATION'] = 'L'; + } else { + $p['ORIENTATION'] = 'P'; + } + } + if (($p['ORIENTATION'] == $this->DefOrientation && !$newformat) || ($newformat && $p['ORIENTATION'] == 'P')) { + $pgw = $this->fw; + $pgh = $this->fh; + } else { + $pgw = $this->fh; + $pgh = $this->fw; + } + } + + if (isset($p['HEADER']) && $p['HEADER']) { + $header = $p['HEADER']; + } + if (isset($p['FOOTER']) && $p['FOOTER']) { + $footer = $p['FOOTER']; + } + if (isset($p['RESETPAGENUM']) && $p['RESETPAGENUM']) { + $resetpagenum = $p['RESETPAGENUM']; + } + if (isset($p['PAGENUMSTYLE']) && $p['PAGENUMSTYLE']) { + $pagenumstyle = $p['PAGENUMSTYLE']; + } + if (isset($p['SUPPRESS']) && $p['SUPPRESS']) { + $suppress = $p['SUPPRESS']; + } + + if (isset($p['MARKS'])) { + if (preg_match('/cross/i', $p['MARKS']) && preg_match('/crop/i', $p['MARKS'])) { + $marks = 'CROPCROSS'; + } elseif (strtoupper($p['MARKS']) == 'CROP') { + $marks = 'CROP'; + } elseif (strtoupper($p['MARKS']) == 'CROSS') { + $marks = 'CROSS'; + } + } + + if (isset($p['BACKGROUND-COLOR']) && $p['BACKGROUND-COLOR']) { + $bg['BACKGROUND-COLOR'] = $p['BACKGROUND-COLOR']; + } + /* -- BACKGROUNDS -- */ + if (isset($p['BACKGROUND-GRADIENT']) && $p['BACKGROUND-GRADIENT']) { + $bg['BACKGROUND-GRADIENT'] = $p['BACKGROUND-GRADIENT']; + } + if (isset($p['BACKGROUND-IMAGE']) && $p['BACKGROUND-IMAGE']) { + $bg['BACKGROUND-IMAGE'] = $p['BACKGROUND-IMAGE']; + } + if (isset($p['BACKGROUND-REPEAT']) && $p['BACKGROUND-REPEAT']) { + $bg['BACKGROUND-REPEAT'] = $p['BACKGROUND-REPEAT']; + } + if (isset($p['BACKGROUND-POSITION']) && $p['BACKGROUND-POSITION']) { + $bg['BACKGROUND-POSITION'] = $p['BACKGROUND-POSITION']; + } + if (isset($p['BACKGROUND-IMAGE-RESIZE']) && $p['BACKGROUND-IMAGE-RESIZE']) { + $bg['BACKGROUND-IMAGE-RESIZE'] = $p['BACKGROUND-IMAGE-RESIZE']; + } + if (isset($p['BACKGROUND-IMAGE-OPACITY'])) { + $bg['BACKGROUND-IMAGE-OPACITY'] = $p['BACKGROUND-IMAGE-OPACITY']; + } + /* -- END BACKGROUNDS -- */ + + if (isset($p['MARGIN-LEFT'])) { + $mgl = $this->sizeConverter->convert($p['MARGIN-LEFT'], $pgw) + $outer_width_LR; + } + if (isset($p['MARGIN-RIGHT'])) { + $mgr = $this->sizeConverter->convert($p['MARGIN-RIGHT'], $pgw) + $outer_width_LR; + } + if (isset($p['MARGIN-BOTTOM'])) { + $mgb = $this->sizeConverter->convert($p['MARGIN-BOTTOM'], $pgh) + $outer_width_TB; + } + if (isset($p['MARGIN-TOP'])) { + $mgt = $this->sizeConverter->convert($p['MARGIN-TOP'], $pgh) + $outer_width_TB; + } + if (isset($p['MARGIN-HEADER'])) { + $mgh = $this->sizeConverter->convert($p['MARGIN-HEADER'], $pgh) + $outer_width_TB; + } + if (isset($p['MARGIN-FOOTER'])) { + $mgf = $this->sizeConverter->convert($p['MARGIN-FOOTER'], $pgh) + $outer_width_TB; + } + + if (isset($p['ORIENTATION']) && $p['ORIENTATION']) { + $orientation = $p['ORIENTATION']; + } + $this->page_box['outer_width_LR'] = $outer_width_LR; // Used in MARKS:crop etc. + $this->page_box['outer_width_TB'] = $outer_width_TB; + + return [$orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $header, $footer, $bg, $resetpagenum, $pagenumstyle, $suppress, $marks, $newformat]; + } + + /* -- END CSS-PAGE -- */ + + + + /* -- CSS-FLOAT -- */ + + // Added mPDF 3.0 Float DIV - CLEAR + function ClearFloats($clear, $blklvl = 0) + { + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($blklvl, true); + $end = $currpos = ($this->page * 1000 + $this->y); + if ($clear == 'BOTH' && ($l_exists || $r_exists)) { + $this->pageoutput[$this->page] = []; + $end = max($l_max, $r_max, $currpos); + } elseif ($clear == 'RIGHT' && $r_exists) { + $this->pageoutput[$this->page] = []; + $end = max($r_max, $currpos); + } elseif ($clear == 'LEFT' && $l_exists) { + $this->pageoutput[$this->page] = []; + $end = max($l_max, $currpos); + } else { + return; + } + $old_page = $this->page; + $new_page = intval($end / 1000); + if ($old_page != $new_page) { + $s = $this->PrintPageBackgrounds(); + // Writes after the marker so not overwritten later by page background etc. + $this->pages[$this->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]); + $this->pageBackgrounds = []; + $this->page = $new_page; + } + $this->ResetMargins(); + $this->pageoutput[$this->page] = []; + $this->y = (($end * 1000) % 1000000) / 1000; // mod changes operands to integers before processing + } + + // Added mPDF 3.0 Float DIV + function GetFloatDivInfo($blklvl = 0, $clear = false) + { + // If blklvl specified, only returns floats at that level - for ClearFloats + $l_exists = false; + $r_exists = false; + $l_max = 0; + $r_max = 0; + $l_width = 0; + $r_width = 0; + if (count($this->floatDivs)) { + $currpos = ($this->page * 1000 + $this->y); + foreach ($this->floatDivs as $f) { + if (($clear && $f['blockContext'] == $this->blk[$blklvl]['blockContext']) || (!$clear && $currpos >= $f['startpos'] && $currpos < ($f['endpos'] - 0.001) && $f['blklvl'] > $blklvl && $f['blockContext'] == $this->blk[$blklvl]['blockContext'])) { + if ($f['side'] == 'L') { + $l_exists = true; + $l_max = max($l_max, $f['endpos']); + $l_width = max($l_width, $f['w']); + } + if ($f['side'] == 'R') { + $r_exists = true; + $r_max = max($r_max, $f['endpos']); + $r_width = max($r_width, $f['w']); + } + } + } + } + return [$l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width]; + } + + /* -- END CSS-FLOAT -- */ + + // LIST MARKERS // mPDF 6 Lists + function _setListMarker($listitemtype, $listitemimage, $listitemposition) + { + // if position:inside (and NOT table) - output now as a textbuffer; (so if next is block, will move to new line) + // elseif position:outside (and NOT table) - output in front of first textbuffer output by setting listitem (cf. _saveTextBuffer) + $e = ''; + $this->listitem = ''; + $spacer = ' '; + // IMAGE + if ($listitemimage && $listitemimage != 'none') { + $listitemimage = trim(preg_replace('/url\(["\']*(.*?)["\']*\)/', '\\1', $listitemimage)); + + // ? Restrict maximum height/width of list marker?? + $maxWidth = 100; + $maxHeight = 100; + + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['visibility'] = 'visible'; + $srcpath = $listitemimage; + $orig_srcpath = $listitemimage; + + $objattr['vertical-align'] = 'BS'; // vertical alignment of marker (baseline) + $w = 0; + $h = 0; + + // Image file + $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath); + if (!$info) { + return; + } + + if ($info['w'] == 0 && $info['h'] == 0) { + $info['h'] = $this->sizeConverter->convert('1em', $this->blk[$this->blklvl]['inner_width'], $this->FontSize, false); + } + + $objattr['file'] = $srcpath; + + // Default width and height calculation if needed + if ($w == 0 and $h == 0) { + /* -- IMAGES-WMF -- */ + if ($info['type'] == 'wmf') { + // WMF units are twips (1/20pt) + // divide by 20 to get points + // divide by k to get user units + $w = abs($info['w']) / (20 * Mpdf::SCALE); + $h = abs($info['h']) / (20 * Mpdf::SCALE); + } else { /* -- END IMAGES-WMF -- */ + if ($info['type'] == 'svg') { + // SVG units are pixels + $w = abs($info['w']) / Mpdf::SCALE; + $h = abs($info['h']) / Mpdf::SCALE; + } else { + // Put image at default image dpi + $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->img_dpi); + $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->img_dpi); + } + } + } + // IF WIDTH OR HEIGHT SPECIFIED + if ($w == 0) { + $w = abs($h * $info['w'] / $info['h']); + } + if ($h == 0) { + $h = abs($w * $info['h'] / $info['w']); + } + + if ($w > $maxWidth) { + $w = $maxWidth; + $h = abs($w * $info['h'] / $info['w']); + } + + if ($h > $maxHeight) { + $h = $maxHeight; + $w = abs($h * $info['w'] / $info['h']); + } + + $objattr['type'] = 'image'; + $objattr['itype'] = $info['type']; + + $objattr['orig_h'] = $info['h']; + $objattr['orig_w'] = $info['w']; + + /* -- IMAGES-WMF -- */ + if ($info['type'] == 'wmf') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + } else { /* -- END IMAGES-WMF -- */ + if ($info['type'] == 'svg') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + } + } + + $objattr['height'] = $h; + $objattr['width'] = $w; + $objattr['image_height'] = $h; + $objattr['image_width'] = $w; + + $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'); + $objattr['listmarker'] = true; + + $objattr['listmarkerposition'] = $listitemposition; + + $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + $this->_saveTextBuffer($e); + + if ($listitemposition == 'inside') { + $e = $spacer; + $this->_saveTextBuffer($e); + } + } elseif ($listitemtype == 'disc' || $listitemtype == 'circle' || $listitemtype == 'square') { // SYMBOL (needs new font) + $objattr = []; + $objattr['type'] = 'listmarker'; + $objattr['listmarkerposition'] = $listitemposition; + $objattr['width'] = 0; + $size = $this->sizeConverter->convert($this->list_symbol_size, $this->FontSize); + $objattr['size'] = $size; + $objattr['offset'] = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize); + + if ($listitemposition == 'inside') { + $objattr['width'] = $size + $objattr['offset']; + } + + $objattr['height'] = $this->FontSize; + $objattr['vertical-align'] = 'T'; + $objattr['text'] = ''; + $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'); + $objattr['bullet'] = $listitemtype; + $objattr['colorarray'] = $this->colorarray; + $objattr['fontfamily'] = $this->FontFamily; + $objattr['fontsize'] = $this->FontSize; + $objattr['fontsizept'] = $this->FontSizePt; + $objattr['fontstyle'] = $this->FontStyle; + + $e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array + + } elseif (preg_match('/U\+([a-fA-F0-9]+)/i', $listitemtype, $m)) { // SYMBOL 2 (needs new font) + + if ($this->_charDefined($this->CurrentFont['cw'], hexdec($m[1]))) { + $list_item_marker = UtfString::codeHex2utf($m[1]); + } else { + $list_item_marker = '-'; + } + if (preg_match('/rgb\(.*?\)/', $listitemtype, $m)) { + $list_item_color = $this->colorConverter->convert($m[0], $this->PDFAXwarnings); + } else { + $list_item_color = ''; + } + + // SAVE then SET COLR + $save_colorarray = $this->colorarray; + if ($list_item_color) { + $this->colorarray = $list_item_color; + } + + if ($listitemposition == 'inside') { + $e = $list_item_marker . $spacer; + $this->_saveTextBuffer($e); + } else { + $objattr = []; + $objattr['type'] = 'listmarker'; + $objattr['width'] = 0; + $objattr['height'] = $this->FontSize; + $objattr['vertical-align'] = 'T'; + $objattr['text'] = $list_item_marker; + $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'); + $objattr['colorarray'] = $this->colorarray; + $objattr['fontfamily'] = $this->FontFamily; + $objattr['fontsize'] = $this->FontSize; + $objattr['fontsizept'] = $this->FontSizePt; + $objattr['fontstyle'] = $this->FontStyle; + $e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array + } + + // RESET COLOR + $this->colorarray = $save_colorarray; + + } else { // TEXT + $counter = $this->listcounter[$this->listlvl]; + + if ($listitemtype == 'none') { + return; + } + + $num = $this->_getStyledNumber($counter, $listitemtype, true); + + if ($listitemposition == 'inside') { + $e = $num . $this->list_number_suffix . $spacer; + $this->_saveTextBuffer($e); + } else { + if (isset($this->blk[$this->blklvl]['direction']) && $this->blk[$this->blklvl]['direction'] == 'rtl') { + // REPLACE MIRRORED RTL $this->list_number_suffix e.g. ) -> ( (NB could use Ucdn::$mirror_pairs) + $m = strtr($this->list_number_suffix, ")]}", "([{") . $num; + } else { + $m = $num . $this->list_number_suffix; + } + + $objattr = []; + $objattr['type'] = 'listmarker'; + $objattr['width'] = 0; + $objattr['height'] = $this->FontSize; + $objattr['vertical-align'] = 'T'; + $objattr['text'] = $m; + $objattr['dir'] = (isset($this->blk[$this->blklvl]['direction']) ? $this->blk[$this->blklvl]['direction'] : 'ltr'); + $objattr['colorarray'] = $this->colorarray; + $objattr['fontfamily'] = $this->FontFamily; + $objattr['fontsize'] = $this->FontSize; + $objattr['fontsizept'] = $this->FontSizePt; + $objattr['fontstyle'] = $this->FontStyle; + $e = "\xbb\xa4\xactype=listmarker,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + $this->listitem = $this->_saveTextBuffer($e, '', '', true); // true returns array + } + } + } + + // mPDF Lists + function _getListMarkerWidth(&$currblk, &$a, &$i) + { + $blt_width = 0; + + $markeroffset = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize); + + // Get Maximum number in the list + $maxnum = $this->listcounter[$this->listlvl]; + if ($currblk['list_style_type'] != 'disc' && $currblk['list_style_type'] != 'circle' && $currblk['list_style_type'] != 'square') { + $lvl = 1; + for ($j = $i + 2; $j < count($a); $j+=2) { + $e = $a[$j]; + if (!$e) { + continue; + } + if ($e[0] == '/') { // end tag + $e = strtoupper(substr($e, 1)); + if ($e == 'OL' || $e == 'UL') { + if ($lvl == 1) { + break; + } + $lvl--; + } + } else { // opening tag + if (strpos($e, ' ')) { + $e = substr($e, 0, strpos($e, ' ')); + } + $e = strtoupper($e); + if ($e == 'LI') { + if ($lvl == 1) { + $maxnum++; + } + } elseif ($e == 'OL' || $e == 'UL') { + $lvl++; + } + } + } + } + + $decToAlpha = new Conversion\DecToAlpha(); + $decToRoman = new Conversion\DecToRoman(); + $decToOther = new Conversion\DecToOther($this); + + switch ($currblk['list_style_type']) { + case 'decimal': + case '1': + $blt_width = $this->GetStringWidth(str_repeat('5', strlen($maxnum)) . $this->list_number_suffix); + break; + case 'none': + $blt_width = 0; + break; + case 'upper-alpha': + case 'upper-latin': + case 'A': + $maxnumA = $decToAlpha->convert($maxnum, true); + if ($maxnum < 13) { + $blt_width = $this->GetStringWidth('D' . $this->list_number_suffix); + } else { + $blt_width = $this->GetStringWidth(str_repeat('W', strlen($maxnumA)) . $this->list_number_suffix); + } + break; + case 'lower-alpha': + case 'lower-latin': + case 'a': + $maxnuma = $decToAlpha->convert($maxnum, false); + if ($maxnum < 13) { + $blt_width = $this->GetStringWidth('b' . $this->list_number_suffix); + } else { + $blt_width = $this->GetStringWidth(str_repeat('m', strlen($maxnuma)) . $this->list_number_suffix); + } + break; + case 'upper-roman': + case 'I': + if ($maxnum > 87) { + $bbit = 87; + } elseif ($maxnum > 86) { + $bbit = 86; + } elseif ($maxnum > 37) { + $bbit = 38; + } elseif ($maxnum > 36) { + $bbit = 37; + } elseif ($maxnum > 27) { + $bbit = 28; + } elseif ($maxnum > 26) { + $bbit = 27; + } elseif ($maxnum > 17) { + $bbit = 18; + } elseif ($maxnum > 16) { + $bbit = 17; + } elseif ($maxnum > 7) { + $bbit = 8; + } elseif ($maxnum > 6) { + $bbit = 7; + } elseif ($maxnum > 3) { + $bbit = 4; + } else { + $bbit = $maxnum; + } + + $maxlnum = $decToRoman->convert($bbit, true); + $blt_width = $this->GetStringWidth($maxlnum . $this->list_number_suffix); + + break; + case 'lower-roman': + case 'i': + if ($maxnum > 87) { + $bbit = 87; + } elseif ($maxnum > 86) { + $bbit = 86; + } elseif ($maxnum > 37) { + $bbit = 38; + } elseif ($maxnum > 36) { + $bbit = 37; + } elseif ($maxnum > 27) { + $bbit = 28; + } elseif ($maxnum > 26) { + $bbit = 27; + } elseif ($maxnum > 17) { + $bbit = 18; + } elseif ($maxnum > 16) { + $bbit = 17; + } elseif ($maxnum > 7) { + $bbit = 8; + } elseif ($maxnum > 6) { + $bbit = 7; + } elseif ($maxnum > 3) { + $bbit = 4; + } else { + $bbit = $maxnum; + } + $maxlnum = $decToRoman->convert($bbit, false); + $blt_width = $this->GetStringWidth($maxlnum . $this->list_number_suffix); + break; + + case 'disc': + case 'circle': + case 'square': + $size = $this->sizeConverter->convert($this->list_symbol_size, $this->FontSize); + $offset = $this->sizeConverter->convert($this->list_marker_offset, $this->FontSize); + $blt_width = $size + $offset; + break; + + case 'arabic-indic': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0660), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'persian': + case 'urdu': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x06F0), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'bengali': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x09E6), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'devanagari': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0966), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'gujarati': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0AE6), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'gurmukhi': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0A66), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'kannada': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0CE6), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'malayalam': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(6, 0x0D66), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'oriya': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0B66), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'telugu': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(3, 0x0C66), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'tamil': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(9, 0x0BE6), strlen($maxnum)) . $this->list_number_suffix); + break; + case 'thai': + $blt_width = $this->GetStringWidth(str_repeat($decToOther->convert(5, 0x0E50), strlen($maxnum)) . $this->list_number_suffix); + break; + default: + $blt_width = $this->GetStringWidth(str_repeat('5', strlen($maxnum)) . $this->list_number_suffix); + break; + } + + return ($blt_width + $markeroffset); + } + + function _saveTextBuffer($t, $link = '', $intlink = '', $return = false) + { + // mPDF 6 Lists + $arr = []; + $arr[0] = $t; + if (isset($link) && $link) { + $arr[1] = $link; + } + $arr[2] = $this->currentfontstyle; + if (isset($this->colorarray) && $this->colorarray) { + $arr[3] = $this->colorarray; + } + $arr[4] = $this->currentfontfamily; + $arr[5] = $this->currentLang; // mPDF 6 + if (isset($intlink) && $intlink) { + $arr[7] = $intlink; + } + // mPDF 6 + // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script, + // set for kerning via kern table + // e.g. Latin script when useOTL set as 0x80 + if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) { + $this->textvar = ($this->textvar | TextVars::FC_KERNING); + } + $arr[8] = $this->textvar; // mPDF 5.7.1 + if (isset($this->textparam) && $this->textparam) { + $arr[9] = $this->textparam; + } + if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) { + $arr[10] = $this->spanbgcolorarray; + } + $arr[11] = $this->currentfontsize; + if (isset($this->ReqFontStyle) && $this->ReqFontStyle) { + $arr[12] = $this->ReqFontStyle; + } + if (isset($this->lSpacingCSS) && $this->lSpacingCSS) { + $arr[14] = $this->lSpacingCSS; + } + if (isset($this->wSpacingCSS) && $this->wSpacingCSS) { + $arr[15] = $this->wSpacingCSS; + } + if (isset($this->spanborddet) && $this->spanborddet) { + $arr[16] = $this->spanborddet; + } + if (isset($this->textshadow) && $this->textshadow) { + $arr[17] = $this->textshadow; + } + if (isset($this->OTLdata) && $this->OTLdata) { + $arr[18] = $this->OTLdata; + $this->OTLdata = []; + } // mPDF 5.7.1 + else { + $arr[18] = null; + } + // mPDF 6 Lists + if ($return) { + return ($arr); + } + if ($this->listitem) { + $this->textbuffer[] = $this->listitem; + $this->listitem = []; + } + $this->textbuffer[] = $arr; + } + + function _saveCellTextBuffer($t, $link = '', $intlink = '') + { + $arr = []; + $arr[0] = $t; + if (isset($link) && $link) { + $arr[1] = $link; + } + $arr[2] = $this->currentfontstyle; + if (isset($this->colorarray) && $this->colorarray) { + $arr[3] = $this->colorarray; + } + $arr[4] = $this->currentfontfamily; + if (isset($intlink) && $intlink) { + $arr[7] = $intlink; + } + // mPDF 6 + // If Kerning set for OTL, and useOTL has positive value, but has not set for this particular script, + // set for kerning via kern table + // e.g. Latin script when useOTL set as 0x80 + if (isset($this->OTLtags['Plus']) && strpos($this->OTLtags['Plus'], 'kern') !== false && empty($this->OTLdata['GPOSinfo'])) { + $this->textvar = ($this->textvar | TextVars::FC_KERNING); + } + $arr[8] = $this->textvar; // mPDF 5.7.1 + if (isset($this->textparam) && $this->textparam) { + $arr[9] = $this->textparam; + } + if (isset($this->spanbgcolorarray) && $this->spanbgcolorarray) { + $arr[10] = $this->spanbgcolorarray; + } + $arr[11] = $this->currentfontsize; + if (isset($this->ReqFontStyle) && $this->ReqFontStyle) { + $arr[12] = $this->ReqFontStyle; + } + if (isset($this->lSpacingCSS) && $this->lSpacingCSS) { + $arr[14] = $this->lSpacingCSS; + } + if (isset($this->wSpacingCSS) && $this->wSpacingCSS) { + $arr[15] = $this->wSpacingCSS; + } + if (isset($this->spanborddet) && $this->spanborddet) { + $arr[16] = $this->spanborddet; + } + if (isset($this->textshadow) && $this->textshadow) { + $arr[17] = $this->textshadow; + } + if (isset($this->OTLdata) && $this->OTLdata) { + $arr[18] = $this->OTLdata; + $this->OTLdata = []; + } // mPDF 5.7.1 + else { + $arr[18] = null; + } + $this->cell[$this->row][$this->col]['textbuffer'][] = $arr; + } + + function printbuffer($arrayaux, $blockstate = 0, $is_table = false, $table_draft = false, $cell_dir = '') + { + // $blockstate = 0; // NO margins/padding + // $blockstate = 1; // Top margins/padding only + // $blockstate = 2; // Bottom margins/padding only + // $blockstate = 3; // Top & bottom margins/padding + $this->spanbgcolorarray = ''; + $this->spanbgcolor = false; + $this->spanborder = false; + $this->spanborddet = []; + $paint_ht_corr = 0; + /* -- CSS-FLOAT -- */ + if (count($this->floatDivs)) { + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->GetFloatDivInfo($this->blklvl); + if (($this->blk[$this->blklvl]['inner_width'] - $l_width - $r_width) < (2 * $this->GetCharWidth('W', false))) { + // Too narrow to fit - try to move down past L or R float + if ($l_max < $r_max && ($this->blk[$this->blklvl]['inner_width'] - $r_width) > (2 * $this->GetCharWidth('W', false))) { + $this->ClearFloats('LEFT', $this->blklvl); + } elseif ($r_max < $l_max && ($this->blk[$this->blklvl]['inner_width'] - $l_width) > (2 * $this->GetCharWidth('W', false))) { + $this->ClearFloats('RIGHT', $this->blklvl); + } else { + $this->ClearFloats('BOTH', $this->blklvl); + } + } + } + /* -- END CSS-FLOAT -- */ + $bak_y = $this->y; + $bak_x = $this->x; + $align = ''; + if (!$is_table) { + if (isset($this->blk[$this->blklvl]['align']) && $this->blk[$this->blklvl]['align']) { + $align = $this->blk[$this->blklvl]['align']; + } + // Block-align is set by e.g. <.. align="center"> Takes priority for this block but not inherited + if (isset($this->blk[$this->blklvl]['block-align']) && $this->blk[$this->blklvl]['block-align']) { + $align = $this->blk[$this->blklvl]['block-align']; + } + if (isset($this->blk[$this->blklvl]['direction'])) { + $blockdir = $this->blk[$this->blklvl]['direction']; + } else { + $blockdir = ""; + } + $this->divwidth = $this->blk[$this->blklvl]['width']; + } else { + $align = $this->cellTextAlign; + $blockdir = $cell_dir; + } + $oldpage = $this->page; + + // ADDED for Out of Block now done as Flowing Block + if ($this->divwidth == 0) { + $this->divwidth = $this->pgwidth; + } + + if (!$is_table) { + $this->SetLineHeight($this->FontSizePt, $this->blk[$this->blklvl]['line_height']); + } + $this->divheight = $this->lineheight; + $old_height = $this->divheight; + + // As a failsafe - if font has been set but not output to page + if (!$table_draft) { + $this->SetFont($this->default_font, '', $this->default_font_size, true, true); // force output to page + } + + $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, true, $blockdir, $table_draft); + + $array_size = count($arrayaux); + + // Added - Otherwise

did not output top margins/padding for 1st/2nd div + if ($array_size == 0) { + $this->finishFlowingBlock(true); + } // true = END of flowing block + // mPDF 6 + // ALL the chunks of textbuffer need to have at least basic OTLdata set + // First make sure each element/chunk has the OTLdata for Bidi set. + for ($i = 0; $i < $array_size; $i++) { + if (empty($arrayaux[$i][18])) { + if (substr($arrayaux[$i][0], 0, 3) == "\xbb\xa4\xac") { // object identifier has been identified! + $unicode = [0xFFFC]; // Object replacement character + } else { + $unicode = $this->UTF8StringToArray($arrayaux[$i][0], false); + } + $is_strong = false; + $this->getBasicOTLdata($arrayaux[$i][18], $unicode, $is_strong); + } + // Gets messed up if try and use core fonts inside a paragraph of text which needs to be BiDi re-ordered or OTLdata set + if (($blockdir == 'rtl' || $this->biDirectional) && isset($arrayaux[$i][4]) && in_array($arrayaux[$i][4], ['ccourier', 'ctimes', 'chelvetica', 'csymbol', 'czapfdingbats'])) { + throw new \Mpdf\MpdfException("You cannot use core fonts in a document which contains RTL text."); + } + } + // mPDF 6 + // Process bidirectional text ready for bidi-re-ordering (which is done after line-breaks are established in WriteFlowingBlock etc.) + if (($blockdir == 'rtl' || $this->biDirectional) && !$table_draft) { + if (empty($this->otl)) { + $this->otl = new Otl($this, $this->fontCache); + } + $this->otl->bidiPrepare($arrayaux, $blockdir); + $array_size = count($arrayaux); + } + + + // Remove empty items // mPDF 6 + for ($i = $array_size - 1; $i > 0; $i--) { + if (empty($arrayaux[$i][0]) && (isset($arrayaux[$i][16]) && $arrayaux[$i][16] !== '0') && empty($arrayaux[$i][7])) { + unset($arrayaux[$i]); + } + } + + // Correct adjoining borders for inline elements + if (isset($arrayaux[0][16])) { + $lastspanborder = $arrayaux[0][16]; + } else { + $lastspanborder = false; + } + for ($i = 1; $i < $array_size; $i++) { + if (isset($arrayaux[$i][16]) && $arrayaux[$i][16] == $lastspanborder && + ((!isset($arrayaux[$i][9]['bord-decoration']) && !isset($arrayaux[$i - 1][9]['bord-decoration'])) || + (isset($arrayaux[$i][9]['bord-decoration']) && isset($arrayaux[$i - 1][9]['bord-decoration']) && $arrayaux[$i][9]['bord-decoration'] == $arrayaux[$i - 1][9]['bord-decoration']) + ) + ) { + if (isset($arrayaux[$i][16]['R'])) { + $lastspanborder = $arrayaux[$i][16]; + } else { + $lastspanborder = false; + } + $arrayaux[$i][16]['L']['s'] = 0; + $arrayaux[$i][16]['L']['w'] = 0; + $arrayaux[$i - 1][16]['R']['s'] = 0; + $arrayaux[$i - 1][16]['R']['w'] = 0; + } else { + if (isset($arrayaux[$i][16]['R'])) { + $lastspanborder = $arrayaux[$i][16]; + } else { + $lastspanborder = false; + } + } + } + + for ($i = 0; $i < $array_size; $i++) { + // COLS + $oldcolumn = $this->CurrCol; + $vetor = isset($arrayaux[$i]) ? $arrayaux[$i] : null; + if ($i == 0 && $vetor[0] != "\n" && ! $this->ispre) { + $vetor[0] = ltrim($vetor[0]); + if (!empty($vetor[18])) { + $this->otl->trimOTLdata($vetor[18], true, false); + } // *OTL* + } + + // FIXED TO ALLOW IT TO SHOW '0' + if (empty($vetor[0]) && !($vetor[0] === '0') && empty($vetor[7])) { // Ignore empty text and not carrying an internal link + // Check if it is the last element. If so then finish printing the block + if ($i == ($array_size - 1)) { + $this->finishFlowingBlock(true); + } // true = END of flowing block + continue; + } + + + // Activating buffer properties + if (isset($vetor[11]) && $vetor[11] != '') { // Font Size + if ($is_table && $this->shrin_k) { + $this->SetFontSize($vetor[11] / $this->shrin_k, false); + } else { + $this->SetFontSize($vetor[11], false); + } + } + + if (isset($vetor[17]) && !empty($vetor[17])) { // TextShadow + $this->textshadow = $vetor[17]; + } + if (isset($vetor[16]) && !empty($vetor[16])) { // Border + $this->spanborddet = $vetor[16]; + $this->spanborder = true; + } + + if (isset($vetor[15])) { // Word spacing + $this->wSpacingCSS = $vetor[15]; + if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') { + $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3 + } + } + if (isset($vetor[14])) { // Letter spacing + $this->lSpacingCSS = $vetor[14]; + if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') { + $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3 + } + } + + + if (isset($vetor[10]) and ! empty($vetor[10])) { // Background color + $this->spanbgcolorarray = $vetor[10]; + $this->spanbgcolor = true; + } + if (isset($vetor[9]) and ! empty($vetor[9])) { // Text parameters - Outline + hyphens + $this->textparam = $vetor[9]; + $this->SetTextOutline($this->textparam); + // mPDF 5.7.3 inline text-decoration parameters + if ($is_table && $this->shrin_k) { + if (isset($this->textparam['text-baseline'])) { + $this->textparam['text-baseline'] /= $this->shrin_k; + } + if (isset($this->textparam['decoration-baseline'])) { + $this->textparam['decoration-baseline'] /= $this->shrin_k; + } + if (isset($this->textparam['decoration-fontsize'])) { + $this->textparam['decoration-fontsize'] /= $this->shrin_k; + } + } + } + if (isset($vetor[8])) { // mPDF 5.7.1 + $this->textvar = $vetor[8]; + } + if (isset($vetor[7]) and $vetor[7] != '') { // internal target: + $ily = $this->y; + if ($this->table_rotate) { + $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "tbrot" => true]; + } elseif ($this->kwt) { + $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "kwt" => true]; + } elseif ($this->ColActive) { + $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page, "col" => $this->CurrCol]; + } elseif (!$this->keep_block_together) { + $this->internallink[$vetor[7]] = ["Y" => $ily, "PAGE" => $this->page]; + } + if (empty($vetor[0])) { // Ignore empty text + // Check if it is the last element. If so then finish printing the block + if ($i == ($array_size - 1)) { + $this->finishFlowingBlock(true); + } // true = END of flowing block + continue; + } + } + if (isset($vetor[5]) and $vetor[5] != '') { // Language // mPDF 6 + $this->currentLang = $vetor[5]; + } + if (isset($vetor[4]) and $vetor[4] != '') { // Font Family + $font = $this->SetFont($vetor[4], $this->FontStyle, 0, false); + } + if (!empty($vetor[3])) { // Font Color + $cor = $vetor[3]; + $this->SetTColor($cor); + } + if (isset($vetor[2]) and $vetor[2] != '') { // Bold,Italic styles + $this->SetStyles($vetor[2]); + } + + if (isset($vetor[12]) and $vetor[12] != '') { // Requested Bold,Italic + $this->ReqFontStyle = $vetor[12]; + } + if (isset($vetor[1]) and $vetor[1] != '') { // LINK + if (strpos($vetor[1], ".") === false && strpos($vetor[1], "@") !== 0) { // assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.) + // Repeated reference to same anchor? + while (array_key_exists($vetor[1], $this->internallink)) { + $vetor[1] = "#" . $vetor[1]; + } + $this->internallink[$vetor[1]] = $this->AddLink(); + $vetor[1] = $this->internallink[$vetor[1]]; + } + $this->HREF = $vetor[1]; // HREF link style set here ****** + } + + // SPECIAL CONTENT - IMAGES & FORM OBJECTS + // Print-out special content + + if (substr($vetor[0], 0, 3) == "\xbb\xa4\xac") { // identifier has been identified! + $objattr = $this->_getObjAttr($vetor[0]); + + /* -- TABLES -- */ + if ($objattr['type'] == 'nestedtable') { + if ($objattr['nestedcontent']) { + $level = $objattr['level']; + $table = &$this->table[$level][$objattr['table']]; + + if ($table_draft) { + $this->y += $this->table[($level + 1)][$objattr['nestedcontent']]['h']; // nested table height + $this->finishFlowingBlock(false, 'nestedtable'); + } else { + $cell = &$table['cells'][$objattr['row']][$objattr['col']]; + $this->finishFlowingBlock(false, 'nestedtable'); + $save_dw = $this->divwidth; + $save_buffer = $this->cellBorderBuffer; + $this->cellBorderBuffer = []; + $ncx = $this->x; + list($dummyx, $w) = $this->_tableGetWidth($table, $objattr['row'], $objattr['col']); + $ntw = $this->table[($level + 1)][$objattr['nestedcontent']]['w']; // nested table width + if (!$this->simpleTables) { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cell['borderbin']); + } else { + $br = $cell['border_details']['R']['w']; + $bl = $cell['border_details']['L']['w']; + } + if ($table['borders_separate']) { + $innerw = $w - $bl - $br - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H']; + } else { + $innerw = $w - $bl / 2 - $br / 2 - $cell['padding']['L'] - $cell['padding']['R']; + } + } elseif ($this->simpleTables) { + if ($table['borders_separate']) { + $innerw = $w - $table['simple']['border_details']['L']['w'] - $table['simple']['border_details']['R']['w'] - $cell['padding']['L'] - $cell['padding']['R'] - $table['border_spacing_H']; + } else { + $innerw = $w - $table['simple']['border_details']['L']['w'] / 2 - $table['simple']['border_details']['R']['w'] / 2 - $cell['padding']['L'] - $cell['padding']['R']; + } + } + if ($cell['a'] == 'C' || $this->table[($level + 1)][$objattr['nestedcontent']]['a'] == 'C') { + $ncx += ($innerw - $ntw) / 2; + } elseif ($cell['a'] == 'R' || $this->table[($level + 1)][$objattr['nestedcontent']]['a'] == 'R') { + $ncx += $innerw - $ntw; + } + $this->x = $ncx; + + $this->_tableWrite($this->table[($level + 1)][$objattr['nestedcontent']]); + $this->cellBorderBuffer = $save_buffer; + $this->x = $bak_x; + $this->divwidth = $save_dw; + } + + $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft); + } + } else { + /* -- END TABLES -- */ + if ($is_table) { // *TABLES* + $maxWidth = $this->divwidth; // *TABLES* + } // *TABLES* + else { // *TABLES* + $maxWidth = $this->divwidth - ($this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_right'] + $this->blk[$this->blklvl]['border_right']['w']); + } // *TABLES* + + /* -- CSS-IMAGE-FLOAT -- */ + // If float (already) exists at this level + if (isset($this->floatmargins['R']) && $this->y <= $this->floatmargins['R']['y1'] && $this->y >= $this->floatmargins['R']['y0']) { + $maxWidth -= $this->floatmargins['R']['w']; + } + if (isset($this->floatmargins['L']) && $this->y <= $this->floatmargins['L']['y1'] && $this->y >= $this->floatmargins['L']['y0']) { + $maxWidth -= $this->floatmargins['L']['w']; + } + /* -- END CSS-IMAGE-FLOAT -- */ + + list($skipln) = $this->inlineObject($objattr['type'], '', $this->y, $objattr, $this->lMargin, ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE), $maxWidth, $this->flowingBlockAttr['height'], false, $is_table); + // 1 -> New line needed because of width + // -1 -> Will fit width on line but NEW PAGE REQUIRED because of height + // -2 -> Will not fit on line therefore needs new line but thus NEW PAGE REQUIRED + $iby = $this->y; + $oldpage = $this->page; + $oldcol = $this->CurrCol; + if (($skipln == 1 || $skipln == -2) && !isset($objattr['float'])) { + $this->finishFlowingBlock(false, $objattr['type']); + $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft); + } + + if (!$table_draft) { + $thispage = $this->page; + if ($this->CurrCol != $oldcol) { + $changedcol = true; + } else { + $changedcol = false; + } + + // the previous lines can already have triggered page break or column change + if (!$changedcol && $skipln < 0 && $this->AcceptPageBreak() && $thispage == $oldpage) { + $this->AddPage($this->CurOrientation); + + // Added to correct Images already set on line before page advanced + // i.e. if second inline image on line is higher than first and forces new page + if (count($this->objectbuffer)) { + $yadj = $iby - $this->y; + foreach ($this->objectbuffer as $ib => $val) { + if ($this->objectbuffer[$ib]['OUTER-Y']) { + $this->objectbuffer[$ib]['OUTER-Y'] -= $yadj; + } + if ($this->objectbuffer[$ib]['BORDER-Y']) { + $this->objectbuffer[$ib]['BORDER-Y'] -= $yadj; + } + if ($this->objectbuffer[$ib]['INNER-Y']) { + $this->objectbuffer[$ib]['INNER-Y'] -= $yadj; + } + } + } + } + + // Added to correct for OddEven Margins + if ($this->page != $oldpage) { + if (($this->page - $oldpage) % 2 == 1) { + $bak_x += $this->MarginCorrection; + } + $oldpage = $this->page; + $y = $this->tMargin - $paint_ht_corr; + $this->oldy = $this->tMargin - $paint_ht_corr; + $old_height = 0; + } + $this->x = $bak_x; + /* -- COLUMNS -- */ + // COLS + // OR COLUMN CHANGE + if ($this->CurrCol != $oldcolumn) { + if ($this->directionality == 'rtl') { // *OTL* + $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL* + } // *OTL* + else { // *OTL* + $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); + } // *OTL* + $this->x = $bak_x; + $oldcolumn = $this->CurrCol; + $y = $this->y0 - $paint_ht_corr; + $this->oldy = $this->y0 - $paint_ht_corr; + $old_height = 0; + } + /* -- END COLUMNS -- */ + } + + /* -- CSS-IMAGE-FLOAT -- */ + if ($objattr['type'] == 'image' && isset($objattr['float'])) { + $fy = $this->y; + + // DIV TOP MARGIN/BORDER/PADDING + if ($this->flowingBlockAttr['newblock'] && ($this->flowingBlockAttr['blockstate'] == 1 || $this->flowingBlockAttr['blockstate'] == 3) && $this->flowingBlockAttr['lineCount'] == 0) { + $fy += $this->blk[$this->blklvl]['margin_top'] + $this->blk[$this->blklvl]['padding_top'] + $this->blk[$this->blklvl]['border_top']['w']; + } + + if ($objattr['float'] == 'R') { + $fx = $this->w - $this->rMargin - $objattr['width'] - ($this->blk[$this->blklvl]['outer_right_margin'] + $this->blk[$this->blklvl]['border_right']['w'] + $this->blk[$this->blklvl]['padding_right']); + } elseif ($objattr['float'] == 'L') { + $fx = $this->lMargin + ($this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']); + } + $w = $objattr['width']; + $h = abs($objattr['height']); + + $widthLeft = $maxWidth - ($this->flowingBlockAttr['contentWidth'] / Mpdf::SCALE); + $maxHeight = $this->h - ($this->tMargin + $this->margin_header + $this->bMargin + 10); + // For Images + $extraWidth = ($objattr['border_left']['w'] + $objattr['border_right']['w'] + $objattr['margin_left'] + $objattr['margin_right']); + $extraHeight = ($objattr['border_top']['w'] + $objattr['border_bottom']['w'] + $objattr['margin_top'] + $objattr['margin_bottom']); + + if ($objattr['itype'] == 'wmf' || $objattr['itype'] == 'svg') { + $file = $objattr['file']; + $info = $this->formobjects[$file]; + } else { + $file = $objattr['file']; + $info = $this->images[$file]; + } + $img_w = $w - $extraWidth; + $img_h = $h - $extraHeight; + if ($objattr['border_left']['w']) { + $objattr['BORDER-WIDTH'] = $img_w + (($objattr['border_left']['w'] + $objattr['border_right']['w']) / 2); + $objattr['BORDER-HEIGHT'] = $img_h + (($objattr['border_top']['w'] + $objattr['border_bottom']['w']) / 2); + $objattr['BORDER-X'] = $fx + $objattr['margin_left'] + (($objattr['border_left']['w']) / 2); + $objattr['BORDER-Y'] = $fy + $objattr['margin_top'] + (($objattr['border_top']['w']) / 2); + } + $objattr['INNER-WIDTH'] = $img_w; + $objattr['INNER-HEIGHT'] = $img_h; + $objattr['INNER-X'] = $fx + $objattr['margin_left'] + ($objattr['border_left']['w']); + $objattr['INNER-Y'] = $fy + $objattr['margin_top'] + ($objattr['border_top']['w']); + $objattr['ID'] = $info['i']; + $objattr['OUTER-WIDTH'] = $w; + $objattr['OUTER-HEIGHT'] = $h; + $objattr['OUTER-X'] = $fx; + $objattr['OUTER-Y'] = $fy; + if ($objattr['float'] == 'R') { + // If R float already exists at this level + $this->floatmargins['R']['skipline'] = false; + if (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) { + $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1 + } // If L float already exists at this level + elseif (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) { + // Final check distance between floats is not now too narrow to fit text + $mw = 2 * $this->GetCharWidth('W', false); + if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['L']['w']) < $mw) { + $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1 + } else { + $this->floatmargins['R']['x'] = $fx; + $this->floatmargins['R']['w'] = $w; + $this->floatmargins['R']['y0'] = $fy; + $this->floatmargins['R']['y1'] = $fy + $h; + if ($skipln == 1) { + $this->floatmargins['R']['skipline'] = true; + $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0; + $objattr['skipline'] = true; + } + $this->floatbuffer[] = $objattr; + } + } else { + $this->floatmargins['R']['x'] = $fx; + $this->floatmargins['R']['w'] = $w; + $this->floatmargins['R']['y0'] = $fy; + $this->floatmargins['R']['y1'] = $fy + $h; + if ($skipln == 1) { + $this->floatmargins['R']['skipline'] = true; + $this->floatmargins['R']['id'] = count($this->floatbuffer) + 0; + $objattr['skipline'] = true; + } + $this->floatbuffer[] = $objattr; + } + } elseif ($objattr['float'] == 'L') { + // If L float already exists at this level + $this->floatmargins['L']['skipline'] = false; + if (isset($this->floatmargins['L']['y1']) && $this->floatmargins['L']['y1'] > 0 && $fy < $this->floatmargins['L']['y1']) { + $this->floatmargins['L']['skipline'] = false; + $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1 + } // If R float already exists at this level + elseif (isset($this->floatmargins['R']['y1']) && $this->floatmargins['R']['y1'] > 0 && $fy < $this->floatmargins['R']['y1']) { + // Final check distance between floats is not now too narrow to fit text + $mw = 2 * $this->GetCharWidth('W', false); + if (($this->blk[$this->blklvl]['inner_width'] - $w - $this->floatmargins['R']['w']) < $mw) { + $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1 + } else { + $this->floatmargins['L']['x'] = $fx + $w; + $this->floatmargins['L']['w'] = $w; + $this->floatmargins['L']['y0'] = $fy; + $this->floatmargins['L']['y1'] = $fy + $h; + if ($skipln == 1) { + $this->floatmargins['L']['skipline'] = true; + $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0; + $objattr['skipline'] = true; + } + $this->floatbuffer[] = $objattr; + } + } else { + $this->floatmargins['L']['x'] = $fx + $w; + $this->floatmargins['L']['w'] = $w; + $this->floatmargins['L']['y0'] = $fy; + $this->floatmargins['L']['y1'] = $fy + $h; + if ($skipln == 1) { + $this->floatmargins['L']['skipline'] = true; + $this->floatmargins['L']['id'] = count($this->floatbuffer) + 0; + $objattr['skipline'] = true; + } + $this->floatbuffer[] = $objattr; + } + } + } else { + /* -- END CSS-IMAGE-FLOAT -- */ + $this->WriteFlowingBlock($vetor[0], (isset($vetor[18]) ? $vetor[18] : null)); // mPDF 5.7.1 + /* -- CSS-IMAGE-FLOAT -- */ + } + /* -- END CSS-IMAGE-FLOAT -- */ + } // *TABLES* + } // END If special content + else { // THE text + if ($this->tableLevel) { + $paint_ht_corr = 0; + } // To move the y up when new column/page started if div border needed + else { + $paint_ht_corr = $this->blk[$this->blklvl]['border_top']['w']; + } + + if ($vetor[0] == "\n") { // We are reading a
now turned into newline ("\n") + if ($this->flowingBlockAttr['content']) { + $this->finishFlowingBlock(false, 'br'); + } elseif ($is_table) { + $this->y+= $this->_computeLineheight($this->cellLineHeight); + } elseif (!$is_table) { + $this->DivLn($this->lineheight); + if ($this->ColActive) { + $this->breakpoints[$this->CurrCol][] = $this->y; + } // *COLUMNS* + } + // Added to correct for OddEven Margins + if ($this->page != $oldpage) { + if (($this->page - $oldpage) % 2 == 1) { + $bak_x += $this->MarginCorrection; + } + $oldpage = $this->page; + $y = $this->tMargin - $paint_ht_corr; + $this->oldy = $this->tMargin - $paint_ht_corr; + $old_height = 0; + } + $this->x = $bak_x; + /* -- COLUMNS -- */ + // COLS + // OR COLUMN CHANGE + if ($this->CurrCol != $oldcolumn) { + if ($this->directionality == 'rtl') { // *OTL* + $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL* + } // *OTL* + else { // *OTL* + $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); + } // *OTL* + $this->x = $bak_x; + $oldcolumn = $this->CurrCol; + $y = $this->y0 - $paint_ht_corr; + $this->oldy = $this->y0 - $paint_ht_corr; + $old_height = 0; + } + /* -- END COLUMNS -- */ + $this->newFlowingBlock($this->divwidth, $this->divheight, $align, $is_table, $blockstate, false, $blockdir, $table_draft); + } else { + $this->WriteFlowingBlock($vetor[0], $vetor[18]); // mPDF 5.7.1 + // Added to correct for OddEven Margins + if ($this->page != $oldpage) { + if (($this->page - $oldpage) % 2 == 1) { + $bak_x += $this->MarginCorrection; + $this->x = $bak_x; + } + $oldpage = $this->page; + $y = $this->tMargin - $paint_ht_corr; + $this->oldy = $this->tMargin - $paint_ht_corr; + $old_height = 0; + } + /* -- COLUMNS -- */ + // COLS + // OR COLUMN CHANGE + if ($this->CurrCol != $oldcolumn) { + if ($this->directionality == 'rtl') { // *OTL* + $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL* + } // *OTL* + else { // *OTL* + $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); + } // *OTL* + $this->x = $bak_x; + $oldcolumn = $this->CurrCol; + $y = $this->y0 - $paint_ht_corr; + $this->oldy = $this->y0 - $paint_ht_corr; + $old_height = 0; + } + /* -- END COLUMNS -- */ + } + } + + // Check if it is the last element. If so then finish printing the block + if ($i == ($array_size - 1)) { + $this->finishFlowingBlock(true); // true = END of flowing block + // Added to correct for OddEven Margins + if ($this->page != $oldpage) { + if (($this->page - $oldpage) % 2 == 1) { + $bak_x += $this->MarginCorrection; + $this->x = $bak_x; + } + $oldpage = $this->page; + $y = $this->tMargin - $paint_ht_corr; + $this->oldy = $this->tMargin - $paint_ht_corr; + $old_height = 0; + } + + /* -- COLUMNS -- */ + // COLS + // OR COLUMN CHANGE + if ($this->CurrCol != $oldcolumn) { + if ($this->directionality == 'rtl') { // *OTL* + $bak_x -= ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); // *OTL* + } // *OTL* + else { // *OTL* + $bak_x += ($this->CurrCol - $oldcolumn) * ($this->ColWidth + $this->ColGap); + } // *OTL* + $this->x = $bak_x; + $oldcolumn = $this->CurrCol; + $y = $this->y0 - $paint_ht_corr; + $this->oldy = $this->y0 - $paint_ht_corr; + $old_height = 0; + } + /* -- END COLUMNS -- */ + } + + // RESETTING VALUES + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + $this->colorarray = ''; + $this->spanbgcolorarray = ''; + $this->spanbgcolor = false; + $this->spanborder = false; + $this->spanborddet = []; + $this->HREF = ''; + $this->textparam = []; + $this->SetTextOutline(); + + $this->textvar = 0x00; // mPDF 5.7.1 + $this->OTLtags = []; + $this->textshadow = ''; + + $this->currentfontfamily = ''; + $this->currentfontsize = ''; + $this->currentfontstyle = ''; + $this->currentLang = $this->default_lang; // mPDF 6 + $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6 + /* -- TABLES -- */ + if ($this->tableLevel) { + $this->SetLineHeight('', $this->table[1][1]['cellLineHeight']); // *TABLES* + } else { /* -- END TABLES -- */ + if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) { + $this->SetLineHeight('', $this->blk[$this->blklvl]['line_height']); // sets default line height + } + } + $this->ResetStyles(); + $this->lSpacingCSS = ''; + $this->wSpacingCSS = ''; + $this->fixedlSpacing = false; + $this->minwSpacing = 0; + $this->SetDash(); + $this->dash_on = false; + $this->dotted_on = false; + }//end of for(i=0;iReset(); // mPDF 6 + // PAINT DIV BORDER // DISABLED IN COLUMNS AS DOESN'T WORK WHEN BROKEN ACROSS COLS?? + if ((isset($this->blk[$this->blklvl]['border']) || isset($this->blk[$this->blklvl]['bgcolor']) || isset($this->blk[$this->blklvl]['box_shadow'])) && $blockstate && ($this->y != $this->oldy)) { + $bottom_y = $this->y; // Does not include Bottom Margin + if (isset($this->blk[$this->blklvl]['startpage']) && $this->blk[$this->blklvl]['startpage'] != $this->page && $blockstate != 1) { + $this->PaintDivBB('pagetop', $blockstate); + } elseif ($blockstate != 1) { + $this->PaintDivBB('', $blockstate); + } + $this->y = $bottom_y; + $this->x = $bak_x; + } + + // Reset Font + $this->SetFontSize($this->default_font_size, false); + if ($table_draft) { + $ch = $this->y - $bak_y; + $this->y = $bak_y; + $this->x = $bak_x; + return $ch; + } + } + + function _setDashBorder($style, $div, $cp, $side) + { + if ($style == 'dashed' && (($side == 'L' || $side == 'R') || ($side == 'T' && $div != 'pagetop' && !$cp) || ($side == 'B' && $div != 'pagebottom') )) { + $dashsize = 2; // final dash will be this + 1*linewidth + $dashsizek = 1.5; // ratio of Dash/Blank + $this->SetDash($dashsize, ($dashsize / $dashsizek) + ($this->LineWidth * 2)); + } elseif ($style == 'dotted' || ($side == 'T' && ($div == 'pagetop' || $cp)) || ($side == 'B' && $div == 'pagebottom')) { + // Round join and cap + $this->SetLineJoin(1); + $this->SetLineCap(1); + $this->SetDash(0.001, ($this->LineWidth * 3)); + } + } + + function _setBorderLine($b, $k = 1) + { + $this->SetLineWidth($b['w'] / $k); + $this->SetDColor($b['c']); + if ($b['c'][0] == 5) { // RGBa + $this->SetAlpha(ord($b['c'][4]) / 100, 'Normal', false, 'S'); // mPDF 5.7.2 + } elseif ($b['c'][0] == 6) { // CMYKa + $this->SetAlpha(ord($b['c'][5]) / 100, 'Normal', false, 'S'); // mPDF 5.7.2 + } + } + + function PaintDivBB($divider = '', $blockstate = 0, $blvl = 0) + { + // Borders & backgrounds are done elsewhere for columns - messes up the repositioning in printcolumnbuffer + if ($this->ColActive) { + return; + } // *COLUMNS* + if ($this->keep_block_together) { + return; + } // mPDF 6 + $save_y = $this->y; + if (!$blvl) { + $blvl = $this->blklvl; + } + $x0 = $x1 = $y0 = $y1 = 0; + + // Added mPDF 3.0 Float DIV + if (isset($this->blk[$blvl]['bb_painted'][$this->page]) && $this->blk[$blvl]['bb_painted'][$this->page]) { + return; + } // *CSS-FLOAT* + + if (isset($this->blk[$blvl]['x0'])) { + $x0 = $this->blk[$blvl]['x0']; + } // left + if (isset($this->blk[$blvl]['y1'])) { + $y1 = $this->blk[$blvl]['y1']; + } // bottom + // Added mPDF 3.0 Float DIV - ensures backgrounds/borders are drawn to bottom of page + if ($y1 == 0) { + if ($divider == 'pagebottom') { + $y1 = $this->h - $this->bMargin; + } else { + $y1 = $this->y; + } + } + + $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page); + + if (isset($this->blk[$blvl]['y0'])) { + $y0 = $this->blk[$blvl]['y0']; + } + $h = $y1 - $y0; + $w = $this->blk[$blvl]['width']; + $x1 = $x0 + $w; + + // Set border-widths as used here + $border_top = $this->blk[$blvl]['border_top']['w']; + $border_bottom = $this->blk[$blvl]['border_bottom']['w']; + $border_left = $this->blk[$blvl]['border_left']['w']; + $border_right = $this->blk[$blvl]['border_right']['w']; + if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) { + $border_top = 0; + } + if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') { + $border_bottom = 0; + } + + $brTL_H = 0; + $brTL_V = 0; + $brTR_H = 0; + $brTR_V = 0; + $brBL_H = 0; + $brBL_V = 0; + $brBR_H = 0; + $brBR_V = 0; + + $brset = false; + /* -- BORDER-RADIUS -- */ + if (isset($this->blk[$blvl]['border_radius_TL_H'])) { + $brTL_H = $this->blk[$blvl]['border_radius_TL_H']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_TL_V'])) { + $brTL_V = $this->blk[$blvl]['border_radius_TL_V']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_TR_H'])) { + $brTR_H = $this->blk[$blvl]['border_radius_TR_H']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_TR_V'])) { + $brTR_V = $this->blk[$blvl]['border_radius_TR_V']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_BR_H'])) { + $brBR_H = $this->blk[$blvl]['border_radius_BR_H']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_BR_V'])) { + $brBR_V = $this->blk[$blvl]['border_radius_BR_V']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_BL_H'])) { + $brBL_H = $this->blk[$blvl]['border_radius_BL_H']; + $brset = true; + } + if (isset($this->blk[$blvl]['border_radius_BL_V'])) { + $brBL_V = $this->blk[$blvl]['border_radius_BL_V']; + $brset = true; + } + + if (!$this->blk[$blvl]['border_top'] || $divider == 'pagetop' || $continuingpage) { + $brTL_H = 0; + $brTL_V = 0; + $brTR_H = 0; + $brTR_V = 0; + } + if (!$this->blk[$blvl]['border_bottom'] || $blockstate == 1 || $divider == 'pagebottom') { + $brBL_H = 0; + $brBL_V = 0; + $brBR_H = 0; + $brBR_V = 0; + } + + // Disallow border-radius if it is smaller than the border width. + if ($brTL_H < min($border_left, $border_top)) { + $brTL_H = $brTL_V = 0; + } + if ($brTL_V < min($border_left, $border_top)) { + $brTL_V = $brTL_H = 0; + } + if ($brTR_H < min($border_right, $border_top)) { + $brTR_H = $brTR_V = 0; + } + if ($brTR_V < min($border_right, $border_top)) { + $brTR_V = $brTR_H = 0; + } + if ($brBL_H < min($border_left, $border_bottom)) { + $brBL_H = $brBL_V = 0; + } + if ($brBL_V < min($border_left, $border_bottom)) { + $brBL_V = $brBL_H = 0; + } + if ($brBR_H < min($border_right, $border_bottom)) { + $brBR_H = $brBR_V = 0; + } + if ($brBR_V < min($border_right, $border_bottom)) { + $brBR_V = $brBR_H = 0; + } + + // CHECK FOR radii that sum to > width or height of div ******** + $f = min($h / ($brTL_V + $brBL_V + 0.001), $h / ($brTR_V + $brBR_V + 0.001), $w / ($brTL_H + $brTR_H + 0.001), $w / ($brBL_H + $brBR_H + 0.001)); + if ($f < 1) { + $brTL_H *= $f; + $brTL_V *= $f; + $brTR_H *= $f; + $brTR_V *= $f; + $brBL_H *= $f; + $brBL_V *= $f; + $brBR_H *= $f; + $brBR_V *= $f; + } + /* -- END BORDER-RADIUS -- */ + + $tbcol = $this->colorConverter->convert(255, $this->PDFAXwarnings); + for ($l = 0; $l <= $blvl; $l++) { + if ($this->blk[$l]['bgcolor']) { + $tbcol = $this->blk[$l]['bgcolorarray']; + } + } + + // BORDERS + if (isset($this->blk[$blvl]['y0']) && $this->blk[$blvl]['y0']) { + $y0 = $this->blk[$blvl]['y0']; + } + $h = $y1 - $y0; + $w = $this->blk[$blvl]['width']; + + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $tbd = $this->blk[$blvl]['border_top']; + + $legend = ''; + $legbreakL = 0; + $legbreakR = 0; + // BORDER LEGEND + if (isset($this->blk[$blvl]['border_legend']) && $this->blk[$blvl]['border_legend']) { + $legend = $this->blk[$blvl]['border_legend']; // Same structure array as textbuffer + $txt = $legend[0] = ltrim($legend[0]); + if (!empty($legend[18])) { + $this->otl->trimOTLdata($legend[18], true, false); + } // *OTL* + // Set font, size, style, color + $this->SetFont($legend[4], $legend[2], $legend[11]); + if (isset($legend[3]) && $legend[3]) { + $cor = $legend[3]; + $this->SetTColor($cor); + } + $stringWidth = $this->GetStringWidth($txt, true, $legend[18], $legend[8]); + $save_x = $this->x; + $save_y = $this->y; + $save_currentfontfamily = $this->FontFamily; + $save_currentfontsize = $this->FontSizePt; + $save_currentfontstyle = $this->FontStyle; + $this->y = $y0 - $this->FontSize / 2 + $this->blk[$blvl]['border_top']['w'] / 2; + $this->x = $x0 + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_left']['w']; + + // Set the distance from the border line to the text ? make configurable variable + $gap = 0.2 * $this->FontSize; + $legbreakL = $this->x - $gap; + $legbreakR = $this->x + $stringWidth + $gap; + $this->magic_reverse_dir($txt, $this->blk[$blvl]['direction'], $legend[18]); + $fill = ''; + $this->Cell($stringWidth, $this->FontSize, $txt, '', 0, 'C', $fill, '', 0, 0, 0, 'M', $fill, false, $legend[18], $legend[8]); + // Reset + $this->x = $save_x; + $this->y = $save_y; + $this->SetFont($save_currentfontfamily, $save_currentfontstyle, $save_currentfontsize); + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + + if (isset($tbd['s']) && $tbd['s']) { + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('q'); + $this->SetLineWidth(0); + $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)); + $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path + } + + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $legbreakL -= $border_top / 2; // because line cap different + $legbreakR += $border_top / 2; + $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'T'); + } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brTR_V && $brTR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $this->SetLineJoin(0); + $this->SetLineCap(0); + } + $s = ''; + if ($brTR_H && $brTR_V) { + $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_top / 2, $brTR_V - $border_top / 2, 1, 2, true)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + } + /* -- BORDER-RADIUS -- */ + if ($brTL_H && $brTL_V) { + if ($legend) { + if ($legbreakR < ($x0 + $w - $brTR_H)) { + $s .= (sprintf('%.3F %.3F l ', $legbreakR * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + if ($legbreakL > ($x0 + $brTL_H )) { + $s .= (sprintf('%.3F %.3F m ', $legbreakL * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + $s .= (sprintf('%.3F %.3F l ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE) . "\n"); + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $brTL_H ) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_top / 2, $brTL_V - $border_top / 2, 2, 1)) . "\n"; + } else { + /* -- END BORDER-RADIUS -- */ + if ($legend) { + if ($legbreakR < ($x0 + $w)) { + $s .= (sprintf('%.3F %.3F l ', $legbreakR * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + if ($legbreakL > ($x0)) { + $s .= (sprintf('%.3F %.3F m ', $legbreakL * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + } elseif ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $border_top / 2) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + } elseif ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_top / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_top / 2))) * Mpdf::SCALE)) . "\n"; + } + /* -- BORDER-RADIUS -- */ + } + /* -- END BORDER-RADIUS -- */ + $s .= 'S' . "\n"; + $this->writer->write($s); + + if ($tbd['style'] == 'double') { + $this->SetLineWidth($tbd['w'] / 3); + $this->SetDColor($tbcol); + $this->writer->write($s); + } + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('Q'); + } + + // Reset Corners and Dash off + $this->SetLineWidth(0.1); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + // Reinstate line above for dotted line divider when block border crosses a page + // elseif ($divider == 'pagetop' || $continuingpage) { + + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $tbd = $this->blk[$blvl]['border_bottom']; + if (isset($tbd['s']) && $tbd['s']) { + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('q'); + $this->SetLineWidth(0); + $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)); + $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path + } + + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'B'); + } /* -- BORDER-RADIUS -- */ elseif (($brBL_V && $brBL_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $this->SetLineJoin(0); + $this->SetLineCap(0); + } + $s = ''; + if ($brBL_H && $brBL_V) { + $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_bottom / 2, $brBL_V - $border_bottom / 2, 3, 2, true)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_bottom / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n"; + } + } + /* -- BORDER-RADIUS -- */ + if ($brBR_H && $brBR_V) { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_bottom / 2) - $brBR_H ) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n"; + $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_bottom / 2, $brBR_V - $border_bottom / 2, 4, 1)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_bottom / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_bottom / 2))) * Mpdf::SCALE)) . "\n"; + } + } + $s .= 'S' . "\n"; + $this->writer->write($s); + + if ($tbd['style'] == 'double') { + $this->SetLineWidth($tbd['w'] / 3); + $this->SetDColor($tbcol); + $this->writer->write($s); + } + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('Q'); + } + + // Reset Corners and Dash off + $this->SetLineWidth(0.1); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + // Reinstate line below for dotted line divider when block border crosses a page + // elseif ($blockstate == 1 || $divider == 'pagebottom') { + + if ($this->blk[$blvl]['border_left']) { + $tbd = $this->blk[$blvl]['border_left']; + if (isset($tbd['s']) && $tbd['s']) { + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('q'); + $this->SetLineWidth(0); + $this->writer->write(sprintf('%.3F %.3F m ', ($x0) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $border_left) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)); + $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path + } + + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'L'); + } /* -- BORDER-RADIUS -- */ elseif (($brTL_V && $brTL_H) || ($brBL_V && $brBL_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $this->SetLineJoin(0); + $this->SetLineCap(0); + } + $s = ''; + if ($brTL_V && $brTL_H) { + $s .= ($this->_EllipseArc($x0 + $brTL_H, $y0 + $brTL_V, $brTL_H - $border_left / 2, $brTL_V - $border_left / 2, 2, 2, true)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_left / 2))) * Mpdf::SCALE)) . "\n"; + } + } + /* -- BORDER-RADIUS -- */ + if ($brBL_V && $brBL_H) { + $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_left / 2) - $brBL_V) ) * Mpdf::SCALE)) . "\n"; + $s .= ($this->_EllipseArc($x0 + $brBL_H, $y0 + $h - $brBL_V, $brBL_H - $border_left / 2, $brBL_V - $border_left / 2, 3, 1)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h) ) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + ($border_left / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_left / 2)) ) * Mpdf::SCALE)) . "\n"; + } + } + $s .= 'S' . "\n"; + $this->writer->write($s); + + if ($tbd['style'] == 'double') { + $this->SetLineWidth($tbd['w'] / 3); + $this->SetDColor($tbcol); + $this->writer->write($s); + } + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('Q'); + } + + // Reset Corners and Dash off + $this->SetLineWidth(0.1); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($this->blk[$blvl]['border_right']) { + $tbd = $this->blk[$blvl]['border_right']; + if (isset($tbd['s']) && $tbd['s']) { + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('q'); + $this->SetLineWidth(0); + $this->writer->write(sprintf('%.3F %.3F m ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $border_top)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w - $border_right) * Mpdf::SCALE, ($this->h - ($y0 + $h - $border_bottom)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F l ', ($x0 + $w) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)); + $this->writer->write(' h W n '); // Ends path no-op & Sets the clipping path + } + + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], $divider, $continuingpage, 'R'); + } /* -- BORDER-RADIUS -- */ elseif (($brTR_V && $brTR_H) || ($brBR_V && $brBR_H) || $tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $this->SetLineJoin(0); + $this->SetLineCap(0); + } + $s = ''; + if ($brBR_V && $brBR_H) { + $s .= ($this->_EllipseArc($x0 + $w - $brBR_H, $y0 + $h - $brBR_V, $brBR_H - $border_right / 2, $brBR_V - $border_right / 2, 4, 2, true)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h)) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F m ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + $h - ($border_right / 2))) * Mpdf::SCALE)) . "\n"; + } + } + /* -- BORDER-RADIUS -- */ + if ($brTR_V && $brTR_H) { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_right / 2) + $brTR_V) ) * Mpdf::SCALE)) . "\n"; + $s .= ($this->_EllipseArc($x0 + $w - $brTR_H, $y0 + $brTR_V, $brTR_H - $border_right / 2, $brTR_V - $border_right / 2, 1, 1)) . "\n"; + } else { /* -- END BORDER-RADIUS -- */ + if ($tbd['style'] == 'solid' || $tbd['style'] == 'double') { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0) ) * Mpdf::SCALE)) . "\n"; + } else { + $s .= (sprintf('%.3F %.3F l ', ($x0 + $w - ($border_right / 2)) * Mpdf::SCALE, ($this->h - ($y0 + ($border_right / 2)) ) * Mpdf::SCALE)) . "\n"; + } + } + $s .= 'S' . "\n"; + $this->writer->write($s); + + if ($tbd['style'] == 'double') { + $this->SetLineWidth($tbd['w'] / 3); + $this->SetDColor($tbcol); + $this->writer->write($s); + } + if (!$brset && $tbd['style'] != 'dotted' && $tbd['style'] != 'dashed') { + $this->writer->write('Q'); + } + + // Reset Corners and Dash off + $this->SetLineWidth(0.1); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + + + $this->SetDash(); + $this->y = $save_y; + + + // BACKGROUNDS are disabled in columns/kbt/headers - messes up the repositioning in printcolumnbuffer + if ($this->ColActive || $this->kwt || $this->keep_block_together) { + return; + } + + + $bgx0 = $x0; + $bgx1 = $x1; + $bgy0 = $y0; + $bgy1 = $y1; + + // Defined br values represent the radius of the outer curve - need to take border-width/2 from each radius for drawing the borders + if (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'padding-box') { + $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w']); + $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w']); + $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w']); + $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w']); + $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w']); + $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w']); + $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w']); + $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w']); + $bgx0 += $this->blk[$blvl]['border_left']['w']; + $bgx1 -= $this->blk[$blvl]['border_right']['w']; + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $bgy0 += $this->blk[$blvl]['border_top']['w']; + } + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $bgy1 -= $this->blk[$blvl]['border_bottom']['w']; + } + } elseif (isset($this->blk[$blvl]['background_clip']) && $this->blk[$blvl]['background_clip'] == 'content-box') { + $brbgTL_H = max(0, $brTL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']); + $brbgTL_V = max(0, $brTL_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']); + $brbgTR_H = max(0, $brTR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']); + $brbgTR_V = max(0, $brTR_V - $this->blk[$blvl]['border_top']['w'] - $this->blk[$blvl]['padding_top']); + $brbgBL_H = max(0, $brBL_H - $this->blk[$blvl]['border_left']['w'] - $this->blk[$blvl]['padding_left']); + $brbgBL_V = max(0, $brBL_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']); + $brbgBR_H = max(0, $brBR_H - $this->blk[$blvl]['border_right']['w'] - $this->blk[$blvl]['padding_right']); + $brbgBR_V = max(0, $brBR_V - $this->blk[$blvl]['border_bottom']['w'] - $this->blk[$blvl]['padding_bottom']); + $bgx0 += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left']; + $bgx1 -= $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']; + if (($this->blk[$blvl]['border_top']['w'] || $this->blk[$blvl]['padding_top']) && $divider != 'pagetop' && !$continuingpage) { + $bgy0 += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top']; + } + if (($this->blk[$blvl]['border_bottom']['w'] || $this->blk[$blvl]['padding_bottom']) && $blockstate != 1 && $divider != 'pagebottom') { + $bgy1 -= $this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']; + } + } else { + $brbgTL_H = $brTL_H; + $brbgTL_V = $brTL_V; + $brbgTR_H = $brTR_H; + $brbgTR_V = $brTR_V; + $brbgBL_H = $brBL_H; + $brbgBL_V = $brBL_V; + $brbgBR_H = $brBR_H; + $brbgBR_V = $brBR_V; + } + + // Set clipping path + $s = ' q 0 w '; // Line width=0 + $s .= sprintf('%.3F %.3F m ', ($bgx0 + $brbgTL_H ) * Mpdf::SCALE, ($this->h - $bgy0) * Mpdf::SCALE); // start point TL before the arc + /* -- BORDER-RADIUS -- */ + if ($brbgTL_H || $brbgTL_V) { + $s .= $this->_EllipseArc($bgx0 + $brbgTL_H, $bgy0 + $brbgTL_V, $brbgTL_H, $brbgTL_V, 2); // segment 2 TL + } + /* -- END BORDER-RADIUS -- */ + $s .= sprintf('%.3F %.3F l ', ($bgx0) * Mpdf::SCALE, ($this->h - ($bgy1 - $brbgBL_V )) * Mpdf::SCALE); // line to BL + /* -- BORDER-RADIUS -- */ + if ($brbgBL_H || $brbgBL_V) { + $s .= $this->_EllipseArc($bgx0 + $brbgBL_H, $bgy1 - $brbgBL_V, $brbgBL_H, $brbgBL_V, 3); // segment 3 BL + } + /* -- END BORDER-RADIUS -- */ + $s .= sprintf('%.3F %.3F l ', ($bgx1 - $brbgBR_H ) * Mpdf::SCALE, ($this->h - ($bgy1)) * Mpdf::SCALE); // line to BR + /* -- BORDER-RADIUS -- */ + if ($brbgBR_H || $brbgBR_V) { + $s .= $this->_EllipseArc($bgx1 - $brbgBR_H, $bgy1 - $brbgBR_V, $brbgBR_H, $brbgBR_V, 4); // segment 4 BR + } + /* -- END BORDER-RADIUS -- */ + $s .= sprintf('%.3F %.3F l ', ($bgx1) * Mpdf::SCALE, ($this->h - ($bgy0 + $brbgTR_V)) * Mpdf::SCALE); // line to TR + /* -- BORDER-RADIUS -- */ + if ($brbgTR_H || $brbgTR_V) { + $s .= $this->_EllipseArc($bgx1 - $brbgTR_H, $bgy0 + $brbgTR_V, $brbgTR_H, $brbgTR_V, 1); // segment 1 TR + } + /* -- END BORDER-RADIUS -- */ + $s .= sprintf('%.3F %.3F l ', ($bgx0 + $brbgTL_H ) * Mpdf::SCALE, ($this->h - $bgy0) * Mpdf::SCALE); // line to TL + // Box Shadow + $shadow = ''; + if (isset($this->blk[$blvl]['box_shadow']) && $this->blk[$blvl]['box_shadow'] && $h > 0) { + foreach ($this->blk[$blvl]['box_shadow'] as $sh) { + // Colors + if ($sh['col'][0] == 1) { + $colspace = 'Gray'; + if ($sh['col'][2] == 1) { + $col1 = '1' . $sh['col'][1] . '1' . $sh['col'][3]; + } else { + $col1 = '1' . $sh['col'][1] . '1' . chr(100); + } + $col2 = '1' . $sh['col'][1] . '1' . chr(0); + } elseif ($sh['col'][0] == 4) { // CMYK + $colspace = 'CMYK'; + $col1 = '6' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(100); + $col2 = '6' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(0); + } elseif ($sh['col'][0] == 5) { // RGBa + $colspace = 'RGB'; + $col1 = '5' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4]; + $col2 = '5' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(0); + } elseif ($sh['col'][0] == 6) { // CMYKa + $colspace = 'CMYK'; + $col1 = '6' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . $sh['col'][5]; + $col2 = '6' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . $sh['col'][4] . chr(0); + } else { + $colspace = 'RGB'; + $col1 = '5' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(100); + $col2 = '5' . $sh['col'][1] . $sh['col'][2] . $sh['col'][3] . chr(0); + } + + // Use clipping path as set above (and rectangle around page) to clip area outside box + $shadow .= $s; // Use the clipping path with W* + $shadow .= sprintf('0 %.3F m %.3F %.3F l ', $this->h * Mpdf::SCALE, $this->w * Mpdf::SCALE, $this->h * Mpdf::SCALE); + $shadow .= sprintf('%.3F 0 l 0 0 l 0 %.3F l ', $this->w * Mpdf::SCALE, $this->h * Mpdf::SCALE); + $shadow .= 'W n' . "\n"; + + $sh['blur'] = abs($sh['blur']); // cannot have negative blur value + // Ensure spread/blur do not make effective shadow width/height < 0 + // Could do more complex things but this just adjusts spread value + if (-$sh['spread'] + $sh['blur'] / 2 > min($w / 2, $h / 2)) { + $sh['spread'] = $sh['blur'] / 2 - min($w / 2, $h / 2) + 0.01; + } + // Shadow Offset + if ($sh['x'] || $sh['y']) { + $shadow .= sprintf(' q 1 0 0 1 %.4F %.4F cm', $sh['x'] * Mpdf::SCALE, -$sh['y'] * Mpdf::SCALE) . "\n"; + } + + // Set path for INNER shadow + $shadow .= ' q 0 w '; + $shadow .= $this->SetFColor($col1, true) . "\n"; + if ($col1[0] == 5 && ord($col1[4]) < 100) { // RGBa + $shadow .= $this->SetAlpha(ord($col1[4]) / 100, 'Normal', true, 'F') . "\n"; + } elseif ($col1[0] == 6 && ord($col1[5]) < 100) { // CMYKa + $shadow .= $this->SetAlpha(ord($col1[5]) / 100, 'Normal', true, 'F') . "\n"; + } elseif ($col1[0] == 1 && $col1[2] == 1 && ord($col1[3]) < 100) { // Gray + $shadow .= $this->SetAlpha(ord($col1[3]) / 100, 'Normal', true, 'F') . "\n"; + } + + // Blur edges + $mag = 0.551784; // Bezier Control magic number for 4-part spline for circle/ellipse + $mag2 = 0.551784; // Bezier Control magic number to fill in edge of blurred rectangle + $d1 = $sh['spread'] + $sh['blur'] / 2; + $d2 = $sh['spread'] - $sh['blur'] / 2; + $bl = $sh['blur']; + $x00 = $x0 - $d1; + $y00 = $y0 - $d1; + $w00 = $w + $d1 * 2; + $h00 = $h + $d1 * 2; + + // If any border-radius is greater width-negative spread(inner edge), ignore radii for shadow or screws up + $flatten = false; + if (max($brbgTR_H, $brbgTL_H, $brbgBR_H, $brbgBL_H) >= $w + $d2) { + $flatten = true; + } + if (max($brbgTR_V, $brbgTL_V, $brbgBR_V, $brbgBL_V) >= $h + $d2) { + $flatten = true; + } + + + // TOP RIGHT corner + $p1x = $x00 + $w00 - $d1 - $brbgTR_H; + $p1c2x = $p1x + ($d2 + $brbgTR_H) * $mag; + $p1y = $y00 + $bl; + $p2x = $x00 + $w00 - $d1 - $brbgTR_H; + $p2c2x = $p2x + ($d1 + $brbgTR_H) * $mag; + $p2y = $y00; + $p2c1y = $p2y + $bl / 2; + $p3x = $x00 + $w00; + $p3c2x = $p3x - $bl / 2; + $p3y = $y00 + $d1 + $brbgTR_V; + $p3c1y = $p3y - ($d1 + $brbgTR_V) * $mag; + $p4x = $x00 + $w00 - $bl; + $p4y = $y00 + $d1 + $brbgTR_V; + $p4c2y = $p4y - ($d2 + $brbgTR_V) * $mag; + if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) { + $p1x = $x00 + $w00 - $bl; + $p1c2x = $p1x; + $p2x = $x00 + $w00 - $bl; + $p2c2x = $p2x + $bl * $mag2; + $p3y = $y00 + $bl; + $p3c1y = $p3y - $bl * $mag2; + $p4y = $y00 + $bl; + $p4c2y = $p4y; + } + + $shadow .= sprintf('%.3F %.3F m ', ($p1x ) * Mpdf::SCALE, ($this->h - ($p1y )) * Mpdf::SCALE); + $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->h - ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE); + $patch_array[0]['f'] = 0; + $patch_array[0]['points'] = [$p1x, $p1y, $p1x, $p1y, + $p2x, $p2c1y, $p2x, $p2y, $p2c2x, $p2y, + $p3x, $p3c1y, $p3x, $p3y, $p3c2x, $p3y, + $p4x, $p4y, $p4x, $p4y, $p4x, $p4c2y, + $p1c2x, $p1y]; + $patch_array[0]['colors'] = [$col1, $col2, $col2, $col1]; + + + // RIGHT + $p1x = $x00 + $w00; // control point only matches p3 preceding + $p1y = $y00 + $d1 + $brbgTR_V; + $p2x = $x00 + $w00 - $bl; // control point only matches p4 preceding + $p2y = $y00 + $d1 + $brbgTR_V; + $p3x = $x00 + $w00 - $bl; + $p3y = $y00 + $h00 - $d1 - $brbgBR_V; + $p4x = $x00 + $w00; + $p4c1x = $p4x - $bl / 2; + $p4y = $y00 + $h00 - $d1 - $brbgBR_V; + if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) { + $p1y = $y00 + $bl; + $p2y = $y00 + $bl; + } + if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) { + $p3y = $y00 + $h00 - $bl; + $p4y = $y00 + $h00 - $bl; + } + + $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE); + $patch_array[1]['f'] = 2; + $patch_array[1]['points'] = [$p2x, $p2y, + $p3x, $p3y, $p3x, $p3y, $p3x, $p3y, + $p4c1x, $p4y, $p4x, $p4y, $p4x, $p4y, + $p1x, $p1y]; + $patch_array[1]['colors'] = [$col1, $col2]; + + + // BOTTOM RIGHT corner + $p1x = $x00 + $w00 - $bl; // control points only matches p3 preceding + $p1y = $y00 + $h00 - $d1 - $brbgBR_V; + $p1c2y = $p1y + ($d2 + $brbgBR_V) * $mag; + $p2x = $x00 + $w00; // control point only matches p4 preceding + $p2y = $y00 + $h00 - $d1 - $brbgBR_V; + $p2c2y = $p2y + ($d1 + $brbgBR_V) * $mag; + $p3x = $x00 + $w00 - $d1 - $brbgBR_H; + $p3c1x = $p3x + ($d1 + $brbgBR_H) * $mag; + $p3y = $y00 + $h00; + $p3c2y = $p3y - $bl / 2; + $p4x = $x00 + $w00 - $d1 - $brbgBR_H; + $p4c2x = $p4x + ($d2 + $brbgBR_H) * $mag; + $p4y = $y00 + $h00 - $bl; + + if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) { + $p1y = $y00 + $h00 - $bl; + $p1c2y = $p1y; + $p2y = $y00 + $h00 - $bl; + $p2c2y = $p2y + $bl * $mag2; + $p3x = $x00 + $w00 - $bl; + $p3c1x = $p3x + $bl * $mag2; + $p4x = $x00 + $w00 - $bl; + $p4c2x = $p4x; + } + + $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->h - ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE); + $patch_array[2]['f'] = 2; + $patch_array[2]['points'] = [$p2x, $p2c2y, + $p3c1x, $p3y, $p3x, $p3y, $p3x, $p3c2y, + $p4x, $p4y, $p4x, $p4y, $p4c2x, $p4y, + $p1x, $p1c2y]; + $patch_array[2]['colors'] = [$col2, $col1]; + + + + // BOTTOM + $p1x = $x00 + $w00 - $d1 - $brbgBR_H; // control point only matches p3 preceding + $p1y = $y00 + $h00; + $p2x = $x00 + $w00 - $d1 - $brbgBR_H; // control point only matches p4 preceding + $p2y = $y00 + $h00 - $bl; + $p3x = $x00 + $d1 + $brbgBL_H; + $p3y = $y00 + $h00 - $bl; + $p4x = $x00 + $d1 + $brbgBL_H; + $p4y = $y00 + $h00; + $p4c1y = $p4y - $bl / 2; + + if (-$d2 > min($brbgBR_H, $brbgBR_V) || $flatten) { + $p1x = $x00 + $w00 - $bl; + $p2x = $x00 + $w00 - $bl; + } + if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) { + $p3x = $x00 + $bl; + $p4x = $x00 + $bl; + } + + $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE); + $patch_array[3]['f'] = 2; + $patch_array[3]['points'] = [$p2x, $p2y, + $p3x, $p3y, $p3x, $p3y, $p3x, $p3y, + $p4x, $p4c1y, $p4x, $p4y, $p4x, $p4y, + $p1x, $p1y]; + $patch_array[3]['colors'] = [$col1, $col2]; + + // BOTTOM LEFT corner + $p1x = $x00 + $d1 + $brbgBL_H; + $p1c2x = $p1x - ($d2 + $brbgBL_H) * $mag; // control points only matches p3 preceding + $p1y = $y00 + $h00 - $bl; + $p2x = $x00 + $d1 + $brbgBL_H; + $p2c2x = $p2x - ($d1 + $brbgBL_H) * $mag; // control point only matches p4 preceding + $p2y = $y00 + $h00; + $p3x = $x00; + $p3c2x = $p3x + $bl / 2; + $p3y = $y00 + $h00 - $d1 - $brbgBL_V; + $p3c1y = $p3y + ($d1 + $brbgBL_V) * $mag; + $p4x = $x00 + $bl; + $p4y = $y00 + $h00 - $d1 - $brbgBL_V; + $p4c2y = $p4y + ($d2 + $brbgBL_V) * $mag; + if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) { + $p1x = $x00 + $bl; + $p1c2x = $p1x; + $p2x = $x00 + $bl; + $p2c2x = $p2x - $bl * $mag2; + $p3y = $y00 + $h00 - $bl; + $p3c1y = $p3y + $bl * $mag2; + $p4y = $y00 + $h00 - $bl; + $p4c2y = $p4y; + } + + $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1c2x) * Mpdf::SCALE, ($this->h - ($p1y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4c2y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE); + $patch_array[4]['f'] = 2; + $patch_array[4]['points'] = [$p2c2x, $p2y, + $p3x, $p3c1y, $p3x, $p3y, $p3c2x, $p3y, + $p4x, $p4y, $p4x, $p4y, $p4x, $p4c2y, + $p1c2x, $p1y]; + $patch_array[4]['colors'] = [$col2, $col1]; + + + // LEFT - joins on the right (C3-C4 of previous): f = 2 + $p1x = $x00; // control point only matches p3 preceding + $p1y = $y00 + $h00 - $d1 - $brbgBL_V; + $p2x = $x00 + $bl; // control point only matches p4 preceding + $p2y = $y00 + $h00 - $d1 - $brbgBL_V; + $p3x = $x00 + $bl; + $p3y = $y00 + $d1 + $brbgTL_V; + $p4x = $x00; + $p4c1x = $p4x + $bl / 2; + $p4y = $y00 + $d1 + $brbgTL_V; + if (-$d2 > min($brbgBL_H, $brbgBL_V) || $flatten) { + $p1y = $y00 + $h00 - $bl; + $p2y = $y00 + $h00 - $bl; + } + if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) { + $p3y = $y00 + $bl; + $p4y = $y00 + $bl; + } + + $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE); + $patch_array[5]['f'] = 2; + $patch_array[5]['points'] = [$p2x, $p2y, + $p3x, $p3y, $p3x, $p3y, $p3x, $p3y, + $p4c1x, $p4y, $p4x, $p4y, $p4x, $p4y, + $p1x, $p1y]; + $patch_array[5]['colors'] = [$col1, $col2]; + + // TOP LEFT corner + $p1x = $x00 + $bl; // control points only matches p3 preceding + $p1y = $y00 + $d1 + $brbgTL_V; + $p1c2y = $p1y - ($d2 + $brbgTL_V) * $mag; + $p2x = $x00; // control point only matches p4 preceding + $p2y = $y00 + $d1 + $brbgTL_V; + $p2c2y = $p2y - ($d1 + $brbgTL_V) * $mag; + $p3x = $x00 + $d1 + $brbgTL_H; + $p3c1x = $p3x - ($d1 + $brbgTL_H) * $mag; + $p3y = $y00; + $p3c2y = $p3y + $bl / 2; + $p4x = $x00 + $d1 + $brbgTL_H; + $p4c2x = $p4x - ($d2 + $brbgTL_H) * $mag; + $p4y = $y00 + $bl; + + if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) { + $p1y = $y00 + $bl; + $p1c2y = $p1y; + $p2y = $y00 + $bl; + $p2c2y = $p2y - $bl * $mag2; + $p3x = $x00 + $bl; + $p3c1x = $p3x - $bl * $mag2; + $p4x = $x00 + $bl; + $p4c2x = $p4x; + } + + $shadow .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($p1x) * Mpdf::SCALE, ($this->h - ($p1c2y)) * Mpdf::SCALE, ($p4c2x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE, ($p4x) * Mpdf::SCALE, ($this->h - ($p4y)) * Mpdf::SCALE); + $patch_array[6]['f'] = 2; + $patch_array[6]['points'] = [$p2x, $p2c2y, + $p3c1x, $p3y, $p3x, $p3y, $p3x, $p3c2y, + $p4x, $p4y, $p4x, $p4y, $p4c2x, $p4y, + $p1x, $p1c2y]; + $patch_array[6]['colors'] = [$col2, $col1]; + + + // TOP - joins on the right (C3-C4 of previous): f = 2 + $p1x = $x00 + $d1 + $brbgTL_H; // control point only matches p3 preceding + $p1y = $y00; + $p2x = $x00 + $d1 + $brbgTL_H; // control point only matches p4 preceding + $p2y = $y00 + $bl; + $p3x = $x00 + $w00 - $d1 - $brbgTR_H; + $p3y = $y00 + $bl; + $p4x = $x00 + $w00 - $d1 - $brbgTR_H; + $p4y = $y00; + $p4c1y = $p4y + $bl / 2; + if (-$d2 > min($brbgTL_H, $brbgTL_V) || $flatten) { + $p1x = $x00 + $bl; + $p2x = $x00 + $bl; + } + if (-$d2 > min($brbgTR_H, $brbgTR_V) || $flatten) { + $p3x = $x00 + $w00 - $bl; + $p4x = $x00 + $w00 - $bl; + } + + $shadow .= sprintf('%.3F %.3F l ', ($p3x ) * Mpdf::SCALE, ($this->h - ($p3y )) * Mpdf::SCALE); + $patch_array[7]['f'] = 2; + $patch_array[7]['points'] = [$p2x, $p2y, + $p3x, $p3y, $p3x, $p3y, $p3x, $p3y, + $p4x, $p4c1y, $p4x, $p4y, $p4x, $p4y, + $p1x, $p1y]; + $patch_array[7]['colors'] = [$col1, $col2]; + + $shadow .= ' h f Q ' . "\n"; // Close path and Fill the inner solid shadow + + if ($bl) { + $shadow .= $this->gradient->CoonsPatchMesh($x00, $y00, $w00, $h00, $patch_array, $x00, $x00 + $w00, $y00, $y00 + $h00, $colspace, true); + } + + if ($sh['x'] || $sh['y']) { + $shadow .= ' Q' . "\n"; // Shadow Offset + } + $shadow .= ' Q' . "\n"; // Ends path no-op & Sets the clipping path + } + } + + $s .= ' W n '; // Ends path no-op & Sets the clipping path + + if ($this->blk[$blvl]['bgcolor']) { + $this->pageBackgrounds[$blvl][] = [ + 'x' => $x0, + 'y' => $y0, + 'w' => $w, + 'h' => $h, + 'col' => $this->blk[$blvl]['bgcolorarray'], + 'clippath' => $s, + 'visibility' => $this->visibility, + 'shadow' => $shadow, + 'z-index' => $this->current_layer, + ]; + } elseif ($shadow) { + $this->pageBackgrounds[$blvl][] = [ + 'x' => 0, + 'y' => 0, + 'w' => 0, + 'h' => 0, + 'shadowonly' => true, + 'col' => '', + 'clippath' => '', + 'visibility' => $this->visibility, + 'shadow' => $shadow, + 'z-index' => $this->current_layer, + ]; + } + + /* -- BACKGROUNDS -- */ + if (isset($this->blk[$blvl]['gradient'])) { + $g = $this->gradient->parseBackgroundGradient($this->blk[$blvl]['gradient']); + if ($g) { + $gx = $x0; + $gy = $y0; + $this->pageBackgrounds[$blvl][] = [ + 'gradient' => true, + 'x' => $gx, + 'y' => $gy, + 'w' => $w, + 'h' => $h, + 'gradtype' => $g['type'], + 'stops' => $g['stops'], + 'colorspace' => $g['colorspace'], + 'coords' => $g['coords'], + 'extend' => $g['extend'], + 'clippath' => $s, + 'visibility' => $this->visibility, + 'z-index' => $this->current_layer + ]; + } + } + + if (isset($this->blk[$blvl]['background-image'])) { + if (isset($this->blk[$blvl]['background-image']['gradient']) && $this->blk[$blvl]['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $this->blk[$blvl]['background-image']['gradient'])) { + $g = $this->gradient->parseMozGradient($this->blk[$blvl]['background-image']['gradient']); + if ($g) { + $gx = $x0; + $gy = $y0; + // origin specifies the background-positioning-area (bpa) + if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') { + $gx += $this->blk[$blvl]['border_left']['w']; + $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']); + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $gy += $this->blk[$blvl]['border_top']['w']; + } + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $gy1 = $y1 - $this->blk[$blvl]['border_bottom']['w']; + } else { + $gy1 = $y1; + } + $h = $gy1 - $gy; + } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') { + $gx += $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left']; + $w -= ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']); + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $gy += $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top']; + } + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $gy1 = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']); + } else { + $gy1 = $y1 - $this->blk[$blvl]['padding_bottom']; + } + $h = $gy1 - $gy; + } + + if (isset($this->blk[$blvl]['background-image']['size']['w']) && $this->blk[$blvl]['background-image']['size']['w']) { + $size = $this->blk[$blvl]['background-image']['size']; + if ($size['w'] != 'contain' && $size['w'] != 'cover') { + if (stristr($size['w'], '%')) { + $size['w'] = (float) $size['w']; + $size['w'] /= 100; + $w *= $size['w']; + } elseif ($size['w'] != 'auto') { + $w = $size['w']; + } + if (stristr($size['h'], '%')) { + $size['h'] = (float) $size['h']; + $size['h'] /= 100; + $h *= $size['h']; + } elseif ($size['h'] != 'auto') { + $h = $size['h']; + } + } + } + $this->pageBackgrounds[$blvl][] = [ + 'gradient' => true, + 'x' => $gx, + 'y' => $gy, + 'w' => $w, + 'h' => $h, + 'gradtype' => $g['type'], + 'stops' => $g['stops'], + 'colorspace' => $g['colorspace'], + 'coords' => $g['coords'], + 'extend' => $g['extend'], + 'clippath' => $s, + 'visibility' => $this->visibility, + 'z-index' => $this->current_layer + ]; + } + + } else { + + $image_id = $this->blk[$blvl]['background-image']['image_id']; + $orig_w = $this->blk[$blvl]['background-image']['orig_w']; + $orig_h = $this->blk[$blvl]['background-image']['orig_h']; + $x_pos = $this->blk[$blvl]['background-image']['x_pos']; + $y_pos = $this->blk[$blvl]['background-image']['y_pos']; + $x_repeat = $this->blk[$blvl]['background-image']['x_repeat']; + $y_repeat = $this->blk[$blvl]['background-image']['y_repeat']; + $resize = $this->blk[$blvl]['background-image']['resize']; + $opacity = $this->blk[$blvl]['background-image']['opacity']; + $itype = $this->blk[$blvl]['background-image']['itype']; + $size = $this->blk[$blvl]['background-image']['size']; + // origin specifies the background-positioning-area (bpa) + + $bpa = ['x' => $x0, 'y' => $y0, 'w' => $w, 'h' => $h]; + + if ($this->blk[$blvl]['background-image']['origin'] == 'padding-box') { + + $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w']; + $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['border_right']['w']); + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w']; + } else { + $bpa['y'] = $y0; + } + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $bpay = $y1 - $this->blk[$blvl]['border_bottom']['w']; + } else { + $bpay = $y1; + } + $bpa['h'] = $bpay - $bpa['y']; + + } elseif ($this->blk[$blvl]['background-image']['origin'] == 'content-box') { + + $bpa['x'] = $x0 + $this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left']; + $bpa['w'] = $w - ($this->blk[$blvl]['border_left']['w'] + $this->blk[$blvl]['padding_left'] + $this->blk[$blvl]['border_right']['w'] + $this->blk[$blvl]['padding_right']); + if ($this->blk[$blvl]['border_top'] && $divider != 'pagetop' && !$continuingpage) { + $bpa['y'] = $y0 + $this->blk[$blvl]['border_top']['w'] + $this->blk[$blvl]['padding_top']; + } else { + $bpa['y'] = $y0 + $this->blk[$blvl]['padding_top']; + } + if ($this->blk[$blvl]['border_bottom'] && $blockstate != 1 && $divider != 'pagebottom') { + $bpay = $y1 - ($this->blk[$blvl]['border_bottom']['w'] + $this->blk[$blvl]['padding_bottom']); + } else { + $bpay = $y1 - $this->blk[$blvl]['padding_bottom']; + } + $bpa['h'] = $bpay - $bpa['y']; + + } + + $this->pageBackgrounds[$blvl][] = [ + 'x' => $x0, + 'y' => $y0, + 'w' => $w, + 'h' => $h, + 'image_id' => $image_id, + 'orig_w' => $orig_w, + 'orig_h' => $orig_h, + 'x_pos' => $x_pos, + 'y_pos' => $y_pos, + 'x_repeat' => $x_repeat, + 'y_repeat' => $y_repeat, + 'clippath' => $s, + 'resize' => $resize, + 'opacity' => $opacity, + 'itype' => $itype, + 'visibility' => $this->visibility, + 'z-index' => $this->current_layer, + 'size' => $size, + 'bpa' => $bpa + ]; + } + } + /* -- END BACKGROUNDS -- */ + + // Float DIV + $this->blk[$blvl]['bb_painted'][$this->page] = true; + } + /* -- BORDER-RADIUS -- */ + + function _EllipseArc($x0, $y0, $rx, $ry, $seg = 1, $part = false, $start = false) + { + // Anticlockwise segment 1-4 TR-TL-BL-BR (part=1 or 2) + $s = ''; + + if ($rx < 0) { + $rx = 0; + } + + if ($ry < 0) { + $ry = 0; + } + + $rx *= Mpdf::SCALE; + $ry *= Mpdf::SCALE; + + $astart = 0; + + if ($seg == 1) { // Top Right + $afinish = 90; + $nSeg = 4; + } elseif ($seg == 2) { // Top Left + $afinish = 180; + $nSeg = 8; + } elseif ($seg == 3) { // Bottom Left + $afinish = 270; + $nSeg = 12; + } else { // Bottom Right + $afinish = 360; + $nSeg = 16; + } + + $astart = deg2rad((float) $astart); + $afinish = deg2rad((float) $afinish); + + $totalAngle = $afinish - $astart; + $dt = $totalAngle / $nSeg; // segment angle + $dtm = $dt / 3; + $x0 *= Mpdf::SCALE; + $y0 = ($this->h - $y0) * Mpdf::SCALE; + $t1 = $astart; + $a0 = $x0 + ($rx * cos($t1)); + $b0 = $y0 + ($ry * sin($t1)); + $c0 = -$rx * sin($t1); + $d0 = $ry * cos($t1); + $op = false; + + for ($i = 1; $i <= $nSeg; $i++) { + // Draw this bit of the total curve + $t1 = ($i * $dt) + $astart; + $a1 = $x0 + ($rx * cos($t1)); + $b1 = $y0 + ($ry * sin($t1)); + $c1 = -$rx * sin($t1); + $d1 = $ry * cos($t1); + if ($i > ($nSeg - 4) && (!$part || ($part == 1 && $i <= $nSeg - 2) || ($part == 2 && $i > $nSeg - 2))) { + if ($start && !$op) { + $s .= sprintf('%.3F %.3F m ', $a0, $b0); + } + $s .= sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c ', ($a0 + ($c0 * $dtm)), ($b0 + ($d0 * $dtm)), ($a1 - ($c1 * $dtm)), ($b1 - ($d1 * $dtm)), $a1, $b1); + $op = true; + } + $a0 = $a1; + $b0 = $b1; + $c0 = $c1; + $d0 = $d1; + } + + return $s; + } + + /* -- END BORDER-RADIUS -- */ + + function PaintDivLnBorder($state = 0, $blvl = 0, $h = 0) + { + // $state = 0 normal; 1 top; 2 bottom; 3 top and bottom + $this->ColDetails[$this->CurrCol]['bottom_margin'] = $this->y + $h; + + $save_y = $this->y; + + $w = $this->blk[$blvl]['width']; + $x0 = $this->x; // left + $y0 = $this->y; // top + $x1 = $this->x + $w; // bottom + $y1 = $this->y + $h; // bottom + $continuingpage = (isset($this->blk[$blvl]['startpage']) && $this->blk[$blvl]['startpage'] != $this->page); + + if ($this->blk[$blvl]['border_top'] && ($state == 1 || $state == 3)) { + $tbd = $this->blk[$blvl]['border_top']; + if (isset($tbd['s']) && $tbd['s']) { + $this->_setBorderLine($tbd); + $this->y = $y0 + ($tbd['w'] / 2); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', $continuingpage, 'T'); + $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $this->y); + } else { + $this->SetLineJoin(0); + $this->SetLineCap(0); + $this->Line($x0, $this->y, $x0 + $w, $this->y); + } + $this->y += $tbd['w']; + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($this->blk[$blvl]['border_left']) { + $tbd = $this->blk[$blvl]['border_left']; + if (isset($tbd['s']) && $tbd['s']) { + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->y = $y0 + ($tbd['w'] / 2); + $this->_setDashBorder($tbd['style'], '', $continuingpage, 'L'); + $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + ($tbd['w'] / 2), $y0 + $h - ($tbd['w'] / 2)); + } else { + $this->y = $y0; + $this->SetLineJoin(0); + $this->SetLineCap(0); + $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + ($tbd['w'] / 2), $y0 + $h); + } + $this->y += $tbd['w']; + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($this->blk[$blvl]['border_right']) { + $tbd = $this->blk[$blvl]['border_right']; + if (isset($tbd['s']) && $tbd['s']) { + $this->_setBorderLine($tbd); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->y = $y0 + ($tbd['w'] / 2); + $this->_setDashBorder($tbd['style'], '', $continuingpage, 'R'); + $this->Line($x0 + $w - ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $y0 + $h - ($tbd['w'] / 2)); + } else { + $this->y = $y0; + $this->SetLineJoin(0); + $this->SetLineCap(0); + $this->Line($x0 + $w - ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $y0 + $h); + } + $this->y += $tbd['w']; + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($this->blk[$blvl]['border_bottom'] && $state > 1) { + $tbd = $this->blk[$blvl]['border_bottom']; + if (isset($tbd['s']) && $tbd['s']) { + $this->_setBorderLine($tbd); + $this->y = $y0 + $h - ($tbd['w'] / 2); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', $continuingpage, 'B'); + $this->Line($x0 + ($tbd['w'] / 2), $this->y, $x0 + $w - ($tbd['w'] / 2), $this->y); + } else { + $this->SetLineJoin(0); + $this->SetLineCap(0); + $this->Line($x0, $this->y, $x0 + $w, $this->y); + } + $this->y += $tbd['w']; + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + $this->SetDash(); + $this->y = $save_y; + } + + function PaintImgBorder($objattr, $is_table) + { + // Borders are disabled in columns - messes up the repositioning in printcolumnbuffer + if ($this->ColActive) { + return; + } // *COLUMNS* + if ($is_table) { + $k = $this->shrin_k; + } else { + $k = 1; + } + $h = (isset($objattr['BORDER-HEIGHT']) ? $objattr['BORDER-HEIGHT'] : 0); + $w = (isset($objattr['BORDER-WIDTH']) ? $objattr['BORDER-WIDTH'] : 0); + $x0 = (isset($objattr['BORDER-X']) ? $objattr['BORDER-X'] : 0); + $y0 = (isset($objattr['BORDER-Y']) ? $objattr['BORDER-Y'] : 0); + + // BORDERS + if ($objattr['border_top']) { + $tbd = $objattr['border_top']; + if (!empty($tbd['s'])) { + $this->_setBorderLine($tbd, $k); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', '', 'T'); + } + $this->Line($x0, $y0, $x0 + $w, $y0); + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($objattr['border_left']) { + $tbd = $objattr['border_left']; + if (!empty($tbd['s'])) { + $this->_setBorderLine($tbd, $k); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', '', 'L'); + } + $this->Line($x0, $y0, $x0, $y0 + $h); + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($objattr['border_right']) { + $tbd = $objattr['border_right']; + if (!empty($tbd['s'])) { + $this->_setBorderLine($tbd, $k); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', '', 'R'); + } + $this->Line($x0 + $w, $y0, $x0 + $w, $y0 + $h); + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + if ($objattr['border_bottom']) { + $tbd = $objattr['border_bottom']; + if (!empty($tbd['s'])) { + $this->_setBorderLine($tbd, $k); + if ($tbd['style'] == 'dotted' || $tbd['style'] == 'dashed') { + $this->_setDashBorder($tbd['style'], '', '', 'B'); + } + $this->Line($x0, $y0 + $h, $x0 + $w, $y0 + $h); + // Reset Corners and Dash off + $this->SetLineJoin(2); + $this->SetLineCap(2); + $this->SetDash(); + } + } + $this->SetDash(); + $this->SetAlpha(1); + } + + /* -- END HTML-CSS -- */ + + function Reset() + { + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + $this->SetAlpha(1); + $this->colorarray = ''; + + $this->spanbgcolorarray = ''; + $this->spanbgcolor = false; + $this->spanborder = false; + $this->spanborddet = []; + + $this->ResetStyles(); + + $this->HREF = ''; + $this->textparam = []; + $this->SetTextOutline(); + + $this->textvar = 0x00; // mPDF 5.7.1 + $this->OTLtags = []; + $this->textshadow = ''; + + $this->currentLang = $this->default_lang; // mPDF 6 + $this->RestrictUnicodeFonts($this->default_available_fonts); // mPDF 6 + $this->SetFont($this->default_font, '', 0, false); + $this->SetFontSize($this->default_font_size, false); + + $this->currentfontfamily = ''; + $this->currentfontsize = ''; + $this->currentfontstyle = ''; + + /* -- TABLES -- */ + if ($this->tableLevel && isset($this->table[1][1]['cellLineHeight'])) { + $this->SetLineHeight('', $this->table[1][1]['cellLineHeight']); // *TABLES* + } else { /* -- END TABLES -- */ + if (isset($this->blk[$this->blklvl]['line_height']) && $this->blk[$this->blklvl]['line_height']) { + $this->SetLineHeight('', $this->blk[$this->blklvl]['line_height']); // sets default line height + } + } + + $this->lSpacingCSS = ''; + $this->wSpacingCSS = ''; + $this->fixedlSpacing = false; + $this->minwSpacing = 0; + $this->SetDash(); // restore to no dash + $this->dash_on = false; + $this->dotted_on = false; + $this->divwidth = 0; + $this->divheight = 0; + $this->cellTextAlign = ''; + $this->cellLineHeight = ''; + $this->cellLineStackingStrategy = ''; + $this->cellLineStackingShift = ''; + $this->oldy = -1; + + $bodystyle = []; + if (isset($this->cssManager->CSS['BODY']['FONT-STYLE'])) { + $bodystyle['FONT-STYLE'] = $this->cssManager->CSS['BODY']['FONT-STYLE']; + } + if (isset($this->cssManager->CSS['BODY']['FONT-WEIGHT'])) { + $bodystyle['FONT-WEIGHT'] = $this->cssManager->CSS['BODY']['FONT-WEIGHT']; + } + if (isset($this->cssManager->CSS['BODY']['COLOR'])) { + $bodystyle['COLOR'] = $this->cssManager->CSS['BODY']['COLOR']; + } + if (isset($bodystyle)) { + $this->setCSS($bodystyle, 'BLOCK', 'BODY'); + } + } + + /* -- HTML-CSS -- */ + + function ReadMetaTags($html) + { + // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags) + $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; + $html = preg_replace($regexp, " \$1=\"\$2\"", $html); + if (preg_match('/(.*?)<\/title>/si', $html, $m)) { + $this->SetTitle($m[1]); + } + preg_match_all('/<meta [^>]*?(name|content)="([^>]*?)" [^>]*?(name|content)="([^>]*?)".*?>/si', $html, $aux); + $firstattr = $aux[1]; + $secondattr = $aux[3]; + for ($i = 0; $i < count($aux[0]); $i++) { + $name = ( strtoupper($firstattr[$i]) == "NAME" ) ? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]); + $content = ( strtoupper($firstattr[$i]) == "CONTENT" ) ? $aux[2][$i] : $aux[4][$i]; + switch ($name) { + case "KEYWORDS": + $this->SetKeywords($content); + break; + case "AUTHOR": + $this->SetAuthor($content); + break; + case "DESCRIPTION": + $this->SetSubject($content); + break; + } + } + } + + function ReadCharset($html) + { + // Charset conversion + if ($this->allow_charset_conversion) { + if (preg_match('/<head.*charset=([^\'\"\s]*).*<\/head>/si', $html, $m)) { + if (strtoupper($m[1]) != 'UTF-8') { + $this->charset_in = strtoupper($m[1]); + } + } + } + } + + function setCSS($arrayaux, $type = '', $tag = '') + { + // type= INLINE | BLOCK | TABLECELL // tag= BODY + if (!is_array($arrayaux)) { + return; // Removes PHP Warning + } + + // mPDF 5.7.3 inline text-decoration parameters + $preceeding_fontkey = $this->FontFamily . $this->FontStyle; + $preceeding_fontsize = $this->FontSize; + $spanbordset = false; + $spanbgset = false; + // mPDF 6 + $prevlevel = (($this->blklvl == 0) ? 0 : $this->blklvl - 1); + + // Set font size first so that e.g. MARGIN 0.83em works on font size for this element + if (isset($arrayaux['FONT-SIZE'])) { + $v = $arrayaux['FONT-SIZE']; + if (is_numeric($v[0]) || ($v[0] === '.')) { + if ($type == 'BLOCK' && $this->blklvl > 0 && isset($this->blk[$this->blklvl - 1]['InlineProperties']) && isset($this->blk[$this->blklvl - 1]['InlineProperties']['size'])) { + $mmsize = $this->sizeConverter->convert($v, $this->blk[$this->blklvl - 1]['InlineProperties']['size']); + } elseif ($type == 'TABLECELL') { + $mmsize = $this->sizeConverter->convert($v, $this->default_font_size / Mpdf::SCALE); + } else { + $mmsize = $this->sizeConverter->convert($v, $this->FontSize); + } + $this->SetFontSize($mmsize * (Mpdf::SCALE), false); // Get size in points (pt) + } else { + $v = strtoupper($v); + if (isset($this->fontsizes[$v])) { + $this->SetFontSize($this->fontsizes[$v] * $this->default_font_size, false); + } + } + if ($tag == 'BODY') { + $this->SetDefaultFontSize($this->FontSizePt); + } + } + + // mPDF 6 + if (isset($arrayaux['LANG']) && $arrayaux['LANG']) { + if ($this->autoLangToFont && !$this->usingCoreFont) { + if ($arrayaux['LANG'] != $this->default_lang && $arrayaux['LANG'] != 'UTF-8') { + list ($coreSuitable, $mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($arrayaux['LANG'], $this->useAdobeCJK); + if ($mpdf_pdf_unifont) { + $arrayaux['FONT-FAMILY'] = $mpdf_pdf_unifont; + } + if ($tag == 'BODY') { + $this->default_lang = $arrayaux['LANG']; + } + } + } + $this->currentLang = $arrayaux['LANG']; + } + + // FOR INLINE and BLOCK OR 'BODY' + if (isset($arrayaux['FONT-FAMILY'])) { + $v = $arrayaux['FONT-FAMILY']; + // If it is a font list, get all font types + $aux_fontlist = explode(",", $v); + $found = 0; + foreach ($aux_fontlist as $f) { + $fonttype = trim($f); + $fonttype = preg_replace('/["\']*(.*?)["\']*/', '\\1', $fonttype); + $fonttype = preg_replace('/ /', '', $fonttype); + $v = strtolower(trim($fonttype)); + if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { + $v = $this->fonttrans[$v]; + } + if ((!$this->onlyCoreFonts && in_array($v, $this->available_unifonts)) || + in_array($v, ['ccourier', 'ctimes', 'chelvetica']) || + ($this->onlyCoreFonts && in_array($v, ['courier', 'times', 'helvetica', 'arial'])) || + in_array($v, ['sjis', 'uhc', 'big5', 'gb'])) { + $fonttype = $v; + $found = 1; + break; + } + } + if (!$found) { + foreach ($aux_fontlist as $f) { + $fonttype = trim($f); + $fonttype = preg_replace('/["\']*(.*?)["\']*/', '\\1', $fonttype); + $fonttype = preg_replace('/ /', '', $fonttype); + $v = strtolower(trim($fonttype)); + if (isset($this->fonttrans[$v]) && $this->fonttrans[$v]) { + $v = $this->fonttrans[$v]; + } + if (in_array($v, $this->sans_fonts) || in_array($v, $this->serif_fonts) || in_array($v, $this->mono_fonts)) { + $fonttype = $v; + break; + } + } + } + + if ($tag == 'BODY') { + $this->SetDefaultFont($fonttype); + } + $this->SetFont($fonttype, $this->currentfontstyle, 0, false); + } else { + $this->SetFont($this->currentfontfamily, $this->currentfontstyle, 0, false); + } + + foreach ($arrayaux as $k => $v) { + if ($type != 'INLINE' && $tag != 'BODY' && $type != 'TABLECELL') { + switch ($k) { + // BORDERS + case 'BORDER-TOP': + $this->blk[$this->blklvl]['border_top'] = $this->border_details($v); + if ($this->blk[$this->blklvl]['border_top']['s']) { + $this->blk[$this->blklvl]['border'] = 1; + } + break; + case 'BORDER-BOTTOM': + $this->blk[$this->blklvl]['border_bottom'] = $this->border_details($v); + if ($this->blk[$this->blklvl]['border_bottom']['s']) { + $this->blk[$this->blklvl]['border'] = 1; + } + break; + case 'BORDER-LEFT': + $this->blk[$this->blklvl]['border_left'] = $this->border_details($v); + if ($this->blk[$this->blklvl]['border_left']['s']) { + $this->blk[$this->blklvl]['border'] = 1; + } + break; + case 'BORDER-RIGHT': + $this->blk[$this->blklvl]['border_right'] = $this->border_details($v); + if ($this->blk[$this->blklvl]['border_right']['s']) { + $this->blk[$this->blklvl]['border'] = 1; + } + break; + + // PADDING + case 'PADDING-TOP': + $this->blk[$this->blklvl]['padding_top'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'PADDING-BOTTOM': + $this->blk[$this->blklvl]['padding_bottom'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'PADDING-LEFT': + if (($tag == 'UL' || $tag == 'OL') && $v == 'auto') { + $this->blk[$this->blklvl]['padding_left'] = 'auto'; + break; + } + $this->blk[$this->blklvl]['padding_left'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'PADDING-RIGHT': + if (($tag == 'UL' || $tag == 'OL') && $v == 'auto') { + $this->blk[$this->blklvl]['padding_right'] = 'auto'; + break; + } + $this->blk[$this->blklvl]['padding_right'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + + // MARGINS + case 'MARGIN-TOP': + $tmp = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + if (isset($this->blk[$this->blklvl]['lastbottommargin'])) { + if ($tmp > $this->blk[$this->blklvl]['lastbottommargin']) { + $tmp -= $this->blk[$this->blklvl]['lastbottommargin']; + } else { + $tmp = 0; + } + } + $this->blk[$this->blklvl]['margin_top'] = $tmp; + break; + case 'MARGIN-BOTTOM': + $this->blk[$this->blklvl]['margin_bottom'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'MARGIN-LEFT': + $this->blk[$this->blklvl]['margin_left'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'MARGIN-RIGHT': + $this->blk[$this->blklvl]['margin_right'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + + /* -- BORDER-RADIUS -- */ + case 'BORDER-TOP-LEFT-RADIUS-H': + $this->blk[$this->blklvl]['border_radius_TL_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-TOP-LEFT-RADIUS-V': + $this->blk[$this->blklvl]['border_radius_TL_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-TOP-RIGHT-RADIUS-H': + $this->blk[$this->blklvl]['border_radius_TR_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-TOP-RIGHT-RADIUS-V': + $this->blk[$this->blklvl]['border_radius_TR_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-BOTTOM-LEFT-RADIUS-H': + $this->blk[$this->blklvl]['border_radius_BL_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-BOTTOM-LEFT-RADIUS-V': + $this->blk[$this->blklvl]['border_radius_BL_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-BOTTOM-RIGHT-RADIUS-H': + $this->blk[$this->blklvl]['border_radius_BR_H'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + case 'BORDER-BOTTOM-RIGHT-RADIUS-V': + $this->blk[$this->blklvl]['border_radius_BR_V'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + break; + /* -- END BORDER-RADIUS -- */ + + case 'BOX-SHADOW': + $bs = $this->cssManager->setCSSboxshadow($v); + if ($bs) { + $this->blk[$this->blklvl]['box_shadow'] = $bs; + } + break; + + case 'BACKGROUND-CLIP': + if (strtoupper($v) == 'PADDING-BOX') { + $this->blk[$this->blklvl]['background_clip'] = 'padding-box'; + } elseif (strtoupper($v) == 'CONTENT-BOX') { + $this->blk[$this->blklvl]['background_clip'] = 'content-box'; + } + break; + + case 'PAGE-BREAK-AFTER': + if (strtoupper($v) == 'AVOID') { + $this->blk[$this->blklvl]['page_break_after_avoid'] = true; + } elseif (strtoupper($v) == 'ALWAYS' || strtoupper($v) == 'LEFT' || strtoupper($v) == 'RIGHT') { + $this->blk[$this->blklvl]['page_break_after'] = strtoupper($v); + } + break; + + // mPDF 6 pagebreaktype + case 'BOX-DECORATION-BREAK': + if (strtoupper($v) == 'CLONE') { + $this->blk[$this->blklvl]['box_decoration_break'] = 'clone'; + } elseif (strtoupper($v) == 'SLICE') { + $this->blk[$this->blklvl]['box_decoration_break'] = 'slice'; + } + break; + + case 'WIDTH': + if (strtoupper($v) != 'AUTO') { + $this->blk[$this->blklvl]['css_set_width'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false); + } + break; + + // mPDF 6 Lists + // LISTS + case 'LIST-STYLE-TYPE': + $this->blk[$this->blklvl]['list_style_type'] = strtolower($v); + break; + case 'LIST-STYLE-IMAGE': + $this->blk[$this->blklvl]['list_style_image'] = strtolower($v); + break; + case 'LIST-STYLE-POSITION': + $this->blk[$this->blklvl]['list_style_position'] = strtolower($v); + break; + }//end of switch($k) + } + + + if ($type != 'INLINE' && $type != 'TABLECELL') { // All block-level, including BODY tag + switch ($k) { + case 'TEXT-INDENT': + // Computed value - to inherit + $this->blk[$this->blklvl]['text_indent'] = $this->sizeConverter->convert($v, $this->blk[$prevlevel]['inner_width'], $this->FontSize, false) . 'mm'; + break; + + case 'MARGIN-COLLAPSE': // Custom tag to collapse margins at top and bottom of page + if (strtoupper($v) == 'COLLAPSE') { + $this->blk[$this->blklvl]['margin_collapse'] = true; + } + break; + + case 'LINE-HEIGHT': + $this->blk[$this->blklvl]['line_height'] = $this->fixLineheight($v); + if (!$this->blk[$this->blklvl]['line_height']) { + $this->blk[$this->blklvl]['line_height'] = 'N'; + } // mPDF 6 + break; + + // mPDF 6 + case 'LINE-STACKING-STRATEGY': + $this->blk[$this->blklvl]['line_stacking_strategy'] = strtolower($v); + break; + + case 'LINE-STACKING-SHIFT': + $this->blk[$this->blklvl]['line_stacking_shift'] = strtolower($v); + break; + + case 'TEXT-ALIGN': // left right center justify + switch (strtoupper($v)) { + case 'LEFT': + $this->blk[$this->blklvl]['align'] = "L"; + break; + case 'CENTER': + $this->blk[$this->blklvl]['align'] = "C"; + break; + case 'RIGHT': + $this->blk[$this->blklvl]['align'] = "R"; + break; + case 'JUSTIFY': + $this->blk[$this->blklvl]['align'] = "J"; + break; + } + break; + + /* -- BACKGROUNDS -- */ + case 'BACKGROUND-GRADIENT': + if ($type == 'BLOCK') { + $this->blk[$this->blklvl]['gradient'] = $v; + } + break; + /* -- END BACKGROUNDS -- */ + + case 'DIRECTION': + if ($v) { + $this->blk[$this->blklvl]['direction'] = strtolower($v); + } + break; + } + } + + // FOR INLINE ONLY + if ($type == 'INLINE') { + switch ($k) { + case 'DISPLAY': + if (strtoupper($v) == 'NONE') { + $this->inlineDisplayOff = true; + } + break; + case 'DIRECTION': + break; + } + } + // FOR INLINE ONLY + if ($type == 'INLINE') { + switch ($k) { + // BORDERS + case 'BORDER-TOP': + $this->spanborddet['T'] = $this->border_details($v); + $this->spanborder = true; + $spanbordset = true; + break; + case 'BORDER-BOTTOM': + $this->spanborddet['B'] = $this->border_details($v); + $this->spanborder = true; + $spanbordset = true; + break; + case 'BORDER-LEFT': + $this->spanborddet['L'] = $this->border_details($v); + $this->spanborder = true; + $spanbordset = true; + break; + case 'BORDER-RIGHT': + $this->spanborddet['R'] = $this->border_details($v); + $this->spanborder = true; + $spanbordset = true; + break; + case 'VISIBILITY': // block is set in OpenTag + $v = strtolower($v); + if ($v == 'visible' || $v == 'hidden' || $v == 'printonly' || $v == 'screenonly') { + $this->textparam['visibility'] = $v; + } + break; + }//end of switch($k) + } + + if ($type != 'TABLECELL') { + // FOR INLINE and BLOCK + switch ($k) { + case 'TEXT-ALIGN': // left right center justify + if (strtoupper($v) == 'NOJUSTIFY' && $this->blk[$this->blklvl]['align'] == "J") { + $this->blk[$this->blklvl]['align'] = ""; + } + break; + // bgcolor only - to stay consistent with original html2fpdf + case 'BACKGROUND': + case 'BACKGROUND-COLOR': + $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings); + if ($cor) { + if ($tag == 'BODY') { + $this->bodyBackgroundColor = $cor; + } elseif ($type == 'INLINE') { + $this->spanbgcolorarray = $cor; + $this->spanbgcolor = true; + $spanbgset = true; + } else { + $this->blk[$this->blklvl]['bgcolorarray'] = $cor; + $this->blk[$this->blklvl]['bgcolor'] = true; + } + } elseif ($type != 'INLINE') { + if ($this->ColActive) { + $this->blk[$this->blklvl]['bgcolorarray'] = $this->blk[$prevlevel]['bgcolorarray']; + $this->blk[$this->blklvl]['bgcolor'] = $this->blk[$prevlevel]['bgcolor']; + } + } + break; + + case 'VERTICAL-ALIGN': // super and sub only dealt with here e.g. <SUB> and <SUP> + switch (strtoupper($v)) { + case 'SUPER': + $this->textvar = ($this->textvar | TextVars::FA_SUPERSCRIPT); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + $this->textparam['text-baseline'] += ($this->baselineSup) * $preceeding_fontsize; + } else { + $this->textparam['text-baseline'] = ($this->baselineSup) * $preceeding_fontsize; + } + break; + case 'SUB': + $this->textvar = ($this->textvar | TextVars::FA_SUBSCRIPT); + $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + $this->textparam['text-baseline'] += ($this->baselineSub) * $preceeding_fontsize; + } else { + $this->textparam['text-baseline'] = ($this->baselineSub) * $preceeding_fontsize; + } + break; + case 'BASELINE': + $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT); + $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + unset($this->textparam['text-baseline']); + } + break; + // mPDF 5.7.3 inline text-decoration parameters + default: + $lh = $this->_computeLineheight($this->blk[$this->blklvl]['line_height']); + $sz = $this->sizeConverter->convert($v, $lh, $this->FontSize, false); + $this->textvar = ($this->textvar & ~TextVars::FA_SUBSCRIPT); + $this->textvar = ($this->textvar & ~TextVars::FA_SUPERSCRIPT); + if ($sz) { + if ($sz > 0) { + $this->textvar = ($this->textvar | TextVars::FA_SUPERSCRIPT); + } else { + $this->textvar = ($this->textvar | TextVars::FA_SUBSCRIPT); + } + if (isset($this->textparam['text-baseline'])) { + $this->textparam['text-baseline'] += $sz; + } else { + $this->textparam['text-baseline'] = $sz; + } + } + } + break; + }//end of switch($k) + } + + + // FOR ALL + switch ($k) { + case 'LETTER-SPACING': + $this->lSpacingCSS = $v; + if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') { + $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize); + } + break; + + case 'WORD-SPACING': + $this->wSpacingCSS = $v; + if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') { + $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize); + } + break; + + case 'FONT-STYLE': // italic normal oblique + switch (strtoupper($v)) { + case 'ITALIC': + case 'OBLIQUE': + $this->SetStyle('I', true); + break; + case 'NORMAL': + $this->SetStyle('I', false); + break; + } + break; + + case 'FONT-WEIGHT': // normal bold // Does not support: bolder, lighter, 100..900(step value=100) + switch (strtoupper($v)) { + case 'BOLD': + $this->SetStyle('B', true); + break; + case 'NORMAL': + $this->SetStyle('B', false); + break; + } + break; + + case 'FONT-KERNING': + if (strtoupper($v) == 'NORMAL' || (strtoupper($v) == 'AUTO' && $this->useKerning)) { + /* -- OTL -- */ + if ($this->CurrentFont['haskernGPOS']) { + if (isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] .= ' kern'; + } else { + $this->OTLtags['Plus'] = ' kern'; + } + } /* -- END OTL -- */ else { // *OTL* + $this->textvar = ($this->textvar | TextVars::FC_KERNING); + } // *OTL* + } elseif (strtoupper($v) == 'NONE' || (strtoupper($v) == 'AUTO' && !$this->useKerning)) { + if (isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = str_replace('kern', '', $this->OTLtags['Plus']); // *OTL* + } + if (isset($this->OTLtags['FFPlus'])) { + $this->OTLtags['FFPlus'] = preg_replace('/kern[\d]*/', '', $this->OTLtags['FFPlus']); + } + $this->textvar = ($this->textvar & ~TextVars::FC_KERNING); + } + break; + + /* -- OTL -- */ + case 'FONT-LANGUAGE-OVERRIDE': + $v = strtoupper($v); + if (strpos($v, 'NORMAL') !== false) { + $this->fontLanguageOverride = ''; + } else { + $this->fontLanguageOverride = trim($v); + } + break; + + + case 'FONT-VARIANT-POSITION': + if (isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = str_replace(['sups', 'subs'], '', $this->OTLtags['Plus']); + } + switch (strtoupper($v)) { + case 'SUPER': + $this->OTLtags['Plus'] .= ' sups'; + break; + case 'SUB': + $this->OTLtags['Plus'] .= ' subs'; + break; + case 'NORMAL': + break; + } + break; + + case 'FONT-VARIANT-CAPS': + $v = strtoupper($v); + if (!isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = ''; + } + $this->OTLtags['Plus'] = str_replace(['c2sc', 'smcp', 'c2pc', 'pcap', 'unic', 'titl'], '', $this->OTLtags['Plus']); + $this->textvar = ($this->textvar & ~TextVars::FC_SMALLCAPS); // ?????????????? <small-caps> + if (strpos($v, 'ALL-SMALL-CAPS') !== false) { + $this->OTLtags['Plus'] .= ' c2sc smcp'; + } elseif (strpos($v, 'SMALL-CAPS') !== false) { + if (isset($this->CurrentFont['hassmallcapsGSUB']) && $this->CurrentFont['hassmallcapsGSUB']) { + $this->OTLtags['Plus'] .= ' smcp'; + } else { + $this->textvar = ($this->textvar | TextVars::FC_SMALLCAPS); + } + } elseif (strpos($v, 'ALL-PETITE-CAPS') !== false) { + $this->OTLtags['Plus'] .= ' c2pc pcap'; + } elseif (strpos($v, 'PETITE-CAPS') !== false) { + $this->OTLtags['Plus'] .= ' pcap'; + } elseif (strpos($v, 'UNICASE') !== false) { + $this->OTLtags['Plus'] .= ' unic'; + } elseif (strpos($v, 'TITLING-CAPS') !== false) { + $this->OTLtags['Plus'] .= ' titl'; + } + break; + + case 'FONT-VARIANT-LIGATURES': + $v = strtoupper($v); + if (!isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = ''; + } + if (!isset($this->OTLtags['Minus'])) { + $this->OTLtags['Minus'] = ''; + } + if (strpos($v, 'NORMAL') !== false) { + $this->OTLtags['Minus'] = str_replace(['liga', 'clig', 'calt'], '', $this->OTLtags['Minus']); + $this->OTLtags['Plus'] = str_replace(['dlig', 'hlig'], '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'NONE') !== false) { + $this->OTLtags['Minus'] .= ' liga clig calt'; + $this->OTLtags['Plus'] = str_replace(['dlig', 'hlig'], '', $this->OTLtags['Plus']); + } + if (strpos($v, 'NO-COMMON-LIGATURES') !== false) { + $this->OTLtags['Minus'] .= ' liga clig'; + } elseif (strpos($v, 'COMMON-LIGATURES') !== false) { + $this->OTLtags['Minus'] = str_replace(['liga', 'clig'], '', $this->OTLtags['Minus']); + } + if (strpos($v, 'NO-CONTEXTUAL') !== false) { + $this->OTLtags['Minus'] .= ' calt'; + } elseif (strpos($v, 'CONTEXTUAL') !== false) { + $this->OTLtags['Minus'] = str_replace('calt', '', $this->OTLtags['Minus']); + } + if (strpos($v, 'NO-DISCRETIONARY-LIGATURES') !== false) { + $this->OTLtags['Plus'] = str_replace('dlig', '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'DISCRETIONARY-LIGATURES') !== false) { + $this->OTLtags['Plus'] .= ' dlig'; + } + if (strpos($v, 'NO-HISTORICAL-LIGATURES') !== false) { + $this->OTLtags['Plus'] = str_replace('hlig', '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'HISTORICAL-LIGATURES') !== false) { + $this->OTLtags['Plus'] .= ' hlig'; + } + + break; + + case 'FONT-VARIANT-NUMERIC': + $v = strtoupper($v); + if (!isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = ''; + } + if (strpos($v, 'NORMAL') !== false) { + $this->OTLtags['Plus'] = str_replace(['ordn', 'zero', 'lnum', 'onum', 'pnum', 'tnum', 'frac', 'afrc'], '', $this->OTLtags['Plus']); + } + if (strpos($v, 'ORDINAL') !== false) { + $this->OTLtags['Plus'] .= ' ordn'; + } + if (strpos($v, 'SLASHED-ZERO') !== false) { + $this->OTLtags['Plus'] .= ' zero'; + } + if (strpos($v, 'LINING-NUMS') !== false) { + $this->OTLtags['Plus'] .= ' lnum'; + $this->OTLtags['Plus'] = str_replace('onum', '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'OLDSTYLE-NUMS') !== false) { + $this->OTLtags['Plus'] .= ' onum'; + $this->OTLtags['Plus'] = str_replace('lnum', '', $this->OTLtags['Plus']); + } + if (strpos($v, 'PROPORTIONAL-NUMS') !== false) { + $this->OTLtags['Plus'] .= ' pnum'; + $this->OTLtags['Plus'] = str_replace('tnum', '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'TABULAR-NUMS') !== false) { + $this->OTLtags['Plus'] .= ' tnum'; + $this->OTLtags['Plus'] = str_replace('pnum', '', $this->OTLtags['Plus']); + } + if (strpos($v, 'DIAGONAL-FRACTIONS') !== false) { + $this->OTLtags['Plus'] .= ' frac'; + $this->OTLtags['Plus'] = str_replace('afrc', '', $this->OTLtags['Plus']); + } elseif (strpos($v, 'STACKED-FRACTIONS') !== false) { + $this->OTLtags['Plus'] .= ' afrc'; + $this->OTLtags['Plus'] = str_replace('frac', '', $this->OTLtags['Plus']); + } + break; + + case 'FONT-VARIANT-ALTERNATES': // Only supports historical-forms + $v = strtoupper($v); + if (!isset($this->OTLtags['Plus'])) { + $this->OTLtags['Plus'] = ''; + } + if (strpos($v, 'NORMAL') !== false) { + $this->OTLtags['Plus'] = str_replace('hist', '', $this->OTLtags['Plus']); + } + if (strpos($v, 'HISTORICAL-FORMS') !== false) { + $this->OTLtags['Plus'] .= ' hist'; + } + break; + + + case 'FONT-FEATURE-SETTINGS': + $v = strtolower($v); + if (strpos($v, 'normal') !== false) { + $this->OTLtags['FFMinus'] = ''; + $this->OTLtags['FFPlus'] = ''; + } else { + if (!isset($this->OTLtags['FFPlus'])) { + $this->OTLtags['FFPlus'] = ''; + } + if (!isset($this->OTLtags['FFMinus'])) { + $this->OTLtags['FFMinus'] = ''; + } + $tags = preg_split('/[,]/', $v); + foreach ($tags as $t) { + if (preg_match('/[\"\']([a-zA-Z0-9]{4})[\"\']\s*(on|off|\d*){0,1}/', $t, $m)) { + if ($m[2] == 'off' || $m[2] === '0') { + if (strpos($this->OTLtags['FFMinus'], $m[1]) === false) { + $this->OTLtags['FFMinus'] .= ' ' . $m[1]; + } + $this->OTLtags['FFPlus'] = preg_replace('/' . $m[1] . '[\d]*/', '', $this->OTLtags['FFPlus']); + } else { + if ($m[2] == 'on') { + $m[2] = '1'; + } + if (strpos($this->OTLtags['FFPlus'], $m[1]) === false) { + $this->OTLtags['FFPlus'] .= ' ' . $m[1] . $m[2]; + } + $this->OTLtags['FFMinus'] = str_replace($m[1], '', $this->OTLtags['FFMinus']); + } + } + } + } + break; + /* -- END OTL -- */ + + + case 'TEXT-TRANSFORM': // none uppercase lowercase // Does support: capitalize + switch (strtoupper($v)) { // Not working 100% + case 'CAPITALIZE': + $this->textvar = ($this->textvar | TextVars::FT_CAPITALIZE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1 + break; + case 'UPPERCASE': + $this->textvar = ($this->textvar | TextVars::FT_UPPERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1 + break; + case 'LOWERCASE': + $this->textvar = ($this->textvar | TextVars::FT_LOWERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1 + break; + case 'NONE': + break; + $this->textvar = ($this->textvar & ~TextVars::FT_UPPERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_LOWERCASE); // mPDF 5.7.1 + $this->textvar = ($this->textvar & ~TextVars::FT_CAPITALIZE); // mPDF 5.7.1 + } + break; + + case 'TEXT-SHADOW': + $ts = $this->cssManager->setCSStextshadow($v); + if ($ts) { + $this->textshadow = $ts; + } + break; + + case 'HYPHENS': + if (strtoupper($v) == 'NONE') { + $this->textparam['hyphens'] = 2; + } elseif (strtoupper($v) == 'AUTO') { + $this->textparam['hyphens'] = 1; + } elseif (strtoupper($v) == 'MANUAL') { + $this->textparam['hyphens'] = 0; + } + break; + + case 'TEXT-OUTLINE': + if (strtoupper($v) == 'NONE') { + $this->textparam['outline-s'] = false; + } + break; + + case 'TEXT-OUTLINE-WIDTH': + case 'OUTLINE-WIDTH': + switch (strtoupper($v)) { + case 'THIN': + $v = '0.03em'; + break; + case 'MEDIUM': + $v = '0.05em'; + break; + case 'THICK': + $v = '0.07em'; + break; + } + $w = $this->sizeConverter->convert($v, $this->FontSize, $this->FontSize); + if ($w) { + $this->textparam['outline-WIDTH'] = $w; + $this->textparam['outline-s'] = true; + } else { + $this->textparam['outline-s'] = false; + } + break; + + case 'TEXT-OUTLINE-COLOR': + case 'OUTLINE-COLOR': + if (strtoupper($v) == 'INVERT') { + if ($this->colorarray) { + $cor = $this->colorarray; + $this->textparam['outline-COLOR'] = $this->colorConverter->invert($cor); + } else { + $this->textparam['outline-COLOR'] = $this->colorConverter->convert(255, $this->PDFAXwarnings); + } + } else { + $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings); + if ($cor) { + $this->textparam['outline-COLOR'] = $cor; + } + } + break; + + case 'COLOR': // font color + $cor = $this->colorConverter->convert($v, $this->PDFAXwarnings); + if ($cor) { + $this->colorarray = $cor; + $this->SetTColor($cor); + } + break; + }//end of switch($k) + }//end of foreach + // mPDF 5.7.3 inline text-decoration parameters + // Needs to be set at the end - after vertical-align = super/sub, so that textparam['text-baseline'] is set + if (isset($arrayaux['TEXT-DECORATION'])) { + $v = $arrayaux['TEXT-DECORATION']; // none underline line-through (strikeout) // Does not support: blink + if (stristr($v, 'LINE-THROUGH')) { + $this->textvar = ($this->textvar | TextVars::FD_LINETHROUGH); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + $this->textparam['s-decoration']['baseline'] = $this->textparam['text-baseline']; + } else { + $this->textparam['s-decoration']['baseline'] = 0; + } + $this->textparam['s-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle; + $this->textparam['s-decoration']['fontsize'] = $this->FontSize; + $this->textparam['s-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG + } + if (stristr($v, 'UNDERLINE')) { + $this->textvar = ($this->textvar | TextVars::FD_UNDERLINE); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + $this->textparam['u-decoration']['baseline'] = $this->textparam['text-baseline']; + } else { + $this->textparam['u-decoration']['baseline'] = 0; + } + $this->textparam['u-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle; + $this->textparam['u-decoration']['fontsize'] = $this->FontSize; + $this->textparam['u-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG + } + if (stristr($v, 'OVERLINE')) { + $this->textvar = ($this->textvar | TextVars::FD_OVERLINE); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['text-baseline'])) { + $this->textparam['o-decoration']['baseline'] = $this->textparam['text-baseline']; + } else { + $this->textparam['o-decoration']['baseline'] = 0; + } + $this->textparam['o-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle; + $this->textparam['o-decoration']['fontsize'] = $this->FontSize; + $this->textparam['o-decoration']['color'] = strtoupper($this->TextColor); // change 0 0 0 rg to 0 0 0 RG + } + if (stristr($v, 'NONE')) { + $this->textvar = ($this->textvar & ~TextVars::FD_UNDERLINE); + $this->textvar = ($this->textvar & ~TextVars::FD_LINETHROUGH); + $this->textvar = ($this->textvar & ~TextVars::FD_OVERLINE); + // mPDF 5.7.3 inline text-decoration parameters + if (isset($this->textparam['u-decoration'])) { + unset($this->textparam['u-decoration']); + } + if (isset($this->textparam['s-decoration'])) { + unset($this->textparam['s-decoration']); + } + if (isset($this->textparam['o-decoration'])) { + unset($this->textparam['o-decoration']); + } + } + } + // mPDF 6 + if ($spanbordset) { // BORDER has been set on this INLINE element + if (isset($this->textparam['text-baseline'])) { + $this->textparam['bord-decoration']['baseline'] = $this->textparam['text-baseline']; + } else { + $this->textparam['bord-decoration']['baseline'] = 0; + } + $this->textparam['bord-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle; + $this->textparam['bord-decoration']['fontsize'] = $this->FontSize; + } + if ($spanbgset) { // BACKGROUND[-COLOR] has been set on this INLINE element + if (isset($this->textparam['text-baseline'])) { + $this->textparam['bg-decoration']['baseline'] = $this->textparam['text-baseline']; + } else { + $this->textparam['bg-decoration']['baseline'] = 0; + } + $this->textparam['bg-decoration']['fontkey'] = $this->FontFamily . $this->FontStyle; + $this->textparam['bg-decoration']['fontsize'] = $this->FontSize; + } + } + + /* -- END HTML-CSS -- */ + + function SetStyle($tag, $enable) + { + $this->$tag = $enable; + $style = ''; + foreach (['B', 'I'] as $s) { + if ($this->$s) { + $style .= $s; + } + } + $this->currentfontstyle = $style; + $this->SetFont('', $style, 0, false); + } + + // Set multiple styles at one time + function SetStylesArray($arr) + { + $style = ''; + foreach (['B', 'I'] as $s) { + if (isset($arr[$s])) { + if ($arr[$s]) { + $this->$s = true; + $style .= $s; + } else { + $this->$s = false; + } + } elseif ($this->$s) { + $style .= $s; + } + } + $this->currentfontstyle = $style; + $this->SetFont('', $style, 0, false); + } + + // Set multiple styles at one $str e.g. "BI" + function SetStyles($str) + { + $style = ''; + foreach (['B', 'I'] as $s) { + if (strpos($str, $s) !== false) { + $this->$s = true; + $style .= $s; + } else { + $this->$s = false; + } + } + $this->currentfontstyle = $style; + $this->SetFont('', $style, 0, false); + } + + function ResetStyles() + { + foreach (['B', 'I'] as $s) { + $this->$s = false; + } + $this->currentfontstyle = ''; + $this->SetFont('', '', 0, false); + } + + function DisableTags($str = '') + { + if ($str == '') { // enable all tags + // Insert new supported tags in the long string below. + $this->enabledtags = "<a><acronym><address><article><aside><b><bdi><bdo><big><blockquote><br><caption><center><cite><code><del><details><dd><div><dl><dt><em><fieldset><figcaption><figure><font><form><h1><h2><h3><h4><h5><h6><hgroup><hr><i><img><input><ins><kbd><legend><li><main><mark><meter><nav><ol><option><p><pre><progress><q><s><samp><section><select><small><span><strike><strong><sub><summary><sup><table><tbody><td><template><textarea><tfoot><th><thead><time><tr><tt><u><ul><var><footer><header><annotation><bookmark><textcircle><barcode><dottab><indexentry><indexinsert><watermarktext><watermarkimage><tts><ttz><tta><column_break><columnbreak><newcolumn><newpage><page_break><pagebreak><formfeed><columns><toc><tocentry><tocpagebreak><pageheader><pagefooter><setpageheader><setpagefooter><sethtmlpageheader><sethtmlpagefooter>"; + } else { + $str = explode(",", $str); + foreach ($str as $v) { + $this->enabledtags = str_replace(trim($v), '', $this->enabledtags); + } + } + } + + /* -- TABLES -- */ + + function TableCheckMinWidth($maxwidth, $forcewrap = 0, $textbuffer = [], $checkletter = false) + { + // mPDF 6 + $acclength = 0; // mPDF 6 (accumulated length across > 1 chunk) + $acclongest = 0; // mPDF 6 (accumulated length max across > 1 chunk) + $biggestword = 0; + $toonarrow = false; + if ((count($textbuffer) == 0) or ( (count($textbuffer) == 1) && ($textbuffer[0][0] == ''))) { + return 0; + } + + foreach ($textbuffer as $chunk) { + $line = $chunk[0]; + $OTLdata = (isset($chunk[18]) ? $chunk[18] : null); + + // mPDF ITERATION + if ($this->iterationCounter) { + $line = preg_replace('/{iteration ([a-zA-Z0-9_]+)}/', '\\1', $line); + } + + // IMAGES & FORM ELEMENTS + if (substr($line, 0, 3) == "\xbb\xa4\xac") { // inline object - FORM element or IMAGE! + $objattr = $this->_getObjAttr($line); + if ($objattr['type'] != 'hr' && isset($objattr['width']) && ($objattr['width'] / $this->shrin_k) > ($maxwidth + 0.0001)) { + if (($objattr['width'] / $this->shrin_k) > $biggestword) { + $biggestword = ($objattr['width'] / $this->shrin_k); + } + $toonarrow = true; + } + continue; + } + + if ($line == "\n") { + $acclength = 0; // mPDF 6 (accumulated length across > 1 chunk) + continue; + } + $line = trim($line); + if (!empty($OTLdata)) { + $this->otl->trimOTLdata($OTLdata, true, true); + } // *OTL* + // SET FONT SIZE/STYLE from $chunk[n] + // FONTSIZE + if (isset($chunk[11]) and $chunk[11] != '') { + if ($this->shrin_k) { + $this->SetFontSize($chunk[11] / $this->shrin_k, false); + } else { + $this->SetFontSize($chunk[11], false); + } + } + // FONTFAMILY + if (isset($chunk[4]) and $chunk[4] != '') { + $font = $this->SetFont($chunk[4], $this->FontStyle, 0, false); + } + // B I + if (isset($chunk[2]) and $chunk[2] != '') { + $this->SetStyles($chunk[2]); + } + + $lbw = $rbw = 0; // Border widths + if (isset($chunk[16]) && !empty($chunk[16])) { // Border + $this->spanborddet = $chunk[16]; + $lbw = (isset($this->spanborddet['L']['w']) ? $this->spanborddet['L']['w'] : 0); + $rbw = (isset($this->spanborddet['R']['w']) ? $this->spanborddet['R']['w'] : 0); + } + if (isset($chunk[15])) { // Word spacing + $this->wSpacingCSS = $chunk[15]; + if ($this->wSpacingCSS && strtoupper($this->wSpacingCSS) != 'NORMAL') { + $this->minwSpacing = $this->sizeConverter->convert($this->wSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3 + } + } + if (isset($chunk[14])) { // Letter spacing + $this->lSpacingCSS = $chunk[14]; + if (($this->lSpacingCSS || $this->lSpacingCSS === '0') && strtoupper($this->lSpacingCSS) != 'NORMAL') { + $this->fixedlSpacing = $this->sizeConverter->convert($this->lSpacingCSS, $this->FontSize) / $this->shrin_k; // mPDF 5.7.3 + } + } + if (isset($chunk[8])) { // mPDF 5.7.1 + $this->textvar = $chunk[8]; + } + + // mPDF 6 + // If overflow==wrap ($checkletter) OR (No word breaks and contains CJK) + if ($checkletter || (!preg_match('/(\xe2\x80\x8b| )/', trim($line)) && preg_match("/([" . $this->pregCJKchars . "])/u", $line) )) { + if (preg_match("/([" . $this->pregCJKchars . "])/u", $line)) { + $checkCJK = true; + } else { + $checkCJK = false; + } + + $letters = preg_split('//u', $line); + foreach ($letters as $k => $letter) { + // mPDF 6 + if ($checkCJK) { + if (preg_match("/[" . $this->CJKleading . "]/u", $letter) && $k > 0) { + $letter = $letters[$k - 1] . $letter; + } + if (preg_match("/[" . $this->CJKfollowing . "]/u", $letter) && $k < (count($letters) - 1)) { + $letter = $letter . $letters[$k + 1]; + } + } + + $letterwidth = $this->GetStringWidth($letter, false, false, $chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here + // so don't have to split OTLdata for each word + if ($k == 0) { + $letterwidth += $lbw; + } + if ($k == (count($letters) - 1)) { + $letterwidth += $rbw; + } + + // Warn user that maxwidth is insufficient + if ($letterwidth > $maxwidth + 0.0001) { + if ($letterwidth > $biggestword) { + $biggestword = $letterwidth; + } + $toonarrow = true; + } + } + } else { + // mPDF 6 + // Need to account for any XAdvance in GPOSinfo (OTLdata = $chunk[18]) + $wordXAdvance = []; + if (isset($chunk[18]) && $chunk[18]) { + preg_match_all('/(\xe2\x80\x8b| )/', $line, $spaces, PREG_OFFSET_CAPTURE); // U+200B Zero Width word boundary, or space + $lastoffset = 0; + $k = -1; // Added so that if no spaces found, "last word" later is calculated for the one and only word + foreach ($spaces[0] as $k => $m) { + $offset = $m[1]; + // ...TableCheckMinWidth... + // At this point, BIDI not applied, Writing direction is not set, and XAdvanceL balances XAdvanceR + for ($n = $lastoffset; $n < $offset; $n++) { + if (isset($chunk[18]['GPOSinfo'][$n]['XAdvanceL'])) { + if (isset($wordXAdvance[$k])) { + $wordXAdvance[$k] += $chunk[18]['GPOSinfo'][$n]['XAdvanceL']; + } else { + $wordXAdvance[$k] = $chunk[18]['GPOSinfo'][$n]['XAdvanceL']; + } + } + } + $lastoffset = $offset + 1; + } + + $k++; // last word + foreach ($chunk[18]['GPOSinfo'] as $n => $gpos) { + if ($n >= $lastoffset && isset($chunk[18]['GPOSinfo'][$n]['XAdvanceL'])) { + if (isset($wordXAdvance[$k])) { + $wordXAdvance[$k] += $chunk[18]['GPOSinfo'][$n]['XAdvanceL']; + } else { + $wordXAdvance[$k] = $chunk[18]['GPOSinfo'][$n]['XAdvanceL']; + } + } + } + } + + $words = preg_split('/(\xe2\x80\x8b| )/', $line); // U+200B Zero Width word boundary, or space + foreach ($words as $k => $word) { + $word = trim($word); + $wordwidth = $this->GetStringWidth($word, false, false, $chunk[8]); // Pass $textvar ($chunk[8]), but do OTLdata here + // so don't have to split OTLdata for each word + if (isset($wordXAdvance[$k])) { + $wordwidth += ($wordXAdvance[$k] * 1000 / $this->CurrentFont['unitsPerEm']) * ($this->FontSize / 1000); + } + if ($k == 0) { + $wordwidth += $lbw; + } + if ($k == (count($words) - 1)) { + $wordwidth += $rbw; + } + + // mPDF 6 + if (count($words) == 1 && substr($chunk[0], 0, 1) != ' ') { + $acclength += $wordwidth; + } elseif (count($words) > 1 && $k == 0 && substr($chunk[0], 0, 1) != ' ') { + $acclength += $wordwidth; + } else { + $acclength = $wordwidth; + } + $acclongest = max($acclongest, $acclength); + if (count($words) == 1 && substr($chunk[0], -1, 1) == ' ') { + $acclength = 0; + } elseif (count($words) > 1 && ($k != (count($words) - 1) || substr($chunk[0], -1, 1) == ' ')) { + $acclength = 0; + } + + // Warn user that maxwidth is insufficient + if ($wordwidth > $maxwidth + 0.0001) { + if ($wordwidth > $biggestword) { + $biggestword = $wordwidth; + } + $toonarrow = true; + } + } + } + + // mPDF 6 Accumulated length of biggest word - across multiple chunks + if ($acclongest > $maxwidth + 0.0001) { + if ($acclongest > $biggestword) { + $biggestword = $acclongest; + } + $toonarrow = true; + } + + // RESET FONT SIZE/STYLE + // RESETTING VALUES + // Now we must deactivate what we have used + if (isset($chunk[2]) and $chunk[2] != '') { + $this->ResetStyles(); + } + if (isset($chunk[4]) and $chunk[4] != '') { + $this->SetFont($this->default_font, $this->FontStyle, 0, false); + } + if (isset($chunk[11]) and $chunk[11] != '') { + $this->SetFontSize($this->default_font_size, false); + } + $this->spanborddet = []; + $this->textvar = 0x00; // mPDF 5.7.1 + $this->OTLtags = []; + $this->lSpacingCSS = ''; + $this->wSpacingCSS = ''; + $this->fixedlSpacing = false; + $this->minwSpacing = 0; + } + + // Return -(wordsize) if word is bigger than maxwidth + // ADDED + if (($toonarrow) && ($this->table_error_report)) { + throw new \Mpdf\MpdfException("Word is too long to fit in table - " . $this->table_error_report_param); + } + if ($toonarrow) { + return -$biggestword; + } else { + return 1; + } + } + + function shrinkTable(&$table, $k) + { + $table['border_spacing_H'] /= $k; + $table['border_spacing_V'] /= $k; + + $table['padding']['T'] /= $k; + $table['padding']['R'] /= $k; + $table['padding']['B'] /= $k; + $table['padding']['L'] /= $k; + + $table['margin']['T'] /= $k; + $table['margin']['R'] /= $k; + $table['margin']['B'] /= $k; + $table['margin']['L'] /= $k; + + $table['border_details']['T']['w'] /= $k; + $table['border_details']['R']['w'] /= $k; + $table['border_details']['B']['w'] /= $k; + $table['border_details']['L']['w'] /= $k; + + if (isset($table['max_cell_border_width']['T'])) { + $table['max_cell_border_width']['T'] /= $k; + } + if (isset($table['max_cell_border_width']['R'])) { + $table['max_cell_border_width']['R'] /= $k; + } + if (isset($table['max_cell_border_width']['B'])) { + $table['max_cell_border_width']['B'] /= $k; + } + if (isset($table['max_cell_border_width']['L'])) { + $table['max_cell_border_width']['L'] /= $k; + } + + if ($this->simpleTables) { + $table['simple']['border_details']['T']['w'] /= $k; + $table['simple']['border_details']['R']['w'] /= $k; + $table['simple']['border_details']['B']['w'] /= $k; + $table['simple']['border_details']['L']['w'] /= $k; + } + + $table['miw'] /= $k; + $table['maw'] /= $k; + + for ($j = 0; $j < $table['nc']; $j++) { // columns + + $table['wc'][$j]['miw'] = isset($table['wc'][$j]['miw']) ? $table['wc'][$j]['miw'] : 0; + $table['wc'][$j]['maw'] = isset($table['wc'][$j]['maw']) ? $table['wc'][$j]['maw'] : 0; + + $table['wc'][$j]['miw'] /= $k; + $table['wc'][$j]['maw'] /= $k; + + if (isset($table['decimal_align'][$j]['maxs0']) && $table['decimal_align'][$j]['maxs0']) { + $table['decimal_align'][$j]['maxs0'] /= $k; + } + + if (isset($table['decimal_align'][$j]['maxs1']) && $table['decimal_align'][$j]['maxs1']) { + $table['decimal_align'][$j]['maxs1'] /= $k; + } + + if (isset($table['wc'][$j]['absmiw']) && $table['wc'][$j]['absmiw']) { + $table['wc'][$j]['absmiw'] /= $k; + } + + for ($i = 0; $i < $table['nr']; $i++) { // rows + + $c = &$table['cells'][$i][$j]; + + if (isset($c) && $c) { + + if (!$this->simpleTables) { + + if ($this->packTableData) { + + $cell = $this->_unpackCellBorder($c['borderbin']); + + $cell['border_details']['T']['w'] /= $k; + $cell['border_details']['R']['w'] /= $k; + $cell['border_details']['B']['w'] /= $k; + $cell['border_details']['L']['w'] /= $k; + $cell['border_details']['mbw']['TL'] /= $k; + $cell['border_details']['mbw']['TR'] /= $k; + $cell['border_details']['mbw']['BL'] /= $k; + $cell['border_details']['mbw']['BR'] /= $k; + $cell['border_details']['mbw']['LT'] /= $k; + $cell['border_details']['mbw']['LB'] /= $k; + $cell['border_details']['mbw']['RT'] /= $k; + $cell['border_details']['mbw']['RB'] /= $k; + + $c['borderbin'] = $this->_packCellBorder($cell); + + } else { + + $c['border_details']['T']['w'] /= $k; + $c['border_details']['R']['w'] /= $k; + $c['border_details']['B']['w'] /= $k; + $c['border_details']['L']['w'] /= $k; + $c['border_details']['mbw']['TL'] /= $k; + $c['border_details']['mbw']['TR'] /= $k; + $c['border_details']['mbw']['BL'] /= $k; + $c['border_details']['mbw']['BR'] /= $k; + $c['border_details']['mbw']['LT'] /= $k; + $c['border_details']['mbw']['LB'] /= $k; + $c['border_details']['mbw']['RT'] /= $k; + $c['border_details']['mbw']['RB'] /= $k; + } + } + + $c['padding']['T'] /= $k; + $c['padding']['R'] /= $k; + $c['padding']['B'] /= $k; + $c['padding']['L'] /= $k; + + $c['maxs'] = isset($c['maxs']) ? $c['maxs'] /= $k : null; + $c['w'] = isset($c['w']) ? $c['w'] /= $k : null; + + $c['s'] = isset($c['s']) ? $c['s'] /= $k : 0; + $c['h'] = isset($c['h']) ? $c['h'] /= $k : null; + + $c['miw'] = isset($c['miw']) ? $c['miw'] /= $k : 0; + $c['maw'] = isset($c['maw']) ? $c['maw'] /= $k : 0; + + $c['absmiw'] = isset($c['absmiw']) ? $c['absmiw'] /= $k : null; + + $c['nestedmaw'] = isset($c['nestedmaw']) ? $c['nestedmaw'] /= $k : null; + $c['nestedmiw'] = isset($c['nestedmiw']) ? $c['nestedmiw'] /= $k : null; + + if (isset($c['textbuffer'])) { + foreach ($c['textbuffer'] as $n => $tb) { + if (!empty($tb[16])) { + !isset($c['textbuffer'][$n][16]['T']) || $c['textbuffer'][$n][16]['T']['w'] /= $k; + !isset($c['textbuffer'][$n][16]['B']) || $c['textbuffer'][$n][16]['B']['w'] /= $k; + !isset($c['textbuffer'][$n][16]['L']) || $c['textbuffer'][$n][16]['L']['w'] /= $k; + !isset($c['textbuffer'][$n][16]['R']) || $c['textbuffer'][$n][16]['R']['w'] /= $k; + } + } + } + + unset($c); + } + + } // rows + } // columns + } + + function read_short(&$fh) + { + $s = fread($fh, 2); + $a = (ord($s[0]) << 8) + ord($s[1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + return $a; + } + + function _packCellBorder($cell) + { + if (!is_array($cell) || !isset($cell)) { + return ''; + } + + if (!$this->packTableData) { + return $cell; + } + // = 186 bytes + $bindata = pack("nnda6A10nnda6A10nnda6A10nnda6A10nd9", $cell['border'], $cell['border_details']['R']['s'], $cell['border_details']['R']['w'], $cell['border_details']['R']['c'], $cell['border_details']['R']['style'], $cell['border_details']['R']['dom'], $cell['border_details']['L']['s'], $cell['border_details']['L']['w'], $cell['border_details']['L']['c'], $cell['border_details']['L']['style'], $cell['border_details']['L']['dom'], $cell['border_details']['T']['s'], $cell['border_details']['T']['w'], $cell['border_details']['T']['c'], $cell['border_details']['T']['style'], $cell['border_details']['T']['dom'], $cell['border_details']['B']['s'], $cell['border_details']['B']['w'], $cell['border_details']['B']['c'], $cell['border_details']['B']['style'], $cell['border_details']['B']['dom'], $cell['border_details']['mbw']['BL'], $cell['border_details']['mbw']['BR'], $cell['border_details']['mbw']['RT'], $cell['border_details']['mbw']['RB'], $cell['border_details']['mbw']['TL'], $cell['border_details']['mbw']['TR'], $cell['border_details']['mbw']['LT'], $cell['border_details']['mbw']['LB'], (isset($cell['border_details']['cellposdom']) ? $cell['border_details']['cellposdom'] : 0)); + return $bindata; + } + + function _getBorderWidths($bindata) + { + if (!$bindata) { + return [0, 0, 0, 0]; + } + if (!$this->packTableData) { + return [$bindata['border_details']['T']['w'], $bindata['border_details']['R']['w'], $bindata['border_details']['B']['w'], $bindata['border_details']['L']['w']]; + } + + $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata); + $cell['border_details']['R']['w'] = $bd['rw']; + $cell['border_details']['L']['w'] = $bd['lw']; + $cell['border_details']['T']['w'] = $bd['tw']; + $cell['border_details']['B']['w'] = $bd['bw']; + return [$bd['tw'], $bd['rw'], $bd['bw'], $bd['lw']]; + } + + function _unpackCellBorder($bindata) + { + if (!$bindata) { + return []; + } + if (!$this->packTableData) { + return $bindata; + } + + $bd = unpack("nbord/nrs/drw/a6rca/A10rst/nrd/nls/dlw/a6lca/A10lst/nld/nts/dtw/a6tca/A10tst/ntd/nbs/dbw/a6bca/A10bst/nbd/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd", $bindata); + + $cell['border'] = $bd['bord']; + $cell['border_details']['R']['s'] = $bd['rs']; + $cell['border_details']['R']['w'] = $bd['rw']; + $cell['border_details']['R']['c'] = str_pad($bd['rca'], 6, "\x00"); + $cell['border_details']['R']['style'] = trim($bd['rst']); + $cell['border_details']['R']['dom'] = $bd['rd']; + + $cell['border_details']['L']['s'] = $bd['ls']; + $cell['border_details']['L']['w'] = $bd['lw']; + $cell['border_details']['L']['c'] = str_pad($bd['lca'], 6, "\x00"); + $cell['border_details']['L']['style'] = trim($bd['lst']); + $cell['border_details']['L']['dom'] = $bd['ld']; + + $cell['border_details']['T']['s'] = $bd['ts']; + $cell['border_details']['T']['w'] = $bd['tw']; + $cell['border_details']['T']['c'] = str_pad($bd['tca'], 6, "\x00"); + $cell['border_details']['T']['style'] = trim($bd['tst']); + $cell['border_details']['T']['dom'] = $bd['td']; + + $cell['border_details']['B']['s'] = $bd['bs']; + $cell['border_details']['B']['w'] = $bd['bw']; + $cell['border_details']['B']['c'] = str_pad($bd['bca'], 6, "\x00"); + $cell['border_details']['B']['style'] = trim($bd['bst']); + $cell['border_details']['B']['dom'] = $bd['bd']; + + $cell['border_details']['mbw']['BL'] = $bd['mbl']; + $cell['border_details']['mbw']['BR'] = $bd['mbr']; + $cell['border_details']['mbw']['RT'] = $bd['mrt']; + $cell['border_details']['mbw']['RB'] = $bd['mrb']; + $cell['border_details']['mbw']['TL'] = $bd['mtl']; + $cell['border_details']['mbw']['TR'] = $bd['mtr']; + $cell['border_details']['mbw']['LT'] = $bd['mlt']; + $cell['border_details']['mbw']['LB'] = $bd['mlb']; + $cell['border_details']['cellposdom'] = $bd['cpd']; + + + return($cell); + } + + ////////////////////////TABLE CODE (from PDFTable)///////////////////////////////////// + ////////////////////////TABLE CODE (from PDFTable)///////////////////////////////////// + ////////////////////////TABLE CODE (from PDFTable)///////////////////////////////////// + // table Array of (w, h, bc, nr, wc, hr, cells) + // w Width of table + // h Height of table + // nc Number column + // nr Number row + // hr List of height of each row + // wc List of width of each column + // cells List of cells of each rows, cells[i][j] is a cell in the table + function _tableColumnWidth(&$table, $firstpass = false) + { + $cs = &$table['cells']; + + $nc = $table['nc']; + $nr = $table['nr']; + $listspan = []; + + if ($table['borders_separate']) { + $tblbw = $table['border_details']['L']['w'] + $table['border_details']['R']['w'] + $table['margin']['L'] + $table['margin']['R'] + $table['padding']['L'] + $table['padding']['R'] + $table['border_spacing_H']; + } else { + $tblbw = $table['max_cell_border_width']['L'] / 2 + $table['max_cell_border_width']['R'] / 2 + $table['margin']['L'] + $table['margin']['R']; + } + + // ADDED table['l'][colno] + // = total length of text approx (using $c['s']) in that column - used to approximately distribute col widths in _tableWidth + // + for ($j = 0; $j < $nc; $j++) { // columns + $wc = &$table['wc'][$j]; + for ($i = 0; $i < $nr; $i++) { // rows + if (isset($cs[$i][$j]) && $cs[$i][$j]) { + $c = &$cs[$i][$j]; + + if ($this->simpleTables) { + if ($table['borders_separate']) { // NB twice border width + $extrcw = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H']; + } else { + $extrcw = $table['simple']['border_details']['L']['w'] / 2 + $table['simple']['border_details']['R']['w'] / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } else { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']); + } else { + $br = $c['border_details']['R']['w']; + $bl = $c['border_details']['L']['w']; + } + if ($table['borders_separate']) { // NB twice border width + $extrcw = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H']; + } else { + $extrcw = $bl / 2 + $br / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } + + // $mw = $this->GetStringWidth('W') + $extrcw ; + $mw = $extrcw; // mPDF 6 + if (substr($c['a'], 0, 1) == 'D') { + $mw = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1'] + $extrcw; + } + + $c['absmiw'] = $mw; + + if (isset($c['R']) && $c['R']) { + $c['maw'] = $c['miw'] = $this->FontSize + $extrcw; + if (isset($c['w'])) { // If cell width is specified + if ($c['miw'] < $c['w']) { + $c['miw'] = $c['w']; + } + } + if (!isset($c['colspan'])) { + if ($wc['miw'] < $c['miw']) { + $wc['miw'] = $c['miw']; + } + if ($wc['maw'] < $c['maw']) { + $wc['maw'] = $c['maw']; + } + + if ($firstpass) { + if (isset($table['l'][$j])) { + $table['l'][$j] += $c['miw']; + } else { + $table['l'][$j] = $c['miw']; + } + } + } + if ($c['miw'] > $wc['miw']) { + $wc['miw'] = $c['miw']; + } + if ($wc['miw'] > $wc['maw']) { + $wc['maw'] = $wc['miw']; + } + continue; + } + + if ($firstpass) { + if (isset($c['s'])) { + $c['s'] += $extrcw; + } + if (isset($c['maxs'])) { + $c['maxs'] += $extrcw; + } + if (isset($c['nestedmiw'])) { + $c['nestedmiw'] += $extrcw; + } + if (isset($c['nestedmaw'])) { + $c['nestedmaw'] += $extrcw; + } + } + + + // If minimum width has already been set by a nested table or inline object (image/form), use it + if (isset($c['nestedmiw']) && (!isset($this->table[1][1]['overflow']) || $this->table[1][1]['overflow'] != 'visible')) { + $miw = $c['nestedmiw']; + } else { + $miw = $mw; + } + + if (isset($c['maxs']) && $c['maxs'] != '') { + $c['s'] = $c['maxs']; + } + + // If maximum width has already been set by a nested table, use it + if (isset($c['nestedmaw'])) { + $c['maw'] = $c['nestedmaw']; + } else { + $c['maw'] = $c['s']; + } + + if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) { + if (($c['maw'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) { + $c['maw'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw; + } + } + + if (isset($c['nowrap']) && $c['nowrap']) { + $miw = $c['maw']; + } + + if (isset($c['wpercent']) && $firstpass) { + if (isset($c['colspan'])) { // Not perfect - but % set on colspan is shared equally on cols. + for ($k = 0; $k < $c['colspan']; $k++) { + $table['wc'][($j + $k)]['wpercent'] = $c['wpercent'] / $c['colspan']; + } + } else { + if (isset($table['w']) && $table['w']) { + $c['w'] = $c['wpercent'] / 100 * ($table['w'] - $tblbw ); + } + $wc['wpercent'] = $c['wpercent']; + } + } + + if (isset($table['overflow']) && $table['overflow'] == 'visible' && $table['level'] == 1) { + if (isset($c['w']) && ($c['w'] + $tblbw) > $this->blk[$this->blklvl]['inner_width']) { + $c['w'] = $this->blk[$this->blklvl]['inner_width'] - $tblbw; + } + } + + + if (isset($c['w'])) { // If cell width is specified + if ($miw < $c['w']) { + $c['miw'] = $c['w']; + } // Cell min width = that specified + if ($miw > $c['w']) { + $c['miw'] = $c['w'] = $miw; + } // If width specified is less than minimum allowed (W) increase it + // mPDF 5.7.4 Do not set column width in colspan + // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug + if (!isset($c['colspan'])) { + if (!isset($wc['w'])) { + $wc['w'] = 1; + } // If the Col width is not specified = set it to 1 + } + // mPDF 5.7.3 cf. http://www.mpdf1.com/forum/discussion/1648/nested-table-bug- + $c['maw'] = $c['w']; + } else { + $c['miw'] = $miw; + } // If cell width not specified -> set Cell min width it to minimum allowed (W) + + if (isset($c['miw']) && $c['maw'] < $c['miw']) { + $c['maw'] = $c['miw']; + } // If Cell max width < Minwidth - increase it to = + if (!isset($c['colspan'])) { + if (isset($c['miw']) && $wc['miw'] < $c['miw']) { + $wc['miw'] = $c['miw']; + } // Update Col Minimum and maximum widths + if ($wc['maw'] < $c['maw']) { + $wc['maw'] = $c['maw']; + } + if ((isset($wc['absmiw']) && $wc['absmiw'] < $c['absmiw']) || !isset($wc['absmiw'])) { + $wc['absmiw'] = $c['absmiw']; + } // Update Col Minimum and maximum widths + + if (isset($table['l'][$j])) { + $table['l'][$j] += $c['s']; + } else { + $table['l'][$j] = $c['s']; + } + } else { + $listspan[] = [$i, $j]; + } + + // Check if minimum width of the whole column is big enough for largest word to fit + // mPDF 6 + if (isset($c['textbuffer'])) { + if (isset($table['overflow']) && $table['overflow'] == 'wrap') { + $letter = true; + } // check for maximum width of letters + else { + $letter = false; + } + $minwidth = $this->TableCheckMinWidth($wc['miw'] - $extrcw, 0, $c['textbuffer'], $letter); + } else { + $minwidth = 0; + } + if ($minwidth < 0) { + // increase minimum width + if (!isset($c['colspan'])) { + $wc['miw'] = max((isset($wc['miw']) ? $wc['miw'] : 0), ((-$minwidth) + $extrcw)); + } else { + $c['miw'] = max((isset($c['miw']) ? $c['miw'] : 0), ((-$minwidth) + $extrcw)); + } + } + if (!isset($c['colspan'])) { + if ($wc['miw'] > $wc['maw']) { + $wc['maw'] = $wc['miw']; + } // update maximum width, if needed + } + } + unset($c); + }//rows + }//columns + // COLUMN SPANS + $wc = &$table['wc']; + foreach ($listspan as $span) { + list($i, $j) = $span; + $c = &$cs[$i][$j]; + $lc = $j + $c['colspan']; + if ($lc > $nc) { + $lc = $nc; + } + $wis = $wisa = 0; + $was = $wasa = 0; + $list = []; + for ($k = $j; $k < $lc; $k++) { + if (isset($table['l'][$k])) { + if ($c['R']) { + $table['l'][$k] += $c['miw'] / $c['colspan']; + } else { + $table['l'][$k] += $c['s'] / $c['colspan']; + } + } else { + if ($c['R']) { + $table['l'][$k] = $c['miw'] / $c['colspan']; + } else { + $table['l'][$k] = $c['s'] / $c['colspan']; + } + } + $wis += $wc[$k]['miw']; // $wis is the sum of the column miw in the colspan + $was += $wc[$k]['maw']; // $was is the sum of the column maw in the colspan + if (!isset($c['w'])) { + $list[] = $k; + $wisa += $wc[$k]['miw']; // $wisa is the sum of the column miw in cells with no width specified in the colspan + $wasa += $wc[$k]['maw']; // $wasa is the sum of the column maw in cells with no width specified in the colspan + } + } + if ($c['miw'] > $wis) { + if (!$wis) { + for ($k = $j; $k < $lc; $k++) { + $wc[$k]['miw'] = $c['miw'] / $c['colspan']; + } + } elseif (!count($list) && $wis != 0) { + $wi = $c['miw'] - $wis; + for ($k = $j; $k < $lc; $k++) { + $wc[$k]['miw'] += ($wc[$k]['miw'] / $wis) * $wi; + } + } else { + $wi = $c['miw'] - $wis; + // mPDF 5.7.2 Extra min width distributed proportionately to all cells in colspan without a specified width + // cf. http://www.mpdf1.com/forum/discussion/1607#Item_4 + foreach ($list as $k) { + if (!isset($wc[$k]['w']) || !$wc[$k]['w']) { + $wc[$k]['miw'] += ($wc[$k]['miw'] / $wisa) * $wi; + } + } // mPDF 5.7.2 + } + } + if ($c['maw'] > $was) { + if (!$wis) { + for ($k = $j; $k < $lc; $k++) { + $wc[$k]['maw'] = $c['maw'] / $c['colspan']; + } + } elseif (!count($list) && $was != 0) { + $wi = $c['maw'] - $was; + for ($k = $j; $k < $lc; $k++) { + $wc[$k]['maw'] += ($wc[$k]['maw'] / $was) * $wi; + } + } else { + $wi = $c['maw'] - $was; + // mPDF 5.7.4 Extra max width distributed evenly to all cells in colspan without a specified width + // cf. http://www.mpdf1.com/forum/discussion/2221/colspan-bug + foreach ($list as $k) { + $wc[$k]['maw'] += $wi / count($list); + } + } + } + unset($c); + } + + $checkminwidth = 0; + $checkmaxwidth = 0; + $totallength = 0; + + for ($i = 0; $i < $nc; $i++) { + $checkminwidth += $table['wc'][$i]['miw']; + $checkmaxwidth += $table['wc'][$i]['maw']; + $totallength += isset($table['l']) ? $table['l'][$i] : 0; + } + + if (!isset($table['w']) && $firstpass) { + $sumpc = 0; + $notset = 0; + for ($i = 0; $i < $nc; $i++) { + if (isset($table['wc'][$i]['wpercent']) && $table['wc'][$i]['wpercent']) { + $sumpc += $table['wc'][$i]['wpercent']; + } else { + $notset++; + } + } + + // If sum of widths as % >= 100% and not all columns are set + // Set a nominal width of 1% for unset columns + if ($sumpc >= 100 && $notset) { + for ($i = 0; $i < $nc; $i++) { + if ((!isset($table['wc'][$i]['wpercent']) || !$table['wc'][$i]['wpercent']) && + (!isset($table['wc'][$i]['w']) || !$table['wc'][$i]['w'])) { + $table['wc'][$i]['wpercent'] = 1; + } + } + } + + + if ($sumpc) { // if any percents are set + $sumnonpc = (100 - $sumpc); + $sumpc = max($sumpc, 100); + $miwleft = 0; + $miwleftcount = 0; + $miwsurplusnonpc = 0; + $maxcalcmiw = 0; + $mawleft = 0; + $mawleftcount = 0; + $mawsurplusnonpc = 0; + $maxcalcmaw = 0; + $mawnon = 0; + $miwnon = 0; + for ($i = 0; $i < $nc; $i++) { + if (isset($table['wc'][$i]['wpercent'])) { + $maxcalcmiw = max($maxcalcmiw, ($table['wc'][$i]['miw'] * $sumpc / $table['wc'][$i]['wpercent'])); + $maxcalcmaw = max($maxcalcmaw, ($table['wc'][$i]['maw'] * $sumpc / $table['wc'][$i]['wpercent'])); + } else { + $miwleft += $table['wc'][$i]['miw']; + $mawleft += $table['wc'][$i]['maw']; + if (!isset($table['wc'][$i]['w'])) { + $miwleftcount++; + $mawleftcount++; + } + } + } + if ($miwleft && $sumnonpc > 0) { + $miwnon = $miwleft * 100 / $sumnonpc; + } + if ($mawleft && $sumnonpc > 0) { + $mawnon = $mawleft * 100 / $sumnonpc; + } + if (($miwnon > $checkminwidth || $maxcalcmiw > $checkminwidth) && $this->keep_table_proportions) { + if ($miwnon > $maxcalcmiw) { + $miwsurplusnonpc = round((($miwnon * $sumnonpc / 100) - $miwleft), 3); + $checkminwidth = $miwnon; + } else { + $checkminwidth = $maxcalcmiw; + } + for ($i = 0; $i < $nc; $i++) { + if (isset($table['wc'][$i]['wpercent'])) { + $newmiw = $checkminwidth * $table['wc'][$i]['wpercent'] / 100; + if ($table['wc'][$i]['miw'] < $newmiw) { + $table['wc'][$i]['miw'] = $newmiw; + } + $table['wc'][$i]['w'] = 1; + } elseif ($miwsurplusnonpc && !$table['wc'][$i]['w']) { + $table['wc'][$i]['miw'] += $miwsurplusnonpc / $miwleftcount; + } + } + } + if (($mawnon > $checkmaxwidth || $maxcalcmaw > $checkmaxwidth)) { + if ($mawnon > $maxcalcmaw) { + $mawsurplusnonpc = round((($mawnon * $sumnonpc / 100) - $mawleft), 3); + $checkmaxwidth = $mawnon; + } else { + $checkmaxwidth = $maxcalcmaw; + } + for ($i = 0; $i < $nc; $i++) { + if (isset($table['wc'][$i]['wpercent'])) { + $newmaw = $checkmaxwidth * $table['wc'][$i]['wpercent'] / 100; + if ($table['wc'][$i]['maw'] < $newmaw) { + $table['wc'][$i]['maw'] = $newmaw; + } + $table['wc'][$i]['w'] = 1; + } elseif ($mawsurplusnonpc && !$table['wc'][$i]['w']) { + $table['wc'][$i]['maw'] += $mawsurplusnonpc / $mawleftcount; + } + if ($table['wc'][$i]['maw'] < $table['wc'][$i]['miw']) { + $table['wc'][$i]['maw'] = $table['wc'][$i]['miw']; + } + } + } + if ($checkminwidth > $checkmaxwidth) { + $checkmaxwidth = $checkminwidth; + } + } + } + + if (isset($table['wpercent']) && $table['wpercent']) { + $checkminwidth *= (100 / $table['wpercent']); + $checkmaxwidth *= (100 / $table['wpercent']); + } + + + $checkminwidth += $tblbw; + $checkmaxwidth += $tblbw; + + // Table['miw'] set by percent in first pass may be larger than sum of column miw + if ((isset($table['miw']) && $checkminwidth > $table['miw']) || !isset($table['miw'])) { + $table['miw'] = $checkminwidth; + } + if ((isset($table['maw']) && $checkmaxwidth > $table['maw']) || !isset($table['maw'])) { + $table['maw'] = $checkmaxwidth; + } + $table['tl'] = $totallength; + + // mPDF 6 + if ($this->table_rotate) { + $mxw = $this->tbrot_maxw; + } else { + $mxw = $this->blk[$this->blklvl]['inner_width']; + } + + if (!isset($table['overflow'])) { + $table['overflow'] = null; + } + + if ($table['overflow'] == 'visible') { + return [0, 0]; + } elseif ($table['overflow'] == 'hidden' && !$this->table_rotate && !$this->ColActive && $checkminwidth > $mxw) { + $table['w'] = $table['miw']; + return [0, 0]; + } + // elseif ($table['overflow']=='wrap') { return array(0,0); } // mPDF 6 + + if (isset($table['w']) && $table['w']) { + + if ($table['w'] >= $checkminwidth && $table['w'] <= $mxw) { + $table['maw'] = $mxw = $table['w']; + } elseif ($table['w'] >= $checkminwidth && $table['w'] > $mxw && $this->keep_table_proportions) { + $checkminwidth = $table['w']; + } elseif ($table['w'] < $checkminwidth && $checkminwidth < $mxw && $this->keep_table_proportions) { + $table['maw'] = $table['w'] = $checkminwidth; + } else { + unset($table['w']); + } + } + + $ratio = $checkminwidth / $mxw; + + if ($checkminwidth > $mxw) { + return [($ratio + 0.001), $checkminwidth]; // 0.001 to allow for rounded numbers when resizing + } + + unset($cs); + + return [0, 0]; + } + + function _tableWidth(&$table) + { + $widthcols = &$table['wc']; + $numcols = $table['nc']; + $tablewidth = 0; + + if ($table['borders_separate']) { + $tblbw = $table['border_details']['L']['w'] + $table['border_details']['R']['w'] + $table['margin']['L'] + $table['margin']['R'] + $table['padding']['L'] + $table['padding']['R'] + $table['border_spacing_H']; + } else { + $tblbw = $table['max_cell_border_width']['L'] / 2 + $table['max_cell_border_width']['R'] / 2 + $table['margin']['L'] + $table['margin']['R']; + } + + if ($table['level'] > 1 && isset($table['w'])) { + + if (isset($table['wpercent']) && $table['wpercent']) { + $table['w'] = $temppgwidth = (($table['w'] - $tblbw) * $table['wpercent'] / 100) + $tblbw; + } else { + $temppgwidth = $table['w']; + } + + } elseif ($this->table_rotate) { + + $temppgwidth = $this->tbrot_maxw; + + // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin) then allow for this + $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w']; + + if ($enddiv / $temppgwidth < 0.05) { + $temppgwidth -= $enddiv; + } + + } else { + + if (isset($table['w']) && $table['w'] < $this->blk[$this->blklvl]['inner_width']) { + $notfullwidth = 1; + $temppgwidth = $table['w']; + } elseif ($table['overflow'] == 'visible' && $table['level'] == 1) { + $temppgwidth = null; + } elseif ($table['overflow'] == 'hidden' && !$this->ColActive && isset($table['w']) && $table['w'] > $this->blk[$this->blklvl]['inner_width'] && $table['w'] == $table) { + // $temppgwidth = $this->blk[$this->blklvl]['inner_width']; + $temppgwidth = $table['w']; + } else { + $temppgwidth = $this->blk[$this->blklvl]['inner_width']; + } + + } + + $totaltextlength = 0; // Added - to sum $table['l'][colno] + $totalatextlength = 0; // Added - to sum $table['l'][colno] for those columns where width not set + $percentages_set = 0; + + for ($i = 0; $i < $numcols; $i++) { + if (isset($widthcols[$i]['wpercent'])) { + $tablewidth += $widthcols[$i]['maw']; + $percentages_set = 1; + } elseif (isset($widthcols[$i]['w'])) { + $tablewidth += $widthcols[$i]['miw']; + } else { + $tablewidth += $widthcols[$i]['maw']; + } + $totaltextlength += isset($table['l']) ? $table['l'][$i] : 0; + } + + if (!$totaltextlength) { + $totaltextlength = 1; + } + + $tablewidth += $tblbw; // Outer half of table borders + + if ($tablewidth > $temppgwidth) { + $table['w'] = $temppgwidth; + } elseif ($tablewidth < $temppgwidth && !isset($table['w']) && $percentages_set) { // if any widths set as percentages and max width fits < page width + $table['w'] = $table['maw']; + } + + // if table width is set and is > allowed width + if (isset($table['w']) && $table['w'] > $temppgwidth) { + $table['w'] = $temppgwidth; + } + + // IF the table width is now set - Need to distribute columns widths + // mPDF 5.7.3 + // If the table width is already set to the maximum width (e.g. nested table), then use maximum column widths exactly + if (isset($table['w']) && ($table['w'] == $tablewidth) && !$percentages_set) { + + // This sets the columns all to maximum width + for ($i = 0; $i < $numcols; $i++) { + $widthcols[$i] = $widthcols[$i]['maw']; + } + + } elseif (isset($table['w'])) { // elseif the table width is set distribute width using algorithm + + $wis = $wisa = 0; + $list = []; + $notsetlist = []; + + for ($i = 0; $i < $numcols; $i++) { + $wis += $widthcols[$i]['miw']; + if (!isset($widthcols[$i]['w']) || ($widthcols[$i]['w'] && $table['w'] > $temppgwidth && !$this->keep_table_proportions && !$notfullwidth )) { + $list[] = $i; + $wisa += $widthcols[$i]['miw']; + $totalatextlength += $table['l'][$i]; + } + } + + if (!$totalatextlength) { + $totalatextlength = 1; + } + + // Allocate spare (more than col's minimum width) across the cols according to their approx total text length + // Do it by setting minimum width here + if ($table['w'] > $wis + $tblbw) { + + // First set any cell widths set as percentages + if ($table['w'] < $temppgwidth || $this->keep_table_proportions) { + for ($k = 0; $k < $numcols; $k++) { + if (isset($widthcols[$k]['wpercent'])) { + $curr = $widthcols[$k]['miw']; + $widthcols[$k]['miw'] = ($table['w'] - $tblbw) * $widthcols[$k]['wpercent'] / 100; + $wis += $widthcols[$k]['miw'] - $curr; + $wisa += $widthcols[$k]['miw'] - $curr; + } + } + } + + // Now allocate surplus up to maximum width of each column + $surplus = 0; + $ttl = 0; // number of surplus columns + + if (!count($list)) { + + $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute + + for ($k = 0; $k < $numcols; $k++) { + + $spareratio = ($table['l'][$k] / $totaltextlength); // gives ratio to divide up free space + + // Don't allocate more than Maximum required width - save rest in surplus + if ($widthcols[$k]['miw'] + ($wi * $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3 + $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']); + $widthcols[$k]['miw'] = $widthcols[$k]['maw']; + } else { + $notsetlist[] = $k; + $ttl += $table['l'][$k]; + $widthcols[$k]['miw'] += ($wi * $spareratio); + } + } + + } else { + + $wi = ($table['w'] - ($wis + $tblbw)); // i.e. extra space to distribute + + foreach ($list as $k) { + + $spareratio = ($table['l'][$k] / $totalatextlength); // gives ratio to divide up free space + + // Don't allocate more than Maximum required width - save rest in surplus + if ($widthcols[$k]['miw'] + ($wi * $spareratio) >= $widthcols[$k]['maw']) { // mPDF 5.7.3 + $surplus += ($wi * $spareratio) - ($widthcols[$k]['maw'] - $widthcols[$k]['miw']); + $widthcols[$k]['miw'] = $widthcols[$k]['maw']; + } else { + $notsetlist[] = $k; + $ttl += $table['l'][$k]; + $widthcols[$k]['miw'] += ($wi * $spareratio); + } + } + } + + // If surplus still left over apportion it across columns + if ($surplus) { + + if (count($notsetlist) && count($notsetlist) < $numcols) { // if some are set only add to remaining - otherwise add to all of them + foreach ($notsetlist as $i) { + if ($ttl) { + $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl; + } + } + } elseif (count($list) && count($list) < $numcols) { // If some widths are defined, and others have been added up to their maxmum + foreach ($list as $i) { + $widthcols[$i]['miw'] += $surplus / count($list); + } + } elseif ($numcols) { // If all columns + $ttl = array_sum($table['l']); + if ($ttl) { + for ($i = 0; $i < $numcols; $i++) { + $widthcols[$i]['miw'] += $surplus * $table['l'][$i] / $ttl; + } + } + } + } + } + + // This sets the columns all to minimum width (which has been increased above if appropriate) + for ($i = 0; $i < $numcols; $i++) { + $widthcols[$i] = $widthcols[$i]['miw']; + } + + // TABLE NOT WIDE ENOUGH EVEN FOR MINIMUM CONTENT WIDTH + // If sum of column widths set are too wide for table + $checktablewidth = 0; + for ($i = 0; $i < $numcols; $i++) { + $checktablewidth += $widthcols[$i]; + } + + if ($checktablewidth > ($temppgwidth + 0.001 - $tblbw)) { + + $usedup = 0; + $numleft = 0; + + for ($i = 0; $i < $numcols; $i++) { + if ((isset($widthcols[$i]) && $widthcols[$i] > (($temppgwidth - $tblbw) / $numcols)) && (!isset($widthcols[$i]['w']))) { + $numleft++; + unset($widthcols[$i]); + } else { + $usedup += $widthcols[$i]; + } + } + + for ($i = 0; $i < $numcols; $i++) { + if (!isset($widthcols[$i]) || !$widthcols[$i]) { + $widthcols[$i] = ((($temppgwidth - $tblbw) - $usedup) / ($numleft)); + } + } + } + + } else { // table has no width defined + + $table['w'] = $tablewidth; + + for ($i = 0; $i < $numcols; $i++) { + + if (isset($widthcols[$i]['wpercent']) && $this->keep_table_proportions) { + $colwidth = $widthcols[$i]['maw']; + } elseif (isset($widthcols[$i]['w'])) { + $colwidth = $widthcols[$i]['miw']; + } else { + $colwidth = $widthcols[$i]['maw']; + } + + unset($widthcols[$i]); + $widthcols[$i] = $colwidth; + + } + } + + if ($table['overflow'] === 'visible' && $table['level'] == 1) { + + if ($tablewidth > $this->blk[$this->blklvl]['inner_width']) { + + for ($j = 0; $j < $numcols; $j++) { // columns + + for ($i = 0; $i < $table['nr']; $i++) { // rows + + if (isset($table['cells'][$i][$j]) && $table['cells'][$i][$j]) { + + $colspan = (isset($table['cells'][$i][$j]['colspan']) ? $table['cells'][$i][$j]['colspan'] : 1); + + if ($colspan > 1) { + $w = 0; + + for ($c = $j; $c < ($j + $colspan); $c++) { + $w += $widthcols[$c]; + } + + if ($w > $this->blk[$this->blklvl]['inner_width']) { + $diff = $w - ($this->blk[$this->blklvl]['inner_width'] - $tblbw); + for ($c = $j; $c < ($j + $colspan); $c++) { + $widthcols[$c] -= $diff * ($widthcols[$c] / $w); + } + $table['w'] -= $diff; + $table['csp'][$j] = $w - $diff; + } + } + } + } + } + } + + $pgNo = 0; + $currWc = 0; + + for ($i = 0; $i < $numcols; $i++) { // columns + + if (isset($table['csp'][$i])) { + $w = $table['csp'][$i]; + unset($table['csp'][$i]); + } else { + $w = $widthcols[$i]; + } + + if (($currWc + $w + $tblbw) > $this->blk[$this->blklvl]['inner_width']) { + $pgNo++; + $currWc = $widthcols[$i]; + } else { + $currWc += $widthcols[$i]; + } + + $table['colPg'][$i] = $pgNo; + } + } + } + + function _tableHeight(&$table) + { + $level = $table['level']; + $levelid = $table['levelid']; + $cells = &$table['cells']; + $numcols = $table['nc']; + $numrows = $table['nr']; + $listspan = []; + $checkmaxheight = 0; + $headerrowheight = 0; + $checkmaxheightplus = 0; + $headerrowheightplus = 0; + $firstrowheight = 0; + + $footerrowheight = 0; + $footerrowheightplus = 0; + if ($this->table_rotate) { + $temppgheight = $this->tbrot_maxh; + $remainingpage = $this->tbrot_maxh; + } else { + $temppgheight = ($this->h - $this->bMargin - $this->tMargin) - $this->kwt_height; + $remainingpage = ($this->h - $this->bMargin - $this->y) - $this->kwt_height; + + // If it is less than 1/20th of the remaining page height to finish the DIV (i.e. DIV padding + table bottom margin) + // then allow for this + $enddiv = $this->blk[$this->blklvl]['padding_bottom'] + $this->blk[$this->blklvl]['border_bottom']['w'] + $table['margin']['B']; + if ($remainingpage > $enddiv && $enddiv / $remainingpage < 0.05) { + $remainingpage -= $enddiv; + } elseif ($remainingpage == 0) { + $remainingpage = 0.001; + } + if ($temppgheight > $enddiv && $enddiv / $temppgheight < 0.05) { + $temppgheight -= $enddiv; + } elseif ($temppgheight == 0) { + $temppgheight = 0.001; + } + } + if ($remainingpage < 0) { + $remainingpage = 0.001; + } + if ($temppgheight < 0) { + $temppgheight = 0.001; + } + + for ($i = 0; $i < $numrows; $i++) { // rows + $heightrow = &$table['hr'][$i]; + for ($j = 0; $j < $numcols; $j++) { // columns + if (isset($cells[$i][$j]) && $cells[$i][$j]) { + $c = &$cells[$i][$j]; + + if ($this->simpleTables) { + if ($table['borders_separate']) { // NB twice border width + $extraWLR = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) + ($c['padding']['L'] + $c['padding']['R']) + $table['border_spacing_H']; + $extrh = ($table['simple']['border_details']['T']['w'] + $table['simple']['border_details']['B']['w']) + ($c['padding']['T'] + $c['padding']['B']) + $table['border_spacing_V']; + } else { + $extraWLR = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) / 2 + ($c['padding']['L'] + $c['padding']['R']); + $extrh = ($table['simple']['border_details']['T']['w'] + $table['simple']['border_details']['B']['w']) / 2 + ($c['padding']['T'] + $c['padding']['B']); + } + } else { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']); + } else { + $bt = $c['border_details']['T']['w']; + $bb = $c['border_details']['B']['w']; + $br = $c['border_details']['R']['w']; + $bl = $c['border_details']['L']['w']; + } + if ($table['borders_separate']) { // NB twice border width + $extraWLR = $bl + $br + $c['padding']['L'] + $c['padding']['R'] + $table['border_spacing_H']; + $extrh = $bt + $bb + $c['padding']['T'] + $c['padding']['B'] + $table['border_spacing_V']; + } else { + $extraWLR = $bl / 2 + $br / 2 + $c['padding']['L'] + $c['padding']['R']; + $extrh = $bt / 2 + $bb / 2 + $c['padding']['T'] + $c['padding']['B']; + } + } + + if ($table['overflow'] == 'visible' && $level == 1) { + list($x, $cw) = $this->_splitTableGetWidth($table, $i, $j); + } else { + list($x, $cw) = $this->_tableGetWidth($table, $i, $j); + } + + + // Get CELL HEIGHT + // ++ extra parameter forces wrap to break word + if ($c['R'] && isset($c['textbuffer'])) { + $str = ''; + foreach ($c['textbuffer'] as $t) { + $str .= $t[0] . ' '; + } + $str = rtrim($str); + $s_fs = $this->FontSizePt; + $s_f = $this->FontFamily; + $s_st = $this->FontStyle; + $this->SetFont($c['textbuffer'][0][4], $c['textbuffer'][0][2], $c['textbuffer'][0][11] / $this->shrin_k, true, true); + $tempch = $this->GetStringWidth($str, true, $c['textbuffer'][0][18], $c['textbuffer'][0][8]); + if ($c['R'] >= 45 && $c['R'] < 90) { + $tempch = ((sin(deg2rad($c['R']))) * $tempch ) + ((sin(deg2rad($c['R']))) * (($c['textbuffer'][0][11] / Mpdf::SCALE) / $this->shrin_k)); + } + $this->SetFont($s_f, $s_st, $s_fs, true, true); + $ch = ($tempch ) + $extrh; + } else { + if (isset($c['textbuffer']) && !empty($c['textbuffer'])) { + $this->cellLineHeight = $c['cellLineHeight']; + $this->cellLineStackingStrategy = $c['cellLineStackingStrategy']; + $this->cellLineStackingShift = $c['cellLineStackingShift']; + $this->divwidth = $cw - $extraWLR; + $tempch = $this->printbuffer($c['textbuffer'], '', true, true); + } else { + $tempch = 0; + } + + // Added cellpadding top and bottom. (Lineheight already adjusted) + $ch = $tempch + $extrh; + } + // If height is defined and it is bigger than calculated $ch then update values + if (isset($c['h']) && $c['h'] > $ch) { + $c['mih'] = $ch; // in order to keep valign working + $ch = $c['h']; + } else { + $c['mih'] = $ch; + } + if (isset($c['rowspan'])) { + $listspan[] = [$i, $j]; + } elseif ($heightrow < $ch) { + $heightrow = $ch; + } + + // this is the extra used in _tableWrite to determine whether to trigger a page change + if ($table['borders_separate']) { + if ($i == ($numrows - 1) || (isset($c['rowspan']) && ($i + $c['rowspan']) == ($numrows))) { + $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + } else { + $extra = $table['border_spacing_V'] / 2; + } + } else { + if (!$this->simpleTables) { + $extra = $bb / 2; + } elseif ($this->simpleTables) { + $extra = $table['simple']['border_details']['B']['w'] / 2; + } + } + if (isset($table['is_thead'][$i]) && $table['is_thead'][$i]) { + if ($j == 0) { + $headerrowheight += $ch; + $headerrowheightplus += $ch + $extra; + } + } elseif (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) { + if ($j == 0) { + $footerrowheight += $ch; + $footerrowheightplus += $ch + $extra; + } + } else { + $checkmaxheight = max($checkmaxheight, $ch); + $checkmaxheightplus = max($checkmaxheightplus, $ch + $extra); + } + if ($this->tableLevel == 1 && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) { + $firstrowheight = max($ch, $firstrowheight); + } + unset($c); + } + }//end of columns + }//end of rows + + $heightrow = &$table['hr']; + foreach ($listspan as $span) { + list($i, $j) = $span; + $c = &$cells[$i][$j]; + $lr = $i + $c['rowspan']; + if ($lr > $numrows) { + $lr = $numrows; + } + $hs = $hsa = 0; + $list = []; + for ($k = $i; $k < $lr; $k++) { + $hs += $heightrow[$k]; + // mPDF 6 + $sh = false; // specified height + for ($m = 0; $m < $numcols; $m++) { // columns + $tc = &$cells[$k][$m]; + if (isset($tc['rowspan'])) { + continue; + } + if (isset($tc['h'])) { + $sh = true; + break; + } + } + if (!$sh) { + $list[] = $k; + } + } + + if ($table['borders_separate']) { + if ($i == ($numrows - 1) || ($i + $c['rowspan']) == ($numrows)) { + $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + } else { + $extra = $table['border_spacing_V'] / 2; + } + } else { + if (!$this->simpleTables) { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($c['borderbin']); + } else { + $bb = $c['border_details']['B']['w']; + } + $extra = $bb / 2; + } elseif ($this->simpleTables) { + $extra = $table['simple']['border_details']['B']['w'] / 2; + } + } + if (!empty($table['is_thead'][$i])) { + $headerrowheight = max($headerrowheight, $hs); + $headerrowheightplus = max($headerrowheightplus, $hs + $extra); + } elseif (!empty($table['is_tfoot'][$i])) { + $footerrowheight = max($footerrowheight, $hs); + $footerrowheightplus = max($footerrowheightplus, $hs + $extra); + } else { + $checkmaxheight = max($checkmaxheight, $hs); + $checkmaxheightplus = max($checkmaxheightplus, $hs + $extra); + } + if ($this->tableLevel == 1 && $i == (isset($table['headernrows']) ? $table['headernrows'] : 0)) { + $firstrowheight = max($hs, $firstrowheight); + } + + if ($c['mih'] > $hs) { + if (!$hs) { + for ($k = $i; $k < $lr; $k++) { + $heightrow[$k] = $c['mih'] / $c['rowspan']; + } + } elseif (!count($list)) { // no rows in the rowspan have a height specified, so share amongst all rows equally + $hi = $c['mih'] - $hs; + for ($k = $i; $k < $lr; $k++) { + $heightrow[$k] += ($heightrow[$k] / $hs) * $hi; + } + } else { + $hi = $c['mih'] - $hs; // mPDF 6 + foreach ($list as $k) { + $heightrow[$k] += $hi / (count($list)); // mPDF 6 + } + } + } + unset($c); + + // If rowspans overlap so that one or more rows do not have a height set... + // i.e. for one or more rows, the only cells (explicit) in that row have rowspan>1 + // so heightrow is still == 0 + if ($heightrow[$i] == 0) { + // Get row extent to analyse above and below + $top = $i; + foreach ($listspan as $checkspan) { + list($cki, $ckj) = $checkspan; + $c = &$cells[$cki][$ckj]; + if (isset($c['rowspan']) && $c['rowspan'] > 1) { + if (($cki + $c['rowspan'] - 1) >= $i) { + $top = min($top, $cki); + } + } + } + $bottom = $i + $c['rowspan'] - 1; + // Check for overconstrained conditions + for ($k = $top; $k <= $bottom; $k++) { + // if ['hr'] for any of the others is also 0, then abort (too complicated) + if ($k != $i && $heightrow[$k] == 0) { + break(1); + } + // check again that top and bottom are not crossed by rowspans - or abort (too complicated) + if ($k == $top) { + // ???? take account of colspan as well??? + for ($m = 0; $m < $numcols; $m++) { // columns + if (!isset($cells[$k][$m]) || $cells[$k][$m] == 0) { + break(2); + } + } + } elseif ($k == $bottom) { + // ???? take account of colspan as well??? + for ($m = 0; $m < $numcols; $m++) { // columns + $c = &$cells[$k][$m]; + if (isset($c['rowspan']) && $c['rowspan'] > 1) { + break(2); + } + } + } + } + // By columns add up col height using ['h'] if set or ['mih'] if not + // Intentionally do not substract border-spacing + $colH = []; + $extH = 0; + $newhr = []; + for ($m = 0; $m < $numcols; $m++) { // columns + for ($k = $top; $k <= $bottom; $k++) { + if (isset($cells[$k][$m]) && $cells[$k][$m] != 0) { + $c = &$cells[$k][$m]; + if (isset($c['h']) && $c['h']) { + $useh = $c['h']; + } // ???? take account of colspan as well??? + else { + $useh = $c['mih']; + } + if (isset($colH[$m])) { + $colH[$m] += $useh; + } else { + $colH[$m] = $useh; + } + if (!isset($c['rowspan']) || $c['rowspan'] < 2) { + $newhr[$k] = max((isset($newhr[$k]) ? $newhr[$k] : 0), $useh); + } + } + } + $extH = max($extH, $colH[$m]); // mPDF 6 + } + $newhr[$i] = $extH - array_sum($newhr); + for ($k = $top; $k <= $bottom; $k++) { + $heightrow[$k] = $newhr[$k]; + } + } + + + unset($c); + } + + $table['h'] = array_sum($heightrow); + unset($heightrow); + + if ($table['borders_separate']) { + $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['border_details']['T']['w'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] + $table['padding']['T'] + $table['padding']['B']; + } else { + $table['h'] += $table['margin']['T'] + $table['margin']['B'] + $table['max_cell_border_width']['T'] / 2 + $table['max_cell_border_width']['B'] / 2; + } + + $maxrowheight = $checkmaxheightplus + $headerrowheightplus + $footerrowheightplus; + $maxfirstrowheight = $firstrowheight + $headerrowheightplus + $footerrowheightplus; // includes thead, 1st row and tfoot + return [$table['h'], $maxrowheight, $temppgheight, $remainingpage, $maxfirstrowheight]; + } + + function _tableGetWidth(&$table, $i, $j) + { + $cell = &$table['cells'][$i][$j]; + if ($cell) { + if (isset($cell['x0'])) { + return [$cell['x0'], $cell['w0']]; + } + $x = 0; + $widthcols = &$table['wc']; + for ($k = 0; $k < $j; $k++) { + $x += $widthcols[$k]; + } + $w = $widthcols[$j]; + if (isset($cell['colspan'])) { + for ($k = $j + $cell['colspan'] - 1; $k > $j; $k--) { + $w += $widthcols[$k]; + } + } + $cell['x0'] = $x; + $cell['w0'] = $w; + return [$x, $w]; + } + return [0, 0]; + } + + function _splitTableGetWidth(&$table, $i, $j) + { + $cell = &$table['cells'][$i][$j]; + if ($cell) { + if (isset($cell['x0'])) { + return [$cell['x0'], $cell['w0']]; + } + $x = 0; + $widthcols = &$table['wc']; + $pg = $table['colPg'][$j]; + for ($k = 0; $k < $j; $k++) { + if ($table['colPg'][$k] == $pg) { + $x += $widthcols[$k]; + } + } + $w = $widthcols[$j]; + if (isset($cell['colspan'])) { + for ($k = $j + $cell['colspan'] - 1; $k > $j; $k--) { + if ($table['colPg'][$k] == $pg) { + $w += $widthcols[$k]; + } + } + } + $cell['x0'] = $x; + $cell['w0'] = $w; + return [$x, $w]; + } + return [0, 0]; + } + + function _tableGetHeight(&$table, $i, $j) + { + $cell = &$table['cells'][$i][$j]; + if ($cell) { + if (isset($cell['y0'])) { + return [$cell['y0'], $cell['h0']]; + } + $y = 0; + $heightrow = &$table['hr']; + for ($k = 0; $k < $i; $k++) { + $y += $heightrow[$k]; + } + $h = $heightrow[$i]; + if (isset($cell['rowspan'])) { + for ($k = $i + $cell['rowspan'] - 1; $k > $i; $k--) { + if (array_key_exists($k, $heightrow)) { + $h += $heightrow[$k]; + } else { + $this->logger->debug('Possible non-wellformed HTML markup in a table', ['context' => LogContext::HTML_MARKUP]); + } + } + } + $cell['y0'] = $y; + $cell['h0'] = $h; + return [$y, $h]; + } + return [0, 0]; + } + + function _tableGetMaxRowHeight($table, $row) + { + if ($row == $table['nc'] - 1) { + return $table['hr'][$row]; + } + $maxrowheight = $table['hr'][$row]; + for ($i = $row + 1; $i < $table['nr']; $i++) { + $cellsset = 0; + for ($j = 0; $j < $table['nc']; $j++) { + if ($table['cells'][$i][$j]) { + if (isset($table['cells'][$i][$j]['colspan'])) { + $cellsset += $table['cells'][$i][$j]['colspan']; + } else { + $cellsset += 1; + } + } + } + if ($cellsset == $table['nc']) { + return $maxrowheight; + } else { + $maxrowheight += $table['hr'][$i]; + } + } + return $maxrowheight; + } + + // CHANGED TO ALLOW TABLE BORDER TO BE SPECIFIED CORRECTLY - added border_details + function _tableRect($x, $y, $w, $h, $bord = -1, $details = [], $buffer = false, $bSeparate = false, $cort = 'cell', $tablecorner = '', $bsv = 0, $bsh = 0) + { + $cellBorderOverlay = []; + + if ($bord == -1) { + $this->Rect($x, $y, $w, $h); + } elseif ($this->simpleTables && ($cort == 'cell')) { + $this->SetLineWidth($details['L']['w']); + if ($details['L']['c']) { + $this->SetDColor($details['L']['c']); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + $this->SetLineJoin(0); + $this->Rect($x, $y, $w, $h); + } elseif ($bord) { + if (!$bSeparate && $buffer) { + $priority = 'LRTB'; + for ($p = 0; $p < strlen($priority); $p++) { + $side = $priority[$p]; + $details['p'] = $side; + + $dom = 0; + if (isset($details[$side]['w'])) { + $dom += ($details[$side]['w'] * 100000); + } + if (isset($details[$side]['style'])) { + $dom += (array_search($details[$side]['style'], $this->borderstyles) * 100); + } + if (isset($details[$side]['dom'])) { + $dom += ($details[$side]['dom'] * 10); + } + + // Precedence to darker colours at joins + $coldom = 0; + if (isset($details[$side]['c']) && is_array($details[$side]['c'])) { + if ($details[$side]['c'][0] == 3) { // RGB + $coldom = 10 - (((ord($details[$side]['c'][1]) * 1.00) + (ord($details[$side]['c'][2]) * 1.00) + (ord($details[$side]['c'][3]) * 1.00)) / 76.5); + } + } // 10 black - 0 white + if ($coldom) { + $dom += $coldom; + } + // Lastly precedence to RIGHT and BOTTOM cells at joins + if (isset($details['cellposdom'])) { + $dom += $details['cellposdom']; + } + + $save = false; + if ($side == 'T' && $this->issetBorder($bord, Border::TOP)) { + $cbord = Border::TOP; + $save = true; + } elseif ($side == 'L' && $this->issetBorder($bord, Border::LEFT)) { + $cbord = Border::LEFT; + $save = true; + } elseif ($side == 'R' && $this->issetBorder($bord, Border::RIGHT)) { + $cbord = Border::RIGHT; + $save = true; + } elseif ($side == 'B' && $this->issetBorder($bord, Border::BOTTOM)) { + $cbord = Border::BOTTOM; + $save = true; + } + + if ($save) { + $this->cellBorderBuffer[] = pack("A16nCnda6A10d14", str_pad(sprintf("%08.7f", $dom), 16, "0", STR_PAD_LEFT), $cbord, ord($side), $details[$side]['s'], $details[$side]['w'], $details[$side]['c'], $details[$side]['style'], $x, $y, $w, $h, $details['mbw']['BL'], $details['mbw']['BR'], $details['mbw']['RT'], $details['mbw']['RB'], $details['mbw']['TL'], $details['mbw']['TR'], $details['mbw']['LT'], $details['mbw']['LB'], $details['cellposdom'], 0); + if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset' || $details[$side]['style'] == 'double') { + $details[$side]['overlay'] = true; + $this->cellBorderBuffer[] = pack("A16nCnda6A10d14", str_pad(sprintf("%08.7f", ($dom + 4)), 16, "0", STR_PAD_LEFT), $cbord, ord($side), $details[$side]['s'], $details[$side]['w'], $details[$side]['c'], $details[$side]['style'], $x, $y, $w, $h, $details['mbw']['BL'], $details['mbw']['BR'], $details['mbw']['RT'], $details['mbw']['RB'], $details['mbw']['TL'], $details['mbw']['TR'], $details['mbw']['LT'], $details['mbw']['LB'], $details['cellposdom'], 1); + } + } + } + return; + } + + if (isset($details['p']) && strlen($details['p']) > 1) { + $priority = $details['p']; + } else { + $priority = 'LTRB'; + } + $Tw = 0; + $Rw = 0; + $Bw = 0; + $Lw = 0; + if (isset($details['T']['w'])) { + $Tw = $details['T']['w']; + } + if (isset($details['R']['w'])) { + $Rw = $details['R']['w']; + } + if (isset($details['B']['w'])) { + $Bw = $details['B']['w']; + } + if (isset($details['L']['w'])) { + $Lw = $details['L']['w']; + } + + $x2 = $x + $w; + $y2 = $y + $h; + $oldlinewidth = $this->LineWidth; + + for ($p = 0; $p < strlen($priority); $p++) { + $side = $priority[$p]; + $xadj = 0; + $xadj2 = 0; + $yadj = 0; + $yadj2 = 0; + $print = false; + if ($Tw && $side == 'T' && $this->issetBorder($bord, Border::TOP)) { // TOP + $ly1 = $y; + $ly2 = $y; + $lx1 = $x; + $lx2 = $x2; + $this->SetLineWidth($Tw); + if ($cort == 'cell' || strpos($tablecorner, 'L') !== false) { + if ($Tw > $Lw) { + $xadj = ($Tw - $Lw) / 2; + } + if ($Tw < $Lw) { + $xadj = ($Tw + $Lw) / 2; + } + } else { + $xadj = $Tw / 2 - $bsh / 2; + } + if ($cort == 'cell' || strpos($tablecorner, 'R') !== false) { + if ($Tw > $Rw) { + $xadj2 = ($Tw - $Rw) / 2; + } + if ($Tw < $Rw) { + $xadj2 = ($Tw + $Rw) / 2; + } + } else { + $xadj2 = $Tw / 2 - $bsh / 2; + } + if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['TL'])) { + $xadj = ($Tw - $details['mbw']['TL']) / 2; + } + if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['TR'])) { + $xadj2 = ($Tw - $details['mbw']['TR']) / 2; + } + $print = true; + } + if ($Lw && $side == 'L' && $this->issetBorder($bord, Border::LEFT)) { // LEFT + $ly1 = $y; + $ly2 = $y2; + $lx1 = $x; + $lx2 = $x; + $this->SetLineWidth($Lw); + if ($cort == 'cell' || strpos($tablecorner, 'T') !== false) { + if ($Lw > $Tw) { + $yadj = ($Lw - $Tw) / 2; + } + if ($Lw < $Tw) { + $yadj = ($Lw + $Tw) / 2; + } + } else { + $yadj = $Lw / 2 - $bsv / 2; + } + if ($cort == 'cell' || strpos($tablecorner, 'B') !== false) { + if ($Lw > $Bw) { + $yadj2 = ($Lw - $Bw) / 2; + } + if ($Lw < $Bw) { + $yadj2 = ($Lw + $Bw) / 2; + } + } else { + $yadj2 = $Lw / 2 - $bsv / 2; + } + if (!$bSeparate && $details['mbw']['LT']) { + $yadj = ($Lw - $details['mbw']['LT']) / 2; + } + if (!$bSeparate && $details['mbw']['LB']) { + $yadj2 = ($Lw - $details['mbw']['LB']) / 2; + } + $print = true; + } + if ($Rw && $side == 'R' && $this->issetBorder($bord, Border::RIGHT)) { // RIGHT + $ly1 = $y; + $ly2 = $y2; + $lx1 = $x2; + $lx2 = $x2; + $this->SetLineWidth($Rw); + if ($cort == 'cell' || strpos($tablecorner, 'T') !== false) { + if ($Rw < $Tw) { + $yadj = ($Rw + $Tw) / 2; + } + if ($Rw > $Tw) { + $yadj = ($Rw - $Tw) / 2; + } + } else { + $yadj = $Rw / 2 - $bsv / 2; + } + + if ($cort == 'cell' || strpos($tablecorner, 'B') !== false) { + if ($Rw > $Bw) { + $yadj2 = ($Rw - $Bw) / 2; + } + if ($Rw < $Bw) { + $yadj2 = ($Rw + $Bw) / 2; + } + } else { + $yadj2 = $Rw / 2 - $bsv / 2; + } + + if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['RT'])) { + $yadj = ($Rw - $details['mbw']['RT']) / 2; + } + if (!$bSeparate && !empty($details['mbw']) && !empty($details['mbw']['RB'])) { + $yadj2 = ($Rw - $details['mbw']['RB']) / 2; + } + $print = true; + } + if ($Bw && $side == 'B' && $this->issetBorder($bord, Border::BOTTOM)) { // BOTTOM + $ly1 = $y2; + $ly2 = $y2; + $lx1 = $x; + $lx2 = $x2; + $this->SetLineWidth($Bw); + if ($cort == 'cell' || strpos($tablecorner, 'L') !== false) { + if ($Bw > $Lw) { + $xadj = ($Bw - $Lw) / 2; + } + if ($Bw < $Lw) { + $xadj = ($Bw + $Lw) / 2; + } + } else { + $xadj = $Bw / 2 - $bsh / 2; + } + if ($cort == 'cell' || strpos($tablecorner, 'R') !== false) { + if ($Bw > $Rw) { + $xadj2 = ($Bw - $Rw) / 2; + } + if ($Bw < $Rw) { + $xadj2 = ($Bw + $Rw) / 2; + } + } else { + $xadj2 = $Bw / 2 - $bsh / 2; + } + if (!$bSeparate && isset($details['mbw']) && isset($details['mbw']['BL'])) { + $xadj = ($Bw - $details['mbw']['BL']) / 2; + } + if (!$bSeparate && isset($details['mbw']) && isset($details['mbw']['BR'])) { + $xadj2 = ($Bw - $details['mbw']['BR']) / 2; + } + $print = true; + } + + // Now draw line + if ($print) { + /* -- TABLES-ADVANCED-BORDERS -- */ + if ($details[$side]['style'] == 'double') { + if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) { + if ($details[$side]['c']) { + $this->SetDColor($details[$side]['c']); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2); + } + if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) { + if ($bSeparate && $cort == 'table') { + if ($side == 'T') { + $xadj -= $this->LineWidth / 2; + $xadj2 -= $this->LineWidth; + if ($this->issetBorder($bord, Border::LEFT)) { + $xadj += $this->LineWidth / 2; + } + if ($this->issetBorder($bord, Border::RIGHT)) { + $xadj2 += $this->LineWidth; + } + } + if ($side == 'L') { + $yadj -= $this->LineWidth / 2; + $yadj2 -= $this->LineWidth; + if ($this->issetBorder($bord, Border::TOP)) { + $yadj += $this->LineWidth / 2; + } + if ($this->issetBorder($bord, Border::BOTTOM)) { + $yadj2 += $this->LineWidth; + } + } + if ($side == 'B') { + $xadj -= $this->LineWidth / 2; + $xadj2 -= $this->LineWidth; + if ($this->issetBorder($bord, Border::LEFT)) { + $xadj += $this->LineWidth / 2; + } + if ($this->issetBorder($bord, Border::RIGHT)) { + $xadj2 += $this->LineWidth; + } + } + if ($side == 'R') { + $yadj -= $this->LineWidth / 2; + $yadj2 -= $this->LineWidth; + if ($this->issetBorder($bord, Border::TOP)) { + $yadj += $this->LineWidth / 2; + } + if ($this->issetBorder($bord, Border::BOTTOM)) { + $yadj2 += $this->LineWidth; + } + } + } + + $this->SetLineWidth($this->LineWidth / 3); + + $tbcol = $this->colorConverter->convert(255, $this->PDFAXwarnings); + for ($l = 0; $l <= $this->blklvl; $l++) { + if ($this->blk[$l]['bgcolor']) { + $tbcol = ($this->blk[$l]['bgcolorarray']); + } + } + + if ($bSeparate) { + $cellBorderOverlay[] = [ + 'x' => $lx1 + $xadj, + 'y' => $ly1 + $yadj, + 'x2' => $lx2 - $xadj2, + 'y2' => $ly2 - $yadj2, + 'col' => $tbcol, + 'lw' => $this->LineWidth, + ]; + } else { + $this->SetDColor($tbcol); + $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2); + } + } + } elseif (isset($details[$side]['style']) && ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'groove' || $details[$side]['style'] == 'inset' || $details[$side]['style'] == 'outset')) { + if (!isset($details[$side]['overlay']) || !$details[$side]['overlay'] || $bSeparate) { + if ($details[$side]['c']) { + $this->SetDColor($details[$side]['c']); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + if ($details[$side]['style'] == 'outset' || $details[$side]['style'] == 'groove') { + $nc = $this->colorConverter->darken($details[$side]['c']); + $this->SetDColor($nc); + } elseif ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') { + $nc = $this->colorConverter->lighten($details[$side]['c']); + $this->SetDColor($nc); + } + $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2); + } + if ((isset($details[$side]['overlay']) && $details[$side]['overlay']) || $bSeparate) { + if ($details[$side]['c']) { + $this->SetDColor($details[$side]['c']); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + $doubleadj = ($this->LineWidth) / 3; + $this->SetLineWidth($this->LineWidth / 2); + $xadj3 = $yadj3 = $wadj3 = $hadj3 = 0; + + if ($details[$side]['style'] == 'ridge' || $details[$side]['style'] == 'inset') { + $nc = $this->colorConverter->darken($details[$side]['c']); + + if ($bSeparate && $cort == 'table') { + if ($side == 'T') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = -$this->LineWidth / 2; + $wadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::LEFT)) { + $xadj3 += $this->LineWidth; + $wadj3 -= $this->LineWidth; + } + if ($this->issetBorder($bord, Border::RIGHT)) { + $wadj3 -= $this->LineWidth * 2; + } + } + if ($side == 'L') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = -$this->LineWidth / 2; + $hadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::TOP)) { + $yadj3 += $this->LineWidth; + $hadj3 -= $this->LineWidth; + } + if ($this->issetBorder($bord, Border::BOTTOM)) { + $hadj3 -= $this->LineWidth * 2; + } + } + if ($side == 'B') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = -$this->LineWidth / 2; + $wadj3 = $this->LineWidth; + } + if ($side == 'R') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = -$this->LineWidth / 2; + $hadj3 = $this->LineWidth; + } + } elseif ($side == 'T') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = $this->LineWidth / 2; + $wadj3 = -$this->LineWidth * 2; + } elseif ($side == 'L') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = $this->LineWidth / 2; + $hadj3 = -$this->LineWidth * 2; + } elseif ($side == 'B' && $bSeparate) { + $yadj3 = $this->LineWidth / 2; + $wadj3 = $this->LineWidth / 2; + } elseif ($side == 'R' && $bSeparate) { + $xadj3 = $this->LineWidth / 2; + $hadj3 = $this->LineWidth / 2; + } elseif ($side == 'B') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = $this->LineWidth / 2; + } elseif ($side == 'R') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = $this->LineWidth / 2; + } + } else { + $nc = $this->colorConverter->lighten($details[$side]['c']); + + if ($bSeparate && $cort == 'table') { + if ($side == 'T') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = -$this->LineWidth / 2; + $wadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::LEFT)) { + $xadj3 += $this->LineWidth; + $wadj3 -= $this->LineWidth; + } + } + if ($side == 'L') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = -$this->LineWidth / 2; + $hadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::TOP)) { + $yadj3 += $this->LineWidth; + $hadj3 -= $this->LineWidth; + } + } + if ($side == 'B') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = -$this->LineWidth / 2; + $wadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::LEFT)) { + $xadj3 += $this->LineWidth; + $wadj3 -= $this->LineWidth; + } + } + if ($side == 'R') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = -$this->LineWidth / 2; + $hadj3 = $this->LineWidth; + if ($this->issetBorder($bord, Border::TOP)) { + $yadj3 += $this->LineWidth; + $hadj3 -= $this->LineWidth; + } + } + } elseif ($side == 'T') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = $this->LineWidth / 2; + } elseif ($side == 'L') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = $this->LineWidth / 2; + } elseif ($side == 'B' && $bSeparate) { + $yadj3 = $this->LineWidth / 2; + $xadj3 = $this->LineWidth / 2; + } elseif ($side == 'R' && $bSeparate) { + $xadj3 = $this->LineWidth / 2; + $yadj3 = $this->LineWidth / 2; + } elseif ($side == 'B') { + $yadj3 = $this->LineWidth / 2; + $xadj3 = -$this->LineWidth / 2; + $wadj3 = $this->LineWidth; + } elseif ($side == 'R') { + $xadj3 = $this->LineWidth / 2; + $yadj3 = -$this->LineWidth / 2; + $hadj3 = $this->LineWidth; + } + } + + if ($bSeparate) { + $cellBorderOverlay[] = [ + 'x' => $lx1 + $xadj + $xadj3, + 'y' => $ly1 + $yadj + $yadj3, + 'x2' => $lx2 - $xadj2 + $xadj3 + $wadj3, + 'y2' => $ly2 - $yadj2 + $yadj3 + $hadj3, + 'col' => $nc, + 'lw' => $this->LineWidth, + ]; + } else { + $this->SetDColor($nc); + $this->Line($lx1 + $xadj + $xadj3, $ly1 + $yadj + $yadj3, $lx2 - $xadj2 + $xadj3 + $wadj3, $ly2 - $yadj2 + $yadj3 + $hadj3); + } + } + } else { + /* -- END TABLES-ADVANCED-BORDERS -- */ + if ($details[$side]['style'] == 'dashed') { + $dashsize = 2; // final dash will be this + 1*linewidth + $dashsizek = 1.5; // ratio of Dash/Blank + $this->SetDash($dashsize, ($dashsize / $dashsizek) + ($this->LineWidth * 2)); + } elseif ($details[$side]['style'] == 'dotted') { + $this->SetLineJoin(1); + $this->SetLineCap(1); + $this->SetDash(0.001, ($this->LineWidth * 2)); + } + if ($details[$side]['c']) { + $this->SetDColor($details[$side]['c']); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + $this->Line($lx1 + $xadj, $ly1 + $yadj, $lx2 - $xadj2, $ly2 - $yadj2); + /* -- TABLES-ADVANCED-BORDERS -- */ + } + /* -- END TABLES-ADVANCED-BORDERS -- */ + + // Reset Corners + $this->SetDash(); + // BUTT style line cap + $this->SetLineCap(2); + } + } + + if ($bSeparate && count($cellBorderOverlay)) { + foreach ($cellBorderOverlay as $cbo) { + $this->SetLineWidth($cbo['lw']); + $this->SetDColor($cbo['col']); + $this->Line($cbo['x'], $cbo['y'], $cbo['x2'], $cbo['y2']); + } + } + + // $this->SetLineWidth($oldlinewidth); + // $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + } + + /* -- TABLES -- */ + /* -- TABLES-ADVANCED-BORDERS -- */ + + /* -- END TABLES-ADVANCED-BORDERS -- */ + + function setBorder(&$var, $flag, $set = true) + { + $flag = intval($flag); + if ($set) { + $set = true; + } + $var = intval($var); + $var = $set ? ($var | $flag) : ($var & ~$flag); + } + + function issetBorder($var, $flag) + { + $flag = intval($flag); + $var = intval($var); + return (($var & $flag) == $flag); + } + + function _table2cellBorder(&$tableb, &$cbdb, &$cellb, $bval) + { + if ($tableb && $tableb['w'] > $cbdb['w']) { + $cbdb = $tableb; + $this->setBorder($cellb, $bval); + } elseif ($tableb && $tableb['w'] == $cbdb['w'] && array_search($tableb['style'], $this->borderstyles) > array_search($cbdb['style'], $this->borderstyles)) { + $cbdb = $tableb; + $this->setBorder($cellb, $bval); + } + } + + // FIX BORDERS ******************************************** + function _fixTableBorders(&$table) + { + if (!$table['borders_separate'] && $table['border_details']['L']['w']) { + $table['max_cell_border_width']['L'] = $table['border_details']['L']['w']; + } + if (!$table['borders_separate'] && $table['border_details']['R']['w']) { + $table['max_cell_border_width']['R'] = $table['border_details']['R']['w']; + } + if (!$table['borders_separate'] && $table['border_details']['T']['w']) { + $table['max_cell_border_width']['T'] = $table['border_details']['T']['w']; + } + if (!$table['borders_separate'] && $table['border_details']['B']['w']) { + $table['max_cell_border_width']['B'] = $table['border_details']['B']['w']; + } + if ($this->simpleTables) { + return; + } + $cells = &$table['cells']; + $numcols = $table['nc']; + $numrows = $table['nr']; + /* -- TABLES-ADVANCED-BORDERS -- */ + if (isset($table['topntail']) && $table['topntail']) { + $tntborddet = $this->border_details($table['topntail']); + } + if (isset($table['thead-underline']) && $table['thead-underline']) { + $thuborddet = $this->border_details($table['thead-underline']); + } + /* -- END TABLES-ADVANCED-BORDERS -- */ + + for ($i = 0; $i < $numrows; $i++) { // Rows + for ($j = 0; $j < $numcols; $j++) { // Columns + if (isset($cells[$i][$j]) && $cells[$i][$j]) { + $cell = &$cells[$i][$j]; + if ($this->packTableData) { + $cbord = $this->_unpackCellBorder($cell['borderbin']); + } else { + $cbord = &$cells[$i][$j]; + } + + // mPDF 5.7.3 + if (!$cbord['border'] && $cbord['border'] !== 0 && isset($table['border']) && $table['border'] && $this->table_border_attr_set) { + $cbord['border'] = $table['border']; + $cbord['border_details'] = $table['border_details']; + } + + if (isset($cell['colspan']) && $cell['colspan'] > 1) { + $ccolsp = $cell['colspan']; + } else { + $ccolsp = 1; + } + if (isset($cell['rowspan']) && $cell['rowspan'] > 1) { + $crowsp = $cell['rowspan']; + } else { + $crowsp = 1; + } + + $cbord['border_details']['cellposdom'] = ((($i + 1) / $numrows) / 10000 ) + ((($j + 1) / $numcols) / 10 ); + // Inherit Cell border from Table border + if ($this->table_border_css_set && !$table['borders_separate']) { + if ($i == 0) { + $this->_table2cellBorder($table['border_details']['T'], $cbord['border_details']['T'], $cbord['border'], Border::TOP); + } + if ($i == ($numrows - 1) || ($i + $crowsp) == ($numrows)) { + $this->_table2cellBorder($table['border_details']['B'], $cbord['border_details']['B'], $cbord['border'], Border::BOTTOM); + } + if ($j == 0) { + $this->_table2cellBorder($table['border_details']['L'], $cbord['border_details']['L'], $cbord['border'], Border::LEFT); + } + if ($j == ($numcols - 1) || ($j + $ccolsp) == ($numcols)) { + $this->_table2cellBorder($table['border_details']['R'], $cbord['border_details']['R'], $cbord['border'], Border::RIGHT); + } + } + + /* -- TABLES-ADVANCED-BORDERS -- */ + $fixbottom = true; + if (isset($table['topntail']) && $table['topntail']) { + if ($i == 0) { + $cbord['border_details']['T'] = $tntborddet; + $this->setBorder($cbord['border'], Border::TOP); + } + if ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows'] - 1) { + $cbord['border_details']['B'] = $tntborddet; + $this->setBorder($cbord['border'], Border::BOTTOM); + $fixbottom = false; + } elseif ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows']) { + if (!$table['borders_separate']) { + $cbord['border_details']['T'] = $tntborddet; + $this->setBorder($cbord['border'], Border::TOP); + } + } + if ($this->tableLevel == 1 && $table['footernrows'] > 0 && $i == ($numrows - $table['footernrows'] - 1)) { + if (!$table['borders_separate']) { + $cbord['border_details']['B'] = $tntborddet; + $this->setBorder($cbord['border'], Border::BOTTOM); + $fixbottom = false; + } + } elseif ($this->tableLevel == 1 && $table['footernrows'] > 0 && $i == ($numrows - $table['footernrows'])) { + $cbord['border_details']['T'] = $tntborddet; + $this->setBorder($cbord['border'], Border::TOP); + } + if ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader + if (!$table['borders_separate']) { + $cbord['border_details']['T'] = $tntborddet; + $this->setBorder($cbord['border'], Border::TOP); + } + } + if ($i == ($numrows - 1) || ($i + $crowsp) == ($numrows)) { + $cbord['border_details']['B'] = $tntborddet; + $this->setBorder($cbord['border'], Border::BOTTOM); + } + } + if (isset($table['thead-underline']) && $table['thead-underline']) { + if ($table['borders_separate']) { + if ($i == 0) { + $cbord['border_details']['B'] = $thuborddet; + $this->setBorder($cbord['border'], Border::BOTTOM); + $fixbottom = false; + } + } else { + if ($this->tableLevel == 1 && $table['headernrows'] > 0 && $i == $table['headernrows'] - 1) { + $cbord['border_details']['T'] = $thuborddet; + $this->setBorder($cbord['border'], Border::TOP); + } elseif ($this->tabletheadjustfinished) { // $this->tabletheadjustfinished called from tableheader + $cbord['border_details']['T'] = $thuborddet; + $this->setBorder($cbord['border'], Border::TOP); + } + } + } + + // Collapse Border - Algorithm for conflicting borders + // Hidden >> Width >> double>solid>dashed>dotted... >> style set on cell>table >> top/left>bottom/right + // Do not turn off border which is overridden + // Needed for page break for TOP/BOTTOM both to be defined in Collapsed borders + // Means it is painted twice. (Left/Right can still disable overridden border) + if (!$table['borders_separate']) { + + if (($i < ($numrows - 1) || ($i + $crowsp) < $numrows ) && $fixbottom) { // Bottom + + for ($cspi = 0; $cspi < $ccolsp; $cspi++) { + + // already defined Top for adjacent cell below + if (isset($cells[($i + $crowsp)][$j + $cspi])) { + if ($this->packTableData) { + $adjc = $cells[($i + $crowsp)][$j + $cspi]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[($i + $crowsp)][$j + $cspi]; + } + } else { + $celladj = false; + } + + if (isset($celladj['border_details']['T']['s']) && $celladj['border_details']['T']['s'] == 1) { + + $csadj = $celladj['border_details']['T']['w']; + $csthis = $cbord['border_details']['B']['w']; + + // Hidden + if ($cbord['border_details']['B']['style'] == 'hidden') { + + $celladj['border_details']['T'] = $cbord['border_details']['B']; + $this->setBorder($celladj['border'], Border::TOP, false); + $this->setBorder($cbord['border'], Border::BOTTOM, false); + + } elseif ($celladj['border_details']['T']['style'] == 'hidden') { + + $cbord['border_details']['B'] = $celladj['border_details']['T']; + $this->setBorder($cbord['border'], Border::BOTTOM, false); + $this->setBorder($celladj['border'], Border::TOP, false); + + } elseif ($csthis > $csadj) { // Width + + if (!isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) || (isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) && $cells[($i + $crowsp)][$j + $cspi]['colspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['T'] = $cbord['border_details']['B']; + $this->setBorder($cbord['border'], Border::BOTTOM); + } + + } elseif ($csadj > $csthis) { + + if ($ccolsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['B'] = $celladj['border_details']['T']; + $this->setBorder($celladj['border'], Border::TOP); + } + + } elseif (array_search($cbord['border_details']['B']['style'], $this->borderstyles) > array_search($celladj['border_details']['T']['style'], $this->borderstyles)) { // double>solid>dashed>dotted... + + if (!isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) || (isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) && $cells[($i + $crowsp)][$j + $cspi]['colspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['T'] = $cbord['border_details']['B']; + $this->setBorder($cbord['border'], Border::BOTTOM); + } + + } elseif (array_search($celladj['border_details']['T']['style'], $this->borderstyles) > array_search($cbord['border_details']['B']['style'], $this->borderstyles)) { + + if ($ccolsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['B'] = $celladj['border_details']['T']; + $this->setBorder($celladj['border'], Border::TOP); + } + + } elseif ($celladj['border_details']['T']['dom'] > $celladj['border_details']['B']['dom']) { // Style set on cell vs. table + + if ($ccolsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['B'] = $celladj['border_details']['T']; + $this->setBorder($celladj['border'], Border::TOP); + } + + } else { // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT + + if (!isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) || (isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) && $cells[($i + $crowsp)][$j + $cspi]['colspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['T'] = $cbord['border_details']['B']; + $this->setBorder($cbord['border'], Border::BOTTOM); + } + + } + + } elseif ($celladj) { + + if (!isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) || (isset($cells[($i + $crowsp)][$j + $cspi]['colspan']) && $cells[($i + $crowsp)][$j + $cspi]['colspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['T'] = $cbord['border_details']['B']; + } + + } + + // mPDF 5.7.4 + if ($celladj && $this->packTableData) { + $cells[$i + $crowsp][$j + $cspi]['borderbin'] = $this->_packCellBorder($celladj); + } + + unset($celladj); + } + } + + if ($j < ($numcols - 1) || ($j + $ccolsp) < $numcols) { // Right-Left + + for ($cspi = 0; $cspi < $crowsp; $cspi++) { + + // already defined Left for adjacent cell to R + if (isset($cells[($i + $cspi)][$j + $ccolsp])) { + if ($this->packTableData) { + $adjc = $cells[($i + $cspi)][$j + $ccolsp]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[$i + $cspi][$j + $ccolsp]; + } + } else { + $celladj = false; + } + if ($celladj && $celladj['border_details']['L']['s'] == 1) { + $csadj = $celladj['border_details']['L']['w']; + $csthis = $cbord['border_details']['R']['w']; + // Hidden + if ($cbord['border_details']['R']['style'] == 'hidden') { + $celladj['border_details']['L'] = $cbord['border_details']['R']; + $this->setBorder($celladj['border'], Border::LEFT, false); + $this->setBorder($cbord['border'], Border::RIGHT, false); + } elseif ($celladj['border_details']['L']['style'] == 'hidden') { + $cbord['border_details']['R'] = $celladj['border_details']['L']; + $this->setBorder($cbord['border'], Border::RIGHT, false); + $this->setBorder($celladj['border'], Border::LEFT, false); + } // Width + elseif ($csthis > $csadj) { + if (!isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) || (isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) && $cells[($i + $cspi)][$j + $ccolsp]['rowspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['L'] = $cbord['border_details']['R']; + $this->setBorder($cbord['border'], Border::RIGHT); + $this->setBorder($celladj['border'], Border::LEFT, false); + } + } elseif ($csadj > $csthis) { + if ($crowsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['R'] = $celladj['border_details']['L']; + $this->setBorder($cbord['border'], Border::RIGHT, false); + $this->setBorder($celladj['border'], Border::LEFT); + } + } // double>solid>dashed>dotted... + elseif (array_search($cbord['border_details']['R']['style'], $this->borderstyles) > array_search($celladj['border_details']['L']['style'], $this->borderstyles)) { + if (!isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) || (isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) && $cells[($i + $cspi)][$j + $ccolsp]['rowspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['L'] = $cbord['border_details']['R']; + $this->setBorder($celladj['border'], Border::LEFT, false); + $this->setBorder($cbord['border'], Border::RIGHT); + } + } elseif (array_search($celladj['border_details']['L']['style'], $this->borderstyles) > array_search($cbord['border_details']['R']['style'], $this->borderstyles)) { + if ($crowsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['R'] = $celladj['border_details']['L']; + $this->setBorder($cbord['border'], Border::RIGHT, false); + $this->setBorder($celladj['border'], Border::LEFT); + } + } // Style set on cell vs. table + elseif ($celladj['border_details']['L']['dom'] > $cbord['border_details']['R']['dom']) { + if ($crowsp < 2) { // don't overwrite this cell if it spans + $cbord['border_details']['R'] = $celladj['border_details']['L']; + $this->setBorder($celladj['border'], Border::LEFT); + } + } // Style set on cell vs. table - OR - LEFT/TOP (cell) in preference to BOTTOM/RIGHT + else { + if (!isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) || (isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) && $cells[($i + $cspi)][$j + $ccolsp]['rowspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['L'] = $cbord['border_details']['R']; + $this->setBorder($cbord['border'], Border::RIGHT); + } + } + } elseif ($celladj) { + // if right-cell border is not set + if (!isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) || (isset($cells[($i + $cspi)][$j + $ccolsp]['rowspan']) && $cells[($i + $cspi)][$j + $ccolsp]['rowspan'] < 2)) { // don't overwrite bordering cells that span + $celladj['border_details']['L'] = $cbord['border_details']['R']; + } + } + // mPDF 5.7.4 + if ($celladj && $this->packTableData) { + $cells[$i + $cspi][$j + $ccolsp]['borderbin'] = $this->_packCellBorder($celladj); + } + unset($celladj); + } + } + } + + + // Set maximum cell border width meeting at LRTB edges of cell - used for extended cell border + // ['border_details']['mbw']['LT'] = meeting border width - Left border - Top end + if (!$table['borders_separate']) { + + $cbord['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['BL'], $cbord['border_details']['L']['w']); + $cbord['border_details']['mbw']['BR'] = max($cbord['border_details']['mbw']['BR'], $cbord['border_details']['R']['w']); + $cbord['border_details']['mbw']['RT'] = max($cbord['border_details']['mbw']['RT'], $cbord['border_details']['T']['w']); + $cbord['border_details']['mbw']['RB'] = max($cbord['border_details']['mbw']['RB'], $cbord['border_details']['B']['w']); + $cbord['border_details']['mbw']['TL'] = max($cbord['border_details']['mbw']['TL'], $cbord['border_details']['L']['w']); + $cbord['border_details']['mbw']['TR'] = max($cbord['border_details']['mbw']['TR'], $cbord['border_details']['R']['w']); + $cbord['border_details']['mbw']['LT'] = max($cbord['border_details']['mbw']['LT'], $cbord['border_details']['T']['w']); + $cbord['border_details']['mbw']['LB'] = max($cbord['border_details']['mbw']['LB'], $cbord['border_details']['B']['w']); + + if (($i + $crowsp) < $numrows && isset($cells[$i + $crowsp][$j])) { // Has Bottom adjoining cell + + if ($this->packTableData) { + $adjc = $cells[$i + $crowsp][$j]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[$i + $crowsp][$j]; + } + + $cbord['border_details']['mbw']['BL'] = max( + $cbord['border_details']['mbw']['BL'], + $celladj ? $celladj['border_details']['L']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['TL']: 0 + ); + + $cbord['border_details']['mbw']['BR'] = max( + $cbord['border_details']['mbw']['BR'], + $celladj ? $celladj['border_details']['R']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['TR']: 0 + ); + + $cbord['border_details']['mbw']['LB'] = max( + $cbord['border_details']['mbw']['LB'], + $celladj ? $celladj['border_details']['mbw']['LT'] : 0 + ); + + $cbord['border_details']['mbw']['RB'] = max( + $cbord['border_details']['mbw']['RB'], + $celladj ? $celladj['border_details']['mbw']['RT'] : 0 + ); + + unset($celladj); + } + + if (($j + $ccolsp) < $numcols && isset($cells[$i][$j + $ccolsp])) { // Has Right adjoining cell + + if ($this->packTableData) { + $adjc = $cells[$i][$j + $ccolsp]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[$i][$j + $ccolsp]; + } + + $cbord['border_details']['mbw']['RT'] = max( + $cbord['border_details']['mbw']['RT'], + $celladj ? $celladj['border_details']['T']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['LT'] : 0 + ); + + $cbord['border_details']['mbw']['RB'] = max( + $cbord['border_details']['mbw']['RB'], + $celladj ? $celladj['border_details']['B']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['LB'] : 0 + ); + + $cbord['border_details']['mbw']['TR'] = max( + $cbord['border_details']['mbw']['TR'], + $celladj ? $celladj['border_details']['mbw']['TL'] : 0 + ); + + $cbord['border_details']['mbw']['BR'] = max( + $cbord['border_details']['mbw']['BR'], + $celladj ? $celladj['border_details']['mbw']['BL'] : 0 + ); + + unset($celladj); + } + + if ($i > 0 && isset($cells[$i - 1][$j]) && is_array($cells[$i - 1][$j]) && (($this->packTableData && $cells[$i - 1][$j]['borderbin']) || $cells[$i - 1][$j]['border'])) { // Has Top adjoining cell + + if ($this->packTableData) { + $adjc = $cells[$i - 1][$j]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[$i - 1][$j]; + } + + $cbord['border_details']['mbw']['TL'] = max( + $cbord['border_details']['mbw']['TL'], + $celladj ? $celladj['border_details']['L']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['BL'] : 0 + ); + + $cbord['border_details']['mbw']['TR'] = max( + $cbord['border_details']['mbw']['TR'], + $celladj ? $celladj['border_details']['R']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['BR'] : 0 + ); + + $cbord['border_details']['mbw']['LT'] = max( + $cbord['border_details']['mbw']['LT'], + $celladj ? $celladj['border_details']['mbw']['LB'] : 0 + ); + + $cbord['border_details']['mbw']['RT'] = max( + $cbord['border_details']['mbw']['RT'], + $celladj ? $celladj['border_details']['mbw']['RB'] : 0 + ); + + if ($celladj['border_details']['mbw']['BL']) { + $celladj['border_details']['mbw']['BL'] = max($cbord['border_details']['mbw']['TL'], $celladj['border_details']['mbw']['BL']); + } + + if ($celladj['border_details']['mbw']['BR']) { + $celladj['border_details']['mbw']['BR'] = max($celladj['border_details']['mbw']['BR'], $cbord['border_details']['mbw']['TR']); + } + + if ($this->packTableData) { + $cells[$i - 1][$j]['borderbin'] = $this->_packCellBorder($celladj); + } + unset($celladj); + } + + if ($j > 0 && isset($cells[$i][$j - 1]) && is_array($cells[$i][$j - 1]) && (($this->packTableData && $cells[$i][$j - 1]['borderbin']) || $cells[$i][$j - 1]['border'])) { // Has Left adjoining cell + + if ($this->packTableData) { + $adjc = $cells[$i][$j - 1]; + $celladj = $this->_unpackCellBorder($adjc['borderbin']); + } else { + $celladj = & $cells[$i][$j - 1]; + } + + $cbord['border_details']['mbw']['LT'] = max( + $cbord['border_details']['mbw']['LT'], + $celladj ? $celladj['border_details']['T']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['RT'] : 0 + ); + + $cbord['border_details']['mbw']['LB'] = max( + $cbord['border_details']['mbw']['LB'], + $celladj ? $celladj['border_details']['B']['w'] : 0, + $celladj ? $celladj['border_details']['mbw']['RB'] : 0 + ); + + $cbord['border_details']['mbw']['BL'] = max( + $cbord['border_details']['mbw']['BL'], + $celladj ? $celladj['border_details']['mbw']['BR'] : 0 + ); + + $cbord['border_details']['mbw']['TL'] = max( + $cbord['border_details']['mbw']['TL'], + $celladj ? $celladj['border_details']['mbw']['TR'] : 0 + ); + + if ($celladj['border_details']['mbw']['RT']) { + $celladj['border_details']['mbw']['RT'] = max($celladj['border_details']['mbw']['RT'], $cbord['border_details']['mbw']['LT']); + } + + if ($celladj['border_details']['mbw']['RB']) { + $celladj['border_details']['mbw']['RB'] = max($celladj['border_details']['mbw']['RB'], $cbord['border_details']['mbw']['LB']); + } + + if ($this->packTableData) { + $cells[$i][$j - 1]['borderbin'] = $this->_packCellBorder($celladj); + } + + unset($celladj); + } + + + // Update maximum cell border width at LRTB edges of table - used for overall table width + if ($j == 0 && $cbord['border_details']['L']['w']) { + $table['max_cell_border_width']['L'] = max($table['max_cell_border_width']['L'], $cbord['border_details']['L']['w']); + } + if (($j == ($numcols - 1) || ($j + $ccolsp) == $numcols ) && $cbord['border_details']['R']['w']) { + $table['max_cell_border_width']['R'] = max($table['max_cell_border_width']['R'], $cbord['border_details']['R']['w']); + } + if ($i == 0 && $cbord['border_details']['T']['w']) { + $table['max_cell_border_width']['T'] = max($table['max_cell_border_width']['T'], $cbord['border_details']['T']['w']); + } + if (($i == ($numrows - 1) || ($i + $crowsp) == $numrows ) && $cbord['border_details']['B']['w']) { + $table['max_cell_border_width']['B'] = max($table['max_cell_border_width']['B'], $cbord['border_details']['B']['w']); + } + } + /* -- END TABLES-ADVANCED-BORDERS -- */ + + if ($this->packTableData) { + $cell['borderbin'] = $this->_packCellBorder($cbord); + } + + unset($cbord); + + unset($cell); + } + } + } + unset($cell); + } + + // END FIX BORDERS ************************************************************************************ + + function _reverseTableDir(&$table) + { + $cells = &$table['cells']; + $numcols = $table['nc']; + $numrows = $table['nr']; + for ($i = 0; $i < $numrows; $i++) { // Rows + $row = []; + for ($j = ($numcols - 1); $j >= 0; $j--) { // Columns + if (isset($cells[$i][$j]) && $cells[$i][$j]) { + $cell = &$cells[$i][$j]; + $col = $numcols - $j - 1; + if (isset($cell['colspan']) && $cell['colspan'] > 1) { + $col -= ($cell['colspan'] - 1); + } + // Nested content + if (isset($cell['textbuffer'])) { + for ($n = 0; $n < count($cell['textbuffer']); $n++) { + $t = $cell['textbuffer'][$n][0]; + if (substr($t, 0, 19) == "\xbb\xa4\xactype=nestedtable") { + $objattr = $this->_getObjAttr($t); + $objattr['col'] = $col; + $cell['textbuffer'][$n][0] = "\xbb\xa4\xactype=nestedtable,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + $this->table[($this->tableLevel + 1)][$objattr['nestedcontent']]['nestedpos'][1] = $col; + } + } + } + $row[$col] = $cells[$i][$j]; + unset($cell); + } + } + for ($f = 0; $f < $numcols; $f++) { + if (!isset($row[$f])) { + $row[$f] = 0; + } + } + $table['cells'][$i] = $row; + } + } + + function _tableWrite(&$table, $split = false, $startrow = 0, $startcol = 0, $splitpg = 0, $rety = 0) + { + $level = $table['level']; + $levelid = $table['levelid']; + + $cells = &$table['cells']; + $numcols = $table['nc']; + $numrows = $table['nr']; + $maxbwtop = 0; + if ($this->ColActive && $level == 1) { + $this->breakpoints[$this->CurrCol][] = $this->y; + } // *COLUMNS* + + if (!$split || ($startrow == 0 && $splitpg == 0) || $startrow > 0) { + // TABLE TOP MARGIN + if ($table['margin']['T']) { + if (!$this->table_rotate && $level == 1) { + $this->DivLn($table['margin']['T'], $this->blklvl, true, 1); // collapsible + } else { + $this->y += ($table['margin']['T']); + } + } + // Advance down page by half width of top border + if ($table['borders_separate']) { + if ($startrow > 0 && (!isset($table['is_thead']) || count($table['is_thead']) == 0)) { + $adv = $table['border_spacing_V'] / 2; + } else { + $adv = $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2; + } + } else { + $adv = $table['max_cell_border_width']['T'] / 2; + } + if (!$this->table_rotate && $level == 1) { + $this->DivLn($adv); + } else { + $this->y += $adv; + } + } + + if ($level == 1) { + $this->x = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w']; + $x0 = $this->x; + $y0 = $this->y; + $right = $x0 + $this->blk[$this->blklvl]['inner_width']; + $outerfilled = $this->y; // Keep track of how far down the outer DIV bgcolor is painted (NB rowspans) + $this->outerfilled = $this->y; + $this->colsums = []; + } else { + $x0 = $this->x; + $y0 = $this->y; + $right = $x0 + $table['w']; + } + + if ($this->table_rotate) { + $temppgwidth = $this->tbrot_maxw; + $this->PageBreakTrigger = $pagetrigger = $y0 + ($this->blk[$this->blklvl]['inner_width']); + if ($level == 1) { + $this->tbrot_y0 = $this->y - $adv - $table['margin']['T']; + $this->tbrot_x0 = $this->x; + $this->tbrot_w = $table['w']; + if ($table['borders_separate']) { + $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2; + } else { + $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['max_cell_border_width']['T']; + } + } + } else { + $this->PageBreakTrigger = $pagetrigger = ($this->h - $this->bMargin); + if ($level == 1) { + $temppgwidth = $this->blk[$this->blklvl]['inner_width']; + if (isset($table['a']) and ( $table['w'] < $this->blk[$this->blklvl]['inner_width'])) { + if ($table['a'] == 'C') { + $x0 += ((($right - $x0) - $table['w']) / 2); + } elseif ($table['a'] == 'R') { + $x0 = $right - $table['w']; + } + } + } else { + $temppgwidth = $table['w']; + } + } + if (!isset($table['overflow'])) { + $table['overflow'] = null; + } + if ($table['overflow'] == 'hidden' && $level == 1 && !$this->table_rotate && !$this->ColActive) { + // Bounding rectangle to clip + $this->tableClipPath = sprintf('q %.3F %.3F %.3F %.3F re W n', $x0 * Mpdf::SCALE, $this->h * Mpdf::SCALE, $this->blk[$this->blklvl]['inner_width'] * Mpdf::SCALE, -$this->h * Mpdf::SCALE); + $this->writer->write($this->tableClipPath); + } else { + $this->tableClipPath = ''; + } + + + if ($table['borders_separate']) { + $indent = $table['margin']['L'] + $table['border_details']['L']['w'] + $table['padding']['L'] + $table['border_spacing_H'] / 2; + } else { + $indent = $table['margin']['L'] + $table['max_cell_border_width']['L'] / 2; + } + $x0 += $indent; + + $returny = 0; + $lastCol = 0; + $tableheader = []; + $tablefooter = []; + $tableheaderrowheight = 0; + $tablefooterrowheight = 0; + $footery = 0; + + // mPD 3.0 Set the Page & Column where table starts + if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN + $tablestartpage = 'EVEN'; + } elseif (($this->mirrorMargins) && (($this->page) % 2 == 1)) { // ODD + $tablestartpage = 'ODD'; + } else { + $tablestartpage = ''; + } + if ($this->ColActive) { + $tablestartcolumn = $this->CurrCol; + } else { + $tablestartcolumn = ''; + } + + $y = $h = 0; + for ($i = 0; $i < $numrows; $i++) { // Rows + if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i] && $level == 1) { + $tablefooterrowheight += $table['hr'][$i]; + $tablefooter[$i][0]['trbackground-images'] = $table['trbackground-images'][$i]; + $tablefooter[$i][0]['trgradients'] = $table['trgradients'][$i]; + $tablefooter[$i][0]['trbgcolor'] = $table['bgcolor'][$i]; + for ($j = $startcol; $j < $numcols; $j++) { // Columns + if (isset($cells[$i][$j]) && $cells[$i][$j]) { + $cell = &$cells[$i][$j]; + if ($split) { + if ($table['colPg'][$j] != $splitpg) { + continue; + } + list($x, $w) = $this->_splitTableGetWidth($table, $i, $j); + $js = $j - $startcol; + } else { + list($x, $w) = $this->_tableGetWidth($table, $i, $j); + $js = $j; + } + + list($y, $h) = $this->_tableGetHeight($table, $i, $j); + $x += $x0; + $y += $y0; + // Get info of tfoot ==>> table footer + $tablefooter[$i][$js]['x'] = $x; + $tablefooter[$i][$js]['y'] = $y; + $tablefooter[$i][$js]['h'] = $h; + $tablefooter[$i][$js]['w'] = $w; + if (isset($cell['textbuffer'])) { + $tablefooter[$i][$js]['textbuffer'] = $cell['textbuffer']; + } else { + $tablefooter[$i][$js]['textbuffer'] = ''; + } + $tablefooter[$i][$js]['a'] = $cell['a']; + $tablefooter[$i][$js]['R'] = $cell['R']; + $tablefooter[$i][$js]['va'] = $cell['va']; + $tablefooter[$i][$js]['mih'] = $cell['mih']; + if (isset($cell['gradient'])) { + $tablefooter[$i][$js]['gradient'] = $cell['gradient']; // *BACKGROUNDS* + } + if (isset($cell['background-image'])) { + $tablefooter[$i][$js]['background-image'] = $cell['background-image']; // *BACKGROUNDS* + } + + // CELL FILL BGCOLOR + if (!$this->simpleTables) { + if ($this->packTableData) { + $c = $this->_unpackCellBorder($cell['borderbin']); + $tablefooter[$i][$js]['border'] = $c['border']; + $tablefooter[$i][$js]['border_details'] = $c['border_details']; + } else { + $tablefooter[$i][$js]['border'] = $cell['border']; + $tablefooter[$i][$js]['border_details'] = $cell['border_details']; + } + } elseif ($this->simpleTables) { + $tablefooter[$i][$js]['border'] = $table['simple']['border']; + $tablefooter[$i][$js]['border_details'] = $table['simple']['border_details']; + } + $tablefooter[$i][$js]['bgcolor'] = $cell['bgcolor']; + $tablefooter[$i][$js]['padding'] = $cell['padding']; + if (isset($cell['rowspan'])) { + $tablefooter[$i][$js]['rowspan'] = $cell['rowspan']; + } + if (isset($cell['colspan'])) { + $tablefooter[$i][$js]['colspan'] = $cell['colspan']; + } + if (isset($cell['direction'])) { + $tablefooter[$i][$js]['direction'] = $cell['direction']; + } + if (isset($cell['cellLineHeight'])) { + $tablefooter[$i][$js]['cellLineHeight'] = $cell['cellLineHeight']; + } + if (isset($cell['cellLineStackingStrategy'])) { + $tablefooter[$i][$js]['cellLineStackingStrategy'] = $cell['cellLineStackingStrategy']; + } + if (isset($cell['cellLineStackingShift'])) { + $tablefooter[$i][$js]['cellLineStackingShift'] = $cell['cellLineStackingShift']; + } + } + } + } + } + + if ($level == 1) { + $this->writer->write('___TABLE___BACKGROUNDS' . $this->uniqstr); + } + $tableheaderadj = 0; + $tablefooteradj = 0; + + $tablestartpageno = $this->page; + + // Draw Table Contents and Borders + for ($i = 0; $i < $numrows; $i++) { // Rows + if ($split && $startrow > 0) { + $thnr = (isset($table['is_thead']) ? count($table['is_thead']) : 0); + if ($i >= $thnr && $i < $startrow) { + continue; + } + if ($i == $startrow) { + $returny = $rety - $tableheaderrowheight; + } + } + + // Get Maximum row/cell height in row - including rowspan>1 + 1 overlapping + $maxrowheight = $this->_tableGetMaxRowHeight($table, $i); + + $skippage = false; + $newpagestarted = false; + for ($j = $startcol; $j < $numcols; $j++) { // Columns + if ($split) { + if ($table['colPg'][$j] > $splitpg) { + break; + } + $lastCol = $j; + } + if (isset($cells[$i][$j]) && $cells[$i][$j]) { + $cell = &$cells[$i][$j]; + if ($split) { + $lastCol = $j + (isset($cell['colspan']) ? ($cell['colspan'] - 1) : 0); + list($x, $w) = $this->_splitTableGetWidth($table, $i, $j); + } else { + list($x, $w) = $this->_tableGetWidth($table, $i, $j); + } + + list($y, $h) = $this->_tableGetHeight($table, $i, $j); + $x += $x0; + $y += $y0; + $y -= $returny; + + if ($table['borders_separate']) { + if (!empty($tablefooter) || $i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i + 1) == $numrows)) { + $extra = $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + // $extra = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V']/2; + } else { + $extra = $table['border_spacing_V'] / 2; + } + } else { + $extra = $table['max_cell_border_width']['B'] / 2; + } + + if ($j == $startcol && ((($y + $maxrowheight + $extra ) > ($pagetrigger + 0.001)) || (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && ($y + $maxrowheight + $tablefooterrowheight + $extra) > $pagetrigger) && ($this->tableLevel == 1 && $i < ($numrows - $table['headernrows']))) && ($y0 > 0 || $x0 > 0) && !$this->InFooter && $this->autoPageBreak) { + if (!$skippage) { + $finalSpread = true; + $firstSpread = true; + if ($split) { + for ($t = $startcol; $t < $numcols; $t++) { + // Are there more columns to print on a next page? + if ($table['colPg'][$t] > $splitpg) { + $finalSpread = false; + break; + } + } + if ($startcol > 0) { + $firstSpread = false; + } + } + + if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0) { + $this->y = $y; + $ya = $this->y; + $this->TableHeaderFooter($tablefooter, $tablestartpage, $tablestartcolumn, 'F', $level, $firstSpread, $finalSpread); + if ($this->table_rotate) { + $this->tbrot_h += $this->y - $ya; + } + $tablefooteradj = $this->y - $ya; + } + $y -= $y0; + $returny += $y; + + $oldcolumn = $this->CurrCol; + if ($this->AcceptPageBreak()) { + $newpagestarted = true; + $this->y = $y + $y0; + + // Move down to account for border-spacing or + // extra half border width in case page breaks in middle + if ($i > 0 && !$this->table_rotate && $level == 1 && !$this->ColActive) { + if ($table['borders_separate']) { + $adv = $table['border_spacing_V'] / 2; + // If table footer + if (($this->keepColumns || !$this->ColActive) && !empty($tablefooter) && $i > 0) { + $adv += ($table['padding']['B'] + $table['border_details']['B']['w']); + } + } else { + $maxbwtop = 0; + $maxbwbottom = 0; + if (!$this->simpleTables) { + if (!empty($tablefooter)) { + $maxbwbottom = $table['max_cell_border_width']['B']; + } else { + $brow = $i - 1; + for ($ctj = 0; $ctj < $numcols; $ctj++) { + if (isset($cells[$brow][$ctj]) && $cells[$brow][$ctj]) { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$brow][$ctj]['borderbin']); + } else { + $bb = $cells[$brow][$ctj]['border_details']['B']['w']; + } + $maxbwbottom = max($maxbwbottom, $bb); + } + } + } + if (!empty($tableheader)) { + $maxbwtop = $table['max_cell_border_width']['T']; + } else { + $trow = $i - 1; + for ($ctj = 0; $ctj < $numcols; $ctj++) { + if (isset($cells[$trow][$ctj]) && $cells[$trow][$ctj]) { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$trow][$ctj]['borderbin']); + } else { + $bt = $cells[$trow][$ctj]['border_details']['T']['w']; + } + $maxbwtop = max($maxbwtop, $bt); + } + } + } + } elseif ($this->simpleTables) { + $maxbwtop = $table['simple']['border_details']['T']['w']; + $maxbwbottom = $table['simple']['border_details']['B']['w']; + } + $adv = $maxbwbottom / 2; + } + $this->y += $adv; + } + + // Rotated table split over pages - needs this->y for borders/backgrounds + if ($i > 0 && $this->table_rotate && $level == 1) { + // $this->y = $y0 + $this->tbrot_w; + } + + if ($this->tableClipPath) { + $this->writer->write("Q"); + } + + $bx = $x0; + $by = $y0; + + if ($table['borders_separate']) { + $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2); + if ($tablestartpageno != $this->page) { // IF already broken across a previous pagebreak + $by += $table['max_cell_border_width']['T'] / 2; + if (empty($tableheader)) { + $by -= ($table['border_spacing_V'] / 2); + } + } else { + $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2); + } + } elseif ($tablestartpageno != $this->page && !empty($tableheader)) { + $by += $maxbwtop / 2; + } + + $by -= $tableheaderadj; + $bh = $this->y - $by + $tablefooteradj; + if (!$table['borders_separate']) { + $bh -= $adv; + } + if ($split) { + $bw = 0; + for ($t = $startcol; $t < $numcols; $t++) { + if ($table['colPg'][$t] == $splitpg) { + $bw += $table['wc'][$t]; + } + if ($table['colPg'][$t] > $splitpg) { + break; + } + } + if ($table['borders_separate']) { + if ($firstSpread) { + $bw += $table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H']; + } else { + $bx += ($table['padding']['L'] + $table['border_details']['L']['w']); + $bw += $table['border_spacing_H']; + } + if ($finalSpread) { + $bw += $table['padding']['R'] + $table['border_details']['R']['w'] / 2 + $table['border_spacing_H']; + } + } + } else { + $bw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + } + + if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tablefooter) && $i > 0 && $table['border_details']['B']['w']) { + $prevDrawColor = $this->DrawColor; + $lw = $this->LineWidth; + $this->SetLineWidth($this->splitTableBorderWidth); + $this->SetDColor($table['border_details']['B']['c']); + $this->SetLineJoin(0); + $this->SetLineCap(0); + $blx = $bx; + $blw = $bw; + if (!$table['borders_separate']) { + $blx -= ($table['max_cell_border_width']['L'] / 2); + $blw += ($table['max_cell_border_width']['L'] / 2 + $table['max_cell_border_width']['R'] / 2); + } + $this->Line($blx, $this->y + ($this->splitTableBorderWidth / 2), $blx + $blw, $this->y + ($this->splitTableBorderWidth / 2)); + $this->DrawColor = $prevDrawColor; + $this->writer->write($this->DrawColor); + $this->SetLineWidth($lw); + $this->SetLineJoin(2); + $this->SetLineCap(2); + } + + if (!$this->ColActive && ($i > 0 || $j > 0)) { + if (isset($table['bgcolor'][-1])) { + $color = $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings); + if ($color) { + if (!$table['borders_separate']) { + $bh -= $table['max_cell_border_width']['B'] / 2; + } + $this->tableBackgrounds[$level * 9][] = ['gradient' => false, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'col' => $color]; + } + } + + /* -- BACKGROUNDS -- */ + if (isset($table['gradient'])) { + $g = $this->gradient->parseBackgroundGradient($table['gradient']); + if ($g) { + $this->tableBackgrounds[$level * 9 + 1][] = ['gradient' => true, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + + if (isset($table['background-image'])) { + if ($table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'])) { + $g = $this->gradient->parseMozGradient($table['background-image']['gradient']); + if ($g) { + $this->tableBackgrounds[$level * 9 + 1][] = ['gradient' => true, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } else { + $image_id = $table['background-image']['image_id']; + $orig_w = $table['background-image']['orig_w']; + $orig_h = $table['background-image']['orig_h']; + $x_pos = $table['background-image']['x_pos']; + $y_pos = $table['background-image']['y_pos']; + $x_repeat = $table['background-image']['x_repeat']; + $y_repeat = $table['background-image']['y_repeat']; + $resize = $table['background-image']['resize']; + $opacity = $table['background-image']['opacity']; + $itype = $table['background-image']['itype']; + $this->tableBackgrounds[$level * 9 + 2][] = ['x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => '', 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } + } + /* -- END BACKGROUNDS -- */ + } + + // $this->AcceptPageBreak() has moved tablebuffer to $this->pages content + if ($this->tableBackgrounds) { + $s = $this->PrintTableBackgrounds(); + if ($this->bufferoutput) { + $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->headerbuffer); + $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->headerbuffer); + } else { + $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]); + $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->pages[$this->page]); + } + $this->tableBackgrounds = []; + } + + if ($split) { + if ($i == 0 && $j == 0) { + $y0 = -1; + } elseif ($finalSpread) { + $splitpg = 0; + $startcol = 0; + $startrow = $i; + } else { + $splitpg++; + $startcol = $t; + $returny -= $y; + } + return [false, $startrow, $startcol, $splitpg, $returny, $y0]; + } + + $this->AddPage($this->CurOrientation); + + $this->writer->write('___TABLE___BACKGROUNDS' . $this->uniqstr); + + + if ($this->tableClipPath) { + $this->writer->write($this->tableClipPath); + } + + // Added to correct for OddEven Margins + $x = $x + $this->MarginCorrection; + $x0 = $x0 + $this->MarginCorrection; + + if ($this->splitTableBorderWidth && ($this->keepColumns || !$this->ColActive) && empty($tableheader) && $i > 0 && $table['border_details']['T']['w']) { + $prevDrawColor = $this->DrawColor; + $lw = $this->LineWidth; + $this->SetLineWidth($this->splitTableBorderWidth); + $this->SetDColor($table['border_details']['T']['c']); + $this->SetLineJoin(0); + $this->SetLineCap(0); + $blx += $this->MarginCorrection; + $this->Line($blx, $this->y - ($this->splitTableBorderWidth / 2), $blx + $blw, $this->y - ($this->splitTableBorderWidth / 2)); + $this->DrawColor = $prevDrawColor; + $this->writer->write($this->DrawColor); + $this->SetLineWidth($lw); + $this->SetLineJoin(2); + $this->SetLineCap(2); + } + + // Move down to account for half of top border-spacing or + // extra half border width in case page was broken in middle + if ($i > 0 && !$this->table_rotate && $level == 1 && $table['headernrows'] == 0) { + if ($table['borders_separate']) { + $adv = $table['border_spacing_V'] / 2; + } else { + $maxbwtop = 0; + for ($ctj = 0; $ctj < $numcols; $ctj++) { + if (isset($cells[$i][$ctj]) && $cells[$i][$ctj]) { + if (!$this->simpleTables) { + if ($this->packTableData) { + list($bt, $br, $bb, $bl) = $this->_getBorderWidths($cells[$i][$ctj]['borderbin']); + } else { + $bt = $cells[$i][$ctj]['border_details']['T']['w']; + } + $maxbwtop = max($maxbwtop, $bt); + } elseif ($this->simpleTables) { + $maxbwtop = max($maxbwtop, $table['simple']['border_details']['T']['w']); + } + } + } + $adv = $maxbwtop / 2; + } + $this->y += $adv; + } + + + if ($this->table_rotate) { + $this->tbrot_x0 = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['padding_left'] + $this->blk[$this->blklvl]['border_left']['w']; + if ($table['borders_separate']) { + $this->tbrot_h = $table['margin']['T'] + $table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2; + } else { + $this->tbrot_h = $table['margin']['T'] + $table['max_cell_border_width']['T']; + } + $this->tbrot_y0 = $this->y; + $pagetrigger = $y0 - $tableheaderadj + ($this->blk[$this->blklvl]['inner_width']); + } else { + $pagetrigger = $this->PageBreakTrigger; + } + + if ($this->kwt_saved && $level == 1) { + $this->kwt_moved = true; + } + + + if (!empty($tableheader)) { + $ya = $this->y; + $this->TableHeaderFooter($tableheader, $tablestartpage, $tablestartcolumn, 'H', $level); + if ($this->table_rotate) { + $this->tbrot_h = $this->y - $ya; + } + $tableheaderadj = $this->y - $ya; + } elseif ($i == 0 && !$this->table_rotate && $level == 1 && !$this->ColActive) { + // Advance down page + if ($table['borders_separate']) { + $adv = $table['border_spacing_V'] / 2 + $table['border_details']['T']['w'] + $table['padding']['T']; + } else { + $adv = $table['max_cell_border_width']['T'] / 2; + } + if ($adv) { + if ($this->table_rotate) { + $this->y += ($adv); + } else { + $this->DivLn($adv, $this->blklvl, true); + } + } + } + + $outerfilled = 0; + $y = $y0 = $this->y; + } + + /* -- COLUMNS -- */ + // COLS + // COLUMN CHANGE + if ($this->CurrCol != $oldcolumn) { + // Added to correct for Columns + $x += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); + $x0 += $this->ChangeColumn * ($this->ColWidth + $this->ColGap); + if ($this->CurrCol == 0) { // just added a page - possibly with tableheader + $y0 = $this->y; // this->y0 is global used by Columns - $y0 is internal to tablewrite + } else { + $y0 = $this->y0; // this->y0 is global used by Columns - $y0 is internal to tablewrite + } + $y = $y0; + $outerfilled = 0; + if ($this->CurrCol != 0 && ($this->keepColumns && $this->ColActive) && !empty($tableheader) && $i > 0) { + $this->x = $x; + $this->y = $y; + $this->TableHeaderFooter($tableheader, $tablestartpage, $tablestartcolumn, 'H', $level); + $y0 = $y = $this->y; + } + } + /* -- END COLUMNS -- */ + } + $skippage = true; + } + + $this->x = $x; + $this->y = $y; + + if ($this->kwt_saved && $level == 1) { + $this->printkwtbuffer(); + $x0 = $x = $this->x; + $y0 = $y = $this->y; + $this->kwt_moved = false; + $this->kwt_saved = false; + } + + + // Set the Page & Column where table actually starts + if ($i == 0 && $j == 0 && $level == 1) { + if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN + $tablestartpage = 'EVEN'; + } elseif (($this->mirrorMargins) && (($this->page) % 2 == 1)) { // ODD + $tablestartpage = 'ODD'; + } else { + $tablestartpage = ''; + } + $tablestartpageno = $this->page; + if ($this->ColActive) { + $tablestartcolumn = $this->CurrCol; + } // *COLUMNS* + } + + // ALIGN + $align = $cell['a']; + + /* -- COLUMNS -- */ + // If outside columns, this is done in PaintDivBB + if ($this->ColActive) { + // OUTER FILL BGCOLOR of DIVS + if ($this->blklvl > 0 && ($j == 0) && !$this->table_rotate && $level == 1) { + $firstblockfill = $this->GetFirstBlockFill(); + if ($firstblockfill && $this->blklvl >= $firstblockfill) { + $divh = $maxrowheight; + // Last row + if ((!isset($cell['rowspan']) && $i == $numrows - 1) || (isset($cell['rowspan']) && (($i == $numrows - 1 && $cell['rowspan'] < 2) || ($cell['rowspan'] > 1 && ($i + $cell['rowspan'] - 1) == $numrows - 1)))) { + if ($table['borders_separate']) { + $adv = $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + } else { + $adv = $table['margin']['B'] + $table['max_cell_border_width']['B'] / 2; + } + $divh += $adv; // last row: fill bottom half of bottom border (y advanced at end) + } + + if (($this->y + $divh) > $outerfilled) { // if not already painted by previous rowspan + $bak_x = $this->x; + $bak_y = $this->y; + if ($outerfilled > $this->y) { + $divh = ($this->y + $divh) - $outerfilled; + $this->y = $outerfilled; + } + + $this->DivLn($divh, -3, false); + $outerfilled = $this->y + $divh; + // Reset current block fill + $bcor = $this->blk[$this->blklvl]['bgcolorarray']; + if ($bcor) { + $this->SetFColor($bcor); + } + $this->x = $bak_x; + $this->y = $bak_y; + } + } + } + } + + // TABLE BACKGROUND FILL BGCOLOR - for cellSpacing + if ($this->ColActive) { + if ($table['borders_separate']) { + $fill = isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0; + if ($fill) { + $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings); + if ($color) { + $xadj = ($table['border_spacing_H'] / 2); + $yadj = ($table['border_spacing_V'] / 2); + $wadj = $table['border_spacing_H']; + $hadj = $table['border_spacing_V']; + if ($i == 0) { // Top + $yadj += $table['padding']['T'] + $table['border_details']['T']['w']; + $hadj += $table['padding']['T'] + $table['border_details']['T']['w']; + } + if ($j == 0) { // Left + $xadj += $table['padding']['L'] + $table['border_details']['L']['w']; + $wadj += $table['padding']['L'] + $table['border_details']['L']['w']; + } + if ($i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows) || (!isset($cell['rowspan']) && ($i + 1) == $numrows)) { // Bottom + $hadj += $table['padding']['B'] + $table['border_details']['B']['w']; + } + if ($j == ($numcols - 1) || (isset($cell['colspan']) && ($j + $cell['colspan']) == $numcols) || (!isset($cell['colspan']) && ($j + 1) == $numcols)) { // Right + $wadj += $table['padding']['R'] + $table['border_details']['R']['w']; + } + $this->SetFColor($color); + $this->Rect($x - $xadj, $y - $yadj, $w + $wadj, $h + $hadj, 'F'); + } + } + } + } + /* -- END COLUMNS -- */ + + if ($table['empty_cells'] != 'hide' || !empty($cell['textbuffer']) || (isset($cell['nestedcontent']) && $cell['nestedcontent']) || !$table['borders_separate']) { + $paintcell = true; + } else { + $paintcell = false; + } + + // Set Borders + $bord = 0; + $bord_det = []; + + if (!$this->simpleTables) { + if ($this->packTableData) { + $c = $this->_unpackCellBorder($cell['borderbin']); + $bord = $c['border']; + $bord_det = $c['border_details']; + } else { + $bord = $cell['border']; + $bord_det = $cell['border_details']; + } + } elseif ($this->simpleTables) { + $bord = $table['simple']['border']; + $bord_det = $table['simple']['border_details']; + } + + // TABLE ROW OR CELL FILL BGCOLOR + $fill = 0; + if (isset($cell['bgcolor']) && $cell['bgcolor'] && $cell['bgcolor'] != 'transparent') { + $fill = $cell['bgcolor']; + $leveladj = 6; + } elseif (isset($table['bgcolor'][$i]) && $table['bgcolor'][$i] && $table['bgcolor'][$i] != 'transparent') { // Row color + $fill = $table['bgcolor'][$i]; + $leveladj = 3; + } + if ($fill && $paintcell) { + $color = $this->colorConverter->convert($fill, $this->PDFAXwarnings); + if ($color) { + if ($table['borders_separate']) { + if ($this->ColActive) { + $this->SetFColor($color); + $this->Rect($x + ($table['border_spacing_H'] / 2), $y + ($table['border_spacing_V'] / 2), $w - $table['border_spacing_H'], $h - $table['border_spacing_V'], 'F'); + } else { + $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => ($x + ($table['border_spacing_H'] / 2)), 'y' => ($y + ($table['border_spacing_V'] / 2)), 'w' => ($w - $table['border_spacing_H']), 'h' => ($h - $table['border_spacing_V']), 'col' => $color]; + } + } else { + if ($this->ColActive) { + $this->SetFColor($color); + $this->Rect($x, $y, $w, $h, 'F'); + } else { + $this->tableBackgrounds[$level * 9 + $leveladj][] = ['gradient' => false, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'col' => $color]; + } + } + } + } + + /* -- BACKGROUNDS -- */ + if (isset($cell['gradient']) && $cell['gradient'] && $paintcell) { + $g = $this->gradient->parseBackgroundGradient($cell['gradient']); + if ($g) { + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']); + } else { + $this->tableBackgrounds[$level * 9 + 7][] = ['gradient' => true, 'x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } + + if (isset($cell['background-image']) && $paintcell) { + if (isset($cell['background-image']['gradient']) && $cell['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $cell['background-image']['gradient'])) { + $g = $this->gradient->parseMozGradient($cell['background-image']['gradient']); + if ($g) { + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + $this->gradient->Gradient($px, $py, $pw, $ph, $g['type'], $g['stops'], $g['colorspace'], $g['coords'], $g['extend']); + } else { + $this->tableBackgrounds[$level * 9 + 7][] = ['gradient' => true, 'x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } elseif (isset($cell['background-image']['image_id']) && $cell['background-image']['image_id']) { // Background pattern + $n = count($this->patterns) + 1; + if ($table['borders_separate']) { + $px = $x + ($table['border_spacing_H'] / 2); + $py = $y + ($table['border_spacing_V'] / 2); + $pw = $w - $table['border_spacing_H']; + $ph = $h - $table['border_spacing_V']; + } else { + $px = $x; + $py = $y; + $pw = $w; + $ph = $h; + } + if ($this->ColActive) { + list($orig_w, $orig_h, $x_repeat, $y_repeat) = $this->_resizeBackgroundImage($cell['background-image']['orig_w'], $cell['background-image']['orig_h'], $pw, $ph, $cell['background-image']['resize'], $cell['background-image']['x_repeat'], $cell['background-image']['y_repeat']); + $this->patterns[$n] = ['x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'pgh' => $this->h, 'image_id' => $cell['background-image']['image_id'], 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $cell['background-image']['x_pos'], 'y_pos' => $cell['background-image']['y_pos'], 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat]; + if ($cell['background-image']['opacity'] > 0 && $cell['background-image']['opacity'] < 1) { + $opac = $this->SetAlpha($cell['background-image']['opacity'], 'Normal', true); + } else { + $opac = ''; + } + $this->writer->write(sprintf('q /Pattern cs /P%d scn %s %.3F %.3F %.3F %.3F re f Q', $n, $opac, $px * Mpdf::SCALE, ($this->h - $py) * Mpdf::SCALE, $pw * Mpdf::SCALE, -$ph * Mpdf::SCALE)); + } else { + $image_id = $cell['background-image']['image_id']; + $orig_w = $cell['background-image']['orig_w']; + $orig_h = $cell['background-image']['orig_h']; + $x_pos = $cell['background-image']['x_pos']; + $y_pos = $cell['background-image']['y_pos']; + $x_repeat = $cell['background-image']['x_repeat']; + $y_repeat = $cell['background-image']['y_repeat']; + $resize = $cell['background-image']['resize']; + $opacity = $cell['background-image']['opacity']; + $itype = $cell['background-image']['itype']; + $this->tableBackgrounds[$level * 9 + 8][] = ['x' => $px, 'y' => $py, 'w' => $pw, 'h' => $ph, 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => '', 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } + } + } + /* -- END BACKGROUNDS -- */ + + if (isset($cell['colspan']) && $cell['colspan'] > 1) { + $ccolsp = $cell['colspan']; + } else { + $ccolsp = 1; + } + if (isset($cell['rowspan']) && $cell['rowspan'] > 1) { + $crowsp = $cell['rowspan']; + } else { + $crowsp = 1; + } + + + // but still need to do this for repeated headers... + if (!$table['borders_separate'] && $this->tabletheadjustfinished && !$this->simpleTables) { + if (isset($table['topntail']) && $table['topntail']) { + $bord_det['T'] = $this->border_details($table['topntail']); + $bord_det['T']['w'] /= $this->shrin_k; + $this->setBorder($bord, Border::TOP); + } + if (isset($table['thead-underline']) && $table['thead-underline']) { + $bord_det['T'] = $this->border_details($table['thead-underline']); + $bord_det['T']['w'] /= $this->shrin_k; + $this->setBorder($bord, Border::TOP); + } + } + + + // Get info of first row ==>> table header + // Use > 1 row if THEAD + if (isset($table['is_thead'][$i]) && $table['is_thead'][$i] && $level == 1) { + if ($j == 0) { + $tableheaderrowheight += $table['hr'][$i]; + } + $tableheader[$i][0]['trbackground-images'] = (isset($table['trbackground-images'][$i]) ? $table['trbackground-images'][$i] : null); + $tableheader[$i][0]['trgradients'] = (isset($table['trgradients'][$i]) ? $table['trgradients'][$i] : null); + $tableheader[$i][0]['trbgcolor'] = (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i] : null); + $tableheader[$i][$j]['x'] = $x; + $tableheader[$i][$j]['y'] = $y; + $tableheader[$i][$j]['h'] = $h; + $tableheader[$i][$j]['w'] = $w; + if (isset($cell['textbuffer'])) { + $tableheader[$i][$j]['textbuffer'] = $cell['textbuffer']; + } else { + $tableheader[$i][$j]['textbuffer'] = ''; + } + $tableheader[$i][$j]['a'] = $cell['a']; + $tableheader[$i][$j]['R'] = $cell['R']; + + $tableheader[$i][$j]['va'] = $cell['va']; + $tableheader[$i][$j]['mih'] = $cell['mih']; + $tableheader[$i][$j]['gradient'] = (isset($cell['gradient']) ? $cell['gradient'] : null); // *BACKGROUNDS* + $tableheader[$i][$j]['background-image'] = (isset($cell['background-image']) ? $cell['background-image'] : null); // *BACKGROUNDS* + $tableheader[$i][$j]['rowspan'] = (isset($cell['rowspan']) ? $cell['rowspan'] : null); + $tableheader[$i][$j]['colspan'] = (isset($cell['colspan']) ? $cell['colspan'] : null); + $tableheader[$i][$j]['bgcolor'] = $cell['bgcolor']; + + if (!$this->simpleTables) { + $tableheader[$i][$j]['border'] = $bord; + $tableheader[$i][$j]['border_details'] = $bord_det; + } elseif ($this->simpleTables) { + $tableheader[$i][$j]['border'] = $table['simple']['border']; + $tableheader[$i][$j]['border_details'] = $table['simple']['border_details']; + } + $tableheader[$i][$j]['padding'] = $cell['padding']; + if (isset($cell['direction'])) { + $tableheader[$i][$j]['direction'] = $cell['direction']; + } + if (isset($cell['cellLineHeight'])) { + $tableheader[$i][$j]['cellLineHeight'] = $cell['cellLineHeight']; + } + if (isset($cell['cellLineStackingStrategy'])) { + $tableheader[$i][$j]['cellLineStackingStrategy'] = $cell['cellLineStackingStrategy']; + } + if (isset($cell['cellLineStackingShift'])) { + $tableheader[$i][$j]['cellLineStackingShift'] = $cell['cellLineStackingShift']; + } + } + + // CELL BORDER + if ($bord) { + if ($table['borders_separate'] && $paintcell) { + $this->_tableRect($x + ($table['border_spacing_H'] / 2) + ($bord_det['L']['w'] / 2), $y + ($table['border_spacing_V'] / 2) + ($bord_det['T']['w'] / 2), $w - $table['border_spacing_H'] - ($bord_det['L']['w'] / 2) - ($bord_det['R']['w'] / 2), $h - $table['border_spacing_V'] - ($bord_det['T']['w'] / 2) - ($bord_det['B']['w'] / 2), $bord, $bord_det, false, $table['borders_separate']); + } elseif (!$table['borders_separate']) { + $this->_tableRect($x, $y, $w, $h, $bord, $bord_det, true, $table['borders_separate']); // true causes buffer + } + } + + // VERTICAL ALIGN + if ($cell['R'] && intval($cell['R']) > 0 && intval($cell['R']) < 90 && isset($cell['va']) && $cell['va'] != 'B') { + $cell['va'] = 'B'; + } + if (!isset($cell['va']) || $cell['va'] == 'M') { + $this->y += ($h - $cell['mih']) / 2; + } elseif (isset($cell['va']) && $cell['va'] == 'B') { + $this->y += $h - $cell['mih']; + } + + // NESTED CONTENT + // TEXT (and nested tables) + + $this->divwidth = $w; + if (!empty($cell['textbuffer'])) { + $this->cellTextAlign = $align; + $this->cellLineHeight = $cell['cellLineHeight']; + $this->cellLineStackingStrategy = $cell['cellLineStackingStrategy']; + $this->cellLineStackingShift = $cell['cellLineStackingShift']; + if ($level == 1) { + if (isset($table['is_tfoot'][$i]) && $table['is_tfoot'][$i]) { + if (preg_match('/{colsum([0-9]*)[_]*}/', $cell['textbuffer'][0][0], $m)) { + $rep = sprintf("%01." . intval($m[1]) . "f", $this->colsums[$j]); + $cell['textbuffer'][0][0] = preg_replace('/{colsum[0-9_]*}/', $rep, $cell['textbuffer'][0][0]); + } + } elseif (!isset($table['is_thead'][$i])) { + if (isset($this->colsums[$j])) { + $this->colsums[$j] += $this->toFloat($cell['textbuffer'][0][0]); + } else { + $this->colsums[$j] = $this->toFloat($cell['textbuffer'][0][0]); + } + } + } + $opy = $this->y; + // mPDF ITERATION + if ($this->iterationCounter) { + foreach ($cell['textbuffer'] as $k => $t) { + if (preg_match('/{iteration ([a-zA-Z0-9_]+)}/', $t[0], $m)) { + $vname = '__' . $m[1] . '_'; + if (!isset($this->$vname)) { + $this->$vname = 1; + } else { + $this->$vname++; + } + $cell['textbuffer'][$k][0] = preg_replace('/{iteration ' . $m[1] . '}/', $this->$vname, $cell['textbuffer'][$k][0]); + } + } + } + + + if ($cell['R']) { + $cellPtSize = $cell['textbuffer'][0][11] / $this->shrin_k; + if (!$cellPtSize) { + $cellPtSize = $this->default_font_size; + } + $cellFontHeight = ($cellPtSize / Mpdf::SCALE); + $opx = $this->x; + $angle = intval($cell['R']); + // Only allow 45 to 89 degrees (when bottom-aligned) or exactly 90 or -90 + if ($angle > 90) { + $angle = 90; + } elseif ($angle > 0 && $angle < 45) { + $angle = 45; + } elseif ($angle < 0) { + $angle = -90; + } + $offset = ((sin(deg2rad($angle))) * 0.37 * $cellFontHeight); + if (isset($cell['a']) && $cell['a'] == 'R') { + $this->x += ($w) + ($offset) - ($cellFontHeight / 3) - ($cell['padding']['R'] + ($table['border_spacing_H'] / 2)); + } elseif (!isset($cell['a']) || $cell['a'] == 'C') { + $this->x += ($w / 2) + ($offset); + } else { + $this->x += ($offset) + ($cellFontHeight / 3) + ($cell['padding']['L'] + ($table['border_spacing_H'] / 2)); + } + $str = ''; + foreach ($cell['textbuffer'] as $t) { + $str .= $t[0] . ' '; + } + $str = rtrim($str); + if (!isset($cell['va']) || $cell['va'] == 'M') { + $this->y -= ($h - $cell['mih']) / 2; // Undo what was added earlier VERTICAL ALIGN + if ($angle > 0) { + $this->y += (($h - $cell['mih']) / 2) + $cell['padding']['T'] + ($cell['mih'] - ($cell['padding']['T'] + $cell['padding']['B'])); + } elseif ($angle < 0) { + $this->y += (($h - $cell['mih']) / 2) + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2)); + } + } elseif (isset($cell['va']) && $cell['va'] == 'B') { + $this->y -= $h - $cell['mih']; // Undo what was added earlier VERTICAL ALIGN + if ($angle > 0) { + $this->y += $h - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2)); + } elseif ($angle < 0) { + $this->y += $h - $cell['mih'] + ($cell['padding']['T'] + ($table['border_spacing_V'] / 2)); + } + } elseif (isset($cell['va']) && $cell['va'] == 'T') { + if ($angle > 0) { + $this->y += $cell['mih'] - ($cell['padding']['B'] + ($table['border_spacing_V'] / 2)); + } elseif ($angle < 0) { + $this->y += ($cell['padding']['T'] + ($table['border_spacing_V'] / 2)); + } + } + $this->Rotate($angle, $this->x, $this->y); + $s_fs = $this->FontSizePt; + $s_f = $this->FontFamily; + $s_st = $this->FontStyle; + if (!empty($cell['textbuffer'][0][3])) { // Font Color + $cor = $cell['textbuffer'][0][3]; + $this->SetTColor($cor); + } + $this->SetFont($cell['textbuffer'][0][4], $cell['textbuffer'][0][2], $cellPtSize, true, true); + + $this->magic_reverse_dir($str, $this->directionality, $cell['textbuffer'][0][18]); + $this->Text($this->x, $this->y, $str, $cell['textbuffer'][0][18], $cell['textbuffer'][0][8]); // textvar + $this->Rotate(0); + $this->SetFont($s_f, $s_st, $s_fs, true, true); + $this->SetTColor(0); + $this->x = $opx; + } else { + if (!$this->simpleTables) { + if ($bord_det) { + $btlw = $bord_det['L']['w']; + $btrw = $bord_det['R']['w']; + $bttw = $bord_det['T']['w']; + } else { + $btlw = 0; + $btrw = 0; + $bttw = 0; + } + if ($table['borders_separate']) { + $xadj = $btlw + $cell['padding']['L'] + ($table['border_spacing_H'] / 2); + $wadj = $btlw + $btrw + $cell['padding']['L'] + $cell['padding']['R'] + $table['border_spacing_H']; + $yadj = $bttw + $cell['padding']['T'] + ($table['border_spacing_H'] / 2); + } else { + $xadj = $btlw / 2 + $cell['padding']['L']; + $wadj = ($btlw + $btrw) / 2 + $cell['padding']['L'] + $cell['padding']['R']; + $yadj = $bttw / 2 + $cell['padding']['T']; + } + } elseif ($this->simpleTables) { + if ($table['borders_separate']) { // NB twice border width + $xadj = $table['simple']['border_details']['L']['w'] + $cell['padding']['L'] + ($table['border_spacing_H'] / 2); + $wadj = $table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w'] + $cell['padding']['L'] + $cell['padding']['R'] + $table['border_spacing_H']; + $yadj = $table['simple']['border_details']['T']['w'] + $cell['padding']['T'] + ($table['border_spacing_H'] / 2); + } else { + $xadj = $table['simple']['border_details']['L']['w'] / 2 + $cell['padding']['L']; + $wadj = ($table['simple']['border_details']['L']['w'] + $table['simple']['border_details']['R']['w']) / 2 + $cell['padding']['L'] + $cell['padding']['R']; + $yadj = $table['simple']['border_details']['T']['w'] / 2 + $cell['padding']['T']; + } + } + $this->decimal_offset = 0; + if (substr($cell['a'], 0, 1) == 'D') { + if (isset($cell['colspan']) && $cell['colspan'] > 1) { + $this->cellTextAlign = $c['a'] = substr($cell['a'], 2, 1); + } else { + $smax = $table['decimal_align'][$j]['maxs0']; + $d_content = $table['decimal_align'][$j]['maxs0'] + $table['decimal_align'][$j]['maxs1']; + $this->decimal_offset = $smax; + $extra = ($w - $d_content - $wadj); + if ($extra > 0) { + if (substr($cell['a'], 2, 1) == 'R') { + $this->decimal_offset += $extra; + } elseif (substr($cell['a'], 2, 1) == 'C') { + $this->decimal_offset += ($extra) / 2; + } + } + } + } + $this->divwidth = $w - $wadj; + if ($this->divwidth == 0) { + $this->divwidth = 0.0001; + } + $this->x += $xadj; + $this->y += $yadj; + $this->printbuffer($cell['textbuffer'], '', true, false, $cell['direction']); + } + $this->y = $opy; + } + + /* -- BACKGROUNDS -- */ + if (!$this->ColActive) { + if (isset($table['trgradients'][$i]) && ($j == 0 || $table['borders_separate'])) { + $g = $this->gradient->parseBackgroundGradient($table['trgradients'][$i]); + if ($g) { + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => $s]; + } else { + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } + if (isset($table['trbackground-images'][$i]) && ($j == 0 || $table['borders_separate'])) { + if (isset($table['trbackground-images'][$i]['gradient']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['trbackground-images'][$i]['gradient'])) { + $g = $this->gradient->parseMozGradient($table['trbackground-images'][$i]['gradient']); + if ($g) { + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => $s]; + } else { + $this->tableBackgrounds[$level * 9 + 4][] = ['gradient' => true, 'x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + } else { + $image_id = $table['trbackground-images'][$i]['image_id']; + $orig_w = $table['trbackground-images'][$i]['orig_w']; + $orig_h = $table['trbackground-images'][$i]['orig_h']; + $x_pos = $table['trbackground-images'][$i]['x_pos']; + $y_pos = $table['trbackground-images'][$i]['y_pos']; + $x_repeat = $table['trbackground-images'][$i]['x_repeat']; + $y_repeat = $table['trbackground-images'][$i]['y_repeat']; + $resize = $table['trbackground-images'][$i]['resize']; + $opacity = $table['trbackground-images'][$i]['opacity']; + $itype = $table['trbackground-images'][$i]['itype']; + $clippath = ''; + $gx = $x0; + $gy = $y; + $gh = $h; + $gw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + if ($table['borders_separate']) { + $gw -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['padding']['R'] + $table['border_details']['R']['w'] + $table['border_spacing_H']); + $clx = $x + ($table['border_spacing_H'] / 2); + $cly = $y + ($table['border_spacing_V'] / 2); + $clw = $w - $table['border_spacing_H']; + $clh = $h - $table['border_spacing_V']; + // Set clipping path + $s = $this->_setClippingPath($clx, $cly, $clw, $clh); // mPDF 6 + $this->tableBackgrounds[$level * 9 + 5][] = ['x' => $gx + ($table['border_spacing_H'] / 2), 'y' => $gy + ($table['border_spacing_V'] / 2), 'w' => $gw - $table['border_spacing_V'], 'h' => $gh - $table['border_spacing_H'], 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => $s, 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } else { + $this->tableBackgrounds[$level * 9 + 5][] = ['x' => $gx, 'y' => $gy, 'w' => $gw, 'h' => $gh, 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => '', 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } + } + } + } + + /* -- END BACKGROUNDS -- */ + + // TABLE BORDER - if separate + if (($table['borders_separate'] || ($this->simpleTables && !$table['simple']['border'])) && $table['border']) { + $halfspaceL = $table['padding']['L'] + ($table['border_spacing_H'] / 2); + $halfspaceR = $table['padding']['R'] + ($table['border_spacing_H'] / 2); + $halfspaceT = $table['padding']['T'] + ($table['border_spacing_V'] / 2); + $halfspaceB = $table['padding']['B'] + ($table['border_spacing_V'] / 2); + $tbx = $x; + $tby = $y; + $tbw = $w; + $tbh = $h; + $tab_bord = 0; + + $corner = ''; + if ($i == 0) { // Top + $tby -= $halfspaceT + ($table['border_details']['T']['w'] / 2); + $tbh += $halfspaceT + ($table['border_details']['T']['w'] / 2); + $this->setBorder($tab_bord, Border::TOP); + $corner .= 'T'; + } + if ($i == ($numrows - 1) || (isset($cell['rowspan']) && ($i + $cell['rowspan']) == $numrows)) { // Bottom + $tbh += $halfspaceB + ($table['border_details']['B']['w'] / 2); + $this->setBorder($tab_bord, Border::BOTTOM); + $corner .= 'B'; + } + if ($j == 0) { // Left + $tbx -= $halfspaceL + ($table['border_details']['L']['w'] / 2); + $tbw += $halfspaceL + ($table['border_details']['L']['w'] / 2); + $this->setBorder($tab_bord, Border::LEFT); + $corner .= 'L'; + } + if ($j == ($numcols - 1) || (isset($cell['colspan']) && ($j + $cell['colspan']) == $numcols)) { // Right + $tbw += $halfspaceR + ($table['border_details']['R']['w'] / 2); + $this->setBorder($tab_bord, Border::RIGHT); + $corner .= 'R'; + } + $this->_tableRect($tbx, $tby, $tbw, $tbh, $tab_bord, $table['border_details'], false, $table['borders_separate'], 'table', $corner, $table['border_spacing_V'], $table['border_spacing_H']); + } + + unset($cell); + // Reset values + $this->Reset(); + }//end of (if isset(cells)...) + }// end of columns + + $newpagestarted = false; + $this->tabletheadjustfinished = false; + + /* -- COLUMNS -- */ + if ($this->ColActive) { + if (!$this->table_keep_together && $i < $numrows - 1 && $level == 1) { + $this->breakpoints[$this->CurrCol][] = $y + $h; + } // mPDF 6 + if (count($this->cellBorderBuffer)) { + $this->printcellbuffer(); + } + } + /* -- END COLUMNS -- */ + + if ($i == $numrows - 1) { + $this->y = $y + $h; + } // last row jump (update this->y position) + if ($this->table_rotate && $level == 1) { + $this->tbrot_h += $h; + } + } // end of rows + + if (count($this->cellBorderBuffer)) { + $this->printcellbuffer(); + } + + + if ($this->tableClipPath) { + $this->writer->write("Q"); + } + $this->tableClipPath = ''; + + // Advance down page by half width of bottom border + if ($table['borders_separate']) { + $this->y += $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + } else { + $this->y += $table['max_cell_border_width']['B'] / 2; + } + + if ($table['borders_separate'] && $level == 1) { + $this->tbrot_h += $table['margin']['B'] + $table['padding']['B'] + $table['border_details']['B']['w'] + $table['border_spacing_V'] / 2; + } elseif ($level == 1) { + $this->tbrot_h += $table['margin']['B'] + $table['max_cell_border_width']['B'] / 2; + } + + $bx = $x0; + $by = $y0; + if ($table['borders_separate']) { + $bx -= ($table['padding']['L'] + $table['border_details']['L']['w'] + $table['border_spacing_H'] / 2); + if ($tablestartpageno != $this->page) { // IF broken across page + $by += $table['max_cell_border_width']['T'] / 2; + if (empty($tableheader)) { + $by -= ($table['border_spacing_V'] / 2); + } + } elseif ($split && $startrow > 0 && empty($tableheader)) { + $by -= ($table['border_spacing_V'] / 2); + } else { + $by -= ($table['padding']['T'] + $table['border_details']['T']['w'] + $table['border_spacing_V'] / 2); + } + } elseif ($tablestartpageno != $this->page && !empty($tableheader)) { + $by += $maxbwtop / 2; + } + $by -= $tableheaderadj; + $bh = $this->y - $by; + if (!$table['borders_separate']) { + $bh -= $table['max_cell_border_width']['B'] / 2; + } + + if ($split) { + $bw = 0; + $finalSpread = true; + for ($t = $startcol; $t < $numcols; $t++) { + if ($table['colPg'][$t] == $splitpg) { + $bw += $table['wc'][$t]; + } + if ($table['colPg'][$t] > $splitpg) { + $finalSpread = false; + break; + } + } + if ($startcol == 0) { + $firstSpread = true; + } else { + $firstSpread = false; + } + if ($table['borders_separate']) { + $bw += $table['border_spacing_H']; + if ($firstSpread) { + $bw += $table['padding']['L'] + $table['border_details']['L']['w']; + } else { + $bx += ($table['padding']['L'] + $table['border_details']['L']['w']); + } + if ($finalSpread) { + $bw += $table['padding']['R'] + $table['border_details']['R']['w']; + } + } + } else { + $bw = $table['w'] - ($table['max_cell_border_width']['L'] / 2) - ($table['max_cell_border_width']['R'] / 2) - $table['margin']['L'] - $table['margin']['R']; + } + + if (!$this->ColActive) { + if (isset($table['bgcolor'][-1])) { + $color = $this->colorConverter->convert($table['bgcolor'][-1], $this->PDFAXwarnings); + if ($color) { + $this->tableBackgrounds[$level * 9][] = ['gradient' => false, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'col' => $color]; + } + } + + /* -- BACKGROUNDS -- */ + if (isset($table['gradient'])) { + $g = $this->gradient->parseBackgroundGradient($table['gradient']); + if ($g) { + $this->tableBackgrounds[$level * 9 + 1][] = ['gradient' => true, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } + + if (isset($table['background-image'])) { + if (isset($table['background-image']['gradient']) && $table['background-image']['gradient'] && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $table['background-image']['gradient'])) { + $g = $this->gradient->parseMozGradient($table['background-image']['gradient']); + if ($g) { + $this->tableBackgrounds[$level * 9 + 1][] = ['gradient' => true, 'x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'gradtype' => $g['type'], 'stops' => $g['stops'], 'colorspace' => $g['colorspace'], 'coords' => $g['coords'], 'extend' => $g['extend'], 'clippath' => '']; + } + } else { + $image_id = $table['background-image']['image_id']; + $orig_w = $table['background-image']['orig_w']; + $orig_h = $table['background-image']['orig_h']; + $x_pos = $table['background-image']['x_pos']; + $y_pos = $table['background-image']['y_pos']; + $x_repeat = $table['background-image']['x_repeat']; + $y_repeat = $table['background-image']['y_repeat']; + $resize = $table['background-image']['resize']; + $opacity = $table['background-image']['opacity']; + $itype = $table['background-image']['itype']; + $this->tableBackgrounds[$level * 9 + 2][] = ['x' => $bx, 'y' => $by, 'w' => $bw, 'h' => $bh, 'image_id' => $image_id, 'orig_w' => $orig_w, 'orig_h' => $orig_h, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'x_repeat' => $x_repeat, 'y_repeat' => $y_repeat, 'clippath' => '', 'resize' => $resize, 'opacity' => $opacity, 'itype' => $itype]; + } + } + /* -- END BACKGROUNDS -- */ + } + + if ($this->tableBackgrounds && $level == 1) { + $s = $this->PrintTableBackgrounds(); + if ($this->table_rotate && !$this->processingHeader && !$this->processingFooter) { + $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->tablebuffer); + if ($level == 1) { + $this->tablebuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->tablebuffer); + } + } elseif ($this->bufferoutput) { + $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->headerbuffer); + if ($level == 1) { + $this->headerbuffer = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->headerbuffer); + } + } else { + $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->pages[$this->page]); + if ($level == 1) { + $this->pages[$this->page] = preg_replace('/(___TABLE___BACKGROUNDS' . $this->uniqstr . ')/', " ", $this->pages[$this->page]); + } + } + $this->tableBackgrounds = []; + } + + + // TABLE BOTTOM MARGIN + if ($table['margin']['B']) { + if (!$this->table_rotate && $level == 1) { + $this->DivLn($table['margin']['B'], $this->blklvl, true); // collapsible + } else { + $this->y += ($table['margin']['B']); + } + } + + if ($this->ColActive && $level == 1) { + $this->breakpoints[$this->CurrCol][] = $this->y; + } // *COLUMNS* + + if ($split) { + // Are there more columns to print on a next page? + if ($lastCol < $numcols - 1) { + $splitpg++; + $startcol = $lastCol + 1; + return [false, $startrow, $startcol, $splitpg, $returny, $y0]; + } else { + return [true, 0, 0, 0, false, false]; + } + } + } + + // END OF FUNCTION _tableWrite() + /////////////////////////END OF TABLE CODE////////////////////////////////// + /* -- END TABLES -- */ + + function _putextgstates() + { + for ($i = 1; $i <= count($this->extgstates); $i++) { + $this->writer->object(); + $this->extgstates[$i]['n'] = $this->n; + $this->writer->write('<</Type /ExtGState'); + foreach ($this->extgstates[$i]['parms'] as $k => $v) { + $this->writer->write('/' . $k . ' ' . $v); + } + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + } + + function SetProtection($permissions = [], $user_pass = '', $owner_pass = null, $length = 40) + { + $this->encrypted = $this->protection->setProtection($permissions, $user_pass, $owner_pass, $length); + } + + // ========================================= + // FROM class PDF_Bookmark + function Bookmark($txt, $level = 0, $y = 0) + { + $txt = $this->purify_utf8_text($txt); + if ($this->text_input_as_HTML) { + $txt = $this->all_entities_to_utf8($txt); + } + if ($y == -1) { + if (!$this->ColActive) { + $y = $this->y; + } else { + $y = $this->y0; + } // If columns are on - mark top of columns + } + + // else y is used as set, or =0 i.e. top of page + // DIRECTIONALITY RTL + $bmo = ['t' => $txt, 'l' => $level, 'y' => $y, 'p' => $this->page]; + + if ($this->keep_block_together) { + // do nothing + } elseif ($this->table_rotate) { + $this->tbrot_BMoutlines[] = $bmo; + } elseif ($this->kwt) { + $this->kwt_BMoutlines[] = $bmo; + } elseif ($this->ColActive) { + $this->col_BMoutlines[] = $bmo; + } else { + $this->BMoutlines[] = $bmo; + } + } + + /** + * Initiate, and Mark a place for the Table of Contents to be inserted + */ + function TOC( + $tocfont = '', + $tocfontsize = 0, + $tocindent = 0, + $resetpagenum = '', + $pagenumstyle = '', + $suppress = '', + $toc_orientation = '', + $TOCusePaging = true, + $TOCuseLinking = false, + $toc_id = 0, + $tocoutdent = '' + ) { + + $this->tableOfContents->TOC( + $tocfont, + $tocfontsize, + $tocindent, + $resetpagenum, + $pagenumstyle, + $suppress, + $toc_orientation, + $TOCusePaging, + $TOCuseLinking, + $toc_id, + $tocoutdent + ); + } + + function TOCpagebreakByArray($a) + { + if (!is_array($a)) { + $a = []; + } + $tocoutdent = (isset($a['tocoutdent']) ? $a['tocoutdent'] : (isset($a['outdent']) ? $a['outdent'] : '')); + $TOCusePaging = (isset($a['TOCusePaging']) ? $a['TOCusePaging'] : (isset($a['paging']) ? $a['paging'] : true)); + $TOCuseLinking = (isset($a['TOCuseLinking']) ? $a['TOCuseLinking'] : (isset($a['links']) ? $a['links'] : '')); + $toc_orientation = (isset($a['toc_orientation']) ? $a['toc_orientation'] : (isset($a['toc-orientation']) ? $a['toc-orientation'] : '')); + $toc_mgl = (isset($a['toc_mgl']) ? $a['toc_mgl'] : (isset($a['toc-margin-left']) ? $a['toc-margin-left'] : '')); + $toc_mgr = (isset($a['toc_mgr']) ? $a['toc_mgr'] : (isset($a['toc-margin-right']) ? $a['toc-margin-right'] : '')); + $toc_mgt = (isset($a['toc_mgt']) ? $a['toc_mgt'] : (isset($a['toc-margin-top']) ? $a['toc-margin-top'] : '')); + $toc_mgb = (isset($a['toc_mgb']) ? $a['toc_mgb'] : (isset($a['toc-margin-bottom']) ? $a['toc-margin-bottom'] : '')); + $toc_mgh = (isset($a['toc_mgh']) ? $a['toc_mgh'] : (isset($a['toc-margin-header']) ? $a['toc-margin-header'] : '')); + $toc_mgf = (isset($a['toc_mgf']) ? $a['toc_mgf'] : (isset($a['toc-margin-footer']) ? $a['toc-margin-footer'] : '')); + $toc_ohname = (isset($a['toc_ohname']) ? $a['toc_ohname'] : (isset($a['toc-odd-header-name']) ? $a['toc-odd-header-name'] : '')); + $toc_ehname = (isset($a['toc_ehname']) ? $a['toc_ehname'] : (isset($a['toc-even-header-name']) ? $a['toc-even-header-name'] : '')); + $toc_ofname = (isset($a['toc_ofname']) ? $a['toc_ofname'] : (isset($a['toc-odd-footer-name']) ? $a['toc-odd-footer-name'] : '')); + $toc_efname = (isset($a['toc_efname']) ? $a['toc_efname'] : (isset($a['toc-even-footer-name']) ? $a['toc-even-footer-name'] : '')); + $toc_ohvalue = (isset($a['toc_ohvalue']) ? $a['toc_ohvalue'] : (isset($a['toc-odd-header-value']) ? $a['toc-odd-header-value'] : 0)); + $toc_ehvalue = (isset($a['toc_ehvalue']) ? $a['toc_ehvalue'] : (isset($a['toc-even-header-value']) ? $a['toc-even-header-value'] : 0)); + $toc_ofvalue = (isset($a['toc_ofvalue']) ? $a['toc_ofvalue'] : (isset($a['toc-odd-footer-value']) ? $a['toc-odd-footer-value'] : 0)); + $toc_efvalue = (isset($a['toc_efvalue']) ? $a['toc_efvalue'] : (isset($a['toc-even-footer-value']) ? $a['toc-even-footer-value'] : 0)); + $toc_preHTML = (isset($a['toc_preHTML']) ? $a['toc_preHTML'] : (isset($a['toc-preHTML']) ? $a['toc-preHTML'] : '')); + $toc_postHTML = (isset($a['toc_postHTML']) ? $a['toc_postHTML'] : (isset($a['toc-postHTML']) ? $a['toc-postHTML'] : '')); + $toc_bookmarkText = (isset($a['toc_bookmarkText']) ? $a['toc_bookmarkText'] : (isset($a['toc-bookmarkText']) ? $a['toc-bookmarkText'] : '')); + $resetpagenum = (isset($a['resetpagenum']) ? $a['resetpagenum'] : ''); + $pagenumstyle = (isset($a['pagenumstyle']) ? $a['pagenumstyle'] : ''); + $suppress = (isset($a['suppress']) ? $a['suppress'] : ''); + $orientation = (isset($a['orientation']) ? $a['orientation'] : ''); + $mgl = (isset($a['mgl']) ? $a['mgl'] : (isset($a['margin-left']) ? $a['margin-left'] : '')); + $mgr = (isset($a['mgr']) ? $a['mgr'] : (isset($a['margin-right']) ? $a['margin-right'] : '')); + $mgt = (isset($a['mgt']) ? $a['mgt'] : (isset($a['margin-top']) ? $a['margin-top'] : '')); + $mgb = (isset($a['mgb']) ? $a['mgb'] : (isset($a['margin-bottom']) ? $a['margin-bottom'] : '')); + $mgh = (isset($a['mgh']) ? $a['mgh'] : (isset($a['margin-header']) ? $a['margin-header'] : '')); + $mgf = (isset($a['mgf']) ? $a['mgf'] : (isset($a['margin-footer']) ? $a['margin-footer'] : '')); + $ohname = (isset($a['ohname']) ? $a['ohname'] : (isset($a['odd-header-name']) ? $a['odd-header-name'] : '')); + $ehname = (isset($a['ehname']) ? $a['ehname'] : (isset($a['even-header-name']) ? $a['even-header-name'] : '')); + $ofname = (isset($a['ofname']) ? $a['ofname'] : (isset($a['odd-footer-name']) ? $a['odd-footer-name'] : '')); + $efname = (isset($a['efname']) ? $a['efname'] : (isset($a['even-footer-name']) ? $a['even-footer-name'] : '')); + $ohvalue = (isset($a['ohvalue']) ? $a['ohvalue'] : (isset($a['odd-header-value']) ? $a['odd-header-value'] : 0)); + $ehvalue = (isset($a['ehvalue']) ? $a['ehvalue'] : (isset($a['even-header-value']) ? $a['even-header-value'] : 0)); + $ofvalue = (isset($a['ofvalue']) ? $a['ofvalue'] : (isset($a['odd-footer-value']) ? $a['odd-footer-value'] : 0)); + $efvalue = (isset($a['efvalue']) ? $a['efvalue'] : (isset($a['even-footer-value']) ? $a['even-footer-value'] : 0)); + $toc_id = (isset($a['toc_id']) ? $a['toc_id'] : (isset($a['name']) ? $a['name'] : 0)); + $pagesel = (isset($a['pagesel']) ? $a['pagesel'] : (isset($a['pageselector']) ? $a['pageselector'] : '')); + $toc_pagesel = (isset($a['toc_pagesel']) ? $a['toc_pagesel'] : (isset($a['toc-pageselector']) ? $a['toc-pageselector'] : '')); + $sheetsize = (isset($a['sheetsize']) ? $a['sheetsize'] : (isset($a['sheet-size']) ? $a['sheet-size'] : '')); + $toc_sheetsize = (isset($a['toc_sheetsize']) ? $a['toc_sheetsize'] : (isset($a['toc-sheet-size']) ? $a['toc-sheet-size'] : '')); + + $this->TOCpagebreak('', '', '', $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); + } + + function TOCpagebreak($tocfont = '', $tocfontsize = '', $tocindent = '', $TOCusePaging = true, $TOCuseLinking = '', $toc_orientation = '', $toc_mgl = '', $toc_mgr = '', $toc_mgt = '', $toc_mgb = '', $toc_mgh = '', $toc_mgf = '', $toc_ohname = '', $toc_ehname = '', $toc_ofname = '', $toc_efname = '', $toc_ohvalue = 0, $toc_ehvalue = 0, $toc_ofvalue = 0, $toc_efvalue = 0, $toc_preHTML = '', $toc_postHTML = '', $toc_bookmarkText = '', $resetpagenum = '', $pagenumstyle = '', $suppress = '', $orientation = '', $mgl = '', $mgr = '', $mgt = '', $mgb = '', $mgh = '', $mgf = '', $ohname = '', $ehname = '', $ofname = '', $efname = '', $ohvalue = 0, $ehvalue = 0, $ofvalue = 0, $efvalue = 0, $toc_id = 0, $pagesel = '', $toc_pagesel = '', $sheetsize = '', $toc_sheetsize = '', $tocoutdent = '') + { + // Start a new page + if ($this->state == 0) { + $this->AddPage(); + } + if ($this->y == $this->tMargin && (!$this->mirrorMargins || ($this->mirrorMargins && $this->page % 2 == 1))) { + // Don't add a page + if ($this->page == 1 && count($this->PageNumSubstitutions) == 0) { + if (!$suppress) { + $suppress = 'off'; + } + // $this->PageNumSubstitutions[] = array('from'=>1, 'reset'=> $resetpagenum, 'type'=>$pagenumstyle, 'suppress'=> $suppress); + } + $this->PageNumSubstitutions[] = ['from' => $this->page, 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress]; + } else { + $this->AddPage($orientation, 'NEXT-ODD', $resetpagenum, $pagenumstyle, $suppress, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $pagesel, $sheetsize); + } + $this->tableOfContents->TOCpagebreak($tocfont, $tocfontsize, $tocindent, $TOCusePaging, $TOCuseLinking, $toc_orientation, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_preHTML, $toc_postHTML, $toc_bookmarkText, $resetpagenum, $pagenumstyle, $suppress, $orientation, $mgl, $mgr, $mgt, $mgb, $mgh, $mgf, $ohname, $ehname, $ofname, $efname, $ohvalue, $ehvalue, $ofvalue, $efvalue, $toc_id, $pagesel, $toc_pagesel, $sheetsize, $toc_sheetsize, $tocoutdent); + } + + function TOC_Entry($txt, $level = 0, $toc_id = 0) + { + if ($this->ColActive) { + $ily = $this->y0; + } else { + $ily = $this->y; + } // use top of columns + + $linkn = $this->AddLink(); + $uid = '__mpdfinternallink_' . $linkn; + if ($this->table_rotate) { + $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "tbrot" => true]; + } elseif ($this->kwt) { + $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "kwt" => true]; + } elseif ($this->ColActive) { + $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page, "col" => $this->CurrCol]; + } elseif (!$this->keep_block_together) { + $this->internallink[$uid] = ["Y" => $ily, "PAGE" => $this->page]; + } + $this->internallink['#' . $uid] = $linkn; + $this->SetLink($linkn, $ily, $this->page); + + if (strtoupper($toc_id) == 'ALL') { + $toc_id = '_mpdf_all'; + } elseif (!$toc_id) { + $toc_id = 0; + } else { + $toc_id = strtolower($toc_id); + } + $btoc = ['t' => $txt, 'l' => $level, 'p' => $this->page, 'link' => $linkn, 'toc_id' => $toc_id]; + if ($this->keep_block_together) { + // do nothing + } /* -- TABLES -- */ elseif ($this->table_rotate) { + $this->tbrot_toc[] = $btoc; + } elseif ($this->kwt) { + $this->kwt_toc[] = $btoc; + } /* -- END TABLES -- */ elseif ($this->ColActive) { // *COLUMNS* + $this->col_toc[] = $btoc; // *COLUMNS* + } // *COLUMNS* + else { + $this->tableOfContents->_toc[] = $btoc; + } + } + + /* -- END TOC -- */ + + // ====================================================== + function MovePages($target_page, $start_page, $end_page = -1) + { + // move a page/pages EARLIER in the document + if ($end_page < 1) { + $end_page = $start_page; + } + $n_toc = $end_page - $start_page + 1; + + // Set/Update PageNumSubstitutions changes before moving anything + if (count($this->PageNumSubstitutions)) { + $tp_present = false; + $sp_present = false; + $ep_present = false; + foreach ($this->PageNumSubstitutions as $k => $v) { + if ($this->PageNumSubstitutions[$k]['from'] == $target_page) { + $tp_present = true; + if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) { + $this->PageNumSubstitutions[$k]['suppress'] = 'off'; + } + } + if ($this->PageNumSubstitutions[$k]['from'] == $start_page) { + $sp_present = true; + if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) { + $this->PageNumSubstitutions[$k]['suppress'] = 'off'; + } + } + if ($this->PageNumSubstitutions[$k]['from'] == ($end_page + 1)) { + $ep_present = true; + if ($this->PageNumSubstitutions[$k]['suppress'] != 'on' && $this->PageNumSubstitutions[$k]['suppress'] != 1) { + $this->PageNumSubstitutions[$k]['suppress'] = 'off'; + } + } + } + + if (!$tp_present) { + list($tp_type, $tp_suppress, $tp_reset) = $this->docPageSettings($target_page); + } + if (!$sp_present) { + list($sp_type, $sp_suppress, $sp_reset) = $this->docPageSettings($start_page); + } + if (!$ep_present) { + list($ep_type, $ep_suppress, $ep_reset) = $this->docPageSettings($start_page - 1); + } + } + + $last = []; + // store pages + for ($i = $start_page; $i <= $end_page; $i++) { + $last[] = $this->pages[$i]; + } + // move pages + for ($i = $start_page - 1; $i >= ($target_page); $i--) { + $this->pages[$i + $n_toc] = $this->pages[$i]; + } + // Put toc pages at insert point + for ($i = 0; $i < $n_toc; $i++) { + $this->pages[$target_page + $i] = $last[$i]; + } + + /* -- BOOKMARKS -- */ + // Update Bookmarks + foreach ($this->BMoutlines as $i => $o) { + if ($o['p'] >= $target_page) { + $this->BMoutlines[$i]['p'] += $n_toc; + } + } + /* -- END BOOKMARKS -- */ + + // Update Page Links + if (count($this->PageLinks)) { + $newarr = []; + foreach ($this->PageLinks as $i => $o) { + foreach ($this->PageLinks[$i] as $key => $pl) { + if (strpos($pl[4], '@') === 0) { + $p = substr($pl[4], 1); + if ($p >= $start_page && $p <= $end_page) { + $this->PageLinks[$i][$key][4] = '@' . ($p + ($target_page - $start_page)); + } elseif ($p >= $target_page && $p < $start_page) { + $this->PageLinks[$i][$key][4] = '@' . ($p + $n_toc); + } + } + } + if ($i >= $start_page && $i <= $end_page) { + $newarr[($i + ($target_page - $start_page))] = $this->PageLinks[$i]; + } elseif ($i >= $target_page && $i < $start_page) { + $newarr[($i + $n_toc)] = $this->PageLinks[$i]; + } else { + $newarr[$i] = $this->PageLinks[$i]; + } + } + $this->PageLinks = $newarr; + } + + // OrientationChanges + if (count($this->OrientationChanges)) { + $newarr = []; + foreach ($this->OrientationChanges as $p => $v) { + if ($p >= $start_page && $p <= $end_page) { + $newarr[($p + ($target_page - $start_page))] = $this->OrientationChanges[$p]; + } elseif ($p >= $target_page && $p < $start_page) { + $newarr[$p + $n_toc] = $this->OrientationChanges[$p]; + } else { + $newarr[$p] = $this->OrientationChanges[$p]; + } + } + ksort($newarr); + $this->OrientationChanges = $newarr; + } + + // Page Dimensions + if (count($this->pageDim)) { + $newarr = []; + foreach ($this->pageDim as $p => $v) { + if ($p >= $start_page && $p <= $end_page) { + $newarr[($p + ($target_page - $start_page))] = $this->pageDim[$p]; + } elseif ($p >= $target_page && $p < $start_page) { + $newarr[$p + $n_toc] = $this->pageDim[$p]; + } else { + $newarr[$p] = $this->pageDim[$p]; + } + } + ksort($newarr); + $this->pageDim = $newarr; + } + + // HTML Headers & Footers + if (count($this->saveHTMLHeader)) { + $newarr = []; + foreach ($this->saveHTMLHeader as $p => $v) { + if ($p >= $start_page && $p <= $end_page) { + $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLHeader[$p]; + } elseif ($p >= $target_page && $p < $start_page) { + $newarr[$p + $n_toc] = $this->saveHTMLHeader[$p]; + } else { + $newarr[$p] = $this->saveHTMLHeader[$p]; + } + } + ksort($newarr); + $this->saveHTMLHeader = $newarr; + } + if (count($this->saveHTMLFooter)) { + $newarr = []; + foreach ($this->saveHTMLFooter as $p => $v) { + if ($p >= $start_page && $p <= $end_page) { + $newarr[($p + ($target_page - $start_page))] = $this->saveHTMLFooter[$p]; + } elseif ($p >= $target_page && $p < $start_page) { + $newarr[$p + $n_toc] = $this->saveHTMLFooter[$p]; + } else { + $newarr[$p] = $this->saveHTMLFooter[$p]; + } + } + ksort($newarr); + $this->saveHTMLFooter = $newarr; + } + + // Update Internal Links + if (count($this->internallink)) { + foreach ($this->internallink as $key => $o) { + if (is_array($o) && $o['PAGE'] >= $start_page && $o['PAGE'] <= $end_page) { + $this->internallink[$key]['PAGE'] += ($target_page - $start_page); + } elseif (is_array($o) && $o['PAGE'] >= $target_page && $o['PAGE'] < $start_page) { + $this->internallink[$key]['PAGE'] += $n_toc; + } + } + } + + // Update Links + if (count($this->links)) { + foreach ($this->links as $key => $o) { + if ($o[0] >= $start_page && $o[0] <= $end_page) { + $this->links[$key][0] += ($target_page - $start_page); + } + if ($o[0] >= $target_page && $o[0] < $start_page) { + $this->links[$key][0] += $n_toc; + } + } + } + + // Update Form fields + if (count($this->form->forms)) { + foreach ($this->form->forms as $key => $f) { + if ($f['page'] >= $start_page && $f['page'] <= $end_page) { + $this->form->forms[$key]['page'] += ($target_page - $start_page); + } + if ($f['page'] >= $target_page && $f['page'] < $start_page) { + $this->form->forms[$key]['page'] += $n_toc; + } + } + } + + /* -- ANNOTATIONS -- */ + // Update Annotations + if (count($this->PageAnnots)) { + $newarr = []; + foreach ($this->PageAnnots as $p => $anno) { + if ($p >= $start_page && $p <= $end_page) { + $np = $p + ($target_page - $start_page); + foreach ($anno as $o) { + $newarr[$np][] = $o; + } + } elseif ($p >= $target_page && $p < $start_page) { + $np = $p + $n_toc; + foreach ($anno as $o) { + $newarr[$np][] = $o; + } + } else { + $newarr[$p] = $this->PageAnnots[$p]; + } + } + $this->PageAnnots = $newarr; + unset($newarr); + } + /* -- END ANNOTATIONS -- */ + + // Update TOC pages + if (count($this->tableOfContents->_toc)) { + foreach ($this->tableOfContents->_toc as $key => $t) { + if ($t['p'] >= $start_page && $t['p'] <= $end_page) { + $this->tableOfContents->_toc[$key]['p'] += ($target_page - $start_page); + } + if ($t['p'] >= $target_page && $t['p'] < $start_page) { + $this->tableOfContents->_toc[$key]['p'] += $n_toc; + } + } + } + + // Update PageNumSubstitutions + if (count($this->PageNumSubstitutions)) { + $newarr = []; + foreach ($this->PageNumSubstitutions as $k => $v) { + if ($this->PageNumSubstitutions[$k]['from'] >= $start_page && $this->PageNumSubstitutions[$k]['from'] <= $end_page) { + $this->PageNumSubstitutions[$k]['from'] += ($target_page - $start_page); + $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k]; + } elseif ($this->PageNumSubstitutions[$k]['from'] >= $target_page && $this->PageNumSubstitutions[$k]['from'] < $start_page) { + $this->PageNumSubstitutions[$k]['from'] += $n_toc; + $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k]; + } else { + $newarr[$this->PageNumSubstitutions[$k]['from']] = $this->PageNumSubstitutions[$k]; + } + } + + if (!$sp_present) { + $newarr[$target_page] = ['from' => $target_page, 'suppress' => $sp_suppress, 'reset' => $sp_reset, 'type' => $sp_type]; + } + if (!$tp_present) { + $newarr[($target_page + $n_toc)] = ['from' => ($target_page + $n_toc), 'suppress' => $tp_suppress, 'reset' => $tp_reset, 'type' => $tp_type]; + } + if (!$ep_present && $end_page > count($this->pages)) { + $newarr[($end_page + 1)] = ['from' => ($end_page + 1), 'suppress' => $ep_suppress, 'reset' => $ep_reset, 'type' => $ep_type]; + } + ksort($newarr); + $this->PageNumSubstitutions = []; + foreach ($newarr as $v) { + $this->PageNumSubstitutions[] = $v; + } + } + } + + function DeletePages($start_page, $end_page = -1) + { + // move a page/pages EARLIER in the document + if ($end_page < 1) { + $end_page = $start_page; + } + $n_tod = $end_page - $start_page + 1; + $last_page = count($this->pages); + $n_atend = $last_page - $end_page + 1; + + // move pages + for ($i = 0; $i < $n_atend; $i++) { + $this->pages[$start_page + $i] = $this->pages[$end_page + 1 + $i]; + } + // delete pages + for ($i = 0; $i < $n_tod; $i++) { + unset($this->pages[$last_page - $i]); + } + + + /* -- BOOKMARKS -- */ + // Update Bookmarks + foreach ($this->BMoutlines as $i => $o) { + if ($o['p'] >= $end_page) { + $this->BMoutlines[$i]['p'] -= $n_tod; + } elseif ($p < $start_page) { + unset($this->BMoutlines[$i]); + } + } + /* -- END BOOKMARKS -- */ + + // Update Page Links + if (count($this->PageLinks)) { + $newarr = []; + foreach ($this->PageLinks as $i => $o) { + foreach ($this->PageLinks[$i] as $key => $pl) { + if (strpos($pl[4], '@') === 0) { + $p = substr($pl[4], 1); + if ($p > $end_page) { + $this->PageLinks[$i][$key][4] = '@' . ($p - $n_tod); + } elseif ($p < $start_page) { + unset($this->PageLinks[$i][$key]); + } + } + } + if ($i > $end_page) { + $newarr[($i - $n_tod)] = $this->PageLinks[$i]; + } elseif ($p < $start_page) { + $newarr[$i] = $this->PageLinks[$i]; + } + } + $this->PageLinks = $newarr; + } + + // OrientationChanges + if (count($this->OrientationChanges)) { + $newarr = []; + foreach ($this->OrientationChanges as $p => $v) { + if ($p > $end_page) { + $newarr[($p - $t_tod)] = $this->OrientationChanges[$p]; + } elseif ($p < $start_page) { + $newarr[$p] = $this->OrientationChanges[$p]; + } + } + ksort($newarr); + $this->OrientationChanges = $newarr; + } + + // Page Dimensions + if (count($this->pageDim)) { + $newarr = []; + foreach ($this->pageDim as $p => $v) { + if ($p > $end_page) { + $newarr[($p - $n_tod)] = $this->pageDim[$p]; + } elseif ($p < $start_page) { + $newarr[$p] = $this->pageDim[$p]; + } + } + ksort($newarr); + $this->pageDim = $newarr; + } + + // HTML Headers & Footers + if (count($this->saveHTMLHeader)) { + foreach ($this->saveHTMLHeader as $p => $v) { + if ($p > $end_page) { + $newarr[($p - $n_tod)] = $this->saveHTMLHeader[$p]; + } // mPDF 5.7.3 + elseif ($p < $start_page) { + $newarr[$p] = $this->saveHTMLHeader[$p]; + } + } + ksort($newarr); + $this->saveHTMLHeader = $newarr; + } + if (count($this->saveHTMLFooter)) { + $newarr = []; + foreach ($this->saveHTMLFooter as $p => $v) { + if ($p > $end_page) { + $newarr[($p - $n_tod)] = $this->saveHTMLFooter[$p]; + } elseif ($p < $start_page) { + $newarr[$p] = $this->saveHTMLFooter[$p]; + } + } + ksort($newarr); + $this->saveHTMLFooter = $newarr; + } + + // Update Internal Links + foreach ($this->internallink as $key => $o) { + if ($o['PAGE'] > $end_page) { + $this->internallink[$key]['PAGE'] -= $n_tod; + } elseif ($o['PAGE'] < $start_page) { + unset($this->internallink[$key]); + } + } + + // Update Links + foreach ($this->links as $key => $o) { + if ($o[0] > $end_page) { + $this->links[$key][0] -= $n_tod; + } elseif ($o[0] < $start_page) { + unset($this->links[$key]); + } + } + + // Update Form fields + foreach ($this->form->forms as $key => $f) { + if ($f['page'] > $end_page) { + $this->form->forms[$key]['page'] -= $n_tod; + } elseif ($f['page'] < $start_page) { + unset($this->form->forms[$key]); + } + } + + /* -- ANNOTATIONS -- */ + // Update Annotations + if (count($this->PageAnnots)) { + $newarr = []; + foreach ($this->PageAnnots as $p => $anno) { + if ($p > $end_page) { + foreach ($anno as $o) { + $newarr[($p - $n_tod)][] = $o; + } + } elseif ($p < $start_page) { + $newarr[$p] = $this->PageAnnots[$p]; + } + } + ksort($newarr); + $this->PageAnnots = $newarr; + } + /* -- END ANNOTATIONS -- */ + + // Update PageNumSubstitutions + foreach ($this->PageNumSubstitutions as $k => $v) { + if ($this->PageNumSubstitutions[$k]['from'] > $end_page) { + $this->PageNumSubstitutions[$k]['from'] -= $n_tod; + } elseif ($this->PageNumSubstitutions[$k]['from'] < $start_page) { + unset($this->PageNumSubstitutions[$k]); + } + } + + unset($newarr); + $this->page = count($this->pages); + } + + // ====================================================== + /* -- INDEX -- */ + // FROM class PDF_Ref == INDEX + + function IndexEntry($txt, $xref = '') + { + if ($xref) { + $this->IndexEntrySee($txt, $xref); + return; + } + + // Search the reference (AND Ref/PageNo) in the array + $Present = false; + if ($this->keep_block_together) { + // do nothing + } /* -- TABLES -- */ elseif ($this->kwt) { + $size = count($this->kwt_Reference); + for ($i = 0; $i < $size; $i++) { + if (isset($this->kwt_Reference[$i]['t']) && $this->kwt_Reference[$i]['t'] == $txt) { + $Present = true; + if ($this->page != $this->kwt_Reference[$i]['op']) { + $this->kwt_Reference[$i]['op'] = $this->page; + } + } + } + if (!$Present) { // If not found, add it + $this->kwt_Reference[] = ['t' => $txt, 'op' => $this->page]; + } + } /* -- END TABLES -- */ else { + $size = count($this->Reference); + for ($i = 0; $i < $size; $i++) { + if (isset($this->Reference[$i]['t']) && $this->Reference[$i]['t'] == $txt) { + $Present = true; + if (!in_array($this->page, $this->Reference[$i]['p'])) { + $this->Reference[$i]['p'][] = $this->page; + } + } + } + if (!$Present) { // If not found, add it + $this->Reference[] = ['t' => $txt, 'p' => [$this->page]]; + } + } + } + + // Added function to add a reference "Elephants. See Chickens" + function IndexEntrySee($txta, $txtb) + { + if ($this->directionality == 'rtl') { // *OTL* + // ONLY DO THIS IF NOT IN TAGS + if ($txta == strip_tags($txta)) { + $txta = str_replace(':', ' - ', $txta); // *OTL* + } + if ($txtb == strip_tags($txtb)) { + $txtb = str_replace(':', ' - ', $txtb); // *OTL* + } + } // *OTL* + else { // *OTL* + if ($txta == strip_tags($txta)) { + $txta = str_replace(':', ', ', $txta); + } + if ($txtb == strip_tags($txtb)) { + $txtb = str_replace(':', ', ', $txtb); + } + } // *OTL* + $this->Reference[] = ['t' => $txta . ' - see ' . $txtb, 'p' => []]; + } + + private function filesInDir($directory) + { + $files = []; + foreach ((new \DirectoryIterator($directory)) as $v) { + if ($v->isDir() || $v->isDot()) { + continue; + } + + $files[] = $v->getPathname(); + } + + return $files; + } + + function InsertIndex($usedivletters = 1, $useLinking = false, $indexCollationLocale = '', $indexCollationGroup = '') + { + $size = count($this->Reference); + if ($size == 0) { + return false; + } + + // $spacer used after named entry + // $sep separates number [groups], $joiner joins numbers in range + // e.g. "elephant 73, 97-99" = elephant[$spacer]73[$sep]97[$joiner]99 + // $subEntrySeparator separates main and subentry (if $this->indexUseSubentries == false;) e.g. + // Mammal:elephant => Mammal[$subEntrySeparator]elephant + // $subEntryInset specifies what precedes a subentry (if $this->indexUseSubentries == true;) e.g. + // Mammal:elephant => [$subEntryInset]elephant + $spacer = "\xc2\xa0 "; + if ($this->directionality == 'rtl') { + $sep = '، '; + $joiner = '-'; + $subEntrySeparator = '، '; + $subEntryInset = ' - '; + } else { + $sep = ', '; + $joiner = '-'; + $subEntrySeparator = ', '; + $subEntryInset = ' - '; + } + + for ($i = 0; $i < $size; $i++) { + $txt = $this->Reference[$i]['t']; + $txt = strip_tags($txt); // mPDF 6 + $txt = $this->purify_utf8($txt); + $this->Reference[$i]['uf'] = $txt; // Unformatted e.g. pure utf-8 encoded characters, no mark-up/tags + // Used for ordering and collation + } + + if ($usedivletters) { + if ($indexCollationGroup && \in_array(strtolower($indexCollationGroup), array_map(function ($v) { + return strtolower(basename($v, '.php')); + }, $this->filesInDir(__DIR__ . '/../data/collations/')))) { + $collation = require __DIR__ . '/../data/collations/' . $indexCollationGroup . '.php'; + } else { + $collation = []; + } + for ($i = 0; $i < $size; $i++) { + if ($this->Reference[$i]['uf']) { + $l = mb_substr($this->Reference[$i]['uf'], 0, 1, 'UTF-8'); + if (isset($indexCollationGroup) && $indexCollationGroup) { + $uni = $this->UTF8StringToArray($l); + $ucode = $uni[0]; + if (isset($collation[$ucode])) { + $this->Reference[$i]['d'] = UtfString::code2utf($collation[$ucode]); + } else { + $this->Reference[$i]['d'] = mb_strtolower($l, 'UTF-8'); + } + } else { + $this->Reference[$i]['d'] = mb_strtolower($l, 'UTF-8'); + } + } + } + } + + // Alphabetic sort of the references + $originalLocale = setlocale(LC_COLLATE, 0); + if ($indexCollationLocale) { + setlocale(LC_COLLATE, $indexCollationLocale); + } + + usort($this->Reference, function ($a, $b) { + return strcoll(strtolower($a['uf']), strtolower($b['uf'])); + }); + + if ($indexCollationLocale) { + setlocale(LC_COLLATE, $originalLocale); + } + + $html = '<div class="mpdf_index_main">'; + + $lett = ''; + $last_lett = ''; + $mainentry = ''; + for ($i = 0; $i < $size; $i++) { + if ($this->Reference[$i]['t']) { + if ($usedivletters) { + $lett = $this->Reference[$i]['d']; + if ($lett != $last_lett) { + $html .= '<div class="mpdf_index_letter">' . $lett . '</div>'; + } + } + $txt = $this->Reference[$i]['t']; + + // Sub-entries e.g. Mammals:elephant + // But allow for tags e.g. <b>Mammal</b>:elephants + $a = preg_split('/(<.*?>)/', $txt, -1, PREG_SPLIT_DELIM_CAPTURE); + $txt = ''; + $marker = false; + foreach ($a as $k => $e) { + if ($k % 2 == 0 && !$marker) { + if (strpos($e, ':') !== false) { // == SubEntry + if ($this->indexUseSubentries) { + // If the Main entry does not have any page numbers associated with it + // create and insert an entry + list($txtmain, $sub) = preg_split('/[:]/', $e, 2); + if (strip_tags($txt . $txtmain) != $mainentry) { + $html .= '<div class="mpdf_index_entry">' . $txt . $txtmain . '</div>'; + $mainentry = strip_tags($txt . $txtmain); + } + + $txt = $subEntryInset; + $e = $sub; // Only replace first one + } else { + $e = preg_replace('/[:]/', $subEntrySeparator, $e, 1); // Only replace first one + } + $marker = true; // Don't replace any more once the subentry marker has been found + } + } + $txt .= $e; + } + + if (!$marker) { + $mainentry = strip_tags($txt); + } + + $html .= '<div class="mpdf_index_entry">'; + $html .= $txt; + $ppp = $this->Reference[$i]['p']; // = array of page numbers to point to + if (count($ppp)) { + sort($ppp); + $newarr = []; + $range_start = $ppp[0]; + $range_end = 0; + + $html .= $spacer; + + for ($zi = 1; $zi < count($ppp); $zi++) { + if ($ppp[$zi] == ($ppp[($zi - 1)] + 1)) { + $range_end = $ppp[$zi]; + } else { + if ($range_end) { + if ($range_end == $range_start + 1) { + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $range_start . '">'; + } + $html .= $this->docPageNum($range_start); + if ($useLinking) { + $html .= '</a>'; + } + $html .= $sep; + + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $ppp[$zi - 1] . '">'; + } + $html .= $this->docPageNum($ppp[$zi - 1]); + if ($useLinking) { + $html .= '</a>'; + } + $html .= $sep; + } + } else { + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $ppp[$zi - 1] . '">'; + } + $html .= $this->docPageNum($ppp[$zi - 1]); + if ($useLinking) { + $html .= '</a>'; + } + $html .= $sep; + } + $range_start = $ppp[$zi]; + $range_end = 0; + } + } + + if ($range_end) { + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $range_start . '">'; + } + $html .= $this->docPageNum($range_start); + if ($range_end == $range_start + 1) { + if ($useLinking) { + $html .= '</a>'; + } + $html .= $sep; + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $range_end . '">'; + } + $html .= $this->docPageNum($range_end); + if ($useLinking) { + $html .= '</a>'; + } + } else { + $html .= $joiner; + $html .= $this->docPageNum($range_end); + if ($useLinking) { + $html .= '</a>'; + } + } + } else { + if ($useLinking) { + $html .= '<a class="mpdf_index_link" href="@' . $ppp[(count($ppp) - 1)] . '">'; + } + $html .= $this->docPageNum($ppp[(count($ppp) - 1)]); + if ($useLinking) { + $html .= '</a>'; + } + } + } + } + $html .= '</div>'; + $last_lett = $lett; + } + $html .= '</div>'; + $save_fpb = $this->fixedPosBlockSave; + $this->WriteHTML($html); + $this->fixedPosBlockSave = $save_fpb; + + $this->breakpoints[$this->CurrCol][] = $this->y; // *COLUMNS* + } + + /* -- END INDEX -- */ + + function AcceptPageBreak() + { + if (count($this->cellBorderBuffer)) { + $this->printcellbuffer(); + } // *TABLES* + /* -- COLUMNS -- */ + if ($this->ColActive == 1) { + if ($this->CurrCol < $this->NbCol - 1) { + // Go to the next column + $this->CurrCol++; + $this->SetCol($this->CurrCol); + $this->y = $this->y0; + $this->ChangeColumn = 1; // Number (and direction) of columns changed +1, +2, -2 etc. + // DIRECTIONALITY RTL + if ($this->directionality == 'rtl') { + $this->ChangeColumn = -($this->ChangeColumn); + } // *OTL* + // Stay on the page + return false; + } else { + // Go back to the first column - NEW PAGE + if (count($this->columnbuffer)) { + $this->printcolumnbuffer(); + } + $this->SetCol(0); + $this->y0 = $this->tMargin; + $this->ChangeColumn = -($this->NbCol - 1); + // DIRECTIONALITY RTL + if ($this->directionality == 'rtl') { + $this->ChangeColumn = -($this->ChangeColumn); + } // *OTL* + // Page break + return true; + } + } /* -- END COLUMNS -- */ + /* -- TABLES -- */ elseif ($this->table_rotate) { + if ($this->tablebuffer) { + $this->printtablebuffer(); + } + return true; + } /* -- END TABLES -- */ else { // *COLUMNS* + $this->ChangeColumn = 0; + return $this->autoPageBreak; + } // *COLUMNS* + return $this->autoPageBreak; + } + + // ----------- COLUMNS --------------------- + /* -- COLUMNS -- */ + + function SetColumns($NbCol, $vAlign = '', $gap = 5) + { + // NbCol = number of columns + // Anything less than 2 turns columns off + if ($NbCol < 2) { // SET COLUMNS OFF + if ($this->ColActive) { + $this->ColActive = 0; + if (count($this->columnbuffer)) { + $this->printcolumnbuffer(); + } + $this->NbCol = 1; + $this->ResetMargins(); + $this->pgwidth = $this->w - $this->lMargin - $this->rMargin; + $this->divwidth = 0; + $this->Ln(); + } + $this->ColActive = 0; + $this->columnbuffer = []; + $this->ColDetails = []; + $this->columnLinks = []; + $this->columnAnnots = []; + $this->columnForms = []; + $this->col_BMoutlines = []; + $this->col_toc = []; + $this->breakpoints = []; + } else { // SET COLUMNS ON + if ($this->ColActive) { + $this->ColActive = 0; + if (count($this->columnbuffer)) { + $this->printcolumnbuffer(); + } + $this->ResetMargins(); + } + if (isset($this->y) && $this->y > $this->tMargin) { + $this->Ln(); + } + $this->NbCol = $NbCol; + $this->ColGap = $gap; + $this->divwidth = 0; + $this->ColActive = 1; + $this->ColumnAdjust = true; // enables column height adjustment for the page + $this->columnbuffer = []; + $this->ColDetails = []; + $this->columnLinks = []; + $this->columnAnnots = []; + $this->columnForms = []; + $this->col_BMoutlines = []; + $this->col_toc = []; + $this->breakpoints = []; + if ((strtoupper($vAlign) == 'J') || (strtoupper($vAlign) == 'JUSTIFY')) { + $vAlign = 'J'; + } else { + $vAlign = ''; + } + $this->colvAlign = $vAlign; + // Save the ordinate + $absL = $this->DeflMargin - ($gap / 2); + $absR = $this->DefrMargin - ($gap / 2); + $PageWidth = $this->w - $absL - $absR; // virtual pagewidth for calculation only + $ColWidth = (($PageWidth - ($gap * ($NbCol))) / $NbCol); + $this->ColWidth = $ColWidth; + /* -- OTL -- */ + + if ($this->directionality == 'rtl') { + for ($i = 0; $i < $this->NbCol; $i++) { + $this->ColL[$i] = $absL + ($gap / 2) + (($NbCol - ($i + 1)) * ($PageWidth / $NbCol)); + $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos + } + } else { + /* -- END OTL -- */ + for ($i = 0; $i < $this->NbCol; $i++) { + $this->ColL[$i] = $absL + ($gap / 2) + ($i * ($PageWidth / $NbCol) ); + $this->ColR[$i] = $this->ColL[$i] + $ColWidth; // NB This is not R margin -> R pos + } + } // *OTL* + $this->pgwidth = $ColWidth; + $this->SetCol(0); + $this->y0 = $this->y; + } + $this->x = $this->lMargin; + } + + function SetCol($CurrCol) + { + // Used internally to set column by number: 0 is 1st column + // Set position on a column + $this->CurrCol = $CurrCol; + $x = $this->ColL[$CurrCol]; + $xR = $this->ColR[$CurrCol]; // NB This is not R margin -> R pos + if (($this->mirrorMargins) && (($this->page) % 2 == 0)) { // EVEN + $x += $this->MarginCorrection; + $xR += $this->MarginCorrection; + } + $this->SetMargins($x, ($this->w - $xR), $this->tMargin); + } + + function AddColumn() + { + $this->NewColumn(); + $this->ColumnAdjust = false; // disables all column height adjustment for the page. + } + + function NewColumn() + { + if ($this->ColActive == 1) { + if ($this->CurrCol < $this->NbCol - 1) { + // Go to the next column + $this->CurrCol++; + $this->SetCol($this->CurrCol); + $this->y = $this->y0; + $this->ChangeColumn = 1; + // DIRECTIONALITY RTL + if ($this->directionality == 'rtl') { + $this->ChangeColumn = -($this->ChangeColumn); + } // *OTL* + // Stay on the page + } else { + // Go back to the first column + // Page break + if (count($this->columnbuffer)) { + $this->printcolumnbuffer(); + } + $this->AddPage($this->CurOrientation); + $this->SetCol(0); + $this->y0 = $this->tMargin; + $this->ChangeColumn = -($this->NbCol - 1); + // DIRECTIONALITY RTL + if ($this->directionality == 'rtl') { + $this->ChangeColumn = -($this->ChangeColumn); + } // *OTL* + } + $this->x = $this->lMargin; + } else { + $this->AddPage($this->CurOrientation); + } + } + + function printcolumnbuffer() + { + // Columns ended (but page not ended) -> try to match all columns - unless disabled by using a custom column-break + if (!$this->ColActive && $this->ColumnAdjust && !$this->keepColumns) { + // Calculate adjustment to add to each column to calculate rel_y value + $this->ColDetails[0]['add_y'] = 0; + $last_col = 0; + // Recursively add previous column's height + for ($i = 1; $i < $this->NbCol; $i++) { + if (isset($this->ColDetails[$i]['bottom_margin']) && $this->ColDetails[$i]['bottom_margin']) { // If any entries in the column + $this->ColDetails[$i]['add_y'] = ($this->ColDetails[$i - 1]['bottom_margin'] - $this->y0) + $this->ColDetails[$i - 1]['add_y']; + $last_col = $i; // Last column actually printed + } + } + + // Calculate value for each position sensitive entry as though for one column + foreach ($this->columnbuffer as $key => $s) { + $t = $s['s']; + if ($t == 'ACROFORM') { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + $this->columnbuffer[$key]['s'] = ''; + } elseif (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } elseif (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } elseif (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/', $t)) { + $this->columnbuffer[$key]['rel_y'] = $s['y'] + $this->ColDetails[$s['col']]['add_y'] - $this->y0; + } + } + foreach ($this->internallink as $key => $f) { + if (is_array($f) && isset($f['col'])) { + $this->internallink[$key]['rel_y'] = $f['Y'] + $this->ColDetails[$f['col']]['add_y'] - $this->y0; + } + } + + $breaks = []; + foreach ($this->breakpoints as $c => $bpa) { + foreach ($bpa as $rely) { + $breaks[] = $rely + $this->ColDetails[$c]['add_y'] - $this->y0; + } + } + + + if (isset($this->ColDetails[$last_col]['bottom_margin'])) { + $lcbm = $this->ColDetails[$last_col]['bottom_margin']; + } else { + $lcbm = 0; + } + $sum_h = $this->ColDetails[$last_col]['add_y'] + $lcbm - $this->y0; + // $sum_h = max($this->ColDetails[$last_col]['add_y'] + $this->ColDetails[$last_col]['bottom_margin'] - $this->y0, end($breaks)); + $target_h = ($sum_h / $this->NbCol); + + $cbr = []; + for ($i = 1; $i < $this->NbCol; $i++) { + $th = ($sum_h * $i / $this->NbCol); + foreach ($breaks as $bk => $val) { + if ($val > $th) { + if (($val - $th) < ($th - $breaks[$bk - 1])) { + $cbr[$i - 1] = $val; + } else { + $cbr[$i - 1] = $breaks[$bk - 1]; + } + break; + } + } + } + $cbr[($this->NbCol - 1)] = $sum_h; + + // mPDF 6 + // Avoid outputing with 1st column empty + if (isset($cbr[0]) && $cbr[0] == 0) { + for ($i = 0; $i < $this->NbCol - 1; $i++) { + $cbr[$i] = $cbr[$i + 1]; + } + } + + // Now update the columns - divide into columns of approximately equal value + $last_new_col = 0; + $yadj = 0; // mm + $xadj = 0; + $last_col_bottom = 0; + $lowest_bottom_y = 0; + $block_bottom = 0; + $newcolumn = 0; + foreach ($this->columnbuffer as $key => $s) { + if (isset($s['rel_y'])) { // only process position sensitive data + if ($s['rel_y'] >= $cbr[$newcolumn]) { + $newcolumn++; + } else { + $newcolumn = $last_new_col; + } + + + $block_bottom = max($block_bottom, ($s['rel_y'] + $s['h'])); + + if ($this->directionality == 'rtl') { // *OTL* + $xadj = -(($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap)); // *OTL* + } // *OTL* + else { // *OTL* + $xadj = ($newcolumn - $s['col']) * ($this->ColWidth + $this->ColGap); + } // *OTL* + + if ($last_new_col != $newcolumn) { // Added new column + $last_col_bottom = $this->columnbuffer[$key]['rel_y']; + $block_bottom = 0; + } + $yadj = ($s['rel_y'] - $s['y']) - ($last_col_bottom) + $this->y0; + // callback function + $t = $s['s']; + + // mPDF 5.7+ + $t = $this->columnAdjustPregReplace('Td', $xadj, $yadj, '/BT (\d+\.\d\d+) (\d+\.\d\d+) Td/', $t); + $t = $this->columnAdjustPregReplace('re', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) ([\-]{0,1}\d+\.\d\d+) re/', $t); + $t = $this->columnAdjustPregReplace('l', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) l/', $t); + $t = $this->columnAdjustPregReplace('img', $xadj, $yadj, '/q (\d+\.\d\d+) 0 0 (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) cm \/(I|FO)/', $t); + $t = $this->columnAdjustPregReplace('draw', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) m/', $t); + $t = $this->columnAdjustPregReplace('bezier', $xadj, $yadj, '/(\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) (\d+\.\d\d+) c/', $t); + + $this->columnbuffer[$key]['s'] = $t; + $this->columnbuffer[$key]['newcol'] = $newcolumn; + $this->columnbuffer[$key]['newy'] = $s['y'] + $yadj; + $last_new_col = $newcolumn; + $clb = $s['y'] + $yadj + $s['h']; // bottom_margin of current + if ((isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb > $this->ColDetails[$newcolumn]['max_bottom']) || (!isset($this->ColDetails[$newcolumn]['max_bottom']) && $clb)) { + $this->ColDetails[$newcolumn]['max_bottom'] = $clb; + } + if ($clb > $lowest_bottom_y) { + $lowest_bottom_y = $clb; + } + // Adjust LINKS + if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->PageLinks[$this->page][$ref][0] += ($xadj * Mpdf::SCALE); + $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE); + unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]); + } + // Adjust FORM FIELDS + if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->form->forms[$ref]['x'] += ($xadj); + $this->form->forms[$ref]['y'] += ($yadj); + unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- ANNOTATIONS -- */ + if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]; + if ($this->PageAnnots[$this->page][$ref]['x'] < 0) { + $this->PageAnnots[$this->page][$ref]['x'] -= ($xadj); + } else { + $this->PageAnnots[$this->page][$ref]['x'] += ($xadj); + } + $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); // unlike PageLinks, Page annots has y values from top in mm + unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- END ANNOTATIONS -- */ + } + } + + /* -- BOOKMARKS -- */ + // Adjust Bookmarks + foreach ($this->col_BMoutlines as $v) { + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0, 'p' => $v['p']]; + } + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + + // Adjust ToC + foreach ($this->col_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + $this->links[$v['link']][1] = $this->y0; + } + /* -- END TOC -- */ + + // Adjust column length to be equal + if ($this->colvAlign == 'J') { + foreach ($this->columnbuffer as $key => $s) { + if (isset($s['rel_y'])) { // only process position sensitive data + // Set ratio to expand y values or heights + if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) { + $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0)); + } else { + $ratio = 1; + } + if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) { + $yadj = ($s['newy'] - $this->y0) * ($ratio - 1); + + // Adjust LINKS + if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE); // y value + $this->PageLinks[$this->page][$ref][3] *= $ratio; // height + unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]); + } + // Adjust FORM FIELDS + if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->form->forms[$ref]['x'] += ($xadj); + $this->form->forms[$ref]['y'] += ($yadj); + unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- ANNOTATIONS -- */ + if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); + unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- END ANNOTATIONS -- */ + } + } + } + foreach ($this->internallink as $key => $f) { + if (is_array($f) && isset($f['col'])) { + $last_col_bottom = 0; + for ($nbc = 0; $nbc < $this->NbCol; $nbc++) { + if ($f['rel_y'] >= $cbr[$nbc]) { + $last_col_bottom = $cbr[$nbc]; + } + } + $yadj = ($f['rel_y'] - $f['Y']) - $last_col_bottom + $this->y0; + $f['Y'] += $yadj; + unset($f['col']); + unset($f['rel_y']); + $this->internallink[$key] = $f; + } + } + + $last_col = -1; + $trans_on = false; + foreach ($this->columnbuffer as $key => $s) { + if (isset($s['rel_y'])) { // only process position sensitive data + // Set ratio to expand y values or heights + if (isset($this->ColDetails[$s['newcol']]['max_bottom']) && $this->ColDetails[$s['newcol']]['max_bottom'] && $this->ColDetails[$s['newcol']]['max_bottom'] != $this->y0) { + $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['newcol']]['max_bottom'] - ($this->y0)); + } else { + $ratio = 1; + } + if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) { + // Start Transformation + $this->pages[$this->page] .= $this->StartTransform(true) . "\n"; + $this->pages[$this->page] .= $this->transformScale(100, $ratio * 100, $x = '', $this->y0, true) . "\n"; + $trans_on = true; + } + } + // Now output the adjusted values + $this->pages[$this->page] .= $s['s'] . "\n"; + if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { // only process position sensitive data + // Stop Transformation + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + $trans_on = false; + } + } + if ($trans_on) { + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + } + } else { // if NOT $this->colvAlign == 'J' + // Now output the adjusted values + foreach ($this->columnbuffer as $s) { + $this->pages[$this->page] .= $s['s'] . "\n"; + } + } + if ($lowest_bottom_y > 0) { + $this->y = $lowest_bottom_y; + } + } // Columns not ended but new page -> align columns (can leave the columns alone - just tidy up the height) + elseif ($this->colvAlign == 'J' && $this->ColumnAdjust && !$this->keepColumns) { + // calculate the lowest bottom margin + $lowest_bottom_y = 0; + foreach ($this->columnbuffer as $key => $s) { + // Only process output data + $t = $s['s']; + if ($t == 'ACROFORM' || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/', $t)) || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/', $t)) || + (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/', $t)) || + (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/', $t)) || + (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/', $t)) || + (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/', $t))) { + $clb = $s['y'] + $s['h']; + if ((isset($this->ColDetails[$s['col']]['max_bottom']) && $clb > $this->ColDetails[$s['col']]['max_bottom']) || !isset($this->ColDetails[$s['col']]['max_bottom'])) { + $this->ColDetails[$s['col']]['max_bottom'] = $clb; + } + if ($clb > $lowest_bottom_y) { + $lowest_bottom_y = $clb; + } + $this->columnbuffer[$key]['rel_y'] = $s['y']; // Marks position sensitive data to process later + if ($t == 'ACROFORM') { + $this->columnbuffer[$key]['s'] = ''; + } + } + } + // Adjust column length equal + foreach ($this->columnbuffer as $key => $s) { + // Set ratio to expand y values or heights + if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) { + $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0)); + } else { + $ratio = 1; + } + if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) { + $yadj = ($s['y'] - $this->y0) * ($ratio - 1); + + // Adjust LINKS + if (isset($s['rel_y'])) { // only process position sensitive data + // otherwise triggers for all entries in column buffer (.e.g. formatting) and makes below adjustments more than once + if (isset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->PageLinks[$this->page][$ref][1] -= ($yadj * Mpdf::SCALE); // y value + $this->PageLinks[$this->page][$ref][3] *= $ratio; // height + unset($this->columnLinks[$s['col']][intval($s['x'])][intval($s['y'])]); + } + // Adjust FORM FIELDS + if (isset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->form->forms[$ref]['x'] += ($xadj); + $this->form->forms[$ref]['y'] += ($yadj); + unset($this->columnForms[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- ANNOTATIONS -- */ + if (isset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])])) { + $ref = $this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]; + $this->PageAnnots[$this->page][$ref]['y'] += ($yadj); + unset($this->columnAnnots[$s['col']][intval($s['x'])][intval($s['y'])]); + } + /* -- END ANNOTATIONS -- */ + } + } + } + + /* -- BOOKMARKS -- */ + + // Adjust Bookmarks + foreach ($this->col_BMoutlines as $v) { + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $this->y0, 'p' => $v['p']]; + } + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + + // Adjust ToC + foreach ($this->col_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + $this->links[$v['link']][1] = $this->y0; + } + /* -- END TOC -- */ + + $trans_on = false; + foreach ($this->columnbuffer as $key => $s) { + + if (isset($s['rel_y'])) { // only process position sensitive data + + // Set ratio to expand y values or heights + if (isset($this->ColDetails[$s['col']]['max_bottom']) && $this->ColDetails[$s['col']]['max_bottom']) { + $ratio = ($lowest_bottom_y - ($this->y0)) / ($this->ColDetails[$s['col']]['max_bottom'] - ($this->y0)); + } else { + $ratio = 1; + } + + if (($ratio > 1) && ($ratio <= $this->max_colH_correction)) { + // Start Transformation + $this->pages[$this->page] .= $this->StartTransform(true) . "\n"; + $this->pages[$this->page] .= $this->transformScale(100, $ratio * 100, $x = '', $this->y0, true) . "\n"; + $trans_on = true; + } + } + + // Now output the adjusted values + $this->pages[$this->page] .= $s['s'] . "\n"; + if (isset($s['rel_y']) && ($ratio > 1) && ($ratio <= $this->max_colH_correction)) { + // Stop Transformation + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + $trans_on = false; + } + } + + if ($trans_on) { + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + } + + if ($lowest_bottom_y > 0) { + $this->y = $lowest_bottom_y; + } + + } else { // Just reproduce the page as it was + + // If page has not ended but height adjustment was disabled by custom column-break - adjust y + $lowest_bottom_y = 0; + + if (!$this->ColActive && (!$this->ColumnAdjust || $this->keepColumns)) { + + // calculate the lowest bottom margin + foreach ($this->columnbuffer as $key => $s) { + + // Only process output data + $t = $s['s']; + if ($t === 'ACROFORM' + || (preg_match('/BT \d+\.\d\d+ (\d+\.\d\d+) Td/', $t)) + || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ [\-]{0,1}\d+\.\d\d+ re/', $t)) + || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) l/', $t)) + || (preg_match('/q \d+\.\d\d+ 0 0 \d+\.\d\d+ \d+\.\d\d+ (\d+\.\d\d+) cm \/(I|FO)\d+ Do Q/', $t)) + || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) m/', $t)) + || (preg_match('/\d+\.\d\d+ (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ c/', $t))) { + + $clb = $s['y'] + $s['h']; + + if (isset($this->ColDetails[$s['col']]['max_bottom']) && $clb > $this->ColDetails[$s['col']]['max_bottom'] || (!isset($this->ColDetails[$s['col']]['max_bottom']) && $clb)) { + $this->ColDetails[$s['col']]['max_bottom'] = $clb; + } + + if ($clb > $lowest_bottom_y) { + $lowest_bottom_y = $clb; + } + } + } + } + + foreach ($this->columnbuffer as $key => $s) { + if ($s['s'] != 'ACROFORM') { + $this->pages[$this->page] .= $s['s'] . "\n"; + } + } + + if ($lowest_bottom_y > 0) { + $this->y = $lowest_bottom_y; + } + + /* -- BOOKMARKS -- */ + // Output Bookmarks + foreach ($this->col_BMoutlines as $v) { + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']]; + } + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + // Output ToC + foreach ($this->col_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + } + /* -- END TOC -- */ + } + + foreach ($this->internallink as $key => $f) { + + if (isset($this->internallink[$key]['col'])) { + unset($this->internallink[$key]['col']); + } + + if (isset($this->internallink[$key]['rel_y'])) { + unset($this->internallink[$key]['rel_y']); + } + } + + $this->columnbuffer = []; + $this->ColDetails = []; + $this->columnLinks = []; + $this->columnAnnots = []; + $this->columnForms = []; + + $this->col_BMoutlines = []; + $this->col_toc = []; + $this->breakpoints = []; + } + + // mPDF 5.7+ + function columnAdjustPregReplace($type, $xadj, $yadj, $pattern, $subject) + { + preg_match($pattern, $subject, $matches); + + if (!count($matches)) { + return $subject; + } + + if (!isset($matches[3])) { + $matches[3] = 0; + } + + if (!isset($matches[4])) { + $matches[4] = 0; + } + + if (!isset($matches[5])) { + $matches[5] = 0; + } + + if (!isset($matches[6])) { + $matches[6] = 0; + } + + return str_replace($matches[0], $this->columnAdjustAdd($type, Mpdf::SCALE, $xadj, $yadj, $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]), $subject); + } + /* -- END COLUMNS -- */ + + // ================================================================== + /* -- TABLES -- */ + function printcellbuffer() + { + if (count($this->cellBorderBuffer)) { + + sort($this->cellBorderBuffer); + + foreach ($this->cellBorderBuffer as $cbb) { + + $cba = unpack("A16dom/nbord/A1side/ns/dbw/a6ca/A10style/dx/dy/dw/dh/dmbl/dmbr/dmrt/dmrb/dmtl/dmtr/dmlt/dmlb/dcpd/dover/", $cbb); + $side = $cba['side']; + $color = str_pad($cba['ca'], 6, "\x00"); + + $details = []; + + $details[$side]['dom'] = (float) $cba['dom']; + $details[$side]['s'] = $cba['s']; + $details[$side]['w'] = $cba['bw']; + $details[$side]['c'] = $color; + $details[$side]['style'] = trim($cba['style']); + + $details['mbw']['BL'] = $cba['mbl']; + $details['mbw']['BR'] = $cba['mbr']; + $details['mbw']['RT'] = $cba['mrt']; + $details['mbw']['RB'] = $cba['mrb']; + $details['mbw']['TL'] = $cba['mtl']; + $details['mbw']['TR'] = $cba['mtr']; + $details['mbw']['LT'] = $cba['mlt']; + $details['mbw']['LB'] = $cba['mlb']; + + $details['cellposdom'] = $cba['cpd']; + + $details['p'] = $side; + + if ($cba['over'] == 1) { + $details[$side]['overlay'] = true; + } else { + $details[$side]['overlay'] = false; + } + + $this->_tableRect($cba['x'], $cba['y'], $cba['w'], $cba['h'], $cba['bord'], $details, false, false); + } + + $this->cellBorderBuffer = []; + } + } + + // ================================================================== + function printtablebuffer() + { + + if (!$this->table_rotate) { + + $this->pages[$this->page] .= $this->tablebuffer; + + foreach ($this->tbrot_Links as $p => $l) { + foreach ($l as $v) { + $this->PageLinks[$p][] = $v; + } + } + $this->tbrot_Links = []; + + /* -- ANNOTATIONS -- */ + foreach ($this->tbrot_Annots as $p => $l) { + foreach ($l as $v) { + $this->PageAnnots[$p][] = $v; + } + } + $this->tbrot_Annots = []; + /* -- END ANNOTATIONS -- */ + + /* -- BOOKMARKS -- */ + // Output Bookmarks + foreach ($this->tbrot_BMoutlines as $v) { + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']]; + } + $this->tbrot_BMoutlines = []; + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + // Output ToC + foreach ($this->tbrot_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + } + $this->tbrot_toc = []; + /* -- END TOC -- */ + + return; + } + + // elseif rotated + $lm = $this->lMargin + $this->blk[$this->blklvl]['outer_left_margin'] + $this->blk[$this->blklvl]['border_left']['w'] + $this->blk[$this->blklvl]['padding_left']; + $pw = $this->blk[$this->blklvl]['inner_width']; + + // Start Transformation + $this->pages[$this->page] .= $this->StartTransform(true) . "\n"; + + if ($this->table_rotate > 1) { // clockwise + + if ($this->tbrot_align == 'L') { + $xadj = $this->tbrot_h; // align L (as is) + } elseif ($this->tbrot_align == 'R') { + $xadj = $lm - $this->tbrot_x0 + ($pw); // align R + } else { + $xadj = $lm - $this->tbrot_x0 + (($pw + $this->tbrot_h) / 2); // align C + } + + $yadj = 0; + + } else { // anti-clockwise + + if ($this->tbrot_align == 'L') { + $xadj = 0; // align L (as is) + } elseif ($this->tbrot_align == 'R') { + $xadj = $lm - $this->tbrot_x0 + ($pw - $this->tbrot_h); // align R + } else { + $xadj = $lm - $this->tbrot_x0 + (($pw - $this->tbrot_h) / 2); // align C + } + + $yadj = $this->tbrot_w; + } + + + $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj, true) . "\n"; + $this->pages[$this->page] .= $this->transformRotate($this->table_rotate, $this->tbrot_x0, $this->tbrot_y0, true) . "\n"; + + // Now output the adjusted values + $this->pages[$this->page] .= $this->tablebuffer; + + foreach ($this->tbrot_Links as $p => $l) { + + foreach ($l as $v) { + + $w = $v[2] / Mpdf::SCALE; + $h = $v[3] / Mpdf::SCALE; + $ax = ($v[0] / Mpdf::SCALE) - $this->tbrot_x0; + $ay = (($this->hPt - $v[1]) / Mpdf::SCALE) - $this->tbrot_y0; + + if ($this->table_rotate > 1) { // clockwise + $bx = $this->tbrot_x0 + $xadj - $ay - $h; + $by = $this->tbrot_y0 + $yadj + $ax; + } else { + $bx = $this->tbrot_x0 + $xadj + $ay; + $by = $this->tbrot_y0 + $yadj - $ax - $w; + } + + $v[0] = $bx * Mpdf::SCALE; + $v[1] = ($this->h - $by) * Mpdf::SCALE; + $v[2] = $h * Mpdf::SCALE; // swap width and height + $v[3] = $w * Mpdf::SCALE; + + $this->PageLinks[$p][] = $v; + } + } + + $this->tbrot_Links = []; + foreach ($this->internallink as $key => $f) { + if (is_array($f) && isset($f['tbrot'])) { + $f['Y'] = $this->tbrot_y0; + $f['PAGE'] = $this->page; + unset($f['tbrot']); + $this->internallink[$key] = $f; + } + } + + /* -- ANNOTATIONS -- */ + foreach ($this->tbrot_Annots as $p => $l) { + foreach ($l as $v) { + $ax = abs($v['x']) - $this->tbrot_x0; // abs because -ve values are internally set and held for reference if annotMargin set + $ay = $v['y'] - $this->tbrot_y0; + + if ($this->table_rotate > 1) { // clockwise + $bx = $this->tbrot_x0 + $xadj - $ay; + $by = $this->tbrot_y0 + $yadj + $ax; + } else { + $bx = $this->tbrot_x0 + $xadj + $ay; + $by = $this->tbrot_y0 + $yadj - $ax; + } + + if ($v['x'] < 0) { + $v['x'] = -$bx; + } else { + $v['x'] = $bx; + } + + $v['y'] = ($by); + $this->PageAnnots[$p][] = $v; + } + } + + $this->tbrot_Annots = []; + /* -- END ANNOTATIONS -- */ + + /* -- BOOKMARKS -- */ + // Adjust Bookmarks + foreach ($this->tbrot_BMoutlines as $v) { + $v['y'] = $this->tbrot_y0; + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page]; + } + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + // Adjust ToC - uses document page number + foreach ($this->tbrot_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page, 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + $this->links[$v['link']][1] = $this->tbrot_y0; + } + /* -- END TOC -- */ + + $this->tbrot_BMoutlines = []; + $this->tbrot_toc = []; + + // Stop Transformation + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + + $this->y = $this->tbrot_y0 + $this->tbrot_w; + $this->x = $this->lMargin; + + $this->tablebuffer = ''; + } + + /** + * Keep-with-table This buffers contents of h1-6 to keep on page with table + */ + function printkwtbuffer() + { + if (!$this->kwt_moved) { + + foreach ($this->kwt_buffer as $s) { + $this->pages[$this->page] .= $s['s'] . "\n"; + } + + foreach ($this->kwt_Links as $p => $l) { + foreach ($l as $v) { + $this->PageLinks[$p][] = $v; + } + } + + $this->kwt_Links = []; + + /* -- ANNOTATIONS -- */ + foreach ($this->kwt_Annots as $p => $l) { + foreach ($l as $v) { + $this->PageAnnots[$p][] = $v; + } + } + $this->kwt_Annots = []; + /* -- END ANNOTATIONS -- */ + + /* -- INDEX -- */ + // Output Reference (index) + foreach ($this->kwt_Reference as $v) { + + $Present = 0; + + for ($i = 0; $i < count($this->Reference); $i++) { + if ($this->Reference[$i]['t'] == $v['t']) { + $Present = 1; + if (!in_array($v['op'], $this->Reference[$i]['p'])) { + $this->Reference[$i]['p'][] = $v['op']; + } + } + } + + if ($Present == 0) { + $this->Reference[] = ['t' => $v['t'], 'p' => [$v['op']]]; + } + } + $this->kwt_Reference = []; + /* -- END INDEX -- */ + + /* -- BOOKMARKS -- */ + // Output Bookmarks + foreach ($this->kwt_BMoutlines as $v) { + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $v['p']]; + } + $this->kwt_BMoutlines = []; + /* -- END BOOKMARKS -- */ + + /* -- TOC -- */ + // Output ToC + foreach ($this->kwt_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $v['p'], 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + } + $this->kwt_toc = []; + /* -- END TOC -- */ + + $this->pageoutput[$this->page] = []; // mPDF 6 + + return; + } + + // Start Transformation + $this->pages[$this->page] .= $this->StartTransform(true) . "\n"; + $xadj = $this->lMargin - $this->kwt_x0; + // $yadj = $this->y - $this->kwt_y0 ; + $yadj = $this->tMargin - $this->kwt_y0; + + $this->pages[$this->page] .= $this->transformTranslate($xadj, $yadj, true) . "\n"; + + // Now output the adjusted values + foreach ($this->kwt_buffer as $s) { + $this->pages[$this->page] .= $s['s'] . "\n"; + } + + // Adjust hyperLinks + foreach ($this->kwt_Links as $p => $l) { + foreach ($l as $v) { + $bx = $this->kwt_x0 + $xadj; + $by = $this->kwt_y0 + $yadj; + $v[0] = $bx * Mpdf::SCALE; + $v[1] = ($this->h - $by) * Mpdf::SCALE; + $this->PageLinks[$p][] = $v; + } + } + + foreach ($this->internallink as $key => $f) { + if (is_array($f) && isset($f['kwt'])) { + $f['Y'] += $yadj; + $f['PAGE'] = $this->page; + unset($f['kwt']); + $this->internallink[$key] = $f; + } + } + + /* -- ANNOTATIONS -- */ + foreach ($this->kwt_Annots as $p => $l) { + foreach ($l as $v) { + $bx = $this->kwt_x0 + $xadj; + $by = $this->kwt_y0 + $yadj; + if ($v['x'] < 0) { + $v['x'] = -$bx; + } else { + $v['x'] = $bx; + } + $v['y'] = $by; + $this->PageAnnots[$p][] = $v; + } + } + /* -- END ANNOTATIONS -- */ + + /* -- BOOKMARKS -- */ + + // Adjust Bookmarks + foreach ($this->kwt_BMoutlines as $v) { + if ($v['y'] != 0) { + $v['y'] += $yadj; + } + $this->BMoutlines[] = ['t' => $v['t'], 'l' => $v['l'], 'y' => $v['y'], 'p' => $this->page]; + } + /* -- END BOOKMARKS -- */ + + /* -- INDEX -- */ + // Adjust Reference (index) + foreach ($this->kwt_Reference as $v) { + + $Present = 0; + + // Search the reference (AND Ref/PageNo) in the array + for ($i = 0; $i < count($this->Reference); $i++) { + if ($this->Reference[$i]['t'] == $v['t']) { + $Present = 1; + if (!in_array($this->page, $this->Reference[$i]['p'])) { + $this->Reference[$i]['p'][] = $this->page; + } + } + } + + if ($Present == 0) { + $this->Reference[] = ['t' => $v['t'], 'p' => [$this->page]]; + } + } + /* -- END INDEX -- */ + + /* -- TOC -- */ + + // Adjust ToC + foreach ($this->kwt_toc as $v) { + $this->tableOfContents->_toc[] = ['t' => $v['t'], 'l' => $v['l'], 'p' => $this->page, 'link' => $v['link'], 'toc_id' => $v['toc_id']]; + $this->links[$v['link']][0] = $this->page; + $this->links[$v['link']][1] += $yadj; + } + /* -- END TOC -- */ + + + $this->kwt_Links = []; + $this->kwt_Annots = []; + + $this->kwt_Reference = []; + $this->kwt_BMoutlines = []; + $this->kwt_toc = []; + + // Stop Transformation + $this->pages[$this->page] .= $this->StopTransform(true) . "\n"; + + $this->kwt_buffer = []; + + $this->y += $this->kwt_height; + $this->pageoutput[$this->page] = []; // mPDF 6 + } + /* -- END TABLES -- */ + + function printfloatbuffer() + { + if (count($this->floatbuffer)) { + $this->objectbuffer = $this->floatbuffer; + $this->printobjectbuffer(false); + $this->objectbuffer = []; + $this->floatbuffer = []; + $this->floatmargins = []; + } + } + + function Circle($x, $y, $r, $style = 'S') + { + $this->Ellipse($x, $y, $r, $r, $style); + } + + function Ellipse($x, $y, $rx, $ry, $style = 'S') + { + if ($style === 'F') { + $op = 'f'; + } elseif ($style === 'FD' or $style === 'DF') { + $op = 'B'; + } else { + $op = 'S'; + } + + $lx = 4 / 3 * (M_SQRT2 - 1) * $rx; + $ly = 4 / 3 * (M_SQRT2 - 1) * $ry; + + $h = $this->h; + + $this->writer->write(sprintf('%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c', ($x + $rx) * Mpdf::SCALE, ($h - $y) * Mpdf::SCALE, ($x + $rx) * Mpdf::SCALE, ($h - ($y - $ly)) * Mpdf::SCALE, ($x + $lx) * Mpdf::SCALE, ($h - ($y - $ry)) * Mpdf::SCALE, $x * Mpdf::SCALE, ($h - ($y - $ry)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x - $lx) * Mpdf::SCALE, ($h - ($y - $ry)) * Mpdf::SCALE, ($x - $rx) * Mpdf::SCALE, ($h - ($y - $ly)) * Mpdf::SCALE, ($x - $rx) * Mpdf::SCALE, ($h - $y) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c', ($x - $rx) * Mpdf::SCALE, ($h - ($y + $ly)) * Mpdf::SCALE, ($x - $lx) * Mpdf::SCALE, ($h - ($y + $ry)) * Mpdf::SCALE, $x * Mpdf::SCALE, ($h - ($y + $ry)) * Mpdf::SCALE)); + $this->writer->write(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F c %s', ($x + $lx) * Mpdf::SCALE, ($h - ($y + $ry)) * Mpdf::SCALE, ($x + $rx) * Mpdf::SCALE, ($h - ($y + $ly)) * Mpdf::SCALE, ($x + $rx) * Mpdf::SCALE, ($h - $y) * Mpdf::SCALE, $op)); + } + + /* -- DIRECTW -- */ + function AutosizeText($text, $w, $font, $style, $szfont = 72) + { + + $text = ' ' . $text . ' '; + + $this->SetFont($font, $style, $szfont, false); + + $text = $this->purify_utf8_text($text); + if ($this->text_input_as_HTML) { + $text = $this->all_entities_to_utf8($text); + } + if ($this->usingCoreFont) { + $text = mb_convert_encoding($text, $this->mb_enc, 'UTF-8'); + } + + // DIRECTIONALITY + if (preg_match("/([" . $this->pregRTLchars . "])/u", $text)) { + $this->biDirectional = true; + } + + $textvar = 0; + $save_OTLtags = $this->OTLtags; + $this->OTLtags = []; + + if ($this->useKerning) { + if ($this->CurrentFont['haskernGPOS']) { + $this->OTLtags['Plus'] .= ' kern'; + } else { + $textvar = ($textvar | TextVars::FC_KERNING); + } + } + + /* -- OTL -- */ + // Use OTL OpenType Table Layout - GSUB & GPOS + if (isset($this->CurrentFont['useOTL']) && $this->CurrentFont['useOTL']) { + $text = $this->otl->applyOTL($text, $this->CurrentFont['useOTL']); + $OTLdata = $this->otl->OTLdata; + } + /* -- END OTL -- */ + + $this->OTLtags = $save_OTLtags; + + $this->magic_reverse_dir($text, $this->directionality, $OTLdata); + + $width = $this->sizeConverter->convert($w); + $loop = 0; + + while ($loop == 0) { + + $this->SetFont($font, $style, $szfont, false); + $sz = $this->GetStringWidth($text, true, $OTLdata, $textvar); + + if ($sz > $w) { + $szfont --; + } else { + $loop ++; + } + } + + $this->SetFont($font, $style, $szfont, true, true); + $this->Cell($w, 0, $text, 0, 0, "C", 0, '', 0, 0, 0, 'M', 0, false, $OTLdata, $textvar); + } + /* -- END DIRECTW -- */ + + // ==================================================== + // ==================================================== + + function magic_reverse_dir(&$chunk, $dir, &$chunkOTLdata) + { + /* -- OTL -- */ + if ($this->usingCoreFont) { + return 0; + } + + if ($chunk == '') { + return 0; + } + + if ($this->biDirectional || $dir == 'rtl') { + + // check if string contains RTL text + // including any added from OTL tables (in PUA) + $pregRTLchars = $this->pregRTLchars; + + if (isset($this->CurrentFont['rtlPUAstr']) && $this->CurrentFont['rtlPUAstr']) { + $pregRTLchars .= $this->CurrentFont['rtlPUAstr']; + } + + if (!preg_match("/[" . $pregRTLchars . "]/u", $chunk) && $dir != 'rtl') { + return 0; + } // Chunk doesn't contain RTL characters + + $unicode = $this->UTF8StringToArray($chunk, false); + + $isStrong = false; + if (empty($chunkOTLdata)) { + $this->getBasicOTLdata($chunkOTLdata, $unicode, $isStrong); + } + + $useGPOS = isset($this->CurrentFont['useOTL']) && ($this->CurrentFont['useOTL'] & 0x80); + + // NB Returned $chunk may be a shorter string (with adjusted $cOTLdata) by removal of LRE, RLE etc embedding codes. + list($chunk, $rtl_content) = $this->otl->bidiSort($unicode, $chunk, $dir, $chunkOTLdata, $useGPOS); + + return $rtl_content; + } + + /* -- END OTL -- */ + return 0; + } + + /* -- OTL -- */ + + function getBasicOTLdata(&$chunkOTLdata, $unicode, &$is_strong) + { + if (empty($this->otl)) { + $this->otl = new Otl($this, $this->fontCache); + } + + $chunkOTLdata['group'] = ''; + $chunkOTLdata['GPOSinfo'] = []; + $chunkOTLdata['char_data'] = []; + + foreach ($unicode as $char) { + + $ucd_record = Ucdn::get_ucd_record($char); + $chunkOTLdata['char_data'][] = ['bidi_class' => $ucd_record[2], 'uni' => $char]; + + if ($ucd_record[2] == 0 || $ucd_record[2] == 3 || $ucd_record[2] == 4) { + $is_strong = true; + } // contains strong character + + if ($ucd_record[0] == Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { + $chunkOTLdata['group'] .= 'M'; + } elseif ($char == 32 || $char == 12288) { + $chunkOTLdata['group'] .= 'S'; + } else { + $chunkOTLdata['group'] .= 'C'; + } + } + } + + function _setBidiCodes($mode = 'start', $bdf = '') + { + $s = ''; + + if ($mode == 'end') { + + // PDF comes before PDI to close isolate-override (e.g. "LRILROPDFPDI") + if (strpos($bdf, 'PDF') !== false) { + $s .= UtfString::code2utf(0x202C); + } // POP DIRECTIONAL FORMATTING + + if (strpos($bdf, 'PDI') !== false) { + $s .= UtfString::code2utf(0x2069); + } // POP DIRECTIONAL ISOLATE + + } elseif ($mode == 'start') { + + // LRI comes before LRO to open isolate-override (e.g. "LRILROPDFPDI") + if (strpos($bdf, 'LRI') !== false) { // U+2066 LRI + $s .= UtfString::code2utf(0x2066); + } elseif (strpos($bdf, 'RLI') !== false) { // U+2067 RLI + $s .= UtfString::code2utf(0x2067); + } elseif (strpos($bdf, 'FSI') !== false) { // U+2068 FSI + $s .= UtfString::code2utf(0x2068); + } + + if (strpos($bdf, 'LRO') !== false) { // U+202D LRO + $s .= UtfString::code2utf(0x202D); + } elseif (strpos($bdf, 'RLO') !== false) { // U+202E RLO + $s .= UtfString::code2utf(0x202E); + } elseif (strpos($bdf, 'LRE') !== false) { // U+202A LRE + $s .= UtfString::code2utf(0x202A); + } elseif (strpos($bdf, 'RLE') !== false) { // U+202B RLE + $s .= UtfString::code2utf(0x202B); + } + } + + return $s; + } + /* -- END OTL -- */ + + function SetSubstitutions() + { + $subsarray = []; + require __DIR__ . '/../data/subs_win-1252.php'; + $this->substitute = []; + foreach ($subsarray as $key => $val) { + $this->substitute[UtfString::code2utf($key)] = $val; + } + } + + function SubstituteChars($html) + { + // only substitute characters between tags + if (count($this->substitute)) { + $a = preg_split('/(<.*?>)/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE); + $html = ''; + foreach ($a as $i => $e) { + if ($i % 2 == 0) { + $e = strtr($e, $this->substitute); + } + $html .= $e; + } + } + + return $html; + } + + function SubstituteCharsSIP(&$writehtml_a, &$writehtml_i, &$writehtml_e) + { + if (preg_match("/^(.*?)([\x{20000}-\x{2FFFF}]+)(.*)/u", $writehtml_e, $m)) { + if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) { + $font = $this->CurrentFont['sipext']; + if (!in_array($font, $this->available_unifonts)) { + return 0; + } + $writehtml_a[$writehtml_i] = $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]); + $this->subPos = $writehtml_i; + return 4; + } + } + + return 0; + } + + /** + * If core font is selected in document which is not onlyCoreFonts - substitute with non-core font + */ + function SubstituteCharsNonCore(&$writehtml_a, &$writehtml_i, &$writehtml_e) + { + // Ignore if in Textarea + if ($writehtml_i > 0 && strtolower(substr($writehtml_a[$writehtml_i - 1], 0, 8)) == 'textarea') { + return 0; + } + + if (mb_convert_encoding(mb_convert_encoding($writehtml_e, $this->mb_enc, "UTF-8"), "UTF-8", $this->mb_enc) == $writehtml_e) { + return 0; + } + + $cw = &$this->CurrentFont['cw']; + $unicode = $this->UTF8StringToArray($writehtml_e, false); + $start = -1; + $end = 0; + $flag = 0; + $ftype = ''; + $u = []; + + if (!$this->subArrMB) { + + require __DIR__ . '/../data/subs_core.php'; + + $this->subArrMB['a'] = $aarr; + $this->subArrMB['s'] = $sarr; + $this->subArrMB['z'] = $zarr; + } + + foreach ($unicode as $c => $char) { + + if (($char > 127 || ($flag == 1 && $char == 32)) && $char != 173 && (!isset($this->subArrMB['a'][$char]) || ($flag == 1 && $char == 32)) && ($char < 1536 || ($char > 1791 && $char < 2304) || $char > 3455)) { + if ($flag == 0) { + $start = $c; + } + $flag = 1; + $u[] = $char; + } elseif ($flag > 0) { + $end = $c - 1; + break; + } + } + + if ($flag > 0 && !$end) { + $end = count($unicode) - 1; + } + + if ($start == -1) { + return 0; + } + + // Try in backup subs font + if (!is_array($this->backupSubsFont)) { + $this->backupSubsFont = ["$this->backupSubsFont"]; + } + + foreach ($this->backupSubsFont as $bsfctr => $bsf) { + + if ($this->fonttrans[$bsf] == 'chelvetica' || $this->fonttrans[$bsf] == 'ctimes' || $this->fonttrans[$bsf] == 'ccourier') { + continue; + } + + $font = $bsf; + unset($cw); + $cw = ''; + + if (isset($this->fonts[$font])) { + $cw = &$this->fonts[$font]['cw']; + } elseif ($this->fontCache->has($font . '.cw.dat')) { + $cw = $this->fontCache->load($font . '.cw.dat'); + } else { + $prevFontFamily = $this->FontFamily; + $prevFontStyle = $this->currentfontstyle; + $prevFontSizePt = $this->FontSizePt; + $this->SetFont($bsf, '', '', false); + $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false); + } + + if (!$cw) { + continue; + } + + $l = 0; + foreach ($u as $char) { + if ($char == 173 || $this->_charDefined($cw, $char) || ($char > 1536 && $char < 1791) || ($char > 2304 && $char < 3455 )) { + $l++; + } else { + if ($l == 0 && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font + $cont = mb_substr($writehtml_e, $start + 1); + $writehtml_e = mb_substr($writehtml_e, 0, $start + 1, 'UTF-8'); + array_splice($writehtml_a, $writehtml_i + 1, 0, ['', $cont]); + $this->subPos = $writehtml_i + 1; + + return 2; + } else { + break; + } + } + } + + if ($l > 0) { + $patt = mb_substr($writehtml_e, $start, $l, 'UTF-8'); + if (preg_match("/(.*?)(" . preg_quote($patt, '/') . ")(.*)/u", $writehtml_e, $m)) { + $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]); + $this->subPos = $writehtml_i + 3; + + return 4; + } + } + } + + unset($cw); + + return 0; + } + + function SubstituteCharsMB(&$writehtml_a, &$writehtml_i, &$writehtml_e) + { + // Ignore if in Textarea + if ($writehtml_i > 0 && strtolower(substr($writehtml_a[$writehtml_i - 1], 0, 8)) == 'textarea') { + return 0; + } + + $cw = &$this->CurrentFont['cw']; + $unicode = $this->UTF8StringToArray($writehtml_e, false); + $start = -1; + $end = 0; + $flag = 0; + $ftype = ''; + $u = []; + + foreach ($unicode as $c => $char) { + + if (($flag == 0 || $flag == 2) && (!$this->_charDefined($cw, $char) || ($flag == 2 && $char == 32)) && $this->checkSIP && $char > 131071) { // Unicode Plane 2 (SIP) + + if (in_array($this->FontFamily, $this->available_CJK_fonts)) { + return 0; + } + + if ($flag == 0) { + $start = $c; + } + + $flag = 2; + $u[] = $char; + + // elseif (($flag == 0 || $flag==1) && $char != 173 && !$this->_charDefined($cw,$char) && ($char<1423 || ($char>3583 && $char < 11263))) { + + } elseif (($flag == 0 || $flag == 1) && $char != 173 && (!$this->_charDefined($cw, $char) || ($flag == 1 && $char == 32)) && ($char < 1536 || ($char > 1791 && $char < 2304) || $char > 3455)) { + + if ($flag == 0) { + $start = $c; + } + + $flag = 1; + $u[] = $char; + + } elseif ($flag > 0) { + + $end = $c - 1; + break; + + } + } + + if ($flag > 0 && !$end) { + $end = count($unicode) - 1; + } + + if ($start == -1) { + return 0; + } + + if ($flag == 2) { // SIP + + // Check if current CJK font has a ext-B related font + if (isset($this->CurrentFont['sipext']) && $this->CurrentFont['sipext']) { + $font = $this->CurrentFont['sipext']; + unset($cw); + $cw = ''; + + if (isset($this->fonts[$font])) { + $cw = &$this->fonts[$font]['cw']; + } elseif ($this->fontCache->has($font . '.cw.dat')) { + $cw = $this->fontCache->load($font . '.cw.dat'); + } else { + $prevFontFamily = $this->FontFamily; + $prevFontStyle = $this->currentfontstyle; + $prevFontSizePt = $this->FontSizePt; + $this->SetFont($font, '', '', false); + $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false); + } + + if (!$cw) { + return 0; + } + + $l = 0; + foreach ($u as $char) { + if ($this->_charDefined($cw, $char) || $char > 131071) { + $l++; + } else { + break; + } + } + + if ($l > 0) { + $patt = mb_substr($writehtml_e, $start, $l); + if (preg_match("/(.*?)(" . preg_quote($patt, '/') . ")(.*)/u", $writehtml_e, $m)) { + $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]); + $this->subPos = $writehtml_i + 3; + return 4; + } + } + } + + // Check Backup SIP font (defined in Config\FontVariables) + if (isset($this->backupSIPFont) && $this->backupSIPFont) { + + if ($this->currentfontfamily != $this->backupSIPFont) { + $font = $this->backupSIPFont; + } else { + unset($cw); + return 0; + } + + unset($cw); + $cw = ''; + + if (isset($this->fonts[$font])) { + $cw = &$this->fonts[$font]['cw']; + } elseif ($this->fontCache->has($font . '.cw.dat')) { + $cw = $this->fontCache->load($font . '.cw.dat'); + } else { + $prevFontFamily = $this->FontFamily; + $prevFontStyle = $this->currentfontstyle; + $prevFontSizePt = $this->FontSizePt; + $this->SetFont($this->backupSIPFont, '', '', false); + $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false); + } + + if (!$cw) { + return 0; + } + + $l = 0; + foreach ($u as $char) { + if ($this->_charDefined($cw, $char) || $char > 131071) { + $l++; + } else { + break; + } + } + + if ($l > 0) { + $patt = mb_substr($writehtml_e, $start, $l); + if (preg_match("/(.*?)(" . preg_quote($patt, '/') . ")(.*)/u", $writehtml_e, $m)) { + $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]); + $this->subPos = $writehtml_i + 3; + return 4; + } + } + } + + return 0; + } + + // FIRST TRY CORE FONTS (when appropriate) + if (!$this->PDFA && !$this->PDFX && !$this->biDirectional) { // mPDF 6 + $repl = []; + if (!$this->subArrMB) { + require __DIR__ . '/../data/subs_core.php'; + $this->subArrMB['a'] = $aarr; + $this->subArrMB['s'] = $sarr; + $this->subArrMB['z'] = $zarr; + } + if (isset($this->subArrMB['a'][$u[0]])) { + $font = 'tta'; + $ftype = 'C'; + foreach ($u as $char) { + if (isset($this->subArrMB['a'][$char])) { + $repl[] = $this->subArrMB['a'][$char]; + } else { + break; + } + } + } elseif (isset($this->subArrMB['z'][$u[0]])) { + $font = 'ttz'; + $ftype = 'C'; + foreach ($u as $char) { + if (isset($this->subArrMB['z'][$char])) { + $repl[] = $this->subArrMB['z'][$char]; + } else { + break; + } + } + } elseif (isset($this->subArrMB['s'][$u[0]])) { + $font = 'tts'; + $ftype = 'C'; + foreach ($u as $char) { + if (isset($this->subArrMB['s'][$char])) { + $repl[] = $this->subArrMB['s'][$char]; + } else { + break; + } + } + } + if ($ftype == 'C') { + $patt = mb_substr($writehtml_e, $start, count($repl)); + if (preg_match("/(.*?)(" . preg_quote($patt, '/') . ")(.*)/u", $writehtml_e, $m)) { + $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, [$font, implode('|', $repl), '/' . $font, $m[3]]); // e.g. <tts> + $this->subPos = $writehtml_i + 3; + return 4; + } + return 0; + } + } + + // LASTLY TRY IN BACKUP SUBS FONT + if (!is_array($this->backupSubsFont)) { + $this->backupSubsFont = ["$this->backupSubsFont"]; + } + + foreach ($this->backupSubsFont as $bsfctr => $bsf) { + if ($this->currentfontfamily != $bsf) { + $font = $bsf; + } else { + continue; + } + + unset($cw); + $cw = ''; + + if (isset($this->fonts[$font])) { + $cw = &$this->fonts[$font]['cw']; + } elseif ($this->fontCache->has($font . '.cw.dat')) { + $cw = $this->fontCache->load($font . '.cw.dat'); + } else { + $prevFontFamily = $this->FontFamily; + $prevFontStyle = $this->currentfontstyle; + $prevFontSizePt = $this->FontSizePt; + $this->SetFont($bsf, '', '', false); + $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt, false); + if ($this->fontCache->has($font . '.cw.dat')) { + $cw = $this->fontCache->load($font . '.cw.dat'); + } + } + + if (!$cw) { + continue; + } + + $l = 0; + foreach ($u as $char) { + if ($char == 173 || $this->_charDefined($cw, $char) || ($char > 1536 && $char < 1791) || ($char > 2304 && $char < 3455 )) { // Arabic and Indic + $l++; + } else { + if ($l == 0 && $bsfctr == (count($this->backupSubsFont) - 1)) { // Not found even in last backup font + $cont = mb_substr($writehtml_e, $start + 1); + $writehtml_e = mb_substr($writehtml_e, 0, $start + 1); + array_splice($writehtml_a, $writehtml_i + 1, 0, ['', $cont]); + $this->subPos = $writehtml_i + 1; + return 2; + } else { + break; + } + } + } + + if ($l > 0) { + $patt = mb_substr($writehtml_e, $start, $l); + if (preg_match("/(.*?)(" . preg_quote($patt, '/') . ")(.*)/u", $writehtml_e, $m)) { + $writehtml_e = $m[1]; + array_splice($writehtml_a, $writehtml_i + 1, 0, ['span style="font-family: ' . $font . '"', $m[2], '/span', $m[3]]); + $this->subPos = $writehtml_i + 3; + return 4; + } + } + } + + unset($cw); + + return 0; + } + + function setHiEntitySubstitutions() + { + $entarr = include __DIR__ . '/../data/entity_substitutions.php'; + + foreach ($entarr as $key => $val) { + $this->entsearch[] = '&' . $key . ';'; + $this->entsubstitute[] = UtfString::code2utf($val); + } + } + + function SubstituteHiEntities($html) + { + // converts html_entities > ASCII 127 to unicode + // Leaves in particular < to distinguish from tag marker + if (count($this->entsearch)) { + $html = str_replace($this->entsearch, $this->entsubstitute, $html); + } + + return $html; + } + + /** + * Edited v1.2 Pass by reference; option to continue if invalid UTF-8 chars + */ + function is_utf8(&$string) + { + if ($string === mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")) { + return true; + } + + if ($this->ignore_invalid_utf8) { + $string = mb_convert_encoding(mb_convert_encoding($string, "UTF-32", "UTF-8"), "UTF-8", "UTF-32"); + return true; + } + + return false; + } + + /** + * For HTML + * + * Checks string is valid UTF-8 encoded + * converts html_entities > ASCII 127 to UTF-8 + * Only exception - leaves low ASCII entities e.g. < & etc. + * Leaves in particular < to distinguish from tag marker + */ + function purify_utf8($html, $lo = true) + { + if (!$this->is_utf8($html)) { + + while (mb_convert_encoding(mb_convert_encoding($html, "UTF-32", "UTF-8"), "UTF-8", "UTF-32") != $html) { + + $a = @iconv('UTF-8', 'UTF-8', $html); + $error = error_get_last(); + if ($error && $error['message'] === 'iconv(): Detected an illegal character in input string') { + throw new \Mpdf\MpdfException('Invalid input characters. Did you set $mpdf->in_charset properly?'); + } + + $pos = $start = strlen($a); + $err = ''; + while (ord(substr($html, $pos, 1)) > 128) { + $err .= '[[#' . ord(substr($html, $pos, 1)) . ']]'; + $pos++; + } + + $this->logger->error($err, ['context' => LogContext::UTF8]); + $html = substr($html, $pos); + } + + throw new \Mpdf\MpdfException("HTML contains invalid UTF-8 character(s). See log for further details"); + } + + $html = preg_replace("/\r/", "", $html); + + // converts html_entities > ASCII 127 to UTF-8 + // Leaves in particular < to distinguish from tag marker + $html = $this->SubstituteHiEntities($html); + + // converts all &#nnn; or &#xHHH; to UTF-8 multibyte + // If $lo==true then includes ASCII < 128 + $html = UtfString::strcode2utf($html, $lo); + + return $html; + } + + /** + * For TEXT + */ + function purify_utf8_text($txt) + { + // Make sure UTF-8 string of characters + if (!$this->is_utf8($txt)) { + throw new \Mpdf\MpdfException("Text contains invalid UTF-8 character(s)"); + } + + $txt = preg_replace("/\r/", "", $txt); + + return ($txt); + } + + function all_entities_to_utf8($txt) + { + // converts txt_entities > ASCII 127 to UTF-8 + // Leaves in particular < to distinguish from tag marker + $txt = $this->SubstituteHiEntities($txt); + + // converts all &#nnn; or &#xHHH; to UTF-8 multibyte + $txt = UtfString::strcode2utf($txt); + + $txt = $this->lesser_entity_decode($txt); + return ($txt); + } + + /* -- BARCODES -- */ + /** + * UPC/EAN barcode + * + * EAN13, EAN8, UPCA, UPCE, ISBN, ISSN + * Accepts 12 or 13 digits with or without - hyphens + */ + function WriteBarcode($code, $showtext = 1, $x = '', $y = '', $size = 1, $border = 0, $paddingL = 1, $paddingR = 1, $paddingT = 2, $paddingB = 2, $height = 1, $bgcol = false, $col = false, $btype = 'ISBN', $supplement = '0', $supplement_code = '', $k = 1) + { + if (empty($code)) { + return; + } + + $codestr = $code; + $code = preg_replace('/\-/', '', $code); + + $this->barcode = new Barcode(); + if ($btype == 'ISSN' || $btype == 'ISBN') { + $arrcode = $this->barcode->getBarcodeArray($code, 'EAN13'); + } else { + $arrcode = $this->barcode->getBarcodeArray($code, $btype); + } + + if ($arrcode === false) { + throw new \Mpdf\MpdfException('Error in barcode string: ' . $codestr); + } + + if ((($btype === 'EAN13' || $btype === 'ISBN' || $btype === 'ISSN') && strlen($code) === 12) + || ($btype == 'UPCA' && strlen($code) === 11) + || ($btype == 'UPCE' && strlen($code) === 11) + || ($btype == 'EAN8' && strlen($code) === 7)) { + + $code .= $arrcode['checkdigit']; + + if (stristr($codestr, '-')) { + $codestr .= '-' . $arrcode['checkdigit']; + } else { + $codestr .= $arrcode['checkdigit']; + } + } + + if ($btype === 'ISBN') { + $codestr = 'ISBN ' . $codestr; + } + + if ($btype === 'ISSN') { + $codestr = 'ISSN ' . $codestr; + } + + if (empty($x)) { + $x = $this->x; + } + + if (empty($y)) { + $y = $this->y; + } + + // set foreground color + $prevDrawColor = $this->DrawColor; + $prevTextColor = $this->TextColor; + $prevFillColor = $this->FillColor; + + $lw = $this->LineWidth; + $this->SetLineWidth(0.01); + + $size /= $k; // in case resized in a table + + $xres = $arrcode['nom-X'] * $size; + $llm = $arrcode['lightmL'] * $arrcode['nom-X'] * $size; // Left Light margin + $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin + + $bcw = ($arrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size + + $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins + $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding + + $fbwi = $fbw - 2; // Full barcode width incl. light margins - 2mm - for isbn string + // cf. http://www.gs1uk.org/downloads/bar_code/Bar coding getting it right.pdf + $num_height = 3 * $size; // Height of numerals + $fbh = $arrcode['nom-H'] * $size * $height; // Full barcode height incl. numerals + $bch = $fbh - (1.5 * $size); // Barcode height of bars (3mm for numerals) + + if (($btype == 'EAN13' && $showtext) || $btype == 'ISSN' || $btype == 'ISBN') { // Add height for ISBN string + margin from top of bars + $tisbnm = 1.5 * $size; // Top margin between isbn (if shown) & bars + $codestr_fontsize = 2.1 * $size; + $paddingT += $codestr_fontsize + $tisbnm; + } + + $oh = $fbh + $paddingT + $paddingB; // Full overall height incl. user-defined padding + + // PRINT border background color + $xpos = $x; + $ypos = $y; + + if ($col) { + $this->SetDColor($col); + $this->SetTColor($col); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + + if ($bgcol) { + $this->SetFColor($bgcol); + } else { + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + } + + if (!$bgcol && !$col) { // fn. called directly - not via HTML + + if ($border) { + $fillb = 'DF'; + } else { + $fillb = 'F'; + } + + $this->Rect($xpos, $ypos, $ow, $oh, $fillb); + } + + + // PRINT BARS + $xpos = $x + $paddingL + $llm; + $ypos = $y + $paddingT; + + if ($col) { + $this->SetFColor($col); + } else { + $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + + if ($arrcode !== false) { + foreach ($arrcode["bcode"] as $v) { + $bw = ($v["w"] * $xres); + if ($v["t"]) { + // draw a vertical bar + $this->Rect($xpos, $ypos, $bw, $bch, 'F'); + } + $xpos += $bw; + } + } + + // print text + $prevFontFamily = $this->FontFamily; + $prevFontStyle = $this->FontStyle; + $prevFontSizePt = $this->FontSizePt; + + // ISBN string + if (($btype === 'EAN13' && $showtext) || $btype === 'ISBN' || $btype === 'ISSN') { + + if ($this->onlyCoreFonts) { + $this->SetFont('chelvetica'); + } else { + $this->SetFont('sans'); + } + + if ($bgcol) { + $this->SetFColor($bgcol); + } else { + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + } + + $this->x = $x + $paddingL + 1; // 1mm left margin (cf. $fbwi above) + + // max width is $fbwi + $loop = 0; + while ($loop == 0) { + $this->SetFontSize($codestr_fontsize * 1.4 * Mpdf::SCALE, false); // don't write + $sz = $this->GetStringWidth($codestr); + + if ($sz > $fbwi) { + $codestr_fontsize -= 0.1; + } else { + $loop ++; + } + } + + $this->SetFont('', '', $codestr_fontsize * 1.4 * Mpdf::SCALE, true, true); // * 1.4 because font height is only 7/10 of given mm + // WORD SPACING + if ($fbwi > $sz) { + $xtra = $fbwi - $sz; + $charspacing = $xtra / (strlen($codestr) - 1); + if ($charspacing) { + $this->writer->write(sprintf('BT %.3F Tc ET', $charspacing * Mpdf::SCALE)); + } + } + + $this->y = $y + $paddingT - ($codestr_fontsize ) - $tisbnm; + $this->Cell($fbw, $codestr_fontsize, $codestr); + + if ($charspacing) { + $this->writer->write('BT 0 Tc ET'); + } + } + + + // Bottom NUMERALS + // mPDF 5.7.4 + if ($this->onlyCoreFonts) { + $this->SetFont('ccourier'); + $fh = 1.3; + } else { + $this->SetFont('ocrb'); + $fh = 1.06; + } + + $charRO = ''; + + if ($btype === 'EAN13' || $btype === 'ISBN' || $btype === 'ISSN') { + + $outerfontsize = 3; // Inner fontsize = 3 + $outerp = $xres * 4; + $innerp = $xres * 2.5; + $textw = ($bcw * 0.5) - $outerp - $innerp; + $chars = 6; // number of numerals in each half + $charLO = substr($code, 0, 1); // Left Outer + $charLI = substr($code, 1, 6); // Left Inner + $charRI = substr($code, 7, 6); // Right Inner + + if (!$supplement) { + $charRO = '>'; // Right Outer + } + + } elseif ($btype === 'UPCA') { + + $outerfontsize = 2.3; // Inner fontsize = 3 + $outerp = $xres * 10; + $innerp = $xres * 2.5; + $textw = ($bcw * 0.5) - $outerp - $innerp; + $chars = 5; + $charLO = substr($code, 0, 1); // Left Outer + $charLI = substr($code, 1, 5); // Left Inner + $charRI = substr($code, 6, 5); // Right Inner + $charRO = substr($code, 11, 1); // Right Outer + + } elseif ($btype === 'UPCE') { + + $outerfontsize = 2.3; // Inner fontsize = 3 + $outerp = $xres * 4; + $innerp = 0; + $textw = ($bcw * 0.5) - $outerp - $innerp; + $chars = 3; + $upce_code = $arrcode['code']; + $charLO = substr($code, 0, 1); // Left Outer + $charLI = substr($upce_code, 0, 3); // Left Inner + $charRI = substr($upce_code, 3, 3); // Right Inner + $charRO = substr($code, 11, 1); // Right Outer + + } elseif ($btype === 'EAN8') { + + $outerfontsize = 3; // Inner fontsize = 3 + $outerp = $xres * 4; + $innerp = $xres * 2.5; + $textw = ($bcw * 0.5) - $outerp - $innerp; + $chars = 4; + $charLO = '<'; // Left Outer + $charLI = substr($code, 0, 4); // Left Inner + $charRI = substr($code, 4, 4); // Right Inner + + if (!$supplement) { + $charRO = '>'; // Right Outer + } + } + + $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters) + + if (!$this->usingCoreFont) { // character width at 3mm + $cw = $this->_getCharWidth($this->CurrentFont['cw'], 32) * 3 * $fh * $size / 1000; + } else { + $cw = 600 * 3 * $fh * $size / 1000; + } + + // Outer left character + $y_text = $y + $paddingT + $bch - ($num_height / 2); + $y_text_outer = $y + $paddingT + $bch - ($num_height * ($outerfontsize / 3) / 2); + + $this->x = $x + $paddingL - ($cw * ($outerfontsize / 3) * 0.1); // 0.1 is correction as char does not fill full width; + $this->y = $y_text_outer; + $this->Cell($cw, $num_height, $charLO); + + // WORD SPACING for inner chars + $xtra = $textw - ($cw * $chars); + $charspacing = $xtra / ($chars - 1); + if ($charspacing) { + $this->writer->write(sprintf('BT %.3F Tc ET', $charspacing * Mpdf::SCALE)); + } + + if ($bgcol) { + $this->SetFColor($bgcol); + } else { + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + } + + $this->SetFontSize(3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters) + + // Inner left half characters + $this->x = $x + $paddingL + $llm + $outerp; + $this->y = $y_text; + $this->Cell($textw, $num_height, $charLI, 0, 0, '', 1); + + // Inner right half characters + $this->x = $x + $paddingL + $llm + ($bcw * 0.5) + $innerp; + $this->y = $y_text; + $this->Cell($textw, $num_height, $charRI, 0, 0, '', 1); + + if ($charspacing) { + $this->writer->write('BT 0 Tc ET'); + } + + // Outer Right character + $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters) + + $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw * ($outerfontsize / 3) * 0.9); // 0.9 is correction as char does not fill full width + $this->y = $y_text_outer; + $this->Cell($cw * ($outerfontsize / 3), $num_height, $charRO, 0, 0, 'R'); + + if ($supplement) { // EAN-2 or -5 Supplement + // PRINT BARS + $supparrcode = $this->barcode->getBarcodeArray($supplement_code, 'EAN' . $supplement); + + if ($supparrcode === false) { + throw new \Mpdf\MpdfException('Error in barcode string (supplement): ' . $codestr . ' ' . $supplement_code); + } + + if (strlen($supplement_code) != $supplement) { + throw new \Mpdf\MpdfException('Barcode supplement incorrect: ' . $supplement_code); + } + + $llm = $fbw - (($arrcode['lightmR'] - $supparrcode['sepM']) * $arrcode['nom-X'] * $size); // Left Light margin + $rlm = $arrcode['lightmR'] * $arrcode['nom-X'] * $size; // Right Light margin + + $bcw = ($supparrcode["maxw"] * $xres); // Barcode width = Should always be 31.35mm * $size + + $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins + $ow = $fbw + $paddingL + $paddingR; // Full overall width incl. user-defined padding + $bch = $fbh - (1.5 * $size) - ($num_height + 0.5); // Barcode height of bars (3mm for numerals) + + $xpos = $x + $paddingL + $llm; + $ypos = $y + $paddingT + $num_height + 0.5; + + if ($col) { + $this->SetFColor($col); + } else { + $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + + if ($supparrcode !== false) { + foreach ($supparrcode["bcode"] as $v) { + $bw = ($v["w"] * $xres); + if ($v["t"]) { + // draw a vertical bar + $this->Rect($xpos, $ypos, $bw, $bch, 'F'); + } + $xpos += $bw; + } + } + + // Characters + if ($bgcol) { + $this->SetFColor($bgcol); + } else { + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + } + + $this->SetFontSize(3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters) + $this->x = $x + $paddingL + $llm; + $this->y = $y + $paddingT; + $this->Cell($bcw, $num_height, $supplement_code, 0, 0, 'C'); + + // Outer Right character (light margin) + $this->SetFontSize(($outerfontsize / 3) * 3 * $fh * $size * Mpdf::SCALE); // 3mm numerals (FontSize is larger to account for space above/below characters) + $this->x = $x + $paddingL + $llm + $bcw + $rlm - ($cw * 0.9); // 0.9 is correction as char does not fill full width + $this->y = $y + $paddingT; + $this->Cell($cw * ($outerfontsize / 3), $num_height, '>', 0, 0, 'R'); + } + + // Restore ************** + $this->SetFont($prevFontFamily, $prevFontStyle, $prevFontSizePt); + $this->DrawColor = $prevDrawColor; + $this->TextColor = $prevTextColor; + $this->FillColor = $prevFillColor; + $this->SetLineWidth($lw); + $this->SetY($y); + } + + /** + * POSTAL and OTHER barcodes + */ + function WriteBarcode2($code, $x = '', $y = '', $size = 1, $height = 1, $bgcol = false, $col = false, $btype = 'IMB', $print_ratio = '', $k = 1) + { + if (empty($code)) { + return; + } + + $this->barcode = new Barcode(); + $arrcode = $this->barcode->getBarcodeArray($code, $btype, $print_ratio); + + if (empty($x)) { + $x = $this->x; + } + + if (empty($y)) { + $y = $this->y; + } + + $prevDrawColor = $this->DrawColor; + $prevTextColor = $this->TextColor; + $prevFillColor = $this->FillColor; + $lw = $this->LineWidth; + $this->SetLineWidth(0.01); + $size /= $k; // in case resized in a table + $xres = $arrcode['nom-X'] * $size; + + if ($btype === 'IMB' || $btype === 'RM4SCC' || $btype === 'KIX' || $btype === 'POSTNET' || $btype === 'PLANET') { + $llm = $arrcode['quietL'] / $k; // Left Quiet margin + $rlm = $arrcode['quietR'] / $k; // Right Quiet margin + $tlm = $blm = $arrcode['quietTB'] / $k; + $height = 1; // Overrides + } elseif (in_array($btype, ['C128A', 'C128B', 'C128C', 'EAN128A', 'EAN128B', 'EAN128C', 'C39', 'C39+', 'C39E', 'C39E+', 'S25', 'S25+', 'I25', 'I25+', 'I25B', 'I25B+', 'C93', 'MSI', 'MSI+', 'CODABAR', 'CODE11'])) { + $llm = $arrcode['lightmL'] * $xres; // Left Quiet margin + $rlm = $arrcode['lightmR'] * $xres; // Right Quiet margin + $tlm = $blm = $arrcode['lightTB'] * $xres * $height; + } + + $bcw = ($arrcode["maxw"] * $xres); + $fbw = $bcw + $llm + $rlm; // Full barcode width incl. light margins + + $bch = ($arrcode["nom-H"] * $size * $height); + $fbh = $bch + $tlm + $blm; // Full barcode height + + // PRINT border background color + $xpos = $x; + $ypos = $y; + + if ($col) { + $this->SetDColor($col); + $this->SetTColor($col); + } else { + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $this->SetTColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + + if ($bgcol) { + $this->SetFColor($bgcol); + } else { + $this->SetFColor($this->colorConverter->convert(255, $this->PDFAXwarnings)); + } + + // PRINT BARS + if ($col) { + $this->SetFColor($col); + } else { + $this->SetFColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + } + $xpos = $x + $llm; + + if ($arrcode !== false) { + foreach ($arrcode["bcode"] as $v) { + $bw = ($v["w"] * $xres); + if ($v["t"]) { + $ypos = $y + $tlm + ($bch * $v['p'] / $arrcode['maxh']); + $this->Rect($xpos, $ypos, $bw, ($v['h'] * $bch / $arrcode['maxh']), 'F'); + } + $xpos += $bw; + } + } + + // PRINT BEARER BARS + if ($btype == 'I25B' || $btype == 'I25B+') { + $this->Rect($x, $y, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F'); + $this->Rect($x, $y + $tlm + $bch, $fbw, ($arrcode['lightTB'] * $xres * $height), 'F'); + } + + // Restore ************** + $this->DrawColor = $prevDrawColor; + $this->TextColor = $prevTextColor; + $this->FillColor = $prevFillColor; + $this->SetLineWidth($lw); + $this->SetY($y); + } + /* -- END BARCODES -- */ + + function StartTransform($returnstring = false) + { + if ($returnstring) { + return('q'); + } else { + $this->writer->write('q'); + } + } + + function StopTransform($returnstring = false) + { + if ($returnstring) { + return('Q'); + } else { + $this->writer->write('Q'); + } + } + + function transformScale($s_x, $s_y, $x = '', $y = '', $returnstring = false) + { + if ($x === '') { + $x = $this->x; + } + + if ($y === '') { + $y = $this->y; + } + + if (($s_x == 0) or ( $s_y == 0)) { + throw new \Mpdf\MpdfException('Please do not use values equal to zero for scaling'); + } + + $y = ($this->h - $y) * Mpdf::SCALE; + $x *= Mpdf::SCALE; + + // calculate elements of transformation matrix + $s_x /= 100; + $s_y /= 100; + $tm = []; + $tm[0] = $s_x; + $tm[1] = 0; + $tm[2] = 0; + $tm[3] = $s_y; + $tm[4] = $x * (1 - $s_x); + $tm[5] = $y * (1 - $s_y); + + // scale the coordinate system + if ($returnstring) { + return($this->_transform($tm, true)); + } else { + $this->_transform($tm); + } + } + + function transformTranslate($t_x, $t_y, $returnstring = false) + { + // calculate elements of transformation matrix + $tm = []; + $tm[0] = 1; + $tm[1] = 0; + $tm[2] = 0; + $tm[3] = 1; + $tm[4] = $t_x * Mpdf::SCALE; + $tm[5] = -$t_y * Mpdf::SCALE; + + // translate the coordinate system + if ($returnstring) { + return($this->_transform($tm, true)); + } else { + $this->_transform($tm); + } + } + + function transformRotate($angle, $x = '', $y = '', $returnstring = false) + { + if ($x === '') { + $x = $this->x; + } + + if ($y === '') { + $y = $this->y; + } + + $angle = -$angle; + $y = ($this->h - $y) * Mpdf::SCALE; + $x *= Mpdf::SCALE; + + // calculate elements of transformation matrix + $tm = []; + $tm[0] = cos(deg2rad($angle)); + $tm[1] = sin(deg2rad($angle)); + $tm[2] = -$tm[1]; + $tm[3] = $tm[0]; + $tm[4] = $x + $tm[1] * $y - $tm[0] * $x; + $tm[5] = $y - $tm[0] * $y - $tm[1] * $x; + + // rotate the coordinate system around ($x,$y) + if ($returnstring) { + return $this->_transform($tm, true); + } else { + $this->_transform($tm); + } + } + + /** + * mPDF 5.7.3 TRANSFORMS + */ + function transformSkew($angle_x, $angle_y, $x = '', $y = '', $returnstring = false) + { + if ($x === '') { + $x = $this->x; + } + + if ($y === '') { + $y = $this->y; + } + + $angle_x = -$angle_x; + $angle_y = -$angle_y; + + $x *= Mpdf::SCALE; + $y = ($this->h - $y) * Mpdf::SCALE; + + // calculate elements of transformation matrix + $tm = []; + $tm[0] = 1; + $tm[1] = tan(deg2rad($angle_y)); + $tm[2] = tan(deg2rad($angle_x)); + $tm[3] = 1; + $tm[4] = -$tm[2] * $y; + $tm[5] = -$tm[1] * $x; + + // skew the coordinate system + if ($returnstring) { + return $this->_transform($tm, true); + } else { + $this->_transform($tm); + } + } + + function _transform($tm, $returnstring = false) + { + if ($returnstring) { + return(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); + } else { + $this->writer->write(sprintf('%.4F %.4F %.4F %.4F %.4F %.4F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5])); + } + } + + // AUTOFONT ========================= + function markScriptToLang($html) + { + if ($this->onlyCoreFonts) { + return $html; + } + + $n = ''; + $a = preg_split('/<(.*?)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE); + foreach ($a as $i => $e) { + if ($i % 2 == 0) { + + // ignore if in Textarea + if ($i > 0 && strtolower(substr($a[$i - 1], 1, 8)) == 'textarea') { + $a[$i] = $e; + continue; + } + + $e = UtfString::strcode2utf($e); + $e = $this->lesser_entity_decode($e); + + $earr = $this->UTF8StringToArray($e, false); + + $scriptblock = 0; + $scriptblocks = []; + $scriptblocks[0] = 0; + $chardata = []; + $subchunk = 0; + $charctr = 0; + + foreach ($earr as $char) { + + $ucd_record = Ucdn::get_ucd_record($char); + $sbl = $ucd_record[6]; + + if ($sbl && $sbl != 40 && $sbl != 102) { + if ($scriptblock == 0) { + $scriptblock = $sbl; + $scriptblocks[$subchunk] = $scriptblock; + } elseif ($scriptblock > 0 && $scriptblock != $sbl) { + // NEW (non-common) Script encountered in this chunk. + // Start a new subchunk + $subchunk++; + $scriptblock = $sbl; + $charctr = 0; + $scriptblocks[$subchunk] = $scriptblock; + } + } + + $chardata[$subchunk][$charctr]['script'] = $sbl; + $chardata[$subchunk][$charctr]['uni'] = $char; + $charctr++; + } + + // If scriptblock[x] = common & non-baseScript + // and scriptblock[x+1] = baseScript + // Move common script from end of x to start of x+1 + for ($sch = 0; $sch < $subchunk; $sch++) { + if ($scriptblocks[$sch] > 0 && $scriptblocks[$sch] != $this->baseScript && $scriptblocks[$sch + 1] == $this->baseScript) { + $end = count($chardata[$sch]) - 1; + while ($chardata[$sch][$end]['script'] == 0 && $end > 1) { // common script + $tmp = array_pop($chardata[$sch]); + array_unshift($chardata[$sch + 1], $tmp); + $end--; + } + } + } + + $o = ''; + for ($sch = 0; $sch <= $subchunk; $sch++) { + + if (isset($chardata[$sch])) { + $s = ''; + for ($j = 0; $j < count($chardata[$sch]); $j++) { + $s .= UtfString::code2utf($chardata[$sch][$j]['uni']); + } + + // ZZZ99 Undo lesser_entity_decode as above - but only for <>& + $s = str_replace("&", "&", $s); + $s = str_replace("<", "<", $s); + $s = str_replace(">", ">", $s); + + // Check Vietnamese if Latin script - even if Basescript + if ($scriptblocks[$sch] == Ucdn::SCRIPT_LATIN && $this->autoVietnamese && preg_match("/([" . $this->scriptToLanguage->getLanguageDelimiters('viet') . "])/u", $s)) { + $o .= '<span lang="vi" class="lang_vi">' . $s . '</span>'; + } elseif ($scriptblocks[$sch] == Ucdn::SCRIPT_ARABIC && $this->autoArabic) { // Check Arabic for different languages if Arabic script - even if Basescript + if (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('sindhi') . "]/u", $s)) { + $o .= '<span lang="sd" class="lang_sd">' . $s . '</span>'; + } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('urdu') . "]/u", $s)) { + $o .= '<span lang="ur" class="lang_ur">' . $s . '</span>'; + } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('pashto') . "]/u", $s)) { + $o .= '<span lang="ps" class="lang_ps">' . $s . '</span>'; + } elseif (preg_match("/[" . $this->scriptToLanguage->getLanguageDelimiters('persian') . "]/u", $s)) { + $o .= '<span lang="fa" class="lang_fa">' . $s . '</span>'; + } elseif ($this->baseScript != Ucdn::SCRIPT_ARABIC && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) { + $o .= '<span lang="' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">' . $s . '</span>'; + } else { + // Just output chars + $o .= $s; + } + } elseif ($scriptblocks[$sch] > 0 && $scriptblocks[$sch] != $this->baseScript && $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch])) { // Identify Script block if not Basescript, and mark up as language + // Encase in <span> + $o .= '<span lang="' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '" class="lang_' . $this->scriptToLanguage->getLanguageByScript($scriptblocks[$sch]) . '">'; + $o .= $s; + $o .= '</span>'; + } else { + // Just output chars + $o .= $s; + } + } + } + + $a[$i] = $o; + } else { + $a[$i] = '<' . $e . '>'; + } + } + + $n = implode('', $a); + + return $n; + } + + /* -- COLUMNS -- */ + /** + * Callback function from function printcolumnbuffer in mpdf + */ + function columnAdjustAdd($type, $k, $xadj, $yadj, $a, $b, $c = 0, $d = 0, $e = 0, $f = 0) + { + if ($type === 'Td') { // xpos,ypos + + $a += ($xadj * $k); + $b -= ($yadj * $k); + + return 'BT ' . sprintf('%.3F %.3F', $a, $b) . ' Td'; + + } elseif ($type === 're') { // xpos,ypos,width,height + + $a += ($xadj * $k); + $b -= ($yadj * $k); + + return sprintf('%.3F %.3F %.3F %.3F', $a, $b, $c, $d) . ' re'; + + } elseif ($type === 'l') { // xpos,ypos,x2pos,y2pos + + $a += ($xadj * $k); + $b -= ($yadj * $k); + + return sprintf('%.3F %.3F l', $a, $b); + + } elseif ($type === 'img') { // width,height,xpos,ypos + + $c += ($xadj * $k); + $d -= ($yadj * $k); + + return sprintf('q %.3F 0 0 %.3F %.3F %.3F', $a, $b, $c, $d) . ' cm /' . $e; + + } elseif ($type === 'draw') { // xpos,ypos + + $a += ($xadj * $k); + $b -= ($yadj * $k); + + return sprintf('%.3F %.3F m', $a, $b); + + } elseif ($type === 'bezier') { // xpos,ypos,x2pos,y2pos,x3pos,y3pos + + $a += ($xadj * $k); + $b -= ($yadj * $k); + $c += ($xadj * $k); + $d -= ($yadj * $k); + $e += ($xadj * $k); + $f -= ($yadj * $k); + + return sprintf('%.3F %.3F %.3F %.3F %.3F %.3F', $a, $b, $c, $d, $e, $f) . ' c'; + } + } + + /* -- END COLUMNS -- */ + + // mPDF 5.7.3 TRANSFORMS + function ConvertAngle($s, $makepositive = true) + { + if (preg_match('/([\-]*[0-9\.]+)(deg|grad|rad)/i', $s, $m)) { + + $angle = $m[1] + 0; + + if (strtolower($m[2]) == 'deg') { + $angle = $angle; + } elseif (strtolower($m[2]) == 'grad') { + $angle *= (360 / 400); + } elseif (strtolower($m[2]) == 'rad') { + $angle = rad2deg($angle); + } + + while ($angle >= 360) { + $angle -= 360; + } + + while ($angle <= -360) { + $angle += 360; + } + + if ($makepositive) { // always returns an angle between 0 and 360deg + if ($angle < 0) { + $angle += 360; + } + } + + } else { + $angle = $s + 0; + } + + return $angle; + } + + function lesser_entity_decode($html) + { + // supports the most used entity codes (only does ascii safe characters) + $html = str_replace("<", "<", $html); + $html = str_replace(">", ">", $html); + + $html = str_replace("'", "'", $html); + $html = str_replace(""", '"', $html); + $html = str_replace("&", "&", $html); + + return $html; + } + + function AdjustHTML($html, $tabSpaces = 8) + { + $limit = ini_get('pcre.backtrack_limit'); + if (strlen($html) > $limit) { + throw new \Mpdf\MpdfException(sprintf( + 'The HTML code size is larger than pcre.backtrack_limit %d. You should use WriteHTML() with smaller string lengths.', + $limit + )); + } + + preg_match_all("/(<annotation.*?>)/si", $html, $m); + if (count($m[1])) { + for ($i = 0; $i < count($m[1]); $i++) { + $sub = preg_replace("/\n/si", "\xbb\xa4\xac", $m[1][$i]); + $html = preg_replace('/' . preg_quote($m[1][$i], '/') . '/si', $sub, $html); + } + } + + preg_match_all("/(<svg.*?<\/svg>)/si", $html, $svgi); + if (count($svgi[0])) { + for ($i = 0; $i < count($svgi[0]); $i++) { + $file = $this->cache->write('/_tempSVG' . uniqid(random_int(1, 100000), true) . '_' . $i . '.svg', $svgi[0][$i]); + $html = str_replace($svgi[0][$i], '<img src="' . $file . '" />', $html); + } + } + + // Remove javascript code from HTML (should not appear in the PDF file) + $html = preg_replace('/<script.*?<\/script>/is', '', $html); + + // Remove special comments + $html = preg_replace('/<!--mpdf/i', '', $html); + $html = preg_replace('/mpdf-->/i', '', $html); + + // Remove comments from HTML (should not appear in the PDF file) + $html = preg_replace('/<!--.*?-->/s', '', $html); + + $html = preg_replace('/\f/', '', $html); // replace formfeed by nothing + $html = preg_replace('/\r/', '', $html); // replace carriage return by nothing + + // Well formed XHTML end tags + $html = preg_replace('/<(br|hr)>/i', "<\\1 />", $html); // mPDF 6 + $html = preg_replace('/<(br|hr)\/>/i', "<\\1 />", $html); + + // Get rid of empty <thead></thead> etc + $html = preg_replace('/<tr>\s*<\/tr>/i', '', $html); + $html = preg_replace('/<thead>\s*<\/thead>/i', '', $html); + $html = preg_replace('/<tfoot>\s*<\/tfoot>/i', '', $html); + $html = preg_replace('/<table[^>]*>\s*<\/table>/i', '', $html); + + // Remove spaces at end of table cells + $html = preg_replace("/[ \n\r]+<\/t(d|h)/", '</t\\1', $html); + + $html = preg_replace("/[ ]*<dottab\s*[\/]*>[ ]*/", '<dottab />', $html); + + // Concatenates any Substitute characters from symbols/dingbats + $html = str_replace('</tts><tts>', '|', $html); + $html = str_replace('</ttz><ttz>', '|', $html); + $html = str_replace('</tta><tta>', '|', $html); + + $html = preg_replace('/<br \/>\s*/is', "<br />", $html); + + $html = preg_replace('/<wbr[ \/]*>\s*/is', "­", $html); + + // Preserve '\n's in content between the tags <pre> and </pre> + if (preg_match('/<pre/', $html)) { + + $html_a = preg_split('/(\<\/?pre[^\>]*\>)/', $html, -1, 2); + $h = []; + $c = 0; + + foreach ($html_a as $s) { + if ($c > 1 && preg_match('/^<\/pre/i', $s)) { + $c--; + $s = preg_replace('/<\/pre/i', '</innerpre', $s); + } elseif ($c > 0 && preg_match('/^<pre/i', $s)) { + $c++; + $s = preg_replace('/<pre/i', '<innerpre', $s); + } elseif (preg_match('/^<pre/i', $s)) { + $c++; + } elseif (preg_match('/^<\/pre/i', $s)) { + $c--; + } + array_push($h, $s); + } + + $html = implode('', $h); + } + + $thereispre = preg_match_all('#<pre(.*?)>(.*?)</pre>#si', $html, $temp); + + // Preserve '\n's in content between the tags <textarea> and </textarea> + $thereistextarea = preg_match_all('#<textarea(.*?)>(.*?)</textarea>#si', $html, $temp2); + $html = preg_replace('/[\n]/', ' ', $html); // replace linefeed by spaces + $html = preg_replace('/[\t]/', ' ', $html); // replace tabs by spaces + + // Converts < to < when not a tag + $html = preg_replace('/<([^!\/a-zA-Z_:])/i', '<\\1', $html); // mPDF 5.7.3 + $html = preg_replace("/[ ]+/", ' ', $html); + + $html = preg_replace('/\/li>\s+<\/(u|o)l/i', '/li></\\1l', $html); + $html = preg_replace('/\/(u|o)l>\s+<\/li/i', '/\\1l></li', $html); + $html = preg_replace('/\/li>\s+<\/(u|o)l/i', '/li></\\1l', $html); + $html = preg_replace('/\/li>\s+<li/i', '/li><li', $html); + $html = preg_replace('/<(u|o)l([^>]*)>[ ]+/i', '<\\1l\\2>', $html); + $html = preg_replace('/[ ]+<(u|o)l/i', '<\\1l', $html); + + // Make self closing tabs valid XHTML + // Tags which are self-closing: 1) Replaceable and 2) Non-replaced items + $selftabs = 'input|hr|img|br|barcode|dottab'; + $selftabs2 = 'indexentry|indexinsert|bookmark|watermarktext|watermarkimage|column_break|columnbreak|newcolumn|newpage|page_break|pagebreak|formfeed|columns|toc|tocpagebreak|setpageheader|setpagefooter|sethtmlpageheader|sethtmlpagefooter|annotation'; + + // Fix self-closing tags which don't close themselves + $html = preg_replace('/(<(' . $selftabs . '|' . $selftabs2 . ')[^>\/]*)>/i', '\\1 />', $html); + + // Fix self-closing tags that don't include a space between the tag name and the closing slash + $html = preg_replace('/(<(' . $selftabs . '|' . $selftabs2 . '))\/>/i', '\\1 />', $html); + + $iterator = 0; + while ($thereispre) { // Recover <pre attributes>content</pre> + $temp[2][$iterator] = preg_replace('/<([^!\/a-zA-Z_:])/', '<\\1', $temp[2][$iterator]); // mPDF 5.7.2 // mPDF 5.7.3 + + $temp[2][$iterator] = preg_replace_callback("/^([^\n\t]*?)\t/m", [$this, 'tabs2spaces_callback'], $temp[2][$iterator]); // mPDF 5.7+ + $temp[2][$iterator] = preg_replace('/\t/', str_repeat(" ", $tabSpaces), $temp[2][$iterator]); + + $temp[2][$iterator] = preg_replace('/\n/', "<br />", $temp[2][$iterator]); + $temp[2][$iterator] = str_replace('\\', "\\\\", $temp[2][$iterator]); + // $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si','<erp'.$temp[1][$iterator].'>'.$temp[2][$iterator].'</erp>',$html,1); + $html = preg_replace('#<pre(.*?)>(.*?)</pre>#si', '<erp' . $temp[1][$iterator] . '>' . str_replace('$', '\$', $temp[2][$iterator]) . '</erp>', $html, 1); // mPDF 5.7+ + $thereispre--; + $iterator++; + } + + $iterator = 0; + while ($thereistextarea) { // Recover <textarea attributes>content</textarea> + $temp2[2][$iterator] = preg_replace('/\t/', str_repeat(" ", $tabSpaces), $temp2[2][$iterator]); + $temp2[2][$iterator] = str_replace('\\', "\\\\", $temp2[2][$iterator]); + $html = preg_replace('#<textarea(.*?)>(.*?)</textarea>#si', '<aeratxet' . $temp2[1][$iterator] . '>' . trim($temp2[2][$iterator]) . '</aeratxet>', $html, 1); + $thereistextarea--; + $iterator++; + } + + // Restore original tag names + $html = str_replace("<erp", "<pre", $html); + $html = str_replace("</erp>", "</pre>", $html); + $html = str_replace("<aeratxet", "<textarea", $html); + $html = str_replace("</aeratxet>", "</textarea>", $html); + $html = str_replace("</innerpre", "</pre", $html); + $html = str_replace("<innerpre", "<pre", $html); + + $html = preg_replace('/<textarea([^>]*)><\/textarea>/si', '<textarea\\1> </textarea>', $html); + $html = preg_replace('/(<table[^>]*>)\s*(<caption)(.*?<\/caption>)(.*?<\/table>)/si', '\\2 position="top"\\3\\1\\4\\2 position="bottom"\\3', $html); // *TABLES* + $html = preg_replace('/<(h[1-6])([^>]*)(>(?:(?!h[1-6]).)*?<\/\\1>\s*<table)/si', '<\\1\\2 keep-with-table="1"\\3', $html); // *TABLES* + $html = preg_replace("/\xbb\xa4\xac/", "\n", $html); + + // Fixes <p>₹</p> which browser copes with even though it is wrong! + $html = preg_replace("/(&#[x]{0,1}[0-9a-f]{1,5})</i", "\\1;<", $html); + + return $html; + } + + // mPDF 5.7+ + function tabs2spaces_callback($matches) + { + return (stripslashes($matches[1]) . str_repeat(' ', $this->tabSpaces - (mb_strlen(stripslashes($matches[1])) % $this->tabSpaces))); + } + + // mPDF 5.7+ + function date_callback($matches) + { + return date($matches[1]); + } + + // ========== OVERWRITE SEARCH STRING IN A PDF FILE ================ + function OverWrite($file_in, $search, $replacement, $dest = Destination::DOWNLOAD, $file_out = "mpdf") + { + $pdf = file_get_contents($file_in); + + if (!is_array($search)) { + $x = $search; + $search = [$x]; + } + if (!is_array($replacement)) { + $x = $replacement; + $replacement = [$x]; // mPDF 5.7.4 + } + + if (!$this->onlyCoreFonts && !$this->usingCoreFont) { + foreach ($search as $k => $val) { + $search[$k] = $this->writer->utf8ToUtf16BigEndian($search[$k], false); + $search[$k] = $this->writer->escape($search[$k]); + $replacement[$k] = $this->writer->utf8ToUtf16BigEndian($replacement[$k], false); + $replacement[$k] = $this->writer->escape($replacement[$k]); + } + } else { + foreach ($replacement as $k => $val) { + $replacement[$k] = mb_convert_encoding($replacement[$k], $this->mb_enc, 'utf-8'); + $replacement[$k] = $this->writer->escape($replacement[$k]); + } + } + + // Get xref into array + $xref = []; + preg_match("/xref\n0 (\d+)\n(.*?)\ntrailer/s", $pdf, $m); + $xref_objid = $m[1]; + preg_match_all('/(\d{10}) (\d{5}) (f|n)/', $m[2], $x); + for ($i = 0; $i < count($x[0]); $i++) { + $xref[] = [intval($x[1][$i]), $x[2][$i], $x[3][$i]]; + } + + $changes = []; + preg_match("/<<\s*\/Type\s*\/Pages\s*\/Kids\s*\[(.*?)\]\s*\/Count/s", $pdf, $m); + preg_match_all("/(\d+) 0 R /s", $m[1], $o); + $objlist = $o[1]; + + foreach ($objlist as $obj) { + if ($this->compress) { + preg_match("/" . ($obj + 1) . " 0 obj\n<<\s*\/Filter\s*\/FlateDecode\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s", $pdf, $m); + } else { + preg_match("/" . ($obj + 1) . " 0 obj\n<<\s*\/Length (\d+)>>\nstream\n(.*?)\nendstream\n/s", $pdf, $m); + } + + $s = $m[2]; + if (!$s) { + continue; + } + + $oldlen = $m[1]; + + if ($this->encrypted) { + $s = $this->protection->rc4($this->protection->objectKey($obj + 1), $s); + } + + if ($this->compress) { + $s = gzuncompress($s); + } + + foreach ($search as $k => $val) { + $s = str_replace($search[$k], $replacement[$k], $s); + } + + if ($this->compress) { + $s = gzcompress($s); + } + + if ($this->encrypted) { + $s = $this->protection->rc4($this->protection->objectKey($obj + 1), $s); + } + + $newlen = strlen($s); + + $changes[($xref[$obj + 1][0])] = ($newlen - $oldlen) + (strlen($newlen) - strlen($oldlen)); + + if ($this->compress) { + $newstr = ($obj + 1) . " 0 obj\n<</Filter /FlateDecode /Length " . $newlen . ">>\nstream\n" . $s . "\nendstream\n"; + } else { + $newstr = ($obj + 1) . " 0 obj\n<</Length " . $newlen . ">>\nstream\n" . $s . "\nendstream\n"; + } + + $pdf = str_replace($m[0], $newstr, $pdf); + } + + // Update xref in PDF + krsort($changes); + $newxref = "xref\n0 " . $xref_objid . "\n"; + foreach ($xref as $v) { + foreach ($changes as $ck => $cv) { + if ($v[0] > $ck) { + $v[0] += $cv; + } + } + $newxref .= sprintf('%010d', $v[0]) . ' ' . $v[1] . ' ' . $v[2] . " \n"; + } + $newxref .= "trailer"; + $pdf = preg_replace("/xref\n0 \d+\n.*?\ntrailer/s", $newxref, $pdf); + + // Update startxref in PDF + preg_match("/startxref\n(\d+)\n%%EOF/s", $pdf, $m); + $startxref = $m[1]; + $startxref += array_sum($changes); + $pdf = preg_replace("/startxref\n(\d+)\n%%EOF/s", "startxref\n" . $startxref . "\n%%EOF", $pdf); + + // OUTPUT + switch ($dest) { + case Destination::INLINE: + if (isset($_SERVER['SERVER_NAME'])) { + // We send to a browser + header('Content-Type: application/pdf'); + header('Content-Length: ' . strlen($pdf)); + header('Content-disposition: inline; filename=' . $file_out); + } + + echo $pdf; + + break; + + case Destination::FILE: + if (!$file_out) { + $file_out = 'mpdf.pdf'; + } + + $f = fopen($file_out, 'wb'); + + if (!$f) { + throw new \Mpdf\MpdfException('Unable to create output file: ' . $file_out); + } + + fwrite($f, $pdf, strlen($pdf)); + + fclose($f); + + break; + + case Destination::STRING_RETURN: + return $pdf; + + case Destination::DOWNLOAD: // Download file + default: + if (isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) { + header('Content-Type: application/force-download'); + } else { + header('Content-Type: application/octet-stream'); + } + + header('Content-Length: ' . strlen($pdf)); + header('Content-disposition: attachment; filename=' . $file_out); + + echo $pdf; + + break; + } + } + + + function Thumbnail($file, $npr = 3, $spacing = 10) + { + // $npr = number per row + $w = (($this->pgwidth + $spacing) / $npr) - $spacing; + $oldlinewidth = $this->LineWidth; + $this->SetLineWidth(0.02); + $this->SetDColor($this->colorConverter->convert(0, $this->PDFAXwarnings)); + $h = 0; + $maxh = 0; + $x = $_x = $this->lMargin; + $_y = $this->tMargin; + + if ($this->y == 0) { + $y = $_y; + } else { + $y = $this->y; + } + + $pagecount = $this->setSourceFile($file); + + for ($n = 1; $n <= $pagecount; $n++) { + $tplidx = $this->importPage($n); + $size = $this->useTemplate($tplidx, $x, $y, $w); + $this->Rect($x, $y, $size['width'], $size['height']); + $h = max($h, $size['height']); + $maxh = max($h, $maxh); + + if ($n % $npr == 0) { + if (($y + $h + $spacing + $maxh) > $this->PageBreakTrigger && $n != $pagecount) { + $this->AddPage(); + $x = $_x; + $y = $_y; + } else { + $y += $h + $spacing; + $x = $_x; + $h = 0; + } + } else { + $x += $w + $spacing; + } + } + $this->SetLineWidth($oldlinewidth); + } + + function SetPageTemplate($tplidx = '') + { + if (!isset($this->importedPages[$tplidx])) { + $this->pageTemplate = ''; + return false; + } + $this->pageTemplate = $tplidx; + } + + function SetDocTemplate($file = '', $continue = 0) + { + $this->docTemplate = $file; + $this->docTemplateContinue = $continue; + } + + /* -- END IMPORTS -- */ + + // JAVASCRIPT + function _set_object_javascript($string) + { + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/S /JavaScript '); + $this->writer->write('/JS ' . $this->writer->string($string)); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + + function SetJS($script) + { + $this->js = $script; + } + + /** + * This function takes the last comma or dot (if any) to make a clean float, ignoring thousand separator, currency or any other letter + * + * @param string $num + * @see http://php.net/manual/de/function.floatval.php#114486 + * @return float + */ + public function toFloat($num) + { + $dotPos = strrpos($num, '.'); + $commaPos = strrpos($num, ','); + $sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos : ((($commaPos > $dotPos) && $commaPos) ? $commaPos : false); + + if (!$sep) { + return floatval(preg_replace('/[^0-9]/', '', $num)); + } + + return floatval( + preg_replace('/[^0-9]/', '', substr($num, 0, $sep)) . '.' . + preg_replace('/[^0-9]/', '', substr($num, $sep+1, strlen($num))) + ); + } + + public function getFontDescriptor() + { + return $this->fontDescriptor; + } + + /** + * Temporarily return the method to preserve example 44 yearbook + */ + public function _out($s) + { + $this->writer->write($s); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/MpdfException.php b/lib/MPDF/vendor/mpdf/mpdf/src/MpdfException.php new file mode 100644 index 0000000..f845354 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/MpdfException.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf; + +class MpdfException extends \ErrorException +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/MpdfImageException.php b/lib/MPDF/vendor/mpdf/mpdf/src/MpdfImageException.php new file mode 100644 index 0000000..c8f4ca0 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/MpdfImageException.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf; + +class MpdfImageException extends \Mpdf\MpdfException +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Otl.php b/lib/MPDF/vendor/mpdf/mpdf/src/Otl.php new file mode 100644 index 0000000..4603996 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Otl.php @@ -0,0 +1,6211 @@ +<?php + +namespace Mpdf; + +use Mpdf\Strict; + +use Mpdf\Css\TextVars; +use Mpdf\Fonts\FontCache; + +use Mpdf\Shaper\Indic; +use Mpdf\Shaper\Myanmar; +use Mpdf\Shaper\Sea; + +use Mpdf\Utils\UtfString; + +class Otl +{ + + use Strict; + + const _OTL_OLD_SPEC_COMPAT_1 = true; + const _DICT_NODE_TYPE_SPLIT = 0x01; + const _DICT_NODE_TYPE_LINEAR = 0x02; + const _DICT_INTERMEDIATE_MATCH = 0x03; + const _DICT_FINAL_MATCH = 0x04; + + private $mpdf; + + private $fontCache; + + var $arabLeftJoining; + + var $arabRightJoining; + + var $arabTransparentJoin; + + var $arabTransparent; + + var $GSUBdata; + + var $GPOSdata; + + var $GSUBfont; + + var $fontkey; + + var $ttfOTLdata; + + var $glyphIDtoUni; + + var $_pos; + + var $GSUB_offset; + + var $GPOS_offset; + + var $MarkAttachmentType; + + var $MarkGlyphSets; + + var $GlyphClassMarks; + + var $GlyphClassLigatures; + + var $GlyphClassBases; + + var $GlyphClassComponents; + + var $Ignores; + + var $LuCoverage; + + var $OTLdata; + + var $assocLigs; + + var $assocMarks; + + var $shaper; + + var $restrictToSyllable; + + var $lbdicts; // Line-breaking dictionaries + + var $LuDataCache; + + var $arabGlyphs; + + var $current_fh; + + var $Entry; + + var $Exit; + + var $GDEFdata; + + var $GPOSLookups; + + var $GSLuCoverage; + + var $GSUB_length; + + var $GSUBLookups; + + var $schOTLdata; + + var $lastBidiStrongType; + + var $debugOTL = false; + + public function __construct(Mpdf $mpdf, FontCache $fontCache) + { + $this->mpdf = $mpdf; + $this->fontCache = $fontCache; + + $this->current_fh = ''; + + $this->lbdicts = []; + $this->LuDataCache = []; + } + + function applyOTL($str, $useOTL) + { + if (!$this->arabLeftJoining) { + $this->arabic_initialise(); + } + + $this->OTLdata = []; + if (trim($str) == '') { + return $str; + } + if (!$useOTL) { + return $str; + } + + // 1. Load GDEF data + //============================== + $this->fontkey = $this->mpdf->CurrentFont['fontkey']; + $this->glyphIDtoUni = $this->mpdf->CurrentFont['glyphIDtoUni']; + $fontCacheFilename = $this->fontkey . '.GDEFdata.json'; + if (!isset($this->GDEFdata[$this->fontkey]) && $this->fontCache->jsonHas($fontCacheFilename)) { + $font = $this->fontCache->jsonLoad($fontCacheFilename); + + $this->GSUB_offset = $this->GDEFdata[$this->fontkey]['GSUB_offset'] = $font['GSUB_offset']; + $this->GPOS_offset = $this->GDEFdata[$this->fontkey]['GPOS_offset'] = $font['GPOS_offset']; + $this->GSUB_length = $this->GDEFdata[$this->fontkey]['GSUB_length'] = $font['GSUB_length']; + $this->MarkAttachmentType = $this->GDEFdata[$this->fontkey]['MarkAttachmentType'] = $font['MarkAttachmentType']; + $this->MarkGlyphSets = $this->GDEFdata[$this->fontkey]['MarkGlyphSets'] = $font['MarkGlyphSets']; + $this->GlyphClassMarks = $this->GDEFdata[$this->fontkey]['GlyphClassMarks'] = $font['GlyphClassMarks']; + $this->GlyphClassLigatures = $this->GDEFdata[$this->fontkey]['GlyphClassLigatures'] = $font['GlyphClassLigatures']; + $this->GlyphClassComponents = $this->GDEFdata[$this->fontkey]['GlyphClassComponents'] = $font['GlyphClassComponents']; + $this->GlyphClassBases = $this->GDEFdata[$this->fontkey]['GlyphClassBases'] = $font['GlyphClassBases']; + } else { + $this->GSUB_offset = $this->GDEFdata[$this->fontkey]['GSUB_offset']; + $this->GPOS_offset = $this->GDEFdata[$this->fontkey]['GPOS_offset']; + $this->GSUB_length = $this->GDEFdata[$this->fontkey]['GSUB_length']; + $this->MarkAttachmentType = $this->GDEFdata[$this->fontkey]['MarkAttachmentType']; + $this->MarkGlyphSets = $this->GDEFdata[$this->fontkey]['MarkGlyphSets']; + $this->GlyphClassMarks = $this->GDEFdata[$this->fontkey]['GlyphClassMarks']; + $this->GlyphClassLigatures = $this->GDEFdata[$this->fontkey]['GlyphClassLigatures']; + $this->GlyphClassComponents = $this->GDEFdata[$this->fontkey]['GlyphClassComponents']; + $this->GlyphClassBases = $this->GDEFdata[$this->fontkey]['GlyphClassBases']; + } + + // 2. Prepare string as HEX string and Analyse character properties + //================================================================= + $earr = $this->mpdf->UTF8StringToArray($str, false); + + $scriptblock = 0; + $scriptblocks = []; + $scriptblocks[0] = 0; + $vstr = ''; + $OTLdata = []; + $subchunk = 0; + $charctr = 0; + foreach ($earr as $char) { + $ucd_record = Ucdn::get_ucd_record($char); + $sbl = $ucd_record[6]; + + // Special case - Arabic End of Ayah + if ($char == 1757) { + $sbl = Ucdn::SCRIPT_ARABIC; + } + + if ($sbl && $sbl != 40 && $sbl != 102) { + if ($scriptblock == 0) { + $scriptblock = $sbl; + $scriptblocks[$subchunk] = $scriptblock; + } elseif ($scriptblock > 0 && $scriptblock != $sbl) { + // ************************************************* + // NEW (non-common) Script encountered in this chunk. Start a new subchunk + $subchunk++; + $scriptblock = $sbl; + $charctr = 0; + $scriptblocks[$subchunk] = $scriptblock; + } + } + + $OTLdata[$subchunk][$charctr]['general_category'] = $ucd_record[0]; + $OTLdata[$subchunk][$charctr]['bidi_type'] = $ucd_record[2]; + + //$OTLdata[$subchunk][$charctr]['combining_class'] = $ucd_record[1]; + //$OTLdata[$subchunk][$charctr]['bidi_type'] = $ucd_record[2]; + //$OTLdata[$subchunk][$charctr]['mirrored'] = $ucd_record[3]; + //$OTLdata[$subchunk][$charctr]['east_asian_width'] = $ucd_record[4]; + //$OTLdata[$subchunk][$charctr]['normalization_check'] = $ucd_record[5]; + //$OTLdata[$subchunk][$charctr]['script'] = $ucd_record[6]; + + $charasstr = $this->unicode_hex($char); + + if (strpos($this->GlyphClassMarks, $charasstr) !== false) { + $OTLdata[$subchunk][$charctr]['group'] = 'M'; + } elseif ($char == 32 || $char == 12288) { + $OTLdata[$subchunk][$charctr]['group'] = 'S'; + } // 12288 = 0x3000 = CJK space + else { + $OTLdata[$subchunk][$charctr]['group'] = 'C'; + } + + $OTLdata[$subchunk][$charctr]['uni'] = $char; + $OTLdata[$subchunk][$charctr]['hex'] = $charasstr; + $charctr++; + } + + /* PROCESS EACH SUBCHUNK WITH DIFFERENT SCRIPTS */ + for ($sch = 0; $sch <= $subchunk; $sch++) { + $this->OTLdata = $OTLdata[$sch]; + $scriptblock = $scriptblocks[$sch]; + + // 3. Get Appropriate Scripts, and Shaper engine from analysing text and list of available scripts/langsys in font + //============================== + // Based on actual script block of text, select shaper (and line-breaking dictionaries) + if (Ucdn::SCRIPT_DEVANAGARI <= $scriptblock && $scriptblock <= Ucdn::SCRIPT_MALAYALAM) { + $this->shaper = "I"; + } // INDIC shaper + elseif ($scriptblock == Ucdn::SCRIPT_ARABIC || $scriptblock == Ucdn::SCRIPT_SYRIAC) { + $this->shaper = "A"; + } // ARABIC shaper + elseif ($scriptblock == Ucdn::SCRIPT_NKO || $scriptblock == Ucdn::SCRIPT_MANDAIC) { + $this->shaper = "A"; + } // ARABIC shaper + elseif ($scriptblock == Ucdn::SCRIPT_KHMER) { + $this->shaper = "K"; + } // KHMER shaper + elseif ($scriptblock == Ucdn::SCRIPT_THAI) { + $this->shaper = "T"; + } // THAI shaper + elseif ($scriptblock == Ucdn::SCRIPT_LAO) { + $this->shaper = "L"; + } // LAO shaper + elseif ($scriptblock == Ucdn::SCRIPT_SINHALA) { + $this->shaper = "S"; + } // SINHALA shaper + elseif ($scriptblock == Ucdn::SCRIPT_MYANMAR) { + $this->shaper = "M"; + } // MYANMAR shaper + elseif ($scriptblock == Ucdn::SCRIPT_NEW_TAI_LUE) { + $this->shaper = "E"; + } // SEA South East Asian shaper + elseif ($scriptblock == Ucdn::SCRIPT_CHAM) { + $this->shaper = "E"; + } // SEA South East Asian shaper + elseif ($scriptblock == Ucdn::SCRIPT_TAI_THAM) { + $this->shaper = "E"; + } // SEA South East Asian shaper + else { + $this->shaper = ""; + } + // Get scripttag based on actual text script + $scripttag = Ucdn::$uni_scriptblock[$scriptblock]; + + $GSUBscriptTag = ''; + $GSUBlangsys = ''; + $GPOSscriptTag = ''; + $GPOSlangsys = ''; + $is_old_spec = false; + + $ScriptLang = $this->mpdf->CurrentFont['GSUBScriptLang']; + if (count($ScriptLang)) { + list($GSUBscriptTag, $is_old_spec) = $this->_getOTLscriptTag($ScriptLang, $scripttag, $scriptblock, $this->shaper, $useOTL, 'GSUB'); + if ($this->mpdf->fontLanguageOverride && strpos($ScriptLang[$GSUBscriptTag], $this->mpdf->fontLanguageOverride) !== false) { + $GSUBlangsys = str_pad($this->mpdf->fontLanguageOverride, 4); + } elseif ($GSUBscriptTag && isset($ScriptLang[$GSUBscriptTag]) && $ScriptLang[$GSUBscriptTag] != '') { + $GSUBlangsys = $this->_getOTLLangTag($this->mpdf->currentLang, $ScriptLang[$GSUBscriptTag]); + } + } + $ScriptLang = $this->mpdf->CurrentFont['GPOSScriptLang']; + + // NB If after GSUB, the same script/lang exist for GPOS, just use these... + if ($GSUBscriptTag && $GSUBlangsys && isset($ScriptLang[$GSUBscriptTag]) && strpos($ScriptLang[$GSUBscriptTag], $GSUBlangsys) !== false) { + $GPOSlangsys = $GSUBlangsys; + $GPOSscriptTag = $GSUBscriptTag; + } // else repeat for GPOS + // [Font XBRiyaz has GSUB tables for latn, but not GPOS for latn] + elseif (count($ScriptLang)) { + list($GPOSscriptTag, $dummy) = $this->_getOTLscriptTag($ScriptLang, $scripttag, $scriptblock, $this->shaper, $useOTL, 'GPOS'); + if ($GPOSscriptTag && $this->mpdf->fontLanguageOverride && strpos($ScriptLang[$GPOSscriptTag], $this->mpdf->fontLanguageOverride) !== false) { + $GPOSlangsys = str_pad($this->mpdf->fontLanguageOverride, 4); + } elseif ($GPOSscriptTag && isset($ScriptLang[$GPOSscriptTag]) && $ScriptLang[$GPOSscriptTag] != '') { + $GPOSlangsys = $this->_getOTLLangTag($this->mpdf->currentLang, $ScriptLang[$GPOSscriptTag]); + } + } + + // This is just for the font_dump_OTL utility to set script and langsys override + // $mpdf->overrideOTLsettings does not exist, this is never called + /*if (isset($this->mpdf->overrideOTLsettings) && isset($this->mpdf->overrideOTLsettings[$this->fontkey])) { + $GSUBscriptTag = $GPOSscriptTag = $this->mpdf->overrideOTLsettings[$this->fontkey]['script']; + $GSUBlangsys = $GPOSlangsys = $this->mpdf->overrideOTLsettings[$this->fontkey]['lang']; + }*/ + + if (!$GSUBscriptTag && !$GSUBlangsys && !$GPOSscriptTag && !$GPOSlangsys) { + // Remove ZWJ and ZWNJ + for ($i = 0; $i < count($this->OTLdata); $i++) { + if ($this->OTLdata[$i]['uni'] == 8204 || $this->OTLdata[$i]['uni'] == 8205) { + array_splice($this->OTLdata, $i, 1); + } + } + $this->schOTLdata[$sch] = $this->OTLdata; + $this->OTLdata = []; + continue; + } + + // Don't use MYANMAR shaper unless using v2 scripttag + if ($this->shaper == 'M' && $GSUBscriptTag != 'mym2') { + $this->shaper = ''; + } + + $GSUBFeatures = (isset($this->mpdf->CurrentFont['GSUBFeatures'][$GSUBscriptTag][$GSUBlangsys]) ? $this->mpdf->CurrentFont['GSUBFeatures'][$GSUBscriptTag][$GSUBlangsys] : false); + $GPOSFeatures = (isset($this->mpdf->CurrentFont['GPOSFeatures'][$GPOSscriptTag][$GPOSlangsys]) ? $this->mpdf->CurrentFont['GPOSFeatures'][$GPOSscriptTag][$GPOSlangsys] : false); + + $this->assocLigs = []; // Ligatures[$posarr lpos] => nc + $this->assocMarks = []; // assocMarks[$posarr mpos] => array(compID, ligPos) + + if (!isset($this->GDEFdata[$this->fontkey]['GSUBGPOStables'])) { + $this->ttfOTLdata = $this->GDEFdata[$this->fontkey]['GSUBGPOStables'] = $this->fontCache->load($this->fontkey . '.GSUBGPOStables.dat', 'rb'); + if (!$this->ttfOTLdata) { + throw new \Mpdf\MpdfException('Can\'t open file ' . $this->fontCache->tempFilename($this->fontkey . '.GSUBGPOStables.dat')); + } + } else { + $this->ttfOTLdata = $this->GDEFdata[$this->fontkey]['GSUBGPOStables']; + } + + if ($this->debugOTL) { + $this->_dumpproc('BEGIN', '-', '-', '-', '-', -1, '-', 0); + } + + //////////////////////////////////////////////////////////////// + ///////// LINE BREAKING FOR KHMER, THAI + LAO ///////////////// + //////////////////////////////////////////////////////////////// + // Insert U+200B at word boundaries using dictionaries + if ($this->mpdf->useDictionaryLBR && ($this->shaper == "K" || $this->shaper == "T" || $this->shaper == "L")) { + // Sets $this->OTLdata[$i]['wordend']=true at possible end of word boundaries + $this->seaLineBreaking(); + } // Insert U+200B at word boundaries for Tibetan + elseif ($this->mpdf->useTibetanLBR && $scriptblock == Ucdn::SCRIPT_TIBETAN) { + // Sets $this->OTLdata[$i]['wordend']=true at possible end of word boundaries + $this->tibetanLineBreaking(); + } + + + //////////////////////////////////////////////////////////////// + ////////// GSUB ///////////////////////////////// + //////////////////////////////////////////////////////////////// + if (($useOTL & 0xFF) && $GSUBscriptTag && $GSUBlangsys && $GSUBFeatures) { + // 4. Load GSUB data, Coverage & Lookups + //================================================================= + + $this->GSUBfont = $this->fontkey . '.GSUB.' . $GSUBscriptTag . '.' . $GSUBlangsys; + + if (!isset($this->GSUBdata[$this->GSUBfont])) { + $fontCacheFilename = $this->GSUBfont . '.json'; + if ($this->fontCache->jsonHas($fontCacheFilename)) { + $font = $this->fontCache->jsonLoad($fontCacheFilename); + + $this->GSUBdata[$this->GSUBfont]['rtlSUB'] = $font['rtlSUB']; + $this->GSUBdata[$this->GSUBfont]['finals'] = $font['finals']; + if ($this->shaper == 'I') { + $this->GSUBdata[$this->GSUBfont]['rphf'] = $font['rphf']; + $this->GSUBdata[$this->GSUBfont]['half'] = $font['half']; + $this->GSUBdata[$this->GSUBfont]['pref'] = $font['pref']; + $this->GSUBdata[$this->GSUBfont]['blwf'] = $font['blwf']; + $this->GSUBdata[$this->GSUBfont]['pstf'] = $font['pstf']; + } + } else { + $this->GSUBdata[$this->GSUBfont] = ['rtlSUB' => [], 'rphf' => [], 'rphf' => [], + 'pref' => [], 'blwf' => [], 'pstf' => [], 'finals' => '' + ]; + } + } + + $fontCacheFilename = $this->fontkey . '.GSUBdata.json'; + if (!isset($this->GSUBdata[$this->fontkey]) && $this->fontCache->jsonHas($fontCacheFilename)) { + $this->GSLuCoverage = $this->GSUBdata[$this->fontkey]['GSLuCoverage'] = $this->fontCache->jsonLoad($fontCacheFilename); + } else { + $this->GSLuCoverage = $this->GSUBdata[$this->fontkey]['GSLuCoverage']; + } + + $this->GSUBLookups = $this->mpdf->CurrentFont['GSUBLookups']; + + + // 5(A). GSUB - Shaper - ARABIC + //============================== + if ($this->shaper == 'A') { + //----------------------------------------------------------------------------------- + // a. Apply initial GSUB Lookups (in order specified in lookup list but only selecting from certain tags) + //----------------------------------------------------------------------------------- + $tags = 'locl ccmp'; + $omittags = ''; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, true); + } + $this->_applyGSUBrules($usetags, $GSUBscriptTag, $GSUBlangsys); + + //----------------------------------------------------------------------------------- + // b. Apply context-specific forms GSUB Lookups (initial, isolated, medial, final) + //----------------------------------------------------------------------------------- + // Arab and Syriac are the only scripts requiring the special joining - which takes the place of + // isol fina medi init rules in GSUB (+ fin2 fin3 med2 in Syriac syrc) + $tags = 'isol fina fin2 fin3 medi med2 init'; + $omittags = ''; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, true); + } + + $this->arabGlyphs = $this->GSUBdata[$this->GSUBfont]['rtlSUB']; + + $gcms = explode("| ", $this->GlyphClassMarks); + $gcm = []; + foreach ($gcms as $g) { + $gcm[hexdec($g)] = 1; + } + $this->arabTransparentJoin = $this->arabTransparent + $gcm; + $this->arabic_shaper($usetags, $GSUBscriptTag); + + //----------------------------------------------------------------------------------- + // c. Set Kashida points (after joining occurred - medi, fina, init) but before other substitutions + //----------------------------------------------------------------------------------- + //if ($scriptblock == Ucdn::SCRIPT_ARABIC ) { + for ($i = 0; $i < count($this->OTLdata); $i++) { + // Put the kashida marker on the character BEFORE which is inserted the kashida + // Kashida marker is inverse of priority i.e. Priority 1 => 7, Priority 7 => 1. + // Priority 1 User-inserted Kashida 0640 = Tatweel + // The user entered a Kashida in a position + // Position: Before the user-inserted kashida + if ($this->OTLdata[$i]['uni'] == 0x0640) { + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 8; // Put before the next character + } // Priority 2 Seen (0633) FEB3, FEB4; Sad (0635) FEBB, FEBC + // Initial or medial form + // Connecting to the next character + // Position: After the character + elseif ($this->OTLdata[$i]['uni'] == 0xFEB3 || $this->OTLdata[$i]['uni'] == 0xFEB4 || $this->OTLdata[$i]['uni'] == 0xFEBB || $this->OTLdata[$i]['uni'] == 0xFEBC) { + $checkpos = $i + 1; + while (isset($this->OTLdata[$checkpos]) && strpos($this->GlyphClassMarks, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + if (isset($this->OTLdata[$checkpos])) { + $this->OTLdata[$checkpos]['GPOSinfo']['kashida'] = 7; // Put after marks on next character + } + } // Priority 3 Taa Marbutah (0629) FE94; Haa (062D) FEA2; Dal (062F) FEAA + // Final form + // Connecting to previous character + // Position: Before the character + elseif ($this->OTLdata[$i]['uni'] == 0xFE94 || $this->OTLdata[$i]['uni'] == 0xFEA2 || $this->OTLdata[$i]['uni'] == 0xFEAA) { + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 6; + } // Priority 4 Alef (0627) FE8E; Tah (0637) FEC2; Lam (0644) FEDE; Kaf (0643) FEDA; Gaf (06AF) FB93 + // Final form + // Connecting to previous character + // Position: Before the character + elseif ($this->OTLdata[$i]['uni'] == 0xFE8E || $this->OTLdata[$i]['uni'] == 0xFEC2 || $this->OTLdata[$i]['uni'] == 0xFEDE || $this->OTLdata[$i]['uni'] == 0xFEDA || $this->OTLdata[$i]['uni'] == 0xFB93) { + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 5; + } // Priority 5 RA (0631) FEAE; Ya (064A) FEF2 FEF4; Alef Maqsurah (0649) FEF0 FBE9 + // Final or Medial form + // Connected to preceding medial BAA (0628) = FE92 + // Position: Before preceding medial Baa + // Although not mentioned in spec, added Farsi Yeh (06CC) FBFD FBFF; equivalent to 064A or 0649 + elseif ($this->OTLdata[$i]['uni'] == 0xFEAE || $this->OTLdata[$i]['uni'] == 0xFEF2 || $this->OTLdata[$i]['uni'] == 0xFEF0 || $this->OTLdata[$i]['uni'] == 0xFEF4 || $this->OTLdata[$i]['uni'] == 0xFBE9 || $this->OTLdata[$i]['uni'] == 0xFBFD || $this->OTLdata[$i]['uni'] == 0xFBFF + ) { + $checkpos = $i - 1; + while (isset($this->OTLdata[$checkpos]) && strpos($this->GlyphClassMarks, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + if (isset($this->OTLdata[$checkpos]) && $this->OTLdata[$checkpos]['uni'] == 0xFE92) { + $this->OTLdata[$checkpos]['GPOSinfo']['kashida'] = 4; // ******* Before preceding BAA + } + } // Priority 6 WAW (0648) FEEE; Ain (0639) FECA; Qaf (0642) FED6; Fa (0641) FED2 + // Final form + // Connecting to previous character + // Position: Before the character + elseif ($this->OTLdata[$i]['uni'] == 0xFEEE || $this->OTLdata[$i]['uni'] == 0xFECA || $this->OTLdata[$i]['uni'] == 0xFED6 || $this->OTLdata[$i]['uni'] == 0xFED2) { + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 3; + } + + // Priority 7 Other connecting characters + // Final form + // Connecting to previous character + // Position: Before the character + /* This isn't in the spec, but using MS WORD as a basis, give a lower priority to the 3 characters already checked + in (5) above. Test case: + خْرَىٰ + فَتُذَكِّر + */ + + if (!isset($this->OTLdata[$i]['GPOSinfo']['kashida'])) { + if (strpos($this->GSUBdata[$this->GSUBfont]['finals'], $this->OTLdata[$i]['hex']) !== false) { // ANY OTHER FINAL FORM + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 2; + } elseif (strpos('0FEAE 0FEF0 0FEF2', $this->OTLdata[$i]['hex']) !== false) { // not already included in 5 above + $this->OTLdata[$i]['GPOSinfo']['kashida'] = 1; + } + } + } + + //----------------------------------------------------------------------------------- + // d. Apply Presentation Forms GSUB Lookups (+ any discretionary) - Apply one at a time in Feature order + //----------------------------------------------------------------------------------- + $tags = 'rlig calt liga clig mset'; + + $omittags = 'locl ccmp nukt akhn rphf rkrf pref blwf abvf half pstf cfar vatu cjct init medi fina isol med2 fin2 fin3 ljmo vjmo tjmo'; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, false); + } + + $ts = explode(' ', $usetags); + foreach ($ts as $ut) { // - Apply one at a time in Feature order + $this->_applyGSUBrules($ut, $GSUBscriptTag, $GSUBlangsys); + } + //----------------------------------------------------------------------------------- + // e. NOT IN SPEC + // If space precedes a mark -> substitute a   before the Mark, to prevent line breaking Test: + //----------------------------------------------------------------------------------- + for ($ptr = 1; $ptr < count($this->OTLdata); $ptr++) { + if ($this->OTLdata[$ptr]['general_category'] == Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK && $this->OTLdata[$ptr - 1]['uni'] == 32) { + $this->OTLdata[$ptr - 1]['uni'] = 0xa0; + $this->OTLdata[$ptr - 1]['hex'] = '000A0'; + } + } + } // 5(I). GSUB - Shaper - INDIC and SINHALA and KHMER + //=================================== + elseif ($this->shaper == 'I' || $this->shaper == 'K' || $this->shaper == 'S') { + $this->restrictToSyllable = true; + //----------------------------------------------------------------------------------- + // a. First decompose/compose split mattras + // (normalize) ??????? Nukta/Halant order etc ?????????????????????????????????????????????????????????????????????????? + //----------------------------------------------------------------------------------- + for ($ptr = 0; $ptr < count($this->OTLdata); $ptr++) { + $char = $this->OTLdata[$ptr]['uni']; + $sub = Indic::decompose_indic($char); + if ($sub) { + $newinfo = []; + for ($i = 0; $i < count($sub); $i++) { + $newinfo[$i] = []; + $ucd_record = Ucdn::get_ucd_record($sub[$i]); + $newinfo[$i]['general_category'] = $ucd_record[0]; + $newinfo[$i]['bidi_type'] = $ucd_record[2]; + $charasstr = $this->unicode_hex($sub[$i]); + if (strpos($this->GlyphClassMarks, $charasstr) !== false) { + $newinfo[$i]['group'] = 'M'; + } else { + $newinfo[$i]['group'] = 'C'; + } + $newinfo[$i]['uni'] = $sub[$i]; + $newinfo[$i]['hex'] = $charasstr; + } + array_splice($this->OTLdata, $ptr, 1, $newinfo); + $ptr += count($sub) - 1; + } + /* Only Composition-exclusion exceptions that we want to recompose. */ + if ($this->shaper == 'I') { + if ($char == 0x09AF && isset($this->OTLdata[$ptr + 1]) && $this->OTLdata[$ptr + 1]['uni'] == 0x09BC) { + $sub = 0x09DF; + $newinfo = []; + $newinfo[0] = []; + $ucd_record = Ucdn::get_ucd_record($sub); + $newinfo[0]['general_category'] = $ucd_record[0]; + $newinfo[0]['bidi_type'] = $ucd_record[2]; + $newinfo[0]['group'] = 'C'; + $newinfo[0]['uni'] = $sub; + $newinfo[0]['hex'] = $this->unicode_hex($sub); + array_splice($this->OTLdata, $ptr, 2, $newinfo); + } + } + } + //----------------------------------------------------------------------------------- + // b. Analyse characters - group as syllables/clusters (Indic); invalid diacritics; add dotted circle + //----------------------------------------------------------------------------------- + $indic_category_string = ''; + foreach ($this->OTLdata as $eid => $c) { + Indic::set_indic_properties($this->OTLdata[$eid], $scriptblock); // sets ['indic_category'] and ['indic_position'] + //$c['general_category'] + //$c['combining_class'] + //$c['uni'] = $char; + + $indic_category_string .= Indic::$indic_category_char[$this->OTLdata[$eid]['indic_category']]; + } + + $broken_syllables = false; + if ($this->shaper == 'I') { + Indic::set_syllables($this->OTLdata, $indic_category_string, $broken_syllables); + } elseif ($this->shaper == 'S') { + Indic::set_syllables_sinhala($this->OTLdata, $indic_category_string, $broken_syllables); + } elseif ($this->shaper == 'K') { + Indic::set_syllables_khmer($this->OTLdata, $indic_category_string, $broken_syllables); + } + $indic_category_string = ''; + + //----------------------------------------------------------------------------------- + // c. Initial Re-ordering (Indic / Khmer / Sinhala) + //----------------------------------------------------------------------------------- + // Find base consonant + // Decompose/compose and reorder Matras + // Reorder marks to canonical order + + $indic_config = Indic::$indic_configs[$scriptblock]; + $dottedcircle = false; + if ($broken_syllables) { + if ($this->mpdf->_charDefined($this->mpdf->fonts[$this->fontkey]['cw'], 0x25CC)) { + $dottedcircle = []; + $ucd_record = Ucdn::get_ucd_record(0x25CC); + $dottedcircle[0]['general_category'] = $ucd_record[0]; + $dottedcircle[0]['bidi_type'] = $ucd_record[2]; + $dottedcircle[0]['group'] = 'C'; + $dottedcircle[0]['uni'] = 0x25CC; + $dottedcircle[0]['indic_category'] = Indic::OT_DOTTEDCIRCLE; + $dottedcircle[0]['indic_position'] = Indic::POS_BASE_C; + + $dottedcircle[0]['hex'] = '025CC'; // TEMPORARY ***** + } + } + Indic::initial_reordering($this->OTLdata, $this->GSUBdata[$this->GSUBfont], $broken_syllables, $indic_config, $scriptblock, $is_old_spec, $dottedcircle); + + //----------------------------------------------------------------------------------- + // d. Apply initial and basic shaping forms GSUB Lookups (one at a time) + //----------------------------------------------------------------------------------- + if ($this->shaper == 'I' || $this->shaper == 'S') { + $tags = 'locl ccmp nukt akhn rphf rkrf pref blwf half pstf vatu cjct'; + } elseif ($this->shaper == 'K') { + $tags = 'locl ccmp pref blwf abvf pstf cfar'; + } + $this->_applyGSUBrulesIndic($tags, $GSUBscriptTag, $GSUBlangsys, $is_old_spec); + + //----------------------------------------------------------------------------------- + // e. Final Re-ordering (Indic / Khmer / Sinhala) + //----------------------------------------------------------------------------------- + // Reorder matras + // Reorder reph + // Reorder pre-base reordering consonants: + + Indic::final_reordering($this->OTLdata, $this->GSUBdata[$this->GSUBfont], $indic_config, $scriptblock, $is_old_spec); + + //----------------------------------------------------------------------------------- + // f. Apply 'init' feature to first syllable in word (indicated by ['mask']) Indic::FLAG(Indic::INIT); + //----------------------------------------------------------------------------------- + if ($this->shaper == 'I' || $this->shaper == 'S') { + $tags = 'init'; + $this->_applyGSUBrulesIndic($tags, $GSUBscriptTag, $GSUBlangsys, $is_old_spec); + } + + //----------------------------------------------------------------------------------- + // g. Apply Presentation Forms GSUB Lookups (+ any discretionary) + //----------------------------------------------------------------------------------- + $tags = 'pres abvs blws psts haln rlig calt liga clig mset'; + + $omittags = 'locl ccmp nukt akhn rphf rkrf pref blwf abvf half pstf cfar vatu cjct init medi fina isol med2 fin2 fin3 ljmo vjmo tjmo'; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, false); + } + if ($this->shaper == 'K') { // Features are applied one at a time, working through each codepoint + $this->_applyGSUBrulesSingly($usetags, $GSUBscriptTag, $GSUBlangsys); + } else { + $this->_applyGSUBrules($usetags, $GSUBscriptTag, $GSUBlangsys); + } + $this->restrictToSyllable = false; + } // 5(M). GSUB - Shaper - MYANMAR (ONLY mym2) + //============================== + // NB Old style 'mymr' is left to go through the default shaper + elseif ($this->shaper == 'M') { + $this->restrictToSyllable = true; + //----------------------------------------------------------------------------------- + // a. Analyse characters - group as syllables/clusters (Myanmar); invalid diacritics; add dotted circle + //----------------------------------------------------------------------------------- + $myanmar_category_string = ''; + foreach ($this->OTLdata as $eid => $c) { + Myanmar::set_myanmar_properties($this->OTLdata[$eid]); // sets ['myanmar_category'] and ['myanmar_position'] + $myanmar_category_string .= Myanmar::$myanmar_category_char[$this->OTLdata[$eid]['myanmar_category']]; + } + $broken_syllables = false; + Myanmar::set_syllables($this->OTLdata, $myanmar_category_string, $broken_syllables); + $myanmar_category_string = ''; + + //----------------------------------------------------------------------------------- + // b. Re-ordering (Myanmar mym2) + //----------------------------------------------------------------------------------- + $dottedcircle = false; + if ($broken_syllables) { + if ($this->mpdf->_charDefined($this->mpdf->fonts[$this->fontkey]['cw'], 0x25CC)) { + $dottedcircle = []; + $ucd_record = Ucdn::get_ucd_record(0x25CC); + $dottedcircle[0]['general_category'] = $ucd_record[0]; + $dottedcircle[0]['bidi_type'] = $ucd_record[2]; + $dottedcircle[0]['group'] = 'C'; + $dottedcircle[0]['uni'] = 0x25CC; + $dottedcircle[0]['myanmar_category'] = Myanmar::OT_DOTTEDCIRCLE; + $dottedcircle[0]['myanmar_position'] = Myanmar::POS_BASE_C; + $dottedcircle[0]['hex'] = '025CC'; + } + } + Myanmar::reordering($this->OTLdata, $this->GSUBdata[$this->GSUBfont], $broken_syllables, $dottedcircle); + + //----------------------------------------------------------------------------------- + // c. Apply initial and basic shaping forms GSUB Lookups (one at a time) + //----------------------------------------------------------------------------------- + + $tags = 'locl ccmp rphf pref blwf pstf'; + $this->_applyGSUBrulesMyanmar($tags, $GSUBscriptTag, $GSUBlangsys); + + //----------------------------------------------------------------------------------- + // d. Apply Presentation Forms GSUB Lookups (+ any discretionary) + //----------------------------------------------------------------------------------- + $tags = 'pres abvs blws psts haln rlig calt liga clig mset'; + $omittags = 'locl ccmp nukt akhn rphf rkrf pref blwf abvf half pstf cfar vatu cjct init medi fina isol med2 fin2 fin3 ljmo vjmo tjmo'; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, false); + } + $this->_applyGSUBrules($usetags, $GSUBscriptTag, $GSUBlangsys); + $this->restrictToSyllable = false; + } // 5(E). GSUB - Shaper - SEA South East Asian (New Tai Lue, Cham, Tai Tam) + //============================== + elseif ($this->shaper == 'E') { + /* HarfBuzz says: If the designer designed the font for the 'DFLT' script, + * use the default shaper. Otherwise, use the SEA shaper. + * Note that for some simple scripts, there may not be *any* + * GSUB/GPOS needed, so there may be no scripts found! */ + + $this->restrictToSyllable = true; + //----------------------------------------------------------------------------------- + // a. Analyse characters - group as syllables/clusters (Indic); invalid diacritics; add dotted circle + //----------------------------------------------------------------------------------- + $sea_category_string = ''; + foreach ($this->OTLdata as $eid => $c) { + Sea::set_sea_properties($this->OTLdata[$eid], $scriptblock); // sets ['sea_category'] and ['sea_position'] + //$c['general_category'] + //$c['combining_class'] + //$c['uni'] = $char; + + $sea_category_string .= Sea::$sea_category_char[$this->OTLdata[$eid]['sea_category']]; + } + + $broken_syllables = false; + Sea::set_syllables($this->OTLdata, $sea_category_string, $broken_syllables); + $sea_category_string = ''; + + //----------------------------------------------------------------------------------- + // b. Apply locl and ccmp shaping forms - before initial re-ordering; GSUB Lookups (one at a time) + //----------------------------------------------------------------------------------- + $tags = 'locl ccmp'; + $this->_applyGSUBrulesSingly($tags, $GSUBscriptTag, $GSUBlangsys); + + //----------------------------------------------------------------------------------- + // c. Initial Re-ordering + //----------------------------------------------------------------------------------- + // Find base consonant + // Decompose/compose and reorder Matras + // Reorder marks to canonical order + + $dottedcircle = false; + if ($broken_syllables) { + if ($this->mpdf->_charDefined($this->mpdf->fonts[$this->fontkey]['cw'], 0x25CC)) { + $dottedcircle = []; + $ucd_record = Ucdn::get_ucd_record(0x25CC); + $dottedcircle[0]['general_category'] = $ucd_record[0]; + $dottedcircle[0]['bidi_type'] = $ucd_record[2]; + $dottedcircle[0]['group'] = 'C'; + $dottedcircle[0]['uni'] = 0x25CC; + $dottedcircle[0]['sea_category'] = Sea::OT_GB; + $dottedcircle[0]['sea_position'] = Sea::POS_BASE_C; + + $dottedcircle[0]['hex'] = '025CC'; // TEMPORARY ***** + } + } + Sea::initial_reordering($this->OTLdata, $this->GSUBdata[$this->GSUBfont], $broken_syllables, $scriptblock, $dottedcircle); + + //----------------------------------------------------------------------------------- + // d. Apply basic shaping forms GSUB Lookups (one at a time) + //----------------------------------------------------------------------------------- + $tags = 'pref abvf blwf pstf'; + $this->_applyGSUBrulesSingly($tags, $GSUBscriptTag, $GSUBlangsys); + + //----------------------------------------------------------------------------------- + // e. Final Re-ordering + //----------------------------------------------------------------------------------- + + Sea::final_reordering($this->OTLdata, $this->GSUBdata[$this->GSUBfont], $scriptblock); + + //----------------------------------------------------------------------------------- + // f. Apply Presentation Forms GSUB Lookups (+ any discretionary) + //----------------------------------------------------------------------------------- + $tags = 'pres abvs blws psts'; + + $omittags = 'locl ccmp nukt akhn rphf rkrf pref blwf abvf half pstf cfar vatu cjct init medi fina isol med2 fin2 fin3 ljmo vjmo tjmo'; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, false); + } + $this->_applyGSUBrules($usetags, $GSUBscriptTag, $GSUBlangsys); + $this->restrictToSyllable = false; + } // 5(D). GSUB - Shaper - DEFAULT (including THAI and LAO and MYANMAR v1 [mymr] and TIBETAN) + //============================== + else { // DEFAULT + //----------------------------------------------------------------------------------- + // a. First decompose/compose in Thai / Lao - Tibetan + //----------------------------------------------------------------------------------- + // Decomposition for THAI or LAO + /* This function implements the shaping logic documented here: + * + * http://linux.thai.net/~thep/th-otf/shaping.html + * + * The first shaping rule listed there is needed even if the font has Thai + * OpenType tables. + * + * + * The following is NOT specified in the MS OT Thai spec, however, it seems + * to be what Uniscribe and other engines implement. According to Eric Muller: + * + * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the + * NIKHAHIT backwards over any tone mark (0E48-0E4B). + * + * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32> + * + * This reordering is legit only when the NIKHAHIT comes from a SARA AM, not + * when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably + * not what a user wanted, but the rendering is nevertheless nikhahit above + * chattawa. + * + * Same for Lao. + * + * Thai Lao + * SARA AM: U+0E33 U+0EB3 + * SARA AA: U+0E32 U+0EB2 + * Nikhahit: U+0E4D U+0ECD + * + * Testing shows that Uniscribe reorder the following marks: + * Thai: <0E31,0E34..0E37,0E47..0E4E> + * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE> + * + * Lao versions are the same as Thai + 0x80. + */ + if ($this->shaper == 'T' || $this->shaper == 'L') { + for ($ptr = 0; $ptr < count($this->OTLdata); $ptr++) { + $char = $this->OTLdata[$ptr]['uni']; + if (($char & ~0x0080) == 0x0E33) { // if SARA_AM (U+0E33 or U+0EB3) + $NIKHAHIT = $char + 0x1A; + $SARA_AA = $char - 1; + $sub = [$SARA_AA, $NIKHAHIT]; + + $newinfo = []; + $ucd_record = Ucdn::get_ucd_record($sub[0]); + $newinfo[0]['general_category'] = $ucd_record[0]; + $newinfo[0]['bidi_type'] = $ucd_record[2]; + $charasstr = $this->unicode_hex($sub[0]); + if (strpos($this->GlyphClassMarks, $charasstr) !== false) { + $newinfo[0]['group'] = 'M'; + } else { + $newinfo[0]['group'] = 'C'; + } + $newinfo[0]['uni'] = $sub[0]; + $newinfo[0]['hex'] = $charasstr; + $this->OTLdata[$ptr] = $newinfo[0]; // Substitute SARA_AM => SARA_AA + + $ntones = 0; // number of (preceding) tone marks + // IS_TONE_MARK ((x) & ~0x0080, 0x0E34 - 0x0E37, 0x0E47 - 0x0E4E, 0x0E31) + while (isset($this->OTLdata[$ptr - 1 - $ntones]) && ( + ($this->OTLdata[$ptr - 1 - $ntones]['uni'] & ~0x0080) == 0x0E31 || + (($this->OTLdata[$ptr - 1 - $ntones]['uni'] & ~0x0080) >= 0x0E34 && + ($this->OTLdata[$ptr - 1 - $ntones]['uni'] & ~0x0080) <= 0x0E37) || + (($this->OTLdata[$ptr - 1 - $ntones]['uni'] & ~0x0080) >= 0x0E47 && + ($this->OTLdata[$ptr - 1 - $ntones]['uni'] & ~0x0080) <= 0x0E4E) + ) + ) { + $ntones++; + } + + $newinfo = []; + $ucd_record = Ucdn::get_ucd_record($sub[1]); + $newinfo[0]['general_category'] = $ucd_record[0]; + $newinfo[0]['bidi_type'] = $ucd_record[2]; + $charasstr = $this->unicode_hex($sub[1]); + if (strpos($this->GlyphClassMarks, $charasstr) !== false) { + $newinfo[0]['group'] = 'M'; + } else { + $newinfo[0]['group'] = 'C'; + } + $newinfo[0]['uni'] = $sub[1]; + $newinfo[0]['hex'] = $charasstr; + // Insert NIKAHIT + array_splice($this->OTLdata, $ptr - $ntones, 0, $newinfo); + + $ptr++; + } + } + } + + if ($scriptblock == Ucdn::SCRIPT_TIBETAN) { + // ========================= + // Reordering TIBETAN + // ========================= + // Tibetan does not need to need a shaper generally, as long as characters are presented in the correct order + // so we will do one minor change here: + // From ICU: If the present character is a number, and the next character is a pre-number combining mark + // then the two characters are reordered + // From MS OTL spec the following are Digit modifiers (Md): 0F18–0F19, 0F3E–0F3F + // Digits: 0F20–0F33 + // On testing only 0x0F3F (pre-based mark) seems to need re-ordering + for ($ptr = 0; $ptr < count($this->OTLdata) - 1; $ptr++) { + if (Indic::in_range($this->OTLdata[$ptr]['uni'], 0x0F20, 0x0F33) && $this->OTLdata[$ptr + 1]['uni'] == 0x0F3F) { + $tmp = $this->OTLdata[$ptr + 1]; + $this->OTLdata[$ptr + 1] = $this->OTLdata[$ptr]; + $this->OTLdata[$ptr] = $tmp; + } + } + + + // ========================= + // Decomposition for TIBETAN + // ========================= + /* Recommended, but does not seem to change anything... + for($ptr=0; $ptr<count($this->OTLdata); $ptr++) { + $char = $this->OTLdata[$ptr]['uni']; + $sub = Indic::decompose_indic($char); + if ($sub) { + $newinfo = array(); + for($i=0;$i<count($sub);$i++) { + $newinfo[$i] = array(); + $ucd_record = Ucdn::get_ucd_record($sub[$i]); + $newinfo[$i]['general_category'] = $ucd_record[0]; + $newinfo[$i]['bidi_type'] = $ucd_record[2]; + $charasstr = $this->unicode_hex($sub[$i]); + if (strpos($this->GlyphClassMarks, $charasstr)!==false) { $newinfo[$i]['group'] = 'M'; } + else { $newinfo[$i]['group'] = 'C'; } + $newinfo[$i]['uni'] = $sub[$i]; + $newinfo[$i]['hex'] = $charasstr; + } + array_splice($this->OTLdata, $ptr, 1, $newinfo); + $ptr += count($sub)-1; + } + } + */ + } + + + //----------------------------------------------------------------------------------- + // b. Apply all GSUB Lookups (in order specified in lookup list) + //----------------------------------------------------------------------------------- + $tags = 'locl ccmp pref blwf abvf pstf pres abvs blws psts haln rlig calt liga clig mset RQD'; + // pref blwf abvf pstf required for Tibetan + // " RQD" is a non-standard tag in Garuda font - presumably intended to be used by default ? "ReQuireD" + // Being a 3 letter tag is non-standard, and does not allow it to be set by font-feature-settings + + + /* ?Add these until shapers witten? + Hangul: ljmo vjmo tjmo + */ + + $omittags = ''; + $useGSUBtags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $useGSUBtags = $this->_applyTagSettings($tags, $GSUBFeatures, $omittags, false); + } + // APPLY GSUB rules (as long as not Latin + SmallCaps - but not OTL smcp) + if (!(($this->mpdf->textvar & TextVars::FC_SMALLCAPS) && $scriptblock == Ucdn::SCRIPT_LATIN && strpos($useGSUBtags, 'smcp') === false)) { + $this->_applyGSUBrules($useGSUBtags, $GSUBscriptTag, $GSUBlangsys); + } + } + } + + // Shapers - KHMER & THAI & LAO - Replace Word boundary marker with U+200B + // Also TIBETAN (no shaper) + //======================================================= + if (($this->shaper == "K" || $this->shaper == "T" || $this->shaper == "L") || $scriptblock == Ucdn::SCRIPT_TIBETAN) { + // Set up properties to insert a U+200B character + $newinfo = []; + //$newinfo[0] = array('general_category' => 1, 'bidi_type' => 14, 'group' => 'S', 'uni' => 0x200B, 'hex' => '0200B'); + $newinfo[0] = [ + 'general_category' => Ucdn::UNICODE_GENERAL_CATEGORY_FORMAT, + 'bidi_type' => Ucdn::BIDI_CLASS_BN, + 'group' => 'S', 'uni' => 0x200B, 'hex' => '0200B']; + // Then insert U+200B at (after) all word end boundaries + for ($i = count($this->OTLdata) - 1; $i > 0; $i--) { + // Make sure after GSUB that wordend has not been moved - check next char is not in the same syllable + if (isset($this->OTLdata[$i]['wordend']) && $this->OTLdata[$i]['wordend'] && + isset($this->OTLdata[$i + 1]['uni']) && (!isset($this->OTLdata[$i + 1]['syllable']) || !isset($this->OTLdata[$i + 1]['syllable']) || $this->OTLdata[$i + 1]['syllable'] != $this->OTLdata[$i]['syllable'])) { + array_splice($this->OTLdata, $i + 1, 0, $newinfo); + $this->_updateLigatureMarks($i, 1); + } elseif ($this->OTLdata[$i]['uni'] == 0x2e) { // Word end if Full-stop. + array_splice($this->OTLdata, $i + 1, 0, $newinfo); + $this->_updateLigatureMarks($i, 1); + } + } + } + + + // Shapers - INDIC & ARABIC & KHMER & SINHALA & MYANMAR - Remove ZWJ and ZWNJ + //======================================================= + if ($this->shaper == 'I' || $this->shaper == 'S' || $this->shaper == 'A' || $this->shaper == 'K' || $this->shaper == 'M') { + // Remove ZWJ and ZWNJ + for ($i = 0; $i < count($this->OTLdata); $i++) { + if ($this->OTLdata[$i]['uni'] == 8204 || $this->OTLdata[$i]['uni'] == 8205) { + array_splice($this->OTLdata, $i, 1); + $this->_updateLigatureMarks($i, -1); + } + } + } + + + //////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////// + ////////// GPOS ///////////////////////////////// + //////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////// + if (($useOTL & 0xFF) && $GPOSscriptTag && $GPOSlangsys && $GPOSFeatures) { + $this->Entry = []; + $this->Exit = []; + + // 6. Load GPOS data, Coverage & Lookups + //================================================================= + $fontCacheFilename = $this->mpdf->CurrentFont['fontkey'] . '.GPOSdata.json'; + if (!isset($this->GPOSdata[$this->fontkey]) && $this->fontCache->jsonHas($fontCacheFilename)) { + $this->LuCoverage = $this->GPOSdata[$this->fontkey]['LuCoverage'] = $this->fontCache->jsonLoad($fontCacheFilename); + } else { + $this->LuCoverage = $this->GPOSdata[$this->fontkey]['LuCoverage']; + } + + $this->GPOSLookups = $this->mpdf->CurrentFont['GPOSLookups']; + + + // 7. Select Feature tags to use (incl optional) + //============================== + $tags = 'abvm blwm mark mkmk curs cpsp dist requ'; // Default set + // 'requ' is not listed in the Microsoft registry of Feature tags + // Found in Arial Unicode MS, it repositions the baseline for punctuation in Kannada script + + // ZZZ96 + // Set kern to be included by default in non-Latin script (? just when shapers used) + // Kern is used in some fonts to reposition marks etc. and is essential for correct display + //if ($this->shaper) {$tags .= ' kern'; } + if ($scriptblock != Ucdn::SCRIPT_LATIN) { + $tags .= ' kern'; + } + + $omittags = ''; + $usetags = $tags; + if (!empty($this->mpdf->OTLtags)) { + $usetags = $this->_applyTagSettings($tags, $GPOSFeatures, $omittags, false); + } + + + + // 8. Get GPOS LookupList from Feature tags + //============================== + $LookupList = []; + foreach ($GPOSFeatures as $tag => $arr) { + if (strpos($usetags, $tag) !== false) { + foreach ($arr as $lu) { + $LookupList[$lu] = $tag; + } + } + } + ksort($LookupList); + + + // 9. Apply GPOS Lookups (in order specified in lookup list but selecting from specified tags) + //============================== + // APPLY THE GPOS RULES (as long as not Latin + SmallCaps - but not OTL smcp) + if (!(($this->mpdf->textvar & TextVars::FC_SMALLCAPS) && $scriptblock == Ucdn::SCRIPT_LATIN && strpos($useGSUBtags, 'smcp') === false)) { + $this->_applyGPOSrules($LookupList, $is_old_spec); + // (sets: $this->OTLdata[n]['GPOSinfo'] XPlacement YPlacement XAdvance Entry Exit ) + } + + // 10. Process cursive text + //============================== + if (count($this->Entry) || count($this->Exit)) { + // RTL + $incurs = false; + for ($i = (count($this->OTLdata) - 1); $i >= 0; $i--) { + if (isset($this->Entry[$i]) && isset($this->Entry[$i]['Y']) && $this->Entry[$i]['dir'] == 'RTL') { + $nextbase = $i - 1; // Set as next base ignoring marks (next base reading RTL in logical oder + while (isset($this->OTLdata[$nextbase]['hex']) && strpos($this->GlyphClassMarks, $this->OTLdata[$nextbase]['hex']) !== false) { + $nextbase--; + } + if (isset($this->Exit[$nextbase]) && isset($this->Exit[$nextbase]['Y'])) { + $diff = $this->Entry[$i]['Y'] - $this->Exit[$nextbase]['Y']; + if ($incurs === false) { + $incurs = $diff; + } else { + $incurs += $diff; + } + for ($j = ($i - 1); $j >= $nextbase; $j--) { + if (isset($this->OTLdata[$j]['GPOSinfo']['YPlacement'])) { + $this->OTLdata[$j]['GPOSinfo']['YPlacement'] += $incurs; + } else { + $this->OTLdata[$j]['GPOSinfo']['YPlacement'] = $incurs; + } + } + if (isset($this->Exit[$i]['X']) && isset($this->Entry[$nextbase]['X'])) { + $adj = -($this->Entry[$i]['X'] - $this->Exit[$nextbase]['X']); + // If XAdvance is aplied - in order for PDF to position the Advance correctly need to place it on: + // in RTL - the current glyph or the last of any associated marks + if (isset($this->OTLdata[$nextbase + 1]['GPOSinfo']['XAdvance'])) { + $this->OTLdata[$nextbase + 1]['GPOSinfo']['XAdvance'] += $adj; + } else { + $this->OTLdata[$nextbase + 1]['GPOSinfo']['XAdvance'] = $adj; + } + } + } else { + $incurs = false; + } + } elseif (strpos($this->GlyphClassMarks, $this->OTLdata[$i]['hex']) !== false) { + continue; + } // ignore Marks + else { + $incurs = false; + } + } + // LTR + $incurs = false; + for ($i = 0; $i < count($this->OTLdata); $i++) { + if (isset($this->Exit[$i]) && isset($this->Exit[$i]['Y']) && $this->Exit[$i]['dir'] == 'LTR') { + $nextbase = $i + 1; // Set as next base ignoring marks + while (strpos($this->GlyphClassMarks, $this->OTLdata[$nextbase]['hex']) !== false) { + $nextbase++; + } + if (isset($this->Entry[$nextbase]) && isset($this->Entry[$nextbase]['Y'])) { + $diff = $this->Exit[$i]['Y'] - $this->Entry[$nextbase]['Y']; + if ($incurs === false) { + $incurs = $diff; + } else { + $incurs += $diff; + } + for ($j = ($i + 1); $j <= $nextbase; $j++) { + if (isset($this->OTLdata[$j]['GPOSinfo']['YPlacement'])) { + $this->OTLdata[$j]['GPOSinfo']['YPlacement'] += $incurs; + } else { + $this->OTLdata[$j]['GPOSinfo']['YPlacement'] = $incurs; + } + } + if (isset($this->Exit[$i]['X']) && isset($this->Entry[$nextbase]['X'])) { + $adj = -($this->Exit[$i]['X'] - $this->Entry[$nextbase]['X']); + // If XAdvance is aplied - in order for PDF to position the Advance correctly need to place it on: + // in LTR - the next glyph, ignoring marks + if (isset($this->OTLdata[$nextbase]['GPOSinfo']['XAdvance'])) { + $this->OTLdata[$nextbase]['GPOSinfo']['XAdvance'] += $adj; + } else { + $this->OTLdata[$nextbase]['GPOSinfo']['XAdvance'] = $adj; + } + } + } else { + $incurs = false; + } + } elseif (strpos($this->GlyphClassMarks, $this->OTLdata[$i]['hex']) !== false) { + continue; + } // ignore Marks + else { + $incurs = false; + } + } + } + } // end GPOS + + if ($this->debugOTL) { + $this->_dumpproc('END', '-', '-', '-', '-', 0, '-', 0); + exit; + } + + $this->schOTLdata[$sch] = $this->OTLdata; + $this->OTLdata = []; + } // END foreach subchunk + // 11. Re-assemble and return text string + //============================== + $newGPOSinfo = []; + $newOTLdata = []; + $newchar_data = []; + $newgroup = ''; + $e = ''; + $ectr = 0; + + for ($sch = 0; $sch <= $subchunk; $sch++) { + for ($i = 0; $i < count($this->schOTLdata[$sch]); $i++) { + if (isset($this->schOTLdata[$sch][$i]['GPOSinfo'])) { + $newGPOSinfo[$ectr] = $this->schOTLdata[$sch][$i]['GPOSinfo']; + } + $newchar_data[$ectr] = ['bidi_class' => $this->schOTLdata[$sch][$i]['bidi_type'], 'uni' => $this->schOTLdata[$sch][$i]['uni']]; + $newgroup .= $this->schOTLdata[$sch][$i]['group']; + $e .= UtfString::code2utf($this->schOTLdata[$sch][$i]['uni']); + if (isset($this->mpdf->CurrentFont['subset'])) { + $this->mpdf->CurrentFont['subset'][$this->schOTLdata[$sch][$i]['uni']] = $this->schOTLdata[$sch][$i]['uni']; + } + $ectr++; + } + } + $this->OTLdata['GPOSinfo'] = $newGPOSinfo; + $this->OTLdata['char_data'] = $newchar_data; + $this->OTLdata['group'] = $newgroup; + + // This leaves OTLdata::GPOSinfo, ::bidi_type, & ::group + + return $e; + } + + function _applyTagSettings($tags, $Features, $omittags = '', $onlytags = false) + { + if (empty($this->mpdf->OTLtags['Plus']) && empty($this->mpdf->OTLtags['Minus']) && empty($this->mpdf->OTLtags['FFPlus']) && empty($this->mpdf->OTLtags['FFMinus'])) { + return $tags; + } + + // Use $tags as starting point + $usetags = $tags; + + // Only set / unset tags which are in the font + // Ignore tags which are in $omittags + // If $onlytags, then just unset tags which are already in the Tag list + + $fp = $fm = $ffp = $ffm = ''; + + // Font features to enable - set by font-variant-xx + if (isset($this->mpdf->OTLtags['Plus'])) { + $fp = $this->mpdf->OTLtags['Plus']; + } + preg_match_all('/([a-zA-Z0-9]{4})/', $fp, $m); + for ($i = 0; $i < count($m[0]); $i++) { + $t = $m[1][$i]; + // Is it a valid tag? + if (isset($Features[$t]) && strpos($omittags, $t) === false && (!$onlytags || strpos($tags, $t) !== false )) { + $usetags .= ' ' . $t; + } + } + + // Font features to disable - set by font-variant-xx + if (isset($this->mpdf->OTLtags['Minus'])) { + $fm = $this->mpdf->OTLtags['Minus']; + } + preg_match_all('/([a-zA-Z0-9]{4})/', $fm, $m); + for ($i = 0; $i < count($m[0]); $i++) { + $t = $m[1][$i]; + // Is it a valid tag? + if (isset($Features[$t]) && strpos($omittags, $t) === false && (!$onlytags || strpos($tags, $t) !== false )) { + $usetags = str_replace($t, '', $usetags); + } + } + + // Font features to enable - set by font-feature-settings + if (isset($this->mpdf->OTLtags['FFPlus'])) { + $ffp = $this->mpdf->OTLtags['FFPlus']; // Font Features - may include integer: salt4 + } + preg_match_all('/([a-zA-Z0-9]{4})([\d+]*)/', $ffp, $m); + for ($i = 0; $i < count($m[0]); $i++) { + $t = $m[1][$i]; + // Is it a valid tag? + if (isset($Features[$t]) && strpos($omittags, $t) === false && (!$onlytags || strpos($tags, $t) !== false )) { + $usetags .= ' ' . $m[0][$i]; // - may include integer: salt4 + } + } + + // Font features to disable - set by font-feature-settings + if (isset($this->mpdf->OTLtags['FFMinus'])) { + $ffm = $this->mpdf->OTLtags['FFMinus']; + } + preg_match_all('/([a-zA-Z0-9]{4})/', $ffm, $m); + for ($i = 0; $i < count($m[0]); $i++) { + $t = $m[1][$i]; + // Is it a valid tag? + if (isset($Features[$t]) && strpos($omittags, $t) === false && (!$onlytags || strpos($tags, $t) !== false )) { + $usetags = str_replace($t, '', $usetags); + } + } + return $usetags; + } + + function _applyGSUBrules($usetags, $scriptTag, $langsys) + { + // Features from all Tags are applied together, in Lookup List order. + // For Indic - should be applied one syllable at a time + // - Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable' + // if $this->restrictToSyllable is true + + $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys]; + $LookupList = []; + foreach ($GSUBFeatures as $tag => $arr) { + if (strpos($usetags, $tag) !== false) { + foreach ($arr as $lu) { + $LookupList[$lu] = $tag; + } + } + } + ksort($LookupList); + + foreach ($LookupList as $lu => $tag) { + $Type = $this->GSUBLookups[$lu]['Type']; + $Flag = $this->GSUBLookups[$lu]['Flag']; + $MarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + $tagInt = 1; + if (preg_match('/' . $tag . '([0-9]{1,2})/', $usetags, $m)) { + $tagInt = $m[1]; + } + $ptr = 0; + // Test each glyph sequentially + while ($ptr < (count($this->OTLdata))) { // whilst there is another glyph ..0064 + $currGlyph = $this->OTLdata[$ptr]['hex']; + $currGID = $this->OTLdata[$ptr]['uni']; + $shift = 1; + foreach ($this->GSUBLookups[$lu]['Subtables'] as $c => $subtable_offset) { + // NB Coverage only looks at glyphs for position 1 (esp. 7.3 and 8.3) + if (isset($this->GSLuCoverage[$lu][$c][$currGID])) { + // Get rules from font GSUB subtable + $shift = $this->_applyGSUBsubtable($lu, $c, $ptr, $currGlyph, $currGID, ($subtable_offset - $this->GSUB_offset), $Type, $Flag, $MarkFilteringSet, $this->GSLuCoverage[$lu][$c], 0, $tag, 0, $tagInt); + + if ($shift) { + break; + } + } + } + if ($shift == 0) { + $shift = 1; + } + $ptr += $shift; + } + } + } + + function _applyGSUBrulesSingly($usetags, $scriptTag, $langsys) + { + // Features are applied one at a time, working through each codepoint + + $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys]; + + $tags = explode(' ', $usetags); + foreach ($tags as $usetag) { + $LookupList = []; + foreach ($GSUBFeatures as $tag => $arr) { + if (strpos($usetags, $tag) !== false) { + foreach ($arr as $lu) { + $LookupList[$lu] = $tag; + } + } + } + ksort($LookupList); + + $ptr = 0; + // Test each glyph sequentially + while ($ptr < (count($this->OTLdata))) { // whilst there is another glyph ..0064 + $currGlyph = $this->OTLdata[$ptr]['hex']; + $currGID = $this->OTLdata[$ptr]['uni']; + $shift = 1; + + foreach ($LookupList as $lu => $tag) { + $Type = $this->GSUBLookups[$lu]['Type']; + $Flag = $this->GSUBLookups[$lu]['Flag']; + $MarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + $tagInt = 1; + if (preg_match('/' . $tag . '([0-9]{1,2})/', $usetags, $m)) { + $tagInt = $m[1]; + } + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $c => $subtable_offset) { + // NB Coverage only looks at glyphs for position 1 (esp. 7.3 and 8.3) + if (isset($this->GSLuCoverage[$lu][$c][$currGID])) { + // Get rules from font GSUB subtable + $shift = $this->_applyGSUBsubtable($lu, $c, $ptr, $currGlyph, $currGID, ($subtable_offset - $this->GSUB_offset), $Type, $Flag, $MarkFilteringSet, $this->GSLuCoverage[$lu][$c], 0, $tag, 0, $tagInt); + + if ($shift) { + break 2; + } + } + } + } + if ($shift == 0) { + $shift = 1; + } + $ptr += $shift; + } + } + } + + function _applyGSUBrulesMyanmar($usetags, $scriptTag, $langsys) + { + // $usetags = locl ccmp rphf pref blwf pstf'; + // applied to all characters + + $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys]; + + // ALL should be applied one syllable at a time + // Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable' + $tags = explode(' ', $usetags); + foreach ($tags as $usetag) { + $LookupList = []; + foreach ($GSUBFeatures as $tag => $arr) { + if ($tag == $usetag) { + foreach ($arr as $lu) { + $LookupList[$lu] = $tag; + } + } + } + ksort($LookupList); + + foreach ($LookupList as $lu => $tag) { + $Type = $this->GSUBLookups[$lu]['Type']; + $Flag = $this->GSUBLookups[$lu]['Flag']; + $MarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + $tagInt = 1; + if (preg_match('/' . $tag . '([0-9]{1,2})/', $usetags, $m)) { + $tagInt = $m[1]; + } + + $ptr = 0; + // Test each glyph sequentially + while ($ptr < (count($this->OTLdata))) { // whilst there is another glyph ..0064 + $currGlyph = $this->OTLdata[$ptr]['hex']; + $currGID = $this->OTLdata[$ptr]['uni']; + $shift = 1; + foreach ($this->GSUBLookups[$lu]['Subtables'] as $c => $subtable_offset) { + // NB Coverage only looks at glyphs for position 1 (esp. 7.3 and 8.3) + if (isset($this->GSLuCoverage[$lu][$c][$currGID])) { + // Get rules from font GSUB subtable + $shift = $this->_applyGSUBsubtable($lu, $c, $ptr, $currGlyph, $currGID, ($subtable_offset - $this->GSUB_offset), $Type, $Flag, $MarkFilteringSet, $this->GSLuCoverage[$lu][$c], 0, $usetag, 0, $tagInt); + + if ($shift) { + break; + } + } + } + if ($shift == 0) { + $shift = 1; + } + $ptr += $shift; + } + } + } + } + + function _applyGSUBrulesIndic($usetags, $scriptTag, $langsys, $is_old_spec) + { + // $usetags = 'locl ccmp nukt akhn rphf rkrf pref blwf half pstf vatu cjct'; then later - init + // rphf, pref, blwf, half, abvf, pstf, and init are only applied where ['mask'] indicates: Indic::FLAG(Indic::RPHF); + // The rest are applied to all characters + + $GSUBFeatures = $this->mpdf->CurrentFont['GSUBFeatures'][$scriptTag][$langsys]; + + // ALL should be applied one syllable at a time + // Implemented in functions checkContextMatch and checkContextMatchMultiple by failing to match if outside scope of current 'syllable' + $tags = explode(' ', $usetags); + foreach ($tags as $usetag) { + $LookupList = []; + foreach ($GSUBFeatures as $tag => $arr) { + if ($tag == $usetag) { + foreach ($arr as $lu) { + $LookupList[$lu] = $tag; + } + } + } + ksort($LookupList); + + foreach ($LookupList as $lu => $tag) { + $Type = $this->GSUBLookups[$lu]['Type']; + $Flag = $this->GSUBLookups[$lu]['Flag']; + $MarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + $tagInt = 1; + if (preg_match('/' . $tag . '([0-9]{1,2})/', $usetags, $m)) { + $tagInt = $m[1]; + } + + $ptr = 0; + // Test each glyph sequentially + while ($ptr < (count($this->OTLdata))) { // whilst there is another glyph ..0064 + $currGlyph = $this->OTLdata[$ptr]['hex']; + $currGID = $this->OTLdata[$ptr]['uni']; + $shift = 1; + foreach ($this->GSUBLookups[$lu]['Subtables'] as $c => $subtable_offset) { + // NB Coverage only looks at glyphs for position 1 (esp. 7.3 and 8.3) + if (isset($this->GSLuCoverage[$lu][$c][$currGID])) { + if (strpos('rphf pref blwf half pstf cfar init', $usetag) !== false) { // only apply when mask indicates + $mask = 0; + switch ($usetag) { + case 'rphf': + $mask = (1 << (Indic::RPHF)); + break; + case 'pref': + $mask = (1 << (Indic::PREF)); + break; + case 'blwf': + $mask = (1 << (Indic::BLWF)); + break; + case 'half': + $mask = (1 << (Indic::HALF)); + break; + case 'pstf': + $mask = (1 << (Indic::PSTF)); + break; + case 'cfar': + $mask = (1 << (Indic::CFAR)); + break; + case 'init': + $mask = (1 << (Indic::INIT)); + break; + } + if (!($this->OTLdata[$ptr]['mask'] & $mask)) { + continue; + } + } + // Get rules from font GSUB subtable + $shift = $this->_applyGSUBsubtable($lu, $c, $ptr, $currGlyph, $currGID, ($subtable_offset - $this->GSUB_offset), $Type, $Flag, $MarkFilteringSet, $this->GSLuCoverage[$lu][$c], 0, $usetag, $is_old_spec, $tagInt); + + if ($shift) { + break; + } + } // Special case for Indic ZZZ99S + // Check to substitute Halant-Consonant in PREF, BLWF or PSTF + // i.e. new spec but GSUB tables have Consonant-Halant in Lookups e.g. FreeSerif, which + // incorrectly just moved old spec tables to new spec. Uniscribe seems to cope with this + // See also ttffontsuni.php + // First check if current glyph is a Halant/Virama + elseif (static::_OTL_OLD_SPEC_COMPAT_1 && $Type == 4 && !$is_old_spec && strpos('0094D 009CD 00A4D 00ACD 00B4D 00BCD 00C4D 00CCD 00D4D', $currGlyph) !== false) { + // only apply when 'pref blwf pstf' tags, and when mask indicates + if (strpos('pref blwf pstf', $usetag) !== false) { + $mask = 0; + switch ($usetag) { + case 'pref': + $mask = (1 << (Indic::PREF)); + break; + case 'blwf': + $mask = (1 << (Indic::BLWF)); + break; + case 'pstf': + $mask = (1 << (Indic::PSTF)); + break; + } + if (!($this->OTLdata[$ptr]['mask'] & $mask)) { + continue; + } + + $nextGlyph = $this->OTLdata[$ptr + 1]['hex']; + $nextGID = $this->OTLdata[$ptr + 1]['uni']; + if (isset($this->GSLuCoverage[$lu][$c][$nextGID])) { + // Get rules from font GSUB subtable + $shift = $this->_applyGSUBsubtableSpecial($lu, $c, $ptr, $currGlyph, $currGID, $nextGlyph, $nextGID, ($subtable_offset - $this->GSUB_offset), $Type, $this->GSLuCoverage[$lu][$c]); + + if ($shift) { + break; + } + } + } + } + } + if ($shift == 0) { + $shift = 1; + } + $ptr += $shift; + } + } + } + } + + function _applyGSUBsubtableSpecial($lookupID, $subtable, $ptr, $currGlyph, $currGID, $nextGlyph, $nextGID, $subtable_offset, $Type, $LuCoverage) + { + + // Special case for Indic + // Check to substitute Halant-Consonant in PREF, BLWF or PSTF + // i.e. new spec but GSUB tables have Consonant-Halant in Lookups e.g. FreeSerif, which + // incorrectly just moved old spec tables to new spec. Uniscribe seems to cope with this + // See also ttffontsuni.php + + $this->seek($subtable_offset); + $SubstFormat = $this->read_ushort(); + + // Subtable contains Consonant - Halant + // Text string contains Halant ($CurrGlyph) - Consonant ($nextGlyph) + // Halant has already been matched, and already checked that $nextGID is in Coverage table + //////////////////////////////////////////////////////////////////////////////// + // Only does: LookupType 4: Ligature Substitution Subtable : n to 1 + //////////////////////////////////////////////////////////////////////////////// + $Coverage = $subtable_offset + $this->read_ushort(); + $NextGlyphPos = $LuCoverage[$nextGID]; + $LigSetCount = $this->read_short(); + + $this->skip($NextGlyphPos * 2); + $LigSet = $subtable_offset + $this->read_short(); + + $this->seek($LigSet); + $LigCount = $this->read_short(); + // LigatureSet i.e. all starting with the same Glyph $nextGlyph [Consonant] + $LigatureOffset = []; + for ($g = 0; $g < $LigCount; $g++) { + $LigatureOffset[$g] = $LigSet + $this->read_ushort(); + } + for ($g = 0; $g < $LigCount; $g++) { + // Ligature tables + $this->seek($LigatureOffset[$g]); + $LigGlyph = $this->read_ushort(); + $substitute = $this->glyphToChar($LigGlyph); + $CompCount = $this->read_ushort(); + + if ($CompCount != 2) { + return 0; + } // Only expecting to work with 2:1 (and no ignore characters in between) + + + $gid = $this->read_ushort(); + $checkGlyph = $this->glyphToChar($gid); // Other component/input Glyphs starting at position 2 (arrayindex 1) + + if ($currGID == $checkGlyph) { + $match = true; + } else { + $match = false; + break; + } + + $GlyphPos = []; + $GlyphPos[] = $ptr; + $GlyphPos[] = $ptr + 1; + + + if ($match) { + $shift = $this->GSUBsubstitute($ptr, $substitute, 4, $GlyphPos); // GlyphPos contains positions to set null + if ($shift) { + return 1; + } + } + } + return 0; + } + + function _applyGSUBsubtable($lookupID, $subtable, $ptr, $currGlyph, $currGID, $subtable_offset, $Type, $Flag, $MarkFilteringSet, $LuCoverage, $level, $currentTag, $is_old_spec, $tagInt) + { + $ignore = $this->_getGCOMignoreString($Flag, $MarkFilteringSet); + + // Lets start + $this->seek($subtable_offset); + $SubstFormat = $this->read_ushort(); + + //////////////////////////////////////////////////////////////////////////////// + // LookupType 1: Single Substitution Subtable : 1 to 1 + //////////////////////////////////////////////////////////////////////////////// + if ($Type == 1) { + // Flag = Ignore + if ($this->_checkGCOMignore($Flag, $currGlyph, $MarkFilteringSet)) { + return 0; + } + $CoverageOffset = $subtable_offset + $this->read_ushort(); + $GlyphPos = $LuCoverage[$currGID]; + //=========== + // Format 1: + //=========== + if ($SubstFormat == 1) { // Calculated output glyph indices + $DeltaGlyphID = $this->read_short(); + $this->seek($CoverageOffset); + $glyphs = $this->_getCoverageGID(); + $GlyphID = $glyphs[$GlyphPos] + $DeltaGlyphID; + } //=========== + // Format 2: + //=========== + elseif ($SubstFormat == 2) { // Specified output glyph indices + $GlyphCount = $this->read_ushort(); + $this->skip($GlyphPos * 2); + $GlyphID = $this->read_ushort(); + } + + $substitute = $this->glyphToChar($GlyphID); + $shift = $this->GSUBsubstitute($ptr, $substitute, $Type); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + return 1; + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 2: Multiple Substitution Subtable : 1 to n + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 2) { + // Flag = Ignore + if ($this->_checkGCOMignore($Flag, $currGlyph, $MarkFilteringSet)) { + return 0; + } + $Coverage = $subtable_offset + $this->read_ushort(); + $GlyphPos = $LuCoverage[$currGID]; + $this->skip(2); + $this->skip($GlyphPos * 2); + $Sequences = $subtable_offset + $this->read_short(); + + $this->seek($Sequences); + $GlyphCount = $this->read_short(); + $SubstituteGlyphs = []; + for ($g = 0; $g < $GlyphCount; $g++) { + $sgid = $this->read_ushort(); + $SubstituteGlyphs[] = $this->glyphToChar($sgid); + } + + $shift = $this->GSUBsubstitute($ptr, $SubstituteGlyphs, $Type); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + return $shift; + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 3: Alternate Forms : 1 to 1(n) + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 3) { + // Flag = Ignore + if ($this->_checkGCOMignore($Flag, $currGlyph, $MarkFilteringSet)) { + return 0; + } + $Coverage = $subtable_offset + $this->read_ushort(); + $AlternateSetCount = $this->read_short(); + ///////////////////////////////////////////////////////////////////////////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Need to set alternate IF set by CSS3 font-feature for a tag + // i.e. if this is 'salt' alternate may be set to 2 + // default value will be $alt=1 ( === index of 0 in list of alternates) + $alt = 1; // $alt=1 points to Alternative[0] + if ($tagInt > 1) { + $alt = $tagInt; + } + ///////////////////////////////////////////////////////////////////////////////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if ($alt == 0) { + return 0; + } // If specified alternate not present, cancel [ or could default $alt = 1 ?] + + $GlyphPos = $LuCoverage[$currGID]; + $this->skip($GlyphPos * 2); + + $AlternateSets = $subtable_offset + $this->read_short(); + $this->seek($AlternateSets); + + $AlternateGlyphCount = $this->read_short(); + if ($alt > $AlternateGlyphCount) { + return 0; + } // If specified alternate not present, cancel [ or could default $alt = 1 ?] + + $this->skip(($alt - 1) * 2); + $GlyphID = $this->read_ushort(); + + $substitute = $this->glyphToChar($GlyphID); + $shift = $this->GSUBsubstitute($ptr, $substitute, $Type); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + return 1; + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 4: Ligature Substitution Subtable : n to 1 + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 4) { + // Flag = Ignore + if ($this->_checkGCOMignore($Flag, $currGlyph, $MarkFilteringSet)) { + return 0; + } + $Coverage = $subtable_offset + $this->read_ushort(); + $FirstGlyphPos = $LuCoverage[$currGID]; + + $LigSetCount = $this->read_short(); + + $this->skip($FirstGlyphPos * 2); + $LigSet = $subtable_offset + $this->read_short(); + + $this->seek($LigSet); + $LigCount = $this->read_short(); + // LigatureSet i.e. all starting with the same first Glyph $currGlyph + $LigatureOffset = []; + for ($g = 0; $g < $LigCount; $g++) { + $LigatureOffset[$g] = $LigSet + $this->read_ushort(); + } + for ($g = 0; $g < $LigCount; $g++) { + // Ligature tables + $this->seek($LigatureOffset[$g]); + $LigGlyph = $this->read_ushort(); // Output Ligature GlyphID + $substitute = $this->glyphToChar($LigGlyph); + $CompCount = $this->read_ushort(); + + $spos = $ptr; + $match = true; + $GlyphPos = []; + $GlyphPos[] = $spos; + for ($l = 1; $l < $CompCount; $l++) { + $gid = $this->read_ushort(); + $checkGlyph = $this->glyphToChar($gid); // Other component/input Glyphs starting at position 2 (arrayindex 1) + + $spos++; + //while $this->OTLdata[$spos]['uni'] is an "ignore" => spos++ + while (isset($this->OTLdata[$spos]) && strpos($ignore, $this->OTLdata[$spos]['hex']) !== false) { + $spos++; + } + + if (isset($this->OTLdata[$spos]) && $this->OTLdata[$spos]['uni'] == $checkGlyph) { + $GlyphPos[] = $spos; + } else { + $match = false; + break; + } + } + + + if ($match) { + $shift = $this->GSUBsubstitute($ptr, $substitute, $Type, $GlyphPos); // GlyphPos contains positions to set null + if ($this->debugOTL && $shift) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + return ($spos - $ptr + 1 - ($CompCount - 1)); + } + } + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 5: Contextual Substitution Subtable + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 5) { + //=========== + // Format 1: Simple Context Glyph Substitution + //=========== + if ($SubstFormat == 1) { + $CoverageTableOffset = $subtable_offset + $this->read_ushort(); + $SubRuleSetCount = $this->read_ushort(); + $SubRuleSetOffset = []; + for ($b = 0; $b < $SubRuleSetCount; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $SubRuleSetOffset[] = $offset; + } else { + $SubRuleSetOffset[] = $subtable_offset + $offset; + } + } + + // SubRuleSet tables: All contexts beginning with the same glyph + // Select the SubRuleSet required using the position of the glyph in the coverage table + $GlyphPos = $LuCoverage[$currGID]; + if ($SubRuleSetOffset[$GlyphPos] > 0) { + $this->seek($SubRuleSetOffset[$GlyphPos]); + $SubRuleCnt = $this->read_ushort(); + $SubRule = []; + for ($b = 0; $b < $SubRuleCnt; $b++) { + $SubRule[$b] = $SubRuleSetOffset[$GlyphPos] + $this->read_ushort(); + } + for ($b = 0; $b < $SubRuleCnt; $b++) { // EACH RULE + $this->seek($SubRule[$b]); + $InputGlyphCount = $this->read_ushort(); + $SubstCount = $this->read_ushort(); + + $Backtrack = []; + $Lookahead = []; + $Input = []; + $Input[0] = $this->OTLdata[$ptr]['uni']; + for ($r = 1; $r < $InputGlyphCount; $r++) { + $gid = $this->read_ushort(); + $Input[$r] = $this->glyphToChar($gid); + } + $matched = $this->checkContextMatch($Input, $Backtrack, $Lookahead, $ignore, $ptr); + if ($matched) { + if ($this->debugOTL) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + for ($p = 0; $p < $SubstCount; $p++) { // EACH LOOKUP + $SequenceIndex[$p] = $this->read_ushort(); + $LookupListIndex[$p] = $this->read_ushort(); + } + + for ($p = 0; $p < $SubstCount; $p++) { + // Apply $LookupListIndex at $SequenceIndex + if ($SequenceIndex[$p] >= $InputGlyphCount) { + continue; + } + $lu = $LookupListIndex[$p]; + $luType = $this->GSUBLookups[$lu]['Type']; + $luFlag = $this->GSUBLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SequenceIndex[$p]]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGSUBsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GSUB_offset), $luType, $luFlag, $luMarkFilteringSet, $this->GSLuCoverage[$lu][$luc], 1, $currentTag, $is_old_spec, $tagInt); + if ($shift) { + break; + } + } + } + + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + } + return 0; + } //=========== + // Format 2: + //=========== + // Format 2: Class-based Context Glyph Substitution + elseif ($SubstFormat == 2) { + $CoverageTableOffset = $subtable_offset + $this->read_ushort(); + $InputClassDefOffset = $subtable_offset + $this->read_ushort(); + $SubClassSetCnt = $this->read_ushort(); + $SubClassSetOffset = []; + for ($b = 0; $b < $SubClassSetCnt; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $SubClassSetOffset[] = $offset; + } else { + $SubClassSetOffset[] = $subtable_offset + $offset; + } + } + + $InputClasses = $this->_getClasses($InputClassDefOffset); + + for ($s = 0; $s < $SubClassSetCnt; $s++) { // $SubClassSet is ordered by input class-may be NULL + // Select $SubClassSet if currGlyph is in First Input Class + if ($SubClassSetOffset[$s] > 0 && isset($InputClasses[$s][$currGID])) { + $this->seek($SubClassSetOffset[$s]); + $SubClassRuleCnt = $this->read_ushort(); + $SubClassRule = []; + for ($b = 0; $b < $SubClassRuleCnt; $b++) { + $SubClassRule[$b] = $SubClassSetOffset[$s] + $this->read_ushort(); + } + + for ($b = 0; $b < $SubClassRuleCnt; $b++) { // EACH RULE + $this->seek($SubClassRule[$b]); + $InputGlyphCount = $this->read_ushort(); + $SubstCount = $this->read_ushort(); + $Input = []; + for ($r = 1; $r < $InputGlyphCount; $r++) { + $Input[$r] = $this->read_ushort(); + } + + $inputClass = $s; + + $inputGlyphs = []; + $inputGlyphs[0] = $InputClasses[$inputClass]; + + if ($InputGlyphCount > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $InputGlyphCount; $gcl++) { + $classindex = $Input[$gcl]; + if (isset($InputClasses[$classindex])) { + $inputGlyphs[$gcl] = $InputClasses[$classindex]; + } else { + $inputGlyphs[$gcl] = ''; + } + } + } + + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = []; + for ($gc = 1; $gc <= count($InputClasses); $gc++) { + if (is_array($InputClasses[$gc])) { + $class0excl = $class0excl + $InputClasses[$gc]; + } + } + + $backtrackGlyphs = []; + $lookaheadGlyphs = []; + + $matched = $this->checkContextMatchMultipleUni($inputGlyphs, $backtrackGlyphs, $lookaheadGlyphs, $ignore, $ptr, $class0excl); + if ($matched) { + if ($this->debugOTL) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + for ($p = 0; $p < $SubstCount; $p++) { // EACH LOOKUP + $SequenceIndex[$p] = $this->read_ushort(); + $LookupListIndex[$p] = $this->read_ushort(); + } + + for ($p = 0; $p < $SubstCount; $p++) { + // Apply $LookupListIndex at $SequenceIndex + if ($SequenceIndex[$p] >= $InputGlyphCount) { + continue; + } + $lu = $LookupListIndex[$p]; + $luType = $this->GSUBLookups[$lu]['Type']; + $luFlag = $this->GSUBLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SequenceIndex[$p]]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGSUBsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GSUB_offset), $luType, $luFlag, $luMarkFilteringSet, $this->GSLuCoverage[$lu][$luc], 1, $currentTag, $is_old_spec, $tagInt); + if ($shift) { + break; + } + } + } + + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + } + } + + return 0; + } //=========== + // Format 3: + //=========== + // Format 3: Coverage-based Context Glyph Substitution + elseif ($SubstFormat == 3) { + throw new \Mpdf\MpdfException("GSUB Lookup Type " . $Type . " Format " . $SubstFormat . " not TESTED YET."); + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 6: Chaining Contextual Substitution Subtable + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 6) { + //=========== + // Format 1: + //=========== + // Format 1: Simple Chaining Context Glyph Substitution + if ($SubstFormat == 1) { + $Coverage = $subtable_offset + $this->read_ushort(); + $GlyphPos = $LuCoverage[$currGID]; + $ChainSubRuleSetCount = $this->read_ushort(); + // All of the ChainSubRule tables defining contexts that begin with the same first glyph are grouped together and defined in a ChainSubRuleSet table + $this->skip($GlyphPos * 2); + $ChainSubRuleSet = $subtable_offset + $this->read_ushort(); + $this->seek($ChainSubRuleSet); + $ChainSubRuleCount = $this->read_ushort(); + + for ($s = 0; $s < $ChainSubRuleCount; $s++) { + $ChainSubRule[$s] = $ChainSubRuleSet + $this->read_ushort(); + } + + for ($s = 0; $s < $ChainSubRuleCount; $s++) { + $this->seek($ChainSubRule[$s]); + + $BacktrackGlyphCount = $this->read_ushort(); + $Backtrack = []; + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $gid = $this->read_ushort(); + $Backtrack[] = $this->glyphToChar($gid); + } + $Input = []; + $Input[0] = $this->OTLdata[$ptr]['uni']; + $InputGlyphCount = $this->read_ushort(); + for ($b = 1; $b < $InputGlyphCount; $b++) { + $gid = $this->read_ushort(); + $Input[$b] = $this->glyphToChar($gid); + } + $LookaheadGlyphCount = $this->read_ushort(); + $Lookahead = []; + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $gid = $this->read_ushort(); + $Lookahead[] = $this->glyphToChar($gid); + } + + $matched = $this->checkContextMatch($Input, $Backtrack, $Lookahead, $ignore, $ptr); + if ($matched) { + if ($this->debugOTL) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + $SubstCount = $this->read_ushort(); + for ($p = 0; $p < $SubstCount; $p++) { + // SubstLookupRecord + $SubstLookupRecord[$p]['SequenceIndex'] = $this->read_ushort(); + $SubstLookupRecord[$p]['LookupListIndex'] = $this->read_ushort(); + } + for ($p = 0; $p < $SubstCount; $p++) { + // Apply $SubstLookupRecord[$p]['LookupListIndex'] at $SubstLookupRecord[$p]['SequenceIndex'] + if ($SubstLookupRecord[$p]['SequenceIndex'] >= $InputGlyphCount) { + continue; + } + $lu = $SubstLookupRecord[$p]['LookupListIndex']; + $luType = $this->GSUBLookups[$lu]['Type']; + $luFlag = $this->GSUBLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SubstLookupRecord[$p]['SequenceIndex']]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGSUBsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GSUB_offset), $luType, $luFlag, $luMarkFilteringSet, $this->GSLuCoverage[$lu][$luc], 1, $currentTag, $is_old_spec, $tagInt); + if ($shift) { + break; + } + } + } + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + return 0; + } //=========== + // Format 2: + //=========== + // Format 2: Class-based Chaining Context Glyph Substitution p257 + elseif ($SubstFormat == 2) { + // NB Format 2 specifies fixed class assignments (identical for each position in the backtrack, input, or lookahead sequence) and exclusive classes (a glyph cannot be in more than one class at a time) + + $CoverageTableOffset = $subtable_offset + $this->read_ushort(); + $BacktrackClassDefOffset = $subtable_offset + $this->read_ushort(); + $InputClassDefOffset = $subtable_offset + $this->read_ushort(); + $LookaheadClassDefOffset = $subtable_offset + $this->read_ushort(); + $ChainSubClassSetCnt = $this->read_ushort(); + $ChainSubClassSetOffset = []; + for ($b = 0; $b < $ChainSubClassSetCnt; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $ChainSubClassSetOffset[] = $offset; + } else { + $ChainSubClassSetOffset[] = $subtable_offset + $offset; + } + } + + $BacktrackClasses = $this->_getClasses($BacktrackClassDefOffset); + $InputClasses = $this->_getClasses($InputClassDefOffset); + $LookaheadClasses = $this->_getClasses($LookaheadClassDefOffset); + + for ($s = 0; $s < $ChainSubClassSetCnt; $s++) { // $ChainSubClassSet is ordered by input class-may be NULL + // Select $ChainSubClassSet if currGlyph is in First Input Class + if ($ChainSubClassSetOffset[$s] > 0 && isset($InputClasses[$s][$currGID])) { + $this->seek($ChainSubClassSetOffset[$s]); + $ChainSubClassRuleCnt = $this->read_ushort(); + $ChainSubClassRule = []; + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { + $ChainSubClassRule[$b] = $ChainSubClassSetOffset[$s] + $this->read_ushort(); + } + + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { // EACH RULE + $this->seek($ChainSubClassRule[$b]); + $BacktrackGlyphCount = $this->read_ushort(); + for ($r = 0; $r < $BacktrackGlyphCount; $r++) { + $Backtrack[$r] = $this->read_ushort(); + } + $InputGlyphCount = $this->read_ushort(); + for ($r = 1; $r < $InputGlyphCount; $r++) { + $Input[$r] = $this->read_ushort(); + } + $LookaheadGlyphCount = $this->read_ushort(); + for ($r = 0; $r < $LookaheadGlyphCount; $r++) { + $Lookahead[$r] = $this->read_ushort(); + } + + + // These contain classes of glyphs as arrays + // $InputClasses[(class)] e.g. 0x02E6,0x02E7,0x02E8 + // $LookaheadClasses[(class)] + // $BacktrackClasses[(class)] + // These contain arrays of classIndexes + // [Backtrack] [Lookahead] and [Input] (Input is from the second position only) + + + $inputClass = $s; //??? + + $inputGlyphs = []; + $inputGlyphs[0] = $InputClasses[$inputClass]; + + if ($InputGlyphCount > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $InputGlyphCount; $gcl++) { + $classindex = $Input[$gcl]; + if (isset($InputClasses[$classindex])) { + $inputGlyphs[$gcl] = $InputClasses[$classindex]; + } else { + $inputGlyphs[$gcl] = ''; + } + } + } + + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = []; + for ($gc = 1; $gc <= count($InputClasses); $gc++) { + if (isset($InputClasses[$gc])) { + $class0excl = $class0excl + $InputClasses[$gc]; + } + } + + if ($BacktrackGlyphCount) { + for ($gcl = 0; $gcl < $BacktrackGlyphCount; $gcl++) { + $classindex = $Backtrack[$gcl]; + if (isset($BacktrackClasses[$classindex])) { + $backtrackGlyphs[$gcl] = $BacktrackClasses[$classindex]; + } else { + $backtrackGlyphs[$gcl] = ''; + } + } + } else { + $backtrackGlyphs = []; + } + + // Class 0 contains all the glyphs NOT in the other classes + $bclass0excl = []; + for ($gc = 1; $gc <= count($BacktrackClasses); $gc++) { + if (isset($BacktrackClasses[$gc])) { + $bclass0excl = $bclass0excl + $BacktrackClasses[$gc]; + } + } + + + if ($LookaheadGlyphCount) { + for ($gcl = 0; $gcl < $LookaheadGlyphCount; $gcl++) { + $classindex = $Lookahead[$gcl]; + if (isset($LookaheadClasses[$classindex])) { + $lookaheadGlyphs[$gcl] = $LookaheadClasses[$classindex]; + } else { + $lookaheadGlyphs[$gcl] = ''; + } + } + } else { + $lookaheadGlyphs = []; + } + + // Class 0 contains all the glyphs NOT in the other classes + $lclass0excl = []; + for ($gc = 1; $gc <= count($LookaheadClasses); $gc++) { + if (isset($LookaheadClasses[$gc])) { + $lclass0excl = $lclass0excl + $LookaheadClasses[$gc]; + } + } + + + $matched = $this->checkContextMatchMultipleUni($inputGlyphs, $backtrackGlyphs, $lookaheadGlyphs, $ignore, $ptr, $class0excl, $bclass0excl, $lclass0excl); + if ($matched) { + if ($this->debugOTL) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + $SubstCount = $this->read_ushort(); + for ($p = 0; $p < $SubstCount; $p++) { // EACH LOOKUP + $SequenceIndex[$p] = $this->read_ushort(); + $LookupListIndex[$p] = $this->read_ushort(); + } + + for ($p = 0; $p < $SubstCount; $p++) { + // Apply $LookupListIndex at $SequenceIndex + if ($SequenceIndex[$p] >= $InputGlyphCount) { + continue; + } + $lu = $LookupListIndex[$p]; + $luType = $this->GSUBLookups[$lu]['Type']; + $luFlag = $this->GSUBLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SequenceIndex[$p]]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGSUBsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GSUB_offset), $luType, $luFlag, $luMarkFilteringSet, $this->GSLuCoverage[$lu][$luc], 1, $currentTag, $is_old_spec, $tagInt); + if ($shift) { + break; + } + } + } + + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + } + } + + return 0; + } //=========== + // Format 3: + //=========== + // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + elseif ($SubstFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $CoverageBacktrackOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $InputGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $InputGlyphCount; $b++) { + $CoverageInputOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $LookaheadGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $CoverageLookaheadOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $SubstCount = $this->read_ushort(); + $save_pos = $this->_pos; // Save the point just after PosCount + + $CoverageBacktrackGlyphs = []; + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $this->seek($CoverageBacktrackOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageBacktrackGlyphs[$b] = implode("|", $glyphs); + } + $CoverageInputGlyphs = []; + for ($b = 0; $b < $InputGlyphCount; $b++) { + $this->seek($CoverageInputOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageInputGlyphs[$b] = implode("|", $glyphs); + } + $CoverageLookaheadGlyphs = []; + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $this->seek($CoverageLookaheadOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageLookaheadGlyphs[$b] = implode("|", $glyphs); + } + + $matched = $this->checkContextMatchMultiple($CoverageInputGlyphs, $CoverageBacktrackGlyphs, $CoverageLookaheadGlyphs, $ignore, $ptr); + if ($matched) { + if ($this->debugOTL) { + $this->_dumpproc('GSUB', $lookupID, $subtable, $Type, $SubstFormat, $ptr, $currGlyph, $level); + } + + $this->seek($save_pos); // Return to just after PosCount + for ($p = 0; $p < $SubstCount; $p++) { + // SubstLookupRecord + $SubstLookupRecord[$p]['SequenceIndex'] = $this->read_ushort(); + $SubstLookupRecord[$p]['LookupListIndex'] = $this->read_ushort(); + } + for ($p = 0; $p < $SubstCount; $p++) { + // Apply $SubstLookupRecord[$p]['LookupListIndex'] at $SubstLookupRecord[$p]['SequenceIndex'] + if ($SubstLookupRecord[$p]['SequenceIndex'] >= $InputGlyphCount) { + continue; + } + $lu = $SubstLookupRecord[$p]['LookupListIndex']; + $luType = $this->GSUBLookups[$lu]['Type']; + $luFlag = $this->GSUBLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GSUBLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SubstLookupRecord[$p]['SequenceIndex']]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GSUBLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGSUBsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GSUB_offset), $luType, $luFlag, $luMarkFilteringSet, $this->GSLuCoverage[$lu][$luc], 1, $currentTag, $is_old_spec, $tagInt); + if ($shift) { + break; + } + } + } + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return (isset($shift) ? $shift : 0); + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + + return 0; + } + } else { + throw new \Mpdf\MpdfException("GSUB Lookup Type " . $Type . " not supported."); + } + } + + function _updateLigatureMarks($pos, $n) + { + if ($n > 0) { + // Update position of Ligatures and associated Marks + // Foreach lig/assocMarks + // Any position lpos or mpos > $pos + count($substitute) + // $this->assocMarks = array(); // assocMarks[$pos mpos] => array(compID, ligPos) + // $this->assocLigs = array(); // Ligatures[$pos lpos] => nc + for ($p = count($this->OTLdata) - 1; $p >= ($pos + $n); $p--) { + if (isset($this->assocLigs[$p])) { + $tmp = $this->assocLigs[$p]; + unset($this->assocLigs[$p]); + $this->assocLigs[($p + $n)] = $tmp; + } + } + for ($p = count($this->OTLdata) - 1; $p >= 0; $p--) { + if (isset($this->assocMarks[$p])) { + if ($this->assocMarks[$p]['ligPos'] >= ($pos + $n)) { + $this->assocMarks[$p]['ligPos'] += $n; + } + if ($p >= ($pos + $n)) { + $tmp = $this->assocMarks[$p]; + unset($this->assocMarks[$p]); + $this->assocMarks[($p + $n)] = $tmp; + } + } + } + } elseif ($n < 1) { // glyphs removed + $nrem = -$n; + // Update position of pre-existing Ligatures and associated Marks + for ($p = ($pos + 1); $p < count($this->OTLdata); $p++) { + if (isset($this->assocLigs[$p])) { + $tmp = $this->assocLigs[$p]; + unset($this->assocLigs[$p]); + $this->assocLigs[($p - $nrem)] = $tmp; + } + } + for ($p = 0; $p < count($this->OTLdata); $p++) { + if (isset($this->assocMarks[$p])) { + if ($this->assocMarks[$p]['ligPos'] >= ($pos)) { + $this->assocMarks[$p]['ligPos'] -= $nrem; + } + if ($p > $pos) { + $tmp = $this->assocMarks[$p]; + unset($this->assocMarks[$p]); + $this->assocMarks[($p - $nrem)] = $tmp; + } + } + } + } + } + + function GSUBsubstitute($pos, $substitute, $Type, $GlyphPos = null) + { + + // LookupType 1: Simple Substitution Subtable : 1 to 1 + // LookupType 3: Alternate Forms : 1 to 1(n) + if ($Type == 1 || $Type == 3) { + $this->OTLdata[$pos]['uni'] = $substitute; + $this->OTLdata[$pos]['hex'] = $this->unicode_hex($substitute); + return 1; + } // LookupType 2: Multiple Substitution Subtable : 1 to n + elseif ($Type == 2) { + for ($i = 0; $i < count($substitute); $i++) { + $uni = $substitute[$i]; + $newOTLdata[$i] = []; + $newOTLdata[$i]['uni'] = $uni; + $newOTLdata[$i]['hex'] = $this->unicode_hex($uni); + + + // Get types of new inserted chars - or replicate type of char being replaced + // $bt = Ucdn::get_bidi_class($uni); + // if (!$bt) { + $bt = $this->OTLdata[$pos]['bidi_type']; + // } + + if (strpos($this->GlyphClassMarks, $newOTLdata[$i]['hex']) !== false) { + $gp = 'M'; + } elseif ($uni == 32) { + $gp = 'S'; + } else { + $gp = 'C'; + } + + // Need to update matra_type ??? of new glyphs inserted ??????????????????????????????????????? + + $newOTLdata[$i]['bidi_type'] = $bt; + $newOTLdata[$i]['group'] = $gp; + + // Need to update details of new glyphs inserted + $newOTLdata[$i]['general_category'] = $this->OTLdata[$pos]['general_category']; + + if ($this->shaper == 'I' || $this->shaper == 'K' || $this->shaper == 'S') { + $newOTLdata[$i]['indic_category'] = $this->OTLdata[$pos]['indic_category']; + $newOTLdata[$i]['indic_position'] = $this->OTLdata[$pos]['indic_position']; + } elseif ($this->shaper == 'M') { + $newOTLdata[$i]['myanmar_category'] = $this->OTLdata[$pos]['myanmar_category']; + $newOTLdata[$i]['myanmar_position'] = $this->OTLdata[$pos]['myanmar_position']; + } + if (isset($this->OTLdata[$pos]['mask'])) { + $newOTLdata[$i]['mask'] = $this->OTLdata[$pos]['mask']; + } + if (isset($this->OTLdata[$pos]['syllable'])) { + $newOTLdata[$i]['syllable'] = $this->OTLdata[$pos]['syllable']; + } + } + if ($this->shaper == 'K' || $this->shaper == 'T' || $this->shaper == 'L') { + if ($this->OTLdata[$pos]['wordend']) { + $newOTLdata[count($substitute) - 1]['wordend'] = true; + } + } + + array_splice($this->OTLdata, $pos, 1, $newOTLdata); // Replace 1 with n + // Update position of Ligatures and associated Marks + // count($substitute)-1 is the number of glyphs added + $nadd = count($substitute) - 1; + $this->_updateLigatureMarks($pos, $nadd); + return count($substitute); + } // LookupType 4: Ligature Substitution Subtable : n to 1 + elseif ($Type == 4) { + // Create Ligatures and associated Marks + $firstGlyph = $this->OTLdata[$pos]['hex']; + + // If all components of the ligature are marks (and in the same syllable), we call this a mark ligature. + $contains_marks = false; + $contains_nonmarks = false; + if (isset($this->OTLdata[$pos]['syllable'])) { + $current_syllable = $this->OTLdata[$pos]['syllable']; + } else { + $current_syllable = 0; + } + for ($i = 0; $i < count($GlyphPos); $i++) { + // If subsequent components are not Marks as well - don't ligate + $unistr = $this->OTLdata[$GlyphPos[$i]]['hex']; + if ($this->restrictToSyllable && isset($this->OTLdata[$GlyphPos[$i]]['syllable']) && $this->OTLdata[$GlyphPos[$i]]['syllable'] != $current_syllable) { + return 0; + } + if (strpos($this->GlyphClassMarks, $unistr) !== false) { + $contains_marks = true; + } else { + $contains_nonmarks = true; + } + } + if ($contains_marks && !$contains_nonmarks) { + // Mark Ligature (all components are Marks) + $firstMarkAssoc = ''; + if (isset($this->assocMarks[$pos])) { + $firstMarkAssoc = $this->assocMarks[$pos]; + } + // If all components of the ligature are marks, we call this a mark ligature. + for ($i = 1; $i < count($GlyphPos); $i++) { + // If subsequent components are not Marks as well - don't ligate + // $unistr = $this->OTLdata[$GlyphPos[$i]]['hex']; + // if (strpos($this->GlyphClassMarks, $unistr )===false) { return; } + + $nextMarkAssoc = ''; + if (isset($this->assocMarks[$GlyphPos[$i]])) { + $nextMarkAssoc = $this->assocMarks[$GlyphPos[$i]]; + } + // If first component was attached to a previous ligature component, + // all subsequent components should be attached to the same ligature + // component, otherwise we shouldn't ligate them. + // If first component was NOT attached to a previous ligature component, + // all subsequent components should also NOT be attached to any ligature component, + if ($firstMarkAssoc != $nextMarkAssoc) { + // unless they are attached to the first component itself! + // if (!is_array($nextMarkAssoc) || $nextMarkAssoc['ligPos']!= $pos) { return; } + // Update/Edit - In test with myanmartext font + // င်္က္ကျြွေိ + // => Lookup 17 E003 E066B E05A 102D + // E003 and 102D should form a mark ligature, but 102D is already associated with (non-mark) ligature E05A + // So instead of disallowing the mark ligature to form, just dissociate... + if (!is_array($nextMarkAssoc) || $nextMarkAssoc['ligPos'] != $pos) { + unset($this->assocMarks[$GlyphPos[$i]]); + } + } + } + + /* + * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave + * the ligature to keep its old ligature id. This will allow it to attach to + * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH, + * and LAM,LAM,HEH form a ligature, they will leave SHADDA and FATHA wit a + * ligature id and component value of 2. Then if SHADDA,FATHA form a ligature + * later, we don't want them to lose their ligature id/component, otherwise + * GPOS will fail to correctly position the mark ligature on top of the + * LAM,LAM,HEH ligature. + */ + // So if is_array($firstMarkAssoc) - the new (Mark) ligature should keep this association + + $lastPos = $GlyphPos[(count($GlyphPos) - 1)]; + } else { + /* + * - Ligatures cannot be formed across glyphs attached to different components + * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and + * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. + * However, it would be wrong to ligate that SHADDA,FATHA sequence. + * There is an exception to this: If a ligature tries ligating with marks that + * belong to it itself, go ahead, assuming that the font designer knows what + * they are doing (otherwise it can break Indic stuff when a matra wants to + * ligate with a conjunct...) + */ + + /* + * - If a ligature is formed of components that some of which are also ligatures + * themselves, and those ligature components had marks attached to *their* + * components, we have to attach the marks to the new ligature component + * positions! Now *that*'s tricky! And these marks may be following the + * last component of the whole sequence, so we should loop forward looking + * for them and update them. + * + * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a + * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature + * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligature + * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to + * the new ligature with a component value of 2. + * + * This in fact happened to a font... See: + * https://bugzilla.gnome.org/show_bug.cgi?id=437633 + */ + + $currComp = 0; + for ($i = 0; $i < count($GlyphPos); $i++) { + if ($i > 0 && isset($this->assocLigs[$GlyphPos[$i]])) { // One of the other components is already a ligature + $nc = $this->assocLigs[$GlyphPos[$i]]; + } else { + $nc = 1; + } + // While next char to right is a mark (but not the next matched glyph) + // ?? + also include a Mark Ligature here + $ic = 1; + while ((($i == count($GlyphPos) - 1) || (isset($GlyphPos[$i + 1]) && ($GlyphPos[$i] + $ic) < $GlyphPos[$i + 1])) && isset($this->OTLdata[($GlyphPos[$i] + $ic)]) && strpos($this->GlyphClassMarks, $this->OTLdata[($GlyphPos[$i] + $ic)]['hex']) !== false) { + $newComp = $currComp; + if (isset($this->assocMarks[$GlyphPos[$i] + $ic])) { // One of the inbetween Marks is already associated with a Lig + // OK as long as it is associated with the current Lig + // if ($this->assocMarks[($GlyphPos[$i]+$ic)]['ligPos'] != ($GlyphPos[$i]+$ic)) { die("Problem #1"); } + $newComp += $this->assocMarks[($GlyphPos[$i] + $ic)]['compID']; + } + $this->assocMarks[($GlyphPos[$i] + $ic)] = ['compID' => $newComp, 'ligPos' => $pos]; + $ic++; + } + $currComp += $nc; + } + $lastPos = $GlyphPos[(count($GlyphPos) - 1)] + $ic - 1; + $this->assocLigs[$pos] = $currComp; // Number of components in new Ligature + } + + // Now remove the unwanted glyphs and associated metadata + $newOTLdata[0] = []; + + // Get types of new inserted chars - or replicate type of char being replaced + // $bt = Ucdn::get_bidi_class($substitute); + // if (!$bt) { + $bt = $this->OTLdata[$pos]['bidi_type']; + // } + + if (strpos($this->GlyphClassMarks, $this->unicode_hex($substitute)) !== false) { + $gp = 'M'; + } elseif ($substitute == 32) { + $gp = 'S'; + } else { + $gp = 'C'; + } + + // Need to update details of new glyphs inserted + $newOTLdata[0]['general_category'] = $this->OTLdata[$pos]['general_category']; + + $newOTLdata[0]['bidi_type'] = $bt; + $newOTLdata[0]['group'] = $gp; + + // KASHIDA: If forming a ligature when the last component was identified as a kashida point (final form) + // If previous/first component of ligature is a medial form, then keep this as a kashida point + // TEST (Arabic Typesetting) يَنتُم + $ka = 0; + if (isset($this->OTLdata[$GlyphPos[(count($GlyphPos) - 1)]]['GPOSinfo']['kashida'])) { + $ka = $this->OTLdata[$GlyphPos[(count($GlyphPos) - 1)]]['GPOSinfo']['kashida']; + } + if ($ka == 1 && isset($this->OTLdata[$pos]['form']) && $this->OTLdata[$pos]['form'] == 3) { + $newOTLdata[0]['GPOSinfo']['kashida'] = $ka; + } + + $newOTLdata[0]['uni'] = $substitute; + $newOTLdata[0]['hex'] = $this->unicode_hex($substitute); + + if ($this->shaper == 'I' || $this->shaper == 'K' || $this->shaper == 'S') { + $newOTLdata[0]['indic_category'] = $this->OTLdata[$pos]['indic_category']; + $newOTLdata[0]['indic_position'] = $this->OTLdata[$pos]['indic_position']; + } elseif ($this->shaper == 'M') { + $newOTLdata[0]['myanmar_category'] = $this->OTLdata[$pos]['myanmar_category']; + $newOTLdata[0]['myanmar_position'] = $this->OTLdata[$pos]['myanmar_position']; + } + if (isset($this->OTLdata[$pos]['mask'])) { + $newOTLdata[0]['mask'] = $this->OTLdata[$pos]['mask']; + } + if (isset($this->OTLdata[$pos]['syllable'])) { + $newOTLdata[0]['syllable'] = $this->OTLdata[$pos]['syllable']; + } + + $newOTLdata[0]['is_ligature'] = true; + + + array_splice($this->OTLdata, $pos, 1, $newOTLdata); + + // GlyphPos contains array of arr_pos to set null - not necessarily contiguous + // +- Remove any assocMarks or assocLigs from the main components (the ones that are deleted) + for ($i = count($GlyphPos) - 1; $i > 0; $i--) { + $gpos = $GlyphPos[$i]; + array_splice($this->OTLdata, $gpos, 1); + unset($this->assocLigs[$gpos]); + unset($this->assocMarks[$gpos]); + } + // $this->assocLigs = array(); // Ligatures[$posarr lpos] => nc + // $this->assocMarks = array(); // assocMarks[$posarr mpos] => array(compID, ligPos) + // Update position of pre-existing Ligatures and associated Marks + // Start after first GlyphPos + // count($GlyphPos)-1 is the number of glyphs removed from string + for ($p = ($GlyphPos[0] + 1); $p < (count($this->OTLdata) + count($GlyphPos) - 1); $p++) { + $nrem = 0; // Number of Glyphs removed at this point in the string + for ($i = 0; $i < count($GlyphPos); $i++) { + if ($i > 0 && $p > $GlyphPos[$i]) { + $nrem++; + } + } + if (isset($this->assocLigs[$p])) { + $tmp = $this->assocLigs[$p]; + unset($this->assocLigs[$p]); + $this->assocLigs[($p - $nrem)] = $tmp; + } + if (isset($this->assocMarks[$p])) { + $tmp = $this->assocMarks[$p]; + unset($this->assocMarks[$p]); + if ($tmp['ligPos'] > $GlyphPos[0]) { + $tmp['ligPos'] -= $nrem; + } + $this->assocMarks[($p - $nrem)] = $tmp; + } + } + return 1; + } else { + return 0; + } + } + + //////////////////////////////////////////////////////////////// + ////////// ARABIC ///////////////////////////////// + //////////////////////////////////////////////////////////////// + private function arabic_initialise() + { + // cf. http://unicode.org/Public/UNIDATA/ArabicShaping.txt + // http://unicode.org/Public/UNIDATA/extracted/DerivedJoiningType.txt + // JOIN TO FOLLOWING LETTER IN LOGICAL ORDER (i.e. AS INITIAL/MEDIAL FORM) = Unicode Left-Joining (+ Dual-Joining + Join_Causing 00640) + $this->arabLeftJoining = [ + 0x0620 => 1, 0x0626 => 1, 0x0628 => 1, 0x062A => 1, 0x062B => 1, 0x062C => 1, 0x062D => 1, 0x062E => 1, + 0x0633 => 1, 0x0634 => 1, 0x0635 => 1, 0x0636 => 1, 0x0637 => 1, 0x0638 => 1, 0x0639 => 1, 0x063A => 1, + 0x063B => 1, 0x063C => 1, 0x063D => 1, 0x063E => 1, 0x063F => 1, 0x0640 => 1, 0x0641 => 1, 0x0642 => 1, + 0x0643 => 1, 0x0644 => 1, 0x0645 => 1, 0x0646 => 1, 0x0647 => 1, 0x0649 => 1, 0x064A => 1, 0x066E => 1, + 0x066F => 1, 0x0678 => 1, 0x0679 => 1, 0x067A => 1, 0x067B => 1, 0x067C => 1, 0x067D => 1, 0x067E => 1, + 0x067F => 1, 0x0680 => 1, 0x0681 => 1, 0x0682 => 1, 0x0683 => 1, 0x0684 => 1, 0x0685 => 1, 0x0686 => 1, + 0x0687 => 1, 0x069A => 1, 0x069B => 1, 0x069C => 1, 0x069D => 1, 0x069E => 1, 0x069F => 1, 0x06A0 => 1, + 0x06A1 => 1, 0x06A2 => 1, 0x06A3 => 1, 0x06A4 => 1, 0x06A5 => 1, 0x06A6 => 1, 0x06A7 => 1, 0x06A8 => 1, + 0x06A9 => 1, 0x06AA => 1, 0x06AB => 1, 0x06AC => 1, 0x06AD => 1, 0x06AE => 1, 0x06AF => 1, 0x06B0 => 1, + 0x06B1 => 1, 0x06B2 => 1, 0x06B3 => 1, 0x06B4 => 1, 0x06B5 => 1, 0x06B6 => 1, 0x06B7 => 1, 0x06B8 => 1, + 0x06B9 => 1, 0x06BA => 1, 0x06BB => 1, 0x06BC => 1, 0x06BD => 1, 0x06BE => 1, 0x06BF => 1, 0x06C1 => 1, + 0x06C2 => 1, 0x06CC => 1, 0x06CE => 1, 0x06D0 => 1, 0x06D1 => 1, 0x06FA => 1, 0x06FB => 1, 0x06FC => 1, + 0x06FF => 1, + /* Arabic Supplement */ + 0x0750 => 1, 0x0751 => 1, 0x0752 => 1, 0x0753 => 1, 0x0754 => 1, 0x0755 => 1, 0x0756 => 1, 0x0757 => 1, + 0x0758 => 1, 0x075C => 1, 0x075D => 1, 0x075E => 1, 0x075F => 1, 0x0760 => 1, 0x0761 => 1, 0x0762 => 1, + 0x0763 => 1, 0x0764 => 1, 0x0765 => 1, 0x0766 => 1, 0x0767 => 1, 0x0768 => 1, 0x0769 => 1, 0x076A => 1, + 0x076D => 1, 0x076E => 1, 0x076F => 1, 0x0770 => 1, 0x0772 => 1, 0x0775 => 1, 0x0776 => 1, 0x0777 => 1, + 0x077A => 1, 0x077B => 1, 0x077C => 1, 0x077D => 1, 0x077E => 1, 0x077F => 1, + /* Extended Arabic */ + 0x08A0 => 1, 0x08A2 => 1, 0x08A3 => 1, 0x08A4 => 1, 0x08A5 => 1, 0x08A6 => 1, 0x08A7 => 1, 0x08A8 => 1, + 0x08A9 => 1, + /* 'syrc' Syriac */ + 0x0712 => 1, 0x0713 => 1, 0x0714 => 1, 0x071A => 1, 0x071B => 1, 0x071C => 1, 0x071D => 1, 0x071F => 1, + 0x0720 => 1, 0x0721 => 1, 0x0722 => 1, 0x0723 => 1, 0x0724 => 1, 0x0725 => 1, 0x0726 => 1, 0x0727 => 1, + 0x0729 => 1, 0x072B => 1, 0x072D => 1, 0x072E => 1, 0x074E => 1, 0x074F => 1, + /* N'Ko */ + 0x07CA => 1, 0x07CB => 1, 0x07CC => 1, 0x07CD => 1, 0x07CE => 1, 0x07CF => 1, 0x07D0 => 1, 0x07D1 => 1, + 0x07D2 => 1, 0x07D3 => 1, 0x07D4 => 1, 0x07D5 => 1, 0x07D6 => 1, 0x07D7 => 1, 0x07D8 => 1, 0x07D9 => 1, + 0x07DA => 1, 0x07DB => 1, 0x07DC => 1, 0x07DD => 1, 0x07DE => 1, 0x07DF => 1, 0x07E0 => 1, 0x07E1 => 1, + 0x07E2 => 1, 0x07E3 => 1, 0x07E4 => 1, 0x07E5 => 1, 0x07E6 => 1, 0x07E7 => 1, 0x07E8 => 1, 0x07E9 => 1, + 0x07EA => 1, 0x07FA => 1, + /* Mandaic */ + 0x0841 => 1, 0x0842 => 1, 0x0843 => 1, 0x0844 => 1, 0x0845 => 1, 0x0847 => 1, 0x0848 => 1, 0x084A => 1, + 0x084B => 1, 0x084C => 1, 0x084D => 1, 0x084E => 1, 0x0850 => 1, 0x0851 => 1, 0x0852 => 1, 0x0853 => 1, + 0x0855 => 1, + /* ZWJ U+200D */ + 0x0200D => 1]; + + /* JOIN TO PREVIOUS LETTER IN LOGICAL ORDER (i.e. AS FINAL/MEDIAL FORM) = Unicode Right-Joining (+ Dual-Joining + Join_Causing) */ + $this->arabRightJoining = [ + 0x0620 => 1, 0x0622 => 1, 0x0623 => 1, 0x0624 => 1, 0x0625 => 1, 0x0626 => 1, 0x0627 => 1, 0x0628 => 1, + 0x0629 => 1, 0x062A => 1, 0x062B => 1, 0x062C => 1, 0x062D => 1, 0x062E => 1, 0x062F => 1, 0x0630 => 1, + 0x0631 => 1, 0x0632 => 1, 0x0633 => 1, 0x0634 => 1, 0x0635 => 1, 0x0636 => 1, 0x0637 => 1, 0x0638 => 1, + 0x0639 => 1, 0x063A => 1, 0x063B => 1, 0x063C => 1, 0x063D => 1, 0x063E => 1, 0x063F => 1, 0x0640 => 1, + 0x0641 => 1, 0x0642 => 1, 0x0643 => 1, 0x0644 => 1, 0x0645 => 1, 0x0646 => 1, 0x0647 => 1, 0x0648 => 1, + 0x0649 => 1, 0x064A => 1, 0x066E => 1, 0x066F => 1, 0x0671 => 1, 0x0672 => 1, 0x0673 => 1, 0x0675 => 1, + 0x0676 => 1, 0x0677 => 1, 0x0678 => 1, 0x0679 => 1, 0x067A => 1, 0x067B => 1, 0x067C => 1, 0x067D => 1, + 0x067E => 1, 0x067F => 1, 0x0680 => 1, 0x0681 => 1, 0x0682 => 1, 0x0683 => 1, 0x0684 => 1, 0x0685 => 1, + 0x0686 => 1, 0x0687 => 1, 0x0688 => 1, 0x0689 => 1, 0x068A => 1, 0x068B => 1, 0x068C => 1, 0x068D => 1, + 0x068E => 1, 0x068F => 1, 0x0690 => 1, 0x0691 => 1, 0x0692 => 1, 0x0693 => 1, 0x0694 => 1, 0x0695 => 1, + 0x0696 => 1, 0x0697 => 1, 0x0698 => 1, 0x0699 => 1, 0x069A => 1, 0x069B => 1, 0x069C => 1, 0x069D => 1, + 0x069E => 1, 0x069F => 1, 0x06A0 => 1, 0x06A1 => 1, 0x06A2 => 1, 0x06A3 => 1, 0x06A4 => 1, 0x06A5 => 1, + 0x06A6 => 1, 0x06A7 => 1, 0x06A8 => 1, 0x06A9 => 1, 0x06AA => 1, 0x06AB => 1, 0x06AC => 1, 0x06AD => 1, + 0x06AE => 1, 0x06AF => 1, 0x06B0 => 1, 0x06B1 => 1, 0x06B2 => 1, 0x06B3 => 1, 0x06B4 => 1, 0x06B5 => 1, + 0x06B6 => 1, 0x06B7 => 1, 0x06B8 => 1, 0x06B9 => 1, 0x06BA => 1, 0x06BB => 1, 0x06BC => 1, 0x06BD => 1, + 0x06BE => 1, 0x06BF => 1, 0x06C0 => 1, 0x06C1 => 1, 0x06C2 => 1, 0x06C3 => 1, 0x06C4 => 1, 0x06C5 => 1, + 0x06C6 => 1, 0x06C7 => 1, 0x06C8 => 1, 0x06C9 => 1, 0x06CA => 1, 0x06CB => 1, 0x06CC => 1, 0x06CD => 1, + 0x06CE => 1, 0x06CF => 1, 0x06D0 => 1, 0x06D1 => 1, 0x06D2 => 1, 0x06D3 => 1, 0x06D5 => 1, 0x06EE => 1, + 0x06EF => 1, 0x06FA => 1, 0x06FB => 1, 0x06FC => 1, 0x06FF => 1, + /* Arabic Supplement */ + 0x0750 => 1, 0x0751 => 1, 0x0752 => 1, 0x0753 => 1, 0x0754 => 1, 0x0755 => 1, 0x0756 => 1, 0x0757 => 1, + 0x0758 => 1, 0x0759 => 1, 0x075A => 1, 0x075B => 1, 0x075C => 1, 0x075D => 1, 0x075E => 1, 0x075F => 1, + 0x0760 => 1, 0x0761 => 1, 0x0762 => 1, 0x0763 => 1, 0x0764 => 1, 0x0765 => 1, 0x0766 => 1, 0x0767 => 1, + 0x0768 => 1, 0x0769 => 1, 0x076A => 1, 0x076B => 1, 0x076C => 1, 0x076D => 1, 0x076E => 1, 0x076F => 1, + 0x0770 => 1, 0x0771 => 1, 0x0772 => 1, 0x0773 => 1, 0x0774 => 1, 0x0775 => 1, 0x0776 => 1, 0x0777 => 1, + 0x0778 => 1, 0x0779 => 1, 0x077A => 1, 0x077B => 1, 0x077C => 1, 0x077D => 1, 0x077E => 1, 0x077F => 1, + /* Extended Arabic */ + 0x08A0 => 1, 0x08A2 => 1, 0x08A3 => 1, 0x08A4 => 1, 0x08A5 => 1, 0x08A6 => 1, 0x08A7 => 1, 0x08A8 => 1, + 0x08A9 => 1, 0x08AA => 1, 0x08AB => 1, 0x08AC => 1, + /* 'syrc' Syriac */ + 0x0710 => 1, 0x0712 => 1, 0x0713 => 1, 0x0714 => 1, 0x0715 => 1, 0x0716 => 1, 0x0717 => 1, 0x0718 => 1, + 0x0719 => 1, 0x071A => 1, 0x071B => 1, 0x071C => 1, 0x071D => 1, 0x071E => 1, 0x071F => 1, 0x0720 => 1, + 0x0721 => 1, 0x0722 => 1, 0x0723 => 1, 0x0724 => 1, 0x0725 => 1, 0x0726 => 1, 0x0727 => 1, 0x0728 => 1, + 0x0729 => 1, 0x072A => 1, 0x072B => 1, 0x072C => 1, 0x072D => 1, 0x072E => 1, 0x072F => 1, 0x074D => 1, + 0x074E => 1, 0x074F, + /* N'Ko */ + 0x07CA => 1, 0x07CB => 1, 0x07CC => 1, 0x07CD => 1, 0x07CE => 1, 0x07CF => 1, 0x07D0 => 1, 0x07D1 => 1, + 0x07D2 => 1, 0x07D3 => 1, 0x07D4 => 1, 0x07D5 => 1, 0x07D6 => 1, 0x07D7 => 1, 0x07D8 => 1, 0x07D9 => 1, + 0x07DA => 1, 0x07DB => 1, 0x07DC => 1, 0x07DD => 1, 0x07DE => 1, 0x07DF => 1, 0x07E0 => 1, 0x07E1 => 1, + 0x07E2 => 1, 0x07E3 => 1, 0x07E4 => 1, 0x07E5 => 1, 0x07E6 => 1, 0x07E7 => 1, 0x07E8 => 1, 0x07E9 => 1, + 0x07EA => 1, 0x07FA => 1, + /* Mandaic */ + 0x0841 => 1, 0x0842 => 1, 0x0843 => 1, 0x0844 => 1, 0x0845 => 1, 0x0847 => 1, 0x0848 => 1, 0x084A => 1, + 0x084B => 1, 0x084C => 1, 0x084D => 1, 0x084E => 1, 0x0850 => 1, 0x0851 => 1, 0x0852 => 1, 0x0853 => 1, + 0x0855 => 1, + 0x0840 => 1, 0x0846 => 1, 0x0849 => 1, 0x084F => 1, 0x0854 => 1, /* Right joining */ + /* ZWJ U+200D */ + 0x0200D => 1]; + + /* VOWELS = TRANSPARENT-JOINING = Unicode Transparent-Joining type (not just vowels) */ + $this->arabTransparent = [ + 0x0610 => 1, 0x0611 => 1, 0x0612 => 1, 0x0613 => 1, 0x0614 => 1, 0x0615 => 1, 0x0616 => 1, 0x0617 => 1, + 0x0618 => 1, 0x0619 => 1, 0x061A => 1, 0x064B => 1, 0x064C => 1, 0x064D => 1, 0x064E => 1, 0x064F => 1, + 0x0650 => 1, 0x0651 => 1, 0x0652 => 1, 0x0653 => 1, 0x0654 => 1, 0x0655 => 1, 0x0656 => 1, 0x0657 => 1, + 0x0658 => 1, 0x0659 => 1, 0x065A => 1, 0x065B => 1, 0x065C => 1, 0x065D => 1, 0x065E => 1, 0x065F => 1, + 0x0670 => 1, 0x06D6 => 1, 0x06D7 => 1, 0x06D8 => 1, 0x06D9 => 1, 0x06DA => 1, 0x06DB => 1, 0x06DC => 1, + 0x06DF => 1, 0x06E0 => 1, 0x06E1 => 1, 0x06E2 => 1, 0x06E3 => 1, 0x06E4 => 1, 0x06E7 => 1, 0x06E8 => 1, + 0x06EA => 1, 0x06EB => 1, 0x06EC => 1, 0x06ED => 1, + /* Extended Arabic */ + 0x08E4 => 1, 0x08E5 => 1, 0x08E6 => 1, 0x08E7 => 1, 0x08E8 => 1, 0x08E9 => 1, 0x08EA => 1, 0x08EB => 1, + 0x08EC => 1, 0x08ED => 1, 0x08EE => 1, 0x08EF => 1, 0x08F0 => 1, 0x08F1 => 1, 0x08F2 => 1, 0x08F3 => 1, + 0x08F4 => 1, 0x08F5 => 1, 0x08F6 => 1, 0x08F7 => 1, 0x08F8 => 1, 0x08F9 => 1, 0x08FA => 1, 0x08FB => 1, + 0x08FC => 1, 0x08FD => 1, 0x08FE => 1, + /* Arabic ligatures in presentation form (converted in 'ccmp' in e.g. Arial and Times ? need to add others in this range) */ + 0xFC5E => 1, 0xFC5F => 1, 0xFC60 => 1, 0xFC61 => 1, 0xFC62 => 1, + /* 'syrc' Syriac */ + 0x070F => 1, 0x0711 => 1, 0x0730 => 1, 0x0731 => 1, 0x0732 => 1, 0x0733 => 1, 0x0734 => 1, 0x0735 => 1, + 0x0736 => 1, 0x0737 => 1, 0x0738 => 1, 0x0739 => 1, 0x073A => 1, 0x073B => 1, 0x073C => 1, 0x073D => 1, + 0x073E => 1, 0x073F => 1, 0x0740 => 1, 0x0741 => 1, 0x0742 => 1, 0x0743 => 1, 0x0744 => 1, 0x0745 => 1, + 0x0746 => 1, 0x0747 => 1, 0x0748 => 1, 0x0749 => 1, 0x074A => 1, + /* N'Ko */ + 0x07EB => 1, 0x07EC => 1, 0x07ED => 1, 0x07EE => 1, 0x07EF => 1, 0x07F0 => 1, 0x07F1 => 1, 0x07F2 => 1, + 0x07F3 => 1, + /* Mandaic */ + 0x0859 => 1, 0x085A => 1, 0x085B => 1, + ]; + } + + private function arabic_shaper($usetags, $scriptTag) + { + $chars = []; + for ($i = 0; $i < count($this->OTLdata); $i++) { + $chars[] = $this->OTLdata[$i]['hex']; + } + + $crntChar = null; + $prevChar = null; + $nextChar = null; + $output = []; + $max = count($chars); + for ($i = $max - 1; $i >= 0; $i--) { + $crntChar = $chars[$i]; + if ($i > 0) { + $prevChar = hexdec($chars[$i - 1]); + } else { + $prevChar = null; + } + if ($prevChar && isset($this->arabTransparentJoin[$prevChar]) && isset($chars[$i - 2])) { + $prevChar = hexdec($chars[$i - 2]); + if ($prevChar && isset($this->arabTransparentJoin[$prevChar]) && isset($chars[$i - 3])) { + $prevChar = hexdec($chars[$i - 3]); + if ($prevChar && isset($this->arabTransparentJoin[$prevChar]) && isset($chars[$i - 4])) { + $prevChar = hexdec($chars[$i - 4]); + } + } + } + if ($crntChar && isset($this->arabTransparentJoin[hexdec($crntChar)])) { + // If next_char = RightJoining && prev_char = LeftJoining: + if (isset($chars[$i + 1]) && $chars[$i + 1] && isset($this->arabRightJoining[hexdec($chars[$i + 1])]) && $prevChar && isset($this->arabLeftJoining[$prevChar])) { + $output[] = $this->get_arab_glyphs($crntChar, 1, $chars, $i, $scriptTag, $usetags); // <final> form + } else { + $output[] = $this->get_arab_glyphs($crntChar, 0, $chars, $i, $scriptTag, $usetags); // <isolated> form + } + continue; + } + if (hexdec($crntChar) < 128) { + $output[] = [$crntChar, 0]; + $nextChar = $crntChar; + continue; + } + // 0=ISOLATED FORM :: 1=FINAL :: 2=INITIAL :: 3=MEDIAL + $form = 0; + if ($prevChar && isset($this->arabLeftJoining[$prevChar])) { + $form++; + } + if ($nextChar && isset($this->arabRightJoining[hexdec($nextChar)])) { + $form += 2; + } + $output[] = $this->get_arab_glyphs($crntChar, $form, $chars, $i, $scriptTag, $usetags); + $nextChar = $crntChar; + } + $ra = array_reverse($output); + for ($i = 0; $i < count($this->OTLdata); $i++) { + $this->OTLdata[$i]['uni'] = hexdec($ra[$i][0]); + $this->OTLdata[$i]['hex'] = $ra[$i][0]; + $this->OTLdata[$i]['form'] = $ra[$i][1]; // Actaul form substituted 0=ISOLATED FORM :: 1=FINAL :: 2=INITIAL :: 3=MEDIAL + } + } + + private function get_arab_glyphs($char, $type, &$chars, $i, $scriptTag, $usetags) + { + // Optional Feature settings // doesn't control Syriac at present + if (($type === 0 && strpos($usetags, 'isol') === false) || ($type === 1 && strpos($usetags, 'fina') === false) || ($type === 2 && strpos($usetags, 'init') === false) || ($type === 3 && strpos($usetags, 'medi') === false)) { + return [$char, 0]; + } + + // 0=ISOLATED FORM :: 1=FINAL :: 2=INITIAL :: 3=MEDIAL (:: 4=MED2 :: 5=FIN2 :: 6=FIN3) + $retk = -1; + // Alaph 00710 in Syriac + if ($scriptTag == 'syrc' && $char == '00710') { + // if there is a preceding (base?) character *** should search back to previous base - ignoring vowels and change $n + // set $n as the position of the last base; for now we'll just do this: + $n = $i - 1; + // if the preceding (base) character cannot be joined to + // not in $this->arabLeftJoining i.e. not a char which can join to the next one + if (isset($chars[$n]) && isset($this->arabLeftJoining[hexdec($chars[$n])])) { + // if in the middle of Syriac words + if (isset($chars[$i + 1]) && preg_match('/[\x{0700}-\x{0745}]/u', UtfString::code2utf(hexdec($chars[$n]))) && preg_match('/[\x{0700}-\x{0745}]/u', UtfString::code2utf(hexdec($chars[$i + 1]))) && isset($this->arabGlyphs[$char][4])) { + $retk = 4; + } // if at the end of Syriac words + elseif (!isset($chars[$i + 1]) || !preg_match('/[\x{0700}-\x{0745}]/u', UtfString::code2utf(hexdec($chars[$i + 1])))) { + // if preceding base character IS (00715|00716|0072A) + if (strpos('0715|0716|072A', $chars[$n]) !== false && isset($this->arabGlyphs[$char][6])) { + $retk = 6; + } // elseif preceding base character is NOT (00715|00716|0072A) + elseif (isset($this->arabGlyphs[$char][5])) { + $retk = 5; + } + } + } + if ($retk != -1) { + return [$this->arabGlyphs[$char][$retk], $retk]; + } else { + return [$char, 0]; + } + } + + if (($type > 0 || $type === 0) && isset($this->arabGlyphs[$char][$type])) { + $retk = $type; + } elseif ($type == 3 && isset($this->arabGlyphs[$char][1])) { // if <medial> not defined, but <final>, return <final> + $retk = 1; + } elseif ($type == 2 && isset($this->arabGlyphs[$char][0])) { // if <initial> not defined, but <isolated>, return <isolated> + $retk = 0; + } + if ($retk != -1) { + $match = true; + // If GSUB includes a Backtrack or Lookahead condition (e.g. font ArabicTypesetting) + if (isset($this->arabGlyphs[$char]['prel'][$retk]) && $this->arabGlyphs[$char]['prel'][$retk]) { + $ig = 1; + foreach ($this->arabGlyphs[$char]['prel'][$retk] as $k => $v) { // $k starts 0, 1... + if (!isset($chars[$i - $ig - $k])) { + $match = false; + } elseif (strpos($v, $chars[$i - $ig - $k]) === false) { + while (strpos($this->arabGlyphs[$char]['ignore'][$retk], $chars[$i - $ig - $k]) !== false) { // ignore + $ig++; + } + if (!isset($chars[$i - $ig - $k])) { + $match = false; + } elseif (strpos($v, $chars[$i - $ig - $k]) === false) { + $match = false; + } + } + } + } + if (isset($this->arabGlyphs[$char]['postl'][$retk]) && $this->arabGlyphs[$char]['postl'][$retk]) { + $ig = 1; + foreach ($this->arabGlyphs[$char]['postl'][$retk] as $k => $v) { // $k starts 0, 1... + if (!isset($chars[$i + $ig + $k])) { + $match = false; + } elseif (strpos($v, $chars[$i + $ig + $k]) === false) { + while (strpos($this->arabGlyphs[$char]['ignore'][$retk], $chars[$i + $ig + $k]) !== false) { // ignore + $ig++; + } + if (!isset($chars[$i + $ig + $k])) { + $match = false; + } elseif (strpos($v, $chars[$i + $ig + $k]) === false) { + $match = false; + } + } + } + } + if ($match) { + return [$this->arabGlyphs[$char][$retk], $retk]; + } else { + return [$char, 0]; + } + } else { + return [$char, 0]; + } + } + + //////////////////////////////////////////////////////////////// + ///////////////// LINE BREAKING /////////////////////// + //////////////////////////////////////////////////////////////// + ///////////// TIBETAN LINE BREAKING /////////////////// + //////////////////////////////////////////////////////////////// + // Sets $this->OTLdata[$i]['wordend']=true at possible end of word boundaries + private function tibetanLineBreaking() + { + for ($ptr = 0; $ptr < count($this->OTLdata); $ptr++) { + // Break opportunities at U+0F0B Tsheg or U=0F0D + if (isset($this->OTLdata[$ptr]['uni']) && ($this->OTLdata[$ptr]['uni'] == 0x0F0B || $this->OTLdata[$ptr]['uni'] == 0x0F0D)) { + if (isset($this->OTLdata[$ptr + 1]['uni']) && ($this->OTLdata[$ptr + 1]['uni'] == 0x0F0D || $this->OTLdata[$ptr + 1]['uni'] == 0xF0E)) { + continue; + } + // Set end of word marker in OTLdata at matchpos + $this->OTLdata[$ptr]['wordend'] = true; + } + } + } + + /** + * South East Asian Linebreaking (Thai, Khmer and Lao) using dictionary of words + * + * Sets $this->OTLdata[$i]['wordend']=true at possible end of word boundaries + */ + private function seaLineBreaking() + { + // Load Line-breaking dictionary + if (!isset($this->lbdicts[$this->shaper]) && file_exists(__DIR__ . '/../data/linebrdict' . $this->shaper . '.dat')) { + $this->lbdicts[$this->shaper] = file_get_contents(__DIR__ . '/../data/linebrdict' . $this->shaper . '.dat'); + } + + $dict = &$this->lbdicts[$this->shaper]; + + // Find all word boundaries and mark end of word $this->OTLdata[$i]['wordend']=true on last character + // If Thai, allow for possible suffixes (not in Lao or Khmer) + // repeater/ellision characters + // (0x0E2F); // Ellision character THAI_PAIYANNOI 0x0E2F UTF-8 0xE0 0xB8 0xAF + // (0x0E46); // Repeat character THAI_MAIYAMOK 0x0E46 UTF-8 0xE0 0xB9 0x86 + // (0x0EC6); // Repeat character LAO UTF-8 0xE0 0xBB 0x86 + + $rollover = []; + $ptr = 0; + + while ($ptr < count($this->OTLdata) - 3) { + if (count($rollover)) { + $matches = $rollover; + $rollover = []; + } else { + $matches = $this->checkwordmatch($dict, $ptr); + } + if (count($matches) == 1) { + $matchpos = $matches[0]; + // Check for repeaters - if so $matchpos++ + if (isset($this->OTLdata[$matchpos + 1]['uni']) && ($this->OTLdata[$matchpos + 1]['uni'] == 0x0E2F || $this->OTLdata[$matchpos + 1]['uni'] == 0x0E46 || $this->OTLdata[$matchpos + 1]['uni'] == 0x0EC6)) { + $matchpos++; + } + // Set end of word marker in OTLdata at matchpos + $this->OTLdata[$matchpos]['wordend'] = true; + $ptr = $matchpos + 1; + } elseif (empty($matches)) { + $ptr++; + // Move past any ASCII characters + while (isset($this->OTLdata[$ptr]['uni']) && ($this->OTLdata[$ptr]['uni'] >> 8) == 0) { + $ptr++; + } + } else { // Multiple matches + $secondmatch = false; + for ($m = count($matches) - 1; $m >= 0; $m--) { + //for ($m=0;$m<count($matches);$m++) { + $firstmatch = $matches[$m]; + $matches2 = $this->checkwordmatch($dict, $firstmatch + 1); + if (count($matches2)) { + // Set end of word marker in OTLdata at matchpos + $this->OTLdata[$firstmatch]['wordend'] = true; + $ptr = $firstmatch + 1; + $rollover = $matches2; + $secondmatch = true; + break; + } + } + if (!$secondmatch) { + // Set end of word marker in OTLdata at end of longest first match + $this->OTLdata[$matches[count($matches) - 1]]['wordend'] = true; + $ptr = $matches[count($matches) - 1] + 1; + // Move past any ASCII characters + while (isset($this->OTLdata[$ptr]['uni']) && ($this->OTLdata[$ptr]['uni'] >> 8) == 0) { + $ptr++; + } + } + } + } + } + + private function checkwordmatch(&$dict, $ptr) + { + /* + Node type: Split. + Divide at < 98 >= 98 + Offset for >= 98 == 79 (long 4-byte unsigned) + + Node type: Linear match. + Char = 97 + + Intermediate match + + Final match + */ + + $dictptr = 0; + $ok = true; + $matches = []; + while ($ok) { + $x = ord($dict[$dictptr]); + $c = $this->OTLdata[$ptr]['uni'] & 0xFF; + if ($x == static::_DICT_INTERMEDIATE_MATCH) { +//echo "DICT_INTERMEDIATE_MATCH: ".dechex($c).'<br />'; + // Do not match if next character in text is a Mark + if (isset($this->OTLdata[$ptr]['uni']) && strpos($this->GlyphClassMarks, $this->OTLdata[$ptr]['hex']) === false) { + $matches[] = $ptr - 1; + } + $dictptr++; + } elseif ($x == static::_DICT_FINAL_MATCH) { +//echo "DICT_FINAL_MATCH: ".dechex($c).'<br />'; + // Do not match if next character in text is a Mark + if (isset($this->OTLdata[$ptr]['uni']) && strpos($this->GlyphClassMarks, $this->OTLdata[$ptr]['hex']) === false) { + $matches[] = $ptr - 1; + } + return $matches; + } elseif ($x == static::_DICT_NODE_TYPE_LINEAR) { +//echo "DICT_NODE_TYPE_LINEAR: ".dechex($c).'<br />'; + $dictptr++; + $m = ord($dict[$dictptr]); + if ($c == $m) { + $ptr++; + if ($ptr > count($this->OTLdata) - 1) { + $next = ord($dict[$dictptr + 1]); + if ($next == static::_DICT_INTERMEDIATE_MATCH || $next == static::_DICT_FINAL_MATCH) { + // Do not match if next character in text is a Mark + if (isset($this->OTLdata[$ptr]['uni']) && strpos($this->GlyphClassMarks, $this->OTLdata[$ptr]['hex']) === false) { + $matches[] = $ptr - 1; + } + } + return $matches; + } + $dictptr++; + continue; + } else { +//echo "DICT_NODE_TYPE_LINEAR NOT: ".dechex($c).'<br />'; + return $matches; + } + } elseif ($x == static::_DICT_NODE_TYPE_SPLIT) { +//echo "DICT_NODE_TYPE_SPLIT ON ".dechex($d).": ".dechex($c).'<br />'; + $dictptr++; + $d = ord($dict[$dictptr]); + if ($c < $d) { + $dictptr += 5; + } else { + $dictptr++; + // Unsigned long 32-bit offset + $offset = (ord($dict[$dictptr]) * 16777216) + (ord($dict[$dictptr + 1]) << 16) + (ord($dict[$dictptr + 2]) << 8) + ord($dict[$dictptr + 3]); + $dictptr = $offset; + } + } else { +//echo "PROBLEM: ".($x).'<br />'; + $ok = false; // Something has gone wrong + } + } + + return $matches; + } + + //////////////////////////////////////////////////////////////// + ////////// GPOS /////////////////////////////////////// + //////////////////////////////////////////////////////////////// + private function _applyGPOSrules($LookupList, $is_old_spec = false) + { + foreach ($LookupList as $lu => $tag) { + $Type = $this->GPOSLookups[$lu]['Type']; + $Flag = $this->GPOSLookups[$lu]['Flag']; + $MarkFilteringSet = ''; + if (isset($this->GPOSLookups[$lu]['MarkFilteringSet'])) { + $MarkFilteringSet = $this->GPOSLookups[$lu]['MarkFilteringSet']; + } + $ptr = 0; + // Test each glyph sequentially + while ($ptr < (count($this->OTLdata))) { // whilst there is another glyph ..0064 + $currGlyph = $this->OTLdata[$ptr]['hex']; + $currGID = $this->OTLdata[$ptr]['uni']; + $shift = 1; + foreach ($this->GPOSLookups[$lu]['Subtables'] as $c => $subtable_offset) { + // NB Coverage only looks at glyphs for position 1 (esp. 7.3 and 8.3) + if (isset($this->LuCoverage[$lu][$c][$currGID])) { + // Get rules from font GPOS subtable + if (isset($this->OTLdata[$ptr]['bidi_type'])) { // No need to check bidi_type - just a check that it exists + $shift = $this->_applyGPOSsubtable($lu, $c, $ptr, $currGlyph, $currGID, ($subtable_offset - $this->GPOS_offset + $this->GSUB_length), $Type, $Flag, $MarkFilteringSet, $this->LuCoverage[$lu][$c], $tag, 0, $is_old_spec); + if ($shift) { + break; + } + } + } + } + if ($shift == 0) { + $shift = 1; + } + $ptr += $shift; + } + } + } + + ////////////////////////////////////////////////////////////////////////////////// + // GPOS Types + // Lookup Type 1: Single Adjustment Positioning Subtable Adjust position of a single glyph + // Lookup Type 2: Pair Adjustment Positioning Subtable Adjust position of a pair of glyphs + // Lookup Type 3: Cursive Attachment Positioning Subtable Attach cursive glyphs + // Lookup Type 4: MarkToBase Attachment Positioning Subtable Attach a combining mark to a base glyph + // Lookup Type 5: MarkToLigature Attachment Positioning Subtable Attach a combining mark to a ligature + // Lookup Type 6: MarkToMark Attachment Positioning Subtable Attach a combining mark to another mark + // Lookup Type 7: Contextual Positioning Subtables Position one or more glyphs in context + // Lookup Type 8: Chaining Contextual Positioning Subtable Position one or more glyphs in chained context + // Lookup Type 9: Extension positioning + ////////////////////////////////////////////////////////////////////////////////// + private function _applyGPOSvaluerecord($basepos, $Value) + { + + // If current glyph is a mark with a defined width, any XAdvance is considered to REPLACE the character Advance Width + // Test case <div style="font-family:myanmartext">င်္က္ကျြွေိ</div> + if (strpos($this->GlyphClassMarks, $this->OTLdata[$basepos]['hex']) !== false) { + $cw = round($this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$basepos]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000); // convert back to font design units + } else { + $cw = 0; + } + + $apos = $this->_getXAdvancePos($basepos); + + if (isset($Value['XAdvance']) && ($Value['XAdvance'] - $cw) != 0) { + // However DON'T REPLACE the character Advance Width if Advance Width is negative + // Test case <div style="font-family: dejavusansmono">ру́сский</div> + if ($Value['XAdvance'] < 0) { + $cw = 0; + } + + // For LTR apply XAdvanceL to the last mark following the base = at $apos + // For RTL apply XAdvanceR to base = at $basepos + if (isset($this->OTLdata[$apos]['GPOSinfo']['XAdvanceL'])) { + $this->OTLdata[$apos]['GPOSinfo']['XAdvanceL'] += $Value['XAdvance'] - $cw; + } else { + $this->OTLdata[$apos]['GPOSinfo']['XAdvanceL'] = $Value['XAdvance'] - $cw; + } + if (isset($this->OTLdata[$basepos]['GPOSinfo']['XAdvanceR'])) { + $this->OTLdata[$basepos]['GPOSinfo']['XAdvanceR'] += $Value['XAdvance'] - $cw; + } else { + $this->OTLdata[$basepos]['GPOSinfo']['XAdvanceR'] = $Value['XAdvance'] - $cw; + } + } + + // Any XPlacement (? and Y Placement) apply to base and marks (from basepos to apos) + for ($a = $basepos; $a <= $apos; $a++) { + if (isset($Value['XPlacement'])) { + if (isset($this->OTLdata[$a]['GPOSinfo']['XPlacement'])) { + $this->OTLdata[$a]['GPOSinfo']['XPlacement'] += $Value['XPlacement']; + } else { + $this->OTLdata[$a]['GPOSinfo']['XPlacement'] = $Value['XPlacement']; + } + } + if (isset($Value['YPlacement'])) { + if (isset($this->OTLdata[$a]['GPOSinfo']['YPlacement'])) { + $this->OTLdata[$a]['GPOSinfo']['YPlacement'] += $Value['YPlacement']; + } else { + $this->OTLdata[$a]['GPOSinfo']['YPlacement'] = $Value['YPlacement']; + } + } + } + } + + // If XAdvance is aplied to $ptr - in order for PDF to position the Advance correctly need to place it on + // the last of any Marks which immediately follow the current glyph + private function _getXAdvancePos($pos) + { + // NB Not all fonts have all marks specified in GlyphClassMarks + // If the current glyph is not a base (but a mark) then ignore this, and apply to the current position + if (strpos($this->GlyphClassMarks, $this->OTLdata[$pos]['hex']) !== false) { + return $pos; + } + + while (isset($this->OTLdata[$pos + 1]['hex']) && strpos($this->GlyphClassMarks, $this->OTLdata[$pos + 1]['hex']) !== false) { + $pos++; + } + return $pos; + } + + private function _applyGPOSsubtable($lookupID, $subtable, $ptr, $currGlyph, $currGID, $subtable_offset, $Type, $Flag, $MarkFilteringSet, $LuCoverage, $tag, $level, $is_old_spec) + { + if (($Flag & 0x0001) == 1) { + $dir = 'RTL'; + } else { // only used for Type 3 + $dir = 'LTR'; + } + + $ignore = $this->_getGCOMignoreString($Flag, $MarkFilteringSet); + + // Lets start + $this->seek($subtable_offset); + $PosFormat = $this->read_ushort(); + + //////////////////////////////////////////////////////////////////////////////// + // LookupType 1: Single adjustment Adjust position of a single glyph (e.g. SmallCaps/Sups/Subs) + //////////////////////////////////////////////////////////////////////////////// + if ($Type == 1) { + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat = $this->read_ushort(); + $Value = $this->_getValueRecord($ValueFormat); + } //=========== + // Format 2: + //=========== + elseif ($PosFormat == 2) { + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat = $this->read_ushort(); + $ValueCount = $this->read_ushort(); + $GlyphPos = $LuCoverage[$currGID]; + $this->skip($GlyphPos * 2 * $this->count_bits($ValueFormat)); + $Value = $this->_getValueRecord($ValueFormat); + } + $this->_applyGPOSvaluerecord($ptr, $Value); + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return 1; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 2: Pair adjustment Adjust position of a pair of glyphs (Kerning) + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 2) { + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat1 = $this->read_ushort(); + $ValueFormat2 = $this->read_ushort(); + $sizeOfPair = ( 2 * $this->count_bits($ValueFormat1) ) + ( 2 * $this->count_bits($ValueFormat2) ); + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + $PairSetCount = $this->read_ushort(); + $PairSetOffset = []; + for ($p = 0; $p < $PairSetCount; $p++) { + $PairSetOffset[] = $subtable_offset + $this->read_ushort(); + } + for ($p = 0; $p < $PairSetCount; $p++) { + if (isset($LuCoverage[$currGID]) && $LuCoverage[$currGID] == $p) { + $this->seek($PairSetOffset[$p]); + //PairSet table + $PairValueCount = $this->read_ushort(); + for ($pv = 0; $pv < $PairValueCount; $pv++) { + //PairValueRecord + $gid = $this->read_ushort(); + $SecondGlyph = $this->glyphToChar($gid); + $FirstGlyph = $this->OTLdata[$ptr]['uni']; + + $checkpos = $ptr; + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + if (isset($this->OTLdata[$checkpos]) && $this->OTLdata[$checkpos]['uni'] == $SecondGlyph) { + $matchedpos = $checkpos; + } else { + $matchedpos = false; + } + + if ($matchedpos !== false) { + $Value1 = $this->_getValueRecord($ValueFormat1); + $Value2 = $this->_getValueRecord($ValueFormat2); + if ($ValueFormat1) { + $this->_applyGPOSvaluerecord($ptr, $Value1); + } + if ($ValueFormat2) { + $this->_applyGPOSvaluerecord($matchedpos, $Value2); + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return $matchedpos - $ptr + 1; + } + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return $matchedpos - $ptr; + } else { + $this->skip($sizeOfPair); + } + } + } + } + return 0; + } //=========== + // Format 2: + //=========== + elseif ($PosFormat == 2) { + $ClassDef1 = $subtable_offset + $this->read_ushort(); + $ClassDef2 = $subtable_offset + $this->read_ushort(); + $Class1Count = $this->read_ushort(); + $Class2Count = $this->read_ushort(); + + $sizeOfValueRecords = $Class1Count * $Class2Count * $sizeOfPair; + + //$this->skip($sizeOfValueRecords ); ???? NOT NEEDED + // NB Class1Count includes Class 0 even though it is not defined by $ClassDef1 + // i.e. Class1Count = 5; Class1 will contain array(indices 1-4); + $Class1 = $this->_getClassDefinitionTable($ClassDef1); + $Class2 = $this->_getClassDefinitionTable($ClassDef2); + $FirstGlyph = $this->OTLdata[$ptr]['uni']; + $checkpos = $ptr; + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + if (isset($this->OTLdata[$checkpos])) { + $matchedpos = $checkpos; + } else { + return 0; + } + + $SecondGlyph = $this->OTLdata[$matchedpos]['uni']; + for ($i = 0; $i < $Class1Count; $i++) { + if (isset($Class1[$i]) && count($Class1[$i])) { + $FirstClassPos = array_search($FirstGlyph, $Class1[$i]); + if ($FirstClassPos === false) { + continue; + } else { + for ($j = 0; $j < $Class2Count; $j++) { + if (isset($Class2[$j]) && count($Class2[$j])) { + $SecondClassPos = array_search($SecondGlyph, $Class2[$j]); + if ($SecondClassPos === false) { + continue; + } + + // Get ValueRecord[$i][$j] + $offs = ($i * $Class2Count * $sizeOfPair) + ($j * $sizeOfPair); + $this->seek($subtable_offset + 16 + $offs); + + $Value1 = $this->_getValueRecord($ValueFormat1); + $Value2 = $this->_getValueRecord($ValueFormat2); + if ($ValueFormat1) { + $this->_applyGPOSvaluerecord($ptr, $Value1); + } + if ($ValueFormat2) { + $this->_applyGPOSvaluerecord($matchedpos, $Value2); + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return $matchedpos - $ptr + 1; + } + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return $matchedpos - $ptr; + } + } + } + } + } + return 0; + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 3: Cursive attachment Attach cursive glyphs + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 3) { + $this->skip(4); + // Need default XAdvance for glyph + $pdfWidth = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], hexdec($currGlyph)); // DON'T convert back to design units + + $CPos = $LuCoverage[$currGID]; + $this->skip($CPos * 4); + $EntryAnchor = $this->read_ushort(); + $ExitAnchor = $this->read_ushort(); + if ($EntryAnchor != 0) { + $EntryAnchor += $subtable_offset; + list($x, $y) = $this->_getAnchorTable($EntryAnchor); + if ($dir == 'RTL') { + if (round($pdfWidth) == round($x * 1000 / $this->mpdf->CurrentFont['unitsPerEm'])) { + $x = 0; + } else { + $x = $x - ($pdfWidth * $this->mpdf->CurrentFont['unitsPerEm'] / 1000); + } + } + + $this->Entry[$ptr] = ['X' => $x, 'Y' => $y, 'dir' => $dir]; + } + if ($ExitAnchor != 0) { + $ExitAnchor += $subtable_offset; + list($x, $y) = $this->_getAnchorTable($ExitAnchor); + if ($dir == 'LTR') { + if (round($pdfWidth) == round($x * 1000 / $this->mpdf->CurrentFont['unitsPerEm'])) { + $x = 0; + } else { + $x = $x - ($pdfWidth * $this->mpdf->CurrentFont['unitsPerEm'] / 1000); + } + } + $this->Exit[$ptr] = ['X' => $x, 'Y' => $y, 'dir' => $dir]; + } + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return 1; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 4: MarkToBase attachment Attach a combining mark to a base glyph + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 4) { + $MarkCoverage = $subtable_offset + $this->read_ushort(); + //$MarkCoverage is already set in $LuCoverage 00065|00073 etc + $BaseCoverage = $subtable_offset + $this->read_ushort(); + $ClassCount = $this->read_ushort(); // Number of classes defined for marks = Number of mark glyphs in the MarkCoverage table + $MarkArray = $subtable_offset + $this->read_ushort(); // Offset to MarkArray table + $BaseArray = $subtable_offset + $this->read_ushort(); // Offset to BaseArray table + + $this->seek($BaseCoverage); + $BaseGlyphs = implode('|', $this->_getCoverage()); + + $checkpos = $ptr; + $checkpos--; + + // ZZZ93 + // In Lohit-Kannada font (old-spec), rules specify a Type 4 GPOS to attach below-forms to base glyph + // the repositioning does not happen in MS Word, and shouldn't happen comparing with other fonts + // ?Why not + // This Fix blocks the GPOS rule if the "mark" is not actually classified as a mark in the GlyphClasses of GDEF + // but only in Indic old-spec. + // Test cases: ನ್ನು and ಕ್ರೌ + if ($this->shaper == 'I' && $is_old_spec && strpos($this->GlyphClassMarks, $this->OTLdata[$ptr]['hex']) === false) { + return; + } + + + // "To identify the base glyph that combines with a mark, the text-processing client must look backward in the glyph string from the mark to the preceding base glyph." + while (isset($this->OTLdata[$checkpos]) && strpos($this->GlyphClassMarks, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + + if (isset($this->OTLdata[$checkpos]) && strpos($BaseGlyphs, $this->OTLdata[$checkpos]['hex']) !== false) { + $matchedpos = $checkpos; + } else { + $matchedpos = false; + } + + if ($matchedpos !== false) { + // Get the relevant MarkRecord + $MarkPos = $LuCoverage[$currGID]; + $MarkRecord = $this->_getMarkRecord($MarkArray, $MarkPos); // e.g. Array ( [Class] => 0 [AnchorX] => -549 [AnchorY] => 1548 ) + //Mark Class is = $MarkRecord['Class'] + // Get the relevant BaseRecord + $this->seek($BaseArray); + $BaseCount = $this->read_ushort(); + $BasePos = strpos($BaseGlyphs, $this->OTLdata[$matchedpos]['hex']) / 6; + + // Move to the BaseRecord we want + $nSkip = (2 * $BasePos * $ClassCount ); + $this->skip($nSkip); + + // Read BaseRecord we want for appropriate Class + $nSkip = 2 * $MarkRecord['Class']; + $this->skip($nSkip); + $BaseRecordOffset = $BaseArray + $this->read_ushort(); + list($x, $y) = $this->_getAnchorTable($BaseRecordOffset); + $BaseRecord = ['AnchorX' => $x, 'AnchorY' => $y]; // e.g. Array ( [AnchorX] => 660 [AnchorY] => 1556 ) + // Need default XAdvance for Base glyph + $BaseWidth = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$matchedpos]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000; // convert back to font design units + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] = $BaseWidth; + // And any intervening (ignored) characters + if (($ptr - $matchedpos) > 1) { + for ($i = $matchedpos + 1; $i < $ptr; $i++) { + $BaseWidthExtra = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$i]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000; // convert back to font design units + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] += $BaseWidthExtra; + } + } + + // Align to previous Glyph by attachment - so need to add to previous placement values + $prevXPlacement = (isset($this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement']) ? $this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement'] : 0); + $prevYPlacement = (isset($this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement']) ? $this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement'] : 0); + + $this->OTLdata[$ptr]['GPOSinfo']['XPlacement'] = $prevXPlacement + $BaseRecord['AnchorX'] - $MarkRecord['AnchorX']; + $this->OTLdata[$ptr]['GPOSinfo']['YPlacement'] = $prevYPlacement + $BaseRecord['AnchorY'] - $MarkRecord['AnchorY']; + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return 1; + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 5: MarkToLigature attachment Attach a combining mark to a ligature + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 5) { + $MarkCoverage = $subtable_offset + $this->read_ushort(); + //$MarkCoverage is already set in $LuCoverage 00065|00073 etc + $LigatureCoverage = $subtable_offset + $this->read_ushort(); + $ClassCount = $this->read_ushort(); // Number of classes defined for marks = Number of mark glyphs in the MarkCoverage table + $MarkArray = $subtable_offset + $this->read_ushort(); // Offset to MarkArray table + $LigatureArray = $subtable_offset + $this->read_ushort(); // Offset to LigatureArray table + + $this->seek($LigatureCoverage); + $LigatureGlyphs = implode('|', $this->_getCoverage()); + + + $checkpos = $ptr; + $checkpos--; + + // "To position a combining mark using a MarkToLigature attachment subtable, the text-processing client must work backward from the mark to the preceding ligature glyph." + while (isset($this->OTLdata[$checkpos]) && strpos($this->GlyphClassMarks, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + + if (isset($this->OTLdata[$checkpos]) && strpos($LigatureGlyphs, $this->OTLdata[$checkpos]['hex']) !== false) { + $matchedpos = $checkpos; + } else { + $matchedpos = false; + } + + if ($matchedpos !== false) { + // Get the relevant MarkRecord + $MarkPos = $LuCoverage[$currGID]; + $MarkRecord = $this->_getMarkRecord($MarkArray, $MarkPos); // e.g. Array ( [Class] => 0 [AnchorX] => -549 [AnchorY] => 1548 ) + //Mark Class is = $MarkRecord['Class'] + // Get the relevant LigatureRecord + $this->seek($LigatureArray); + $LigatureCount = $this->read_ushort(); + $LigaturePos = strpos($LigatureGlyphs, $this->OTLdata[$matchedpos]['hex']) / 6; + + // Move to the LigatureAttach table Record we want + $nSkip = (2 * $LigaturePos); + $this->skip($nSkip); + $LigatureAttachOffset = $LigatureArray + $this->read_ushort(); + $this->seek($LigatureAttachOffset); + $ComponentCount = $this->read_ushort(); + $offsets = []; + for ($comp = 0; $comp < $ComponentCount; $comp++) { + // ComponentRecords + for ($class = 0; $class < $ClassCount; $class++) { + $offsets[$comp][$class] = $this->read_ushort(); + } + } + + // Get the specific component for this mark attachment + if (isset($this->assocLigs[$matchedpos]) && isset($this->assocMarks[$ptr]['ligPos']) && $this->assocMarks[$ptr]['ligPos'] == $matchedpos) { + $component = $this->assocMarks[$ptr]['compID']; + } else { + $component = $ComponentCount - 1; + } + + $offset = $offsets[$component][$MarkRecord['Class']]; + if ($offset != 0) { + $LigatureRecordOffset = $offset + $LigatureAttachOffset; + list($x, $y) = $this->_getAnchorTable($LigatureRecordOffset); + $LigatureRecord = ['AnchorX' => $x, 'AnchorY' => $y]; + + // Need default XAdvance for Ligature glyph + $LigatureWidth = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$matchedpos]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000; // convert back to font design units + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] = $LigatureWidth; + // And any intervening (ignored)characters + if (($ptr - $matchedpos) > 1) { + for ($i = $matchedpos + 1; $i < $ptr; $i++) { + $LigatureWidthExtra = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$i]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000; // convert back to font design units + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] += $LigatureWidthExtra; + } + } + + // Align to previous Ligature by attachment - so need to add to previous placement values + if (isset($this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement'])) { + $prevXPlacement = $this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement']; + } else { + $prevXPlacement = 0; + } + if (isset($this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement'])) { + $prevYPlacement = $this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement']; + } else { + $prevYPlacement = 0; + } + + $this->OTLdata[$ptr]['GPOSinfo']['XPlacement'] = $prevXPlacement + $LigatureRecord['AnchorX'] - $MarkRecord['AnchorX']; + $this->OTLdata[$ptr]['GPOSinfo']['YPlacement'] = $prevYPlacement + $LigatureRecord['AnchorY'] - $MarkRecord['AnchorY']; + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return 1; + } + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 6: MarkToMark attachment Attach a combining mark to another mark + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 6) { + $Mark1Coverage = $subtable_offset + $this->read_ushort(); // Combining Mark + //$Mark1Coverage is already set in $LuCoverage 0065|0073 etc + $Mark2Coverage = $subtable_offset + $this->read_ushort(); // Base Mark + $ClassCount = $this->read_ushort(); // Number of classes defined for marks = No. of Combining mark1 glyphs in the MarkCoverage table + $Mark1Array = $subtable_offset + $this->read_ushort(); // Offset to MarkArray table + $Mark2Array = $subtable_offset + $this->read_ushort(); // Offset to Mark2Array table + $this->seek($Mark2Coverage); + $Mark2Glyphs = implode('|', $this->_getCoverage()); + $checkpos = $ptr; + $checkpos--; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + if (isset($this->OTLdata[$checkpos]) && strpos($Mark2Glyphs, $this->OTLdata[$checkpos]['hex']) !== false) { + $matchedpos = $checkpos; + } else { + $matchedpos = false; + } + + if ($matchedpos !== false) { + // Get the relevant MarkRecord + $Mark1Pos = $LuCoverage[$currGID]; + $Mark1Record = $this->_getMarkRecord($Mark1Array, $Mark1Pos); // e.g. Array ( [Class] => 0 [AnchorX] => -549 [AnchorY] => 1548 ) + //Mark Class is = $Mark1Record['Class'] + // Get the relevant Mark2Record + $this->seek($Mark2Array); + $Mark2Count = $this->read_ushort(); + $Mark2Pos = strpos($Mark2Glyphs, $this->OTLdata[$matchedpos]['hex']) / 6; + + // Move to the Mark2Record we want + $nSkip = (2 * $Mark2Pos * $ClassCount ); + $this->skip($nSkip); + + // Read Mark2Record we want for appropriate Class + $nSkip = 2 * $Mark1Record['Class']; + $this->skip($nSkip); + $Mark2RecordOffset = $Mark2Array + $this->read_ushort(); + list($x, $y) = $this->_getAnchorTable($Mark2RecordOffset); + $Mark2Record = ['AnchorX' => $x, 'AnchorY' => $y]; // e.g. Array ( [AnchorX] => 660 [AnchorY] => 1556 ) + // Need default XAdvance for Mark2 glyph + $Mark2Width = $this->mpdf->_getCharWidth($this->mpdf->CurrentFont['cw'], $this->OTLdata[$matchedpos]['uni']) * $this->mpdf->CurrentFont['unitsPerEm'] / 1000; // convert back to font design units + // IF combining marks are set on different components of a ligature glyph, do not apply this rule + // Test: arabictypesetting: إِلَىٰٓ + // Test: arabictypesetting: بَّيْنَكُمْ + $prevLig = -1; + $thisLig = -1; + $prevComp = -1; + $thisComp = -1; + if (isset($this->assocMarks[$matchedpos])) { + $prevLig = $this->assocMarks[$matchedpos]['ligPos']; + $prevComp = $this->assocMarks[$matchedpos]['compID']; + } + if (isset($this->assocMarks[$ptr])) { + $thisLig = $this->assocMarks[$ptr]['ligPos']; + $thisComp = $this->assocMarks[$ptr]['compID']; + } + + // However IF Mark2 (first in logical order, i.e. being attached to) is not associated with a base, carry on + // This happens in Indic when the Mark being attached to e.g. [Halant Ma lig] -> MatraU, [U+0B4D + U+B2E as E0F5]-> U+0B41 become E135 + if (!defined("OMIT_OTL_FIX_1") || OMIT_OTL_FIX_1 != 1) { + /* OTL_FIX_1 */ + if (isset($this->assocMarks[$matchedpos]) && ($prevLig != $thisLig || $prevComp != $thisComp )) { + return 0; + } + } else { + /* Original code */ + if ($prevLig != $thisLig || $prevComp != $thisComp) { + return 0; + } + } + + + if (!defined("OMIT_OTL_FIX_2") || OMIT_OTL_FIX_2 != 1) { + /* OTL_FIX_2 */ + if (!isset($this->OTLdata[$matchedpos]['GPOSinfo']['BaseWidth']) || !$this->OTLdata[$matchedpos]['GPOSinfo']['BaseWidth']) { + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] = $Mark2Width; + } + } + + // ZZZ99Q - Test Case font-family: garuda น้ำ + if (isset($this->OTLdata[$matchedpos]['GPOSinfo']['BaseWidth']) && $this->OTLdata[$matchedpos]['GPOSinfo']['BaseWidth']) { + $this->OTLdata[$ptr]['GPOSinfo']['BaseWidth'] = $this->OTLdata[$matchedpos]['GPOSinfo']['BaseWidth']; + } + + // Align to previous Mark by attachment - so need to add the previous placement values + $prevXPlacement = (isset($this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement']) ? $this->OTLdata[$matchedpos]['GPOSinfo']['XPlacement'] : 0); + $prevYPlacement = (isset($this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement']) ? $this->OTLdata[$matchedpos]['GPOSinfo']['YPlacement'] : 0); + $this->OTLdata[$ptr]['GPOSinfo']['XPlacement'] = $prevXPlacement + $Mark2Record['AnchorX'] - $Mark1Record['AnchorX']; + $this->OTLdata[$ptr]['GPOSinfo']['YPlacement'] = $prevYPlacement + $Mark2Record['AnchorY'] - $Mark1Record['AnchorY']; + if ($this->debugOTL) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + return 1; + } + return 0; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 7: Context positioning Position one or more glyphs in context + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 7) { + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not TESTED YET."); + } //=========== + // Format 2: + //=========== + elseif ($PosFormat == 2) { + $CoverageTableOffset = $subtable_offset + $this->read_ushort(); + $InputClassDefOffset = $subtable_offset + $this->read_ushort(); + $PosClassSetCnt = $this->read_ushort(); + $PosClassSetOffset = []; + for ($b = 0; $b < $PosClassSetCnt; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $PosClassSetOffset[] = $offset; + } else { + $PosClassSetOffset[] = $subtable_offset + $offset; + } + } + + $InputClasses = $this->_getClasses($InputClassDefOffset); + + for ($s = 0; $s < $PosClassSetCnt; $s++) { // $ChainPosClassSet is ordered by input class-may be NULL + // Select $PosClassSet if currGlyph is in First Input Class + if ($PosClassSetOffset[$s] > 0 && isset($InputClasses[$s][$currGID])) { + $this->seek($PosClassSetOffset[$s]); + $PosClassRuleCnt = $this->read_ushort(); + $PosClassRule = []; + for ($b = 0; $b < $PosClassRuleCnt; $b++) { + $PosClassRule[$b] = $PosClassSetOffset[$s] + $this->read_ushort(); + } + + for ($b = 0; $b < $PosClassRuleCnt; $b++) { // EACH RULE + $this->seek($PosClassRule[$b]); + $InputGlyphCount = $this->read_ushort(); + $PosCount = $this->read_ushort(); + + $Input = []; + for ($r = 1; $r < $InputGlyphCount; $r++) { + $Input[$r] = $this->read_ushort(); + } + $inputClass = $s; + + $inputGlyphs = []; + $inputGlyphs[0] = $InputClasses[$inputClass]; + + if ($InputGlyphCount > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $InputGlyphCount; $gcl++) { + $classindex = $Input[$gcl]; + if (isset($InputClasses[$classindex])) { + $inputGlyphs[$gcl] = $InputClasses[$classindex]; + } else { + $inputGlyphs[$gcl] = ''; + } + } + } + + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = []; + for ($gc = 1; $gc <= count($InputClasses); $gc++) { + if (is_array($InputClasses[$gc])) { + $class0excl = $class0excl + $InputClasses[$gc]; + } + } + + $backtrackGlyphs = []; + $lookaheadGlyphs = []; + + $matched = $this->checkContextMatchMultipleUni($inputGlyphs, $backtrackGlyphs, $lookaheadGlyphs, $ignore, $ptr, $class0excl); + if ($matched) { + for ($p = 0; $p < $PosCount; $p++) { // EACH LOOKUP + $SequenceIndex[$p] = $this->read_ushort(); + $LookupListIndex[$p] = $this->read_ushort(); + } + + for ($p = 0; $p < $PosCount; $p++) { + // Apply $LookupListIndex at $SequenceIndex + if ($SequenceIndex[$p] >= $InputGlyphCount) { + continue; + } + $lu = $LookupListIndex[$p]; + $luType = $this->GPOSLookups[$lu]['Type']; + $luFlag = $this->GPOSLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GPOSLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SequenceIndex[$p]]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GPOSLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGPOSsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GPOS_offset + $this->GSUB_length), $luType, $luFlag, $luMarkFilteringSet, $this->LuCoverage[$lu][$luc], $tag, 1, $is_old_spec); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + break; + } + } + } + + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + } + } + + return 0; + } //=========== + // Format 3: + //=========== + elseif ($PosFormat == 3) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not TESTED YET."); + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . ", Format " . $PosFormat . " not supported."); + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 8: Chained Context positioning Position one or more glyphs in chained context + //////////////////////////////////////////////////////////////////////////////// + elseif ($Type == 8) { + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not TESTED YET."); + return 0; + } //=========== + // Format 2: + //=========== + elseif ($PosFormat == 2) { + $CoverageTableOffset = $subtable_offset + $this->read_ushort(); + $BacktrackClassDefOffset = $subtable_offset + $this->read_ushort(); + $InputClassDefOffset = $subtable_offset + $this->read_ushort(); + $LookaheadClassDefOffset = $subtable_offset + $this->read_ushort(); + $ChainPosClassSetCnt = $this->read_ushort(); + $ChainPosClassSetOffset = []; + for ($b = 0; $b < $ChainPosClassSetCnt; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $ChainPosClassSetOffset[] = $offset; + } else { + $ChainPosClassSetOffset[] = $subtable_offset + $offset; + } + } + + $BacktrackClasses = $this->_getClasses($BacktrackClassDefOffset); + $InputClasses = $this->_getClasses($InputClassDefOffset); + $LookaheadClasses = $this->_getClasses($LookaheadClassDefOffset); + + for ($s = 0; $s < $ChainPosClassSetCnt; $s++) { // $ChainPosClassSet is ordered by input class-may be NULL + // Select $ChainPosClassSet if currGlyph is in First Input Class + if ($ChainPosClassSetOffset[$s] > 0 && isset($InputClasses[$s][$currGID])) { + $this->seek($ChainPosClassSetOffset[$s]); + $ChainPosClassRuleCnt = $this->read_ushort(); + $ChainPosClassRule = []; + for ($b = 0; $b < $ChainPosClassRuleCnt; $b++) { + $ChainPosClassRule[$b] = $ChainPosClassSetOffset[$s] + $this->read_ushort(); + } + + for ($b = 0; $b < $ChainPosClassRuleCnt; $b++) { // EACH RULE + $this->seek($ChainPosClassRule[$b]); + $BacktrackGlyphCount = $this->read_ushort(); + $Backtrack = []; + for ($r = 0; $r < $BacktrackGlyphCount; $r++) { + $Backtrack[$r] = $this->read_ushort(); + } + $InputGlyphCount = $this->read_ushort(); + $Input = []; + for ($r = 1; $r < $InputGlyphCount; $r++) { + $Input[$r] = $this->read_ushort(); + } + $LookaheadGlyphCount = $this->read_ushort(); + $Lookahead = []; + for ($r = 0; $r < $LookaheadGlyphCount; $r++) { + $Lookahead[$r] = $this->read_ushort(); + } + + $inputClass = $s; //??? + + $inputGlyphs = []; + $inputGlyphs[0] = $InputClasses[$inputClass]; + + if ($InputGlyphCount > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $InputGlyphCount; $gcl++) { + $classindex = $Input[$gcl]; + if (isset($InputClasses[$classindex])) { + $inputGlyphs[$gcl] = $InputClasses[$classindex]; + } else { + $inputGlyphs[$gcl] = ''; + } + } + } + + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = []; + for ($gc = 1; $gc <= count($InputClasses); $gc++) { + if (isset($InputClasses[$gc]) && is_array($InputClasses[$gc])) { + $class0excl = $class0excl + $InputClasses[$gc]; + } + } + + if ($BacktrackGlyphCount) { + $backtrackGlyphs = []; + for ($gcl = 0; $gcl < $BacktrackGlyphCount; $gcl++) { + $classindex = $Backtrack[$gcl]; + if (isset($BacktrackClasses[$classindex])) { + $backtrackGlyphs[$gcl] = $BacktrackClasses[$classindex]; + } else { + $backtrackGlyphs[$gcl] = ''; + } + } + } else { + $backtrackGlyphs = []; + } + + // Class 0 contains all the glyphs NOT in the other classes + $bclass0excl = []; + for ($gc = 1; $gc <= count($BacktrackClasses); $gc++) { + if (isset($BacktrackClasses[$gc]) && is_array($BacktrackClasses[$gc])) { + $bclass0excl = $bclass0excl + $BacktrackClasses[$gc]; + } + } + + if ($LookaheadGlyphCount) { + $lookaheadGlyphs = []; + for ($gcl = 0; $gcl < $LookaheadGlyphCount; $gcl++) { + $classindex = $Lookahead[$gcl]; + if (isset($LookaheadClasses[$classindex])) { + $lookaheadGlyphs[$gcl] = $LookaheadClasses[$classindex]; + } else { + $lookaheadGlyphs[$gcl] = ''; + } + } + } else { + $lookaheadGlyphs = []; + } + + // Class 0 contains all the glyphs NOT in the other classes + $lclass0excl = []; + for ($gc = 1; $gc <= count($LookaheadClasses); $gc++) { + if (isset($LookaheadClasses[$gc]) && is_array($LookaheadClasses[$gc])) { + $lclass0excl = $lclass0excl + $LookaheadClasses[$gc]; + } + } + + $matched = $this->checkContextMatchMultipleUni($inputGlyphs, $backtrackGlyphs, $lookaheadGlyphs, $ignore, $ptr, $class0excl, $bclass0excl, $lclass0excl); + if ($matched) { + $PosCount = $this->read_ushort(); + $SequenceIndex = []; + $LookupListIndex = []; + for ($p = 0; $p < $PosCount; $p++) { // EACH LOOKUP + $SequenceIndex[$p] = $this->read_ushort(); + $LookupListIndex[$p] = $this->read_ushort(); + } + + for ($p = 0; $p < $PosCount; $p++) { + // Apply $LookupListIndex at $SequenceIndex + if ($SequenceIndex[$p] >= $InputGlyphCount) { + continue; + } + $lu = $LookupListIndex[$p]; + $luType = $this->GPOSLookups[$lu]['Type']; + $luFlag = $this->GPOSLookups[$lu]['Flag']; + $luMarkFilteringSet = $this->GPOSLookups[$lu]['MarkFilteringSet']; + + $luptr = $matched[$SequenceIndex[$p]]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GPOSLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGPOSsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GPOS_offset + $this->GSUB_length), $luType, $luFlag, $luMarkFilteringSet, $this->LuCoverage[$lu][$luc], $tag, 1, $is_old_spec); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + break; + } + } + } + + if (!defined("OMIT_OTL_FIX_3") || OMIT_OTL_FIX_3 != 1) { + return $shift; + } /* OTL_FIX_3 */ + else { + return $InputGlyphCount; // should be + matched ignores in Input Sequence + } + } + } + } + } + + return 0; + } //=========== + // Format 3: + //=========== + elseif ($PosFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $CoverageBacktrackOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $InputGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $InputGlyphCount; $b++) { + $CoverageInputOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $LookaheadGlyphCount = $this->read_ushort(); + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $CoverageLookaheadOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $PosCount = $this->read_ushort(); + $save_pos = $this->_pos; // Save the point just after PosCount + + $CoverageBacktrackGlyphs = []; + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $this->seek($CoverageBacktrackOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageBacktrackGlyphs[$b] = implode("|", $glyphs); + } + $CoverageInputGlyphs = []; + for ($b = 0; $b < $InputGlyphCount; $b++) { + $this->seek($CoverageInputOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageInputGlyphs[$b] = implode("|", $glyphs); + } + $CoverageLookaheadGlyphs = []; + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $this->seek($CoverageLookaheadOffset[$b]); + $glyphs = $this->_getCoverage(); + $CoverageLookaheadGlyphs[$b] = implode("|", $glyphs); + } + $matched = $this->checkContextMatchMultiple($CoverageInputGlyphs, $CoverageBacktrackGlyphs, $CoverageLookaheadGlyphs, $ignore, $ptr); + if ($matched) { + $this->seek($save_pos); // Return to just after PosCount + for ($p = 0; $p < $PosCount; $p++) { + // PosLookupRecord + $PosLookupRecord[$p]['SequenceIndex'] = $this->read_ushort(); + $PosLookupRecord[$p]['LookupListIndex'] = $this->read_ushort(); + } + for ($p = 0; $p < $PosCount; $p++) { + // Apply $PosLookupRecord[$p]['LookupListIndex'] at $PosLookupRecord[$p]['SequenceIndex'] + if ($PosLookupRecord[$p]['SequenceIndex'] >= $InputGlyphCount) { + continue; + } + $lu = $PosLookupRecord[$p]['LookupListIndex']; + $luType = $this->GPOSLookups[$lu]['Type']; + $luFlag = $this->GPOSLookups[$lu]['Flag']; + if (isset($this->GPOSLookups[$lu]['MarkFilteringSet'])) { + $luMarkFilteringSet = $this->GPOSLookups[$lu]['MarkFilteringSet']; + } else { + $luMarkFilteringSet = ''; + } + + $luptr = $matched[$PosLookupRecord[$p]['SequenceIndex']]; + $lucurrGlyph = $this->OTLdata[$luptr]['hex']; + $lucurrGID = $this->OTLdata[$luptr]['uni']; + + foreach ($this->GPOSLookups[$lu]['Subtables'] as $luc => $lusubtable_offset) { + $shift = $this->_applyGPOSsubtable($lu, $luc, $luptr, $lucurrGlyph, $lucurrGID, ($lusubtable_offset - $this->GPOS_offset + $this->GSUB_length), $luType, $luFlag, $luMarkFilteringSet, $this->LuCoverage[$lu][$luc], $tag, 1, $is_old_spec); + if ($this->debugOTL && $shift) { + $this->_dumpproc('GPOS', $lookupID, $subtable, $Type, $PosFormat, $ptr, $currGlyph, $level); + } + if ($shift) { + break; + } + } + } + } + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . ", Format " . $PosFormat . " not supported."); + } + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " not supported."); + } + } + + ////////////////////////////////////////////////////////////////////////////////// + // GPOS / GSUB / GCOM (common) functions + ////////////////////////////////////////////////////////////////////////////////// + private function checkContextMatch($Input, $Backtrack, $Lookahead, $ignore, $ptr) + { + // Input etc are single numbers - GSUB Format 6.1 + // Input starts with (1=>xxx) + // return false if no match, else an array of ptr for matches (0=>0, 1=>3,...) + + $current_syllable = (isset($this->OTLdata[$ptr]['syllable']) ? $this->OTLdata[$ptr]['syllable'] : 0); + + // BACKTRACK + $checkpos = $ptr; + for ($i = 0; $i < count($Backtrack); $i++) { + $checkpos--; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || $this->OTLdata[$checkpos]['uni'] != $Backtrack[$i]) { + return false; + } + } + + // INPUT + $matched = [0 => $ptr]; + $checkpos = $ptr; + for ($i = 1; $i < count($Input); $i++) { + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } elseif (isset($this->OTLdata[$checkpos]) && $this->OTLdata[$checkpos]['uni'] == $Input[$i]) { + $matched[] = $checkpos; + } else { + return false; + } + } + + // LOOKAHEAD + for ($i = 0; $i < count($Lookahead); $i++) { + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || $this->OTLdata[$checkpos]['uni'] != $Lookahead[$i]) { + return false; + } + } + + return $matched; + } + + private function checkContextMatchMultiple($Input, $Backtrack, $Lookahead, $ignore, $ptr, $class0excl = '', $bclass0excl = '', $lclass0excl = '') + { + // Input etc are string/array of glyph strings - GSUB Format 5.2, 5.3, 6.2, 6.3, GPOS Format 7.2, 7.3, 8.2, 8.3 + // Input starts with (1=>xxx) + // return false if no match, else an array of ptr for matches (0=>0, 1=>3,...) + // $class0excl is the string of glyphs in all classes except Class 0 (GSUB 5.2, 6.2, GPOS 7.2, 8.2) + // $bclass0excl & $lclass0excl are the same for lookahead and backtrack (GSUB 6.2, GPOS 8.2) + + $current_syllable = (isset($this->OTLdata[$ptr]['syllable']) ? $this->OTLdata[$ptr]['syllable'] : 0); + + // BACKTRACK + $checkpos = $ptr; + for ($i = 0; $i < count($Backtrack); $i++) { + $checkpos--; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Class 0 specified, matches anything NOT in $bclass0excl + elseif (!$Backtrack[$i] && isset($this->OTLdata[$checkpos]) && strpos($bclass0excl, $this->OTLdata[$checkpos]['hex']) !== false) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || strpos($Backtrack[$i], $this->OTLdata[$checkpos]['hex']) === false) { + return false; + } + } + + // INPUT + $matched = [0 => $ptr]; + $checkpos = $ptr; + for ($i = 1; $i < count($Input); $i++) { // Start at 1 - already matched the first InputGlyph + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Input Class 0 specified, matches anything NOT in $class0excl + elseif (!$Input[$i] && isset($this->OTLdata[$checkpos]) && strpos($class0excl, $this->OTLdata[$checkpos]['hex']) === false) { + $matched[] = $checkpos; + } elseif (isset($this->OTLdata[$checkpos]) && strpos($Input[$i], $this->OTLdata[$checkpos]['hex']) !== false) { + $matched[] = $checkpos; + } else { + return false; + } + } + + // LOOKAHEAD + for ($i = 0; $i < count($Lookahead); $i++) { + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Class 0 specified, matches anything NOT in $lclass0excl + elseif (!$Lookahead[$i] && isset($this->OTLdata[$checkpos]) && strpos($lclass0excl, $this->OTLdata[$checkpos]['hex']) !== false) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || strpos($Lookahead[$i], $this->OTLdata[$checkpos]['hex']) === false) { + return false; + } + } + return $matched; + } + + private function checkContextMatchMultipleUni($Input, $Backtrack, $Lookahead, $ignore, $ptr, $class0excl = [], $bclass0excl = [], $lclass0excl = []) + { + // Input etc are array of glyphs - GSUB Format 5.2, 5.3, 6.2, 6.3, GPOS Format 7.2, 7.3, 8.2, 8.3 + // Input starts with (1=>xxx) + // return false if no match, else an array of ptr for matches (0=>0, 1=>3,...) + // $class0excl is array of glyphs in all classes except Class 0 (GSUB 5.2, 6.2, GPOS 7.2, 8.2) + // $bclass0excl & $lclass0excl are the same for lookahead and backtrack (GSUB 6.2, GPOS 8.2) + + $current_syllable = (isset($this->OTLdata[$ptr]['syllable']) ? $this->OTLdata[$ptr]['syllable'] : 0); + + // BACKTRACK + $checkpos = $ptr; + for ($i = 0; $i < count($Backtrack); $i++) { + $checkpos--; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos--; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Class 0 specified, matches anything NOT in $bclass0excl + elseif (!$Backtrack[$i] && isset($this->OTLdata[$checkpos]) && isset($bclass0excl[$this->OTLdata[$checkpos]['uni']])) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || !isset($Backtrack[$i][$this->OTLdata[$checkpos]['uni']])) { + return false; + } + } + + // INPUT + $matched = [0 => $ptr]; + $checkpos = $ptr; + for ($i = 1; $i < count($Input); $i++) { // Start at 1 - already matched the first InputGlyph + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Input Class 0 specified, matches anything NOT in $class0excl + elseif (!$Input[$i] && isset($this->OTLdata[$checkpos]) && !isset($class0excl[$this->OTLdata[$checkpos]['uni']])) { + $matched[] = $checkpos; + } elseif (isset($this->OTLdata[$checkpos]) && isset($Input[$i][$this->OTLdata[$checkpos]['uni']])) { + $matched[] = $checkpos; + } else { + return false; + } + } + + // LOOKAHEAD + for ($i = 0; $i < count($Lookahead); $i++) { + $checkpos++; + while (isset($this->OTLdata[$checkpos]) && strpos($ignore, $this->OTLdata[$checkpos]['hex']) !== false) { + $checkpos++; + } + // If outside scope of current syllable - return no match + if ($this->restrictToSyllable && isset($this->OTLdata[$checkpos]['syllable']) && $this->OTLdata[$checkpos]['syllable'] != $current_syllable) { + return false; + } // If Class 0 specified, matches anything NOT in $lclass0excl + elseif (!$Lookahead[$i] && isset($this->OTLdata[$checkpos]) && isset($lclass0excl[$this->OTLdata[$checkpos]['uni']])) { + return false; + } elseif (!isset($this->OTLdata[$checkpos]) || !isset($Lookahead[$i][$this->OTLdata[$checkpos]['uni']])) { + return false; + } + } + return $matched; + } + + private function _getClassDefinitionTable($offset) + { + if (isset($this->LuDataCache[$this->fontkey][$offset])) { + $GlyphByClass = $this->LuDataCache[$this->fontkey][$offset]; + } else { + $this->seek($offset); + $ClassFormat = $this->read_ushort(); + $GlyphClass = []; + // $GlyphByClass = array(0=>array()); // NB This forces an index[0] + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $GlyphClass[$i]['startGlyphID'] = $StartGlyph + $i; + $GlyphClass[$i]['endGlyphID'] = $StartGlyph + $i; + $GlyphClass[$i]['class'] = $this->read_ushort(); + for ($g = $GlyphClass[$i]['startGlyphID']; $g <= $GlyphClass[$i]['endGlyphID']; $g++) { + $GlyphByClass[$GlyphClass[$i]['class']][] = $this->glyphToChar($g); + } + } + } elseif ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $GlyphClass[$i]['startGlyphID'] = $this->read_ushort(); + $GlyphClass[$i]['endGlyphID'] = $this->read_ushort(); + $GlyphClass[$i]['class'] = $this->read_ushort(); + for ($g = $GlyphClass[$i]['startGlyphID']; $g <= $GlyphClass[$i]['endGlyphID']; $g++) { + $GlyphByClass[$GlyphClass[$i]['class']][] = $this->glyphToChar($g); + } + } + } + ksort($GlyphByClass); + $this->LuDataCache[$this->fontkey][$offset] = $GlyphByClass; + } + return $GlyphByClass; + } + + private function count_bits($n) + { + for ($c = 0; $n; $c++) { + $n &= $n - 1; // clear the least significant bit set + } + return $c; + } + + private function _getValueRecord($ValueFormat) + { + // Common ValueRecord for GPOS + // Only returns 3 possible: $vra['XPlacement'] $vra['YPlacement'] $vra['XAdvance'] + $vra = []; + // Horizontal adjustment for placement - in design units + if (($ValueFormat & 0x0001) == 0x0001) { + $vra['XPlacement'] = $this->read_short(); + } + // Vertical adjustment for placement - in design units + if (($ValueFormat & 0x0002) == 0x0002) { + $vra['YPlacement'] = $this->read_short(); + } + // Horizontal adjustment for advance - in design units (only used for horizontal writing) + if (($ValueFormat & 0x0004) == 0x0004) { + $vra['XAdvance'] = $this->read_short(); + } + // Vertical adjustment for advance - in design units (only used for vertical writing) + if (($ValueFormat & 0x0008) == 0x0008) { + $this->read_short(); + } + // Offset to Device table for horizontal placement-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0010) == 0x0010) { + $this->read_ushort(); + } + // Offset to Device table for vertical placement-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0020) == 0x0020) { + $this->read_ushort(); + } + // Offset to Device table for horizontal advance-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0040) == 0x0040) { + $this->read_ushort(); + } + // Offset to Device table for vertical advance-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0080) == 0x0080) { + $this->read_ushort(); + } + return $vra; + } + + private function _getAnchorTable($offset = 0) + { + if ($offset) { + $this->seek($offset); + } + $AnchorFormat = $this->read_ushort(); + $XCoordinate = $this->read_short(); + $YCoordinate = $this->read_short(); + // Format 2 specifies additional link to contour point; Format 3 additional Device table + return [$XCoordinate, $YCoordinate]; + } + + private function _getMarkRecord($offset, $MarkPos) + { + $this->seek($offset); + $MarkCount = $this->read_ushort(); + $this->skip($MarkPos * 4); + $Class = $this->read_ushort(); + $MarkAnchor = $offset + $this->read_ushort(); // = Offset to anchor table + list($x, $y) = $this->_getAnchorTable($MarkAnchor); + $MarkRecord = ['Class' => $Class, 'AnchorX' => $x, 'AnchorY' => $y]; + return $MarkRecord; + } + + private function _getGCOMignoreString($flag, $MarkFilteringSet) + { + // If ignoreFlag set, combine all ignore glyphs into -> "(?:( 0FBA1| 0FBA2| 0FBA3)*)" + // else "()" + // for Input - set on secondary Lookup table if in Context, and set Backtrack and Lookahead on Context Lookup + $str = ""; + $ignoreflag = 0; + + // Flag & 0xFF?? = MarkAttachmentType + if ($flag & 0xFF00) { + // "a lookup must ignore any mark glyphs that are not in the specified mark attachment class" + // $this->MarkAttachmentType is already adjusted for this i.e. contains all Marks except those in the MarkAttachmentClassDef table + $MarkAttachmentType = $flag >> 8; + $ignoreflag = $flag; + $str = $this->MarkAttachmentType[$MarkAttachmentType]; + } + + // Flag & 0x0010 = UseMarkFilteringSet + if ($flag & 0x0010) { + throw new \Mpdf\MpdfException("This font [" . $this->fontkey . "] contains MarkGlyphSets - Not tested yet"); + // Change also in ttfontsuni.php + if ($MarkFilteringSet == '') { + throw new \Mpdf\MpdfException("This font [" . $this->fontkey . "] contains MarkGlyphSets - but MarkFilteringSet not set"); + } + $str = $this->MarkGlyphSets[$MarkFilteringSet]; + } + + // If Ignore Marks set, supercedes any above + // Flag & 0x0008 = Ignore Marks - (unless already done with MarkAttachmentType) + if (($flag & 0x0008) == 0x0008 && ($flag & 0xFF00) == 0) { + $ignoreflag = 8; + $str = $this->GlyphClassMarks; + } + + // Flag & 0x0004 = Ignore Ligatures + if (($flag & 0x0004) == 0x0004) { + $ignoreflag += 4; + if ($str) { + $str .= "|"; + } + $str .= $this->GlyphClassLigatures; + } + // Flag & 0x0002 = Ignore BaseGlyphs + if (($flag & 0x0002) == 0x0002) { + $ignoreflag += 2; + if ($str) { + $str .= "|"; + } + $str .= $this->GlyphClassBases; + } + if ($str) { + return "((?:(?:" . $str . "))*)"; + } else { + return "()"; + } + } + + private function _checkGCOMignore($flag, $glyph, $MarkFilteringSet) + { + $ignore = false; + // Flag & 0x0008 = Ignore Marks - (unless already done with MarkAttachmentType) + if (($flag & 0x0008 && ($flag & 0xFF00) == 0) && strpos($this->GlyphClassMarks, $glyph)) { + $ignore = true; + } + if (($flag & 0x0004) && strpos($this->GlyphClassLigatures, $glyph)) { + $ignore = true; + } + if (($flag & 0x0002) && strpos($this->GlyphClassBases, $glyph)) { + $ignore = true; + } + // Flag & 0xFF?? = MarkAttachmentType + if ($flag & 0xFF00) { + // "a lookup must ignore any mark glyphs that are not in the specified mark attachment class" + // $this->MarkAttachmentType is already adjusted for this i.e. contains all Marks except those in the MarkAttachmentClassDef table + if (strpos($this->MarkAttachmentType[($flag >> 8)], $glyph)) { + $ignore = true; + } + } + // Flag & 0x0010 = UseMarkFilteringSet + if (($flag & 0x0010) && strpos($this->MarkGlyphSets[$MarkFilteringSet], $glyph)) { + $ignore = true; + } + return $ignore; + } + + /** + * Bidi algorithm + * + * These functions are called from mpdf after GSUB/GPOS has taken place + * At this stage the bidi-type is in string form + * + * Bidirectional Character Types + * ============================= + * Type Description General Scope + * Strong + * L Left-to-Right LRM, most alphabetic, syllabic, Han ideographs, non-European or non-Arabic digits, ... + * LRE Left-to-Right Embedding LRE + * LRO Left-to-Right Override LRO + * R Right-to-Left RLM, Hebrew alphabet, and related punctuation + * AL Right-to-Left Arabic Arabic, Thaana, and Syriac alphabets, most punctuation specific to those scripts, ... + * RLE Right-to-Left Embedding RLE + * RLO Right-to-Left Override RLO + * Weak + * PDF Pop Directional Format PDF + * EN European Number European digits, Eastern Arabic-Indic digits, ... + * ES European Number Separator Plus sign, minus sign + * ET European Number Terminator Degree sign, currency symbols, ... + * AN Arabic Number Arabic-Indic digits, Arabic decimal and thousands separators, ... + * CS Common Number Separator Colon, comma, full stop (period), No-break space, ... + * NSM Nonspacing Mark Characters marked Mn (Nonspacing_Mark) and Me (Enclosing_Mark) in the Unicode Character Database + * BN Boundary Neutral Default ignorables, non-characters, and control characters, other than those explicitly given other types. + * Neutral + * B Paragraph Separator Paragraph separator, appropriate Newline Functions, higher-level protocol paragraph determination + * S Segment Separator Tab + * WS Whitespace Space, figure space, line separator, form feed, General Punctuation spaces, ... + * ON Other Neutrals All other characters, including OBJECT REPLACEMENT CHARACTER + */ + public function bidiSort($ta, $str, $dir, &$chunkOTLdata, $useGPOS) + { + + $pel = 0; // paragraph embedding level + $maxlevel = 0; + $numchars = count($chunkOTLdata['char_data']); + + // Set the initial paragraph embedding level + if ($dir == 'rtl') { + $pel = 1; + } else { + $pel = 0; + } + + // X1. Begin by setting the current embedding level to the paragraph embedding level. Set the directional override status to neutral. + // Current Embedding Level + $cel = $pel; + // directional override status (-1 is Neutral) + $dos = -1; + $remember = []; + + // Array of characters data + $chardata = []; + + // Process each character iteratively, applying rules X2 through X9. Only embedding levels from 0 to 61 are valid in this phase. + // In the resolution of levels in rules I1 and I2, the maximum embedding level of 62 can be reached. + for ($i = 0; $i < $numchars; ++$i) { + if ($chunkOTLdata['char_data'][$i]['uni'] == 8235) { // RLE + // X2. With each RLE, compute the least greater odd embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + ($cel % 2) + 1; + if ($next_level < 62) { + $remember[] = ['num' => 8235, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = -1; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8234) { // LRE + // X3. With each LRE, compute the least greater even embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + 2 - ($cel % 2); + if ($next_level < 62) { + $remember[] = ['num' => 8234, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = -1; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8238) { // RLO + // X4. With each RLO, compute the least greater odd embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to right-to-left. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + ($cel % 2) + 1; + if ($next_level < 62) { + $remember[] = ['num' => 8238, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = Ucdn::BIDI_CLASS_R; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8237) { // LRO + // X5. With each LRO, compute the least greater even embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to left-to-right. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + 2 - ($cel % 2); + if ($next_level < 62) { + $remember[] = ['num' => 8237, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = Ucdn::BIDI_CLASS_L; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8236) { // PDF + // X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override. + if (count($remember)) { + $last = count($remember) - 1; + if (($remember[$last]['num'] == 8235) || ($remember[$last]['num'] == 8234) || ($remember[$last]['num'] == 8238) || + ($remember[$last]['num'] == 8237)) { + $match = array_pop($remember); + $cel = $match['cel']; + $dos = $match['dos']; + } + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 10) { // NEW LINE + // Reset to start values + $cel = $pel; + $dos = -1; + $remember = []; + } else { + // X6. For all types besides RLE, LRE, RLO, LRO, and PDF: + // a. Set the level of the current character to the current embedding level. + // b. When the directional override status is not neutral, reset the current character type to directional override status. + if ($dos != -1) { + $chardir = $dos; + } else { + $chardir = $chunkOTLdata['char_data'][$i]['bidi_class']; + } + // stores string characters and other information + if (isset($chunkOTLdata['GPOSinfo'][$i])) { + $gpos = $chunkOTLdata['GPOSinfo'][$i]; + } else { + $gpos = ''; + } + $chardata[] = ['char' => $chunkOTLdata['char_data'][$i]['uni'], 'level' => $cel, 'type' => $chardir, 'group' => $chunkOTLdata['group'][$i], 'GPOSinfo' => $gpos]; + } + } + + $numchars = count($chardata); + + // X8. All explicit directional embeddings and overrides are completely terminated at the end of each paragraph. + // Paragraph separators are not included in the embedding. + // X9. Remove all RLE, LRE, RLO, LRO, and PDF codes. + // This is effectively done by only saving other codes to chardata + // X10. Determine the start-of-sequence (sor) and end-of-sequence (eor) types, either L or R, for each isolating run sequence. These depend on the higher of the two levels on either side of the sequence boundary: + // For sor, compare the level of the first character in the sequence with the level of the character preceding it in the paragraph or if there is none, with the paragraph embedding level. + // For eor, compare the level of the last character in the sequence with the level of the character following it in the paragraph or if there is none, with the paragraph embedding level. + // If the higher level is odd, the sor or eor is R; otherwise, it is L. + + $prelevel = $pel; + $postlevel = $pel; + $cel = $prelevel; // current embedding level + for ($i = 0; $i < $numchars; ++$i) { + $level = $chardata[$i]['level']; + if ($i == 0) { + $left = $prelevel; + } else { + $left = $chardata[$i - 1]['level']; + } + if ($i == ($numchars - 1)) { + $right = $postlevel; + } else { + $right = $chardata[$i + 1]['level']; + } + $chardata[$i]['sor'] = max($left, $level) % 2 ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + $chardata[$i]['eor'] = max($right, $level) % 2 ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + } + + + + // 3.3.3 Resolving Weak Types + // Weak types are now resolved one level run at a time. At level run boundaries where the type of the character on the other side of the boundary is required, the type assigned to sor or eor is used. + // Nonspacing marks are now resolved based on the previous characters. + // W1. Examine each nonspacing mark (NSM) in the level run, and change the type of the NSM to the type of the previous character. If the NSM is at the start of the level run, it will get the type of sor. + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_NSM) { + if ($i == 0 || $chardata[$i]['level'] != $chardata[$i - 1]['level']) { + $chardata[$i]['type'] = $chardata[$i]['sor']; + } else { + $chardata[$i]['type'] = $chardata[($i - 1)]['type']; + } + } + } + + // W2. Search backward from each instance of a European number until the first strong type (R, L, AL, or sor) is found. If an AL is found, change the type of the European number to Arabic number. + $prevlevel = -1; + $levcount = 0; + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN) { + $found = false; + for ($j = $levcount; $j >= 0; $j--) { + if ($chardata[$j]['type'] == Ucdn::BIDI_CLASS_AL) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_AN; + $found = true; + break; + } elseif (($chardata[$j]['type'] == Ucdn::BIDI_CLASS_L) || ($chardata[$j]['type'] == Ucdn::BIDI_CLASS_R)) { + $found = true; + break; + } + } + } + if ($chardata[$i]['level'] != $prevlevel) { + $levcount = 0; + } else { + ++$levcount; + } + $prevlevel = $chardata[$i]['level']; + } + + // W3. Change all ALs to R. + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_AL) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_R; + } + } + + // W4. A single European separator between two European numbers changes to a European number. A single common separator between two numbers of the same type changes to that type. + for ($i = 1; $i < $numchars; ++$i) { + if (($i + 1) < $numchars && $chardata[($i)]['level'] == $chardata[($i + 1)]['level'] && $chardata[($i)]['level'] == $chardata[($i - 1)]['level']) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ES && $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_EN && $chardata[($i + 1)]['type'] == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } elseif ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS && $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_EN && $chardata[($i + 1)]['type'] == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } elseif ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS && $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_AN && $chardata[($i + 1)]['type'] == Ucdn::BIDI_CLASS_AN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_AN; + } + } + } + + // W5. A sequence of European terminators adjacent to European numbers changes to all European numbers. + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ET) { + if ($i > 0 && $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_EN && $chardata[($i)]['level'] == $chardata[($i - 1)]['level']) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } else { + $j = $i + 1; + while ($j < $numchars && $chardata[$j]['level'] == $chardata[$i]['level']) { + if ($chardata[$j]['type'] == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + break; + } elseif ($chardata[$j]['type'] != Ucdn::BIDI_CLASS_ET) { + break; + } + ++$j; + } + } + } + } + + // W6. Otherwise, separators and terminators change to Other Neutral. + for ($i = 0; $i < $numchars; ++$i) { + if (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ET) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ES) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS)) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_ON; + } + } + + //W7. Search backward from each instance of a European number until the first strong type (R, L, or sor) is found. If an L is found, then change the type of the European number to L. + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN) { + if ($i == 0) { // Start of Level run + if ($chardata[$i]['sor'] == Ucdn::BIDI_CLASS_L) { + $chardata[$i]['type'] = $chardata[$i]['sor']; + } + } else { + for ($j = $i - 1; $j >= 0; $j--) { + if ($chardata[$j]['level'] != $chardata[$i]['level']) { // Level run boundary + if ($chardata[$j + 1]['sor'] == Ucdn::BIDI_CLASS_L) { + $chardata[$i]['type'] = $chardata[$j + 1]['sor']; + } + break; + } elseif ($chardata[$j]['type'] == Ucdn::BIDI_CLASS_L) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_L; + break; + } elseif ($chardata[$j]['type'] == Ucdn::BIDI_CLASS_R) { + break; + } + } + } + } + } + + // N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction. European and Arabic numbers act as if they were R in terms of their influence on neutrals. Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries. + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ON || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_WS) { + $left = -1; + // LEFT + if ($i == 0) { // first char + $left = $chardata[($i)]['sor']; + } elseif ($chardata[($i - 1)]['level'] != $chardata[($i)]['level']) { // run boundary + $left = $chardata[($i)]['sor']; + } elseif ($chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_L) { + $left = Ucdn::BIDI_CLASS_L; + } elseif ($chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_R || $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_EN || $chardata[($i - 1)]['type'] == Ucdn::BIDI_CLASS_AN) { + $left = Ucdn::BIDI_CLASS_R; + } + // RIGHT + $right = -1; + $j = $i; + // move to the right of any following neutrals OR hit a run boundary + while (($chardata[$j]['type'] == Ucdn::BIDI_CLASS_ON || $chardata[$j]['type'] == Ucdn::BIDI_CLASS_WS) && $j <= ($numchars - 1)) { + if ($j == ($numchars - 1)) { // last char + $right = $chardata[($j)]['eor']; + break; + } elseif ($chardata[($j + 1)]['level'] != $chardata[($j)]['level']) { // run boundary + $right = $chardata[($j)]['eor']; + break; + } elseif ($chardata[($j + 1)]['type'] == Ucdn::BIDI_CLASS_L) { + $right = Ucdn::BIDI_CLASS_L; + break; + } elseif ($chardata[($j + 1)]['type'] == Ucdn::BIDI_CLASS_R || $chardata[($j + 1)]['type'] == Ucdn::BIDI_CLASS_EN || $chardata[($j + 1)]['type'] == Ucdn::BIDI_CLASS_AN) { + $right = Ucdn::BIDI_CLASS_R; + break; + } + $j++; + } + if ($left > -1 && $left == $right) { + $chardata[$i]['orig_type'] = $chardata[$i]['type']; // Need to store the original 'WS' for reference in L1 below + $chardata[$i]['type'] = $left; + } + } + } + + // N2. Any remaining neutrals take the embedding direction + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ON || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_WS) { + $chardata[$i]['type'] = ($chardata[$i]['level'] % 2) ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + $chardata[$i]['orig_type'] = $chardata[$i]['type']; // Need to store the original 'WS' for reference in L1 below + } + } + + // I1. For all characters with an even (left-to-right) embedding direction, those of type R go up one level and those of type AN or EN go up two levels. + // I2. For all characters with an odd (right-to-left) embedding direction, those of type L, EN or AN go up one level. + for ($i = 0; $i < $numchars; ++$i) { + $odd = $chardata[$i]['level'] % 2; + if ($odd) { + if (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_L) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_AN) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN)) { + $chardata[$i]['level'] += 1; + } + } else { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_R) { + $chardata[$i]['level'] += 1; + } elseif (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_AN) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN)) { + $chardata[$i]['level'] += 2; + } + } + $maxlevel = max($chardata[$i]['level'], $maxlevel); + } + + // NB + // Separate into lines at this point************ + // + // L1. On each line, reset the embedding level of the following characters to the paragraph embedding level: + // 1. Segment separators (Tab) 'S', + // 2. Paragraph separators 'B', + // 3. Any sequence of whitespace characters 'WS' preceding a segment separator or paragraph separator, and + // 4. Any sequence of whitespace characters 'WS' at the end of the line. + // The types of characters used here are the original types, not those modified by the previous phase cf N1 and N2******* + // Because a Paragraph Separator breaks lines, there will be at most one per line, at the end of that line. + + for ($i = ($numchars - 1); $i > 0; $i--) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_WS || (isset($chardata[$i]['orig_type']) && $chardata[$i]['orig_type'] == Ucdn::BIDI_CLASS_WS)) { + $chardata[$i]['level'] = $pel; + } else { + break; + } + } + + + // L2. From the highest level found in the text to the lowest odd level on each line, including intermediate levels not actually present in the text, reverse any contiguous sequence of characters that are at that level or higher. + for ($j = $maxlevel; $j > 0; $j--) { + $ordarray = []; + $revarr = []; + $onlevel = false; + for ($i = 0; $i < $numchars; ++$i) { + if ($chardata[$i]['level'] >= $j) { + $onlevel = true; + + // L4. A character is depicted by a mirrored glyph if and only if (a) the resolved directionality of that character is R, and (b) the Bidi_Mirrored property value of that character is true. + if (isset(Ucdn::$mirror_pairs[$chardata[$i]['char']]) && $chardata[$i]['type'] == Ucdn::BIDI_CLASS_R) { + $chardata[$i]['char'] = Ucdn::$mirror_pairs[$chardata[$i]['char']]; + } + + $revarr[] = $chardata[$i]; + } else { + if ($onlevel) { + $revarr = array_reverse($revarr); + $ordarray = array_merge($ordarray, $revarr); + $revarr = []; + $onlevel = false; + } + $ordarray[] = $chardata[$i]; + } + } + if ($onlevel) { + $revarr = array_reverse($revarr); + $ordarray = array_merge($ordarray, $revarr); + } + $chardata = $ordarray; + } + + $group = ''; + $e = ''; + $GPOS = []; + $cctr = 0; + $rtl_content = 0x0; + foreach ($chardata as $cd) { + $e .= UtfString::code2utf($cd['char']); + $group .= $cd['group']; + if ($useGPOS && is_array($cd['GPOSinfo'])) { + $GPOS[$cctr] = $cd['GPOSinfo']; + $GPOS[$cctr]['wDir'] = ($cd['level'] % 2) ? 'RTL' : 'LTR'; + } + if ($cd['type'] == Ucdn::BIDI_CLASS_L) { + $rtl_content |= 1; + } elseif ($cd['type'] == Ucdn::BIDI_CLASS_R) { + $rtl_content |= 2; + } + $cctr++; + } + + + $chunkOTLdata['group'] = $group; + if ($useGPOS) { + $chunkOTLdata['GPOSinfo'] = $GPOS; + } + + return [$e, $rtl_content]; + } + + /** + * The following versions for BidiSort work on amalgamated chunks to process the whole paragraph + * + * Firstly set the level in the OTLdata - called from fn printbuffer() [_bidiPrepare] + * Secondly re-order - called from fn writeFlowingBlock and FinishFlowingBlock, when already divided into lines. [_bidiReorder] + */ + public function bidiPrepare(&$para, $dir) + { + + // Set the initial paragraph embedding level + $pel = 0; // paragraph embedding level + if ($dir == 'rtl') { + $pel = 1; + } + + // X1. Begin by setting the current embedding level to the paragraph embedding level. Set the directional override status to neutral. + // Current Embedding Level + $cel = $pel; + // directional override status (-1 is Neutral) + $dos = -1; + $remember = []; + $controlchars = false; + $strongrtl = false; + $diid = 0; // direction isolate ID + $dictr = 0; // direction isolate counter + // Process each character iteratively, applying rules X2 through X9. Only embedding levels from 0 to 61 are valid in this phase. + // In the resolution of levels in rules I1 and I2, the maximum embedding level of 62 can be reached. + $numchunks = count($para); + for ($nc = 0; $nc < $numchunks; $nc++) { + $chunkOTLdata = & $para[$nc][18]; + + $numchars = count($chunkOTLdata['char_data']); + for ($i = 0; $i < $numchars; ++$i) { + if ($chunkOTLdata['char_data'][$i]['uni'] == 8235) { // RLE + // X2. With each RLE, compute the least greater odd embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + ($cel % 2) + 1; + if ($next_level < 62) { + $remember[] = ['num' => 8235, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = -1; + $controlchars = true; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8234) { // LRE + // X3. With each LRE, compute the least greater even embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + 2 - ($cel % 2); + if ($next_level < 62) { + $remember[] = ['num' => 8234, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = -1; + $controlchars = true; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8238) { // RLO + // X4. With each RLO, compute the least greater odd embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to right-to-left. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + ($cel % 2) + 1; + if ($next_level < 62) { + $remember[] = ['num' => 8238, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = Ucdn::BIDI_CLASS_R; + $controlchars = true; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8237) { // LRO + // X5. With each LRO, compute the least greater even embedding level. + // a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to left-to-right. + // b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status. + $next_level = $cel + 2 - ($cel % 2); + if ($next_level < 62) { + $remember[] = ['num' => 8237, 'cel' => $cel, 'dos' => $dos]; + $cel = $next_level; + $dos = Ucdn::BIDI_CLASS_L; + $controlchars = true; + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8236) { // PDF + // X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override. + if (count($remember)) { + $last = count($remember) - 1; + if (($remember[$last]['num'] == 8235) || ($remember[$last]['num'] == 8234) || ($remember[$last]['num'] == 8238) || + ($remember[$last]['num'] == 8237)) { + $match = array_pop($remember); + $cel = $match['cel']; + $dos = $match['dos']; + } + } + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8294 || $chunkOTLdata['char_data'][$i]['uni'] == 8295 || + $chunkOTLdata['char_data'][$i]['uni'] == 8296) { // LRI // RLI // FSI + // X5a. With each RLI: + // X5b. With each LRI: + // X5c. With each FSI, apply rules P2 and P3 for First Strong character + // Set the RLI/LRI/FSI embedding level to the embedding level of the last entry on the directional status stack. + if ($dos != -1) { + $chardir = $dos; + } else { + $chardir = $chunkOTLdata['char_data'][$i]['bidi_class']; + } + $chunkOTLdata['char_data'][$i]['level'] = $cel; + $chunkOTLdata['char_data'][$i]['type'] = $chardir; + $chunkOTLdata['char_data'][$i]['diid'] = $diid; + + $fsi = ''; + // X5c. With each FSI, apply rules P2 and P3 within the isolate run for First Strong character + if ($chunkOTLdata['char_data'][$i]['uni'] == 8296) { // FSI + $lvl = 0; + $nc2 = $nc; + $i2 = $i; + while (!($nc2 == ($numchunks - 1) && $i2 == ((count($para[$nc2][18]['char_data'])) - 1))) { // while not at end of last chunk + $i2++; + if ($i2 >= count($para[$nc2][18]['char_data'])) { + $nc2++; + $i2 = 0; + } + if ($lvl > 0) { + continue; + } + if ($para[$nc2][18]['char_data'][$i2]['uni'] == 8294 || $para[$nc2][18]['char_data'][$i2]['uni'] == 8295 || $para[$nc2][18]['char_data'][$i2]['uni'] == 8296) { + $lvl++; + continue; + } + if ($para[$nc2][18]['char_data'][$i2]['uni'] == 8297) { + $lvl--; + if ($lvl < 0) { + break; + } + } + if ($para[$nc2][18]['char_data'][$i2]['bidi_class'] === Ucdn::BIDI_CLASS_L || $para[$nc2][18]['char_data'][$i2]['bidi_class'] == Ucdn::BIDI_CLASS_AL || $para[$nc2][18]['char_data'][$i2]['bidi_class'] === Ucdn::BIDI_CLASS_R) { + $fsi = $para[$nc2][18]['char_data'][$i2]['bidi_class']; + break; + } + } + // if fsi not found, fsi is same as paragraph embedding level + if (!$fsi && $fsi !== 0) { + if ($pel == 1) { + $fsi = Ucdn::BIDI_CLASS_R; + } else { + $fsi = Ucdn::BIDI_CLASS_L; + } + } + } + + if ($chunkOTLdata['char_data'][$i]['uni'] == 8294 || $fsi === Ucdn::BIDI_CLASS_L) { // LRI or FSI-L + // Compute the least even embedding level greater than the embedding level of the last entry on the directional status stack. + $next_level = $cel + 2 - ($cel % 2); + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8295 || $fsi == Ucdn::BIDI_CLASS_R || $fsi == Ucdn::BIDI_CLASS_AL) { // RLI or FSI-R + // Compute the least odd embedding level greater than the embedding level of the last entry on the directional status stack. + $next_level = $cel + ($cel % 2) + 1; + } + + + // Increment the isolate count by one, and push an entry consisting of the new embedding level, + // neutral directional override status, and true directional isolate status onto the directional status stack. + $remember[] = ['num' => $chunkOTLdata['char_data'][$i]['uni'], 'cel' => $cel, 'dos' => $dos, 'diid' => $diid]; + $cel = $next_level; + $dos = -1; + $diid = ++$dictr; // Set new direction isolate ID after incrementing direction isolate counter + + $controlchars = true; + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 8297) { // PDI + // X6a. With each PDI, perform the following steps: + // Pop the last entry from the directional status stack and decrement the isolate count by one. + while (count($remember)) { + $last = count($remember) - 1; + if (($remember[$last]['num'] == 8294) || ($remember[$last]['num'] == 8295) || ($remember[$last]['num'] == 8296)) { + $match = array_pop($remember); + $cel = $match['cel']; + $dos = $match['dos']; + $diid = $match['diid']; + break; + } // End/close any open embedding states not explicitly closed during the isolate + elseif (($remember[$last]['num'] == 8235) || ($remember[$last]['num'] == 8234) || ($remember[$last]['num'] == 8238) || + ($remember[$last]['num'] == 8237)) { + $match = array_pop($remember); + } + } + // In all cases, set the PDI’s level to the embedding level of the last entry on the directional status stack left after the steps above. + // NB The level assigned to an isolate initiator is always the same as that assigned to the matching PDI. + if ($dos != -1) { + $chardir = $dos; + } else { + $chardir = $chunkOTLdata['char_data'][$i]['bidi_class']; + } + $chunkOTLdata['char_data'][$i]['level'] = $cel; + $chunkOTLdata['char_data'][$i]['type'] = $chardir; + $chunkOTLdata['char_data'][$i]['diid'] = $diid; + $controlchars = true; + } elseif ($chunkOTLdata['char_data'][$i]['uni'] == 10) { // NEW LINE + // Reset to start values + $cel = $pel; + $dos = -1; + $remember = []; + } else { + // X6. For all types besides RLE, LRE, RLO, LRO, and PDF: + // a. Set the level of the current character to the current embedding level. + // b. When the directional override status is not neutral, reset the current character type to directional override status. + if ($dos != -1) { + $chardir = $dos; + } else { + $chardir = $chunkOTLdata['char_data'][$i]['bidi_class']; + if ($chardir == Ucdn::BIDI_CLASS_R || $chardir == Ucdn::BIDI_CLASS_AL) { + $strongrtl = true; + } + } + $chunkOTLdata['char_data'][$i]['level'] = $cel; + $chunkOTLdata['char_data'][$i]['type'] = $chardir; + $chunkOTLdata['char_data'][$i]['diid'] = $diid; + } + } + // X8. All explicit directional embeddings and overrides are completely terminated at the end of each paragraph. + // Paragraph separators are not included in the embedding. + // X9. Remove all RLE, LRE, RLO, LRO, and PDF codes. + if ($controlchars) { + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xaa"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xab"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xac"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xad"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x80\xae"); + preg_replace("/\x{202a}-\x{202e}/u", '', $para[$nc][0]); + } + } + + // Remove any blank chunks made by removing directional codes + $numchunks = count($para); + for ($nc = ($numchunks - 1); $nc >= 0; $nc--) { + if (count($para[$nc][18]['char_data']) == 0) { + array_splice($para, $nc, 1); + } + } + if ($dir != 'rtl' && !$strongrtl && !$controlchars) { + return; + } + + $numchunks = count($para); + + // X10. Determine the start-of-sequence (sor) and end-of-sequence (eor) types, either L or R, for each isolating run sequence. These depend on the higher of the two levels on either side of the sequence boundary: + // For sor, compare the level of the first character in the sequence with the level of the character preceding it in the paragraph or if there is none, with the paragraph embedding level. + // For eor, compare the level of the last character in the sequence with the level of the character following it in the paragraph or if there is none, with the paragraph embedding level. + // If the higher level is odd, the sor or eor is R; otherwise, it is L. + + for ($ir = 0; $ir <= $dictr; $ir++) { + $prelevel = $pel; + $postlevel = $pel; + $firstchar = true; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + $right = $postlevel; + $nc2 = $nc; + $i2 = $i; + while (!($nc2 == ($numchunks - 1) && $i2 == ((count($para[$nc2][18]['char_data'])) - 1))) { // while not at end of last chunk + $i2++; + if ($i2 >= count($para[$nc2][18]['char_data'])) { + $nc2++; + $i2 = 0; + } + + if (isset($para[$nc2][18]['char_data'][$i2]['diid']) && $para[$nc2][18]['char_data'][$i2]['diid'] == $ir) { + $right = $para[$nc2][18]['char_data'][$i2]['level']; + break; + } + } + + $level = $chardata[$i]['level']; + if ($firstchar || $level != $prelevel) { + $chardata[$i]['sor'] = max($prelevel, $level) % 2 ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + } + if (($nc == ($numchunks - 1) && $i == ($numchars - 1)) || $level != $right) { + $chardata[$i]['eor'] = max($right, $level) % 2 ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + } + $prelevel = $level; + $firstchar = false; + } + } + } + + + // 3.3.3 Resolving Weak Types + // Weak types are now resolved one level run at a time. At level run boundaries where the type of the character on the other side of the boundary is required, the type assigned to sor or eor is used. + // Nonspacing marks are now resolved based on the previous characters. + // W1. Examine each nonspacing mark (NSM) in the level run, and change the type of the NSM to the type of the previous character. If the NSM is at the start of the level run, it will get the type of sor. + for ($ir = 0; $ir <= $dictr; $ir++) { + $prevtype = 0; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_NSM) { + if (isset($chardata[$i]['sor'])) { + $chardata[$i]['type'] = $chardata[$i]['sor']; + } else { + $chardata[$i]['type'] = $prevtype; + } + } + $prevtype = $chardata[$i]['type']; + } + } + } + + // W2. Search backward from each instance of a European number until the first strong type (R, L, AL or sor) is found. If an AL is found, change the type of the European number to Arabic number. + for ($ir = 0; $ir <= $dictr; $ir++) { + $laststrongtype = -1; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + if (isset($chardata[$i]['sor'])) { + $laststrongtype = $chardata[$i]['sor']; + } + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN && $laststrongtype == Ucdn::BIDI_CLASS_AL) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_AN; + } + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_L || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_R || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_AL) { + $laststrongtype = $chardata[$i]['type']; + } + } + } + } + + + // W3. Change all ALs to R. + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (isset($chardata[$i]['type']) && $chardata[$i]['type'] == Ucdn::BIDI_CLASS_AL) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_R; + } + } + } + + + // W4. A single European separator between two European numbers changes to a European number. A single common separator between two numbers of the same type changes to that type. + for ($ir = 0; $ir <= $dictr; $ir++) { + $prevtype = -1; + $nexttype = -1; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + // Get next type + $nexttype = -1; + $nc2 = $nc; + $i2 = $i; + while (!($nc2 == ($numchunks - 1) && $i2 == ((count($para[$nc2][18]['char_data'])) - 1))) { // while not at end of last chunk + $i2++; + if ($i2 >= count($para[$nc2][18]['char_data'])) { + $nc2++; + $i2 = 0; + } + + if (isset($para[$nc2][18]['char_data'][$i2]['diid']) && $para[$nc2][18]['char_data'][$i2]['diid'] == $ir) { + $nexttype = $para[$nc2][18]['char_data'][$i2]['type']; + break; + } + } + + if (!isset($chardata[$i]['sor']) && !isset($chardata[$i]['eor'])) { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ES && $prevtype == Ucdn::BIDI_CLASS_EN && $nexttype == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } elseif ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS && $prevtype == Ucdn::BIDI_CLASS_EN && $nexttype == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } elseif ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS && $prevtype == Ucdn::BIDI_CLASS_AN && $nexttype == Ucdn::BIDI_CLASS_AN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_AN; + } + } + $prevtype = $chardata[$i]['type']; + } + } + } + + // W5. A sequence of European terminators adjacent to European numbers changes to all European numbers. + for ($ir = 0; $ir <= $dictr; $ir++) { + $prevtype = -1; + $nexttype = -1; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + if (isset($chardata[$i]['sor'])) { + $prevtype = $chardata[$i]['sor']; + } + + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ET) { + if ($prevtype == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + } elseif (!isset($chardata[$i]['eor'])) { + $nexttype = -1; + $nc2 = $nc; + $i2 = $i; + while (!($nc2 == ($numchunks - 1) && $i2 == ((count($para[$nc2][18]['char_data'])) - 1))) { // while not at end of last chunk + $i2++; + if ($i2 >= count($para[$nc2][18]['char_data'])) { + $nc2++; + $i2 = 0; + } + if (!isset($para[$nc2][18]['char_data'][$i2]['diid']) || $para[$nc2][18]['char_data'][$i2]['diid'] != $ir) { + continue; + } + $nexttype = $para[$nc2][18]['char_data'][$i2]['type']; + if (isset($para[$nc2][18]['char_data'][$i2]['sor'])) { + break; + } + if ($nexttype == Ucdn::BIDI_CLASS_EN) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_EN; + break; + } elseif ($nexttype != Ucdn::BIDI_CLASS_ET) { + break; + } + } + } + } + $prevtype = $chardata[$i]['type']; + } + } + } + + // W6. Otherwise, separators and terminators change to Other Neutral. + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (isset($chardata[$i]['type']) && (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ET) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ES) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_CS))) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_ON; + } + } + } + + //W7. Search backward from each instance of a European number until the first strong type (R, L, or sor) is found. If an L is found, then change the type of the European number to L. + for ($ir = 0; $ir <= $dictr; $ir++) { + $laststrongtype = -1; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + if (isset($chardata[$i]['sor'])) { + $laststrongtype = $chardata[$i]['sor']; + } + if (isset($chardata[$i]['type']) && $chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN && $laststrongtype == Ucdn::BIDI_CLASS_L) { + $chardata[$i]['type'] = Ucdn::BIDI_CLASS_L; + } + if (isset($chardata[$i]['type']) && ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_L || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_R || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_AL)) { + $laststrongtype = $chardata[$i]['type']; + } + } + } + } + + // N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction. European and Arabic numbers act as if they were R in terms of their influence on neutrals. Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries. + for ($ir = 0; $ir <= $dictr; $ir++) { + $laststrongtype = -1; + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (!isset($chardata[$i]['diid']) || $chardata[$i]['diid'] != $ir) { + continue; + } // Ignore characters in a different isolate run + if (isset($chardata[$i]['sor'])) { + $laststrongtype = $chardata[$i]['sor']; + } + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ON || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_WS) { + $left = -1; + // LEFT + if ($laststrongtype == Ucdn::BIDI_CLASS_R || $laststrongtype == Ucdn::BIDI_CLASS_EN || $laststrongtype == Ucdn::BIDI_CLASS_AN) { + $left = Ucdn::BIDI_CLASS_R; + } elseif ($laststrongtype == Ucdn::BIDI_CLASS_L) { + $left = Ucdn::BIDI_CLASS_L; + } + // RIGHT + $right = -1; + // move to the right of any following neutrals OR hit a run boundary + + if (isset($chardata[$i]['eor'])) { + $right = $chardata[$i]['eor']; + } else { + $nexttype = -1; + $nc2 = $nc; + $i2 = $i; + while (!($nc2 == ($numchunks - 1) && $i2 == ((count($para[$nc2][18]['char_data'])) - 1))) { // while not at end of last chunk + $i2++; + if ($i2 >= count($para[$nc2][18]['char_data'])) { + $nc2++; + $i2 = 0; + } + if (!isset($para[$nc2][18]['char_data'][$i2]['diid']) || $para[$nc2][18]['char_data'][$i2]['diid'] != $ir) { + continue; + } + $nexttype = $para[$nc2][18]['char_data'][$i2]['type']; + if ($nexttype == Ucdn::BIDI_CLASS_R || $nexttype == Ucdn::BIDI_CLASS_EN || $nexttype == Ucdn::BIDI_CLASS_AN) { + $right = Ucdn::BIDI_CLASS_R; + break; + } elseif ($nexttype == Ucdn::BIDI_CLASS_L) { + $right = Ucdn::BIDI_CLASS_L; + break; + } elseif (isset($para[$nc2][18]['char_data'][$i2]['eor'])) { + $right = $para[$nc2][18]['char_data'][$i2]['eor']; + break; + } + } + } + + if ($left > -1 && $left == $right) { + $chardata[$i]['orig_type'] = $chardata[$i]['type']; // Need to store the original 'WS' for reference in L1 below + $chardata[$i]['type'] = $left; + } + } elseif ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_L || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_R || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_AN) { + $laststrongtype = $chardata[$i]['type']; + } + } + } + } + + // N2. Any remaining neutrals take the embedding direction + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (isset($chardata[$i]['type']) && ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_ON || $chardata[$i]['type'] == Ucdn::BIDI_CLASS_WS)) { + $chardata[$i]['orig_type'] = $chardata[$i]['type']; // Need to store the original 'WS' for reference in L1 below + $chardata[$i]['type'] = ($chardata[$i]['level'] % 2) ? Ucdn::BIDI_CLASS_R : Ucdn::BIDI_CLASS_L; + } + } + } + + // I1. For all characters with an even (left-to-right) embedding direction, those of type R go up one level and those of type AN or EN go up two levels. + // I2. For all characters with an odd (right-to-left) embedding direction, those of type L, EN or AN go up one level. + for ($nc = 0; $nc < $numchunks; $nc++) { + $chardata = & $para[$nc][18]['char_data']; + $numchars = count($chardata); + for ($i = 0; $i < $numchars; ++$i) { + if (isset($chardata[$i]['level'])) { + $odd = $chardata[$i]['level'] % 2; + if ($odd) { + if (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_L) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_AN) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN)) { + $chardata[$i]['level'] += 1; + } + } else { + if ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_R) { + $chardata[$i]['level'] += 1; + } elseif (($chardata[$i]['type'] == Ucdn::BIDI_CLASS_AN) || ($chardata[$i]['type'] == Ucdn::BIDI_CLASS_EN)) { + $chardata[$i]['level'] += 2; + } + } + } + } + } + + // Remove Isolate formatters + $numchunks = count($para); + if ($controlchars) { + for ($nc = 0; $nc < $numchunks; $nc++) { + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa6"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa7"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa8"); + $this->removeChar($para[$nc][0], $para[$nc][18], "\xe2\x81\xa9"); + preg_replace("/\x{2066}-\x{2069}/u", '', $para[$nc][0]); + } + // Remove any blank chunks made by removing directional codes + for ($nc = ($numchunks - 1); $nc >= 0; $nc--) { + if (count($para[$nc][18]['char_data']) == 0) { + array_splice($para, $nc, 1); + } + } + } + } + + /** + * Reorder, once divided into lines + */ + public function bidiReorder(&$chunkorder, &$content, &$cOTLdata, $blockdir) + { + + $bidiData = []; + + // First combine into one array (and get the highest level in use) + $numchunks = count($content); + $maxlevel = 0; + for ($nc = 0; $nc < $numchunks; $nc++) { + $numchars = isset($cOTLdata[$nc]['char_data']) ? count($cOTLdata[$nc]['char_data']) : 0; + for ($i = 0; $i < $numchars; ++$i) { + $carac = []; + if (isset($cOTLdata[$nc]['GPOSinfo'][$i])) { + $carac['GPOSinfo'] = $cOTLdata[$nc]['GPOSinfo'][$i]; + } + $carac['uni'] = $cOTLdata[$nc]['char_data'][$i]['uni']; + if (isset($cOTLdata[$nc]['char_data'][$i]['type'])) { + $carac['type'] = $cOTLdata[$nc]['char_data'][$i]['type']; + } + if (isset($cOTLdata[$nc]['char_data'][$i]['level'])) { + $carac['level'] = $cOTLdata[$nc]['char_data'][$i]['level']; + } + if (isset($cOTLdata[$nc]['char_data'][$i]['orig_type'])) { + $carac['orig_type'] = $cOTLdata[$nc]['char_data'][$i]['orig_type']; + } + $carac['group'] = $cOTLdata[$nc]['group'][$i]; + $carac['chunkid'] = $chunkorder[$nc]; // gives font id and/or object ID + + $maxlevel = max((isset($carac['level']) ? $carac['level'] : 0), $maxlevel); + $bidiData[] = $carac; + } + } + if ($maxlevel == 0) { + return; + } + + $numchars = count($bidiData); + + // L1. On each line, reset the embedding level of the following characters to the paragraph embedding level: + // 1. Segment separators (Tab) 'S', + // 2. Paragraph separators 'B', + // 3. Any sequence of whitespace characters 'WS' preceding a segment separator or paragraph separator, and + // 4. Any sequence of whitespace characters 'WS' at the end of the line. + // The types of characters used here are the original types, not those modified by the previous phase cf N1 and N2******* + // Because a Paragraph Separator breaks lines, there will be at most one per line, at the end of that line. + // Set the initial paragraph embedding level + if ($blockdir == 'rtl') { + $pel = 1; + } else { + $pel = 0; + } + + for ($i = ($numchars - 1); $i > 0; $i--) { + if ($bidiData[$i]['type'] == Ucdn::BIDI_CLASS_WS || (isset($bidiData[$i]['orig_type']) && $bidiData[$i]['orig_type'] == Ucdn::BIDI_CLASS_WS)) { + $bidiData[$i]['level'] = $pel; + } else { + break; + } + } + + // L2. From the highest level found in the text to the lowest odd level on each line, including intermediate levels not actually present in the text, reverse any contiguous sequence of characters that are at that level or higher. + for ($j = $maxlevel; $j > 0; $j--) { + $ordarray = []; + $revarr = []; + $onlevel = false; + for ($i = 0; $i < $numchars; ++$i) { + if ($bidiData[$i]['level'] >= $j) { + $onlevel = true; + // L4. A character is depicted by a mirrored glyph if and only if (a) the resolved directionality of that character is R, and (b) the Bidi_Mirrored property value of that character is true. + if (isset(Ucdn::$mirror_pairs[$bidiData[$i]['uni']]) && $bidiData[$i]['type'] == Ucdn::BIDI_CLASS_R) { + $bidiData[$i]['uni'] = Ucdn::$mirror_pairs[$bidiData[$i]['uni']]; + } + + $revarr[] = $bidiData[$i]; + } else { + if ($onlevel) { + $revarr = array_reverse($revarr); + $ordarray = array_merge($ordarray, $revarr); + $revarr = []; + $onlevel = false; + } + $ordarray[] = $bidiData[$i]; + } + } + if ($onlevel) { + $revarr = array_reverse($revarr); + $ordarray = array_merge($ordarray, $revarr); + } + $bidiData = $ordarray; + } + + $content = []; + $cOTLdata = []; + $chunkorder = []; + + $nc = -1; // New chunk order ID + $chunkid = -1; + + foreach ($bidiData as $carac) { + if ($carac['chunkid'] != $chunkid) { + $nc++; + $chunkorder[$nc] = $carac['chunkid']; + $cctr = 0; + $content[$nc] = ''; + $cOTLdata[$nc]['group'] = ''; + } + if ($carac['uni'] != 0xFFFC) { // Object replacement character (65532) + $content[$nc] .= UtfString::code2utf($carac['uni']); + $cOTLdata[$nc]['group'] .= $carac['group']; + if (!empty($carac['GPOSinfo'])) { + if (isset($carac['GPOSinfo'])) { + $cOTLdata[$nc]['GPOSinfo'][$cctr] = $carac['GPOSinfo']; + } + $cOTLdata[$nc]['GPOSinfo'][$cctr]['wDir'] = ($carac['level'] % 2) ? 'RTL' : 'LTR'; + } + } + $chunkid = $carac['chunkid']; + $cctr++; + } + } + + public function splitOTLdata(&$cOTLdata, $OTLcutoffpos, $OTLrestartpos = '') + { + if (!$OTLrestartpos) { + $OTLrestartpos = $OTLcutoffpos; + } + $newOTLdata = ['GPOSinfo' => [], 'char_data' => []]; + $newOTLdata['group'] = substr($cOTLdata['group'], $OTLrestartpos); + $cOTLdata['group'] = substr($cOTLdata['group'], 0, $OTLcutoffpos); + + if (isset($cOTLdata['GPOSinfo']) && $cOTLdata['GPOSinfo']) { + foreach ($cOTLdata['GPOSinfo'] as $k => $val) { + if ($k >= $OTLrestartpos) { + $newOTLdata['GPOSinfo'][($k - $OTLrestartpos)] = $val; + } + if ($k >= $OTLcutoffpos) { + unset($cOTLdata['GPOSinfo'][$k]); + //$cOTLdata['GPOSinfo'][$k] = array(); + } + } + } + if (isset($cOTLdata['char_data'])) { + $newOTLdata['char_data'] = array_slice($cOTLdata['char_data'], $OTLrestartpos); + array_splice($cOTLdata['char_data'], $OTLcutoffpos); + } + + // Not necessary - easier to debug + if (isset($cOTLdata['GPOSinfo'])) { + ksort($cOTLdata['GPOSinfo']); + } + if (isset($newOTLdata['GPOSinfo'])) { + ksort($newOTLdata['GPOSinfo']); + } + + return $newOTLdata; + } + + public function sliceOTLdata($OTLdata, $pos, $len) + { + $newOTLdata = ['GPOSinfo' => [], 'char_data' => []]; + $newOTLdata['group'] = substr($OTLdata['group'], $pos, $len); + + if ($OTLdata['GPOSinfo']) { + foreach ($OTLdata['GPOSinfo'] as $k => $val) { + if ($k >= $pos && $k < ($pos + $len)) { + $newOTLdata['GPOSinfo'][($k - $pos)] = $val; + } + } + } + + if (isset($OTLdata['char_data'])) { + $newOTLdata['char_data'] = array_slice($OTLdata['char_data'], $pos, $len); + } + + // Not necessary - easier to debug + if ($newOTLdata['GPOSinfo']) { + ksort($newOTLdata['GPOSinfo']); + } + + return $newOTLdata; + } + + /** + * Remove one or more occurrences of $char (single character) from $txt and adjust OTLdata + */ + public function removeChar(&$txt, &$cOTLdata, $char) + { + while (mb_strpos($txt, $char, 0, $this->mpdf->mb_enc) !== false) { + $pos = mb_strpos($txt, $char, 0, $this->mpdf->mb_enc); + $newGPOSinfo = []; + $cOTLdata['group'] = substr_replace($cOTLdata['group'], '', $pos, 1); + if ($cOTLdata['GPOSinfo']) { + foreach ($cOTLdata['GPOSinfo'] as $k => $val) { + if ($k > $pos) { + $newGPOSinfo[($k - 1)] = $val; + } elseif ($k != $pos) { + $newGPOSinfo[$k] = $val; + } + } + $cOTLdata['GPOSinfo'] = $newGPOSinfo; + } + if (isset($cOTLdata['char_data'])) { + array_splice($cOTLdata['char_data'], $pos, 1); + } + + $txt = preg_replace("/" . $char . "/", '', $txt, 1); + } + } + + /** + * Remove one or more occurrences of $char (single character) from $txt and adjust OTLdata + */ + public function replaceSpace(&$txt, &$cOTLdata) + { + $char = chr(194) . chr(160); // NBSP + while (mb_strpos($txt, $char, 0, $this->mpdf->mb_enc) !== false) { + $pos = mb_strpos($txt, $char, 0, $this->mpdf->mb_enc); + if ($cOTLdata['char_data'][$pos]['uni'] == 160) { + $cOTLdata['char_data'][$pos]['uni'] = 32; + } + $txt = preg_replace("/" . $char . "/", ' ', $txt, 1); + } + } + + public function trimOTLdata(&$cOTLdata, $Left = true, $Right = true) + { + $len = (!is_array($cOTLdata) || $cOTLdata['char_data'] === null) ? 0 : count($cOTLdata['char_data']); + $nLeft = 0; + $nRight = 0; + for ($i = 0; $i < $len; $i++) { + if ($cOTLdata['char_data'][$i]['uni'] == 32 || $cOTLdata['char_data'][$i]['uni'] == 12288) { + $nLeft++; + } // 12288 = 0x3000 = CJK space + else { + break; + } + } + for ($i = ($len - 1); $i >= 0; $i--) { + if ($cOTLdata['char_data'][$i]['uni'] == 32 || $cOTLdata['char_data'][$i]['uni'] == 12288) { + $nRight++; + } // 12288 = 0x3000 = CJK space + else { + break; + } + } + + // Trim Right + if ($Right && $nRight) { + $cOTLdata['group'] = substr($cOTLdata['group'], 0, strlen($cOTLdata['group']) - $nRight); + if ($cOTLdata['GPOSinfo']) { + foreach ($cOTLdata['GPOSinfo'] as $k => $val) { + if ($k >= $len - $nRight) { + unset($cOTLdata['GPOSinfo'][$k]); + } + } + } + if (isset($cOTLdata['char_data'])) { + for ($i = 0; $i < $nRight; $i++) { + array_pop($cOTLdata['char_data']); + } + } + } + // Trim Left + if ($Left && $nLeft) { + $cOTLdata['group'] = substr($cOTLdata['group'], $nLeft); + if ($cOTLdata['GPOSinfo']) { + $newPOSinfo = []; + foreach ($cOTLdata['GPOSinfo'] as $k => $val) { + if ($k >= $nLeft) { + $newPOSinfo[$k - $nLeft] = $cOTLdata['GPOSinfo'][$k]; + } + } + $cOTLdata['GPOSinfo'] = $newPOSinfo; + } + if (isset($cOTLdata['char_data'])) { + for ($i = 0; $i < $nLeft; $i++) { + array_shift($cOTLdata['char_data']); + } + } + } + } + + //////////////////////////////////////////////////////////////// + ////////// GENERAL OTL FUNCTIONS ///////////////// + //////////////////////////////////////////////////////////////// + + private function glyphToChar($gid) + { + return (ord($this->glyphIDtoUni[$gid * 3]) << 16) + (ord($this->glyphIDtoUni[$gid * 3 + 1]) << 8) + ord($this->glyphIDtoUni[$gid * 3 + 2]); + } + + private function unicode_hex($unicode_dec) + { + return (str_pad(strtoupper(dechex($unicode_dec)), 5, '0', STR_PAD_LEFT)); + } + + private function seek($pos) + { + $this->_pos = $pos; + } + + private function skip($delta) + { + $this->_pos += $delta; + } + + private function read_short() + { + $a = (ord($this->ttfOTLdata[$this->_pos]) << 8) + ord($this->ttfOTLdata[$this->_pos + 1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + $this->_pos += 2; + return $a; + } + + private function read_ushort() + { + $a = (ord($this->ttfOTLdata[$this->_pos]) << 8) + ord($this->ttfOTLdata[$this->_pos + 1]); + $this->_pos += 2; + return $a; + } + + private function _getCoverageGID() + { + // Called from Lookup Type 1, Format 1 - returns glyphIDs rather than hexstrings + // Need to do this separately to cache separately + // Otherwise the same as fn below _getCoverage + $offset = $this->_pos; + if (isset($this->LuDataCache[$this->fontkey]['GID'][$offset])) { + $g = $this->LuDataCache[$this->fontkey]['GID'][$offset]; + } else { + $g = []; + $CoverageFormat = $this->read_ushort(); + if ($CoverageFormat == 1) { + $CoverageGlyphCount = $this->read_ushort(); + for ($gid = 0; $gid < $CoverageGlyphCount; $gid++) { + $glyphID = $this->read_ushort(); + $g[] = $glyphID; + } + } + if ($CoverageFormat == 2) { + $RangeCount = $this->read_ushort(); + for ($r = 0; $r < $RangeCount; $r++) { + $start = $this->read_ushort(); + $end = $this->read_ushort(); + $StartCoverageIndex = $this->read_ushort(); // n/a + for ($glyphID = $start; $glyphID <= $end; $glyphID++) { + $g[] = $glyphID; + } + } + } + $this->LuDataCache[$this->fontkey]['GID'][$offset] = $g; + } + return $g; + } + + private function _getCoverage() + { + $offset = $this->_pos; + if (isset($this->LuDataCache[$this->fontkey][$offset])) { + $g = $this->LuDataCache[$this->fontkey][$offset]; + } else { + $g = []; + $CoverageFormat = $this->read_ushort(); + if ($CoverageFormat == 1) { + $CoverageGlyphCount = $this->read_ushort(); + for ($gid = 0; $gid < $CoverageGlyphCount; $gid++) { + $glyphID = $this->read_ushort(); + $g[] = $this->unicode_hex($this->glyphToChar($glyphID)); + } + } + if ($CoverageFormat == 2) { + $RangeCount = $this->read_ushort(); + for ($r = 0; $r < $RangeCount; $r++) { + $start = $this->read_ushort(); + $end = $this->read_ushort(); + $StartCoverageIndex = $this->read_ushort(); // n/a + for ($glyphID = $start; $glyphID <= $end; $glyphID++) { + $g[] = $this->unicode_hex($this->glyphToChar($glyphID)); + } + } + } + $this->LuDataCache[$this->fontkey][$offset] = $g; + } + return $g; + } + + private function _getClasses($offset) + { + if (isset($this->LuDataCache[$this->fontkey][$offset])) { + $GlyphByClass = $this->LuDataCache[$this->fontkey][$offset]; + } else { + $this->seek($offset); + $ClassFormat = $this->read_ushort(); + $GlyphByClass = []; + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $startGlyphID = $StartGlyph + $i; + $endGlyphID = $StartGlyph + $i; + $class = $this->read_ushort(); + // Note: Font FreeSerif , tag "blws" + // $BacktrackClasses[0] is defined ? a mistake in the font ??? + // Let's ignore for now + if ($class > 0) { + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if ($this->glyphToChar($g)) { + $GlyphByClass[$class][$this->glyphToChar($g)] = 1; + } + } + } + } + } elseif ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $startGlyphID = $this->read_ushort(); + $endGlyphID = $this->read_ushort(); + $class = $this->read_ushort(); + // Note: Font FreeSerif , tag "blws" + // $BacktrackClasses[0] is defined ? a mistake in the font ??? + // Let's ignore for now + if ($class > 0) { + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if ($this->glyphToChar($g)) { + $GlyphByClass[$class][$this->glyphToChar($g)] = 1; + } + } + } + } + } + $this->LuDataCache[$this->fontkey][$offset] = $GlyphByClass; + } + return $GlyphByClass; + } + + private function _getOTLscriptTag($ScriptLang, $scripttag, $scriptblock, $shaper, $useOTL, $mode) + { + // ScriptLang is the array of available script/lang tags supported by the font + // $scriptblock is the (number/code) for the script of the actual text string based on Unicode properties (Ucdn::$uni_scriptblock) + // $scripttag is the default tag derived from $scriptblock + /* + http://www.microsoft.com/typography/otspec/ttoreg.htm + http://www.microsoft.com/typography/otspec/scripttags.htm + + Values for useOTL + + Bit dn hn Value + 1 1 0x0001 GSUB/GPOS - Latin scripts + 2 2 0x0002 GSUB/GPOS - Cyrillic scripts + 3 4 0x0004 GSUB/GPOS - Greek scripts + 4 8 0x0008 GSUB/GPOS - CJK scripts (excluding Hangul-Jamo) + 5 16 0x0010 (Reserved) + 6 32 0x0020 (Reserved) + 7 64 0x0040 (Reserved) + 8 128 0x0080 GSUB/GPOS - All other scripts (including all RTL scripts, complex scripts with shapers etc) + + NB If change for RTL - cf. function magic_reverse_dir in mpdf.php to update + + */ + + + if ($scriptblock == Ucdn::SCRIPT_LATIN) { + if (!($useOTL & 0x01)) { + return ['', false]; + } + } elseif ($scriptblock == Ucdn::SCRIPT_CYRILLIC) { + if (!($useOTL & 0x02)) { + return ['', false]; + } + } elseif ($scriptblock == Ucdn::SCRIPT_GREEK) { + if (!($useOTL & 0x04)) { + return ['', false]; + } + } elseif ($scriptblock >= Ucdn::SCRIPT_HIRAGANA && $scriptblock <= Ucdn::SCRIPT_YI) { + if (!($useOTL & 0x08)) { + return ['', false]; + } + } else { + if (!($useOTL & 0x80)) { + return ['', false]; + } + } + + // If availabletags includes scripttag - choose + if (isset($ScriptLang[$scripttag])) { + return [$scripttag, false]; + } + + // If INDIC (or Myanmar) and available tag not includes new version, check if includes old version & choose old version + if ($shaper) { + switch ($scripttag) { + case 'bng2': + if (isset($ScriptLang['beng'])) { + return ['beng', true]; + } + // fallthrough + case 'dev2': + if (isset($ScriptLang['deva'])) { + return ['deva', true]; + } + // fallthrough + case 'gjr2': + if (isset($ScriptLang['gujr'])) { + return ['gujr', true]; + } + // fallthrough + case 'gur2': + if (isset($ScriptLang['guru'])) { + return ['guru', true]; + } + // fallthrough + case 'knd2': + if (isset($ScriptLang['knda'])) { + return ['knda', true]; + } + // fallthrough + case 'mlm2': + if (isset($ScriptLang['mlym'])) { + return ['mlym', true]; + } + // fallthrough + case 'ory2': + if (isset($ScriptLang['orya'])) { + return ['orya', true]; + } + // fallthrough + case 'tml2': + if (isset($ScriptLang['taml'])) { + return ['taml', true]; + } + // fallthrough + case 'tel2': + if (isset($ScriptLang['telu'])) { + return ['telu', true]; + } + // fallthrough + case 'mym2': + if (isset($ScriptLang['mymr'])) { + return ['mymr', true]; + } + } + } + + // choose DFLT if present + if (isset($ScriptLang['DFLT'])) { + return ['DFLT', false]; + } + // else choose dflt if present + if (isset($ScriptLang['dflt'])) { + return ['dflt', false]; + } + // else return no scriptTag + if (isset($ScriptLang['latn'])) { + return ['latn', false]; + } + // else return no scriptTag + return ['', false]; + } + + // LangSys tags + private function _getOTLLangTag($ietf, $available) + { + // http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + // http://www.microsoft.com/typography/otspec/languagetags.htm + // IETF tag = e.g. en-US, und-Arab, sr-Cyrl cf. class LangToFont + if ($available == '') { + return ''; + } + $tags = preg_split('/-/', $ietf); + $lang = ''; + $country = ''; + $script = ''; + $lang = strtolower($tags[0]); + if (isset($tags[1]) && $tags[1]) { + if (strlen($tags[1]) == 2) { + $country = strtolower($tags[1]); + } + } + if (isset($tags[2]) && $tags[2]) { + $country = strtolower($tags[2]); + } + + if ($lang != '' && isset(Ucdn::$ot_languages[$lang])) { + $langsys = Ucdn::$ot_languages[$lang]; + } elseif ($lang != '' && $country != '' && isset(Ucdn::$ot_languages[$lang . '' . $country])) { + $langsys = Ucdn::$ot_languages[$lang . '' . $country]; + } else { + $langsys = "DFLT"; + } + if (strpos($available, $langsys) === false) { + if (strpos($available, "DFLT") !== false) { + return "DFLT"; + } else { + return ''; + } + } + return $langsys; + } + + private function _dumpproc($GPOSSUB, $lookupID, $subtable, $Type, $Format, $ptr, $currGlyph, $level) + { + echo '<div style="padding-left: ' . ($level * 2) . 'em;">'; + echo $GPOSSUB . ' LookupID #' . $lookupID . ' Subtable#' . $subtable . ' Type: ' . $Type . ' Format: ' . $Format . '<br />'; + echo '<div style="font-family:monospace">'; + echo 'Glyph position: ' . $ptr . ' Current Glyph: ' . $currGlyph . '<br />'; + + for ($i = 0; $i < count($this->OTLdata); $i++) { + if ($i == $ptr) { + echo '<b>'; + } + echo $this->OTLdata[$i]['hex'] . ' '; + if ($i == $ptr) { + echo '</b>'; + } + } + echo '<br />'; + + for ($i = 0; $i < count($this->OTLdata); $i++) { + if ($i == $ptr) { + echo '<b>'; + } + echo str_pad($this->OTLdata[$i]['uni'], 5) . ' '; + if ($i == $ptr) { + echo '</b>'; + } + } + echo '<br />'; + + if ($GPOSSUB == 'GPOS') { + for ($i = 0; $i < count($this->OTLdata); $i++) { + if (!empty($this->OTLdata[$i]['GPOSinfo'])) { + echo $this->OTLdata[$i]['hex'] . ' &#x' . $this->OTLdata[$i]['hex'] . '; '; + print_r($this->OTLdata[$i]['GPOSinfo']); + echo ' '; + } + } + } + + echo '</div>'; + echo '</div>'; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/OtlDump.php b/lib/MPDF/vendor/mpdf/mpdf/src/OtlDump.php new file mode 100644 index 0000000..024c54d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/OtlDump.php @@ -0,0 +1,4369 @@ +<?php + +namespace Mpdf; + +// Define the value used in the "head" table of a created TTF file +// 0x74727565 "true" for Mac +// 0x00010000 for Windows +// Either seems to work for a font embedded in a PDF file +// when read by Adobe Reader on a Windows PC(!) +use Mpdf\Fonts\GlyphOperator; + +if (!defined('_TTF_MAC_HEADER')) { + define("_TTF_MAC_HEADER", false); +} + +// Recalculate correct metadata/profiles when making subset fonts (not SIP/SMP) +// e.g. xMin, xMax, maxNContours +if (!defined('_RECALC_PROFILE')) { + define("_RECALC_PROFILE", false); +} + +// mPDF 5.7.1 +if (!function_exists('Mpdf\unicode_hex')) { + function unicode_hex($unicode_dec) + { + return (sprintf("%05s", strtoupper(dechex($unicode_dec)))); + } +} + +class OtlDump +{ + + var $GPOSFeatures; // mPDF 5.7.1 + + var $GPOSLookups; // mPDF 5.7.1 + + var $GPOSScriptLang; // mPDF 5.7.1 + + var $ignoreStrings; // mPDF 5.7.1 + + var $MarkAttachmentType; // mPDF 5.7.1 + + var $MarkGlyphSets; // mPDF 7.5.1 + + var $GlyphClassMarks; // mPDF 5.7.1 + + var $GlyphClassLigatures; // mPDF 5.7.1 + + var $GlyphClassBases; // mPDF 5.7.1 + + var $GlyphClassComponents; // mPDF 5.7.1 + + var $GSUBScriptLang; // mPDF 5.7.1 + + var $rtlPUAstr; // mPDF 5.7.1 + + var $rtlPUAarr; // mPDF 5.7.1 + + var $fontkey; // mPDF 5.7.1 + + var $useOTL; // mPDF 5.7.1 + + var $panose; + + var $maxUni; + + var $sFamilyClass; + + var $sFamilySubClass; + + var $sipset; + + var $smpset; + + var $_pos; + + var $numTables; + + var $searchRange; + + var $entrySelector; + + var $rangeShift; + + var $tables; + + var $otables; + + var $filename; + + var $fh; + + var $glyphPos; + + var $charToGlyph; + + var $ascent; + + var $descent; + + var $name; + + var $familyName; + + var $styleName; + + var $fullName; + + var $uniqueFontID; + + var $unitsPerEm; + + var $bbox; + + var $capHeight; + + var $stemV; + + var $italicAngle; + + var $flags; + + var $underlinePosition; + + var $underlineThickness; + + var $charWidths; + + var $defaultWidth; + + var $maxStrLenRead; + + var $numTTCFonts; + + var $TTCFonts; + + var $maxUniChar; + + var $kerninfo; + + var $mode; + + var $glyphToChar; + + var $fontRevision; + + var $glyphdata; + + var $glyphIDtoUn; + + var $restrictedUse; + + var $GSUBFeatures; + + var $GSUBLookups; + + var $glyphIDtoUni; + + var $GSLuCoverage; + + var $version; + + private $mpdf; + + public function __construct(Mpdf $mpdf) + { + $this->mpdf = $mpdf; + $this->maxStrLenRead = 200000; // Maximum size of glyf table to read in as string (otherwise reads each glyph from file) + } + + function getMetrics($file, $fontkey, $TTCfontID = 0, $debug = false, $BMPonly = false, $kerninfo = false, $useOTL = 0, $mode = null) + { + // mPDF 5.7.1 + $this->mode = $mode; + $this->useOTL = $useOTL; // mPDF 5.7.1 + $this->fontkey = $fontkey; // mPDF 5.7.1 + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file "%s"', $file)); + } + + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->kerninfo = []; + $this->ascent = 0; + $this->descent = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->version = $version = $this->read_ulong(); + $this->panose = []; + + if ($version == 0x4F54544F) { + throw new \Mpdf\MpdfException("Postscript outlines are not supported"); + } + + if ($version == 0x74746366 && !$TTCfontID) { + throw new \Mpdf\MpdfException("TTCfontID for a TrueType Collection has to be defined in ttfontdata configuration key (" . $file . ")"); + } + + if (!in_array($version, [0x00010000, 0x74727565]) && !$TTCfontID) { + throw new \Mpdf\MpdfException("Not a TrueType font: version=" . $version); + } + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000])) { + throw new \Mpdf\MpdfException("Error parsing TrueType Collection: version=" . $version . " - " . $file); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + $this->readTableDirectory($debug); + $this->extractInfo($debug, $BMPonly, $kerninfo, $useOTL); + fclose($this->fh); + } + + function readTableDirectory($debug = false) + { + $this->numTables = $this->read_ushort(); + $this->searchRange = $this->read_ushort(); + $this->entrySelector = $this->read_ushort(); + $this->rangeShift = $this->read_ushort(); + $this->tables = []; + for ($i = 0; $i < $this->numTables; $i++) { + $record = []; + $record['tag'] = $this->read_tag(); + $record['checksum'] = [$this->read_ushort(), $this->read_ushort()]; + $record['offset'] = $this->read_ulong(); + $record['length'] = $this->read_ulong(); + $this->tables[$record['tag']] = $record; + } + if ($debug) { + $this->checksumTables(); + } + } + + function checksumTables() + { + // Check the checksums for all tables + foreach ($this->tables as $t) { + if ($t['length'] > 0 && $t['length'] < $this->maxStrLenRead) { // 1.02 + $table = $this->get_chunk($t['offset'], $t['length']); + $checksum = $this->calcChecksum($table); + if ($t['tag'] == 'head') { + $up = unpack('n*', substr($table, 8, 4)); + $adjustment[0] = $up[1]; + $adjustment[1] = $up[2]; + $checksum = $this->sub32($checksum, $adjustment); + } + $xchecksum = $t['checksum']; + if ($xchecksum != $checksum) { + throw new \Mpdf\MpdfException(sprintf('TTF file "%s": invalid checksum %s table: %s (expected %s)', $this->filename, dechex($checksum[0]) . dechex($checksum[1]), $t['tag'], dechex($xchecksum[0]) . dechex($xchecksum[1]))); + } + } + } + } + + function sub32($x, $y) + { + $xlo = $x[1]; + $xhi = $x[0]; + $ylo = $y[1]; + $yhi = $y[0]; + if ($ylo > $xlo) { + $xlo += 1 << 16; + $yhi += 1; + } + $reslo = $xlo - $ylo; + if ($yhi > $xhi) { + $xhi += 1 << 16; + } + $reshi = $xhi - $yhi; + $reshi = $reshi & 0xFFFF; + + return [$reshi, $reslo]; + } + + function calcChecksum($data) + { + if (strlen($data) % 4) { + $data .= str_repeat("\0", (4 - (strlen($data) % 4))); + } + $len = strlen($data); + $hi = 0x0000; + $lo = 0x0000; + for ($i = 0; $i < $len; $i += 4) { + $hi += (ord($data[$i]) << 8) + ord($data[$i + 1]); + $lo += (ord($data[$i + 2]) << 8) + ord($data[$i + 3]); + $hi += ($lo >> 16) & 0xFFFF; + $lo = $lo & 0xFFFF; + } + + return [$hi, $lo]; + } + + function get_table_pos($tag) + { + $offset = isset($this->tables[$tag]['offset']) ? $this->tables[$tag]['offset'] : null; + $length = isset($this->tables[$tag]['length']) ? $this->tables[$tag]['length'] : null; + + return [$offset, $length]; + } + + function seek($pos) + { + $this->_pos = $pos; + fseek($this->fh, $this->_pos); + } + + function skip($delta) + { + $this->_pos = $this->_pos + $delta; + fseek($this->fh, $delta, SEEK_CUR); + } + + function seek_table($tag, $offset_in_table = 0) + { + $tpos = $this->get_table_pos($tag); + $this->_pos = $tpos[0] + $offset_in_table; + fseek($this->fh, $this->_pos); + + return $this->_pos; + } + + function read_tag() + { + $this->_pos += 4; + + return fread($this->fh, 4); + } + + function read_short() + { + $this->_pos += 2; + $s = fread($this->fh, 2); + $a = (ord($s[0]) << 8) + ord($s[1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + + return $a; + } + + function unpack_short($s) + { + $a = (ord($s[0]) << 8) + ord($s[1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + + return $a; + } + + function read_ushort() + { + $this->_pos += 2; + $s = fread($this->fh, 2); + + return (ord($s[0]) << 8) + ord($s[1]); + } + + function read_ulong() + { + $this->_pos += 4; + $s = fread($this->fh, 4); + + // if large uInt32 as an integer, PHP converts it to -ve + return (ord($s[0]) * 16777216) + (ord($s[1]) << 16) + (ord($s[2]) << 8) + ord($s[3]); // 16777216 = 1<<24 + } + + function get_ushort($pos) + { + fseek($this->fh, $pos); + $s = fread($this->fh, 2); + + return (ord($s[0]) << 8) + ord($s[1]); + } + + function get_ulong($pos) + { + fseek($this->fh, $pos); + $s = fread($this->fh, 4); + + // iF large uInt32 as an integer, PHP converts it to -ve + return (ord($s[0]) * 16777216) + (ord($s[1]) << 16) + (ord($s[2]) << 8) + ord($s[3]); // 16777216 = 1<<24 + } + + function pack_short($val) + { + if ($val < 0) { + $val = abs($val); + $val = ~$val; + $val += 1; + } + + return pack("n", $val); + } + + function splice($stream, $offset, $value) + { + return substr($stream, 0, $offset) . $value . substr($stream, $offset + strlen($value)); + } + + function _set_ushort($stream, $offset, $value) + { + $up = pack("n", $value); + + return $this->splice($stream, $offset, $up); + } + + function _set_short($stream, $offset, $val) + { + if ($val < 0) { + $val = abs($val); + $val = ~$val; + $val += 1; + } + $up = pack("n", $val); + + return $this->splice($stream, $offset, $up); + } + + function get_chunk($pos, $length) + { + fseek($this->fh, $pos); + if ($length < 1) { + return ''; + } + + return (fread($this->fh, $length)); + } + + function get_table($tag) + { + list($pos, $length) = $this->get_table_pos($tag); + if ($length == 0) { + return ''; + } + fseek($this->fh, $pos); + + return (fread($this->fh, $length)); + } + + function add($tag, $data) + { + if ($tag == 'head') { + $data = $this->splice($data, 8, "\0\0\0\0"); + } + $this->otables[$tag] = $data; + } + + ///////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + function extractInfo($debug = false, $BMPonly = false, $kerninfo = false, $useOTL = 0) + { + $this->panose = []; + $this->sFamilyClass = 0; + $this->sFamilySubClass = 0; + /////////////////////////////////// + // name - Naming table + /////////////////////////////////// + $name_offset = $this->seek_table("name"); + $format = $this->read_ushort(); + if ($format != 0 && $format != 1) { + throw new \Mpdf\MpdfException("Unknown name table format " . $format); + } + $numRecords = $this->read_ushort(); + $string_data_offset = $name_offset + $this->read_ushort(); + $names = [1 => '', 2 => '', 3 => '', 4 => '', 6 => '']; + $K = array_keys($names); + $nameCount = count($names); + for ($i = 0; $i < $numRecords; $i++) { + $platformId = $this->read_ushort(); + $encodingId = $this->read_ushort(); + $languageId = $this->read_ushort(); + $nameId = $this->read_ushort(); + $length = $this->read_ushort(); + $offset = $this->read_ushort(); + if (!in_array($nameId, $K)) { + continue; + } + $N = ''; + if ($platformId == 3 && $encodingId == 1 && $languageId == 0x409) { // Microsoft, Unicode, US English, PS Name + $opos = $this->_pos; + $this->seek($string_data_offset + $offset); + if ($length % 2 != 0) { + throw new \Mpdf\MpdfException("PostScript name is UTF-16BE string of odd length"); + } + $length /= 2; + $N = ''; + while ($length > 0) { + $char = $this->read_ushort(); + $N .= (chr($char)); + $length -= 1; + } + $this->_pos = $opos; + $this->seek($opos); + } else { + if ($platformId == 1 && $encodingId == 0 && $languageId == 0) { // Macintosh, Roman, English, PS Name + $opos = $this->_pos; + $N = $this->get_chunk($string_data_offset + $offset, $length); + $this->_pos = $opos; + $this->seek($opos); + } + } + if ($N && $names[$nameId] == '') { + $names[$nameId] = $N; + $nameCount -= 1; + if ($nameCount == 0) { + break; + } + } + } + if ($names[6]) { + $psName = $names[6]; + } else { + if ($names[4]) { + $psName = preg_replace('/ /', '-', $names[4]); + } else { + if ($names[1]) { + $psName = preg_replace('/ /', '-', $names[1]); + } else { + $psName = ''; + } + } + } + if (!$psName) { + throw new \Mpdf\MpdfException("Could not find PostScript font name: " . $this->filename); + } + if ($debug) { + for ($i = 0; $i < count($psName); $i++) { + $c = $psName[$i]; + $oc = ord($c); + if ($oc > 126 || strpos(' [](){}<>/%', $c) !== false) { + throw new \Mpdf\MpdfException("psName=" . $psName . " contains invalid character " . $c . " ie U+" . ord(c)); + } + } + } + $this->name = $psName; + if ($names[1]) { + $this->familyName = $names[1]; + } else { + $this->familyName = $psName; + } + if ($names[2]) { + $this->styleName = $names[2]; + } else { + $this->styleName = 'Regular'; + } + if ($names[4]) { + $this->fullName = $names[4]; + } else { + $this->fullName = $psName; + } + if ($names[3]) { + $this->uniqueFontID = $names[3]; + } else { + $this->uniqueFontID = $psName; + } + + if ($names[6]) { + $this->fullName = $names[6]; + } + + /////////////////////////////////// + // head - Font header table + /////////////////////////////////// + $this->seek_table("head"); + if ($debug) { + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException('Unknown head table version ' . $ver_maj . '.' . $ver_min); + } + $this->fontRevision = $this->read_ushort() . $this->read_ushort(); + + $this->skip(4); + $magic = $this->read_ulong(); + if ($magic != 0x5F0F3CF5) { + throw new \Mpdf\MpdfException('Invalid head table magic ' . $magic); + } + $this->skip(2); + } else { + $this->skip(18); + } + $this->unitsPerEm = $unitsPerEm = $this->read_ushort(); + $scale = 1000 / $unitsPerEm; + $this->skip(16); + $xMin = $this->read_short(); + $yMin = $this->read_short(); + $xMax = $this->read_short(); + $yMax = $this->read_short(); + $this->bbox = [($xMin * $scale), ($yMin * $scale), ($xMax * $scale), ($yMax * $scale)]; + $this->skip(3 * 2); + $indexToLocFormat = $this->read_ushort(); + $glyphDataFormat = $this->read_ushort(); + if ($glyphDataFormat != 0) { + throw new \Mpdf\MpdfException('Unknown glyph data format ' . $glyphDataFormat); + } + + /////////////////////////////////// + // hhea metrics table + /////////////////////////////////// + // ttf2t1 seems to use this value rather than the one in OS/2 - so put in for compatibility + if (isset($this->tables["hhea"])) { + $this->seek_table("hhea"); + $this->skip(4); + $hheaAscender = $this->read_short(); + $hheaDescender = $this->read_short(); + $this->ascent = ($hheaAscender * $scale); + $this->descent = ($hheaDescender * $scale); + } + + /////////////////////////////////// + // OS/2 - OS/2 and Windows metrics table + /////////////////////////////////// + if (isset($this->tables["OS/2"])) { + $this->seek_table("OS/2"); + $version = $this->read_ushort(); + $this->skip(2); + $usWeightClass = $this->read_ushort(); + $this->skip(2); + $fsType = $this->read_ushort(); + if ($fsType == 0x0002 || ($fsType & 0x0300) != 0) { + global $overrideTTFFontRestriction; + if (!$overrideTTFFontRestriction) { + throw new \Mpdf\MpdfException('ERROR - Font file ' . $this->filename . ' cannot be embedded due to copyright restrictions.'); + } + $this->restrictedUse = true; + } + $this->skip(20); + $sF = $this->read_short(); + $this->sFamilyClass = ($sF >> 8); + $this->sFamilySubClass = ($sF & 0xFF); + $this->_pos += 10; //PANOSE = 10 byte length + $panose = fread($this->fh, 10); + $this->panose = []; + for ($p = 0; $p < strlen($panose); $p++) { + $this->panose[] = ord($panose[$p]); + } + $this->skip(26); + $sTypoAscender = $this->read_short(); + $sTypoDescender = $this->read_short(); + if (!$this->ascent) { + $this->ascent = ($sTypoAscender * $scale); + } + if (!$this->descent) { + $this->descent = ($sTypoDescender * $scale); + } + if ($version > 1) { + $this->skip(16); + $sCapHeight = $this->read_short(); + $this->capHeight = ($sCapHeight * $scale); + } else { + $this->capHeight = $this->ascent; + } + } else { + $usWeightClass = 500; + if (!$this->ascent) { + $this->ascent = ($yMax * $scale); + } + if (!$this->descent) { + $this->descent = ($yMin * $scale); + } + $this->capHeight = $this->ascent; + } + $this->stemV = 50 + intval(pow(($usWeightClass / 65.0), 2)); + + /////////////////////////////////// + // post - PostScript table + /////////////////////////////////// + $this->seek_table("post"); + if ($debug) { + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj < 1 || $ver_maj > 4) { + throw new \Mpdf\MpdfException('Unknown post table version ' . $ver_maj); + } + } else { + $this->skip(4); + } + $this->italicAngle = $this->read_short() + $this->read_ushort() / 65536.0; + $this->underlinePosition = $this->read_short() * $scale; + $this->underlineThickness = $this->read_short() * $scale; + $isFixedPitch = $this->read_ulong(); + + $this->flags = 4; + + if ($this->italicAngle != 0) { + $this->flags = $this->flags | 64; + } + if ($usWeightClass >= 600) { + $this->flags = $this->flags | 262144; + } + if ($isFixedPitch) { + $this->flags = $this->flags | 1; + } + + /////////////////////////////////// + // hhea - Horizontal header table + /////////////////////////////////// + $this->seek_table("hhea"); + if ($debug) { + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException('Unknown hhea table version ' . $ver_maj); + } + $this->skip(28); + } else { + $this->skip(32); + } + $metricDataFormat = $this->read_ushort(); + if ($metricDataFormat != 0) { + throw new \Mpdf\MpdfException('Unknown horizontal metric data format ' . $metricDataFormat); + } + $numberOfHMetrics = $this->read_ushort(); + if ($numberOfHMetrics == 0) { + throw new \Mpdf\MpdfException('Number of horizontal metrics is 0'); + } + + /////////////////////////////////// + // maxp - Maximum profile table + /////////////////////////////////// + $this->seek_table("maxp"); + if ($debug) { + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException('Unknown maxp table version ' . $ver_maj); + } + } else { + $this->skip(4); + } + $numGlyphs = $this->read_ushort(); + + /////////////////////////////////// + // cmap - Character to glyph index mapping table + /////////////////////////////////// + $cmap_offset = $this->seek_table("cmap"); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + if (!$unicode_cmap_offset) { + $unicode_cmap_offset = $cmap_offset + $offset; + } + if ($BMPonly) { + break; + } + } + } // Microsoft, Unicode Format 12 table HKCS + else { + if ((($platformID == 3 && $encodingID == 10) || $platformID == 0) && !$BMPonly) { + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 12) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + } + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException('Font (' . $this->filename . ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)'); + } + + $sipset = false; + $smpset = false; + + // mPDF 5.7.1 + $this->GSUBScriptLang = []; + $this->rtlPUAstr = ''; + $this->rtlPUAarr = []; + $this->GSUBFeatures = []; + $this->GSUBLookups = []; + $this->GPOSScriptLang = []; + $this->GPOSFeatures = []; + $this->GPOSLookups = []; + $this->glyphIDtoUni = ''; + + // Format 12 CMAP does characters above Unicode BMP i.e. some HKCS characters U+20000 and above + if ($format == 12 && !$BMPonly) { + $this->maxUniChar = 0; + $this->seek($unicode_cmap_offset + 4); + $length = $this->read_ulong(); + $limit = $unicode_cmap_offset + $length; + $this->skip(4); + + $nGroups = $this->read_ulong(); + + $glyphToChar = []; + $charToGlyph = []; + for ($i = 0; $i < $nGroups; $i++) { + $startCharCode = $this->read_ulong(); + $endCharCode = $this->read_ulong(); + $startGlyphCode = $this->read_ulong(); + if ($endCharCode > 0x20000 && $endCharCode < 0x2FFFF) { + $sipset = true; + } else { + if ($endCharCode > 0x10000 && $endCharCode < 0x1FFFF) { + $smpset = true; + } + } + $offset = 0; + for ($unichar = $startCharCode; $unichar <= $endCharCode; $unichar++) { + $glyph = $startGlyphCode + $offset; + $offset++; + if ($unichar < 0x30000) { + $charToGlyph[$unichar] = $glyph; + $this->maxUniChar = max($unichar, $this->maxUniChar); + $glyphToChar[$glyph][] = $unichar; + } + } + } + } else { + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + } + $this->sipset = $sipset; + $this->smpset = $smpset; + + /////////////////////////////////// + // mPDF 5.7.1 + // Map Unmapped glyphs - from $numGlyphs + if ($this->useOTL) { + $bctr = 0xE000; + for ($gid = 1; $gid < $numGlyphs; $gid++) { + if (!isset($glyphToChar[$gid])) { + while (isset($charToGlyph[$bctr])) { + $bctr++; + } // Avoid overwriting a glyph already mapped in PUA + if (($bctr > 0xF8FF) && ($bctr < 0x2CEB0)) { + if (!$BMPonly) { + $bctr = 0x2CEB0; // Use unassigned area 0x2CEB0 to 0x2F7FF (space for 10,000 characters) + $this->sipset = $sipset = true; // forces subsetting; also ensure charwidths are saved + while (isset($charToGlyph[$bctr])) { + $bctr++; + } + } else { + throw new \Mpdf\MpdfException($names[1] . " : WARNING - The font does not have enough space to map all (unmapped) included glyphs into Private Use Area U+E000 - U+F8FF"); + } + } + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $this->maxUniChar = max($bctr, $this->maxUniChar); + $bctr++; + } + } + } + $this->glyphToChar = $glyphToChar; + $this->charToGlyph = $charToGlyph; + /////////////////////////////////// + // mPDF 5.7.1 OpenType Layout tables + $this->GSUBScriptLang = []; + $this->rtlPUAstr = ''; + $this->rtlPUAarr = []; + if ($useOTL) { + $this->_getGDEFtables(); + list($this->GSUBScriptLang, $this->GSUBFeatures, $this->GSUBLookups, $this->rtlPUAstr, $this->rtlPUAarr) = $this->_getGSUBtables(); + list($this->GPOSScriptLang, $this->GPOSFeatures, $this->GPOSLookups) = $this->_getGPOStables(); + $this->glyphIDtoUni = str_pad('', 256 * 256 * 3, "\x00"); + foreach ($glyphToChar as $gid => $arr) { + if (isset($glyphToChar[$gid][0])) { + $char = $glyphToChar[$gid][0]; + if ($char != 0 && $char != 65535) { + $this->glyphIDtoUni[$gid * 3] = chr($char >> 16); + $this->glyphIDtoUni[$gid * 3 + 1] = chr(($char >> 8) & 0xFF); + $this->glyphIDtoUni[$gid * 3 + 2] = chr($char & 0xFF); + } + } + } + } + /////////////////////////////////// + /////////////////////////////////// + // hmtx - Horizontal metrics table + /////////////////////////////////// + $this->getHMTX($numberOfHMetrics, $numGlyphs, $glyphToChar, $scale); + + /////////////////////////////////// + // kern - Kerning pair table + /////////////////////////////////// + if ($kerninfo) { + // Recognises old form of Kerning table - as required by Windows - Format 0 only + $kern_offset = $this->seek_table("kern"); + $version = $this->read_ushort(); + $nTables = $this->read_ushort(); + // subtable header + $sversion = $this->read_ushort(); + $slength = $this->read_ushort(); + $scoverage = $this->read_ushort(); + $format = $scoverage >> 8; + if ($kern_offset && $version == 0 && $format == 0) { + // Format 0 + $nPairs = $this->read_ushort(); + $this->skip(6); + for ($i = 0; $i < $nPairs; $i++) { + $left = $this->read_ushort(); + $right = $this->read_ushort(); + $val = $this->read_short(); + if (count($glyphToChar[$left]) == 1 && count($glyphToChar[$right]) == 1) { + if ($left != 32 && $right != 32) { + $this->kerninfo[$glyphToChar[$left][0]][$glyphToChar[$right][0]] = intval($val * $scale); + } + } + } + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////// + function _getGDEFtables() + { + /////////////////////////////////// + // GDEF - Glyph Definition + /////////////////////////////////// + // http://www.microsoft.com/typography/otspec/gdef.htm + if (isset($this->tables["GDEF"])) { + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h1>GDEF table</h1>'); + } + $gdef_offset = $this->seek_table("GDEF"); + // ULONG Version of the GDEF table-currently 0x00010000 + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + // Version 0x00010002 of GDEF header contains additional Offset to a list defining mark glyph set definitions (MarkGlyphSetDef) + $GlyphClassDef_offset = $this->read_ushort(); + $AttachList_offset = $this->read_ushort(); + $LigCaretList_offset = $this->read_ushort(); + $MarkAttachClassDef_offset = $this->read_ushort(); + if ($ver_min == 2) { + $MarkGlyphSetsDef_offset = $this->read_ushort(); + } + + // GlyphClassDef + $this->seek($gdef_offset + $GlyphClassDef_offset); + /* + 1 Base glyph (single character, spacing glyph) + 2 Ligature glyph (multiple character, spacing glyph) + 3 Mark glyph (non-spacing combining glyph) + 4 Component glyph (part of single character, spacing glyph) + */ + $GlyphByClass = $this->_getClassDefinitionTable(); + + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h2>Glyph classes</h2>'); + } + + if (isset($GlyphByClass[1]) && count($GlyphByClass[1]) > 0) { + $this->GlyphClassBases = $this->formatClassArr($GlyphByClass[1]); + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Glyph class 1</h3>'); + $this->mpdf->WriteHTML('<h5>Base glyph (single character, spacing glyph)</h5>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($GlyphByClass[1] as $g) { + $html .= '&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } else { + $this->GlyphClassBases = ''; + } + if (isset($GlyphByClass[2]) && count($GlyphByClass[2]) > 0) { + $this->GlyphClassLigatures = $this->formatClassArr($GlyphByClass[2]); + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Glyph class 2</h3>'); + $this->mpdf->WriteHTML('<h5>Ligature glyph (multiple character, spacing glyph)</h5>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($GlyphByClass[2] as $g) { + $html .= '&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } else { + $this->GlyphClassLigatures = ''; + } + if (isset($GlyphByClass[3]) && count($GlyphByClass[3]) > 0) { + $this->GlyphClassMarks = $this->formatClassArr($GlyphByClass[3]); + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Glyph class 3</h3>'); + $this->mpdf->WriteHTML('<h5>Mark glyph (non-spacing combining glyph)</h5>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($GlyphByClass[3] as $g) { + $html .= '◌&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } else { + $this->GlyphClassMarks = ''; + } + if (isset($GlyphByClass[4]) && count($GlyphByClass[4]) > 0) { + $this->GlyphClassComponents = $this->formatClassArr($GlyphByClass[4]); + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Glyph class 4</h3>'); + $this->mpdf->WriteHTML('<h5>Component glyph (part of single character, spacing glyph)</h5>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($GlyphByClass[4] as $g) { + $html .= '&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } else { + $this->GlyphClassComponents = ''; + } + + $Marks = $GlyphByClass[3]; // to use for MarkAttachmentType + + /* Required for GPOS + // Attachment List + if ($AttachList_offset) { + $this->seek($gdef_offset+$AttachList_offset ); + } + The Attachment Point List table (AttachmentList) identifies all the attachment points defined in the GPOS table and their associated glyphs so a client can quickly access coordinates for each glyph's attachment points. As a result, the client can cache coordinates for attachment points along with glyph bitmaps and avoid recalculating the attachment points each time it displays a glyph. Without this table, processing speed would be slower because the client would have to decode the GPOS lookups that define attachment points and compile the points in a list. + + The Attachment List table (AttachList) may be used to cache attachment point coordinates along with glyph bitmaps. + + The table consists of an offset to a Coverage table (Coverage) listing all glyphs that define attachment points in the GPOS table, a count of the glyphs with attachment points (GlyphCount), and an array of offsets to AttachPoint tables (AttachPoint). The array lists the AttachPoint tables, one for each glyph in the Coverage table, in the same order as the Coverage Index. + AttachList table + Type Name Description + Offset Coverage Offset to Coverage table - from beginning of AttachList table + uint16 GlyphCount Number of glyphs with attachment points + Offset AttachPoint[GlyphCount] Array of offsets to AttachPoint tables-from beginning of AttachList table-in Coverage Index order + + An AttachPoint table consists of a count of the attachment points on a single glyph (PointCount) and an array of contour indices of those points (PointIndex), listed in increasing numerical order. + + AttachPoint table + Type Name Description + uint16 PointCount Number of attachment points on this glyph + uint16 PointIndex[PointCount] Array of contour point indices -in increasing numerical order + + See Example 3 - http://www.microsoft.com/typography/otspec/gdef.htm + */ + + // Ligature Caret List + // The Ligature Caret List table (LigCaretList) defines caret positions for all the ligatures in a font. + // Not required for mDPF + // MarkAttachmentType + if ($MarkAttachClassDef_offset) { + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h1>Mark Attachment Types</h1>'); + } + $this->seek($gdef_offset + $MarkAttachClassDef_offset); + $MarkAttachmentTypes = $this->_getClassDefinitionTable(); + foreach ($MarkAttachmentTypes as $class => $glyphs) { + if (is_array($Marks) && count($Marks)) { + $mat = array_diff($Marks, $MarkAttachmentTypes[$class]); + sort($mat, SORT_STRING); + } else { + $mat = []; + } + + $this->MarkAttachmentType[$class] = $this->formatClassArr($mat); + + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Mark Attachment Type: ' . $class . '</h3>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($glyphs as $g) { + $html .= '◌&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } + } else { + $this->MarkAttachmentType = []; + } + + // MarkGlyphSets only in Version 0x00010002 of GDEF + if ($ver_min == 2 && $MarkGlyphSetsDef_offset) { + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h1>Mark Glyph Sets</h1>'); + } + $this->seek($gdef_offset + $MarkGlyphSetsDef_offset); + $MarkSetTableFormat = $this->read_ushort(); + $MarkSetCount = $this->read_ushort(); + $MarkSetOffset = []; + for ($i = 0; $i < $MarkSetCount; $i++) { + $MarkSetOffset[] = $this->read_ulong(); + } + for ($i = 0; $i < $MarkSetCount; $i++) { + $this->seek($MarkSetOffset[$i]); + $glyphs = $this->_getCoverage(); + $this->MarkGlyphSets[$i] = $this->formatClassArr($glyphs); + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>Mark Glyph Set class: ' . $i . '</h3>'); + $html = ''; + $html .= '<div class="glyphs">'; + foreach ($glyphs as $g) { + $html .= '◌&#x' . $g . '; '; + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + } + } + } else { + $this->MarkGlyphSets = []; + } + } else { + $this->mpdf->WriteHTML('<div>GDEF table not defined</div>'); + } + +//echo $this->GlyphClassMarks ; exit; +//print_r($GlyphClass); exit; +//print_r($GlyphByClass); exit; + } + + function _getClassDefinitionTable($offset = 0) + { + + if ($offset > 0) { + $this->seek($offset); + } + + // NB Any glyph not included in the range of covered GlyphIDs automatically belongs to Class 0. This is not returned by this function + $ClassFormat = $this->read_ushort(); + $GlyphByClass = []; + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $gid = $StartGlyph + $i; + $class = $this->read_ushort(); + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$gid][0]); + } + } else { + if ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $startGlyphID = $this->read_ushort(); + $endGlyphID = $this->read_ushort(); + $class = $this->read_ushort(); + for ($gid = $startGlyphID; $gid <= $endGlyphID; $gid++) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$gid][0]); + } + } + } + } + ksort($GlyphByClass); + + return $GlyphByClass; + } + + function _getGSUBtables() + { + /////////////////////////////////// + // GSUB - Glyph Substitution + /////////////////////////////////// + if (isset($this->tables["GSUB"])) { + $this->mpdf->WriteHTML('<h1>GSUB Tables</h1>'); + $ffeats = []; + $gsub_offset = $this->seek_table("GSUB"); + $this->skip(4); + $ScriptList_offset = $gsub_offset + $this->read_ushort(); + $FeatureList_offset = $gsub_offset + $this->read_ushort(); + $LookupList_offset = $gsub_offset + $this->read_ushort(); + + // ScriptList + $this->seek($ScriptList_offset); + $ScriptCount = $this->read_ushort(); + for ($i = 0; $i < $ScriptCount; $i++) { + $ScriptTag = $this->read_tag(); // = "beng", "deva" etc. + $ScriptTableOffset = $this->read_ushort(); + $ffeats[$ScriptTag] = $ScriptList_offset + $ScriptTableOffset; + } + + // Script Table + foreach ($ffeats as $t => $o) { + $ls = []; + $this->seek($o); + $DefLangSys_offset = $this->read_ushort(); + if ($DefLangSys_offset > 0) { + $ls['DFLT'] = $DefLangSys_offset + $o; + } + $LangSysCount = $this->read_ushort(); + for ($i = 0; $i < $LangSysCount; $i++) { + $LangTag = $this->read_tag(); // = + $LangTableOffset = $this->read_ushort(); + $ls[$LangTag] = $o + $LangTableOffset; + } + $ffeats[$t] = $ls; + } +//print_r($ffeats); exit; + // Get FeatureIndexList + // LangSys Table - from first listed langsys + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = []; + $langsystable_offset = $o; + $this->seek($langsystable_offset); + $LookUpOrder = $this->read_ushort(); //==NULL + $ReqFeatureIndex = $this->read_ushort(); + if ($ReqFeatureIndex != 0xFFFF) { + $FeatureIndex[] = $ReqFeatureIndex; + } + $FeatureCount = $this->read_ushort(); + for ($i = 0; $i < $FeatureCount; $i++) { + $FeatureIndex[] = $this->read_ushort(); // = index of feature + } + $ffeats[$st][$t] = $FeatureIndex; + } + } +//print_r($ffeats); exit; + // Feauture List => LookupListIndex es + $this->seek($FeatureList_offset); + $FeatureCount = $this->read_ushort(); + $Feature = []; + for ($i = 0; $i < $FeatureCount; $i++) { + $Feature[$i] = ['tag' => $this->read_tag()]; + $Feature[$i]['offset'] = $FeatureList_offset + $this->read_ushort(); + } + for ($i = 0; $i < $FeatureCount; $i++) { + $this->seek($Feature[$i]['offset']); + $this->read_ushort(); // null + $Feature[$i]['LookupCount'] = $Lookupcount = $this->read_ushort(); + $Feature[$i]['LookupListIndex'] = []; + for ($c = 0; $c < $Lookupcount; $c++) { + $Feature[$i]['LookupListIndex'][] = $this->read_ushort(); + } + } + + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = $ffeats[$st][$t]; + foreach ($FeatureIndex as $k => $fi) { + $ffeats[$st][$t][$k] = $Feature[$fi]; + } + } + } + //===================================================================================== + $gsub = []; + $GSUBScriptLang = []; + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $langsys) { + $lg = []; + foreach ($langsys as $ft) { + $lg[$ft['LookupListIndex'][0]] = $ft; + } + // list of Lookups in order they need to be run i.e. order listed in Lookup table + ksort($lg); + foreach ($lg as $ft) { + $gsub[$st][$t][$ft['tag']] = $ft['LookupListIndex']; + } + if (!isset($GSUBScriptLang[$st])) { + $GSUBScriptLang[$st] = ''; + } + $GSUBScriptLang[$st] .= $t . ' '; + } + } + +//print_r($gsub); exit; + + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>GSUB Scripts & Languages</h3>'); + $this->mpdf->WriteHTML('<div class="glyphs">'); + $html = ''; + if (count($gsub)) { + foreach ($gsub as $st => $g) { + $html .= '<h5>' . $st . '</h5>'; + foreach ($g as $l => $t) { + $html .= '<div><a href="font_dump_OTL.php?script=' . $st . '&lang=' . $l . '">' . $l . '</a></b>: '; + foreach ($t as $tag => $o) { + $html .= $tag . ' '; + } + $html .= '</div>'; + } + } + } else { + $html .= '<div>No entries in GSUB table.</div>'; + } + $this->mpdf->WriteHTML($html); + $this->mpdf->WriteHTML('</div>'); + + return 0; + } + + //===================================================================================== + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $GSLookup = []; + $Offsets = []; + $SubtableCount = []; + for ($i = 0; $i < $LookupCount; $i++) { + $Offsets[$i] = $LookupList_offset + $this->read_ushort(); + } + for ($i = 0; $i < $LookupCount; $i++) { + $this->seek($Offsets[$i]); + $GSLookup[$i]['Type'] = $this->read_ushort(); + $GSLookup[$i]['Flag'] = $flag = $this->read_ushort(); + $GSLookup[$i]['SubtableCount'] = $SubtableCount[$i] = $this->read_ushort(); + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $GSLookup[$i]['Subtables'][$c] = $Offsets[$i] + $this->read_ushort(); + } + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) == 0x0010) { + $GSLookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } + // else { $GSLookup[$i]['MarkFilteringSet'] = ''; } + // Lookup Type 7: Extension + if ($GSLookup[$i]['Type'] == 7) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $this->seek($GSLookup[$i]['Subtables'][$c]); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $GSLookup[$i]['Subtables'][$c] = $GSLookup[$i]['Subtables'][$c] + $this->read_ulong(); + } + $GSLookup[$i]['Type'] = $type; + } + } + +//print_r($GSLookup); exit; + //===================================================================================== + // Process Whole LookupList - Get LuCoverage = Lookup coverage just for first glyph + $this->GSLuCoverage = []; + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $GSLookup[$i]['SubtableCount']; $c++) { + $this->seek($GSLookup[$i]['Subtables'][$c]); + $PosFormat = $this->read_ushort(); + + if ($GSLookup[$i]['Type'] == 5 && $PosFormat == 3) { + $this->skip(4); + } else { + if ($GSLookup[$i]['Type'] == 6 && $PosFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + $this->skip(2 * $BacktrackGlyphCount + 2); + } + } + // NB Coverage only looks at glyphs for position 1 (i.e. 5.3 and 6.3) // NEEDS TO READ ALL ******************** + $Coverage = $GSLookup[$i]['Subtables'][$c] + $this->read_ushort(); + $this->seek($Coverage); + $glyphs = $this->_getCoverage(); + $this->GSLuCoverage[$i][$c] = implode('|', $glyphs); + } + } + +// $this->GSLuCoverage and $GSLookup + //===================================================================================== + $s = '<?php +$GSLuCoverage = ' . var_export($this->GSLuCoverage, true) . '; +?>'; + + //===================================================================================== + $s = '<?php +$GlyphClassBases = \'' . $this->GlyphClassBases . '\'; +$GlyphClassMarks = \'' . $this->GlyphClassMarks . '\'; +$GlyphClassLigatures = \'' . $this->GlyphClassLigatures . '\'; +$GlyphClassComponents = \'' . $this->GlyphClassComponents . '\'; +$MarkGlyphSets = ' . var_export($this->MarkGlyphSets, true) . '; +$MarkAttachmentType = ' . var_export($this->MarkAttachmentType, true) . '; +?>'; + + //===================================================================================== + //===================================================================================== + //===================================================================================== +// Now repeats as original to get Substitution rules + //===================================================================================== + //===================================================================================== + //===================================================================================== + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $Lookup = []; + for ($i = 0; $i < $LookupCount; $i++) { + $Lookup[$i]['offset'] = $LookupList_offset + $this->read_ushort(); + } + for ($i = 0; $i < $LookupCount; $i++) { + $this->seek($Lookup[$i]['offset']); + $Lookup[$i]['Type'] = $this->read_ushort(); + $Lookup[$i]['Flag'] = $flag = $this->read_ushort(); + $Lookup[$i]['SubtableCount'] = $this->read_ushort(); + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $Lookup[$i]['Subtable'][$c]['Offset'] = $Lookup[$i]['offset'] + $this->read_ushort(); + } + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) == 0x0010) { + $Lookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } else { + $Lookup[$i]['MarkFilteringSet'] = ''; + } + + // Lookup Type 7: Extension + if ($Lookup[$i]['Type'] == 7) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $this->seek($Lookup[$i]['Subtable'][$c]['Offset']); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ulong(); + } + $Lookup[$i]['Type'] = $type; + } + } + +//print_r($Lookup); exit; + //===================================================================================== + // Process (1) Whole LookupList + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $this->seek($Lookup[$i]['Subtable'][$c]['Offset']); + $SubstFormat = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['Format'] = $SubstFormat; + + /* + Lookup['Type'] Enumeration table for glyph substitution + Value Type Description + 1 Single Replace one glyph with one glyph + 2 Multiple Replace one glyph with more than one glyph + 3 Alternate Replace one glyph with one of many glyphs + 4 Ligature Replace multiple glyphs with one glyph + 5 Context Replace one or more glyphs in context + 6 Chaining Context Replace one or more glyphs in chained context + 7 Extension Substitution Extension mechanism for other substitutions (i.e. this excludes the Extension type substitution itself) + 8 Reverse chaining context single Applied in reverse order, replace single glyph in chaining context + */ + + // LookupType 1: Single Substitution Subtable + if ($Lookup[$i]['Type'] == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + if ($SubstFormat == 1) { // Calculated output glyph indices + $Lookup[$i]['Subtable'][$c]['DeltaGlyphID'] = $this->read_short(); + } else { + if ($SubstFormat == 2) { // Specified output glyph indices + $GlyphCount = $this->read_ushort(); + for ($g = 0; $g < $GlyphCount; $g++) { + $Lookup[$i]['Subtable'][$c]['Glyphs'][] = $this->read_ushort(); + } + } + } + } // LookupType 2: Multiple Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SequenceCount'] = $SequenceCount = $this->read_short(); + for ($s = 0; $s < $SequenceCount; $s++) { + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $SequenceCount; $s++) { + // Sequence Tables + $this->seek($Lookup[$i]['Subtable'][$c]['Sequences'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['GlyphCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['GlyphCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['SubstituteGlyphID'][] = $this->read_ushort(); + } + } + } // LookupType 3: Alternate Forms + else { + if ($Lookup[$i]['Type'] == 3) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['AlternateSetCount'] = $AlternateSetCount = $this->read_short(); + for ($s = 0; $s < $AlternateSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + + for ($s = 0; $s < $AlternateSetCount; $s++) { + // AlternateSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['GlyphCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['GlyphCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['SubstituteGlyphID'][] = $this->read_ushort(); + } + } + } // LookupType 4: Ligature Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 4) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LigSetCount'] = $LigSetCount = $this->read_short(); + for ($s = 0; $s < $LigSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $LigSetCount; $s++) { + // LigatureSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigatureOffset'][$g] = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset'] + $this->read_ushort(); + } + } + for ($s = 0; $s < $LigSetCount; $s++) { + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + // Ligature tables + $this->seek($Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigatureOffset'][$g]); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['LigGlyph'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount'] = $this->read_ushort(); + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['GlyphID'][$l] = $this->read_ushort(); + } + } + } + } // LookupType 5: Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 5) { + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSetCount'] = $SubRuleSetCount = $this->read_short(); + for ($s = 0; $s < $SubRuleSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $SubRuleSetCount; $s++) { + // SubRuleSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleOffset'][$g] = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset'] + $this->read_ushort(); + } + } + for ($s = 0; $s < $SubRuleSetCount; $s++) { + // SubRule Tables + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $g++) { + // Ligature tables + $this->seek($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleOffset'][$g]); + + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['GlyphCount'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstCount'] = $this->read_ushort(); + // "Input"::[GlyphCount - 1]::Array of input GlyphIDs-start with second glyph + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['GlyphCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['Input'][$l] = $this->read_ushort(); + } + // "SubstLookupRecord"::[SubstCount]::Array of SubstLookupRecords-in design order + for ($l = 0; $l < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstLookupRecord'][$l]['SequenceIndex'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstLookupRecord'][$l]['LookupListIndex'] = $this->read_ushort(); + } + } + } + } // Format 2: Class-based Context Glyph Substitution + else { + if ($SubstFormat == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubClassSetCnt'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][] = 0; + } else { + $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $offset; + } + } + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Lookup[$i]['Type'] . ", Format " . $SubstFormat . " not supported (ttfontsuni.php)."); + } + } + } // LookupType 6: Chaining Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 6) { + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + else { + if ($SubstFormat == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['BacktrackClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['InputClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LookaheadClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][] = $offset; + } else { + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $offset; + } + } + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + else { + if ($SubstFormat == 3) { + $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageBacktrack'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['InputGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageInput'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageLookahead'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['SubstCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex'] = $this->read_ushort(); + /* + Substitution Lookup Record + All contextual substitution subtables specify the substitution data in a Substitution Lookup Record (SubstLookupRecord). Each record contains a SequenceIndex, which indicates the position where the substitution will occur in the glyph sequence. In addition, a LookupListIndex identifies the lookup to be applied at the glyph position specified by the SequenceIndex. + */ + } + } + } + } + } else { + throw new \Mpdf\MpdfException("Lookup Type " . $Lookup[$i]['Type'] . " not supported."); + } + } + } + } + } + } + } + } +//print_r($Lookup); exit; + //===================================================================================== + // Process (2) Whole LookupList + // Get Coverage tables and prepare preg_replace + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $SubstFormat = $Lookup[$i]['Subtable'][$c]['Format']; + + // LookupType 1: Single Substitution Subtable 1 => 1 + if ($Lookup[$i]['Type'] == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(false); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = unicode_hex($this->glyphToChar[$glyphs[$g]][0]); + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + if (isset($Lookup[$i]['Subtable'][$c]['DeltaGlyphID'])) { // Format 1 + $substitute[] = unicode_hex($this->glyphToChar[($glyphs[$g] + $Lookup[$i]['Subtable'][$c]['DeltaGlyphID'])][0]); + } else { // Format 2 + $substitute[] = unicode_hex($this->glyphToChar[($Lookup[$i]['Subtable'][$c]['Glyphs'][$g])][0]); + } + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + } // LookupType 2: Multiple Substitution Subtable 1 => n + else { + if ($Lookup[$i]['Type'] == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$g]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + if (!isset($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID']) || count($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID']) == 0) { + continue; + } // Illegal for GlyphCount to be 0; either error in font, or something has gone wrong - lets carry on for now! + foreach ($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID'] as $sub) { + $substitute[] = unicode_hex($this->glyphToChar[$sub][0]); + } + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + } // LookupType 3: Alternate Forms 1 => 1 (only first alternate form is used) + else { + if ($Lookup[$i]['Type'] == 3) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$g]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + + for ($gl = 0; $gl < $Lookup[$i]['Subtable'][$c]['AlternateSets'][$g]['GlyphCount']; $gl++) { + $gid = $Lookup[$i]['Subtable'][$c]['AlternateSets'][$g]['SubstituteGlyphID'][$gl]; + $substitute[] = unicode_hex($this->glyphToChar[$gid][0]); + } + + //$gid = $Lookup[$i]['Subtable'][$c]['AlternateSets'][$g]['SubstituteGlyphID'][0]; + //$substitute[] = unicode_hex($this->glyphToChar[$gid][0]); + + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + if ($i == 166) { + print_r($Lookup[$i]['Subtable']); + exit; + } + } // LookupType 4: Ligature Substitution Subtable n => 1 + else { + if ($Lookup[$i]['Type'] == 4) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + $LigSetCount = $Lookup[$i]['Subtable'][$c]['LigSetCount']; + for ($s = 0; $s < $LigSetCount; $s++) { + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$s]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']; $l++) { + $gid = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['GlyphID'][$l]; + $rpl = unicode_hex($this->glyphToChar[$gid][0]); + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $rpl, $Lookup[$i]['MarkFilteringSet'])) { + continue 2; + } + $replace[] = $rpl; + } + $gid = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['LigGlyph']; + $substitute[] = unicode_hex($this->glyphToChar[$gid][0]); + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute, 'CompCount' => $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']]; + } + } + } // LookupType 5: Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 5) { + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubRuleSetCount']; $s++) { + $SubRuleSet = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]; + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['FirstGlyph'] = $CoverageGlyphs[$s]; + for ($r = 0; $r < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $r++) { + $GlyphCount = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['GlyphCount']; + for ($g = 1; $g < $GlyphCount; $g++) { + $glyphID = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['Input'][$g]; + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['InputGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + } + } + } // Format 2: Class-based Context Glyph Substitution + else { + if ($SubstFormat == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $InputClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['ClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['InputClasses'] = $InputClasses; + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $s++) { + if ($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s]); + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRuleCnt'] = $SubClassRuleCnt = $this->read_ushort(); + $SubClassRule = []; + for ($b = 0; $b < $SubClassRuleCnt; $b++) { + $SubClassRule[$b] = $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b] = $SubClassRule[$b]; + } + } + } + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $s++) { + $SubClassRuleCnt = $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRuleCnt']; + for ($b = 0; $b < $SubClassRuleCnt; $b++) { + if ($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b]); + $Rule = []; + $Rule['InputGlyphCount'] = $this->read_ushort(); + $Rule['SubstCount'] = $this->read_ushort(); + for ($r = 1; $r < $Rule['InputGlyphCount']; $r++) { + $Rule['Input'][$r] = $this->read_ushort(); + } + for ($r = 0; $r < $Rule['SubstCount']; $r++) { + $Rule['SequenceIndex'][$r] = $this->read_ushort(); + $Rule['LookupListIndex'][$r] = $this->read_ushort(); + } + + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b] = $Rule; + } + } + } + } // Format 3: Coverage-based Context Glyph Substitution + else { + if ($SubstFormat == 3) { + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageInput'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs'][] = implode("|", $glyphs); + } + throw new \Mpdf\MpdfException("Lookup Type 5, SubstFormat 3 not tested. Please report this with the name of font used - " . $this->fontkey); + } + } + } + } // LookupType 6: Chaining Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 6) { + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $ChainSubRuleSetCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; + + for ($s = 0; $s < $ChainSubRuleSetCnt; $s++) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][$s]); + $ChainSubRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleCount'] = $this->read_ushort(); + for ($r = 0; $r < $ChainSubRuleCnt; $r++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleOffset'][$r] = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][$s] + $this->read_ushort(); + } + } + for ($s = 0; $s < $ChainSubRuleSetCnt; $s++) { + $ChainSubRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleCount']; + for ($r = 0; $r < $ChainSubRuleCnt; $r++) { + // ChainSubRule + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleOffset'][$r]); + + $BacktrackGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['BacktrackGlyphCount'] = $this->read_ushort(); + for ($g = 0; $g < $BacktrackGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['BacktrackGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $InputGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['InputGlyphCount'] = $this->read_ushort(); + for ($g = 1; $g < $InputGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['InputGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $LookaheadGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookaheadGlyphCount'] = $this->read_ushort(); + for ($g = 0; $g < $LookaheadGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookaheadGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $SubstCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['SubstCount'] = $this->read_ushort(); + for ($lu = 0; $lu < $SubstCount; $lu++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['SequenceIndex'][$lu] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookupListIndex'][$lu] = $this->read_ushort(); + } + } + } + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + else { + if ($SubstFormat == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $BacktrackClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['BacktrackClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['BacktrackClasses'] = $BacktrackClasses; + + $InputClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['InputClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['InputClasses'] = $InputClasses; + + $LookaheadClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['LookaheadClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['LookaheadClasses'] = $LookaheadClasses; + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $s++) { + if ($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s]); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRuleCnt'] = $ChainSubClassRuleCnt = $this->read_ushort(); + $ChainSubClassRule = []; + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { + $ChainSubClassRule[$b] = $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b] = $ChainSubClassRule[$b]; + } + } + } + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $s++) { + $ChainSubClassRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRuleCnt']; + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { + if ($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b]); + $Rule = []; + $Rule['BacktrackGlyphCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['BacktrackGlyphCount']; $r++) { + $Rule['Backtrack'][$r] = $this->read_ushort(); + } + $Rule['InputGlyphCount'] = $this->read_ushort(); + for ($r = 1; $r < $Rule['InputGlyphCount']; $r++) { + $Rule['Input'][$r] = $this->read_ushort(); + } + $Rule['LookaheadGlyphCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['LookaheadGlyphCount']; $r++) { + $Rule['Lookahead'][$r] = $this->read_ushort(); + } + $Rule['SubstCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['SubstCount']; $r++) { + $Rule['SequenceIndex'][$r] = $this->read_ushort(); + $Rule['LookupListIndex'][$r] = $this->read_ushort(); + } + + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b] = $Rule; + } + } + } + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + else { + if ($SubstFormat == 3) { + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageBacktrack'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageBacktrackGlyphs'][] = implode("|", $glyphs); + } + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageInput'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs'][] = implode("|", $glyphs); + // Don't use above value as these are ordered numerically not as need to process + } + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageLookahead'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageLookaheadGlyphs'][] = implode("|", $glyphs); + } + } + } + } + } + } + } + } + } + } + } + } + + //===================================================================================== + //===================================================================================== + //===================================================================================== + + $st = $this->mpdf->OTLscript; + $t = $this->mpdf->OTLlang; + $langsys = $gsub[$st][$t]; + + $lul = []; // array of LookupListIndexes + $tags = []; // corresponding array of feature tags e.g. 'ccmp' + foreach ($langsys as $tag => $ft) { + foreach ($ft as $ll) { + $lul[$ll] = $tag; + } + } + ksort($lul); // Order the Lookups in the order they are in the GUSB table, regardless of Feature order + $this->_getGSUBarray($Lookup, $lul, $st); +//print_r($lul); exit; + } + +//print_r($Lookup); exit; + + return [$GSUBScriptLang, $gsub, $GSLookup, $rtlPUAstr, $rtlPUAarr]; + } + +///////////////////////////////////////////////////////////////////////////////////////// + // GSUB functions + function _getGSUBarray(&$Lookup, &$lul, $scripttag, $level = 1, $coverage = '', $exB = '', $exL = '') + { + // Process (3) LookupList for specific Script-LangSys + // Generate preg_replace + $html = ''; + if ($level == 1) { + $html .= '<bookmark level="0" content="GSUB features">'; + } + foreach ($lul as $i => $tag) { + $html .= '<div class="level' . $level . '">'; + $html .= '<h5 class="level' . $level . '">'; + if ($level == 1) { + $html .= '<bookmark level="1" content="' . $tag . ' [#' . $i . ']">'; + } + $html .= 'Lookup #' . $i . ' [tag: <span style="color:#000066;">' . $tag . '</span>]</h5>'; + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + if ($ignore) { + $html .= '<div class="ignore">Ignoring: ' . $ignore . '</div> '; + } + + $Type = $Lookup[$i]['Type']; + $Flag = $Lookup[$i]['Flag']; + if (($Flag & 0x0001) == 1) { + $dir = 'RTL'; + } else { + $dir = 'LTR'; + } + + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $html .= '<div class="subtable">Subtable #' . $c; + if ($level == 1) { + $html .= '<bookmark level="2" content="Subtable #' . $c . '">'; + } + $html .= '</div>'; + + $SubstFormat = $Lookup[$i]['Subtable'][$c]['Format']; + + // LookupType 1: Single Substitution Subtable + if ($Lookup[$i]['Type'] == 1) { + $html .= '<div class="lookuptype">LookupType 1: Single Substitution Subtable</div>'; + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + if ($level == 2 && strpos($coverage, $inputGlyphs[0]) === false) { + continue; + } + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($inputGlyphs[0]) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($inputGlyphs[0]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed"> ' . $this->formatEntity($substitute) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  <span class="unicode">' . $this->formatUni($substitute) . '</span> '; + $html .= '</div>'; + } + } // LookupType 2: Multiple Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 2) { + $html .= '<div class="lookuptype">LookupType 2: Multiple Substitution Subtable</div>'; + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute']; + if ($level == 2 && strpos($coverage, $inputGlyphs[0]) === false) { + continue; + } + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($inputGlyphs[0]) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($inputGlyphs[0]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed"> ' . $this->formatEntityArr($substitute) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  <span class="unicode">' . $this->formatUniArr($substitute) . '</span> '; + $html .= '</div>'; + } + } // LookupType 3: Alternate Forms + else { + if ($Lookup[$i]['Type'] == 3) { + $html .= '<div class="lookuptype">LookupType 3: Alternate Forms</div>'; + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + if ($level == 2 && strpos($coverage, $inputGlyphs[0]) === false) { + continue; + } + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($inputGlyphs[0]) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($inputGlyphs[0]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed"> ' . $this->formatEntity($substitute) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  <span class="unicode">' . $this->formatUni($substitute) . '</span> '; + if (count($Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute']) > 1) { + for ($alt = 1; $alt < count($Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute']); $alt++) { + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][$alt]; + $html .= '  |   ALT #' . $alt . '   '; + $html .= '<span class="changed"> ' . $this->formatEntity($substitute) . '</span>'; + $html .= '  <span class="unicode">' . $this->formatUni($substitute) . '</span> '; + } + } + $html .= '</div>'; + } + } // LookupType 4: Ligature Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 4) { + $html .= '<div class="lookuptype">LookupType 4: Ligature Substitution Subtable</div>'; + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + if ($level == 2 && strpos($coverage, $inputGlyphs[0]) === false) { + continue; + } + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUniArr($inputGlyphs) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntityArr($inputGlyphs) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed"> ' . $this->formatEntity($substitute) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  <span class="unicode">' . $this->formatUni($substitute) . '</span> '; + $html .= '</div>'; + } + } // LookupType 5: Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 5) { + $html .= '<div class="lookuptype">LookupType 5: Contextual Substitution Subtable</div>'; + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $html .= '<div class="lookuptypesub">Format 1: Context Substitution</div>'; + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubRuleSetCount']; $s++) { + // SubRuleSet + $subRule = []; + $html .= '<div class="rule">Subrule Set: ' . $s . '</div>'; + foreach ($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'] as $rctr => $rule) { + // SubRule + $html .= '<div class="rule">SubRule: ' . $rctr . '</div>'; + $inputGlyphs = []; + if ($rule['GlyphCount'] > 1) { + $inputGlyphs = $rule['InputGlyphs']; + } + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['FirstGlyph']; + ksort($inputGlyphs); + $nInput = count($inputGlyphs); + + $exampleI = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + $html .= '</div>'; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $rule['SubstLookupRecord'][$b]['SequenceIndex']; + + // GENERATE exampleI[<seqIndex] .... exampleI[>seqIndex] + $exB = ''; + $exL = ''; + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + $exB .= $this->formatEntity($inputGlyphs[$ip]) . '‍'; + } + $exB .= '</span>'; + } + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + $exL .= $this->formatEntity($inputGlyphs[$ip]) . '‍'; + } + $exL .= '</span>'; + } + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } // Format 2: Class-based Context Glyph Substitution + else { + if ($SubstFormat == 2) { + $html .= '<div class="lookuptypesub">Format 2: Class-based Context Glyph Substitution</div>'; + foreach ($Lookup[$i]['Subtable'][$c]['SubClassSet'] as $inputClass => $cscs) { + $html .= '<div class="rule">Input Class: ' . $inputClass . '</div>'; + for ($cscrule = 0; $cscrule < $cscs['SubClassRuleCnt']; $cscrule++) { + $html .= '<div class="rule">Rule: ' . $cscrule . '</div>'; + $rule = $cscs['SubClassRule'][$cscrule]; + + $inputGlyphs = []; + + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$inputClass]; + + if ($rule['InputGlyphCount'] > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $rule['InputGlyphCount']; $gcl++) { + $classindex = $rule['Input'][$gcl]; + $inputGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex]; + } + } + + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = implode('|', $Lookup[$i]['Subtable'][$c]['InputClasses']); + + $exampleI = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + if (!$inputGlyphs[$ff]) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> [NOT ' . $this->formatEntityStr($class0excl) . '] </span></div>'; + $exampleI[] = '[NOT ' . $this->formatEntityFirst($class0excl) . ']'; + } else { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + } + $html .= '</div>'; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // GENERATE exampleI[<seqIndex] .... exampleI[>seqIndex] + $exB = ''; + $exL = ''; + + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + if (!$inputGlyphs[$ip]) { + $exB .= '[*]'; + } else { + $exB .= $this->formatEntityFirst($inputGlyphs[$ip]) . '‍'; + } + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + if (!$inputGlyphs[$ip]) { + $exL .= '[*]'; + } else { + $exL .= $this->formatEntityFirst($inputGlyphs[$ip]) . '‍'; + } + } + $exL .= '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } // Format 3: Coverage-based Context Glyph Substitution p259 + else { + if ($SubstFormat == 3) { + $html .= '<div class="lookuptypesub">Format 3: Coverage-based Context Glyph Substitution </div>'; + // IgnoreMarks flag set on main Lookup table + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs']; + $CoverageInputGlyphs = implode('|', $inputGlyphs); + $nInput = $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; + + $exampleI = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + $html .= '</div>'; + + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $lup = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex']; + // GENERATE exampleI[<seqIndex] .... exampleI[>seqIndex] + $exB = ''; + $exL = ''; + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + $exB .= $exampleI[$ip] . '‍'; + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + $exL .= $exampleI[$ip] . '‍'; + } + $exL .= '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } + +//print_r($Lookup[$i]); +//print_r($volt[(count($volt)-1)]); exit; + } // LookupType 6: Chaining Contextual Substitution Subtable + else { + if ($Lookup[$i]['Type'] == 6) { + $html .= '<div class="lookuptype">LookupType 6: Chaining Contextual Substitution Subtable</div>'; + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $html .= '<div class="lookuptypesub">Format 1: Simple Chaining Context Glyph Substitution </div>'; + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; $s++) { + // ChainSubRuleSet + $subRule = []; + $html .= '<div class="rule">Subrule Set: ' . $s . '</div>'; + $firstInputGlyph = $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'][$s]; // First input gyyph + foreach ($Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'] as $rctr => $rule) { + $html .= '<div class="rule">SubRule: ' . $rctr . '</div>'; + // ChainSubRule + $inputGlyphs = []; + if ($rule['InputGlyphCount'] > 1) { + $inputGlyphs = $rule['InputGlyphs']; + } + $inputGlyphs[0] = $firstInputGlyph; + ksort($inputGlyphs); + $nInput = count($inputGlyphs); + + if ($rule['BacktrackGlyphCount']) { + $backtrackGlyphs = $rule['BacktrackGlyphs']; + } else { + $backtrackGlyphs = []; + } + + if ($rule['LookaheadGlyphCount']) { + $lookaheadGlyphs = $rule['LookaheadGlyphs']; + } else { + $lookaheadGlyphs = []; + } + + $exampleB = []; + $exampleI = []; + $exampleL = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = count($backtrackGlyphs) - 1; $ff >= 0; $ff--) { + $html .= '<div>Backtrack #' . $ff . ': <span class="unicode">' . $this->formatUniStr($backtrackGlyphs[$ff]) . '</span></div>'; + $exampleB[] = $this->formatEntityFirst($backtrackGlyphs[$ff]); + } + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + for ($ff = 0; $ff < count($lookaheadGlyphs); $ff++) { + $html .= '<div>Lookahead #' . $ff . ': <span class="unicode">' . $this->formatUniStr($lookaheadGlyphs[$ff]) . '</span></div>'; + $exampleL[] = $this->formatEntityFirst($lookaheadGlyphs[$ff]); + } + $html .= '</div>'; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // GENERATE exampleB[n] exampleI[<seqIndex] .... exampleI[>seqIndex] exampleL[n] + $exB = ''; + $exL = ''; + if (count($exampleB)) { + $exB .= '<span class="backtrack">' . implode('‍', $exampleB) . '</span>'; + } + + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + $exB .= $this->formatEntity($inputGlyphs[$ip]) . '‍'; + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + $exL .= $this->formatEntity($inputGlyphs[$ip]) . '‍'; + } + $exL .= '</span>'; + } + + if (count($exampleL)) { + $exL .= '<span class="lookahead">' . implode('‍', $exampleL) . '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + else { + if ($SubstFormat == 2) { + $html .= '<div class="lookuptypesub">Format 2: Class-based Chaining Context Glyph Substitution </div>'; + foreach ($Lookup[$i]['Subtable'][$c]['ChainSubClassSet'] as $inputClass => $cscs) { + $html .= '<div class="rule">Input Class: ' . $inputClass . '</div>'; + for ($cscrule = 0; $cscrule < $cscs['ChainSubClassRuleCnt']; $cscrule++) { + $html .= '<div class="rule">Rule: ' . $cscrule . '</div>'; + $rule = $cscs['ChainSubClassRule'][$cscrule]; + + // These contain classes of glyphs as strings + // $Lookup[$i]['Subtable'][$c]['InputClasses'][(class)] e.g. 02E6|02E7|02E8 + // $Lookup[$i]['Subtable'][$c]['LookaheadClasses'][(class)] + // $Lookup[$i]['Subtable'][$c]['BacktrackClasses'][(class)] + // These contain arrays of classIndexes + // [Backtrack] [Lookahead] and [Input] (Input is from the second position only) + + $inputGlyphs = []; + + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$inputClass]; + if ($rule['InputGlyphCount'] > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $rule['InputGlyphCount']; $gcl++) { + $classindex = $rule['Input'][$gcl]; + $inputGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex]; + } + } + // Class 0 contains all the glyphs NOT in the other classes + $class0excl = implode('|', $Lookup[$i]['Subtable'][$c]['InputClasses']); + + $nInput = $rule['InputGlyphCount']; + + if ($rule['BacktrackGlyphCount']) { + for ($gcl = 0; $gcl < $rule['BacktrackGlyphCount']; $gcl++) { + $classindex = $rule['Backtrack'][$gcl]; + $backtrackGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['BacktrackClasses'][$classindex]; + } + } else { + $backtrackGlyphs = []; + } + + if ($rule['LookaheadGlyphCount']) { + for ($gcl = 0; $gcl < $rule['LookaheadGlyphCount']; $gcl++) { + $classindex = $rule['Lookahead'][$gcl]; + $lookaheadGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['LookaheadClasses'][$classindex]; + } + } else { + $lookaheadGlyphs = []; + } + + $exampleB = []; + $exampleI = []; + $exampleL = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = count($backtrackGlyphs) - 1; $ff >= 0; $ff--) { + if (!$backtrackGlyphs[$ff]) { + $html .= '<div>Backtrack #' . $ff . ': <span class="unchanged"> [NOT ' . $this->formatEntityStr($class0excl) . '] </span></div>'; + $exampleB[] = '[NOT ' . $this->formatEntityFirst($class0excl) . ']'; + } else { + $html .= '<div>Backtrack #' . $ff . ': <span class="unicode">' . $this->formatUniStr($backtrackGlyphs[$ff]) . '</span></div>'; + $exampleB[] = $this->formatEntityFirst($backtrackGlyphs[$ff]); + } + } + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + if (!$inputGlyphs[$ff]) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> [NOT ' . $this->formatEntityStr($class0excl) . '] </span></div>'; + $exampleI[] = '[NOT ' . $this->formatEntityFirst($class0excl) . ']'; + } else { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + } + for ($ff = 0; $ff < count($lookaheadGlyphs); $ff++) { + if (!$lookaheadGlyphs[$ff]) { + $html .= '<div>Lookahead #' . $ff . ': <span class="unchanged"> [NOT ' . $this->formatEntityStr($class0excl) . '] </span></div>'; + $exampleL[] = '[NOT ' . $this->formatEntityFirst($class0excl) . ']'; + } else { + $html .= '<div>Lookahead #' . $ff . ': <span class="unicode">' . $this->formatUniStr($lookaheadGlyphs[$ff]) . '</span></div>'; + $exampleL[] = $this->formatEntityFirst($lookaheadGlyphs[$ff]); + } + } + $html .= '</div>'; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // GENERATE exampleB[n] exampleI[<seqIndex] .... exampleI[>seqIndex] exampleL[n] + $exB = ''; + $exL = ''; + if (count($exampleB)) { + $exB .= '<span class="backtrack">' . implode('‍', $exampleB) . '</span>'; + } + + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + if (!$inputGlyphs[$ip]) { + $exB .= '[*]'; + } else { + $exB .= $this->formatEntityFirst($inputGlyphs[$ip]) . '‍'; + } + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + if (!$inputGlyphs[$ip]) { + $exL .= '[*]'; + } else { + $exL .= $this->formatEntityFirst($inputGlyphs[$ip]) . '‍'; + } + } + $exL .= '</span>'; + } + + if (count($exampleL)) { + $exL .= '<span class="lookahead">' . implode('‍', $exampleL) . '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + } + } + +//print_r($Lookup[$i]['Subtable'][$c]); exit; + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + else { + if ($SubstFormat == 3) { + $html .= '<div class="lookuptypesub">Format 3: Coverage-based Chaining Context Glyph Substitution </div>'; + // IgnoreMarks flag set on main Lookup table + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs']; + $CoverageInputGlyphs = implode('|', $inputGlyphs); + $nInput = $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; + + if ($Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']) { + $backtrackGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageBacktrackGlyphs']; + } else { + $backtrackGlyphs = []; + } + + if ($Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']) { + $lookaheadGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageLookaheadGlyphs']; + } else { + $lookaheadGlyphs = []; + } + + $exampleB = []; + $exampleI = []; + $exampleL = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = count($backtrackGlyphs) - 1; $ff >= 0; $ff--) { + $html .= '<div>Backtrack #' . $ff . ': <span class="unicode">' . $this->formatUniStr($backtrackGlyphs[$ff]) . '</span></div>'; + $exampleB[] = $this->formatEntityFirst($backtrackGlyphs[$ff]); + } + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + for ($ff = 0; $ff < count($lookaheadGlyphs); $ff++) { + $html .= '<div>Lookahead #' . $ff . ': <span class="unicode">' . $this->formatUniStr($lookaheadGlyphs[$ff]) . '</span></div>'; + $exampleL[] = $this->formatEntityFirst($lookaheadGlyphs[$ff]); + } + $html .= '</div>'; + + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $lup = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex']; + + // GENERATE exampleB[n] exampleI[<seqIndex] .... exampleI[>seqIndex] exampleL[n] + $exB = ''; + $exL = ''; + if (count($exampleB)) { + $exB .= '<span class="backtrack">' . implode('‍', $exampleB) . '</span>'; + } + + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + $exB .= $exampleI[$ip] . '‍'; + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + $exL .= $exampleI[$ip] . '‍'; + } + $exL .= '</span>'; + } + + if (count($exampleL)) { + $exL .= '<span class="lookahead">' . implode('‍', $exampleL) . '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGSUBarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + } + } + } + } + } + } + } + } + } + } + $html .= '</div>'; + } + if ($level == 1) { + $this->mpdf->WriteHTML($html); + } else { + return $html; + } +//print_r($Lookup); exit; + } + + //===================================================================================== + //===================================================================================== + // mPDF 5.7.1 + function _checkGSUBignore($flag, $glyph, $MarkFilteringSet) + { + $ignore = false; + // Flag & 0x0008 = Ignore Marks + if ((($flag & 0x0008) == 0x0008) && strpos($this->GlyphClassMarks, $glyph)) { + $ignore = true; + } + if ((($flag & 0x0004) == 0x0004) && strpos($this->GlyphClassLigatures, $glyph)) { + $ignore = true; + } + if ((($flag & 0x0002) == 0x0002) && strpos($this->GlyphClassBases, $glyph)) { + $ignore = true; + } + // Flag & 0xFF?? = MarkAttachmentType + if (($flag & 0xFF00) && strpos($this->MarkAttachmentType[($flag >> 8)], $glyph)) { + $ignore = true; + } + // Flag & 0x0010 = UseMarkFilteringSet + if (($flag & 0x0010) && strpos($this->MarkGlyphSets[$MarkFilteringSet], $glyph)) { + $ignore = true; + } + + return $ignore; + } + + function _getGSUBignoreString($flag, $MarkFilteringSet) + { + // If ignoreFlag set, combine all ignore glyphs into -> "((?:(?: FBA1| FBA2| FBA3))*)" + // else "()" + // for Input - set on secondary Lookup table if in Context, and set Backtrack and Lookahead on Context Lookup + $str = ""; + $ignoreflag = 0; + + // Flag & 0xFF?? = MarkAttachmentType + if ($flag & 0xFF00) { + $MarkAttachmentType = $flag >> 8; + $ignoreflag = $flag; + //$str = $this->MarkAttachmentType[$MarkAttachmentType]; + $str = "MarkAttachmentType[" . $MarkAttachmentType . "] "; + } + + // Flag & 0x0010 = UseMarkFilteringSet + if ($flag & 0x0010) { + throw new \Mpdf\MpdfException("This font " . $this->fontkey . " contains MarkGlyphSets"); + $str = "Mark Glyph Set: "; + $str .= $this->MarkGlyphSets[$MarkFilteringSet]; + } + + // If Ignore Marks set, supercedes any above + // Flag & 0x0008 = Ignore Marks + if (($flag & 0x0008) == 0x0008) { + $ignoreflag = 8; + //$str = $this->GlyphClassMarks; + $str = "Mark Glyphs "; + } + + // Flag & 0x0004 = Ignore Ligatures + if (($flag & 0x0004) == 0x0004) { + $ignoreflag += 4; + if ($str) { + $str .= "|"; + } + //$str .= $this->GlyphClassLigatures; + $str .= "Ligature Glyphs "; + } + // Flag & 0x0002 = Ignore BaseGlyphs + if (($flag & 0x0002) == 0x0002) { + $ignoreflag += 2; + if ($str) { + $str .= "|"; + } + //$str .= $this->GlyphClassBases; + $str .= "Base Glyphs "; + } + if ($str) { + return $str; + } else { + return ""; + } + } + + // GSUB Patterns + + /* + BACKTRACK INPUT LOOKAHEAD + ================================== ================== ================================== + (FEEB|FEEC)(ign) ¦(FD12|FD13)(ign) ¦(0612)¦(ign) (0613)¦(ign) (FD12|FD13)¦(ign) (FEEB|FEEC) + ---------------- ---------------- ----- ------------ --------------- --------------- + Backtrack 1 Backtrack 2 Input 1 Input 2 Lookahead 1 Lookahead 2 + -------- --- --------- --- ---- --- ---- --- --------- --- ------- + \${1} \${2} \${3} \${4} \${5+} \${6+} \${7+} \${8+} + + nBacktrack = 2 nInput = 2 nLookahead = 2 + + nBsubs = 2xnBack nIsubs = (nBsubs+) nLsubs = (nBsubs+nIsubs+) 2xnLookahead + "\${1}\${2} " (nInput*2)-1 "\${5+} \${6+}" + "REPL" + + ¦\${1}\${2} ¦\${3}\${4} ¦REPL¦\${5+} \${6+}¦\${7+} \${8+}¦ + + + INPUT nInput = 5 + ============================================================ + ¦(0612)¦(ign) (0613)¦(ign) (0614)¦(ign) (0615)¦(ign) (0615)¦ + \${1} \${2} \${3} \${4} \${5} \${6} \${7} \${8} \${9} (All backreference numbers are + nBsubs) + ----- ------------ ------------ ------------ ------------ + Input 1 Input 2 Input 3 Input 4 Input 5 + + A====== SequenceIndex=1 ; Lookup match nGlyphs=1 + B=================== SequenceIndex=1 ; Lookup match nGlyphs=2 + C=============================== SequenceIndex=1 ; Lookup match nGlyphs=3 + D======================= SequenceIndex=2 ; Lookup match nGlyphs=2 + E===================================== SequenceIndex=2 ; Lookup match nGlyphs=3 + F====================== SequenceIndex=4 ; Lookup match nGlyphs=2 + + All backreference numbers are + nBsubs + A - "REPL\${2} \${3}\${4} \${5}\${6} \${7}\${8} \${9}" + B - "REPL\${2}\${4} \${5}\${6} \${7}\${8} \${9}" + C - "REPL\${2}\${4}\${6} \${7}\${8} \${9}" + D - "\${1} REPL\${2}\${4}\${6} \${7}\${8} \${9}" + E - "\${1} REPL\${2}\${4}\${6}\${8} \${9}" + F - "\${1}\${2} \${3}\${4} \${5} REPL\${6}\${8}" + */ + + function _makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + // $inputGlyphs = array of glyphs(glyphstrings) making up Input sequence in Context + // $lookupGlyphs = array of glyphs (single Glyphs) making up Lookup Input sequence + $mLen = count($lookupGlyphs); // nGlyphs in the secondary Lookup match + $nInput = count($inputGlyphs); // nGlyphs in the Primary Input sequence + $str = ""; + for ($i = 0; $i < $nInput; $i++) { + if ($i > 0) { + $str .= $ignore . " "; + } + if ($i >= $seqIndex && $i < ($seqIndex + $mLen)) { + $str .= "" . $lookupGlyphs[($i - $seqIndex)] . ""; + } else { + $str .= "" . $inputGlyphs[($i)] . ""; + } + } + + return $str; + } + + function _makeGSUBinputMatch($inputGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + // $inputGlyphs = array of glyphs(glyphstrings) making up Input sequence in Context + // $lookupGlyphs = array of glyphs making up Lookup Input sequence - if applicable + $str = ""; + for ($i = 1; $i <= count($inputGlyphs); $i++) { + if ($i > 1) { + $str .= $ignore . " "; + } + $str .= "" . $inputGlyphs[($i - 1)] . ""; + } + + return $str; + } + + function _makeGSUBbacktrackMatch($backtrackGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(FEEB|FEEC)(ignore) ¦(FD12|FD13)(ignore) ¦ + // $backtrackGlyphs = array of glyphstrings making up Backtrack sequence + // 3 2 1 0 + // each item being e.g. E0AD|E0AF|F1FD + $str = ""; + for ($i = (count($backtrackGlyphs) - 1); $i >= 0; $i--) { + $str .= "" . $backtrackGlyphs[$i] . " " . $ignore . " "; + } + + return $str; + } + + function _makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(ignore) (FD12|FD13)¦(ignore) (FEEB|FEEC)¦ + // $lookaheadGlyphs = array of glyphstrings making up Lookahead sequence + // 0 1 2 3 + // each item being e.g. E0AD|E0AF|F1FD + $str = ""; + for ($i = 0; $i < count($lookaheadGlyphs); $i++) { + $str .= $ignore . " " . $lookaheadGlyphs[$i] . ""; + } + + return $str; + } + + function _makeGSUBinputReplacement($nInput, $REPL, $ignore, $nBsubs, $mLen, $seqIndex) + { + // Returns e.g. "REPL\${6}\${8}" or "\${1}\${2} \${3} REPL\${4}\${6}\${8} \${9}" + // $nInput nGlyphs in the Primary Input sequence + // $REPL replacement glyphs from secondary lookup + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // $nBsubs Number of Backtrack substitutions (= 2x Number of Backtrack glyphs) + // $mLen nGlyphs in the secondary Lookup match - if no secondary lookup, should=$nInput + // $seqIndex Sequence Index to apply the secondary match + if ($ignore == "()") { + $ign = false; + } else { + $ign = true; + } + $str = ""; + if ($nInput == 1) { + $str = $REPL; + } else { + if ($nInput > 1) { + if ($mLen == $nInput) { // whole string replaced + $str = $REPL; + if ($ign) { + // for every nInput over 1, add another replacement backreference, to move IGNORES after replacement + for ($x = 2; $x <= $nInput; $x++) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + } + } else { // if only part of string replaced: + for ($x = 1; $x < ($seqIndex + 1); $x++) { + if ($x == 1) { + $str .= '\\' . ($nBsubs + 1); + } else { + if ($ign) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + $str .= ' \\' . ($nBsubs + 1 + (2 * ($x - 1))); + } + } + if ($seqIndex > 0) { + $str .= " "; + } + $str .= $REPL; + if ($ign) { + for ($x = (max(($seqIndex + 1), 2)); $x < ($seqIndex + 1 + $mLen); $x++) { // move IGNORES after replacement + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + } + for ($x = ($seqIndex + 1 + $mLen); $x <= $nInput; $x++) { + if ($ign) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + $str .= ' \\' . ($nBsubs + 1 + (2 * ($x - 1))); + } + } + } + } + + return $str; + } + + ////////////////////////////////////////////////////////////////////////////////// + function _getCoverage($convert2hex = true) + { + $g = []; + $CoverageFormat = $this->read_ushort(); + if ($CoverageFormat == 1) { + $CoverageGlyphCount = $this->read_ushort(); + for ($gid = 0; $gid < $CoverageGlyphCount; $gid++) { + $glyphID = $this->read_ushort(); + if ($convert2hex) { + $g[] = unicode_hex($this->glyphToChar[$glyphID][0]); + } else { + $g[] = $glyphID; + } + } + } + if ($CoverageFormat == 2) { + $RangeCount = $this->read_ushort(); + for ($r = 0; $r < $RangeCount; $r++) { + $start = $this->read_ushort(); + $end = $this->read_ushort(); + $StartCoverageIndex = $this->read_ushort(); // n/a + for ($gid = $start; $gid <= $end; $gid++) { + $glyphID = $gid; + if ($convert2hex) { + $g[] = unicode_hex($this->glyphToChar[$glyphID][0]); + } else { + $g[] = $glyphID; + } + } + } + } + + return $g; + } + + ////////////////////////////////////////////////////////////////////////////////// + function _getClasses($offset) + { + $this->seek($offset); + $ClassFormat = $this->read_ushort(); + $GlyphByClass = []; + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $startGlyphID = $StartGlyph + $i; + $endGlyphID = $StartGlyph + $i; + $class = $this->read_ushort(); + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if ($this->glyphToChar[$g][0]) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$g][0]); + } + } + } + } else { + if ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $startGlyphID = $this->read_ushort(); + $endGlyphID = $this->read_ushort(); + $class = $this->read_ushort(); + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if ($this->glyphToChar[$g][0]) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$g][0]); + } + } + } + } + } + $gbc = []; + foreach ($GlyphByClass as $class => $garr) { + $gbc[$class] = implode('|', $garr); + } + + return $gbc; + } + + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + function _getGPOStables() + { + /////////////////////////////////// + // GPOS - Glyph Positioning + /////////////////////////////////// + if (isset($this->tables["GPOS"])) { + $this->mpdf->WriteHTML('<h1>GPOS Tables</h1>'); + $ffeats = []; + $gpos_offset = $this->seek_table("GPOS"); + $this->skip(4); + $ScriptList_offset = $gpos_offset + $this->read_ushort(); + $FeatureList_offset = $gpos_offset + $this->read_ushort(); + $LookupList_offset = $gpos_offset + $this->read_ushort(); + + // ScriptList + $this->seek($ScriptList_offset); + $ScriptCount = $this->read_ushort(); + for ($i = 0; $i < $ScriptCount; $i++) { + $ScriptTag = $this->read_tag(); // = "beng", "deva" etc. + $ScriptTableOffset = $this->read_ushort(); + $ffeats[$ScriptTag] = $ScriptList_offset + $ScriptTableOffset; + } + + // Script Table + foreach ($ffeats as $t => $o) { + $ls = []; + $this->seek($o); + $DefLangSys_offset = $this->read_ushort(); + if ($DefLangSys_offset > 0) { + $ls['DFLT'] = $DefLangSys_offset + $o; + } + $LangSysCount = $this->read_ushort(); + for ($i = 0; $i < $LangSysCount; $i++) { + $LangTag = $this->read_tag(); // = + $LangTableOffset = $this->read_ushort(); + $ls[$LangTag] = $o + $LangTableOffset; + } + $ffeats[$t] = $ls; + } + + // Get FeatureIndexList + // LangSys Table - from first listed langsys + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = []; + $langsystable_offset = $o; + $this->seek($langsystable_offset); + $LookUpOrder = $this->read_ushort(); //==NULL + $ReqFeatureIndex = $this->read_ushort(); + if ($ReqFeatureIndex != 0xFFFF) { + $FeatureIndex[] = $ReqFeatureIndex; + } + $FeatureCount = $this->read_ushort(); + for ($i = 0; $i < $FeatureCount; $i++) { + $FeatureIndex[] = $this->read_ushort(); // = index of feature + } + $ffeats[$st][$t] = $FeatureIndex; + } + } +//print_r($ffeats); exit; + // Feauture List => LookupListIndex es + $this->seek($FeatureList_offset); + $FeatureCount = $this->read_ushort(); + $Feature = []; + for ($i = 0; $i < $FeatureCount; $i++) { + $Feature[$i] = ['tag' => $this->read_tag()]; + $Feature[$i]['offset'] = $FeatureList_offset + $this->read_ushort(); + } + for ($i = 0; $i < $FeatureCount; $i++) { + $this->seek($Feature[$i]['offset']); + $this->read_ushort(); // null + $Feature[$i]['LookupCount'] = $Lookupcount = $this->read_ushort(); + $Feature[$i]['LookupListIndex'] = []; + for ($c = 0; $c < $Lookupcount; $c++) { + $Feature[$i]['LookupListIndex'][] = $this->read_ushort(); + } + } + + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = $ffeats[$st][$t]; + foreach ($FeatureIndex as $k => $fi) { + $ffeats[$st][$t][$k] = $Feature[$fi]; + } + } + } +//print_r($ffeats); exit; + //===================================================================================== + $gpos = []; + $GPOSScriptLang = []; + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $langsys) { + $lg = []; + foreach ($langsys as $ft) { + $lg[$ft['LookupListIndex'][0]] = $ft; + } + // list of Lookups in order they need to be run i.e. order listed in Lookup table + ksort($lg); + foreach ($lg as $ft) { + $gpos[$st][$t][$ft['tag']] = $ft['LookupListIndex']; + } + if (!isset($GPOSScriptLang[$st])) { + $GPOSScriptLang[$st] = ''; + } + $GPOSScriptLang[$st] .= $t . ' '; + } + } + if ($this->mode == 'summary') { + $this->mpdf->WriteHTML('<h3>GPOS Scripts & Languages</h3>'); + $html = ''; + if (count($gpos)) { + foreach ($gpos as $st => $g) { + $html .= '<h5>' . $st . '</h5>'; + foreach ($g as $l => $t) { + $html .= '<div><a href="font_dump_OTL.php?script=' . $st . '&lang=' . $l . '">' . $l . '</a></b>: '; + foreach ($t as $tag => $o) { + $html .= $tag . ' '; + } + $html .= '</div>'; + } + } + } else { + $html .= '<div>No entries in GPOS table.</div>'; + } + $this->mpdf->WriteHTML($html); + $this->mpdf->WriteHTML('</div>'); + + return 0; + } + + //===================================================================================== + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $Lookup = []; + $Offsets = []; + $SubtableCount = []; + for ($i = 0; $i < $LookupCount; $i++) { + $Offsets[$i] = $LookupList_offset + $this->read_ushort(); + } + for ($i = 0; $i < $LookupCount; $i++) { + $this->seek($Offsets[$i]); + $Lookup[$i]['Type'] = $this->read_ushort(); + $Lookup[$i]['Flag'] = $flag = $this->read_ushort(); + $Lookup[$i]['SubtableCount'] = $SubtableCount[$i] = $this->read_ushort(); + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $Lookup[$i]['Subtables'][$c] = $Offsets[$i] + $this->read_ushort(); + } + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) == 0x0010) { + $Lookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } + // else { $Lookup[$i]['MarkFilteringSet'] = ''; } + // Lookup Type 9: Extension + if ($Lookup[$i]['Type'] == 9) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $this->seek($Lookup[$i]['Subtables'][$c]); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $Lookup[$i]['Subtables'][$c] = $Lookup[$i]['Subtables'][$c] + $this->read_ulong(); + } + $Lookup[$i]['Type'] = $type; + } + } + + //===================================================================================== + + $st = $this->mpdf->OTLscript; + $t = $this->mpdf->OTLlang; + $langsys = $gpos[$st][$t]; + + $lul = []; // array of LookupListIndexes + $tags = []; // corresponding array of feature tags e.g. 'ccmp' + if (count($langsys)) { + foreach ($langsys as $tag => $ft) { + foreach ($ft as $ll) { + $lul[$ll] = $tag; + } + } + } + ksort($lul); // Order the Lookups in the order they are in the GUSB table, regardless of Feature order + $this->_getGPOSarray($Lookup, $lul, $st); + +//print_r($lul); exit; + + return [$GPOSScriptLang, $gpos, $Lookup]; + } // end if GPOS + } + + ////////////////////////////////////////////////////////////////////////////////// + //===================================================================================== + //===================================================================================== + //===================================================================================== +///////////////////////////////////////////////////////////////////////////////////////// + // GPOS functions + function _getGPOSarray(&$Lookup, $lul, $scripttag, $level = 1, $lcoverage = '', $exB = '', $exL = '') + { + // Process (3) LookupList for specific Script-LangSys + $html = ''; + if ($level == 1) { + $html .= '<bookmark level="0" content="GPOS features">'; + } + foreach ($lul as $luli => $tag) { + $html .= '<div class="level' . $level . '">'; + $html .= '<h5 class="level' . $level . '">'; + if ($level == 1) { + $html .= '<bookmark level="1" content="' . $tag . ' [#' . $luli . ']">'; + } + $html .= 'Lookup #' . $luli . ' [tag: <span style="color:#000066;">' . $tag . '</span>]</h5>'; + $ignore = $this->_getGSUBignoreString($Lookup[$luli]['Flag'], $Lookup[$luli]['MarkFilteringSet']); + if ($ignore) { + $html .= '<div class="ignore">Ignoring: ' . $ignore . '</div> '; + } + + $Type = $Lookup[$luli]['Type']; + $Flag = $Lookup[$luli]['Flag']; + if (($Flag & 0x0001) == 1) { + $dir = 'RTL'; + } else { + $dir = 'LTR'; + } + + for ($c = 0; $c < $Lookup[$luli]['SubtableCount']; $c++) { + $html .= '<div class="subtable">Subtable #' . $c; + if ($level == 1) { + $html .= '<bookmark level="2" content="Subtable #' . $c . '">'; + } + $html .= '</div>'; + + // Lets start + $subtable_offset = $Lookup[$luli]['Subtables'][$c]; + $this->seek($subtable_offset); + $PosFormat = $this->read_ushort(); + + //////////////////////////////////////////////////////////////////////////////// + // LookupType 1: Single adjustment Adjust position of a single glyph (e.g. SmallCaps/Sups/Subs) + //////////////////////////////////////////////////////////////////////////////// + if ($Lookup[$luli]['Type'] == 1) { + $html .= '<div class="lookuptype">LookupType 1: Single adjustment [Format ' . $PosFormat . ']</div>'; + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat = $this->read_ushort(); + $Value = $this->_getValueRecord($ValueFormat); + + $this->seek($Coverage); + $glyphs = $this->_getCoverage(); // Array of Hex Glyphs + for ($g = 0; $g < count($glyphs); $g++) { + if ($level == 2 && strpos($lcoverage, $glyphs[$g]) === false) { + continue; + } + + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($glyphs[$g]) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($glyphs[$g]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed" style="font-feature-settings:\'' . $tag . '\' 1;"> ' . $this->formatEntity($glyphs[$g]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= ' <span class="unicode">'; + if ($Value['XPlacement']) { + $html .= ' Xpl: ' . $Value['XPlacement'] . ';'; + } + if ($Value['YPlacement']) { + $html .= ' YPl: ' . $Value['YPlacement'] . ';'; + } + if ($Value['XAdvance']) { + $html .= ' Xadv: ' . $Value['XAdvance']; + } + $html .= '</span>'; + $html .= '</div>'; + } + } //=========== + // Format 2: + //=========== + else { + if ($PosFormat == 2) { + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat = $this->read_ushort(); + $ValueCount = $this->read_ushort(); + $Values = []; + for ($v = 0; $v < $ValueCount; $v++) { + $Values[] = $this->_getValueRecord($ValueFormat); + } + + $this->seek($Coverage); + $glyphs = $this->_getCoverage(); // Array of Hex Glyphs + + for ($g = 0; $g < count($glyphs); $g++) { + if ($level == 2 && strpos($lcoverage, $glyphs[$g]) === false) { + continue; + } + $Value = $Values[$g]; + + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($glyphs[$g]) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($glyphs[$g]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed" style="font-feature-settings:\'' . $tag . '\' 1;"> ' . $this->formatEntity($glyphs[$g]) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= ' <span class="unicode">'; + if ($Value['XPlacement']) { + $html .= ' Xpl: ' . $Value['XPlacement'] . ';'; + } + if ($Value['YPlacement']) { + $html .= ' YPl: ' . $Value['YPlacement'] . ';'; + } + if ($Value['XAdvance']) { + $html .= ' Xadv: ' . $Value['XAdvance']; + } + $html .= '</span>'; + $html .= '</div>'; + } + } + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 2: Pair adjustment Adjust position of a pair of glyphs (Kerning) + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 2) { + $html .= '<div class="lookuptype">LookupType 2: Pair adjustment e.g. Kerning [Format ' . $PosFormat . ']</div>'; + $Coverage = $subtable_offset + $this->read_ushort(); + $ValueFormat1 = $this->read_ushort(); + $ValueFormat2 = $this->read_ushort(); + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + $PairSetCount = $this->read_ushort(); + $PairSetOffset = []; + for ($p = 0; $p < $PairSetCount; $p++) { + $PairSetOffset[] = $subtable_offset + $this->read_ushort(); + } + $this->seek($Coverage); + $glyphs = $this->_getCoverage(); // Array of Hex Glyphs + for ($p = 0; $p < $PairSetCount; $p++) { + if ($level == 2 && strpos($lcoverage, $glyphs[$p]) === false) { + continue; + } + $this->seek($PairSetOffset[$p]); + // First Glyph = $glyphs[$p] +// Takes too long e.g. Calibri font - just list kerning pairs with this: + $html .= '<div class="glyphs">'; + $html .= '<span class="unchanged"> ' . $this->formatEntity($glyphs[$p]) . ' </span>'; + + //PairSet table + $PairValueCount = $this->read_ushort(); + for ($pv = 0; $pv < $PairValueCount; $pv++) { + //PairValueRecord + $gid = $this->read_ushort(); + $SecondGlyph = unicode_hex($this->glyphToChar[$gid][0]); + $Value1 = $this->_getValueRecord($ValueFormat1); + $Value2 = $this->_getValueRecord($ValueFormat2); + + // If RTL pairs, GPOS declares a XPlacement e.g. -180 for an XAdvance of -180 to take + // account of direction. mPDF does not need the XPlacement adjustment + if ($dir == 'RTL' && $Value1['XPlacement']) { + $Value1['XPlacement'] -= $Value1['XAdvance']; + } + + if ($ValueFormat2) { + // If RTL pairs, GPOS declares a XPlacement e.g. -180 for an XAdvance of -180 to take + // account of direction. mPDF does not need the XPlacement adjustment + if ($dir == 'RTL' && $Value2['XPlacement'] && $Value2['XAdvance']) { + $Value2['XPlacement'] -= $Value2['XAdvance']; + } + } + + $html .= ' ' . $this->formatEntity($SecondGlyph) . ' '; + + /* + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">'.$this->formatUni($glyphs[$p]).' </span> '; + if ($level==2 && $exB) { $html .= $exB; } + $html .= '<span class="unchanged"> '.$this->formatEntity($glyphs[$p]).$this->formatEntity($SecondGlyph).'</span>'; + if ($level==2 && $exL) { $html .= $exL; } + $html .= '  » »  '; + if ($level==2 && $exB) { $html .= $exB; } + $html .= '<span class="changed" style="font-feature-settings:\''.$tag.'\' 1;"> '.$this->formatEntity($glyphs[$p]).$this->formatEntity($SecondGlyph).'</span>'; + if ($level==2 && $exL) { $html .= $exL; } + $html .= ' <span class="unicode">'; + if ($Value1['XPlacement']) { $html .= ' Xpl[1]: '.$Value1['XPlacement'].';'; } + if ($Value1['YPlacement']) { $html .= ' YPl[1]: '.$Value1['YPlacement'].';'; } + if ($Value1['XAdvance']) { $html .= ' Xadv[1]: '.$Value1['XAdvance']; } + if ($Value2['XPlacement']) { $html .= ' Xpl[2]: '.$Value2['XPlacement'].';'; } + if ($Value2['YPlacement']) { $html .= ' YPl[2]: '.$Value2['YPlacement'].';'; } + if ($Value2['XAdvance']) { $html .= ' Xadv[2]: '.$Value2['XAdvance']; } + $html .= '</span>'; + $html .= '</div>'; + */ + } + $html .= '</div>'; + } + } //=========== + // Format 2: + //=========== + else { + if ($PosFormat == 2) { + $ClassDef1 = $subtable_offset + $this->read_ushort(); + $ClassDef2 = $subtable_offset + $this->read_ushort(); + $Class1Count = $this->read_ushort(); + $Class2Count = $this->read_ushort(); + + $sizeOfPair = (2 * $this->count_bits($ValueFormat1)) + (2 * $this->count_bits($ValueFormat2)); + $sizeOfValueRecords = $Class1Count * $Class2Count * $sizeOfPair; + + // NB Class1Count includes Class 0 even though it is not defined by $ClassDef1 + // i.e. Class1Count = 5; Class1 will contain array(indices 1-4); + $Class1 = $this->_getClassDefinitionTable($ClassDef1); + $Class2 = $this->_getClassDefinitionTable($ClassDef2); + + $this->seek($subtable_offset + 16); + + for ($i = 0; $i < $Class1Count; $i++) { + for ($j = 0; $j < $Class2Count; $j++) { + $Value1 = $this->_getValueRecord($ValueFormat1); + $Value2 = $this->_getValueRecord($ValueFormat2); + + // If RTL pairs, GPOS declares a XPlacement e.g. -180 for an XAdvance of -180 + // of direction. mPDF does not need the XPlacement adjustment + if ($dir == 'RTL' && $Value1['XPlacement'] && $Value1['XAdvance']) { + $Value1['XPlacement'] -= $Value1['XAdvance']; + } + if ($ValueFormat2) { + if ($dir == 'RTL' && $Value2['XPlacement'] && $Value2['XAdvance']) { + $Value2['XPlacement'] -= $Value2['XAdvance']; + } + } + + for ($c1 = 0; $c1 < count($Class1[$i]); $c1++) { + $FirstGlyph = $Class1[$i][$c1]; + if ($level == 2 && strpos($lcoverage, $FirstGlyph) === false) { + continue; + } + + for ($c2 = 0; $c2 < count($Class2[$j]); $c2++) { + $SecondGlyph = $Class2[$j][$c2]; + + if (!$Value1['XPlacement'] && !$Value1['YPlacement'] && !$Value1['XAdvance'] && !$Value2['XPlacement'] && !$Value2['YPlacement'] && !$Value2['XAdvance']) { + continue; + } + + $html .= '<div class="substitution">'; + $html .= '<span class="unicode">' . $this->formatUni($FirstGlyph) . ' </span> '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="unchanged"> ' . $this->formatEntity($FirstGlyph) . $this->formatEntity($SecondGlyph) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= '  » »  '; + if ($level == 2 && $exB) { + $html .= $exB; + } + $html .= '<span class="changed" style="font-feature-settings:\'' . $tag . '\' 1;"> ' . $this->formatEntity($FirstGlyph) . $this->formatEntity($SecondGlyph) . '</span>'; + if ($level == 2 && $exL) { + $html .= $exL; + } + $html .= ' <span class="unicode">'; + if ($Value1['XPlacement']) { + $html .= ' Xpl[1]: ' . $Value1['XPlacement'] . ';'; + } + if ($Value1['YPlacement']) { + $html .= ' YPl[1]: ' . $Value1['YPlacement'] . ';'; + } + if ($Value1['XAdvance']) { + $html .= ' Xadv[1]: ' . $Value1['XAdvance']; + } + if ($Value2['XPlacement']) { + $html .= ' Xpl[2]: ' . $Value2['XPlacement'] . ';'; + } + if ($Value2['YPlacement']) { + $html .= ' YPl[2]: ' . $Value2['YPlacement'] . ';'; + } + if ($Value2['XAdvance']) { + $html .= ' Xadv[2]: ' . $Value2['XAdvance']; + } + $html .= '</span>'; + $html .= '</div>'; + } + } + } + } + } + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 3: Cursive attachment Attach cursive glyphs + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 3) { + $html .= '<div class="lookuptype">LookupType 3: Cursive attachment </div>'; + $Coverage = $subtable_offset + $this->read_ushort(); + $EntryExitCount = $this->read_ushort(); + $EntryAnchors = []; + $ExitAnchors = []; + for ($i = 0; $i < $EntryExitCount; $i++) { + $EntryAnchors[$i] = $this->read_ushort(); + $ExitAnchors[$i] = $this->read_ushort(); + } + + $this->seek($Coverage); + $Glyphs = $this->_getCoverage(); + for ($i = 0; $i < $EntryExitCount; $i++) { + // Need default XAdvance for glyph + $pdfWidth = $this->mpdf->_getCharWidth($this->mpdf->fonts[$this->fontkey]['cw'], hexdec($Glyphs[$i])); + $EntryAnchor = $EntryAnchors[$i]; + $ExitAnchor = $ExitAnchors[$i]; + $html .= '<div class="glyphs">'; + $html .= '<span class="unchanged">' . $this->formatEntity($Glyphs[$i]) . ' </span> '; + $html .= '<span class="unicode"> ' . $this->formatUni($Glyphs[$i]) . ' => '; + + if ($EntryAnchor != 0) { + $EntryAnchor += $subtable_offset; + list($x, $y) = $this->_getAnchorTable($EntryAnchor); + if ($dir == 'RTL') { + if (round($pdfWidth) == round($x * 1000 / $this->mpdf->fonts[$this->fontkey]['desc']['unitsPerEm'])) { + $x = 0; + } else { + $x = $x - ($pdfWidth * $this->mpdf->fonts[$this->fontkey]['desc']['unitsPerEm'] / 1000); + } + } + $html .= " Entry X: " . $x . " Y: " . $y . "; "; + } + if ($ExitAnchor != 0) { + $ExitAnchor += $subtable_offset; + list($x, $y) = $this->_getAnchorTable($ExitAnchor); + if ($dir == 'LTR') { + if (round($pdfWidth) == round($x * 1000 / $this->mpdf->fonts[$this->fontkey]['desc']['unitsPerEm'])) { + $x = 0; + } else { + $x = $x - ($pdfWidth * $this->mpdf->fonts[$this->fontkey]['desc']['unitsPerEm'] / 1000); + } + } + $html .= " Exit X: " . $x . " Y: " . $y . "; "; + } + + $html .= '</span></div>'; + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 4: MarkToBase attachment Attach a combining mark to a base glyph + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 4) { + $html .= '<div class="lookuptype">LookupType 4: MarkToBase attachment </div>'; + $MarkCoverage = $subtable_offset + $this->read_ushort(); + $BaseCoverage = $subtable_offset + $this->read_ushort(); + + $this->seek($MarkCoverage); + $MarkGlyphs = $this->_getCoverage(); + + $this->seek($BaseCoverage); + $BaseGlyphs = $this->_getCoverage(); + + $firstMark = ''; + $html .= '<div class="glyphs">Marks: '; + for ($i = 0; $i < count($MarkGlyphs); $i++) { + if ($level == 2 && strpos($lcoverage, $MarkGlyphs[$i]) === false) { + continue; + } else { + if (!$firstMark) { + $firstMark = $MarkGlyphs[$i]; + } + } + $html .= ' ' . $this->formatEntity($MarkGlyphs[$i]) . ' '; + } + $html .= '</div>'; + if (!$firstMark) { + return; + } + + $html .= '<div class="glyphs">Bases: '; + for ($j = 0; $j < count($BaseGlyphs); $j++) { + $html .= ' ' . $this->formatEntity($BaseGlyphs[$j]) . ' '; + } + $html .= '</div>'; + + // Example + $html .= '<div class="glyphs" style="font-feature-settings:\'' . $tag . '\' 1;">Example(s): '; + for ($j = 0; $j < min(count($BaseGlyphs), 20); $j++) { + $html .= ' ' . $this->formatEntity($BaseGlyphs[$j]) . $this->formatEntity($firstMark, true) . '   '; + } + $html .= '</div>'; + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 5: MarkToLigature attachment Attach a combining mark to a ligature + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 5) { + $html .= '<div class="lookuptype">LookupType 5: MarkToLigature attachment </div>'; + $MarkCoverage = $subtable_offset + $this->read_ushort(); + //$MarkCoverage is already set in $lcoverage 00065|00073 etc + $LigatureCoverage = $subtable_offset + $this->read_ushort(); + $ClassCount = $this->read_ushort(); // Number of classes defined for marks = Number of mark glyphs in the MarkCoverage table + $MarkArray = $subtable_offset + $this->read_ushort(); // Offset to MarkArray table + $LigatureArray = $subtable_offset + $this->read_ushort(); // Offset to LigatureArray table + + $this->seek($MarkCoverage); + $MarkGlyphs = $this->_getCoverage(); + $this->seek($LigatureCoverage); + $LigatureGlyphs = $this->_getCoverage(); + + $firstMark = ''; + $html .= '<div class="glyphs">Marks: <span class="unchanged">'; + $MarkRecord = []; + for ($i = 0; $i < count($MarkGlyphs); $i++) { + if ($level == 2 && strpos($lcoverage, $MarkGlyphs[$i]) === false) { + continue; + } else { + if (!$firstMark) { + $firstMark = $MarkGlyphs[$i]; + } + } + // Get the relevant MarkRecord + $MarkRecord[$i] = $this->_getMarkRecord($MarkArray, $i); + //Mark Class is = $MarkRecord[$i]['Class'] + $html .= ' ' . $this->formatEntity($MarkGlyphs[$i]) . ' '; + } + $html .= '</span></div>'; + if (!$firstMark) { + return; + } + + $this->seek($LigatureArray); + $LigatureCount = $this->read_ushort(); + $LigatureAttach = []; + $html .= '<div class="glyphs">Ligatures: <span class="unchanged">'; + for ($j = 0; $j < count($LigatureGlyphs); $j++) { + // Get the relevant LigatureRecord + $LigatureAttach[$j] = $LigatureArray + $this->read_ushort(); + $html .= ' ' . $this->formatEntity($LigatureGlyphs[$j]) . ' '; + } + $html .= '</span></div>'; + + /* + for ($i=0;$i<count($MarkGlyphs);$i++) { + $html .= '<div class="glyphs">'; + $html .= '<span class="unchanged">'.$this->formatEntity($MarkGlyphs[$i]).'</span>'; + + for ($j=0;$j<count($LigatureGlyphs);$j++) { + $this->seek($LigatureAttach[$j]); + $ComponentCount = $this->read_ushort(); + $html .= '<span class="unchanged">'.$this->formatEntity($LigatureGlyphs[$j]).'</span>'; + $offsets = array(); + for ($comp=0;$comp<$ComponentCount;$comp++) { + // ComponentRecords + for ($class=0;$class<$ClassCount;$class++) { + $offset = $this->read_ushort(); + if ($offset!= 0 && $class == $MarkRecord[$i]['Class']) { + + $html .= ' ['.$comp.'] '; + + } + } + } + } + $html .= '</span></div>'; + } + */ + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 6: MarkToMark attachment Attach a combining mark to another mark + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 6) { + $html .= '<div class="lookuptype">LookupType 6: MarkToMark attachment </div>'; + $Mark1Coverage = $subtable_offset + $this->read_ushort(); // Combining Mark + //$Mark1Coverage is already set in $LuCoverage 0065|0073 etc + $Mark2Coverage = $subtable_offset + $this->read_ushort(); // Base Mark + $ClassCount = $this->read_ushort(); // Number of classes defined for marks = No. of Combining mark1 glyphs in the MarkCoverage table + $this->seek($Mark1Coverage); + $Mark1Glyphs = $this->_getCoverage(); + $this->seek($Mark2Coverage); + $Mark2Glyphs = $this->_getCoverage(); + + $firstMark = ''; + $html .= '<div class="glyphs">Marks: <span class="unchanged">'; + for ($i = 0; $i < count($Mark1Glyphs); $i++) { + if ($level == 2 && strpos($lcoverage, $Mark1Glyphs[$i]) === false) { + continue; + } else { + if (!$firstMark) { + $firstMark = $Mark1Glyphs[$i]; + } + } + $html .= ' ' . $this->formatEntity($Mark1Glyphs[$i]) . ' '; + } + $html .= '</span></div>'; + + if ($firstMark) { + $html .= '<div class="glyphs">Bases: <span class="unchanged">'; + for ($j = 0; $j < count($Mark2Glyphs); $j++) { + $html .= ' ' . $this->formatEntity($Mark2Glyphs[$j]) . ' '; + } + $html .= '</span></div>'; + + // Example + $html .= '<div class="glyphs" style="font-feature-settings:\'' . $tag . '\' 1;">Example(s): <span class="changed">'; + for ($j = 0; $j < min(count($Mark2Glyphs), 20); $j++) { + $html .= ' ' . $this->formatEntity($Mark2Glyphs[$j]) . $this->formatEntity($firstMark, true) . '   '; + } + $html .= '</span></div>'; + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 7: Context positioning Position one or more glyphs in context + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 7) { + $html .= '<div class="lookuptype">LookupType 7: Context positioning [Format ' . $PosFormat . ']</div>'; + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not YET TESTED."); + } //=========== + // Format 2: + //=========== + else { + if ($PosFormat == 2) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not YET TESTED."); + } //=========== + // Format 3: + //=========== + else { + if ($PosFormat == 3) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not YET TESTED."); + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . ", Format " . $PosFormat . " not supported."); + } + } + } + } //////////////////////////////////////////////////////////////////////////////// + // LookupType 8: Chained Context positioning Position one or more glyphs in chained context + //////////////////////////////////////////////////////////////////////////////// + else { + if ($Lookup[$luli]['Type'] == 8) { + $html .= '<div class="lookuptype">LookupType 8: Chained Context positioning [Format ' . $PosFormat . ']</div>'; + //=========== + // Format 1: + //=========== + if ($PosFormat == 1) { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not TESTED YET."); + } //=========== + // Format 2: + //=========== + else { + if ($PosFormat == 2) { + $html .= '<div>GPOS Lookup Type 8: Format 2 not yet supported in OTL dump</div>'; + continue; + /* NB When developing - cf. GSUB 6.2 */ + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Type . " Format " . $PosFormat . " not TESTED YET."); + } //=========== + // Format 3: + //=========== + else { + if ($PosFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + $CoverageBacktrackOffset = []; + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $CoverageBacktrackOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $InputGlyphCount = $this->read_ushort(); + $CoverageInputOffset = []; + for ($b = 0; $b < $InputGlyphCount; $b++) { + $CoverageInputOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $LookaheadGlyphCount = $this->read_ushort(); + $CoverageLookaheadOffset = []; + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $CoverageLookaheadOffset[] = $subtable_offset + $this->read_ushort(); // in glyph sequence order + } + $PosCount = $this->read_ushort(); + + $PosLookupRecord = []; + for ($p = 0; $p < $PosCount; $p++) { + // PosLookupRecord + $PosLookupRecord[$p]['SequenceIndex'] = $this->read_ushort(); + $PosLookupRecord[$p]['LookupListIndex'] = $this->read_ushort(); + } + + $backtrackGlyphs = []; + for ($b = 0; $b < $BacktrackGlyphCount; $b++) { + $this->seek($CoverageBacktrackOffset[$b]); + $backtrackGlyphs[$b] = implode('|', $this->_getCoverage()); + } + $inputGlyphs = []; + for ($b = 0; $b < $InputGlyphCount; $b++) { + $this->seek($CoverageInputOffset[$b]); + $inputGlyphs[$b] = implode('|', $this->_getCoverage()); + } + $lookaheadGlyphs = []; + for ($b = 0; $b < $LookaheadGlyphCount; $b++) { + $this->seek($CoverageLookaheadOffset[$b]); + $lookaheadGlyphs[$b] = implode('|', $this->_getCoverage()); + } + + $exampleB = []; + $exampleI = []; + $exampleL = []; + $html .= '<div class="context">CONTEXT: '; + for ($ff = count($backtrackGlyphs) - 1; $ff >= 0; $ff--) { + $html .= '<div>Backtrack #' . $ff . ': <span class="unicode">' . $this->formatUniStr($backtrackGlyphs[$ff]) . '</span></div>'; + $exampleB[] = $this->formatEntityFirst($backtrackGlyphs[$ff]); + } + for ($ff = 0; $ff < count($inputGlyphs); $ff++) { + $html .= '<div>Input #' . $ff . ': <span class="unchanged"> ' . $this->formatEntityStr($inputGlyphs[$ff]) . ' </span></div>'; + $exampleI[] = $this->formatEntityFirst($inputGlyphs[$ff]); + } + for ($ff = 0; $ff < count($lookaheadGlyphs); $ff++) { + $html .= '<div>Lookahead #' . $ff . ': <span class="unicode">' . $this->formatUniStr($lookaheadGlyphs[$ff]) . '</span></div>'; + $exampleL[] = $this->formatEntityFirst($lookaheadGlyphs[$ff]); + } + $html .= '</div>'; + + for ($p = 0; $p < $PosCount; $p++) { + $lup = $PosLookupRecord[$p]['LookupListIndex']; + $seqIndex = $PosLookupRecord[$p]['SequenceIndex']; + + // GENERATE exampleB[n] exampleI[<seqIndex] .... exampleI[>seqIndex] exampleL[n] + $exB = ''; + $exL = ''; + if (count($exampleB)) { + $exB .= '<span class="backtrack">' . implode('‍', $exampleB) . '</span>'; + } + + if ($seqIndex > 0) { + $exB .= '<span class="inputother">'; + for ($ip = 0; $ip < $seqIndex; $ip++) { + $exB .= $exampleI[$ip] . '‍'; + } + $exB .= '</span>'; + } + + if (count($inputGlyphs) > ($seqIndex + 1)) { + $exL .= '<span class="inputother">'; + for ($ip = $seqIndex + 1; $ip < count($inputGlyphs); $ip++) { + $exL .= '‍' . $exampleI[$ip]; + } + $exL .= '</span>'; + } + + if (count($exampleL)) { + $exL .= '<span class="lookahead">' . implode('‍', $exampleL) . '</span>'; + } + + $html .= '<div class="sequenceIndex">Substitution Position: ' . $seqIndex . '</div>'; + + $lul2 = [$lup => $tag]; + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // Pass $inputGlyphs[$seqIndex] e.g. 00636|00645|00656 + // to level 2 and only apply if first Replace glyph is in this list + $html .= $this->_getGPOSarray($Lookup, $lul2, $scripttag, 2, $inputGlyphs[$seqIndex], $exB, $exL); + } + } + } + } + } + } + } + } + } + } + } + } + } + $html .= '</div>'; + } + if ($level == 1) { + $this->mpdf->WriteHTML($html); + } else { + return $html; + } +//print_r($Lookup); exit; + } + + //===================================================================================== + //===================================================================================== + // GPOS FUNCTIONS + //===================================================================================== + + function count_bits($n) + { + for ($c = 0; $n; $c++) { + $n &= $n - 1; // clear the least significant bit set + } + + return $c; + } + + function _getValueRecord($ValueFormat) + { + // Common ValueRecord for GPOS + // Only returns 3 possible: $vra['XPlacement'] $vra['YPlacement'] $vra['XAdvance'] + $vra = []; + // Horizontal adjustment for placement-in design units + if (($ValueFormat & 0x0001) == 0x0001) { + $vra['XPlacement'] = $this->read_short(); + } + // Vertical adjustment for placement-in design units + if (($ValueFormat & 0x0002) == 0x0002) { + $vra['YPlacement'] = $this->read_short(); + } + // Horizontal adjustment for advance-in design units (only used for horizontal writing) + if (($ValueFormat & 0x0004) == 0x0004) { + $vra['XAdvance'] = $this->read_short(); + } + // Vertical adjustment for advance-in design units (only used for vertical writing) + if (($ValueFormat & 0x0008) == 0x0008) { + $this->read_short(); + } + // Offset to Device table for horizontal placement-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0010) == 0x0010) { + $this->read_ushort(); + } + // Offset to Device table for vertical placement-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0020) == 0x0020) { + $this->read_ushort(); + } + // Offset to Device table for horizontal advance-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0040) == 0x0040) { + $this->read_ushort(); + } + // Offset to Device table for vertical advance-measured from beginning of PosTable (may be NULL) + if (($ValueFormat & 0x0080) == 0x0080) { + $this->read_ushort(); + } + + return $vra; + } + + function _getAnchorTable($offset = 0) + { + if ($offset) { + $this->seek($offset); + } + $AnchorFormat = $this->read_ushort(); + $XCoordinate = $this->read_short(); + $YCoordinate = $this->read_short(); + + // Format 2 specifies additional link to contour point; Format 3 additional Device table + return [$XCoordinate, $YCoordinate]; + } + + function _getMarkRecord($offset, $MarkPos) + { + $this->seek($offset); + $MarkCount = $this->read_ushort(); + $this->skip($MarkPos * 4); + $Class = $this->read_ushort(); + $MarkAnchor = $offset + $this->read_ushort(); // = Offset to anchor table + list($x, $y) = $this->_getAnchorTable($MarkAnchor); + $MarkRecord = ['Class' => $Class, 'AnchorX' => $x, 'AnchorY' => $y]; + + return $MarkRecord; + } + + ////////////////////////////////////////////////////////////////////////////////// + // Recursively get composite glyph data + function getGlyphData($originalGlyphIdx, &$maxdepth, &$depth, &$points, &$contours) + { + $depth++; + $maxdepth = max($maxdepth, $depth); + if (count($this->glyphdata[$originalGlyphIdx]['compGlyphs'])) { + foreach ($this->glyphdata[$originalGlyphIdx]['compGlyphs'] as $glyphIdx) { + $this->getGlyphData($glyphIdx, $maxdepth, $depth, $points, $contours); + } + } else { + if (($this->glyphdata[$originalGlyphIdx]['nContours'] > 0) && $depth > 0) { // simple + $contours += $this->glyphdata[$originalGlyphIdx]['nContours']; + $points += $this->glyphdata[$originalGlyphIdx]['nPoints']; + } + } + $depth--; + } + + ////////////////////////////////////////////////////////////////////////////////// + // Recursively get composite glyphs + function getGlyphs($originalGlyphIdx, &$start, &$glyphSet, &$subsetglyphs) + { + $glyphPos = $this->glyphPos[$originalGlyphIdx]; + $glyphLen = $this->glyphPos[$originalGlyphIdx + 1] - $glyphPos; + if (!$glyphLen) { + return; + } + $this->seek($start + $glyphPos); + $numberOfContours = $this->read_short(); + if ($numberOfContours < 0) { + $this->skip(8); + $flags = GlyphOperator::MORE; + while ($flags & GlyphOperator::MORE) { + $flags = $this->read_ushort(); + } + $glyphIdx = $this->read_ushort(); + if (!isset($glyphSet[$glyphIdx])) { + $glyphSet[$glyphIdx] = count($subsetglyphs); // old glyphID to new glyphID + $subsetglyphs[$glyphIdx] = true; + } + $savepos = ftell($this->fh); + $this->getGlyphs($glyphIdx, $start, $glyphSet, $subsetglyphs); + $this->seek($savepos); + if ($flags & GlyphOperator::WORDS) { + $this->skip(4); + } else { + $this->skip(2); + } + if ($flags & GlyphOperator::SCALE) { + $this->skip(2); + } else { + if ($flags & GlyphOperator::XYSCALE) { + $this->skip(4); + } else { + if ($flags & GlyphOperator::TWOBYTWO) { + $this->skip(8); + } + } + } + } + } + + + ////////////////////////////////////////////////////////////////////////////////// + + function getHMTX($numberOfHMetrics, $numGlyphs, &$glyphToChar, $scale) + { + $start = $this->seek_table("hmtx"); + $aw = 0; + $this->charWidths = str_pad('', 256 * 256 * 2, "\x00"); + if ($this->maxUniChar > 65536) { + $this->charWidths .= str_pad('', 256 * 256 * 2, "\x00"); + } // Plane 1 SMP + if ($this->maxUniChar > 131072) { + $this->charWidths .= str_pad('', 256 * 256 * 2, "\x00"); + } // Plane 2 SMP + $nCharWidths = 0; + if (($numberOfHMetrics * 4) < $this->maxStrLenRead) { + $data = $this->get_chunk($start, ($numberOfHMetrics * 4)); + $arr = unpack("n*", $data); + } else { + $this->seek($start); + } + for ($glyph = 0; $glyph < $numberOfHMetrics; $glyph++) { + if (($numberOfHMetrics * 4) < $this->maxStrLenRead) { + $aw = $arr[($glyph * 2) + 1]; + } else { + $aw = $this->read_ushort(); + $lsb = $this->read_ushort(); + } + if (isset($glyphToChar[$glyph]) || $glyph == 0) { + if ($aw >= (1 << 15)) { + $aw = 0; + } // 1.03 Some (arabic) fonts have -ve values for width + // although should be unsigned value - comes out as e.g. 65108 (intended -50) + if ($glyph == 0) { + $this->defaultWidth = $scale * $aw; + continue; + } + foreach ($glyphToChar[$glyph] as $char) { + //$this->charWidths[$char] = intval(round($scale*$aw)); + if ($char != 0 && $char != 65535) { + $w = intval(round($scale * $aw)); + if ($w == 0) { + $w = 65535; + } + if ($char < 196608) { + $this->charWidths[$char * 2] = chr($w >> 8); + $this->charWidths[$char * 2 + 1] = chr($w & 0xFF); + $nCharWidths++; + } + } + } + } + } + $data = $this->get_chunk(($start + $numberOfHMetrics * 4), ($numGlyphs * 2)); + $arr = unpack("n*", $data); + $diff = $numGlyphs - $numberOfHMetrics; + $w = intval(round($scale * $aw)); + if ($w == 0) { + $w = 65535; + } + for ($pos = 0; $pos < $diff; $pos++) { + $glyph = $pos + $numberOfHMetrics; + if (isset($glyphToChar[$glyph])) { + foreach ($glyphToChar[$glyph] as $char) { + if ($char != 0 && $char != 65535) { + if ($char < 196608) { + $this->charWidths[$char * 2] = chr($w >> 8); + $this->charWidths[$char * 2 + 1] = chr($w & 0xFF); + $nCharWidths++; + } + } + } + } + } + // NB 65535 is a set width of 0 + // First bytes define number of chars in font + $this->charWidths[0] = chr($nCharWidths >> 8); + $this->charWidths[1] = chr($nCharWidths & 0xFF); + } + + function getHMetric($numberOfHMetrics, $gid) + { + $start = $this->seek_table("hmtx"); + if ($gid < $numberOfHMetrics) { + $this->seek($start + ($gid * 4)); + $hm = fread($this->fh, 4); + } else { + $this->seek($start + (($numberOfHMetrics - 1) * 4)); + $hm = fread($this->fh, 2); + $this->seek($start + ($numberOfHMetrics * 2) + ($gid * 2)); + $hm .= fread($this->fh, 2); + } + + return $hm; + } + + function getLOCA($indexToLocFormat, $numGlyphs) + { + $start = $this->seek_table('loca'); + $this->glyphPos = []; + if ($indexToLocFormat == 0) { + $data = $this->get_chunk($start, ($numGlyphs * 2) + 2); + $arr = unpack("n*", $data); + for ($n = 0; $n <= $numGlyphs; $n++) { + $this->glyphPos[] = ($arr[$n + 1] * 2); + } + } else { + if ($indexToLocFormat == 1) { + $data = $this->get_chunk($start, ($numGlyphs * 4) + 4); + $arr = unpack("N*", $data); + for ($n = 0; $n <= $numGlyphs; $n++) { + $this->glyphPos[] = ($arr[$n + 1]); + } + } else { + throw new \Mpdf\MpdfException('Unknown location table format ' . $indexToLocFormat); + } + } + } + + // CMAP Format 4 + function getCMAP4($unicode_cmap_offset, &$glyphToChar, &$charToGlyph) + { + $this->maxUniChar = 0; + $this->seek($unicode_cmap_offset + 2); + $length = $this->read_ushort(); + $limit = $unicode_cmap_offset + $length; + $this->skip(2); + + $segCount = $this->read_ushort() / 2; + $this->skip(6); + $endCount = []; + for ($i = 0; $i < $segCount; $i++) { + $endCount[] = $this->read_ushort(); + } + $this->skip(2); + $startCount = []; + for ($i = 0; $i < $segCount; $i++) { + $startCount[] = $this->read_ushort(); + } + $idDelta = []; + for ($i = 0; $i < $segCount; $i++) { + $idDelta[] = $this->read_short(); + } // ???? was unsigned short + $idRangeOffset_start = $this->_pos; + $idRangeOffset = []; + for ($i = 0; $i < $segCount; $i++) { + $idRangeOffset[] = $this->read_ushort(); + } + + for ($n = 0; $n < $segCount; $n++) { + $endpoint = ($endCount[$n] + 1); + for ($unichar = $startCount[$n]; $unichar < $endpoint; $unichar++) { + if ($idRangeOffset[$n] == 0) { + $glyph = ($unichar + $idDelta[$n]) & 0xFFFF; + } else { + $offset = ($unichar - $startCount[$n]) * 2 + $idRangeOffset[$n]; + $offset = $idRangeOffset_start + 2 * $n + $offset; + if ($offset >= $limit) { + $glyph = 0; + } else { + $glyph = $this->get_ushort($offset); + if ($glyph != 0) { + $glyph = ($glyph + $idDelta[$n]) & 0xFFFF; + } + } + } + $charToGlyph[$unichar] = $glyph; + if ($unichar < 196608) { + $this->maxUniChar = max($unichar, $this->maxUniChar); + } + $glyphToChar[$glyph][] = $unichar; + } + } + } + + function formatUni($char) + { + $x = preg_replace('/^[0]*/', '', $char); + $x = str_pad($x, 4, '0', STR_PAD_LEFT); + $d = hexdec($x); + if (($d > 57343 && $d < 63744) || ($d > 122879 && $d < 126977)) { + $id = 'M'; + } // E000 - F8FF, 1E000-1F000 + else { + $id = 'U'; + } + + return $id . '+' . $x; + } + + function formatEntity($char, $allowjoining = false) + { + $char = preg_replace('/^[0]/', '', $char); + $x = '&#x' . $char . ';'; + if (strpos($this->GlyphClassMarks, $char) !== false) { + if (!$allowjoining) { + $x = '◌' . $x; + } + } + + return $x; + } + + function formatUniArr($arr) + { + $s = []; + foreach ($arr as $c) { + $x = preg_replace('/^[0]*/', '', $c); + $d = hexdec($x); + if (($d > 57343 && $d < 63744) || ($d > 122879 && $d < 126977)) { + $id = 'M'; + } // E000 - F8FF, 1E000-1F000 + else { + $id = 'U'; + } + $s[] = $id . '+' . str_pad($x, 4, '0', STR_PAD_LEFT); + } + + return implode(', ', $s); + } + + function formatEntityArr($arr) + { + $s = []; + foreach ($arr as $c) { + $c = preg_replace('/^[0]/', '', $c); + $x = '&#x' . $c . ';'; + if (strpos($this->GlyphClassMarks, $c) !== false) { + $x = '◌' . $x; + } + $s[] = $x; + } + + return implode(' ', $s); // ZWNJ? ‍ + } + + function formatClassArr($arr) + { + $s = []; + foreach ($arr as $c) { + $x = preg_replace('/^[0]*/', '', $c); + $d = hexdec($x); + if (($d > 57343 && $d < 63744) || ($d > 122879 && $d < 126977)) { + $id = 'M'; + } // E000 - F8FF, 1E000-1F000 + else { + $id = 'U'; + } + $s[] = $id . '+' . str_pad($x, 4, '0', STR_PAD_LEFT); + } + + return implode(', ', $s); + } + + function formatUniStr($str) + { + $s = []; + $arr = explode('|', $str); + foreach ($arr as $c) { + $x = preg_replace('/^[0]*/', '', $c); + $d = hexdec($x); + if (($d > 57343 && $d < 63744) || ($d > 122879 && $d < 126977)) { + $id = 'M'; + } // E000 - F8FF, 1E000-1F000 + else { + $id = 'U'; + } + $s[] = $id . '+' . str_pad($x, 4, '0', STR_PAD_LEFT); + } + + return implode(', ', $s); + } + + function formatEntityStr($str) + { + $s = []; + $arr = explode('|', $str); + foreach ($arr as $c) { + $c = preg_replace('/^[0]/', '', $c); + $x = '&#x' . $c . ';'; + if (strpos($this->GlyphClassMarks, $c) !== false) { + $x = '◌' . $x; + } + $s[] = $x; + } + + return implode(' ', $s); // ZWNJ? ‍ + } + + function formatEntityFirst($str) + { + $arr = explode('|', $str); + $char = preg_replace('/^[0]/', '', $arr[0]); + $x = '&#x' . $char . ';'; + if (strpos($this->GlyphClassMarks, $char) !== false) { + $x = '◌' . $x; + } + + return $x; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Output/Destination.php b/lib/MPDF/vendor/mpdf/mpdf/src/Output/Destination.php new file mode 100644 index 0000000..25b46d6 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Output/Destination.php @@ -0,0 +1,15 @@ +<?php + +namespace Mpdf\Output; + +class Destination +{ + + const FILE = 'F'; + + const DOWNLOAD = 'D'; + + const STRING_RETURN = 'S'; + + const INLINE = 'I'; +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/PageFormat.php b/lib/MPDF/vendor/mpdf/mpdf/src/PageFormat.php new file mode 100644 index 0000000..57a534e --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/PageFormat.php @@ -0,0 +1,83 @@ +<?php + +namespace Mpdf; + +class PageFormat +{ + + /** + * This method returns an array of width and height of given named format. + * + * Returned values are milimeters multiplied by scale factor of 72 / 25.4 + * + * @param string $name + * @return float[] Width and height of given format + */ + public static function getSizeFromName($name) + { + $format = strtoupper($name); + $formats = [ + '4A0' => [4767.87, 6740.79], + '2A0' => [3370.39, 4767.87], + 'A0' => [2383.94, 3370.39], + 'A1' => [1683.78, 2383.94], + 'A2' => [1190.55, 1683.78], + 'A3' => [841.89, 1190.55], + 'A4' => [595.28, 841.89], + 'A5' => [419.53, 595.28], + 'A6' => [297.64, 419.53], + 'A7' => [209.76, 297.64], + 'A8' => [147.40, 209.76], + 'A9' => [104.88, 147.40], + 'A10' => [73.70, 104.88], + 'B0' => [2834.65, 4008.19], + 'B1' => [2004.09, 2834.65], + 'B2' => [1417.32, 2004.09], + 'B3' => [1000.63, 1417.32], + 'B4' => [708.66, 1000.63], + 'B5' => [498.90, 708.66], + 'B6' => [354.33, 498.90], + 'B7' => [249.45, 354.33], + 'B8' => [175.75, 249.45], + 'B9' => [124.72, 175.75], + 'B10' => [87.87, 124.72], + 'C0' => [2599.37, 3676.54], + 'C1' => [1836.85, 2599.37], + 'C2' => [1298.27, 1836.85], + 'C3' => [918.43, 1298.27], + 'C4' => [649.13, 918.43], + 'C5' => [459.21, 649.13], + 'C6' => [323.15, 459.21], + 'C7' => [229.61, 323.15], + 'C8' => [161.57, 229.61], + 'C9' => [113.39, 161.57], + 'C10' => [79.37, 113.39], + 'RA0' => [2437.80, 3458.27], + 'RA1' => [1729.13, 2437.80], + 'RA2' => [1218.90, 1729.13], + 'RA3' => [864.57, 1218.90], + 'RA4' => [609.45, 864.57], + 'SRA0' => [2551.18, 3628.35], + 'SRA1' => [1814.17, 2551.18], + 'SRA2' => [1275.59, 1814.17], + 'SRA3' => [907.09, 1275.59], + 'SRA4' => [637.80, 907.09], + 'LETTER' => [612.00, 792.00], + 'LEGAL' => [612.00, 1008.00], + 'LEDGER' => [1224.00, 792.00], + 'TABLOID' => [792.00, 1224.00], + 'EXECUTIVE' => [521.86, 756.00], + 'FOLIO' => [612.00, 936.00], + 'B' => [362.83, 561.26], // 'B' format paperback size 128x198mm + 'A' => [314.65, 504.57], // 'A' format paperback size 111x178mm + 'DEMY' => [382.68, 612.28], // 'Demy' format paperback size 135x216mm + 'ROYAL' => [433.70, 663.30], // 'Royal' format paperback size 153x234mm + ]; + + if (!isset($formats[$format])) { + throw new \Mpdf\MpdfException(sprintf('Unknown page format %s', $format)); + } + + return $formats[$format]; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection.php b/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection.php new file mode 100644 index 0000000..8a63da9 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection.php @@ -0,0 +1,360 @@ +<?php + +namespace Mpdf\Pdf; + +use Mpdf\Pdf\Protection\UniqidGenerator; + +class Protection +{ + + /** + * @var string + */ + private $lastRc4Key; + + /** + * @var string + */ + private $lastRc4KeyC; + + /** + * @var bool + */ + private $useRC128Encryption; + + /** + * @var string + */ + private $encryptionKey; + + /** + * @var string + */ + private $padding; + + /** + * @var string + */ + private $uniqid; + + /** + * @var string + */ + private $oValue; + + /** + * @var string + */ + private $uValue; + + /** + * @var string + */ + private $pValue; + + /** + * @var int[] Array of permission => byte representation + */ + private $options; + + /** + * @var \Mpdf\Pdf\Protection\UniqidGenerator + */ + private $uniqidGenerator; + + public function __construct(UniqidGenerator $uniqidGenerator) + { + if (!function_exists('random_int') || !function_exists('random_bytes')) { + throw new \Mpdf\MpdfException( + 'Unable to set PDF file protection, CSPRNG Functions are not available. ' + . 'Use paragonie/random_compat polyfill or upgrade to PHP 7.' + ); + } + + $this->uniqidGenerator = $uniqidGenerator; + + $this->lastRc4Key = ''; + + $this->padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08" . + "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A"; + + $this->useRC128Encryption = false; + + $this->options = [ + 'print' => 4, // bit 3 + 'modify' => 8, // bit 4 + 'copy' => 16, // bit 5 + 'annot-forms' => 32, // bit 6 + 'fill-forms' => 256, // bit 9 + 'extract' => 512, // bit 10 + 'assemble' => 1024, // bit 11 + 'print-highres' => 2048 // bit 12 + ]; + } + + /** + * @param array $permissions + * @param string $user_pass + * @param string $owner_pass + * @param int $length + * + * @return bool + */ + public function setProtection($permissions = [], $user_pass = '', $owner_pass = null, $length = 40) + { + if (is_string($permissions) && strlen($permissions) > 0) { + $permissions = [$permissions]; + } elseif (!is_array($permissions)) { + return false; + } + + $protection = $this->getProtectionBitsFromOptions($permissions); + + if ($length === 128) { + $this->useRC128Encryption = true; + } elseif ($length !== 40) { + throw new \Mpdf\MpdfException('PDF protection only allows lenghts of 40 or 128'); + } + + if ($owner_pass === null) { + $owner_pass = bin2hex(random_bytes(23)); + } + + $this->generateEncryptionKey($user_pass, $owner_pass, $protection); + + return true; + } + + /** + * Compute key depending on object number where the encrypted data is stored + * + * @param int $n + * + * @return string + */ + public function objectKey($n) + { + if ($this->useRC128Encryption) { + $len = 16; + } else { + $len = 10; + } + + return substr($this->md5toBinary($this->encryptionKey . pack('VXxx', $n)), 0, $len); + } + + /** + * RC4 is the standard encryption algorithm used in PDF format + * + * @param string $key + * @param string $text + * + * @return string + */ + public function rc4($key, $text) + { + if ($this->lastRc4Key != $key) { + $k = str_repeat($key, 256 / strlen($key) + 1); + $rc4 = range(0, 255); + $j = 0; + for ($i = 0; $i < 256; $i++) { + $t = $rc4[$i]; + $j = ($j + $t + ord($k[$i])) % 256; + $rc4[$i] = $rc4[$j]; + $rc4[$j] = $t; + } + $this->lastRc4Key = $key; + $this->lastRc4KeyC = $rc4; + } else { + $rc4 = $this->lastRc4KeyC; + } + + $len = strlen($text); + $a = 0; + $b = 0; + $out = ''; + for ($i = 0; $i < $len; $i++) { + $a = ($a + 1) % 256; + $t = $rc4[$a]; + $b = ($b + $t) % 256; + $rc4[$a] = $rc4[$b]; + $rc4[$b] = $t; + $k = $rc4[($rc4[$a] + $rc4[$b]) % 256]; + $out .= chr(ord($text[$i]) ^ $k); + } + + return $out; + } + + /** + * @return mixed + */ + public function getUseRC128Encryption() + { + return $this->useRC128Encryption; + } + + /** + * @return mixed + */ + public function getUniqid() + { + return $this->uniqid; + } + + /** + * @return mixed + */ + public function getOValue() + { + return $this->oValue; + } + + /** + * @return mixed + */ + public function getUValue() + { + return $this->uValue; + } + + /** + * @return mixed + */ + public function getPValue() + { + return $this->pValue; + } + + private function getProtectionBitsFromOptions($permissions) + { + // bit 31 = 1073741824 + // bit 32 = 2147483648 + // bits 13-31 = 2147479552 + // bits 13-32 = 4294963200 + 192 = 4294963392 + + $protection = 4294963392; // bits 7, 8, 13-32 + + foreach ($permissions as $permission) { + if (!isset($this->options[$permission])) { + throw new \Mpdf\MpdfException(sprintf('Invalid permission type "%s"', $permission)); + } + if ($this->options[$permission] > 32) { + $this->useRC128Encryption = true; + } + if (isset($this->options[$permission])) { + $protection += $this->options[$permission]; + } + } + + return $protection; + } + + private function oValue($user_pass, $owner_pass) + { + $tmp = $this->md5toBinary($owner_pass); + if ($this->useRC128Encryption) { + for ($i = 0; $i < 50; ++$i) { + $tmp = $this->md5toBinary($tmp); + } + } + if ($this->useRC128Encryption) { + $keybytelen = (128 / 8); + } else { + $keybytelen = (40 / 8); + } + $owner_rc4_key = substr($tmp, 0, $keybytelen); + $enc = $this->rc4($owner_rc4_key, $user_pass); + if ($this->useRC128Encryption) { + $len = strlen($owner_rc4_key); + for ($i = 1; $i <= 19; ++$i) { + $key = ''; + for ($j = 0; $j < $len; ++$j) { + $key .= chr(ord($owner_rc4_key[$j]) ^ $i); + } + $enc = $this->rc4($key, $enc); + } + } + + return $enc; + } + + private function uValue() + { + if ($this->useRC128Encryption) { + $tmp = $this->md5toBinary($this->padding . $this->hexToString($this->uniqid)); + $enc = $this->rc4($this->encryptionKey, $tmp); + $len = strlen($tmp); + for ($i = 1; $i <= 19; ++$i) { + $key = ''; + for ($j = 0; $j < $len; ++$j) { + $key .= chr(ord($this->encryptionKey[$j]) ^ $i); + } + $enc = $this->rc4($key, $enc); + } + $enc .= str_repeat("\x00", 16); + + return substr($enc, 0, 32); + } else { + return $this->rc4($this->encryptionKey, $this->padding); + } + } + + private function generateEncryptionKey($user_pass, $owner_pass, $protection) + { + // Pad passwords + $user_pass = substr($user_pass . $this->padding, 0, 32); + $owner_pass = substr($owner_pass . $this->padding, 0, 32); + + $this->oValue = $this->oValue($user_pass, $owner_pass); + + $this->uniqid = $this->uniqidGenerator->generate(); + + // Compute encyption key + if ($this->useRC128Encryption) { + $keybytelen = (128 / 8); + } else { + $keybytelen = (40 / 8); + } + + $prot = sprintf('%032b', $protection); + + $perms = chr(bindec(substr($prot, 24, 8))); + $perms .= chr(bindec(substr($prot, 16, 8))); + $perms .= chr(bindec(substr($prot, 8, 8))); + $perms .= chr(bindec(substr($prot, 0, 8))); + + $tmp = $this->md5toBinary($user_pass . $this->oValue . $perms . $this->hexToString($this->uniqid)); + + if ($this->useRC128Encryption) { + for ($i = 0; $i < 50; ++$i) { + $tmp = $this->md5toBinary(substr($tmp, 0, $keybytelen)); + } + } + + $this->encryptionKey = substr($tmp, 0, $keybytelen); + + $this->uValue = $this->uValue(); + $this->pValue = $protection; + } + + private function md5toBinary($string) + { + return pack('H*', md5($string)); + } + + private function hexToString($hs) + { + $s = ''; + $len = strlen($hs); + if (($len % 2) != 0) { + $hs .= '0'; + ++$len; + } + for ($i = 0; $i < $len; $i += 2) { + $s .= chr(hexdec($hs[$i] . $hs[($i + 1)])); + } + + return $s; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php b/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php new file mode 100644 index 0000000..54753d4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Pdf/Protection/UniqidGenerator.php @@ -0,0 +1,32 @@ +<?php + +namespace Mpdf\Pdf\Protection; + +class UniqidGenerator +{ + + public function __construct() + { + if (!function_exists('random_int') || !function_exists('random_bytes')) { + throw new \Mpdf\MpdfException( + 'Unable to set PDF file protection, CSPRNG Functions are not available. ' + . 'Use paragonie/random_compat polyfill or upgrade to PHP 7.' + ); + } + } + + /** + * @return string + */ + public function generate() + { + $chars = 'ABCDEF1234567890'; + $id = ''; + + for ($i = 0; $i < 32; $i++) { + $id .= $chars[random_int(0, 15)]; + } + + return md5($id); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/RemoteContentFetcher.php b/lib/MPDF/vendor/mpdf/mpdf/src/RemoteContentFetcher.php new file mode 100644 index 0000000..f1547ec --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/RemoteContentFetcher.php @@ -0,0 +1,148 @@ +<?php + +namespace Mpdf; + +use Mpdf\Utils\Arrays; +use Psr\Log\LoggerInterface; +use Mpdf\Log\Context as LogContext; + +class RemoteContentFetcher implements \Psr\Log\LoggerAwareInterface +{ + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + public function __construct(Mpdf $mpdf, LoggerInterface $logger) + { + $this->mpdf = $mpdf; + $this->logger = $logger; + } + + public function getFileContentsByCurl($url) + { + $this->logger->debug(sprintf('Fetching (cURL) content of remote URL "%s"', $url), ['context' => LogContext::REMOTE_CONTENT]); + + $ch = curl_init($url); + + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1'); // mPDF 5.7.4 + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_NOBODY, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->mpdf->curlTimeout); + + if ($this->mpdf->curlFollowLocation) { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + } + + if ($this->mpdf->curlAllowUnsafeSslRequests) { + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + } + + if (is_file($this->mpdf->curlCaCertificate)) { + curl_setopt($ch, CURLOPT_CAINFO, $this->mpdf->curlCaCertificate); + } + + if ($this->mpdf->curlProxy) { + curl_setopt($ch, CURLOPT_PROXY, $this->mpdf->curlProxy); + if ($this->mpdf->curlProxyAuth) { + curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->mpdf->curlProxyAuth); + } + } + + $data = curl_exec($ch); + + if (curl_error($ch)) { + $message = sprintf('cURL error: "%s"', curl_error($ch)); + $this->logger->error($message, ['context' => LogContext::REMOTE_CONTENT]); + + if ($this->mpdf->debug) { + throw new \Mpdf\MpdfException($message); + } + } + + $info = curl_getinfo($ch); + if (isset($info['http_code']) && $info['http_code'] !== 200) { + $message = sprintf('HTTP error: %d', $info['http_code']); + $this->logger->error($message, ['context' => LogContext::REMOTE_CONTENT]); + + if ($this->mpdf->debug) { + throw new \Mpdf\MpdfException($message); + } + } + + curl_close($ch); + + return $data; + } + + public function getFileContentsBySocket($url) + { + $this->logger->debug(sprintf('Fetching (socket) content of remote URL "%s"', $url), ['context' => LogContext::REMOTE_CONTENT]); + // mPDF 5.7.3 + + $timeout = 1; + $p = parse_url($url); + + $file = Arrays::get($p, 'path', ''); + $scheme = Arrays::get($p, 'scheme', ''); + $port = Arrays::get($p, 'port', 80); + $prefix = ''; + + if ($scheme === 'https') { + $prefix = 'ssl://'; + $port = Arrays::get($p, 'port', 443); + } + + $query = Arrays::get($p, 'query', null); + if ($query) { + $file .= '?' . $query; + } + + if (!($fh = @fsockopen($prefix . $p['host'], $port, $errno, $errstr, $timeout))) { + $this->logger->error(sprintf('Socket error "%s": "%s"', $errno, $errstr), ['context' => LogContext::REMOTE_CONTENT]); + return false; + } + + $getstring = 'GET ' . $file . " HTTP/1.0 \r\n" . + 'Host: ' . $p['host'] . " \r\n" . + "Connection: close\r\n\r\n"; + + fwrite($fh, $getstring); + + // Get rid of HTTP header + $s = fgets($fh, 1024); + if (!$s) { + return false; + } + + while (!feof($fh)) { + $s = fgets($fh, 1024); + if ($s === "\r\n") { + break; + } + } + + $data = ''; + + while (!feof($fh)) { + $data .= fgets($fh, 1024); + } + + fclose($fh); + + return $data; + } + + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/ServiceFactory.php b/lib/MPDF/vendor/mpdf/mpdf/src/ServiceFactory.php new file mode 100644 index 0000000..f81e6f7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/ServiceFactory.php @@ -0,0 +1,173 @@ +<?php + +namespace Mpdf; + +use Mpdf\Color\ColorConverter; +use Mpdf\Color\ColorModeConverter; +use Mpdf\Color\ColorSpaceRestrictor; + +use Mpdf\Fonts\FontCache; +use Mpdf\Fonts\FontFileFinder; + +use Mpdf\Image\ImageProcessor; + +use Mpdf\Pdf\Protection; +use Mpdf\Pdf\Protection\UniqidGenerator; + +use Mpdf\Writer\BaseWriter; +use Mpdf\Writer\BackgroundWriter; +use Mpdf\Writer\ColorWriter; +use Mpdf\Writer\BookmarkWriter; +use Mpdf\Writer\FontWriter; +use Mpdf\Writer\FormWriter; +use Mpdf\Writer\ImageWriter; +use Mpdf\Writer\JavaScriptWriter; +use Mpdf\Writer\MetadataWriter; +use Mpdf\Writer\OptionalContentWriter; +use Mpdf\Writer\PageWriter; + +use Mpdf\Writer\ResourceWriter; +use Psr\Log\LoggerInterface; + +class ServiceFactory +{ + + public function getServices( + Mpdf $mpdf, + LoggerInterface $logger, + $config, + $restrictColorSpace, + $languageToFont, + $scriptToLanguage, + $fontDescriptor, + $bmp, + $directWrite, + $wmf + ) { + $sizeConverter = new SizeConverter($mpdf->dpi, $mpdf->default_font_size, $mpdf, $logger); + + $colorModeConverter = new ColorModeConverter(); + $colorSpaceRestrictor = new ColorSpaceRestrictor( + $mpdf, + $colorModeConverter, + $restrictColorSpace + ); + $colorConverter = new ColorConverter($mpdf, $colorModeConverter, $colorSpaceRestrictor); + + $tableOfContents = new TableOfContents($mpdf, $sizeConverter); + + $cache = new Cache($config['tempDir']); + $fontCache = new FontCache(new Cache($config['tempDir'] . '/ttfontdata')); + + $fontFileFinder = new FontFileFinder($config['fontDir']); + + $cssManager = new CssManager($mpdf, $cache, $sizeConverter, $colorConverter); + + $otl = new Otl($mpdf, $fontCache); + + $protection = new Protection(new UniqidGenerator()); + + $writer = new BaseWriter($mpdf, $protection); + + $gradient = new Gradient($mpdf, $sizeConverter, $colorConverter, $writer); + + $formWriter = new FormWriter($mpdf, $writer); + + $form = new Form($mpdf, $otl, $colorConverter, $writer, $formWriter); + + $hyphenator = new Hyphenator($mpdf); + + $remoteContentFetcher = new RemoteContentFetcher($mpdf, $logger); + + $imageProcessor = new ImageProcessor( + $mpdf, + $otl, + $cssManager, + $sizeConverter, + $colorConverter, + $colorModeConverter, + $cache, + $languageToFont, + $scriptToLanguage, + $remoteContentFetcher, + $logger + ); + + $tag = new Tag( + $mpdf, + $cache, + $cssManager, + $form, + $otl, + $tableOfContents, + $sizeConverter, + $colorConverter, + $imageProcessor, + $languageToFont + ); + + $fontWriter = new FontWriter($mpdf, $writer, $fontCache, $fontDescriptor); + $metadataWriter = new MetadataWriter($mpdf, $writer, $form, $protection, $logger); + $imageWriter = new ImageWriter($mpdf, $writer); + $pageWriter = new PageWriter($mpdf, $form, $writer, $metadataWriter); + $bookmarkWriter = new BookmarkWriter($mpdf, $writer); + $optionalContentWriter = new OptionalContentWriter($mpdf, $writer); + $colorWriter = new ColorWriter($mpdf, $writer); + $backgroundWriter = new BackgroundWriter($mpdf, $writer); + $javaScriptWriter = new JavaScriptWriter($mpdf, $writer); + + $resourceWriter = new ResourceWriter( + $mpdf, + $writer, + $colorWriter, + $fontWriter, + $imageWriter, + $formWriter, + $optionalContentWriter, + $backgroundWriter, + $bookmarkWriter, + $metadataWriter, + $javaScriptWriter, + $logger + ); + + return [ + 'otl' => $otl, + 'bmp' => $bmp, + 'cache' => $cache, + 'cssManager' => $cssManager, + 'directWrite' => $directWrite, + 'fontCache' => $fontCache, + 'fontFileFinder' => $fontFileFinder, + 'form' => $form, + 'gradient' => $gradient, + 'tableOfContents' => $tableOfContents, + 'tag' => $tag, + 'wmf' => $wmf, + 'sizeConverter' => $sizeConverter, + 'colorConverter' => $colorConverter, + 'hyphenator' => $hyphenator, + 'remoteContentFetcher' => $remoteContentFetcher, + 'imageProcessor' => $imageProcessor, + 'protection' => $protection, + + 'languageToFont' => $languageToFont, + 'scriptToLanguage' => $scriptToLanguage, + + 'writer' => $writer, + 'fontWriter' => $fontWriter, + 'metadataWriter' => $metadataWriter, + 'imageWriter' => $imageWriter, + 'formWriter' => $formWriter, + 'pageWriter' => $pageWriter, + 'bookmarkWriter' => $bookmarkWriter, + 'optionalContentWriter' => $optionalContentWriter, + 'colorWriter' => $colorWriter, + 'backgroundWriter' => $backgroundWriter, + 'javaScriptWriter' => $javaScriptWriter, + + 'resourceWriter' => $resourceWriter + ]; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Indic.php b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Indic.php new file mode 100644 index 0000000..28e3001 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Indic.php @@ -0,0 +1,1945 @@ +<?php + +namespace Mpdf\Shaper; + +use Mpdf\Ucdn; + +class Indic +{ + /* FROM hb-ot-shape-complex-indic-private.hh */ + + // indic_category + const OT_X = 0; + const OT_C = 1; + const OT_V = 2; + const OT_N = 3; + const OT_H = 4; + const OT_ZWNJ = 5; + const OT_ZWJ = 6; + const OT_M = 7; /* Matra or Dependent Vowel */ + const OT_SM = 8; + const OT_VD = 9; + const OT_A = 10; + const OT_NBSP = 11; + const OT_DOTTEDCIRCLE = 12; /* Not in the spec, but special in Uniscribe. /Very very/ special! */ + const OT_RS = 13; /* Register Shifter, used in Khmer OT spec */ + const OT_COENG = 14; + const OT_REPHA = 15; + + const OT_RA = 16; /* Not explicitly listed in the OT spec, but used in the grammar. */ + const OT_CM = 17; + + /* Visual positions in a syllable from left to right. */ + /* FROM hb-ot-shape-complex-indic-private.hh */ + + // indic_position + const POS_START = 0; + + const POS_RA_TO_BECOME_REPH = 1; + const POS_PRE_M = 2; + const POS_PRE_C = 3; + + const POS_BASE_C = 4; + const POS_AFTER_MAIN = 5; + + const POS_ABOVE_C = 6; + + const POS_BEFORE_SUB = 7; + const POS_BELOW_C = 8; + const POS_AFTER_SUB = 9; + + const POS_BEFORE_POST = 10; + const POS_POST_C = 11; + const POS_AFTER_POST = 12; + + const POS_FINAL_C = 13; + const POS_SMVD = 14; + + const POS_END = 15; + + /* + * Basic features. + * These features are applied in order, one at a time, after initial_reordering. + */ + + /* + * Must be in the same order as the indic_features array. Ones starting with _ are F_GLOBAL + * Ones without the _ are only applied where the mask says! + */ + + const _NUKT = 0; + const _AKHN = 1; + const RPHF = 2; + const _RKRF = 3; + const PREF = 4; + const BLWF = 5; + const HALF = 6; + const ABVF = 7; + const PSTF = 8; + const CFAR = 9; // Khmer only + const _VATU = 10; + const _CJCT = 11; + const INIT = 12; + + // Based on indic_category used to make string to find syllables + // OT_ to string character (using e.g. OT_C from INDIC) hb-ot-shape-complex-indic-private.hh + public static $indic_category_char = [ + 'x', + 'C', + 'V', + 'N', + 'H', + 'Z', + 'J', + 'M', + 'S', + 'v', + 'A', /* Spec gives Andutta U+0952 as OT_A. However, testing shows that Uniscribe + * treats U+0951..U+0952 all as OT_VD - see set_indic_properties */ + 's', + 'D', + 'F', /* Register shift Khmer only */ + 'G', /* Khmer only */ + 'r', /* 0D4E (dot reph) only one in Malayalam */ + 'R', + 'm', /* Consonant medial only used in Indic 0A75 in Gurmukhi (0A00..0A7F) : also in Lao, Myanmar, Tai Tham, Javanese & Cham */ + ]; + + public static function set_indic_properties(&$info, $scriptblock) + { + $u = $info['uni']; + $type = self::indic_get_categories($u); + $cat = ($type & 0x7F); + $pos = ($type >> 8); + + /* + * Re-assign category + */ + + if ($u == 0x17D1) { + $cat = self::OT_X; + } + + if ($cat == self::OT_X && self::in_range($u, 0x17CB, 0x17D3)) { /* Khmer Various signs */ + /* These are like Top Matras. */ + $cat = self::OT_M; + $pos = self::POS_ABOVE_C; + } + + if ($u == 0x17C6) { + $cat = self::OT_N; + } /* Khmer Bindu doesn't like to be repositioned. */ + + if ($u == 0x17D2) { + $cat = self::OT_COENG; + } /* Khmer coeng */ + + /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe + * treats U+0951..U+0952 all as OT_VD. + * TESTS: + * U+092E,U+0947,U+0952 + * U+092E,U+0952,U+0947 + * U+092E,U+0947,U+0951 + * U+092E,U+0951,U+0947 + * */ + //if ($u == 0x0952) $cat = self::OT_A; + if (self::in_range($u, 0x0951, 0x0954)) { + $cat = self::OT_VD; + } + + if ($u == 0x200C) { + $cat = self::OT_ZWNJ; + } elseif ($u == 0x200D) { + $cat = self::OT_ZWJ; + } elseif ($u == 0x25CC) { + $cat = self::OT_DOTTEDCIRCLE; + } elseif ($u == 0x0A71) { + $cat = self::OT_SM; + } /* GURMUKHI ADDAK. More like consonant medial. like 0A75. */ + + if ($cat == self::OT_REPHA) { + /* There are two kinds of characters marked as Repha: + * - The ones that are GenCat=Mn are already positioned visually, ie. after base. (eg. Khmer) + * - The ones that are GenCat=Lo is encoded logically, ie. beginning of syllable. (eg. Malayalam) + * + * We recategorize the first kind to look like a Nukta and attached to the base directly. + */ + if ($info['general_category'] == Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { + $cat = self::OT_N; + } + } + + /* + * Re-assign position. + */ + + if ((self::FLAG($cat) & (self::FLAG(self::OT_C) | self::FLAG(self::OT_CM) | self::FLAG(self::OT_RA) | self::FLAG(self::OT_V) | self::FLAG(self::OT_NBSP) | self::FLAG(self::OT_DOTTEDCIRCLE)))) { // = CONSONANT_FLAGS like is_consonant + if ($scriptblock == Ucdn::SCRIPT_KHMER) { + $pos = self::POS_BELOW_C; + } /* Khmer differs from Indic here. */ + else { + $pos = self::POS_BASE_C; + } /* Will recategorize later based on font lookups. */ + + if (self::is_ra($u)) { + $cat = self::OT_RA; + } + } elseif ($cat == self::OT_M) { + $pos = self::matra_position($u, $pos); + } elseif ($cat == self::OT_SM || $cat == self::OT_VD) { + $pos = self::POS_SMVD; + } + + if ($u == 0x0B01) { + $pos = self::POS_BEFORE_SUB; + } /* Oriya Bindu is BeforeSub in the spec. */ + + $info['indic_category'] = $cat; + $info['indic_position'] = $pos; + } + + // syllable_type + const CONSONANT_SYLLABLE = 0; + const VOWEL_SYLLABLE = 1; + const STANDALONE_CLUSTER = 2; + const BROKEN_CLUSTER = 3; + const NON_INDIC_CLUSTER = 4; + + public static function set_syllables(&$o, $s, &$broken_syllables) + { + $ptr = 0; + $syllable_serial = 1; + $broken_syllables = false; + + while ($ptr < strlen($s)) { + $match = ''; + $syllable_length = 1; + $syllable_type = self::NON_INDIC_CLUSTER; + // CONSONANT_SYLLABLE Consonant syllable + // From OT spec: + if (preg_match('/^([CR]m*[N]?(H[ZJ]?|[ZJ]H))*[CR]m*[N]?[A]?(H[ZJ]?|[M]*[N]?[H]?)?[S]?[v]{0,2}/', substr($s, $ptr), $ma)) { + // From HarfBuzz: + //if (preg_match('/^r?([CR]J?(Z?[N]{0,2})?[ZJ]?H(J[N]?)?){0,4}[CR]J?(Z?[N]{0,2})?A?((([ZJ]?H(J[N]?)?)|HZ)|(HJ)?([ZJ]{0,3}M[N]?(H|JHJR)?){0,4})?(S[Z]?)?[v]{0,2}/', substr($s,$ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::CONSONANT_SYLLABLE; + } // VOWEL_SYLLABLE Vowel-based syllable + // From OT spec: + elseif (preg_match('/^(RH|r)?V[N]?([ZJ]?H[CR]m*|J[CR]m*)?([M]*[N]?[H]?)?[S]?[v]{0,2}/', substr($s, $ptr), $ma)) { + // From HarfBuzz: + //else if (preg_match('/^(RH|r)?V(Z?[N]{0,2})?(J|([ZJ]?H(J[N]?)?[CR]J?(Z?[N]{0,2})?){0,4}((([ZJ]?H(J[N]?)?)|HZ)|(HJ)?([ZJ]{0,3}M[N]?(H|JHJR)?){0,4})?(S[Z]?)?[v]{0,2})/', substr($s,$ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::VOWEL_SYLLABLE; + } /* Apply only if it's a word start. */ + // STANDALONE_CLUSTER Stand Alone syllable at start of word + // From OT spec: + elseif (($ptr == 0 || + $o[$ptr - 1]['general_category'] < Ucdn::UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER || + $o[$ptr - 1]['general_category'] > Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK + ) && (preg_match('/^(RH|r)?[sD][N]?([ZJ]?H[CR]m*)?([M]*[N]?[H]?)?[S]?[v]{0,2}/', substr($s, $ptr), $ma))) { + // From HarfBuzz: + // && (preg_match('/^(RH|r)?[sD](Z?[N]{0,2})?(([ZJ]?H(J[N]?)?)[CR]J?(Z?[N]{0,2})?){0,4}((([ZJ]?H(J[N]?)?)|HZ)|(HJ)?([ZJ]{0,3}M[N]?(H|JHJR)?){0,4})?(S[Z]?)?[v]{0,2}/', substr($s,$ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::STANDALONE_CLUSTER; + } // BROKEN_CLUSTER syllable + elseif (preg_match('/^(RH|r)?[N]?([ZJ]?H[CR])?([M]*[N]?[H]?)?[S]?[v]{0,2}/', substr($s, $ptr), $ma)) { + // From HarfBuzz: + //else if (preg_match('/^(RH|r)?(Z?[N]{0,2})?(([ZJ]?H(J[N]?)?)[CR]J?(Z?[N]{0,2})?){0,4}((([ZJ]?H(J[N]?)?)|HZ)|(HJ)?([ZJ]{0,3}M[N]?(H|JHJR)?){0,4})(S[Z]?)?[v]{0,2}/', substr($s,$ptr), $ma)) { + if (strlen($ma[0])) { // May match blank + $syllable_length = strlen($ma[0]); + $syllable_type = self::BROKEN_CLUSTER; + $broken_syllables = true; + } + } + + for ($i = $ptr; $i < $ptr + $syllable_length; $i++) { + $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; + } + $ptr += $syllable_length; + $syllable_serial++; + if ($syllable_serial == 16) { + $syllable_serial = 1; + } + } + } + + public static function set_syllables_sinhala(&$o, $s, &$broken_syllables) + { + $ptr = 0; + $syllable_serial = 1; + $broken_syllables = false; + + while ($ptr < strlen($s)) { + $match = ''; + $syllable_length = 1; + $syllable_type = self::NON_INDIC_CLUSTER; + // CONSONANT_SYLLABLE Consonant syllable + // From OT spec: + if (preg_match('/^([CR]HJ|[CR]JH){0,8}[CR][HM]{0,3}[S]{0,1}/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::CONSONANT_SYLLABLE; + } // VOWEL_SYLLABLE Vowel-based syllable + // From OT spec: + elseif (preg_match('/^V[S]{0,1}/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::VOWEL_SYLLABLE; + } + + for ($i = $ptr; $i < $ptr + $syllable_length; $i++) { + $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; + } + $ptr += $syllable_length; + $syllable_serial++; + if ($syllable_serial == 16) { + $syllable_serial = 1; + } + } + } + + public static function set_syllables_khmer(&$o, $s, &$broken_syllables) + { + $ptr = 0; + $syllable_serial = 1; + $broken_syllables = false; + + while ($ptr < strlen($s)) { + $match = ''; + $syllable_length = 1; + $syllable_type = self::NON_INDIC_CLUSTER; + // CONSONANT_SYLLABLE Consonant syllable + if (preg_match('/^r?([CR]J?((Z?F)?[N]{0,2})?[ZJ]?G(JN?)?){0,4}[CR]J?((Z?F)?[N]{0,2})?A?((([ZJ]?G(JN?)?)|GZ)|(GJ)?([ZJ]{0,3}MN?(H|JHJR)?){0,4})?(G([CR]J?((Z?F)?[N]{0,2})?|V))?(SZ?)?[v]{0,2}/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::CONSONANT_SYLLABLE; + } // VOWEL_SYLLABLE Vowel-based syllable + elseif (preg_match('/^(RH|r)?V((Z?F)?[N]{0,2})?(J|([ZJ]?G(JN?)?[CR]J?((Z?F)?[N]{0,2})?){0,4}((([ZJ]?G(JN?)?)|GZ)|(GJ)?([ZJ]{0,3}MN?(H|JHJR)?){0,4})?(G([CR]J?((Z?F)?[N]{0,2})?|V))?(SZ?)?[v]{0,2})/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::VOWEL_SYLLABLE; + } // BROKEN_CLUSTER syllable + elseif (preg_match('/^(RH|r)?((Z?F)?[N]{0,2})?(([ZJ]?G(JN?)?)[CR]J?((Z?F)?[N]{0,2})?){0,4}((([ZJ]?G(JN?)?)|GZ)|(GJ)?([ZJ]{0,3}MN?(H|JHJR)?){0,4})(G([CR]J?((Z?F)?[N]{0,2})?|V))?(SZ?)?[v]{0,2}/', substr($s, $ptr), $ma)) { + if (strlen($ma[0])) { // May match blank + $syllable_length = strlen($ma[0]); + $syllable_type = self::BROKEN_CLUSTER; + $broken_syllables = true; + } + } + + for ($i = $ptr; $i < $ptr + $syllable_length; $i++) { + $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; + } + $ptr += $syllable_length; + $syllable_serial++; + if ($syllable_serial == 16) { + $syllable_serial = 1; + } + } + } + + public static function initial_reordering(&$info, $GSUBdata, $broken_syllables, $indic_config, $scriptblock, $is_old_spec, $dottedcircle) + { + + self::update_consonant_positions($info, $GSUBdata); + + if ($broken_syllables && $dottedcircle) { + self::insert_dotted_circles($info, $dottedcircle); + } + + $count = count($info); + if (!$count) { + return; + } + $last = 0; + $last_syllable = $info[0]['syllable']; + for ($i = 1; $i < $count; $i++) { + if ($last_syllable != $info[$i]['syllable']) { + self::initial_reordering_syllable($info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $last, $i); + $last = $i; + $last_syllable = $info[$last]['syllable']; + } + } + self::initial_reordering_syllable($info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $last, $count); + } + + public static function update_consonant_positions(&$info, $GSUBdata) + { + $count = count($info); + for ($i = 0; $i < $count; $i++) { + if ($info[$i]['indic_position'] == self::POS_BASE_C) { + $c = $info[$i]['uni']; + // If would substitute... + if (isset($GSUBdata['pref'][$c])) { + $info[$i]['indic_position'] = self::POS_POST_C; + } elseif (isset($GSUBdata['blwf'][$c])) { + $info[$i]['indic_position'] = self::POS_BELOW_C; + } elseif (isset($GSUBdata['pstf'][$c])) { + $info[$i]['indic_position'] = self::POS_POST_C; + } + } + } + } + + public static function insert_dotted_circles(&$info, $dottedcircle) + { + $idx = 0; + $last_syllable = 0; + while ($idx < count($info)) { + $syllable = $info[$idx]['syllable']; + $syllable_type = ($syllable & 0x0F); + if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) { + $last_syllable = $syllable; + + $dottedcircle[0]['syllable'] = $info[$idx]['syllable']; + + /* Insert dottedcircle after possible Repha. */ + while ($idx < count($info) && $last_syllable == $info[$idx]['syllable'] && $info[$idx]['indic_category'] == self::OT_REPHA) { + $idx++; + } + array_splice($info, $idx, 0, $dottedcircle); + } else { + $idx++; + } + } + + // I am not sue how this code below got in here, since $idx should now be > count($info) and thus invalid. + // In case I am missing something(!) I'll leave a warning here for now: + if (isset($info[$idx])) { + throw new \Mpdf\MpdfException('Unexpected error occured in Indic processing'); + } + // In case of final bloken cluster... + //$syllable = $info[$idx]['syllable']; + //$syllable_type = ($syllable & 0x0F); + //if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) { + // $dottedcircle[0]['syllable'] = $info[$idx]['syllable']; + // array_splice($info, $idx, 0, $dottedcircle); + //} + } + + /* Rules from: + * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ + + public static function initial_reordering_syllable(&$info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $start, $end) + { + /* vowel_syllable: We made the vowels look like consonants. So uses the consonant logic! */ + /* broken_cluster: We already inserted dotted-circles, so just call the standalone_cluster. */ + /* standalone_cluster: We treat NBSP/dotted-circle as if they are consonants, so we should just chain. */ + + $syllable_type = ($info[$start]['syllable'] & 0x0F); + if ($syllable_type == self::NON_INDIC_CLUSTER) { + return; + } + if ($syllable_type == self::BROKEN_CLUSTER || $syllable_type == self::STANDALONE_CLUSTER) { + //if ($uniscribe_bug_compatible) { + /* For dotted-circle, this is what Uniscribe does: + * If dotted-circle is the last glyph, it just does nothing. + * i.e. It doesn't form Reph. */ + if ($info[$end - 1]['indic_category'] == self::OT_DOTTEDCIRCLE) { + return; + } + } + + /* 1. Find base consonant: + * + * The shaping engine finds the base consonant of the syllable, using the + * following algorithm: starting from the end of the syllable, move backwards + * until a consonant is found that does not have a below-base or post-base + * form (post-base forms have to follow below-base forms), or that is not a + * pre-base reordering Ra, or arrive at the first consonant. The consonant + * stopped at will be the base. + * + * o If the syllable starts with Ra + Halant (in a script that has Reph) + * and has more than one consonant, Ra is excluded from candidates for + * base consonants. + */ + + $base = $end; + $has_reph = false; + $limit = $start; + + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + /* -> If the syllable starts with Ra + Halant (in a script that has Reph) + * and has more than one consonant, Ra is excluded from candidates for + * base consonants. */ + if (count($GSUBdata['rphf']) /* ?? $indic_plan->mask_array[RPHF] */ && $start + 3 <= $end && + ( + ($indic_config[4] == self::REPH_MODE_IMPLICIT && !self::is_joiner($info[$start + 2])) || + ($indic_config[4] == self::REPH_MODE_EXPLICIT && $info[$start + 2]['indic_category'] == self::OT_ZWJ) + )) { + /* See if it matches the 'rphf' feature. */ + //$glyphs = array($info[$start]['uni'], $info[$start + 1]['uni']); + //if ($indic_plan->rphf->would_substitute ($glyphs, count($glyphs), true, face)) { + if (isset($GSUBdata['rphf'][$info[$start]['uni']]) && self::is_halant_or_coeng($info[$start + 1])) { + $limit += 2; + while ($limit < $end && self::is_joiner($info[$limit])) { + $limit++; + } + $base = $start; + $has_reph = true; + } + } elseif ($indic_config[4] == self::REPH_MODE_LOG_REPHA && $info[$start]['indic_category'] == self::OT_REPHA) { + $limit += 1; + while ($limit < $end && self::is_joiner($info[$limit])) { + $limit++; + } + $base = $start; + $has_reph = true; + } + } + + switch ($indic_config[2]) { // base_pos + case self::BASE_POS_LAST: + /* -> starting from the end of the syllable, move backwards */ + $i = $end; + $seen_below = false; + do { + $i--; + /* -> until a consonant is found */ + if (self::is_consonant($info[$i])) { + /* -> that does not have a below-base or post-base form + * (post-base forms have to follow below-base forms), */ + if ($info[$i]['indic_position'] != self::POS_BELOW_C && ($info[$i]['indic_position'] != self::POS_POST_C || $seen_below)) { + $base = $i; + break; + } + if ($info[$i]['indic_position'] == self::POS_BELOW_C) { + $seen_below = true; + } + + /* -> or that is not a pre-base reordering Ra, + * + * IMPLEMENTATION NOTES: + * + * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped + * by the logic above already. + */ + + /* -> or arrive at the first consonant. The consonant stopped at will + * be the base. */ + $base = $i; + } else { + /* A ZWJ after a Halant stops the base search, and requests an explicit + * half form. + * [A ZWJ before a Halant, requests a subjoined form instead, and hence + * search continues. This is particularly important for Bengali + * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya] */ + if ($start < $i && $info[$i]['indic_category'] == self::OT_ZWJ && $info[$i - 1]['indic_category'] == self::OT_H) { + if (!defined("OMIT_INDIC_FIX_1") || OMIT_INDIC_FIX_1 != 1) { + $base = $i; + } // INDIC_FIX_1 + break; + } + // ZKI8 + if ($start < $i && $info[$i]['indic_category'] == self::OT_ZWNJ) { + break; + } + } + } while ($i > $limit); + break; + + case self::BASE_POS_FIRST: + /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */ + + if (!$has_reph) { + $base = $limit; + } + + /* Find the last base consonant that is not blocked by ZWJ. If there is + * a ZWJ right before a base consonant, that would request a subjoined form. */ + for ($i = $limit; $i < $end; $i++) { + if (self::is_consonant($info[$i]) && $info[$i]['indic_position'] == self::POS_BASE_C) { + if ($limit < $i && $info[$i - 1]['indic_category'] == self::OT_ZWJ) { + break; + } else { + $base = $i; + } + } + } + + /* Mark all subsequent consonants as below. */ + for ($i = $base + 1; $i < $end; $i++) { + if (self::is_consonant($info[$i]) && $info[$i]['indic_position'] == self::POS_BASE_C) { + $info[$i]['indic_position'] = self::POS_BELOW_C; + } + } + break; + //default: + //assert (false); + /* fallthrough */ + } + + /* -> If the syllable starts with Ra + Halant (in a script that has Reph) + * and has more than one consonant, Ra is excluded from candidates for + * base consonants. + * + * Only do this for unforced Reph. (ie. not for Ra,H,ZWJ. */ + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + if ($has_reph && $base == $start && $limit - $base <= 2) { + /* Have no other consonant, so Reph is not formed and Ra becomes base. */ + $has_reph = false; + } + } + + /* 2. Decompose and reorder Matras: + * + * Each matra and any syllable modifier sign in the cluster are moved to the + * appropriate position relative to the consonant(s) in the cluster. The + * shaping engine decomposes two- or three-part matras into their constituent + * parts before any repositioning. Matra characters are classified by which + * consonant in a conjunct they have affinity for and are reordered to the + * following positions: + * + * o Before first half form in the syllable + * o After subjoined consonants + * o After post-form consonant + * o After main consonant (for above marks) + * + * IMPLEMENTATION NOTES: + * + * The normalize() routine has already decomposed matras for us, so we don't + * need to worry about that. + */ + + + /* 3. Reorder marks to canonical order: + * + * Adjacent nukta and halant or nukta and vedic sign are always repositioned + * if necessary, so that the nukta is first. + * + * IMPLEMENTATION NOTES: + * + * Use the combining Class from Unicode categories? to bubble_sort. + */ + + /* Reorder characters */ + + for ($i = $start; $i < $base; $i++) { + $info[$i]['indic_position'] = min(self::POS_PRE_C, $info[$i]['indic_position']); + } + + if ($base < $end) { + $info[$base]['indic_position'] = self::POS_BASE_C; + } + + /* Mark final consonants. A final consonant is one appearing after a matra, + * ? only in Khmer. */ + for ($i = $base + 1; $i < $end; $i++) { + if ($info[$i]['indic_category'] == self::OT_M) { + for ($j = $i + 1; $j < $end; $j++) { + if (self::is_consonant($info[$j])) { + $info[$j]['indic_position'] = self::POS_FINAL_C; + break; + } + } + break; + } + } + + /* Handle beginning Ra */ + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + if ($has_reph) { + $info[$start]['indic_position'] = self::POS_RA_TO_BECOME_REPH; + } + } + + + /* For old-style Indic script tags, move the first post-base Halant after + * last consonant. Only do this if there is *not* a Halant after last + * consonant. Otherwise it becomes messy. */ + if ($is_old_spec) { + for ($i = $base + 1; $i < $end; $i++) { + if ($info[$i]['indic_category'] == self::OT_H) { + for ($j = $end - 1; $j > $i; $j--) { + if (self::is_consonant($info[$j]) || $info[$j]['indic_category'] == self::OT_H) { + break; + } + } + if ($info[$j]['indic_category'] != self::OT_H && $j > $i) { + /* Move Halant to after last consonant. */ + self::_move_info_pos($info, $i, $j + 1); + } + break; + } + } + } + + /* Attach misc marks to previous char to move with them. */ + $last_pos = self::POS_START; + for ($i = $start; $i < $end; $i++) { + if ((self::FLAG($info[$i]['indic_category']) & (self::FLAG(self::OT_ZWJ) | self::FLAG(self::OT_ZWNJ) | self::FLAG(self::OT_N) | self::FLAG(self::OT_RS) | self::FLAG(self::OT_H) | self::FLAG(self::OT_COENG) ))) { + $info[$i]['indic_position'] = $last_pos; + if ($info[$i]['indic_category'] == self::OT_H && $info[$i]['indic_position'] == self::POS_PRE_M) { + /* + * Uniscribe doesn't move the Halant with Left Matra. + * TEST: U+092B,U+093F,U+094DE + * We follow. This is important for the Sinhala + * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA + * where U+0DD9 is a left matra and U+0DCA is the virama. + * We don't want to move the virama with the left matra. + * TEST: U+0D9A,U+0DDA + */ + for ($j = $i; $j > $start; $j--) { + if ($info[$j - 1]['indic_position'] != self::POS_PRE_M) { + $info[$i]['indic_position'] = $info[$j - 1]['indic_position']; + break; + } + } + } + } elseif ($info[$i]['indic_position'] != self::POS_SMVD) { + $last_pos = $info[$i]['indic_position']; + } + } + + /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */ + $last_halant = $end; + for ($i = $base + 1; $i < $end; $i++) { + if (self::is_halant_or_coeng($info[$i])) { + $last_halant = $i; + } elseif (self::is_consonant($info[$i])) { + for ($j = $last_halant; $j < $i; $j++) { + if ($info[$j]['indic_position'] != self::POS_SMVD) { + $info[$j]['indic_position'] = $info[$i]['indic_position']; + } + } + } + } + + + if ($scriptblock == Ucdn::SCRIPT_KHMER) { + /* KHMER_FIX_2 */ + /* Move Coeng+RO (Halant,Ra) sequence before base consonant. */ + for ($i = $base + 1; $i < $end; $i++) { + if (self::is_halant_or_coeng($info[$i]) && self::is_ra($info[$i + 1]['uni'])) { + $info[$i]['indic_position'] = self::POS_PRE_C; + $info[$i + 1]['indic_position'] = self::POS_PRE_C; + break; + } + } + } + + + /* + if (!defined("OMIT_INDIC_FIX_2") || OMIT_INDIC_FIX_2 != 1) { + // INDIC_FIX_2 + $ZWNJ_found = false; + $POST_ZWNJ_c_found = false; + for ($i = $base + 1; $i < $end; $i++) { + if ($info[$i]['indic_category'] == self::OT_ZWNJ) { $ZWNJ_found = true; } + else if ($ZWNJ_found && $info[$i]['indic_category'] == self::OT_C) { $POST_ZWNJ_c_found = true; } + else if ($POST_ZWNJ_c_found && $info[$i]['indic_position'] == self::POS_BEFORE_SUB) { $info[$i]['indic_position'] = self::POS_AFTER_SUB; } + } + } + */ + + /* Setup masks now */ + for ($i = $start; $i < $end; $i++) { + $info[$i]['mask'] = 0; + } + + + if ($scriptblock == Ucdn::SCRIPT_KHMER) { + /* Find a Coeng+RO (Halant,Ra) sequence and mark it for pre-base processing. */ + $mask = self::FLAG(self::PREF); + for ($i = $base; $i < $end - 1; $i++) { /* KHMER_FIX_1 From $start (not base) */ + if (self::is_halant_or_coeng($info[$i]) && self::is_ra($info[$i + 1]['uni'])) { + $info[$i]['mask'] |= self::FLAG(self::PREF); + $info[$i + 1]['mask'] |= self::FLAG(self::PREF); + + /* Mark the subsequent stuff with 'cfar'. Used in Khmer. + * Read the feature spec. + * This allows distinguishing the following cases with MS Khmer fonts: + * U+1784,U+17D2,U+179A,U+17D2,U+1782 [C+Coeng+RO+Coeng+C] => Should activate CFAR + * U+1784,U+17D2,U+1782,U+17D2,U+179A [C+Coeng+C+Coeng+RO] => Should NOT activate CFAR + */ + for ($j = ($i + 2); $j < $end; $j++) { + $info[$j]['mask'] |= self::FLAG(self::CFAR); + } + + break; + } + } + } + + + + /* Sit tight, rock 'n roll! */ + self::bubble_sort($info, $start, $end - $start); + + /* Find base again */ + $base = $end; + for ($i = $start; $i < $end; $i++) { + if ($info[$i]['indic_position'] == self::POS_BASE_C) { + $base = $i; + break; + } + } + + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + /* Reph */ + for ($i = $start; $i < $end; $i++) { + if ($info[$i]['indic_position'] == self::POS_RA_TO_BECOME_REPH) { + $info[$i]['mask'] |= self::FLAG(self::RPHF); + } + } + + /* Pre-base */ + $mask = self::FLAG(self::HALF); + for ($i = $start; $i < $base; $i++) { + $info[$i]['mask'] |= $mask; + } + } + + /* Post-base */ + $mask = (self::FLAG(self::BLWF) | self::FLAG(self::ABVF) | self::FLAG(self::PSTF)); + for ($i = $base + 1; $i < $end; $i++) { + $info[$i]['mask'] |= $mask; + } + + + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + if (!defined("OMIT_INDIC_FIX_3") || OMIT_INDIC_FIX_3 != 1) { + /* INDIC_FIX_3 */ + /* Find a (pre-base) Consonant, Halant,Ra sequence and mark Halant|Ra for below-base BLWF processing. */ + // TEST CASE ক্র্ক in FreeSans versus Vrinda + if (($base - $start) >= 3) { + for ($i = $start; $i < ($base - 2); $i++) { + if (self::is_consonant($info[$i])) { + if (self::is_halant_or_coeng($info[$i + 1]) && self::is_ra($info[$i + 2]['uni'])) { + // If would substitute Halant+Ra...BLWF + if (isset($GSUBdata['blwf'][$info[$i + 2]['uni']])) { + $info[$i + 1]['mask'] |= self::FLAG(self::BLWF); + $info[$i + 2]['mask'] |= self::FLAG(self::BLWF); + } /* If would not substitute as blwf, mark Ra+Halant for RPHF using following Halant (if present) */ elseif (self::is_halant_or_coeng($info[$i + 3])) { + $info[$i + 2]['mask'] |= self::FLAG(self::RPHF); + $info[$i + 3]['mask'] |= self::FLAG(self::RPHF); + } + break; + } + } + } + } + } + } + + + + if ($is_old_spec && $scriptblock == Ucdn::SCRIPT_DEVANAGARI) { + /* Old-spec eye-lash Ra needs special handling. From the spec: + * "The feature 'below-base form' is applied to consonants + * having below-base forms and following the base consonant. + * The exception is vattu, which may appear below half forms + * as well as below the base glyph. The feature 'below-base + * form' will be applied to all such occurrences of Ra as well." + * + * Test case: U+0924,U+094D,U+0930,U+094d,U+0915 + * with Sanskrit 2003 font. + * + * However, note that Ra,Halant,ZWJ is the correct way to + * request eyelash form of Ra, so we wouldbn't inhibit it + * in that sequence. + * + * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915 + */ + for ($i = $start; ($i + 1) < $base; $i++) { + if ($info[$i]['indic_category'] == self::OT_RA && $info[$i + 1]['indic_category'] == self::OT_H && + ($i + 2 == $base || $info[$i + 2]['indic_category'] != self::OT_ZWJ)) { + $info[$i]['mask'] |= self::FLAG(self::BLWF); + $info[$i + 1]['mask'] |= self::FLAG(self::BLWF); + } + } + } + + if ($scriptblock != Ucdn::SCRIPT_KHMER) { + if (count($GSUBdata['pref']) && $base + 2 < $end) { + /* Find a Halant,Ra sequence and mark it for pre-base processing. */ + for ($i = $base + 1; $i + 1 < $end; $i++) { + // If old_spec find Ra-Halant... + if ((isset($GSUBdata['pref'][$info[$i + 1]['uni']]) && self::is_halant_or_coeng($info[$i]) && self::is_ra($info[$i + 1]['uni']) ) || + ($is_old_spec && isset($GSUBdata['pref'][$info[$i]['uni']]) && self::is_halant_or_coeng($info[$i + 1]) && self::is_ra($info[$i]['uni']) ) + ) { + $info[$i++]['mask'] |= self::FLAG(self::PREF); + $info[$i++]['mask'] |= self::FLAG(self::PREF); + break; + } + } + } + } + + + /* Apply ZWJ/ZWNJ effects */ + for ($i = $start + 1; $i < $end; $i++) { + if (self::is_joiner($info[$i])) { + $non_joiner = ($info[$i]['indic_category'] == self::OT_ZWNJ); + $j = $i; + while ($j > $start) { + if (defined("OMIT_INDIC_FIX_4") && OMIT_INDIC_FIX_4 == 1) { + // INDIC_FIX_4 = do nothing - carry on // + // ZWNJ should block H C from forming blwf post-base - need to unmask backwards beyond first consonant arrived at // + if (!self::is_consonant($info[$j])) { + break; + } + } + $j--; + + /* ZWJ/ZWNJ should disable CJCT. They do that by simply + * being there, since we don't skip them for the CJCT + * feature (ie. F_MANUAL_ZWJ) */ + + /* A ZWNJ disables HALF. */ + if ($non_joiner) { + $info[$j]['mask'] &= ~(self::FLAG(self::HALF) | self::FLAG(self::BLWF)); + } + } + } + } + } + + public static function final_reordering(&$info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec) + { + $count = count($info); + if (!$count) { + return; + } + $last = 0; + $last_syllable = $info[0]['syllable']; + for ($i = 1; $i < $count; $i++) { + if ($last_syllable != $info[$i]['syllable']) { + self::final_reordering_syllable($info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $last, $i); + $last = $i; + $last_syllable = $info[$last]['syllable']; + } + } + self::final_reordering_syllable($info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $last, $count); + } + + public static function final_reordering_syllable(&$info, $GSUBdata, $indic_config, $scriptblock, $is_old_spec, $start, $end) + { + + /* 4. Final reordering: + * + * After the localized forms and basic shaping forms GSUB features have been + * applied (see below), the shaping engine performs some final glyph + * reordering before applying all the remaining font features to the entire + * cluster. + */ + + /* Find base again */ + for ($base = $start; $base < $end; $base++) { + if ($info[$base]['indic_position'] >= self::POS_BASE_C) { + if ($start < $base && $info[$base]['indic_position'] > self::POS_BASE_C) { + $base--; + } + break; + } + } + if ($base == $end && $start < $base && $info[$base - 1]['indic_category'] != self::OT_ZWJ) { + $base--; + } + while ($start < $base && isset($info[$base]) && ($info[$base]['indic_category'] == self::OT_H || $info[$base]['indic_category'] == self::OT_N)) { + $base--; + } + + + /* o Reorder matras: + * + * If a pre-base matra character had been reordered before applying basic + * features, the glyph can be moved closer to the main consonant based on + * whether half-forms had been formed. Actual position for the matra is + * defined as "after last standalone halant glyph, after initial matra + * position and before the main consonant". If ZWJ or ZWNJ follow this + * halant, position is moved after it. + */ + + + if ($start + 1 < $end && $start < $base) { /* Otherwise there can't be any pre-base matra characters. */ + /* If we lost track of base, alas, position before last thingy. */ + $new_pos = ($base == $end) ? $base - 2 : $base - 1; + + /* Malayalam / Tamil do not have "half" forms or explicit virama forms. + * The glyphs formed by 'half' are Chillus or ligated explicit viramas. + * We want to position matra after them. + */ + if ($scriptblock != Ucdn::SCRIPT_MALAYALAM && $scriptblock != Ucdn::SCRIPT_TAMIL) { + while ($new_pos > $start && !(self::is_one_of($info[$new_pos], (self::FLAG(self::OT_M) | self::FLAG(self::OT_H) | self::FLAG(self::OT_COENG))))) { + $new_pos--; + } + + /* If we found no Halant we are done. + * Otherwise only proceed if the Halant does + * not belong to the Matra itself! */ + if (self::is_halant_or_coeng($info[$new_pos]) && $info[$new_pos]['indic_position'] != self::POS_PRE_M) { + /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ + if ($new_pos + 1 < $end && self::is_joiner($info[$new_pos + 1])) { + $new_pos++; + } + } else { + $new_pos = $start; + } /* No move. */ + } + + if ($start < $new_pos && $info[$new_pos]['indic_position'] != self::POS_PRE_M) { + /* Now go see if there's actually any matras... */ + for ($i = $new_pos; $i > $start; $i--) { + if ($info[$i - 1]['indic_position'] == self::POS_PRE_M) { + $old_pos = $i - 1; + //memmove (&info[$old_pos], &info[$old_pos + 1], ($new_pos - $old_pos) * sizeof ($info[0])); + self::_move_info_pos($info, $old_pos, $new_pos + 1); + + if ($old_pos < $base && $base <= $new_pos) { /* Shouldn't actually happen. */ + $base--; + } + $new_pos--; + } + } + } + } + + + /* o Reorder reph: + * + * Reph's original position is always at the beginning of the syllable, + * (i.e. it is not reordered at the character reordering stage). However, + * it will be reordered according to the basic-forms shaping results. + * Possible positions for reph, depending on the script, are; after main, + * before post-base consonant forms, and after post-base consonant forms. + */ + + /* If there's anything after the Ra that has the REPH pos, it ought to be halant. + * Which means that the font has failed to ligate the Reph. In which case, we + * shouldn't move. */ + if ($start + 1 < $end && + $info[$start]['indic_position'] == self::POS_RA_TO_BECOME_REPH && $info[$start + 1]['indic_position'] != self::POS_RA_TO_BECOME_REPH) { + $reph_pos = $indic_config[3]; + $skip_to_reph_step_5 = false; + $skip_to_reph_move = false; + + /* 1. If reph should be positioned after post-base consonant forms, + * proceed to step 5. + */ + if ($reph_pos == self::REPH_POS_AFTER_POST) { + $skip_to_reph_step_5 = true; + } + + /* 2. If the reph repositioning class is not after post-base: target + * position is after the first explicit halant glyph between the + * first post-reph consonant and last main consonant. If ZWJ or ZWNJ + * are following this halant, position is moved after it. If such + * position is found, this is the target position. Otherwise, + * proceed to the next step. + * + * Note: in old-implementation fonts, where classifications were + * fixed in shaping engine, there was no case where reph position + * will be found on this step. + */ + + if (!$skip_to_reph_step_5) { + $new_reph_pos = $start + 1; + + while ($new_reph_pos < $base && !self::is_halant_or_coeng($info[$new_reph_pos])) { + $new_reph_pos++; + } + + if ($new_reph_pos < $base && self::is_halant_or_coeng($info[$new_reph_pos])) { + /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ + if ($new_reph_pos + 1 < $base && self::is_joiner($info[$new_reph_pos + 1])) { + $new_reph_pos++; + } + $skip_to_reph_move = true; + } + } + + /* 3. If reph should be repositioned after the main consonant: find the + * first consonant not ligated with main, or find the first + * consonant that is not a potential pre-base reordering Ra. + */ + if ($reph_pos == self::REPH_POS_AFTER_MAIN && !$skip_to_reph_move && !$skip_to_reph_step_5) { + $new_reph_pos = $base; + /* XXX Skip potential pre-base reordering Ra. */ + while ($new_reph_pos + 1 < $end && $info[$new_reph_pos + 1]['indic_position'] <= self::POS_AFTER_MAIN) { + $new_reph_pos++; + } + if ($new_reph_pos < $end) { + $skip_to_reph_move = true; + } + } + + /* 4. If reph should be positioned before post-base consonant, find + * first post-base classified consonant not ligated with main. If no + * consonant is found, the target position should be before the + * first matra, syllable modifier sign or vedic sign. + */ + /* This is our take on what step 4 is trying to say (and failing, BADLY). */ + if ($reph_pos == self::REPH_POS_AFTER_SUB && !$skip_to_reph_move && !$skip_to_reph_step_5) { + $new_reph_pos = $base; + while ($new_reph_pos < $end && isset($info[$new_reph_pos + 1]['indic_position']) && + !( self::FLAG($info[$new_reph_pos + 1]['indic_position']) & (self::FLAG(self::POS_POST_C) | self::FLAG(self::POS_AFTER_POST) | self::FLAG(self::POS_SMVD)))) { + $new_reph_pos++; + } + if ($new_reph_pos < $end) { + $skip_to_reph_move = true; + } + } + + /* 5. If no consonant is found in steps 3 or 4, move reph to a position + * immediately before the first post-base matra, syllable modifier + * sign or vedic sign that has a reordering class after the intended + * reph position. For example, if the reordering position for reph + * is post-main, it will skip above-base matras that also have a + * post-main position. + */ + if (!$skip_to_reph_move) { + /* Copied from step 2. */ + $new_reph_pos = $start + 1; + while ($new_reph_pos < $base && !self::is_halant_or_coeng($info[$new_reph_pos])) { + $new_reph_pos++; + } + + if ($new_reph_pos < $base && self::is_halant_or_coeng($info[$new_reph_pos])) { + /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ + if ($new_reph_pos + 1 < $base && self::is_joiner($info[$new_reph_pos + 1])) { + $new_reph_pos++; + } + $skip_to_reph_move = true; + } + } + + + /* 6. Otherwise, reorder reph to the end of the syllable. + */ + if (!$skip_to_reph_move) { + $new_reph_pos = $end - 1; + while ($new_reph_pos > $start && $info[$new_reph_pos]['indic_position'] == self::POS_SMVD) { + $new_reph_pos--; + } + + /* + * If the Reph is to be ending up after a Matra,Halant sequence, + * position it before that Halant so it can interact with the Matra. + * However, if it's a plain Consonant,Halant we shouldn't do that. + * Uniscribe doesn't do this. + * TEST: U+0930,U+094D,U+0915,U+094B,U+094D + */ + //if (!$hb_options.uniscribe_bug_compatible && self::is_halant_or_coeng($info[$new_reph_pos])) { + if (self::is_halant_or_coeng($info[$new_reph_pos])) { + for ($i = $base + 1; $i < $new_reph_pos; $i++) { + if ($info[$i]['indic_category'] == self::OT_M) { + /* Ok, got it. */ + $new_reph_pos--; + } + } + } + } + + + /* Move */ + self::_move_info_pos($info, $start, $new_reph_pos + 1); + + if ($start < $base && $base <= $new_reph_pos) { + $base--; + } + } + + + /* o Reorder pre-base reordering consonants: + * + * If a pre-base reordering consonant is found, reorder it according to + * the following rules: + */ + + + if (count($GSUBdata['pref']) && $base + 1 < $end) { /* Otherwise there can't be any pre-base reordering Ra. */ + for ($i = $base + 1; $i < $end; $i++) { + if ($info[$i]['mask'] & self::FLAG(self::PREF)) { + /* 1. Only reorder a glyph produced by substitution during application + * of the <pref> feature. (Note that a font may shape a Ra consonant with + * the feature generally but block it in certain contexts.) + */ + // ??? Need to TEST if actual substitution has occurred + if ($i + 1 == $end || ($info[$i + 1]['mask'] & self::FLAG(self::PREF)) == 0) { + /* + * 2. Try to find a target position the same way as for pre-base matra. + * If it is found, reorder pre-base consonant glyph. + * + * 3. If position is not found, reorder immediately before main + * consonant. + */ + $new_pos = $base; + /* Malayalam / Tamil do not have "half" forms or explicit virama forms. + * The glyphs formed by 'half' are Chillus or ligated explicit viramas. + * We want to position matra after them. + */ + if ($scriptblock != Ucdn::SCRIPT_MALAYALAM && $scriptblock != Ucdn::SCRIPT_TAMIL) { + while ($new_pos > $start && + !(self::is_one_of($info[$new_pos - 1], self::FLAG(self::OT_M) | self::FLAG(self::OT_H) | self::FLAG(self::OT_COENG)))) { + $new_pos--; + } + + /* In Khmer coeng model, a V,Ra can go *after* matras. If it goes after a + * split matra, it should be reordered to *before* the left part of such matra. */ + if ($new_pos > $start && $info[$new_pos - 1]['indic_category'] == self::OT_M) { + $old_pos = $i; + for ($i = $base + 1; $i < $old_pos; $i++) { + if ($info[$i]['indic_category'] == self::OT_M) { + $new_pos--; + break; + } + } + } + } + + if ($new_pos > $start && self::is_halant_or_coeng($info[$new_pos - 1])) { + /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ + if ($new_pos < $end && self::is_joiner($info[$new_pos])) { + $new_pos++; + } + } + + $old_pos = $i; + self::_move_info_pos($info, $old_pos, $new_pos); + + if ($new_pos <= $base && $base < $old_pos) { + $base++; + } + } + + break; + } + } + } + + + /* Apply 'init' to the Left Matra if it's a word start. */ + if ($info[$start]['indic_position'] == self::POS_PRE_M && + ($start == 0 || + ($info[$start - 1]['general_category'] < Ucdn::UNICODE_GENERAL_CATEGORY_FORMAT || $info[$start - 1]['general_category'] > Ucdn::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + )) { + $info[$start]['mask'] |= self::FLAG(self::INIT); + } + + + /* + * Finish off and go home! + */ + } + + public static function _move_info_pos(&$info, $from, $to) + { + $t = []; + $t[0] = $info[$from]; + if ($from > $to) { + array_splice($info, $from, 1); + array_splice($info, $to, 0, $t); + } else { + array_splice($info, $to, 0, $t); + array_splice($info, $from, 1); + } + } + + public static $ra_chars = [ + 0x0930 => 1, /* Devanagari */ + 0x09B0 => 1, /* Bengali */ + 0x09F0 => 1, /* Bengali (Assamese) */ + 0x0A30 => 1, /* Gurmukhi */ /* No Reph */ + 0x0AB0 => 1, /* Gujarati */ + 0x0B30 => 1, /* Oriya */ + 0x0BB0 => 1, /* Tamil */ /* No Reph */ + 0x0C30 => 1, /* Telugu */ /* Reph formed only with ZWJ */ + 0x0CB0 => 1, /* Kannada */ + 0x0D30 => 1, /* Malayalam */ /* No Reph, Logical Repha */ + 0x0DBB => 1, /* Sinhala */ /* Reph formed only with ZWJ */ + 0x179A => 1, /* Khmer */ /* No Reph, Visual Repha */ + ]; + + public static function is_ra($u) + { + return isset(self::$ra_chars[$u]); + } + + public static function is_one_of($info, $flags) + { + if (isset($info['is_ligature']) && $info['is_ligature']) { + return false; + } /* If it ligated, all bets are off. */ + return !!(self::FLAG($info['indic_category']) & $flags); + } + + public static function is_joiner($info) + { + return self::is_one_of($info, (self::FLAG(self::OT_ZWJ) | self::FLAG(self::OT_ZWNJ))); + } + + /* Vowels and placeholders treated as if they were consonants. */ + + public static function is_consonant($info) + { + return self::is_one_of($info, (self::FLAG(self::OT_C) | self::FLAG(self::OT_CM) | self::FLAG(self::OT_RA) | self::FLAG(self::OT_V) | self::FLAG(self::OT_NBSP) | self::FLAG(self::OT_DOTTEDCIRCLE))); + } + + public static function is_halant_or_coeng($info) + { + return self::is_one_of($info, (self::FLAG(self::OT_H) | self::FLAG(self::OT_COENG))); + } + + // From hb-private.hh + public static function in_range($u, $lo, $hi) + { + if ((($lo ^ $hi) & $lo) == 0 && (($lo ^ $hi) & $hi) == ($lo ^ $hi) && (($lo ^ $hi) & (($lo ^ $hi) + 1)) == 0) { + return ($u & ~($lo ^ $hi)) == $lo; + } else { + return $lo <= $u && $u <= $hi; + } + } + + // From hb-private.hh + public static function FLAG($x) + { + return (1 << ($x)); + } + + // BELOW from hb-ot-shape-complex-indic.cc + + /* + * Indic configurations. + */ + + // base_position + const BASE_POS_FIRST = 0; + const BASE_POS_LAST = 1; + + // reph_position + const REPH_POS_DEFAULT = 10; // POS_BEFORE_POST, + + const REPH_POS_AFTER_MAIN = 5; // POS_AFTER_MAIN, + + const REPH_POS_BEFORE_SUB = 7; // POS_BEFORE_SUB, + const REPH_POS_AFTER_SUB = 9; // POS_AFTER_SUB, + const REPH_POS_BEFORE_POST = 10; // POS_BEFORE_POST, + const REPH_POS_AFTER_POST = 12; // POS_AFTER_POST + + // reph_mode + const REPH_MODE_IMPLICIT = 0; /* Reph formed out of initial Ra,H sequence. */ + const REPH_MODE_EXPLICIT = 1; /* Reph formed out of initial Ra,H,ZWJ sequence. */ + const REPH_MODE_VIS_REPHA = 2; /* Encoded Repha character, no reordering needed. */ + const REPH_MODE_LOG_REPHA = 3; /* Encoded Repha character, needs reordering. */ + + /* + struct of indic_configs{ + KEY - script; + 0 - has_old_spec; + 1 - virama; + 2 - base_pos; + 3 - reph_pos; + 4 - reph_mode; + }; + */ + + public static $indic_configs = [/* index is SCRIPT_number from UCDN */ + 9 => [true, 0x094D, 1, 10, 0], + 10 => [true, 0x09CD, 1, 9, 0], + 11 => [true, 0x0A4D, 1, 7, 0], + 12 => [true, 0x0ACD, 1, 10, 0], + 13 => [true, 0x0B4D, 1, 5, 0], + 14 => [true, 0x0BCD, 1, 12, 0], + 15 => [true, 0x0C4D, 1, 12, 1], + 16 => [true, 0x0CCD, 1, 12, 0], + 17 => [true, 0x0D4D, 1, 5, 3], + 18 => [false, 0x0DCA, 0, 5, 1], /* Sinhala */ + 30 => [false, 0x17D2, 0, 10, 2], /* Khmer */ + 84 => [false, 0xA9C0, 1, 10, 0], /* Javanese */ + ]; + + + + /* + + // from "hb-ot-shape-complex-indic-table.cc" + + + const ISC_A = 0; // INDIC_SYLLABIC_CATEGORY_AVAGRAHA Avagraha + const ISC_Bi = 8; // INDIC_SYLLABIC_CATEGORY_BINDU Bindu + const ISC_C = 1; // INDIC_SYLLABIC_CATEGORY_CONSONANT Consonant + const ISC_CD = 1; // INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD Consonant_Dead + const ISC_CF = 17; // INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL Consonant_Final + const ISC_CHL = 1; // INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER Consonant_Head_Letter + const ISC_CM = 17; // INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL Consonant_Medial + const ISC_CP = 11; // INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER Consonant_Placeholder + const ISC_CR = 15; // INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA Consonant_Repha + const ISC_CS = 1; // INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED Consonant_Subjoined + const ISC_ML = 0; // INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER Modifying_Letter + const ISC_N = 3; // INDIC_SYLLABIC_CATEGORY_NUKTA Nukta + const ISC_x = 0; // INDIC_SYLLABIC_CATEGORY_OTHER Other + const ISC_RS = 13; // INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER Register_Shifter + const ISC_TL = 0; // INDIC_SYLLABIC_CATEGORY_TONE_LETTER Tone_Letter + const ISC_TM = 3; // INDIC_SYLLABIC_CATEGORY_TONE_MARK Tone_Mark + const ISC_V = 4; // INDIC_SYLLABIC_CATEGORY_VIRAMA Virama + const ISC_Vs = 8; // INDIC_SYLLABIC_CATEGORY_VISARGA Visarga + const ISC_Vo = 2; // INDIC_SYLLABIC_CATEGORY_VOWEL Vowel + const ISC_M = 7; // INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT Vowel_Dependent + const ISC_VI = 2; // INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT Vowel_Independent + + const IMC_B = 8; // INDIC_MATRA_CATEGORY_BOTTOM Bottom + const IMC_BR = 11; // INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT Bottom_And_Right + const IMC_I = 15; // INDIC_MATRA_CATEGORY_INVISIBLE Invisible + const IMC_L = 3; // INDIC_MATRA_CATEGORY_LEFT Left + const IMC_LR = 11; // INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT Left_And_Right + const IMC_x = 15; // INDIC_MATRA_CATEGORY_NOT_APPLICABLE Not_Applicable + const IMC_O = 5; // INDIC_MATRA_CATEGORY_OVERSTRUCK Overstruck + const IMC_R = 11; // INDIC_MATRA_CATEGORY_RIGHT Right + const IMC_T = 6; // INDIC_MATRA_CATEGORY_TOP Top + const IMC_TB = 8; // INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM Top_And_Bottom + const IMC_TBR = 11; // INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT Top_And_Bottom_And_Right + const IMC_TL = 6; // INDIC_MATRA_CATEGORY_TOP_AND_LEFT Top_And_Left + const IMC_TLR = 11; // INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT Top_And_Left_And_Right + const IMC_TR = 11; // INDIC_MATRA_CATEGORY_TOP_AND_RIGHT Top_And_Right + const IMC_VOL = 2; // INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT Visual_Order_Left + + If in original table = _(C,x), that = ISC_C,IMC_x + Value is IMC_x << 8 (or IMC_x * 256) = 3840 + plus ISC_C = 1, so = 3841 + + */ + + public static $indic_table = [ + /* Devanagari (0900..097F) */ + + /* 0900 */ 3848, 3848, 3848, 3848, 3842, 3842, 3842, 3842, + /* 0908 */ 3842, 3842, 3842, 3842, 3842, 3842, 3842, 3842, + /* 0910 */ 3842, 3842, 3842, 3842, 3842, 3841, 3841, 3841, + /* 0918 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0920 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0928 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0930 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0938 */ 3841, 3841, 1543, 2823, 3843, 3840, 2823, 775, + /* 0940 */ 2823, 2055, 2055, 2055, 2055, 1543, 1543, 1543, + /* 0948 */ 1543, 2823, 2823, 2823, 2823, 2052, 775, 2823, + /* 0950 */ 3840, 3840, 3840, 3840, 3840, 1543, 2055, 2055, + /* 0958 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0960 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0968 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0970 */ 3840, 3840, 3842, 3842, 3842, 3842, 3842, 3842, + /* 0978 */ 3840, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* Bengali (0980..09FF) */ + + /* 0980 */ 3840, 3848, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0988 */ 3842, 3842, 3842, 3842, 3842, 3840, 3840, 3842, + /* 0990 */ 3842, 3840, 3840, 3842, 3842, 3841, 3841, 3841, + /* 0998 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 09A0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 09A8 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 09B0 */ 3841, 3840, 3841, 3840, 3840, 3840, 3841, 3841, + /* 09B8 */ 3841, 3841, 3840, 3840, 3843, 3840, 2823, 775, + /* 09C0 */ 2823, 2055, 2055, 2055, 2055, 3840, 3840, 775, + /* 09C8 */ 775, 3840, 3840, 2823, 2823, 2052, 3841, 3840, + /* 09D0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 2823, + /* 09D8 */ 3840, 3840, 3840, 3840, 3841, 3841, 3840, 3841, + /* 09E0 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 09E8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 09F0 */ 3841, 3841, 3840, 3840, 3840, 3840, 3840, 3840, + /* 09F8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Gurmukhi (0A00..0A7F) */ + + /* 0A00 */ 3840, 3848, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0A08 */ 3842, 3842, 3842, 3840, 3840, 3840, 3840, 3842, + /* 0A10 */ 3842, 3840, 3840, 3842, 3842, 3841, 3841, 3841, + /* 0A18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0A20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0A28 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0A30 */ 3841, 3840, 3841, 3841, 3840, 3841, 3841, 3840, + /* 0A38 */ 3841, 3841, 3840, 3840, 3843, 3840, 2823, 775, + /* 0A40 */ 2823, 2055, 2055, 3840, 3840, 3840, 3840, 1543, + /* 0A48 */ 1543, 3840, 3840, 1543, 1543, 2052, 3840, 3840, + /* 0A50 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0A58 */ 3840, 3841, 3841, 3841, 3841, 3840, 3841, 3840, + /* 0A60 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0A68 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0A70 */ 3848, 3840, 13841, 13841, 3840, 3857, 3840, 3840, + /* 0A78 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Gujarati (0A80..0AFF) */ + + /* 0A80 */ 3840, 3848, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0A88 */ 3842, 3842, 3842, 3842, 3842, 3842, 3840, 3842, + /* 0A90 */ 3842, 3842, 3840, 3842, 3842, 3841, 3841, 3841, + /* 0A98 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0AA0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0AA8 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0AB0 */ 3841, 3840, 3841, 3841, 3840, 3841, 3841, 3841, + /* 0AB8 */ 3841, 3841, 3840, 3840, 3843, 3840, 2823, 775, + /* 0AC0 */ 2823, 2055, 2055, 2055, 2055, 1543, 3840, 1543, + /* 0AC8 */ 1543, 2823, 3840, 2823, 2823, 2052, 3840, 3840, + /* 0AD0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0AD8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0AE0 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0AE8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0AF0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0AF8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Oriya (0B00..0B7F) */ + + /* 0B00 */ 3840, 3848, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0B08 */ 3842, 3842, 3842, 3842, 3842, 3840, 3840, 3842, + /* 0B10 */ 3842, 3840, 3840, 3842, 3842, 3841, 3841, 3841, + /* 0B18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0B20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0B28 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0B30 */ 3841, 3840, 3841, 3841, 3840, 3841, 3841, 3841, + /* 0B38 */ 3841, 3841, 3840, 3840, 3843, 3840, 2823, 1543, + /* 0B40 */ 2823, 2055, 2055, 2055, 2055, 3840, 3840, 775, + /* 0B48 */ 1543, 3840, 3840, 2823, 2823, 2052, 3840, 3840, + /* 0B50 */ 3840, 3840, 3840, 3840, 3840, 3840, 1543, 2823, + /* 0B58 */ 3840, 3840, 3840, 3840, 3841, 3841, 3840, 3841, + /* 0B60 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0B68 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0B70 */ 3840, 3841, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0B78 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Tamil (0B80..0BFF) */ + + /* 0B80 */ 3840, 3840, 3848, 3840, 3840, 3842, 3842, 3842, + /* 0B88 */ 3842, 3842, 3842, 3840, 3840, 3840, 3842, 3842, + /* 0B90 */ 3842, 3840, 3842, 3842, 3842, 3841, 3840, 3840, + /* 0B98 */ 3840, 3841, 3841, 3840, 3841, 3840, 3841, 3841, + /* 0BA0 */ 3840, 3840, 3840, 3841, 3841, 3840, 3840, 3840, + /* 0BA8 */ 3841, 3841, 3841, 3840, 3840, 3840, 3841, 3841, + /* 0BB0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0BB8 */ 3841, 3841, 3840, 3840, 3840, 3840, 2823, 2823, + /* 0BC0 */ 1543, 2055, 2055, 3840, 3840, 3840, 775, 775, + /* 0BC8 */ 775, 3840, 2823, 2823, 2823, 1540, 3840, 3840, + /* 0BD0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 2823, + /* 0BD8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0BE0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0BE8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0BF0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0BF8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Telugu (0C00..0C7F) */ + + /* 0C00 */ 3840, 3848, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0C08 */ 3842, 3842, 3842, 3842, 3842, 3840, 3842, 3842, + /* 0C10 */ 3842, 3840, 3842, 3842, 3842, 3841, 3841, 3841, + /* 0C18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0C20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0C28 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0C30 */ 3841, 3841, 3841, 3841, 3840, 3841, 3841, 3841, + /* 0C38 */ 3841, 3841, 3840, 3840, 3840, 3840, 1543, 1543, + /* 0C40 */ 1543, 2823, 2823, 2823, 2823, 3840, 1543, 1543, + /* 0C48 */ 2055, 3840, 1543, 1543, 1543, 1540, 3840, 3840, + /* 0C50 */ 3840, 3840, 3840, 3840, 3840, 1543, 2055, 3840, + /* 0C58 */ 3841, 3841, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0C60 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0C68 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0C70 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0C78 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Kannada (0C80..0CFF) */ + + /* 0C80 */ 3840, 3840, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0C88 */ 3842, 3842, 3842, 3842, 3842, 3840, 3842, 3842, + /* 0C90 */ 3842, 3840, 3842, 3842, 3842, 3841, 3841, 3841, + /* 0C98 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0CA0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0CA8 */ 3841, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0CB0 */ 3841, 3841, 3841, 3841, 3840, 3841, 3841, 3841, + /* 0CB8 */ 3841, 3841, 3840, 3840, 3843, 3840, 2823, 1543, + /* 0CC0 */ 2823, 2823, 2823, 2823, 2823, 3840, 1543, 2823, + /* 0CC8 */ 2823, 3840, 2823, 2823, 1543, 1540, 3840, 3840, + /* 0CD0 */ 3840, 3840, 3840, 3840, 3840, 2823, 2823, 3840, + /* 0CD8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3841, 3840, + /* 0CE0 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0CE8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0CF0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0CF8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Malayalam (0D00..0D7F) */ + + /* 0D00 */ 3840, 3840, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0D08 */ 3842, 3842, 3842, 3842, 3842, 3840, 3842, 3842, + /* 0D10 */ 3842, 3840, 3842, 3842, 3842, 3841, 3841, 3841, + /* 0D18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0D20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0D28 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0D30 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0D38 */ 3841, 3841, 3841, 3840, 3840, 3840, 2823, 2823, + /* 0D40 */ 2823, 2823, 2823, 2055, 2055, 3840, 775, 775, + /* 0D48 */ 775, 3840, 2823, 2823, 2823, 1540, 3855, 3840, + /* 0D50 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 2823, + /* 0D58 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0D60 */ 3842, 3842, 2055, 2055, 3840, 3840, 3840, 3840, + /* 0D68 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0D70 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0D78 */ 3840, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* Sinhala (0D80..0DFF) */ + + /* 0D80 */ 3840, 3840, 3848, 3848, 3840, 3842, 3842, 3842, + /* 0D88 */ 3842, 3842, 3842, 3842, 3842, 3842, 3842, 3842, + /* 0D90 */ 3842, 3842, 3842, 3842, 3842, 3842, 3842, 3840, + /* 0D98 */ 3840, 3840, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0DA0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0DA8 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 0DB0 */ 3841, 3841, 3840, 3841, 3841, 3841, 3841, 3841, + /* 0DB8 */ 3841, 3841, 3841, 3841, 3840, 3841, 3840, 3840, + /* 0DC0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3840, + /* 0DC8 */ 3840, 3840, 1540, 3840, 3840, 3840, 3840, 2823, + /* 0DD0 */ 2823, 2823, 1543, 1543, 2055, 3840, 2055, 3840, + /* 0DD8 */ 2823, 775, 1543, 775, 2823, 2823, 2823, 2823, + /* 0DE0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0DE8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 0DF0 */ 3840, 3840, 2823, 2823, 3840, 3840, 3840, 3840, + /* 0DF8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Vedic Extensions (1CD0..1CFF) */ + + /* 1CD0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1CD8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1CE0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1CE8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1CF0 */ 3840, 3840, 3848, 3848, 3840, 3840, 3840, 3840, + /* 1CF8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + ]; + + public static $khmer_table = [ + /* Khmer (1780..17FF) */ + + /* 1780 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1788 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1790 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1798 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 17A0 */ 3841, 3841, 3841, 3842, 3842, 3842, 3842, 3842, + /* 17A8 */ 3842, 3842, 3842, 3842, 3842, 3842, 3842, 3842, + /* 17B0 */ 3842, 3842, 3842, 3842, 3840, 3840, 2823, 1543, + /* 17B8 */ 1543, 1543, 1543, 2055, 2055, 2055, 1543, 2823, + /* 17C0 */ 2823, 775, 775, 775, 2823, 2823, 3848, 3848, + /* 17C8 */ 2823, 3853, 3853, 3840, 3855, 3840, 3840, 3840, + /* 17D0 */ 3840, 1540, 3844, 3840, 3840, 3840, 3840, 3840, + /* 17D8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 17E0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 17E8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 17F0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 17F8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + ]; + + // from "hb-ot-shape-complex-indic-table.cc" + public static function indic_get_categories($u) + { + if (0x0900 <= $u && $u <= 0x0DFF) { + return self::$indic_table[$u - 0x0900 + 0]; // offset 0 for Most "indic" + } + if (0x1CD0 <= $u && $u <= 0x1D00) { + return self::$indic_table[$u - 0x1CD0 + 1152]; // offset for Vedic extensions + } + if (0x1780 <= $u && $u <= 0x17FF) { + return self::$khmer_table[$u - 0x1780]; // Khmer + } + if ($u == 0x00A0) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + if ($u == 0x25CC) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + return 3840; // (ISC_x | (IMC_x << 8)) + } + + // BELOW from hb-ot-shape-complex-indic.cc + /* + * Indic shaper. + */ + + public static function IN_HALF_BLOCK($u, $Base) + { + return (($u & ~0x7F) == $Base); + } + + public static function IS_DEVA($u) + { + return self::IN_HALF_BLOCK($u, 0x0900); + } + + public static function IS_BENG($u) + { + return self::IN_HALF_BLOCK($u, 0x0980); + } + + public static function IS_GURU($u) + { + return self::IN_HALF_BLOCK($u, 0x0A00); + } + + public static function IS_GUJR($u) + { + return self::IN_HALF_BLOCK($u, 0x0A80); + } + + public static function IS_ORYA($u) + { + return self::IN_HALF_BLOCK($u, 0x0B00); + } + + public static function IS_TAML($u) + { + return self::IN_HALF_BLOCK($u, 0x0B80); + } + + public static function IS_TELU($u) + { + return self::IN_HALF_BLOCK($u, 0x0C00); + } + + public static function IS_KNDA($u) + { + return self::IN_HALF_BLOCK($u, 0x0C80); + } + + public static function IS_MLYM($u) + { + return self::IN_HALF_BLOCK($u, 0x0D00); + } + + public static function IS_SINH($u) + { + return self::IN_HALF_BLOCK($u, 0x0D80); + } + + public static function IS_KHMR($u) + { + return self::IN_HALF_BLOCK($u, 0x1780); + } + + public static function MATRA_POS_LEFT($u) + { + return self::POS_PRE_M; + } + + public static function MATRA_POS_RIGHT($u) + { + return + (self::IS_DEVA($u) ? self::POS_AFTER_SUB : + (self::IS_BENG($u) ? self::POS_AFTER_POST : + (self::IS_GURU($u) ? self::POS_AFTER_POST : + (self::IS_GUJR($u) ? self::POS_AFTER_POST : + (self::IS_ORYA($u) ? self::POS_AFTER_POST : + (self::IS_TAML($u) ? self::POS_AFTER_POST : + (self::IS_TELU($u) ? ($u <= 0x0C42 ? self::POS_BEFORE_SUB : self::POS_AFTER_SUB) : + (self::IS_KNDA($u) ? ($u < 0x0CC3 || $u > 0xCD6 ? self::POS_BEFORE_SUB : self::POS_AFTER_SUB) : + (self::IS_MLYM($u) ? self::POS_AFTER_POST : + (self::IS_SINH($u) ? self::POS_AFTER_SUB : + (self::IS_KHMR($u) ? self::POS_AFTER_POST : + self::POS_AFTER_SUB))))))))))); /* default */ + } + + public static function MATRA_POS_TOP($u) + { + return /* BENG and MLYM don't have top matras. */ + (self::IS_DEVA($u) ? self::POS_AFTER_SUB : + (self::IS_GURU($u) ? self::POS_AFTER_POST : /* Deviate from spec */ + (self::IS_GUJR($u) ? self::POS_AFTER_SUB : + (self::IS_ORYA($u) ? self::POS_AFTER_MAIN : + (self::IS_TAML($u) ? self::POS_AFTER_SUB : + (self::IS_TELU($u) ? self::POS_BEFORE_SUB : + (self::IS_KNDA($u) ? self::POS_BEFORE_SUB : + (self::IS_SINH($u) ? self::POS_AFTER_SUB : + (self::IS_KHMR($u) ? self::POS_AFTER_POST : + self::POS_AFTER_SUB))))))))); /* default */ + } + + public static function MATRA_POS_BOTTOM($u) + { + return + (self::IS_DEVA($u) ? self::POS_AFTER_SUB : + (self::IS_BENG($u) ? self::POS_AFTER_SUB : + (self::IS_GURU($u) ? self::POS_AFTER_POST : + (self::IS_GUJR($u) ? self::POS_AFTER_POST : + (self::IS_ORYA($u) ? self::POS_AFTER_SUB : + (self::IS_TAML($u) ? self::POS_AFTER_POST : + (self::IS_TELU($u) ? self::POS_BEFORE_SUB : + (self::IS_KNDA($u) ? self::POS_BEFORE_SUB : + (self::IS_MLYM($u) ? self::POS_AFTER_POST : + (self::IS_SINH($u) ? self::POS_AFTER_SUB : + (self::IS_KHMR($u) ? self::POS_AFTER_POST : + self::POS_AFTER_SUB))))))))))); /* default */ + } + + public static function matra_position($u, $side) + { + switch ($side) { + case self::POS_PRE_C: + return self::MATRA_POS_LEFT($u); + case self::POS_POST_C: + return self::MATRA_POS_RIGHT($u); + case self::POS_ABOVE_C: + return self::MATRA_POS_TOP($u); + case self::POS_BELOW_C: + return self::MATRA_POS_BOTTOM($u); + } + return $side; + } + + // vowel matras that have to be split into two parts. + // From Harfbuzz (old) + // New HarfBuzz uses /src/hb-ucdn/ucdn.c and unicodedata_db.h for full method of decomposition for all characters + // Should always fully decompose and then recompose back, but we will just do the split matras + public static function decompose_indic($ab) + { + $sub = []; + switch ($ab) { + /* + * Decompose split matras. + */ + /* bengali */ + case 0x9cb: + $sub[0] = 0x9c7; + $sub[1] = 0x9be; + return $sub; + case 0x9cc: + $sub[0] = 0x9c7; + $sub[1] = 0x9d7; + return $sub; + /* oriya */ + case 0xb48: + $sub[0] = 0xb47; + $sub[1] = 0xb56; + return $sub; + case 0xb4b: + $sub[0] = 0xb47; + $sub[1] = 0xb3e; + return $sub; + case 0xb4c: + $sub[0] = 0xb47; + $sub[1] = 0xb57; + return $sub; + /* tamil */ + case 0xbca: + $sub[0] = 0xbc6; + $sub[1] = 0xbbe; + return $sub; + case 0xbcb: + $sub[0] = 0xbc7; + $sub[1] = 0xbbe; + return $sub; + case 0xbcc: + $sub[0] = 0xbc6; + $sub[1] = 0xbd7; + return $sub; + /* telugu */ + case 0xc48: + $sub[0] = 0xc46; + $sub[1] = 0xc56; + return $sub; + /* kannada */ + case 0xcc0: + $sub[0] = 0xcbf; + $sub[1] = 0xcd5; + return $sub; + case 0xcc7: + $sub[0] = 0xcc6; + $sub[1] = 0xcd5; + return $sub; + case 0xcc8: + $sub[0] = 0xcc6; + $sub[1] = 0xcd6; + return $sub; + case 0xcca: + $sub[0] = 0xcc6; + $sub[1] = 0xcc2; + return $sub; + case 0xccb: + $sub[0] = 0xcc6; + $sub[1] = 0xcc2; + $sub[2] = 0xcd5; + return $sub; + /* malayalam */ + case 0xd4a: + $sub[0] = 0xd46; + $sub[1] = 0xd3e; + return $sub; + case 0xd4b: + $sub[0] = 0xd47; + $sub[1] = 0xd3e; + return $sub; + case 0xd4c: + $sub[0] = 0xd46; + $sub[1] = 0xd57; + return $sub; + /* sinhala */ + // NB Some fonts break with these Sinhala decomps (although this is Uniscribe spec) + // Can check if character would be substituted by pstf and only decompose if true + // e.g. if (isset($GSUBdata['pstf'][$ab])) - would need to pass $GSUBdata as parameter to this function + case 0xdda: + $sub[0] = 0xdd9; + $sub[1] = 0xdca; + return $sub; + case 0xddc: + $sub[0] = 0xdd9; + $sub[1] = 0xdcf; + return $sub; + case 0xddd: + $sub[0] = 0xdd9; + $sub[1] = 0xdcf; + $sub[2] = 0xdca; + return $sub; + case 0xdde: + $sub[0] = 0xdd9; + $sub[1] = 0xddf; + return $sub; + /* khmer */ + case 0x17be: + $sub[0] = 0x17c1; + $sub[1] = 0x17be; + return $sub; + case 0x17bf: + $sub[0] = 0x17c1; + $sub[1] = 0x17bf; + return $sub; + case 0x17c0: + $sub[0] = 0x17c1; + $sub[1] = 0x17c0; + return $sub; + + case 0x17c4: + $sub[0] = 0x17c1; + $sub[1] = 0x17c4; + return $sub; + case 0x17c5: + $sub[0] = 0x17c1; + $sub[1] = 0x17c5; + return $sub; + /* tibetan - included here although does not use Inidc shaper in other ways */ + case 0xf73: + $sub[0] = 0xf71; + $sub[1] = 0xf72; + return $sub; + case 0xf75: + $sub[0] = 0xf71; + $sub[1] = 0xf74; + return $sub; + case 0xf76: + $sub[0] = 0xfb2; + $sub[1] = 0xf80; + return $sub; + case 0xf77: + $sub[0] = 0xfb2; + $sub[1] = 0xf81; + return $sub; + case 0xf78: + $sub[0] = 0xfb3; + $sub[1] = 0xf80; + return $sub; + case 0xf79: + $sub[0] = 0xfb3; + $sub[1] = 0xf71; + $sub[2] = 0xf80; + return $sub; + case 0xf81: + $sub[0] = 0xf71; + $sub[1] = 0xf80; + return $sub; + } + return false; + } + + public static function bubble_sort(&$arr, $start, $len) + { + if ($len < 2) { + return; + } + $k = $start + $len - 2; + while ($k >= $start) { + for ($j = $start; $j <= $k; $j++) { + if ($arr[$j]['indic_position'] > $arr[$j + 1]['indic_position']) { + $t = $arr[$j]; + $arr[$j] = $arr[$j + 1]; + $arr[$j + 1] = $t; + } + } + $k--; + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Myanmar.php b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Myanmar.php new file mode 100644 index 0000000..9a68eda --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Myanmar.php @@ -0,0 +1,543 @@ +<?php + +namespace Mpdf\Shaper; + +class Myanmar +{ + /* FROM hb-ot-shape-complex-indic-private.hh */ + + // indic_category + const OT_X = 0; + const OT_C = 1; + const OT_V = 2; + const OT_N = 3; + const OT_H = 4; + const OT_ZWNJ = 5; + const OT_ZWJ = 6; + const OT_M = 7; /* Matra or Dependent Vowel */ + const OT_SM = 8; + const OT_VD = 9; + const OT_A = 10; + const OT_NBSP = 11; + const OT_DOTTEDCIRCLE = 12; /* Not in the spec, but special in Uniscribe. /Very very/ special! */ + const OT_RS = 13; /* Register Shifter, used in Khmer OT spec */ + const OT_COENG = 14; + const OT_REPHA = 15; + const OT_RA = 16; /* Not explicitly listed in the OT spec, but used in the grammar. */ + const OT_CM = 17; + + /* FROM hb-ot-shape-complex-myanmar.hh */ + + // myanmar_category + const OT_DB = 3; // same as Indic::OT_N; /* Dot below */ + const OT_GB = 12; // same as Indic::OT_DOTTEDCIRCLE; + const OT_AS = 18; /* Asat */ + const OT_D = 19; /* Digits except zero */ + const OT_D0 = 20; /* Digit zero */ + const OT_MH = 21; /* Various consonant medial types */ + const OT_MR = 22; /* Various consonant medial types */ + const OT_MW = 23; /* Various consonant medial types */ + const OT_MY = 24; /* Various consonant medial types */ + const OT_PT = 25; /* Pwo and other tones */ + + const OT_VABV = 26; + const OT_VBLW = 27; + const OT_VPRE = 28; + const OT_VPST = 29; + const OT_VS = 30; /* Variation selectors */ + + /* Visual positions in a syllable from left to right. */ + /* FROM hb-ot-shape-complex-myanmar-private.hh */ + + // myanmar_position + const POS_START = 0; + + const POS_RA_TO_BECOME_REPH = 1; + const POS_PRE_M = 2; + const POS_PRE_C = 3; + + const POS_BASE_C = 4; + const POS_AFTER_MAIN = 5; + + const POS_ABOVE_C = 6; + + const POS_BEFORE_SUB = 7; + const POS_BELOW_C = 8; + const POS_AFTER_SUB = 9; + + const POS_BEFORE_POST = 10; + const POS_POST_C = 11; + const POS_AFTER_POST = 12; + + const POS_FINAL_C = 13; + const POS_SMVD = 14; + + const POS_END = 15; + + // Based on myanmar_category used to make string to find syllables + // OT_ to string character (using e.g. OT_C from MYANMAR) hb-ot-shape-complex-myanmar-private.hh + public static $myanmar_category_char = [ + 'x', + 'C', + 'V', + 'N', + 'H', + 'Z', + 'J', + 'x', + 'S', + 'x', + 'A', + 'x', + 'D', + 'x', + 'x', + 'x', + 'R', + 'x', + 'a', /* As Asat */ + 'd', /* Digits except zero */ + 'o', /* Digit zero */ + 'k', /* Medial types */ + 'l', /* Medial types */ + 'm', /* Medial types */ + 'n', /* Medial types */ + 'p', /* Pwo and other tones */ + 'v', /* Vowel aboVe */ + 'b', /* Vowel Below */ + 'e', /* Vowel prE */ + 't', /* Vowel posT */ + 's', /* variation Selector */ + ]; + + public static function set_myanmar_properties(&$info) + { + $u = $info['uni']; + $type = self::myanmar_get_categories($u); + $cat = ($type & 0x7F); + $pos = ($type >> 8); + /* + * Re-assign category + * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze + */ + if (self::in_range($u, 0xFE00, 0xFE0F)) { + $cat = self::OT_VS; + } elseif ($u == 0x200C) { + $cat = self::OT_ZWNJ; + } elseif ($u == 0x200D) { + $cat = self::OT_ZWJ; + } + + switch ($u) { + case 0x002D: + case 0x00A0: + case 0x00D7: + case 0x2012: + case 0x2013: + case 0x2014: + case 0x2015: + case 0x2022: + case 0x25CC: + case 0x25FB: + case 0x25FC: + case 0x25FD: + case 0x25FE: + $cat = self::OT_GB; + break; + + case 0x1004: + case 0x101B: + case 0x105A: + $cat = self::OT_RA; + break; + + case 0x1032: + case 0x1036: + $cat = self::OT_A; + break; + + case 0x103A: + $cat = self::OT_AS; + break; + + case 0x1041: + case 0x1042: + case 0x1043: + case 0x1044: + case 0x1045: + case 0x1046: + case 0x1047: + case 0x1048: + case 0x1049: + case 0x1090: + case 0x1091: + case 0x1092: + case 0x1093: + case 0x1094: + case 0x1095: + case 0x1096: + case 0x1097: + case 0x1098: + case 0x1099: + $cat = self::OT_D; + break; + + case 0x1040: + $cat = self::OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ + break; + + case 0x103E: + case 0x1060: + $cat = self::OT_MH; + break; + + case 0x103C: + $cat = self::OT_MR; + break; + + case 0x103D: + case 0x1082: + $cat = self::OT_MW; + break; + + case 0x103B: + case 0x105E: + case 0x105F: + $cat = self::OT_MY; + break; + + case 0x1063: + case 0x1064: + case 0x1069: + case 0x106A: + case 0x106B: + case 0x106C: + case 0x106D: + case 0xAA7B: + $cat = self::OT_PT; + break; + + case 0x1038: + case 0x1087: + case 0x1088: + case 0x1089: + case 0x108A: + case 0x108B: + case 0x108C: + case 0x108D: + case 0x108F: + case 0x109A: + case 0x109B: + case 0x109C: + $cat = self::OT_SM; + break; + } + + if ($cat == self::OT_M) { + switch ($pos) { + case self::POS_PRE_C: + $cat = self::OT_VPRE; + $pos = self::POS_PRE_M; + break; + case self::POS_ABOVE_C: + $cat = self::OT_VABV; + break; + case self::POS_BELOW_C: + $cat = self::OT_VBLW; + break; + case self::POS_POST_C: + $cat = self::OT_VPST; + break; + } + } + $info['myanmar_category'] = $cat; + $info['myanmar_position'] = $pos; + } + + // syllable_type + const CONSONANT_SYLLABLE = 0; + const BROKEN_CLUSTER = 3; + const NON_MYANMAR_CLUSTER = 4; + + public static function set_syllables(&$o, $s, &$broken_syllables) + { + $ptr = 0; + $syllable_serial = 1; + $broken_syllables = false; + + while ($ptr < strlen($s)) { + $match = ''; + $syllable_length = 1; + $syllable_type = self::NON_MYANMAR_CLUSTER; + // CONSONANT_SYLLABLE Consonant syllable + // From OT spec: + if (preg_match('/^(RaH)?([C|R]|V|d|D)[s]?(H([C|R|V])[s]?)*(H|[a]*[n]?[l]?((m[k]?|k)[a]?)?[e]*[v]*[b]*[A]*(N[a]?)?(t[k]?[a]*[v]*[A]*(N[a]?)?)*(p[A]*(N[a]?)?)*S*[J|Z]?)/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::CONSONANT_SYLLABLE; + } // BROKEN_CLUSTER syllable + elseif (preg_match('/^(RaH)?s?(H|[a]*[n]?[l]?((m[k]?|k)[a]?)?[e]*[v]*[b]*[A]*(N[a]?)?(t[k]?[a]*[v]*[A]*(N[a]?)?)*(p[A]*(N[a]?)?)*S*[J|Z]?)/', substr($s, $ptr), $ma)) { + if (strlen($ma[0])) { // May match blank + $syllable_length = strlen($ma[0]); + $syllable_type = self::BROKEN_CLUSTER; + $broken_syllables = true; + } + } + for ($i = $ptr; $i < $ptr + $syllable_length; $i++) { + $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; + } + $ptr += $syllable_length; + $syllable_serial++; + if ($syllable_serial == 16) { + $syllable_serial = 1; + } + } + } + + public static function reordering(&$info, $GSUBdata, $broken_syllables, $dottedcircle) + { + if ($broken_syllables && $dottedcircle) { + self::insert_dotted_circles($info, $dottedcircle); + } + $count = count($info); + if (!$count) { + return; + } + $last = 0; + $last_syllable = $info[0]['syllable']; + for ($i = 1; $i < $count; $i++) { + if ($last_syllable != $info[$i]['syllable']) { + self::reordering_syllable($info, $GSUBdata, $last, $i); + $last = $i; + $last_syllable = $info[$last]['syllable']; + } + } + self::reordering_syllable($info, $GSUBdata, $last, $count); + } + + public static function insert_dotted_circles(&$info, $dottedcircle) + { + $idx = 0; + $last_syllable = 0; + while ($idx < count($info)) { + $syllable = $info[$idx]['syllable']; + $syllable_type = ($syllable & 0x0F); + if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) { + $last_syllable = $syllable; + $dottedcircle[0]['syllable'] = $info[$idx]['syllable']; + array_splice($info, $idx, 0, $dottedcircle); + } else { + $idx++; + } + } + // In case of final bloken cluster... + $syllable = $info[$idx]['syllable']; + $syllable_type = ($syllable & 0x0F); + if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) { + $dottedcircle[0]['syllable'] = $info[$idx]['syllable']; + array_splice($info, $idx, 0, $dottedcircle); + } + } + + /* Rules from: + * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ + + public static function reordering_syllable(&$info, $GSUBdata, $start, $end) + { + /* vowel_syllable: We made the vowels look like consonants. So uses the consonant logic! */ + /* broken_cluster: We already inserted dotted-circles, so just call the standalone_cluster. */ + + $syllable_type = ($info[$start]['syllable'] & 0x0F); + if ($syllable_type == self::NON_MYANMAR_CLUSTER) { + return; + } + if ($syllable_type == self::BROKEN_CLUSTER) { + //if ($uniscribe_bug_compatible) { + /* For dotted-circle, this is what Uniscribe does: + * If dotted-circle is the last glyph, it just does nothing. + * i.e. It doesn't form Reph. */ + if ($info[$end - 1]['myanmar_category'] == self::OT_DOTTEDCIRCLE) { + return; + } + } + + $base = $end; + $has_reph = false; + $limit = $start; + + if (($start + 3 <= $end) && + $info[$start]['myanmar_category'] == self::OT_RA && + $info[$start + 1]['myanmar_category'] == self::OT_AS && + $info[$start + 2]['myanmar_category'] == self::OT_H) { + $limit += 3; + $base = $start; + $has_reph = true; + } + + if (!$has_reph) { + $base = $limit; + } + + for ($i = $limit; $i < $end; $i++) { + if (self::is_consonant($info[$i])) { + $base = $i; + break; + } + } + + + /* Reorder! */ + $i = $start; + for (; $i < $start + ($has_reph ? 3 : 0); $i++) { + $info[$i]['myanmar_position'] = self::POS_AFTER_MAIN; + } + for (; $i < $base; $i++) { + $info[$i]['myanmar_position'] = self::POS_PRE_C; + } + if ($i < $end) { + $info[$i]['myanmar_position'] = self::POS_BASE_C; + $i++; + } + $pos = self::POS_AFTER_MAIN; + /* The following loop may be ugly, but it implements all of + * Myanmar reordering! */ + for (; $i < $end; $i++) { + if ($info[$i]['myanmar_category'] == self::OT_MR) { /* Pre-base reordering */ + $info[$i]['myanmar_position'] = self::POS_PRE_C; + continue; + } + if ($info[$i]['myanmar_position'] < self::POS_BASE_C) { /* Left matra */ + continue; + } + + if ($pos == self::POS_AFTER_MAIN && $info[$i]['myanmar_category'] == self::OT_VBLW) { + $pos = self::POS_BELOW_C; + $info[$i]['myanmar_position'] = $pos; + continue; + } + + if ($pos == self::POS_BELOW_C && $info[$i]['myanmar_category'] == self::OT_A) { + $info[$i]['myanmar_position'] = self::POS_BEFORE_SUB; + continue; + } + if ($pos == self::POS_BELOW_C && $info[$i]['myanmar_category'] == self::OT_VBLW) { + $info[$i]['myanmar_position'] = $pos; + continue; + } + if ($pos == self::POS_BELOW_C && $info[$i]['myanmar_category'] != self::OT_A) { + $pos = self::POS_AFTER_SUB; + $info[$i]['myanmar_position'] = $pos; + continue; + } + $info[$i]['myanmar_position'] = $pos; + } + + + /* Sit tight, rock 'n roll! */ + self::bubble_sort($info, $start, $end - $start); + } + + public static function is_one_of($info, $flags) + { + if (isset($info['is_ligature']) && $info['is_ligature']) { + return false; + } /* If it ligated, all bets are off. */ + return !!(self::FLAG($info['myanmar_category']) & $flags); + } + + /* Vowels and placeholders treated as if they were consonants. */ + + public static function is_consonant($info) + { + return self::is_one_of($info, (self::FLAG(self::OT_C) | self::FLAG(self::OT_CM) | self::FLAG(self::OT_RA) | self::FLAG(self::OT_V) | self::FLAG(self::OT_NBSP) | self::FLAG(self::OT_GB))); + } + +// From hb-private.hh + public static function in_range($u, $lo, $hi) + { + if ((($lo ^ $hi) & $lo) == 0 && (($lo ^ $hi) & $hi) == ($lo ^ $hi) && (($lo ^ $hi) & (($lo ^ $hi) + 1)) == 0) { + return ($u & ~($lo ^ $hi)) == $lo; + } else { + return $lo <= $u && $u <= $hi; + } + } + + // From hb-private.hh + public static function FLAG($x) + { + return (1 << ($x)); + } + + public static function FLAG_RANGE($x, $y) + { + return self::FLAG($y + 1) - self::FLAG($x); + } + + // BELOW from hb-ot-shape-complex-indic.cc + // see INDIC for details + public static $myanmar_table = [ + /* Myanmar (1000..109F) */ + + /* 1000 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1008 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1010 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1018 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1020 */ 3841, 3842, 3842, 3842, 3842, 3842, 3842, 3842, + /* 1028 */ 3842, 3842, 3842, 2823, 2823, 1543, 1543, 2055, + /* 1030 */ 2055, 775, 1543, 1543, 1543, 1543, 3848, 3843, + /* 1038 */ 3848, 3844, 1540, 3857, 3857, 3857, 3857, 3841, + /* 1040 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1048 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1050 */ 3841, 3841, 3842, 3842, 3842, 3842, 2823, 2823, + /* 1058 */ 2055, 2055, 3841, 3841, 3841, 3841, 3857, 3857, + /* 1060 */ 3857, 3841, 2823, 3843, 3843, 3841, 3841, 2823, + /* 1068 */ 2823, 3843, 3843, 3843, 3843, 3843, 3841, 3841, + /* 1070 */ 3841, 1543, 1543, 1543, 1543, 3841, 3841, 3841, + /* 1078 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1080 */ 3841, 3841, 3857, 2823, 775, 1543, 1543, 3843, + /* 1088 */ 3843, 3843, 3843, 3843, 3843, 3843, 3841, 3843, + /* 1090 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1098 */ 3840, 3840, 3843, 3843, 2823, 1543, 3840, 3840, + /* Myanmar Extended-A (AA60..AA7F) */ + + /* AA60 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA68 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA70 */ 3840, 3841, 3841, 3841, 3840, 3840, 3840, 3840, + /* AA78 */ 3840, 3840, 3841, 3843, 3840, 3840, 3840, 3840, + ]; + + // from "hb-ot-shape-complex-indic-table.cc" + public static function myanmar_get_categories($u) + { + if (0x1000 <= $u && $u <= 0x109F) { + return self::$myanmar_table[$u - 0x1000 + 0]; // offset 0 for Most "myanmar" + } + if (0xAA60 <= $u && $u <= 0xAA7F) { + return self::$myanmar_table[$u - 0xAA60 + 160]; // offset for extensions + } + if ($u == 0x00A0) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + if ($u == 0x25CC) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + return 3840; // (ISC_x | (IMC_x << 8)) + } + + public static function bubble_sort(&$arr, $start, $len) + { + if ($len < 2) { + return; + } + $k = $start + $len - 2; + while ($k >= $start) { + for ($j = $start; $j <= $k; $j++) { + if ($arr[$j]['myanmar_position'] > $arr[$j + 1]['myanmar_position']) { + $t = $arr[$j]; + $arr[$j] = $arr[$j + 1]; + $arr[$j + 1] = $t; + } + } + $k--; + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Sea.php b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Sea.php new file mode 100644 index 0000000..40adacc --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Shaper/Sea.php @@ -0,0 +1,397 @@ +<?php + +namespace Mpdf\Shaper; + +class Sea +{ + // South East Asian shaper + // sea_category + const OT_X = 0; + + const OT_C = 1; + + const OT_IV = 2; # Independent Vowel + + const OT_T = 3; # Tone Marks + + const OT_H = 4; # Halant + + const OT_A = 10; # Anusvara + + const OT_GB = 12; # Generic Base (OT_DOTTEDCIRCLE in Indic) + + const OT_CM = 17; # Consonant Medial + + const OT_MR = 22; # Medial Ra + + const OT_VABV = 26; + + const OT_VBLW = 27; + + const OT_VPRE = 28; + + const OT_VPST = 29; + + // ? From Indic categories + const OT_ZWNJ = 5; + + const OT_ZWJ = 6; + + const OT_M = 7; + + const OT_SM = 8; + + const OT_VD = 9; + + const OT_NBSP = 11; + + const OT_RS = 13; + + const OT_COENG = 14; + + const OT_REPHA = 15; + + const OT_RA = 16; + + /* Visual positions in a syllable from left to right. */ + // sea_position + const POS_START = 0; + + const POS_RA_TO_BECOME_REPH = 1; + + const POS_PRE_M = 2; + + const POS_PRE_C = 3; + + const POS_BASE_C = 4; + + const POS_AFTER_MAIN = 5; + + const POS_ABOVE_C = 6; + + const POS_BEFORE_SUB = 7; + + const POS_BELOW_C = 8; + + const POS_AFTER_SUB = 9; + + const POS_BEFORE_POST = 10; + + const POS_POST_C = 11; + + const POS_AFTER_POST = 12; + + const POS_FINAL_C = 13; + + const POS_SMVD = 14; + + const POS_END = 15; + + // Based on sea_category used to make string to find syllables + // OT_ to string character (using e.g. OT_C from INDIC) hb-ot-shape-complex-sea-private.hh + public static $sea_category_char = [ + 'x', + 'C', + 'V', + 'T', + 'H', + 'x', + 'x', + 'x', + 'x', + 'x', + 'A', + 'x', + 'G', + 'x', + 'x', + 'x', + 'x', + 'M', + 'x', + 'x', + 'x', + 'x', + 'R', + 'x', + 'x', + 'x', + 'a', + 'b', + 'p', + 't', + ]; + + public static function set_sea_properties(&$info, $scriptblock) + { + $u = $info['uni']; + $type = self::sea_get_categories($u); + $cat = ($type & 0x7F); + $pos = ($type >> 8); + + /* + * Re-assign category + */ + // Medial Ra + if ($u == 0x1A55 || $u == 0xAA34) { + $cat = self::OT_MR; + } + + /* + * Re-assign position. + */ + if ($cat == self::OT_M) { // definitely "OT_M" in HarfBuzz - although this does not seem to have been defined ? should be OT_MR + switch ($pos) { + case self::POS_PRE_C: + $cat = self::OT_VPRE; + break; + case self::POS_ABOVE_C: + $cat = self::OT_VABV; + break; + case self::POS_BELOW_C: + $cat = self::OT_VBLW; + break; + case self::POS_POST_C: + $cat = self::OT_VPST; + break; + } + } + + $info['sea_category'] = $cat; + $info['sea_position'] = $pos; + } + + // syllable_type + const CONSONANT_SYLLABLE = 0; + + const BROKEN_CLUSTER = 1; + + const NON_SEA_CLUSTER = 2; + + public static function set_syllables(&$o, $s, &$broken_syllables) + { + $ptr = 0; + $syllable_serial = 1; + $broken_syllables = false; + while ($ptr < strlen($s)) { + $match = ''; + $syllable_length = 1; + $syllable_type = self::NON_SEA_CLUSTER; + + // CONSONANT_SYLLABLE Consonant syllable + if (preg_match('/^(C|V|G)(p|a|b|t|HC|M|R|T|A)*/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::CONSONANT_SYLLABLE; + } // BROKEN_CLUSTER syllable + elseif (preg_match('/^(p|a|b|t|HC|M|R|T|A)+/', substr($s, $ptr), $ma)) { + $syllable_length = strlen($ma[0]); + $syllable_type = self::BROKEN_CLUSTER; + $broken_syllables = true; + } + + for ($i = $ptr; $i < $ptr + $syllable_length; $i++) { + $o[$i]['syllable'] = ($syllable_serial << 4) | $syllable_type; + } + $ptr += $syllable_length; + $syllable_serial++; + if ($syllable_serial == 16) { + $syllable_serial = 1; + } + } + } + + public static function initial_reordering(&$info, $GSUBdata, $broken_syllables, $scriptblock, $dottedcircle) + { + + if ($broken_syllables && $dottedcircle) { + self::insert_dotted_circles($info, $dottedcircle); + } + + $count = count($info); + if (!$count) { + return; + } + $last = 0; + $last_syllable = $info[0]['syllable']; + for ($i = 1; $i < $count; $i++) { + if ($last_syllable != $info[$i]['syllable']) { + self::initial_reordering_syllable($info, $GSUBdata, $scriptblock, $last, $i); + $last = $i; + $last_syllable = $info[$last]['syllable']; + } + } + self::initial_reordering_syllable($info, $GSUBdata, $scriptblock, $last, $count); + } + + public static function insert_dotted_circles(&$info, $dottedcircle) + { + $idx = 0; + $last_syllable = 0; + while ($idx < count($info)) { + $syllable = $info[$idx]['syllable']; + $syllable_type = ($syllable & 0x0F); + if ($last_syllable != $syllable && $syllable_type == self::BROKEN_CLUSTER) { + $last_syllable = $syllable; + $dottedcircle[0]['syllable'] = $info[$idx]['syllable']; + array_splice($info, $idx, 0, $dottedcircle); + } else { + $idx++; + } + } + } + + public static function initial_reordering_syllable(&$info, $GSUBdata, $scriptblock, $start, $end) + { + /* broken_cluster: We already inserted dotted-circles, so just call the standalone_cluster. */ + + $syllable_type = ($info[$start]['syllable'] & 0x0F); + if ($syllable_type == self::NON_SEA_CLUSTER) { + return; + } + if ($syllable_type == self::BROKEN_CLUSTER) { + /* For dotted-circle, this is what Uniscribe does: + * If dotted-circle is the last glyph, it just does nothing. */ + if ($info[$end - 1]['sea_category'] == self::OT_GB) { + return; + } + } + + $base = $start; + $i = $start; + for (; $i < $base; $i++) { + $info[$i]['sea_position'] = self::POS_PRE_C; + } + if ($i < $end) { + $info[$i]['sea_position'] = self::POS_BASE_C; + $i++; + } + for (; $i < $end; $i++) { + if (isset($info[$i]['sea_category']) && $info[$i]['sea_category'] == self::OT_MR) { /* Pre-base reordering */ + $info[$i]['sea_position'] = self::POS_PRE_C; + continue; + } + if (isset($info[$i]['sea_category']) && $info[$i]['sea_category'] == self::OT_VPRE) { /* Left matra */ + $info[$i]['sea_position'] = self::POS_PRE_M; + continue; + } + $info[$i]['sea_position'] = self::POS_AFTER_MAIN; + } + + /* Sit tight, rock 'n roll! */ + self::bubble_sort($info, $start, $end - $start); + } + + public static function final_reordering(&$info, $GSUBdata, $scriptblock) + { + $count = count($info); + if (!$count) { + return; + } + $last = 0; + $last_syllable = $info[0]['syllable']; + for ($i = 1; $i < $count; $i++) { + if ($last_syllable != $info[$i]['syllable']) { + self::final_reordering_syllable($info, $GSUBdata, $scriptblock, $last, $i); + $last = $i; + $last_syllable = $info[$last]['syllable']; + } + } + self::final_reordering_syllable($info, $GSUBdata, $scriptblock, $last, $count); + } + + public static function final_reordering_syllable(&$info, $GSUBdata, $scriptblock, $start, $end) + { + /* + * Nothing to do here at present! + */ + } + + public static $sea_table = [ + /* New Tai Lue (1980..19DF) */ + + /* 1980 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1988 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1990 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1998 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 19A0 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 19A8 */ 3841, 3841, 3841, 3841, 3840, 3840, 3840, 3840, + /* 19B0 */ 2823, 2823, 2823, 2823, 2823, 775, 775, 775, + /* 19B8 */ 2823, 2823, 775, 2823, 2823, 2823, 2823, 2823, + /* 19C0 */ 2823, 3857, 3857, 3857, 3857, 3857, 3857, 3857, + /* 19C8 */ 3843, 3843, 3840, 3840, 3840, 3840, 3840, 3840, + /* 19D0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 19D8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Tai Tham (1A20..1AAF) */ + + /* 1A20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1A28 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1A30 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1A38 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1A40 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* 1A48 */ 3841, 3841, 3841, 3841, 3841, 3842, 3842, 3842, + /* 1A50 */ 3842, 3842, 3842, 3841, 3841, 3857, 3857, 3857, + /* 1A58 */ 3857, 3857, 3857, 3857, 3857, 3857, 3857, 3840, + /* 1A60 */ 3844, 2823, 1543, 2823, 2823, 1543, 1543, 1543, + /* 1A68 */ 1543, 2055, 2055, 1543, 2055, 2823, 775, 775, + /* 1A70 */ 775, 775, 775, 1543, 1543, 3843, 3843, 3843, + /* 1A78 */ 3843, 3843, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1A80 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1A88 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1A90 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1A98 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1AA0 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* 1AA8 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* Cham (AA00..AA5F) */ + + /* AA00 */ 3842, 3842, 3842, 3842, 3842, 3842, 3841, 3841, + /* AA08 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA10 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA18 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA20 */ 3841, 3841, 3841, 3841, 3841, 3841, 3841, 3841, + /* AA28 */ 3841, 1543, 1543, 1543, 1543, 2055, 1543, 775, + /* AA30 */ 775, 1543, 2055, 3857, 3857, 3857, 3857, 3840, + /* AA38 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* AA40 */ 3857, 3857, 3857, 3857, 3857, 3857, 3857, 3857, + /* AA48 */ 3857, 3857, 3857, 3857, 3857, 3857, 3840, 3840, + /* AA50 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + /* AA58 */ 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + ]; + + public static function sea_get_categories($u) + { + if (0x1980 <= $u && $u <= 0x19DF) { + return self::$sea_table[$u - 0x1980]; // offset 0 for New Tai Lue + } + if (0x1A20 <= $u && $u <= 0x1AAF) { + return self::$sea_table[$u - 0x1A20 + 96]; // offset for Tai Tham + } + if (0xAA00 <= $u && $u <= 0xAA5F) { + return self::$sea_table[$u - 0xAA00 + 96 + 144]; // Cham + } + if ($u == 0x00A0) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + if ($u == 0x25CC) { + return 3851; // (ISC_CP | (IMC_x << 8)) + } + return 3840; // (ISC_x | (IMC_x << 8)) + } + + public static function bubble_sort(&$arr, $start, $len) + { + if ($len < 2) { + return; + } + $k = $start + $len - 2; + while ($k >= $start) { + for ($j = $start; $j <= $k; $j++) { + if ($arr[$j]['sea_position'] > $arr[$j + 1]['sea_position']) { + $t = $arr[$j]; + $arr[$j] = $arr[$j + 1]; + $arr[$j + 1] = $t; + } + } + $k--; + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/SizeConverter.php b/lib/MPDF/vendor/mpdf/mpdf/src/SizeConverter.php new file mode 100644 index 0000000..9ec93fd --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/SizeConverter.php @@ -0,0 +1,161 @@ +<?php + +namespace Mpdf; + +use Psr\Log\LoggerInterface; +use Mpdf\Log\Context as LogContext; + +class SizeConverter implements \Psr\Log\LoggerAwareInterface +{ + + private $dpi; + + private $defaultFontSize; + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + public function __construct($dpi, $defaultFontSize, Mpdf $mpdf, LoggerInterface $logger) + { + $this->dpi = $dpi; + $this->defaultFontSize = $defaultFontSize; + $this->mpdf = $mpdf; + $this->logger = $logger; + } + + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Depends of maxsize value to make % work properly. Usually maxsize == pagewidth + * For text $maxsize = $fontsize + * Setting e.g. margin % will use maxsize (pagewidth) and em will use fontsize + * + * @param mixed $size + * @param mixed $maxsize + * @param mixed $fontsize + * @param mixed $usefontsize Set false for e.g. margins - will ignore fontsize for % values + * + * @return float Final size in mm + */ + public function convert($size = 5, $maxsize = 0, $fontsize = false, $usefontsize = true) + { + $size = trim(strtolower($size)); + $res = preg_match('/^(?P<size>[-0-9.,]+([eE]\-?[0-9]+)?)?(?P<unit>[%a-z-]+)?$/', $size, $parts); + if (!$res) { + // ignore definition + $this->logger->warning(sprintf('Invalid size representation "%s"', $size), ['context' => LogContext::CSS_SIZE_CONVERSION]); + } + + $unit = !empty($parts['unit']) ? $parts['unit'] : null; + $size = !empty($parts['size']) ? (float) $parts['size'] : 0.0; + + switch ($unit) { + case 'mm': + // do nothing + break; + + case 'cm': + $size *= 10; + break; + + case 'pt': + $size *= 1 / Mpdf::SCALE; + break; + + case 'rem': + $size *= $this->mpdf->default_font_size / Mpdf::SCALE; + break; + + case '%': + if ($fontsize && $usefontsize) { + $size *= $fontsize / 100; + } else { + $size *= $maxsize / 100; + } + break; + + case 'in': + // mm in an inch + $size *= 25.4; + break; + + case 'pc': + // PostScript picas + $size *= 38.1 / 9; + break; + + case 'ex': + // Approximates "ex" as half of font height + $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.5); + break; + + case 'em': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 1); + break; + + case 'thin': + $size = 1 * (25.4 / $this->dpi); + break; + + case 'medium': + $size = 3 * (25.4 / $this->dpi); + // Commented-out dead code from legacy method + // $size *= $this->multiplyFontSize($fontsize, $maxsize, 1); + break; + + case 'thick': + $size = 5 * (25.4 / $this->dpi); // 5 pixel width for table borders + break; + + case 'xx-small': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.7); + break; + + case 'x-small': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.77); + break; + + case 'small': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 0.86); + break; + + case 'large': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 1.2); + break; + + case 'x-large': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 1.5); + break; + + case 'xx-large': + $size *= $this->multiplyFontSize($fontsize, $maxsize, 2); + break; + + case 'px': + default: + $size *= (25.4 / $this->dpi); + break; + } + + return $size; + } + + private function multiplyFontSize($fontsize, $maxsize, $ratio) + { + if ($fontsize) { + return $fontsize * $ratio; + } + + return $maxsize * $ratio; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Strict.php b/lib/MPDF/vendor/mpdf/mpdf/src/Strict.php new file mode 100644 index 0000000..bab863d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Strict.php @@ -0,0 +1,67 @@ +<?php + +namespace Mpdf; + +trait Strict +{ + + /** + * @param string $name method name + * @param array $args arguments + */ + public function __call($name, $args) + { + $class = method_exists($this, $name) ? 'parent' : get_class($this); + throw new \Mpdf\MpdfException("Call to undefined method $class::$name()"); + } + + /** + * @param string $name lowercase method name + * @param array $args arguments + */ + public static function __callStatic($name, $args) + { + $class = get_called_class(); + throw new \Mpdf\MpdfException("Call to undefined static function $class::$name()"); + } + + /** + * @param string $name property name + */ + public function &__get($name) + { + $class = get_class($this); + throw new \Mpdf\MpdfException("Cannot read an undeclared property $class::\$$name"); + } + + /** + * @param string $name property name + * @param mixed $value property value + */ + public function __set($name, $value) + { + $class = get_class($this); + throw new \Mpdf\MpdfException("Cannot write to an undeclared property $class::\$$name"); + } + + /** + * @param string $name property name + * @throws \Kdyby\StrictObjects\\Mpdf\MpdfException + */ + public function __isset($name) + { + $class = get_class($this); + throw new \Mpdf\MpdfException("Cannot read an undeclared property $class::\$$name"); + } + + /** + * @param string $name property name + * @throws \Kdyby\StrictObjects\\Mpdf\MpdfException + */ + public function __unset($name) + { + $class = get_class($this); + throw new \Mpdf\MpdfException("Cannot unset the property $class::\$$name."); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFile.php b/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFile.php new file mode 100644 index 0000000..0834ff0 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFile.php @@ -0,0 +1,4947 @@ +<?php + +namespace Mpdf; + +use Mpdf\Fonts\FontCache; +use Mpdf\Fonts\GlyphOperator; + +// NOTE*** If you change the defined constants below, be sure to delete all temporary font data files in /ttfontdata/ +// to force mPDF to regenerate cached font files. +if (!defined('_OTL_OLD_SPEC_COMPAT_2')) { + define('_OTL_OLD_SPEC_COMPAT_2', true); +} + +// Define the value used in the "head" table of a created TTF file +// 0x74727565 "true" for Mac +// 0x00010000 for Windows +// Either seems to work for a font embedded in a PDF file +// when read by Adobe Reader on a Windows PC(!) +if (!defined('_TTF_MAC_HEADER')) { + define('_TTF_MAC_HEADER', false); +} + +// Recalculate correct metadata/profiles when making subset fonts (not SIP/SMP) +// e.g. xMin, xMax, maxNContours +if (!defined('_RECALC_PROFILE')) { + define('_RECALC_PROFILE', false); +} + +// mPDF 5.7.1 +if (!function_exists('\Mpdf\unicode_hex')) { + function unicode_hex($unicode_dec) + { + return sprintf("%05s", strtoupper(dechex($unicode_dec))); + } +} + +/** + * TTFontFile class + * + * This class is based on The ReportLab Open Source PDF library + * written in Python - http://www.reportlab.com/software/opensource/ + * together with ideas from the OpenOffice source code and others. + * This header must be retained in any redistribution or + * modification of the file. + * + * @author Ian Back <ianb@bpm1.com> + * @license LGPL + */ +class TTFontFile +{ + + use Strict; + + private $fontCache; + + private $fontDescriptor; + + var $GPOSFeatures; + + var $GPOSLookups; + + var $GPOSScriptLang; + + var $MarkAttachmentType; + + var $MarkGlyphSets; + + var $GlyphClassMarks; + + var $GlyphClassLigatures; + + var $GlyphClassBases; + + var $GlyphClassComponents; + + var $GSUBScriptLang; + + var $rtlPUAstr; + + var $fontkey; + + var $useOTL; + + var $maxUni; + + var $sFamilyClass; + + var $sFamilySubClass; + + var $sipset; + + var $smpset; + + var $_pos; + + var $numTables; + + var $searchRange; + + var $entrySelector; + + var $rangeShift; + + var $tables; + + var $otables; + + var $filename; + + var $fh; + + var $glyphPos; + + var $charToGlyph; + + var $ascent; + + var $descent; + + var $lineGap; + + var $hheaascent; + + var $hheadescent; + + var $hhealineGap; + + var $advanceWidthMax; + + var $typoAscender; + + var $typoDescender; + + var $typoLineGap; + + var $usWinAscent; + + var $usWinDescent; + + var $strikeoutSize; + + var $strikeoutPosition; + + var $name; + + var $familyName; + + var $styleName; + + var $fullName; + + var $uniqueFontID; + + var $unitsPerEm; + + var $bbox; + + var $capHeight; + + var $xHeight; + + var $stemV; + + var $italicAngle; + + var $flags; + + var $underlinePosition; + + var $underlineThickness; + + var $charWidths; + + var $defaultWidth; + + var $maxStrLenRead; + + var $numTTCFonts; + + var $TTCFonts; + + var $maxUniChar; + + var $kerninfo; + + var $haskernGPOS; + + var $hassmallcapsGSUB; + + var $codeToGlyph; + + var $glyphdata; + + var $LuCoverage; + + public $panose; + + public $version; + + public $fontRevision; + + public $restrictedUse; + + public $glyphIDtoUni; + + public $glyphToChar; + + public $GSUBFeatures; + + public $GSUBLookups; + + public $GSLuCoverage; + + public function __construct(FontCache $fontCache, $fontDescriptor) + { + $this->fontCache = $fontCache; + $this->fontDescriptor = $fontDescriptor; + + // Maximum size of glyf table to read in as string (otherwise reads each glyph from file) + $this->maxStrLenRead = 200000; + } + + public function getMetrics($file, $fontkey, $TTCfontID = 0, $debug = false, $BMPonly = false, $useOTL = 0) + { + $this->useOTL = $useOTL; + $this->fontkey = $fontkey; + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open font file "%s"', $file)); + } + + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->kerninfo = []; + $this->haskernGPOS = []; + $this->hassmallcapsGSUB = []; + $this->ascent = 0; + $this->descent = 0; + $this->lineGap = 0; + $this->hheaascent = 0; + $this->hheadescent = 0; + $this->hhealineGap = 0; + $this->xHeight = 0; + $this->capHeight = 0; + $this->panose = []; + $this->sFamilyClass = 0; + $this->sFamilySubClass = 0; + $this->typoAscender = 0; + $this->typoDescender = 0; + $this->typoLineGap = 0; + $this->usWinAscent = 0; + $this->usWinDescent = 0; + $this->advanceWidthMax = 0; + $this->strikeoutSize = 0; + $this->strikeoutPosition = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->version = $version = $this->read_ulong(); + $this->panose = []; + + if ($version === 0x4F54544F) { + throw new \Mpdf\MpdfException('Postscript outlines are not supported'); + } + + if ($version === 0x74746366 && !$TTCfontID) { + throw new \Mpdf\MpdfException(sprintf('TTCfontID for a TrueType Collection is not defined in mPDF "fontdata" configuration (%s)', $file)); + } + + if (!in_array($version, [0x00010000, 0x74727565], true) && !$TTCfontID) { + throw new \Mpdf\MpdfException(sprintf('Not a TrueType font: version=%s)', $version)); + } + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000], true)) { + throw new \Mpdf\MpdfException(sprintf('Error parsing TrueType Collection: version=%s - (%s)', $version, $file)); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + + $this->readTableDirectory($debug); + $this->extractInfo($debug, $BMPonly, $useOTL); + + fclose($this->fh); + } + + function readTableDirectory($debug = false) + { + $this->numTables = $this->read_ushort(); + $this->searchRange = $this->read_ushort(); + $this->entrySelector = $this->read_ushort(); + $this->rangeShift = $this->read_ushort(); + $this->tables = []; + + for ($i = 0; $i < $this->numTables; $i++) { + $record = []; + $record['tag'] = $this->read_tag(); + $record['checksum'] = [$this->read_ushort(), $this->read_ushort()]; + $record['offset'] = $this->read_ulong(); + $record['length'] = $this->read_ulong(); + $this->tables[$record['tag']] = $record; + } + + if ($debug) { + $this->checksumTables(); + } + } + + function checksumTables() + { + // Check the checksums for all tables + foreach ($this->tables as $t) { + if ($t['length'] > 0 && $t['length'] < $this->maxStrLenRead) { // 1.02 + $table = $this->get_chunk($t['offset'], $t['length']); + $checksum = $this->calcChecksum($table); + if ($t['tag'] === 'head') { + $up = unpack('n*', substr($table, 8, 4)); + $adjustment[0] = $up[1]; + $adjustment[1] = $up[2]; + $checksum = $this->sub32($checksum, $adjustment); + } + $xchecksum = $t['checksum']; + if ($xchecksum != $checksum) { + throw new \Mpdf\MpdfException(sprintf('TTF file "%s": invalid checksum %s table: %s (expected %s)', $this->filename, dechex($checksum[0]) . dechex($checksum[1]), $t['tag'], dechex($xchecksum[0]) . dechex($xchecksum[1]))); + } + } + } + } + + function sub32($x, $y) + { + $xlo = $x[1]; + $xhi = $x[0]; + $ylo = $y[1]; + $yhi = $y[0]; + + if ($ylo > $xlo) { + $xlo += 1 << 16; + ++$yhi; + } + $reslo = $xlo - $ylo; + if ($yhi > $xhi) { + $xhi += 1 << 16; + } + $reshi = $xhi - $yhi; + $reshi &= 0xFFFF; + + return [$reshi, $reslo]; + } + + function calcChecksum($data) + { + if (strlen($data) % 4) { + $data .= str_repeat("\0", 4 - (strlen($data) % 4)); + } + + $len = strlen($data); + $hi = 0x0000; + $lo = 0x0000; + + for ($i = 0; $i < $len; $i += 4) { + $hi += (ord($data[$i]) << 8) + ord($data[$i + 1]); + $lo += (ord($data[$i + 2]) << 8) + ord($data[$i + 3]); + $hi += ($lo >> 16) & 0xFFFF; + $lo &= 0xFFFF; + } + + $hi &= 0xFFFF; + + return [$hi, $lo]; + } + + function get_table_pos($tag) + { + if (!isset($this->tables[$tag])) { + return [0, 0]; + } + $offset = $this->tables[$tag]['offset']; + $length = $this->tables[$tag]['length']; + + return [$offset, $length]; + } + + function seek($pos) + { + $this->_pos = $pos; + fseek($this->fh, $this->_pos); + } + + function skip($delta) + { + $this->_pos = $this->_pos + $delta; + fseek($this->fh, $delta, SEEK_CUR); + } + + function seek_table($tag, $offset_in_table = 0) + { + $tpos = $this->get_table_pos($tag); + $this->_pos = $tpos[0] + $offset_in_table; + fseek($this->fh, $this->_pos); + + return $this->_pos; + } + + function read_tag() + { + $this->_pos += 4; + + return fread($this->fh, 4); + } + + function read_short() + { + $this->_pos += 2; + $s = fread($this->fh, 2); + $a = (ord($s[0]) << 8) + ord($s[1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + + return $a; + } + + function unpack_short($s) + { + $a = (ord($s[0]) << 8) + ord($s[1]); + if ($a & (1 << 15)) { + $a = ($a - (1 << 16)); + } + + return $a; + } + + function read_ushort() + { + $this->_pos += 2; + $s = fread($this->fh, 2); + + return (ord($s[0]) << 8) + ord($s[1]); + } + + function read_ulong() + { + $this->_pos += 4; + $s = fread($this->fh, 4); + + // if large uInt32 as an integer, PHP converts it to -ve + return (ord($s[0]) * 16777216) + (ord($s[1]) << 16) + (ord($s[2]) << 8) + ord($s[3]); // 16777216 = 1<<24 + } + + function get_ushort($pos) + { + fseek($this->fh, $pos); + $s = fread($this->fh, 2); + + return (ord($s[0]) << 8) + ord($s[1]); + } + + function get_ulong($pos) + { + fseek($this->fh, $pos); + $s = fread($this->fh, 4); + + // iF large uInt32 as an integer, PHP converts it to -ve + return (ord($s[0]) * 16777216) + (ord($s[1]) << 16) + (ord($s[2]) << 8) + ord($s[3]); // 16777216 = 1<<24 + } + + function pack_short($val) + { + if ($val < 0) { + $val = abs($val); + $val = ~$val; + ++$val; + } + + return pack('n', $val); + } + + function splice($stream, $offset, $value) + { + return substr($stream, 0, $offset) . $value . substr($stream, $offset + strlen($value)); + } + + function _set_ushort($stream, $offset, $value) + { + $up = pack("n", $value); + + return $this->splice($stream, $offset, $up); + } + + function _set_short($stream, $offset, $val) + { + if ($val < 0) { + $val = abs($val); + $val = ~$val; + $val += 1; + } + $up = pack("n", $val); + + return $this->splice($stream, $offset, $up); + } + + function get_chunk($pos, $length) + { + fseek($this->fh, $pos); + if ($length < 1) { + return ''; + } + + return (fread($this->fh, $length)); + } + + function get_table($tag) + { + list($pos, $length) = $this->get_table_pos($tag); + if ($length == 0) { + return ''; + } + fseek($this->fh, $pos); + + return (fread($this->fh, $length)); + } + + function add($tag, $data) + { + if ($tag === 'head') { + $data = $this->splice($data, 8, "\0\0\0\0"); + } + $this->otables[$tag] = $data; + } + + function getCTG($file, $TTCfontID = 0, $debug = false, $useOTL = false) + { + // Only called if font is not to be used as embedded subset i.e. NOT called for SIP/SMP fonts + $this->useOTL = $useOTL; // mPDF 5.7.1 + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file "%s"', $file)); + } + + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->skip(4); + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000], true)) { + throw new \Mpdf\MpdfException(sprintf("Error parsing TrueType Collection: version=%s (%s)", $version, $file)); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + $this->readTableDirectory($debug); + + // cmap - Character to glyph index mapping table + $cmap_offset = $this->seek_table('cmap'); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if ($platformID == 3 && $encodingID == 1) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } elseif ($platformID == 0) { // Unicode -- assume all encodings are compatible + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + $this->seek($save_pos); + } + + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + + // Map Unmapped glyphs - from $numGlyphs + if ($useOTL) { + $this->seek_table("maxp"); + $this->skip(4); + $numGlyphs = $this->read_ushort(); + $bctr = 0xE000; + for ($gid = 1; $gid < $numGlyphs; $gid++) { + if (!isset($glyphToChar[$gid])) { + while (isset($charToGlyph[$bctr])) { + $bctr++; + } // Avoid overwriting a glyph already mapped in PUA + if ($bctr > 0xF8FF) { + throw new \Mpdf\MpdfException(sprintf('Font "%s" cannot map all included glyphs into Private Use Area U+E000-U+F8FF; cannot use useOTL on this font', $file)); + } + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $bctr++; + } + } + } + + fclose($this->fh); + + return $charToGlyph; + } + + function getTTCFonts($file) + { + $this->filename = $file; + + $this->fh = fopen($file, 'rb'); + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file "%s"', $file)); + } + + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->version = $version = $this->read_ulong(); + if ($version === 0x74746366) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000], true)) { + throw new \Mpdf\MpdfException(sprintf("Error parsing TrueType Collection: version=%s (%s)", $version, $file)); + } + } else { + throw new \Mpdf\MpdfException(sprintf("Not a TrueType Collection: version=%s (%s)", $version, $file)); + } + + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + } + + function extractInfo($debug = false, $BMPonly = false, $useOTL = 0) + { + // Values are all set to 0 or blank at start of getMetrics + // name - Naming table + $name_offset = $this->seek_table("name"); + $format = $this->read_ushort(); + if ($format != 0 && $format != 1) { + throw new \Mpdf\MpdfException("Unknown name table format " . $format); + } + + $numRecords = $this->read_ushort(); + $string_data_offset = $name_offset + $this->read_ushort(); + $names = [1 => '', 2 => '', 3 => '', 4 => '', 6 => '']; + $K = array_keys($names); + $nameCount = count($names); + + for ($i = 0; $i < $numRecords; $i++) { + + $platformId = $this->read_ushort(); + $encodingId = $this->read_ushort(); + $languageId = $this->read_ushort(); + $nameId = $this->read_ushort(); + $length = $this->read_ushort(); + $offset = $this->read_ushort(); + + if (!in_array($nameId, $K)) { + continue; + } + + $N = ''; + if ($platformId == 3 && $encodingId == 1 && $languageId == 0x409) { // Microsoft, Unicode, US English, PS Name + $opos = $this->_pos; + $this->seek($string_data_offset + $offset); + if ($length % 2 != 0) { + throw new \Mpdf\MpdfException("PostScript name is UTF-16BE string of odd length"); + } + $length /= 2; + $N = ''; + while ($length > 0) { + $char = $this->read_ushort(); + $N .= (chr($char)); + $length -= 1; + } + $this->_pos = $opos; + $this->seek($opos); + } elseif ($platformId == 1 && $encodingId == 0 && $languageId == 0) { // Macintosh, Roman, English, PS Name + $opos = $this->_pos; + $N = $this->get_chunk($string_data_offset + $offset, $length); + $this->_pos = $opos; + $this->seek($opos); + } + if ($N && $names[$nameId] == '') { + $names[$nameId] = $N; + $nameCount -= 1; + if ($nameCount == 0) { + break; + } + } + } + + if ($names[6]) { + $psName = $names[6]; + } elseif ($names[4]) { + $psName = preg_replace('/ /', '-', $names[4]); + } elseif ($names[1]) { + $psName = preg_replace('/ /', '-', $names[1]); + } else { + $psName = ''; + } + + if (!$psName) { + throw new \Mpdf\MpdfException("Could not find PostScript font name: " . $this->filename); + } + + // CHECK IF psName valid (PadaukBook contains illegal characters in Name ID 6 i.e. Postscript Name) + $psNameInvalid = false; + $nameLength = strlen($psName); + for ($i = 0; $i < $nameLength; $i++) { + $c = $psName[$i]; + $oc = ord($c); + if ($oc > 126 || strpos(' [](){}<>/%', $c) !== false) { + //throw new \Mpdf\MpdfException("psName=".$psName." contains invalid character ".$c." ie U+".ord(c)); + $psNameInvalid = true; + break; + } + } + + if ($psNameInvalid && $names[4]) { + $psName = preg_replace('/ /', '-', $names[4]); + } + + $this->name = $psName; + if ($names[1]) { + $this->familyName = $names[1]; + } else { + $this->familyName = $psName; + } + if ($names[2]) { + $this->styleName = $names[2]; + } else { + $this->styleName = 'Regular'; + } + if ($names[4]) { + $this->fullName = $names[4]; + } else { + $this->fullName = $psName; + } + if ($names[3]) { + $this->uniqueFontID = $names[3]; + } else { + $this->uniqueFontID = $psName; + } + + if (!$psNameInvalid && $names[6]) { + $this->fullName = $names[6]; + } + + // head - Font header table + $this->seek_table('head'); + if ($debug) { + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException('Unknown head table version ' . $ver_maj . '.' . $ver_min); + } + $this->fontRevision = $this->read_ushort() . $this->read_ushort(); + + $this->skip(4); + $magic = $this->read_ulong(); + if ($magic !== 0x5F0F3CF5) { + throw new \Mpdf\MpdfException('Invalid head table magic ' . $magic); + } + $this->skip(2); + } else { + $this->skip(18); + } + $this->unitsPerEm = $unitsPerEm = $this->read_ushort(); + $scale = 1000 / $unitsPerEm; + $this->skip(16); + $xMin = $this->read_short(); + $yMin = $this->read_short(); + $xMax = $this->read_short(); + $yMax = $this->read_short(); + $this->bbox = [($xMin * $scale), ($yMin * $scale), ($xMax * $scale), ($yMax * $scale)]; + + $this->skip(3 * 2); + $indexToLocFormat = $this->read_ushort(); + $glyphDataFormat = $this->read_ushort(); + if ($glyphDataFormat != 0) { + throw new \Mpdf\MpdfException(sprintf('Unknown glyph data format %s', $glyphDataFormat)); + } + + // hhea metrics table + if (isset($this->tables["hhea"])) { + $this->seek_table("hhea"); + $this->skip(4); + $hheaAscender = $this->read_short(); + $hheaDescender = $this->read_short(); + $hheaLineGap = $this->read_short(); + $hheaAdvanceWidthMax = $this->read_ushort(); + $this->hheaascent = ($hheaAscender * $scale); + $this->hheadescent = ($hheaDescender * $scale); + $this->hhealineGap = ($hheaLineGap * $scale); + $this->advanceWidthMax = ($hheaAdvanceWidthMax * $scale); + } + + // OS/2 - OS/2 and Windows metrics table + $use_typo_metrics = false; + if (isset($this->tables["OS/2"])) { + $this->seek_table("OS/2"); + $version = $this->read_ushort(); + $this->skip(2); + $usWeightClass = $this->read_ushort(); + $this->skip(2); + $fsType = $this->read_ushort(); + if ($fsType == 0x0002 || ($fsType & 0x0300) != 0) { + $this->restrictedUse = true; + } + + $this->skip(16); + $yStrikeoutSize = $this->read_short(); + $yStrikeoutPosition = $this->read_short(); + $this->strikeoutSize = ($yStrikeoutSize * $scale); + $this->strikeoutPosition = ($yStrikeoutPosition * $scale); + + $sF = $this->read_short(); + $this->sFamilyClass = ($sF >> 8); + $this->sFamilySubClass = ($sF & 0xFF); + $this->_pos += 10; //PANOSE = 10 byte length + $panose = fread($this->fh, 10); + $this->panose = []; + $panoseLenght = strlen($panose); + for ($p = 0; $p < $panoseLenght; $p++) { + $this->panose[] = ord($panose[$p]); + } + + $this->skip(20); + $fsSelection = $this->read_ushort(); + $use_typo_metrics = (($fsSelection & 0x80) === 0x80); // bit#7 = USE_TYPO_METRICS + $this->skip(4); + + $sTypoAscender = $this->read_short(); + $sTypoDescender = $this->read_short(); + $sTypoLineGap = $this->read_short(); + + if ($sTypoAscender) { + $this->typoAscender = ($sTypoAscender * $scale); + } + if ($sTypoDescender) { + $this->typoDescender = ($sTypoDescender * $scale); + } + if ($sTypoLineGap) { + $this->typoLineGap = ($sTypoLineGap * $scale); + } + + $usWinAscent = $this->read_ushort(); + $usWinDescent = $this->read_ushort(); + if ($usWinAscent) { + $this->usWinAscent = ($usWinAscent * $scale); + } + if ($usWinDescent) { + $this->usWinDescent = ($usWinDescent * $scale); + } + + if ($version > 1) { + $this->skip(8); + $sxHeight = $this->read_short(); + $this->xHeight = ($sxHeight * $scale); + $sCapHeight = $this->read_short(); + $this->capHeight = ($sCapHeight * $scale); + } + } else { + $usWeightClass = 400; + } + $this->stemV = 50 + (int) (($usWeightClass / 65.0) ** 2); + + // FONT DESCRIPTOR METRICS + if ($this->fontDescriptor === 'winTypo') { + $this->ascent = $this->typoAscender; + $this->descent = $this->typoDescender; + $this->lineGap = $this->typoLineGap; + } elseif ($this->fontDescriptor === 'mac') { + $this->ascent = $this->hheaascent; + $this->descent = $this->hheadescent; + $this->lineGap = $this->hhealineGap; + } else { // $this->fontDescriptor === 'win' + $this->ascent = $this->usWinAscent; + $this->descent = -$this->usWinDescent; + $this->lineGap = 0; + + // Special case - if either the winAscent or winDescent are greater than the + // font bounding box yMin yMax, then reduce them accordingly. + // This works with Myanmar Text (Windows 8 version) to give a + // line-height normal that is equivalent to that produced in browsers. + // Also Khmer OS = compatible with MSWord, Wordpad and browser. + if ($this->ascent > $this->bbox[3]) { + $this->ascent = $this->bbox[3]; + } + + if ($this->descent < $this->bbox[1]) { + $this->descent = $this->bbox[1]; + } + + // Override case - if the USE_TYPO_METRICS bit is set on OS/2 fsSelection + // this is telling the font to use the sTypo values and not the usWinAscent values. + // This works as a fix with Cambria Math to give a normal line-height; + // at present, this is the only font I have found with this bit set; + // although note that MS WordPad and windows FF browser uses the big line-height from winAscent + // but Word 2007 get it right + if ($use_typo_metrics && $this->typoAscender) { + $this->ascent = $this->typoAscender; + $this->descent = $this->typoDescender; + $this->lineGap = $this->typoLineGap; + } + } + + // post - PostScript table + $this->seek_table('post'); + if ($debug) { + $ver_maj = $this->read_ushort(); + if ($ver_maj < 1 || $ver_maj > 4) { + throw new \Mpdf\MpdfException(sprintf('Unknown post table version %s', $ver_maj)); + } + } else { + $this->skip(4); + } + + $this->italicAngle = $this->read_short() + $this->read_ushort() / 65536.0; + $this->underlinePosition = $this->read_short() * $scale; + $this->underlineThickness = $this->read_short() * $scale; + $isFixedPitch = $this->read_ulong(); + + $this->flags = 4; + + if ($this->italicAngle != 0) { + $this->flags |= 64; + } + if ($usWeightClass >= 600) { + $this->flags |= 262144; + } + if ($isFixedPitch) { + $this->flags |= 1; + } + + // hhea - Horizontal header table + $this->seek_table('hhea'); + if ($debug) { + $ver_maj = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException(sprintf('Unknown hhea table version %s', $ver_maj)); + } + $this->skip(28); + } else { + $this->skip(32); + } + + $metricDataFormat = $this->read_ushort(); + + if ($metricDataFormat != 0) { + throw new \Mpdf\MpdfException(sprintf('Unknown horizontal metric data format "%s"', $metricDataFormat)); + } + + $numberOfHMetrics = $this->read_ushort(); + + if ($numberOfHMetrics == 0) { + throw new \Mpdf\MpdfException('Number of horizontal metrics is 0'); + } + + // maxp - Maximum profile table + $this->seek_table('maxp'); + if ($debug) { + $ver_maj = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException(sprintf('Unknown maxp table version ', $ver_maj)); + } + } else { + $this->skip(4); + } + $numGlyphs = $this->read_ushort(); + + // cmap - Character to glyph index mapping table + $cmap_offset = $this->seek_table('cmap'); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + if (!$unicode_cmap_offset) { + $unicode_cmap_offset = $cmap_offset + $offset; + } + if ($BMPonly) { + break; + } + } + } elseif ((($platformID == 3 && $encodingID == 10) || $platformID == 0) && !$BMPonly) { // Microsoft, Unicode Format 12 table HKCS + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 12) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException(sprintf('Font "%s" does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)', $this->filename)); + } + + $sipset = false; + $smpset = false; + + $this->rtlPUAstr = ''; + $this->GSUBScriptLang = []; + $this->GSUBFeatures = []; + $this->GSUBLookups = []; + $this->GPOSScriptLang = []; + $this->GPOSFeatures = []; + $this->GPOSLookups = []; + $this->glyphIDtoUni = ''; + + // Format 12 CMAP does characters above Unicode BMP i.e. some HKCS characters U+20000 and above + if ($format == 12 && !$BMPonly) { + $this->maxUniChar = 0; + $this->seek($unicode_cmap_offset + 4); + $length = $this->read_ulong(); + $limit = $unicode_cmap_offset + $length; + $this->skip(4); + + $nGroups = $this->read_ulong(); + + $glyphToChar = []; + $charToGlyph = []; + for ($i = 0; $i < $nGroups; $i++) { + $startCharCode = $this->read_ulong(); + $endCharCode = $this->read_ulong(); + $startGlyphCode = $this->read_ulong(); + // ZZZ98 + if ($endCharCode > 0x20000 && $endCharCode < 0x2FFFF) { + $sipset = true; + } elseif ($endCharCode > 0x10000 && $endCharCode < 0x1FFFF) { + $smpset = true; + } + $offset = 0; + for ($unichar = $startCharCode; $unichar <= $endCharCode; $unichar++) { + $glyph = $startGlyphCode + $offset; + $offset++; + // ZZZ98 + if ($unichar < 0x30000) { + $charToGlyph[$unichar] = $glyph; + $this->maxUniChar = max($unichar, $this->maxUniChar); + $glyphToChar[$glyph][] = $unichar; + } + } + } + } else { + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + } + $this->sipset = $sipset; + $this->smpset = $smpset; + + // Map Unmapped glyphs (or glyphs mapped to upper PUA U+F00000 onwards i.e. > U+2FFFF) - from $numGlyphs + if ($this->useOTL) { + + $bctr = 0xE000; + + for ($gid = 1; $gid < $numGlyphs; $gid++) { + + if (!isset($glyphToChar[$gid])) { + + while (isset($charToGlyph[$bctr])) { + $bctr++; + } + + // Avoid overwriting a glyph already mapped in PUA + // ZZZ98 + if (($bctr > 0xF8FF) && ($bctr < 0x2CEB0)) { + if (!$BMPonly) { + $bctr = 0x2CEB0; // Use unassigned area 0x2CEB0 to 0x2F7FF (space for 10,000 characters) + $this->sipset = $sipset = true; // forces subsetting; also ensure charwidths are saved + while (isset($charToGlyph[$bctr])) { + $bctr++; + } + } else { + throw new \Mpdf\MpdfException(sprintf('The font "%s" does not have enough space to map all (unmapped) included glyphs into Private Use Area U+E000-U+F8FF', $names[1])); + } + } + + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $this->maxUniChar = max($bctr, $this->maxUniChar); + $bctr++; + } + } + } + + $this->glyphToChar = $glyphToChar; + + $this->GSUBScriptLang = []; + $this->rtlPUAstr = ''; + if ($useOTL) { + $this->_getGDEFtables(); + list($this->GSUBScriptLang, $this->GSUBFeatures, $this->GSUBLookups, $this->rtlPUAstr) = $this->_getGSUBtables(); + list($this->GPOSScriptLang, $this->GPOSFeatures, $this->GPOSLookups) = $this->_getGPOStables(); + $this->glyphIDtoUni = str_pad('', 256 * 256 * 3, "\x00"); + foreach ($glyphToChar as $gid => $arr) { + if (isset($glyphToChar[$gid][0])) { + $char = $glyphToChar[$gid][0]; + + if ($char != 0 && $char != 65535) { + $this->glyphIDtoUni[$gid * 3] = chr($char >> 16); + $this->glyphIDtoUni[$gid * 3 + 1] = chr(($char >> 8) & 0xFF); + $this->glyphIDtoUni[$gid * 3 + 2] = chr($char & 0xFF); + } + } + } + } + + // if xHeight and/or CapHeight are not available from OS/2 (e.g. eraly versions) + // Calculate from yMax of 'x' or 'H' Glyphs... + if ($this->xHeight == 0) { + if (isset($charToGlyph[0x78])) { + $gidx = $charToGlyph[0x78]; // U+0078 (LATIN SMALL LETTER X) + $start = $this->seek_table('loca'); + if ($indexToLocFormat == 0) { + $this->skip($gidx * 2); + $locax = $this->read_ushort() * 2; + } elseif ($indexToLocFormat == 1) { + $this->skip($gidx * 4); + $locax = $this->read_ulong(); + } + $start = $this->seek_table('glyf'); + $this->skip($locax); + $this->skip(8); + $yMaxx = $this->read_short(); + $this->xHeight = $yMaxx * $scale; + } + } + + if ($this->capHeight == 0) { + if (isset($charToGlyph[0x48])) { + $gidH = $charToGlyph[0x48]; // U+0048 (LATIN CAPITAL LETTER H) + $start = $this->seek_table('loca'); + if ($indexToLocFormat == 0) { + $this->skip($gidH * 2); + $locaH = $this->read_ushort() * 2; + } elseif ($indexToLocFormat == 1) { + $this->skip($gidH * 4); + $locaH = $this->read_ulong(); + } + $start = $this->seek_table('glyf'); + $this->skip($locaH); + $this->skip(8); + $yMaxH = $this->read_short(); + $this->capHeight = $yMaxH * $scale; + } else { + $this->capHeight = $this->ascent; + } + // final default is to set it = to Ascent + } + + // hmtx - Horizontal metrics table + $this->getHMTX($numberOfHMetrics, $numGlyphs, $glyphToChar, $scale); + + // kern - Kerning pair table + // Recognises old form of Kerning table - as required by Windows - Format 0 only + $kern_offset = $this->seek_table("kern"); + $version = $this->read_ushort(); + $nTables = $this->read_ushort(); + + // subtable header + $sversion = $this->read_ushort(); + $slength = $this->read_ushort(); + $scoverage = $this->read_ushort(); + $format = $scoverage >> 8; + if ($kern_offset && $version == 0 && $format == 0) { + // Format 0 + $nPairs = $this->read_ushort(); + $this->skip(6); + for ($i = 0; $i < $nPairs; $i++) { + $left = $this->read_ushort(); + $right = $this->read_ushort(); + $val = $this->read_short(); + if (isset($glyphToChar[$left]) && count($glyphToChar[$left]) == 1 && isset($glyphToChar[$right]) && count($glyphToChar[$right]) == 1) { + if ($left != 32 && $right != 32) { + $this->kerninfo[$glyphToChar[$left][0]][$glyphToChar[$right][0]] = intval($val * $scale); + } + } + } + } + } + + function _getGDEFtables() + { + // http://www.microsoft.com/typography/otspec/gdef.htm + if (isset($this->tables["GDEF"])) { + $gdef_offset = $this->seek_table("GDEF"); + + // ULONG Version of the GDEF table-currently 0x00010000 + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + $GlyphClassDef_offset = $this->read_ushort(); + $AttachList_offset = $this->read_ushort(); + $LigCaretList_offset = $this->read_ushort(); + $MarkAttachClassDef_offset = $this->read_ushort(); + + // Version 0x00010002 of GDEF header contains additional Offset to a list defining mark glyph set definitions (MarkGlyphSetDef) + if ($ver_min == 2) { + $MarkGlyphSetsDef_offset = $this->read_ushort(); + } + + // GlyphClassDef + if ($GlyphClassDef_offset) { + + $this->seek($gdef_offset + $GlyphClassDef_offset); + // 1 Base glyph (single character, spacing glyph) + // 2 Ligature glyph (multiple character, spacing glyph) + // 3 Mark glyph (non-spacing combining glyph) + // 4 Component glyph (part of single character, spacing glyph) + $GlyphByClass = $this->_getClassDefinitionTable(); + } else { + $GlyphByClass = []; + } + + if (isset($GlyphByClass[1]) && count($GlyphByClass[1]) > 0) { + $this->GlyphClassBases = ' ' . implode('| ', $GlyphByClass[1]); + } else { + $this->GlyphClassBases = ''; + } + if (isset($GlyphByClass[2]) && count($GlyphByClass[2]) > 0) { + $this->GlyphClassLigatures = ' ' . implode('| ', $GlyphByClass[2]); + } else { + $this->GlyphClassLigatures = ''; + } + if (isset($GlyphByClass[3]) && count($GlyphByClass[3]) > 0) { + $this->GlyphClassMarks = ' ' . implode('| ', $GlyphByClass[3]); + } else { + $this->GlyphClassMarks = ''; + } + if (isset($GlyphByClass[4]) && count($GlyphByClass[4]) > 0) { + $this->GlyphClassComponents = ' ' . implode('| ', $GlyphByClass[4]); + } else { + $this->GlyphClassComponents = ''; + } + + if (isset($GlyphByClass[3]) && count($GlyphByClass[3]) > 0) { + $Marks = $GlyphByClass[3]; + } else { // to use for MarkAttachmentType + $Marks = []; + } + + /* Required for GPOS + // Attachment List + if ($AttachList_offset) { + $this->seek($gdef_offset+$AttachList_offset ); + } + The Attachment Point List table (AttachmentList) identifies all the attachment points defined in the GPOS table and their associated glyphs so a client can quickly access coordinates for each glyph's attachment points. As a result, the client can cache coordinates for attachment points along with glyph bitmaps and avoid recalculating the attachment points each time it displays a glyph. Without this table, processing speed would be slower because the client would have to decode the GPOS lookups that define attachment points and compile the points in a list. + + The Attachment List table (AttachList) may be used to cache attachment point coordinates along with glyph bitmaps. + + The table consists of an offset to a Coverage table (Coverage) listing all glyphs that define attachment points in the GPOS table, a count of the glyphs with attachment points (GlyphCount), and an array of offsets to AttachPoint tables (AttachPoint). The array lists the AttachPoint tables, one for each glyph in the Coverage table, in the same order as the Coverage Index. + AttachList table + Type Name Description + Offset Coverage Offset to Coverage table - from beginning of AttachList table + uint16 GlyphCount Number of glyphs with attachment points + Offset AttachPoint[GlyphCount] Array of offsets to AttachPoint tables-from beginning of AttachList table-in Coverage Index order + + An AttachPoint table consists of a count of the attachment points on a single glyph (PointCount) and an array of contour indices of those points (PointIndex), listed in increasing numerical order. + + AttachPoint table + Type Name Description + uint16 PointCount Number of attachment points on this glyph + uint16 PointIndex[PointCount] Array of contour point indices -in increasing numerical order + + See Example 3 - http://www.microsoft.com/typography/otspec/gdef.htm + */ + + // Ligature Caret List + // The Ligature Caret List table (LigCaretList) defines caret positions for all the ligatures in a font. + // Not required for mDPF + // MarkAttachmentType + if ($MarkAttachClassDef_offset) { + $this->seek($gdef_offset + $MarkAttachClassDef_offset); + $MarkAttachmentTypes = $this->_getClassDefinitionTable(); + foreach ($MarkAttachmentTypes as $class => $glyphs) { + if (is_array($Marks) && count($Marks)) { + $mat = array_diff($Marks, $MarkAttachmentTypes[$class]); + sort($mat, SORT_STRING); + } else { + $mat = []; + } + + $this->MarkAttachmentType[$class] = ' ' . implode('| ', $mat); + } + } else { + $this->MarkAttachmentType = []; + } + + // MarkGlyphSets only in Version 0x00010002 of GDEF + if ($ver_min == 2 && $MarkGlyphSetsDef_offset) { + $this->seek($gdef_offset + $MarkGlyphSetsDef_offset); + $MarkSetTableFormat = $this->read_ushort(); + $MarkSetCount = $this->read_ushort(); + $MarkSetOffset = []; + for ($i = 0; $i < $MarkSetCount; $i++) { + $MarkSetOffset[] = $this->read_ulong(); + } + for ($i = 0; $i < $MarkSetCount; $i++) { + $this->seek($MarkSetOffset[$i]); + $glyphs = $this->_getCoverage(); + $this->MarkGlyphSets[$i] = ' ' . implode('| ', $glyphs); + } + } else { + $this->MarkGlyphSets = []; + } + } else { + throw new \Mpdf\MpdfException(sprintf('Unable to set font "%s" to use OTL as it does not include OTL tables (or at least not a GDEF table).', $this->filename)); + } + + $GSUB_offset = 0; + $GPOS_offset = 0; + $GSUB_length = 0; + + $s = ''; + + if (isset($this->tables['GSUB'])) { + $GSUB_offset = $this->seek_table('GSUB'); + $GSUB_length = $this->tables['GSUB']['length']; + $s .= fread($this->fh, $this->tables['GSUB']['length']); + } + + if (isset($this->tables['GPOS'])) { + $GPOS_offset = $this->seek_table('GPOS'); + $s .= fread($this->fh, $this->tables['GPOS']['length']); + } + + if ($s) { + $this->fontCache->write($this->fontkey . '.GSUBGPOStables.dat', $s); + } + + $font = [ + 'GSUB_offset' => $GSUB_offset, + 'GPOS_offset' => $GPOS_offset, + 'GSUB_length' => $GSUB_length, + 'GlyphClassBases' => $this->GlyphClassBases, + 'GlyphClassMarks' => $this->GlyphClassMarks, + 'GlyphClassLigatures' => $this->GlyphClassLigatures, + 'GlyphClassComponents' => $this->GlyphClassComponents, + 'MarkGlyphSets' => $this->MarkGlyphSets, + 'MarkAttachmentType' => $this->MarkAttachmentType, + ]; + + $this->fontCache->jsonWrite($this->fontkey . '.GDEFdata.json', $font); + } + + function _getClassDefinitionTable() + { + // NB Any glyph not included in the range of covered GlyphIDs automatically belongs to Class 0. This is not returned by this function + $ClassFormat = $this->read_ushort(); + $GlyphByClass = []; + + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $gid = $StartGlyph + $i; + $class = $this->read_ushort(); + // Several fonts (mainly dejavu.../Freeserif etc) have a MarkAttachClassDef Format 1, where StartGlyph is 0 and GlyphCount is 1 + // This doesn't seem to do anything useful? + // Freeserif does not have $this->glyphToChar[0] allocated and would throw an error, so check if isset: + if (isset($this->glyphToChar[$gid][0])) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$gid][0]); + } + } + } elseif ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $startGlyphID = $this->read_ushort(); + $endGlyphID = $this->read_ushort(); + $class = $this->read_ushort(); + for ($gid = $startGlyphID; $gid <= $endGlyphID; $gid++) { + if (isset($this->glyphToChar[$gid][0])) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$gid][0]); + } + } + } + } + foreach ($GlyphByClass as $class => $glyphs) { + sort($GlyphByClass[$class], SORT_STRING); // SORT makes it easier to read in development ? order not important ??? + } + ksort($GlyphByClass); + + return $GlyphByClass; + } + + /** + * GSUB - Glyph Substitution + */ + function _getGSUBtables() + { + if (!isset($this->tables['GSUB'])) { + return [[], [], [], '']; + } + + $ffeats = []; + $gsub_offset = $this->seek_table('GSUB'); + $this->skip(4); + $ScriptList_offset = $gsub_offset + $this->read_ushort(); + $FeatureList_offset = $gsub_offset + $this->read_ushort(); + $LookupList_offset = $gsub_offset + $this->read_ushort(); + + // ScriptList + $this->seek($ScriptList_offset); + $ScriptCount = $this->read_ushort(); + for ($i = 0; $i < $ScriptCount; $i++) { + $ScriptTag = $this->read_tag(); // = "beng", "deva" etc. + $ScriptTableOffset = $this->read_ushort(); + $ffeats[$ScriptTag] = $ScriptList_offset + $ScriptTableOffset; + } + + // Script Table + foreach ($ffeats as $t => $o) { + $ls = []; + $this->seek($o); + $DefLangSys_offset = $this->read_ushort(); + if ($DefLangSys_offset > 0) { + $ls['DFLT'] = $DefLangSys_offset + $o; + } + $LangSysCount = $this->read_ushort(); + for ($i = 0; $i < $LangSysCount; $i++) { + $LangTag = $this->read_tag(); // = + $LangTableOffset = $this->read_ushort(); + $ls[$LangTag] = $o + $LangTableOffset; + } + $ffeats[$t] = $ls; + } + + // Get FeatureIndexList + // LangSys Table - from first listed langsys + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = []; + $langsystable_offset = $o; + $this->seek($langsystable_offset); + $LookUpOrder = $this->read_ushort(); //==NULL + $ReqFeatureIndex = $this->read_ushort(); + if ($ReqFeatureIndex != 0xFFFF) { + $FeatureIndex[] = $ReqFeatureIndex; + } + $FeatureCount = $this->read_ushort(); + for ($i = 0; $i < $FeatureCount; $i++) { + $FeatureIndex[] = $this->read_ushort(); // = index of feature + } + $ffeats[$st][$t] = $FeatureIndex; + } + } + + // Feauture List => LookupListIndex es + $this->seek($FeatureList_offset); + $FeatureCount = $this->read_ushort(); + $Feature = []; + + for ($i = 0; $i < $FeatureCount; $i++) { + $tag = $this->read_tag(); + if ($tag == 'smcp') { + $this->hassmallcapsGSUB = true; + } + $Feature[$i] = ['tag' => $tag]; + $Feature[$i]['offset'] = $FeatureList_offset + $this->read_ushort(); + } + + for ($i = 0; $i < $FeatureCount; $i++) { + $this->seek($Feature[$i]['offset']); + $this->read_ushort(); // null [FeatureParams] + $Feature[$i]['LookupCount'] = $Lookupcount = $this->read_ushort(); + $Feature[$i]['LookupListIndex'] = []; + for ($c = 0; $c < $Lookupcount; $c++) { + $Feature[$i]['LookupListIndex'][] = $this->read_ushort(); + } + } + + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = $ffeats[$st][$t]; + foreach ($FeatureIndex as $k => $fi) { + $ffeats[$st][$t][$k] = $Feature[$fi]; + } + } + } + + $gsub = []; + $GSUBScriptLang = []; + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $langsys) { + $lg = []; + foreach ($langsys as $ft) { + $lg[$ft['LookupListIndex'][0]] = $ft; + } + // list of Lookups in order they need to be run i.e. order listed in Lookup table + ksort($lg); + foreach ($lg as $ft) { + $gsub[$st][$t][$ft['tag']] = $ft['LookupListIndex']; + } + if (!isset($GSUBScriptLang[$st])) { + $GSUBScriptLang[$st] = ''; + } + $GSUBScriptLang[$st] .= $t . ' '; + } + } + + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $GSLookup = []; + $Offsets = []; + $SubtableCount = []; + + for ($i = 0; $i < $LookupCount; $i++) { + $Offsets[$i] = $LookupList_offset + $this->read_ushort(); + } + + for ($i = 0; $i < $LookupCount; $i++) { + + $this->seek($Offsets[$i]); + + $GSLookup[$i]['Type'] = $this->read_ushort(); + $GSLookup[$i]['Flag'] = $flag = $this->read_ushort(); + $GSLookup[$i]['SubtableCount'] = $SubtableCount[$i] = $this->read_ushort(); + + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $GSLookup[$i]['Subtables'][$c] = $Offsets[$i] + $this->read_ushort(); + } + + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) == 0x0010) { + $GSLookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } else { + $GSLookup[$i]['MarkFilteringSet'] = ''; + } + + // Lookup Type 7: Extension + if ($GSLookup[$i]['Type'] == 7) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $this->seek($GSLookup[$i]['Subtables'][$c]); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $ext_offset = $this->read_ulong(); + $GSLookup[$i]['Subtables'][$c] = $GSLookup[$i]['Subtables'][$c] + $ext_offset; + } + $GSLookup[$i]['Type'] = $type; + } + } + + // Process Whole LookupList - Get LuCoverage = Lookup coverage just for first glyph + $this->GSLuCoverage = []; + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $GSLookup[$i]['SubtableCount']; $c++) { + $this->seek($GSLookup[$i]['Subtables'][$c]); + $PosFormat = $this->read_ushort(); + + if ($GSLookup[$i]['Type'] == 5 && $PosFormat == 3) { + $this->skip(4); + } elseif ($GSLookup[$i]['Type'] == 6 && $PosFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + $this->skip(2 * $BacktrackGlyphCount + 2); + } + + // NB Coverage only looks at glyphs for position 1 (i.e. 5.3 and 6.3) // NEEDS TO READ ALL ******************** + $Coverage = $GSLookup[$i]['Subtables'][$c] + $this->read_ushort(); + $this->seek($Coverage); + $glyphs = $this->_getCoverage(false, 2); + $this->GSLuCoverage[$i][$c] = $glyphs; + } + } + + // $this->GSLuCoverage and $GSLookup + $this->fontCache->jsonWrite($this->fontkey . '.GSUBdata.json', $this->GSLuCoverage); + + // Now repeats as original to get Substitution rules + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $Lookup = []; + + for ($i = 0; $i < $LookupCount; $i++) { + $Lookup[$i]['offset'] = $LookupList_offset + $this->read_ushort(); + } + + for ($i = 0; $i < $LookupCount; $i++) { + $this->seek($Lookup[$i]['offset']); + $Lookup[$i]['Type'] = $this->read_ushort(); + $Lookup[$i]['Flag'] = $flag = $this->read_ushort(); + $Lookup[$i]['SubtableCount'] = $this->read_ushort(); + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $Lookup[$i]['Subtable'][$c]['Offset'] = $Lookup[$i]['offset'] + $this->read_ushort(); + } + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) == 0x0010) { + $Lookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } else { + $Lookup[$i]['MarkFilteringSet'] = ''; + } + + // Lookup Type 7: Extension + if ($Lookup[$i]['Type'] == 7) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $this->seek($Lookup[$i]['Subtable'][$c]['Offset']); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ulong(); + } + $Lookup[$i]['Type'] = $type; + } + } + + // Process (1) Whole LookupList + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $this->seek($Lookup[$i]['Subtable'][$c]['Offset']); + $SubstFormat = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['Format'] = $SubstFormat; + + /* + Lookup['Type'] Enumeration table for glyph substitution + Value Type Description + 1 Single Replace one glyph with one glyph + 2 Multiple Replace one glyph with more than one glyph + 3 Alternate Replace one glyph with one of many glyphs + 4 Ligature Replace multiple glyphs with one glyph + 5 Context Replace one or more glyphs in context + 6 Chaining Context Replace one or more glyphs in chained context + 7 Extension Substitution Extension mechanism for other substitutions (i.e. this excludes the Extension type substitution itself) + 8 Reverse chaining context single Applied in reverse order, replace single glyph in chaining context + */ + + // LookupType 1: Single Substitution Subtable + if ($Lookup[$i]['Type'] == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + if ($SubstFormat == 1) { // Calculated output glyph indices + $Lookup[$i]['Subtable'][$c]['DeltaGlyphID'] = $this->read_short(); + } elseif ($SubstFormat == 2) { // Specified output glyph indices + $GlyphCount = $this->read_ushort(); + for ($g = 0; $g < $GlyphCount; $g++) { + $Lookup[$i]['Subtable'][$c]['Glyphs'][] = $this->read_ushort(); + } + } + } // LookupType 2: Multiple Substitution Subtable + elseif ($Lookup[$i]['Type'] == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SequenceCount'] = $SequenceCount = $this->read_short(); + for ($s = 0; $s < $SequenceCount; $s++) { + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $SequenceCount; $s++) { + // Sequence Tables + $this->seek($Lookup[$i]['Subtable'][$c]['Sequences'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['GlyphCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['GlyphCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['Sequences'][$s]['SubstituteGlyphID'][] = $this->read_ushort(); + } + } + } // LookupType 3: Alternate Forms + elseif ($Lookup[$i]['Type'] == 3) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['AlternateSetCount'] = $AlternateSetCount = $this->read_short(); + for ($s = 0; $s < $AlternateSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + + for ($s = 0; $s < $AlternateSetCount; $s++) { + // AlternateSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['GlyphCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['GlyphCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['AlternateSets'][$s]['SubstituteGlyphID'][] = $this->read_ushort(); + } + } + } // LookupType 4: Ligature Substitution Subtable + elseif ($Lookup[$i]['Type'] == 4) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LigSetCount'] = $LigSetCount = $this->read_short(); + for ($s = 0; $s < $LigSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $LigSetCount; $s++) { + // LigatureSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigatureOffset'][$g] = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Offset'] + $this->read_ushort(); + } + } + for ($s = 0; $s < $LigSetCount; $s++) { + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + // Ligature tables + $this->seek($Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigatureOffset'][$g]); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['LigGlyph'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount'] = $this->read_ushort(); + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['GlyphID'][$l] = $this->read_ushort(); + } + } + } + } // LookupType 5: Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 5) { + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSetCount'] = $SubRuleSetCount = $this->read_short(); + for ($s = 0; $s < $SubRuleSetCount; $s++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_short(); + } + for ($s = 0; $s < $SubRuleSetCount; $s++) { + // SubRuleSet Tables + $this->seek($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset']); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount'] = $this->read_short(); + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $g++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleOffset'][$g] = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['Offset'] + $this->read_ushort(); + } + } + for ($s = 0; $s < $SubRuleSetCount; $s++) { + // SubRule Tables + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $g++) { + // Ligature tables + $this->seek($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleOffset'][$g]); + + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['GlyphCount'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstCount'] = $this->read_ushort(); + // "Input"::[GlyphCount - 1]::Array of input GlyphIDs-start with second glyph + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['GlyphCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['Input'][$l] = $this->read_ushort(); + } + // "SubstLookupRecord"::[SubstCount]::Array of SubstLookupRecords-in design order + for ($l = 0; $l < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstCount']; $l++) { + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstLookupRecord'][$l]['SequenceIndex'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$g]['SubstLookupRecord'][$l]['LookupListIndex'] = $this->read_ushort(); + } + } + } + } // Format 2: Class-based Context Glyph Substitution + elseif ($SubstFormat == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubClassSetCnt'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][] = 0; + } else { + $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $offset; + } + } + } else { + throw new \Mpdf\MpdfException("GPOS Lookup Type " . $Lookup[$i]['Type'] . ", Format " . $SubstFormat . " not supported (ttfontsuni.php)."); + } + } // LookupType 6: Chaining Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 6) { + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + elseif ($SubstFormat == 2) { + $Lookup[$i]['Subtable'][$c]['CoverageTableOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['BacktrackClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['InputClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['LookaheadClassDefOffset'] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $b++) { + $offset = $this->read_ushort(); + if ($offset == 0x0000) { + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][] = $offset; + } else { + $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $offset; + } + } + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + elseif ($SubstFormat == 3) { + $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageBacktrack'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['InputGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageInput'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['CoverageLookahead'][] = $Lookup[$i]['Subtable'][$c]['Offset'] + $this->read_ushort(); + } + $Lookup[$i]['Subtable'][$c]['SubstCount'] = $this->read_ushort(); + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex'] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex'] = $this->read_ushort(); + // Substitution Lookup Record + // All contextual substitution subtables specify the substitution data in a Substitution Lookup Record + // (SubstLookupRecord). Each record contains a SequenceIndex, which indicates the position where the substitution + // will occur in the glyph sequence. In addition, a LookupListIndex identifies the lookup to be applied at the + // glyph position specified by the SequenceIndex. + } + } + } else { + throw new \Mpdf\MpdfException(sprintf('Lookup Type "%s" not supported.', $Lookup[$i]['Type'])); + } + } + } + + // Process (2) Whole LookupList + // Get Coverage tables and prepare preg_replace + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $SubstFormat = $Lookup[$i]['Subtable'][$c]['Format']; + + // LookupType 1: Single Substitution Subtable 1 => 1 + if ($Lookup[$i]['Type'] == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(false); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = unicode_hex($this->glyphToChar[$glyphs[$g]][0]); + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + if (isset($Lookup[$i]['Subtable'][$c]['DeltaGlyphID'])) { // Format 1 + $substitute[] = unicode_hex($this->glyphToChar[($glyphs[$g] + $Lookup[$i]['Subtable'][$c]['DeltaGlyphID'])][0]); + } else { // Format 2 + $substitute[] = unicode_hex($this->glyphToChar[($Lookup[$i]['Subtable'][$c]['Glyphs'][$g])][0]); + } + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + } // LookupType 2: Multiple Substitution Subtable 1 => n + elseif ($Lookup[$i]['Type'] == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$g]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + if (!isset($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID']) || count($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID']) == 0) { + continue; + } // Illegal for GlyphCount to be 0; either error in font, or something has gone wrong - lets carry on for now! + foreach ($Lookup[$i]['Subtable'][$c]['Sequences'][$g]['SubstituteGlyphID'] as $sub) { + $substitute[] = unicode_hex($this->glyphToChar[$sub][0]); + } + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + } // LookupType 3: Alternate Forms 1 => 1 (only first alternate form is used) + elseif ($Lookup[$i]['Type'] == 3) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + for ($g = 0; $g < count($glyphs); $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$g]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + $gid = $Lookup[$i]['Subtable'][$c]['AlternateSets'][$g]['SubstituteGlyphID'][0]; + if (!isset($this->glyphToChar[$gid][0])) { + continue; + } + $substitute[] = unicode_hex($this->glyphToChar[$gid][0]); + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute]; + } + } // LookupType 4: Ligature Substitution Subtable n => 1 + elseif ($Lookup[$i]['Type'] == 4) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $glyphs = $this->_getCoverage(); + $LigSetCount = $Lookup[$i]['Subtable'][$c]['LigSetCount']; + for ($s = 0; $s < $LigSetCount; $s++) { + for ($g = 0; $g < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['LigCount']; $g++) { + $replace = []; + $substitute = []; + $replace[] = $glyphs[$s]; + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $replace[0], $Lookup[$i]['MarkFilteringSet'])) { + continue; + } + for ($l = 1; $l < $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']; $l++) { + $gid = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['GlyphID'][$l]; + $rpl = unicode_hex($this->glyphToChar[$gid][0]); + // Flag = Ignore + if ($this->_checkGSUBignore($Lookup[$i]['Flag'], $rpl, $Lookup[$i]['MarkFilteringSet'])) { + continue 2; + } + $replace[] = $rpl; + } + $gid = $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['LigGlyph']; + if (!isset($this->glyphToChar[$gid][0])) { + continue; + } + $substitute[] = unicode_hex($this->glyphToChar[$gid][0]); + $Lookup[$i]['Subtable'][$c]['subs'][] = ['Replace' => $replace, 'substitute' => $substitute, 'CompCount' => $Lookup[$i]['Subtable'][$c]['LigSet'][$s]['Ligature'][$g]['CompCount']]; + } + } + } // LookupType 5: Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 5) { + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubRuleSetCount']; $s++) { + $SubRuleSet = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]; + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['FirstGlyph'] = $CoverageGlyphs[$s]; + for ($r = 0; $r < $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRuleCount']; $r++) { + $GlyphCount = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['GlyphCount']; + for ($g = 1; $g < $GlyphCount; $g++) { + $glyphID = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['Input'][$g]; + $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'][$r]['InputGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + } + } + } // Format 2: Class-based Context Glyph Substitution + elseif ($SubstFormat == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $InputClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['ClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['InputClasses'] = $InputClasses; + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $s++) { + if ($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s]); + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRuleCnt'] = $SubClassRuleCnt = $this->read_ushort(); + $SubClassRule = []; + for ($b = 0; $b < $SubClassRuleCnt; $b++) { + $SubClassRule[$b] = $Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b] = $SubClassRule[$b]; + } + } + } + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubClassSetCnt']; $s++) { + if ($Lookup[$i]['Subtable'][$c]['SubClassSetOffset'][$s] > 0) { + $SubClassRuleCnt = $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRuleCnt']; + for ($b = 0; $b < $SubClassRuleCnt; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b]); + $Rule = []; + $Rule['InputGlyphCount'] = $this->read_ushort(); + $Rule['SubstCount'] = $this->read_ushort(); + for ($r = 1; $r < $Rule['InputGlyphCount']; $r++) { + $Rule['Input'][$r] = $this->read_ushort(); + } + for ($r = 0; $r < $Rule['SubstCount']; $r++) { + $Rule['SequenceIndex'][$r] = $this->read_ushort(); + $Rule['LookupListIndex'][$r] = $this->read_ushort(); + } + + $Lookup[$i]['Subtable'][$c]['SubClassSet'][$s]['SubClassRule'][$b] = $Rule; + } + } + } + } // Format 3: Coverage-based Context Glyph Substitution + elseif ($SubstFormat == 3) { + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageInput'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs'][] = implode("|", $glyphs); + } + throw new \Mpdf\MpdfException("Lookup Type 5, SubstFormat 3 not tested. Please report this with the name of font used - " . $this->fontkey); + } + } // LookupType 6: Chaining Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 6) { + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $ChainSubRuleSetCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; + + for ($s = 0; $s < $ChainSubRuleSetCnt; $s++) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][$s]); + $ChainSubRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleCount'] = $this->read_ushort(); + for ($r = 0; $r < $ChainSubRuleCnt; $r++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleOffset'][$r] = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetOffset'][$s] + $this->read_ushort(); + } + } + for ($s = 0; $s < $ChainSubRuleSetCnt; $s++) { + $ChainSubRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleCount']; + for ($r = 0; $r < $ChainSubRuleCnt; $r++) { + // ChainSubRule + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRuleOffset'][$r]); + + $BacktrackGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['BacktrackGlyphCount'] = $this->read_ushort(); + for ($g = 0; $g < $BacktrackGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['BacktrackGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $InputGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['InputGlyphCount'] = $this->read_ushort(); + for ($g = 1; $g < $InputGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['InputGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $LookaheadGlyphCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookaheadGlyphCount'] = $this->read_ushort(); + for ($g = 0; $g < $LookaheadGlyphCount; $g++) { + $glyphID = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookaheadGlyphs'][$g] = unicode_hex($this->glyphToChar[$glyphID][0]); + } + + $SubstCount = $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['SubstCount'] = $this->read_ushort(); + for ($lu = 0; $lu < $SubstCount; $lu++) { + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['SequenceIndex'][$lu] = $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'][$r]['LookupListIndex'][$lu] = $this->read_ushort(); + } + } + } + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + elseif ($SubstFormat == 2) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageTableOffset']); + $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'] = $CoverageGlyphs = $this->_getCoverage(); + + $BacktrackClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['BacktrackClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['BacktrackClasses'] = $BacktrackClasses; + + $InputClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['InputClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['InputClasses'] = $InputClasses; + + $LookaheadClasses = $this->_getClasses($Lookup[$i]['Subtable'][$c]['LookaheadClassDefOffset']); + $Lookup[$i]['Subtable'][$c]['LookaheadClasses'] = $LookaheadClasses; + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $s++) { + if ($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s]); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRuleCnt'] = $ChainSubClassRuleCnt = $this->read_ushort(); + $ChainSubClassRule = []; + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { + $ChainSubClassRule[$b] = $Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] + $this->read_ushort(); + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b] = $ChainSubClassRule[$b]; + } + } + } + + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubClassSetCnt']; $s++) { + if (isset($Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRuleCnt'])) { + $ChainSubClassRuleCnt = $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRuleCnt']; + } else { + $ChainSubClassRuleCnt = 0; + } + for ($b = 0; $b < $ChainSubClassRuleCnt; $b++) { + if ($Lookup[$i]['Subtable'][$c]['ChainSubClassSetOffset'][$s] > 0) { + $this->seek($Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b]); + $Rule = []; + $Rule['BacktrackGlyphCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['BacktrackGlyphCount']; $r++) { + $Rule['Backtrack'][$r] = $this->read_ushort(); + } + $Rule['InputGlyphCount'] = $this->read_ushort(); + for ($r = 1; $r < $Rule['InputGlyphCount']; $r++) { + $Rule['Input'][$r] = $this->read_ushort(); + } + $Rule['LookaheadGlyphCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['LookaheadGlyphCount']; $r++) { + $Rule['Lookahead'][$r] = $this->read_ushort(); + } + $Rule['SubstCount'] = $this->read_ushort(); + for ($r = 0; $r < $Rule['SubstCount']; $r++) { + $Rule['SequenceIndex'][$r] = $this->read_ushort(); + $Rule['LookupListIndex'][$r] = $this->read_ushort(); + } + + $Lookup[$i]['Subtable'][$c]['ChainSubClassSet'][$s]['ChainSubClassRule'][$b] = $Rule; + } + } + } + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + elseif ($SubstFormat == 3) { + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageBacktrack'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageBacktrackGlyphs'][] = implode("|", $glyphs); + } + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageInput'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs'][] = implode("|", $glyphs); + // Don't use above value as these are ordered numerically not as need to process + } + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']; $b++) { + $this->seek($Lookup[$i]['Subtable'][$c]['CoverageLookahead'][$b]); + $glyphs = $this->_getCoverage(); + $Lookup[$i]['Subtable'][$c]['CoverageLookaheadGlyphs'][] = implode("|", $glyphs); + } + } + } + } + } + + $GSUBScriptLang = []; + $rtlpua = []; // All glyphs added to PUA [for magic_reverse] + foreach ($gsub as $st => $scripts) { + foreach ($scripts as $t => $langsys) { + $lul = []; // array of LookupListIndexes + $tags = []; // corresponding array of feature tags e.g. 'ccmp' + + foreach ($langsys as $tag => $ft) { + foreach ($ft as $ll) { + $lul[$ll] = $tag; + } + } + ksort($lul); // Order the Lookups in the order they are in the GUSB table, regardless of Feature order + $volt = $this->_getGSUBarray($Lookup, $lul, $st); + + // Interrogate $volt + // isol, fin, medi, init(arab syrc) into $rtlSUB for use in ArabJoin + // but also identify all RTL chars in PUA for magic_reverse (arab syrc hebr thaa nko samr) + // identify reph, matras, vatu, half forms etc for Indic for final re-ordering + $rtl = []; + $rtlSUB = []; + $finals = ''; + + if (strpos('arab syrc hebr thaa nko samr', $st) !== false) { // all RTL scripts [any/all languages] ? Mandaic + + foreach ($volt as $v) { + // isol fina fin2 fin3 medi med2 for Syriac + // ISOLATED FORM :: FINAL :: INITIAL :: MEDIAL :: MED2 :: FIN2 :: FIN3 + if (strpos('isol fina init medi fin2 fin3 med2', $v['tag']) !== false) { + + $key = $v['match']; + $key = preg_replace('/[\(\)]*/', '', $key); + $sub = $v['replace']; + if ($v['tag'] === 'isol') { + $kk = 0; + } elseif ($v['tag'] === 'fina') { + $kk = 1; + } elseif ($v['tag'] === 'init') { + $kk = 2; + } elseif ($v['tag'] === 'medi') { + $kk = 3; + } elseif ($v['tag'] === 'med2') { + $kk = 4; + } elseif ($v['tag'] === 'fin2') { + $kk = 5; + } elseif ($v['tag'] === 'fin3') { + $kk = 6; + } + + $rtl[$key][$kk] = $sub; + if (isset($v['prel']) && count($v['prel'])) { + $rtl[$key]['prel'][$kk] = $v['prel']; + } + if (isset($v['postl']) && count($v['postl'])) { + $rtl[$key]['postl'][$kk] = $v['postl']; + } + if (isset($v['ignore']) && $v['ignore']) { + $rtl[$key]['ignore'][$kk] = $v['ignore']; + } + $rtlpua[] = $sub; + + } else { // Add any other glyphs which are in PUA + if (isset($v['context']) && $v['context']) { + foreach ($v['rules'] as $vs) { + $matchCount = count($vs['match']); + for ($i = 0; $i < $matchCount; $i++) { + if (isset($vs['replace'][$i]) && preg_match('/^0[A-F0-9]{4}$/', $vs['match'][$i])) { + if (preg_match('/^0[EF][A-F0-9]{3}$/', $vs['replace'][$i])) { + $rtlpua[] = $vs['replace'][$i]; + } + } + } + } + } else { + preg_match_all('/\((0[A-F0-9]{4})\)/', $v['match'], $m); + $matchCount = count($m[0]); + for ($i = 0; $i < $matchCount; $i++) { + $sb = explode(' ', $v['replace']); + foreach ($sb as $sbg) { + if (preg_match('/(0[EF][A-F0-9]{3})/', $sbg, $mr)) { + $rtlpua[] = $mr[1]; + } + } + } + } + } + } + + // For kashida, need to determine all final forms except ones already identified by kashida priority rules (see \Mpdf\Otl) + foreach ($rtl as $base => $variants) { + if (isset($variants[1])) { // i.e. final form + if (strpos('0FE8E 0FE94 0FEA2 0FEAA 0FEAE 0FEC2 0FEDA 0FEDE 0FB93 0FECA 0FED2 0FED6 0FEEE 0FEF0 0FEF2', $variants[1]) === false) { // not already included + // This version does not exclude RA (0631) FEAE; Ya (064A) FEF2; Alef Maqsurah (0649) FEF0 which + // are selected in priority if connected to a medial Bah + //if (strpos('0FE8E 0FE94 0FEA2 0FEAA 0FEC2 0FEDA 0FEDE 0FB93 0FECA 0FED2 0FED6 0FEEE', $variants[1])===false) { // not already included + $finals .= $variants[1] . ' '; + } + } + } + + ksort($rtl); + $rtlSUB = $rtl; + } + + // INDIC - Dynamic properties + $rphf = []; + $half = []; + $pref = []; + $blwf = []; + $pstf = []; + + if (strpos('dev2 bng2 gur2 gjr2 ory2 tml2 tel2 knd2 mlm2 deva beng guru gujr orya taml telu knda mlym', $st) !== false) { // all INDIC scripts [any/all languages] + if (strpos('deva beng guru gujr orya taml telu knda mlym', $st) !== false) { + $is_old_spec = true; + } else { + $is_old_spec = false; + } + + // First get 'locl' substitutions (reversed!) + $loclsubs = []; + foreach ($volt as $v) { + if (strpos('locl', $v['tag']) !== false) { + $key = $v['match']; + $key = preg_replace('/[\(\)]*/', '', $key); + $sub = $v['replace']; + if ($key && strlen(trim($key)) == 5 && $sub) { + $loclsubs[$sub] = $key; + } + } + } + + foreach ($volt as $v) { + // <rphf> <half> <pref> <blwf> <pstf> + // defines consonant types: + // Reph <rphf> + // Half forms <half> + // Pre-base-reordering forms of Ra/Rra <pref> + // Below-base forms <blwf> + // Post-base forms <pstf> + // applied together with <locl> feature to input sequences consisting of two characters + // This is done for each consonant + // for <rphf> and <half>, features are applied to Consonant + Halant combinations + // for <pref>, <blwf> and <pstf>, features are applied to Halant + Consonant combinations + // Old version eg 'deva' <pref>, <blwf> and <pstf>, features are applied to Consonant + Halant + // Some malformed fonts still do Consonant + Halant for these - so match both?? + // If these two glyphs form a ligature, with no additional glyphs in context + // this means the consonant has the corresponding form + // Currently set to cope with both + // See also classes/otl.php + + if (strpos('rphf half pref blwf pstf', $v['tag']) !== false) { + if (isset($v['context']) && $v['context'] && $v['nBacktrack'] == 0 && $v['nLookahead'] == 0) { + foreach ($v['rules'] as $vs) { + if (count($vs['match']) == 2 && count($vs['replace']) == 1) { + $sub = $vs['replace'][0]; + // If Halant Cons <pref>, <blwf> and <pstf> in New version only + if (strpos('0094D 009CD 00A4D 00ACD 00B4D 00BCD 00C4D 00CCD 00D4D', $vs['match'][0]) !== false && strpos('pref blwf pstf', $v['tag']) !== false && !$is_old_spec) { + $key = $vs['match'][1]; + $tag = $v['tag']; + if (isset($loclsubs[$key])) { + ${$tag[$loclsubs[$key]]} = $sub; + } + $tmp = &$$tag; + $tmp[hexdec($key)] = hexdec($sub); + } // If Cons Halant <rphf> and <half> always + // and <pref>, <blwf> and <pstf> in Old version + elseif (strpos('0094D 009CD 00A4D 00ACD 00B4D 00BCD 00C4D 00CCD 00D4D', $vs['match'][1]) !== false && (strpos('rphf half', $v['tag']) !== false || (strpos('pref blwf pstf', $v['tag']) !== false && ($is_old_spec || _OTL_OLD_SPEC_COMPAT_2)))) { + $key = $vs['match'][0]; + $tag = $v['tag']; + if (isset($loclsubs[$key])) { + ${$tag[$loclsubs[$key]]} = $sub; + } + $tmp = &$$tag; + $tmp[hexdec($key)] = hexdec($sub); + } + } + } + } elseif (!isset($v['context'])) { + $key = $v['match']; + $key = preg_replace('/[\(\)]*/', '', $key); + $sub = $v['replace']; + if ($key && strlen(trim($key)) == 11 && $sub) { + // If Cons Halant <rphf> and <half> always + // and <pref>, <blwf> and <pstf> in Old version + // If Halant Cons <pref>, <blwf> and <pstf> in New version only + if (strpos('0094D 009CD 00A4D 00ACD 00B4D 00BCD 00C4D 00CCD 00D4D', substr($key, 0, 5)) !== false && strpos('pref blwf pstf', $v['tag']) !== false && !$is_old_spec) { + $key = substr($key, 6, 5); + $tag = $v['tag']; + if (isset($loclsubs[$key])) { + ${$tag[$loclsubs[$key]]} = $sub; + } + $tmp = &$$tag; + $tmp[hexdec($key)] = hexdec($sub); + } elseif (strpos('0094D 009CD 00A4D 00ACD 00B4D 00BCD 00C4D 00CCD 00D4D', substr($key, 6, 5)) !== false && (strpos('rphf half', $v['tag']) !== false || (strpos('pref blwf pstf', $v['tag']) !== false && ($is_old_spec || _OTL_OLD_SPEC_COMPAT_2)))) { + $key = substr($key, 0, 5); + $tag = $v['tag']; + if (isset($loclsubs[$key])) { + ${$tag[$loclsubs[$key]]} = $sub; + } + $tmp = &$$tag; + $tmp[hexdec($key)] = hexdec($sub); + } + } + } + } + } + } + + if (count($rtl) || count($rphf) || count($half) || count($pref) || count($blwf) || count($pstf) || $finals) { + $font = [ + 'rtlSUB' => $rtlSUB, + 'finals' => $finals, + 'rphf' => $rphf, + 'half' => $half, + 'pref' => $pref, + 'blwf' => $blwf, + 'pstf' => $pstf, + ]; + + $this->fontCache->jsonWrite($this->fontkey . '.GSUB.' . $st . '.' . $t . '.json', $font); + } + + if (!isset($GSUBScriptLang[$st])) { + $GSUBScriptLang[$st] = ''; + } + $GSUBScriptLang[$st] .= $t . ' '; + } + } + + // All RTL glyphs from font added to (or already in) PUA [reqd for magic_reverse] + $rtlPUAstr = ''; + if (count($rtlpua)) { + $rtlpua = array_unique($rtlpua); + sort($rtlpua); + $n = count($rtlpua); + for ($i = 0; $i < $n; $i++) { + if (hexdec($rtlpua[$i]) < hexdec('E000') || hexdec($rtlpua[$i]) > hexdec('F8FF')) { + unset($rtlpua[$i]); + } + } + sort($rtlpua, SORT_STRING); + + $rangeid = -1; + $range = []; + $prevgid = -2; + + // for each character + foreach ($rtlpua as $gidhex) { + $gid = hexdec($gidhex); + if ($gid == ($prevgid + 1)) { + $range[$rangeid]['end'] = $gidhex; + $range[$rangeid]['count']++; + } else { + // new range + $rangeid++; + $range[$rangeid] = []; + $range[$rangeid]['start'] = $gidhex; + $range[$rangeid]['end'] = $gidhex; + $range[$rangeid]['count'] = 1; + } + $prevgid = $gid; + } + + foreach ($range as $rg) { + if ($rg['count'] == 1) { + $rtlPUAstr .= "\x{" . $rg['start'] . "}"; + } elseif ($rg['count'] == 2) { + $rtlPUAstr .= "\x{" . $rg['start'] . "}\x{" . $rg['end'] . "}"; + } else { + $rtlPUAstr .= "\x{" . $rg['start'] . "}-\x{" . $rg['end'] . "}"; + } + } + } + + return [$GSUBScriptLang, $gsub, $GSLookup, $rtlPUAstr]; + } + + // GSUB functions + function _getGSUBarray(&$Lookup, &$lul, $scripttag) + { + // Process (3) LookupList for specific Script-LangSys + // Generate preg_replace + $volt = []; + $reph = ''; + $matraE = ''; + $vatu = ''; + + foreach ($lul as $i => $tag) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $SubstFormat = $Lookup[$i]['Subtable'][$c]['Format']; + + // LookupType 1: Single Substitution Subtable + if ($Lookup[$i]['Type'] == 1) { + $subCount = count($Lookup[$i]['Subtable'][$c]['subs']); + for ($s = 0; $s < $subCount; $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + // Ignore has already been applied earlier on + $repl = $this->_makeGSUBinputMatch($inputGlyphs, "()"); + $subs = $this->_makeGSUBinputReplacement(1, $substitute, "()", 0, 1, 0); + $volt[] = ['match' => $repl, 'replace' => $subs, 'tag' => $tag, 'key' => $inputGlyphs[0], 'type' => 1]; + } + } // LookupType 2: Multiple Substitution Subtable + elseif ($Lookup[$i]['Type'] == 2) { + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = implode(" ", $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute']); + // Ignore has already been applied earlier on + $repl = $this->_makeGSUBinputMatch($inputGlyphs, "()"); + $subs = $this->_makeGSUBinputReplacement(1, $substitute, "()", 0, 1, 0); + $volt[] = ['match' => $repl, 'replace' => $subs, 'tag' => $tag, 'key' => $inputGlyphs[0], 'type' => 2]; + } + } // LookupType 3: Alternate Forms + elseif ($Lookup[$i]['Type'] == 3) { + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + // Ignore has already been applied earlier on + $repl = $this->_makeGSUBinputMatch($inputGlyphs, "()"); + $subs = $this->_makeGSUBinputReplacement(1, $substitute, "()", 0, 1, 0); + $volt[] = ['match' => $repl, 'replace' => $subs, 'tag' => $tag, 'key' => $inputGlyphs[0], 'type' => 3]; + } + } // LookupType 4: Ligature Substitution Subtable + elseif ($Lookup[$i]['Type'] == 4) { + for ($s = 0; $s < count($Lookup[$i]['Subtable'][$c]['subs']); $s++) { + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['subs'][$s]['Replace']; + $substitute = $Lookup[$i]['Subtable'][$c]['subs'][$s]['substitute'][0]; + // Ignore has already been applied earlier on + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + $repl = $this->_makeGSUBinputMatch($inputGlyphs, $ignore); + $subs = $this->_makeGSUBinputReplacement(count($inputGlyphs), $substitute, $ignore, 0, count($inputGlyphs), 0); + $volt[] = ['match' => $repl, 'replace' => $subs, 'tag' => $tag, 'key' => $inputGlyphs[0], 'type' => 4, 'CompCount' => $Lookup[$i]['Subtable'][$c]['subs'][$s]['CompCount'], 'Lig' => $substitute]; + } + } // LookupType 5: Chaining Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 5) { + // Format 1: Context Substitution + if ($SubstFormat == 1) { + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['SubRuleSetCount']; $s++) { + // SubRuleSet + $subRule = []; + foreach ($Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['SubRule'] as $rule) { + // SubRule + $inputGlyphs = []; + if ($rule['GlyphCount'] > 1) { + $inputGlyphs = $rule['InputGlyphs']; + } + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['SubRuleSet'][$s]['FirstGlyph']; + ksort($inputGlyphs); + $nInput = count($inputGlyphs); + + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => '', 'match' => $contextInputMatch, 'nBacktrack' => 0, 'nInput' => $nInput, 'nLookahead' => 0, 'rules' => [],]; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $rule['SubstLookupRecord'][$b]['SequenceIndex']; + + // $Lookup[$lup] = secondary Lookup + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + $REPL = implode(" ", $luss['substitute']); + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } // Format 2: Class-based Context Glyph Substitution + elseif ($SubstFormat == 2) { + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + foreach ($Lookup[$i]['Subtable'][$c]['SubClassSet'] as $inputClass => $cscs) { + for ($cscrule = 0; $cscrule < $cscs['SubClassRuleCnt']; $cscrule++) { + $rule = $cscs['SubClassRule'][$cscrule]; + + $inputGlyphs = []; + + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$inputClass]; + if ($rule['InputGlyphCount'] > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $rule['InputGlyphCount']; $gcl++) { + $classindex = $rule['Input'][$gcl]; + if (isset($Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex])) { + $inputGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex]; + } // if class[0] = all glyphs excluding those specified in all other classes + // set to blank '' for now + else { + $inputGlyphs[$gcl] = ''; + } + } + } + + $nInput = $rule['InputGlyphCount']; + $nIsubs = (2 * $nInput) - 1; + + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => '', 'match' => $contextInputMatch, 'nBacktrack' => 0, 'nInput' => $nInput, 'nLookahead' => 0, 'rules' => [],]; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // $Lookup[$lup] = secondary Lookup + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (isset($Lookup[$lup]['Subtable'][$lus]['subs']) && count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex); + $REPL = implode(" ", $luss['substitute']); + // Returns e.g. "REPL\${6}\${8}" or "\${1}\${2} \${3} REPL\${4}\${6}\${8} \${9}" + + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + + } // Format 3: Coverage-based Context Glyph Substitution p259 + elseif ($SubstFormat == 3) { + + // IgnoreMarks flag set on main Lookup table + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs']; + $CoverageInputGlyphs = implode('|', $inputGlyphs); + $nInput = $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; + + if ($Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']) { + $backtrackGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageBacktrackGlyphs']; + } else { + $backtrackGlyphs = []; + } + + // Returns e.g. ¦(FEEB|FEEC)(ignore) ¦(FD12|FD13)(ignore) ¦ + $backtrackMatch = $this->_makeGSUBbacktrackMatch($backtrackGlyphs, $ignore); + + if ($Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']) { + $lookaheadGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageLookaheadGlyphs']; + } else { + $lookaheadGlyphs = []; + } + + // Returns e.g. ¦(ignore) (FD12|FD13)¦(ignore) (FEEB|FEEC)¦ + $lookaheadMatch = $this->_makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore); + + $nBsubs = 2 * count($backtrackGlyphs); + $nIsubs = (2 * $nInput) - 1; + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => $backtrackMatch, 'match' => ($contextInputMatch . $lookaheadMatch), 'nBacktrack' => count($backtrackGlyphs), 'nInput' => $nInput, 'nLookahead' => count($lookaheadGlyphs), 'rules' => [],]; + + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $lup = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex']; + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex); + $REPL = implode(" ", $luss['substitute']); + + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + + } // LookupType 6: ing Contextual Substitution Subtable + elseif ($Lookup[$i]['Type'] == 6) { + + // Format 1: Simple Chaining Context Glyph Substitution p255 + if ($SubstFormat == 1) { + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + for ($s = 0; $s < $Lookup[$i]['Subtable'][$c]['ChainSubRuleSetCount']; $s++) { + + // ChainSubRuleSet + $subRule = []; + $firstInputGlyph = $Lookup[$i]['Subtable'][$c]['CoverageGlyphs'][$s]; // First input gyyph + + foreach ($Lookup[$i]['Subtable'][$c]['ChainSubRuleSet'][$s]['ChainSubRule'] as $rule) { + // ChainSubRule + $inputGlyphs = []; + if ($rule['InputGlyphCount'] > 1) { + $inputGlyphs = $rule['InputGlyphs']; + } + $inputGlyphs[0] = $firstInputGlyph; + ksort($inputGlyphs); + $nInput = count($inputGlyphs); + + if ($rule['BacktrackGlyphCount']) { + $backtrackGlyphs = $rule['BacktrackGlyphs']; + } else { + $backtrackGlyphs = []; + } + $backtrackMatch = $this->_makeGSUBbacktrackMatch($backtrackGlyphs, $ignore); + + if ($rule['LookaheadGlyphCount']) { + $lookaheadGlyphs = $rule['LookaheadGlyphs']; + } else { + $lookaheadGlyphs = []; + } + + $lookaheadMatch = $this->_makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore); + + $nBsubs = 2 * count($backtrackGlyphs); + $nIsubs = (2 * $nInput) - 1; + + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => $backtrackMatch, 'match' => ($contextInputMatch . $lookaheadMatch), 'nBacktrack' => count($backtrackGlyphs), 'nInput' => $nInput, 'nLookahead' => count($lookaheadGlyphs), 'rules' => [],]; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // $Lookup[$lup] = secondary Lookup + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex); + + $REPL = implode(" ", $luss['substitute']); + + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + + } // Format 2: Class-based Chaining Context Glyph Substitution p257 + elseif ($SubstFormat == 2) { + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + foreach ($Lookup[$i]['Subtable'][$c]['ChainSubClassSet'] as $inputClass => $cscs) { + for ($cscrule = 0; $cscrule < $cscs['ChainSubClassRuleCnt']; $cscrule++) { + $rule = $cscs['ChainSubClassRule'][$cscrule]; + + // These contain classes of glyphs as strings + // $Lookup[$i]['Subtable'][$c]['InputClasses'][(class)] e.g. 02E6|02E7|02E8 + // $Lookup[$i]['Subtable'][$c]['LookaheadClasses'][(class)] + // $Lookup[$i]['Subtable'][$c]['BacktrackClasses'][(class)] + // These contain arrays of classIndexes + // [Backtrack] [Lookahead] and [Input] (Input is from the second position only) + + $inputGlyphs = []; + + if (isset($Lookup[$i]['Subtable'][$c]['InputClasses'][$inputClass])) { + $inputGlyphs[0] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$inputClass]; + } else { + $inputGlyphs[0] = ''; + } + if ($rule['InputGlyphCount'] > 1) { + // NB starts at 1 + for ($gcl = 1; $gcl < $rule['InputGlyphCount']; $gcl++) { + $classindex = $rule['Input'][$gcl]; + if (isset($Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex])) { + $inputGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['InputClasses'][$classindex]; + } // if class[0] = all glyphs excluding those specified in all other classes + // set to blank '' for now + else { + $inputGlyphs[$gcl] = ''; + } + } + } + + $nInput = $rule['InputGlyphCount']; + + if ($rule['BacktrackGlyphCount']) { + for ($gcl = 0; $gcl < $rule['BacktrackGlyphCount']; $gcl++) { + $classindex = $rule['Backtrack'][$gcl]; + if (isset($Lookup[$i]['Subtable'][$c]['BacktrackClasses'][$classindex])) { + $backtrackGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['BacktrackClasses'][$classindex]; + } // if class[0] = all glyphs excluding those specified in all other classes + // set to blank '' for now + else { + $backtrackGlyphs[$gcl] = ''; + } + } + } else { + $backtrackGlyphs = []; + } + // Returns e.g. ¦(FEEB|FEEC)(ignore) ¦(FD12|FD13)(ignore) ¦ + $backtrackMatch = $this->_makeGSUBbacktrackMatch($backtrackGlyphs, $ignore); + + if ($rule['LookaheadGlyphCount']) { + for ($gcl = 0; $gcl < $rule['LookaheadGlyphCount']; $gcl++) { + $classindex = $rule['Lookahead'][$gcl]; + if (isset($Lookup[$i]['Subtable'][$c]['LookaheadClasses'][$classindex])) { + $lookaheadGlyphs[$gcl] = $Lookup[$i]['Subtable'][$c]['LookaheadClasses'][$classindex]; + } // if class[0] = all glyphs excluding those specified in all other classes + // set to blank '' for now + else { + $lookaheadGlyphs[$gcl] = ''; + } + } + } else { + $lookaheadGlyphs = []; + } + // Returns e.g. ¦(ignore) (FD12|FD13)¦(ignore) (FEEB|FEEC)¦ + $lookaheadMatch = $this->_makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore); + + $nBsubs = 2 * count($backtrackGlyphs); + $nIsubs = (2 * $nInput) - 1; + + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => $backtrackMatch, 'match' => ($contextInputMatch . $lookaheadMatch), 'nBacktrack' => count($backtrackGlyphs), 'nInput' => $nInput, 'nLookahead' => count($lookaheadGlyphs), 'rules' => [],]; + + for ($b = 0; $b < $rule['SubstCount']; $b++) { + $lup = $rule['LookupListIndex'][$b]; + $seqIndex = $rule['SequenceIndex'][$b]; + + // $Lookup[$lup] = secondary Lookup + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex); + $REPL = implode(" ", $luss['substitute']); + // Returns e.g. "REPL\${6}\${8}" or "\${1}\${2} \${3} REPL\${4}\${6}\${8} \${9}" + + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + + } // Format 3: Coverage-based Chaining Context Glyph Substitution p259 + elseif ($SubstFormat == 3) { + // IgnoreMarks flag set on main Lookup table + $ignore = $this->_getGSUBignoreString($Lookup[$i]['Flag'], $Lookup[$i]['MarkFilteringSet']); + $inputGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageInputGlyphs']; + $CoverageInputGlyphs = implode('|', $inputGlyphs); + $nInput = $Lookup[$i]['Subtable'][$c]['InputGlyphCount']; + + if ($Lookup[$i]['Subtable'][$c]['BacktrackGlyphCount']) { + $backtrackGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageBacktrackGlyphs']; + } else { + $backtrackGlyphs = []; + } + // Returns e.g. ¦(FEEB|FEEC)(ignore) ¦(FD12|FD13)(ignore) ¦ + $backtrackMatch = $this->_makeGSUBbacktrackMatch($backtrackGlyphs, $ignore); + + if ($Lookup[$i]['Subtable'][$c]['LookaheadGlyphCount']) { + $lookaheadGlyphs = $Lookup[$i]['Subtable'][$c]['CoverageLookaheadGlyphs']; + } else { + $lookaheadGlyphs = []; + } + // Returns e.g. ¦(ignore) (FD12|FD13)¦(ignore) (FEEB|FEEC)¦ + $lookaheadMatch = $this->_makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore); + + $nBsubs = 2 * count($backtrackGlyphs); + $nIsubs = (2 * $nInput) - 1; + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, [], 0); + $subRule = ['context' => 1, 'tag' => $tag, 'matchback' => $backtrackMatch, 'match' => ($contextInputMatch . $lookaheadMatch), 'nBacktrack' => count($backtrackGlyphs), 'nInput' => $nInput, 'nLookahead' => count($lookaheadGlyphs), 'rules' => [],]; + + for ($b = 0; $b < $Lookup[$i]['Subtable'][$c]['SubstCount']; $b++) { + $lup = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['LookupListIndex']; + $seqIndex = $Lookup[$i]['Subtable'][$c]['SubstLookupRecord'][$b]['SequenceIndex']; + for ($lus = 0; $lus < $Lookup[$lup]['SubtableCount']; $lus++) { + if (count($Lookup[$lup]['Subtable'][$lus]['subs'])) { + foreach ($Lookup[$lup]['Subtable'][$lus]['subs'] as $luss) { + $lookupGlyphs = $luss['Replace']; + $mLen = count($lookupGlyphs); + + // Only apply if the (first) 'Replace' glyph from the + // Lookup list is in the [inputGlyphs] at ['SequenceIndex'] + // then apply the substitution + if (strpos($inputGlyphs[$seqIndex], $lookupGlyphs[0]) === false) { + continue; + } + + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + $contextInputMatch = $this->_makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex); + $REPL = implode(" ", $luss['substitute']); + + if (strpos("isol fina fin2 fin3 medi med2 init ", $tag) !== false && $scripttag == 'arab') { + $volt[] = ['match' => $lookupGlyphs[0], 'replace' => $REPL, 'tag' => $tag, 'prel' => $backtrackGlyphs, 'postl' => $lookaheadGlyphs, 'ignore' => $ignore]; + } else { + $subRule['rules'][] = ['type' => $Lookup[$lup]['Type'], 'match' => $lookupGlyphs, 'replace' => $luss['substitute'], 'seqIndex' => $seqIndex, 'key' => $lookupGlyphs[0],]; + } + } + } + } + } + if (count($subRule['rules'])) { + $volt[] = $subRule; + } + } + } + } + } + + return $volt; + } + + function _checkGSUBignore($flag, $glyph, $MarkFilteringSet) + { + $ignore = false; + // Flag & 0x0008 = Ignore Marks - (unless already done with MarkAttachmentType) + if ((($flag & 0x0008) == 0x0008 && ($flag & 0xFF00) == 0) && strpos($this->GlyphClassMarks, $glyph)) { + $ignore = true; + } + if ((($flag & 0x0004) == 0x0004) && strpos($this->GlyphClassLigatures, $glyph)) { + $ignore = true; + } + if ((($flag & 0x0002) == 0x0002) && strpos($this->GlyphClassBases, $glyph)) { + $ignore = true; + } + // Flag & 0xFF?? = MarkAttachmentType + if ($flag & 0xFF00) { + // "a lookup must ignore any mark glyphs that are not in the specified mark attachment class" + // $this->MarkAttachmentType is already adjusted for this i.e. contains all Marks except those in the MarkAttachmentClassDef table + if (strpos($this->MarkAttachmentType[($flag >> 8)], $glyph)) { + $ignore = true; + } + } + // Flag & 0x0010 = UseMarkFilteringSet + if (($flag & 0x0010) && strpos($this->MarkGlyphSets[$MarkFilteringSet], $glyph)) { + $ignore = true; + } + + return $ignore; + } + + function _getGSUBignoreString($flag, $MarkFilteringSet) + { + // If ignoreFlag set, combine all ignore glyphs into -> "((?:(?: FBA1| FBA2| FBA3))*)" + // else "()" + // for Input - set on secondary Lookup table if in Context, and set Backtrack and Lookahead on Context Lookup + $str = ""; + $ignoreflag = 0; + + // Flag & 0xFF?? = MarkAttachmentType + if ($flag & 0xFF00) { + // "a lookup must ignore any mark glyphs that are not in the specified mark attachment class" + // $this->MarkAttachmentType is already adjusted for this i.e. contains all Marks except those in the MarkAttachmentClassDef table + $MarkAttachmentType = $flag >> 8; + $ignoreflag = $flag; + $str = $this->MarkAttachmentType[$MarkAttachmentType]; + } + + // Flag & 0x0010 = UseMarkFilteringSet + if ($flag & 0x0010) { + throw new \Mpdf\MpdfException("This font " . $this->fontkey . " contains MarkGlyphSets - Not tested yet"); + $str = $this->MarkGlyphSets[$MarkFilteringSet]; + } + + // If Ignore Marks set, supercedes any above + // Flag & 0x0008 = Ignore Marks - (unless already done with MarkAttachmentType) + if (($flag & 0x0008) == 0x0008 && ($flag & 0xFF00) == 0) { + $ignoreflag = 8; + $str = $this->GlyphClassMarks; + } + + // Flag & 0x0004 = Ignore Ligatures + if (($flag & 0x0004) == 0x0004) { + $ignoreflag += 4; + if ($str) { + $str .= "|"; + } + $str .= $this->GlyphClassLigatures; + } + // Flag & 0x0002 = Ignore BaseGlyphs + if (($flag & 0x0002) == 0x0002) { + $ignoreflag += 2; + if ($str) { + $str .= "|"; + } + $str .= $this->GlyphClassBases; + } + if ($str) { + // This originally returned e.g. ((?:(?:[IGNORE8]))*) when NOT specific to a Lookup e.g. rtlSub in + // arabictypesetting.GSUB.arab.DFLT.php + // This would save repeatedly saving long text strings if used multiple times + // When writing e.g. arabictypesetting.GSUB.arab.DFLT.php to file, included as $ignore[8] + // Would need to also write the $ignore array to that file + // // If UseMarkFilteringSet (specific to the Lookup) return the string + // if (($flag & 0x0010) && ($flag & 0x0008) != 0x0008) { + // return "((?:(?:" . $str . "))*)"; + // } + // else { return "((?:(?:" . "[IGNORE".$ignoreflag."]" . "))*)"; } + // // e.g. ((?:(?: 0031| 0032| 0033| 0034| 0045))*) + // But never finished coding it to add the $ignore array to the file, and it doesn't seem to occur often enough to be worth + // writing. So just output it as a string: + return "((?:(?:" . $str . "))*)"; + } else { + return "()"; + } + } + + // GSUB Patterns + + /* + BACKTRACK INPUT LOOKAHEAD + ================================== ================== ================================== + (FEEB|FEEC)(ign) ¦(FD12|FD13)(ign) ¦(0612)¦(ign) (0613)¦(ign) (FD12|FD13)¦(ign) (FEEB|FEEC) + ---------------- ---------------- ----- ------------ --------------- --------------- + Backtrack 1 Backtrack 2 Input 1 Input 2 Lookahead 1 Lookahead 2 + -------- --- --------- --- ---- --- ---- --- --------- --- ------- + \${1} \${2} \${3} \${4} \${5+} \${6+} \${7+} \${8+} + + nBacktrack = 2 nInput = 2 nLookahead = 2 + + nBsubs = 2xnBack nIsubs = (nBsubs+) nLsubs = (nBsubs+nIsubs+) 2xnLookahead + "\${1}\${2} " (nInput*2)-1 "\${5+} \${6+}" + "REPL" + + ¦\${1}\${2} ¦\${3}\${4} ¦REPL¦\${5+} \${6+}¦\${7+} \${8+}¦ + + + INPUT nInput = 5 + ============================================================ + ¦(0612)¦(ign) (0613)¦(ign) (0614)¦(ign) (0615)¦(ign) (0615)¦ + \${1} \${2} \${3} \${4} \${5} \${6} \${7} \${8} \${9} (All backreference numbers are + nBsubs) + ----- ------------ ------------ ------------ ------------ + Input 1 Input 2 Input 3 Input 4 Input 5 + + A====== SequenceIndex=1 ; Lookup match nGlyphs=1 + B=================== SequenceIndex=1 ; Lookup match nGlyphs=2 + C=============================== SequenceIndex=1 ; Lookup match nGlyphs=3 + D======================= SequenceIndex=2 ; Lookup match nGlyphs=2 + E===================================== SequenceIndex=2 ; Lookup match nGlyphs=3 + F====================== SequenceIndex=4 ; Lookup match nGlyphs=2 + + All backreference numbers are + nBsubs + A - "REPL\${2} \${3}\${4} \${5}\${6} \${7}\${8} \${9}" + B - "REPL\${2}\${4} \${5}\${6} \${7}\${8} \${9}" + C - "REPL\${2}\${4}\${6} \${7}\${8} \${9}" + D - "\${1} REPL\${2}\${4}\${6} \${7}\${8} \${9}" + E - "\${1} REPL\${2}\${4}\${6}\${8} \${9}" + F - "\${1}\${2} \${3}\${4} \${5} REPL\${6}\${8}" + */ + + function _makeGSUBcontextInputMatch($inputGlyphs, $ignore, $lookupGlyphs, $seqIndex) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + // $inputGlyphs = array of glyphs(glyphstrings) making up Input sequence in Context + // $lookupGlyphs = array of glyphs (single Glyphs) making up Lookup Input sequence + $mLen = count($lookupGlyphs); // nGlyphs in the secondary Lookup match + $nInput = count($inputGlyphs); // nGlyphs in the Primary Input sequence + $str = ""; + for ($i = 0; $i < $nInput; $i++) { + if ($i > 0) { + $str .= $ignore . " "; + } + if ($i >= $seqIndex && $i < ($seqIndex + $mLen)) { + $str .= "(" . $lookupGlyphs[($i - $seqIndex)] . ")"; + } else { + $str .= "(" . $inputGlyphs[($i)] . ")"; + } + } + + return $str; + } + + function _makeGSUBinputMatch($inputGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(0612)¦(ignore) (0613)¦(ignore) (0614)¦ + // $inputGlyphs = array of glyphs(glyphstrings) making up Input sequence in Context + // $lookupGlyphs = array of glyphs making up Lookup Input sequence - if applicable + $str = ""; + for ($i = 1; $i <= count($inputGlyphs); $i++) { + if ($i > 1) { + $str .= $ignore . " "; + } + $str .= "(" . $inputGlyphs[($i - 1)] . ")"; + } + + return $str; + } + + function _makeGSUBbacktrackMatch($backtrackGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(FEEB|FEEC)(ignore) ¦(FD12|FD13)(ignore) ¦ + // $backtrackGlyphs = array of glyphstrings making up Backtrack sequence + // 3 2 1 0 + // each item being e.g. E0AD|E0AF|F1FD + $str = ""; + for ($i = (count($backtrackGlyphs) - 1); $i >= 0; $i--) { + $str .= "(" . $backtrackGlyphs[$i] . ")" . $ignore . " "; + } + + return $str; + } + + function _makeGSUBlookaheadMatch($lookaheadGlyphs, $ignore) + { + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // Returns e.g. ¦(ignore) (FD12|FD13)¦(ignore) (FEEB|FEEC)¦ + // $lookaheadGlyphs = array of glyphstrings making up Lookahead sequence + // 0 1 2 3 + // each item being e.g. E0AD|E0AF|F1FD + $str = ""; + for ($i = 0; $i < count($lookaheadGlyphs); $i++) { + $str .= $ignore . " (" . $lookaheadGlyphs[$i] . ")"; + } + + return $str; + } + + function _makeGSUBinputReplacement($nInput, $REPL, $ignore, $nBsubs, $mLen, $seqIndex) + { + // Returns e.g. "REPL\${6}\${8}" or "\${1}\${2} \${3} REPL\${4}\${6}\${8} \${9}" + // $nInput nGlyphs in the Primary Input sequence + // $REPL replacement glyphs from secondary lookup + // $ignore = "((?:(?: FBA1| FBA2| FBA3))*)" or "()" + // $nBsubs Number of Backtrack substitutions (= 2x Number of Backtrack glyphs) + // $mLen nGlyphs in the secondary Lookup match - if no secondary lookup, should=$nInput + // $seqIndex Sequence Index to apply the secondary match + if ($ignore == "()") { + $ign = false; + } else { + $ign = true; + } + $str = ""; + if ($nInput == 1) { + $str = $REPL; + } elseif ($nInput > 1) { + if ($mLen == $nInput) { // whole string replaced + $str = $REPL; + if ($ign) { + // for every nInput over 1, add another replacement backreference, to move IGNORES after replacement + for ($x = 2; $x <= $nInput; $x++) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + } + } else { // if only part of string replaced: + for ($x = 1; $x < ($seqIndex + 1); $x++) { + if ($x == 1) { + $str .= '\\' . ($nBsubs + 1); + } else { + if ($ign) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + $str .= ' \\' . ($nBsubs + 1 + (2 * ($x - 1))); + } + } + if ($seqIndex > 0) { + $str .= " "; + } + $str .= $REPL; + if ($ign) { + for ($x = (max(($seqIndex + 1), 2)); $x < ($seqIndex + 1 + $mLen); $x++) { // move IGNORES after replacement + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + } + for ($x = ($seqIndex + 1 + $mLen); $x <= $nInput; $x++) { + if ($ign) { + $str .= '\\' . ($nBsubs + (2 * ($x - 1))); + } + $str .= ' \\' . ($nBsubs + 1 + (2 * ($x - 1))); + } + } + } + + return $str; + } + + function _getCoverage($convert2hex = true, $mode = 1) + { + $g = []; + $ctr = 0; + $CoverageFormat = $this->read_ushort(); + if ($CoverageFormat == 1) { + $CoverageGlyphCount = $this->read_ushort(); + for ($gid = 0; $gid < $CoverageGlyphCount; $gid++) { + $glyphID = $this->read_ushort(); + $uni = $this->glyphToChar[$glyphID][0]; + if ($convert2hex) { + $g[] = unicode_hex($uni); + } elseif ($mode == 2) { + $g[$uni] = $ctr; + $ctr++; + } else { + $g[] = $glyphID; + } + } + } + if ($CoverageFormat == 2) { + $RangeCount = $this->read_ushort(); + for ($r = 0; $r < $RangeCount; $r++) { + $start = $this->read_ushort(); + $end = $this->read_ushort(); + $StartCoverageIndex = $this->read_ushort(); // n/a + for ($glyphID = $start; $glyphID <= $end; $glyphID++) { + $uni = $this->glyphToChar[$glyphID][0]; + if ($convert2hex) { + $g[] = unicode_hex($uni); + } elseif ($mode == 2) { + $uni = $g[$uni] = $ctr; + $ctr++; + } else { + $g[] = $glyphID; + } + } + } + } + + return $g; + } + + function _getClasses($offset) + { + $this->seek($offset); + $ClassFormat = $this->read_ushort(); + $GlyphByClass = []; + if ($ClassFormat == 1) { + $StartGlyph = $this->read_ushort(); + $GlyphCount = $this->read_ushort(); + for ($i = 0; $i < $GlyphCount; $i++) { + $startGlyphID = $StartGlyph + $i; + $endGlyphID = $StartGlyph + $i; + $class = $this->read_ushort(); + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if (isset($this->glyphToChar[$g][0])) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$g][0]); + } + } + } + } elseif ($ClassFormat == 2) { + $tableCount = $this->read_ushort(); + for ($i = 0; $i < $tableCount; $i++) { + $startGlyphID = $this->read_ushort(); + $endGlyphID = $this->read_ushort(); + $class = $this->read_ushort(); + for ($g = $startGlyphID; $g <= $endGlyphID; $g++) { + if ($this->glyphToChar[$g][0]) { + $GlyphByClass[$class][] = unicode_hex($this->glyphToChar[$g][0]); + } + } + } + } + $gbc = []; + foreach ($GlyphByClass as $class => $garr) { + $gbc[$class] = implode('|', $garr); + } + + return $gbc; + } + + function _getGPOStables() + { + /////////////////////////////////// + // GPOS - Glyph Positioning + /////////////////////////////////// + if (!isset($this->tables["GPOS"])) { + return [[], [], []]; + } + + $ffeats = []; + $gpos_offset = $this->seek_table("GPOS"); + $this->skip(4); + $ScriptList_offset = $gpos_offset + $this->read_ushort(); + $FeatureList_offset = $gpos_offset + $this->read_ushort(); + $LookupList_offset = $gpos_offset + $this->read_ushort(); + + // ScriptList + $this->seek($ScriptList_offset); + $ScriptCount = $this->read_ushort(); + for ($i = 0; $i < $ScriptCount; $i++) { + $ScriptTag = $this->read_tag(); // = "beng", "deva" etc. + $ScriptTableOffset = $this->read_ushort(); + $ffeats[$ScriptTag] = $ScriptList_offset + $ScriptTableOffset; + } + + // Script Table + foreach ($ffeats as $t => $o) { + $ls = []; + $this->seek($o); + $DefLangSys_offset = $this->read_ushort(); + if ($DefLangSys_offset > 0) { + $ls['DFLT'] = $DefLangSys_offset + $o; + } + $LangSysCount = $this->read_ushort(); + for ($i = 0; $i < $LangSysCount; $i++) { + $LangTag = $this->read_tag(); // = + $LangTableOffset = $this->read_ushort(); + $ls[$LangTag] = $o + $LangTableOffset; + } + $ffeats[$t] = $ls; + } + + // Get FeatureIndexList + // LangSys Table - from first listed langsys + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = []; + $langsystable_offset = $o; + $this->seek($langsystable_offset); + $LookUpOrder = $this->read_ushort(); //==NULL + $ReqFeatureIndex = $this->read_ushort(); + if ($ReqFeatureIndex != 0xFFFF) { + $FeatureIndex[] = $ReqFeatureIndex; + } + $FeatureCount = $this->read_ushort(); + for ($i = 0; $i < $FeatureCount; $i++) { + $FeatureIndex[] = $this->read_ushort(); // = index of feature + } + $ffeats[$st][$t] = $FeatureIndex; + } + } + // Feauture List => LookupListIndex es + $this->seek($FeatureList_offset); + $FeatureCount = $this->read_ushort(); + $Feature = []; + for ($i = 0; $i < $FeatureCount; $i++) { + $tag = $this->read_tag(); + if ($tag === 'kern') { + $this->haskernGPOS = true; + } + $Feature[$i] = ['tag' => $tag]; + $Feature[$i]['offset'] = $FeatureList_offset + $this->read_ushort(); + } + + for ($i = 0; $i < $FeatureCount; $i++) { + $this->seek($Feature[$i]['offset']); + $this->read_ushort(); // null + $Feature[$i]['LookupCount'] = $Lookupcount = $this->read_ushort(); + $Feature[$i]['LookupListIndex'] = []; + for ($c = 0; $c < $Lookupcount; $c++) { + $Feature[$i]['LookupListIndex'][] = $this->read_ushort(); + } + } + + foreach ($ffeats as $st => $scripts) { + foreach ($scripts as $t => $o) { + $FeatureIndex = $ffeats[$st][$t]; + foreach ($FeatureIndex as $k => $fi) { + $ffeats[$st][$t][$k] = $Feature[$fi]; + } + } + } + + $gpos = []; + $GPOSScriptLang = []; + foreach ($ffeats as $st => $scripts) { + + foreach ($scripts as $t => $langsys) { + + $lg = []; + foreach ($langsys as $ft) { + $lg[$ft['LookupListIndex'][0]] = $ft; + } + + // list of Lookups in order they need to be run i.e. order listed in Lookup table + ksort($lg); + foreach ($lg as $ft) { + $gpos[$st][$t][$ft['tag']] = $ft['LookupListIndex']; + } + if (!isset($GPOSScriptLang[$st])) { + $GPOSScriptLang[$st] = ''; + } + $GPOSScriptLang[$st] .= $t . ' '; + } + } + + // Get metadata and offsets for whole Lookup List table + $this->seek($LookupList_offset); + $LookupCount = $this->read_ushort(); + $Lookup = []; + $Offsets = []; + $SubtableCount = []; + + for ($i = 0; $i < $LookupCount; $i++) { + $Offsets[$i] = $LookupList_offset + $this->read_ushort(); + } + + for ($i = 0; $i < $LookupCount; $i++) { + $this->seek($Offsets[$i]); + $Lookup[$i]['Type'] = $this->read_ushort(); + $Lookup[$i]['Flag'] = $flag = $this->read_ushort(); + $Lookup[$i]['SubtableCount'] = $SubtableCount[$i] = $this->read_ushort(); + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $Lookup[$i]['Subtables'][$c] = $Offsets[$i] + $this->read_ushort(); + } + // MarkFilteringSet = Index (base 0) into GDEF mark glyph sets structure + if (($flag & 0x0010) === 0x0010) { + $Lookup[$i]['MarkFilteringSet'] = $this->read_ushort(); + } else { + $Lookup[$i]['MarkFilteringSet'] = ''; + } + + // Lookup Type 9: Extension + if ($Lookup[$i]['Type'] == 9) { + // Overwrites new offset (32-bit) for each subtable, and a new lookup Type + for ($c = 0; $c < $SubtableCount[$i]; $c++) { + $this->seek($Lookup[$i]['Subtables'][$c]); + $ExtensionPosFormat = $this->read_ushort(); + $type = $this->read_ushort(); + $Lookup[$i]['Subtables'][$c] = $Lookup[$i]['Subtables'][$c] + $this->read_ulong(); + } + $Lookup[$i]['Type'] = $type; + } + } + + // Process Whole LookupList - Get LuCoverage = Lookup coverage just for first glyph + $this->LuCoverage = []; + for ($i = 0; $i < $LookupCount; $i++) { + for ($c = 0; $c < $Lookup[$i]['SubtableCount']; $c++) { + $this->seek($Lookup[$i]['Subtables'][$c]); + $PosFormat = $this->read_ushort(); + + if ($Lookup[$i]['Type'] == 7 && $PosFormat == 3) { + $this->skip(4); + } elseif ($Lookup[$i]['Type'] == 8 && $PosFormat == 3) { + $BacktrackGlyphCount = $this->read_ushort(); + $this->skip(2 * $BacktrackGlyphCount + 2); + } + // NB Coverage only looks at glyphs for position 1 (i.e. 7.3 and 8.3) // NEEDS TO READ ALL ******************** + // NB For e.g. Type 4, this may be the Coverage for the Mark + $Coverage = $Lookup[$i]['Subtables'][$c] + $this->read_ushort(); + $this->seek($Coverage); + $glyphs = $this->_getCoverage(false, 2); + $this->LuCoverage[$i][$c] = $glyphs; + } + } + + $this->fontCache->jsonWrite($this->fontkey . '.GPOSdata.json', $this->LuCoverage); + + return [$GPOSScriptLang, $gpos, $Lookup]; + } + + function makeSubset($file, &$subset, $TTCfontID = 0, $debug = false, $useOTL = false) + { + $this->useOTL = $useOTL; + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file %s', $file)); + } + + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->ascent = 0; + $this->descent = 0; + $this->strikeoutSize = 0; + $this->strikeoutPosition = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->skip(4); + $this->maxUni = 0; + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000], true)) { + throw new \Mpdf\MpdfException(sprintf('Error parsing TrueType Collection: version=%s - %s', $version, $file)); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + $this->readTableDirectory($debug); + + // head - Font header table + $this->seek_table('head'); + $this->skip(50); + $indexToLocFormat = $this->read_ushort(); + $glyphDataFormat = $this->read_ushort(); + + // hhea - Horizontal header table + $this->seek_table('hhea'); + $this->skip(32); + $metricDataFormat = $this->read_ushort(); + $orignHmetrics = $numberOfHMetrics = $this->read_ushort(); + + // maxp - Maximum profile table + $this->seek_table('maxp'); + $this->skip(4); + $numGlyphs = $this->read_ushort(); + + // cmap - Character to glyph index mapping table + $cmap_offset = $this->seek_table('cmap'); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException(sprintf('Font "%s" does not have Unicode cmap (platform 3, encoding 1, format 4, or platform 0 [any encoding] format 4)', $this->filename)); + } + + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + + // Map Unmapped glyphs - from $numGlyphs + if ($useOTL) { + $bctr = 0xE000; + for ($gid = 1; $gid < $numGlyphs; $gid++) { + if (!isset($glyphToChar[$gid])) { + while (isset($charToGlyph[$bctr])) { + $bctr++; + } // Avoid overwriting a glyph already mapped in PUA + if ($bctr > 0xF8FF) { + throw new \Mpdf\MpdfException($file . " : WARNING - Font cannot map all included glyphs into Private Use Area U+E000 - U+F8FF; cannot use useOTL on this font"); + } + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $bctr++; + } + } + } + + $this->charToGlyph = $charToGlyph; + $this->glyphToChar = $glyphToChar; + + // hmtx - Horizontal metrics table + $scale = 1; // not used + $this->getHMTX($numberOfHMetrics, $numGlyphs, $glyphToChar, $scale); + + // loca - Index to location + $this->getLOCA($indexToLocFormat, $numGlyphs); + + $subsetglyphs = [0 => 0, 1 => 1, 2 => 2]; + $subsetCharToGlyph = []; + foreach ($subset as $code) { + if (isset($this->charToGlyph[$code])) { + $subsetglyphs[$this->charToGlyph[$code]] = $code; // Old Glyph ID => Unicode + $subsetCharToGlyph[$code] = $this->charToGlyph[$code]; // Unicode to old GlyphID + } + $this->maxUni = max($this->maxUni, $code); + } + + list($start, $dummy) = $this->get_table_pos('glyf'); + + $glyphSet = []; + ksort($subsetglyphs); + $n = 0; + $fsLastCharIndex = 0; // maximum Unicode index (character code) in this font, according to the cmap subtable for platform ID 3 and platform- specific encoding ID 0 or 1. + foreach ($subsetglyphs as $originalGlyphIdx => $uni) { + $fsLastCharIndex = max($fsLastCharIndex, $uni); + $glyphSet[$originalGlyphIdx] = $n; // old glyphID to new glyphID + $n++; + } + + $codeToGlyph = []; + ksort($subsetCharToGlyph); + foreach ($subsetCharToGlyph as $uni => $originalGlyphIdx) { + $codeToGlyph[$uni] = $glyphSet[$originalGlyphIdx]; + } + $this->codeToGlyph = $codeToGlyph; + + ksort($subsetglyphs); + foreach ($subsetglyphs as $originalGlyphIdx => $uni) { + $this->getGlyphs($originalGlyphIdx, $start, $glyphSet, $subsetglyphs); + } + + $numGlyphs = $numberOfHMetrics = count($subsetglyphs); + + // name - table copied from the original + // MS spec says that "Platform and encoding ID's in the name table should be consistent with those in the cmap table. + // If they are not, the font will not load in Windows" + // Doesn't seem to be a problem? + $this->add('name', $this->get_table('name')); + + // tables copied from the original + $tags = ['cvt ', 'fpgm', 'prep', 'gasp']; + foreach ($tags as $tag) { + if (isset($this->tables[$tag])) { + $this->add($tag, $this->get_table($tag)); + } + } + + // post - PostScript + if (isset($this->tables['post'])) { + $opost = $this->get_table('post'); + $post = "\x00\x03\x00\x00" . substr($opost, 4, 12) . "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + $this->add('post', $post); + } + + // Sort CID2GID map into segments of contiguous codes + ksort($codeToGlyph); + unset($codeToGlyph[0]); + + $rangeid = 0; + $range = []; + $prevcid = -2; + $prevglidx = -1; + + // for each character + foreach ($codeToGlyph as $cid => $glidx) { + if ($cid == ($prevcid + 1) && $glidx == ($prevglidx + 1)) { + $range[$rangeid][] = $glidx; + } else { + // new range + $rangeid = $cid; + $range[$rangeid] = []; + $range[$rangeid][] = $glidx; + } + $prevcid = $cid; + $prevglidx = $glidx; + } + + // cmap - Character to glyph mapping + $segCount = count($range) + 1; // + 1 Last segment has missing character 0xFFFF + $searchRange = 1; + $entrySelector = 0; + + while ($searchRange * 2 <= $segCount) { + $searchRange *= 2; + ++$entrySelector; + } + + $searchRange *= 2; + $rangeShift = $segCount * 2 - $searchRange; + $length = 16 + (8 * $segCount) + ($numGlyphs + 1); + $cmap = [ + 0, 3, // Index : version, number of encoding subtables + 0, 0, // Encoding Subtable : platform (UNI=0), encoding 0 + 0, 28, // Encoding Subtable : offset (hi,lo) + 0, 3, // Encoding Subtable : platform (UNI=0), encoding 3 + 0, 28, // Encoding Subtable : offset (hi,lo) + 3, 1, // Encoding Subtable : platform (MS=3), encoding 1 + 0, 28, // Encoding Subtable : offset (hi,lo) + 4, $length, 0, // Format 4 Mapping subtable: format, length, language + $segCount * 2, + $searchRange, + $entrySelector, + $rangeShift, + ]; + + // endCode(s) + foreach ($range as $start => $subrange) { + $endCode = $start + (count($subrange) - 1); + $cmap[] = $endCode; // endCode(s) + } + + $cmap[] = 0xFFFF; // endCode of last Segment + $cmap[] = 0; // reservedPad + + // startCode(s) + foreach ($range as $start => $subrange) { + $cmap[] = $start; // startCode(s) + } + + $cmap[] = 0xFFFF; // startCode of last Segment + + // idDelta(s) + foreach ($range as $start => $subrange) { + $idDelta = -($start - $subrange[0]); + $n += count($subrange); + $cmap[] = $idDelta; // idDelta(s) + } + + $cmap[] = 1; // idDelta of last Segment + // idRangeOffset(s) + + foreach ($range as $subrange) { + $cmap[] = 0; // idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 + } + + $cmap[] = 0; // idRangeOffset of last Segment + foreach ($range as $subrange) { + foreach ($subrange as $glidx) { + $cmap[] = $glidx; + } + } + + $cmap[] = 0; // Mapping for last character + $cmapstr = ''; + + foreach ($cmap as $cm) { + $cmapstr .= pack('n', $cm); + } + $this->add('cmap', $cmapstr); + + // glyf - Glyph data + list($glyfOffset, $glyfLength) = $this->get_table_pos('glyf'); + if ($glyfLength < $this->maxStrLenRead) { + $glyphData = $this->get_table('glyf'); + } + + $offsets = []; + $glyf = ''; + $pos = 0; + $hmtxstr = ''; + $xMinT = 0; + $yMinT = 0; + $xMaxT = 0; + $yMaxT = 0; + $advanceWidthMax = 0; + $minLeftSideBearing = 0; + $minRightSideBearing = 0; + $xMaxExtent = 0; + $maxPoints = 0; // points in non-compound glyph + $maxContours = 0; // contours in non-compound glyph + $maxComponentPoints = 0; // points in compound glyph + $maxComponentContours = 0; // contours in compound glyph + $maxComponentElements = 0; // number of glyphs referenced at top level + $maxComponentDepth = 0; // levels of recursion, set to 0 if font has only simple glyphs + $this->glyphdata = []; + + foreach ($subsetglyphs as $originalGlyphIdx => $uni) { + // hmtx - Horizontal Metrics + $hm = $this->getHMetric($orignHmetrics, $originalGlyphIdx); + $hmtxstr .= $hm; + + $offsets[] = $pos; + $glyphPos = $this->glyphPos[$originalGlyphIdx]; + $glyphLen = $this->glyphPos[$originalGlyphIdx + 1] - $glyphPos; + if ($glyfLength < $this->maxStrLenRead) { + $data = substr($glyphData, $glyphPos, $glyphLen); + } else { + if ($glyphLen > 0) { + $data = $this->get_chunk($glyfOffset + $glyphPos, $glyphLen); + } else { + $data = ''; + } + } + + if ($glyphLen > 0) { + if (_RECALC_PROFILE) { + $xMin = $this->unpack_short(substr($data, 2, 2)); + $yMin = $this->unpack_short(substr($data, 4, 2)); + $xMax = $this->unpack_short(substr($data, 6, 2)); + $yMax = $this->unpack_short(substr($data, 8, 2)); + $xMinT = min($xMinT, $xMin); + $yMinT = min($yMinT, $yMin); + $xMaxT = max($xMaxT, $xMax); + $yMaxT = max($yMaxT, $yMax); + $aw = $this->unpack_short(substr($hm, 0, 2)); + $lsb = $this->unpack_short(substr($hm, 2, 2)); + $advanceWidthMax = max($advanceWidthMax, $aw); + $minLeftSideBearing = min($minLeftSideBearing, $lsb); + $minRightSideBearing = min($minRightSideBearing, ($aw - $lsb - ($xMax - $xMin))); + $xMaxExtent = max($xMaxExtent, ($lsb + ($xMax - $xMin))); + } + $up = unpack("n", substr($data, 0, 2)); + } + if ($glyphLen > 2 && ($up[1] & (1 << 15))) { // If number of contours <= -1 i.e. composiste glyph + $pos_in_glyph = 10; + $flags = GlyphOperator::MORE; + $nComponentElements = 0; + while ($flags & GlyphOperator::MORE) { + $nComponentElements += 1; // number of glyphs referenced at top level + $up = unpack("n", substr($data, $pos_in_glyph, 2)); + $flags = $up[1]; + $up = unpack("n", substr($data, $pos_in_glyph + 2, 2)); + $glyphIdx = $up[1]; + $this->glyphdata[$originalGlyphIdx]['compGlyphs'][] = $glyphIdx; + $data = $this->_set_ushort($data, $pos_in_glyph + 2, $glyphSet[$glyphIdx]); + $pos_in_glyph += 4; + if ($flags & GlyphOperator::WORDS) { + $pos_in_glyph += 4; + } else { + $pos_in_glyph += 2; + } + if ($flags & GlyphOperator::SCALE) { + $pos_in_glyph += 2; + } elseif ($flags & GlyphOperator::XYSCALE) { + $pos_in_glyph += 4; + } elseif ($flags & GlyphOperator::TWOBYTWO) { + $pos_in_glyph += 8; + } + } + $maxComponentElements = max($maxComponentElements, $nComponentElements); + + } // Simple Glyph + elseif (_RECALC_PROFILE && $glyphLen > 2 && $up[1] < (1 << 15) && $up[1] > 0) { // Number of contours > 0 simple glyph + $nContours = $up[1]; + $this->glyphdata[$originalGlyphIdx]['nContours'] = $nContours; + $maxContours = max($maxContours, $nContours); + + // Count number of points in simple glyph + $pos_in_glyph = 10 + ($nContours * 2) - 2; // Last endContourPoint + $up = unpack("n", substr($data, $pos_in_glyph, 2)); + $points = $up[1] + 1; + $this->glyphdata[$originalGlyphIdx]['nPoints'] = $points; + $maxPoints = max($maxPoints, $points); + } + + $glyf .= $data; + $pos += $glyphLen; + if ($pos % 4 != 0) { + $padding = 4 - ($pos % 4); + $glyf .= str_repeat("\0", $padding); + $pos += $padding; + } + } + + if (_RECALC_PROFILE) { + foreach ($this->glyphdata as $originalGlyphIdx => $val) { + $maxdepth = $depth = -1; + $points = 0; + $contours = 0; + $this->getGlyphData($originalGlyphIdx, $maxdepth, $depth, $points, $contours); + $maxComponentDepth = max($maxComponentDepth, $maxdepth); + $maxComponentPoints = max($maxComponentPoints, $points); + $maxComponentContours = max($maxComponentContours, $contours); + } + } + + $offsets[] = $pos; + $this->add('glyf', $glyf); + + // hmtx - Horizontal Metrics + $this->add('hmtx', $hmtxstr); + + // loca - Index to location + $locastr = ''; + if ((($pos + 1) >> 1) > 0xFFFF) { + $indexToLocFormat = 1; // long format + foreach ($offsets as $offset) { + $locastr .= pack("N", $offset); + } + } else { + $indexToLocFormat = 0; // short format + foreach ($offsets as $offset) { + $locastr .= pack("n", ($offset / 2)); + } + } + $this->add('loca', $locastr); + + // head - Font header + $head = $this->get_table('head'); + $head = $this->_set_ushort($head, 50, $indexToLocFormat); + + if (_RECALC_PROFILE) { + $head = $this->_set_short($head, 36, $xMinT); // for all glyph bounding boxes + $head = $this->_set_short($head, 38, $yMinT); // for all glyph bounding boxes + $head = $this->_set_short($head, 40, $xMaxT); // for all glyph bounding boxes + $head = $this->_set_short($head, 42, $yMaxT); // for all glyph bounding boxes + $head[17] = chr($head[17] & ~(1 << 4)); // Unset Bit 4 (as hdmx/LTSH tables not included) + } + + $this->add('head', $head); + + // hhea - Horizontal Header + $hhea = $this->get_table('hhea'); + $hhea = $this->_set_ushort($hhea, 34, $numberOfHMetrics); + if (_RECALC_PROFILE) { + $hhea = $this->_set_ushort($hhea, 10, $advanceWidthMax); + $hhea = $this->_set_short($hhea, 12, $minLeftSideBearing); + $hhea = $this->_set_short($hhea, 14, $minRightSideBearing); + $hhea = $this->_set_short($hhea, 16, $xMaxExtent); + } + $this->add('hhea', $hhea); + + // maxp - Maximum Profile + $maxp = $this->get_table('maxp'); + $maxp = $this->_set_ushort($maxp, 4, $numGlyphs); + if (_RECALC_PROFILE) { + $maxp = $this->_set_ushort($maxp, 6, $maxPoints); // points in non-compound glyph + $maxp = $this->_set_ushort($maxp, 8, $maxContours); // contours in non-compound glyph + $maxp = $this->_set_ushort($maxp, 10, $maxComponentPoints); // points in compound glyph + $maxp = $this->_set_ushort($maxp, 12, $maxComponentContours); // contours in compound glyph + $maxp = $this->_set_ushort($maxp, 28, $maxComponentElements); // number of glyphs referenced at top level + $maxp = $this->_set_ushort($maxp, 30, $maxComponentDepth); // levels of recursion, set to 0 if font has only simple glyphs + } + $this->add('maxp', $maxp); + + // OS/2 - OS/2 + if (isset($this->tables['OS/2'])) { + $os2_offset = $this->seek_table("OS/2"); + if (_RECALC_PROFILE) { + $fsSelection = $this->get_ushort($os2_offset + 62); + $fsSelection = ($fsSelection & ~(1 << 6)); // 2-byte bit field containing information concerning the nature of the font patterns + // bit#0 = Italic; bit#5=Bold + // Match name table's font subfamily string + // Clear bit#6 used for 'Regular' and optional + } + + // NB Currently this method never subsets characters above BMP + // Could set nonBMP bit according to $this->maxUni + $nonBMP = $this->get_ushort($os2_offset + 46); + $nonBMP = ($nonBMP & ~(1 << 9)); // Unset Bit 57 (indicates non-BMP) - for interactive forms + + $os2 = $this->get_table('OS/2'); + if (_RECALC_PROFILE) { + $os2 = $this->_set_ushort($os2, 62, $fsSelection); + $os2 = $this->_set_ushort($os2, 66, $fsLastCharIndex); + $os2 = $this->_set_ushort($os2, 42, 0x0000); // ulCharRange (ulUnicodeRange) bits 24-31 | 16-23 + $os2 = $this->_set_ushort($os2, 44, 0x0000); // ulCharRange (Unicode ranges) bits 8-15 | 0-7 + $os2 = $this->_set_ushort($os2, 46, $nonBMP); // ulCharRange (Unicode ranges) bits 56-63 | 48-55 + $os2 = $this->_set_ushort($os2, 48, 0x0000); // ulCharRange (Unicode ranges) bits 40-47 | 32-39 + $os2 = $this->_set_ushort($os2, 50, 0x0000); // ulCharRange (Unicode ranges) bits 88-95 | 80-87 + $os2 = $this->_set_ushort($os2, 52, 0x0000); // ulCharRange (Unicode ranges) bits 72-79 | 64-71 + $os2 = $this->_set_ushort($os2, 54, 0x0000); // ulCharRange (Unicode ranges) bits 120-127 | 112-119 + $os2 = $this->_set_ushort($os2, 56, 0x0000); // ulCharRange (Unicode ranges) bits 104-111 | 96-103 + } + $os2 = $this->_set_ushort($os2, 46, $nonBMP); // Unset Bit 57 (indicates non-BMP) - for interactive forms + + $this->add('OS/2', $os2); + } + + fclose($this->fh); + + // Put the TTF file together + $stm = ''; + $this->endTTFile($stm); + + return $stm; + } + + function makeSubsetSIP($file, &$subset, $TTCfontID = 0, $debug = false, $useOTL = 0) + { + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file "%s"', $file)); + } + + $this->filename = $file; + $this->_pos = 0; + $this->useOTL = $useOTL; // mPDF 5.7.1 + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->ascent = 0; + $this->descent = 0; + $this->strikeoutSize = 0; + $this->strikeoutPosition = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->skip(4); + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000])) { + throw new \Mpdf\MpdfException("ERROR - Error parsing TrueType Collection: version=" . $version . " - " . $file); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + $this->readTableDirectory($debug); + + // head - Font header table + $this->seek_table('head'); + $this->skip(50); + $indexToLocFormat = $this->read_ushort(); + $glyphDataFormat = $this->read_ushort(); + + // hhea - Horizontal header table + $this->seek_table('hhea'); + $this->skip(32); + $metricDataFormat = $this->read_ushort(); + $orignHmetrics = $numberOfHMetrics = $this->read_ushort(); + + // maxp - Maximum profile table + $this->seek_table('maxp'); + $this->skip(4); + $numGlyphs = $this->read_ushort(); + + // cmap - Character to glyph index mapping table + $cmap_offset = $this->seek_table('cmap'); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + + if (($platformID == 3 && $encodingID == 10) || $platformID == 0) { // Microsoft, Unicode Format 12 table HKCS + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 12) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + $unicode_cmap_offset = $cmap_offset + $offset; + } + } + + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException(sprintf('Font "%s" does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)', $file)); + } + + // Format 12 CMAP does characters above Unicode BMP i.e. some HKCS characters U+20000 and above + if ($format == 12) { + $this->maxUniChar = 0; + $this->seek($unicode_cmap_offset + 4); + $length = $this->read_ulong(); + $limit = $unicode_cmap_offset + $length; + $this->skip(4); + + $nGroups = $this->read_ulong(); + + $glyphToChar = []; + $charToGlyph = []; + for ($i = 0; $i < $nGroups; $i++) { + $startCharCode = $this->read_ulong(); + $endCharCode = $this->read_ulong(); + $startGlyphCode = $this->read_ulong(); + $offset = 0; + for ($unichar = $startCharCode; $unichar <= $endCharCode; $unichar++) { + $glyph = $startGlyphCode + $offset; + $offset++; + // ZZZ98 + if ($unichar < 0x30000) { + $charToGlyph[$unichar] = $glyph; + $this->maxUniChar = max($unichar, $this->maxUniChar); + $glyphToChar[$glyph][] = $unichar; + } + } + } + } else { + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + } + + // Map Unmapped glyphs - from $numGlyphs + if ($useOTL) { + $bctr = 0xE000; + for ($gid = 1; $gid < $numGlyphs; $gid++) { + if (!isset($glyphToChar[$gid])) { + while (isset($charToGlyph[$bctr])) { + $bctr++; + } // Avoid overwriting a glyph already mapped in PUA + // ZZZ98 + if ($bctr > 0xF8FF && $bctr < 0x2CEB0) { + $bctr = 0x2CEB0; + while (isset($charToGlyph[$bctr])) { + $bctr++; + } + } + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $this->maxUniChar = max($bctr, $this->maxUniChar); + $bctr++; + } + } + } + + // hmtx - Horizontal metrics table + $scale = 1; // not used here + $this->getHMTX($numberOfHMetrics, $numGlyphs, $glyphToChar, $scale); + + // loca - Index to location + $this->getLOCA($indexToLocFormat, $numGlyphs); + + $glyphMap = [0 => 0]; + $glyphSet = [0 => 0]; + $codeToGlyph = []; + + // Set a substitute if ASCII characters do not have glyphs + if (isset($charToGlyph[0x3F])) { + $subs = $charToGlyph[0x3F]; + } else { // Question mark + $subs = $charToGlyph[32]; + } + + foreach ($subset as $code) { + if (isset($charToGlyph[$code])) { + $originalGlyphIdx = $charToGlyph[$code]; + } elseif ($code < 128) { + $originalGlyphIdx = $subs; + } else { + $originalGlyphIdx = 0; + } + if (!isset($glyphSet[$originalGlyphIdx])) { + $glyphSet[$originalGlyphIdx] = count($glyphMap); + $glyphMap[] = $originalGlyphIdx; + } + $codeToGlyph[$code] = $glyphSet[$originalGlyphIdx]; + } + + list($start, $dummy) = $this->get_table_pos('glyf'); + + $n = 0; + while ($n < count($glyphMap)) { + $originalGlyphIdx = $glyphMap[$n]; + $glyphPos = $this->glyphPos[$originalGlyphIdx]; + $glyphLen = $this->glyphPos[$originalGlyphIdx + 1] - $glyphPos; + ++$n; + if (!$glyphLen) { + continue; + } + $this->seek($start + $glyphPos); + $numberOfContours = $this->read_short(); + if ($numberOfContours < 0) { + $this->skip(8); + $flags = GlyphOperator::MORE; + while ($flags & GlyphOperator::MORE) { + $flags = $this->read_ushort(); + $glyphIdx = $this->read_ushort(); + if (!isset($glyphSet[$glyphIdx])) { + $glyphSet[$glyphIdx] = count($glyphMap); + $glyphMap[] = $glyphIdx; + } + if ($flags & GlyphOperator::WORDS) { + $this->skip(4); + } else { + $this->skip(2); + } + if ($flags & GlyphOperator::SCALE) { + $this->skip(2); + } elseif ($flags & GlyphOperator::XYSCALE) { + $this->skip(4); + } elseif ($flags & GlyphOperator::TWOBYTWO) { + $this->skip(8); + } + } + } + } + + $numGlyphs = $n = count($glyphMap); + $numberOfHMetrics = $n; + + // MS spec says that "Platform and encoding ID's in the name table should be consistent with those in the cmap table. + // If they are not, the font will not load in Windows" + // Doesn't seem to be a problem? + // Needs to have a name entry in 3,0 (e.g. symbol) - original font will be 3,1 (i.e. Unicode) + $name = $this->get_table('name'); + $name_offset = $this->seek_table("name"); + $format = $this->read_ushort(); + $numRecords = $this->read_ushort(); + $string_data_offset = $name_offset + $this->read_ushort(); + for ($i = 0; $i < $numRecords; $i++) { + $platformId = $this->read_ushort(); + $encodingId = $this->read_ushort(); + if ($platformId == 3 && $encodingId == 1) { + $pos = 6 + ($i * 12) + 2; + $name = $this->_set_ushort($name, $pos, 0x00); // Change encoding to 3,0 rather than 3,1 + } + $this->skip(8); + } + $this->add('name', $name); + + // OS/2 + if (isset($this->tables['OS/2'])) { + $os2 = $this->get_table('OS/2'); + $os2 = $this->_set_ushort($os2, 42, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 44, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 46, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 48, 0x00); // ulCharRange (Unicode ranges) + + $os2 = $this->_set_ushort($os2, 50, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 52, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 54, 0x00); // ulCharRange (Unicode ranges) + $os2 = $this->_set_ushort($os2, 56, 0x00); // ulCharRange (Unicode ranges) + // Set Symbol character only in ulCodePageRange + $os2 = $this->_set_ushort($os2, 78, 0x8000); // ulCodePageRange = Bit #31 Symbol **** 78 = Bit 16-31 + $os2 = $this->_set_ushort($os2, 80, 0x0000); // ulCodePageRange = Bit #31 Symbol **** 80 = Bit 0-15 + $os2 = $this->_set_ushort($os2, 82, 0x0000); // ulCodePageRange = Bit #32- Symbol **** 82 = Bits 48-63 + $os2 = $this->_set_ushort($os2, 84, 0x0000); // ulCodePageRange = Bit #32- Symbol **** 84 = Bits 32-47 + + $os2 = $this->_set_ushort($os2, 64, 0x01); // FirstCharIndex + $os2 = $this->_set_ushort($os2, 66, count($subset)); // LastCharIndex + // Set PANOSE first bit to 5 for Symbol + $os2 = $this->splice($os2, 32, chr(5) . chr(0) . chr(1) . chr(0) . chr(1) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0)); + $this->add('OS/2', $os2); + } + + //tables copied from the original + $tags = ['cvt ', 'fpgm', 'prep', 'gasp']; + foreach ($tags as $tag) { // 1.02 + if (isset($this->tables[$tag])) { + $this->add($tag, $this->get_table($tag)); + } + } + + // post - PostScript + if (isset($this->tables['post'])) { + $opost = $this->get_table('post'); + $post = "\x00\x03\x00\x00" . substr($opost, 4, 12) . "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + } + $this->add('post', $post); + + // hhea - Horizontal Header + $hhea = $this->get_table('hhea'); + $hhea = $this->_set_ushort($hhea, 34, $numberOfHMetrics); + $this->add('hhea', $hhea); + + // maxp - Maximum Profile + $maxp = $this->get_table('maxp'); + $maxp = $this->_set_ushort($maxp, 4, $numGlyphs); + $this->add('maxp', $maxp); + + // CMap table Formats [1,0,]6 and [3,0,]4 + // Sort CID2GID map into segments of contiguous codes + $rangeid = 0; + $range = []; + $prevcid = -2; + $prevglidx = -1; + + // for each character + foreach ($subset as $cid => $code) { + $glidx = $codeToGlyph[$code]; + if ($cid == ($prevcid + 1) && $glidx == ($prevglidx + 1)) { + $range[$rangeid][] = $glidx; + } else { + // new range + $rangeid = $cid; + $range[$rangeid] = []; + $range[$rangeid][] = $glidx; + } + $prevcid = $cid; + $prevglidx = $glidx; + } + + // cmap - Character to glyph mapping + $segCount = count($range) + 1; // + 1 Last segment has missing character 0xFFFF + $searchRange = 1; + $entrySelector = 0; + + while ($searchRange * 2 <= $segCount) { + $searchRange = $searchRange * 2; + $entrySelector = $entrySelector + 1; + } + + $searchRange = $searchRange * 2; + $rangeShift = $segCount * 2 - $searchRange; + $length = 16 + (8 * $segCount) + ($numGlyphs + 1); + $cmap = [ + 4, $length, 0, // Format 4 Mapping subtable: format, length, language + $segCount * 2, + $searchRange, + $entrySelector, + $rangeShift, + ]; + + // endCode(s) + foreach ($range as $start => $subrange) { + $endCode = $start + (count($subrange) - 1); + $cmap[] = $endCode; // endCode(s) + } + $cmap[] = 0xFFFF; // endCode of last Segment + $cmap[] = 0; // reservedPad + + // startCode(s) + foreach ($range as $start => $subrange) { + $cmap[] = $start; // startCode(s) + } + $cmap[] = 0xFFFF; // startCode of last Segment + + // idDelta(s) + foreach ($range as $start => $subrange) { + $idDelta = -($start - $subrange[0]); + $n += count($subrange); + $cmap[] = $idDelta; // idDelta(s) + } + $cmap[] = 1; // idDelta of last Segment + + // idRangeOffset(s) + foreach ($range as $subrange) { + $cmap[] = 0; // idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 + } + + $cmap[] = 0; // idRangeOffset of last Segment + foreach ($range as $subrange) { + foreach ($subrange as $glidx) { + $cmap[] = $glidx; + } + } + + $cmap[] = 0; // Mapping for last character + $cmapstr4 = ''; + foreach ($cmap as $cm) { + $cmapstr4 .= pack("n", $cm); + } + + // cmap - Character to glyph mapping + $entryCount = count($subset); + $length = 10 + $entryCount * 2; + + $off = 20 + $length; + $hoff = $off >> 16; + $loff = $off & 0xFFFF; + + $cmap = [ + 0, 2, // Index : version, number of subtables + 1, 0, // Subtable : platform, encoding + 0, 20, // offset (hi,lo) + 3, 0, // Subtable : platform, encoding // See note above for 'name' + $hoff, $loff, // offset (hi,lo) + 6, $length, // Format 6 Mapping table: format, length + 0, 1, // language, First char code + $entryCount, + ]; + + $cmapstr = ''; + foreach ($subset as $code) { + $cmap[] = $codeToGlyph[$code]; + } + + foreach ($cmap as $cm) { + $cmapstr .= pack("n", $cm); + } + + $cmapstr .= $cmapstr4; + $this->add('cmap', $cmapstr); + + // hmtx - Horizontal Metrics + $hmtxstr = ''; + for ($n = 0; $n < $numGlyphs; $n++) { + $originalGlyphIdx = $glyphMap[$n]; + $hm = $this->getHMetric($orignHmetrics, $originalGlyphIdx); + $hmtxstr .= $hm; + } + $this->add('hmtx', $hmtxstr); + + // glyf - Glyph data + list($glyfOffset, $glyfLength) = $this->get_table_pos('glyf'); + if ($glyfLength < $this->maxStrLenRead) { + $glyphData = $this->get_table('glyf'); + } + + $offsets = []; + $glyf = ''; + $pos = 0; + for ($n = 0; $n < $numGlyphs; $n++) { + + $offsets[] = $pos; + $originalGlyphIdx = $glyphMap[$n]; + $glyphPos = $this->glyphPos[$originalGlyphIdx]; + $glyphLen = $this->glyphPos[$originalGlyphIdx + 1] - $glyphPos; + + if ($glyfLength < $this->maxStrLenRead) { + $data = substr($glyphData, $glyphPos, $glyphLen); + } else { + if ($glyphLen > 0) { + $data = $this->get_chunk($glyfOffset + $glyphPos, $glyphLen); + } else { + $data = ''; + } + } + + if ($glyphLen > 0) { + $up = unpack('n', substr($data, 0, 2)); + } + + if ($glyphLen > 2 && ($up[1] & (1 << 15))) { + + $pos_in_glyph = 10; + $flags = GlyphOperator::MORE; + + while ($flags & GlyphOperator::MORE) { + $up = unpack('n', substr($data, $pos_in_glyph, 2)); + $flags = $up[1]; + $up = unpack('n', substr($data, $pos_in_glyph + 2, 2)); + $glyphIdx = $up[1]; + $data = $this->_set_ushort($data, $pos_in_glyph + 2, $glyphSet[$glyphIdx]); + $pos_in_glyph += 4; + + if ($flags & GlyphOperator::WORDS) { + $pos_in_glyph += 4; + } else { + $pos_in_glyph += 2; + } + + if ($flags & GlyphOperator::SCALE) { + $pos_in_glyph += 2; + } elseif ($flags & GlyphOperator::XYSCALE) { + $pos_in_glyph += 4; + } elseif ($flags & GlyphOperator::TWOBYTWO) { + $pos_in_glyph += 8; + } + } + } + + $glyf .= $data; + $pos += $glyphLen; + + if ($pos % 4 != 0) { + $padding = 4 - ($pos % 4); + $glyf .= str_repeat("\0", $padding); + $pos += $padding; + } + } + + $offsets[] = $pos; + $this->add('glyf', $glyf); + + // loca - Index to location + $locastr = ''; + if ((($pos + 1) >> 1) > 0xFFFF) { + $indexToLocFormat = 1; // long format + foreach ($offsets as $offset) { + $locastr .= pack("N", $offset); + } + } else { + $indexToLocFormat = 0; // short format + foreach ($offsets as $offset) { + $locastr .= pack("n", ($offset / 2)); + } + } + + $this->add('loca', $locastr); + + // head - Font header + $head = $this->get_table('head'); + $head = $this->_set_ushort($head, 50, $indexToLocFormat); + $this->add('head', $head); + + fclose($this->fh); + + $stm = ''; + $this->endTTFile($stm); + + return $stm; + } + + function getGlyphData($originalGlyphIdx, &$maxdepth, &$depth, &$points, &$contours) + { + $depth++; + $maxdepth = max($maxdepth, $depth); + + if (count($this->glyphdata[$originalGlyphIdx]['compGlyphs'])) { + foreach ($this->glyphdata[$originalGlyphIdx]['compGlyphs'] as $glyphIdx) { + $this->getGlyphData($glyphIdx, $maxdepth, $depth, $points, $contours); + } + } elseif (($this->glyphdata[$originalGlyphIdx]['nContours'] > 0) && $depth > 0) { // simple + $contours += $this->glyphdata[$originalGlyphIdx]['nContours']; + $points += $this->glyphdata[$originalGlyphIdx]['nPoints']; + } + + $depth--; + } + + function getGlyphs($originalGlyphIdx, &$start, &$glyphSet, &$subsetglyphs) + { + $glyphPos = $this->glyphPos[$originalGlyphIdx]; + $glyphLen = $this->glyphPos[$originalGlyphIdx + 1] - $glyphPos; + + if (!$glyphLen) { + return; + } + + $this->seek($start + $glyphPos); + $numberOfContours = $this->read_short(); + + if ($numberOfContours < 0) { + $this->skip(8); + $flags = GlyphOperator::MORE; + while ($flags & GlyphOperator::MORE) { + $flags = $this->read_ushort(); + $glyphIdx = $this->read_ushort(); + if (!isset($glyphSet[$glyphIdx])) { + $glyphSet[$glyphIdx] = count($subsetglyphs); // old glyphID to new glyphID + $subsetglyphs[$glyphIdx] = true; + } + $savepos = ftell($this->fh); + $this->getGlyphs($glyphIdx, $start, $glyphSet, $subsetglyphs); + $this->seek($savepos); + if ($flags & GlyphOperator::WORDS) { + $this->skip(4); + } else { + $this->skip(2); + } + if ($flags & GlyphOperator::SCALE) { + $this->skip(2); + } elseif ($flags & GlyphOperator::XYSCALE) { + $this->skip(4); + } elseif ($flags & GlyphOperator::TWOBYTWO) { + $this->skip(8); + } + } + } + } + + function getHMTX($numberOfHMetrics, $numGlyphs, &$glyphToChar, $scale) + { + $start = $this->seek_table('hmtx'); + $aw = 0; + $this->charWidths = str_pad('', 256 * 256 * 2, "\x00"); + + if ($this->maxUniChar > 65536) { + $this->charWidths .= str_pad('', 256 * 256 * 2, "\x00"); + } // Plane 1 SMP + + if ($this->maxUniChar > 131072) { + $this->charWidths .= str_pad('', 256 * 256 * 2, "\x00"); + } // Plane 2 SMP + + $nCharWidths = 0; + if (($numberOfHMetrics * 4) < $this->maxStrLenRead) { + $data = $this->get_chunk($start, $numberOfHMetrics * 4); + $arr = unpack('n*', $data); + } else { + $this->seek($start); + } + + for ($glyph = 0; $glyph < $numberOfHMetrics; $glyph++) { + + if (($numberOfHMetrics * 4) < $this->maxStrLenRead) { + $aw = $arr[($glyph * 2) + 1]; + } else { + $aw = $this->read_ushort(); + $lsb = $this->read_ushort(); + } + if (isset($glyphToChar[$glyph]) || $glyph == 0) { + if ($aw >= (1 << 15)) { + $aw = 0; + } + + // 1.03 Some (arabic) fonts have -ve values for width + // although should be unsigned value - comes out as e.g. 65108 (intended -50) + if ($glyph === 0) { + $this->defaultWidth = $scale * $aw; + continue; + } + + foreach ($glyphToChar[$glyph] as $char) { + if ($char != 0 && $char != 65535) { + $w = (int) round($scale * $aw); + if ($w === 0) { + $w = 65535; + } + if ($char < 196608) { + $this->charWidths[$char * 2] = chr($w >> 8); + $this->charWidths[$char * 2 + 1] = chr($w & 0xFF); + $nCharWidths++; + } + } + } + } + } + + $data = $this->get_chunk(($start + $numberOfHMetrics * 4), ($numGlyphs * 2)); + $arr = unpack("n*", $data); + $diff = $numGlyphs - $numberOfHMetrics; + $w = (int) round($scale * $aw); + if ($w === 0) { + $w = 65535; + } + for ($pos = 0; $pos < $diff; $pos++) { + $glyph = $pos + $numberOfHMetrics; + if (isset($glyphToChar[$glyph])) { + foreach ($glyphToChar[$glyph] as $char) { + if ($char != 0 && $char != 65535) { + if ($char < 196608) { + $this->charWidths[$char * 2] = chr($w >> 8); + $this->charWidths[$char * 2 + 1] = chr($w & 0xFF); + $nCharWidths++; + } + } + } + } + } + + // NB 65535 is a set width of 0 + // First bytes define number of chars in font + $this->charWidths[0] = chr($nCharWidths >> 8); + $this->charWidths[1] = chr($nCharWidths & 0xFF); + } + + function getHMetric($numberOfHMetrics, $gid) + { + $start = $this->seek_table("hmtx"); + if ($gid < $numberOfHMetrics) { + $this->seek($start + ($gid * 4)); + $hm = fread($this->fh, 4); + } else { + $this->seek($start + (($numberOfHMetrics - 1) * 4)); + $hm = fread($this->fh, 2); + $this->seek($start + ($numberOfHMetrics * 2) + ($gid * 2)); + $hm .= fread($this->fh, 2); + } + + return $hm; + } + + function getLOCA($indexToLocFormat, $numGlyphs) + { + $start = $this->seek_table('loca'); + $this->glyphPos = []; + if ($indexToLocFormat == 0) { + $data = $this->get_chunk($start, ($numGlyphs * 2) + 2); + $arr = unpack("n*", $data); + for ($n = 0; $n <= $numGlyphs; $n++) { + $this->glyphPos[] = ($arr[$n + 1] * 2); + } + } elseif ($indexToLocFormat == 1) { + $data = $this->get_chunk($start, ($numGlyphs * 4) + 4); + $arr = unpack("N*", $data); + for ($n = 0; $n <= $numGlyphs; $n++) { + $this->glyphPos[] = ($arr[$n + 1]); + } + } else { + throw new \Mpdf\MpdfException('Unknown location table format ' . $indexToLocFormat); + } + } + + /** + * CMAP Format 4 + */ + function getCMAP4($unicode_cmap_offset, &$glyphToChar, &$charToGlyph) + { + $this->maxUniChar = 0; + $this->seek($unicode_cmap_offset + 2); + $length = $this->read_ushort(); + $limit = $unicode_cmap_offset + $length; + $this->skip(2); + + $segCount = $this->read_ushort() / 2; + $this->skip(6); + $endCount = []; + + for ($i = 0; $i < $segCount; $i++) { + $endCount[] = $this->read_ushort(); + } + + $this->skip(2); + $startCount = []; + + for ($i = 0; $i < $segCount; $i++) { + $startCount[] = $this->read_ushort(); + } + + $idDelta = []; + + for ($i = 0; $i < $segCount; $i++) { + $idDelta[] = $this->read_short(); + } // ???? was unsigned short + + $idRangeOffset_start = $this->_pos; + $idRangeOffset = []; + + for ($i = 0; $i < $segCount; $i++) { + $idRangeOffset[] = $this->read_ushort(); + } + + for ($n = 0; $n < $segCount; $n++) { + $endpoint = ($endCount[$n] + 1); + for ($unichar = $startCount[$n]; $unichar < $endpoint; $unichar++) { + if ($idRangeOffset[$n] == 0) { + $glyph = ($unichar + $idDelta[$n]) & 0xFFFF; + } else { + $offset = ($unichar - $startCount[$n]) * 2 + $idRangeOffset[$n]; + $offset = $idRangeOffset_start + 2 * $n + $offset; + if ($offset >= $limit) { + $glyph = 0; + } else { + $glyph = $this->get_ushort($offset); + if ($glyph != 0) { + $glyph = ($glyph + $idDelta[$n]) & 0xFFFF; + } + } + } + $charToGlyph[$unichar] = $glyph; + if ($unichar < 196608) { + $this->maxUniChar = max($unichar, $this->maxUniChar); + } + $glyphToChar[$glyph][] = $unichar; + } + } + } + + function endTTFile(&$stm) + { + $stm = ''; + $numTables = count($this->otables); + $searchRange = 1; + $entrySelector = 0; + while ($searchRange * 2 <= $numTables) { + $searchRange *= 2; + $entrySelector += 1; + } + $searchRange *= 16; + $rangeShift = $numTables * 16 - $searchRange; + + // Header + if (_TTF_MAC_HEADER) { + $stm .= pack('Nnnnn', 0x74727565, $numTables, $searchRange, $entrySelector, $rangeShift); // Mac + } else { + $stm .= pack('Nnnnn', 0x00010000, $numTables, $searchRange, $entrySelector, $rangeShift); // Windows + } + + // Table directory + $tables = $this->otables; + ksort($tables); + $offset = 12 + $numTables * 16; + foreach ($tables as $tag => $data) { + if ($tag === 'head') { + $head_start = $offset; + } + $stm .= $tag; + $checksum = $this->calcChecksum($data); + $stm .= pack('nn', $checksum[0], $checksum[1]); + $stm .= pack('NN', $offset, strlen($data)); + $paddedLength = (strlen($data) + 3) & ~3; + $offset += $paddedLength; + } + + // Table data + foreach ($tables as $tag => $data) { + $data .= "\0\0\0"; + $stm .= substr($data, 0, (strlen($data) & ~3)); + } + + $checksum = $this->calcChecksum($stm); + $checksum = $this->sub32([0xB1B0, 0xAFBA], $checksum); + $chk = pack("nn", $checksum[0], $checksum[1]); + $stm = $this->splice($stm, ($head_start + 8), $chk); + + return $stm; + } + + function repackageTTF($file, $TTCfontID = 0, $debug = false, $useOTL = false) + { + $this->useOTL = $useOTL; + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + + if (!$this->fh) { + throw new \Mpdf\MpdfException(sprintf('Unable to open file "%s"', $file)); + } + + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->ascent = 0; + $this->descent = 0; + $this->strikeoutSize = 0; + $this->strikeoutPosition = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->skip(4); + $this->maxUni = 0; + + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000], true)) { + throw new \Mpdf\MpdfException(sprintf('Error parsing TrueType Collection: version=%s - %s', $version, $file)); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + } + + $this->readTableDirectory($debug); + $tags = ['OS/2', 'glyf', 'head', 'hhea', 'hmtx', 'loca', 'maxp', 'name', 'post', 'cvt ', 'fpgm', 'gasp', 'prep']; + + foreach ($tags as $tag) { + if (isset($this->tables[$tag])) { + $this->add($tag, $this->get_table($tag)); + } + } + + if ($useOTL) { + + // maxp - Maximum profile table + $this->seek_table('maxp'); + $this->skip(4); + $numGlyphs = $this->read_ushort(); + + // cmap - Character to glyph index mapping table + $cmap_offset = $this->seek_table('cmap'); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException(sprintf('Font "%s" does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)', $this->filename)); + } + + $glyphToChar = []; + $charToGlyph = []; + $this->getCMAP4($unicode_cmap_offset, $glyphToChar, $charToGlyph); + + // Map Unmapped glyphs - from $numGlyphs + $bctr = 0xE000; + for ($gid = 1; $gid < $numGlyphs; $gid++) { + if (!isset($glyphToChar[$gid])) { + while (isset($charToGlyph[$bctr])) { + $bctr++; + } // Avoid overwriting a glyph already mapped in PUA (6,400) + if ($bctr > 0xF8FF) { + throw new \Mpdf\MpdfException("Problem. Trying to repackage TF file; not enough space for unmapped glyphs"); + } + $glyphToChar[$gid][] = $bctr; + $charToGlyph[$bctr] = $gid; + $bctr++; + } + } + + // Sort CID2GID map into segments of contiguous codes + unset($charToGlyph[65535]); + unset($charToGlyph[0]); + + ksort($charToGlyph); + $rangeid = 0; + $range = []; + $prevcid = -2; + $prevglidx = -1; + + // for each character + foreach ($charToGlyph as $cid => $glidx) { + if ($cid == ($prevcid + 1) && $glidx == ($prevglidx + 1)) { + $range[$rangeid][] = $glidx; + } else { + // new range + $rangeid = $cid; + $range[$rangeid] = []; + $range[$rangeid][] = $glidx; + } + $prevcid = $cid; + $prevglidx = $glidx; + } + + // CMap table + // cmap - Character to glyph mapping + $segCount = count($range) + 1; // + 1 Last segment has missing character 0xFFFF + $searchRange = 1; + $entrySelector = 0; + + while ($searchRange * 2 <= $segCount) { + $searchRange *= 2; + ++$entrySelector; + } + + $searchRange *= 2; + $rangeShift = $segCount * 2 - $searchRange; + $length = 16 + (8 * $segCount) + ($numGlyphs + 1); + $cmap = [0, 3, // Index : version, number of encoding subtables + 0, 0, // Encoding Subtable : platform (UNI=0), encoding 0 + 0, 28, // Encoding Subtable : offset (hi,lo) + 0, 3, // Encoding Subtable : platform (UNI=0), encoding 3 + 0, 28, // Encoding Subtable : offset (hi,lo) + 3, 1, // Encoding Subtable : platform (MS=3), encoding 1 + 0, 28, // Encoding Subtable : offset (hi,lo) + 4, $length, 0, // Format 4 Mapping subtable: format, length, language + $segCount * 2, + $searchRange, + $entrySelector, + $rangeShift]; + + // endCode(s) + foreach ($range as $start => $subrange) { + $endCode = $start + (count($subrange) - 1); + $cmap[] = $endCode; // endCode(s) + } + $cmap[] = 0xFFFF; // endCode of last Segment + $cmap[] = 0; // reservedPad + + // startCode(s) + foreach ($range as $start => $subrange) { + $cmap[] = $start; // startCode(s) + } + $cmap[] = 0xFFFF; // startCode of last Segment + + // idDelta(s) + foreach ($range as $start => $subrange) { + $idDelta = -($start - $subrange[0]); + $cmap[] = $idDelta; // idDelta(s) + } + + $cmap[] = 1; // idDelta of last Segment + // idRangeOffset(s) + foreach ($range as $subrange) { + $cmap[] = 0; // idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 + } + + $cmap[] = 0; // idRangeOffset of last Segment + foreach ($range as $subrange) { + foreach ($subrange as $glidx) { + $cmap[] = $glidx; + } + } + $cmap[] = 0; // Mapping for last character + $cmapstr = ''; + foreach ($cmap as $cm) { + $cmapstr .= pack('n', $cm); + } + + $this->add('cmap', $cmapstr); + } else { + $this->add('cmap', $this->get_table('cmap')); + } + + fclose($this->fh); + $stm = ''; + $this->endTTFile($stm); + + return $stm; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFileAnalysis.php b/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFileAnalysis.php new file mode 100644 index 0000000..2851ea0 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/TTFontFileAnalysis.php @@ -0,0 +1,454 @@ +<?php + +namespace Mpdf; + +class TTFontFileAnalysis extends TTFontFile +{ + + // Used to get font information from files in directory + function extractCoreInfo($file, $TTCfontID = 0) + { + $this->filename = $file; + $this->fh = fopen($file, 'rb'); + if (!$this->fh) { + throw new \Mpdf\MpdfException('ERROR - Can\'t open file ' . $file); + } + $this->_pos = 0; + $this->charWidths = ''; + $this->glyphPos = []; + $this->charToGlyph = []; + $this->tables = []; + $this->otables = []; + $this->ascent = 0; + $this->descent = 0; + $this->numTTCFonts = 0; + $this->TTCFonts = []; + $this->version = $version = $this->read_ulong(); + $this->panose = []; // mPDF 5.0 + + if ($version == 0x4F54544F) { + throw new \Mpdf\MpdfException('ERROR - NOT ADDED as Postscript outlines are not supported - ' . $file); + } + + if ($version == 0x74746366) { + if ($TTCfontID > 0) { + $this->version = $version = $this->read_ulong(); // TTC Header version now + if (!in_array($version, [0x00010000, 0x00020000])) { + throw new \Mpdf\MpdfException("ERROR - NOT ADDED as Error parsing TrueType Collection: version=" . $version . " - " . $file); + } + } else { + throw new \Mpdf\MpdfException("ERROR - Error parsing TrueType Collection - " . $file); + } + $this->numTTCFonts = $this->read_ulong(); + for ($i = 1; $i <= $this->numTTCFonts; $i++) { + $this->TTCFonts[$i]['offset'] = $this->read_ulong(); + } + $this->seek($this->TTCFonts[$TTCfontID]['offset']); + $this->version = $version = $this->read_ulong(); // TTFont version again now + $this->readTableDirectory(false); + } else { + if (!in_array($version, [0x00010000, 0x74727565])) { + throw new \Mpdf\MpdfException("ERROR - NOT ADDED as Not a TrueType font: version=" . $version . " - " . $file); + } + $this->readTableDirectory(false); + } + + /* Included for testing... + $cmap_offset = $this->seek_table("cmap"); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i=0;$i<$cmapTableCount;$i++) { + $x[$i]['platformId'] = $this->read_ushort(); + $x[$i]['encodingId'] = $this->read_ushort(); + $x[$i]['offset'] = $this->read_ulong(); + $save_pos = $this->_pos; + $x[$i]['format'] = $this->get_ushort($cmap_offset + $x[$i]['offset'] ); + $this->seek($save_pos ); + } + print_r($x); exit; + */ + /////////////////////////////////// + // name - Naming table + /////////////////////////////////// + + /* Test purposes - displays table of names + $name_offset = $this->seek_table("name"); + $format = $this->read_ushort(); + if ($format != 0 && $format != 1) // mPDF 5.3.73 + die("Unknown name table format ".$format); + $numRecords = $this->read_ushort(); + $string_data_offset = $name_offset + $this->read_ushort(); + for ($i=0;$i<$numRecords; $i++) { + $x[$i]['platformId'] = $this->read_ushort(); + $x[$i]['encodingId'] = $this->read_ushort(); + $x[$i]['languageId'] = $this->read_ushort(); + $x[$i]['nameId'] = $this->read_ushort(); + $x[$i]['length'] = $this->read_ushort(); + $x[$i]['offset'] = $this->read_ushort(); + + $N = ''; + if ($x[$i]['platformId'] == 1 && $x[$i]['encodingId'] == 0 && $x[$i]['languageId'] == 0) { // Roman + $opos = $this->_pos; + $N = $this->get_chunk($string_data_offset + $x[$i]['offset'] , $x[$i]['length'] ); + $this->_pos = $opos; + $this->seek($opos); + } + else { // Unicode + $opos = $this->_pos; + $this->seek($string_data_offset + $x[$i]['offset'] ); + $length = $x[$i]['length'] ; + if ($length % 2 != 0) + $length -= 1; + // die("PostScript name is UTF-16BE string of odd length"); + $length /= 2; + $N = ''; + while ($length > 0) { + $char = $this->read_ushort(); + $N .= (chr($char)); + $length -= 1; + } + $this->_pos = $opos; + $this->seek($opos); + } + $x[$i]['names'][$nameId] = $N; + } + print_r($x); exit; + */ + + $name_offset = $this->seek_table("name"); + $format = $this->read_ushort(); + if ($format != 0 && $format != 1) { // mPDF 5.3.73 + throw new \Mpdf\MpdfException("ERROR - NOT ADDED as Unknown name table format " . $format . " - " . $file); + } + $numRecords = $this->read_ushort(); + $string_data_offset = $name_offset + $this->read_ushort(); + $names = [1 => '', 2 => '', 3 => '', 4 => '', 6 => '']; + $K = array_keys($names); + $nameCount = count($names); + for ($i = 0; $i < $numRecords; $i++) { + $platformId = $this->read_ushort(); + $encodingId = $this->read_ushort(); + $languageId = $this->read_ushort(); + $nameId = $this->read_ushort(); + $length = $this->read_ushort(); + $offset = $this->read_ushort(); + if (!in_array($nameId, $K)) { + continue; + } + $N = ''; + if ($platformId == 3 && $encodingId == 1 && $languageId == 0x409) { // Microsoft, Unicode, US English, PS Name + $opos = $this->_pos; + $this->seek($string_data_offset + $offset); + if ($length % 2 != 0) { + $length += 1; + } + $length /= 2; + $N = ''; + while ($length > 0) { + $char = $this->read_ushort(); + $N .= (chr($char)); + $length -= 1; + } + $this->_pos = $opos; + $this->seek($opos); + } elseif ($platformId == 1 && $encodingId == 0 && $languageId == 0) { // Macintosh, Roman, English, PS Name + $opos = $this->_pos; + $N = $this->get_chunk($string_data_offset + $offset, $length); + $this->_pos = $opos; + $this->seek($opos); + } + if ($N && $names[$nameId] == '') { + $names[$nameId] = $N; + $nameCount -= 1; + if ($nameCount == 0) { + break; + } + } + } + if ($names[6]) { + $psName = preg_replace('/ /', '-', $names[6]); + } elseif ($names[4]) { + $psName = preg_replace('/ /', '-', $names[4]); + } elseif ($names[1]) { + $psName = preg_replace('/ /', '-', $names[1]); + } else { + $psName = ''; + } + if (!$names[1] && !$psName) { + throw new \Mpdf\MpdfException("ERROR - NOT ADDED as Could not find valid font name - " . $file); + } + $this->name = $psName; + if ($names[1]) { + $this->familyName = $names[1]; + } else { + $this->familyName = $psName; + } + if ($names[2]) { + $this->styleName = $names[2]; + } else { + $this->styleName = 'Regular'; + } + + /////////////////////////////////// + // head - Font header table + /////////////////////////////////// + $this->seek_table("head"); + $ver_maj = $this->read_ushort(); + $ver_min = $this->read_ushort(); + if ($ver_maj != 1) { + throw new \Mpdf\MpdfException('ERROR - NOT ADDED as Unknown head table version ' . $ver_maj . '.' . $ver_min . " - " . $file); + } + $this->fontRevision = $this->read_ushort() . $this->read_ushort(); + $this->skip(4); + $magic = $this->read_ulong(); + if ($magic != 0x5F0F3CF5) { + throw new \Mpdf\MpdfException('ERROR - NOT ADDED as Invalid head table magic ' . $magic . " - " . $file); + } + $this->skip(2); + $this->unitsPerEm = $unitsPerEm = $this->read_ushort(); + $scale = 1000 / $unitsPerEm; + $this->skip(24); + $macStyle = $this->read_short(); + $this->skip(4); + $indexLocFormat = $this->read_short(); + + /////////////////////////////////// + // OS/2 - OS/2 and Windows metrics table + /////////////////////////////////// + $sFamily = ''; + $panose = ''; + $fsSelection = ''; + if (isset($this->tables["OS/2"])) { + $this->seek_table("OS/2"); + $this->skip(30); + $sF = $this->read_short(); + $sFamily = ($sF >> 8); + $this->_pos += 10; //PANOSE = 10 byte length + $panose = fread($this->fh, 10); + $this->panose = []; + for ($p = 0; $p < strlen($panose); $p++) { + $this->panose[] = ord($panose[$p]); + } + $this->skip(20); + $fsSelection = $this->read_short(); + } + + /////////////////////////////////// + // post - PostScript table + /////////////////////////////////// + $this->seek_table("post"); + $this->skip(4); + $this->italicAngle = $this->read_short() + $this->read_ushort() / 65536.0; + $this->skip(4); + $isFixedPitch = $this->read_ulong(); + + + + /////////////////////////////////// + // cmap - Character to glyph index mapping table + /////////////////////////////////// + $cmap_offset = $this->seek_table("cmap"); + $this->skip(2); + $cmapTableCount = $this->read_ushort(); + $unicode_cmap_offset = 0; + for ($i = 0; $i < $cmapTableCount; $i++) { + $platformID = $this->read_ushort(); + $encodingID = $this->read_ushort(); + $offset = $this->read_ulong(); + $save_pos = $this->_pos; + if (($platformID == 3 && $encodingID == 1) || $platformID == 0) { // Microsoft, Unicode + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 4) { + if (!$unicode_cmap_offset) { + $unicode_cmap_offset = $cmap_offset + $offset; + } + } + } elseif ((($platformID == 3 && $encodingID == 10) || $platformID == 0)) { // Microsoft, Unicode Format 12 table HKCS + $format = $this->get_ushort($cmap_offset + $offset); + if ($format == 12) { + $unicode_cmap_offset = $cmap_offset + $offset; + break; + } + } + $this->seek($save_pos); + } + + if (!$unicode_cmap_offset) { + throw new \Mpdf\MpdfException('ERROR - Font (' . $this->filename . ') NOT ADDED as it is not Unicode encoded, and cannot be used by mPDF'); + } + + $rtl = false; + $indic = false; + $cjk = false; + $sip = false; + $smp = false; + $pua = false; + $puaag = false; + $glyphToChar = []; + $unAGlyphs = ''; + // Format 12 CMAP does characters above Unicode BMP i.e. some HKCS characters U+20000 and above + if ($format == 12) { + $this->seek($unicode_cmap_offset + 4); + $length = $this->read_ulong(); + $limit = $unicode_cmap_offset + $length; + $this->skip(4); + $nGroups = $this->read_ulong(); + for ($i = 0; $i < $nGroups; $i++) { + $startCharCode = $this->read_ulong(); + $endCharCode = $this->read_ulong(); + $startGlyphCode = $this->read_ulong(); + if (($endCharCode > 0x20000 && $endCharCode < 0x2A6DF) || ($endCharCode > 0x2F800 && $endCharCode < 0x2FA1F)) { + $sip = true; + } + if ($endCharCode > 0x10000 && $endCharCode < 0x1FFFF) { + $smp = true; + } + if (($endCharCode > 0x0590 && $endCharCode < 0x077F) || ($endCharCode > 0xFE70 && $endCharCode < 0xFEFF) || ($endCharCode > 0xFB50 && $endCharCode < 0xFDFF)) { + $rtl = true; + } + if ($endCharCode > 0x0900 && $endCharCode < 0x0DFF) { + $indic = true; + } + if ($endCharCode > 0xE000 && $endCharCode < 0xF8FF) { + $pua = true; + if ($endCharCode > 0xF500 && $endCharCode < 0xF7FF) { + $puaag = true; + } + } + if (($endCharCode > 0x2E80 && $endCharCode < 0x4DC0) || ($endCharCode > 0x4E00 && $endCharCode < 0xA4CF) || ($endCharCode > 0xAC00 && $endCharCode < 0xD7AF) || ($endCharCode > 0xF900 && $endCharCode < 0xFAFF) || ($endCharCode > 0xFE30 && $endCharCode < 0xFE4F)) { + $cjk = true; + } + + $offset = 0; + // Get each glyphToChar - only point if going to analyse un-mapped Arabic Glyphs + if (isset($this->tables['post'])) { + for ($unichar = $startCharCode; $unichar <= $endCharCode; $unichar++) { + $glyph = $startGlyphCode + $offset; + $offset++; + $glyphToChar[$glyph][] = $unichar; + } + } + } + } else { // Format 4 CMap + $this->seek($unicode_cmap_offset + 2); + $length = $this->read_ushort(); + $limit = $unicode_cmap_offset + $length; + $this->skip(2); + + $segCount = $this->read_ushort() / 2; + $this->skip(6); + $endCount = []; + for ($i = 0; $i < $segCount; $i++) { + $endCount[] = $this->read_ushort(); + } + $this->skip(2); + $startCount = []; + for ($i = 0; $i < $segCount; $i++) { + $startCount[] = $this->read_ushort(); + } + $idDelta = []; + for ($i = 0; $i < $segCount; $i++) { + $idDelta[] = $this->read_short(); + } + $idRangeOffset_start = $this->_pos; + $idRangeOffset = []; + for ($i = 0; $i < $segCount; $i++) { + $idRangeOffset[] = $this->read_ushort(); + } + + for ($n = 0; $n < $segCount; $n++) { + if (($endCount[$n] > 0x0590 && $endCount[$n] < 0x077F) || ($endCount[$n] > 0xFE70 && $endCount[$n] < 0xFEFF) || ($endCount[$n] > 0xFB50 && $endCount[$n] < 0xFDFF)) { + $rtl = true; + } + if ($endCount[$n] > 0x0900 && $endCount[$n] < 0x0DFF) { + $indic = true; + } + if (($endCount[$n] > 0x2E80 && $endCount[$n] < 0x4DC0) || ($endCount[$n] > 0x4E00 && $endCount[$n] < 0xA4CF) || ($endCount[$n] > 0xAC00 && $endCount[$n] < 0xD7AF) || ($endCount[$n] > 0xF900 && $endCount[$n] < 0xFAFF) || ($endCount[$n] > 0xFE30 && $endCount[$n] < 0xFE4F)) { + $cjk = true; + } + if ($endCount[$n] > 0xE000 && $endCount[$n] < 0xF8FF) { + $pua = true; + if ($endCount[$n] > 0xF500 && $endCount[$n] < 0xF7FF) { + $puaag = true; + } + } + // Get each glyphToChar - only point if going to analyse un-mapped Arabic Glyphs + if (isset($this->tables['post'])) { + $endpoint = ($endCount[$n] + 1); + for ($unichar = $startCount[$n]; $unichar < $endpoint; $unichar++) { + if ($idRangeOffset[$n] == 0) { + $glyph = ($unichar + $idDelta[$n]) & 0xFFFF; + } else { + $offset = ($unichar - $startCount[$n]) * 2 + $idRangeOffset[$n]; + $offset = $idRangeOffset_start + 2 * $n + $offset; + if ($offset >= $limit) { + $glyph = 0; + } else { + $glyph = $this->get_ushort($offset); + if ($glyph != 0) { + $glyph = ($glyph + $idDelta[$n]) & 0xFFFF; + } + } + } + $glyphToChar[$glyph][] = $unichar; + } + } + } + } + + + $bold = false; + $italic = false; + $ftype = ''; + if ($macStyle & (1 << 0)) { + $bold = true; + } // bit 0 bold + elseif ($fsSelection & (1 << 5)) { + $bold = true; + } // 5 BOLD Characters are emboldened + + if ($macStyle & (1 << 1)) { + $italic = true; + } // bit 1 italic + elseif ($fsSelection & (1 << 0)) { + $italic = true; + } // 0 ITALIC Font contains Italic characters, otherwise they are upright + elseif ($this->italicAngle <> 0) { + $italic = true; + } + + if ($isFixedPitch) { + $ftype = 'mono'; + } elseif ($sFamily > 0 && $sFamily < 8) { + $ftype = 'serif'; + } elseif ($sFamily == 8) { + $ftype = 'sans'; + } elseif ($sFamily == 10) { + $ftype = 'cursive'; + } + // Use PANOSE + if ($panose) { + $bFamilyType = ord($panose[0]); + if ($bFamilyType == 2) { + $bSerifStyle = ord($panose[1]); + if (!$ftype) { + if ($bSerifStyle > 1 && $bSerifStyle < 11) { + $ftype = 'serif'; + } elseif ($bSerifStyle > 10) { + $ftype = 'sans'; + } + } + $bProportion = ord($panose[3]); + if ($bProportion == 9 || $bProportion == 1) { + $ftype = 'mono'; + } // ==1 i.e. No Fit needed for OCR-a and -b + } elseif ($bFamilyType == 3) { + $ftype = 'cursive'; + } + } + + fclose($this->fh); + return [$this->familyName, $bold, $italic, $ftype, $TTCfontID, $rtl, $indic, $cjk, $sip, $smp, $puaag, $pua, $unAGlyphs]; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/TableOfContents.php b/lib/MPDF/vendor/mpdf/mpdf/src/TableOfContents.php new file mode 100644 index 0000000..82ce748 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/TableOfContents.php @@ -0,0 +1,908 @@ +<?php + +namespace Mpdf; + +use Mpdf\Utils\Arrays; +use DeepCopy\DeepCopy; + +class TableOfContents +{ + + private $mpdf; + + private $sizeConverter; + + var $_toc; + + var $TOCmark; + + var $TOCoutdent; // mPDF 5.6.31 + + var $TOCpreHTML; + + var $TOCpostHTML; + + var $TOCbookmarkText; + + var $TOCusePaging; + + var $TOCuseLinking; + + var $TOCorientation; + + var $TOC_margin_left; + + var $TOC_margin_right; + + var $TOC_margin_top; + + var $TOC_margin_bottom; + + var $TOC_margin_header; + + var $TOC_margin_footer; + + var $TOC_odd_header_name; + + var $TOC_even_header_name; + + var $TOC_odd_footer_name; + + var $TOC_even_footer_name; + + var $TOC_odd_header_value; + + var $TOC_even_header_value; + + var $TOC_odd_footer_value; + + var $TOC_even_footer_value; + + var $TOC_page_selector; + + var $TOC_resetpagenum; // mPDF 6 + + var $TOC_pagenumstyle; // mPDF 6 + + var $TOC_suppress; // mPDF 6 + + var $TOCsheetsize; + + var $m_TOC; + + /** + * @var bool Determine if the TOC should be cloned to calculate the correct page numbers + */ + protected $tocTocPaintBegun = false; + + public function __construct(Mpdf $mpdf, SizeConverter $sizeConverter) + { + $this->mpdf = $mpdf; + $this->sizeConverter = $sizeConverter; + + $this->_toc = []; + $this->TOCmark = 0; + $this->m_TOC = []; + } + + /** + * Mark the TOC Paint as having begun + */ + public function beginTocPaint() + { + $this->tocTocPaintBegun = true; + } + + public function TOCpagebreak( + $tocfont = '', + $tocfontsize = '', + $tocindent = '', + $TOCusePaging = true, + $TOCuseLinking = '', + $toc_orientation = '', + $toc_mgl = '', + $toc_mgr = '', + $toc_mgt = '', + $toc_mgb = '', + $toc_mgh = '', + $toc_mgf = '', + $toc_ohname = '', + $toc_ehname = '', + $toc_ofname = '', + $toc_efname = '', + $toc_ohvalue = 0, + $toc_ehvalue = 0, + $toc_ofvalue = 0, + $toc_efvalue = 0, + $toc_preHTML = '', + $toc_postHTML = '', + $toc_bookmarkText = '', + $resetpagenum = '', + $pagenumstyle = '', + $suppress = '', + $orientation = '', + $mgl = '', + $mgr = '', + $mgt = '', + $mgb = '', + $mgh = '', + $mgf = '', + $ohname = '', + $ehname = '', + $ofname = '', + $efname = '', + $ohvalue = 0, + $ehvalue = 0, + $ofvalue = 0, + $efvalue = 0, + $toc_id = 0, + $pagesel = '', + $toc_pagesel = '', + $sheetsize = '', + $toc_sheetsize = '', + $tocoutdent = '', + $toc_resetpagenum = '', + $toc_pagenumstyle = '', + $toc_suppress = '' + ) { + + if (strtoupper($toc_id) == 'ALL') { + $toc_id = '_mpdf_all'; + } elseif (!$toc_id) { + $toc_id = 0; + } else { + $toc_id = strtolower($toc_id); + } + + if ($TOCusePaging === false || strtolower($TOCusePaging) == "off" || $TOCusePaging === 0 || $TOCusePaging === "0" || $TOCusePaging === "") { + $TOCusePaging = false; + } else { + $TOCusePaging = true; + } + if (!$TOCuseLinking) { + $TOCuseLinking = false; + } + if ($toc_id) { + $this->m_TOC[$toc_id]['TOCmark'] = $this->mpdf->page; + $this->m_TOC[$toc_id]['TOCoutdent'] = $tocoutdent; + $this->m_TOC[$toc_id]['TOCorientation'] = $toc_orientation; + $this->m_TOC[$toc_id]['TOCuseLinking'] = $TOCuseLinking; + $this->m_TOC[$toc_id]['TOCusePaging'] = $TOCusePaging; + + if ($toc_preHTML) { + $this->m_TOC[$toc_id]['TOCpreHTML'] = $toc_preHTML; + } + if ($toc_postHTML) { + $this->m_TOC[$toc_id]['TOCpostHTML'] = $toc_postHTML; + } + if ($toc_bookmarkText) { + $this->m_TOC[$toc_id]['TOCbookmarkText'] = $toc_bookmarkText; + } + + $this->m_TOC[$toc_id]['TOC_margin_left'] = $toc_mgl; + $this->m_TOC[$toc_id]['TOC_margin_right'] = $toc_mgr; + $this->m_TOC[$toc_id]['TOC_margin_top'] = $toc_mgt; + $this->m_TOC[$toc_id]['TOC_margin_bottom'] = $toc_mgb; + $this->m_TOC[$toc_id]['TOC_margin_header'] = $toc_mgh; + $this->m_TOC[$toc_id]['TOC_margin_footer'] = $toc_mgf; + $this->m_TOC[$toc_id]['TOC_odd_header_name'] = $toc_ohname; + $this->m_TOC[$toc_id]['TOC_even_header_name'] = $toc_ehname; + $this->m_TOC[$toc_id]['TOC_odd_footer_name'] = $toc_ofname; + $this->m_TOC[$toc_id]['TOC_even_footer_name'] = $toc_efname; + $this->m_TOC[$toc_id]['TOC_odd_header_value'] = $toc_ohvalue; + $this->m_TOC[$toc_id]['TOC_even_header_value'] = $toc_ehvalue; + $this->m_TOC[$toc_id]['TOC_odd_footer_value'] = $toc_ofvalue; + $this->m_TOC[$toc_id]['TOC_even_footer_value'] = $toc_efvalue; + $this->m_TOC[$toc_id]['TOC_page_selector'] = $toc_pagesel; + $this->m_TOC[$toc_id]['TOC_resetpagenum'] = $toc_resetpagenum; // mPDF 6 + $this->m_TOC[$toc_id]['TOC_pagenumstyle'] = $toc_pagenumstyle; // mPDF 6 + $this->m_TOC[$toc_id]['TOC_suppress'] = $toc_suppress; // mPDF 6 + $this->m_TOC[$toc_id]['TOCsheetsize'] = $toc_sheetsize; + } else { + $this->TOCmark = $this->mpdf->page; + $this->TOCoutdent = $tocoutdent; + $this->TOCorientation = $toc_orientation; + $this->TOCuseLinking = $TOCuseLinking; + $this->TOCusePaging = $TOCusePaging; + + if ($toc_preHTML) { + $this->TOCpreHTML = $toc_preHTML; + } + if ($toc_postHTML) { + $this->TOCpostHTML = $toc_postHTML; + } + if ($toc_bookmarkText) { + $this->TOCbookmarkText = $toc_bookmarkText; + } + + $this->TOC_margin_left = $toc_mgl; + $this->TOC_margin_right = $toc_mgr; + $this->TOC_margin_top = $toc_mgt; + $this->TOC_margin_bottom = $toc_mgb; + $this->TOC_margin_header = $toc_mgh; + $this->TOC_margin_footer = $toc_mgf; + $this->TOC_odd_header_name = $toc_ohname; + $this->TOC_even_header_name = $toc_ehname; + $this->TOC_odd_footer_name = $toc_ofname; + $this->TOC_even_footer_name = $toc_efname; + $this->TOC_odd_header_value = $toc_ohvalue; + $this->TOC_even_header_value = $toc_ehvalue; + $this->TOC_odd_footer_value = $toc_ofvalue; + $this->TOC_even_footer_value = $toc_efvalue; + $this->TOC_page_selector = $toc_pagesel; + $this->TOC_resetpagenum = $toc_resetpagenum; // mPDF 6 + $this->TOC_pagenumstyle = $toc_pagenumstyle; // mPDF 6 + $this->TOC_suppress = $toc_suppress; // mPDF 6 + $this->TOCsheetsize = $toc_sheetsize; + } + } + + /** + * Initiate, and Mark a place for the Table of Contents to be inserted + */ + public function TOC( + $tocfont = '', + $tocfontsize = 0, + $tocindent = 0, + $resetpagenum = '', + $pagenumstyle = '', + $suppress = '', + $toc_orientation = '', + $TOCusePaging = true, + $TOCuseLinking = false, + $toc_id = 0, + $tocoutdent = '', + $toc_resetpagenum = '', + $toc_pagenumstyle = '', + $toc_suppress = '' + ) { + + if (strtoupper($toc_id) == 'ALL') { + $toc_id = '_mpdf_all'; + } elseif (!$toc_id) { + $toc_id = 0; + } else { + $toc_id = strtolower($toc_id); + } + // To use odd and even pages + // Cannot start table of contents on an even page + if (($this->mpdf->mirrorMargins) && (($this->mpdf->page) % 2 == 0)) { // EVEN + if ($this->mpdf->ColActive) { + if (count($this->mpdf->columnbuffer)) { + $this->mpdf->printcolumnbuffer(); + } + } + $this->mpdf->AddPage($this->mpdf->CurOrientation, '', $resetpagenum, $pagenumstyle, $suppress); + } else { + $this->mpdf->PageNumSubstitutions[] = ['from' => $this->mpdf->page, 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress]; + } + if ($toc_id) { + $this->m_TOC[$toc_id]['TOCmark'] = $this->mpdf->page; + $this->m_TOC[$toc_id]['TOCoutdent'] = $tocoutdent; + $this->m_TOC[$toc_id]['TOCorientation'] = $toc_orientation; + $this->m_TOC[$toc_id]['TOCuseLinking'] = $TOCuseLinking; + $this->m_TOC[$toc_id]['TOCusePaging'] = $TOCusePaging; + $this->m_TOC[$toc_id]['TOC_resetpagenum'] = $toc_resetpagenum; // mPDF 6 + $this->m_TOC[$toc_id]['TOC_pagenumstyle'] = $toc_pagenumstyle; // mPDF 6 + $this->m_TOC[$toc_id]['TOC_suppress'] = $toc_suppress; // mPDF 6 + } else { + $this->TOCmark = $this->mpdf->page; + $this->TOCoutdent = $tocoutdent; + $this->TOCorientation = $toc_orientation; + $this->TOCuseLinking = $TOCuseLinking; + $this->TOCusePaging = $TOCusePaging; + $this->TOC_resetpagenum = $toc_resetpagenum; // mPDF 6 + $this->TOC_pagenumstyle = $toc_pagenumstyle; // mPDF 6 + $this->TOC_suppress = $toc_suppress; // mPDF 6 + } + } + + public function insertTOC() + { + /* + * Fix the TOC page numbering problem + * + * To do this, the current class is deep cloned and then the TOC functionality run. The correct page + * numbers are calculated when the TOC pages are moved into position in the cloned object (see Mpdf::MovePages). + * It's then a matter of copying the correct page numbers to the original object and letting the TOC functionality + * run as per normal. + * + * See https://github.com/mpdf/mpdf/issues/642 + */ + if (!$this->tocTocPaintBegun) { + $copier = new DeepCopy(true); + $tocClassClone = $copier->copy($this); + $tocClassClone->beginTocPaint(); + $tocClassClone->insertTOC(); + $this->_toc = $tocClassClone->_toc; + } + + $notocs = 0; + if ($this->TOCmark) { + $notocs = 1; + } + $notocs += count($this->m_TOC); + + if ($notocs == 0) { + return; + } + + if (count($this->m_TOC)) { + reset($this->m_TOC); + } + $added_toc_pages = 0; + + if ($this->mpdf->ColActive) { + $this->mpdf->SetColumns(0); + } + if (($this->mpdf->mirrorMargins) && (($this->mpdf->page) % 2 == 1)) { // ODD + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $extrapage = true; + } else { + $extrapage = false; + } + + for ($toci = 0; $toci < $notocs; $toci++) { + if ($toci == 0 && $this->TOCmark) { + $toc_id = 0; + $toc_page = $this->TOCmark; + $tocoutdent = $this->TOCoutdent; + $toc_orientation = $this->TOCorientation; + $TOCuseLinking = $this->TOCuseLinking; + $TOCusePaging = $this->TOCusePaging; + $toc_preHTML = $this->TOCpreHTML; + $toc_postHTML = $this->TOCpostHTML; + $toc_bookmarkText = $this->TOCbookmarkText; + $toc_mgl = $this->TOC_margin_left; + $toc_mgr = $this->TOC_margin_right; + $toc_mgt = $this->TOC_margin_top; + $toc_mgb = $this->TOC_margin_bottom; + $toc_mgh = $this->TOC_margin_header; + $toc_mgf = $this->TOC_margin_footer; + $toc_ohname = $this->TOC_odd_header_name; + $toc_ehname = $this->TOC_even_header_name; + $toc_ofname = $this->TOC_odd_footer_name; + $toc_efname = $this->TOC_even_footer_name; + $toc_ohvalue = $this->TOC_odd_header_value; + $toc_ehvalue = $this->TOC_even_header_value; + $toc_ofvalue = $this->TOC_odd_footer_value; + $toc_efvalue = $this->TOC_even_footer_value; + $toc_page_selector = $this->TOC_page_selector; + $toc_resetpagenum = $this->TOC_resetpagenum; // mPDF 6 + $toc_pagenumstyle = $this->TOC_pagenumstyle; // mPDF 6 + $toc_suppress = $this->TOC_suppress; // mPDF 6 + $toc_sheet_size = (isset($this->TOCsheetsize) ? $this->TOCsheetsize : ''); + } else { + $arr = current($this->m_TOC); + + $toc_id = key($this->m_TOC); + $toc_page = $this->m_TOC[$toc_id]['TOCmark']; + $tocoutdent = $this->m_TOC[$toc_id]['TOCoutdent']; + $toc_orientation = $this->m_TOC[$toc_id]['TOCorientation']; + $TOCuseLinking = $this->m_TOC[$toc_id]['TOCuseLinking']; + $TOCusePaging = $this->m_TOC[$toc_id]['TOCusePaging']; + if (isset($this->m_TOC[$toc_id]['TOCpreHTML'])) { + $toc_preHTML = $this->m_TOC[$toc_id]['TOCpreHTML']; + } else { + $toc_preHTML = ''; + } + if (isset($this->m_TOC[$toc_id]['TOCpostHTML'])) { + $toc_postHTML = $this->m_TOC[$toc_id]['TOCpostHTML']; + } else { + $toc_postHTML = ''; + } + if (isset($this->m_TOC[$toc_id]['TOCbookmarkText'])) { + $toc_bookmarkText = $this->m_TOC[$toc_id]['TOCbookmarkText']; + } else { + $toc_bookmarkText = ''; + } // *BOOKMARKS* + $toc_mgl = $this->m_TOC[$toc_id]['TOC_margin_left']; + $toc_mgr = $this->m_TOC[$toc_id]['TOC_margin_right']; + $toc_mgt = $this->m_TOC[$toc_id]['TOC_margin_top']; + $toc_mgb = $this->m_TOC[$toc_id]['TOC_margin_bottom']; + $toc_mgh = $this->m_TOC[$toc_id]['TOC_margin_header']; + $toc_mgf = $this->m_TOC[$toc_id]['TOC_margin_footer']; + $toc_ohname = $this->m_TOC[$toc_id]['TOC_odd_header_name']; + $toc_ehname = $this->m_TOC[$toc_id]['TOC_even_header_name']; + $toc_ofname = $this->m_TOC[$toc_id]['TOC_odd_footer_name']; + $toc_efname = $this->m_TOC[$toc_id]['TOC_even_footer_name']; + $toc_ohvalue = $this->m_TOC[$toc_id]['TOC_odd_header_value']; + $toc_ehvalue = $this->m_TOC[$toc_id]['TOC_even_header_value']; + $toc_ofvalue = $this->m_TOC[$toc_id]['TOC_odd_footer_value']; + $toc_efvalue = $this->m_TOC[$toc_id]['TOC_even_footer_value']; + $toc_page_selector = $this->m_TOC[$toc_id]['TOC_page_selector']; + $toc_resetpagenum = $this->m_TOC[$toc_id]['TOC_resetpagenum']; // mPDF 6 + $toc_pagenumstyle = $this->m_TOC[$toc_id]['TOC_pagenumstyle']; // mPDF 6 + $toc_suppress = $this->m_TOC[$toc_id]['TOC_suppress']; // mPDF 6 + $toc_sheet_size = (isset($this->m_TOC[$toc_id]['TOCsheetsize']) ? $this->m_TOC[$toc_id]['TOCsheetsize'] : ''); + next($this->m_TOC); + } + + // mPDF 5.6.31 + if (!$toc_orientation) { + $toc_orientation = $this->mpdf->DefOrientation; + } + + // mPDF 6 number style and suppress now picked up from section preceding ToC + list($tp_pagenumstyle, $tp_suppress, $tp_reset) = $this->mpdf->docPageSettings($toc_page - 1); + + if ($toc_resetpagenum) { + $tp_reset = $toc_resetpagenum; // mPDF 6 + } + if ($toc_pagenumstyle) { + $tp_pagenumstyle = $toc_pagenumstyle; // mPDF 6 + } + if ($toc_suppress || $toc_suppress === '0') { + $tp_suppress = $toc_suppress; // mPDF 6 + } + + $this->mpdf->AddPage($toc_orientation, '', $tp_reset, $tp_pagenumstyle, $tp_suppress, $toc_mgl, $toc_mgr, $toc_mgt, $toc_mgb, $toc_mgh, $toc_mgf, $toc_ohname, $toc_ehname, $toc_ofname, $toc_efname, $toc_ohvalue, $toc_ehvalue, $toc_ofvalue, $toc_efvalue, $toc_page_selector, $toc_sheet_size); // mPDF 6 + + $this->mpdf->writingToC = true; // mPDF 5.6.38 + + /* + * Ensure the TOC Page Number Style doesn't effect the TOC Numbering (added automatically in `AddPage()` above) + * Ensure the page numbers show in the TOC when the 'suppress' setting is enabled + * @see https://github.com/mpdf/mpdf/issues/792 + * @see https://github.com/mpdf/mpdf/issues/777 + */ + if (isset($tocClassClone)) { + $this->mpdf->PageNumSubstitutions = array_map(function ($sub) { + $sub['suppress'] = ''; + return $sub; + }, $tocClassClone->mpdf->PageNumSubstitutions); + } + + // mPDF 5.6.31 + $tocstart = count($this->mpdf->pages); + if (isset($toc_preHTML) && $toc_preHTML) { + $this->mpdf->WriteHTML($toc_preHTML); + } + + // mPDF 5.6.19 + $html = '<div class="mpdf_toc" id="mpdf_toc_' . $toc_id . '">'; + foreach ($this->_toc as $t) { + if ($t['toc_id'] === '_mpdf_all' || $t['toc_id'] === $toc_id) { + $html .= '<div class="mpdf_toc_level_' . $t['l'] . '">'; + if ($TOCuseLinking) { + $html .= '<a class="mpdf_toc_a" href="#__mpdfinternallink_' . $t['link'] . '">'; + } + $html .= '<span class="mpdf_toc_t_level_' . $t['l'] . '">' . $t['t'] . '</span>'; + if ($TOCuseLinking) { + $html .= '</a>'; + } + if (!$tocoutdent) { + $tocoutdent = '0'; + } + if ($TOCusePaging) { + $html .= ' <dottab outdent="' . $tocoutdent . '" /> '; + if ($TOCuseLinking) { + $html .= '<a class="mpdf_toc_a" href="#__mpdfinternallink_' . $t['link'] . '">'; + } + $html .= '<span class="mpdf_toc_p_level_' . $t['l'] . '">' . $this->mpdf->docPageNum($t['p']) . '</span>'; + if ($TOCuseLinking) { + $html .= '</a>'; + } + } + $html .= '</div>'; + } + } + $html .= '</div>'; + $this->mpdf->WriteHTML($html); + + if (isset($toc_postHTML) && $toc_postHTML) { + $this->mpdf->WriteHTML($toc_postHTML); + } + $this->mpdf->writingToC = false; // mPDF 5.6.38 + $this->mpdf->AddPage($toc_orientation, 'E'); + + $n_toc = $this->mpdf->page - $tocstart + 1; + + if ($toci == 0 && $this->TOCmark) { + $TOC_start = $tocstart; + $TOC_end = $this->mpdf->page; + $TOC_npages = $n_toc; + } else { + $this->m_TOC[$toc_id]['start'] = $tocstart; + $this->m_TOC[$toc_id]['end'] = $this->mpdf->page; + $this->m_TOC[$toc_id]['npages'] = $n_toc; + } + } + + $s = ''; + + $s .= $this->mpdf->PrintBodyBackgrounds(); + + $s .= $this->mpdf->PrintPageBackgrounds(); + $this->mpdf->pages[$this->mpdf->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->mpdf->uniqstr . ')/', "\n" . $s . "\n" . '\\1', $this->mpdf->pages[$this->mpdf->page]); + $this->mpdf->pageBackgrounds = []; + + //Page footer + $this->mpdf->InFooter = true; + $this->mpdf->Footer(); + $this->mpdf->InFooter = false; + + // 2nd time through to move pages etc. + $added_toc_pages = 0; + if (count($this->m_TOC)) { + reset($this->m_TOC); + } + + for ($toci = 0; $toci < $notocs; $toci++) { + if ($toci == 0 && $this->TOCmark) { + $toc_id = 0; + $toc_page = $this->TOCmark + $added_toc_pages; + $toc_orientation = $this->TOCorientation; + $TOCuseLinking = $this->TOCuseLinking; + $TOCusePaging = $this->TOCusePaging; + $toc_bookmarkText = $this->TOCbookmarkText; // *BOOKMARKS* + + $tocstart = $TOC_start; + $tocend = $n = $TOC_end; + $n_toc = $TOC_npages; + } else { + $arr = current($this->m_TOC); + + $toc_id = key($this->m_TOC); + $toc_page = $this->m_TOC[$toc_id]['TOCmark'] + $added_toc_pages; + $toc_orientation = $this->m_TOC[$toc_id]['TOCorientation']; + $TOCuseLinking = $this->m_TOC[$toc_id]['TOCuseLinking']; + $TOCusePaging = $this->m_TOC[$toc_id]['TOCusePaging']; + $toc_bookmarkText = Arrays::get($this->m_TOC[$toc_id], 'TOCbookmarkText', null); // *BOOKMARKS* + + $tocstart = $this->m_TOC[$toc_id]['start']; + $tocend = $n = $this->m_TOC[$toc_id]['end']; + $n_toc = $this->m_TOC[$toc_id]['npages']; + + next($this->m_TOC); + } + + // Now pages moved + $added_toc_pages += $n_toc; + + $this->mpdf->MovePages($toc_page, $tocstart, $tocend); + $this->mpdf->pgsIns[$toc_page] = $tocend - $tocstart + 1; + + /* -- BOOKMARKS -- */ + // Insert new Bookmark for Bookmark + if ($toc_bookmarkText) { + $insert = -1; + foreach ($this->mpdf->BMoutlines as $i => $o) { + if ($o['p'] < $toc_page) { // i.e. before point of insertion + $insert = $i; + } + } + $txt = $this->mpdf->purify_utf8_text($toc_bookmarkText); + if ($this->mpdf->text_input_as_HTML) { + $txt = $this->mpdf->all_entities_to_utf8($txt); + } + $newBookmark[0] = ['t' => $txt, 'l' => 0, 'y' => 0, 'p' => $toc_page]; + array_splice($this->mpdf->BMoutlines, ($insert + 1), 0, $newBookmark); + } + /* -- END BOOKMARKS -- */ + } + + // Delete empty page that was inserted earlier + if ($extrapage) { + unset($this->mpdf->pages[count($this->mpdf->pages)]); + $this->mpdf->page--; // Reset page pointer + } + + /* Fix the over adjustment of the TOC and Page Substitutions values */ + if (isset($tocClassClone)) { + $this->_toc = $tocClassClone->_toc; + $this->mpdf->PageNumSubstitutions = $tocClassClone->mpdf->PageNumSubstitutions; + unset($tocClassClone); + } + } + + public function openTagTOC($attr) + { + if (isset($attr['OUTDENT']) && $attr['OUTDENT']) { + $tocoutdent = $attr['OUTDENT']; + } else { + $tocoutdent = ''; + } // mPDF 5.6.19 + if (isset($attr['RESETPAGENUM']) && $attr['RESETPAGENUM']) { + $resetpagenum = $attr['RESETPAGENUM']; + } else { + $resetpagenum = ''; + } + if (isset($attr['PAGENUMSTYLE']) && $attr['PAGENUMSTYLE']) { + $pagenumstyle = $attr['PAGENUMSTYLE']; + } else { + $pagenumstyle = ''; + } + if (isset($attr['SUPPRESS']) && $attr['SUPPRESS']) { + $suppress = $attr['SUPPRESS']; + } else { + $suppress = ''; + } + if (isset($attr['TOC-ORIENTATION']) && $attr['TOC-ORIENTATION']) { + $toc_orientation = $attr['TOC-ORIENTATION']; + } else { + $toc_orientation = ''; + } + if (isset($attr['PAGING']) && (strtoupper($attr['PAGING']) == 'OFF' || $attr['PAGING'] === '0')) { + $paging = false; + } else { + $paging = true; + } + if (isset($attr['LINKS']) && (strtoupper($attr['LINKS']) == 'ON' || $attr['LINKS'] == 1)) { + $links = true; + } else { + $links = false; + } + if (isset($attr['NAME']) && $attr['NAME']) { + $toc_id = strtolower($attr['NAME']); + } else { + $toc_id = 0; + } + $this->TOC('', 0, 0, $resetpagenum, $pagenumstyle, $suppress, $toc_orientation, $paging, $links, $toc_id, $tocoutdent); // mPDF 5.6.19 5.6.31 + } + + public function openTagTOCPAGEBREAK($attr) + { + if (isset($attr['NAME']) && $attr['NAME']) { + $toc_id = strtolower($attr['NAME']); + } else { + $toc_id = 0; + } + if ($toc_id) { + if (isset($attr['OUTDENT']) && $attr['OUTDENT']) { + $this->m_TOC[$toc_id]['TOCoutdent'] = $attr['OUTDENT']; + } else { + $this->m_TOC[$toc_id]['TOCoutdent'] = ''; + } // mPDF 5.6.19 + if (isset($attr['TOC-ORIENTATION']) && $attr['TOC-ORIENTATION']) { + $this->m_TOC[$toc_id]['TOCorientation'] = $attr['TOC-ORIENTATION']; + } else { + $this->m_TOC[$toc_id]['TOCorientation'] = ''; + } + if (isset($attr['PAGING']) && (strtoupper($attr['PAGING']) == 'OFF' || $attr['PAGING'] === '0')) { + $this->m_TOC[$toc_id]['TOCusePaging'] = false; + } else { + $this->m_TOC[$toc_id]['TOCusePaging'] = true; + } + if (isset($attr['LINKS']) && (strtoupper($attr['LINKS']) == 'ON' || $attr['LINKS'] == 1)) { + $this->m_TOC[$toc_id]['TOCuseLinking'] = true; + } else { + $this->m_TOC[$toc_id]['TOCuseLinking'] = false; + } + + $this->m_TOC[$toc_id]['TOC_margin_left'] = $this->m_TOC[$toc_id]['TOC_margin_right'] = $this->m_TOC[$toc_id]['TOC_margin_top'] = $this->m_TOC[$toc_id]['TOC_margin_bottom'] = $this->m_TOC[$toc_id]['TOC_margin_header'] = $this->m_TOC[$toc_id]['TOC_margin_footer'] = ''; + if (isset($attr['TOC-MARGIN-RIGHT'])) { + $this->m_TOC[$toc_id]['TOC_margin_right'] = $this->sizeConverter->convert($attr['TOC-MARGIN-RIGHT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-LEFT'])) { + $this->m_TOC[$toc_id]['TOC_margin_left'] = $this->sizeConverter->convert($attr['TOC-MARGIN-LEFT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-TOP'])) { + $this->m_TOC[$toc_id]['TOC_margin_top'] = $this->sizeConverter->convert($attr['TOC-MARGIN-TOP'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-BOTTOM'])) { + $this->m_TOC[$toc_id]['TOC_margin_bottom'] = $this->sizeConverter->convert($attr['TOC-MARGIN-BOTTOM'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-HEADER'])) { + $this->m_TOC[$toc_id]['TOC_margin_header'] = $this->sizeConverter->convert($attr['TOC-MARGIN-HEADER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-FOOTER'])) { + $this->m_TOC[$toc_id]['TOC_margin_footer'] = $this->sizeConverter->convert($attr['TOC-MARGIN-FOOTER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + $this->m_TOC[$toc_id]['TOC_odd_header_name'] = $this->m_TOC[$toc_id]['TOC_even_header_name'] = $this->m_TOC[$toc_id]['TOC_odd_footer_name'] = $this->m_TOC[$toc_id]['TOC_even_footer_name'] = ''; + if (isset($attr['TOC-ODD-HEADER-NAME']) && $attr['TOC-ODD-HEADER-NAME']) { + $this->m_TOC[$toc_id]['TOC_odd_header_name'] = $attr['TOC-ODD-HEADER-NAME']; + } + if (isset($attr['TOC-EVEN-HEADER-NAME']) && $attr['TOC-EVEN-HEADER-NAME']) { + $this->m_TOC[$toc_id]['TOC_even_header_name'] = $attr['TOC-EVEN-HEADER-NAME']; + } + if (isset($attr['TOC-ODD-FOOTER-NAME']) && $attr['TOC-ODD-FOOTER-NAME']) { + $this->m_TOC[$toc_id]['TOC_odd_footer_name'] = $attr['TOC-ODD-FOOTER-NAME']; + } + if (isset($attr['TOC-EVEN-FOOTER-NAME']) && $attr['TOC-EVEN-FOOTER-NAME']) { + $this->m_TOC[$toc_id]['TOC_even_footer_name'] = $attr['TOC-EVEN-FOOTER-NAME']; + } + $this->m_TOC[$toc_id]['TOC_odd_header_value'] = $this->m_TOC[$toc_id]['TOC_even_header_value'] = $this->m_TOC[$toc_id]['TOC_odd_footer_value'] = $this->m_TOC[$toc_id]['TOC_even_footer_value'] = 0; + if (isset($attr['TOC-ODD-HEADER-VALUE']) && ($attr['TOC-ODD-HEADER-VALUE'] == '1' || strtoupper($attr['TOC-ODD-HEADER-VALUE']) == 'ON')) { + $this->m_TOC[$toc_id]['TOC_odd_header_value'] = 1; + } elseif (isset($attr['TOC-ODD-HEADER-VALUE']) && ($attr['TOC-ODD-HEADER-VALUE'] == '-1' || strtoupper($attr['TOC-ODD-HEADER-VALUE']) == 'OFF')) { + $this->m_TOC[$toc_id]['TOC_odd_header_value'] = -1; + } + if (isset($attr['TOC-EVEN-HEADER-VALUE']) && ($attr['TOC-EVEN-HEADER-VALUE'] == '1' || strtoupper($attr['TOC-EVEN-HEADER-VALUE']) == 'ON')) { + $this->m_TOC[$toc_id]['TOC_even_header_value'] = 1; + } elseif (isset($attr['TOC-EVEN-HEADER-VALUE']) && ($attr['TOC-EVEN-HEADER-VALUE'] == '-1' || strtoupper($attr['TOC-EVEN-HEADER-VALUE']) == 'OFF')) { + $this->m_TOC[$toc_id]['TOC_even_header_value'] = -1; + } + if (isset($attr['TOC-ODD-FOOTER-VALUE']) && ($attr['TOC-ODD-FOOTER-VALUE'] == '1' || strtoupper($attr['TOC-ODD-FOOTER-VALUE']) == 'ON')) { + $this->m_TOC[$toc_id]['TOC_odd_footer_value'] = 1; + } elseif (isset($attr['TOC-ODD-FOOTER-VALUE']) && ($attr['TOC-ODD-FOOTER-VALUE'] == '-1' || strtoupper($attr['TOC-ODD-FOOTER-VALUE']) == 'OFF')) { + $this->m_TOC[$toc_id]['TOC_odd_footer_value'] = -1; + } + if (isset($attr['TOC-EVEN-FOOTER-VALUE']) && ($attr['TOC-EVEN-FOOTER-VALUE'] == '1' || strtoupper($attr['TOC-EVEN-FOOTER-VALUE']) == 'ON')) { + $this->m_TOC[$toc_id]['TOC_even_footer_value'] = 1; + } elseif (isset($attr['TOC-EVEN-FOOTER-VALUE']) && ($attr['TOC-EVEN-FOOTER-VALUE'] == '-1' || strtoupper($attr['TOC-EVEN-FOOTER-VALUE']) == 'OFF')) { + $this->m_TOC[$toc_id]['TOC_even_footer_value'] = -1; + } + if (isset($attr['TOC-RESETPAGENUM']) && $attr['TOC-RESETPAGENUM']) { + $this->m_TOC[$toc_id]['TOC_resetpagenum'] = $attr['TOC-RESETPAGENUM']; + } else { + $this->m_TOC[$toc_id]['TOC_resetpagenum'] = ''; + } // mPDF 6 + if (isset($attr['TOC-PAGENUMSTYLE']) && $attr['TOC-PAGENUMSTYLE']) { + $this->m_TOC[$toc_id]['TOC_pagenumstyle'] = $attr['TOC-PAGENUMSTYLE']; + } else { + $this->m_TOC[$toc_id]['TOC_pagenumstyle'] = ''; + } // mPDF 6 + if (isset($attr['TOC-SUPPRESS']) && ($attr['TOC-SUPPRESS'] || $attr['TOC-SUPPRESS'] === '0')) { + $this->m_TOC[$toc_id]['TOC_suppress'] = $attr['TOC-SUPPRESS']; + } else { + $this->m_TOC[$toc_id]['TOC_suppress'] = ''; + } // mPDF 6 + if (isset($attr['TOC-PAGE-SELECTOR']) && $attr['TOC-PAGE-SELECTOR']) { + $this->m_TOC[$toc_id]['TOC_page_selector'] = $attr['TOC-PAGE-SELECTOR']; + } else { + $this->m_TOC[$toc_id]['TOC_page_selector'] = ''; + } + if (isset($attr['TOC-SHEET-SIZE']) && $attr['TOC-SHEET-SIZE']) { + $this->m_TOC[$toc_id]['TOCsheetsize'] = $attr['TOC-SHEET-SIZE']; + } else { + $this->m_TOC[$toc_id]['TOCsheetsize'] = ''; + } + + + if (isset($attr['TOC-PREHTML']) && $attr['TOC-PREHTML']) { + $this->m_TOC[$toc_id]['TOCpreHTML'] = htmlspecialchars_decode($attr['TOC-PREHTML'], ENT_QUOTES); + } + if (isset($attr['TOC-POSTHTML']) && $attr['TOC-POSTHTML']) { + $this->m_TOC[$toc_id]['TOCpostHTML'] = htmlspecialchars_decode($attr['TOC-POSTHTML'], ENT_QUOTES); + } + + if (isset($attr['TOC-BOOKMARKTEXT']) && $attr['TOC-BOOKMARKTEXT']) { + $this->m_TOC[$toc_id]['TOCbookmarkText'] = htmlspecialchars_decode($attr['TOC-BOOKMARKTEXT'], ENT_QUOTES); + } // *BOOKMARKS* + } else { + if (isset($attr['OUTDENT']) && $attr['OUTDENT']) { + $this->TOCoutdent = $attr['OUTDENT']; + } else { + $this->TOCoutdent = ''; + } // mPDF 5.6.19 + if (isset($attr['TOC-ORIENTATION']) && $attr['TOC-ORIENTATION']) { + $this->TOCorientation = $attr['TOC-ORIENTATION']; + } else { + $this->TOCorientation = ''; + } + if (isset($attr['PAGING']) && (strtoupper($attr['PAGING']) == 'OFF' || $attr['PAGING'] === '0')) { + $this->TOCusePaging = false; + } else { + $this->TOCusePaging = true; + } + if (isset($attr['LINKS']) && (strtoupper($attr['LINKS']) == 'ON' || $attr['LINKS'] == 1)) { + $this->TOCuseLinking = true; + } else { + $this->TOCuseLinking = false; + } + + $this->TOC_margin_left = $this->TOC_margin_right = $this->TOC_margin_top = $this->TOC_margin_bottom = $this->TOC_margin_header = $this->TOC_margin_footer = ''; + if (isset($attr['TOC-MARGIN-RIGHT'])) { + $this->TOC_margin_right = $this->sizeConverter->convert($attr['TOC-MARGIN-RIGHT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-LEFT'])) { + $this->TOC_margin_left = $this->sizeConverter->convert($attr['TOC-MARGIN-LEFT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-TOP'])) { + $this->TOC_margin_top = $this->sizeConverter->convert($attr['TOC-MARGIN-TOP'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-BOTTOM'])) { + $this->TOC_margin_bottom = $this->sizeConverter->convert($attr['TOC-MARGIN-BOTTOM'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-HEADER'])) { + $this->TOC_margin_header = $this->sizeConverter->convert($attr['TOC-MARGIN-HEADER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['TOC-MARGIN-FOOTER'])) { + $this->TOC_margin_footer = $this->sizeConverter->convert($attr['TOC-MARGIN-FOOTER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + $this->TOC_odd_header_name = $this->TOC_even_header_name = $this->TOC_odd_footer_name = $this->TOC_even_footer_name = ''; + if (isset($attr['TOC-ODD-HEADER-NAME']) && $attr['TOC-ODD-HEADER-NAME']) { + $this->TOC_odd_header_name = $attr['TOC-ODD-HEADER-NAME']; + } + if (isset($attr['TOC-EVEN-HEADER-NAME']) && $attr['TOC-EVEN-HEADER-NAME']) { + $this->TOC_even_header_name = $attr['TOC-EVEN-HEADER-NAME']; + } + if (isset($attr['TOC-ODD-FOOTER-NAME']) && $attr['TOC-ODD-FOOTER-NAME']) { + $this->TOC_odd_footer_name = $attr['TOC-ODD-FOOTER-NAME']; + } + if (isset($attr['TOC-EVEN-FOOTER-NAME']) && $attr['TOC-EVEN-FOOTER-NAME']) { + $this->TOC_even_footer_name = $attr['TOC-EVEN-FOOTER-NAME']; + } + $this->TOC_odd_header_value = $this->TOC_even_header_value = $this->TOC_odd_footer_value = $this->TOC_even_footer_value = 0; + if (isset($attr['TOC-ODD-HEADER-VALUE']) && ($attr['TOC-ODD-HEADER-VALUE'] == '1' || strtoupper($attr['TOC-ODD-HEADER-VALUE']) == 'ON')) { + $this->TOC_odd_header_value = 1; + } elseif (isset($attr['TOC-ODD-HEADER-VALUE']) && ($attr['TOC-ODD-HEADER-VALUE'] == '-1' || strtoupper($attr['TOC-ODD-HEADER-VALUE']) == 'OFF')) { + $this->TOC_odd_header_value = -1; + } + if (isset($attr['TOC-EVEN-HEADER-VALUE']) && ($attr['TOC-EVEN-HEADER-VALUE'] == '1' || strtoupper($attr['TOC-EVEN-HEADER-VALUE']) == 'ON')) { + $this->TOC_even_header_value = 1; + } elseif (isset($attr['TOC-EVEN-HEADER-VALUE']) && ($attr['TOC-EVEN-HEADER-VALUE'] == '-1' || strtoupper($attr['TOC-EVEN-HEADER-VALUE']) == 'OFF')) { + $this->TOC_even_header_value = -1; + } + + if (isset($attr['TOC-ODD-FOOTER-VALUE']) && ($attr['TOC-ODD-FOOTER-VALUE'] == '1' || strtoupper($attr['TOC-ODD-FOOTER-VALUE']) == 'ON')) { + $this->TOC_odd_footer_value = 1; + } elseif (isset($attr['TOC-ODD-FOOTER-VALUE']) && ($attr['TOC-ODD-FOOTER-VALUE'] == '-1' || strtoupper($attr['TOC-ODD-FOOTER-VALUE']) == 'OFF')) { + $this->TOC_odd_footer_value = -1; + } + if (isset($attr['TOC-EVEN-FOOTER-VALUE']) && ($attr['TOC-EVEN-FOOTER-VALUE'] == '1' || strtoupper($attr['TOC-EVEN-FOOTER-VALUE']) == 'ON')) { + $this->TOC_even_footer_value = 1; + } elseif (isset($attr['TOC-EVEN-FOOTER-VALUE']) && ($attr['TOC-EVEN-FOOTER-VALUE'] == '-1' || strtoupper($attr['TOC-EVEN-FOOTER-VALUE']) == 'OFF')) { + $this->TOC_even_footer_value = -1; + } + if (isset($attr['TOC-PAGE-SELECTOR']) && $attr['TOC-PAGE-SELECTOR']) { + $this->TOC_page_selector = $attr['TOC-PAGE-SELECTOR']; + } else { + $this->TOC_page_selector = ''; + } + if (isset($attr['TOC-RESETPAGENUM']) && $attr['TOC-RESETPAGENUM']) { + $this->TOC_resetpagenum = $attr['TOC-RESETPAGENUM']; + } else { + $this->TOC_resetpagenum = ''; + } // mPDF 6 + if (isset($attr['TOC-PAGENUMSTYLE']) && $attr['TOC-PAGENUMSTYLE']) { + $this->TOC_pagenumstyle = $attr['TOC-PAGENUMSTYLE']; + } else { + $this->TOC_pagenumstyle = ''; + } // mPDF 6 + if (isset($attr['TOC-SUPPRESS']) && ($attr['TOC-SUPPRESS'] || $attr['TOC-SUPPRESS'] === '0')) { + $this->TOC_suppress = $attr['TOC-SUPPRESS']; + } else { + $this->TOC_suppress = ''; + } // mPDF 6 + if (isset($attr['TOC-SHEET-SIZE']) && $attr['TOC-SHEET-SIZE']) { + $this->TOCsheetsize = $attr['TOC-SHEET-SIZE']; + } else { + $this->TOCsheetsize = ''; + } + + if (isset($attr['TOC-PREHTML']) && $attr['TOC-PREHTML']) { + $this->TOCpreHTML = htmlspecialchars_decode($attr['TOC-PREHTML'], ENT_QUOTES); + } + if (isset($attr['TOC-POSTHTML']) && $attr['TOC-POSTHTML']) { + $this->TOCpostHTML = htmlspecialchars_decode($attr['TOC-POSTHTML'], ENT_QUOTES); + } + if (isset($attr['TOC-BOOKMARKTEXT']) && $attr['TOC-BOOKMARKTEXT']) { + $this->TOCbookmarkText = htmlspecialchars_decode($attr['TOC-BOOKMARKTEXT'], ENT_QUOTES); + } + } + + if ($this->mpdf->y == $this->mpdf->tMargin && (!$this->mpdf->mirrorMargins || ($this->mpdf->mirrorMargins && $this->mpdf->page % 2 == 1))) { + if ($toc_id) { + $this->m_TOC[$toc_id]['TOCmark'] = $this->mpdf->page; + } else { + $this->TOCmark = $this->mpdf->page; + } + // Don't add a page + if ($this->mpdf->page == 1 && count($this->mpdf->PageNumSubstitutions) == 0) { + $resetpagenum = ''; + $pagenumstyle = ''; + $suppress = ''; + if (isset($attr['RESETPAGENUM'])) { + $resetpagenum = $attr['RESETPAGENUM']; + } + if (isset($attr['PAGENUMSTYLE'])) { + $pagenumstyle = $attr['PAGENUMSTYLE']; + } + if (isset($attr['SUPPRESS'])) { + $suppress = $attr['SUPPRESS']; + } + if (!$suppress) { + $suppress = 'off'; + } + $this->mpdf->PageNumSubstitutions[] = ['from' => 1, 'reset' => $resetpagenum, 'type' => $pagenumstyle, 'suppress' => $suppress]; + } + return [true, $toc_id]; + } + + // No break - continues as PAGEBREAK... + return [false, $toc_id]; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag.php new file mode 100644 index 0000000..6886d1c --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag.php @@ -0,0 +1,253 @@ +<?php + +namespace Mpdf; + +use Mpdf\Strict; + +use Mpdf\Color\ColorConverter; + +use Mpdf\Image\ImageProcessor; + +use Mpdf\Language\LanguageToFontInterface; + +class Tag +{ + + use Strict; + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Mpdf\Cache + */ + private $cache; + + /** + * @var \Mpdf\CssManager + */ + private $cssManager; + + /** + * @var \Mpdf\Form + */ + private $form; + + /** + * @var \Mpdf\Otl + */ + private $otl; + + /** + * @var \Mpdf\TableOfContents + */ + private $tableOfContents; + + /** + * @var \Mpdf\SizeConverter + */ + private $sizeConverter; + + /** + * @var \Mpdf\Color\ColorConverter + */ + private $colorConverter; + + /** + * @var \Mpdf\Image\ImageProcessor + */ + private $imageProcessor; + + /** + * @var \Mpdf\Language\LanguageToFontInterface + */ + private $languageToFont; + + /** + * @param \Mpdf\Mpdf $mpdf + * @param \Mpdf\Cache $cache + * @param \Mpdf\CssManager $cssManager + * @param \Mpdf\Form $form + * @param \Mpdf\Otl $otl + * @param \Mpdf\TableOfContents $tableOfContents + * @param \Mpdf\SizeConverter $sizeConverter + * @param \Mpdf\Color\ColorConverter $colorConverter + * @param \Mpdf\Image\ImageProcessor $imageProcessor + * @param \Mpdf\Language\LanguageToFontInterface $languageToFont + */ + public function __construct( + Mpdf $mpdf, + Cache $cache, + CssManager $cssManager, + Form $form, + Otl $otl, + TableOfContents $tableOfContents, + SizeConverter $sizeConverter, + ColorConverter $colorConverter, + ImageProcessor $imageProcessor, + LanguageToFontInterface $languageToFont + ) { + + $this->mpdf = $mpdf; + $this->cache = $cache; + $this->cssManager = $cssManager; + $this->form = $form; + $this->otl = $otl; + $this->tableOfContents = $tableOfContents; + $this->sizeConverter = $sizeConverter; + $this->colorConverter = $colorConverter; + $this->imageProcessor = $imageProcessor; + $this->languageToFont = $languageToFont; + } + + /** + * @param string $tag The tag name + * @return \Mpdf\Tag\Tag + */ + private function getTagInstance($tag) + { + $className = self::getTagClassName($tag); + if (class_exists($className)) { + return new $className( + $this->mpdf, + $this->cache, + $this->cssManager, + $this->form, + $this->otl, + $this->tableOfContents, + $this->sizeConverter, + $this->colorConverter, + $this->imageProcessor, + $this->languageToFont + ); + } + } + + /** + * Returns the fully qualified name of the class handling the rendering of the given tag + * + * @param string $tag The tag name + * @return string The fully qualified name + */ + public static function getTagClassName($tag) + { + static $map = [ + 'BARCODE' => 'BarCode', + 'BLOCKQUOTE' => 'BlockQuote', + 'COLUMN_BREAK' => 'ColumnBreak', + 'COLUMNBREAK' => 'ColumnBreak', + 'DOTTAB' => 'DotTab', + 'FIELDSET' => 'FieldSet', + 'FIGCAPTION' => 'FigCaption', + 'FORMFEED' => 'FormFeed', + 'HGROUP' => 'HGroup', + 'INDEXENTRY' => 'IndexEntry', + 'INDEXINSERT' => 'IndexInsert', + 'NEWCOLUMN' => 'NewColumn', + 'NEWPAGE' => 'NewPage', + 'PAGEFOOTER' => 'PageFooter', + 'PAGEHEADER' => 'PageHeader', + 'PAGE_BREAK' => 'PageBreak', + 'PAGEBREAK' => 'PageBreak', + 'SETHTMLPAGEFOOTER' => 'SetHtmlPageFooter', + 'SETHTMLPAGEHEADER' => 'SetHtmlPageHeader', + 'SETPAGEFOOTER' => 'SetPageFooter', + 'SETPAGEHEADER' => 'SetPageHeader', + 'TBODY' => 'TBody', + 'TFOOT' => 'TFoot', + 'THEAD' => 'THead', + 'TEXTAREA' => 'TextArea', + 'TEXTCIRCLE' => 'TextCircle', + 'TOCENTRY' => 'TocEntry', + 'TOCPAGEBREAK' => 'TocPageBreak', + 'VAR' => 'VarTag', + 'WATERMARKIMAGE' => 'WatermarkImage', + 'WATERMARKTEXT' => 'WatermarkText', + ]; + + $className = 'Mpdf\Tag\\'; + $className .= isset($map[$tag]) ? $map[$tag] : ucfirst(strtolower($tag)); + + return $className; + } + + public function OpenTag($tag, $attr, &$ahtml, &$ihtml) + { + // Correct for tags where HTML5 specifies optional end tags excluding table elements (cf WriteHTML() ) + if ($this->mpdf->allow_html_optional_endtags) { + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['tag'])) { + $closed = false; + // li end tag may be omitted if immediately followed by another li element + if (!$closed && $this->mpdf->blk[$this->mpdf->blklvl]['tag'] == 'LI' && $tag == 'LI') { + $this->CloseTag('LI', $ahtml, $ihtml); + $closed = true; + } + // dt end tag may be omitted if immediately followed by another dt element or a dd element + if (!$closed && $this->mpdf->blk[$this->mpdf->blklvl]['tag'] == 'DT' && ($tag == 'DT' || $tag == 'DD')) { + $this->CloseTag('DT', $ahtml, $ihtml); + $closed = true; + } + // dd end tag may be omitted if immediately followed by another dd element or a dt element + if (!$closed && $this->mpdf->blk[$this->mpdf->blklvl]['tag'] == 'DD' && ($tag == 'DT' || $tag == 'DD')) { + $this->CloseTag('DD', $ahtml, $ihtml); + $closed = true; + } + // p end tag may be omitted if immediately followed by an address, article, aside, blockquote, div, dl, + // fieldset, form, h1, h2, h3, h4, h5, h6, hgroup, hr, main, nav, ol, p, pre, section, table, ul + if (!$closed && $this->mpdf->blk[$this->mpdf->blklvl]['tag'] == 'P' + && ($tag == 'P' || $tag == 'DIV' || $tag == 'H1' || $tag == 'H2' || $tag == 'H3' + || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' || $tag == 'UL' || $tag == 'OL' + || $tag == 'TABLE' || $tag == 'PRE' || $tag == 'FORM' || $tag == 'ADDRESS' || $tag == 'BLOCKQUOTE' + || $tag == 'CENTER' || $tag == 'DL' || $tag == 'HR' || $tag == 'ARTICLE' || $tag == 'ASIDE' + || $tag == 'FIELDSET' || $tag == 'HGROUP' || $tag == 'MAIN' || $tag == 'NAV' || $tag == 'SECTION')) { + $this->CloseTag('P', $ahtml, $ihtml); + $closed = true; + } + // option end tag may be omitted if immediately followed by another option element + // (or if it is immediately followed by an optgroup element) + if (!$closed && $this->mpdf->blk[$this->mpdf->blklvl]['tag'] == 'OPTION' && $tag == 'OPTION') { + $this->CloseTag('OPTION', $ahtml, $ihtml); + $closed = true; + } + // Table elements - see also WriteHTML() + if (!$closed && ($tag == 'TD' || $tag == 'TH') && $this->mpdf->lastoptionaltag == 'TD') { + $this->CloseTag($this->mpdf->lastoptionaltag, $ahtml, $ihtml); + $closed = true; + } // *TABLES* + if (!$closed && ($tag == 'TD' || $tag == 'TH') && $this->mpdf->lastoptionaltag == 'TH') { + $this->CloseTag($this->mpdf->lastoptionaltag, $ahtml, $ihtml); + $closed = true; + } // *TABLES* + if (!$closed && $tag == 'TR' && $this->mpdf->lastoptionaltag == 'TR') { + $this->CloseTag($this->mpdf->lastoptionaltag, $ahtml, $ihtml); + $closed = true; + } // *TABLES* + if (!$closed && $tag == 'TR' && $this->mpdf->lastoptionaltag == 'TD') { + $this->CloseTag($this->mpdf->lastoptionaltag, $ahtml, $ihtml); + $this->CloseTag('TR', $ahtml, $ihtml); + $this->CloseTag('THEAD', $ahtml, $ihtml); + $closed = true; + } // *TABLES* + if (!$closed && $tag == 'TR' && $this->mpdf->lastoptionaltag == 'TH') { + $this->CloseTag($this->mpdf->lastoptionaltag, $ahtml, $ihtml); + $this->CloseTag('TR', $ahtml, $ihtml); + $this->CloseTag('THEAD', $ahtml, $ihtml); + $closed = true; + } // *TABLES* + } + } + + if ($object = $this->getTagInstance($tag)) { + return $object->open($attr, $ahtml, $ihtml); + } + } + + public function CloseTag($tag, &$ahtml, &$ihtml) + { + if ($object = $this->getTagInstance($tag)) { + return $object->close($ahtml, $ihtml); + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/A.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/A.php new file mode 100644 index 0000000..6a6488b --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/A.php @@ -0,0 +1,50 @@ +<?php + +namespace Mpdf\Tag; + +class A extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + if (isset($attr['NAME']) && $attr['NAME'] != '') { + $e = ''; + /* -- BOOKMARKS -- */ + if ($this->mpdf->anchor2Bookmark) { + $objattr = []; + $objattr['CONTENT'] = htmlspecialchars_decode($attr['NAME'], ENT_QUOTES); + $objattr['type'] = 'bookmark'; + if (!empty($attr['LEVEL'])) { + $objattr['bklevel'] = $attr['LEVEL']; + } else { + $objattr['bklevel'] = 0; + } + $e = "\xbb\xa4\xactype=bookmark,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + } + /* -- END BOOKMARKS -- */ + if ($this->mpdf->tableLevel) { // *TABLES* + $this->mpdf->_saveCellTextBuffer($e, '', $attr['NAME']); // *TABLES* + } // *TABLES* + else { // *TABLES* + $this->mpdf->_saveTextBuffer($e, '', $attr['NAME']); //an internal link (adds a space for recognition) + } // *TABLES* + } + if (isset($attr['HREF'])) { + $this->mpdf->InlineProperties['A'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('INLINE', 'A', $attr); + if (!empty($properties)) { + $this->mpdf->setCSS($properties, 'INLINE'); + } + $this->mpdf->HREF = $attr['HREF']; // mPDF 5.7.4 URLs + } + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->HREF = ''; + if (isset($this->mpdf->InlineProperties['A'])) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['A']); + } + unset($this->mpdf->InlineProperties['A']); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Acronym.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Acronym.php new file mode 100644 index 0000000..e33eea5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Acronym.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Acronym extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Address.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Address.php new file mode 100644 index 0000000..44b5b3c --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Address.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Address extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Annotation.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Annotation.php new file mode 100644 index 0000000..6ed5e0e --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Annotation.php @@ -0,0 +1,99 @@ +<?php + +namespace Mpdf\Tag; + +class Annotation extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + //if (isset($attr['CONTENT']) && !$this->mpdf->writingHTMLheader && !$this->mpdf->writingHTMLfooter) { // Stops annotations in FixedPos + if (isset($attr['CONTENT'])) { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES); + $objattr['type'] = 'annot'; + $objattr['POPUP'] = ''; + } else { + return; + } + if (isset($attr['POS-X'])) { + $objattr['POS-X'] = $attr['POS-X']; + } else { + $objattr['POS-X'] = 0; + } + if (isset($attr['POS-Y'])) { + $objattr['POS-Y'] = $attr['POS-Y']; + } else { + $objattr['POS-Y'] = 0; + } + if (isset($attr['ICON'])) { + $objattr['ICON'] = $attr['ICON']; + } else { + $objattr['ICON'] = 'Note'; + } + if (isset($attr['AUTHOR'])) { + $objattr['AUTHOR'] = $attr['AUTHOR']; + } elseif (isset($attr['TITLE'])) { + $objattr['AUTHOR'] = $attr['TITLE']; + } else { + $objattr['AUTHOR'] = ''; + } + if (isset($attr['FILE'])) { + $objattr['FILE'] = $attr['FILE']; + } else { + $objattr['FILE'] = ''; + } + if (isset($attr['SUBJECT'])) { + $objattr['SUBJECT'] = $attr['SUBJECT']; + } else { + $objattr['SUBJECT'] = ''; + } + if (isset($attr['OPACITY']) && $attr['OPACITY'] > 0 && $attr['OPACITY'] <= 1) { + $objattr['OPACITY'] = $attr['OPACITY']; + } elseif ($this->mpdf->annotMargin) { + $objattr['OPACITY'] = 1; + } else { + $objattr['OPACITY'] = $this->mpdf->annotOpacity; + } + if (isset($attr['COLOR'])) { + $cor = $this->colorConverter->convert($attr['COLOR'], $this->mpdf->PDFAXwarnings); + if ($cor) { + $objattr['COLOR'] = $cor; + } else { + $objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings); + } + } else { + $objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings); + } + + if (isset($attr['POPUP']) && !empty($attr['POPUP'])) { + $pop = preg_split('/\s+/', trim($attr['POPUP'])); + if (count($pop) > 1) { + $objattr['POPUP'] = $pop; + } else { + $objattr['POPUP'] = true; + } + } + $e = "\xbb\xa4\xactype=annot,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$e]; + } // *TABLES* + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Article.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Article.php new file mode 100644 index 0000000..180d69d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Article.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Article extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Aside.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Aside.php new file mode 100644 index 0000000..fa7e697 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Aside.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Aside extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/B.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/B.php new file mode 100644 index 0000000..15e2eb3 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/B.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class B extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BarCode.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BarCode.php new file mode 100644 index 0000000..e80fe59 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BarCode.php @@ -0,0 +1,256 @@ +<?php + +namespace Mpdf\Tag; + +class BarCode extends Tag +{ + + /** + * @var \Mpdf\Barcode + */ + protected $barcode; + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->ignorefollowingspaces = false; + if (!empty($attr['CODE'])) { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['code'] = $attr['CODE']; + + if (isset($attr['TYPE'])) { + $objattr['btype'] = strtoupper(trim($attr['TYPE'])); + } else { + $objattr['btype'] = 'EAN13'; + } // default + if (preg_match('/^(EAN13|ISBN|ISSN|EAN8|UPCA|UPCE)P([25])$/', $objattr['btype'], $m)) { + $objattr['btype'] = $m[1]; + $objattr['bsupp'] = $m[2]; + if (preg_match('/^(\S+)\s+(.*)$/', $objattr['code'], $mm)) { + $objattr['code'] = $mm[1]; + $objattr['bsupp_code'] = $mm[2]; + } + } else { + $objattr['bsupp'] = 0; + } + + if (isset($attr['TEXT']) && $attr['TEXT'] == 1) { + $objattr['showtext'] = 1; + } else { + $objattr['showtext'] = 0; + } + if (isset($attr['SIZE']) && $attr['SIZE'] > 0) { + $objattr['bsize'] = $attr['SIZE']; + } else { + $objattr['bsize'] = 1; + } + if (isset($attr['HEIGHT']) && $attr['HEIGHT'] > 0) { + $objattr['bheight'] = $attr['HEIGHT']; + } else { + $objattr['bheight'] = 1; + } + if (isset($attr['PR']) && $attr['PR'] > 0) { + $objattr['pr_ratio'] = $attr['PR']; + } else { + $objattr['pr_ratio'] = ''; + } + $properties = $this->cssManager->MergeCSS('', 'BARCODE', $attr); + if (isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY']) === 'none') { + return; + } + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-LEFT'])) { + $objattr['margin_left'] = $this->sizeConverter->convert( + $properties['MARGIN-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-RIGHT'])) { + $objattr['margin_right'] = $this->sizeConverter->convert( + $properties['MARGIN-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['PADDING-TOP'])) { + $objattr['padding_top'] = $this->sizeConverter->convert( + $properties['PADDING-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-BOTTOM'])) { + $objattr['padding_bottom'] = $this->sizeConverter->convert( + $properties['PADDING-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-LEFT'])) { + $objattr['padding_left'] = $this->sizeConverter->convert( + $properties['PADDING-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-RIGHT'])) { + $objattr['padding_right'] = $this->sizeConverter->convert( + $properties['PADDING-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['BORDER-TOP'])) { + $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + } + if (isset($properties['BORDER-LEFT'])) { + $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } + if (isset($properties['BORDER-RIGHT'])) { + $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } + + if (isset($properties['VERTICAL-ALIGN'])) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + if (isset($properties['COLOR']) && $properties['COLOR'] != '') { + $objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } else { + $objattr['color'] = false; + } + if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { + $objattr['bgcolor'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); + } else { + $objattr['bgcolor'] = false; + } + + $this->barcode = new \Mpdf\Barcode(); + + if (in_array($objattr['btype'], ['EAN13', 'ISBN', 'ISSN', 'UPCA', 'UPCE', 'EAN8'])) { + + $code = preg_replace('/\-/', '', $objattr['code']); + $arrcode = $this->barcode->getBarcodeArray($code, $objattr['btype']); + + if ($objattr['bsupp'] == 2 || $objattr['bsupp'] == 5) { // EAN-2 or -5 Supplement + $supparrcode = $this->barcode->getBarcodeArray($objattr['bsupp_code'], 'EAN' . $objattr['bsupp']); + $w = ($arrcode['maxw'] + $arrcode['lightmL'] + $arrcode['lightmR'] + + $supparrcode['maxw'] + $supparrcode['sepM']) * $arrcode['nom-X'] * $objattr['bsize']; + } else { + $w = ($arrcode['maxw'] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize']; + } + + $h = $arrcode['nom-H'] * $objattr['bsize'] * $objattr['bheight']; + // Add height for ISBN string + margin from top of bars + if (($objattr['showtext'] && $objattr['btype'] === 'EAN13') || $objattr['btype'] === 'ISBN' || $objattr['btype'] === 'ISSN') { + $tisbnm = 1.5 * $objattr['bsize']; // Top margin between TOP TEXT (isbn - if shown) & bars + $isbn_fontsize = 2.1 * $objattr['bsize']; + $h += $isbn_fontsize + $tisbnm; + } + + } elseif ($objattr['btype'] === 'QR') { // QR-code + $w = $h = $objattr['bsize'] * 25; // Factor of 25mm (default) + $objattr['errorlevel'] = 'L'; + if (isset($attr['ERROR'])) { + $objattr['errorlevel'] = $attr['ERROR']; + } + $objattr['disableborder'] = false; + if (isset($attr['DISABLEBORDER'])) { + $objattr['disableborder'] = (bool) $attr['DISABLEBORDER']; + } + + } elseif (in_array($objattr['btype'], ['IMB', 'RM4SCC', 'KIX', 'POSTNET', 'PLANET'])) { + + $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype']); + + $w = ($arrcode['maxw'] * $arrcode['nom-X'] * $objattr['bsize']) + $arrcode['quietL'] + $arrcode['quietR']; + $h = ($arrcode['nom-H'] * $objattr['bsize']) + (2 * $arrcode['quietTB']); + + } elseif (in_array($objattr['btype'], ['C128A', 'C128B', 'C128C', 'EAN128A', 'EAN128B', 'EAN128C', + 'C39', 'C39+', 'C39E', 'C39E+', 'S25', 'S25+', 'I25', 'I25+', 'I25B', + 'I25B+', 'C93', 'MSI', 'MSI+', 'CODABAR', 'CODE11'])) { + + $arrcode = $this->barcode->getBarcodeArray($objattr['code'], $objattr['btype'], $objattr['pr_ratio']); + $w = ($arrcode['maxw'] + $arrcode['lightmL'] + $arrcode['lightmR']) * $arrcode['nom-X'] * $objattr['bsize']; + $h = ((2 * $arrcode['lightTB'] * $arrcode['nom-X']) + $arrcode['nom-H']) * $objattr['bsize'] * $objattr['bheight']; + + } else { + return; + } + + $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; + $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; + + $objattr['type'] = 'barcode'; + $objattr['height'] = $h + $extraheight; + $objattr['width'] = $w + $extrawidth; + $objattr['barcode_height'] = $h; + $objattr['barcode_width'] = $w; + + /* -- CSS-IMAGE-FLOAT -- */ + if (!$this->mpdf->ColActive && !$this->mpdf->tableLevel && !$this->mpdf->listlvl && !$this->mpdf->kwt) { + if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) === 'RIGHT' || strtoupper($properties['FLOAT']) === 'LEFT')) { + $objattr['float'] = strtoupper(substr($properties['FLOAT'], 0, 1)); + } + } + /* -- END CSS-IMAGE-FLOAT -- */ + + $e = "\xbb\xa4\xactype=barcode,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdi.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdi.php new file mode 100644 index 0000000..3de3ec5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdi.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Bdi extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdo.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdo.php new file mode 100644 index 0000000..6435d3f --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bdo.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Bdo extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Big.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Big.php new file mode 100644 index 0000000..fffd893 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Big.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Big extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockQuote.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockQuote.php new file mode 100644 index 0000000..44287ca --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockQuote.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class BlockQuote extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockTag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockTag.php new file mode 100644 index 0000000..cbe4bc5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/BlockTag.php @@ -0,0 +1,1352 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Conversion\DecToAlpha; +use Mpdf\Conversion\DecToRoman; + +use Mpdf\Utils\Arrays; +use Mpdf\Utils\UtfString; + +abstract class BlockTag extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + + // mPDF 6 Lists + $this->mpdf->lastoptionaltag = ''; + + // mPDF 6 bidi + // Block + // If unicode-bidi set on current clock, any embedding levels, isolates, or overrides are closed (not inherited) + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['bidicode'])) { + $blockpost = $this->mpdf->_setBidiCodes('end', $this->mpdf->blk[$this->mpdf->blklvl]['bidicode']); + if ($blockpost) { + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($blockpost); + } else { + $this->mpdf->_saveTextBuffer($blockpost); + } + } + } + + + $p = $this->cssManager->PreviewBlockCSS($tag, $attr); + if (isset($p['DISPLAY']) && strtolower($p['DISPLAY']) === 'none') { + $this->mpdf->blklvl++; + $this->mpdf->blk[$this->mpdf->blklvl]['hide'] = true; + $this->mpdf->blk[$this->mpdf->blklvl]['tag'] = $tag; // mPDF 6 + return; + } + if ($tag === 'CAPTION') { + // position is written in AdjstHTML + $divpos = 'T'; + if (isset($attr['POSITION']) && strtolower($attr['POSITION']) === 'bottom') { + $divpos = 'B'; + } + + $cappos = 'T'; + if (isset($attr['ALIGN']) && strtolower($attr['ALIGN']) === 'bottom') { + $cappos = 'B'; + } elseif (isset($p['CAPTION-SIDE']) && strtolower($p['CAPTION-SIDE']) === 'bottom') { + $cappos = 'B'; + } + if (isset($attr['ALIGN'])) { + unset($attr['ALIGN']); + } + if ($cappos != $divpos) { + $this->mpdf->blklvl++; + $this->mpdf->blk[$this->mpdf->blklvl]['hide'] = true; + $this->mpdf->blk[$this->mpdf->blklvl]['tag'] = $tag; // mPDF 6 + return; + } + } + + /* -- FORMS -- */ + if ($tag === 'FORM') { + $this->form->formMethod = 'POST'; + if (isset($attr['METHOD']) && strtolower($attr['METHOD']) === 'get') { + $this->form->formMethod = 'GET'; + } + + $this->form->formAction = ''; + if (isset($attr['ACTION'])) { + $this->form->formAction = $attr['ACTION']; + } + } + /* -- END FORMS -- */ + + + /* -- CSS-POSITION -- */ + if ((isset($p['POSITION']) + && (strtolower($p['POSITION']) === 'fixed' + || strtolower($p['POSITION']) === 'absolute')) + && $this->mpdf->blklvl == 0) { + if ($this->mpdf->inFixedPosBlock) { + throw new \Mpdf\MpdfException('Cannot nest block with position:fixed or position:absolute'); + } + $this->mpdf->inFixedPosBlock = true; + return; + } + /* -- END CSS-POSITION -- */ + // Start Block + $this->mpdf->ignorefollowingspaces = true; + + $lastbottommargin = 0; + if ($this->mpdf->blockjustfinished && !count($this->mpdf->textbuffer) + && $this->mpdf->y != $this->mpdf->tMargin + && $this->mpdf->collapseBlockMargins) { + $lastbottommargin = $this->mpdf->lastblockbottommargin; + } + $this->mpdf->lastblockbottommargin = 0; + $this->mpdf->blockjustfinished = false; + + + $this->mpdf->InlineBDF = []; // mPDF 6 + $this->mpdf->InlineBDFctr = 0; // mPDF 6 + $this->mpdf->InlineProperties = []; + $this->mpdf->divbegin = true; + + $this->mpdf->linebreakjustfinished = false; + + /* -- TABLES -- */ + if ($this->mpdf->tableLevel) { + // If already something on the line + if ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] > 0 && !$this->mpdf->nestedtablejustfinished) { + $this->mpdf->_saveCellTextBuffer("\n"); + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; // reset + } + // Cannot set block properties inside table - use Bold to indicate h1-h6 + if ($tag === 'CENTER' && $this->mpdf->tdbegin) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['a'] = self::ALIGN['center']; + } + + $this->mpdf->InlineProperties['BLOCKINTABLE'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('', $tag, $attr); + if (!empty($properties)) { + $this->mpdf->setCSS($properties, 'INLINE'); + } + + // mPDF 6 Lists + if ($tag === 'UL' || $tag === 'OL') { + $this->mpdf->listlvl++; + if (isset($attr['START'])) { + $this->mpdf->listcounter[$this->mpdf->listlvl] = (int) $attr['START'] - 1; + } else { + $this->mpdf->listcounter[$this->mpdf->listlvl] = 0; + } + $this->mpdf->listitem = []; + if ($tag === 'OL') { + $this->mpdf->listtype[$this->mpdf->listlvl] = 'decimal'; + } elseif ($tag === 'UL') { + if ($this->mpdf->listlvl % 3 == 1) { + $this->mpdf->listtype[$this->mpdf->listlvl] = 'disc'; + } elseif ($this->mpdf->listlvl % 3 == 2) { + $this->mpdf->listtype[$this->mpdf->listlvl] = 'circle'; + } else { + $this->mpdf->listtype[$this->mpdf->listlvl] = 'square'; + } + } + } + + // mPDF 6 Lists - in Tables + if ($tag === 'LI') { + + if ($this->mpdf->listlvl == 0) { //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...) + $this->mpdf->listlvl++; // first depth level + $this->mpdf->listcounter[$this->mpdf->listlvl] = 0; + } + + $this->mpdf->listcounter[$this->mpdf->listlvl]++; + $this->mpdf->listitem = []; + //if in table - output here as a tabletextbuffer + //position:inside OR position:outside (always output in table as position:inside) + + $decToAlpha = new DecToAlpha(); + $decToRoman = new DecToRoman(); + + switch ($this->mpdf->listtype[$this->mpdf->listlvl]) { + case 'upper-alpha': + case 'upper-latin': + case 'A': + $blt = $decToAlpha->convert($this->mpdf->listcounter[$this->mpdf->listlvl]) . $this->mpdf->list_number_suffix; + break; + case 'lower-alpha': + case 'lower-latin': + case 'a': + $blt = $decToAlpha->convert($this->mpdf->listcounter[$this->mpdf->listlvl], false) . $this->mpdf->list_number_suffix; + break; + case 'upper-roman': + case 'I': + $blt = $decToRoman->convert($this->mpdf->listcounter[$this->mpdf->listlvl]) . $this->mpdf->list_number_suffix; + break; + case 'lower-roman': + case 'i': + $blt = $decToRoman->convert($this->mpdf->listcounter[$this->mpdf->listlvl]) . $this->mpdf->list_number_suffix; + break; + case 'decimal': + case '1': + $blt = $this->mpdf->listcounter[$this->mpdf->listlvl] . $this->mpdf->list_number_suffix; + break; + default: + $blt = '-'; + if ($this->mpdf->listlvl % 3 == 1 && $this->mpdf->_charDefined($this->mpdf->CurrentFont['cw'], 8226)) { + $blt = "\xe2\x80\xa2"; + } // • + elseif ($this->mpdf->listlvl % 3 == 2 && $this->mpdf->_charDefined($this->mpdf->CurrentFont['cw'], 9900)) { + $blt = "\xe2\x9a\xac"; + } // ⚬ + elseif ($this->mpdf->listlvl % 3 == 0 && $this->mpdf->_charDefined($this->mpdf->CurrentFont['cw'], 9642)) { + $blt = "\xe2\x96\xaa"; + } // ▪ + break; + } + + // change to   spaces + if ($this->mpdf->usingCoreFont) { + $ls = str_repeat(chr(160) . chr(160), ($this->mpdf->listlvl - 1) * 2) . $blt . ' '; + } else { + $ls = str_repeat("\xc2\xa0\xc2\xa0", ($this->mpdf->listlvl - 1) * 2) . $blt . ' '; + } + $this->mpdf->_saveCellTextBuffer($ls); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $this->mpdf->GetStringWidth($ls); + } + + return; + } + /* -- END TABLES -- */ + + if ($this->mpdf->lastblocklevelchange == 1) { + $blockstate = 1; + } // Top margins/padding only + elseif ($this->mpdf->lastblocklevelchange < 1) { + $blockstate = 0; + } // NO margins/padding + + $this->mpdf->printbuffer($this->mpdf->textbuffer, $blockstate); + $this->mpdf->textbuffer = []; + + $save_blklvl = $this->mpdf->blklvl; + $save_blk = $this->mpdf->blk; + + $this->mpdf->Reset(); + + $pagesel = ''; + /* -- CSS-PAGE -- */ + if (isset($p['PAGE'])) { + $pagesel = $p['PAGE']; + } // mPDF 6 (uses $p - preview of properties so blklvl can be incremented after page-break) + /* -- END CSS-PAGE -- */ + + // If page-box has changed AND/OR PAGE-BREAK-BEFORE + // mPDF 6 (uses $p - preview of properties so blklvl can be imcremented after page-break) + if (!$this->mpdf->tableLevel && (($pagesel && (!isset($this->mpdf->page_box['current']) + || $pagesel != $this->mpdf->page_box['current'])) + || (isset($p['PAGE-BREAK-BEFORE']) + && $p['PAGE-BREAK-BEFORE']))) { + // mPDF 6 pagebreaktype + $startpage = $this->mpdf->page; + $pagebreaktype = $this->mpdf->defaultPagebreakType; + $this->mpdf->lastblocklevelchange = -1; + if ($this->mpdf->ColActive) { + $pagebreaktype = 'cloneall'; + } + if ($pagesel && (!isset($this->mpdf->page_box['current']) || $pagesel != $this->mpdf->page_box['current'])) { + $pagebreaktype = 'cloneall'; + } + $this->mpdf->_preForcedPagebreak($pagebreaktype); + + if (isset($p['PAGE-BREAK-BEFORE'])) { + if (strtoupper($p['PAGE-BREAK-BEFORE']) === 'RIGHT') { + $this->mpdf->AddPage( + $this->mpdf->CurOrientation, + 'NEXT-ODD', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 0, + 0, + 0, + 0, + $pagesel + ); + } elseif (strtoupper($p['PAGE-BREAK-BEFORE']) === 'LEFT') { + $this->mpdf->AddPage( + $this->mpdf->CurOrientation, + 'NEXT-EVEN', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + 0, + 0, + 0, + 0, + $pagesel + ); + } elseif (strtoupper($p['PAGE-BREAK-BEFORE']) === 'ALWAYS') { + $this->mpdf->AddPage($this->mpdf->CurOrientation, '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, $pagesel); + } elseif ($this->mpdf->page_box['current'] != $pagesel) { + $this->mpdf->AddPage($this->mpdf->CurOrientation, '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, $pagesel); + } // *CSS-PAGE* + } /* -- CSS-PAGE -- */ + // Must Add new page if changed page properties + elseif (!isset($this->mpdf->page_box['current']) || $pagesel != $this->mpdf->page_box['current']) { + $this->mpdf->AddPage($this->mpdf->CurOrientation, '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, $pagesel); + } + /* -- END CSS-PAGE -- */ + + // mPDF 6 pagebreaktype + $this->mpdf->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl); + } + + // mPDF 6 pagebreaktype - moved after pagebreak + $this->mpdf->blklvl++; + $currblk = & $this->mpdf->blk[$this->mpdf->blklvl]; + $this->mpdf->initialiseBlock($currblk); + $prevblk = & $this->mpdf->blk[$this->mpdf->blklvl - 1]; + $currblk['tag'] = $tag; + $currblk['attr'] = $attr; + + $properties = $this->cssManager->MergeCSS('BLOCK', $tag, $attr); // mPDF 6 - moved to after page-break-before + // mPDF 6 page-break-inside:avoid + if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) === 'AVOID' + && !$this->mpdf->ColActive && !$this->mpdf->keep_block_together && !isset($attr['PAGEBREAKAVOIDCHECKED'])) { + // avoid re-iterating using PAGEBREAKAVOIDCHECKED; set in CloseTag + $currblk['keep_block_together'] = 1; + $currblk['array_i'] = $ihtml; // mPDF 6 + $this->mpdf->kt_y00 = $this->mpdf->y; + $this->mpdf->kt_p00 = $this->mpdf->page; + $this->mpdf->keep_block_together = 1; + } + if ($lastbottommargin && !empty($properties['MARGIN-TOP']) && empty($properties['FLOAT'])) { + $currblk['lastbottommargin'] = $lastbottommargin; + } + + if (isset($properties['Z-INDEX']) && $this->mpdf->current_layer == 0) { + $v = (int) $properties['Z-INDEX']; + if ($v > 0) { + $currblk['z-index'] = $v; + $this->mpdf->BeginLayer($v); + } + } + + + // mPDF 6 Lists + // List-type set by attribute + if ($tag === 'OL' || $tag === 'UL' || $tag === 'LI') { + if (!empty($attr['TYPE'])) { + $listtype = $attr['TYPE']; + switch ($listtype) { + case 'A': + $listtype = 'upper-latin'; + break; + case 'a': + $listtype = 'lower-latin'; + break; + case 'I': + $listtype = 'upper-roman'; + break; + case 'i': + $listtype = 'lower-roman'; + break; + case '1': + $listtype = 'decimal'; + break; + } + $currblk['list_style_type'] = $listtype; + } + } + + $this->mpdf->setCSS($properties, 'BLOCK', $tag); //name(id/class/style) found in the CSS array! + $currblk['InlineProperties'] = $this->mpdf->saveInlineProperties(); + + if (isset($properties['VISIBILITY'])) { + $v = strtolower($properties['VISIBILITY']); + if (($v === 'hidden' || $v === 'printonly' || $v === 'screenonly') && $this->mpdf->visibility === 'visible' && !$this->mpdf->tableLevel) { + $currblk['visibility'] = $v; + $this->mpdf->SetVisibility($v); + } + } + + // mPDF 6 + if (!empty($attr['ALIGN'])) { + $currblk['block-align'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } + + + if (isset($properties['HEIGHT'])) { + $currblk['css_set_height'] = $this->sizeConverter->convert( + $properties['HEIGHT'], + $this->mpdf->h - $this->mpdf->tMargin - $this->mpdf->bMargin, + $this->mpdf->FontSize, + false + ); + if (($currblk['css_set_height'] + $this->mpdf->y) > $this->mpdf->PageBreakTrigger + && $this->mpdf->y > $this->mpdf->tMargin + 5 + && $currblk['css_set_height'] < ($this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin))) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + } else { + $currblk['css_set_height'] = false; + } + + + // Added mPDF 3.0 Float DIV + if (isset($prevblk['blockContext'])) { + $currblk['blockContext'] = $prevblk['blockContext']; + } // *CSS-FLOAT* + + if (isset($properties['CLEAR'])) { + $this->mpdf->ClearFloats(strtoupper($properties['CLEAR']), $this->mpdf->blklvl - 1); + } // *CSS-FLOAT* + + $currblk['padding_left'] = is_numeric($currblk['padding_left']) ? $currblk['padding_left'] : 0; + $currblk['padding_right'] = is_numeric($currblk['padding_right']) ? $currblk['padding_right'] : 0; + + $container_w = $prevblk['inner_width']; + $bdr = $currblk['border_right']['w']; + $bdl = $currblk['border_left']['w']; + $pdr = $currblk['padding_right']; + $pdl = $currblk['padding_left']; + + $setwidth = 0; + if (isset($currblk['css_set_width'])) { + $setwidth = $currblk['css_set_width']; + } + + /* -- CSS-FLOAT -- */ + if (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) === 'RIGHT' && !$this->mpdf->ColActive) { + + // Cancel Keep-Block-together + $currblk['keep_block_together'] = false; + $this->mpdf->kt_y00 = ''; + $this->mpdf->keep_block_together = 0; + + $this->mpdf->blockContext++; + $currblk['blockContext'] = $this->mpdf->blockContext; + + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + + // DIV is too narrow for text to fit! + $maxw = $container_w - $l_width - $r_width; + $doubleCharWidth = (2 * $this->mpdf->GetCharWidth('W', false)); + if (($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw + || ($maxw - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) < (2 * $this->mpdf->GetCharWidth('W', false))) { + // Too narrow to fit - try to move down past L or R float + if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) + && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('LEFT', $this->mpdf->blklvl - 1); + } elseif ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) + && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('RIGHT', $this->mpdf->blklvl - 1); + } else { + $this->mpdf->ClearFloats('BOTH', $this->mpdf->blklvl - 1); + } + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + } + + if ($r_exists) { + $currblk['margin_right'] += $r_width; + } + + $currblk['float'] = 'R'; + $currblk['float_start_y'] = $this->mpdf->y; + + if (isset($currblk['css_set_width'])) { + $currblk['margin_left'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']); + $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']); + } else { + // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width + // and do borders and backgrounds - For now - just set to maximum width left + + if ($l_exists) { + $currblk['margin_left'] += $l_width; + } + $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr); + + $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_right']); + } + + } elseif (isset($properties['FLOAT']) && strtoupper($properties['FLOAT']) === 'LEFT' && !$this->mpdf->ColActive) { + // Cancel Keep-Block-together + $currblk['keep_block_together'] = false; + $this->mpdf->kt_y00 = ''; + $this->mpdf->keep_block_together = 0; + + $this->mpdf->blockContext++; + $currblk['blockContext'] = $this->mpdf->blockContext; + + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + + // DIV is too narrow for text to fit! + $maxw = $container_w - $l_width - $r_width; + $doubleCharWidth = (2 * $this->mpdf->GetCharWidth('W', false)); + if (($setwidth + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr) > $maxw + || ($maxw - ($currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < (2 * $this->mpdf->GetCharWidth('W', false))) { + // Too narrow to fit - try to move down past L or R float + if ($l_max < $r_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) + && (($container_w - $r_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('LEFT', $this->mpdf->blklvl - 1); + } elseif ($r_max < $l_max && ($setwidth + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) + && (($container_w - $l_width) - ($currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('RIGHT', $this->mpdf->blklvl - 1); + } else { + $this->mpdf->ClearFloats('BOTH', $this->mpdf->blklvl - 1); + } + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + } + + if ($l_exists) { + $currblk['margin_left'] += $l_width; + } + + $currblk['float'] = 'L'; + $currblk['float_start_y'] = $this->mpdf->y; + if ($setwidth) { + $currblk['margin_right'] = $container_w - ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']); + $currblk['float_width'] = ($setwidth + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']); + } else { + // *** If no width set - would need to buffer and keep track of max width, then Right-align if not full width + // and do borders and backgrounds - For now - just set to maximum width left + + if ($r_exists) { + $currblk['margin_right'] += $r_width; + } + $currblk['css_set_width'] = $container_w - ($currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr); + + $currblk['float_width'] = ($currblk['css_set_width'] + $bdl + $pdl + $bdr + $pdr + $currblk['margin_left']); + } + } else { + // Don't allow overlap - if floats present - adjust padding to avoid overlap with Floats + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + $maxw = $container_w - $l_width - $r_width; + + $pdl = is_numeric($pdl) ? $pdl : 0; + $pdr = is_numeric($pdr) ? $pdr : 0; + + $doubleCharWidth = (2 * $this->mpdf->GetCharWidth('W', false)); + if (($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) > $maxw + || ($maxw - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) < $doubleCharWidth) { + // Too narrow to fit - try to move down past L or R float + if ($l_max < $r_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $r_width) + && (($container_w - $r_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('LEFT', $this->mpdf->blklvl - 1); + } elseif ($r_max < $l_max && ($setwidth + $currblk['margin_left'] + $currblk['margin_right'] + $bdl + $pdl + $bdr + $pdr) <= ($container_w - $l_width) + && (($container_w - $l_width) - ($currblk['margin_right'] + $currblk['margin_left'] + $bdl + $pdl + $bdr + $pdr)) > $doubleCharWidth) { + $this->mpdf->ClearFloats('RIGHT', $this->mpdf->blklvl - 1); + } else { + $this->mpdf->ClearFloats('BOTH', $this->mpdf->blklvl - 1); + } + list($l_exists, $r_exists, $l_max, $r_max, $l_width, $r_width) = $this->mpdf->GetFloatDivInfo($this->mpdf->blklvl - 1); + } + if ($r_exists) { + $currblk['padding_right'] = max($r_width - $currblk['margin_right'] - $bdr, $pdr); + } + if ($l_exists) { + $currblk['padding_left'] = max($l_width - $currblk['margin_left'] - $bdl, $pdl); + } + } + /* -- END CSS-FLOAT -- */ + + + /* -- BORDER-RADIUS -- */ + // Automatically increase padding if required for border-radius + if ($this->mpdf->autoPadding && !$this->mpdf->ColActive) { + $currblk['border_radius_TL_H'] = Arrays::get($currblk, 'border_radius_TL_H', 0); + $currblk['border_radius_TL_V'] = Arrays::get($currblk, 'border_radius_TL_V', 0); + $currblk['border_radius_TR_H'] = Arrays::get($currblk, 'border_radius_TR_H', 0); + $currblk['border_radius_TR_V'] = Arrays::get($currblk, 'border_radius_TR_V', 0); + $currblk['border_radius_BL_H'] = Arrays::get($currblk, 'border_radius_BL_H', 0); + $currblk['border_radius_BL_V'] = Arrays::get($currblk, 'border_radius_BL_V', 0); + $currblk['border_radius_BR_H'] = Arrays::get($currblk, 'border_radius_BR_H', 0); + $currblk['border_radius_BR_V'] = Arrays::get($currblk, 'border_radius_BR_V', 0); + + if ($currblk['border_radius_TL_H'] > $currblk['padding_left'] && $currblk['border_radius_TL_V'] > $currblk['padding_top']) { + if ($currblk['border_radius_TL_H'] > $currblk['border_radius_TL_V']) { + $this->mpdf->_borderPadding( + $currblk['border_radius_TL_H'], + $currblk['border_radius_TL_V'], + $currblk['padding_left'], + $currblk['padding_top'] + ); + } else { + $this->mpdf->_borderPadding( + $currblk['border_radius_TL_V'], + $currblk['border_radius_TL_H'], + $currblk['padding_top'], + $currblk['padding_left'] + ); + } + } + if ($currblk['border_radius_TR_H'] > $currblk['padding_right'] && $currblk['border_radius_TR_V'] > $currblk['padding_top']) { + if ($currblk['border_radius_TR_H'] > $currblk['border_radius_TR_V']) { + $this->mpdf->_borderPadding( + $currblk['border_radius_TR_H'], + $currblk['border_radius_TR_V'], + $currblk['padding_right'], + $currblk['padding_top'] + ); + } else { + $this->mpdf->_borderPadding( + $currblk['border_radius_TR_V'], + $currblk['border_radius_TR_H'], + $currblk['padding_top'], + $currblk['padding_right'] + ); + } + } + if ($currblk['border_radius_BL_H'] > $currblk['padding_left'] && $currblk['border_radius_BL_V'] > $currblk['padding_bottom']) { + if ($currblk['border_radius_BL_H'] > $currblk['border_radius_BL_V']) { + $this->mpdf->_borderPadding( + $currblk['border_radius_BL_H'], + $currblk['border_radius_BL_V'], + $currblk['padding_left'], + $currblk['padding_bottom'] + ); + } else { + $this->mpdf->_borderPadding( + $currblk['border_radius_BL_V'], + $currblk['border_radius_BL_H'], + $currblk['padding_bottom'], + $currblk['padding_left'] + ); + } + } + if ($currblk['border_radius_BR_H'] > $currblk['padding_right'] && $currblk['border_radius_BR_V'] > $currblk['padding_bottom']) { + if ($currblk['border_radius_BR_H'] > $currblk['border_radius_BR_V']) { + $this->mpdf->_borderPadding( + $currblk['border_radius_BR_H'], + $currblk['border_radius_BR_V'], + $currblk['padding_right'], + $currblk['padding_bottom'] + ); + } else { + $this->mpdf->_borderPadding( + $currblk['border_radius_BR_V'], + $currblk['border_radius_BR_H'], + $currblk['padding_bottom'], + $currblk['padding_right'] + ); + } + } + } + /* -- END BORDER-RADIUS -- */ + + // Hanging indent - if negative indent: ensure padding is >= indent + if (!isset($currblk['text_indent'])) { + $currblk['text_indent'] = null; + } + if (!isset($currblk['inner_width'])) { + $currblk['inner_width'] = null; + } + $cbti = $this->sizeConverter->convert( + $currblk['text_indent'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + if ($cbti < 0) { + $hangind = -$cbti; + if (isset($currblk['direction']) && $currblk['direction'] === 'rtl') { // *OTL* + $currblk['padding_right'] = max($currblk['padding_right'], $hangind); // *OTL* + } // *OTL* + else { // *OTL* + $currblk['padding_left'] = max($currblk['padding_left'], $hangind); + } // *OTL* + } + + if (isset($currblk['css_set_width'])) { + if (isset($properties['MARGIN-LEFT'], $properties['MARGIN-RIGHT']) + && strtolower($properties['MARGIN-LEFT']) === 'auto' && strtolower($properties['MARGIN-RIGHT']) === 'auto') { + // Try to reduce margins to accomodate - if still too wide, set margin-right/left=0 (reduces width) + $anyextra = $prevblk['inner_width'] - ($currblk['css_set_width'] + $currblk['border_left']['w'] + + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']); + if ($anyextra > 0) { + $currblk['margin_left'] = $currblk['margin_right'] = $anyextra / 2; + } else { + $currblk['margin_left'] = $currblk['margin_right'] = 0; + } + } elseif (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT']) === 'auto') { + // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width) + $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + + $currblk['padding_right'] + $currblk['margin_right']); + if ($currblk['margin_left'] < 0) { + $currblk['margin_left'] = 0; + } + } elseif (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT']) === 'auto') { + // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width) + $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + + $currblk['border_left']['w'] + $currblk['padding_left'] + + $currblk['border_right']['w'] + $currblk['padding_right'] + $currblk['margin_left']); + if ($currblk['margin_right'] < 0) { + $currblk['margin_right'] = 0; + } + } else { + if ($currblk['direction'] === 'rtl') { // *OTL* + // Try to reduce margin-left to accomodate - if still too wide, set margin-left=0 (reduces width) + $currblk['margin_left'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + + $currblk['padding_right'] + $currblk['margin_right']); // *OTL* + if ($currblk['margin_left'] < 0) { // *OTL* + $currblk['margin_left'] = 0; // *OTL* + } // *OTL* + } // *OTL* + else { // *OTL* + // Try to reduce margin-right to accomodate - if still too wide, set margin-right=0 (reduces width) + $currblk['margin_right'] = $prevblk['inner_width'] - ($currblk['css_set_width'] + + $currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + + $currblk['padding_right'] + $currblk['margin_left']); + if ($currblk['margin_right'] < 0) { + $currblk['margin_right'] = 0; + } + } // *OTL* + } + } + + $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + + $prevblk['border_left']['w'] + $prevblk['padding_left']; + + $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + + $prevblk['border_right']['w'] + $prevblk['padding_right']; + + $currblk['width'] = $this->mpdf->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']); + + $currblk['inner_width'] = $currblk['width'] + - ($currblk['border_left']['w'] + $currblk['padding_left'] + $currblk['border_right']['w'] + $currblk['padding_right']); + + // Check DIV is not now too narrow to fit text + $mw = 2 * $this->mpdf->GetCharWidth('W', false); + if ($currblk['inner_width'] < $mw) { + $currblk['padding_left'] = 0; + $currblk['padding_right'] = 0; + $currblk['border_left']['w'] = 0.2; + $currblk['border_right']['w'] = 0.2; + $currblk['margin_left'] = 0; + $currblk['margin_right'] = 0; + $currblk['outer_left_margin'] = $prevblk['outer_left_margin'] + $currblk['margin_left'] + + $prevblk['border_left']['w'] + $prevblk['padding_left']; + $currblk['outer_right_margin'] = $prevblk['outer_right_margin'] + $currblk['margin_right'] + + $prevblk['border_right']['w'] + $prevblk['padding_right']; + $currblk['width'] = $this->mpdf->pgwidth - ($currblk['outer_right_margin'] + $currblk['outer_left_margin']); + $currblk['inner_width'] = $this->mpdf->pgwidth - ($currblk['outer_right_margin'] + + $currblk['outer_left_margin'] + $currblk['border_left']['w'] + $currblk['padding_left'] + + $currblk['border_right']['w'] + $currblk['padding_right']); + // if ($currblk['inner_width'] < $mw) { throw new \Mpdf\MpdfException("DIV is too narrow for text to fit!"); } + } + + $this->mpdf->x = $this->mpdf->lMargin + $currblk['outer_left_margin']; + + /* -- BACKGROUNDS -- */ + if (!empty($properties['BACKGROUND-IMAGE']) && !$this->mpdf->kwt && !$this->mpdf->ColActive && !$this->mpdf->keep_block_together) { + $ret = $this->mpdf->SetBackground($properties, $currblk['inner_width']); + if ($ret) { + $currblk['background-image'] = $ret; + } + } + /* -- END BACKGROUNDS -- */ + + /* -- TABLES -- */ + if ($this->mpdf->use_kwt && isset($attr['KEEP-WITH-TABLE']) && !$this->mpdf->ColActive && !$this->mpdf->keep_block_together) { + $this->mpdf->kwt = true; + $this->mpdf->kwt_y0 = $this->mpdf->y; + //$this->mpdf->kwt_x0 = $this->mpdf->x; + $this->mpdf->kwt_x0 = $this->mpdf->lMargin; // mPDF 6 + $this->mpdf->kwt_height = 0; + $this->mpdf->kwt_buffer = []; + $this->mpdf->kwt_Links = []; + $this->mpdf->kwt_Annots = []; + $this->mpdf->kwt_moved = false; + $this->mpdf->kwt_saved = false; + $this->mpdf->kwt_Reference = []; + $this->mpdf->kwt_BMoutlines = []; + $this->mpdf->kwt_toc = []; + } else { + /* -- END TABLES -- */ + $this->mpdf->kwt = false; + } // *TABLES* + + // Save x,y coords in case we need to print borders... + $currblk['y0'] = $this->mpdf->y; + $currblk['initial_y0'] = $this->mpdf->y; // mPDF 6 + $currblk['x0'] = $this->mpdf->x; + $currblk['initial_x0'] = $this->mpdf->x; // mPDF 6 + $currblk['initial_startpage'] = $this->mpdf->page; + $currblk['startpage'] = $this->mpdf->page; // mPDF 6 + $this->mpdf->oldy = $this->mpdf->y; + + $this->mpdf->lastblocklevelchange = 1; + + // mPDF 6 Lists + if ($tag === 'OL' || $tag === 'UL') { + $this->mpdf->listlvl++; + if (!empty($attr['START'])) { + $this->mpdf->listcounter[$this->mpdf->listlvl] = (int) $attr['START'] - 1; + } else { + $this->mpdf->listcounter[$this->mpdf->listlvl] = 0; + } + $this->mpdf->listitem = []; + + // List-type + if (empty($currblk['list_style_type'])) { + if ($tag === 'OL') { + $currblk['list_style_type'] = 'decimal'; + } elseif ($tag === 'UL') { + if ($this->mpdf->listlvl % 3 == 1) { + $currblk['list_style_type'] = 'disc'; + } elseif ($this->mpdf->listlvl % 3 == 2) { + $currblk['list_style_type'] = 'circle'; + } else { + $currblk['list_style_type'] = 'square'; + } + } + } + + // List-image + if (empty($currblk['list_style_image'])) { + $currblk['list_style_image'] = 'none'; + } + + // List-position + if (empty($currblk['list_style_position'])) { + $currblk['list_style_position'] = 'outside'; + } + + // Default indentation using padding + if (strtolower($this->mpdf->list_auto_mode) === 'mpdf' && isset($currblk['list_style_position']) + && $currblk['list_style_position'] === 'outside' && isset($currblk['list_style_image']) + && $currblk['list_style_image'] === 'none' && (!isset($currblk['list_style_type']) + || !preg_match('/U\+([a-fA-F0-9]+)/i', $currblk['list_style_type']))) { + $autopadding = $this->mpdf->_getListMarkerWidth($currblk, $ahtml, $ihtml); + if ($this->mpdf->listlvl > 1 || $this->mpdf->list_indent_first_level) { + $autopadding += $this->sizeConverter->convert( + $this->mpdf->list_indent_default, + $currblk['inner_width'], + $this->mpdf->FontSize, + false + ); + } + // autopadding value is applied to left or right according + // to dir of block. Once a CSS value is set for padding it overrides this default value. + if (isset($properties['PADDING-RIGHT']) && $properties['PADDING-RIGHT'] === 'auto' + && isset($currblk['direction']) && $currblk['direction'] === 'rtl') { + $currblk['padding_right'] = $autopadding; + } elseif (isset($properties['PADDING-LEFT']) && $properties['PADDING-LEFT'] === 'auto') { + $currblk['padding_left'] = $autopadding; + } + } else { + // Initial default value is set by $this->mpdf->list_indent_default in config.php; this value is applied to left or right according + // to dir of block. Once a CSS value is set for padding it overrides this default value. + if (isset($properties['PADDING-RIGHT']) && $properties['PADDING-RIGHT'] === 'auto' + && isset($currblk['direction']) && $currblk['direction'] === 'rtl') { + $currblk['padding_right'] = $this->sizeConverter->convert( + $this->mpdf->list_indent_default, + $currblk['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($properties['PADDING-LEFT']) && $properties['PADDING-LEFT'] === 'auto') { + $currblk['padding_left'] = $this->sizeConverter->convert( + $this->mpdf->list_indent_default, + $currblk['inner_width'], + $this->mpdf->FontSize, + false + ); + } + } + } + + // mPDF 6 Lists + if ($tag === 'LI') { + if ($this->mpdf->listlvl == 0) { // in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...) + $this->mpdf->listlvl++; // first depth level + $this->mpdf->listcounter[$this->mpdf->listlvl] = 0; + } + + if (!isset($attr['PAGEBREAKAVOIDCHECKED']) || !$attr['PAGEBREAKAVOIDCHECKED']) { + $this->mpdf->listcounter[$this->mpdf->listlvl]++; + } + + $this->mpdf->listitem = []; + + // Listitem-type + $this->mpdf->_setListMarker($currblk['list_style_type'], $currblk['list_style_image'], $currblk['list_style_position']); + } + + // mPDF 6 Bidirectional formatting for block elements + $bdf = false; + $bdf2 = ''; + $popd = ''; + + // Get current direction + $currdir = 'ltr'; + if (isset($currblk['direction'])) { + $currdir = $currblk['direction']; + } + if (isset($attr['DIR']) && $attr['DIR'] != '') { + $currdir = strtolower($attr['DIR']); + } + if (isset($properties['DIRECTION'])) { + $currdir = strtolower($properties['DIRECTION']); + } + + // mPDF 6 bidi + // cf. http://www.w3.org/TR/css3-writing-modes/#unicode-bidi + if (isset($properties ['UNICODE-BIDI']) + && (strtolower($properties ['UNICODE-BIDI']) === 'bidi-override' || strtolower($properties ['UNICODE-BIDI']) === 'isolate-override')) { + if ($currdir === 'rtl') { + $bdf = 0x202E; + $popd = 'RLOPDF'; + } // U+202E RLO + else { + $bdf = 0x202D; + $popd = 'LROPDF'; + } // U+202D LRO + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'plaintext') { + $bdf = 0x2068; + $popd = 'FSIPDI'; // U+2068 FSI + } + if ($bdf) { + if ($bdf2) { + $bdf2 = UtfString::code2utf($bdf); + } + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer(UtfString::code2utf($bdf) . $bdf2); + } else { + $this->mpdf->_saveTextBuffer(UtfString::code2utf($bdf) . $bdf2); + } + $this->mpdf->biDirectional = true; + $currblk['bidicode'] = $popd; + } + } + + public function close(&$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + + // mPDF 6 bidi + // Block + // If unicode-bidi set, any embedding levels, isolates, or overrides started by this box are closed + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['bidicode'])) { + $blockpost = $this->mpdf->_setBidiCodes('end', $this->mpdf->blk[$this->mpdf->blklvl]['bidicode']); + if ($blockpost) { + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($blockpost); + } else { + $this->mpdf->_saveTextBuffer($blockpost); + } + } + } + + $this->mpdf->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces + $this->mpdf->blockjustfinished = true; + + $this->mpdf->lastblockbottommargin = $this->mpdf->blk[$this->mpdf->blklvl]['margin_bottom']; + // mPDF 6 Lists + if ($tag === 'UL' || $tag === 'OL') { + if ($this->mpdf->listlvl > 0 && $this->mpdf->tableLevel) { + if (isset($this->mpdf->listtype[$this->mpdf->listlvl])) { + unset($this->mpdf->listtype[$this->mpdf->listlvl]); + } + } + $this->mpdf->listlvl--; + $this->mpdf->listitem = []; + } + if ($tag === 'LI') { + $this->mpdf->listitem = []; + } + + if (preg_match('/^H\d/', $tag) && !$this->mpdf->tableLevel && !$this->mpdf->writingToC) { + if (isset($this->mpdf->h2toc[$tag]) || isset($this->mpdf->h2bookmarks[$tag])) { + $content = ''; + if (count($this->mpdf->textbuffer) == 1) { + $content = $this->mpdf->textbuffer[0][0]; + } else { + for ($i = 0; $i < count($this->mpdf->textbuffer); $i++) { + if (0 !== strpos($this->mpdf->textbuffer[$i][0], "\xbb\xa4\xac")) { //inline object + $content .= $this->mpdf->textbuffer[$i][0]; + } + } + } + /* -- TOC -- */ + if (isset($this->mpdf->h2toc[$tag])) { + $objattr = []; + $objattr['type'] = 'toc'; + $objattr['toclevel'] = $this->mpdf->h2toc[$tag]; + $objattr['CONTENT'] = htmlspecialchars($content); + $e = "\xbb\xa4\xactype=toc,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + array_unshift($this->mpdf->textbuffer, [$e]); + } + /* -- END TOC -- */ + /* -- BOOKMARKS -- */ + if (isset($this->mpdf->h2bookmarks[$tag])) { + $objattr = []; + $objattr['type'] = 'bookmark'; + $objattr['bklevel'] = $this->mpdf->h2bookmarks[$tag]; + $objattr['CONTENT'] = $content; + $e = "\xbb\xa4\xactype=toc,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + array_unshift($this->mpdf->textbuffer, [$e]); + } + /* -- END BOOKMARKS -- */ + } + } + + /* -- TABLES -- */ + if ($this->mpdf->tableLevel) { + if ($this->mpdf->linebreakjustfinished) { + $this->mpdf->blockjustfinished = false; + } + if (isset($this->mpdf->InlineProperties['BLOCKINTABLE'])) { + if ($this->mpdf->InlineProperties['BLOCKINTABLE']) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['BLOCKINTABLE']); + } + unset($this->mpdf->InlineProperties['BLOCKINTABLE']); + } + if ($tag === 'PRE') { + $this->mpdf->ispre = false; + } + return; + } + /* -- END TABLES -- */ + $this->mpdf->lastoptionaltag = ''; + $this->mpdf->divbegin = false; + + $this->mpdf->linebreakjustfinished = false; + + $this->mpdf->x = $this->mpdf->lMargin + $this->mpdf->blk[$this->mpdf->blklvl]['outer_left_margin']; + + /* -- CSS-FLOAT -- */ + // If float contained in a float, need to extend bottom to allow for it + $currpos = $this->mpdf->page * 1000 + $this->mpdf->y; + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['float_endpos']) && $this->mpdf->blk[$this->mpdf->blklvl]['float_endpos'] > $currpos) { + $old_page = $this->mpdf->page; + $new_page = (int) ($this->mpdf->blk[$this->mpdf->blklvl]['float_endpos'] / 1000); + if ($old_page != $new_page) { + $s = $this->mpdf->PrintPageBackgrounds(); + // Writes after the marker so not overwritten later by page background etc. + $this->mpdf->pages[$this->mpdf->page] = preg_replace( + '/(___BACKGROUND___PATTERNS' . $this->mpdf->uniqstr . ')/', + '\\1' . "\n" . $s . "\n", + $this->mpdf->pages[$this->mpdf->page] + ); + $this->mpdf->pageBackgrounds = []; + $this->mpdf->page = $new_page; + $this->mpdf->ResetMargins(); + $this->mpdf->Reset(); + $this->mpdf->pageoutput[$this->mpdf->page] = []; + } + // mod changes operands to integers before processing + $this->mpdf->y = (($this->mpdf->blk[$this->mpdf->blklvl]['float_endpos'] * 1000) % 1000000) / 1000; + } + /* -- END CSS-FLOAT -- */ + + + //Print content + $blockstate = 0; + if ($this->mpdf->lastblocklevelchange == 1) { + $blockstate = 3; + } // Top & bottom margins/padding + elseif ($this->mpdf->lastblocklevelchange == -1) { + $blockstate = 2; + } // Bottom margins/padding only + + // called from after e.g. </table> </div> </div> ... Outputs block margin/border and padding + if (count($this->mpdf->textbuffer) && $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1]) { + if (0 !== strpos($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0], "\xbb\xa4\xac")) { // not special content + // Right trim last content and adjust OTLdata + if (preg_match('/[ ]+$/', $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0], $m)) { + $strip = strlen($m[0]); + $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0] = substr( + $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0], + 0, + strlen($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0]) - $strip + ); + /* -- OTL -- */ + if (!empty($this->mpdf->CurrentFont['useOTL'])) { + $this->otl->trimOTLdata($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][18], false); // mPDF 6 ZZZ99K + } + /* -- END OTL -- */ + } + } + } + + if (count($this->mpdf->textbuffer) == 0 && $this->mpdf->lastblocklevelchange != 0) { + /*$this->mpdf->newFlowingBlock( + $this->mpdf->blk[$this->mpdf->blklvl]['width'], + $this->mpdf->lineheight, + '', + false, + 2, + true, + (isset($this->mpdf->blk[$this->mpdf->blklvl]['direction']) ? $this->mpdf->blk[$this->mpdf->blklvl]['direction'] : 'ltr') + );*/ + + $this->mpdf->newFlowingBlock( + $this->mpdf->blk[$this->mpdf->blklvl]['width'], + $this->mpdf->lineheight, + '', + false, + $blockstate, + true, + (isset($this->mpdf->blk[$this->mpdf->blklvl]['direction']) ? $this->mpdf->blk[$this->mpdf->blklvl]['direction'] : 'ltr') + ); + + $this->mpdf->finishFlowingBlock(true); // true = END of flowing block + $this->mpdf->PaintDivBB('', $blockstate); + } else { + $this->mpdf->printbuffer($this->mpdf->textbuffer, $blockstate); + } + + + $this->mpdf->textbuffer = []; + + if ($this->mpdf->kwt) { + $this->mpdf->kwt_height = $this->mpdf->y - $this->mpdf->kwt_y0; + } + + /* -- CSS-IMAGE-FLOAT -- */ + $this->mpdf->printfloatbuffer(); + /* -- END CSS-IMAGE-FLOAT -- */ + + if ($tag === 'PRE') { + $this->mpdf->ispre = false; + } + + /* -- CSS-FLOAT -- */ + if ($this->mpdf->blk[$this->mpdf->blklvl]['float'] === 'R') { + // If width not set, here would need to adjust and output buffer + $s = $this->mpdf->PrintPageBackgrounds(); + // Writes after the marker so not overwritten later by page background etc. + $this->mpdf->pages[$this->mpdf->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->mpdf->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->mpdf->pages[$this->mpdf->page]); + $this->mpdf->pageBackgrounds = []; + $this->mpdf->Reset(); + $this->mpdf->pageoutput[$this->mpdf->page] = []; + + for ($i = ($this->mpdf->blklvl - 1); $i >= 0; $i--) { + if (isset($this->mpdf->blk[$i]['float_endpos'])) { + $this->mpdf->blk[$i]['float_endpos'] = max($this->mpdf->blk[$i]['float_endpos'], $this->mpdf->page * 1000 + $this->mpdf->y); + } else { + $this->mpdf->blk[$i]['float_endpos'] = $this->mpdf->page * 1000 + $this->mpdf->y; + } + } + + $this->mpdf->floatDivs[] = [ + 'side' => 'R', + 'startpage' => $this->mpdf->blk[$this->mpdf->blklvl]['startpage'], + 'y0' => $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y'], + 'startpos' => $this->mpdf->blk[$this->mpdf->blklvl]['startpage'] * 1000 + $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y'], + 'endpage' => $this->mpdf->page, + 'y1' => $this->mpdf->y, + 'endpos' => $this->mpdf->page * 1000 + $this->mpdf->y, + 'w' => $this->mpdf->blk[$this->mpdf->blklvl]['float_width'], + 'blklvl' => $this->mpdf->blklvl, + 'blockContext' => $this->mpdf->blk[$this->mpdf->blklvl - 1]['blockContext'] + ]; + + $this->mpdf->y = $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y']; + $this->mpdf->page = $this->mpdf->blk[$this->mpdf->blklvl]['startpage']; + $this->mpdf->ResetMargins(); + $this->mpdf->pageoutput[$this->mpdf->page] = []; + } + if ($this->mpdf->blk[$this->mpdf->blklvl]['float'] === 'L') { + // If width not set, here would need to adjust and output buffer + $s = $this->mpdf->PrintPageBackgrounds(); + // Writes after the marker so not overwritten later by page background etc. + $this->mpdf->pages[$this->mpdf->page] = preg_replace('/(___BACKGROUND___PATTERNS' . $this->mpdf->uniqstr . ')/', '\\1' . "\n" . $s . "\n", $this->mpdf->pages[$this->mpdf->page]); + $this->mpdf->pageBackgrounds = []; + $this->mpdf->Reset(); + $this->mpdf->pageoutput[$this->mpdf->page] = []; + + for ($i = ($this->mpdf->blklvl - 1); $i >= 0; $i--) { + if (isset($this->mpdf->blk[$i]['float_endpos'])) { + $this->mpdf->blk[$i]['float_endpos'] = max($this->mpdf->blk[$i]['float_endpos'], $this->mpdf->page * 1000 + $this->mpdf->y); + } else { + $this->mpdf->blk[$i]['float_endpos'] = $this->mpdf->page * 1000 + $this->mpdf->y; + } + } + + $this->mpdf->floatDivs[] = [ + 'side' => 'L', + 'startpage' => $this->mpdf->blk[$this->mpdf->blklvl]['startpage'], + 'y0' => $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y'], + 'startpos' => $this->mpdf->blk[$this->mpdf->blklvl]['startpage'] * 1000 + $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y'], + 'endpage' => $this->mpdf->page, + 'y1' => $this->mpdf->y, + 'endpos' => $this->mpdf->page * 1000 + $this->mpdf->y, + 'w' => $this->mpdf->blk[$this->mpdf->blklvl]['float_width'], + 'blklvl' => $this->mpdf->blklvl, + 'blockContext' => $this->mpdf->blk[$this->mpdf->blklvl - 1]['blockContext'] + ]; + + $this->mpdf->y = $this->mpdf->blk[$this->mpdf->blklvl]['float_start_y']; + $this->mpdf->page = $this->mpdf->blk[$this->mpdf->blklvl]['startpage']; + $this->mpdf->ResetMargins(); + $this->mpdf->pageoutput[$this->mpdf->page] = []; + } + /* -- END CSS-FLOAT -- */ + + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['visibility']) && $this->mpdf->blk[$this->mpdf->blklvl]['visibility'] !== 'visible') { + $this->mpdf->SetVisibility('visible'); + } + + $page_break_after = ''; + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['page_break_after'])) { + $page_break_after = $this->mpdf->blk[$this->mpdf->blklvl]['page_break_after']; + } + + // Reset values + $this->mpdf->Reset(); + + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['z-index']) && $this->mpdf->blk[$this->mpdf->blklvl]['z-index'] > 0) { + $this->mpdf->EndLayer(); + } + + // mPDF 6 page-break-inside:avoid + if ($this->mpdf->blk[$this->mpdf->blklvl]['keep_block_together']) { + $movepage = false; + // If page-break-inside:avoid section has broken to new page but fits on one side - then move: + if (($this->mpdf->page - $this->mpdf->kt_p00) == 1 && $this->mpdf->y < $this->mpdf->kt_y00) { + $movepage = true; + } + if (($this->mpdf->page - $this->mpdf->kt_p00) > 0) { + for ($i = $this->mpdf->page; $i > $this->mpdf->kt_p00; $i--) { + unset($this->mpdf->pages[$i]); + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['bb_painted'][$i])) { + unset($this->mpdf->blk[$this->mpdf->blklvl]['bb_painted'][$i]); + } + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['marginCorrected'][$i])) { + unset($this->mpdf->blk[$this->mpdf->blklvl]['marginCorrected'][$i]); + } + if (isset($this->mpdf->pageoutput[$i])) { + unset($this->mpdf->pageoutput[$i]); + } + } + $this->mpdf->page = $this->mpdf->kt_p00; + } + $this->mpdf->keep_block_together = 0; + $this->mpdf->pageoutput[$this->mpdf->page] = []; + + $this->mpdf->y = $this->mpdf->kt_y00; + $ihtml = $this->mpdf->blk[$this->mpdf->blklvl]['array_i'] - 1; + + $ahtml[$ihtml + 1] .= ' pagebreakavoidchecked="true";'; // avoid re-iterating; read in OpenTag() + + unset($this->mpdf->blk[$this->mpdf->blklvl]); + $this->mpdf->blklvl--; + + for ($blklvl = 1; $blklvl <= $this->mpdf->blklvl; $blklvl++) { + $this->mpdf->blk[$blklvl]['y0'] = $this->mpdf->blk[$blklvl]['initial_y0']; + $this->mpdf->blk[$blklvl]['x0'] = $this->mpdf->blk[$blklvl]['initial_x0']; + $this->mpdf->blk[$blklvl]['startpage'] = $this->mpdf->blk[$blklvl]['initial_startpage']; + } + + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['x0'])) { + $this->mpdf->x = $this->mpdf->blk[$this->mpdf->blklvl]['x0']; + } else { + $this->mpdf->x = $this->mpdf->lMargin; + } + + $this->mpdf->lastblocklevelchange = 0; + $this->mpdf->ResetMargins(); + if ($movepage) { + $this->mpdf->AddPage(); + } + return; + } + + if ($this->mpdf->blklvl > 0) { // ==0 SHOULDN'T HAPPEN - NOT XHTML + if ($this->mpdf->blk[$this->mpdf->blklvl]['tag'] == $tag) { + unset($this->mpdf->blk[$this->mpdf->blklvl]); + $this->mpdf->blklvl--; + } + //else { echo $tag; exit; } // debug - forces error if incorrectly nested html tags + } + + $this->mpdf->lastblocklevelchange = -1; + // Reset Inline-type properties + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['InlineProperties'])) { + $this->mpdf->restoreInlineProperties($this->mpdf->blk[$this->mpdf->blklvl]['InlineProperties']); + } + + $this->mpdf->x = $this->mpdf->lMargin + $this->mpdf->blk[$this->mpdf->blklvl]['outer_left_margin']; + + if (!$this->mpdf->tableLevel && $page_break_after) { + $save_blklvl = $this->mpdf->blklvl; + $save_blk = $this->mpdf->blk; + $save_silp = $this->mpdf->saveInlineProperties(); + $save_ilp = $this->mpdf->InlineProperties; + $save_bflp = $this->mpdf->InlineBDF; + $save_bflpc = $this->mpdf->InlineBDFctr; // mPDF 6 + // mPDF 6 pagebreaktype + $startpage = $this->mpdf->page; + $pagebreaktype = $this->mpdf->defaultPagebreakType; + if ($this->mpdf->ColActive) { + $pagebreaktype = 'cloneall'; + } + + // mPDF 6 pagebreaktype + $this->mpdf->_preForcedPagebreak($pagebreaktype); + + if ($page_break_after === 'RIGHT') { + $this->mpdf->AddPage($this->mpdf->CurOrientation, 'NEXT-ODD'); + } elseif ($page_break_after === 'LEFT') { + $this->mpdf->AddPage($this->mpdf->CurOrientation, 'NEXT-EVEN'); + } else { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + + // mPDF 6 pagebreaktype + $this->mpdf->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl); + + $this->mpdf->InlineProperties = $save_ilp; + $this->mpdf->InlineBDF = $save_bflp; + $this->mpdf->InlineBDFctr = $save_bflpc; // mPDF 6 + $this->mpdf->restoreInlineProperties($save_silp); + } + // mPDF 6 bidi + // Block + // If unicode-bidi set, any embedding levels, isolates, or overrides reopened in the continuing block + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['bidicode'])) { + $blockpre = $this->mpdf->_setBidiCodes('start', $this->mpdf->blk[$this->mpdf->blklvl]['bidicode']); + if ($blockpre) { + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($blockpre); + } else { + $this->mpdf->_saveTextBuffer($blockpre); + } + } + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bookmark.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bookmark.php new file mode 100644 index 0000000..b414cf4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Bookmark.php @@ -0,0 +1,32 @@ +<?php + +namespace Mpdf\Tag; + +class Bookmark extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + if (isset($attr['CONTENT'])) { + $objattr = []; + $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES); + $objattr['type'] = 'bookmark'; + if (!empty($attr['LEVEL'])) { + $objattr['bklevel'] = $attr['LEVEL']; + } else { + $objattr['bklevel'] = 0; + } + $e = "\xbb\xa4\xactype=bookmark,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$e]; + } // *TABLES* + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Br.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Br.php new file mode 100644 index 0000000..125a18a --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Br.php @@ -0,0 +1,88 @@ +<?php + +namespace Mpdf\Tag; + +class Br extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + // Added mPDF 3.0 Float DIV - CLEAR + if (isset($attr['STYLE'])) { + $properties = $this->cssManager->readInlineCSS($attr['STYLE']); + if (isset($properties['CLEAR'])) { + $this->mpdf->ClearFloats(strtoupper($properties['CLEAR']), $this->mpdf->blklvl); + } // *CSS-FLOAT* + } + + // mPDF 6 bidi + // Inline + // If unicode-bidi set, any embedding levels, isolates, or overrides started by + // the inline box are closed at the br and reopened on the other side + $blockpre = ''; + $blockpost = ''; + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['bidicode'])) { + $blockpre = $this->mpdf->_setBidiCodes('end', $this->mpdf->blk[$this->mpdf->blklvl]['bidicode']); + $blockpost = $this->mpdf->_setBidiCodes('start', $this->mpdf->blk[$this->mpdf->blklvl]['bidicode']); + } + + // Inline + // If unicode-bidi set, any embedding levels, isolates, or overrides started by + // the inline box are closed at the br and reopened on the other side + $inlinepre = ''; + $inlinepost = ''; + $iBDF = []; + if (count($this->mpdf->InlineBDF)) { + foreach ($this->mpdf->InlineBDF as $k => $ib) { + foreach ($ib as $ib2) { + $iBDF[$ib2[1]] = $ib2[0]; + } + } + if (count($iBDF)) { + ksort($iBDF); + for ($i = count($iBDF) - 1; $i >= 0; $i--) { + $inlinepre .= $this->mpdf->_setBidiCodes('end', $iBDF[$i]); + } + for ($i = 0; $i < count($iBDF); $i++) { + $inlinepost .= $this->mpdf->_setBidiCodes('start', $iBDF[$i]); + } + } + } + + /* -- TABLES -- */ + if ($this->mpdf->tableLevel) { + if ($this->mpdf->blockjustfinished) { + $this->mpdf->_saveCellTextBuffer($blockpre . $inlinepre . "\n" . $inlinepost . $blockpost); + } + + $this->mpdf->_saveCellTextBuffer($blockpre . $inlinepre . "\n" . $inlinepost . $blockpost); + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; // reset + } else { + /* -- END TABLES -- */ + if (count($this->mpdf->textbuffer)) { + $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0] = preg_replace( + '/ $/', + '', + $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][0] + ); + if (!empty($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][18])) { + $this->otl->trimOTLdata($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1][18], false); + } // *OTL* + } + $this->mpdf->_saveTextBuffer($blockpre . $inlinepre . "\n" . $inlinepost . $blockpost); + } // *TABLES* + $this->mpdf->ignorefollowingspaces = true; + $this->mpdf->blockjustfinished = false; + + $this->mpdf->linebreakjustfinished = true; + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Caption.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Caption.php new file mode 100644 index 0000000..ffcb99a --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Caption.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Caption extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Center.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Center.php new file mode 100644 index 0000000..36fbe77 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Center.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Center extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Cite.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Cite.php new file mode 100644 index 0000000..869cfc4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Cite.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Cite extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Code.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Code.php new file mode 100644 index 0000000..47776e7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Code.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Code extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/ColumnBreak.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/ColumnBreak.php new file mode 100644 index 0000000..5b2ff05 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/ColumnBreak.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf\Tag; + +class ColumnBreak extends NewColumn +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Columns.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Columns.php new file mode 100644 index 0000000..0e6bed4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Columns.php @@ -0,0 +1,67 @@ +<?php + +namespace Mpdf\Tag; + +class Columns extends Tag +{ + /** + * @param string $tag + * @return \Mpdf\Tag\Tag + */ + private function getTagInstance($tag) + { + $className = \Mpdf\Tag::getTagClassName($tag); + if (class_exists($className)) { + return new $className( + $this->mpdf, + $this->cache, + $this->cssManager, + $this->form, + $this->otl, + $this->tableOfContents, + $this->sizeConverter, + $this->colorConverter, + $this->imageProcessor, + $this->languageToFont + ); + } + + return null; + } + + public function open($attr, &$ahtml, &$ihtml) + { + if (isset($attr['COLUMN-COUNT']) && ($attr['COLUMN-COUNT'] || $attr['COLUMN-COUNT'] === '0')) { + // Close any open block tags + for ($b = $this->mpdf->blklvl; $b > 0; $b--) { + if ($t = $this->getTagInstance($this->mpdf->blk[$b]['tag'])) { + $t->close($ahtml, $ihtml); + } + } + if (!empty($this->mpdf->textbuffer)) { //Output previously buffered content + $this->mpdf->printbuffer($this->mpdf->textbuffer); + $this->mpdf->textbuffer = []; + } + + if (!empty($attr['VALIGN'])) { + if ($attr['VALIGN'] === 'J') { + $valign = 'J'; + } else { + $valign = self::ALIGN[$attr['VALIGN']]; + } + } else { + $valign = ''; + } + if (!empty($attr['COLUMN-GAP'])) { + $this->mpdf->SetColumns($attr['COLUMN-COUNT'], $valign, $attr['COLUMN-GAP']); + } else { + $this->mpdf->SetColumns($attr['COLUMN-COUNT'], $valign); + } + } + $this->mpdf->ignorefollowingspaces = true; + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dd.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dd.php new file mode 100644 index 0000000..ce0ccfb --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dd.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Dd extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Del.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Del.php new file mode 100644 index 0000000..8af9cd0 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Del.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Del extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Details.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Details.php new file mode 100644 index 0000000..bd81da0 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Details.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Details extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Div.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Div.php new file mode 100644 index 0000000..30fb2b7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Div.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Div extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dl.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dl.php new file mode 100644 index 0000000..80bafc2 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dl.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Dl extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/DotTab.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/DotTab.php new file mode 100644 index 0000000..278ce38 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/DotTab.php @@ -0,0 +1,68 @@ +<?php + +namespace Mpdf\Tag; + +class DotTab extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $objattr = []; + $objattr['type'] = 'dottab'; + $dots = str_repeat('.', 3) . ' '; // minimum number of dots + $objattr['width'] = $this->mpdf->GetStringWidth($dots); + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['height'] = 0; + $objattr['colorarray'] = $this->mpdf->colorarray; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['vertical_align'] = 'BS'; // mPDF 6 DOTTAB + + $properties = $this->cssManager->MergeCSS('INLINE', 'DOTTAB', $attr); + if (isset($properties['OUTDENT'])) { + $objattr['outdent'] = $this->sizeConverter->convert( + $properties['OUTDENT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['OUTDENT'])) { + $objattr['outdent'] = $this->sizeConverter->convert( + $attr['OUTDENT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } else { + $objattr['outdent'] = 0; + } + + $objattr['fontfamily'] = $this->mpdf->FontFamily; + $objattr['fontsize'] = $this->mpdf->FontSizePt; + + $e = "\xbb\xa4\xactype=dottab,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; // reset + $this->mpdf->_saveCellTextBuffer($e); + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e); + } // *TABLES* + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dt.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dt.php new file mode 100644 index 0000000..22492fb --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Dt.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Dt extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Em.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Em.php new file mode 100644 index 0000000..a353bd2 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Em.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Em extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FieldSet.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FieldSet.php new file mode 100644 index 0000000..33356f1 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FieldSet.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class FieldSet extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FigCaption.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FigCaption.php new file mode 100644 index 0000000..1e738a5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FigCaption.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class FigCaption extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Figure.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Figure.php new file mode 100644 index 0000000..1074a63 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Figure.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Figure extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Font.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Font.php new file mode 100644 index 0000000..e290414 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Font.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Font extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Footer.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Footer.php new file mode 100644 index 0000000..46abbc4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Footer.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Footer extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Form.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Form.php new file mode 100644 index 0000000..588000e --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Form.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Form extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FormFeed.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FormFeed.php new file mode 100644 index 0000000..6b2f46b --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/FormFeed.php @@ -0,0 +1,293 @@ +<?php + +namespace Mpdf\Tag; + +class FormFeed extends Tag +{ + public $toc_id; + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + if (isset($attr['SHEET-SIZE'])) { + // Convert to same types as accepted in initial mPDF() A4, A4-L, or array(w,h) + $prop = preg_split('/\s+/', trim($attr['SHEET-SIZE'])); + if (count($prop) == 2) { + $newformat = [$this->sizeConverter->convert($prop[0]), $this->sizeConverter->convert($prop[1])]; + } else { + $newformat = $attr['SHEET-SIZE']; + } + } else { + $newformat = ''; + } + + $save_blklvl = $this->mpdf->blklvl; + $save_blk = $this->mpdf->blk; + $save_silp = $this->mpdf->saveInlineProperties(); + $save_ilp = $this->mpdf->InlineProperties; + $save_bflp = $this->mpdf->InlineBDF; + $save_bflpc = $this->mpdf->InlineBDFctr; // mPDF 6 + + $mgr = $mgl = $mgt = $mgb = $mgh = $mgf = ''; + if (isset($attr['MARGIN-RIGHT'])) { + $mgr = $this->sizeConverter->convert($attr['MARGIN-RIGHT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['MARGIN-LEFT'])) { + $mgl = $this->sizeConverter->convert($attr['MARGIN-LEFT'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['MARGIN-TOP'])) { + $mgt = $this->sizeConverter->convert($attr['MARGIN-TOP'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['MARGIN-BOTTOM'])) { + $mgb = $this->sizeConverter->convert($attr['MARGIN-BOTTOM'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['MARGIN-HEADER'])) { + $mgh = $this->sizeConverter->convert($attr['MARGIN-HEADER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + if (isset($attr['MARGIN-FOOTER'])) { + $mgf = $this->sizeConverter->convert($attr['MARGIN-FOOTER'], $this->mpdf->w, $this->mpdf->FontSize, false); + } + $ohname = $ehname = $ofname = $efname = ''; + if (isset($attr['ODD-HEADER-NAME'])) { + $ohname = $attr['ODD-HEADER-NAME']; + } + if (isset($attr['EVEN-HEADER-NAME'])) { + $ehname = $attr['EVEN-HEADER-NAME']; + } + if (isset($attr['ODD-FOOTER-NAME'])) { + $ofname = $attr['ODD-FOOTER-NAME']; + } + if (isset($attr['EVEN-FOOTER-NAME'])) { + $efname = $attr['EVEN-FOOTER-NAME']; + } + $ohvalue = $ehvalue = $ofvalue = $efvalue = 0; + if (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE'] == '1' || strtoupper($attr['ODD-HEADER-VALUE']) === 'ON')) { + $ohvalue = 1; + } elseif (isset($attr['ODD-HEADER-VALUE']) && ($attr['ODD-HEADER-VALUE'] == '-1' || strtoupper($attr['ODD-HEADER-VALUE']) === 'OFF')) { + $ohvalue = -1; + } + if (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE'] == '1' || strtoupper($attr['EVEN-HEADER-VALUE']) === 'ON')) { + $ehvalue = 1; + } elseif (isset($attr['EVEN-HEADER-VALUE']) && ($attr['EVEN-HEADER-VALUE'] == '-1' || strtoupper($attr['EVEN-HEADER-VALUE']) === 'OFF')) { + $ehvalue = -1; + } + if (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE'] == '1' || strtoupper($attr['ODD-FOOTER-VALUE']) === 'ON')) { + $ofvalue = 1; + } elseif (isset($attr['ODD-FOOTER-VALUE']) && ($attr['ODD-FOOTER-VALUE'] == '-1' || strtoupper($attr['ODD-FOOTER-VALUE']) === 'OFF')) { + $ofvalue = -1; + } + if (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE'] == '1' || strtoupper($attr['EVEN-FOOTER-VALUE']) === 'ON')) { + $efvalue = 1; + } elseif (isset($attr['EVEN-FOOTER-VALUE']) && ($attr['EVEN-FOOTER-VALUE'] == '-1' || strtoupper($attr['EVEN-FOOTER-VALUE']) === 'OFF')) { + $efvalue = -1; + } + + if (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION']) === 'L' || strtoupper($attr['ORIENTATION']) === 'LANDSCAPE')) { + $orient = 'L'; + } elseif (isset($attr['ORIENTATION']) && (strtoupper($attr['ORIENTATION']) === 'P' || strtoupper($attr['ORIENTATION']) === 'PORTRAIT')) { + $orient = 'P'; + } else { + $orient = $this->mpdf->CurOrientation; + } + + $pagesel = ''; + if (!empty($attr['PAGE-SELECTOR'])) { + $pagesel = $attr['PAGE-SELECTOR']; + } + + // mPDF 6 pagebreaktype + $pagebreaktype = $this->mpdf->defaultPagebreakType; + if ($tag === 'FORMFEED') { + $pagebreaktype = 'slice'; + } // can be overridden by PAGE-BREAK-TYPE + $startpage = $this->mpdf->page; + if (isset($attr['PAGE-BREAK-TYPE'])) { + if (strtolower($attr['PAGE-BREAK-TYPE']) === 'cloneall' + || strtolower($attr['PAGE-BREAK-TYPE']) === 'clonebycss' + || strtolower($attr['PAGE-BREAK-TYPE']) === 'slice') { + $pagebreaktype = strtolower($attr['PAGE-BREAK-TYPE']); + } + } + if ($tag === 'TOCPAGEBREAK') { + $pagebreaktype = 'cloneall'; + } elseif ($this->mpdf->ColActive) { + $pagebreaktype = 'cloneall'; + } // Any change in headers/footers (may need to _getHtmlHeight), or page size/orientation, @page selector, or margins - force cloneall + elseif ($mgr !== '' || $mgl !== '' || $mgt !== '' || $mgb !== '' || $mgh !== '' || $mgf !== '' || + $ohname !== '' || $ehname !== '' || $ofname !== '' || $efname !== '' || + $ohvalue || $ehvalue || $ofvalue || $efvalue || + $orient != $this->mpdf->CurOrientation || $newformat || $pagesel) { + $pagebreaktype = 'cloneall'; + } + + // mPDF 6 pagebreaktype + $this->mpdf->_preForcedPagebreak($pagebreaktype); + + $this->mpdf->ignorefollowingspaces = true; + + + $resetpagenum = ''; + $pagenumstyle = ''; + $suppress = ''; + if (isset($attr['RESETPAGENUM'])) { + $resetpagenum = $attr['RESETPAGENUM']; + } + if (isset($attr['PAGENUMSTYLE'])) { + $pagenumstyle = $attr['PAGENUMSTYLE']; + } + if (isset($attr['SUPPRESS'])) { + $suppress = $attr['SUPPRESS']; + } + + $type = ''; + if ($tag === 'TOCPAGEBREAK') { + $type = 'NEXT-ODD'; + } elseif (isset($attr['TYPE'])) { + $type = strtoupper($attr['TYPE']); + } + + if ($type === 'E' || $type === 'EVEN') { + $this->mpdf->AddPage( + $orient, + 'E', + $resetpagenum, + $pagenumstyle, + $suppress, + $mgl, + $mgr, + $mgt, + $mgb, + $mgh, + $mgf, + $ohname, + $ehname, + $ofname, + $efname, + $ohvalue, + $ehvalue, + $ofvalue, + $efvalue, + $pagesel, + $newformat + ); + } elseif ($type === 'O' || $type === 'ODD') { + $this->mpdf->AddPage( + $orient, + 'O', + $resetpagenum, + $pagenumstyle, + $suppress, + $mgl, + $mgr, + $mgt, + $mgb, + $mgh, + $mgf, + $ohname, + $ehname, + $ofname, + $efname, + $ohvalue, + $ehvalue, + $ofvalue, + $efvalue, + $pagesel, + $newformat + ); + } elseif ($type === 'NEXT-ODD') { + $this->mpdf->AddPage( + $orient, + 'NEXT-ODD', + $resetpagenum, + $pagenumstyle, + $suppress, + $mgl, + $mgr, + $mgt, + $mgb, + $mgh, + $mgf, + $ohname, + $ehname, + $ofname, + $efname, + $ohvalue, + $ehvalue, + $ofvalue, + $efvalue, + $pagesel, + $newformat + ); + } elseif ($type === 'NEXT-EVEN') { + $this->mpdf->AddPage( + $orient, + 'NEXT-EVEN', + $resetpagenum, + $pagenumstyle, + $suppress, + $mgl, + $mgr, + $mgt, + $mgb, + $mgh, + $mgf, + $ohname, + $ehname, + $ofname, + $efname, + $ohvalue, + $ehvalue, + $ofvalue, + $efvalue, + $pagesel, + $newformat + ); + } else { + $this->mpdf->AddPage( + $orient, + '', + $resetpagenum, + $pagenumstyle, + $suppress, + $mgl, + $mgr, + $mgt, + $mgb, + $mgh, + $mgf, + $ohname, + $ehname, + $ofname, + $efname, + $ohvalue, + $ehvalue, + $ofvalue, + $efvalue, + $pagesel, + $newformat + ); + } + + /* -- TOC -- */ + if ($tag === 'TOCPAGEBREAK') { + if ($this->toc_id) { + $this->tableOfContents->m_TOC[$this->toc_id]['TOCmark'] = $this->mpdf->page; + } else { + $this->tableOfContents->TOCmark = $this->mpdf->page; + } + } + /* -- END TOC -- */ + + // mPDF 6 pagebreaktype + $this->mpdf->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl); + + $this->mpdf->InlineProperties = $save_ilp; + $this->mpdf->InlineBDF = $save_bflp; + $this->mpdf->InlineBDFctr = $save_bflpc; // mPDF 6 + $this->mpdf->restoreInlineProperties($save_silp); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H1.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H1.php new file mode 100644 index 0000000..5174afb --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H1.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H1 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H2.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H2.php new file mode 100644 index 0000000..199bb55 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H2.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H2 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H3.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H3.php new file mode 100644 index 0000000..b9db924 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H3.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H3 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H4.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H4.php new file mode 100644 index 0000000..3083ba1 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H4.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H4 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H5.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H5.php new file mode 100644 index 0000000..50b78d7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H5.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H5 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H6.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H6.php new file mode 100644 index 0000000..f33dacf --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/H6.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class H6 extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/HGroup.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/HGroup.php new file mode 100644 index 0000000..e519b93 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/HGroup.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class HGroup extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Header.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Header.php new file mode 100644 index 0000000..f948559 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Header.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Header extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Hr.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Hr.php new file mode 100644 index 0000000..5155c63 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Hr.php @@ -0,0 +1,126 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Utils\NumericString; + +class Hr extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + + // Added mPDF 3.0 Float DIV - CLEAR + if (isset($attr['STYLE'])) { + $properties = $this->cssManager->readInlineCSS($attr['STYLE']); + if (isset($properties['CLEAR'])) { + $this->mpdf->ClearFloats(strtoupper($properties['CLEAR']), $this->mpdf->blklvl); + } // *CSS-FLOAT* + } + + $this->mpdf->ignorefollowingspaces = true; + + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $properties = $this->cssManager->MergeCSS('', 'HR', $attr); + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['WIDTH'])) { + $objattr['width'] = $this->sizeConverter->convert($properties['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + } elseif (isset($attr['WIDTH']) && $attr['WIDTH'] != '') { + $objattr['width'] = $this->sizeConverter->convert($attr['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + } + if (isset($properties['TEXT-ALIGN'])) { + $objattr['align'] = self::ALIGN[strtolower($properties['TEXT-ALIGN'])]; + } elseif (isset($attr['ALIGN']) && $attr['ALIGN'] != '') { + $objattr['align'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } + + if (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT']) === 'auto') { + $objattr['align'] = 'R'; + } + if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT']) === 'auto') { + $objattr['align'] = 'L'; + if (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT']) === 'auto' + && isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT']) === 'auto') { + $objattr['align'] = 'C'; + } + } + if (isset($properties['COLOR'])) { + $objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } elseif (isset($attr['COLOR']) && $attr['COLOR'] != '') { + $objattr['color'] = $this->colorConverter->convert($attr['COLOR'], $this->mpdf->PDFAXwarnings); + } + if (isset($properties['HEIGHT'])) { + $objattr['linewidth'] = $this->sizeConverter->convert( + $properties['HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + + /* -- TABLES -- */ + if ($this->mpdf->tableLevel) { + $objattr['W-PERCENT'] = 100; + if (isset($properties['WIDTH']) && NumericString::containsPercentChar($properties['WIDTH'])) { + $properties['WIDTH'] = NumericString::removePercentChar($properties['WIDTH']); // make "90%" become simply "90" + $objattr['W-PERCENT'] = $properties['WIDTH']; + } + if (isset($attr['WIDTH']) && NumericString::containsPercentChar($attr['WIDTH'])) { + $attr['WIDTH'] = NumericString::removePercentChar($attr['WIDTH']); // make "90%" become simply "90" + $objattr['W-PERCENT'] = $attr['WIDTH']; + } + } + /* -- END TABLES -- */ + + $objattr['type'] = 'hr'; + $objattr['height'] = $objattr['linewidth'] + $objattr['margin_top'] + $objattr['margin_bottom']; + $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + if ($this->mpdf->cell) { + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; // reset + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + } + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/I.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/I.php new file mode 100644 index 0000000..8c03c2d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/I.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class I extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Img.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Img.php new file mode 100644 index 0000000..cd7fc0d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Img.php @@ -0,0 +1,458 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class Img extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->ignorefollowingspaces = false; + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + if (isset($attr['SRC'])) { + $srcpath = $attr['SRC']; + $orig_srcpath = (isset($attr['ORIG_SRC']) ? $attr['ORIG_SRC'] : ''); + $properties = $this->cssManager->MergeCSS('', 'IMG', $attr); + if (isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY']) === 'none') { + return; + } + if (isset($properties['Z-INDEX']) && $this->mpdf->current_layer == 0) { + $v = (int) $properties['Z-INDEX']; + if ($v > 0) { + $objattr['z-index'] = $v; + } + } + + $objattr['visibility'] = 'visible'; + if (isset($properties['VISIBILITY'])) { + $v = strtolower($properties['VISIBILITY']); + if (($v === 'hidden' || $v === 'printonly' || $v === 'screenonly') && $this->mpdf->visibility === 'visible') { + $objattr['visibility'] = $v; + } + } + + // VSPACE and HSPACE converted to margins in MergeCSS + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-LEFT'])) { + $objattr['margin_left'] = $this->sizeConverter->convert( + $properties['MARGIN-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-RIGHT'])) { + $objattr['margin_right'] = $this->sizeConverter->convert( + $properties['MARGIN-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['PADDING-TOP'])) { + $objattr['padding_top'] = $this->sizeConverter->convert( + $properties['PADDING-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-BOTTOM'])) { + $objattr['padding_bottom'] = $this->sizeConverter->convert( + $properties['PADDING-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-LEFT'])) { + $objattr['padding_left'] = $this->sizeConverter->convert( + $properties['PADDING-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-RIGHT'])) { + $objattr['padding_right'] = $this->sizeConverter->convert( + $properties['PADDING-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['BORDER-TOP'])) { + $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + } + if (isset($properties['BORDER-LEFT'])) { + $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } + if (isset($properties['BORDER-RIGHT'])) { + $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } + + if (isset($properties['VERTICAL-ALIGN'])) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + $w = 0; + $h = 0; + if (isset($properties['WIDTH'])) { + $w = $this->sizeConverter->convert( + $properties['WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['WIDTH'])) { + $w = $this->sizeConverter->convert( + $attr['WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['HEIGHT'])) { + $h = $this->sizeConverter->convert( + $properties['HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['HEIGHT'])) { + $h = $this->sizeConverter->convert( + $attr['HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + $maxw = $maxh = $minw = $minh = false; + if (isset($properties['MAX-WIDTH'])) { + $maxw = $this->sizeConverter->convert( + $properties['MAX-WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['MAX-WIDTH'])) { + $maxw = $this->sizeConverter->convert( + $attr['MAX-WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MAX-HEIGHT'])) { + $maxh = $this->sizeConverter->convert( + $properties['MAX-HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['MAX-HEIGHT'])) { + $maxh = $this->sizeConverter->convert( + $attr['MAX-HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MIN-WIDTH'])) { + $minw = $this->sizeConverter->convert( + $properties['MIN-WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['MIN-WIDTH'])) { + $minw = $this->sizeConverter->convert( + $attr['MIN-WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MIN-HEIGHT'])) { + $minh = $this->sizeConverter->convert( + $properties['MIN-HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['MIN-HEIGHT'])) { + $minh = $this->sizeConverter->convert( + $attr['MIN-HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { + $objattr['opacity'] = $properties['OPACITY']; + } + if ($this->mpdf->HREF) { + if (strpos($this->mpdf->HREF, '.') === false && strpos($this->mpdf->HREF, '@') !== 0) { + $href = $this->mpdf->HREF; + while (array_key_exists($href, $this->mpdf->internallink)) { + $href = '#' . $href; + } + $this->mpdf->internallink[$href] = $this->mpdf->AddLink(); + $objattr['link'] = $this->mpdf->internallink[$href]; + } else { + $objattr['link'] = $this->mpdf->HREF; + } + } + $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; + + $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; + + // mPDF 5.7.3 TRANSFORMS + if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { + $objattr['bgcolor'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); + } + + /* -- BACKGROUNDS -- */ + if (isset($properties['GRADIENT-MASK']) && preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient/', $properties['GRADIENT-MASK'])) { + $objattr['GRADIENT-MASK'] = $properties['GRADIENT-MASK']; + } + /* -- END BACKGROUNDS -- */ + + // mPDF 6 + $interpolation = false; + if (!empty($properties['IMAGE-RENDERING'])) { + $interpolation = false; + if (strtolower($properties['IMAGE-RENDERING']) === 'crisp-edges') { + $interpolation = false; + } elseif (strtolower($properties['IMAGE-RENDERING']) === 'optimizequality') { + $interpolation = true; + } elseif (strtolower($properties['IMAGE-RENDERING']) === 'smooth') { + $interpolation = true; + } elseif (strtolower($properties['IMAGE-RENDERING']) === 'auto') { + $interpolation = $this->mpdf->interpolateImages; + } + $info['interpolation'] = $interpolation; + } + + // Image file + $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath, $interpolation); // mPDF 6 + if (!$info) { + $info = $this->imageProcessor->getImage($this->mpdf->noImageFile); + if ($info) { + $srcpath = $this->mpdf->noImageFile; + $w = ($info['w'] * (25.4 / $this->mpdf->img_dpi)); + $h = ($info['h'] * (25.4 / $this->mpdf->img_dpi)); + } + } + if (!$info) { + return; + } + + $image_orientation = 0; + if (isset($attr['ROTATE'])) { + $image_orientation = $attr['ROTATE']; + } elseif (isset($properties['IMAGE-ORIENTATION'])) { + $image_orientation = $properties['IMAGE-ORIENTATION']; + } + if ($image_orientation) { + if ($image_orientation == 90 || $image_orientation == -90 || $image_orientation == 270) { + $tmpw = $info['w']; + $info['w'] = $info['h']; + $info['h'] = $tmpw; + } + $objattr['ROTATE'] = $image_orientation; + } + + $objattr['file'] = $srcpath; + //Default width and height calculation if needed + if ($w == 0 && $h == 0) { + /* -- IMAGES-WMF -- */ + if ($info['type'] === 'wmf') { + // WMF units are twips (1/20pt) + // divide by 20 to get points + // divide by k to get user units + $w = abs($info['w']) / (20 * Mpdf::SCALE); + $h = abs($info['h']) / (20 * Mpdf::SCALE); + } else { /* -- END IMAGES-WMF -- */ + if ($info['type'] === 'svg') { + // SVG units are pixels + $w = abs($info['w']) / Mpdf::SCALE; + $h = abs($info['h']) / Mpdf::SCALE; + } else { + //Put image at default image dpi + $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); + $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); + } + } + if (isset($properties['IMAGE-RESOLUTION'])) { + if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi'] > 0) { + $w *= $this->mpdf->img_dpi / $info['set-dpi']; + $h *= $this->mpdf->img_dpi / $info['set-dpi']; + } elseif (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) { + $dpi = $m[1]; + if ($dpi > 0) { + $w *= $this->mpdf->img_dpi / $dpi; + $h *= $this->mpdf->img_dpi / $dpi; + } + } + } + } + // IF WIDTH OR HEIGHT SPECIFIED + if ($w == 0) { + $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; + } + + if ($h == 0) { + $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; + } + + if ($minw && $w < $minw) { + $w = $minw; + $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; + } + if ($maxw && $w > $maxw) { + $w = $maxw; + $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; + } + if ($minh && $h < $minh) { + $h = $minh; + $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; + } + if ($maxh && $h > $maxh) { + $h = $maxh; + $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; + } + + // Resize to maximum dimensions of page + $maxWidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; + $maxHeight = $this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin + 1); + if ($this->mpdf->fullImageHeight) { + $maxHeight = $this->mpdf->fullImageHeight; + } + if (($w + $extrawidth) > ($maxWidth + 0.0001)) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth + $w = $maxWidth - $extrawidth; + $h = abs($w * $info['h'] / $info['w']); + } + + if ($h + $extraheight > $maxHeight) { + $h = $maxHeight - $extraheight; + $w = abs($h * $info['w'] / $info['h']); + } + $objattr['type'] = 'image'; + $objattr['itype'] = $info['type']; + + $objattr['orig_h'] = $info['h']; + $objattr['orig_w'] = $info['w']; + /* -- IMAGES-WMF -- */ + if ($info['type'] === 'wmf') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + } else { /* -- END IMAGES-WMF -- */ + if ($info['type'] === 'svg') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + } + } + $objattr['height'] = $h + $extraheight; + $objattr['width'] = $w + $extrawidth; + $objattr['image_height'] = $h; + $objattr['image_width'] = $w; + /* -- CSS-IMAGE-FLOAT -- */ + if (!$this->mpdf->ColActive && !$this->mpdf->tableLevel && !$this->mpdf->listlvl && !$this->mpdf->kwt) { + if (isset($properties['FLOAT']) && (strtoupper($properties['FLOAT']) === 'RIGHT' || strtoupper($properties['FLOAT']) === 'LEFT')) { + $objattr['float'] = strtoupper(substr($properties['FLOAT'], 0, 1)); + } + } + /* -- END CSS-IMAGE-FLOAT -- */ + // mPDF 5.7.3 TRANSFORMS + if (isset($properties['TRANSFORM']) && !$this->mpdf->ColActive && !$this->mpdf->kwt) { + $objattr['transform'] = $properties['TRANSFORM']; + } + + $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + /* -- ANNOTATIONS -- */ + if ($this->mpdf->title2annots && isset($attr['TITLE'])) { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['CONTENT'] = $attr['TITLE']; + $objattr['type'] = 'annot'; + $objattr['POS-X'] = 0; + $objattr['POS-Y'] = 0; + $objattr['ICON'] = 'Comment'; + $objattr['AUTHOR'] = ''; + $objattr['SUBJECT'] = ''; + $objattr['OPACITY'] = $this->mpdf->annotOpacity; + $objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings); + $e = "\xbb\xa4\xactype=annot,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { // *TABLES* + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; // *TABLES* + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$e]; + } // *TABLES* + } + /* -- END ANNOTATIONS -- */ + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexEntry.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexEntry.php new file mode 100644 index 0000000..2ca06a4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexEntry.php @@ -0,0 +1,32 @@ +<?php + +namespace Mpdf\Tag; + +class IndexEntry extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + if (!empty($attr['CONTENT'])) { + if (!empty($attr['XREF'])) { + $this->mpdf->IndexEntry(htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES), $attr['XREF']); + return; + } + $objattr = []; + $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES); + $objattr['type'] = 'indexentry'; + $objattr['vertical-align'] = 'T'; + $e = "\xbb\xa4\xactype=indexentry,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$e]; + } // *TABLES* + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexInsert.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexInsert.php new file mode 100644 index 0000000..2704b4f --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/IndexInsert.php @@ -0,0 +1,33 @@ +<?php + +namespace Mpdf\Tag; + +class IndexInsert extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $indexCollationLocale = ''; + if (isset($attr['COLLATION'])) { + $indexCollationLocale = $attr['COLLATION']; + } + + $indexCollationGroup = ''; + if (isset($attr['COLLATION-GROUP'])) { + $indexCollationGroup = $attr['COLLATION-GROUP']; + } + + $usedivletters = 1; + if (isset($attr['USEDIVLETTERS']) && (strtoupper($attr['USEDIVLETTERS']) === 'OFF' + || $attr['USEDIVLETTERS'] == -1 + || $attr['USEDIVLETTERS'] === '0')) { + $usedivletters = 0; + } + $links = isset($attr['LINKS']) && (strtoupper($attr['LINKS']) === 'ON' || $attr['LINKS'] == 1); + $this->mpdf->InsertIndex($usedivletters, $links, $indexCollationLocale, $indexCollationGroup); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/InlineTag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/InlineTag.php new file mode 100644 index 0000000..69ea5f5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/InlineTag.php @@ -0,0 +1,232 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Utils\UtfString; + +abstract class InlineTag extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + + /* -- ANNOTATIONS -- */ + if ($this->mpdf->title2annots && isset($attr['TITLE'])) { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + + $objattr['CONTENT'] = $attr['TITLE']; + $objattr['type'] = 'annot'; + $objattr['POS-X'] = 0; + $objattr['POS-Y'] = 0; + $objattr['ICON'] = 'Comment'; + $objattr['AUTHOR'] = ''; + $objattr['SUBJECT'] = ''; + $objattr['OPACITY'] = $this->mpdf->annotOpacity; + $objattr['COLOR'] = $this->colorConverter->convert('yellow', $this->mpdf->PDFAXwarnings); + $annot = "\xbb\xa4\xactype=annot,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + } + /* -- END ANNOTATIONS -- */ + + // mPDF 5.7.3 Inline tags + if (!isset($this->mpdf->InlineProperties[$tag])) { + $this->mpdf->InlineProperties[$tag] = [$this->mpdf->saveInlineProperties()]; + } else { + $this->mpdf->InlineProperties[$tag][] = $this->mpdf->saveInlineProperties(); + } + if (isset($annot)) { // *ANNOTATIONS* + if (!isset($this->mpdf->InlineAnnots[$tag])) { + $this->mpdf->InlineAnnots[$tag] = []; + } // *ANNOTATIONS* + $this->mpdf->InlineAnnots[$tag][] = $annot; + } // *ANNOTATIONS* + + $properties = $this->cssManager->MergeCSS('INLINE', $tag, $attr); + if (!empty($properties)) { + $this->mpdf->setCSS($properties, 'INLINE'); + } + + // mPDF 6 Bidirectional formatting for inline elements + $bdf = false; + $bdf2 = ''; + $popd = ''; + + // Get current direction + $currdir = 'ltr'; + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['direction'])) { + $currdir = $this->mpdf->blk[$this->mpdf->blklvl]['direction']; + } + if ($this->mpdf->tableLevel + && isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['direction']) + && $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['direction'] === 'rtl') { + $currdir = 'rtl'; + } + if (isset($attr['DIR']) && $attr['DIR'] != '') { + $currdir = strtolower($attr['DIR']); + } + if (isset($properties['DIRECTION'])) { + $currdir = strtolower($properties['DIRECTION']); + } + + // mPDF 6 bidi + // cf. http://www.w3.org/TR/css3-writing-modes/#unicode-bidi + if ($tag === 'BDO') { + if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') { + $bdf = 0x202E; + $popd = 'RLOPDF'; + } // U+202E RLO + elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') { + $bdf = 0x202D; + $popd = 'LROPDF'; + } // U+202D LRO + } elseif ($tag === 'BDI') { + if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') { + $bdf = 0x2067; + $popd = 'RLIPDI'; + } // U+2067 RLI + elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') { + $bdf = 0x2066; + $popd = 'LRIPDI'; + } // U+2066 LRI + else { + $bdf = 0x2068; + $popd = 'FSIPDI'; + } // U+2068 FSI + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'bidi-override') { + if ($currdir === 'rtl') { + $bdf = 0x202E; + $popd = 'RLOPDF'; + } // U+202E RLO + else { + $bdf = 0x202D; + $popd = 'LROPDF'; + } // U+202D LRO + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'embed') { + if ($currdir === 'rtl') { + $bdf = 0x202B; + $popd = 'RLEPDF'; + } // U+202B RLE + else { + $bdf = 0x202A; + $popd = 'LREPDF'; + } // U+202A LRE + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'isolate') { + if ($currdir === 'rtl') { + $bdf = 0x2067; + $popd = 'RLIPDI'; + } // U+2067 RLI + else { + $bdf = 0x2066; + $popd = 'LRIPDI'; + } // U+2066 LRI + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'isolate-override') { + if ($currdir === 'rtl') { + $bdf = 0x2067; + $bdf2 = 0x202E; + $popd = 'RLIRLOPDFPDI'; + } // U+2067 RLI // U+202E RLO + else { + $bdf = 0x2066; + $bdf2 = 0x202D; + $popd = 'LRILROPDFPDI'; + } // U+2066 LRI // U+202D LRO + } elseif (isset($properties ['UNICODE-BIDI']) && strtolower($properties ['UNICODE-BIDI']) === 'plaintext') { + $bdf = 0x2068; + $popd = 'FSIPDI'; // U+2068 FSI + } else { + if (isset($attr['DIR']) && strtolower($attr['DIR']) === 'rtl') { + $bdf = 0x202B; + $popd = 'RLEPDF'; + } // U+202B RLE + elseif (isset($attr['DIR']) && strtolower($attr['DIR']) === 'ltr') { + $bdf = 0x202A; + $popd = 'LREPDF'; + } // U+202A LRE + } + + if ($bdf) { + // mPDF 5.7.3 Inline tags + if (!isset($this->mpdf->InlineBDF[$tag])) { + $this->mpdf->InlineBDF[$tag] = [[$popd, $this->mpdf->InlineBDFctr]]; + } else { + $this->mpdf->InlineBDF[$tag][] = [$popd, $this->mpdf->InlineBDFctr]; + } + $this->mpdf->InlineBDFctr++; + if ($bdf2) { + $bdf2 = UtfString::code2utf($bdf); + } + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer(UtfString::code2utf($bdf) . $bdf2); + } else { + $this->mpdf->_saveTextBuffer(UtfString::code2utf($bdf) . $bdf2); + } + $this->mpdf->biDirectional = true; + } + } + + public function close(&$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + + $annot = false; // mPDF 6 + $bdf = false; // mPDF 6 + + // mPDF 5.7.3 Inline tags + if ($tag === 'PROGRESS' || $tag === 'METER') { + if (!empty($this->mpdf->InlineProperties[$tag])) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]); + } + unset($this->mpdf->InlineProperties[$tag]); + if (!empty($this->mpdf->InlineAnnots[$tag])) { + $annot = $this->mpdf->InlineAnnots[$tag]; + } // *ANNOTATIONS* + unset($this->mpdf->InlineAnnots[$tag]); // *ANNOTATIONS* + } else { + if (isset($this->mpdf->InlineProperties[$tag]) && count($this->mpdf->InlineProperties[$tag])) { + $tmpProps = array_pop($this->mpdf->InlineProperties[$tag]); // mPDF 5.7.4 + $this->mpdf->restoreInlineProperties($tmpProps); + } + if (isset($this->mpdf->InlineAnnots[$tag]) && count($this->mpdf->InlineAnnots[$tag])) { // *ANNOTATIONS* + $annot = array_pop($this->mpdf->InlineAnnots[$tag]); // *ANNOTATIONS* + } // *ANNOTATIONS* + if (isset($this->mpdf->InlineBDF[$tag]) && count($this->mpdf->InlineBDF[$tag])) { // mPDF 6 + $bdfarr = array_pop($this->mpdf->InlineBDF[$tag]); + $bdf = $bdfarr[0]; + } + } + + /* -- ANNOTATIONS -- */ + if ($annot) { // mPDF 6 + if ($this->mpdf->tableLevel) { // *TABLES* + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$annot]; // *TABLES* + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$annot]; + } // *TABLES* + } + /* -- END ANNOTATIONS -- */ + + // mPDF 6 bidi + // mPDF 6 Bidirectional formatting for inline elements + if ($bdf) { + $popf = $this->mpdf->_setBidiCodes('end', $bdf); + $this->mpdf->OTLdata = []; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($popf); + } else { + $this->mpdf->_saveTextBuffer($popf); + } + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Input.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Input.php new file mode 100644 index 0000000..2b5b534 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Input.php @@ -0,0 +1,425 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; +use Mpdf\Utils\UtfString; + +class Input extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + $this->mpdf->ignorefollowingspaces = false; + if (!isset($attr['TYPE'])) { + $attr['TYPE'] = 'TEXT'; + } + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['type'] = 'input'; + if (isset($attr['DISABLED'])) { + $objattr['disabled'] = true; + } + if (isset($attr['READONLY'])) { + $objattr['readonly'] = true; + } + if (isset($attr['REQUIRED'])) { + $objattr['required'] = true; + } + if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK']) === 'true') { + $objattr['spellcheck'] = true; + } + if (isset($attr['TITLE'])) { + $objattr['title'] = $attr['TITLE']; + } elseif (isset($attr['ALT'])) { + $objattr['title'] = $attr['ALT']; + } else { + $objattr['title'] = ''; + } + $objattr['title'] = UtfString::strcode2utf($objattr['title']); + $objattr['title'] = $this->mpdf->lesser_entity_decode($objattr['title']); + if ($this->mpdf->onlyCoreFonts) { + $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mpdf->mb_enc, 'UTF-8'); + } + if ($this->mpdf->useActiveForms && isset($attr['NAME'])) { + $objattr['fieldname'] = $attr['NAME']; + } + if (isset($attr['VALUE'])) { + $attr['VALUE'] = UtfString::strcode2utf($attr['VALUE']); + $attr['VALUE'] = $this->mpdf->lesser_entity_decode($attr['VALUE']); + if ($this->mpdf->onlyCoreFonts) { + $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mpdf->mb_enc, 'UTF-8'); + } + $objattr['value'] = $attr['VALUE']; + } + + $this->mpdf->InlineProperties['INPUT'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('', 'INPUT', $attr); + $objattr['vertical-align'] = ''; + + if (isset($properties['FONT-FAMILY'])) { + $this->mpdf->SetFont($properties['FONT-FAMILY'], $this->mpdf->FontStyle, 0, false); + } + if (isset($properties['FONT-SIZE'])) { + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE); + $this->mpdf->SetFontSize($mmsize * Mpdf::SCALE, false); + } + if (isset($properties['COLOR'])) { + $objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } + $objattr['fontfamily'] = $this->mpdf->FontFamily; + $objattr['fontsize'] = $this->mpdf->FontSizePt; + if ($this->mpdf->useActiveForms) { + if (isset($attr['ALIGN'])) { + $objattr['text_align'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } elseif (isset($properties['TEXT-ALIGN'])) { + $objattr['text_align'] = self::ALIGN[strtolower($properties['TEXT-ALIGN'])]; + } + if (isset($properties['BORDER-TOP-COLOR'])) { + $objattr['border-col'] = $this->colorConverter->convert($properties['BORDER-TOP-COLOR'], $this->mpdf->PDFAXwarnings); + } + if (isset($properties['BACKGROUND-COLOR'])) { + $objattr['background-col'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); + } + } + + $type = ''; + $texto = ''; + $height = $this->mpdf->FontSize; + $width = 0; + $spacesize = $this->mpdf->GetCharWidth(' ', false); + + $w = 0; + if (isset($properties['WIDTH'])) { + $w = $this->sizeConverter->convert($properties['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + } + + if ($properties['VERTICAL-ALIGN']) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + + switch (strtoupper($attr['TYPE'])) { + case 'HIDDEN': + $this->mpdf->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces + if ($this->mpdf->useActiveForms) { + $this->form->SetFormText(0, 0, $objattr['fieldname'], $objattr['value'], $objattr['value'], '', 0, '', true); + } + if ($this->mpdf->InlineProperties[$tag]) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]); + } + unset($this->mpdf->InlineProperties[$tag]); + return; + + case 'CHECKBOX': //Draw Checkbox + $type = 'CHECKBOX'; + if (isset($attr['CHECKED'])) { + $objattr['checked'] = true; + } else { + $objattr['checked'] = false; + } + $width = $this->mpdf->FontSize; + $height = $this->mpdf->FontSize; + break; + + case 'RADIO': //Draw Radio button + $type = 'RADIO'; + if (isset($attr['CHECKED'])) { + $objattr['checked'] = true; + } + $width = $this->mpdf->FontSize; + $height = $this->mpdf->FontSize; + break; + + /* -- IMAGES-CORE -- */ + case 'IMAGE': // Draw an Image button + if (isset($attr['SRC'])) { + $type = 'IMAGE'; + $srcpath = $attr['SRC']; + $orig_srcpath = $attr['ORIG_SRC']; + // VSPACE and HSPACE converted to margins in MergeCSS + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-LEFT'])) { + $objattr['margin_left'] = $this->sizeConverter->convert( + $properties['MARGIN-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-RIGHT'])) { + $objattr['margin_right'] = $this->sizeConverter->convert( + $properties['MARGIN-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['BORDER-TOP'])) { + $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + } + if (isset($properties['BORDER-LEFT'])) { + $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } + if (isset($properties['BORDER-RIGHT'])) { + $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } + + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + + if (isset($properties['VERTICAL-ALIGN'])) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + + $w = 0; + $h = 0; + if (isset($properties['WIDTH'])) { + $w = $this->sizeConverter->convert($properties['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + } + if (isset($properties['HEIGHT'])) { + $h = $this->sizeConverter->convert($properties['HEIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + } + + $extraheight = $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; + $extrawidth = $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; + + // Image file + $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath); + if (!$info) { + $info = $this->imageProcessor->getImage($this->mpdf->noImageFile); + if ($info) { + $srcpath = $this->mpdf->noImageFile; + $w = ($info['w'] * (25.4 / $this->mpdf->img_dpi)); + $h = ($info['h'] * (25.4 / $this->mpdf->img_dpi)); + } + } + if (!$info) { + break; + } + if ($info['cs'] === 'Indexed') { + $objattr['Indexed'] = true; + } + $objattr['file'] = $srcpath; + //Default width and height calculation if needed + if ($w == 0 && $h == 0) { + /* -- IMAGES-WMF -- */ + if ($info['type'] === 'wmf') { + // WMF units are twips (1/20pt) + // divide by 20 to get points + // divide by k to get user units + $w = abs($info['w']) / (20 * Mpdf::SCALE); + $h = abs($info['h']) / (20 * Mpdf::SCALE); + } else { /* -- END IMAGES-WMF -- */ + if ($info['type'] === 'svg') { + // SVG units are pixels + $w = abs($info['w']) / Mpdf::SCALE; + $h = abs($info['h']) / Mpdf::SCALE; + } else { + //Put image at default image dpi + $w = ($info['w'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); + $h = ($info['h'] / Mpdf::SCALE) * (72 / $this->mpdf->img_dpi); + } + } + if (isset($properties['IMAGE-RESOLUTION'])) { + if (preg_match('/from-image/i', $properties['IMAGE-RESOLUTION']) && isset($info['set-dpi']) && $info['set-dpi'] > 0) { + $w *= $this->mpdf->img_dpi / $info['set-dpi']; + $h *= $this->mpdf->img_dpi / $info['set-dpi']; + } elseif (preg_match('/(\d+)dpi/i', $properties['IMAGE-RESOLUTION'], $m)) { + $dpi = $m[1]; + if ($dpi > 0) { + $w *= $this->mpdf->img_dpi / $dpi; + $h *= $this->mpdf->img_dpi / $dpi; + } + } + } + } + // IF WIDTH OR HEIGHT SPECIFIED + if ($w == 0) { + $w = $h * $info['w'] / $info['h']; + } + if ($h == 0) { + $h = $w * $info['h'] / $info['w']; + } + // Resize to maximum dimensions of page + $maxWidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; + $maxHeight = $this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin + 10); + if ($this->mpdf->fullImageHeight) { + $maxHeight = $this->mpdf->fullImageHeight; + } + if (($w + $extrawidth) > ($maxWidth + 0.0001)) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth + $w = $maxWidth - $extrawidth; + $h = $w * $info['h'] / $info['w']; + } + if ($h + $extraheight > $maxHeight) { + $h = $maxHeight - $extraheight; + $w = $h * $info['w'] / $info['h']; + } + $height = $h + $extraheight; + $width = $w + $extrawidth; + $objattr['type'] = 'image'; + $objattr['itype'] = $info['type']; + $objattr['orig_h'] = $info['h']; + $objattr['orig_w'] = $info['w']; + /* -- IMAGES-WMF -- */ + if ($info['type'] === 'wmf') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + /* -- END IMAGES-WMF -- */ + } else { + if ($info['type'] === 'svg') { + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + } + } + $objattr['height'] = $h + $extraheight; + $objattr['width'] = $w + $extrawidth; + + $objattr['image_height'] = $h; + $objattr['image_width'] = $w; + $objattr['ID'] = $info['i']; + $texto = 'X'; + if ($this->mpdf->useActiveForms) { + if (isset($attr['ONCLICK'])) { + $objattr['onClick'] = $attr['ONCLICK']; + } + $objattr['type'] = 'input'; + $type = 'IMAGE'; + } + break; + } + /* -- END IMAGES-CORE -- */ + + case 'BUTTON': // Draw a button + case 'SUBMIT': + case 'RESET': + $type = strtoupper($attr['TYPE']); + if ($type === 'IMAGE') { + $type = 'BUTTON'; + } // src path not found + if (isset($attr['NOPRINT'])) { + $objattr['noprint'] = true; + } + if (!isset($attr['VALUE'])) { + $objattr['value'] = ucfirst(strtolower($type)); + } + + $texto = ' ' . $objattr['value'] . ' '; + + $width = $this->mpdf->GetStringWidth($texto) + ($this->form->form_element_spacing['button']['outer']['h'] * 2) + + ($this->form->form_element_spacing['button']['inner']['h'] * 2); + + $height = $this->mpdf->FontSize + ($this->form->form_element_spacing['button']['outer']['v'] * 2) + + ($this->form->form_element_spacing['button']['inner']['v'] * 2); + + if ($this->mpdf->useActiveForms && isset($attr['ONCLICK'])) { + $objattr['onClick'] = $attr['ONCLICK']; + } + break; + + case 'PASSWORD': + case 'TEXT': + default: + if ($type == '') { + $type = 'TEXT'; + } + if (strtoupper($attr['TYPE']) === 'PASSWORD') { + $type = 'PASSWORD'; + } + if (isset($attr['VALUE'])) { + if ($type === 'PASSWORD') { + $num_stars = mb_strlen($attr['VALUE'], $this->mpdf->mb_enc); + $texto = str_repeat('*', $num_stars); + } else { + $texto = $attr['VALUE']; + } + } + $xw = ($this->form->form_element_spacing['input']['outer']['h'] * 2) + ($this->form->form_element_spacing['input']['inner']['h'] * 2); + $xh = ($this->form->form_element_spacing['input']['outer']['v'] * 2) + ($this->form->form_element_spacing['input']['inner']['v'] * 2); + if ($w) { + $width = $w + $xw; + } else { + $width = (20 * $spacesize) + $xw; + } // Default width in chars + if (isset($attr['SIZE']) && ctype_digit($attr['SIZE'])) { + $width = ($attr['SIZE'] * $spacesize) + $xw; + } + $height = $this->mpdf->FontSize + $xh; + if (isset($attr['MAXLENGTH']) && ctype_digit($attr['MAXLENGTH'])) { + $objattr['maxlength'] = $attr['MAXLENGTH']; + } + if ($this->mpdf->useActiveForms) { + if (isset($attr['ONCALCULATE'])) { + $objattr['onCalculate'] = $attr['ONCALCULATE']; + } elseif (isset($attr['ONCHANGE'])) { + $objattr['onCalculate'] = $attr['ONCHANGE']; + } + if (isset($attr['ONVALIDATE'])) { + $objattr['onValidate'] = $attr['ONVALIDATE']; + } + if (isset($attr['ONKEYSTROKE'])) { + $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; + } + if (isset($attr['ONFORMAT'])) { + $objattr['onFormat'] = $attr['ONFORMAT']; + } + } + break; + } + + $objattr['subtype'] = $type; + $objattr['text'] = $texto; + $objattr['width'] = $width; + $objattr['height'] = $height; + $e = "\xbb\xa4\xactype=input,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + + if ($this->mpdf->InlineProperties[$tag]) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]); + } + unset($this->mpdf->InlineProperties[$tag]); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ins.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ins.php new file mode 100644 index 0000000..03ec244 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ins.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Ins extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Kbd.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Kbd.php new file mode 100644 index 0000000..10b7880 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Kbd.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Kbd extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Legend.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Legend.php new file mode 100644 index 0000000..90308d4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Legend.php @@ -0,0 +1,35 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class Legend extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->InlineProperties['LEGEND'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('INLINE', 'LEGEND', $attr); + if (!empty($properties)) { + $this->mpdf->setCSS($properties, 'INLINE'); + } + } + + public function close(&$ahtml, &$ihtml) + { + if (count($this->mpdf->textbuffer) && !$this->mpdf->tableLevel) { + $leg = $this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1]; + unset($this->mpdf->textbuffer[count($this->mpdf->textbuffer) - 1]); + $this->mpdf->textbuffer = array_values($this->mpdf->textbuffer); + $this->mpdf->blk[$this->mpdf->blklvl]['border_legend'] = $leg; + $this->mpdf->blk[$this->mpdf->blklvl]['margin_top'] += ($leg[11] / 2) / Mpdf::SCALE; + $this->mpdf->blk[$this->mpdf->blklvl]['padding_top'] += ($leg[11] / 2) / Mpdf::SCALE; + } + if (isset($this->mpdf->InlineProperties['LEGEND'])) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['LEGEND']); + } + unset($this->mpdf->InlineProperties['LEGEND']); + $this->mpdf->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Li.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Li.php new file mode 100644 index 0000000..361af06 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Li.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Li extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Main.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Main.php new file mode 100644 index 0000000..2e2fe39 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Main.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Main extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Mark.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Mark.php new file mode 100644 index 0000000..38c14a4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Mark.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Mark extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Meter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Meter.php new file mode 100644 index 0000000..e3f9297 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Meter.php @@ -0,0 +1,517 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class Meter extends InlineTag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + $this->mpdf->inMeter = true; + + $max = 1; + if (!empty($attr['MAX'])) { + $max = $attr['MAX']; + } + + $min = 0; + if (!empty($attr['MIN']) && $tag === 'METER') { + $min = $attr['MIN']; + } + + if ($max < $min) { + $max = $min; + } + + $value = ''; + if (isset($attr['VALUE']) && ($attr['VALUE'] || $attr['VALUE'] === '0')) { + $value = $attr['VALUE']; + if ($value < $min) { + $value = $min; + } elseif ($value > $max) { + $value = $max; + } + } + + $low = $min; + if (!empty($attr['LOW'])) { + $low = $attr['LOW']; + } + if ($low < $min) { + $low = $min; + } elseif ($low > $max) { + $low = $max; + } + $high = $max; + if (!empty($attr['HIGH'])) { + $high = $attr['HIGH']; + } + if ($high < $low) { + $high = $low; + } elseif ($high > $max) { + $high = $max; + } + if (!empty($attr['OPTIMUM'])) { + $optimum = $attr['OPTIMUM']; + } else { + $optimum = $min + (($max - $min) / 2); + } + if ($optimum < $min) { + $optimum = $min; + } elseif ($optimum > $max) { + $optimum = $max; + } + $type = ''; + if (!empty($attr['TYPE'])) { + $type = $attr['TYPE']; + } + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + + $properties = $this->cssManager->MergeCSS('INLINE', $tag, $attr); + if (isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY']) === 'none') { + return; + } + $objattr['visibility'] = 'visible'; + if (isset($properties['VISIBILITY'])) { + $v = strtolower($properties['VISIBILITY']); + if (($v === 'hidden' || $v === 'printonly' || $v === 'screenonly') && $this->mpdf->visibility === 'visible') { + $objattr['visibility'] = $v; + } + } + + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-LEFT'])) { + $objattr['margin_left'] = $this->sizeConverter->convert( + $properties['MARGIN-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-RIGHT'])) { + $objattr['margin_right'] = $this->sizeConverter->convert( + $properties['MARGIN-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['PADDING-TOP'])) { + $objattr['padding_top'] = $this->sizeConverter->convert( + $properties['PADDING-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-BOTTOM'])) { + $objattr['padding_bottom'] = $this->sizeConverter->convert( + $properties['PADDING-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-LEFT'])) { + $objattr['padding_left'] = $this->sizeConverter->convert( + $properties['PADDING-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-RIGHT'])) { + $objattr['padding_right'] = $this->sizeConverter->convert( + $properties['PADDING-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['BORDER-TOP'])) { + $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + } + if (isset($properties['BORDER-LEFT'])) { + $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } + if (isset($properties['BORDER-RIGHT'])) { + $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } + + if (isset($properties['VERTICAL-ALIGN'])) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + $w = 0; + $h = 0; + if (isset($properties['WIDTH'])) { + $w = $this->sizeConverter->convert( + $properties['WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['WIDTH'])) { + $w = $this->sizeConverter->convert($attr['WIDTH'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['HEIGHT'])) { + $h = $this->sizeConverter->convert( + $properties['HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } elseif (isset($attr['HEIGHT'])) { + $h = $this->sizeConverter->convert($attr['HEIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { + $objattr['opacity'] = $properties['OPACITY']; + } + if ($this->mpdf->HREF) { + if (strpos($this->mpdf->HREF, '.') === false && strpos($this->mpdf->HREF, '@') !== 0) { + $href = $this->mpdf->HREF; + while (array_key_exists($href, $this->mpdf->internallink)) { + $href = '#' . $href; + } + $this->mpdf->internallink[$href] = $this->mpdf->AddLink(); + $objattr['link'] = $this->mpdf->internallink[$href]; + } else { + $objattr['link'] = $this->mpdf->HREF; + } + } + $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; + + $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; + + $svg = $this->makeSVG($type, $value, $max, $min, $optimum, $low, $high); + //Save to local file + $srcpath = $this->cache->write('/_tempSVG' . uniqid(random_int(1, 100000), true) . '_' . strtolower($tag) . '.svg', $svg); + $orig_srcpath = $srcpath; + $this->mpdf->GetFullPath($srcpath); + + $info = $this->imageProcessor->getImage($srcpath, true, true, $orig_srcpath); + if (!$info) { + $info = $this->imageProcessor->getImage($this->mpdf->noImageFile); + if ($info) { + $srcpath = $this->mpdf->noImageFile; + $w = ($info['w'] * (25.4 / $this->mpdf->img_dpi)); + $h = ($info['h'] * (25.4 / $this->mpdf->img_dpi)); + } + } + if (!$info) { + return; + } + + $objattr['file'] = $srcpath; + + // Default width and height calculation if needed + if ($w == 0 && $h == 0) { + // SVG units are pixels + $w = $this->mpdf->FontSize / (10 / Mpdf::SCALE) * abs($info['w']) / Mpdf::SCALE; + $h = $this->mpdf->FontSize / (10 / Mpdf::SCALE) * abs($info['h']) / Mpdf::SCALE; + } + + // IF WIDTH OR HEIGHT SPECIFIED + if ($w == 0) { + $w = $info['h'] ? abs($h * $info['w'] / $info['h']) : INF; + } + if ($h == 0) { + $h = $info['w'] ? abs($w * $info['h'] / $info['w']) : INF; + } + + // Resize to maximum dimensions of page + $maxWidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; + $maxHeight = $this->mpdf->h - ($this->mpdf->tMargin + $this->mpdf->bMargin + 1); + if ($this->mpdf->fullImageHeight) { + $maxHeight = $this->mpdf->fullImageHeight; + } + if (($w + $extrawidth) > ($maxWidth + 0.0001)) { // mPDF 5.7.4 0.0001 to allow for rounding errors when w==maxWidth + $w = $maxWidth - $extrawidth; + $h = abs($w * $info['h'] / $info['w']); + } + + if ($h + $extraheight > $maxHeight) { + $h = $maxHeight - $extraheight; + $w = abs($h * $info['w'] / $info['h']); + } + $objattr['type'] = 'image'; + $objattr['itype'] = $info['type']; + + $objattr['orig_h'] = $info['h']; + $objattr['orig_w'] = $info['w']; + $objattr['wmf_x'] = $info['x']; + $objattr['wmf_y'] = $info['y']; + $objattr['height'] = $h + $extraheight; + $objattr['width'] = $w + $extrawidth; + $objattr['image_height'] = $h; + $objattr['image_width'] = $w; + $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; + } else { + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } + } + + public function close(&$ahtml, &$ihtml) + { + parent::close($ahtml, $ihtml); + $this->mpdf->ignorefollowingspaces = false; + $this->mpdf->inMeter = false; + } + + protected function makeSVG($type, $value, $max, $min, $optimum, $low, $high) + { + if ($type == '2') { + ///////////////////////////////////////////////////////////////////////////////////// + ///////// CUSTOM <meter type="2"> + ///////////////////////////////////////////////////////////////////////////////////// + $h = 10; + $w = 160; + $border_radius = 0.143; // Factor of Height + + $svg = '<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="' . $w . 'px" height="' . $h . 'px" viewBox="0 0 ' . $w . ' ' . $h . '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ><g> + + +<defs> +<linearGradient id="GrGRAY" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(222, 222, 222)" /> +<stop offset="20%" stop-color="rgb(232, 232, 232)" /> +<stop offset="25%" stop-color="rgb(232, 232, 232)" /> +<stop offset="100%" stop-color="rgb(182, 182, 182)" /> +</linearGradient> + +</defs> +'; + $svg .= '<rect x="0" y="0" width="' . $w . '" height="' . $h . '" fill="#f4f4f4" stroke="none" />'; + + // LOW to HIGH region + //if ($low && $high && ($low != $min || $high != $max)) { + if ($low && $high) { + $barx = (($low - $min) / ($max - $min) ) * $w; + $barw = (($high - $low) / ($max - $min) ) * $w; + $svg .= '<rect x="' . $barx . '" y="0" width="' . $barw . '" height="' . $h . '" fill="url(#GrGRAY)" stroke="#888888" stroke-width="0.5px" />'; + } + + // OPTIMUM Marker (? AVERAGE) + if ($optimum) { + $barx = (($optimum - $min) / ($max - $min) ) * $w; + $barw = $h / 2; + $barcol = '#888888'; + $svg .= '<rect x="' . $barx . '" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $barw . '" height="' . $h . '" fill="' . $barcol . '" stroke="none" />'; + } + + // VALUE Marker + if ($value) { + if ($min != $low && $value < $low) { + $col = 'orange'; + } elseif ($max != $high && $value > $high) { + $col = 'orange'; + } else { + $col = '#008800'; + } + $cx = (($value - $min) / ($max - $min) ) * $w; + $cy = $h / 2; + $rx = $h / 3.5; + $ry = $h / 2.2; + $svg .= '<ellipse fill="' . $col . '" stroke="#000000" stroke-width="0.5px" cx="' . $cx . '" cy="' . $cy . '" rx="' . $rx . '" ry="' . $ry . '"/>'; + } + + // BoRDER + $svg .= '<rect x="0" y="0" width="' . $w . '" height="' . $h . '" fill="none" stroke="#888888" stroke-width="0.5px" />'; + + $svg .= '</g></svg>'; + } elseif ($type == '3') { + ///////////////////////////////////////////////////////////////////////////////////// + ///////// CUSTOM <meter type="2"> + ///////////////////////////////////////////////////////////////////////////////////// + $h = 10; + $w = 100; + $border_radius = 0.143; // Factor of Height + + $svg = '<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="' . $w . 'px" height="' . $h . 'px" viewBox="0 0 ' . $w . ' ' . $h . '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ><g> + + +<defs> +<linearGradient id="GrGRAY" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(222, 222, 222)" /> +<stop offset="20%" stop-color="rgb(232, 232, 232)" /> +<stop offset="25%" stop-color="rgb(232, 232, 232)" /> +<stop offset="100%" stop-color="rgb(182, 182, 182)" /> +</linearGradient> + +</defs> +'; + $svg .= '<rect x="0" y="0" width="' . $w . '" height="' . $h . '" fill="#f4f4f4" stroke="none" />'; + + // LOW to HIGH region + if ($low && $high && ($low != $min || $high != $max)) { + //if ($low && $high) { + $barx = (($low - $min) / ($max - $min) ) * $w; + $barw = (($high - $low) / ($max - $min) ) * $w; + $svg .= '<rect x="' . $barx . '" y="0" width="' . $barw . '" height="' . $h . '" fill="url(#GrGRAY)" stroke="#888888" stroke-width="0.5px" />'; + } + + // OPTIMUM Marker (? AVERAGE) + if ($optimum) { + $barx = (($optimum - $min) / ($max - $min) ) * $w; + $barw = $h / 2; + $barcol = '#888888'; + $svg .= '<rect x="' . $barx . '" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $barw . '" height="' . $h . '" fill="' . $barcol . '" stroke="none" />'; + } + + // VALUE Marker + if ($value) { + if ($min != $low && $value < $low) { + $col = 'orange'; + } elseif ($max != $high && $value > $high) { + $col = 'orange'; + } else { + $col = 'orange'; + } + $cx = (($value - $min) / ($max - $min) ) * $w; + $cy = $h / 2; + $rx = $h / 2.2; + $ry = $h / 2.2; + $svg .= '<ellipse fill="' . $col . '" stroke="#000000" stroke-width="0.5px" cx="' . $cx . '" cy="' . $cy . '" rx="' . $rx . '" ry="' . $ry . '"/>'; + } + + // BoRDER + $svg .= '<rect x="0" y="0" width="' . $w . '" height="' . $h . '" fill="none" stroke="#888888" stroke-width="0.5px" />'; + + $svg .= '</g></svg>'; + } else { + ///////////////////////////////////////////////////////////////////////////////////// + ///////// DEFAULT <meter> + ///////////////////////////////////////////////////////////////////////////////////// + $h = 10; + $w = 50; + $border_radius = 0.143; // Factor of Height + + $svg = '<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="' . $w . 'px" height="' . $h . 'px" viewBox="0 0 ' . $w . ' ' . $h . '" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ><g> + +<defs> +<linearGradient id="GrGRAY" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(222, 222, 222)" /> +<stop offset="20%" stop-color="rgb(232, 232, 232)" /> +<stop offset="25%" stop-color="rgb(232, 232, 232)" /> +<stop offset="100%" stop-color="rgb(182, 182, 182)" /> +</linearGradient> + +<linearGradient id="GrRED" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(255, 162, 162)" /> +<stop offset="20%" stop-color="rgb(255, 218, 218)" /> +<stop offset="25%" stop-color="rgb(255, 218, 218)" /> +<stop offset="100%" stop-color="rgb(255, 0, 0)" /> +</linearGradient> + +<linearGradient id="GrGREEN" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(102, 230, 102)" /> +<stop offset="20%" stop-color="rgb(218, 255, 218)" /> +<stop offset="25%" stop-color="rgb(218, 255, 218)" /> +<stop offset="100%" stop-color="rgb(0, 148, 0)" /> +</linearGradient> + +<linearGradient id="GrBLUE" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(102, 102, 230)" /> +<stop offset="20%" stop-color="rgb(238, 238, 238)" /> +<stop offset="25%" stop-color="rgb(238, 238, 238)" /> +<stop offset="100%" stop-color="rgb(0, 0, 128)" /> +</linearGradient> + +<linearGradient id="GrORANGE" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(255, 186, 0)" /> +<stop offset="20%" stop-color="rgb(255, 238, 168)" /> +<stop offset="25%" stop-color="rgb(255, 238, 168)" /> +<stop offset="100%" stop-color="rgb(255, 155, 0)" /> +</linearGradient> +</defs> + +<rect x="0" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $w . '" height="' . $h . '" fill="url(#GrGRAY)" stroke="none" /> +'; + + if ($value) { + $barw = (($value - $min) / ($max - $min) ) * $w; + if ($optimum < $low) { + if ($value < $low) { + $barcol = 'url(#GrGREEN)'; + } elseif ($value > $high) { + $barcol = 'url(#GrRED)'; + } else { + $barcol = 'url(#GrORANGE)'; + } + } elseif ($optimum > $high) { + if ($value < $low) { + $barcol = 'url(#GrRED)'; + } elseif ($value > $high) { + $barcol = 'url(#GrGREEN)'; + } else { + $barcol = 'url(#GrORANGE)'; + } + } else { + if ($value < $low) { + $barcol = 'url(#GrORANGE)'; + } elseif ($value > $high) { + $barcol = 'url(#GrORANGE)'; + } else { + $barcol = 'url(#GrGREEN)'; + } + } + $svg .= '<rect x="0" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $barw . '" height="' . $h . '" fill="' . $barcol . '" stroke="none" />'; + } + + $svg .= '</g></svg>'; + } + + + return $svg; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Nav.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Nav.php new file mode 100644 index 0000000..7845cfa --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Nav.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Nav extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewColumn.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewColumn.php new file mode 100644 index 0000000..a9ff5a1 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewColumn.php @@ -0,0 +1,18 @@ +<?php + +namespace Mpdf\Tag; + +class NewColumn extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->ignorefollowingspaces = true; + $this->mpdf->NewColumn(); + $this->mpdf->ColumnAdjust = false; // disables all column height adjustment for the page. + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewPage.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewPage.php new file mode 100644 index 0000000..3a7f50f --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/NewPage.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf\Tag; + +class NewPage extends FormFeed +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ol.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ol.php new file mode 100644 index 0000000..75deba9 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ol.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Ol extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Option.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Option.php new file mode 100644 index 0000000..c5233d1 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Option.php @@ -0,0 +1,38 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Utils\UtfString; + +class Option extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = ''; + $this->mpdf->selectoption['ACTIVE'] = true; + $this->mpdf->selectoption['currentSEL'] = false; + if (empty($this->mpdf->selectoption)) { + $this->mpdf->selectoption['MAXWIDTH'] = ''; + $this->mpdf->selectoption['SELECTED'] = ''; + } + if (isset($attr['SELECTED'])) { + $this->mpdf->selectoption['SELECTED'] = ''; + $this->mpdf->selectoption['currentSEL'] = true; + } + if (isset($attr['VALUE'])) { + $attr['VALUE'] = UtfString::strcode2utf($attr['VALUE']); + $attr['VALUE'] = $this->mpdf->lesser_entity_decode($attr['VALUE']); + if ($this->mpdf->onlyCoreFonts) { + $attr['VALUE'] = mb_convert_encoding($attr['VALUE'], $this->mpdf->mb_enc, 'UTF-8'); + } + } + $this->mpdf->selectoption['currentVAL'] = $attr['VALUE']; + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->selectoption['ACTIVE'] = false; + $this->mpdf->lastoptionaltag = ''; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/P.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/P.php new file mode 100644 index 0000000..61b2a80 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/P.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class P extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageBreak.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageBreak.php new file mode 100644 index 0000000..9f721c4 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageBreak.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf\Tag; + +class PageBreak extends FormFeed +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageFooter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageFooter.php new file mode 100644 index 0000000..7b18a61 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageFooter.php @@ -0,0 +1,153 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class PageFooter extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + $this->mpdf->ignorefollowingspaces = true; + $pname = '_nonhtmldefault'; + if ($attr['NAME']) { + $pname = $attr['NAME']; + } // mPDF 6 + + $p = []; // mPDF 6 + $p['L'] = []; + $p['C'] = []; + $p['R'] = []; + $p['L']['font-style'] = ''; + $p['C']['font-style'] = ''; + $p['R']['font-style'] = ''; + + if (isset($attr['CONTENT-LEFT'])) { + $p['L']['content'] = $attr['CONTENT-LEFT']; + } + if (isset($attr['CONTENT-CENTER'])) { + $p['C']['content'] = $attr['CONTENT-CENTER']; + } + if (isset($attr['CONTENT-RIGHT'])) { + $p['R']['content'] = $attr['CONTENT-RIGHT']; + } + + if (isset($attr['HEADER-STYLE']) || isset($attr['FOOTER-STYLE'])) { // font-family,size,weight,style,color + if ($tag === 'PAGEHEADER') { + $properties = $this->cssManager->readInlineCSS($attr['HEADER-STYLE']); + } else { + $properties = $this->cssManager->readInlineCSS($attr['FOOTER-STYLE']); + } + if (isset($properties['FONT-FAMILY'])) { + $p['L']['font-family'] = $properties['FONT-FAMILY']; + $p['C']['font-family'] = $properties['FONT-FAMILY']; + $p['R']['font-family'] = $properties['FONT-FAMILY']; + } + if (isset($properties['FONT-SIZE'])) { + $p['L']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + $p['C']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + $p['R']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + } + if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT'] === 'bold') { + $p['L']['font-style'] = 'B'; + $p['C']['font-style'] = 'B'; + $p['R']['font-style'] = 'B'; + } + if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE'] === 'italic') { + $p['L']['font-style'] .= 'I'; + $p['C']['font-style'] .= 'I'; + $p['R']['font-style'] .= 'I'; + } + if (isset($properties['COLOR'])) { + $p['L']['color'] = $properties['COLOR']; + $p['C']['color'] = $properties['COLOR']; + $p['R']['color'] = $properties['COLOR']; + } + } + if (isset($attr['HEADER-STYLE-LEFT']) || isset($attr['FOOTER-STYLE-LEFT'])) { + if ($tag === 'PAGEHEADER') { + $properties = $this->cssManager->readInlineCSS($attr['HEADER-STYLE-LEFT']); + } else { + $properties = $this->cssManager->readInlineCSS($attr['FOOTER-STYLE-LEFT']); + } + if (isset($properties['FONT-FAMILY'])) { + $p['L']['font-family'] = $properties['FONT-FAMILY']; + } + if (isset($properties['FONT-SIZE'])) { + $p['L']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + } + if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT'] === 'bold') { + $p['L']['font-style'] = 'B'; + } + if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE'] === 'italic') { + $p['L']['font-style'] .='I'; + } + if (isset($properties['COLOR'])) { + $p['L']['color'] = $properties['COLOR']; + } + } + if (isset($attr['HEADER-STYLE-CENTER']) || isset($attr['FOOTER-STYLE-CENTER'])) { + if ($tag === 'PAGEHEADER') { + $properties = $this->cssManager->readInlineCSS($attr['HEADER-STYLE-CENTER']); + } else { + $properties = $this->cssManager->readInlineCSS($attr['FOOTER-STYLE-CENTER']); + } + if (isset($properties['FONT-FAMILY'])) { + $p['C']['font-family'] = $properties['FONT-FAMILY']; + } + if (isset($properties['FONT-SIZE'])) { + $p['C']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + } + if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT'] === 'bold') { + $p['C']['font-style'] = 'B'; + } + if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE'] === 'italic') { + $p['C']['font-style'] .= 'I'; + } + if (isset($properties['COLOR'])) { + $p['C']['color'] = $properties['COLOR']; + } + } + if (isset($attr['HEADER-STYLE-RIGHT']) || isset($attr['FOOTER-STYLE-RIGHT'])) { + if ($tag === 'PAGEHEADER') { + $properties = $this->cssManager->readInlineCSS($attr['HEADER-STYLE-RIGHT']); + } else { + $properties = $this->cssManager->readInlineCSS($attr['FOOTER-STYLE-RIGHT']); + } + if (isset($properties['FONT-FAMILY'])) { + $p['R']['font-family'] = $properties['FONT-FAMILY']; + } + if (isset($properties['FONT-SIZE'])) { + $p['R']['font-size'] = $this->sizeConverter->convert($properties['FONT-SIZE']) * Mpdf::SCALE; + } + if (isset($properties['FONT-WEIGHT']) && $properties['FONT-WEIGHT'] === 'bold') { + $p['R']['font-style'] = 'B'; + } + if (isset($properties['FONT-STYLE']) && $properties['FONT-STYLE'] === 'italic') { + $p['R']['font-style'] .= 'I'; + } + if (isset($properties['COLOR'])) { + $p['R']['color'] = $properties['COLOR']; + } + } + if (!empty($attr['LINE'])) { // 0|1|on|off + $lineset = 0; + if ($attr['LINE'] == '1' || strtoupper($attr['LINE']) === 'ON') { + $lineset = 1; + } + $p['line'] = $lineset; + } + // mPDF 6 + if ($tag === 'PAGEHEADER') { + $this->mpdf->DefHeaderByName($pname, $p); + } else { + $this->mpdf->DefFooterByName($pname, $p); + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageHeader.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageHeader.php new file mode 100644 index 0000000..9920ee7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/PageHeader.php @@ -0,0 +1,8 @@ +<?php + +namespace Mpdf\Tag; + +class PageHeader extends PageFooter +{ + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Pre.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Pre.php new file mode 100644 index 0000000..ef21606 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Pre.php @@ -0,0 +1,13 @@ +<?php + +namespace Mpdf\Tag; + +class Pre extends BlockTag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->ispre = true; // ADDED - Prevents left trim of textbuffer in printbuffer() + parent::open($attr, $ahtml, $ihtml); // TODO: Change the autogenerated stub + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Progress.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Progress.php new file mode 100644 index 0000000..32e22da --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Progress.php @@ -0,0 +1,72 @@ +<?php + +namespace Mpdf\Tag; + +class Progress extends Meter +{ + protected function makeSVG($type, $value, $max, $min, $optimum, $low, $high) + { + $svg = ''; + + if ($type == '2') { + ///////////////////////////////////////////////////////////////////////////////////// + ///////// CUSTOM <progress type="2"> + ///////////////////////////////////////////////////////////////////////////////////// + } else { + ///////////////////////////////////////////////////////////////////////////////////// + ///////// DEFAULT <progress> + ///////////////////////////////////////////////////////////////////////////////////// + $h = 10; + $w = 100; + $border_radius = 0.143; // Factor of Height + + if ($value or $value === '0') { + $fill = 'url(#GrGRAY)'; + } else { + $fill = '#f8f8f8'; + } + + $svg = '<svg width="' . $w . 'px" height="' . $h . 'px" viewBox="0 0 ' . $w . ' ' . $h . '"><g> + +<defs> +<linearGradient id="GrGRAY" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(222, 222, 222)" /> +<stop offset="20%" stop-color="rgb(232, 232, 232)" /> +<stop offset="25%" stop-color="rgb(232, 232, 232)" /> +<stop offset="100%" stop-color="rgb(182, 182, 182)" /> +</linearGradient> + +<linearGradient id="GrGREEN" x1="0" y1="0" x2="0" y2="1" gradientUnits="boundingBox"> +<stop offset="0%" stop-color="rgb(102, 230, 102)" /> +<stop offset="20%" stop-color="rgb(218, 255, 218)" /> +<stop offset="25%" stop-color="rgb(218, 255, 218)" /> +<stop offset="100%" stop-color="rgb(0, 148, 0)" /> +</linearGradient> + +</defs> + +<rect x="0" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $w . '" height="' . $h . '" fill="' . $fill . '" stroke="none" /> +'; + + if ($value) { + $barw = (($value - $min) / ($max - $min) ) * $w; + $barcol = 'url(#GrGREEN)'; + $svg .= '<rect x="0" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $barw . '" height="' . $h . '" fill="' . $barcol . '" stroke="none" />'; + } + + + // Borders + $svg .= '<rect x="0" y="0" rx="' . ($h * $border_radius) . 'px" ry="' . ($h * $border_radius) . 'px" width="' . $w . '" height="' . $h . '" fill="none" stroke="#888888" stroke-width="0.5px" />'; + if ($value) { + // $svg .= '<rect x="0" y="0" rx="'.($h*$border_radius).'px" ry="'.($h*$border_radius).'px" width="'.$barw.'" height="'.$h.'" fill="none" stroke="#888888" stroke-width="0.5px" />'; + } + + + $svg .= '</g></svg>'; + } + + + return $svg; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Q.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Q.php new file mode 100644 index 0000000..3e05674 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Q.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Q extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/S.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/S.php new file mode 100644 index 0000000..37aa832 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/S.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class S extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Samp.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Samp.php new file mode 100644 index 0000000..c541cdd --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Samp.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Samp extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Section.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Section.php new file mode 100644 index 0000000..1c41a7b --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Section.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Section extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Select.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Select.php new file mode 100644 index 0000000..1d3c131 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Select.php @@ -0,0 +1,154 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class Select extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = ''; // Save current HTML specified optional endtag + $this->mpdf->InlineProperties['SELECT'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('', 'SELECT', $attr); + if (isset($properties['FONT-FAMILY'])) { + $this->mpdf->SetFont($properties['FONT-FAMILY'], $this->mpdf->FontStyle, 0, false); + } + if (isset($properties['FONT-SIZE'])) { + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE); + $this->mpdf->SetFontSize($mmsize * Mpdf::SCALE, false); + } + if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK']) === 'true') { + $this->mpdf->selectoption['SPELLCHECK'] = true; + } + + if (isset($properties['COLOR'])) { + $this->mpdf->selectoption['COLOR'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } + $this->mpdf->specialcontent = 'type=select'; + if (isset($attr['DISABLED'])) { + $this->mpdf->selectoption['DISABLED'] = $attr['DISABLED']; + } + if (isset($attr['READONLY'])) { + $this->mpdf->selectoption['READONLY'] = $attr['READONLY']; + } + if (isset($attr['REQUIRED'])) { + $this->mpdf->selectoption['REQUIRED'] = $attr['REQUIRED']; + } + if (isset($attr['EDITABLE'])) { + $this->mpdf->selectoption['EDITABLE'] = $attr['EDITABLE']; + } + if (isset($attr['TITLE'])) { + $this->mpdf->selectoption['TITLE'] = $attr['TITLE']; + } + if (isset($attr['MULTIPLE'])) { + $this->mpdf->selectoption['MULTIPLE'] = $attr['MULTIPLE']; + } + if (isset($attr['SIZE']) && $attr['SIZE'] > 1) { + $this->mpdf->selectoption['SIZE'] = $attr['SIZE']; + } + if ($this->mpdf->useActiveForms) { + if (isset($attr['NAME'])) { + $this->mpdf->selectoption['NAME'] = $attr['NAME']; + } + if (isset($attr['ONCHANGE'])) { + $this->mpdf->selectoption['ONCHANGE'] = $attr['ONCHANGE']; + } + } + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->ignorefollowingspaces = false; + $this->mpdf->lastoptionaltag = ''; + $texto = ''; + $OTLdata = false; + if (isset($this->mpdf->selectoption['SELECTED'])) { + $texto = $this->mpdf->selectoption['SELECTED']; + } + if (isset($this->mpdf->selectoption['SELECTED-OTLDATA'])) { + $OTLdata = $this->mpdf->selectoption['SELECTED-OTLDATA']; + } + + if ($this->mpdf->useActiveForms) { + $w = $this->mpdf->selectoption['MAXWIDTH']; + } else { + $w = $this->mpdf->GetStringWidth($texto, true, $OTLdata); + } + if ($w == 0) { + $w = 5; + } + $objattr['type'] = 'select'; + $objattr['text'] = $texto; + $objattr['OTLdata'] = $OTLdata; + if (isset($this->mpdf->selectoption['NAME'])) { + $objattr['fieldname'] = $this->mpdf->selectoption['NAME']; + } + if (isset($this->mpdf->selectoption['READONLY'])) { + $objattr['readonly'] = true; + } + if (isset($this->mpdf->selectoption['REQUIRED'])) { + $objattr['required'] = true; + } + if (isset($this->mpdf->selectoption['SPELLCHECK'])) { + $objattr['spellcheck'] = true; + } + if (isset($this->mpdf->selectoption['EDITABLE'])) { + $objattr['editable'] = true; + } + if (isset($this->mpdf->selectoption['ONCHANGE'])) { + $objattr['onChange'] = $this->mpdf->selectoption['ONCHANGE']; + } + if (isset($this->mpdf->selectoption['ITEMS'])) { + $objattr['items'] = $this->mpdf->selectoption['ITEMS']; + } + if (isset($this->mpdf->selectoption['MULTIPLE'])) { + $objattr['multiple'] = $this->mpdf->selectoption['MULTIPLE']; + } + if (isset($this->mpdf->selectoption['DISABLED'])) { + $objattr['disabled'] = $this->mpdf->selectoption['DISABLED']; + } + if (isset($this->mpdf->selectoption['TITLE'])) { + $objattr['title'] = $this->mpdf->selectoption['TITLE']; + } + if (isset($this->mpdf->selectoption['COLOR'])) { + $objattr['color'] = $this->mpdf->selectoption['COLOR']; + } + if (isset($this->mpdf->selectoption['SIZE'])) { + $objattr['size'] = $this->mpdf->selectoption['SIZE']; + } + $rows = 1; + if (isset($objattr['size']) && $objattr['size'] > 1) { + $rows = $objattr['size']; + } + + $objattr['fontfamily'] = $this->mpdf->FontFamily; + $objattr['fontsize'] = $this->mpdf->FontSizePt; + + $objattr['width'] = $w + ($this->form->form_element_spacing['select']['outer']['h'] * 2) + + ($this->form->form_element_spacing['select']['inner']['h'] * 2) + ($this->mpdf->FontSize * 1.4); + + $objattr['height'] = ($this->mpdf->FontSize * $rows) + ($this->form->form_element_spacing['select']['outer']['v'] * 2) + + ($this->form->form_element_spacing['select']['inner']['v'] * 2); + + $e = "\xbb\xa4\xactype=select,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + // Output it to buffers + if ($this->mpdf->tableLevel) { // *TABLES* + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; // *TABLES* + } // *TABLES* + else { // *TABLES* + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + + $this->mpdf->selectoption = []; + $this->mpdf->specialcontent = ''; + + if ($this->mpdf->InlineProperties['SELECT']) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['SELECT']); + } + unset($this->mpdf->InlineProperties['SELECT']); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php new file mode 100644 index 0000000..6cb5242 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageFooter.php @@ -0,0 +1,73 @@ +<?php + +namespace Mpdf\Tag; + +class SetHtmlPageFooter extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + $this->mpdf->ignorefollowingspaces = true; + + $pname = '_default'; + if (!empty($attr['NAME'])) { + $pname = $attr['NAME']; + } elseif ($tag === 'SETPAGEHEADER' || $tag === 'SETPAGEFOOTER') { + $pname = '_nonhtmldefault'; + } // mPDF 6 + + if (!empty($attr['PAGE'])) { // O|odd|even|E|ALL|[blank] + $side = 'odd'; + if (strtoupper($attr['PAGE']) === 'O' || strtoupper($attr['PAGE']) === 'ODD') { + $side = 'odd'; + } elseif (strtoupper($attr['PAGE']) === 'E' || strtoupper($attr['PAGE']) === 'EVEN') { + $side = 'even'; + } elseif (strtoupper($attr['PAGE']) === 'ALL') { + $side = 'both'; + } + } else { + $side = 'odd'; + } + if (!empty($attr['VALUE'])) { // -1|1|on|off + $set = 1; + if ($attr['VALUE'] == '1' || strtoupper($attr['VALUE']) === 'ON') { + $set = 1; + } elseif ($attr['VALUE'] == '-1' || strtoupper($attr['VALUE']) === 'OFF') { + $set = 0; + } + } else { + $set = 1; + } + $write = 0; + if (!empty($attr['SHOW-THIS-PAGE']) && ($tag === 'SETHTMLPAGEHEADER' || $tag === 'SETPAGEHEADER')) { + $write = 1; + } + if ($side === 'odd' || $side === 'both') { + if ($set && ($tag === 'SETHTMLPAGEHEADER' || $tag === 'SETPAGEHEADER')) { + $this->mpdf->SetHTMLHeader($this->mpdf->pageHTMLheaders[$pname], 'O', $write); + } elseif ($set && ($tag === 'SETHTMLPAGEFOOTER' || $tag === 'SETPAGEFOOTER')) { + $this->mpdf->SetHTMLFooter($this->mpdf->pageHTMLfooters[$pname], 'O'); + } elseif ($tag === 'SETHTMLPAGEHEADER' || $tag === 'SETPAGEHEADER') { + $this->mpdf->SetHTMLHeader('', 'O'); + } else { + $this->mpdf->SetHTMLFooter('', 'O'); + } + } + if ($side === 'even' || $side === 'both') { + if ($set && ($tag === 'SETHTMLPAGEHEADER' || $tag === 'SETPAGEHEADER')) { + $this->mpdf->SetHTMLHeader($this->mpdf->pageHTMLheaders[$pname], 'E', $write); + } elseif ($set && ($tag === 'SETHTMLPAGEFOOTER' || $tag === 'SETPAGEFOOTER')) { + $this->mpdf->SetHTMLFooter($this->mpdf->pageHTMLfooters[$pname], 'E'); + } elseif ($tag === 'SETHTMLPAGEHEADER' || $tag === 'SETPAGEHEADER') { + $this->mpdf->SetHTMLHeader('', 'E'); + } else { + $this->mpdf->SetHTMLFooter('', 'E'); + } + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php new file mode 100644 index 0000000..ea98783 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetHtmlPageHeader.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class SetHtmlPageHeader extends SetHtmlPageFooter +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageFooter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageFooter.php new file mode 100644 index 0000000..7596c80 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageFooter.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class SetPageFooter extends SetHtmlPageFooter +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageHeader.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageHeader.php new file mode 100644 index 0000000..ff83dbc --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SetPageHeader.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class SetPageHeader extends SetHtmlPageFooter +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Small.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Small.php new file mode 100644 index 0000000..686c1eb --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Small.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Small extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Span.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Span.php new file mode 100644 index 0000000..eaa3c6a --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Span.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Span extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strike.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strike.php new file mode 100644 index 0000000..65ae0f8 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strike.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Strike extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strong.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strong.php new file mode 100644 index 0000000..5592c3d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Strong.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Strong extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sub.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sub.php new file mode 100644 index 0000000..66a99e1 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sub.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Sub extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SubstituteTag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SubstituteTag.php new file mode 100644 index 0000000..602aa51 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/SubstituteTag.php @@ -0,0 +1,18 @@ +<?php + +namespace Mpdf\Tag; + +abstract class SubstituteTag extends Tag +{ + + public function close(&$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + if ($this->mpdf->InlineProperties[$tag]) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties[$tag]); + } + unset($this->mpdf->InlineProperties[$tag]); + $ltag = strtolower($tag); + $this->mpdf->$ltag = false; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Summary.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Summary.php new file mode 100644 index 0000000..977cc44 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Summary.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Summary extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sup.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sup.php new file mode 100644 index 0000000..9722165 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Sup.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Sup extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TBody.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TBody.php new file mode 100644 index 0000000..25b4c45 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TBody.php @@ -0,0 +1,23 @@ +<?php + +namespace Mpdf\Tag; + +class TBody extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->tablethead = 0; + $this->mpdf->tabletfoot = 0; + $this->mpdf->lastoptionaltag = 'TBODY'; // Save current HTML specified optional endtag + $this->cssManager->tbCSSlvl++; + $this->cssManager->MergeCSS('TABLE', 'TBODY', $attr); + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = ''; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TFoot.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TFoot.php new file mode 100644 index 0000000..d3bd8e8 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TFoot.php @@ -0,0 +1,59 @@ +<?php + +namespace Mpdf\Tag; + +// TODO: Extend THEAD instead? + +class TFoot extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = 'TFOOT'; // Save current HTML specified optional endtag + $this->cssManager->tbCSSlvl++; + $this->mpdf->tabletfoot = 1; + $this->mpdf->tablethead = 0; + $properties = $this->cssManager->MergeCSS('TABLE', 'TFOOT', $attr); + if (isset($properties['FONT-WEIGHT'])) { + $this->mpdf->tfoot_font_weight = ''; + if (strtoupper($properties['FONT-WEIGHT']) === 'BOLD') { + $this->mpdf->tfoot_font_weight = 'B'; + } + } + + if (isset($properties['FONT-STYLE'])) { + $this->mpdf->tfoot_font_style = ''; + if (strtoupper($properties['FONT-STYLE']) === 'ITALIC') { + $this->mpdf->tfoot_font_style = 'I'; + } + } + if (isset($properties['FONT-VARIANT'])) { + $this->mpdf->tfoot_font_smCaps = ''; + if (strtoupper($properties['FONT-VARIANT']) === 'SMALL-CAPS') { + $this->mpdf->tfoot_font_smCaps = 'S'; + } + } + + if (isset($properties['VERTICAL-ALIGN'])) { + $this->mpdf->tfoot_valign_default = $properties['VERTICAL-ALIGN']; + } + if (isset($properties['TEXT-ALIGN'])) { + $this->mpdf->tfoot_textalign_default = $properties['TEXT-ALIGN']; + } + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = ''; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + $this->mpdf->tabletfoot = 0; + $this->mpdf->ResetStyles(); + $this->mpdf->tfoot_font_weight = ''; + $this->mpdf->tfoot_font_style = ''; + $this->mpdf->tfoot_font_smCaps = ''; + + $this->mpdf->tfoot_valign_default = ''; + $this->mpdf->tfoot_textalign_default = ''; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/THead.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/THead.php new file mode 100644 index 0000000..acd8015 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/THead.php @@ -0,0 +1,58 @@ +<?php + +namespace Mpdf\Tag; + +class THead extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = 'THEAD'; // Save current HTML specified optional endtag + $this->cssManager->tbCSSlvl++; + $this->mpdf->tablethead = 1; + $this->mpdf->tabletfoot = 0; + $properties = $this->cssManager->MergeCSS('TABLE', 'THEAD', $attr); + if (isset($properties['FONT-WEIGHT'])) { + $this->mpdf->thead_font_weight = ''; + if (strtoupper($properties['FONT-WEIGHT']) === 'BOLD') { + $this->mpdf->thead_font_weight = 'B'; + } + } + + if (isset($properties['FONT-STYLE'])) { + $this->mpdf->thead_font_style = ''; + if (strtoupper($properties['FONT-STYLE']) === 'ITALIC') { + $this->mpdf->thead_font_style = 'I'; + } + } + if (isset($properties['FONT-VARIANT'])) { + $this->mpdf->thead_font_smCaps = ''; + if (strtoupper($properties['FONT-VARIANT']) === 'SMALL-CAPS') { + $this->mpdf->thead_font_smCaps = 'S'; + } + } + + if (isset($properties['VERTICAL-ALIGN'])) { + $this->mpdf->thead_valign_default = $properties['VERTICAL-ALIGN']; + } + if (isset($properties['TEXT-ALIGN'])) { + $this->mpdf->thead_textalign_default = $properties['TEXT-ALIGN']; + } + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->lastoptionaltag = ''; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + $this->mpdf->tablethead = 0; + $this->mpdf->tabletheadjustfinished = true; + $this->mpdf->ResetStyles(); + $this->mpdf->thead_font_weight = ''; + $this->mpdf->thead_font_style = ''; + $this->mpdf->thead_font_smCaps = ''; + + $this->mpdf->thead_valign_default = ''; + $this->mpdf->thead_textalign_default = ''; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Table.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Table.php new file mode 100644 index 0000000..3261ed6 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Table.php @@ -0,0 +1,1272 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Css\Border; +use Mpdf\Mpdf; + +class Table extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->tdbegin = false; + $this->mpdf->lastoptionaltag = ''; + // Disable vertical justification in columns + if ($this->mpdf->ColActive) { + $this->mpdf->colvAlign = ''; + } // *COLUMNS* + if ($this->mpdf->lastblocklevelchange == 1) { + $blockstate = 1; + } // Top margins/padding only + elseif ($this->mpdf->lastblocklevelchange < 1) { + $blockstate = 0; + } // NO margins/padding + // called from block after new div e.g. <div> ... <table> ... Outputs block top margin/border and padding + if (count($this->mpdf->textbuffer) == 0 && $this->mpdf->lastblocklevelchange == 1 && !$this->mpdf->tableLevel && !$this->mpdf->kwt) { + $this->mpdf->newFlowingBlock($this->mpdf->blk[$this->mpdf->blklvl]['width'], $this->mpdf->lineheight, '', false, 1, true, $this->mpdf->blk[$this->mpdf->blklvl]['direction']); + $this->mpdf->finishFlowingBlock(true); // true = END of flowing block + } elseif (!$this->mpdf->tableLevel && count($this->mpdf->textbuffer)) { + $this->mpdf->printbuffer($this->mpdf->textbuffer, $blockstate); + } + + $this->mpdf->textbuffer = []; + $this->mpdf->lastblocklevelchange = -1; + + + + if ($this->mpdf->tableLevel) { // i.e. now a nested table coming... + // Save current level table + $this->mpdf->cell['PARENTCELL'] = $this->mpdf->saveInlineProperties(); + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['baseProperties'] = $this->mpdf->base_table_properties; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['cells'] = $this->mpdf->cell; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['currrow'] = $this->mpdf->row; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['currcol'] = $this->mpdf->col; + } + $this->mpdf->tableLevel++; + $this->cssManager->tbCSSlvl++; + + if ($this->mpdf->tableLevel > 1) { // inherit table properties from cell in which nested + //$this->mpdf->base_table_properties['FONT-KERNING'] = ($this->mpdf->textvar & TextVars::FC_KERNING); // mPDF 6 + $this->mpdf->base_table_properties['LETTER-SPACING'] = $this->mpdf->lSpacingCSS; + $this->mpdf->base_table_properties['WORD-SPACING'] = $this->mpdf->wSpacingCSS; + // mPDF 6 + $direction = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['direction']; + $txta = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['a']; + $cellLineHeight = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['cellLineHeight']; + $cellLineStackingStrategy = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['cellLineStackingStrategy']; + $cellLineStackingShift = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['cellLineStackingShift']; + } + + if (isset($this->mpdf->tbctr[$this->mpdf->tableLevel])) { + $this->mpdf->tbctr[$this->mpdf->tableLevel] ++; + } else { + $this->mpdf->tbctr[$this->mpdf->tableLevel] = 1; + } + + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['level'] = $this->mpdf->tableLevel; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['levelid'] = $this->mpdf->tbctr[$this->mpdf->tableLevel]; + + if ($this->mpdf->tableLevel > $this->mpdf->innermostTableLevel) { + $this->mpdf->innermostTableLevel = $this->mpdf->tableLevel; + } + if ($this->mpdf->tableLevel > 1) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nestedpos'] = [ + $this->mpdf->row, + $this->mpdf->col, + $this->mpdf->tbctr[$this->mpdf->tableLevel - 1], + ]; + } + //++++++++++++++++++++++++++++ + + $this->mpdf->cell = []; + $this->mpdf->col = -1; //int + $this->mpdf->row = -1; //int + $table = &$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]; + + // New table - any level + $table['direction'] = $this->mpdf->directionality; + $table['bgcolor'] = false; + $table['va'] = false; + $table['txta'] = false; + $table['topntail'] = false; + $table['thead-underline'] = false; + $table['border'] = false; + $table['border_details']['R']['w'] = 0; + $table['border_details']['L']['w'] = 0; + $table['border_details']['T']['w'] = 0; + $table['border_details']['B']['w'] = 0; + $table['border_details']['R']['style'] = ''; + $table['border_details']['L']['style'] = ''; + $table['border_details']['T']['style'] = ''; + $table['border_details']['B']['style'] = ''; + $table['max_cell_border_width']['R'] = 0; + $table['max_cell_border_width']['L'] = 0; + $table['max_cell_border_width']['T'] = 0; + $table['max_cell_border_width']['B'] = 0; + $table['padding']['L'] = false; + $table['padding']['R'] = false; + $table['padding']['T'] = false; + $table['padding']['B'] = false; + $table['margin']['L'] = false; + $table['margin']['R'] = false; + $table['margin']['T'] = false; + $table['margin']['B'] = false; + $table['a'] = false; + $table['border_spacing_H'] = false; + $table['border_spacing_V'] = false; + $table['decimal_align'] = false; + $this->mpdf->Reset(); + $this->mpdf->InlineProperties = []; + $this->mpdf->InlineBDF = []; // mPDF 6 + $this->mpdf->InlineBDFctr = 0; // mPDF 6 + $table['nc'] = $table['nr'] = 0; + $this->mpdf->tablethead = 0; + $this->mpdf->tabletfoot = 0; + $this->mpdf->tabletheadjustfinished = false; + + // mPDF 6 + if ($this->mpdf->tableLevel > 1) { // inherit table properties from cell in which nested + $table['direction'] = $direction; + $table['txta'] = $txta; + $table['cellLineHeight'] = $cellLineHeight; + $table['cellLineStackingStrategy'] = $cellLineStackingStrategy; + $table['cellLineStackingShift'] = $cellLineStackingShift; + } + + + $lastbottommargin = 0; + if ($this->mpdf->blockjustfinished && !count($this->mpdf->textbuffer) && $this->mpdf->y != $this->mpdf->tMargin && $this->mpdf->collapseBlockMargins && $this->mpdf->tableLevel == 1) { + $lastbottommargin = $this->mpdf->lastblockbottommargin; + } + $this->mpdf->lastblockbottommargin = 0; + $this->mpdf->blockjustfinished = false; + + if ($this->mpdf->tableLevel == 1) { + $table['headernrows'] = 0; + $table['footernrows'] = 0; + $this->mpdf->base_table_properties = []; + } + + // ADDED CSS FUNCIONS FOR TABLE + if ($this->cssManager->tbCSSlvl == 1) { + $properties = $this->cssManager->MergeCSS('TOPTABLE', 'TABLE', $attr); + } else { + $properties = $this->cssManager->MergeCSS('TABLE', 'TABLE', $attr); + } + + $w = ''; + if (isset($properties['WIDTH'])) { + $w = $properties['WIDTH']; + } elseif (!empty($attr['WIDTH'])) { + $w = $attr['WIDTH']; + } + + if (isset($attr['ALIGN']) && array_key_exists(strtolower($attr['ALIGN']), self::ALIGN)) { + $table['a'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } + if (!$table['a']) { + if ($table['direction'] === 'rtl') { + $table['a'] = 'R'; + } else { + $table['a'] = 'L'; + } + } + + if (!empty($properties['DIRECTION'])) { + $table['direction'] = strtolower($properties['DIRECTION']); + } elseif (!empty($attr['DIR'])) { + $table['direction'] = strtolower($attr['DIR']); + } elseif ($this->mpdf->tableLevel == 1) { + $table['direction'] = $this->mpdf->blk[$this->mpdf->blklvl]['direction']; + } + + if (isset($properties['BACKGROUND-COLOR'])) { + $table['bgcolor'][-1] = $properties['BACKGROUND-COLOR']; + } elseif (isset($properties['BACKGROUND'])) { + $table['bgcolor'][-1] = $properties['BACKGROUND']; + } elseif (isset($attr['BGCOLOR'])) { + $table['bgcolor'][-1] = $attr['BGCOLOR']; + } + + if (isset($properties['VERTICAL-ALIGN']) && array_key_exists(strtolower($properties['VERTICAL-ALIGN']), self::ALIGN)) { + $table['va'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + if (isset($properties['TEXT-ALIGN']) && array_key_exists(strtolower($properties['TEXT-ALIGN']), self::ALIGN)) { + $table['txta'] = self::ALIGN[strtolower($properties['TEXT-ALIGN'])]; + } + + if (!empty($properties['AUTOSIZE']) && $this->mpdf->tableLevel == 1) { + $this->mpdf->shrink_this_table_to_fit = $properties['AUTOSIZE']; + if ($this->mpdf->shrink_this_table_to_fit < 1) { + $this->mpdf->shrink_this_table_to_fit = 0; + } + } + if (!empty($properties['ROTATE']) && $this->mpdf->tableLevel == 1) { + $this->mpdf->table_rotate = $properties['ROTATE']; + } + if (isset($properties['TOPNTAIL'])) { + $table['topntail'] = $properties['TOPNTAIL']; + } + if (isset($properties['THEAD-UNDERLINE'])) { + $table['thead-underline'] = $properties['THEAD-UNDERLINE']; + } + + if (isset($properties['BORDER'])) { + $bord = $this->mpdf->border_details($properties['BORDER']); + if ($bord['s']) { + $table['border'] = Border::ALL; + $table['border_details']['R'] = $bord; + $table['border_details']['L'] = $bord; + $table['border_details']['T'] = $bord; + $table['border_details']['B'] = $bord; + } + } + if (isset($properties['BORDER-RIGHT'])) { + if ($table['direction'] === 'rtl') { // *OTL* + $table['border_details']['R'] = $this->mpdf->border_details($properties['BORDER-LEFT']); // *OTL* + } // *OTL* + else { // *OTL* + $table['border_details']['R'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } // *OTL* + $this->mpdf->setBorder($table['border'], Border::RIGHT, $table['border_details']['R']['s']); + } + if (isset($properties['BORDER-LEFT'])) { + if ($table['direction'] === 'rtl') { // *OTL* + $table['border_details']['L'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); // *OTL* + } // *OTL* + else { // *OTL* + $table['border_details']['L'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } // *OTL* + $this->mpdf->setBorder($table['border'], Border::LEFT, $table['border_details']['L']['s']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $table['border_details']['B'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + $this->mpdf->setBorder($table['border'], Border::BOTTOM, $table['border_details']['B']['s']); + } + if (isset($properties['BORDER-TOP'])) { + $table['border_details']['T'] = $this->mpdf->border_details($properties['BORDER-TOP']); + $this->mpdf->setBorder($table['border'], Border::TOP, $table['border_details']['T']['s']); + } + + $this->mpdf->table_border_css_set = 0; + if ($table['border']) { + $this->mpdf->table_border_css_set = 1; + } + + // mPDF 6 + if (!empty($properties['LANG'])) { + if ($this->mpdf->autoLangToFont && !$this->mpdf->usingCoreFont) { + if ($properties['LANG'] != $this->mpdf->default_lang && $properties['LANG'] !== 'UTF-8') { + list ($coreSuitable, $mpdf_pdf_unifont) = $this->languageToFont->getLanguageOptions($properties['LANG'], $this->mpdf->useAdobeCJK); + if ($mpdf_pdf_unifont) { + $properties['FONT-FAMILY'] = $mpdf_pdf_unifont; + } + } + } + $this->mpdf->currentLang = $properties['LANG']; + } + + + if (isset($properties['FONT-FAMILY'])) { + $this->mpdf->default_font = $properties['FONT-FAMILY']; + $this->mpdf->SetFont($this->mpdf->default_font, '', 0, false); + } + $this->mpdf->base_table_properties['FONT-FAMILY'] = $this->mpdf->FontFamily; + + if (isset($properties['FONT-SIZE'])) { + if ($this->mpdf->tableLevel > 1) { + $tableFontSize = $this->sizeConverter->convert($this->mpdf->base_table_properties['FONT-SIZE']); + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $tableFontSize); + } else { + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE); + } + if ($mmsize) { + $this->mpdf->default_font_size = $mmsize * Mpdf::SCALE; + $this->mpdf->SetFontSize($this->mpdf->default_font_size, false); + } + } + $this->mpdf->base_table_properties['FONT-SIZE'] = $this->mpdf->FontSize . 'mm'; + + if (isset($properties['FONT-WEIGHT'])) { + if (strtoupper($properties['FONT-WEIGHT']) === 'BOLD') { + $this->mpdf->base_table_properties['FONT-WEIGHT'] = 'BOLD'; + } + } + if (isset($properties['FONT-STYLE'])) { + if (strtoupper($properties['FONT-STYLE']) === 'ITALIC') { + $this->mpdf->base_table_properties['FONT-STYLE'] = 'ITALIC'; + } + } + if (isset($properties['COLOR'])) { + $this->mpdf->base_table_properties['COLOR'] = $properties['COLOR']; + } + if (isset($properties['FONT-KERNING'])) { + $this->mpdf->base_table_properties['FONT-KERNING'] = $properties['FONT-KERNING']; + } + if (isset($properties['LETTER-SPACING'])) { + $this->mpdf->base_table_properties['LETTER-SPACING'] = $properties['LETTER-SPACING']; + } + if (isset($properties['WORD-SPACING'])) { + $this->mpdf->base_table_properties['WORD-SPACING'] = $properties['WORD-SPACING']; + } + // mPDF 6 + if (isset($properties['HYPHENS'])) { + $this->mpdf->base_table_properties['HYPHENS'] = $properties['HYPHENS']; + } + if (!empty($properties['LINE-HEIGHT'])) { + $table['cellLineHeight'] = $this->mpdf->fixLineheight($properties['LINE-HEIGHT']); + } elseif ($this->mpdf->tableLevel == 1) { + $table['cellLineHeight'] = $this->mpdf->blk[$this->mpdf->blklvl]['line_height']; + } + + if (!empty($properties['LINE-STACKING-STRATEGY'])) { + $table['cellLineStackingStrategy'] = strtolower($properties['LINE-STACKING-STRATEGY']); + } elseif ($this->mpdf->tableLevel == 1 && isset($this->mpdf->blk[$this->mpdf->blklvl]['line_stacking_strategy'])) { + $table['cellLineStackingStrategy'] = $this->mpdf->blk[$this->mpdf->blklvl]['line_stacking_strategy']; + } else { + $table['cellLineStackingStrategy'] = 'inline-line-height'; + } + + if (!empty($properties['LINE-STACKING-SHIFT'])) { + $table['cellLineStackingShift'] = strtolower($properties['LINE-STACKING-SHIFT']); + } elseif ($this->mpdf->tableLevel == 1 && isset($this->mpdf->blk[$this->mpdf->blklvl]['line_stacking_shift'])) { + $table['cellLineStackingShift'] = $this->mpdf->blk[$this->mpdf->blklvl]['line_stacking_shift']; + } else { + $table['cellLineStackingShift'] = 'consider-shifts'; + } + + if (isset($properties['PADDING-LEFT'])) { + $table['padding']['L'] = $this->sizeConverter->convert($properties['PADDING-LEFT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-RIGHT'])) { + $table['padding']['R'] = $this->sizeConverter->convert($properties['PADDING-RIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-TOP'])) { + $table['padding']['T'] = $this->sizeConverter->convert($properties['PADDING-TOP'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-BOTTOM'])) { + $table['padding']['B'] = $this->sizeConverter->convert($properties['PADDING-BOTTOM'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['MARGIN-TOP'])) { + if ($lastbottommargin) { + $tmp = $this->sizeConverter->convert($properties['MARGIN-TOP'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + if ($tmp > $lastbottommargin) { + $properties['MARGIN-TOP'] = (int) $properties['MARGIN-TOP'] - $lastbottommargin; + } else { + $properties['MARGIN-TOP'] = 0; + } + } + $table['margin']['T'] = $this->sizeConverter->convert($properties['MARGIN-TOP'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['MARGIN-BOTTOM'])) { + $table['margin']['B'] = $this->sizeConverter->convert($properties['MARGIN-BOTTOM'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['MARGIN-LEFT'])) { + $table['margin']['L'] = $this->sizeConverter->convert($properties['MARGIN-LEFT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['MARGIN-RIGHT'])) { + $table['margin']['R'] = $this->sizeConverter->convert($properties['MARGIN-RIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['MARGIN-LEFT'], $properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-LEFT']) === 'auto' && strtolower($properties['MARGIN-RIGHT']) === 'auto') { + $table['a'] = 'C'; + } elseif (isset($properties['MARGIN-LEFT']) && strtolower($properties['MARGIN-LEFT']) === 'auto') { + $table['a'] = 'R'; + } elseif (isset($properties['MARGIN-RIGHT']) && strtolower($properties['MARGIN-RIGHT']) === 'auto') { + $table['a'] = 'L'; + } + + if (isset($properties['BORDER-COLLAPSE']) && strtoupper($properties['BORDER-COLLAPSE']) === 'SEPARATE') { + $table['borders_separate'] = true; + } else { + $table['borders_separate'] = false; + } + + // mPDF 5.7.3 + + if (isset($properties['BORDER-SPACING-H'])) { + $table['border_spacing_H'] = $this->sizeConverter->convert($properties['BORDER-SPACING-H'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['BORDER-SPACING-V'])) { + $table['border_spacing_V'] = $this->sizeConverter->convert($properties['BORDER-SPACING-V'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + // mPDF 5.7.3 + if (!$table['borders_separate']) { + $table['border_spacing_H'] = $table['border_spacing_V'] = 0; + } + + if (isset($properties['EMPTY-CELLS'])) { + $table['empty_cells'] = strtolower($properties['EMPTY-CELLS']); // 'hide' or 'show' + } else { + $table['empty_cells'] = ''; + } + + if (isset($properties['PAGE-BREAK-INSIDE']) && strtoupper($properties['PAGE-BREAK-INSIDE']) === 'AVOID' && $this->mpdf->tableLevel == 1 && !$this->mpdf->writingHTMLfooter) { + $this->mpdf->table_keep_together = true; + } elseif ($this->mpdf->tableLevel == 1) { + $this->mpdf->table_keep_together = false; + } + if (isset($properties['PAGE-BREAK-AFTER']) && $this->mpdf->tableLevel == 1) { + $table['page_break_after'] = strtoupper($properties['PAGE-BREAK-AFTER']); + } + + /* -- BACKGROUNDS -- */ + if (isset($properties['BACKGROUND-GRADIENT']) && !$this->mpdf->kwt && !$this->mpdf->ColActive) { + $table['gradient'] = $properties['BACKGROUND-GRADIENT']; + } + + if (!empty($properties['BACKGROUND-IMAGE']) && !$this->mpdf->kwt && !$this->mpdf->ColActive) { + $ret = $this->mpdf->SetBackground($properties, $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + if ($ret) { + $table['background-image'] = $ret; + } + } + /* -- END BACKGROUNDS -- */ + + if (isset($properties['OVERFLOW'])) { + $table['overflow'] = strtolower($properties['OVERFLOW']); // 'hidden' 'wrap' or 'visible' or 'auto' + if (($this->mpdf->ColActive || $this->mpdf->tableLevel > 1) && $table['overflow'] === 'visible') { + unset($table['overflow']); + } + } + + if (isset($attr['CELLPADDING'])) { + $table['cell_padding'] = $attr['CELLPADDING']; + } else { + $table['cell_padding'] = false; + } + + if (isset($attr['BORDER']) && $attr['BORDER'] == '1') { + $this->mpdf->table_border_attr_set = 1; + $bord = $this->mpdf->border_details('#000000 1px solid'); + if ($bord['s']) { + $table['border'] = Border::ALL; + $table['border_details']['R'] = $bord; + $table['border_details']['L'] = $bord; + $table['border_details']['T'] = $bord; + $table['border_details']['B'] = $bord; + } + } else { + $this->mpdf->table_border_attr_set = 0; + } + + if ($w) { + $maxwidth = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; + if ($table['borders_separate']) { + $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['border_details']['L']['w'] / 2 + $table['border_details']['R']['w'] / 2; + } else { + $tblblw = $table['margin']['L'] + $table['margin']['R'] + $table['max_cell_border_width']['L'] / 2 + $table['max_cell_border_width']['R'] / 2; + } + if (strpos($w, '%') && $this->mpdf->tableLevel == 1 && !$this->mpdf->ignore_table_percents) { + // % needs to be of inner box without table margins etc. + $maxwidth -= $tblblw; + $wmm = $this->sizeConverter->convert($w, $maxwidth, $this->mpdf->FontSize, false); + $table['w'] = $wmm + $tblblw; + } + if (strpos($w, '%') && $this->mpdf->tableLevel > 1 && !$this->mpdf->ignore_table_percents && $this->mpdf->keep_table_proportions) { + $table['wpercent'] = (int) $w; // makes 80% -> 80 + } + if (!strpos($w, '%') && !$this->mpdf->ignore_table_widths) { + $wmm = $this->sizeConverter->convert($w, $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + $table['w'] = $wmm + $tblblw; + } + if (!$this->mpdf->keep_table_proportions) { + if (isset($table['w']) && $table['w'] > $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']) { + $table['w'] = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; + } + } + } + + if (isset($attr['AUTOSIZE']) && $this->mpdf->tableLevel == 1) { + $this->mpdf->shrink_this_table_to_fit = $attr['AUTOSIZE']; + if ($this->mpdf->shrink_this_table_to_fit < 1) { + $this->mpdf->shrink_this_table_to_fit = 1; + } + } + if (isset($attr['ROTATE']) && $this->mpdf->tableLevel == 1) { + $this->mpdf->table_rotate = $attr['ROTATE']; + } + + //++++++++++++++++++++++++++++ + if ($this->mpdf->table_rotate) { + $this->mpdf->tbrot_Links = []; + $this->mpdf->tbrot_Annots = []; + $this->mpdf->tbrotForms = []; + $this->mpdf->tbrot_BMoutlines = []; + $this->mpdf->tbrot_toc = []; + } + + if ($this->mpdf->kwt) { + if ($this->mpdf->table_rotate) { + $this->mpdf->table_keep_together = true; + } + $this->mpdf->kwt = false; + $this->mpdf->kwt_saved = true; + } + + //++++++++++++++++++++++++++++ + $this->mpdf->plainCell_properties = []; + unset($table); + } + + public function close(&$ahtml, &$ihtml) + { + + $this->mpdf->lastoptionaltag = ''; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + $this->mpdf->ignorefollowingspaces = true; //Eliminate exceeding left-side spaces + // mPDF 5.7.3 + // In case a colspan (on a row after first row) exceeded number of columns in table + for ($k = 0; $k < $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nr']; $k++) { + for ($l = 0; $l < $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc']; $l++) { + if (!isset($this->mpdf->cell[$k][$l])) { + for ($n = $l - 1; $n >= 0; $n--) { + if (isset($this->mpdf->cell[$k][$n]) && $this->mpdf->cell[$k][$n] != 0) { + break; + } + } + $this->mpdf->cell[$k][$l] = [ + 'a' => 'C', + 'va' => 'M', + 'R' => false, + 'nowrap' => false, + 'bgcolor' => false, + 'padding' => ['L' => false, 'R' => false, 'T' => false, 'B' => false], + 'gradient' => false, + 's' => 0, + 'maxs' => 0, + 'textbuffer' => [], + 'dfs' => $this->mpdf->FontSize, + ]; + + if (!$this->mpdf->simpleTables) { + $this->mpdf->cell[$k][$l]['border'] = 0; + $this->mpdf->cell[$k][$l]['border_details']['R'] = ['s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0]; + $this->mpdf->cell[$k][$l]['border_details']['L'] = ['s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0]; + $this->mpdf->cell[$k][$l]['border_details']['T'] = ['s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0]; + $this->mpdf->cell[$k][$l]['border_details']['B'] = ['s' => 0, 'w' => 0, 'c' => false, 'style' => 'none', 'dom' => 0]; + $this->mpdf->cell[$k][$l]['border_details']['mbw'] = ['BL' => 0, 'BR' => 0, 'RT' => 0, 'RB' => 0, 'TL' => 0, 'TR' => 0, 'LT' => 0, 'LB' => 0]; + if ($this->mpdf->packTableData) { + $this->mpdf->cell[$k][$l]['borderbin'] = $this->mpdf->_packCellBorder($this->mpdf->cell[$k][$l]); + unset($this->mpdf->cell[$k][$l]['border'], $this->mpdf->cell[$k][$l]['border_details']); + } + } + } + } + } + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['cells'] = $this->mpdf->cell; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['wc'] = array_pad( + [], + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc'], + ['miw' => 0, 'maw' => 0] + ); + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['hr'] = array_pad( + [], + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nr'], + 0 + ); + + // Move table footer <tfoot> row to end of table + if (isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot']) + && count($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'])) { + $tfrows = []; + foreach ($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'] as $r => $val) { + if ($val) { + $tfrows[] = $r; + } + } + $temp = []; + $temptf = []; + foreach ($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['cells'] as $k => $row) { + if (in_array($k, $tfrows)) { + $temptf[] = $row; + } else { + $temp[] = $row; + } + } + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'] = []; + for ($i = count($temp); $i < (count($temp) + count($temptf)); $i++) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'][$i] = true; + } + // Update nestedpos row references + if (isset($this->mpdf->table[$this->mpdf->tableLevel + 1]) && count($this->mpdf->table[$this->mpdf->tableLevel + 1])) { + foreach ($this->mpdf->table[$this->mpdf->tableLevel + 1] as $nid => $nested) { + $this->mpdf->table[$this->mpdf->tableLevel + 1][$nid]['nestedpos'][0] -= count($temptf); + } + } + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['cells'] = array_merge($temp, $temptf); + + // Update other arays set on row number + // [trbackground-images] [trgradients] + $temptrbgi = []; + $temptrbgg = []; + $temptrbgc = []; + if (isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][-1])) { + $temptrbgc[-1] = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][-1]; + } + for ($k = 0; $k < $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nr']; $k++) { + if (!in_array($k, $tfrows)) { + $temptrbgi[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'][$k] + : null; + $temptrbgg[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'][$k] + : null; + $temptrbgc[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$k] + : null; + } + } + for ($k = 0; $k < $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nr']; $k++) { + if (in_array($k, $tfrows)) { + $temptrbgi[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'][$k] + : null; + $temptrbgg[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'][$k] + : null; + $temptrbgc[] = isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$k]) + ? $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$k] + : null; + } + } + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'] = $temptrbgi; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'] = $temptrbgg; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'] = $temptrbgc; + // Should Update all other arays set on row number, but cell properties have been set so not needed + // [bgcolor] [trborder-left] [trborder-right] [trborder-top] [trborder-bottom] + } + + if ($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['direction'] === 'rtl') { + $this->mpdf->_reverseTableDir($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]); + } + + // Fix Borders ********************************************* + $this->mpdf->_fixTableBorders($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]); + + if ($this->mpdf->ColActive) { + $this->mpdf->table_rotate = 0; + } // *COLUMNS* + if ($this->mpdf->table_rotate <> 0) { + $this->mpdf->tablebuffer = ''; + // Max width for rotated table + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 1); + $this->mpdf->tbrot_maxh = $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']; // Max width for rotated table + $this->mpdf->tbrot_align = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['a']; + } + $this->mpdf->shrin_k = 1; + + if ($this->mpdf->shrink_tables_to_fit < 1) { + $this->mpdf->shrink_tables_to_fit = 1; + } + if (!$this->mpdf->shrink_this_table_to_fit) { + $this->mpdf->shrink_this_table_to_fit = $this->mpdf->shrink_tables_to_fit; + } + + if ($this->mpdf->tableLevel > 1) { + // deal with nested table + + $this->mpdf->_tableColumnWidth($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]], true); + + $tmiw = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['miw']; + $tmaw = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['maw']; + $tl = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['tl']; + + // Go down to lower table level + $this->mpdf->tableLevel--; + + // Reset lower level table + $this->mpdf->base_table_properties = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['baseProperties']; + // mPDF 5.7.3 + $this->mpdf->default_font = $this->mpdf->base_table_properties['FONT-FAMILY']; + $this->mpdf->SetFont($this->mpdf->default_font, '', 0, false); + $this->mpdf->default_font_size = $this->sizeConverter->convert($this->mpdf->base_table_properties['FONT-SIZE']) * Mpdf::SCALE; + $this->mpdf->SetFontSize($this->mpdf->default_font_size, false); + + $this->mpdf->cell = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['cells']; + if (isset($this->mpdf->cell['PARENTCELL'])) { + if ($this->mpdf->cell['PARENTCELL']) { + $this->mpdf->restoreInlineProperties($this->mpdf->cell['PARENTCELL']); + } + unset($this->mpdf->cell['PARENTCELL']); + } + $this->mpdf->row = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['currrow']; + $this->mpdf->col = $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['currcol']; + $objattr = []; + $objattr['type'] = 'nestedtable'; + $objattr['nestedcontent'] = $this->mpdf->tbctr[$this->mpdf->tableLevel + 1]; + $objattr['table'] = $this->mpdf->tbctr[$this->mpdf->tableLevel]; + $objattr['row'] = $this->mpdf->row; + $objattr['col'] = $this->mpdf->col; + $objattr['level'] = $this->mpdf->tableLevel; + $e = "\xbb\xa4\xactype=nestedtable,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + $this->mpdf->_saveCellTextBuffer($e); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $tl; + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; // reset + if ((isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmaw']) && $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmaw'] < $tmaw) + || !isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmaw'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmaw'] = $tmaw; + } + if ((isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmiw']) && $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmiw'] < $tmiw) + || !isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmiw'])) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['nestedmiw'] = $tmiw; + } + $this->mpdf->tdbegin = true; + $this->mpdf->nestedtablejustfinished = true; + $this->mpdf->ignorefollowingspaces = true; + return; + } + $this->mpdf->cMarginL = 0; + $this->mpdf->cMarginR = 0; + $this->mpdf->cMarginT = 0; + $this->mpdf->cMarginB = 0; + $this->mpdf->cellPaddingL = 0; + $this->mpdf->cellPaddingR = 0; + $this->mpdf->cellPaddingT = 0; + $this->mpdf->cellPaddingB = 0; + + if (isset($this->mpdf->table[1][1]['overflow']) && $this->mpdf->table[1][1]['overflow'] === 'visible') { + if ($this->mpdf->kwt || $this->mpdf->table_rotate || $this->mpdf->table_keep_together || $this->mpdf->ColActive) { + $this->mpdf->kwt = false; + $this->mpdf->table_rotate = 0; + $this->mpdf->table_keep_together = false; + //throw new \Mpdf\MpdfException("mPDF Warning: You cannot use CSS overflow:visible together with any of these functions: + // 'Keep-with-table', rotated tables, page-break-inside:avoid, or columns"); + } + $this->mpdf->_tableColumnWidth($this->mpdf->table[1][1], true); + $this->mpdf->_tableWidth($this->mpdf->table[1][1]); + } else { + if (!$this->mpdf->kwt_saved) { + $this->mpdf->kwt_height = 0; + } + + list($check, $tablemiw) = $this->mpdf->_tableColumnWidth($this->mpdf->table[1][1], true); + $save_table = $this->mpdf->table; + $reset_to_minimum_width = false; + $added_page = false; + + if ($check > 1) { + if ($check > $this->mpdf->shrink_this_table_to_fit && $this->mpdf->table_rotate) { + if ($this->mpdf->y != $this->mpdf->tMargin) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $this->mpdf->kwt_moved = true; + } + $added_page = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + //$check = $tablemiw/$this->mpdf->tbrot_maxw; // undo any shrink + $check = 1; // undo any shrink + } + $reset_to_minimum_width = true; + } + + if ($reset_to_minimum_width) { + $this->mpdf->shrin_k = $check; + + $this->mpdf->default_font_size /= $this->mpdf->shrin_k; + $this->mpdf->SetFontSize($this->mpdf->default_font_size, false); + + $this->mpdf->shrinkTable($this->mpdf->table[1][1], $this->mpdf->shrin_k); + + $this->mpdf->_tableColumnWidth($this->mpdf->table[1][1]); // repeat + // Starting at $this->mpdf->innermostTableLevel + // Shrink table values - and redo columnWidth + for ($lvl = 2; $lvl <= $this->mpdf->innermostTableLevel; $lvl++) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + $this->mpdf->shrinkTable($this->mpdf->table[$lvl][$nid], $this->mpdf->shrin_k); + $this->mpdf->_tableColumnWidth($this->mpdf->table[$lvl][$nid]); + } + } + } + + // Set table cell widths for top level table + // Use $shrin_k to resize but don't change again + $this->mpdf->SetLineHeight('', $this->mpdf->table[1][1]['cellLineHeight']); + + // Top level table + $this->mpdf->_tableWidth($this->mpdf->table[1][1]); + } + + // Now work through any nested tables setting child table[w'] = parent cell['w'] + // Now do nested tables _tableWidth + for ($lvl = 2; $lvl <= $this->mpdf->innermostTableLevel; $lvl++) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + // HERE set child table width = cell width + + list($parentrow, $parentcol, $parentnid) = $this->mpdf->table[$lvl][$nid]['nestedpos']; + + $c = & $this->mpdf->table[$lvl - 1][$parentnid]['cells'][$parentrow][$parentcol]; + + if (isset($c['colspan']) && $c['colspan'] > 1) { + $parentwidth = 0; + for ($cs = 0; $cs < $c['colspan']; $cs++) { + $parentwidth += $this->mpdf->table[$lvl - 1][$parentnid]['wc'][$parentcol + $cs]; + } + } else { + $parentwidth = $this->mpdf->table[$lvl - 1][$parentnid]['wc'][$parentcol]; + } + + //$parentwidth -= ALLOW FOR PADDING ETC. in parent cell + if (!$this->mpdf->simpleTables) { + if ($this->mpdf->packTableData) { + list($bt, $br, $bb, $bl) = $this->mpdf->_getBorderWidths($c['borderbin']); + } else { + $br = $c['border_details']['R']['w']; + $bl = $c['border_details']['L']['w']; + } + if ($this->mpdf->table[$lvl - 1][$parentnid]['borders_separate']) { + $parentwidth -= $br + $bl + $c['padding']['L'] + $c['padding']['R'] + $this->mpdf->table[$lvl - 1][$parentnid]['border_spacing_H']; + } else { + $parentwidth -= $br / 2 + $bl / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } elseif ($this->mpdf->simpleTables) { + if ($this->mpdf->table[$lvl - 1][$parentnid]['borders_separate']) { + $parentwidth -= $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['L']['w'] + + $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['R']['w'] + $c['padding']['L'] + + $c['padding']['R'] + $this->mpdf->table[$lvl - 1][$parentnid]['border_spacing_H']; + } else { + $parentwidth -= $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['L']['w'] / 2 + + $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['R']['w'] / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } + if (!empty($this->mpdf->table[$lvl][$nid]['wpercent']) && $lvl > 1) { + $this->mpdf->table[$lvl][$nid]['w'] = $parentwidth; + } elseif ($parentwidth > $this->mpdf->table[$lvl][$nid]['maw']) { + $this->mpdf->table[$lvl][$nid]['w'] = $this->mpdf->table[$lvl][$nid]['maw']; + } else { + $this->mpdf->table[$lvl][$nid]['w'] = $parentwidth; + } + unset($c); + $this->mpdf->_tableWidth($this->mpdf->table[$lvl][$nid]); + } + } + + // Starting at $this->mpdf->innermostTableLevel + // Cascade back up nested tables: setting heights back up the tree + for ($lvl = $this->mpdf->innermostTableLevel; $lvl > 0; $lvl--) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + list($tableheight, $maxrowheight, $fullpage, $remainingpage, $maxfirstrowheight) = $this->mpdf->_tableHeight($this->mpdf->table[$lvl][$nid]); + } + } + + if ($this->mpdf->table[1][1]['overflow'] === 'visible') { + if ($maxrowheight > $fullpage) { + throw new \Mpdf\MpdfException('mPDF Warning: A Table row is greater than available height. You cannot use CSS overflow:visible'); + } + if ($maxfirstrowheight > $remainingpage) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + $r = 0; + $c = 0; + $p = 0; + $y = 0; + $finished = false; + while (!$finished) { + list($finished, $r, $c, $p, $y, $y0) = $this->mpdf->_tableWrite($this->mpdf->table[1][1], true, $r, $c, $p, $y); + if (!$finished) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + // If printed something on first spread, set same y + if ($r == 0 && $y0 > -1) { + $this->mpdf->y = $y0; + } + } + } + } else { + $recalculate = 1; + $forcerecalc = false; + // RESIZING ALGORITHM + if ($maxrowheight > $fullpage) { + $recalculate = $this->tbsqrt($maxrowheight / $fullpage, 1); + $forcerecalc = true; + } elseif ($this->mpdf->table_rotate) { // NB $remainingpage == $fullpage == the width of the page + if ($tableheight > $remainingpage) { + // If can fit on remainder of page whilst respecting autsize value.. + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1); + } elseif (!$added_page) { + if ($this->mpdf->y != $this->mpdf->tMargin) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $this->mpdf->kwt_moved = true; + } + $added_page = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + // 0.001 to force it to recalculate + $recalculate = (1 / $this->mpdf->shrin_k) + 0.001; // undo any shrink + } + } else { + $recalculate = 1; + } + } elseif ($this->mpdf->table_keep_together || ($this->mpdf->table[1][1]['nr'] == 1 && !$this->mpdf->writingHTMLfooter)) { + if ($tableheight > $fullpage) { + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $fullpage, 1)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $fullpage, 1); + } elseif ($this->mpdf->tableMinSizePriority) { + $this->mpdf->table_keep_together = false; + $recalculate = 1.001; + } else { + if ($this->mpdf->y != $this->mpdf->tMargin) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $this->mpdf->kwt_moved = true; + } + $added_page = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + $recalculate = $this->tbsqrt($tableheight / $fullpage, 1); + } + } elseif ($tableheight > $remainingpage) { + // If can fit on remainder of page whilst respecting autsize value.. + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $remainingpage, 1)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $remainingpage, 1); + } else { + if ($this->mpdf->y != $this->mpdf->tMargin) { + // mPDF 6 + if ($this->mpdf->AcceptPageBreak()) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } elseif ($this->mpdf->ColActive && $tableheight > (($this->mpdf->h - $this->mpdf->bMargin) - $this->mpdf->y0)) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + $this->mpdf->kwt_moved = true; + } + $added_page = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + $recalculate = 1.001; + } + } else { + $recalculate = 1; + } + } else { + $recalculate = 1; + } + + if ($recalculate > $this->mpdf->shrink_this_table_to_fit && !$forcerecalc) { + $recalculate = $this->mpdf->shrink_this_table_to_fit; + } + + $iteration = 1; + + // RECALCULATE + while ($recalculate <> 1) { + $this->mpdf->shrin_k1 = $recalculate; + $this->mpdf->shrin_k *= $recalculate; + $this->mpdf->default_font_size /= $this->mpdf->shrin_k1; + $this->mpdf->SetFontSize($this->mpdf->default_font_size, false); + $this->mpdf->SetLineHeight('', $this->mpdf->table[1][1]['cellLineHeight']); + $this->mpdf->table = $save_table; + if ($this->mpdf->shrin_k <> 1) { + $this->mpdf->shrinkTable($this->mpdf->table[1][1], $this->mpdf->shrin_k); + } + $this->mpdf->_tableColumnWidth($this->mpdf->table[1][1]); // repeat + // Starting at $this->mpdf->innermostTableLevel + // Shrink table values - and redo columnWidth + for ($lvl = 2; $lvl <= $this->mpdf->innermostTableLevel; $lvl++) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + if ($this->mpdf->shrin_k <> 1) { + $this->mpdf->shrinkTable($this->mpdf->table[$lvl][$nid], $this->mpdf->shrin_k); + } + $this->mpdf->_tableColumnWidth($this->mpdf->table[$lvl][$nid]); + } + } + // Set table cell widths for top level table + // Top level table + $this->mpdf->_tableWidth($this->mpdf->table[1][1]); + + // Now work through any nested tables setting child table[w'] = parent cell['w'] + // Now do nested tables _tableWidth + for ($lvl = 2; $lvl <= $this->mpdf->innermostTableLevel; $lvl++) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + // HERE set child table width = cell width + + list($parentrow, $parentcol, $parentnid) = $this->mpdf->table[$lvl][$nid]['nestedpos']; + $c = & $this->mpdf->table[$lvl - 1][$parentnid]['cells'][$parentrow][$parentcol]; + + if (isset($c['colspan']) && $c['colspan'] > 1) { + $parentwidth = 0; + for ($cs = 0; $cs < $c['colspan']; $cs++) { + $parentwidth += $this->mpdf->table[$lvl - 1][$parentnid]['wc'][$parentcol + $cs]; + } + } else { + $parentwidth = $this->mpdf->table[$lvl - 1][$parentnid]['wc'][$parentcol]; + } + + //$parentwidth -= ALLOW FOR PADDING ETC.in parent cell + if (!$this->mpdf->simpleTables) { + if ($this->mpdf->packTableData) { + list($bt, $br, $bb, $bl) = $this->mpdf->_getBorderWidths($c['borderbin']); + } else { + $br = $c['border_details']['R']['w']; + $bl = $c['border_details']['L']['w']; + } + if ($this->mpdf->table[$lvl - 1][$parentnid]['borders_separate']) { + $parentwidth -= $br + $bl + $c['padding']['L'] + $c['padding']['R'] + $this->mpdf->table[$lvl - 1][$parentnid]['border_spacing_H']; + } else { + $parentwidth -= $br / 2 + $bl / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } elseif ($this->mpdf->simpleTables) { + if ($this->mpdf->table[$lvl - 1][$parentnid]['borders_separate']) { + $parentwidth -= $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['L']['w'] + + $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['R']['w'] + $c['padding']['L'] + $c['padding']['R'] + + $this->mpdf->table[$lvl - 1][$parentnid]['border_spacing_H']; + } else { + $parentwidth -= ($this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['L']['w'] + + $this->mpdf->table[$lvl - 1][$parentnid]['simple']['border_details']['R']['w']) / 2 + $c['padding']['L'] + $c['padding']['R']; + } + } + if (!empty($this->mpdf->table[$lvl][$nid]['wpercent']) && $lvl > 1) { + $this->mpdf->table[$lvl][$nid]['w'] = $parentwidth; + } elseif ($parentwidth > $this->mpdf->table[$lvl][$nid]['maw']) { + $this->mpdf->table[$lvl][$nid]['w'] = $this->mpdf->table[$lvl][$nid]['maw']; + } else { + $this->mpdf->table[$lvl][$nid]['w'] = $parentwidth; + } + unset($c); + $this->mpdf->_tableWidth($this->mpdf->table[$lvl][$nid]); + } + } + + // Starting at $this->mpdf->innermostTableLevel + // Cascade back up nested tables: setting heights back up the tree + for ($lvl = $this->mpdf->innermostTableLevel; $lvl > 0; $lvl--) { + for ($nid = 1; $nid <= $this->mpdf->tbctr[$lvl]; $nid++) { + list($tableheight, $maxrowheight, $fullpage, $remainingpage, $maxfirstrowheight) = $this->mpdf->_tableHeight($this->mpdf->table[$lvl][$nid]); + } + } + + // RESIZING ALGORITHM + + if ($maxrowheight > $fullpage) { + $recalculate = $this->tbsqrt($maxrowheight / $fullpage, $iteration); + $iteration++; + } elseif ($this->mpdf->table_rotate && $tableheight > $remainingpage && !$added_page) { + // If can fit on remainder of page whilst respecting autosize value.. + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); + $iteration++; + } else { + if (!$added_page) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $added_page = true; + $this->mpdf->kwt_moved = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + } + // 0.001 to force it to recalculate + $recalculate = (1 / $this->mpdf->shrin_k) + 0.001; // undo any shrink + } + } elseif ($this->mpdf->table_keep_together || ($this->mpdf->table[1][1]['nr'] == 1 && !$this->mpdf->writingHTMLfooter)) { + if ($tableheight > $fullpage) { + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $fullpage, $iteration)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); + $iteration++; + } elseif ($this->mpdf->tableMinSizePriority) { + $this->mpdf->table_keep_together = false; + $recalculate = (1 / $this->mpdf->shrin_k) + 0.001; + } else { + if (!$added_page && $this->mpdf->y != $this->mpdf->tMargin) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $added_page = true; + $this->mpdf->kwt_moved = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + } + $recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); + $iteration++; + } + } elseif ($tableheight > $remainingpage) { + // If can fit on remainder of page whilst respecting autosize value.. + if (($this->mpdf->shrin_k * $this->tbsqrt($tableheight / $remainingpage, $iteration)) <= $this->mpdf->shrink_this_table_to_fit) { + $recalculate = $this->tbsqrt($tableheight / $remainingpage, $iteration); + $iteration++; + } else { + if (!$added_page) { + // mPDF 6 + if ($this->mpdf->AcceptPageBreak()) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } elseif ($this->mpdf->ColActive && $tableheight > (($this->mpdf->h - $this->mpdf->bMargin) - $this->mpdf->y0)) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + $added_page = true; + $this->mpdf->kwt_moved = true; + $this->mpdf->tbrot_maxw = $this->mpdf->h - ($this->mpdf->y + $this->mpdf->bMargin + 5) - $this->mpdf->kwt_height; + } + + //$recalculate = $this->tbsqrt($tableheight / $fullpage, $iteration); $iteration++; + $recalculate = (1 / $this->mpdf->shrin_k) + 0.001; // undo any shrink + } + } else { + $recalculate = 1; + } + } else { + $recalculate = 1; + } + } + + if ($maxfirstrowheight > $remainingpage && !$added_page && !$this->mpdf->table_rotate && !$this->mpdf->ColActive + && !$this->mpdf->table_keep_together && !$this->mpdf->writingHTMLheader && !$this->mpdf->writingHTMLfooter) { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + $this->mpdf->kwt_moved = true; + } + + // keep-with-table: if page has advanced, print out buffer now, else done in fn. _Tablewrite() + if ($this->mpdf->kwt_saved && $this->mpdf->kwt_moved) { + $this->mpdf->printkwtbuffer(); + $this->mpdf->kwt_moved = false; + $this->mpdf->kwt_saved = false; + } + + // Recursively writes all tables starting at top level + $this->mpdf->_tableWrite($this->mpdf->table[1][1]); + + if ($this->mpdf->table_rotate && $this->mpdf->tablebuffer) { + $this->mpdf->PageBreakTrigger = $this->mpdf->h - $this->mpdf->bMargin; + $save_tr = $this->mpdf->table_rotate; + $save_y = $this->mpdf->y; + $this->mpdf->table_rotate = 0; + $this->mpdf->y = $this->mpdf->tbrot_y0; + $h = $this->mpdf->tbrot_w; + $this->mpdf->DivLn($h, $this->mpdf->blklvl); + + $this->mpdf->table_rotate = $save_tr; + $this->mpdf->y = $save_y; + + $this->mpdf->printtablebuffer(); + } + $this->mpdf->table_rotate = 0; + } + + + $this->mpdf->x = $this->mpdf->lMargin + $this->mpdf->blk[$this->mpdf->blklvl]['outer_left_margin']; + + $this->mpdf->maxPosR = max($this->mpdf->maxPosR, $this->mpdf->x + $this->mpdf->table[1][1]['w']); + + $this->mpdf->blockjustfinished = true; + $this->mpdf->lastblockbottommargin = $this->mpdf->table[1][1]['margin']['B']; + //Reset values + + $page_break_after = ''; + if (isset($this->mpdf->table[1][1]['page_break_after'])) { + $page_break_after = $this->mpdf->table[1][1]['page_break_after']; + } + + // Keep-with-table + $this->mpdf->kwt = false; + $this->mpdf->kwt_y0 = 0; + $this->mpdf->kwt_x0 = 0; + $this->mpdf->kwt_height = 0; + $this->mpdf->kwt_buffer = []; + $this->mpdf->kwt_Links = []; + $this->mpdf->kwt_Annots = []; + $this->mpdf->kwt_moved = false; + $this->mpdf->kwt_saved = false; + + $this->mpdf->kwt_Reference = []; + $this->mpdf->kwt_BMoutlines = []; + $this->mpdf->kwt_toc = []; + + $this->mpdf->shrin_k = 1; + $this->mpdf->shrink_this_table_to_fit = 0; + + $this->mpdf->table = []; //array + $this->mpdf->tableLevel = 0; + $this->mpdf->tbctr = []; + $this->mpdf->innermostTableLevel = 0; + $this->cssManager->tbCSSlvl = 0; + $this->cssManager->tablecascadeCSS = []; + + $this->mpdf->cell = []; //array + + $this->mpdf->col = -1; //int + $this->mpdf->row = -1; //int + + $this->mpdf->Reset(); + + $this->mpdf->cellPaddingL = 0; + $this->mpdf->cellPaddingT = 0; + $this->mpdf->cellPaddingR = 0; + $this->mpdf->cellPaddingB = 0; + $this->mpdf->cMarginL = 0; + $this->mpdf->cMarginT = 0; + $this->mpdf->cMarginR = 0; + $this->mpdf->cMarginB = 0; + $this->mpdf->default_font_size = $this->mpdf->original_default_font_size; + $this->mpdf->default_font = $this->mpdf->original_default_font; + $this->mpdf->SetFontSize($this->mpdf->default_font_size, false); + $this->mpdf->SetFont($this->mpdf->default_font, '', 0, false); + $this->mpdf->SetLineHeight(); + + if (isset($this->mpdf->blk[$this->mpdf->blklvl]['InlineProperties'])) { + $this->mpdf->restoreInlineProperties($this->mpdf->blk[$this->mpdf->blklvl]['InlineProperties']); + } + + if ($page_break_after) { + $save_blklvl = $this->mpdf->blklvl; + $save_blk = $this->mpdf->blk; + $save_silp = $this->mpdf->saveInlineProperties(); + $save_ilp = $this->mpdf->InlineProperties; + $save_bflp = $this->mpdf->InlineBDF; + $save_bflpc = $this->mpdf->InlineBDFctr; // mPDF 6 + // mPDF 6 pagebreaktype + $startpage = $this->mpdf->page; + $pagebreaktype = $this->mpdf->defaultPagebreakType; + if ($this->mpdf->ColActive) { + $pagebreaktype = 'cloneall'; + } + + // mPDF 6 pagebreaktype + $this->mpdf->_preForcedPagebreak($pagebreaktype); + + if ($page_break_after === 'RIGHT') { + $this->mpdf->AddPage($this->mpdf->CurOrientation, 'NEXT-ODD'); + } elseif ($page_break_after === 'LEFT') { + $this->mpdf->AddPage($this->mpdf->CurOrientation, 'NEXT-EVEN'); + } else { + $this->mpdf->AddPage($this->mpdf->CurOrientation); + } + + // mPDF 6 pagebreaktype + $this->mpdf->_postForcedPagebreak($pagebreaktype, $startpage, $save_blk, $save_blklvl); + + $this->mpdf->InlineProperties = $save_ilp; + $this->mpdf->InlineBDF = $save_bflp; + $this->mpdf->InlineBDFctr = $save_bflpc; // mPDF 6 + $this->mpdf->restoreInlineProperties($save_silp); + } + } + + /** + * This function determines the shrink factor when resizing tables + * val is the table_height / page_height_available + * returns a scaling factor used as $shrin_k to resize the table + * Overcompensating will be quicker but may unnecessarily shrink table too much + * Undercompensating means it will reiterate more times (taking more processing time) + */ + private function tbsqrt($val, $iteration = 3) + { + // Alters number of iterations until it returns $val itself - Must be > 2 + $k = 4; + + // Probably best guess and most accurate + if ($iteration === 1) { + return sqrt($val); + } + + // Faster than using sqrt (because it won't undercompensate), and gives reasonable results + // return 1 + (($val - 1) / 2); + $x = 2 - (($iteration - 2) / ($k - 2)); + + if ($x === 0) { + $ret = $val + 0.00001; + } elseif ($x < 0) { + $ret = 1 + ( pow(2, ($iteration - 2 - $k)) / 1000 ); + } else { + $ret = 1 + (($val - 1) / $x); + } + + return $ret; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tag.php new file mode 100644 index 0000000..9f7c52c --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tag.php @@ -0,0 +1,121 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Strict; + +use Mpdf\Cache; +use Mpdf\Color\ColorConverter; +use Mpdf\CssManager; +use Mpdf\Form; +use Mpdf\Image\ImageProcessor; +use Mpdf\Language\LanguageToFontInterface; +use Mpdf\Mpdf; +use Mpdf\Otl; +use Mpdf\SizeConverter; +use Mpdf\TableOfContents; + +abstract class Tag +{ + + use Strict; + + /** + * @var \Mpdf\Mpdf + */ + protected $mpdf; + + /** + * @var \Mpdf\Cache + */ + protected $cache; + + /** + * @var \Mpdf\CssManager + */ + protected $cssManager; + + /** + * @var \Mpdf\Form + */ + protected $form; + + /** + * @var \Mpdf\Otl + */ + protected $otl; + + /** + * @var \Mpdf\TableOfContents + */ + protected $tableOfContents; + + /** + * @var \Mpdf\SizeConverter + */ + protected $sizeConverter; + + /** + * @var \Mpdf\Color\ColorConverter + */ + protected $colorConverter; + + /** + * @var \Mpdf\Image\ImageProcessor + */ + protected $imageProcessor; + + /** + * @var \Mpdf\Language\LanguageToFontInterface + */ + protected $languageToFont; + + const ALIGN = [ + 'left' => 'L', + 'center' => 'C', + 'right' => 'R', + 'top' => 'T', + 'text-top' => 'TT', + 'middle' => 'M', + 'baseline' => 'BS', + 'bottom' => 'B', + 'text-bottom' => 'TB', + 'justify' => 'J' + ]; + + public function __construct( + Mpdf $mpdf, + Cache $cache, + CssManager $cssManager, + Form $form, + Otl $otl, + TableOfContents $tableOfContents, + SizeConverter $sizeConverter, + ColorConverter $colorConverter, + ImageProcessor $imageProcessor, + LanguageToFontInterface $languageToFont + ) { + + $this->mpdf = $mpdf; + $this->cache = $cache; + $this->cssManager = $cssManager; + $this->form = $form; + $this->otl = $otl; + $this->tableOfContents = $tableOfContents; + $this->sizeConverter = $sizeConverter; + $this->colorConverter = $colorConverter; + $this->imageProcessor = $imageProcessor; + $this->languageToFont = $languageToFont; + } + + public function getTagName() + { + $tag = get_class($this); + return strtoupper(str_replace('Mpdf\Tag\\', '', $tag)); + } + + abstract public function open($attr, &$ahtml, &$ihtml); + + abstract public function close(&$ahtml, &$ihtml); + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Td.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Td.php new file mode 100644 index 0000000..6708a67 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Td.php @@ -0,0 +1,469 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Css\Border; +use Mpdf\Css\TextVars; +use Mpdf\Utils\UtfString; + +class Td extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $tag = $this->getTagName(); + $this->mpdf->ignorefollowingspaces = true; + $this->mpdf->lastoptionaltag = $tag; // Save current HTML specified optional endtag + $this->cssManager->tbCSSlvl++; + $this->mpdf->InlineProperties = []; + $this->mpdf->InlineBDF = []; // mPDF 6 + $this->mpdf->InlineBDFctr = 0; // mPDF 6 + $this->mpdf->tdbegin = true; + $this->mpdf->col++; + while (isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col])) { + $this->mpdf->col++; + } + + //Update number column + if ($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc'] < $this->mpdf->col + 1) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc'] = $this->mpdf->col + 1; + } + + $table = &$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]; + + $c = ['a' => false, + 'R' => false, + 'nowrap' => false, + 'bgcolor' => false, + 'padding' => ['L' => false, + 'R' => false, + 'T' => false, + 'B' => false + ] + ]; + + if ($this->mpdf->simpleTables && $this->mpdf->row == 0 && $this->mpdf->col == 0) { + $table['simple']['border'] = false; + $table['simple']['border_details']['R']['w'] = 0; + $table['simple']['border_details']['L']['w'] = 0; + $table['simple']['border_details']['T']['w'] = 0; + $table['simple']['border_details']['B']['w'] = 0; + $table['simple']['border_details']['R']['style'] = ''; + $table['simple']['border_details']['L']['style'] = ''; + $table['simple']['border_details']['T']['style'] = ''; + $table['simple']['border_details']['B']['style'] = ''; + } elseif (!$this->mpdf->simpleTables) { + $c['border'] = false; + $c['border_details']['R']['w'] = 0; + $c['border_details']['L']['w'] = 0; + $c['border_details']['T']['w'] = 0; + $c['border_details']['B']['w'] = 0; + $c['border_details']['mbw']['BL'] = 0; + $c['border_details']['mbw']['BR'] = 0; + $c['border_details']['mbw']['RT'] = 0; + $c['border_details']['mbw']['RB'] = 0; + $c['border_details']['mbw']['TL'] = 0; + $c['border_details']['mbw']['TR'] = 0; + $c['border_details']['mbw']['LT'] = 0; + $c['border_details']['mbw']['LB'] = 0; + $c['border_details']['R']['style'] = ''; + $c['border_details']['L']['style'] = ''; + $c['border_details']['T']['style'] = ''; + $c['border_details']['B']['style'] = ''; + $c['border_details']['R']['s'] = 0; + $c['border_details']['L']['s'] = 0; + $c['border_details']['T']['s'] = 0; + $c['border_details']['B']['s'] = 0; + $c['border_details']['R']['c'] = $this->colorConverter->convert(0, $this->mpdf->PDFAXwarnings); + $c['border_details']['L']['c'] = $this->colorConverter->convert(0, $this->mpdf->PDFAXwarnings); + $c['border_details']['T']['c'] = $this->colorConverter->convert(0, $this->mpdf->PDFAXwarnings); + $c['border_details']['B']['c'] = $this->colorConverter->convert(0, $this->mpdf->PDFAXwarnings); + $c['border_details']['R']['dom'] = 0; + $c['border_details']['L']['dom'] = 0; + $c['border_details']['T']['dom'] = 0; + $c['border_details']['B']['dom'] = 0; + $c['border_details']['cellposdom'] = 0; + } + + + if ($table['va']) { + $c['va'] = $table['va']; + } + if ($table['txta']) { + $c['a'] = $table['txta']; + } + if ($this->mpdf->table_border_attr_set && $table['border_details']) { + if (!$this->mpdf->simpleTables) { + $c['border_details']['R'] = $table['border_details']['R']; + $c['border_details']['L'] = $table['border_details']['L']; + $c['border_details']['T'] = $table['border_details']['T']; + $c['border_details']['B'] = $table['border_details']['B']; + $c['border'] = $table['border']; + $c['border_details']['L']['dom'] = 1; + $c['border_details']['R']['dom'] = 1; + $c['border_details']['T']['dom'] = 1; + $c['border_details']['B']['dom'] = 1; + } elseif ($this->mpdf->simpleTables && $this->mpdf->row == 0 && $this->mpdf->col == 0) { + $table['simple']['border_details']['R'] = $table['border_details']['R']; + $table['simple']['border_details']['L'] = $table['border_details']['L']; + $table['simple']['border_details']['T'] = $table['border_details']['T']; + $table['simple']['border_details']['B'] = $table['border_details']['B']; + $table['simple']['border'] = $table['border']; + } + } + // INHERITED THEAD CSS Properties + if ($this->mpdf->tablethead) { + if ($this->mpdf->thead_valign_default) { + $c['va'] = self::ALIGN[strtolower($this->mpdf->thead_valign_default)]; + } + if ($this->mpdf->thead_textalign_default) { + $c['a'] = self::ALIGN[strtolower($this->mpdf->thead_textalign_default)]; + } + if ($this->mpdf->thead_font_weight === 'B') { + $this->mpdf->SetStyle('B', true); + } + if ($this->mpdf->thead_font_style === 'I') { + $this->mpdf->SetStyle('I', true); + } + if ($this->mpdf->thead_font_smCaps === 'S') { + $this->mpdf->textvar |= TextVars::FC_SMALLCAPS; + } // mPDF 5.7.1 + } + + // INHERITED TFOOT CSS Properties + if ($this->mpdf->tabletfoot) { + if ($this->mpdf->tfoot_valign_default) { + $c['va'] = self::ALIGN[strtolower($this->mpdf->tfoot_valign_default)]; + } + if ($this->mpdf->tfoot_textalign_default) { + $c['a'] = self::ALIGN[strtolower($this->mpdf->tfoot_textalign_default)]; + } + if ($this->mpdf->tfoot_font_weight === 'B') { + $this->mpdf->SetStyle('B', true); + } + if ($this->mpdf->tfoot_font_style === 'I') { + $this->mpdf->SetStyle('I', true); + } + if ($this->mpdf->tfoot_font_style === 'S') { + $this->mpdf->textvar |= TextVars::FC_SMALLCAPS; + } // mPDF 5.7.1 + } + + + if ($this->mpdf->trow_text_rotate) { + $c['R'] = $this->mpdf->trow_text_rotate; + } + + $this->mpdf->cell_border_dominance_L = 0; + $this->mpdf->cell_border_dominance_R = 0; + $this->mpdf->cell_border_dominance_T = 0; + $this->mpdf->cell_border_dominance_B = 0; + + $properties = $this->cssManager->MergeCSS('TABLE', $tag, $attr); + + $properties = $this->cssManager->array_merge_recursive_unique($this->mpdf->base_table_properties, $properties); + + $this->mpdf->Reset(); // mPDF 6 ????????????????????? + + $this->mpdf->setCSS($properties, 'TABLECELL', $tag); + + $c['dfs'] = $this->mpdf->FontSize; // Default Font size + + + if (isset($properties['BACKGROUND-COLOR'])) { + $c['bgcolor'] = $properties['BACKGROUND-COLOR']; + } elseif (isset($properties['BACKGROUND'])) { + $c['bgcolor'] = $properties['BACKGROUND']; + } elseif (isset($attr['BGCOLOR'])) { + $c['bgcolor'] = $attr['BGCOLOR']; + } + + + + /* -- BACKGROUNDS -- */ + if (isset($properties['BACKGROUND-GRADIENT'])) { + $c['gradient'] = $properties['BACKGROUND-GRADIENT']; + } else { + $c['gradient'] = false; + } + + if (!empty($properties['BACKGROUND-IMAGE']) && !$this->mpdf->keep_block_together) { + $ret = $this->mpdf->SetBackground($properties, $this->mpdf->blk[$this->mpdf->blklvl]['inner_width']); + if ($ret) { + $c['background-image'] = $ret; + } + } + /* -- END BACKGROUNDS -- */ + if (isset($properties['VERTICAL-ALIGN'])) { + $c['va'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } elseif (isset($attr['VALIGN'])) { + $c['va'] = self::ALIGN[strtolower($attr['VALIGN'])]; + } + + + if (!empty($properties['TEXT-ALIGN'])) { + if (0 === strpos($properties['TEXT-ALIGN'], 'D')) { + $c['a'] = $properties['TEXT-ALIGN']; + } else { + $c['a'] = self::ALIGN[strtolower($properties['TEXT-ALIGN'])]; + } + } + if (!empty($attr['ALIGN'])) { + if (strtolower($attr['ALIGN']) === 'char') { + if (!empty($attr['CHAR'])) { + $char = html_entity_decode($attr['CHAR']); + $char = UtfString::strcode2utf($char); + $d = array_search($char, $this->mpdf->decimal_align); + if ($d !== false) { + $c['a'] = $d . 'R'; + } + } else { + $c['a'] = 'DPR'; + } + } else { + $c['a'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } + } + + // mPDF 6 + $c['direction'] = $table['direction']; + if (isset($attr['DIR']) && $attr['DIR'] != '') { + $c['direction'] = strtolower($attr['DIR']); + } + if (isset($properties['DIRECTION'])) { + $c['direction'] = strtolower($properties['DIRECTION']); + } + + if (!$c['a']) { + if (isset($c['direction']) && $c['direction'] === 'rtl') { + $c['a'] = 'R'; + } else { + $c['a'] = 'L'; + } + } + + $c['cellLineHeight'] = $table['cellLineHeight']; + if (isset($properties['LINE-HEIGHT'])) { + $c['cellLineHeight'] = $this->mpdf->fixLineheight($properties['LINE-HEIGHT']); + } + + $c['cellLineStackingStrategy'] = $table['cellLineStackingStrategy']; + if (isset($properties['LINE-STACKING-STRATEGY'])) { + $c['cellLineStackingStrategy'] = strtolower($properties['LINE-STACKING-STRATEGY']); + } + + $c['cellLineStackingShift'] = $table['cellLineStackingShift']; + if (isset($properties['LINE-STACKING-SHIFT'])) { + $c['cellLineStackingShift'] = strtolower($properties['LINE-STACKING-SHIFT']); + } + + if (isset($properties['TEXT-ROTATE']) && ($properties['TEXT-ROTATE'] || $properties['TEXT-ROTATE'] === '0')) { + $c['R'] = $properties['TEXT-ROTATE']; + } + if (isset($properties['BORDER'])) { + $bord = $this->mpdf->border_details($properties['BORDER']); + if ($bord['s']) { + if (!$this->mpdf->simpleTables) { + $c['border'] = Border::ALL; + $c['border_details']['R'] = $bord; + $c['border_details']['L'] = $bord; + $c['border_details']['T'] = $bord; + $c['border_details']['B'] = $bord; + $c['border_details']['L']['dom'] = $this->mpdf->cell_border_dominance_L; + $c['border_details']['R']['dom'] = $this->mpdf->cell_border_dominance_R; + $c['border_details']['T']['dom'] = $this->mpdf->cell_border_dominance_T; + $c['border_details']['B']['dom'] = $this->mpdf->cell_border_dominance_B; + } elseif ($this->mpdf->simpleTables && $this->mpdf->row == 0 && $this->mpdf->col == 0) { + $table['simple']['border'] = Border::ALL; + $table['simple']['border_details']['R'] = $bord; + $table['simple']['border_details']['L'] = $bord; + $table['simple']['border_details']['T'] = $bord; + $table['simple']['border_details']['B'] = $bord; + } + } + } + if (!$this->mpdf->simpleTables) { + if (!empty($properties['BORDER-RIGHT'])) { + $c['border_details']['R'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + $this->mpdf->setBorder($c['border'], Border::RIGHT, $c['border_details']['R']['s']); + $c['border_details']['R']['dom'] = $this->mpdf->cell_border_dominance_R; + } + if (!empty($properties['BORDER-LEFT'])) { + $c['border_details']['L'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + $this->mpdf->setBorder($c['border'], Border::LEFT, $c['border_details']['L']['s']); + $c['border_details']['L']['dom'] = $this->mpdf->cell_border_dominance_L; + } + if (!empty($properties['BORDER-BOTTOM'])) { + $c['border_details']['B'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + $this->mpdf->setBorder($c['border'], Border::BOTTOM, $c['border_details']['B']['s']); + $c['border_details']['B']['dom'] = $this->mpdf->cell_border_dominance_B; + } + if (!empty($properties['BORDER-TOP'])) { + $c['border_details']['T'] = $this->mpdf->border_details($properties['BORDER-TOP']); + $this->mpdf->setBorder($c['border'], Border::TOP, $c['border_details']['T']['s']); + $c['border_details']['T']['dom'] = $this->mpdf->cell_border_dominance_T; + } + } elseif ($this->mpdf->simpleTables && $this->mpdf->row == 0 && $this->mpdf->col == 0) { + if (!empty($properties['BORDER-LEFT'])) { + $bord = $this->mpdf->border_details($properties['BORDER-LEFT']); + if ($bord['s']) { + $table['simple']['border'] = Border::ALL; + } else { + $table['simple']['border'] = 0; + } + $table['simple']['border_details']['R'] = $bord; + $table['simple']['border_details']['L'] = $bord; + $table['simple']['border_details']['T'] = $bord; + $table['simple']['border_details']['B'] = $bord; + } + } + + if ($this->mpdf->simpleTables && $this->mpdf->row == 0 && $this->mpdf->col == 0 && !$table['borders_separate'] && $table['simple']['border']) { + $table['border_details'] = $table['simple']['border_details']; + $table['border'] = $table['simple']['border']; + } + + // Border set on TR (if collapsed only) + if (!$table['borders_separate'] && !$this->mpdf->simpleTables && isset($table['trborder-left'][$this->mpdf->row])) { + if ($this->mpdf->col == 0) { + $left = $this->mpdf->border_details($table['trborder-left'][$this->mpdf->row]); + $c['border_details']['L'] = $left; + $this->mpdf->setBorder($c['border'], Border::LEFT, $c['border_details']['L']['s']); + } + $c['border_details']['B'] = $this->mpdf->border_details($table['trborder-bottom'][$this->mpdf->row]); + $this->mpdf->setBorder($c['border'], Border::BOTTOM, $c['border_details']['B']['s']); + $c['border_details']['T'] = $this->mpdf->border_details($table['trborder-top'][$this->mpdf->row]); + $this->mpdf->setBorder($c['border'], Border::TOP, $c['border_details']['T']['s']); + } + + if ($this->mpdf->packTableData && !$this->mpdf->simpleTables) { + $c['borderbin'] = $this->mpdf->_packCellBorder($c); + unset($c['border'], $c['border_details']); + } + + if (isset($properties['PADDING-LEFT'])) { + $c['padding']['L'] = $this->sizeConverter->convert($properties['PADDING-LEFT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-RIGHT'])) { + $c['padding']['R'] = $this->sizeConverter->convert($properties['PADDING-RIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-BOTTOM'])) { + $c['padding']['B'] = $this->sizeConverter->convert($properties['PADDING-BOTTOM'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + if (isset($properties['PADDING-TOP'])) { + $c['padding']['T'] = $this->sizeConverter->convert($properties['PADDING-TOP'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + $w = ''; + if (isset($properties['WIDTH'])) { + $w = $properties['WIDTH']; + } elseif (isset($attr['WIDTH'])) { + $w = $attr['WIDTH']; + } + if ($w) { + if (strpos($w, '%') && !$this->mpdf->ignore_table_percents) { + $c['wpercent'] = (float) $w; + } // makes 80% -> 80 + elseif (!strpos($w, '%') && !$this->mpdf->ignore_table_widths) { + $c['w'] = $this->sizeConverter->convert($w, $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + } + + if (isset($properties['HEIGHT']) && !strpos($properties['HEIGHT'], '%')) { + $c['h'] = $this->sizeConverter->convert($properties['HEIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } elseif (isset($attr['HEIGHT']) && !strpos($attr['HEIGHT'], '%')) { + $c['h'] = $this->sizeConverter->convert($attr['HEIGHT'], $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], $this->mpdf->FontSize, false); + } + + if (isset($properties['WHITE-SPACE'])) { + if (strtoupper($properties['WHITE-SPACE']) === 'NOWRAP') { + $c['nowrap'] = 1; + } + } + + if (isset($attr['TEXT-ROTATE'])) { + $c['R'] = $attr['TEXT-ROTATE']; + } + if (!empty($attr['NOWRAP'])) { + $c['nowrap'] = 1; + } + + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col] = $c; + unset($c); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] = 0; + + $cs = $rs = 1; + if (isset($attr['COLSPAN']) && $attr['COLSPAN'] > 1) { + $cs = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['colspan'] = $attr['COLSPAN']; + } + if ($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc'] < $this->mpdf->col + $cs) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nc'] = $this->mpdf->col + $cs; + } // following code moved outside if... + for ($l = $this->mpdf->col; $l < $this->mpdf->col + $cs; $l++) { + if ($l - $this->mpdf->col) { + $this->mpdf->cell[$this->mpdf->row][$l] = 0; + } + } + if (isset($attr['ROWSPAN']) && $attr['ROWSPAN'] > 1) { + $rs = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['rowspan'] = $attr['ROWSPAN']; + } + for ($k = $this->mpdf->row; $k < $this->mpdf->row + $rs; $k++) { + for ($l = $this->mpdf->col; $l < $this->mpdf->col + $cs; $l++) { + if ($k - $this->mpdf->row || $l - $this->mpdf->col) { + $this->mpdf->cell[$k][$l] = 0; + } + } + } + unset($table); + } + + public function close(&$ahtml, &$ihtml) + { + if ($this->mpdf->tableLevel) { + $this->mpdf->lastoptionaltag = 'TR'; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + if (!$this->mpdf->tdbegin) { + return; + } + $this->mpdf->tdbegin = false; + // Added for correct calculation of cell column width - otherwise misses the last line if not end </p> etc. + if (!isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'])) { + if (!is_array($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col])) { + throw new \Mpdf\MpdfException('You may have an error in your HTML code e.g. </td></td>'); + } + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } elseif ($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] < $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['maxs'] = $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s']; + } + + // Remove last <br> if at end of cell + $ntb = 0; + if (isset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'])) { + $ntb = count($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer']); + } + if ($ntb > 1 && $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][$ntb - 1][0] === "\n") { + unset($this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][$ntb - 1]); + } + + if ($this->mpdf->tablethead) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_thead'][$this->mpdf->row] = true; + if ($this->mpdf->tableLevel == 1) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['headernrows'] + = max($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['headernrows'], $this->mpdf->row + 1); + } + } + if ($this->mpdf->tabletfoot) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'][$this->mpdf->row] = true; + if ($this->mpdf->tableLevel == 1) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['footernrows'] + = max( + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['footernrows'], + $this->mpdf->row + 1 - $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['headernrows'] + ); + } + } + $this->mpdf->Reset(); + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextArea.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextArea.php new file mode 100644 index 0000000..8685fab --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextArea.php @@ -0,0 +1,162 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; + +class TextArea extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + if (isset($attr['DISABLED'])) { + $objattr['disabled'] = true; + } + if (isset($attr['READONLY'])) { + $objattr['readonly'] = true; + } + if (isset($attr['REQUIRED'])) { + $objattr['required'] = true; + } + if (isset($attr['SPELLCHECK']) && strtolower($attr['SPELLCHECK']) === 'true') { + $objattr['spellcheck'] = true; + } + if (isset($attr['TITLE'])) { + $objattr['title'] = $attr['TITLE']; + if ($this->mpdf->onlyCoreFonts) { + $objattr['title'] = mb_convert_encoding($objattr['title'], $this->mpdf->mb_enc, 'UTF-8'); + } + } + if ($this->mpdf->useActiveForms) { + if (isset($attr['NAME'])) { + $objattr['fieldname'] = $attr['NAME']; + } + $this->form->form_element_spacing['textarea']['outer']['v'] = 0; + $this->form->form_element_spacing['textarea']['inner']['v'] = 0; + if (isset($attr['ONCALCULATE'])) { + $objattr['onCalculate'] = $attr['ONCALCULATE']; + } elseif (isset($attr['ONCHANGE'])) { + $objattr['onCalculate'] = $attr['ONCHANGE']; + } + if (isset($attr['ONVALIDATE'])) { + $objattr['onValidate'] = $attr['ONVALIDATE']; + } + if (isset($attr['ONKEYSTROKE'])) { + $objattr['onKeystroke'] = $attr['ONKEYSTROKE']; + } + if (isset($attr['ONFORMAT'])) { + $objattr['onFormat'] = $attr['ONFORMAT']; + } + } + $this->mpdf->InlineProperties['TEXTAREA'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('', 'TEXTAREA', $attr); + if (isset($properties['FONT-FAMILY'])) { + $this->mpdf->SetFont($properties['FONT-FAMILY'], '', 0, false); + } + if (isset($properties['FONT-SIZE'])) { + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE); + $this->mpdf->SetFontSize($mmsize * Mpdf::SCALE, false); + } + if (isset($properties['COLOR'])) { + $objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } + $objattr['fontfamily'] = $this->mpdf->FontFamily; + $objattr['fontsize'] = $this->mpdf->FontSizePt; + if ($this->mpdf->useActiveForms) { + if (isset($properties['TEXT-ALIGN'])) { + $objattr['text_align'] = self::ALIGN[strtolower($properties['TEXT-ALIGN'])]; + } elseif (isset($attr['ALIGN'])) { + $objattr['text_align'] = self::ALIGN[strtolower($attr['ALIGN'])]; + } + if (isset($properties['OVERFLOW']) && strtolower($properties['OVERFLOW']) === 'hidden') { + $objattr['donotscroll'] = true; + } + if (isset($properties['BORDER-TOP-COLOR'])) { + $objattr['border-col'] = $this->colorConverter->convert($properties['BORDER-TOP-COLOR'], $this->mpdf->PDFAXwarnings); + } + if (isset($properties['BACKGROUND-COLOR'])) { + $objattr['background-col'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); + } + } + $this->mpdf->SetLineHeight('', $this->form->textarea_lineheight); + + $w = 0; + $h = 0; + if (isset($properties['WIDTH'])) { + $w = $this->sizeConverter->convert( + $properties['WIDTH'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['HEIGHT'])) { + $h = $this->sizeConverter->convert( + $properties['HEIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['VERTICAL-ALIGN'])) { + $objattr['vertical-align'] = self::ALIGN[strtolower($properties['VERTICAL-ALIGN'])]; + } + + $colsize = 20; //HTML default value + $rowsize = 2; //HTML default value + if (isset($attr['COLS'])) { + $colsize = (int) $attr['COLS']; + } + if (isset($attr['ROWS'])) { + $rowsize = (int) $attr['ROWS']; + } + + $charsize = $this->mpdf->GetCharWidth('w', false); + if ($w) { + $colsize = round(($w - ($this->form->form_element_spacing['textarea']['outer']['h'] * 2) + - ($this->form->form_element_spacing['textarea']['inner']['h'] * 2)) / $charsize); + } + if ($h) { + $rowsize = round(($h - ($this->form->form_element_spacing['textarea']['outer']['v'] * 2) + - ($this->form->form_element_spacing['textarea']['inner']['v'] * 2)) / $this->mpdf->lineheight); + } + + $objattr['type'] = 'textarea'; + $objattr['width'] = ($colsize * $charsize) + ($this->form->form_element_spacing['textarea']['outer']['h'] * 2) + + ($this->form->form_element_spacing['textarea']['inner']['h'] * 2); + + $objattr['height'] = ($rowsize * $this->mpdf->lineheight) + + ($this->form->form_element_spacing['textarea']['outer']['v'] * 2) + + ($this->form->form_element_spacing['textarea']['inner']['v'] * 2); + + $objattr['rows'] = $rowsize; + $objattr['cols'] = $colsize; + + $this->mpdf->specialcontent = serialize($objattr); + + if ($this->mpdf->tableLevel) { // *TABLES* + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; // *TABLES* + } // *TABLES* + } + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->ignorefollowingspaces = false; + $this->mpdf->specialcontent = ''; + if ($this->mpdf->InlineProperties['TEXTAREA']) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['TEXTAREA']); + } + unset($this->mpdf->InlineProperties['TEXTAREA']); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextCircle.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextCircle.php new file mode 100644 index 0000000..6bd5313 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TextCircle.php @@ -0,0 +1,250 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Mpdf; +use Mpdf\Utils\UtfString; + +class TextCircle extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $objattr = []; + $objattr['margin_top'] = 0; + $objattr['margin_bottom'] = 0; + $objattr['margin_left'] = 0; + $objattr['margin_right'] = 0; + $objattr['padding_top'] = 0; + $objattr['padding_bottom'] = 0; + $objattr['padding_left'] = 0; + $objattr['padding_right'] = 0; + $objattr['width'] = 0; + $objattr['height'] = 0; + $objattr['border_top']['w'] = 0; + $objattr['border_bottom']['w'] = 0; + $objattr['border_left']['w'] = 0; + $objattr['border_right']['w'] = 0; + $objattr['top-text'] = ''; + $objattr['bottom-text'] = ''; + $objattr['r'] = 20; // radius (default value here for safety) + $objattr['space-width'] = 120; + $objattr['char-width'] = 100; + + $this->mpdf->InlineProperties['TEXTCIRCLE'] = $this->mpdf->saveInlineProperties(); + $properties = $this->cssManager->MergeCSS('INLINE', 'TEXTCIRCLE', $attr); + + if (isset($properties ['DISPLAY']) && strtolower($properties ['DISPLAY']) === 'none') { + return; + } + if (isset($attr['R'])) { + $objattr['r'] = $this->sizeConverter->convert( + $attr['R'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($attr['TOP-TEXT'])) { + $objattr['top-text'] = UtfString::strcode2utf($attr['TOP-TEXT']); + $objattr['top-text'] = $this->mpdf->lesser_entity_decode($objattr['top-text']); + if ($this->mpdf->onlyCoreFonts) { + $objattr['top-text'] = mb_convert_encoding($objattr['top-text'], $this->mpdf->mb_enc, 'UTF-8'); + } + } + if (isset($attr['BOTTOM-TEXT'])) { + $objattr['bottom-text'] = UtfString::strcode2utf($attr['BOTTOM-TEXT']); + $objattr['bottom-text'] = $this->mpdf->lesser_entity_decode($objattr['bottom-text']); + if ($this->mpdf->onlyCoreFonts) { + $objattr['bottom-text'] = mb_convert_encoding($objattr['bottom-text'], $this->mpdf->mb_enc, 'UTF-8'); + } + } + if (!empty($attr['SPACE-WIDTH'])) { + $objattr['space-width'] = $attr['SPACE-WIDTH']; + } + if (!empty($attr['CHAR-WIDTH'])) { + $objattr['char-width'] = $attr['CHAR-WIDTH']; + } + + // VISIBILITY + $objattr['visibility'] = 'visible'; + if (isset($properties['VISIBILITY'])) { + $v = strtolower($properties['VISIBILITY']); + if (($v === 'hidden' || $v === 'printonly' || $v === 'screenonly') && $this->mpdf->visibility === 'visible') { + $objattr['visibility'] = $v; + } + } + if (isset($properties['FONT-SIZE'])) { + if (strtolower($properties['FONT-SIZE']) === 'auto') { + if ($objattr['top-text'] && $objattr['bottom-text']) { + $objattr['fontsize'] = -2; + } else { + $objattr['fontsize'] = -1; + } + } else { + $mmsize = $this->sizeConverter->convert($properties['FONT-SIZE'], $this->mpdf->default_font_size / Mpdf::SCALE); + $this->mpdf->SetFontSize($mmsize * Mpdf::SCALE, false); + $objattr['fontsize'] = $this->mpdf->FontSizePt; + } + } + if (isset($attr['DIVIDER'])) { + $objattr['divider'] = UtfString::strcode2utf($attr['DIVIDER']); + $objattr['divider'] = $this->mpdf->lesser_entity_decode($objattr['divider']); + if ($this->mpdf->onlyCoreFonts) { + $objattr['divider'] = mb_convert_encoding($objattr['divider'], $this->mpdf->mb_enc, 'UTF-8'); + } + } + + if (isset($properties['COLOR'])) { + $objattr['color'] = $this->colorConverter->convert($properties['COLOR'], $this->mpdf->PDFAXwarnings); + } + + $objattr['fontstyle'] = ''; + if (isset($properties['FONT-WEIGHT'])) { + if (strtoupper($properties['FONT-WEIGHT']) === 'BOLD') { + $objattr['fontstyle'] .= 'B'; + } + } + if (isset($properties['FONT-STYLE'])) { + if (strtoupper($properties['FONT-STYLE']) === 'ITALIC') { + $objattr['fontstyle'] .= 'I'; + } + } + + if (isset($properties['FONT-FAMILY'])) { + $this->mpdf->SetFont($properties['FONT-FAMILY'], $this->mpdf->FontStyle, 0, false); + } + $objattr['fontfamily'] = $this->mpdf->FontFamily; + + // VSPACE and HSPACE converted to margins in MergeCSS + if (isset($properties['MARGIN-TOP'])) { + $objattr['margin_top'] = $this->sizeConverter->convert( + $properties['MARGIN-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-BOTTOM'])) { + $objattr['margin_bottom'] = $this->sizeConverter->convert( + $properties['MARGIN-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-LEFT'])) { + $objattr['margin_left'] = $this->sizeConverter->convert( + $properties['MARGIN-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['MARGIN-RIGHT'])) { + $objattr['margin_right'] = $this->sizeConverter->convert( + $properties['MARGIN-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['PADDING-TOP'])) { + $objattr['padding_top'] = $this->sizeConverter->convert( + $properties['PADDING-TOP'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-BOTTOM'])) { + $objattr['padding_bottom'] = $this->sizeConverter->convert( + $properties['PADDING-BOTTOM'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-LEFT'])) { + $objattr['padding_left'] = $this->sizeConverter->convert( + $properties['PADDING-LEFT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + if (isset($properties['PADDING-RIGHT'])) { + $objattr['padding_right'] = $this->sizeConverter->convert( + $properties['PADDING-RIGHT'], + $this->mpdf->blk[$this->mpdf->blklvl]['inner_width'], + $this->mpdf->FontSize, + false + ); + } + + if (isset($properties['BORDER-TOP'])) { + $objattr['border_top'] = $this->mpdf->border_details($properties['BORDER-TOP']); + } + if (isset($properties['BORDER-BOTTOM'])) { + $objattr['border_bottom'] = $this->mpdf->border_details($properties['BORDER-BOTTOM']); + } + if (isset($properties['BORDER-LEFT'])) { + $objattr['border_left'] = $this->mpdf->border_details($properties['BORDER-LEFT']); + } + if (isset($properties['BORDER-RIGHT'])) { + $objattr['border_right'] = $this->mpdf->border_details($properties['BORDER-RIGHT']); + } + + if (isset($properties['OPACITY']) && $properties['OPACITY'] > 0 && $properties['OPACITY'] <= 1) { + $objattr['opacity'] = $properties['OPACITY']; + } + if (isset($properties['BACKGROUND-COLOR']) && $properties['BACKGROUND-COLOR'] != '') { + $objattr['bgcolor'] = $this->colorConverter->convert($properties['BACKGROUND-COLOR'], $this->mpdf->PDFAXwarnings); + } else { + $objattr['bgcolor'] = false; + } + if ($this->mpdf->HREF) { + if (strpos($this->mpdf->HREF, '.') === false && strpos($this->mpdf->HREF, '@') !== 0) { + $href = $this->mpdf->HREF; + while (array_key_exists($href, $this->mpdf->internallink)) { + $href = '#' . $href; + } + $this->mpdf->internallink[$href] = $this->mpdf->AddLink(); + $objattr['link'] = $this->mpdf->internallink[$href]; + } else { + $objattr['link'] = $this->mpdf->HREF; + } + } + $extraheight = $objattr['padding_top'] + $objattr['padding_bottom'] + $objattr['margin_top'] + $objattr['margin_bottom'] + $objattr['border_top']['w'] + $objattr['border_bottom']['w']; + $extrawidth = $objattr['padding_left'] + $objattr['padding_right'] + $objattr['margin_left'] + $objattr['margin_right'] + $objattr['border_left']['w'] + $objattr['border_right']['w']; + + + $w = $objattr['r'] * 2; + $h = $w; + $objattr['height'] = $h + $extraheight; + $objattr['width'] = $w + $extrawidth; + $objattr['type'] = 'textcircle'; + + $e = "\xbb\xa4\xactype=image,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + + /* -- TABLES -- */ + // Output it to buffers + if ($this->mpdf->tableLevel) { + $this->mpdf->_saveCellTextBuffer($e, $this->mpdf->HREF); + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['s'] += $objattr['width']; + } else { + /* -- END TABLES -- */ + $this->mpdf->_saveTextBuffer($e, $this->mpdf->HREF); + } // *TABLES* + + if ($this->mpdf->InlineProperties['TEXTCIRCLE']) { + $this->mpdf->restoreInlineProperties($this->mpdf->InlineProperties['TEXTCIRCLE']); + } + unset($this->mpdf->InlineProperties['TEXTCIRCLE']); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Th.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Th.php new file mode 100644 index 0000000..c0df792 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Th.php @@ -0,0 +1,13 @@ +<?php + +namespace Mpdf\Tag; + +class Th extends Td +{ + + public function close(&$ahtml, &$ihtml) + { + $this->mpdf->SetStyle('B', false); + parent::close($ahtml, $ihtml); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Time.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Time.php new file mode 100644 index 0000000..04ffb6e --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Time.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Time extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Toc.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Toc.php new file mode 100644 index 0000000..1afeae8 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Toc.php @@ -0,0 +1,17 @@ +<?php + +namespace Mpdf\Tag; + +class Toc extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + //added custom-tag - set Marker for insertion later of ToC + $this->tableOfContents->openTagTOC($attr); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocEntry.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocEntry.php new file mode 100644 index 0000000..1b315ab --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocEntry.php @@ -0,0 +1,38 @@ +<?php + +namespace Mpdf\Tag; + +class TocEntry extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + if (!empty($attr['CONTENT'])) { + $objattr = []; + $objattr['CONTENT'] = htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES); + $objattr['type'] = 'toc'; + $objattr['vertical-align'] = 'T'; + if (!empty($attr['LEVEL'])) { + $objattr['toclevel'] = $attr['LEVEL']; + } else { + $objattr['toclevel'] = 0; + } + if (!empty($attr['NAME'])) { + $objattr['toc_id'] = $attr['NAME']; + } else { + $objattr['toc_id'] = 0; + } + $e = "\xbb\xa4\xactype=toc,objattr=" . serialize($objattr) . "\xbb\xa4\xac"; + if ($this->mpdf->tableLevel) { + $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]['textbuffer'][] = [$e]; + } // *TABLES* + else { // *TABLES* + $this->mpdf->textbuffer[] = [$e]; + } // *TABLES* + } + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocPageBreak.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocPageBreak.php new file mode 100644 index 0000000..19c5167 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/TocPageBreak.php @@ -0,0 +1,16 @@ +<?php + +namespace Mpdf\Tag; + +class TocPageBreak extends FormFeed +{ + public function open($attr, &$ahtml, &$ihtml) + { + list($isbreak, $toc_id) = $this->tableOfContents->openTagTOCPAGEBREAK($attr); + $this->toc_id = $toc_id; + if ($isbreak) { + return; + } + parent::open($attr, $ahtml, $ihtml); + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tr.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tr.php new file mode 100644 index 0000000..f891df9 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tr.php @@ -0,0 +1,102 @@ +<?php + +namespace Mpdf\Tag; + +use Mpdf\Css\Border; + +class Tr extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + + $this->mpdf->lastoptionaltag = 'TR'; // Save current HTML specified optional endtag + $this->cssManager->tbCSSlvl++; + $this->mpdf->row++; + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['nr'] ++; + $this->mpdf->col = -1; + $properties = $this->cssManager->MergeCSS('TABLE', 'TR', $attr); + + if (!$this->mpdf->simpleTables && (!isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['borders_separate']) + || !$this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['borders_separate'])) { + if (!empty($properties['BORDER-LEFT'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-left'][$this->mpdf->row] = $properties['BORDER-LEFT']; + } + if (!empty($properties['BORDER-RIGHT'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-right'][$this->mpdf->row] = $properties['BORDER-RIGHT']; + } + if (!empty($properties['BORDER-TOP'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-top'][$this->mpdf->row] = $properties['BORDER-TOP']; + } + if (!empty($properties['BORDER-BOTTOM'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-bottom'][$this->mpdf->row] = $properties['BORDER-BOTTOM']; + } + } + + if (isset($properties['BACKGROUND-COLOR'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$this->mpdf->row] = $properties['BACKGROUND-COLOR']; + } elseif (isset($attr['BGCOLOR'])) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['bgcolor'][$this->mpdf->row] = $attr['BGCOLOR']; + } + + /* -- BACKGROUNDS -- */ + if (isset($properties['BACKGROUND-GRADIENT']) && !$this->mpdf->kwt && !$this->mpdf->ColActive) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trgradients'][$this->mpdf->row] = $properties['BACKGROUND-GRADIENT']; + } + + // FIXME: undefined variable $currblk + if (!empty($properties['BACKGROUND-IMAGE']) && !$this->mpdf->kwt && !$this->mpdf->ColActive) { + $ret = $this->mpdf->SetBackground($properties, $currblk['inner_width']); + if ($ret) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trbackground-images'][$this->mpdf->row] = $ret; + } + } + /* -- END BACKGROUNDS -- */ + + if (isset($properties['TEXT-ROTATE'])) { + $this->mpdf->trow_text_rotate = $properties['TEXT-ROTATE']; + } + if (isset($attr['TEXT-ROTATE'])) { + $this->mpdf->trow_text_rotate = $attr['TEXT-ROTATE']; + } + + if ($this->mpdf->tablethead) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_thead'][$this->mpdf->row] = true; + } + if ($this->mpdf->tabletfoot) { + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['is_tfoot'][$this->mpdf->row] = true; + } + } + + public function close(&$ahtml, &$ihtml) + { + if ($this->mpdf->tableLevel) { + // If Border set on TR - Update right border + if (isset($this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-left'][$this->mpdf->row])) { + $c = & $this->mpdf->cell[$this->mpdf->row][$this->mpdf->col]; + if ($c) { + if ($this->mpdf->packTableData) { + $cell = $this->mpdf->_unpackCellBorder($c['borderbin']); + } else { + $cell = $c; + } + $cell['border_details']['R'] = $this->mpdf->border_details( + $this->mpdf->table[$this->mpdf->tableLevel][$this->mpdf->tbctr[$this->mpdf->tableLevel]]['trborder-right'][$this->mpdf->row] + ); + $this->mpdf->setBorder($cell['border'], Border::RIGHT, $cell['border_details']['R']['s']); + if ($this->mpdf->packTableData) { + $c['borderbin'] = $this->mpdf->_packCellBorder($cell); + unset($c['border'], $c['border_details']); + } else { + $c = $cell; + } + } + } + $this->mpdf->lastoptionaltag = ''; + unset($this->cssManager->tablecascadeCSS[$this->cssManager->tbCSSlvl]); + $this->cssManager->tbCSSlvl--; + $this->mpdf->trow_text_rotate = ''; + $this->mpdf->tabletheadjustfinished = false; + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tt.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tt.php new file mode 100644 index 0000000..078277a --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tt.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Tt extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tta.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tta.php new file mode 100644 index 0000000..bac9fb5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tta.php @@ -0,0 +1,22 @@ +<?php + +namespace Mpdf\Tag; + +class Tta extends SubstituteTag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->tta = true; + $this->mpdf->InlineProperties['TTA'] = $this->mpdf->saveInlineProperties(); + + if (in_array($this->mpdf->FontFamily, $this->mpdf->mono_fonts)) { + $this->mpdf->setCSS(['FONT-FAMILY' => 'ccourier'], 'INLINE'); + } elseif (in_array($this->mpdf->FontFamily, $this->mpdf->serif_fonts)) { + $this->mpdf->setCSS(['FONT-FAMILY' => 'ctimes'], 'INLINE'); + } else { + $this->mpdf->setCSS(['FONT-FAMILY' => 'chelvetica'], 'INLINE'); + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tts.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tts.php new file mode 100644 index 0000000..f24d722 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Tts.php @@ -0,0 +1,15 @@ +<?php + +namespace Mpdf\Tag; + +class Tts extends SubstituteTag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->tts = true; + $this->mpdf->InlineProperties['TTS'] = $this->mpdf->saveInlineProperties(); + $this->mpdf->setCSS(['FONT-FAMILY' => 'csymbol', 'FONT-WEIGHT' => 'normal', 'FONT-STYLE' => 'normal'], 'INLINE'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ttz.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ttz.php new file mode 100644 index 0000000..d76d4c5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ttz.php @@ -0,0 +1,15 @@ +<?php + +namespace Mpdf\Tag; + +class Ttz extends SubstituteTag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $this->mpdf->ttz = true; + $this->mpdf->InlineProperties['TTZ'] = $this->mpdf->saveInlineProperties(); + $this->mpdf->setCSS(['FONT-FAMILY' => 'czapfdingbats', 'FONT-WEIGHT' => 'normal', 'FONT-STYLE' => 'normal'], 'INLINE'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/U.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/U.php new file mode 100644 index 0000000..513298d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/U.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class U extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ul.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ul.php new file mode 100644 index 0000000..6efa4d6 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/Ul.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class Ul extends BlockTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/VarTag.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/VarTag.php new file mode 100644 index 0000000..556dd40 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/VarTag.php @@ -0,0 +1,9 @@ +<?php + +namespace Mpdf\Tag; + +class VarTag extends InlineTag +{ + + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkImage.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkImage.php new file mode 100644 index 0000000..21f8c48 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkImage.php @@ -0,0 +1,41 @@ +<?php + +namespace Mpdf\Tag; + +class WatermarkImage extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $src = ''; + if (isset($attr['SRC'])) { + $src = $attr['SRC']; + } + + $alpha = -1; + if (isset($attr['ALPHA']) && $attr['ALPHA'] > 0) { + $alpha = $attr['ALPHA']; + } + + $size = 'D'; + if (!empty($attr['SIZE'])) { + $size = $attr['SIZE']; + if (strpos($size, ',')) { + $size = explode(',', $size); + } + } + + $pos = 'P'; + if (!empty($attr['POSITION'])) { // mPDF 5.7.2 + $pos = $attr['POSITION']; + if (strpos($pos, ',')) { + $pos = explode(',', $pos); + } + } + $this->mpdf->SetWatermarkImage($src, $alpha, $size, $pos); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkText.php b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkText.php new file mode 100644 index 0000000..8d6dcc2 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Tag/WatermarkText.php @@ -0,0 +1,25 @@ +<?php + +namespace Mpdf\Tag; + +class WatermarkText extends Tag +{ + + public function open($attr, &$ahtml, &$ihtml) + { + $txt = ''; + if (!empty($attr['CONTENT'])) { + $txt = htmlspecialchars_decode($attr['CONTENT'], ENT_QUOTES); + } + + $alpha = -1; + if (isset($attr['ALPHA']) && $attr['ALPHA'] > 0) { + $alpha = $attr['ALPHA']; + } + $this->mpdf->SetWatermarkText($txt, $alpha); + } + + public function close(&$ahtml, &$ihtml) + { + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Ucdn.php b/lib/MPDF/vendor/mpdf/mpdf/src/Ucdn.php new file mode 100644 index 0000000..dbf7caa --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Ucdn.php @@ -0,0 +1,2921 @@ +<?php + +namespace Mpdf; + +class Ucdn +{ + + /* HarfBuzz ucdn/unicodedata_db.h */ + /* HarfBuzz ucdn/ucdn.c */ + /* HarfBuzz ucdn/ucdn.h */ + + const SCRIPT_COMMON = 0; + const SCRIPT_LATIN = 1; + const SCRIPT_GREEK = 2; + const SCRIPT_CYRILLIC = 3; + const SCRIPT_ARMENIAN = 4; + const SCRIPT_HEBREW = 5; + const SCRIPT_ARABIC = 6; + const SCRIPT_SYRIAC = 7; + const SCRIPT_THAANA = 8; + const SCRIPT_DEVANAGARI = 9; + const SCRIPT_BENGALI = 10; + const SCRIPT_GURMUKHI = 11; + const SCRIPT_GUJARATI = 12; + const SCRIPT_ORIYA = 13; + const SCRIPT_TAMIL = 14; + const SCRIPT_TELUGU = 15; + const SCRIPT_KANNADA = 16; + const SCRIPT_MALAYALAM = 17; + const SCRIPT_SINHALA = 18; + const SCRIPT_THAI = 19; + const SCRIPT_LAO = 20; + const SCRIPT_TIBETAN = 21; + const SCRIPT_MYANMAR = 22; + const SCRIPT_GEORGIAN = 23; + const SCRIPT_HANGUL = 24; + const SCRIPT_ETHIOPIC = 25; + const SCRIPT_CHEROKEE = 26; + const SCRIPT_CANADIAN_ABORIGINAL = 27; + const SCRIPT_OGHAM = 28; + const SCRIPT_RUNIC = 29; + const SCRIPT_KHMER = 30; + const SCRIPT_MONGOLIAN = 31; + const SCRIPT_HIRAGANA = 32; + const SCRIPT_KATAKANA = 33; + const SCRIPT_BOPOMOFO = 34; + const SCRIPT_HAN = 35; + const SCRIPT_YI = 36; + const SCRIPT_OLD_ITALIC = 37; + const SCRIPT_GOTHIC = 38; + const SCRIPT_DESERET = 39; + const SCRIPT_INHERITED = 40; + const SCRIPT_TAGALOG = 41; + const SCRIPT_HANUNOO = 42; + const SCRIPT_BUHID = 43; + const SCRIPT_TAGBANWA = 44; + const SCRIPT_LIMBU = 45; + const SCRIPT_TAI_LE = 46; + const SCRIPT_LINEAR_B = 47; + const SCRIPT_UGARITIC = 48; + const SCRIPT_SHAVIAN = 49; + const SCRIPT_OSMANYA = 50; + const SCRIPT_CYPRIOT = 51; + const SCRIPT_BRAILLE = 52; + const SCRIPT_BUGINESE = 53; + const SCRIPT_COPTIC = 54; + const SCRIPT_NEW_TAI_LUE = 55; + const SCRIPT_GLAGOLITIC = 56; + const SCRIPT_TIFINAGH = 57; + const SCRIPT_SYLOTI_NAGRI = 58; + const SCRIPT_OLD_PERSIAN = 59; + const SCRIPT_KHAROSHTHI = 60; + const SCRIPT_BALINESE = 61; + const SCRIPT_CUNEIFORM = 62; + const SCRIPT_PHOENICIAN = 63; + const SCRIPT_PHAGS_PA = 64; + const SCRIPT_NKO = 65; + const SCRIPT_SUNDANESE = 66; + const SCRIPT_LEPCHA = 67; + const SCRIPT_OL_CHIKI = 68; + const SCRIPT_VAI = 69; + const SCRIPT_SAURASHTRA = 70; + const SCRIPT_KAYAH_LI = 71; + const SCRIPT_REJANG = 72; + const SCRIPT_LYCIAN = 73; + const SCRIPT_CARIAN = 74; + const SCRIPT_LYDIAN = 75; + const SCRIPT_CHAM = 76; + const SCRIPT_TAI_THAM = 77; + const SCRIPT_TAI_VIET = 78; + const SCRIPT_AVESTAN = 79; + const SCRIPT_EGYPTIAN_HIEROGLYPHS = 80; + const SCRIPT_SAMARITAN = 81; + const SCRIPT_LISU = 82; + const SCRIPT_BAMUM = 83; + const SCRIPT_JAVANESE = 84; + const SCRIPT_MEETEI_MAYEK = 85; + const SCRIPT_IMPERIAL_ARAMAIC = 86; + const SCRIPT_OLD_SOUTH_ARABIAN = 87; + const SCRIPT_INSCRIPTIONAL_PARTHIAN = 88; + const SCRIPT_INSCRIPTIONAL_PAHLAVI = 89; + const SCRIPT_OLD_TURKIC = 90; + const SCRIPT_KAITHI = 91; + const SCRIPT_BATAK = 92; + const SCRIPT_BRAHMI = 93; + const SCRIPT_MANDAIC = 94; + const SCRIPT_CHAKMA = 95; + const SCRIPT_MEROITIC_CURSIVE = 96; + const SCRIPT_MEROITIC_HIEROGLYPHS = 97; + const SCRIPT_MIAO = 98; + const SCRIPT_SHARADA = 99; + const SCRIPT_SORA_SOMPENG = 100; + const SCRIPT_TAKRI = 101; + const SCRIPT_UNKNOWN = 102; + + public static function get_ucd_record($code) + { + if ($code >= 0x110000) { + $index = 0; + } else { + $index = self::$index0[$code >> (8)] << 5; + $offset = ($code >> 3) & ((1 << 5) - 1); + $index = self::$index1[$index + $offset] << 3; + $offset = $code & ((1 << 3) - 1); + $index = self::$index2[$index + $offset]; + } + return self::$ucd_records[$index]; + } + + public static function get_general_category($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[0]; + } + + public static function get_combining_class($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[1]; + } + + public static function get_bidi_class($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[2]; + } + + public static function get_mirrored($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[3]; + } + + public static function get_east_asian_width($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[4]; + } + + public static function get_normalization_check($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[5]; + } + + public static function get_script($code) + { + $ucd_record = self::get_ucd_record($code); + return $ucd_record[6]; + } + + // mPDF added + public static $uni_scriptblock = [ + /* SCRIPT_COMMON */ 0 => '', + /* SCRIPT_LATIN */ 1 => 'latn', + /* SCRIPT_GREEK */ 2 => 'grek', + /* SCRIPT_CYRILLIC */ 3 => 'cyrl', + /* SCRIPT_ARMENIAN */ 4 => 'armn', + /* SCRIPT_HEBREW */ 5 => 'hebr', + /* SCRIPT_ARABIC */ 6 => 'arab', + /* SCRIPT_SYRIAC */ 7 => 'syrc', + /* SCRIPT_THAANA */ 8 => 'thaa', + /* SCRIPT_DEVANAGARI */ 9 => 'dev2', + /* SCRIPT_BENGALI */ 10 => 'bng2', + /* SCRIPT_GURMUKHI */ 11 => 'gur2', + /* SCRIPT_GUJARATI */ 12 => 'gjr2', + /* SCRIPT_ORIYA */ 13 => 'ory2', + /* SCRIPT_TAMIL */ 14 => 'tml2', + /* SCRIPT_TELUGU */ 15 => 'tel2', + /* SCRIPT_KANNADA */ 16 => 'knd2', + /* SCRIPT_MALAYALAM */ 17 => 'mlm2', + /* SCRIPT_SINHALA */ 18 => 'sinh', + /* SCRIPT_THAI */ 19 => 'thai', + /* SCRIPT_LAO */ 20 => 'lao ', + /* SCRIPT_TIBETAN */ 21 => 'tibt', + /* SCRIPT_MYANMAR */ 22 => 'mym2', + /* SCRIPT_GEORGIAN */ 23 => 'geor', + /* SCRIPT_HANGUL */ 24 => 'jamo', /* there is also a hang tag, but we want to activate jamo features if present */ + /* SCRIPT_ETHIOPIC */ 25 => 'ethi', + /* SCRIPT_CHEROKEE */ 26 => 'cher', + /* SCRIPT_CANADIAN_ABORIGINAL */ 27 => 'cans', + /* SCRIPT_OGHAM */ 28 => 'ogam', + /* SCRIPT_RUNIC */ 29 => 'runr', + /* SCRIPT_KHMER */ 30 => 'khmr', + /* SCRIPT_MONGOLIAN */ 31 => 'mong', + /* SCRIPT_HIRAGANA */ 32 => 'kana', + /* SCRIPT_KATAKANA */ 33 => 'kana', + /* SCRIPT_BOPOMOFO */ 34 => 'bopo', + /* SCRIPT_HAN */ 35 => 'hani', + /* SCRIPT_YI */ 36 => 'yi ', + /* SCRIPT_OLD_ITALIC */ 37 => 'ital', + /* SCRIPT_GOTHIC */ 38 => 'goth', + /* SCRIPT_DESERET */ 39 => 'dsrt', + /* SCRIPT_INHERITED */ 40 => '', + /* SCRIPT_TAGALOG */ 41 => 'tglg', + /* SCRIPT_HANUNOO */ 42 => 'hano', + /* SCRIPT_BUHID */ 43 => 'buhd', + /* SCRIPT_TAGBANWA */ 44 => 'tagb', + /* SCRIPT_LIMBU */ 45 => 'limb', + /* SCRIPT_TAI_LE */ 46 => 'tale', + /* SCRIPT_LINEAR_B */ 47 => 'linb', + /* SCRIPT_UGARITIC */ 48 => 'ugar', + /* SCRIPT_SHAVIAN */ 49 => 'shaw', + /* SCRIPT_OSMANYA */ 50 => 'osma', + /* SCRIPT_CYPRIOT */ 51 => 'cprt', + /* SCRIPT_BRAILLE */ 52 => 'brai', + /* SCRIPT_BUGINESE */ 53 => 'bugi', + /* SCRIPT_COPTIC */ 54 => 'copt', + /* SCRIPT_NEW_TAI_LUE */ 55 => 'talu', + /* SCRIPT_GLAGOLITIC */ 56 => 'glag', + /* SCRIPT_TIFINAGH */ 57 => 'tfng', + /* SCRIPT_SYLOTI_NAGRI */ 58 => 'sylo', + /* SCRIPT_OLD_PERSIAN */ 59 => 'xpeo', + /* SCRIPT_KHAROSHTHI */ 60 => 'khar', + /* SCRIPT_BALINESE */ 61 => 'bali', + /* SCRIPT_CUNEIFORM */ 62 => 'xsux', + /* SCRIPT_PHOENICIAN */ 63 => 'phnx', + /* SCRIPT_PHAGS_PA */ 64 => 'phag', + /* SCRIPT_NKO */ 65 => 'nko ', + /* SCRIPT_SUNDANESE */ 66 => 'sund', + /* SCRIPT_LEPCHA */ 67 => 'lepc', + /* SCRIPT_OL_CHIKI */ 68 => 'olck', + /* SCRIPT_VAI */ 69 => 'vai ', + /* SCRIPT_SAURASHTRA */ 70 => 'saur', + /* SCRIPT_KAYAH_LI */ 71 => 'kali', + /* SCRIPT_REJANG */ 72 => 'rjng', + /* SCRIPT_LYCIAN */ 73 => 'lyci', + /* SCRIPT_CARIAN */ 74 => 'cari', + /* SCRIPT_LYDIAN */ 75 => 'lydi', + /* SCRIPT_CHAM */ 76 => 'cham', + /* SCRIPT_TAI_THAM */ 77 => 'lana', + /* SCRIPT_TAI_VIET */ 78 => 'tavt', + /* SCRIPT_AVESTAN */ 79 => 'avst', + /* SCRIPT_EGYPTIAN_HIEROGLYPHS */ 80 => 'egyp', + /* SCRIPT_SAMARITAN */ 81 => 'samr', + /* SCRIPT_LISU */ 82 => 'lisu', + /* SCRIPT_BAMUM */ 83 => 'bamu', + /* SCRIPT_JAVANESE */ 84 => 'java', + /* SCRIPT_MEETEI_MAYEK */ 85 => 'mtei', + /* SCRIPT_IMPERIAL_ARAMAIC */ 86 => 'armi', + /* SCRIPT_OLD_SOUTH_ARABIAN */ 87 => 'sarb', + /* SCRIPT_INSCRIPTIONAL_PARTHIAN */ 88 => 'prti', + /* SCRIPT_INSCRIPTIONAL_PAHLAVI */ 89 => 'phli', + /* SCRIPT_OLD_TURKIC */ 90 => 'orkh', + /* SCRIPT_KAITHI */ 91 => 'kthi', + /* SCRIPT_BATAK */ 92 => 'batk', + /* SCRIPT_BRAHMI */ 93 => 'brah', + /* SCRIPT_MANDAIC */ 94 => 'mand', + /* SCRIPT_CHAKMA */ 95 => 'cakm', + /* SCRIPT_MEROITIC_CURSIVE */ 96 => 'merc', + /* SCRIPT_MEROITIC_HIEROGLYPHS */ 97 => 'mero', + /* SCRIPT_MIAO */ 98 => 'plrd', + /* SCRIPT_SHARADA */ 99 => 'shrd', + /* SCRIPT_SORA_SOMPENG */ 100 => 'sora', + /* SCRIPT_TAKRI */ 101 => 'takr', + /* SCRIPT_UNKNOWN */ 102 => '', + ]; + + public static $ot_languages = [ + 'aa' => 'AFR ', /* Afar */ + 'ab' => 'ABK ', /* Abkhazian */ + 'abq' => 'ABA ', /* Abaza */ + 'ada' => 'DNG ', /* Dangme */ + 'ady' => 'ADY ', /* Adyghe */ + 'af' => 'AFK ', /* Afrikaans */ + 'aii' => 'SWA ', /* Swadaya Aramaic */ + 'aiw' => 'ARI ', /* Aari */ + 'alt' => 'ALT ', /* [Southern] Altai */ + 'am' => 'AMH ', /* Amharic */ + 'amf' => 'HBN ', /* Hammer-Banna */ + 'ar' => 'ARA ', /* Arabic */ + 'arn' => 'MAP ', /* Mapudungun */ + 'as' => 'ASM ', /* Assamese */ + 'ath' => 'ATH ', /* Athapaskan [family] */ + 'atv' => 'ALT ', /* [Northern] Altai */ + 'av' => 'AVR ', /* Avaric */ + 'awa' => 'AWA ', /* Awadhi */ + 'ay' => 'AYM ', /* Aymara */ + 'az' => 'AZE ', /* Azerbaijani */ + 'ba' => 'BSH ', /* Bashkir */ + 'bai' => 'BML ', /* Bamileke [family] */ + 'bal' => 'BLI ', /* Baluchi */ + 'bci' => 'BAU ', /* Baule */ + 'bcq' => 'BCH ', /* Bench */ + 'be' => 'BEL ', /* Belarussian */ + 'bem' => 'BEM ', /* Bemba (Zambia) */ + 'ber' => 'BER ', /* Berber [family] */ + 'bfq' => 'BAD ', /* Badaga */ + 'bft' => 'BLT ', /* Balti */ + 'bfy' => 'BAG ', /* Baghelkhandi */ + 'bg' => 'BGR ', /* Bulgarian */ + 'bhb' => 'BHI ', /* Bhili */ + 'bho' => 'BHO ', /* Bhojpuri */ + 'bik' => 'BIK ', /* Bikol */ + 'bin' => 'EDO ', /* Bini */ + 'bjt' => 'BLN ', /* Balanta-Ganja */ + 'bla' => 'BKF ', /* Blackfoot */ + 'ble' => 'BLN ', /* Balanta-Kentohe */ + 'bm' => 'BMB ', /* Bambara */ + 'bn' => 'BEN ', /* Bengali */ + 'bo' => 'TIB ', /* Tibetan */ + 'br' => 'BRE ', /* Breton */ + 'bra' => 'BRI ', /* Braj Bhasha */ + 'brh' => 'BRH ', /* Brahui */ + 'bs' => 'BOS ', /* Bosnian */ + 'btb' => 'BTI ', /* Beti (Cameroon) */ + 'bxr' => 'RBU ', /* Russian Buriat */ + 'byn' => 'BIL ', /* Bilen */ + 'ca' => 'CAT ', /* Catalan */ + 'ce' => 'CHE ', /* Chechen */ + 'ceb' => 'CEB ', /* Cebuano */ + 'chp' => 'CHP ', /* Chipewyan */ + 'chr' => 'CHR ', /* Cherokee */ + 'ckt' => 'CHK ', /* Chukchi */ + 'cop' => 'COP ', /* Coptic */ + 'cr' => 'CRE ', /* Cree */ + 'crh' => 'CRT ', /* Crimean Tatar */ + 'crj' => 'ECR ', /* [Southern] East Cree */ + 'crl' => 'ECR ', /* [Northern] East Cree */ + 'crm' => 'MCR ', /* Moose Cree */ + 'crx' => 'CRR ', /* Carrier */ + 'cs' => 'CSY ', /* Czech */ + 'cu' => 'CSL ', /* Church Slavic */ + 'cv' => 'CHU ', /* Chuvash */ + 'cwd' => 'DCR ', /* Woods Cree */ + 'cy' => 'WEL ', /* Welsh */ + 'da' => 'DAN ', /* Danish */ + 'dap' => 'NIS ', /* Nisi (India) */ + 'dar' => 'DAR ', /* Dargwa */ + 'de' => 'DEU ', /* German */ + 'din' => 'DNK ', /* Dinka */ + 'dje' => 'DJR ', /* Djerma */ + 'dng' => 'DUN ', /* Dungan */ + 'doi' => 'DGR ', /* Dogri */ + 'dsb' => 'LSB ', /* Lower Sorbian */ + 'dv' => 'DIV ', /* Dhivehi */ + 'dyu' => 'JUL ', /* Jula */ + 'dz' => 'DZN ', /* Dzongkha */ + 'ee' => 'EWE ', /* Ewe */ + 'efi' => 'EFI ', /* Efik */ + 'el' => 'ELL ', /* Modern Greek (1453-) */ + 'grc' => 'PGR ', /* Polytonic Greek */ + 'en' => 'ENG ', /* English */ + 'eo' => 'NTO ', /* Esperanto */ + 'eot' => 'BTI ', /* Beti (Côte d'Ivoire) */ + 'es' => 'ESP ', /* Spanish */ + 'et' => 'ETI ', /* Estonian */ + 'eu' => 'EUQ ', /* Basque */ + 'eve' => 'EVN ', /* Even */ + 'evn' => 'EVK ', /* Evenki */ + 'fa' => 'FAR ', /* Persian */ + 'ff' => 'FUL ', /* Fulah */ + 'fi' => 'FIN ', /* Finnish */ + 'fil' => 'PIL ', /* Filipino */ + 'fj' => 'FJI ', /* Fijian */ + 'fo' => 'FOS ', /* Faroese */ + 'fon' => 'FON ', /* Fon */ + 'fr' => 'FRA ', /* French */ + 'fur' => 'FRL ', /* Friulian */ + 'fy' => 'FRI ', /* Western Frisian */ + 'ga' => 'IRI ', /* Irish */ + 'gaa' => 'GAD ', /* Ga */ + 'gag' => 'GAG ', /* Gagauz */ + 'gbm' => 'GAW ', /* Garhwali */ + 'gd' => 'GAE ', /* Scottish Gaelic */ + 'gez' => 'GEZ ', /* Ge'ez */ + 'gl' => 'GAL ', /* Galician */ + 'gld' => 'NAN ', /* Nanai */ + 'gn' => 'GUA ', /* Guarani */ + 'gon' => 'GON ', /* Gondi */ + 'grt' => 'GRO ', /* Garo */ + 'gru' => 'SOG ', /* Sodo Gurage */ + 'gu' => 'GUJ ', /* Gujarati */ + 'guk' => 'GMZ ', /* Gumuz */ + 'gv' => 'MNX ', /* Manx Gaelic */ + 'ha' => 'HAU ', /* Hausa */ + 'har' => 'HRI ', /* Harari */ + 'haw' => 'HAW ', /* Hawaiin */ + 'he' => 'IWR ', /* Hebrew */ + 'hi' => 'HIN ', /* Hindi */ + 'hil' => 'HIL ', /* Hiligaynon */ + 'hnd' => 'HND ', /* [Southern] Hindko */ + 'hne' => 'CHH ', /* Chattisgarhi */ + 'hno' => 'HND ', /* [Northern] Hindko */ + 'hoc' => 'HO ', /* Ho */ + 'hoj' => 'HAR ', /* Harauti */ + 'hr' => 'HRV ', /* Croatian */ + 'hsb' => 'USB ', /* Upper Sorbian */ + 'ht' => 'HAI ', /* Haitian */ + 'hu' => 'HUN ', /* Hungarian */ + 'hy' => 'HYE ', /* Armenian */ + 'id' => 'IND ', /* Indonesian */ + 'ig' => 'IBO ', /* Igbo */ + 'igb' => 'EBI ', /* Ebira */ + 'ijo' => 'IJO ', /* Ijo [family] */ + 'ilo' => 'ILO ', /* Ilokano */ + 'inh' => 'ING ', /* Ingush */ + 'is' => 'ISL ', /* Icelandic */ + 'it' => 'ITA ', /* Italian */ + 'iu' => 'INU ', /* Inuktitut */ + 'ja' => 'JAN ', /* Japanese */ + 'jv' => 'JAV ', /* Javanese */ + 'ka' => 'KAT ', /* Georgian */ + 'kaa' => 'KRK ', /* Karakalpak */ + 'kam' => 'KMB ', /* Kamba (Kenya) */ + 'kar' => 'KRN ', /* Karen [family] */ + 'kbd' => 'KAB ', /* Kabardian */ + 'kdr' => 'KRM ', /* Karaim */ + 'kdt' => 'KUY ', /* Kuy */ + 'kex' => 'KKN ', /* Kokni */ + 'kfr' => 'KAC ', /* Kachchi */ + 'kfy' => 'KMN ', /* Kumaoni */ + 'kha' => 'KSI ', /* Khasi */ + 'khb' => 'XBD ', /* Tai Lue */ + 'khw' => 'KHW ', /* Khowar */ + 'ki' => 'KIK ', /* Kikuyu */ + 'kjh' => 'KHA ', /* Khakass */ + 'kk' => 'KAZ ', /* Kazakh */ + 'kl' => 'GRN ', /* Kalaallisut */ + 'kln' => 'KAL ', /* Kalenjin */ + 'km' => 'KHM ', /* Central Khmer */ + 'kmb' => 'MBN ', /* [North] Mbundu */ + 'kmw' => 'KMO ', /* Komo (Democratic Republic of Congo) */ + 'kn' => 'KAN ', /* Kannada */ + 'ko' => 'KOR ', /* Korean */ + 'koi' => 'KOP ', /* Komi-Permyak */ + 'kok' => 'KOK ', /* Konkani */ + 'kpe' => 'KPL ', /* Kpelle */ + 'kpv' => 'KOZ ', /* Komi-Zyrian */ + 'kpy' => 'KYK ', /* Koryak */ + 'kqy' => 'KRT ', /* Koorete */ + 'kr' => 'KNR ', /* Kanuri */ + 'kri' => 'KRI ', /* Krio */ + 'krl' => 'KRL ', /* Karelian */ + 'kru' => 'KUU ', /* Kurukh */ + 'ks' => 'KSH ', /* Kashmiri */ + 'ku' => 'KUR ', /* Kurdish */ + 'kum' => 'KUM ', /* Kumyk */ + 'kvd' => 'KUI ', /* Kui (Indonesia) */ + 'kxc' => 'KMS ', /* Komso */ + 'kxu' => 'KUI ', /* Kui (India) */ + 'ky' => 'KIR ', /* Kirghiz */ + 'la' => 'LAT ', /* Latin */ + 'lad' => 'JUD ', /* Ladino */ + 'lb' => 'LTZ ', /* Luxembourgish */ + 'lbe' => 'LAK ', /* Lak */ + 'lbj' => 'LDK ', /* Ladakhi */ + 'lez' => 'LEZ ', /* Lezgi */ + 'lg' => 'LUG ', /* Luganda */ + 'lif' => 'LMB ', /* Limbu */ + 'lld' => 'LAD ', /* Ladin */ + 'lmn' => 'LAM ', /* Lambani */ + 'ln' => 'LIN ', /* Lingala */ + 'lo' => 'LAO ', /* Lao */ + 'lt' => 'LTH ', /* Lithuanian */ + 'lu' => 'LUB ', /* Luba-Katanga */ + 'lua' => 'LUB ', /* Luba-Kasai */ + 'luo' => 'LUO ', /* Luo (Kenya and Tanzania) */ + 'lus' => 'MIZ ', /* Mizo */ + 'luy' => 'LUH ', /* Luhya [macrolanguage] */ + 'lv' => 'LVI ', /* Latvian */ + 'lzz' => 'LAZ ', /* Laz */ + 'mai' => 'MTH ', /* Maithili */ + 'mdc' => 'MLE ', /* Male (Papua New Guinea) */ + 'mdf' => 'MOK ', /* Moksha */ + 'mdy' => 'MLE ', /* Male (Ethiopia) */ + 'men' => 'MDE ', /* Mende (Sierra Leone) */ + 'mg' => 'MLG ', /* Malagasy */ + 'mhr' => 'LMA ', /* Low Mari */ + 'mi' => 'MRI ', /* Maori */ + 'mk' => 'MKD ', /* Macedonian */ + 'ml' => 'MLR ', /* Malayalam reformed (MAL is Malayalam Traditional) */ + 'mn' => 'MNG ', /* Mongolian */ + 'mnc' => 'MCH ', /* Manchu */ + 'mni' => 'MNI ', /* Manipuri */ + 'mnk' => 'MND ', /* Mandinka */ + 'mns' => 'MAN ', /* Mansi */ + 'mnw' => 'MON ', /* Mon */ + 'mo' => 'MOL ', /* Moldavian */ + 'moh' => 'MOH ', /* Mohawk */ + 'mpe' => 'MAJ ', /* Majang */ + 'mr' => 'MAR ', /* Marathi */ + 'mrj' => 'HMA ', /* High Mari */ + 'ms' => 'MLY ', /* Malay */ + 'mt' => 'MTS ', /* Maltese */ + 'mwr' => 'MAW ', /* Marwari */ + 'my' => 'BRM ', /* Burmese */ + 'mym' => 'MEN ', /* Me'en */ + 'myv' => 'ERZ ', /* Erzya */ + 'nag' => 'NAG ', /* Naga-Assamese */ + 'nb' => 'NOR ', /* Norwegian Bokmål */ + 'nco' => 'SIB ', /* Sibe */ + 'nd' => 'NDB ', /* [North] Ndebele */ + 'ne' => 'NEP ', /* Nepali */ + 'new' => 'NEW ', /* Newari */ + 'ng' => 'NDG ', /* Ndonga */ + 'ngl' => 'LMW ', /* Lomwe */ + 'niu' => 'NIU ', /* Niuean */ + 'niv' => 'GIL ', /* Gilyak */ + 'nl' => 'NLD ', /* Dutch */ + 'nn' => 'NYN ', /* Norwegian Nynorsk */ + 'no' => 'NOR ', /* Norwegian (deprecated) */ + 'nod' => 'NTA ', /* Northern Tai */ + 'nog' => 'NOG ', /* Nogai */ + 'nqo' => 'NKO ', /* N'Ko */ + 'nr' => 'NDB ', /* [South] Ndebele */ + 'nsk' => 'NAS ', /* Naskapi */ + 'nso' => 'SOT ', /* [Northern] Sotho */ + 'ny' => 'CHI ', /* Nyanja */ + 'nyn' => 'NKL ', /* Nkole */ + 'oc' => 'OCI ', /* Occitan (post 1500) */ + 'oj' => 'OJB ', /* Ojibwa */ + 'ojs' => 'OCR ', /* Oji-Cree */ + 'om' => 'ORO ', /* Oromo */ + 'or' => 'ORI ', /* Oriya */ + 'os' => 'OSS ', /* Ossetian */ + 'pa' => 'PAN ', /* Panjabi */ + 'pce' => 'PLG ', /* [Ruching] Palaung */ + 'pi' => 'PAL ', /* Pali */ + 'pl' => 'PLK ', /* Polish */ + 'pll' => 'PLG ', /* [Shwe] Palaung */ + 'plp' => 'PAP ', /* Palpa */ + 'prs' => 'DRI ', /* Dari */ + 'ps' => 'PAS ', /* Pushto */ + 'pt' => 'PTG ', /* Portuguese */ + 'raj' => 'RAJ ', /* Rajasthani */ + 'rbb' => 'PLG ', /* [Rumai] Palaung */ + 'ria' => 'RIA ', /* Riang (India) */ + 'ril' => 'RIA ', /* Riang (Myanmar) */ + 'rki' => 'ARK ', /* Arakanese */ + 'rm' => 'RMS ', /* Rhaeto-Romanic */ + 'ro' => 'ROM ', /* Romanian */ + 'rom' => 'ROY ', /* Romany */ + 'ru' => 'RUS ', /* Russian */ + 'rue' => 'RSY ', /* Rusyn */ + 'rw' => 'RUA ', /* Ruanda */ + 'sa' => 'SAN ', /* Sanskrit */ + 'sah' => 'YAK ', /* Yakut */ + 'sat' => 'SAT ', /* Santali */ + 'sck' => 'SAD ', /* Sadri */ + 'scs' => 'SLA ', /* [North] Slavey */ + 'sd' => 'SND ', /* Sindhi */ + 'se' => 'NSM ', /* Northern Sami */ + 'seh' => 'SNA ', /* Sena */ + 'sel' => 'SEL ', /* Selkup */ + 'sg' => 'SGO ', /* Sango */ + 'shn' => 'SHN ', /* Shan */ + 'si' => 'SNH ', /* Sinhala */ + 'sid' => 'SID ', /* Sidamo */ + 'sjd' => 'KSM ', /* Kildin Sami */ + 'sk' => 'SKY ', /* Slovak */ + 'skr' => 'SRK ', /* Seraiki */ + 'sl' => 'SLV ', /* Slovenian */ + 'sm' => 'SMO ', /* Samoan */ + 'sma' => 'SSM ', /* Southern Sami */ + 'smj' => 'LSM ', /* Lule Sami */ + 'smn' => 'ISM ', /* Inari Sami */ + 'sms' => 'SKS ', /* Skolt Sami */ + 'snk' => 'SNK ', /* Soninke */ + 'so' => 'SML ', /* Somali */ + 'sq' => 'SQI ', /* Albanian */ + 'sr' => 'SRB ', /* Serbian */ + 'srr' => 'SRR ', /* Serer */ + 'ss' => 'SWZ ', /* Swazi */ + 'st' => 'SOT ', /* [Southern] Sotho */ + 'suq' => 'SUR ', /* Suri */ + 'sv' => 'SVE ', /* Swedish */ + 'sva' => 'SVA ', /* Svan */ + 'sw' => 'SWK ', /* Swahili */ + 'swb' => 'CMR ', /* Comorian */ + 'syr' => 'SYR ', /* Syriac */ + 'ta' => 'TAM ', /* Tamil */ + 'tab' => 'TAB ', /* Tabasaran */ + 'tcy' => 'TUL ', /* Tulu */ + 'te' => 'TEL ', /* Telugu */ + 'tem' => 'TMN ', /* Temne */ + 'tg' => 'TAJ ', /* Tajik */ + 'th' => 'THA ', /* Thai */ + 'ti' => 'TGY ', /* Tigrinya */ + 'tig' => 'TGR ', /* Tigre */ + 'tk' => 'TKM ', /* Turkmen */ + 'tn' => 'TNA ', /* Tswana */ + 'to' => 'TGN ', /* Tonga (Tonga Islands) */ + 'tr' => 'TRK ', /* Turkish */ + 'tru' => 'TUA ', /* Turoyo Aramaic */ + 'ts' => 'TSG ', /* Tsonga */ + 'tt' => 'TAT ', /* Tatar */ + 'tw' => 'TWI ', /* Twi */ + 'ty' => 'THT ', /* Tahitian */ + 'tyv' => 'TUV ', /* Tuvin */ + 'udm' => 'UDM ', /* Udmurt */ + 'ug' => 'UYG ', /* Uighur */ + 'uk' => 'UKR ', /* Ukrainian */ + 'umb' => 'MBN ', /* [South] Mbundu */ + 'unr' => 'MUN ', /* Mundari */ + 'ur' => 'URD ', /* Urdu */ + 'uz' => 'UZB ', /* Uzbek */ + 've' => 'VEN ', /* Venda */ + 'vi' => 'VIT ', /* Vietnamese */ + 'vmw' => 'MAK ', /* Makua */ + 'wbm' => 'WA ', /* Wa */ + 'wbr' => 'WAG ', /* Wagdi */ + 'wo' => 'WLF ', /* Wolof */ + 'xal' => 'KLM ', /* Kalmyk */ + 'xh' => 'XHS ', /* Xhosa */ + 'xom' => 'KMO ', /* Komo (Sudan) */ + 'xsl' => 'SSL ', /* South Slavey */ + 'yi' => 'JII ', /* Yiddish */ + 'yid' => 'JII ', /* Yiddish */ + 'yo' => 'YBA ', /* Yoruba */ + 'yso' => 'NIS ', /* Nisi (China) */ + 'zne' => 'ZND ', /* Zande */ + 'zu' => 'ZUL ', /* Zulu */ + 'zh-cn' => 'ZHS ', /* Chinese (China) */ + 'zh-hk' => 'ZHH ', /* Chinese (Hong Kong) */ + 'zh-mo' => 'ZHT ', /* Chinese (Macao) */ + 'zh-sg' => 'ZHS ', /* Chinese (Singapore) */ + 'zh-tw' => 'ZHT ', /* Chinese (Taiwan) */ + ]; + + // hb-unicode.h + const UNICODE_GENERAL_CATEGORY_CONTROL = 0; /* Cc */ + const UNICODE_GENERAL_CATEGORY_FORMAT = 1; /* Cf */ + const UNICODE_GENERAL_CATEGORY_UNASSIGNED = 2; /* Cn */ + const UNICODE_GENERAL_CATEGORY_PRIVATE_USE = 3; /* Co */ + const UNICODE_GENERAL_CATEGORY_SURROGATE = 4; /* Cs */ + const UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER = 5; /* Ll */ + const UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER = 6; /* Lm */ + const UNICODE_GENERAL_CATEGORY_OTHER_LETTER = 7; /* Lo */ + const UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER = 8; /* Lt */ + const UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER = 9; /* Lu */ + const UNICODE_GENERAL_CATEGORY_SPACING_MARK = 10; /* Mc */ + const UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK = 11; /* Me */ + const UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK = 12; /* Mn */ + const UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER = 13; /* Nd */ + const UNICODE_GENERAL_CATEGORY_LETTER_NUMBER = 14; /* Nl */ + const UNICODE_GENERAL_CATEGORY_OTHER_NUMBER = 15; /* No */ + const UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION = 16; /* Pc */ + const UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION = 17; /* Pd */ + const UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION = 18; /* Pe */ + const UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION = 19; /* Pf */ + const UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION = 20; /* Pi */ + const UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION = 21; /* Po */ + const UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION = 22; /* Ps */ + const UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL = 23; /* Sc */ + const UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL = 24; /* Sk */ + const UNICODE_GENERAL_CATEGORY_MATH_SYMBOL = 25; /* Sm */ + const UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL = 26; /* So */ + const UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR = 27; /* Zl */ + const UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR = 28; /* Zp */ + const UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR = 29; /* Zs */ + + function general_category_is_mark($gen_cat) + { + return $gen_cat == self::UNICODE_GENERAL_CATEGORY_SPACING_MARK || $gen_cat == self::UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK || + $gen_cat == self::UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK; + // define UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) + //if (FLAG(gen_cat) & (FLAG(UNICODE_GENERAL_CATEGORY_SPACING_MARK) | FLAG(UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) { return true; } + } + + const BIDI_CLASS_L = 0; + const BIDI_CLASS_LRE = 1; + const BIDI_CLASS_LRO = 2; + const BIDI_CLASS_R = 3; + const BIDI_CLASS_AL = 4; + const BIDI_CLASS_RLE = 5; + const BIDI_CLASS_RLO = 6; + const BIDI_CLASS_PDF = 7; + const BIDI_CLASS_EN = 8; + const BIDI_CLASS_ES = 9; + const BIDI_CLASS_ET = 10; + const BIDI_CLASS_AN = 11; + const BIDI_CLASS_CS = 12; + const BIDI_CLASS_NSM = 13; + const BIDI_CLASS_BN = 14; + const BIDI_CLASS_B = 15; + const BIDI_CLASS_S = 16; + const BIDI_CLASS_WS = 17; + const BIDI_CLASS_ON = 18; + + // UNIDATA_VERSION 6.2.0 + /* a list of unique database records */ + /* struct { + category; + combining; + bidi_class; + mirrored; + east_asian_width; + normalization_check; + script; + } + */ + private static $ucd_records = [ + [2, 0, 18, 0, 5, 0, 102], + [0, 0, 14, 0, 5, 0, 0], + [0, 0, 16, 0, 5, 0, 0], + [0, 0, 15, 0, 5, 0, 0], + [0, 0, 17, 0, 5, 0, 0], + [29, 0, 17, 0, 3, 0, 0], + [21, 0, 18, 0, 3, 0, 0], + [21, 0, 10, 0, 3, 0, 0], + [23, 0, 10, 0, 3, 0, 0], + [22, 0, 18, 1, 3, 0, 0], + [18, 0, 18, 1, 3, 0, 0], + [25, 0, 9, 0, 3, 0, 0], + [21, 0, 12, 0, 3, 0, 0], + [17, 0, 9, 0, 3, 0, 0], + [13, 0, 8, 0, 3, 0, 0], + [25, 0, 18, 1, 3, 0, 0], + [25, 0, 18, 0, 3, 0, 0], + [9, 0, 0, 0, 3, 0, 1], + [24, 0, 18, 0, 3, 0, 0], + [16, 0, 18, 0, 3, 0, 0], + [5, 0, 0, 0, 3, 0, 1], + [29, 0, 12, 0, 5, 0, 0], + [21, 0, 18, 0, 4, 0, 0], + [23, 0, 10, 0, 4, 0, 0], + [26, 0, 18, 0, 3, 0, 0], + [24, 0, 18, 0, 4, 0, 0], + [26, 0, 18, 0, 5, 0, 0], + [7, 0, 0, 0, 4, 0, 1], + [20, 0, 18, 1, 5, 0, 0], + [1, 0, 14, 0, 4, 0, 0], + [26, 0, 18, 0, 4, 0, 0], + [26, 0, 10, 0, 4, 0, 0], + [25, 0, 10, 0, 4, 0, 0], + [15, 0, 8, 0, 4, 0, 0], + [5, 0, 0, 0, 5, 0, 0], + [19, 0, 18, 1, 5, 0, 0], + [15, 0, 18, 0, 4, 0, 0], + [9, 0, 0, 0, 5, 0, 1], + [9, 0, 0, 0, 4, 0, 1], + [25, 0, 18, 0, 4, 0, 0], + [5, 0, 0, 0, 4, 0, 1], + [5, 0, 0, 0, 5, 0, 1], + [7, 0, 0, 0, 5, 0, 1], + [8, 0, 0, 0, 5, 0, 1], + [6, 0, 0, 0, 5, 0, 1], + [6, 0, 18, 0, 5, 0, 0], + [6, 0, 0, 0, 5, 0, 0], + [24, 0, 18, 0, 5, 0, 0], + [6, 0, 18, 0, 4, 0, 0], + [6, 0, 0, 0, 4, 0, 0], + [24, 0, 18, 0, 5, 0, 34], + [12, 230, 13, 0, 4, 0, 40], + [12, 232, 13, 0, 4, 0, 40], + [12, 220, 13, 0, 4, 0, 40], + [12, 216, 13, 0, 4, 0, 40], + [12, 202, 13, 0, 4, 0, 40], + [12, 1, 13, 0, 4, 0, 40], + [12, 240, 13, 0, 4, 0, 40], + [12, 0, 13, 0, 4, 0, 40], + [12, 233, 13, 0, 4, 0, 40], + [12, 234, 13, 0, 4, 0, 40], + [9, 0, 0, 0, 5, 0, 2], + [5, 0, 0, 0, 5, 0, 2], + [24, 0, 18, 0, 5, 0, 2], + [2, 0, 18, 0, 5, 0, 102], + [6, 0, 0, 0, 5, 0, 2], + [21, 0, 18, 0, 5, 0, 0], + [9, 0, 0, 0, 4, 0, 2], + [5, 0, 0, 0, 4, 0, 2], + [9, 0, 0, 0, 5, 0, 54], + [5, 0, 0, 0, 5, 0, 54], + [25, 0, 18, 0, 5, 0, 2], + [9, 0, 0, 0, 5, 0, 3], + [9, 0, 0, 0, 4, 0, 3], + [5, 0, 0, 0, 4, 0, 3], + [5, 0, 0, 0, 5, 0, 3], + [26, 0, 0, 0, 5, 0, 3], + [12, 230, 13, 0, 5, 0, 3], + [12, 230, 13, 0, 5, 0, 40], + [11, 0, 13, 0, 5, 0, 3], + [9, 0, 0, 0, 5, 0, 4], + [6, 0, 0, 0, 5, 0, 4], + [21, 0, 0, 0, 5, 0, 4], + [5, 0, 0, 0, 5, 0, 4], + [21, 0, 0, 0, 5, 0, 0], + [17, 0, 18, 0, 5, 0, 4], + [23, 0, 10, 0, 5, 0, 4], + [12, 220, 13, 0, 5, 0, 5], + [12, 230, 13, 0, 5, 0, 5], + [12, 222, 13, 0, 5, 0, 5], + [12, 228, 13, 0, 5, 0, 5], + [12, 10, 13, 0, 5, 0, 5], + [12, 11, 13, 0, 5, 0, 5], + [12, 12, 13, 0, 5, 0, 5], + [12, 13, 13, 0, 5, 0, 5], + [12, 14, 13, 0, 5, 0, 5], + [12, 15, 13, 0, 5, 0, 5], + [12, 16, 13, 0, 5, 0, 5], + [12, 17, 13, 0, 5, 0, 5], + [12, 18, 13, 0, 5, 0, 5], + [12, 19, 13, 0, 5, 0, 5], + [12, 20, 13, 0, 5, 0, 5], + [12, 21, 13, 0, 5, 0, 5], + [12, 22, 13, 0, 5, 0, 5], + [17, 0, 3, 0, 5, 0, 5], + [12, 23, 13, 0, 5, 0, 5], + [21, 0, 3, 0, 5, 0, 5], + [12, 24, 13, 0, 5, 0, 5], + [12, 25, 13, 0, 5, 0, 5], + [7, 0, 3, 0, 5, 0, 5], + [1, 0, 11, 0, 5, 0, 6], + [25, 0, 18, 0, 5, 0, 6], + [25, 0, 4, 0, 5, 0, 6], + [21, 0, 10, 0, 5, 0, 6], + [23, 0, 4, 0, 5, 0, 6], + [21, 0, 12, 0, 5, 0, 0], + [21, 0, 4, 0, 5, 0, 6], + [26, 0, 18, 0, 5, 0, 6], + [12, 230, 13, 0, 5, 0, 6], + [12, 30, 13, 0, 5, 0, 6], + [12, 31, 13, 0, 5, 0, 6], + [12, 32, 13, 0, 5, 0, 6], + [21, 0, 4, 0, 5, 0, 0], + [7, 0, 4, 0, 5, 0, 6], + [6, 0, 4, 0, 5, 0, 0], + [12, 27, 13, 0, 5, 0, 40], + [12, 28, 13, 0, 5, 0, 40], + [12, 29, 13, 0, 5, 0, 40], + [12, 30, 13, 0, 5, 0, 40], + [12, 31, 13, 0, 5, 0, 40], + [12, 32, 13, 0, 5, 0, 40], + [12, 33, 13, 0, 5, 0, 40], + [12, 34, 13, 0, 5, 0, 40], + [12, 220, 13, 0, 5, 0, 40], + [12, 220, 13, 0, 5, 0, 6], + [13, 0, 11, 0, 5, 0, 0], + [21, 0, 11, 0, 5, 0, 6], + [12, 35, 13, 0, 5, 0, 40], + [1, 0, 11, 0, 5, 0, 0], + [6, 0, 4, 0, 5, 0, 6], + [13, 0, 8, 0, 5, 0, 6], + [26, 0, 4, 0, 5, 0, 6], + [21, 0, 4, 0, 5, 0, 7], + [1, 0, 4, 0, 5, 0, 7], + [7, 0, 4, 0, 5, 0, 7], + [12, 36, 13, 0, 5, 0, 7], + [12, 230, 13, 0, 5, 0, 7], + [12, 220, 13, 0, 5, 0, 7], + [7, 0, 4, 0, 5, 0, 8], + [12, 0, 13, 0, 5, 0, 8], + [13, 0, 3, 0, 5, 0, 65], + [7, 0, 3, 0, 5, 0, 65], + [12, 230, 13, 0, 5, 0, 65], + [12, 220, 13, 0, 5, 0, 65], + [6, 0, 3, 0, 5, 0, 65], + [26, 0, 18, 0, 5, 0, 65], + [21, 0, 18, 0, 5, 0, 65], + [7, 0, 3, 0, 5, 0, 81], + [12, 230, 13, 0, 5, 0, 81], + [6, 0, 3, 0, 5, 0, 81], + [21, 0, 3, 0, 5, 0, 81], + [7, 0, 3, 0, 5, 0, 94], + [12, 220, 13, 0, 5, 0, 94], + [21, 0, 3, 0, 5, 0, 94], + [12, 27, 13, 0, 5, 0, 6], + [12, 28, 13, 0, 5, 0, 6], + [12, 29, 13, 0, 5, 0, 6], + [12, 0, 13, 0, 5, 0, 9], + [10, 0, 0, 0, 5, 0, 9], + [7, 0, 0, 0, 5, 0, 9], + [12, 7, 13, 0, 5, 0, 9], + [12, 9, 13, 0, 5, 0, 9], + [12, 230, 13, 0, 5, 0, 9], + [13, 0, 0, 0, 5, 0, 9], + [21, 0, 0, 0, 5, 0, 9], + [6, 0, 0, 0, 5, 0, 9], + [12, 0, 13, 0, 5, 0, 10], + [10, 0, 0, 0, 5, 0, 10], + [7, 0, 0, 0, 5, 0, 10], + [12, 7, 13, 0, 5, 0, 10], + [12, 9, 13, 0, 5, 0, 10], + [13, 0, 0, 0, 5, 0, 10], + [23, 0, 10, 0, 5, 0, 10], + [15, 0, 0, 0, 5, 0, 10], + [26, 0, 0, 0, 5, 0, 10], + [12, 0, 13, 0, 5, 0, 11], + [10, 0, 0, 0, 5, 0, 11], + [7, 0, 0, 0, 5, 0, 11], + [12, 7, 13, 0, 5, 0, 11], + [12, 9, 13, 0, 5, 0, 11], + [13, 0, 0, 0, 5, 0, 11], + [12, 0, 13, 0, 5, 0, 12], + [10, 0, 0, 0, 5, 0, 12], + [7, 0, 0, 0, 5, 0, 12], + [12, 7, 13, 0, 5, 0, 12], + [12, 9, 13, 0, 5, 0, 12], + [13, 0, 0, 0, 5, 0, 12], + [21, 0, 0, 0, 5, 0, 12], + [23, 0, 10, 0, 5, 0, 12], + [12, 0, 13, 0, 5, 0, 13], + [10, 0, 0, 0, 5, 0, 13], + [7, 0, 0, 0, 5, 0, 13], + [12, 7, 13, 0, 5, 0, 13], + [12, 9, 13, 0, 5, 0, 13], + [13, 0, 0, 0, 5, 0, 13], + [26, 0, 0, 0, 5, 0, 13], + [15, 0, 0, 0, 5, 0, 13], + [12, 0, 13, 0, 5, 0, 14], + [7, 0, 0, 0, 5, 0, 14], + [10, 0, 0, 0, 5, 0, 14], + [12, 9, 13, 0, 5, 0, 14], + [13, 0, 0, 0, 5, 0, 14], + [15, 0, 0, 0, 5, 0, 14], + [26, 0, 18, 0, 5, 0, 14], + [23, 0, 10, 0, 5, 0, 14], + [10, 0, 0, 0, 5, 0, 15], + [7, 0, 0, 0, 5, 0, 15], + [12, 0, 13, 0, 5, 0, 15], + [12, 9, 13, 0, 5, 0, 15], + [12, 84, 13, 0, 5, 0, 15], + [12, 91, 13, 0, 5, 0, 15], + [13, 0, 0, 0, 5, 0, 15], + [15, 0, 18, 0, 5, 0, 15], + [26, 0, 0, 0, 5, 0, 15], + [10, 0, 0, 0, 5, 0, 16], + [7, 0, 0, 0, 5, 0, 16], + [12, 7, 13, 0, 5, 0, 16], + [12, 0, 0, 0, 5, 0, 16], + [12, 0, 13, 0, 5, 0, 16], + [12, 9, 13, 0, 5, 0, 16], + [13, 0, 0, 0, 5, 0, 16], + [10, 0, 0, 0, 5, 0, 17], + [7, 0, 0, 0, 5, 0, 17], + [12, 0, 13, 0, 5, 0, 17], + [12, 9, 13, 0, 5, 0, 17], + [13, 0, 0, 0, 5, 0, 17], + [15, 0, 0, 0, 5, 0, 17], + [26, 0, 0, 0, 5, 0, 17], + [10, 0, 0, 0, 5, 0, 18], + [7, 0, 0, 0, 5, 0, 18], + [12, 9, 13, 0, 5, 0, 18], + [12, 0, 13, 0, 5, 0, 18], + [21, 0, 0, 0, 5, 0, 18], + [7, 0, 0, 0, 5, 0, 19], + [12, 0, 13, 0, 5, 0, 19], + [12, 103, 13, 0, 5, 0, 19], + [12, 9, 13, 0, 5, 0, 19], + [23, 0, 10, 0, 5, 0, 0], + [6, 0, 0, 0, 5, 0, 19], + [12, 107, 13, 0, 5, 0, 19], + [21, 0, 0, 0, 5, 0, 19], + [13, 0, 0, 0, 5, 0, 19], + [7, 0, 0, 0, 5, 0, 20], + [12, 0, 13, 0, 5, 0, 20], + [12, 118, 13, 0, 5, 0, 20], + [6, 0, 0, 0, 5, 0, 20], + [12, 122, 13, 0, 5, 0, 20], + [13, 0, 0, 0, 5, 0, 20], + [7, 0, 0, 0, 5, 0, 21], + [26, 0, 0, 0, 5, 0, 21], + [21, 0, 0, 0, 5, 0, 21], + [12, 220, 13, 0, 5, 0, 21], + [13, 0, 0, 0, 5, 0, 21], + [15, 0, 0, 0, 5, 0, 21], + [12, 216, 13, 0, 5, 0, 21], + [22, 0, 18, 1, 5, 0, 21], + [18, 0, 18, 1, 5, 0, 21], + [10, 0, 0, 0, 5, 0, 21], + [12, 129, 13, 0, 5, 0, 21], + [12, 130, 13, 0, 5, 0, 21], + [12, 0, 13, 0, 5, 0, 21], + [12, 132, 13, 0, 5, 0, 21], + [12, 230, 13, 0, 5, 0, 21], + [12, 9, 13, 0, 5, 0, 21], + [26, 0, 0, 0, 5, 0, 0], + [7, 0, 0, 0, 5, 0, 22], + [10, 0, 0, 0, 5, 0, 22], + [12, 0, 13, 0, 5, 0, 22], + [12, 7, 13, 0, 5, 0, 22], + [12, 9, 13, 0, 5, 0, 22], + [13, 0, 0, 0, 5, 0, 22], + [21, 0, 0, 0, 5, 0, 22], + [12, 220, 13, 0, 5, 0, 22], + [26, 0, 0, 0, 5, 0, 22], + [9, 0, 0, 0, 5, 0, 23], + [7, 0, 0, 0, 5, 0, 23], + [6, 0, 0, 0, 5, 0, 23], + [7, 0, 0, 0, 2, 0, 24], + [7, 0, 0, 0, 5, 0, 24], + [7, 0, 0, 0, 5, 0, 25], + [12, 230, 13, 0, 5, 0, 25], + [21, 0, 0, 0, 5, 0, 25], + [15, 0, 0, 0, 5, 0, 25], + [26, 0, 18, 0, 5, 0, 25], + [7, 0, 0, 0, 5, 0, 26], + [17, 0, 18, 0, 5, 0, 27], + [7, 0, 0, 0, 5, 0, 27], + [21, 0, 0, 0, 5, 0, 27], + [29, 0, 17, 0, 5, 0, 28], + [7, 0, 0, 0, 5, 0, 28], + [22, 0, 18, 1, 5, 0, 28], + [18, 0, 18, 1, 5, 0, 28], + [7, 0, 0, 0, 5, 0, 29], + [14, 0, 0, 0, 5, 0, 29], + [7, 0, 0, 0, 5, 0, 41], + [12, 0, 13, 0, 5, 0, 41], + [12, 9, 13, 0, 5, 0, 41], + [7, 0, 0, 0, 5, 0, 42], + [12, 0, 13, 0, 5, 0, 42], + [12, 9, 13, 0, 5, 0, 42], + [7, 0, 0, 0, 5, 0, 43], + [12, 0, 13, 0, 5, 0, 43], + [7, 0, 0, 0, 5, 0, 44], + [12, 0, 13, 0, 5, 0, 44], + [7, 0, 0, 0, 5, 0, 30], + [12, 0, 13, 0, 5, 0, 30], + [10, 0, 0, 0, 5, 0, 30], + [12, 9, 13, 0, 5, 0, 30], + [21, 0, 0, 0, 5, 0, 30], + [6, 0, 0, 0, 5, 0, 30], + [23, 0, 10, 0, 5, 0, 30], + [12, 230, 13, 0, 5, 0, 30], + [13, 0, 0, 0, 5, 0, 30], + [15, 0, 18, 0, 5, 0, 30], + [21, 0, 18, 0, 5, 0, 31], + [17, 0, 18, 0, 5, 0, 31], + [12, 0, 13, 0, 5, 0, 31], + [29, 0, 17, 0, 5, 0, 31], + [13, 0, 0, 0, 5, 0, 31], + [7, 0, 0, 0, 5, 0, 31], + [6, 0, 0, 0, 5, 0, 31], + [12, 228, 13, 0, 5, 0, 31], + [7, 0, 0, 0, 5, 0, 45], + [12, 0, 13, 0, 5, 0, 45], + [10, 0, 0, 0, 5, 0, 45], + [12, 222, 13, 0, 5, 0, 45], + [12, 230, 13, 0, 5, 0, 45], + [12, 220, 13, 0, 5, 0, 45], + [26, 0, 18, 0, 5, 0, 45], + [21, 0, 18, 0, 5, 0, 45], + [13, 0, 0, 0, 5, 0, 45], + [7, 0, 0, 0, 5, 0, 46], + [7, 0, 0, 0, 5, 0, 55], + [10, 0, 0, 0, 5, 0, 55], + [13, 0, 0, 0, 5, 0, 55], + [15, 0, 0, 0, 5, 0, 55], + [26, 0, 18, 0, 5, 0, 55], + [26, 0, 18, 0, 5, 0, 30], + [7, 0, 0, 0, 5, 0, 53], + [12, 230, 13, 0, 5, 0, 53], + [12, 220, 13, 0, 5, 0, 53], + [10, 0, 0, 0, 5, 0, 53], + [21, 0, 0, 0, 5, 0, 53], + [7, 0, 0, 0, 5, 0, 77], + [10, 0, 0, 0, 5, 0, 77], + [12, 0, 13, 0, 5, 0, 77], + [12, 9, 13, 0, 5, 0, 77], + [12, 230, 13, 0, 5, 0, 77], + [12, 220, 13, 0, 5, 0, 77], + [13, 0, 0, 0, 5, 0, 77], + [21, 0, 0, 0, 5, 0, 77], + [6, 0, 0, 0, 5, 0, 77], + [12, 0, 13, 0, 5, 0, 61], + [10, 0, 0, 0, 5, 0, 61], + [7, 0, 0, 0, 5, 0, 61], + [12, 7, 13, 0, 5, 0, 61], + [10, 9, 0, 0, 5, 0, 61], + [13, 0, 0, 0, 5, 0, 61], + [21, 0, 0, 0, 5, 0, 61], + [26, 0, 0, 0, 5, 0, 61], + [12, 230, 13, 0, 5, 0, 61], + [12, 220, 13, 0, 5, 0, 61], + [12, 0, 13, 0, 5, 0, 66], + [10, 0, 0, 0, 5, 0, 66], + [7, 0, 0, 0, 5, 0, 66], + [10, 9, 0, 0, 5, 0, 66], + [12, 9, 13, 0, 5, 0, 66], + [13, 0, 0, 0, 5, 0, 66], + [7, 0, 0, 0, 5, 0, 92], + [12, 7, 13, 0, 5, 0, 92], + [10, 0, 0, 0, 5, 0, 92], + [12, 0, 13, 0, 5, 0, 92], + [10, 9, 0, 0, 5, 0, 92], + [21, 0, 0, 0, 5, 0, 92], + [7, 0, 0, 0, 5, 0, 67], + [10, 0, 0, 0, 5, 0, 67], + [12, 0, 13, 0, 5, 0, 67], + [12, 7, 13, 0, 5, 0, 67], + [21, 0, 0, 0, 5, 0, 67], + [13, 0, 0, 0, 5, 0, 67], + [13, 0, 0, 0, 5, 0, 68], + [7, 0, 0, 0, 5, 0, 68], + [6, 0, 0, 0, 5, 0, 68], + [21, 0, 0, 0, 5, 0, 68], + [21, 0, 0, 0, 5, 0, 66], + [12, 1, 13, 0, 5, 0, 40], + [10, 0, 0, 0, 5, 0, 0], + [7, 0, 0, 0, 5, 0, 0], + [6, 0, 0, 0, 5, 0, 3], + [12, 234, 13, 0, 5, 0, 40], + [12, 214, 13, 0, 5, 0, 40], + [12, 202, 13, 0, 5, 0, 40], + [12, 233, 13, 0, 5, 0, 40], + [8, 0, 0, 0, 5, 0, 2], + [29, 0, 17, 0, 5, 0, 0], + [1, 0, 14, 0, 5, 0, 0], + [1, 0, 14, 0, 5, 0, 40], + [1, 0, 0, 0, 5, 0, 0], + [1, 0, 3, 0, 5, 0, 0], + [17, 0, 18, 0, 4, 0, 0], + [17, 0, 18, 0, 5, 0, 0], + [20, 0, 18, 0, 4, 0, 0], + [19, 0, 18, 0, 4, 0, 0], + [22, 0, 18, 0, 5, 0, 0], + [20, 0, 18, 0, 5, 0, 0], + [27, 0, 17, 0, 5, 0, 0], + [28, 0, 15, 0, 5, 0, 0], + [1, 0, 1, 0, 5, 0, 0], + [1, 0, 5, 0, 5, 0, 0], + [1, 0, 7, 0, 5, 0, 0], + [1, 0, 2, 0, 5, 0, 0], + [1, 0, 6, 0, 5, 0, 0], + [21, 0, 10, 0, 4, 0, 0], + [21, 0, 10, 0, 5, 0, 0], + [16, 0, 18, 0, 5, 0, 0], + [25, 0, 12, 0, 5, 0, 0], + [22, 0, 18, 1, 5, 0, 0], + [18, 0, 18, 1, 5, 0, 0], + [25, 0, 18, 0, 5, 0, 0], + [15, 0, 8, 0, 5, 0, 0], + [25, 0, 9, 0, 5, 0, 0], + [6, 0, 0, 0, 4, 0, 1], + [23, 0, 10, 0, 1, 0, 0], + [11, 0, 13, 0, 5, 0, 40], + [9, 0, 0, 0, 5, 0, 0], + [5, 0, 0, 0, 4, 0, 0], + [26, 0, 10, 0, 5, 0, 0], + [25, 0, 18, 1, 5, 0, 0], + [15, 0, 18, 0, 5, 0, 0], + [14, 0, 0, 0, 4, 0, 1], + [14, 0, 0, 0, 5, 0, 1], + [25, 0, 18, 1, 4, 0, 0], + [25, 0, 10, 0, 5, 0, 0], + [22, 0, 18, 1, 2, 0, 0], + [18, 0, 18, 1, 2, 0, 0], + [26, 0, 0, 0, 4, 0, 0], + [26, 0, 0, 0, 5, 0, 52], + [9, 0, 0, 0, 5, 0, 56], + [5, 0, 0, 0, 5, 0, 56], + [26, 0, 18, 0, 5, 0, 54], + [12, 230, 13, 0, 5, 0, 54], + [21, 0, 18, 0, 5, 0, 54], + [15, 0, 18, 0, 5, 0, 54], + [5, 0, 0, 0, 5, 0, 23], + [7, 0, 0, 0, 5, 0, 57], + [6, 0, 0, 0, 5, 0, 57], + [21, 0, 0, 0, 5, 0, 57], + [12, 9, 13, 0, 5, 0, 57], + [26, 0, 18, 0, 2, 0, 35], + [26, 0, 18, 0, 2, 0, 0], + [29, 0, 17, 0, 0, 0, 0], + [21, 0, 18, 0, 2, 0, 0], + [6, 0, 0, 0, 2, 0, 35], + [7, 0, 0, 0, 2, 0, 0], + [14, 0, 0, 0, 2, 0, 35], + [17, 0, 18, 0, 2, 0, 0], + [22, 0, 18, 0, 2, 0, 0], + [18, 0, 18, 0, 2, 0, 0], + [12, 218, 13, 0, 2, 0, 40], + [12, 228, 13, 0, 2, 0, 40], + [12, 232, 13, 0, 2, 0, 40], + [12, 222, 13, 0, 2, 0, 40], + [10, 224, 0, 0, 2, 0, 24], + [6, 0, 0, 0, 2, 0, 0], + [7, 0, 0, 0, 2, 0, 32], + [12, 8, 13, 0, 2, 0, 40], + [24, 0, 18, 0, 2, 0, 0], + [6, 0, 0, 0, 2, 0, 32], + [7, 0, 0, 0, 2, 0, 33], + [6, 0, 0, 0, 2, 0, 33], + [7, 0, 0, 0, 2, 0, 34], + [26, 0, 0, 0, 2, 0, 0], + [15, 0, 0, 0, 2, 0, 0], + [26, 0, 0, 0, 2, 0, 24], + [26, 0, 18, 0, 2, 0, 24], + [15, 0, 0, 0, 4, 0, 0], + [15, 0, 18, 0, 2, 0, 0], + [26, 0, 0, 0, 2, 0, 33], + [7, 0, 0, 0, 2, 0, 35], + [2, 0, 18, 0, 2, 0, 35], + [2, 0, 18, 0, 2, 0, 102], + [7, 0, 0, 0, 2, 0, 36], + [6, 0, 0, 0, 2, 0, 36], + [26, 0, 18, 0, 2, 0, 36], + [7, 0, 0, 0, 5, 0, 82], + [6, 0, 0, 0, 5, 0, 82], + [21, 0, 0, 0, 5, 0, 82], + [7, 0, 0, 0, 5, 0, 69], + [6, 0, 0, 0, 5, 0, 69], + [21, 0, 18, 0, 5, 0, 69], + [13, 0, 0, 0, 5, 0, 69], + [7, 0, 0, 0, 5, 0, 3], + [21, 0, 18, 0, 5, 0, 3], + [6, 0, 18, 0, 5, 0, 3], + [7, 0, 0, 0, 5, 0, 83], + [14, 0, 0, 0, 5, 0, 83], + [12, 230, 13, 0, 5, 0, 83], + [21, 0, 0, 0, 5, 0, 83], + [24, 0, 0, 0, 5, 0, 0], + [7, 0, 0, 0, 5, 0, 58], + [12, 0, 13, 0, 5, 0, 58], + [12, 9, 13, 0, 5, 0, 58], + [10, 0, 0, 0, 5, 0, 58], + [26, 0, 18, 0, 5, 0, 58], + [15, 0, 0, 0, 5, 0, 0], + [7, 0, 0, 0, 5, 0, 64], + [21, 0, 18, 0, 5, 0, 64], + [10, 0, 0, 0, 5, 0, 70], + [7, 0, 0, 0, 5, 0, 70], + [12, 9, 13, 0, 5, 0, 70], + [21, 0, 0, 0, 5, 0, 70], + [13, 0, 0, 0, 5, 0, 70], + [13, 0, 0, 0, 5, 0, 71], + [7, 0, 0, 0, 5, 0, 71], + [12, 0, 13, 0, 5, 0, 71], + [12, 220, 13, 0, 5, 0, 71], + [21, 0, 0, 0, 5, 0, 71], + [7, 0, 0, 0, 5, 0, 72], + [12, 0, 13, 0, 5, 0, 72], + [10, 0, 0, 0, 5, 0, 72], + [10, 9, 0, 0, 5, 0, 72], + [21, 0, 0, 0, 5, 0, 72], + [12, 0, 13, 0, 5, 0, 84], + [10, 0, 0, 0, 5, 0, 84], + [7, 0, 0, 0, 5, 0, 84], + [12, 7, 13, 0, 5, 0, 84], + [10, 9, 0, 0, 5, 0, 84], + [21, 0, 0, 0, 5, 0, 84], + [6, 0, 0, 0, 5, 0, 84], + [13, 0, 0, 0, 5, 0, 84], + [7, 0, 0, 0, 5, 0, 76], + [12, 0, 13, 0, 5, 0, 76], + [10, 0, 0, 0, 5, 0, 76], + [13, 0, 0, 0, 5, 0, 76], + [21, 0, 0, 0, 5, 0, 76], + [6, 0, 0, 0, 5, 0, 22], + [7, 0, 0, 0, 5, 0, 78], + [12, 230, 13, 0, 5, 0, 78], + [12, 220, 13, 0, 5, 0, 78], + [6, 0, 0, 0, 5, 0, 78], + [21, 0, 0, 0, 5, 0, 78], + [7, 0, 0, 0, 5, 0, 85], + [10, 0, 0, 0, 5, 0, 85], + [12, 0, 13, 0, 5, 0, 85], + [21, 0, 0, 0, 5, 0, 85], + [6, 0, 0, 0, 5, 0, 85], + [12, 9, 13, 0, 5, 0, 85], + [13, 0, 0, 0, 5, 0, 85], + [2, 0, 18, 0, 2, 0, 24], + [4, 0, 0, 0, 5, 0, 102], + [3, 0, 0, 0, 4, 0, 102], + [2, 0, 18, 0, 4, 0, 102], + [12, 26, 13, 0, 5, 0, 5], + [25, 0, 9, 0, 5, 0, 5], + [24, 0, 4, 0, 5, 0, 6], + [18, 0, 18, 0, 5, 0, 0], + [16, 0, 18, 0, 2, 0, 0], + [21, 0, 12, 0, 2, 0, 0], + [21, 0, 10, 0, 2, 0, 0], + [25, 0, 9, 0, 2, 0, 0], + [17, 0, 9, 0, 2, 0, 0], + [25, 0, 18, 1, 2, 0, 0], + [25, 0, 18, 0, 2, 0, 0], + [23, 0, 10, 0, 2, 0, 0], + [21, 0, 18, 0, 0, 0, 0], + [21, 0, 10, 0, 0, 0, 0], + [23, 0, 10, 0, 0, 0, 0], + [22, 0, 18, 1, 0, 0, 0], + [18, 0, 18, 1, 0, 0, 0], + [25, 0, 9, 0, 0, 0, 0], + [21, 0, 12, 0, 0, 0, 0], + [17, 0, 9, 0, 0, 0, 0], + [13, 0, 8, 0, 0, 0, 0], + [25, 0, 18, 1, 0, 0, 0], + [25, 0, 18, 0, 0, 0, 0], + [9, 0, 0, 0, 0, 0, 1], + [24, 0, 18, 0, 0, 0, 0], + [16, 0, 18, 0, 0, 0, 0], + [5, 0, 0, 0, 0, 0, 1], + [21, 0, 18, 0, 1, 0, 0], + [22, 0, 18, 1, 1, 0, 0], + [18, 0, 18, 1, 1, 0, 0], + [7, 0, 0, 0, 1, 0, 33], + [6, 0, 0, 0, 1, 0, 0], + [7, 0, 0, 0, 1, 0, 24], + [26, 0, 18, 0, 0, 0, 0], + [26, 0, 18, 0, 1, 0, 0], + [25, 0, 18, 0, 1, 0, 0], + [1, 0, 18, 0, 5, 0, 0], + [7, 0, 0, 0, 5, 0, 47], + [14, 0, 18, 0, 5, 0, 2], + [15, 0, 18, 0, 5, 0, 2], + [26, 0, 18, 0, 5, 0, 2], + [7, 0, 0, 0, 5, 0, 73], + [7, 0, 0, 0, 5, 0, 74], + [7, 0, 0, 0, 5, 0, 37], + [15, 0, 0, 0, 5, 0, 37], + [7, 0, 0, 0, 5, 0, 38], + [14, 0, 0, 0, 5, 0, 38], + [7, 0, 0, 0, 5, 0, 48], + [21, 0, 0, 0, 5, 0, 48], + [7, 0, 0, 0, 5, 0, 59], + [21, 0, 0, 0, 5, 0, 59], + [14, 0, 0, 0, 5, 0, 59], + [9, 0, 0, 0, 5, 0, 39], + [5, 0, 0, 0, 5, 0, 39], + [7, 0, 0, 0, 5, 0, 49], + [7, 0, 0, 0, 5, 0, 50], + [13, 0, 0, 0, 5, 0, 50], + [7, 0, 3, 0, 5, 0, 51], + [7, 0, 3, 0, 5, 0, 86], + [21, 0, 3, 0, 5, 0, 86], + [15, 0, 3, 0, 5, 0, 86], + [7, 0, 3, 0, 5, 0, 63], + [15, 0, 3, 0, 5, 0, 63], + [21, 0, 18, 0, 5, 0, 63], + [7, 0, 3, 0, 5, 0, 75], + [21, 0, 3, 0, 5, 0, 75], + [7, 0, 3, 0, 5, 0, 97], + [7, 0, 3, 0, 5, 0, 96], + [7, 0, 3, 0, 5, 0, 60], + [12, 0, 13, 0, 5, 0, 60], + [12, 220, 13, 0, 5, 0, 60], + [12, 230, 13, 0, 5, 0, 60], + [12, 1, 13, 0, 5, 0, 60], + [12, 9, 13, 0, 5, 0, 60], + [15, 0, 3, 0, 5, 0, 60], + [21, 0, 3, 0, 5, 0, 60], + [7, 0, 3, 0, 5, 0, 87], + [15, 0, 3, 0, 5, 0, 87], + [21, 0, 3, 0, 5, 0, 87], + [7, 0, 3, 0, 5, 0, 79], + [21, 0, 18, 0, 5, 0, 79], + [7, 0, 3, 0, 5, 0, 88], + [15, 0, 3, 0, 5, 0, 88], + [7, 0, 3, 0, 5, 0, 89], + [15, 0, 3, 0, 5, 0, 89], + [7, 0, 3, 0, 5, 0, 90], + [15, 0, 11, 0, 5, 0, 6], + [10, 0, 0, 0, 5, 0, 93], + [12, 0, 13, 0, 5, 0, 93], + [7, 0, 0, 0, 5, 0, 93], + [12, 9, 13, 0, 5, 0, 93], + [21, 0, 0, 0, 5, 0, 93], + [15, 0, 18, 0, 5, 0, 93], + [13, 0, 0, 0, 5, 0, 93], + [12, 0, 13, 0, 5, 0, 91], + [10, 0, 0, 0, 5, 0, 91], + [7, 0, 0, 0, 5, 0, 91], + [12, 9, 13, 0, 5, 0, 91], + [12, 7, 13, 0, 5, 0, 91], + [21, 0, 0, 0, 5, 0, 91], + [1, 0, 0, 0, 5, 0, 91], + [7, 0, 0, 0, 5, 0, 100], + [13, 0, 0, 0, 5, 0, 100], + [12, 230, 13, 0, 5, 0, 95], + [7, 0, 0, 0, 5, 0, 95], + [12, 0, 13, 0, 5, 0, 95], + [10, 0, 0, 0, 5, 0, 95], + [12, 9, 13, 0, 5, 0, 95], + [13, 0, 0, 0, 5, 0, 95], + [21, 0, 0, 0, 5, 0, 95], + [12, 0, 13, 0, 5, 0, 99], + [10, 0, 0, 0, 5, 0, 99], + [7, 0, 0, 0, 5, 0, 99], + [10, 9, 0, 0, 5, 0, 99], + [21, 0, 0, 0, 5, 0, 99], + [13, 0, 0, 0, 5, 0, 99], + [7, 0, 0, 0, 5, 0, 101], + [12, 0, 13, 0, 5, 0, 101], + [10, 0, 0, 0, 5, 0, 101], + [10, 9, 0, 0, 5, 0, 101], + [12, 7, 13, 0, 5, 0, 101], + [13, 0, 0, 0, 5, 0, 101], + [7, 0, 0, 0, 5, 0, 62], + [14, 0, 0, 0, 5, 0, 62], + [21, 0, 0, 0, 5, 0, 62], + [7, 0, 0, 0, 5, 0, 80], + [7, 0, 0, 0, 5, 0, 98], + [10, 0, 0, 0, 5, 0, 98], + [12, 0, 13, 0, 5, 0, 98], + [6, 0, 0, 0, 5, 0, 98], + [10, 216, 0, 0, 5, 0, 0], + [10, 226, 0, 0, 5, 0, 0], + [12, 230, 13, 0, 5, 0, 2], + [25, 0, 0, 0, 5, 0, 0], + [13, 0, 8, 0, 5, 0, 0], + [26, 0, 0, 0, 2, 0, 32], + ]; + + /* Mirror unicode characters. Bidirectional Algorithm, at http://www.unicode.org/unicode/reports/tr9/ */ + + public static $mirror_pairs = [ + 40 => 41, + 41 => 40, + 60 => 62, + 62 => 60, + 91 => 93, + 93 => 91, + 123 => 125, + 125 => 123, + 171 => 187, + 187 => 171, + 3898 => 3899, + 3899 => 3898, + 3900 => 3901, + 3901 => 3900, + 5787 => 5788, + 5788 => 5787, + 8249 => 8250, + 8250 => 8249, + 8261 => 8262, + 8262 => 8261, + 8317 => 8318, + 8318 => 8317, + 8333 => 8334, + 8334 => 8333, + 8712 => 8715, + 8713 => 8716, + 8714 => 8717, + 8715 => 8712, + 8716 => 8713, + 8717 => 8714, + 8725 => 10741, + 8764 => 8765, + 8765 => 8764, + 8771 => 8909, + 8786 => 8787, + 8787 => 8786, + 8788 => 8789, + 8789 => 8788, + 8804 => 8805, + 8805 => 8804, + 8806 => 8807, + 8807 => 8806, + 8808 => 8809, + 8809 => 8808, + 8810 => 8811, + 8811 => 8810, + 8814 => 8815, + 8815 => 8814, + 8816 => 8817, + 8817 => 8816, + 8818 => 8819, + 8819 => 8818, + 8820 => 8821, + 8821 => 8820, + 8822 => 8823, + 8823 => 8822, + 8824 => 8825, + 8825 => 8824, + 8826 => 8827, + 8827 => 8826, + 8828 => 8829, + 8829 => 8828, + 8830 => 8831, + 8831 => 8830, + 8832 => 8833, + 8833 => 8832, + 8834 => 8835, + 8835 => 8834, + 8836 => 8837, + 8837 => 8836, + 8838 => 8839, + 8839 => 8838, + 8840 => 8841, + 8841 => 8840, + 8842 => 8843, + 8843 => 8842, + 8847 => 8848, + 8848 => 8847, + 8849 => 8850, + 8850 => 8849, + 8856 => 10680, + 8866 => 8867, + 8867 => 8866, + 8870 => 10974, + 8872 => 10980, + 8873 => 10979, + 8875 => 10981, + 8880 => 8881, + 8881 => 8880, + 8882 => 8883, + 8883 => 8882, + 8884 => 8885, + 8885 => 8884, + 8886 => 8887, + 8887 => 8886, + 8905 => 8906, + 8906 => 8905, + 8907 => 8908, + 8908 => 8907, + 8909 => 8771, + 8912 => 8913, + 8913 => 8912, + 8918 => 8919, + 8919 => 8918, + 8920 => 8921, + 8921 => 8920, + 8922 => 8923, + 8923 => 8922, + 8924 => 8925, + 8925 => 8924, + 8926 => 8927, + 8927 => 8926, + 8928 => 8929, + 8929 => 8928, + 8930 => 8931, + 8931 => 8930, + 8932 => 8933, + 8933 => 8932, + 8934 => 8935, + 8935 => 8934, + 8936 => 8937, + 8937 => 8936, + 8938 => 8939, + 8939 => 8938, + 8940 => 8941, + 8941 => 8940, + 8944 => 8945, + 8945 => 8944, + 8946 => 8954, + 8947 => 8955, + 8948 => 8956, + 8950 => 8957, + 8951 => 8958, + 8954 => 8946, + 8955 => 8947, + 8956 => 8948, + 8957 => 8950, + 8958 => 8951, + 8968 => 8969, + 8969 => 8968, + 8970 => 8971, + 8971 => 8970, + 9001 => 9002, + 9002 => 9001, + 10088 => 10089, + 10089 => 10088, + 10090 => 10091, + 10091 => 10090, + 10092 => 10093, + 10093 => 10092, + 10094 => 10095, + 10095 => 10094, + 10096 => 10097, + 10097 => 10096, + 10098 => 10099, + 10099 => 10098, + 10100 => 10101, + 10101 => 10100, + 10179 => 10180, + 10180 => 10179, + 10181 => 10182, + 10182 => 10181, + 10184 => 10185, + 10185 => 10184, + 10187 => 10189, + 10189 => 10187, + 10197 => 10198, + 10198 => 10197, + 10205 => 10206, + 10206 => 10205, + 10210 => 10211, + 10211 => 10210, + 10212 => 10213, + 10213 => 10212, + 10214 => 10215, + 10215 => 10214, + 10216 => 10217, + 10217 => 10216, + 10218 => 10219, + 10219 => 10218, + 10220 => 10221, + 10221 => 10220, + 10222 => 10223, + 10223 => 10222, + 10627 => 10628, + 10628 => 10627, + 10629 => 10630, + 10630 => 10629, + 10631 => 10632, + 10632 => 10631, + 10633 => 10634, + 10634 => 10633, + 10635 => 10636, + 10636 => 10635, + 10637 => 10640, + 10638 => 10639, + 10639 => 10638, + 10640 => 10637, + 10641 => 10642, + 10642 => 10641, + 10643 => 10644, + 10644 => 10643, + 10645 => 10646, + 10646 => 10645, + 10647 => 10648, + 10648 => 10647, + 10680 => 8856, + 10688 => 10689, + 10689 => 10688, + 10692 => 10693, + 10693 => 10692, + 10703 => 10704, + 10704 => 10703, + 10705 => 10706, + 10706 => 10705, + 10708 => 10709, + 10709 => 10708, + 10712 => 10713, + 10713 => 10712, + 10714 => 10715, + 10715 => 10714, + 10741 => 8725, + 10744 => 10745, + 10745 => 10744, + 10748 => 10749, + 10749 => 10748, + 10795 => 10796, + 10796 => 10795, + 10797 => 10798, + 10798 => 10797, + 10804 => 10805, + 10805 => 10804, + 10812 => 10813, + 10813 => 10812, + 10852 => 10853, + 10853 => 10852, + 10873 => 10874, + 10874 => 10873, + 10877 => 10878, + 10878 => 10877, + 10879 => 10880, + 10880 => 10879, + 10881 => 10882, + 10882 => 10881, + 10883 => 10884, + 10884 => 10883, + 10891 => 10892, + 10892 => 10891, + 10897 => 10898, + 10898 => 10897, + 10899 => 10900, + 10900 => 10899, + 10901 => 10902, + 10902 => 10901, + 10903 => 10904, + 10904 => 10903, + 10905 => 10906, + 10906 => 10905, + 10907 => 10908, + 10908 => 10907, + 10913 => 10914, + 10914 => 10913, + 10918 => 10919, + 10919 => 10918, + 10920 => 10921, + 10921 => 10920, + 10922 => 10923, + 10923 => 10922, + 10924 => 10925, + 10925 => 10924, + 10927 => 10928, + 10928 => 10927, + 10931 => 10932, + 10932 => 10931, + 10939 => 10940, + 10940 => 10939, + 10941 => 10942, + 10942 => 10941, + 10943 => 10944, + 10944 => 10943, + 10945 => 10946, + 10946 => 10945, + 10947 => 10948, + 10948 => 10947, + 10949 => 10950, + 10950 => 10949, + 10957 => 10958, + 10958 => 10957, + 10959 => 10960, + 10960 => 10959, + 10961 => 10962, + 10962 => 10961, + 10963 => 10964, + 10964 => 10963, + 10965 => 10966, + 10966 => 10965, + 10974 => 8870, + 10979 => 8873, + 10980 => 8872, + 10981 => 8875, + 10988 => 10989, + 10989 => 10988, + 10999 => 11000, + 11000 => 10999, + 11001 => 11002, + 11002 => 11001, + 11778 => 11779, + 11779 => 11778, + 11780 => 11781, + 11781 => 11780, + 11785 => 11786, + 11786 => 11785, + 11788 => 11789, + 11789 => 11788, + 11804 => 11805, + 11805 => 11804, + 11808 => 11809, + 11809 => 11808, + 11810 => 11811, + 11811 => 11810, + 11812 => 11813, + 11813 => 11812, + 11814 => 11815, + 11815 => 11814, + 11816 => 11817, + 11817 => 11816, + 12296 => 12297, + 12297 => 12296, + 12298 => 12299, + 12299 => 12298, + 12300 => 12301, + 12301 => 12300, + 12302 => 12303, + 12303 => 12302, + 12304 => 12305, + 12305 => 12304, + 12308 => 12309, + 12309 => 12308, + 12310 => 12311, + 12311 => 12310, + 12312 => 12313, + 12313 => 12312, + 12314 => 12315, + 12315 => 12314, + 65113 => 65114, + 65114 => 65113, + 65115 => 65116, + 65116 => 65115, + 65117 => 65118, + 65118 => 65117, + 65124 => 65125, + 65125 => 65124, + 65288 => 65289, + 65289 => 65288, + 65308 => 65310, + 65310 => 65308, + 65339 => 65341, + 65341 => 65339, + 65371 => 65373, + 65373 => 65371, + 65375 => 65376, + 65376 => 65375, + 65378 => 65379, + 65379 => 65378, + ]; + + + /* index tables for the database records */ + + private static $index0 = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 54, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 55, 56, 57, 57, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 69, 70, 70, + 71, 69, 70, 70, 72, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 70, 70, 70, 88, 89, 90, 91, 92, 70, 93, 70, 94, + 95, 70, 70, 70, 70, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 97, 97, 97, + 98, 99, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 100, 100, 100, 100, + 101, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 102, 102, + 103, 70, 70, 70, 70, 104, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 105, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 106, 107, 108, 109, 110, + 111, 112, 113, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 114, 70, 115, 116, 117, 118, 119, 120, + 121, 122, 70, 70, 70, 70, 70, 70, 70, 70, 52, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 123, 52, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 124, 125, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 76, 76, 127, 126, 126, 126, 126, 128, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 128, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 129, 130, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 131, 73, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 131, + ]; + + private static $index1 = [ + 0, 1, 0, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 0, 0, 0, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 31, 32, + 33, 34, 35, 27, 30, 29, 27, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 27, 27, 49, 27, 27, 27, 27, 27, 27, 27, 50, 51, 52, 27, 53, 54, + 53, 54, 54, 54, 54, 54, 55, 54, 54, 54, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 65, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 97, 97, 97, 98, 98, 98, 98, 99, 100, 101, 101, 101, 101, 102, 103, + 101, 101, 101, 101, 101, 101, 104, 105, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 106, 107, 108, 108, 108, 109, 110, 111, 112, + 112, 112, 112, 113, 114, 115, 116, 117, 118, 119, 120, 106, 121, 121, + 121, 122, 123, 106, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130, + 131, 132, 133, 134, 135, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 145, 145, + 146, 147, 148, 149, 128, 128, 128, 128, 128, 128, 150, 150, 150, 150, + 151, 152, 153, 106, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160, + 161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 106, 106, 106, 106, + 106, 106, 106, 106, 169, 170, 106, 106, 106, 106, 106, 106, 171, 172, + 173, 174, 175, 176, 176, 176, 176, 176, 176, 177, 178, 179, 180, 176, + 181, 182, 183, 184, 185, 186, 187, 188, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 106, 214, 215, 216, 217, 217, 218, + 219, 220, 221, 222, 223, 106, 224, 225, 226, 106, 227, 228, 229, 230, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 106, 241, 242, + 243, 244, 245, 242, 246, 247, 248, 249, 250, 106, 251, 252, 253, 254, + 255, 256, 257, 258, 258, 257, 259, 260, 261, 262, 263, 264, 265, 266, + 106, 267, 268, 269, 270, 271, 271, 270, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 106, 281, 282, 283, 284, 284, 284, 284, 285, 286, 287, + 288, 106, 289, 290, 291, 292, 293, 294, 295, 296, 294, 294, 297, 298, + 295, 299, 300, 301, 106, 106, 302, 106, 303, 304, 304, 304, 304, 304, + 305, 306, 307, 308, 309, 310, 106, 106, 106, 106, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 106, 106, 106, 106, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 331, 331, 331, 333, 334, 335, + 336, 337, 338, 339, 338, 338, 338, 340, 341, 342, 343, 344, 106, 106, + 106, 106, 345, 345, 345, 345, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 345, 356, 357, 349, 358, 359, 359, 359, 359, 360, 361, + 362, 362, 362, 362, 362, 363, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 367, 368, 367, 366, 366, 366, 366, 366, 367, + 366, 366, 366, 366, 367, 368, 367, 366, 368, 366, 366, 366, 366, 366, + 366, 366, 367, 366, 366, 366, 366, 366, 366, 366, 366, 369, 370, 371, + 372, 373, 366, 366, 374, 375, 376, 376, 376, 376, 376, 376, 376, 376, + 376, 376, 377, 106, 378, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 380, 379, 379, + 381, 382, 382, 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, + 386, 106, 387, 388, 389, 106, 390, 390, 391, 106, 392, 392, 393, 106, + 394, 395, 396, 106, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 412, 412, 412, + 413, 412, 412, 412, 412, 412, 412, 106, 412, 412, 412, 412, 412, 414, + 379, 379, 379, 379, 379, 379, 379, 379, 415, 106, 416, 416, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 424, 424, 425, 426, 106, 427, 427, + 427, 427, 427, 428, 429, 429, 430, 431, 432, 433, 434, 434, 434, 434, + 435, 435, 436, 437, 438, 438, 438, 438, 438, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 445, 446, 447, 448, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 449, 450, 450, 450, 450, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 462, 462, 463, 464, 465, 466, + 467, 467, 467, 467, 468, 469, 470, 471, 472, 472, 472, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 481, 481, 482, 106, 106, 106, 106, + 106, 106, 106, 106, 483, 106, 484, 485, 486, 487, 488, 106, 54, 54, 54, + 54, 489, 490, 56, 56, 56, 56, 56, 491, 492, 493, 54, 494, 54, 54, 54, + 495, 56, 56, 56, 496, 497, 498, 499, 500, 501, 106, 106, 502, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 503, 504, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 505, 506, 507, 508, 505, 506, + 505, 506, 507, 508, 505, 509, 505, 506, 505, 507, 505, 510, 505, 510, + 505, 510, 511, 512, 513, 514, 515, 516, 505, 517, 518, 519, 520, 521, + 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, + 536, 537, 56, 538, 539, 540, 539, 541, 106, 106, 542, 543, 544, 545, 546, + 106, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, + 560, 559, 561, 562, 563, 564, 565, 566, 567, 568, 569, 568, 570, 571, + 568, 572, 568, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, + 584, 585, 586, 587, 588, 583, 583, 589, 590, 591, 592, 593, 583, 583, + 594, 574, 595, 596, 583, 583, 597, 583, 583, 568, 598, 599, 568, 600, + 601, 602, 603, 603, 603, 603, 603, 603, 603, 603, 604, 568, 568, 605, + 606, 574, 574, 607, 568, 568, 568, 568, 573, 608, 568, 609, 106, 568, + 568, 568, 568, 610, 106, 106, 106, 568, 611, 106, 106, 612, 612, 612, + 612, 612, 613, 613, 614, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 616, 612, 612, 617, 617, 617, 617, 617, 617, 617, 617, 617, 618, 617, + 617, 617, 617, 618, 568, 617, 617, 619, 568, 620, 569, 621, 622, 623, + 624, 569, 568, 619, 572, 568, 574, 625, 626, 622, 627, 568, 568, 568, + 568, 628, 568, 568, 568, 629, 630, 568, 568, 568, 568, 568, 631, 568, + 632, 568, 631, 633, 634, 617, 617, 635, 617, 617, 617, 636, 568, 568, + 568, 568, 568, 568, 637, 568, 568, 572, 568, 568, 638, 639, 612, 640, + 640, 641, 568, 568, 568, 568, 568, 642, 643, 644, 645, 646, 647, 574, + 574, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 574, 574, 574, 574, 574, 574, 574, 574, 574, + 574, 574, 574, 574, 574, 574, 574, 649, 650, 650, 651, 583, 583, 574, + 652, 597, 653, 654, 655, 656, 657, 658, 659, 574, 660, 583, 661, 662, + 663, 664, 645, 574, 574, 586, 652, 664, 665, 666, 667, 583, 583, 583, + 583, 668, 669, 583, 583, 583, 583, 670, 671, 672, 645, 673, 674, 568, + 568, 568, 568, 568, 568, 574, 574, 675, 676, 677, 678, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 679, 679, 679, 679, 679, 680, 681, 681, 681, 681, 681, + 682, 683, 684, 685, 686, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 687, 688, 689, 690, 691, 691, 691, 691, 692, 693, 694, 694, 694, 694, + 694, 694, 694, 695, 696, 697, 366, 366, 368, 106, 368, 368, 368, 368, + 368, 368, 368, 368, 698, 698, 698, 698, 699, 700, 701, 702, 703, 704, + 529, 705, 106, 106, 106, 106, 106, 106, 106, 106, 706, 706, 706, 707, + 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 708, 106, 706, 706, + 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 709, 106, 106, 106, + 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 721, 721, + 721, 721, 721, 721, 721, 721, 722, 723, 724, 725, 725, 725, 725, 725, + 725, 725, 725, 725, 725, 726, 727, 728, 728, 728, 728, 729, 730, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 731, 732, 733, 728, 728, + 728, 734, 710, 710, 710, 710, 711, 106, 725, 725, 735, 735, 735, 736, + 737, 738, 733, 733, 733, 739, 740, 741, 735, 735, 735, 742, 737, 738, + 733, 733, 733, 733, 743, 741, 733, 744, 745, 745, 745, 745, 745, 746, + 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 733, 733, 733, + 747, 748, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 749, + 733, 733, 733, 747, 750, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 752, 753, 568, 568, 568, 568, 568, 568, + 568, 568, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 754, + 753, 753, 753, 753, 753, 753, 755, 755, 756, 755, 755, 755, 755, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, + 755, 755, 755, 757, 758, 758, 758, 758, 758, 758, 759, 106, 760, 760, + 760, 760, 760, 761, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 763, 762, 762, 764, 765, + 106, 106, 101, 101, 101, 101, 101, 766, 767, 768, 101, 101, 101, 769, + 770, 770, 770, 770, 770, 770, 770, 770, 771, 772, 773, 106, 64, 64, 774, + 775, 776, 27, 777, 27, 27, 27, 27, 27, 27, 27, 778, 779, 27, 780, 781, + 106, 27, 782, 106, 106, 106, 106, 106, 106, 106, 106, 106, 783, 784, 785, + 786, 786, 787, 788, 789, 790, 791, 791, 791, 791, 791, 791, 792, 106, + 793, 794, 794, 794, 794, 794, 795, 796, 797, 798, 799, 800, 801, 801, + 802, 803, 804, 805, 806, 806, 807, 808, 809, 809, 810, 811, 812, 813, + 364, 364, 364, 814, 815, 816, 816, 816, 816, 816, 817, 818, 819, 820, + 821, 822, 106, 106, 106, 106, 823, 823, 823, 823, 823, 824, 825, 106, + 826, 827, 828, 829, 345, 345, 830, 831, 832, 832, 832, 832, 832, 832, + 833, 834, 835, 106, 106, 836, 837, 838, 839, 106, 840, 840, 840, 106, + 368, 368, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 837, 837, 837, 837, 841, 842, 843, 844, + 845, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 847, 106, 365, 365, 848, 849, 365, 365, 365, 365, 365, 850, 851, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 852, 851, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 852, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 852, + 853, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 855, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + 856, 857, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + 856, 858, 753, 753, 753, 753, 859, 106, 860, 861, 121, 862, 863, 864, + 865, 121, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 866, 867, 868, 106, 869, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 870, 106, 106, 128, 128, 128, 128, + 128, 128, 128, 128, 871, 128, 128, 128, 128, 128, 128, 106, 106, 106, + 106, 106, 128, 872, 873, 873, 874, 875, 501, 106, 876, 877, 878, 879, + 880, 881, 882, 883, 884, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 885, 886, 887, 888, 889, 890, 891, + 891, 892, 893, 894, 894, 895, 896, 897, 898, 897, 897, 897, 897, 899, + 900, 900, 900, 901, 902, 902, 902, 903, 904, 905, 106, 906, 907, 908, + 907, 907, 909, 907, 907, 910, 907, 911, 907, 911, 106, 106, 106, 106, + 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, + 907, 912, 913, 914, 914, 914, 914, 914, 915, 603, 916, 916, 916, 916, + 916, 916, 917, 918, 919, 920, 568, 609, 106, 106, 106, 106, 106, 106, + 603, 603, 603, 603, 603, 921, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 922, 922, 922, 923, 924, 924, + 924, 924, 924, 924, 925, 106, 106, 106, 106, 106, 926, 926, 926, 927, + 928, 106, 929, 929, 930, 931, 106, 106, 106, 106, 106, 106, 932, 932, + 932, 933, 934, 934, 934, 934, 935, 934, 936, 106, 106, 106, 106, 106, + 937, 937, 937, 937, 937, 938, 938, 938, 938, 938, 939, 939, 939, 939, + 939, 939, 940, 940, 940, 941, 942, 943, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 944, 945, 946, 946, 946, 946, 947, 948, 949, 949, + 950, 951, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 952, 952, 953, 954, 955, 955, + 955, 956, 106, 106, 106, 106, 106, 106, 106, 106, 957, 957, 957, 957, + 958, 958, 958, 959, 106, 106, 106, 106, 106, 106, 106, 106, 960, 961, + 962, 963, 964, 964, 965, 966, 967, 106, 968, 969, 970, 970, 970, 971, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 972, 972, 972, 972, 972, 972, 973, 974, 975, 975, 976, 977, + 978, 978, 979, 980, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 981, 981, 981, 981, 981, 981, 981, 981, + 981, 982, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 983, 983, 983, 984, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 985, 986, 986, 986, 986, 986, 986, 987, 988, 989, 990, 991, 992, 993, + 106, 106, 994, 995, 995, 995, 995, 995, 996, 997, 998, 106, 999, 999, + 999, 1000, 1001, 1002, 1003, 1004, 1004, 1004, 1005, 1006, 1007, 1008, + 1009, 106, 106, 106, 106, 106, 106, 106, 1010, 1011, 1011, 1011, 1011, + 1011, 1012, 1013, 1014, 1015, 1016, 1017, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 1018, 1018, 1018, 1018, 1018, 1019, 1020, 106, 1021, 1022, 106, 106, 106, + 106, 106, 106, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, + 1024, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1025, 1025, 1026, 106, 1027, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 1028, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 770, 770, 770, + 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, 770, 770, 770, 770, 770, 770, 1030, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + 1032, 106, 1033, 1034, 1034, 1034, 1034, 1035, 106, 1036, 1037, 1038, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 1039, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 1040, 106, 603, 603, 603, 603, 1041, 1042, 603, 603, + 603, 603, 603, 603, 1043, 1044, 1045, 1046, 1047, 1048, 603, 603, 603, + 1049, 603, 603, 603, 603, 603, 1040, 106, 106, 106, 106, 919, 919, 919, + 919, 919, 919, 919, 919, 1050, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 610, 106, 914, + 914, 1051, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 1052, 1052, 1052, 1053, 1054, 1054, 1055, 1052, + 1052, 1056, 1057, 1054, 1054, 1052, 1052, 1052, 1053, 1054, 1054, 1058, + 1059, 1060, 1056, 1061, 1062, 1054, 1052, 1052, 1052, 1053, 1054, 1054, + 1063, 1064, 1065, 1066, 1054, 1054, 1054, 1067, 1068, 1069, 1070, 1054, + 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, 1052, 1053, + 1054, 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, 1052, + 1053, 1054, 1054, 1055, 1052, 1052, 1056, 1054, 1054, 1054, 1052, 1052, + 1052, 1053, 1054, 1054, 1071, 1052, 1052, 1052, 1072, 1054, 1054, 1073, + 1074, 1052, 1052, 1075, 1054, 1054, 1076, 1055, 1052, 1052, 1077, 1054, + 1054, 1078, 1079, 1052, 1052, 1080, 1054, 1054, 1054, 1081, 1052, 1052, + 1052, 1072, 1054, 1054, 1073, 1082, 1083, 1083, 1083, 1083, 1083, 1083, + 1084, 128, 128, 128, 1085, 1086, 1087, 1088, 1089, 1090, 1085, 1091, + 1085, 1087, 1087, 1092, 128, 1093, 128, 1094, 1095, 1093, 128, 1094, 106, + 106, 106, 106, 106, 106, 1096, 106, 568, 568, 568, 568, 568, 609, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 609, 106, 568, + 610, 636, 610, 636, 568, 636, 568, 106, 106, 106, 106, 613, 1097, 615, + 615, 615, 1098, 615, 615, 615, 615, 615, 615, 615, 1099, 615, 615, 615, + 615, 615, 1100, 106, 106, 106, 106, 106, 106, 106, 106, 1101, 603, 603, + 603, 1102, 106, 733, 733, 733, 733, 733, 1103, 733, 1104, 1105, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 568, 568, 568, 568, 1106, 106, 1107, 568, 568, + 568, 568, 568, 568, 568, 568, 1108, 568, 568, 609, 106, 568, 568, 568, + 568, 1109, 611, 106, 106, 568, 568, 1106, 106, 568, 568, 568, 568, 568, + 568, 568, 610, 1110, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 1111, 568, + 568, 568, 568, 568, 568, 568, 1112, 609, 106, 568, 568, 568, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 1113, 568, 568, 568, 568, 568, 568, 568, 568, 1114, 568, 106, + 106, 106, 106, 106, 106, 568, 568, 568, 568, 568, 568, 568, 568, 1112, + 106, 106, 106, 106, 106, 106, 106, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 609, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 1115, 753, 753, 753, 753, + 753, 751, 751, 751, 751, 751, 751, 754, 753, 750, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 752, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 856, + 856, 856, 857, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 753, 753, 753, 753, 753, 1116, 1117, 106, 106, 106, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 106, 106, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 1119, + ]; + + private static $index2 = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, + 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 12, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 16, + 10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 21, 22, 8, 8, 23, 8, 24, 22, 25, 26, + 27, 28, 16, 29, 30, 18, 31, 32, 33, 33, 25, 34, 22, 22, 25, 33, 27, 35, + 36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37, 37, 38, 40, + 40, 40, 41, 41, 41, 41, 40, 41, 40, 40, 40, 41, 40, 40, 41, 41, 40, 41, + 40, 40, 41, 41, 41, 39, 40, 40, 40, 41, 40, 41, 40, 41, 37, 40, 37, 41, + 37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 37, 40, 37, 40, 37, 41, + 37, 41, 37, 41, 37, 40, 37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 38, 40, + 37, 40, 38, 40, 37, 41, 37, 41, 40, 37, 41, 37, 41, 37, 41, 38, 40, 38, + 40, 37, 40, 37, 41, 37, 40, 40, 38, 40, 37, 40, 37, 41, 37, 41, 38, 40, + 37, 41, 37, 41, 37, 37, 41, 37, 41, 37, 41, 41, 41, 37, 37, 41, 37, 41, + 37, 37, 41, 37, 37, 37, 41, 41, 37, 37, 37, 37, 41, 37, 37, 41, 37, 37, + 37, 41, 41, 41, 37, 37, 41, 37, 37, 41, 37, 41, 37, 41, 37, 37, 41, 37, + 41, 41, 37, 41, 37, 37, 41, 37, 37, 37, 41, 37, 41, 37, 37, 41, 41, 42, + 37, 41, 41, 41, 42, 42, 42, 42, 37, 43, 41, 37, 43, 41, 37, 43, 41, 37, + 40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 41, 37, 41, + 41, 37, 43, 41, 37, 41, 37, 37, 37, 41, 37, 41, 41, 41, 41, 41, 41, 41, + 37, 37, 41, 37, 37, 41, 41, 37, 41, 37, 37, 37, 37, 41, 41, 40, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, + 41, 41, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 46, 46, 46, 46, 46, + 46, 46, 47, 47, 25, 47, 45, 48, 45, 48, 48, 48, 45, 48, 45, 45, 49, 46, + 47, 47, 47, 47, 47, 47, 25, 25, 25, 25, 47, 25, 47, 25, 44, 44, 44, 44, + 44, 47, 47, 47, 47, 47, 50, 50, 45, 47, 46, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 53, + 53, 53, 52, 54, 53, 53, 53, 53, 53, 55, 55, 53, 53, 53, 53, 55, 55, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 53, 53, 53, + 53, 51, 51, 51, 51, 51, 51, 51, 51, 57, 51, 53, 53, 53, 51, 51, 51, 53, + 53, 58, 51, 51, 51, 53, 53, 53, 53, 51, 52, 53, 53, 51, 59, 60, 60, 59, + 60, 60, 59, 51, 51, 51, 51, 51, 61, 62, 61, 62, 45, 63, 61, 62, 64, 64, + 65, 62, 62, 62, 66, 64, 64, 64, 64, 64, 63, 47, 61, 66, 61, 61, 61, 64, + 61, 64, 61, 61, 62, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 64, 67, 67, 67, 67, 67, 67, 67, 61, 61, 62, 62, 62, 62, + 62, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 62, 68, 68, 68, 68, 68, 68, 68, 62, 62, 62, 62, 62, 61, 62, 62, 61, 61, + 61, 62, 62, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 69, 70, 69, 70, + 69, 70, 69, 70, 69, 70, 69, 70, 69, 70, 62, 62, 62, 62, 61, 62, 71, 61, + 62, 61, 61, 62, 62, 61, 61, 61, 72, 73, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 75, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 72, 75, 72, 75, 72, 75, 72, 75, 72, 75, 76, 77, 77, 78, 78, 77, + 79, 79, 72, 75, 72, 75, 72, 75, 72, 72, 75, 72, 75, 72, 75, 72, 75, 72, + 75, 72, 75, 72, 75, 75, 64, 64, 64, 64, 64, 64, 64, 64, 64, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 64, 64, 81, 82, 82, 82, 82, 82, 82, 64, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 64, 84, 85, 64, 64, 64, 64, 86, 64, 87, + 88, 88, 88, 88, 87, 88, 88, 88, 89, 87, 88, 88, 88, 88, 88, 88, 87, 87, + 87, 87, 87, 87, 88, 88, 87, 88, 88, 89, 90, 88, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 100, 101, 102, 103, 104, 105, 106, 107, 108, 106, 88, + 87, 106, 99, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 64, + 64, 64, 64, 64, 109, 109, 109, 106, 106, 64, 64, 64, 110, 110, 110, 110, + 110, 64, 111, 111, 112, 113, 113, 114, 115, 116, 117, 117, 118, 118, 118, + 118, 118, 118, 118, 118, 119, 120, 121, 122, 64, 64, 116, 122, 123, 123, + 123, 123, 123, 123, 123, 123, 124, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 125, 126, 127, 128, 129, 130, 131, 132, 78, 78, 133, 134, + 118, 118, 118, 118, 118, 134, 118, 118, 134, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 113, 136, 136, 116, 123, 123, 137, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 116, 123, 118, 118, 118, + 118, 118, 118, 118, 138, 117, 118, 118, 118, 118, 134, 118, 139, 139, + 118, 118, 117, 134, 118, 118, 134, 123, 123, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 123, 123, 123, 141, 141, 123, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 64, 143, 144, 145, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 146, 147, 146, 146, 147, 146, 146, 147, 147, 147, 146, 147, 147, 146, + 147, 146, 146, 146, 147, 146, 147, 146, 147, 146, 147, 146, 146, 64, 64, + 144, 144, 144, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 148, 64, 64, 64, 64, 64, 64, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 153, 152, 154, + 154, 155, 156, 156, 156, 154, 64, 64, 64, 64, 64, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, + 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, + 159, 158, 158, 158, 158, 158, 64, 64, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 64, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 162, 162, 162, 64, 64, 163, 64, 123, 64, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 64, 64, 64, 64, 64, 64, 64, 118, + 118, 134, 118, 118, 134, 118, 118, 118, 134, 134, 134, 164, 165, 166, + 118, 118, 118, 134, 118, 118, 134, 134, 118, 118, 118, 118, 64, 167, 167, + 167, 168, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 167, 168, 170, 169, 168, 168, 168, 167, 167, 167, 167, 167, + 167, 167, 167, 168, 168, 168, 168, 171, 168, 168, 169, 78, 133, 172, 172, + 167, 167, 167, 169, 169, 167, 167, 84, 84, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 174, 175, 169, 169, 169, 169, 169, 169, 64, 169, 169, + 169, 169, 169, 169, 169, 64, 176, 177, 177, 64, 178, 178, 178, 178, 178, + 178, 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178, + 178, 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 179, 178, 177, 177, + 177, 176, 176, 176, 176, 64, 64, 177, 177, 64, 64, 177, 177, 180, 178, + 64, 64, 64, 64, 64, 64, 64, 64, 177, 64, 64, 64, 64, 178, 178, 64, 178, + 178, 178, 176, 176, 64, 64, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 178, 178, 182, 182, 183, 183, 183, 183, 183, 183, 184, 182, 64, 64, + 64, 64, 64, 185, 185, 186, 64, 187, 187, 187, 187, 187, 187, 64, 64, 64, + 64, 187, 187, 64, 64, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 64, 187, 187, 187, 187, 187, 187, 187, 64, 187, 187, + 64, 187, 187, 64, 187, 187, 64, 64, 188, 64, 186, 186, 186, 185, 185, 64, + 64, 64, 64, 185, 185, 64, 64, 185, 185, 189, 64, 64, 64, 185, 64, 64, 64, + 64, 64, 64, 64, 187, 187, 187, 187, 64, 187, 64, 64, 64, 64, 64, 64, 64, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 187, 187, + 187, 185, 64, 64, 64, 191, 191, 192, 64, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 64, 193, 193, 193, 64, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 64, 193, 193, 193, 193, 193, 193, 193, + 64, 193, 193, 64, 193, 193, 193, 193, 193, 64, 64, 194, 193, 192, 192, + 192, 191, 191, 191, 191, 191, 64, 191, 191, 192, 64, 192, 192, 195, 64, + 64, 193, 64, 64, 64, 64, 64, 64, 64, 193, 193, 191, 191, 64, 64, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 198, 64, 64, 64, 64, + 64, 64, 64, 199, 200, 200, 64, 201, 201, 201, 201, 201, 201, 201, 201, + 64, 64, 201, 201, 64, 64, 201, 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 64, 201, 201, 201, 201, 201, 201, 201, 64, 201, + 201, 64, 201, 201, 201, 201, 201, 64, 64, 202, 201, 200, 199, 200, 199, + 199, 199, 199, 64, 64, 200, 200, 64, 64, 200, 200, 203, 64, 64, 64, 64, + 64, 64, 64, 64, 199, 200, 64, 64, 64, 64, 201, 201, 64, 201, 201, 201, + 199, 199, 64, 64, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, + 201, 206, 206, 206, 206, 206, 206, 64, 64, 207, 208, 64, 208, 208, 208, + 208, 208, 208, 64, 64, 64, 208, 208, 208, 64, 208, 208, 208, 208, 64, 64, + 64, 208, 208, 64, 208, 64, 208, 208, 64, 64, 64, 208, 208, 64, 64, 64, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 64, 64, 64, 64, 209, + 209, 207, 209, 209, 64, 64, 64, 209, 209, 209, 64, 209, 209, 209, 210, + 64, 64, 208, 64, 64, 64, 64, 64, 64, 209, 64, 64, 64, 64, 64, 64, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 212, 212, 212, 213, 213, + 213, 213, 213, 213, 214, 213, 64, 64, 64, 64, 64, 64, 215, 215, 215, 64, + 216, 216, 216, 216, 216, 216, 216, 216, 64, 216, 216, 216, 64, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 64, 216, 216, 216, 216, 216, 64, 64, 64, 216, 217, 217, 217, + 215, 215, 215, 215, 64, 217, 217, 217, 64, 217, 217, 217, 218, 64, 64, + 64, 64, 64, 64, 64, 219, 220, 64, 216, 216, 64, 64, 64, 64, 64, 64, 216, + 216, 217, 217, 64, 64, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 222, 222, 222, 222, 222, 222, 222, 223, 64, 64, 224, 224, 64, 225, 225, + 225, 225, 225, 225, 225, 225, 64, 225, 225, 225, 64, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 64, + 225, 225, 225, 225, 225, 64, 64, 226, 225, 224, 227, 224, 224, 224, 224, + 224, 64, 227, 224, 224, 64, 224, 224, 228, 229, 64, 64, 64, 64, 64, 64, + 64, 224, 224, 64, 64, 64, 64, 64, 64, 64, 225, 64, 225, 225, 228, 228, + 64, 64, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 64, 225, 225, + 64, 64, 64, 64, 64, 64, 64, 231, 231, 64, 232, 232, 232, 232, 232, 232, + 232, 232, 64, 232, 232, 232, 64, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 64, 64, 232, 231, 231, 231, + 233, 233, 233, 233, 64, 231, 231, 231, 64, 231, 231, 231, 234, 232, 64, + 64, 64, 64, 64, 64, 64, 64, 231, 232, 232, 233, 233, 64, 64, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 236, 64, + 64, 64, 237, 232, 232, 232, 232, 232, 232, 64, 64, 238, 238, 64, 239, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 64, 64, 64, 239, 239, 239, 239, 239, 239, 239, 239, 64, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 64, 239, 64, 64, 64, 64, + 240, 64, 64, 64, 64, 238, 238, 238, 241, 241, 241, 64, 241, 64, 238, 238, + 238, 238, 238, 238, 238, 238, 64, 64, 238, 238, 242, 64, 64, 64, 64, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 244, 243, 243, 244, 244, 244, 244, 245, 245, 246, 64, 64, 64, 64, + 247, 243, 243, 243, 243, 243, 243, 248, 244, 249, 249, 249, 249, 244, + 244, 244, 250, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, + 250, 64, 64, 64, 64, 64, 252, 252, 64, 252, 64, 64, 252, 252, 64, 252, + 64, 64, 252, 64, 64, 64, 64, 64, 64, 252, 252, 252, 252, 64, 252, 252, + 252, 252, 252, 252, 252, 64, 252, 252, 252, 64, 252, 64, 252, 64, 64, + 252, 252, 64, 252, 252, 252, 252, 253, 252, 252, 253, 253, 253, 253, 254, + 254, 64, 253, 253, 252, 64, 64, 252, 252, 252, 252, 252, 64, 255, 64, + 256, 256, 256, 256, 253, 253, 64, 64, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 64, 64, 252, 252, 252, 252, 258, 259, 259, 259, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 259, + 260, 259, 259, 259, 261, 261, 259, 259, 259, 259, 259, 259, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 259, 261, 259, 261, 259, 264, 265, 266, 265, 266, + 267, 267, 258, 258, 258, 258, 258, 258, 258, 258, 64, 258, 258, 258, 258, + 258, 258, 258, 258, 258, 258, 258, 258, 64, 64, 64, 64, 268, 269, 270, + 271, 270, 270, 270, 270, 270, 269, 269, 269, 269, 270, 267, 269, 270, + 272, 272, 273, 260, 272, 272, 258, 258, 258, 258, 258, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 64, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 64, 259, 259, 259, 259, 259, 259, 259, 259, + 261, 259, 259, 259, 259, 259, 259, 64, 259, 259, 260, 260, 260, 260, 260, + 274, 274, 274, 274, 260, 260, 64, 64, 64, 64, 64, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 276, 276, 277, 277, 277, 277, 276, + 277, 277, 277, 277, 277, 278, 276, 279, 279, 276, 276, 277, 277, 275, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, + 281, 281, 275, 275, 275, 275, 275, 275, 276, 276, 277, 277, 275, 275, + 275, 275, 277, 277, 277, 275, 276, 276, 276, 275, 275, 276, 276, 276, + 276, 276, 276, 276, 275, 275, 275, 277, 277, 277, 277, 275, 275, 275, + 275, 275, 277, 276, 276, 277, 277, 276, 276, 276, 276, 276, 276, 282, + 275, 276, 280, 280, 276, 276, 276, 277, 283, 283, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 64, 284, 64, 64, 64, + 64, 64, 284, 64, 64, 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 84, 286, 285, 285, 285, 287, 287, 287, 287, 287, 287, 287, 287, 288, + 288, 288, 288, 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 64, 289, 289, 289, 289, 64, 64, 289, 289, 289, 289, 289, 289, + 289, 64, 289, 289, 289, 64, 64, 290, 290, 290, 291, 291, 291, 291, 291, + 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, + 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 64, 64, 64, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 293, 64, 64, 64, 64, 64, 64, 294, 294, + 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 64, 64, 64, 295, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 297, 297, 296, 298, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 300, 301, 64, 64, 64, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 84, 84, 84, 303, 303, 303, 64, 64, 64, 64, 64, 64, 64, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 64, 304, 304, 304, + 304, 305, 305, 306, 64, 64, 64, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 308, 308, 309, 84, 84, 64, 310, 310, 310, 310, 310, 310, 310, + 310, 310, 310, 311, 311, 64, 64, 64, 64, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 64, 312, 312, 312, 64, 313, 313, 64, + 64, 64, 64, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 315, 315, 316, 315, 315, 315, 315, 315, 315, 315, 316, 316, 316, 316, + 316, 316, 316, 316, 315, 316, 316, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 317, 315, 318, 318, 318, 319, 318, 318, 318, 320, 314, 321, 64, + 64, 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, 64, 64, 64, 64, 64, + 64, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 64, 64, 64, 64, 64, + 64, 324, 324, 66, 66, 324, 66, 325, 324, 324, 324, 324, 326, 326, 326, + 327, 64, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 64, 64, 64, + 64, 64, 64, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, + 329, 329, 329, 329, 329, 331, 329, 64, 64, 64, 64, 64, 296, 296, 296, + 296, 296, 296, 64, 64, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 64, 64, 64, 333, 333, 333, 334, 334, 334, 334, 333, 333, + 334, 334, 334, 64, 64, 64, 64, 334, 334, 333, 334, 334, 334, 334, 334, + 334, 335, 336, 337, 64, 64, 64, 64, 338, 64, 64, 64, 339, 339, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 341, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 341, 341, 341, 341, 64, 64, 341, 341, 341, 341, 341, + 64, 64, 64, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 64, 64, 64, 64, 343, 343, 343, 343, 343, 343, 343, 343, 343, 342, 342, + 342, 342, 342, 342, 342, 343, 343, 64, 64, 64, 64, 64, 64, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 345, 64, 64, 64, 346, 346, 347, 347, + 347, 347, 347, 347, 347, 347, 348, 348, 348, 348, 348, 348, 348, 348, + 348, 348, 348, 348, 348, 348, 348, 349, 350, 351, 351, 351, 64, 64, 352, + 352, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, 353, + 354, 355, 354, 355, 355, 355, 355, 355, 355, 355, 64, 356, 354, 355, 354, + 354, 355, 355, 355, 355, 355, 355, 355, 355, 354, 354, 354, 354, 354, + 354, 355, 355, 357, 357, 357, 357, 357, 357, 357, 357, 64, 64, 358, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 64, 64, 64, 64, 64, 64, 360, + 360, 360, 360, 360, 360, 360, 361, 360, 360, 360, 360, 360, 360, 64, 64, + 362, 362, 362, 362, 363, 364, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 365, 363, 362, 362, 362, 362, 362, 363, + 362, 363, 363, 363, 363, 363, 362, 363, 366, 364, 364, 364, 364, 364, + 364, 364, 64, 64, 64, 64, 367, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 368, 368, 368, 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 370, 371, 370, 370, 370, 370, 370, 370, 370, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 64, 64, 64, 372, 372, 373, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 373, + 372, 372, 372, 372, 373, 373, 372, 372, 375, 376, 373, 373, 374, 374, + 377, 377, 377, 377, 377, 377, 377, 377, 377, 377, 374, 374, 374, 374, + 374, 374, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 379, 380, 381, 381, 380, 380, 380, 381, 380, 381, 381, 381, + 382, 382, 64, 64, 64, 64, 64, 64, 64, 64, 383, 383, 383, 383, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385, + 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, 386, 386, 385, 385, + 386, 387, 64, 64, 64, 388, 388, 388, 388, 388, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 64, 64, 64, 384, 384, 384, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 392, 392, 392, 392, 392, 392, 393, 393, + 394, 394, 394, 394, 394, 394, 394, 394, 78, 78, 78, 84, 395, 133, 133, + 133, 133, 133, 78, 78, 133, 133, 133, 133, 78, 396, 395, 395, 395, 395, + 395, 395, 395, 397, 397, 397, 397, 133, 397, 397, 397, 397, 396, 396, 78, + 397, 397, 64, 41, 41, 41, 41, 41, 41, 62, 62, 62, 62, 62, 75, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 44, 44, 44, 44, 65, 65, 65, + 65, 65, 41, 41, 41, 41, 41, 398, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 78, 78, 133, 78, 78, + 78, 78, 78, 78, 78, 133, 78, 78, 399, 400, 133, 401, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 64, + 64, 64, 64, 64, 402, 133, 78, 133, 37, 41, 37, 41, 37, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 37, 41, 62, 62, 62, 62, 62, 62, 62, 62, 61, 61, 61, + 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 64, 64, 61, 61, 61, 61, 61, + 61, 64, 64, 64, 61, 64, 61, 64, 61, 64, 61, 403, 403, 403, 403, 403, 403, + 403, 403, 62, 62, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, 63, 62, + 63, 63, 63, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, 63, 63, 63, 62, + 62, 62, 62, 64, 64, 62, 62, 61, 61, 61, 61, 64, 63, 63, 63, 61, 61, 61, + 61, 61, 63, 63, 63, 64, 64, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 403, + 63, 63, 64, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, 405, + 406, 406, 407, 408, 409, 410, 410, 409, 409, 409, 22, 66, 411, 412, 413, + 414, 411, 412, 413, 414, 22, 22, 22, 66, 22, 22, 22, 22, 415, 416, 417, + 418, 419, 420, 421, 21, 422, 423, 422, 422, 423, 22, 66, 66, 66, 28, 35, + 22, 66, 66, 22, 424, 424, 66, 66, 66, 425, 426, 427, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 428, 66, 424, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 404, 405, 405, 405, 405, 405, 64, 64, 64, 64, 64, 405, 405, 405, 405, + 405, 405, 429, 44, 64, 64, 33, 429, 429, 429, 429, 429, 430, 430, 428, + 426, 427, 431, 429, 33, 33, 33, 33, 429, 429, 429, 429, 429, 430, 430, + 428, 426, 427, 64, 44, 44, 44, 44, 44, 64, 64, 64, 247, 247, 247, 247, + 247, 247, 247, 247, 247, 432, 247, 247, 23, 247, 247, 247, 247, 247, 247, + 64, 64, 64, 64, 64, 78, 78, 395, 395, 78, 78, 78, 78, 395, 395, 395, 78, + 78, 433, 433, 433, 433, 78, 433, 433, 433, 395, 395, 78, 133, 78, 395, + 395, 133, 133, 133, 133, 78, 64, 64, 64, 64, 64, 64, 64, 26, 26, 434, 30, + 26, 30, 26, 434, 26, 30, 34, 434, 434, 434, 34, 34, 434, 434, 434, 435, + 26, 434, 30, 26, 428, 434, 434, 434, 434, 434, 26, 26, 26, 30, 30, 26, + 434, 26, 67, 26, 434, 26, 37, 38, 434, 434, 436, 34, 434, 434, 37, 434, + 34, 397, 397, 397, 397, 34, 26, 26, 34, 34, 434, 434, 437, 428, 428, 428, + 428, 434, 34, 34, 34, 34, 26, 428, 26, 26, 41, 274, 438, 438, 438, 36, + 36, 438, 438, 438, 438, 438, 438, 36, 36, 36, 36, 438, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 440, 440, 440, 440, 439, + 439, 440, 440, 440, 440, 440, 440, 440, 440, 440, 37, 41, 440, 440, 440, + 440, 36, 64, 64, 64, 64, 64, 64, 39, 39, 39, 39, 39, 30, 30, 30, 30, 30, + 428, 428, 26, 26, 26, 26, 428, 26, 26, 428, 26, 26, 428, 26, 26, 26, 26, + 26, 26, 26, 428, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 428, 428, 26, 26, 39, 26, 39, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 39, 437, 441, 441, 437, 428, 428, + 39, 441, 437, 437, 441, 437, 437, 428, 39, 428, 441, 430, 442, 428, 441, + 437, 428, 428, 428, 441, 437, 437, 441, 39, 441, 441, 437, 437, 39, 437, + 39, 437, 39, 39, 39, 39, 441, 441, 437, 441, 437, 437, 437, 437, 437, 39, + 39, 39, 39, 428, 437, 428, 437, 441, 441, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 437, 441, 437, 437, 437, 441, 428, 428, 428, 428, 428, + 441, 437, 437, 437, 428, 428, 428, 428, 428, 428, 428, 428, 428, 437, + 441, 39, 437, 428, 441, 441, 441, 441, 437, 437, 441, 441, 428, 428, 441, + 441, 437, 437, 441, 441, 437, 437, 441, 441, 437, 437, 437, 437, 437, + 428, 428, 437, 437, 437, 437, 428, 428, 39, 428, 428, 437, 39, 428, 428, + 428, 428, 428, 428, 428, 428, 437, 437, 428, 39, 437, 437, 437, 428, 428, + 428, 428, 428, 437, 441, 428, 437, 437, 437, 437, 437, 428, 428, 437, + 437, 428, 428, 428, 428, 437, 437, 437, 437, 437, 437, 437, 437, 428, + 428, 437, 437, 437, 437, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, + 437, 437, 26, 26, 26, 26, 26, 26, 26, 443, 444, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 26, 428, 26, 26, 26, 26, 26, 26, 26, 26, 274, 26, 26, 26, + 26, 26, 428, 428, 428, 428, 428, 428, 428, 428, 428, 26, 26, 26, 26, 428, + 428, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 26, 26, 26, + 26, 26, 26, 26, 64, 26, 26, 26, 64, 64, 64, 64, 64, 36, 36, 36, 36, 36, + 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 438, 36, 36, + 36, 36, 36, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, + 26, 26, 26, 30, 30, 30, 30, 26, 26, 30, 30, 26, 30, 30, 30, 30, 30, 26, + 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, 26, 26, 30, 39, 26, + 26, 26, 26, 30, 30, 30, 26, 26, 30, 26, 26, 30, 30, 26, 26, 26, 26, 26, + 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 30, 26, 30, + 26, 30, 26, 30, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, 26, 30, 30, + 30, 30, 26, 30, 30, 26, 39, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, + 26, 274, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 26, 30, 30, 30, 26, 30, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 30, 26, 26, 426, 427, 426, 427, 426, 427, 426, + 427, 426, 427, 426, 427, 426, 427, 36, 36, 438, 438, 438, 438, 438, 438, + 438, 438, 438, 438, 438, 438, 26, 26, 26, 26, 437, 428, 428, 437, 437, + 426, 427, 428, 437, 437, 428, 437, 437, 437, 428, 428, 428, 428, 428, + 437, 437, 437, 437, 428, 428, 428, 428, 428, 437, 437, 437, 428, 428, + 428, 437, 437, 437, 437, 9, 10, 9, 10, 9, 10, 9, 10, 426, 427, 446, 446, + 446, 446, 446, 446, 446, 446, 428, 428, 428, 426, 427, 9, 10, 426, 427, + 426, 427, 426, 427, 426, 427, 426, 427, 428, 428, 437, 437, 437, 437, + 437, 437, 428, 428, 428, 428, 428, 428, 428, 428, 437, 428, 428, 428, + 428, 437, 437, 437, 437, 437, 428, 437, 437, 428, 428, 426, 427, 426, + 427, 437, 428, 428, 428, 428, 437, 428, 437, 437, 437, 428, 428, 437, + 437, 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, 437, 437, 437, + 437, 437, 437, 428, 428, 426, 427, 428, 428, 428, 428, 437, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 437, 428, 437, 437, 437, 437, 428, + 428, 437, 428, 437, 428, 428, 437, 428, 437, 437, 437, 437, 428, 428, + 428, 428, 428, 437, 437, 428, 428, 428, 428, 437, 437, 437, 437, 428, + 437, 437, 428, 428, 437, 437, 428, 428, 428, 428, 437, 437, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 428, 428, 437, 437, 437, 437, 437, + 437, 437, 437, 428, 437, 437, 437, 437, 437, 437, 437, 437, 428, 428, + 428, 428, 428, 437, 428, 437, 428, 428, 428, 437, 437, 437, 437, 437, + 428, 428, 428, 428, 437, 428, 428, 428, 437, 437, 437, 437, 437, 428, + 437, 428, 428, 428, 428, 428, 428, 428, 26, 26, 428, 428, 428, 428, 428, + 428, 64, 64, 64, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30, 64, 64, 64, 64, + 64, 64, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 64, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 64, 37, 41, 37, 37, 37, 41, 41, 37, 41, 37, 41, 37, 41, + 37, 37, 37, 37, 41, 37, 41, 41, 37, 41, 41, 41, 41, 41, 41, 44, 44, 37, + 37, 69, 70, 69, 70, 70, 449, 449, 449, 449, 449, 449, 69, 70, 69, 70, + 450, 450, 450, 69, 70, 64, 64, 64, 64, 64, 451, 451, 451, 451, 452, 451, + 451, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, + 453, 64, 453, 64, 64, 64, 64, 64, 453, 64, 64, 454, 454, 454, 454, 454, + 454, 454, 454, 64, 64, 64, 64, 64, 64, 64, 455, 456, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 457, 77, 77, 77, 77, 77, 77, 77, 77, + 66, 66, 28, 35, 28, 35, 66, 66, 66, 28, 35, 66, 28, 35, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 410, 66, 66, 410, 66, 28, 35, 66, 66, 28, 35, 426, + 427, 426, 427, 426, 427, 426, 427, 66, 66, 66, 66, 66, 45, 66, 66, 410, + 410, 64, 64, 64, 64, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 64, 458, 458, 458, 458, 458, 458, 458, 458, 458, 64, 64, 64, 64, 458, + 458, 458, 458, 458, 458, 64, 64, 459, 459, 459, 459, 459, 459, 459, 459, + 459, 459, 459, 459, 64, 64, 64, 64, 460, 461, 461, 461, 459, 462, 463, + 464, 443, 444, 443, 444, 443, 444, 443, 444, 443, 444, 459, 459, 443, + 444, 443, 444, 443, 444, 443, 444, 465, 466, 467, 467, 459, 464, 464, + 464, 464, 464, 464, 464, 464, 464, 468, 469, 470, 471, 472, 472, 465, + 473, 473, 473, 473, 473, 459, 459, 464, 464, 464, 462, 463, 461, 459, 26, + 64, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 64, 64, 475, 475, 476, 476, 477, + 477, 474, 465, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 461, 473, 479, 479, 478, 64, 64, 64, + 64, 64, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, + 480, 480, 480, 480, 64, 64, 64, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 64, 481, 481, 482, 482, 482, 482, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 480, 480, 480, 64, 64, 64, 64, + 64, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, 484, + 484, 64, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 481, 481, 481, + 481, 481, 481, 485, 485, 485, 485, 485, 485, 485, 485, 459, 486, 486, + 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 483, + 483, 483, 483, 484, 484, 484, 481, 481, 486, 486, 486, 486, 486, 486, + 486, 481, 481, 481, 481, 459, 459, 459, 459, 487, 487, 487, 487, 487, + 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 64, 481, 481, 481, 481, + 481, 481, 481, 459, 459, 459, 459, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 459, 459, 488, 489, 489, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 488, + 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, 489, 489, 489, 489, + 488, 490, 490, 490, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 492, 491, 491, 491, 491, 491, 491, 491, 64, 64, 64, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 64, + 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, 495, 495, 495, 495, + 496, 496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 498, 499, 499, 499, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 497, 497, 64, 64, 64, 64, 72, 75, 72, 75, 72, 75, 501, 77, 79, 79, 79, + 502, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 502, 503, 64, 64, 64, 64, + 64, 64, 64, 77, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, + 506, 507, 507, 507, 507, 507, 507, 47, 47, 47, 47, 47, 47, 47, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 47, 47, 37, 41, 37, 41, 37, 41, 41, 41, 37, + 41, 37, 41, 37, 41, 44, 41, 41, 41, 41, 41, 41, 41, 41, 37, 41, 37, 41, + 37, 37, 41, 45, 508, 508, 37, 41, 37, 41, 64, 37, 41, 37, 41, 64, 64, 64, + 64, 37, 41, 37, 64, 64, 64, 64, 64, 44, 44, 41, 42, 42, 42, 42, 42, 509, + 509, 510, 509, 509, 509, 511, 509, 509, 509, 509, 510, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 512, 512, + 510, 510, 512, 513, 513, 513, 513, 64, 64, 64, 64, 514, 514, 514, 514, + 514, 514, 274, 274, 247, 436, 64, 64, 64, 64, 64, 64, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 516, 516, 516, 516, 517, 517, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, + 517, 517, 517, 517, 517, 517, 519, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 520, 520, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 64, 64, 64, + 64, 64, 64, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 169, 169, + 169, 169, 169, 169, 174, 174, 174, 169, 64, 64, 64, 64, 522, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 524, + 524, 524, 524, 524, 525, 525, 525, 526, 526, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 529, 530, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 531, 287, 287, 287, 287, 287, 64, 64, 64, 532, 532, 532, + 533, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, 534, 535, 533, 533, 532, 532, 532, 532, 533, 533, 532, 533, 533, + 533, 536, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 64, 538, 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, 64, 64, + 64, 64, 537, 537, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 541, + 541, 541, 541, 541, 542, 542, 541, 541, 542, 542, 541, 541, 64, 540, 540, + 540, 541, 540, 540, 540, 540, 540, 540, 540, 540, 541, 542, 64, 64, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 64, 64, 544, 544, 544, 544, + 545, 275, 275, 275, 275, 275, 275, 283, 283, 283, 275, 276, 64, 64, 64, + 64, 546, 546, 546, 546, 546, 546, 546, 546, 547, 546, 547, 547, 548, 546, + 546, 547, 547, 546, 546, 546, 546, 546, 547, 547, 546, 547, 546, 64, 64, + 64, 64, 64, 64, 64, 64, 546, 546, 549, 550, 550, 551, 551, 551, 551, 551, + 551, 551, 551, 551, 551, 551, 552, 553, 553, 552, 552, 554, 554, 551, + 555, 555, 552, 556, 64, 64, 289, 289, 289, 289, 289, 289, 64, 551, 551, + 551, 552, 552, 553, 552, 552, 553, 552, 552, 554, 552, 556, 64, 64, 557, + 557, 557, 557, 557, 557, 557, 557, 557, 557, 64, 64, 64, 64, 64, 64, 287, + 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 287, 64, 64, 64, 64, 288, 288, 288, 288, 288, 288, + 288, 64, 64, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288, 64, 64, + 64, 64, 559, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 559, + 560, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 560, 488, 488, 488, 488, + 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 490, 490, 488, 488, + 490, 490, 490, 490, 490, 490, 41, 41, 41, 41, 41, 41, 41, 64, 64, 64, 64, + 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 109, 562, 109, 109, 563, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 64, 109, 109, + 109, 109, 109, 64, 109, 64, 109, 109, 64, 109, 109, 64, 109, 109, 123, + 123, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, + 564, 564, 564, 64, 64, 64, 64, 64, 64, 64, 64, 64, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 413, 565, 64, 64, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 114, 26, 64, 64, 58, 58, 58, 58, 58, 58, + 58, 58, 461, 461, 461, 461, 461, 461, 461, 466, 467, 461, 64, 64, 64, 64, + 64, 64, 461, 465, 465, 566, 566, 466, 467, 466, 467, 466, 467, 466, 467, + 466, 467, 466, 467, 466, 467, 466, 467, 461, 461, 466, 467, 461, 461, + 461, 461, 566, 566, 566, 567, 461, 567, 64, 461, 567, 461, 461, 465, 443, + 444, 443, 444, 443, 444, 568, 461, 461, 569, 570, 571, 571, 572, 64, 461, + 573, 568, 461, 64, 64, 64, 64, 123, 123, 123, 123, 123, 64, 123, 123, + 123, 123, 123, 123, 123, 64, 64, 405, 64, 574, 574, 575, 576, 575, 574, + 574, 577, 578, 574, 579, 580, 581, 580, 580, 582, 582, 582, 582, 582, + 582, 582, 582, 582, 582, 580, 574, 583, 584, 583, 574, 574, 585, 585, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, + 585, 585, 577, 574, 578, 586, 587, 586, 588, 588, 588, 588, 588, 588, + 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 577, 584, + 578, 584, 577, 578, 589, 590, 591, 589, 589, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 593, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 593, 593, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 64, 64, 64, 594, 594, 594, 594, + 594, 594, 64, 64, 594, 594, 594, 64, 64, 64, 576, 576, 584, 586, 595, + 576, 576, 64, 596, 597, 597, 597, 597, 596, 596, 64, 64, 598, 598, 598, + 26, 30, 64, 64, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, + 599, 64, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 64, 599, 599, + 599, 64, 599, 599, 64, 599, 599, 599, 599, 599, 599, 599, 64, 64, 599, + 599, 599, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64, 64, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, 64, 64, 64, 274, 600, + 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 601, + 601, 601, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 601, 64, 64, 64, 64, 64, 274, 274, 274, 274, + 274, 133, 64, 64, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 64, 64, 64, 604, 604, 604, 604, 604, 604, 604, 604, 604, 64, + 64, 64, 64, 64, 64, 64, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 64, 606, 606, 606, 606, 64, 64, 64, 64, 607, + 607, 607, 607, 607, 607, 607, 607, 607, 608, 607, 607, 607, 607, 607, + 607, 607, 607, 608, 64, 64, 64, 64, 64, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 64, 610, 611, 611, 611, 611, 611, + 611, 611, 611, 611, 611, 611, 611, 64, 64, 64, 64, 612, 613, 613, 613, + 613, 613, 64, 64, 614, 614, 614, 614, 614, 614, 614, 614, 615, 615, 615, + 615, 615, 615, 615, 615, 616, 616, 616, 616, 616, 616, 616, 616, 617, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 64, 64, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 64, 64, 64, 64, 64, 64, + 619, 619, 619, 619, 619, 619, 64, 64, 619, 64, 619, 619, 619, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 64, 619, 619, 64, 64, 64, 619, 64, 64, 619, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 64, 621, 622, 622, 622, 622, + 622, 622, 622, 622, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 624, 624, 624, 624, 624, 624, 64, 64, 64, 625, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 64, 64, 64, 64, 64, 627, + 628, 628, 628, 628, 628, 628, 628, 628, 629, 629, 629, 629, 629, 629, + 629, 629, 64, 64, 64, 64, 64, 64, 629, 629, 630, 631, 631, 631, 64, 631, + 631, 64, 64, 64, 64, 64, 631, 632, 631, 633, 630, 630, 630, 630, 64, 630, + 630, 630, 64, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, + 630, 630, 630, 630, 630, 630, 630, 64, 64, 64, 64, 633, 634, 632, 64, 64, + 64, 64, 635, 636, 636, 636, 636, 636, 636, 636, 636, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 64, 64, 64, 64, 64, 64, 64, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 638, 638, 638, 639, 639, 640, 641, 641, + 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, 64, 64, 64, + 642, 642, 642, 642, 642, 642, 642, 643, 643, 643, 643, 643, 643, 643, + 643, 643, 643, 643, 643, 643, 643, 64, 64, 644, 644, 644, 644, 644, 644, + 644, 644, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, 64, 64, + 64, 64, 64, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, 647, + 647, 647, 647, 647, 647, 64, 64, 64, 64, 64, 64, 64, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 64, 649, 650, 649, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 652, + 653, 653, 653, 653, 653, 653, 653, 64, 64, 64, 64, 654, 654, 654, 654, + 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, 654, + 654, 654, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 656, 656, + 657, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, 658, + 657, 657, 657, 656, 656, 656, 656, 657, 657, 659, 660, 661, 661, 662, + 661, 661, 661, 661, 64, 64, 64, 64, 64, 64, 663, 663, 663, 663, 663, 663, + 663, 663, 663, 64, 64, 64, 64, 64, 64, 64, 664, 664, 664, 664, 664, 664, + 664, 664, 664, 664, 64, 64, 64, 64, 64, 64, 665, 665, 665, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 667, 667, 667, 667, 667, 668, 667, 667, 667, 667, 667, + 667, 669, 669, 64, 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, 671, + 671, 671, 671, 64, 64, 64, 64, 672, 672, 673, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, 673, 673, 673, + 672, 672, 672, 672, 672, 672, 672, 672, 672, 673, 675, 674, 674, 674, + 674, 676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 677, 64, 64, 64, 64, 64, 64, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 679, 680, 679, 680, 680, 679, 679, + 679, 679, 679, 679, 681, 682, 683, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 64, 64, 64, 64, 64, 64, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 64, 685, 685, 685, 685, 685, 685, 685, + 685, 685, 685, 685, 64, 64, 64, 64, 64, 686, 686, 686, 686, 64, 64, 64, + 64, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, + 687, 64, 504, 64, 64, 64, 64, 64, 64, 64, 688, 688, 688, 688, 688, 688, + 688, 688, 688, 688, 688, 688, 688, 64, 64, 64, 688, 689, 689, 689, 689, + 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, + 689, 689, 689, 689, 64, 64, 64, 64, 64, 64, 64, 64, 690, 690, 690, 690, + 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, 478, + 474, 64, 64, 64, 64, 64, 64, 274, 274, 274, 274, 274, 274, 64, 64, 274, + 274, 274, 274, 274, 274, 274, 64, 64, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 692, 692, 395, 395, 395, 274, 274, 274, 693, + 692, 692, 692, 692, 692, 405, 405, 405, 405, 405, 405, 405, 405, 133, + 133, 133, 133, 133, 133, 133, 133, 274, 274, 78, 78, 78, 78, 78, 133, + 133, 274, 274, 274, 274, 274, 274, 78, 78, 78, 78, 274, 274, 602, 602, + 694, 694, 694, 602, 64, 64, 514, 514, 64, 64, 64, 64, 64, 64, 434, 434, + 434, 434, 434, 434, 434, 434, 434, 434, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, 434, 434, + 434, 434, 434, 434, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34, + 34, 434, 64, 434, 434, 64, 64, 434, 64, 64, 434, 434, 64, 64, 434, 434, + 434, 434, 64, 434, 434, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34, + 64, 34, 34, 34, 34, 34, 34, 34, 434, 434, 64, 434, 434, 434, 434, 64, 64, + 434, 434, 434, 434, 434, 434, 434, 434, 64, 434, 434, 434, 434, 434, 434, + 434, 64, 34, 34, 434, 434, 64, 434, 434, 434, 434, 64, 434, 434, 434, + 434, 434, 64, 434, 64, 64, 64, 434, 434, 434, 434, 434, 434, 434, 64, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 64, 64, 434, 695, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 437, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, + 434, 434, 434, 434, 434, 695, 34, 34, 34, 34, 34, 34, 34, 34, 34, 437, + 34, 34, 434, 434, 434, 434, 434, 695, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 437, 34, 34, 34, 34, 34, 34, 434, 434, 434, 434, 434, 434, 434, 434, 434, + 695, 34, 437, 34, 34, 34, 34, 34, 34, 34, 34, 434, 34, 64, 64, 696, 696, + 696, 696, 696, 696, 696, 696, 696, 696, 123, 123, 123, 123, 64, 123, 123, + 123, 64, 123, 123, 64, 123, 64, 64, 123, 64, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 64, 123, 123, 123, 123, 64, 123, 64, 123, 64, + 64, 64, 64, 64, 64, 123, 64, 64, 64, 64, 123, 64, 123, 64, 123, 64, 123, + 123, 123, 64, 123, 64, 123, 64, 123, 64, 123, 64, 123, 123, 123, 123, 64, + 123, 64, 123, 123, 64, 123, 123, 123, 123, 123, 123, 123, 123, 123, 64, + 64, 64, 64, 64, 123, 123, 123, 64, 123, 123, 123, 111, 111, 64, 64, 64, + 64, 64, 64, 33, 33, 33, 64, 64, 64, 64, 64, 445, 445, 445, 445, 445, 445, + 274, 64, 445, 445, 26, 26, 64, 64, 64, 64, 445, 445, 445, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 274, 274, 697, 481, 481, 64, 64, 64, 64, 64, + 481, 481, 481, 64, 64, 64, 64, 64, 481, 64, 64, 64, 64, 64, 64, 64, 481, + 481, 64, 64, 64, 64, 64, 64, 26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, + 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 64, 64, 26, 26, 26, 26, 26, + 64, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26, 26, 64, 64, + 64, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, + 64, 64, 64, 64, 26, 26, 26, 489, 489, 489, 489, 489, 489, 488, 490, 490, + 490, 490, 490, 490, 490, 64, 64, 64, 405, 64, 64, 64, 64, 64, 64, 405, + 405, 405, 405, 405, 405, 405, 405, 561, 561, 561, 561, 561, 560, 64, 64, + ]; +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Utils/Arrays.php b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/Arrays.php new file mode 100644 index 0000000..f27c83a --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/Arrays.php @@ -0,0 +1,92 @@ +<?php + +namespace Mpdf\Utils; + +class Arrays +{ + + public static function get($array, $key, $default = null) + { + if (is_array($array) && array_key_exists($key, $array)) { + return $array[$key]; + } + + if (func_num_args() < 3) { + throw new \InvalidArgumentException(sprintf('Array does not contain key "%s"', $key)); + } + + return $default; + } + + /** + * Returns an array of all k-combinations from an input array of n elements, where k equals 1..n. + * Elements will be sorted and unique in every combination. + * + * Example: array[one, two] will give: + * [ + * [one], + * [two], + * [one, two] + * ] + * @param array $array + * @return array + */ + public static function allUniqueSortedCombinations($array) + { + $input = array_unique($array); + if (count($input) <= 1) { + return [$input]; + } + + sort($input); + $combinations = []; + foreach ($input as $value) { + $combinations[] = [$value]; + } + + $n = count($input); + for ($k = 2; $k <= $n; $k++) { + $combinations = array_merge($combinations, self::combinations($input, $k)); + } + + return $combinations; + } + + /** + * Returns an array of unique k-combinations from an input array. + * + * Example: array=[one, two, three] and k=2 will give: + * [ + * [one, two], + * [one, three] + * ] + * @param array $array + * @param int $k + * @return array + */ + public static function combinations($array, $k) + { + $n = count($array); + $combinations = []; + $indexes = range(0, $k - 1); + $maxIndexes = range($n - $k, $n - 1); + do { + $combination = []; + foreach ($indexes as $index) { + $combination[] = $array[$index]; + } + $combinations[] = $combination; + + $anotherCombination = false; + for ($i = $k - 1; $i >= 0; $i--) { + if ($indexes[$i] < $maxIndexes[$i]) { + $indexes[$i]++; + $anotherCombination = true; + break; + } + } + } while ($anotherCombination); + + return $combinations; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Utils/NumericString.php b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/NumericString.php new file mode 100644 index 0000000..db10287 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/NumericString.php @@ -0,0 +1,18 @@ +<?php + +namespace Mpdf\Utils; + +class NumericString +{ + + public static function containsPercentChar($string) + { + return strstr($string, '%'); + } + + public static function removePercentChar($string) + { + return str_replace('%', '', $string); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Utils/PdfDate.php b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/PdfDate.php new file mode 100644 index 0000000..1fc3900 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/PdfDate.php @@ -0,0 +1,30 @@ +<?php + +namespace Mpdf\Utils; + +class PdfDate +{ + + /** + * PDF documents use the internal date format: (D:YYYYMMDDHHmmSSOHH'mm'). The date format has these parts: + * + * YYYY The full four-digit year. (For example, 2004) + * MM The month from 01 to 12. + * DD The day from 01 to 31. + * HH The hour from 00 to 23. + * mm The minute from 00 to 59. + * SS The seconds from 00 to 59. + * O The relationship of local time to Universal Time (UT), as denoted by one of the characters +, -, or Z. + * HH The absolute value of the offset from UT in hours specified as 00 to 23. + * mm The absolute value of the offset from UT in minutes specified as 00 to 59. + * + * @return string + */ + public static function format($date) + { + $z = date('O'); // +0200 + $offset = substr($z, 0, 3) . "'" . substr($z, 3, 2) . "'"; // +02'00' + return date('YmdHis', $date) . $offset; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Utils/UtfString.php b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/UtfString.php new file mode 100644 index 0000000..8b5c8c9 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Utils/UtfString.php @@ -0,0 +1,67 @@ +<?php + +namespace Mpdf\Utils; + +class UtfString +{ + + /** + * Converts all the &#nnn; and &#xhhh; in a string to Unicode + * + * @since mPDF 5.7 + * @param string $str + * @param bool $lo + * + * @return string + */ + public static function strcode2utf($str, $lo = true) + { + $str = preg_replace_callback('/\&\#(\d+)\;/m', function ($matches) use ($lo) { + return static::code2utf($matches[1], $lo ? 1 : 0); + }, $str); + $str = preg_replace_callback('/\&\#x([0-9a-fA-F]+)\;/m', function ($matches) use ($lo) { + return static::codeHex2utf($matches[1], $lo ? 1 : 0); + }, $str); + + return $str; + } + + /** + * @param int $num + * @param bool $lo + * + * @return string + */ + public static function code2utf($num, $lo = true) + { + // Returns the utf string corresponding to the unicode value + if ($num < 128) { + if ($lo) { + return chr($num); + } + return '&#' . $num . ';'; + } + if ($num < 2048) { + return chr(($num >> 6) + 192) . chr(($num & 63) + 128); + } + if ($num < 65536) { + return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128); + } + if ($num < 2097152) { + return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128); + } + + return '?'; + } + + public static function codeHex2utf($hex, $lo = true) + { + $num = hexdec($hex); + if (($num < 128) && !$lo) { + return '&#x' . $hex . ';'; + } + + return static::code2utf($num, $lo); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BackgroundWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BackgroundWriter.php new file mode 100644 index 0000000..6dbce84 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BackgroundWriter.php @@ -0,0 +1,451 @@ +<?php + +namespace Mpdf\Writer; + +use Mpdf\Strict; +use Mpdf\Mpdf; + +final class BackgroundWriter +{ + + use Strict; + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Mpdf\Writer\BaseWriter + */ + private $writer; + + public function __construct(Mpdf $mpdf, BaseWriter $writer) + { + $this->mpdf = $mpdf; + $this->writer = $writer; + } + + public function writePatterns() // _putpatterns + { + $patternCount = count($this->mpdf->patterns); + + for ($i = 1; $i <= $patternCount; $i++) { + + $x = $this->mpdf->patterns[$i]['x']; + $y = $this->mpdf->patterns[$i]['y']; + $w = $this->mpdf->patterns[$i]['w']; + $h = $this->mpdf->patterns[$i]['h']; + $pgh = $this->mpdf->patterns[$i]['pgh']; + $orig_w = $this->mpdf->patterns[$i]['orig_w']; + $orig_h = $this->mpdf->patterns[$i]['orig_h']; + $image_id = $this->mpdf->patterns[$i]['image_id']; + $itype = $this->mpdf->patterns[$i]['itype']; + + if (isset($this->mpdf->patterns[$i]['bpa'])) { + $bpa = $this->mpdf->patterns[$i]['bpa']; + } else { + $bpa = []; // background positioning area + } + + if ($this->mpdf->patterns[$i]['x_repeat']) { + $x_repeat = true; + } else { + $x_repeat = false; + } + + if ($this->mpdf->patterns[$i]['y_repeat']) { + $y_repeat = true; + } else { + $y_repeat = false; + } + + $x_pos = $this->mpdf->patterns[$i]['x_pos']; + + if (false !== strpos($x_pos, '%')) { + $x_pos = (float) $x_pos; + $x_pos /= 100; + + if (isset($bpa['w']) && $bpa['w']) { + $x_pos = ($bpa['w'] * $x_pos) - ($orig_w / Mpdf::SCALE * $x_pos); + } else { + $x_pos = ($w * $x_pos) - ($orig_w / Mpdf::SCALE * $x_pos); + } + } + + $y_pos = $this->mpdf->patterns[$i]['y_pos']; + + if (false !== strpos($y_pos, '%')) { + $y_pos = (float) $y_pos; + $y_pos /= 100; + + if (isset($bpa['h']) && $bpa['h']) { + $y_pos = ($bpa['h'] * $y_pos) - ($orig_h / Mpdf::SCALE * $y_pos); + } else { + $y_pos = ($h * $y_pos) - ($orig_h / Mpdf::SCALE * $y_pos); + } + } + + if (isset($bpa['x']) && $bpa['x']) { + $adj_x = ($x_pos + $bpa['x']) * Mpdf::SCALE; + } else { + $adj_x = ($x_pos + $x) * Mpdf::SCALE; + } + + if (isset($bpa['y']) && $bpa['y']) { + $adj_y = (($pgh - $y_pos - $bpa['y']) * Mpdf::SCALE) - $orig_h; + } else { + $adj_y = (($pgh - $y_pos - $y) * Mpdf::SCALE) - $orig_h; + } + + $img_obj = false; + + if ($itype === 'svg' || $itype === 'wmf') { + foreach ($this->mpdf->formobjects as $fo) { + if ($fo['i'] == $image_id) { + $img_obj = $fo['n']; + $fo_w = $fo['w']; + $fo_h = -$fo['h']; + $wmf_x = $fo['x']; + $wmf_y = $fo['y']; + break; + } + } + } else { + foreach ($this->mpdf->images as $img) { + if ($img['i'] == $image_id) { + $img_obj = $img['n']; + break; + } + } + } + + if (!$img_obj) { + throw new \Mpdf\MpdfException('Problem: Image object not found for background pattern ' . $img['i']); + } + + $this->writer->object(); + $this->writer->write('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); + + if ($itype === 'svg' || $itype === 'wmf') { + $this->writer->write('/XObject <</FO' . $image_id . ' ' . $img_obj . ' 0 R >>'); + + // ******* ADD ANY ExtGStates, Shading AND Fonts needed for the FormObject + // Set in classes/svg array['fo'] = true + // Required that _putshaders comes before _putpatterns in _putresources + // This adds any resources associated with any FormObject to every Formobject - overkill but works! + if (count($this->mpdf->extgstates)) { + $this->writer->write('/ExtGState <<'); + foreach ($this->mpdf->extgstates as $k => $extgstate) { + if (isset($extgstate['fo']) && $extgstate['fo']) { + if (isset($extgstate['trans'])) { + $this->writer->write('/' . $extgstate['trans'] . ' ' . $extgstate['n'] . ' 0 R'); + } else { + $this->writer->write('/GS' . $k . ' ' . $extgstate['n'] . ' 0 R'); + } + } + } + $this->writer->write('>>'); + } + + /* -- BACKGROUNDS -- */ + if (isset($this->mpdf->gradients) && ( count($this->mpdf->gradients) > 0)) { + $this->writer->write('/Shading <<'); + foreach ($this->mpdf->gradients as $id => $grad) { + if (isset($grad['fo']) && $grad['fo']) { + $this->writer->write('/Sh' . $id . ' ' . $grad['id'] . ' 0 R'); + } + } + $this->writer->write('>>'); + } + + /* -- END BACKGROUNDS -- */ + $this->writer->write('/Font <<'); + + foreach ($this->mpdf->fonts as $font) { + if (!$font['used'] && $font['type'] === 'TTF') { + continue; + } + if (isset($font['fo']) && $font['fo']) { + if ($font['type'] === 'TTF' && ($font['sip'] || $font['smp'])) { + foreach ($font['n'] as $k => $fid) { + $this->writer->write('/F' . $font['subsetfontids'][$k] . ' ' . $font['n'][$k] . ' 0 R'); + } + } else { + $this->writer->write('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); + } + } + } + $this->writer->write('>>'); + } else { + $this->writer->write('/XObject <</I' . $image_id . ' ' . $img_obj . ' 0 R >>'); + } + + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $this->writer->object(); + $this->mpdf->patterns[$i]['n'] = $this->mpdf->n; + $this->writer->write('<< /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 2'); + $this->writer->write('/Resources ' . ($this->mpdf->n - 1) . ' 0 R'); + + $this->writer->write(sprintf('/BBox [0 0 %.3F %.3F]', $orig_w, $orig_h)); + + if ($x_repeat) { + $this->writer->write(sprintf('/XStep %.3F', $orig_w)); + } else { + $this->writer->write(sprintf('/XStep %d', 99999)); + } + + if ($y_repeat) { + $this->writer->write(sprintf('/YStep %.3F', $orig_h)); + } else { + $this->writer->write(sprintf('/YStep %d', 99999)); + } + + if ($itype === 'svg' || $itype === 'wmf') { + $this->writer->write(sprintf('/Matrix [1 0 0 -1 %.3F %.3F]', $adj_x, $adj_y + $orig_h)); + $s = sprintf('q %.3F 0 0 %.3F %.3F %.3F cm /FO%d Do Q', $orig_w / $fo_w, -$orig_h / $fo_h, -($orig_w / $fo_w) * $wmf_x, ($orig_w / $fo_w) * $wmf_y, $image_id); + } else { + $this->writer->write(sprintf('/Matrix [1 0 0 1 %.3F %.3F]', $adj_x, $adj_y)); + $s = sprintf('q %.3F 0 0 %.3F 0 0 cm /I%d Do Q', $orig_w, $orig_h, $image_id); + } + + if ($this->mpdf->compress) { + $this->writer->write('/Filter /FlateDecode'); + $s = gzcompress($s); + } + $this->writer->write('/Length ' . strlen($s) . '>>'); + $this->writer->stream($s); + $this->writer->write('endobj'); + } + } + + public function writeShaders() // _putshaders + { + $maxid = count($this->mpdf->gradients); // index for transparency gradients + + foreach ($this->mpdf->gradients as $id => $grad) { + + if (empty($grad['is_mask']) && ($grad['type'] == 2 || $grad['type'] == 3)) { + + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/FunctionType 3'); + $this->writer->write('/Domain [0 1]'); + + $fn = []; + $bd = []; + $en = []; + + for ($i = 0; $i < (count($grad['stops']) - 1); $i++) { + $fn[] = ($this->mpdf->n + 1 + $i) . ' 0 R'; + $en[] = '0 1'; + if ($i > 0) { + $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); + } + } + + $this->writer->write('/Functions [' . implode(' ', $fn) . ']'); + $this->writer->write('/Bounds [' . implode(' ', $bd) . ']'); + $this->writer->write('/Encode [' . implode(' ', $en) . ']'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $f1 = $this->mpdf->n; + + for ($i = 0; $i < (count($grad['stops']) - 1); $i++) { + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/FunctionType 2'); + $this->writer->write('/Domain [0 1]'); + $this->writer->write('/C0 [' . $grad['stops'][$i]['col'] . ']'); + $this->writer->write('/C1 [' . $grad['stops'][$i + 1]['col'] . ']'); + $this->writer->write('/N 1'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + } + + if ($grad['type'] == 2 || $grad['type'] == 3) { + + if (isset($grad['trans']) && $grad['trans']) { + + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/FunctionType 3'); + $this->writer->write('/Domain [0 1]'); + + $fn = []; + $bd = []; + $en = []; + + for ($i = 0; $i < (count($grad['stops']) - 1); $i++) { + $fn[] = ($this->mpdf->n + 1 + $i) . ' 0 R'; + $en[] = '0 1'; + if ($i > 0) { + $bd[] = sprintf('%.3F', $grad['stops'][$i]['offset']); + } + } + + $this->writer->write('/Functions [' . implode(' ', $fn) . ']'); + $this->writer->write('/Bounds [' . implode(' ', $bd) . ']'); + $this->writer->write('/Encode [' . implode(' ', $en) . ']'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $f2 = $this->mpdf->n; + + for ($i = 0; $i < (count($grad['stops']) - 1); $i++) { + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/FunctionType 2'); + $this->writer->write('/Domain [0 1]'); + $this->writer->write(sprintf('/C0 [%.3F]', $grad['stops'][$i]['opacity'])); + $this->writer->write(sprintf('/C1 [%.3F]', $grad['stops'][$i + 1]['opacity'])); + $this->writer->write('/N 1'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + } + } + + if (empty($grad['is_mask'])) { + + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/ShadingType ' . $grad['type']); + + if (isset($grad['colorspace'])) { + $this->writer->write('/ColorSpace /Device' . $grad['colorspace']); // Can use CMYK if all C0 and C1 above have 4 values + } else { + $this->writer->write('/ColorSpace /DeviceRGB'); + } + + if ($grad['type'] == 2) { + $this->writer->write(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3])); + $this->writer->write('/Function ' . $f1 . ' 0 R'); + $this->writer->write('/Extend [' . $grad['extend'][0] . ' ' . $grad['extend'][1] . '] '); + $this->writer->write('>>'); + } elseif ($grad['type'] == 3) { + // x0, y0, r0, x1, y1, r1 + // at this this time radius of inner circle is 0 + $ir = 0; + if (isset($grad['coords'][5]) && $grad['coords'][5]) { + $ir = $grad['coords'][5]; + } + $this->writer->write(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4])); + $this->writer->write('/Function ' . $f1 . ' 0 R'); + $this->writer->write('/Extend [' . $grad['extend'][0] . ' ' . $grad['extend'][1] . '] '); + $this->writer->write('>>'); + } elseif ($grad['type'] == 6) { + $this->writer->write('/BitsPerCoordinate 16'); + $this->writer->write('/BitsPerComponent 8'); + if ($grad['colorspace'] === 'CMYK') { + $this->writer->write('/Decode[0 1 0 1 0 1 0 1 0 1 0 1]'); + } elseif ($grad['colorspace'] === 'Gray') { + $this->writer->write('/Decode[0 1 0 1 0 1]'); + } else { + $this->writer->write('/Decode[0 1 0 1 0 1 0 1 0 1]'); + } + $this->writer->write('/BitsPerFlag 8'); + $this->writer->write('/Length ' . strlen($grad['stream'])); + $this->writer->write('>>'); + $this->writer->stream($grad['stream']); + } + + $this->writer->write('endobj'); + } + + $this->mpdf->gradients[$id]['id'] = $this->mpdf->n; + + // set pattern object + $this->writer->object(); + $out = '<< /Type /Pattern /PatternType 2'; + $out .= ' /Shading ' . $this->mpdf->gradients[$id]['id'] . ' 0 R'; + $out .= ' >>'; + $out .= "\n" . 'endobj'; + $this->writer->write($out); + + + $this->mpdf->gradients[$id]['pattern'] = $this->mpdf->n; + + if (isset($grad['trans']) && $grad['trans']) { + + // luminosity pattern + $transid = $id + $maxid; + + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/ShadingType ' . $grad['type']); + $this->writer->write('/ColorSpace /DeviceGray'); + + if ($grad['type'] == 2) { + $this->writer->write(sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3])); + $this->writer->write('/Function ' . $f2 . ' 0 R'); + $this->writer->write('/Extend [' . $grad['extend'][0] . ' ' . $grad['extend'][1] . '] '); + $this->writer->write('>>'); + } elseif ($grad['type'] == 3) { + // x0, y0, r0, x1, y1, r1 + // at this this time radius of inner circle is 0 + $ir = 0; + if (isset($grad['coords'][5]) && $grad['coords'][5]) { + $ir = $grad['coords'][5]; + } + $this->writer->write(sprintf('/Coords [%.3F %.3F %.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $ir, $grad['coords'][2], $grad['coords'][3], $grad['coords'][4])); + $this->writer->write('/Function ' . $f2 . ' 0 R'); + $this->writer->write('/Extend [' . $grad['extend'][0] . ' ' . $grad['extend'][1] . '] '); + $this->writer->write('>>'); + } elseif ($grad['type'] == 6) { + $this->writer->write('/BitsPerCoordinate 16'); + $this->writer->write('/BitsPerComponent 8'); + $this->writer->write('/Decode[0 1 0 1 0 1]'); + $this->writer->write('/BitsPerFlag 8'); + $this->writer->write('/Length ' . strlen($grad['stream_trans'])); + $this->writer->write('>>'); + $this->writer->stream($grad['stream_trans']); + } + $this->writer->write('endobj'); + + $this->mpdf->gradients[$transid]['id'] = $this->mpdf->n; + + $this->writer->object(); + $this->writer->write('<< /Type /Pattern /PatternType 2'); + $this->writer->write('/Shading ' . $this->mpdf->gradients[$transid]['id'] . ' 0 R'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $this->mpdf->gradients[$transid]['pattern'] = $this->mpdf->n; + $this->writer->object(); + + // Need to extend size of viewing box in case of transformations + $str = 'q /a0 gs /Pattern cs /p' . $transid . ' scn -' . ($this->mpdf->wPt / 2) . ' -' . ($this->mpdf->hPt / 2) . ' ' . (2 * $this->mpdf->wPt) . ' ' . (2 * $this->mpdf->hPt) . ' re f Q'; + $filter = ($this->mpdf->compress) ? '/Filter /FlateDecode ' : ''; + $p = ($this->mpdf->compress) ? gzcompress($str) : $str; + + $this->writer->write('<< /Type /XObject /Subtype /Form /FormType 1 ' . $filter); + $this->writer->write('/Length ' . strlen($p)); + $this->writer->write('/BBox [-' . ($this->mpdf->wPt / 2) . ' -' . ($this->mpdf->hPt / 2) . ' ' . (2 * $this->mpdf->wPt) . ' ' . (2 * $this->mpdf->hPt) . ']'); + $this->writer->write('/Group << /Type /Group /S /Transparency /CS /DeviceGray >>'); + $this->writer->write('/Resources <<'); + $this->writer->write('/ExtGState << /a0 << /ca 1 /CA 1 >> >>'); + $this->writer->write('/Pattern << /p' . $transid . ' ' . $this->mpdf->gradients[$transid]['pattern'] . ' 0 R >>'); + $this->writer->write('>>'); + $this->writer->write('>>'); + $this->writer->stream($p); + $this->writer->write('endobj'); + $this->writer->object(); + $this->writer->write('<< /Type /Mask /S /Luminosity /G ' . ($this->mpdf->n - 1) . ' 0 R >>' . "\n" . 'endobj'); + $this->writer->object(); + $this->writer->write('<< /Type /ExtGState /SMask ' . ($this->mpdf->n - 1) . ' 0 R /AIS false >>' . "\n" . 'endobj'); + + if (isset($grad['fo']) && $grad['fo']) { + $this->mpdf->extgstates[] = ['n' => $this->mpdf->n, 'trans' => 'TGS' . $id, 'fo' => true]; + } else { + $this->mpdf->extgstates[] = ['n' => $this->mpdf->n, 'trans' => 'TGS' . $id]; + } + } + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BaseWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BaseWriter.php new file mode 100644 index 0000000..8abff91 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BaseWriter.php @@ -0,0 +1,250 @@ +<?php + +namespace Mpdf\Writer; + +use Mpdf\Strict; + +use Mpdf\Mpdf; +use Mpdf\Pdf\Protection; + +final class BaseWriter +{ + + use Strict; + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Mpdf\Pdf\Protection + */ + private $protection; + + public function __construct(Mpdf $mpdf, Protection $protection) + { + $this->mpdf = $mpdf; + $this->protection = $protection; + } + + public function write($s, $ln = true) + { + if ($this->mpdf->state === 2) { + $this->endPage($s, $ln); + } else { + $this->mpdf->buffer .= $s . ($ln ? "\n" : ''); + } + } + + public function string($s) + { + if ($this->mpdf->encrypted) { + $s = $this->protection->rc4($this->protection->objectKey($this->mpdf->currentObjectNumber), $s); + } + + return '(' . $this->escape($s) . ')'; + } + + public function object($obj_id = false, $onlynewobj = false) + { + if (!$obj_id) { + $obj_id = ++$this->mpdf->n; + } + + // Begin a new object + if (!$onlynewobj) { + $this->mpdf->offsets[$obj_id] = strlen($this->mpdf->buffer); + $this->write($obj_id . ' 0 obj'); + $this->mpdf->currentObjectNumber = $obj_id; // for later use with encryption + } + } + + public function stream($s) + { + if ($this->mpdf->encrypted) { + $s = $this->protection->rc4($this->protection->objectKey($this->mpdf->currentObjectNumber), $s); + } + + $this->write('stream'); + $this->write($s); + $this->write('endstream'); + } + + public function utf16BigEndianTextString($s) // _UTF16BEtextstring + { + $s = $this->utf8ToUtf16BigEndian($s, true); + if ($this->mpdf->encrypted) { + $s = $this->protection->rc4($this->protection->objectKey($this->mpdf->currentObjectNumber), $s); + } + + return '(' . $this->escape($s) . ')'; + } + + // Converts UTF-8 strings to UTF16-BE. + public function utf8ToUtf16BigEndian($str, $setbom = true) // UTF8ToUTF16BE + { + if ($this->mpdf->checkSIP && preg_match("/([\x{20000}-\x{2FFFF}])/u", $str)) { + if (!in_array($this->mpdf->currentfontfamily, ['gb', 'big5', 'sjis', 'uhc', 'gbB', 'big5B', 'sjisB', 'uhcB', 'gbI', 'big5I', 'sjisI', 'uhcI', + 'gbBI', 'big5BI', 'sjisBI', 'uhcBI'])) { + $str = preg_replace("/[\x{20000}-\x{2FFFF}]/u", chr(0), $str); + } + } + if ($this->mpdf->checkSMP && preg_match("/([\x{10000}-\x{1FFFF}])/u", $str)) { + $str = preg_replace("/[\x{10000}-\x{1FFFF}]/u", chr(0), $str); + } + + $outstr = ''; // string to be returned + if ($setbom) { + $outstr .= "\xFE\xFF"; // Byte Order Mark (BOM) + } + + $outstr .= mb_convert_encoding($str, 'UTF-16BE', 'UTF-8'); + + return $outstr; + } + + public function escape($s) // _escape + { + return strtr($s, [')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r']); + } + + public function escapeSlashes($s) // _escapeName + { + return strtr($s, ['/' => '#2F']); + } + + /** + * Un-escapes a PDF string + * + * @param string $s + * @return string + */ + public function unescape($s) + { + $out = ''; + for ($count = 0, $n = strlen($s); $count < $n; $count++) { + if ($count === $n - 1 || $s[$count] !== '\\') { + $out .= $s[$count]; + } else { + switch ($s[++$count]) { + case ')': + case '(': + case '\\': + $out .= $s[$count]; + break; + case 'f': + $out .= chr(0x0C); + break; + case 'b': + $out .= chr(0x08); + break; + case 't': + $out .= chr(0x09); + break; + case 'r': + $out .= chr(0x0D); + break; + case 'n': + $out .= chr(0x0A); + break; + case "\r": + if ($count !== $n - 1 && $s[$count + 1] === "\n") { + $count++; + } + break; + case "\n": + break; + default: + // Octal-Values + $ord = ord($s[$count]); + if ($ord >= ord('0') && $ord <= ord('9')) { + $oct = ''. $s[$count]; + $ord = ord($s[$count + 1]); + if ($ord >= ord('0') && $ord <= ord('9')) { + $oct .= $s[++$count]; + $ord = ord($s[$count + 1]); + if ($ord >= ord('0') && $ord <= ord('9')) { + $oct .= $s[++$count]; + } + } + $out .= chr(octdec($oct)); + } else { + $out .= $s[$count]; + } + } + } + } + + return $out; + } + + private function endPage($s, $ln) + { + if ($this->mpdf->bufferoutput) { + + $this->mpdf->headerbuffer.= $s . "\n"; + + } elseif ($this->mpdf->ColActive && !$this->mpdf->processingHeader && !$this->mpdf->processingFooter) { + + // Captures everything in buffer for columns; Almost everything is sent from fn. Cell() except: + // Images sent from Image() or + // later sent as write($textto) in printbuffer + // Line() + + if (preg_match('/q \d+\.\d\d+ 0 0 (\d+\.\d\d+) \d+\.\d\d+ \d+\.\d\d+ cm \/(I|FO)\d+ Do Q/', $s, $m)) { // Image data + + $h = ($m[1] / Mpdf::SCALE); + // Update/overwrite the lowest bottom of printing y value for a column + $this->mpdf->ColDetails[$this->mpdf->CurrCol]['bottom_margin'] = $this->mpdf->y + $h; + + } elseif ($this->mpdf->tableLevel > 0 && preg_match('/\d+\.\d\d+ \d+\.\d\d+ \d+\.\d\d+ ([\-]{0,1}\d+\.\d\d+) re/', $s, $m)) { // Rect in table + + $h = ($m[1] / Mpdf::SCALE); + // Update/overwrite the lowest bottom of printing y value for a column + $this->mpdf->ColDetails[$this->mpdf->CurrCol]['bottom_margin'] = max($this->mpdf->ColDetails[$this->mpdf->CurrCol]['bottom_margin'], $this->mpdf->y + $h); + + } elseif (isset($this->mpdf->ColDetails[$this->mpdf->CurrCol]['bottom_margin'])) { + + $h = $this->mpdf->ColDetails[$this->mpdf->CurrCol]['bottom_margin'] - $this->mpdf->y; + + } else { + + $h = 0; + + } + + if ($h < 0) { + $h = -$h; + } + + $this->mpdf->columnbuffer[] = [ + 's' => $s, // Text string to output + 'col' => $this->mpdf->CurrCol, // Column when printed + 'x' => $this->mpdf->x, // x when printed + 'y' => $this->mpdf->y, // this->y when printed (after column break) + 'h' => $h // actual y at bottom when printed = y+h + ]; + + } elseif ($this->mpdf->table_rotate && !$this->mpdf->processingHeader && !$this->mpdf->processingFooter) { + + // Captures eveything in buffer for rotated tables; + $this->mpdf->tablebuffer .= $s . "\n"; + + } elseif ($this->mpdf->kwt && !$this->mpdf->processingHeader && !$this->mpdf->processingFooter) { + + // Captures eveything in buffer for keep-with-table (h1-6); + $this->mpdf->kwt_buffer[] = [ + 's' => $s, // Text string to output + 'x' => $this->mpdf->x, // x when printed + 'y' => $this->mpdf->y, // y when printed + ]; + + } elseif ($this->mpdf->keep_block_together && !$this->mpdf->processingHeader && !$this->mpdf->processingFooter) { + // do nothing + } else { + $this->mpdf->pages[$this->mpdf->page] .= $s . ($ln ? "\n" : ''); + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BookmarkWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BookmarkWriter.php new file mode 100644 index 0000000..bbec0d7 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/BookmarkWriter.php @@ -0,0 +1,138 @@ +<?php + +namespace Mpdf\Writer; + +use Mpdf\Strict; +use Mpdf\Mpdf; + +final class BookmarkWriter +{ + + use Strict; + + /** + * @var \Mpdf\Mpdf + */ + private $mpdf; + + /** + * @var \Mpdf\Writer\BaseWriter + */ + private $writer; + + public function __construct(Mpdf $mpdf, BaseWriter $writer) + { + $this->mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeBookmarks() // _putbookmarks + { + $nb = count($this->mpdf->BMoutlines); + if ($nb === 0) { + return; + } + + $bmo = $this->mpdf->BMoutlines; + $this->mpdf->BMoutlines = []; + $lastlevel = -1; + for ($i = 0; $i < count($bmo); $i++) { + if ($bmo[$i]['l'] > 0) { + while ($bmo[$i]['l'] - $lastlevel > 1) { // If jump down more than one level, insert a new entry + $new = $bmo[$i]; + $new['t'] = "[" . $new['t'] . "]"; // Put [] around text/title to highlight + $new['l'] = $lastlevel + 1; + $lastlevel++; + $this->mpdf->BMoutlines[] = $new; + } + } + $this->mpdf->BMoutlines[] = $bmo[$i]; + $lastlevel = $bmo[$i]['l']; + } + $nb = count($this->mpdf->BMoutlines); + + $lru = []; + $level = 0; + foreach ($this->mpdf->BMoutlines as $i => $o) { + if ($o['l'] > 0) { + $parent = $lru[$o['l'] - 1]; + // Set parent and last pointers + $this->mpdf->BMoutlines[$i]['parent'] = $parent; + $this->mpdf->BMoutlines[$parent]['last'] = $i; + if ($o['l'] > $level) { + // Level increasing: set first pointer + $this->mpdf->BMoutlines[$parent]['first'] = $i; + } + } else { + $this->mpdf->BMoutlines[$i]['parent'] = $nb; + } + if ($o['l'] <= $level and $i > 0) { + // Set prev and next pointers + $prev = $lru[$o['l']]; + $this->mpdf->BMoutlines[$prev]['next'] = $i; + $this->mpdf->BMoutlines[$i]['prev'] = $prev; + } + $lru[$o['l']] = $i; + $level = $o['l']; + } + + + // Outline items + $n = $this->mpdf->n + 1; + foreach ($this->mpdf->BMoutlines as $i => $o) { + $this->writer->object(); + $this->writer->write('<writer->utf16BigEndianTextString($o['t'])); + $this->writer->write('/Parent ' . ($n + $o['parent']) . ' 0 R'); + if (isset($o['prev'])) { + $this->writer->write('/Prev ' . ($n + $o['prev']) . ' 0 R'); + } + if (isset($o['next'])) { + $this->writer->write('/Next ' . ($n + $o['next']) . ' 0 R'); + } + if (isset($o['first'])) { + $this->writer->write('/First ' . ($n + $o['first']) . ' 0 R'); + } + if (isset($o['last'])) { + $this->writer->write('/Last ' . ($n + $o['last']) . ' 0 R'); + } + + + if (isset($this->mpdf->pageDim[$o['p']]['h'])) { + $h = $this->mpdf->pageDim[$o['p']]['h']; + } else { + $h = 0; + } + + $this->writer->write(sprintf('/Dest [%d 0 R /XYZ 0 %.3F null]', 1 + 2 * ($o['p']), ($h - $o['y']) * Mpdf::SCALE)); + if (isset($this->mpdf->bookmarkStyles) && isset($this->mpdf->bookmarkStyles[$o['l']])) { + // font style + $bms = $this->mpdf->bookmarkStyles[$o['l']]['style']; + $style = 0; + if (strpos($bms, 'B') !== false) { + $style += 2; + } + if (strpos($bms, 'I') !== false) { + $style += 1; + } + $this->writer->write(sprintf('/F %d', $style)); + // Colour + $col = $this->mpdf->bookmarkStyles[$o['l']]['color']; + if (isset($col) && is_array($col) && count($col) == 3) { + $this->writer->write(sprintf('/C [%.3F %.3F %.3F]', ($col[0] / 255), ($col[1] / 255), ($col[2] / 255))); + } + } + + $this->writer->write('/Count 0>>'); + $this->writer->write('endobj'); + } + // Outline root + $this->writer->object(); + + $this->mpdf->OutlineRoot = $this->mpdf->n; + + $this->writer->write('<writer->write('/Last ' . ($n + $lru[0]) . ' 0 R>>'); + $this->writer->write('endobj'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ColorWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ColorWriter.php new file mode 100644 index 0000000..c6ece98 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ColorWriter.php @@ -0,0 +1,46 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeSpotColors() // _putspotcolors + { + foreach ($this->mpdf->spotColors as $name => $color) { + + $this->writer->object(); + + $this->writer->write('[/Separation /' . str_replace(' ', '#20', $name)); + $this->writer->write('/DeviceCMYK <<'); + $this->writer->write('/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] '); + $this->writer->write(sprintf('/C1 [%.3F %.3F %.3F %.3F] ', $color['c'] / 100, $color['m'] / 100, $color['y'] / 100, $color['k'] / 100)); + $this->writer->write('/FunctionType 2 /Domain [0 1] /N 1>>]'); + $this->writer->write('endobj'); + + $this->mpdf->spotColors[$name]['n'] = $this->mpdf->n; + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FontWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FontWriter.php new file mode 100644 index 0000000..8d6b2cf --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FontWriter.php @@ -0,0 +1,680 @@ +mpdf = $mpdf; + $this->writer = $writer; + $this->fontCache = $fontCache; + $this->fontDescriptor = $fontDescriptor; + } + + public function writeFonts() + { + foreach ($this->mpdf->FontFiles as $fontkey => $info) { + // TrueType embedded + if (isset($info['type']) && $info['type'] === 'TTF' && !$info['sip'] && !$info['smp']) { + $used = true; + $asSubset = false; + foreach ($this->mpdf->fonts as $k => $f) { + if (isset($f['fontkey']) && $f['fontkey'] === $fontkey && $f['type'] === 'TTF') { + $used = $f['used']; + if ($used) { + $nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]); + $usage = (int) (count($f['subset']) * 100 / $nChars); + $fsize = $info['length1']; + // Always subset the very large TTF files + if ($fsize > ($this->mpdf->maxTTFFilesize * 1024)) { + $asSubset = true; + } elseif ($usage < $this->mpdf->percentSubset) { + $asSubset = true; + } + } + if ($this->mpdf->PDFA || $this->mpdf->PDFX) { + $asSubset = false; + } + $this->mpdf->fonts[$k]['asSubset'] = $asSubset; + break; + } + } + if ($used && !$asSubset) { + // Font file embedding + $this->writer->object(); + $this->mpdf->FontFiles[$fontkey]['n'] = $this->mpdf->n; + $originalsize = $info['length1']; + if ($this->mpdf->repackageTTF || $this->mpdf->fonts[$fontkey]['TTCfontID'] > 0 || $this->mpdf->fonts[$fontkey]['useOTL'] > 0) { // mPDF 5.7.1 + // First see if there is a cached compressed file + if ($this->fontCache->has($fontkey . '.ps.z') && $this->fontCache->jsonHas($fontkey . '.ps.json')) { + $font = $this->fontCache->load($fontkey . '.ps.z'); + $originalsize = $this->fontCache->jsonLoad($fontkey . '.ps.json'); // sets $originalsize (of repackaged font) + } else { + $ttf = new TTFontFile($this->fontCache, $this->fontDescriptor); + $font = $ttf->repackageTTF($this->mpdf->FontFiles[$fontkey]['ttffile'], $this->mpdf->fonts[$fontkey]['TTCfontID'], $this->mpdf->debugfonts, $this->mpdf->fonts[$fontkey]['useOTL']); // mPDF 5.7.1 + + $originalsize = strlen($font); + $font = gzcompress($font); + unset($ttf); + + $this->fontCache->binaryWrite($fontkey . '.ps.z', $font); + $this->fontCache->jsonWrite($fontkey . '.ps.json', $originalsize); + } + } elseif ($this->fontCache->has($fontkey . '.z')) { + $font = $this->fontCache->load($fontkey . '.z'); + } else { + $font = file_get_contents($this->mpdf->FontFiles[$fontkey]['ttffile']); + $font = gzcompress($font); + $this->fontCache->binaryWrite($fontkey . '.z', $font); + } + + $this->writer->write('<writer->write('/Filter /FlateDecode'); + $this->writer->write('/Length1 ' . $originalsize); + $this->writer->write('>>'); + $this->writer->stream($font); + $this->writer->write('endobj'); + } + } + } + + foreach ($this->mpdf->fonts as $k => $font) { + + // Font objects + $type = $font['type']; + $name = $font['name']; + + if ($type === 'TTF' && (!isset($font['used']) || !$font['used'])) { + continue; + } + + // @log Writing fonts + + if (isset($font['asSubset'])) { + $asSubset = $font['asSubset']; + } else { + $asSubset = ''; + } + + if ($type === 'Type0') { // Adobe CJK Fonts + + $this->mpdf->fonts[$k]['n'] = $this->mpdf->n + 1; + $this->writer->object(); + $this->writer->write('<writeType0($font); + + } elseif ($type === 'core') { + + // Standard font + $this->mpdf->fonts[$k]['n'] = $this->mpdf->n + 1; + + if ($this->mpdf->PDFA || $this->mpdf->PDFX) { + throw new \Mpdf\MpdfException('Core fonts are not allowed in PDF/A1-b or PDFX/1-a files (Times, Helvetica, Courier etc.)'); + } + + $this->writer->object(); + $this->writer->write('<writer->write('/BaseFont /' . $name); + $this->writer->write('/Subtype /Type1'); + + if ($name !== 'Symbol' && $name !== 'ZapfDingbats') { + $this->writer->write('/Encoding /WinAnsiEncoding'); + } + + $this->writer->write('>>'); + $this->writer->write('endobj'); + + } elseif ($type === 'TTF' && ($font['sip'] || $font['smp'])) { + + // TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2) + // Or Unicode Plane 1 - Supplementary Multilingual Plane + + if (!$font['used']) { + continue; + } + + $ssfaid = 'AA'; + $ttf = new TTFontFile($this->fontCache, $this->fontDescriptor); + $subsetCount = count($font['subsetfontids']); + for ($sfid = 0; $sfid < $subsetCount; $sfid++) { + $this->mpdf->fonts[$k]['n'][$sfid] = $this->mpdf->n + 1; // NB an array for subset + $subsetname = 'MPDF' . $ssfaid . '+' . $font['name']; + $ssfaid++; + + /* For some strange reason a subset ($sfid > 0) containing less than 97 characters causes an error + so fill up the array */ + for ($j = count($font['subsets'][$sfid]); $j < 98; $j++) { + $font['subsets'][$sfid][$j] = 0; + } + + $subset = $font['subsets'][$sfid]; + unset($subset[0]); + $ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->mpdf->debugfonts, $font['useOTL']); // mPDF 5.7.1 + $ttfontsize = strlen($ttfontstream); + $fontstream = gzcompress($ttfontstream); + $widthstring = ''; + $toUnistring = ''; + + foreach ($font['subsets'][$sfid] as $cp => $u) { + $w = $this->mpdf->_getCharWidth($font['cw'], $u); + if ($w !== false) { + $widthstring .= $w . ' '; + } else { + $widthstring .= round($ttf->defaultWidth) . ' '; + } + if ($u > 65535) { + $utf8 = chr(($u >> 18) + 240) . chr((($u >> 12) & 63) + 128) . chr((($u >> 6) & 63) + 128) . chr(($u & 63) + 128); + $utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8'); + $l1 = ord($utf16[0]); + $h1 = ord($utf16[1]); + $l2 = ord($utf16[2]); + $h2 = ord($utf16[3]); + $toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2))); + } else { + $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u))); + } + } + + // Additional Type1 or TrueType font + $this->writer->object(); + $this->writer->write('<writer->write('/BaseFont /' . $subsetname); + $this->writer->write('/Subtype /TrueType'); + $this->writer->write('/FirstChar 0 /LastChar ' . (count($font['subsets'][$sfid]) - 1)); + $this->writer->write('/Widths ' . ($this->mpdf->n + 1) . ' 0 R'); + $this->writer->write('/FontDescriptor ' . ($this->mpdf->n + 2) . ' 0 R'); + $this->writer->write('/ToUnicode ' . ($this->mpdf->n + 3) . ' 0 R'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // Widths + $this->writer->object(); + $this->writer->write('[' . $widthstring . ']'); + $this->writer->write('endobj'); + + // Descriptor + $this->writer->object(); + $s = '< $v) { + if ($kd === 'Flags') { + $v |= 4; + $v &= ~32; + } // SYMBOLIC font flag + $s .= ' /' . $kd . ' ' . $v . "\n"; + } + $s .= '/FontFile2 ' . ($this->mpdf->n + 2) . ' 0 R'; + $this->writer->write($s . '>>'); + $this->writer->write('endobj'); + + // ToUnicode + $this->writer->object(); + $toUni = "/CIDInit /ProcSet findresource begin\n"; + $toUni .= "12 dict begin\n"; + $toUni .= "begincmap\n"; + $toUni .= "/CIDSystemInfo\n"; + $toUni .= "< <%02s>\n", strtoupper(dechex(count($font['subsets'][$sfid])-1))); + $toUni .= "endcodespacerange\n"; + $toUni .= count($font['subsets'][$sfid]) . " beginbfchar\n"; + $toUni .= $toUnistring; + $toUni .= "endbfchar\n"; + $toUni .= "endcmap\n"; + $toUni .= "CMapName currentdict /CMap defineresource pop\n"; + $toUni .= "end\n"; + $toUni .= "end\n"; + $this->writer->write('<>'); + $this->writer->stream($toUni); + $this->writer->write('endobj'); + + // Font file + $this->writer->object(); + $this->writer->write('<writer->write('/Filter /FlateDecode'); + $this->writer->write('/Length1 ' . $ttfontsize); + $this->writer->write('>>'); + $this->writer->stream($fontstream); + $this->writer->write('endobj'); + } // foreach subset + unset($ttf); + + } elseif ($type === 'TTF') { // TrueType embedded SUBSETS or FULL + + $this->mpdf->fonts[$k]['n'] = $this->mpdf->n + 1; + + if ($asSubset) { + $ssfaid = 'A'; + $ttf = new TTFontFile($this->fontCache, $this->fontDescriptor); + $fontname = 'MPDFA' . $ssfaid . '+' . $font['name']; + $subset = $font['subset']; + unset($subset[0]); + $ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->mpdf->debugfonts, $font['useOTL']); + $ttfontsize = strlen($ttfontstream); + $fontstream = gzcompress($ttfontstream); + $codeToGlyph = $ttf->codeToGlyph; + unset($codeToGlyph[0]); + } else { + $fontname = $font['name']; + } + + // Type0 Font + // A composite font - a font composed of other fonts, organized hierarchically + $this->writer->object(); + $this->writer->write('<writer->write('/Subtype /Type0'); + $this->writer->write('/BaseFont /' . $fontname . ''); + $this->writer->write('/Encoding /Identity-H'); + $this->writer->write('/DescendantFonts [' . ($this->mpdf->n + 1) . ' 0 R]'); + $this->writer->write('/ToUnicode ' . ($this->mpdf->n + 2) . ' 0 R'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // CIDFontType2 + // A CIDFont whose glyph descriptions are based on TrueType font technology + $this->writer->object(); + $this->writer->write('<writer->write('/Subtype /CIDFontType2'); + $this->writer->write('/BaseFont /' . $fontname . ''); + $this->writer->write('/CIDSystemInfo ' . ($this->mpdf->n + 2) . ' 0 R'); + $this->writer->write('/FontDescriptor ' . ($this->mpdf->n + 3) . ' 0 R'); + + if (isset($font['desc']['MissingWidth'])) { + $this->writer->write('/DW ' . $font['desc']['MissingWidth'] . ''); + } + + if (!$asSubset && $this->fontCache->has($font['fontkey'] . '.cw')) { + $w = $this->fontCache->load($font['fontkey'] . '.cw'); + $this->writer->write($w); + } else { + $this->writeTTFontWidths($font, $asSubset, ($asSubset ? $ttf->maxUni : 0)); + } + + $this->writer->write('/CIDToGIDMap ' . ($this->mpdf->n + 4) . ' 0 R'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // ToUnicode + $this->writer->object(); + $toUni = "/CIDInit /ProcSet findresource begin\n"; + $toUni .= "12 dict begin\n"; + $toUni .= "begincmap\n"; + $toUni .= "/CIDSystemInfo\n"; + $toUni .= "<writer->write('<>'); + $this->writer->stream($toUni); + $this->writer->write('endobj'); + + // CIDSystemInfo dictionary + $this->writer->object(); + $this->writer->write('<writer->write('/Ordering (UCS)'); + $this->writer->write('/Supplement 0'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // Font descriptor + $this->writer->object(); + $this->writer->write('<writer->write('/FontName /' . $fontname); + + foreach ($font['desc'] as $kd => $v) { + if ($asSubset && $kd === 'Flags') { + $v |= 4; + $v &= ~32; + } // SYMBOLIC font flag + $this->writer->write(' /' . $kd . ' ' . $v); + } + + if ($font['panose']) { + $this->writer->write(' /Style << /Panose <' . $font['panose'] . '> >>'); + } + + if ($asSubset) { + $this->writer->write('/FontFile2 ' . ($this->mpdf->n + 2) . ' 0 R'); + } elseif ($font['fontkey']) { + // obj ID of a stream containing a TrueType font program + $this->writer->write('/FontFile2 ' . $this->mpdf->FontFiles[$font['fontkey']]['n'] . ' 0 R'); + } + + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // Embed CIDToGIDMap + // A specification of the mapping from CIDs to glyph indices + if ($asSubset) { + $cidtogidmap = str_pad('', 256 * 256 * 2, "\x00"); + foreach ($codeToGlyph as $cc => $glyph) { + $cidtogidmap[$cc * 2] = chr($glyph >> 8); + $cidtogidmap[$cc * 2 + 1] = chr($glyph & 0xFF); + } + $cidtogidmap = gzcompress($cidtogidmap); + } else { + // First see if there is a cached CIDToGIDMapfile + if ($this->fontCache->has($font['fontkey'] . '.cgm')) { + $cidtogidmap = $this->fontCache->load($font['fontkey'] . '.cgm'); + } else { + $ttf = new TTFontFile($this->fontCache, $this->fontDescriptor); + $charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->mpdf->debugfonts, $font['useOTL']); + $cidtogidmap = str_pad('', 256 * 256 * 2, "\x00"); + foreach ($charToGlyph as $cc => $glyph) { + $cidtogidmap[$cc * 2] = chr($glyph >> 8); + $cidtogidmap[$cc * 2 + 1] = chr($glyph & 0xFF); + } + unset($ttf); + $cidtogidmap = gzcompress($cidtogidmap); + $this->fontCache->binaryWrite($font['fontkey'] . '.cgm', $cidtogidmap); + } + } + $this->writer->object(); + $this->writer->write('<writer->write('/Filter /FlateDecode'); + $this->writer->write('>>'); + $this->writer->stream($cidtogidmap); + $this->writer->write('endobj'); + + // Font file + if ($asSubset) { + $this->writer->object(); + $this->writer->write('<writer->write('/Filter /FlateDecode'); + $this->writer->write('/Length1 ' . $ttfontsize); + $this->writer->write('>>'); + $this->writer->stream($fontstream); + $this->writer->write('endobj'); + unset($ttf); + } + } else { + throw new \Mpdf\MpdfException(sprintf('Unsupported font type: %s (%s)', $type, $name)); + } + } + } + + private function writeTTFontWidths(&$font, $asSubset, $maxUni) // _putTTfontwidths + { + $character = [ + 'startcid' => 1, + 'rangeid' => 0, + 'prevcid' => -2, + 'prevwidth' => -1, + 'interval' => false, + 'range' => [], + ]; + + $fontCacheFilename = $font['fontkey'] . '.cw127.json'; + if ($asSubset && $this->fontCache->jsonHas($fontCacheFilename)) { + $character = $this->fontCache->jsonLoad($fontCacheFilename); + $character['startcid'] = 128; + } + + // for each character + $cwlen = ($asSubset) ? $maxUni + 1 : (strlen($font['cw']) / 2); + for ($cid = $character['startcid']; $cid < $cwlen; $cid++) { + if ($cid == 128 && $asSubset && (!$this->fontCache->has($fontCacheFilename))) { + $character = [ + 'rangeid' => $character['rangeid'], + 'prevcid' => $character['prevcid'], + 'prevwidth' => $character['prevwidth'], + 'interval' => $character['interval'], + 'range' => $character['range'], + ]; + + $this->fontCache->jsonWrite($fontCacheFilename, $character); + } + + $character1 = isset($font['cw'][$cid * 2]) ? $font['cw'][$cid * 2] : ''; + $character2 = isset($font['cw'][$cid * 2 + 1]) ? $font['cw'][$cid * 2 + 1] : ''; + + if ($character1 === "\00" && $character2 === "\00") { + continue; + } + + $width = (ord($character1) << 8) + ord($character2); + + if ($width === 65535) { + $width = 0; + } + + if ($asSubset && $cid > 255 && (!isset($font['subset'][$cid]) || !$font['subset'][$cid])) { + continue; + } + + if ($asSubset && $cid > 0xFFFF) { + continue; + } // mPDF 6 + + if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) { + if ($cid === ($character['prevcid'] + 1)) { + // consecutive CID + if ($width === $character['prevwidth']) { + if (isset($character['range'][$character['rangeid']][0]) && $width === $character['range'][$character['rangeid']][0]) { + $character['range'][$character['rangeid']][] = $width; + } else { + array_pop($character['range'][$character['rangeid']]); + // new range + $character['rangeid'] = $character['prevcid']; + $character['range'][$character['rangeid']] = []; + $character['range'][$character['rangeid']][] = $character['prevwidth']; + $character['range'][$character['rangeid']][] = $width; + } + $character['interval'] = true; + $character['range'][$character['rangeid']]['interval'] = true; + } else { + if ($character['interval']) { + // new range + $character['rangeid'] = $cid; + $character['range'][$character['rangeid']] = []; + $character['range'][$character['rangeid']][] = $width; + } else { + $character['range'][$character['rangeid']][] = $width; + } + $character['interval'] = false; + } + } else { + // new range + $character['rangeid'] = $cid; + $character['range'][$character['rangeid']] = []; + $character['range'][$character['rangeid']][] = $width; + $character['interval'] = false; + } + $character['prevcid'] = $cid; + $character['prevwidth'] = $width; + } + } + $w = $this->writeFontRanges($character['range']); + $this->writer->write($w); + if (!$asSubset) { + $this->fontCache->binaryWrite($font['fontkey'] . '.cw', $w); + } + } + + private function writeFontRanges(&$range) // _putfontranges + { + // optimize ranges + $prevk = -1; + $nextk = -1; + $prevint = false; + foreach ($range as $k => $ws) { + $cws = count($ws); + if (($k == $nextk) and ( !$prevint) and ( (!isset($ws['interval'])) or ( $cws < 4))) { + if (isset($range[$k]['interval'])) { + unset($range[$k]['interval']); + } + $range[$prevk] = array_merge($range[$prevk], $range[$k]); + unset($range[$k]); + } else { + $prevk = $k; + } + $nextk = $k + $cws; + if (isset($ws['interval'])) { + if ($cws > 3) { + $prevint = true; + } else { + $prevint = false; + } + unset($range[$k]['interval']); + --$nextk; + } else { + $prevint = false; + } + } + // output data + $w = ''; + foreach ($range as $k => $ws) { + if (count(array_count_values($ws)) === 1) { + // interval mode is more compact + $w .= ' ' . $k . ' ' . ($k + count($ws) - 1) . ' ' . $ws[0]; + } else { + // range mode + $w .= ' ' . $k . ' [ ' . implode(' ', $ws) . ' ]' . "\n"; + } + } + return '/W [' . $w . ' ]'; + } + + private function writeFontWidths(&$font, $cidoffset = 0) // _putfontwidths + { + ksort($font['cw']); + unset($font['cw'][65535]); + $rangeid = 0; + $range = []; + $prevcid = -2; + $prevwidth = -1; + $interval = false; + // for each character + foreach ($font['cw'] as $cid => $width) { + $cid -= $cidoffset; + if (!isset($font['dw']) || (isset($font['dw']) && $width != $font['dw'])) { + if ($cid === ($prevcid + 1)) { + // consecutive CID + if ($width === $prevwidth) { + if ($width === $range[$rangeid][0]) { + $range[$rangeid][] = $width; + } else { + array_pop($range[$rangeid]); + // new range + $rangeid = $prevcid; + $range[$rangeid] = []; + $range[$rangeid][] = $prevwidth; + $range[$rangeid][] = $width; + } + $interval = true; + $range[$rangeid]['interval'] = true; + } else { + if ($interval) { + // new range + $rangeid = $cid; + $range[$rangeid] = []; + $range[$rangeid][] = $width; + } else { + $range[$rangeid][] = $width; + } + $interval = false; + } + } else { + // new range + $rangeid = $cid; + $range[$rangeid] = []; + $range[$rangeid][] = $width; + $interval = false; + } + $prevcid = $cid; + $prevwidth = $width; + } + } + $this->writer->write($this->writeFontRanges($range)); + } + + // from class PDF_Chinese CJK EXTENSIONS + public function writeType0(&$font) // _putType0 + { + // Type0 + $this->writer->write('/Subtype /Type0'); + $this->writer->write('/BaseFont /' . $font['name'] . '-' . $font['CMap']); + $this->writer->write('/Encoding /' . $font['CMap']); + $this->writer->write('/DescendantFonts [' . ($this->mpdf->n + 1) . ' 0 R]'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + // CIDFont + $this->writer->object(); + $this->writer->write('<writer->write('/Subtype /CIDFontType0'); + $this->writer->write('/BaseFont /' . $font['name']); + + $cidinfo = '/Registry ' . $this->writer->string('Adobe'); + $cidinfo .= ' /Ordering ' . $this->writer->string($font['registry']['ordering']); + $cidinfo .= ' /Supplement ' . $font['registry']['supplement']; + $this->writer->write('/CIDSystemInfo <<' . $cidinfo . '>>'); + + $this->writer->write('/FontDescriptor ' . ($this->mpdf->n + 1) . ' 0 R'); + if (isset($font['MissingWidth'])) { + $this->writer->write('/DW ' . $font['MissingWidth'] . ''); + } + $this->writeFontWidths($font, 31); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + // Font descriptor + $this->writer->object(); + $s = '< $v) { + if ($k !== 'Style') { + $s .= ' /' . $k . ' ' . $v . ''; + } + } + $this->writer->write($s . '>>'); + $this->writer->write('endobj'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FormWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FormWriter.php new file mode 100644 index 0000000..609aac5 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/FormWriter.php @@ -0,0 +1,63 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeFormObjects() // _putformobjects + { + foreach ($this->mpdf->formobjects as $file => $info) { + + $this->writer->object(); + + $this->mpdf->formobjects[$file]['n'] = $this->mpdf->n; + + $this->writer->write('<writer->write('/Subtype /Form'); + $this->writer->write('/Group ' . ($this->mpdf->n + 1) . ' 0 R'); + $this->writer->write('/BBox [' . $info['x'] . ' ' . $info['y'] . ' ' . ($info['w'] + $info['x']) . ' ' . ($info['h'] + $info['y']) . ']'); + + if ($this->mpdf->compress) { + $this->writer->write('/Filter /FlateDecode'); + } + + $data = $this->mpdf->compress ? gzcompress($info['data']) : $info['data']; + $this->writer->write('/Length ' . strlen($data) . '>>'); + $this->writer->stream($data); + + unset($this->mpdf->formobjects[$file]['data']); + + $this->writer->write('endobj'); + + // Required for SVG transparency (opacity) to work + $this->writer->object(); + $this->writer->write('<writer->write('/S /Transparency'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ImageWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ImageWriter.php new file mode 100644 index 0000000..b4d3ac8 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ImageWriter.php @@ -0,0 +1,119 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeImages() + { + $filter = $this->mpdf->compress ? '/Filter /FlateDecode ' : ''; + + foreach ($this->mpdf->images as $file => $info) { + + $this->writer->object(); + + $this->mpdf->images[$file]['n'] = $this->mpdf->n; + + $this->writer->write('<writer->write('/Subtype /Image'); + $this->writer->write('/Width ' . $info['w']); + $this->writer->write('/Height ' . $info['h']); + + if (isset($info['interpolation']) && $info['interpolation']) { + $this->writer->write('/Interpolate true'); // mPDF 6 - image interpolation shall be performed by a conforming reader + } + + if (isset($info['masked'])) { + $this->writer->write('/SMask ' . ($this->mpdf->n - 1) . ' 0 R'); + } + + // set color space + $icc = false; + if (isset($info['icc']) && ( $info['icc'] !== false)) { + // ICC Colour Space + $icc = true; + $this->writer->write('/ColorSpace [/ICCBased ' . ($this->mpdf->n + 1) . ' 0 R]'); + } elseif ($info['cs'] === 'Indexed') { + if ($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mpdf->restrictColorSpace === 3)) { + throw new \Mpdf\MpdfException('PDFA1-b and PDFX/1-a files do not permit using mixed colour space (' . $file . ').'); + } + $this->writer->write('/ColorSpace [/Indexed /DeviceRGB ' . (strlen($info['pal']) / 3 - 1) . ' ' . ($this->mpdf->n + 1) . ' 0 R]'); + } else { + $this->writer->write('/ColorSpace /' . $info['cs']); + if ($info['cs'] === 'DeviceCMYK') { + if ($this->mpdf->PDFA && $this->mpdf->restrictColorSpace !== 3) { + throw new \Mpdf\MpdfException('PDFA1-b does not permit Images using mixed colour space (' . $file . ').'); + } + if ($info['type'] === 'jpg') { + $this->writer->write('/Decode [1 0 1 0 1 0 1 0]'); + } + } elseif (($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mpdf->restrictColorSpace === 3)) && $info['cs'] === 'DeviceRGB') { + throw new \Mpdf\MpdfException('PDFA1-b and PDFX/1-a files do not permit using mixed colour space (' . $file . ').'); + } + } + + $this->writer->write('/BitsPerComponent ' . $info['bpc']); + + if (isset($info['f']) && $info['f']) { + $this->writer->write('/Filter /' . $info['f']); + } + + if (isset($info['parms'])) { + $this->writer->write($info['parms']); + } + + if (isset($info['trns']) && is_array($info['trns'])) { + $trns = ''; + $maskCount = count($info['trns']); + for ($i = 0; $i < $maskCount; $i++) { + $trns .= $info['trns'][$i] . ' ' . $info['trns'][$i] . ' '; + } + $this->writer->write('/Mask [' . $trns . ']'); + } + + $this->writer->write('/Length ' . strlen($info['data']) . '>>'); + $this->writer->stream($info['data']); + + unset($this->mpdf->images[$file]['data']); + + $this->writer->write('endobj'); + + if ($icc) { // ICC colour profile + $this->writer->object(); + $icc = $this->mpdf->compress ? gzcompress($info['icc']) : $info['icc']; + $this->writer->write('<>'); + $this->writer->stream($icc); + $this->writer->write('endobj'); + } elseif ($info['cs'] === 'Indexed') { // Palette + $this->writer->object(); + $pal = $this->mpdf->compress ? gzcompress($info['pal']) : $info['pal']; + $this->writer->write('<<' . $filter . '/Length ' . strlen($pal) . '>>'); + $this->writer->stream($pal); + $this->writer->write('endobj'); + } + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/JavaScriptWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/JavaScriptWriter.php new file mode 100644 index 0000000..f3bb290 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/JavaScriptWriter.php @@ -0,0 +1,46 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeJavascript() // _putjavascript + { + $this->writer->object(); + $this->mpdf->n_js = $this->mpdf->n; + $this->writer->write('<<'); + $this->writer->write('/Names [(EmbeddedJS) ' . (1 + $this->mpdf->n) . ' 0 R ]'); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $this->writer->object(); + $this->writer->write('<<'); + $this->writer->write('/S /JavaScript'); + $this->writer->write('/JS ' . $this->writer->string($this->mpdf->js)); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/MetadataWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/MetadataWriter.php new file mode 100644 index 0000000..568776e --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/MetadataWriter.php @@ -0,0 +1,821 @@ +mpdf = $mpdf; + $this->writer = $writer; + $this->form = $form; + $this->protection = $protection; + $this->logger = $logger; + } + + public function writeMetadata() // _putmetadata + { + $this->writer->object(); + $this->mpdf->MetadataRoot = $this->mpdf->n; + $Producer = 'mPDF ' . Mpdf::VERSION; + $z = date('O'); // +0200 + $offset = substr($z, 0, 3) . ':' . substr($z, 3, 2); + $CreationDate = date('Y-m-d\TH:i:s') . $offset; // 2006-03-10T10:47:26-05:00 2006-06-19T09:05:17Z + $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0x0fff) | 0x4000, random_int(0, 0x3fff) | 0x8000, random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0xffff)); + + + $m = '' . "\n"; // begin = FEFF BOM + $m .= ' ' . "\n"; + $m .= ' ' . "\n"; + $m .= ' ' . "\n"; + $m .= ' ' . $Producer . '' . "\n"; + if (!empty($this->mpdf->keywords)) { + $m .= ' ' . $this->mpdf->keywords . '' . "\n"; + } + $m .= ' ' . "\n"; + + $m .= ' ' . "\n"; + $m .= ' ' . $CreationDate . '' . "\n"; + $m .= ' ' . $CreationDate . '' . "\n"; + $m .= ' ' . $CreationDate . '' . "\n"; + if (!empty($this->mpdf->creator)) { + $m .= ' ' . $this->mpdf->creator . '' . "\n"; + } + $m .= ' ' . "\n"; + + // DC elements + $m .= ' ' . "\n"; + $m .= ' application/pdf' . "\n"; + if (!empty($this->mpdf->title)) { + $m .= ' + + ' . $this->mpdf->title . ' + + ' . "\n"; + } + if (!empty($this->mpdf->keywords)) { + $m .= ' + + ' . $this->mpdf->keywords . ' + + ' . "\n"; + } + if (!empty($this->mpdf->subject)) { + $m .= ' + + ' . $this->mpdf->subject . ' + + ' . "\n"; + } + if (!empty($this->mpdf->author)) { + $m .= ' + + ' . $this->mpdf->author . ' + + ' . "\n"; + } + $m .= ' ' . "\n"; + + if (!empty($this->mpdf->additionalXmpRdf)) { + $m .= $this->mpdf->additionalXmpRdf; + } + + // This bit is specific to PDFX-1a + if ($this->mpdf->PDFX) { + $m .= ' ' . "\n"; + } // This bit is specific to PDFA-1b + elseif ($this->mpdf->PDFA) { + + if (strpos($this->mpdf->PDFAversion, '-') === false) { + throw new \Mpdf\MpdfException(sprintf('PDFA version (%s) is not valid. (Use: 1-B, 3-B, etc.)', $this->mpdf->PDFAversion)); + } + + list($part, $conformance) = explode('-', strtoupper($this->mpdf->PDFAversion)); + $m .= ' ' . "\n"; + $m .= ' ' . $part . '' . "\n"; + $m .= ' ' . $conformance . '' . "\n"; + if ($part === '1' && $conformance === 'B') { + $m .= ' 2005' . "\n"; + } + $m .= ' ' . "\n"; + } + + $m .= ' ' . "\n"; + $m .= ' uuid:' . $uuid . '' . "\n"; + $m .= ' ' . "\n"; + $m .= ' ' . "\n"; + $m .= ' ' . "\n"; + $m .= str_repeat(str_repeat(' ', 100) . "\n", 20); // 2-4kB whitespace padding required + $m .= ''; // "r" read only + $this->writer->write('<>'); + $this->writer->stream($m); + $this->writer->write('endobj'); + } + + public function writeInfo() // _putinfo + { + $this->writer->write('/Producer ' . $this->writer->utf16BigEndianTextString('mPDF ' . $this->getVersionString())); + + if (!empty($this->mpdf->title)) { + $this->writer->write('/Title ' . $this->writer->utf16BigEndianTextString($this->mpdf->title)); + } + + if (!empty($this->mpdf->subject)) { + $this->writer->write('/Subject ' . $this->writer->utf16BigEndianTextString($this->mpdf->subject)); + } + + if (!empty($this->mpdf->author)) { + $this->writer->write('/Author ' . $this->writer->utf16BigEndianTextString($this->mpdf->author)); + } + + if (!empty($this->mpdf->keywords)) { + $this->writer->write('/Keywords ' . $this->writer->utf16BigEndianTextString($this->mpdf->keywords)); + } + + if (!empty($this->mpdf->creator)) { + $this->writer->write('/Creator ' . $this->writer->utf16BigEndianTextString($this->mpdf->creator)); + } + + foreach ($this->mpdf->customProperties as $key => $value) { + $this->writer->write('/' . $key . ' ' . $this->writer->utf16BigEndianTextString($value)); + } + + $now = PdfDate::format(time()); + $this->writer->write('/CreationDate ' . $this->writer->string('D:' . $now)); + $this->writer->write('/ModDate ' . $this->writer->string('D:' . $now)); + if ($this->mpdf->PDFX) { + $this->writer->write('/Trapped/False'); + $this->writer->write('/GTS_PDFXVersion(PDF/X-1a:2003)'); + } + } + + public function writeOutputIntent() // _putoutputintent + { + $this->writer->object(); + $this->mpdf->OutputIntentRoot = $this->mpdf->n; + $this->writer->write('<mpdf->ICCProfile, '.icc')); + + if ($this->mpdf->PDFA) { + $this->writer->write('/S /GTS_PDFA1'); + if ($this->mpdf->ICCProfile) { + $this->writer->write('/Info (' . $ICCProfile . ')'); + $this->writer->write('/OutputConditionIdentifier (Custom)'); + $this->writer->write('/OutputCondition ()'); + } else { + $this->writer->write('/Info (sRGB IEC61966-2.1)'); + $this->writer->write('/OutputConditionIdentifier (sRGB IEC61966-2.1)'); + $this->writer->write('/OutputCondition ()'); + } + $this->writer->write('/DestOutputProfile ' . ($this->mpdf->n + 1) . ' 0 R'); + } elseif ($this->mpdf->PDFX) { // always a CMYK profile + $this->writer->write('/S /GTS_PDFX'); + if ($this->mpdf->ICCProfile) { + $this->writer->write('/Info (' . $ICCProfile . ')'); + $this->writer->write('/OutputConditionIdentifier (Custom)'); + $this->writer->write('/OutputCondition ()'); + $this->writer->write('/DestOutputProfile ' . ($this->mpdf->n + 1) . ' 0 R'); + } else { + $this->writer->write('/Info (CGATS TR 001)'); + $this->writer->write('/OutputConditionIdentifier (CGATS TR 001)'); + $this->writer->write('/OutputCondition (CGATS TR 001 (SWOP))'); + $this->writer->write('/RegistryName (http://www.color.org)'); + } + } + $this->writer->write('>>'); + $this->writer->write('endobj'); + + if ($this->mpdf->PDFX && !$this->mpdf->ICCProfile) { + return; + } + + $this->writer->object(); + + if ($this->mpdf->ICCProfile) { + if (!file_exists($this->mpdf->ICCProfile)) { + throw new \Mpdf\MpdfException(sprintf('Unable to find ICC profile "%s"', $this->mpdf->ICCProfile)); + } + $s = file_get_contents($this->mpdf->ICCProfile); + } else { + $s = file_get_contents(__DIR__ . '/../../data/iccprofiles/sRGB_IEC61966-2-1.icc'); + } + + if ($this->mpdf->compress) { + $s = gzcompress($s); + } + + $this->writer->write('<<'); + + if ($this->mpdf->PDFX || ($this->mpdf->PDFA && $this->mpdf->restrictColorSpace === 3)) { + $this->writer->write('/N 4'); + } else { + $this->writer->write('/N 3'); + } + + if ($this->mpdf->compress) { + $this->writer->write('/Filter /FlateDecode '); + } + + $this->writer->write('/Length ' . strlen($s) . '>>'); + $this->writer->stream($s); + $this->writer->write('endobj'); + } + + public function writeAssociatedFiles() // _putAssociatedFiles + { + if (!function_exists('gzcompress')) { + throw new \Mpdf\MpdfException('ext-zlib is required for compression of associated files'); + } + + // for each file, we create the spec object + the stream object + foreach ($this->mpdf->associatedFiles as $k => $file) { + // spec + $this->writer->object(); + $this->mpdf->associatedFiles[$k]['_root'] = $this->mpdf->n; // we store the root ref of object for future reference (e.g. /EmbeddedFiles catalog) + $this->writer->write('<writer->string($file['name'])); + if ($file['description']) { + $this->writer->write('/Desc ' . $this->writer->string($file['description'])); + } + $this->writer->write('/Type /Filespec'); + $this->writer->write('/EF <<'); + $this->writer->write('/F ' . ($this->mpdf->n + 1) . ' 0 R'); + $this->writer->write('/UF ' . ($this->mpdf->n + 1) . ' 0 R'); + $this->writer->write('>>'); + if ($file['AFRelationship']) { + $this->writer->write('/AFRelationship /' . $file['AFRelationship']); + } + $this->writer->write('/UF ' . $this->writer->string($file['name'])); + $this->writer->write('>>'); + $this->writer->write('endobj'); + + $fileContent = null; + if (isset($file['path'])) { + $fileContent = @file_get_contents($file['path']); + } elseif (isset($file['content'])) { + $fileContent = $file['content']; + } + + if (!$fileContent) { + throw new \Mpdf\MpdfException(sprintf('Cannot access associated file - %s', $file['path'])); + } + + $filestream = gzcompress($fileContent); + $this->writer->object(); + $this->writer->write('<writer->write('/Subtype /' . $this->writer->escapeSlashes($file['mime'])); + } + $this->writer->write('/Length '.strlen($filestream)); + $this->writer->write('/Filter /FlateDecode'); + if (isset($file['path'])) { + $this->writer->write('/Params <writer->string('D:' . PdfDate::format(filemtime($file['path']))).' >>'); + } else { + $this->writer->write('/Params <writer->string('D:' . PdfDate::format(time())).' >>'); + } + + $this->writer->write('>>'); + $this->writer->stream($filestream); + $this->writer->write('endobj'); + } + + // AF array + $this->writer->object(); + $refs = []; + foreach ($this->mpdf->associatedFiles as $file) { + $refs[] = '' . $file['_root'] . ' 0 R'; + } + $this->writer->write('[' . implode(' ', $refs) . ']'); + $this->writer->write('endobj'); + + $this->mpdf->associatedFilesRoot = $this->mpdf->n; + } + + public function writeCatalog() //_putcatalog + { + $this->writer->write('/Type /Catalog'); + $this->writer->write('/Pages 1 0 R'); + + if ($this->mpdf->ZoomMode === 'fullpage') { + $this->writer->write('/OpenAction [3 0 R /Fit]'); + } elseif ($this->mpdf->ZoomMode === 'fullwidth') { + $this->writer->write('/OpenAction [3 0 R /FitH null]'); + } elseif ($this->mpdf->ZoomMode === 'real') { + $this->writer->write('/OpenAction [3 0 R /XYZ null null 1]'); + } elseif (!is_string($this->mpdf->ZoomMode)) { + $this->writer->write('/OpenAction [3 0 R /XYZ null null ' . ($this->mpdf->ZoomMode / 100) . ']'); + } elseif ($this->mpdf->ZoomMode === 'none') { + // do not write any zoom mode / OpenAction + } else { + $this->writer->write('/OpenAction [3 0 R /XYZ null null null]'); + } + + if ($this->mpdf->LayoutMode === 'single') { + $this->writer->write('/PageLayout /SinglePage'); + } elseif ($this->mpdf->LayoutMode === 'continuous') { + $this->writer->write('/PageLayout /OneColumn'); + } elseif ($this->mpdf->LayoutMode === 'twoleft') { + $this->writer->write('/PageLayout /TwoColumnLeft'); + } elseif ($this->mpdf->LayoutMode === 'tworight') { + $this->writer->write('/PageLayout /TwoColumnRight'); + } elseif ($this->mpdf->LayoutMode === 'two') { + if ($this->mpdf->mirrorMargins) { + $this->writer->write('/PageLayout /TwoColumnRight'); + } else { + $this->writer->write('/PageLayout /TwoColumnLeft'); + } + } + + // Bookmarks + if (count($this->mpdf->BMoutlines) > 0) { + $this->writer->write('/Outlines ' . $this->mpdf->OutlineRoot . ' 0 R'); + $this->writer->write('/PageMode /UseOutlines'); + } + + // Fullscreen + if (is_int(strpos($this->mpdf->DisplayPreferences, 'FullScreen'))) { + $this->writer->write('/PageMode /FullScreen'); + } + + // Metadata + if ($this->mpdf->PDFA || $this->mpdf->PDFX) { + $this->writer->write('/Metadata ' . $this->mpdf->MetadataRoot . ' 0 R'); + } + + // OutputIntents + if ($this->mpdf->PDFA || $this->mpdf->PDFX || $this->mpdf->ICCProfile) { + $this->writer->write('/OutputIntents [' . $this->mpdf->OutputIntentRoot . ' 0 R]'); + } + + // Associated files + if ($this->mpdf->associatedFilesRoot) { + $this->writer->write('/AF '. $this->mpdf->associatedFilesRoot .' 0 R'); + + $names = []; + foreach ($this->mpdf->associatedFiles as $file) { + $names[] = $this->writer->string($file['name']) . ' ' . $file['_root'] . ' 0 R'; + } + $this->writer->write('/Names << /EmbeddedFiles << /Names [' . implode(' ', $names) . '] >> >>'); + } + + // Forms + if (count($this->form->forms) > 0) { + $this->form->_putFormsCatalog(); + } + + if ($this->mpdf->js !== null) { + $this->writer->write('/Names << /JavaScript ' . $this->mpdf->n_js . ' 0 R >> '); + } + + if ($this->mpdf->DisplayPreferences || $this->mpdf->directionality === 'rtl' || $this->mpdf->mirrorMargins) { + + $this->writer->write('/ViewerPreferences<<'); + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'HideMenubar'))) { + $this->writer->write('/HideMenubar true'); + } + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'HideToolbar'))) { + $this->writer->write('/HideToolbar true'); + } + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'HideWindowUI'))) { + $this->writer->write('/HideWindowUI true'); + } + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'DisplayDocTitle'))) { + $this->writer->write('/DisplayDocTitle true'); + } + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'CenterWindow'))) { + $this->writer->write('/CenterWindow true'); + } + + if (is_int(strpos($this->mpdf->DisplayPreferences, 'FitWindow'))) { + $this->writer->write('/FitWindow true'); + } + + // PrintScaling is PDF 1.6 spec. + if (!$this->mpdf->PDFA && !$this->mpdf->PDFX && is_int(strpos($this->mpdf->DisplayPreferences, 'NoPrintScaling'))) { + $this->writer->write('/PrintScaling /None'); + } + + if ($this->mpdf->directionality === 'rtl') { + $this->writer->write('/Direction /R2L'); + } + + // Duplex is PDF 1.7 spec. + if ($this->mpdf->mirrorMargins && !$this->mpdf->PDFA && !$this->mpdf->PDFX) { + // if ($this->mpdf->DefOrientation=='P') $this->writer->write('/Duplex /DuplexFlipShortEdge'); + $this->writer->write('/Duplex /DuplexFlipLongEdge'); // PDF v1.7+ + } + + $this->writer->write('>>'); + } + + if ($this->mpdf->open_layer_pane && ($this->mpdf->hasOC || count($this->mpdf->layers))) { + $this->writer->write('/PageMode /UseOC'); + } + + if ($this->mpdf->hasOC || count($this->mpdf->layers)) { + $p = $v = $h = $l = $loff = $lall = $as = ''; + if ($this->mpdf->hasOC) { + if (($this->mpdf->hasOC & 1) === 1) { + $p = $this->mpdf->n_ocg_print . ' 0 R'; + } + if (($this->mpdf->hasOC & 2) === 2) { + $v = $this->mpdf->n_ocg_view . ' 0 R'; + } + if (($this->mpdf->hasOC & 4) === 4) { + $h = $this->mpdf->n_ocg_hidden . ' 0 R'; + } + $as = "<> <>"; + } + + if (count($this->mpdf->layers)) { + foreach ($this->mpdf->layers as $k => $layer) { + if (strtolower($this->mpdf->layerDetails[$k]['state']) === 'hidden') { + $loff .= $layer['n'] . ' 0 R '; + } else { + $l .= $layer['n'] . ' 0 R '; + } + $lall .= $layer['n'] . ' 0 R '; + } + } + $this->writer->write("/OCProperties <writer->write("/Order [$v $p $h $lall] "); + if ($as) { + $this->writer->write("/AS [$as] "); + } + $this->writer->write('>>>>'); + } + } + + /** + * @since 5.7.2 + */ + public function writeAnnotations() // _putannots + { + $nb = $this->mpdf->page; + + for ($n = 1; $n <= $nb; $n++) { + + if (isset($this->mpdf->PageLinks[$n]) || isset($this->mpdf->PageAnnots[$n]) || count($this->form->forms) > 0) { + + $wPt = $this->mpdf->pageDim[$n]['w'] * Mpdf::SCALE; + $hPt = $this->mpdf->pageDim[$n]['h'] * Mpdf::SCALE; + + // Links + if (isset($this->mpdf->PageLinks[$n])) { + + foreach ($this->mpdf->PageLinks[$n] as $key => $pl) { + + $this->writer->object(); + $annot = ''; + + $rect = sprintf('%.3F %.3F %.3F %.3F', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]); + + $annot .= '<writer->utf16BigEndianTextString($pl[4]); + $annot .= ' /NM ' . $this->writer->string(sprintf('%04u-%04u', $n, $key)); + $annot .= ' /M ' . $this->writer->string('D:' . date('YmdHis')); + + $annot .= ' /Border [0 0 0]'; + + // Use this (instead of /Border) to specify border around link + + // $annot .= ' /BS <mpdf->PDFA || $this->mpdf->PDFX) { + $annot .= ' /F 28'; + } + + if (strpos($pl[4], '@') === 0) { + + $p = substr($pl[4], 1); + // $h=isset($this->mpdf->OrientationChanges[$p]) ? $wPt : $hPt; + $htarg = $this->mpdf->pageDim[$p]['h'] * Mpdf::SCALE; + $annot .= sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>', 1 + 2 * $p, $htarg); + + } elseif (is_string($pl[4])) { + + $annot .= ' /A <writer->string($pl[4]) . '>> >>'; + + } else { + + $l = $this->mpdf->links[$pl[4]]; + // may not be set if #link points to non-existent target + if (isset($this->mpdf->pageDim[$l[0]]['h'])) { + $htarg = $this->mpdf->pageDim[$l[0]]['h'] * Mpdf::SCALE; + } else { + $htarg = $this->mpdf->h * Mpdf::SCALE; + } // doesn't really matter + + $annot .= sprintf(' /Dest [%d 0 R /XYZ 0 %.3F null]>>', 1 + 2 * $l[0], $htarg - $l[1] * Mpdf::SCALE); + } + + $this->writer->write($annot); + $this->writer->write('endobj'); + + } + } + + /* -- ANNOTATIONS -- */ + if (isset($this->mpdf->PageAnnots[$n])) { + + foreach ($this->mpdf->PageAnnots[$n] as $key => $pl) { + + $fileAttachment = (bool) $pl['opt']['file']; + + if ($fileAttachment && !$this->mpdf->allowAnnotationFiles) { + $this->logger->warning('Embedded files for annotations have to be allowed explicitly with "allowAnnotationFiles" config key'); + $fileAttachment = false; + } + + $this->writer->object(); + + $annot = ''; + $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER); + $x = $pl['x']; + + if ($this->mpdf->annotMargin != 0 || $x == 0 || $x < 0) { // Odd page, intentional non-strict comparison + $x = ($wPt / Mpdf::SCALE) - $this->mpdf->annotMargin; + } + + $w = $h = 0; + $a = $x * Mpdf::SCALE; + $b = $hPt - ($pl['y'] * Mpdf::SCALE); + + $annot .= '<mpdf->n + 1) . ' 0 R>>'; + $annot .= '>>'; + + } else { + $annot .= '/Subtype /Text'; + $w = 20; + $h = 20; // mPDF 6 + } + + $rect = sprintf('%.3F %.3F %.3F %.3F', $a, $b - $h, $a + $w, $b); + $annot .= ' /Rect [' . $rect . ']'; + + // contents = description of file in free text + $annot .= ' /Contents ' . $this->writer->utf16BigEndianTextString($pl['txt']); + + $annot .= ' /NM ' . $this->writer->string(sprintf('%04u-%04u', $n, 2000 + $key)); + $annot .= ' /M ' . $this->writer->string('D:' . date('YmdHis')); + $annot .= ' /CreationDate ' . $this->writer->string('D:' . date('YmdHis')); + $annot .= ' /Border [0 0 0]'; + + if ($this->mpdf->PDFA || $this->mpdf->PDFX) { + $annot .= ' /F 28'; + $annot .= ' /CA 1'; + } elseif ($pl['opt']['ca'] > 0) { + $annot .= ' /CA ' . $pl['opt']['ca']; + } + + $annotcolor = ' /C ['; + if (isset($pl['opt']['c']) && $pl['opt']['c']) { + $col = $pl['opt']['c']; + if ($col[0] == 3 || $col[0] == 5) { + $annotcolor .= sprintf('%.3F %.3F %.3F', ord($col[1]) / 255, ord($col[2]) / 255, ord($col[3]) / 255); + } elseif ($col[0] == 1) { + $annotcolor .= sprintf('%.3F', ord($col[1]) / 255); + } elseif ($col[0] == 4 || $col[0] == 6) { + $annotcolor .= sprintf('%.3F %.3F %.3F %.3F', ord($col[1]) / 100, ord($col[2]) / 100, ord($col[3]) / 100, ord($col[4]) / 100); + } else { + $annotcolor .= '1 1 0'; + } + } else { + $annotcolor .= '1 1 0'; + } + $annotcolor .= ']'; + $annot .= $annotcolor; + + // Usually Author + // Use as Title for fileattachment + if (isset($pl['opt']['t']) && is_string($pl['opt']['t'])) { + $annot .= ' /T ' . $this->writer->utf16BigEndianTextString($pl['opt']['t']); + } + + if ($fileAttachment) { + $iconsapp = ['Paperclip', 'Graph', 'PushPin', 'Tag']; + } else { + $iconsapp = ['Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph']; + } + + if (isset($pl['opt']['icon']) && in_array($pl['opt']['icon'], $iconsapp)) { + $annot .= ' /Name /' . $pl['opt']['icon']; + } elseif ($fileAttachment) { + $annot .= ' /Name /PushPin'; + } else { + $annot .= ' /Name /Note'; + } + + if (!$fileAttachment) { + // Subj is PDF 1.5 spec. + if (!$this->mpdf->PDFA && !$this->mpdf->PDFX && isset($pl['opt']['subj'])) { + $annot .= ' /Subj ' . $this->writer->utf16BigEndianTextString($pl['opt']['subj']); + } + if (!empty($pl['opt']['popup'])) { + $annot .= ' /Open true'; + $annot .= ' /Popup ' . ($this->mpdf->n + 1) . ' 0 R'; + } else { + $annot .= ' /Open false'; + } + } + + $annot .= ' /P ' . $pl['pageobj'] . ' 0 R'; + $annot .= '>>'; + $this->writer->write($annot); + $this->writer->write('endobj'); + + if ($fileAttachment) { + + $file = @file_get_contents($pl['opt']['file']); + if (!$file) { + throw new \Mpdf\MpdfException('mPDF Error: Cannot access file attachment - ' . $pl['opt']['file']); + } + + $filestream = gzcompress($file); + $this->writer->object(); + $this->writer->write('<writer->write('/Length ' . strlen($filestream)); + $this->writer->write('/Filter /FlateDecode'); + $this->writer->write('>>'); + $this->writer->stream($filestream); + $this->writer->write('endobj'); + + } elseif (!empty($pl['opt']['popup'])) { + $this->writer->object(); + $annot = ''; + if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][0])) { + $x = $pl['opt']['popup'][0] * Mpdf::SCALE; + } else { + $x = $pl['x'] * Mpdf::SCALE; + } + if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][1])) { + $y = $hPt - ($pl['opt']['popup'][1] * Mpdf::SCALE); + } else { + $y = $hPt - ($pl['y'] * Mpdf::SCALE); + } + if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][2])) { + $w = $pl['opt']['popup'][2] * Mpdf::SCALE; + } else { + $w = 180; + } + if (is_array($pl['opt']['popup']) && isset($pl['opt']['popup'][3])) { + $h = $pl['opt']['popup'][3] * Mpdf::SCALE; + } else { + $h = 120; + } + $rect = sprintf('%.3F %.3F %.3F %.3F', $x, $y - $h, $x + $w, $y); + $annot .= '<writer->string('D:' . date('YmdHis')); + if ($this->mpdf->PDFA || $this->mpdf->PDFX) { + $annot .= ' /F 28'; + } + $annot .= ' /Parent ' . ($this->mpdf->n - 1) . ' 0 R'; + $annot .= '>>'; + $this->writer->write($annot); + $this->writer->write('endobj'); + } + } + } + + // Active Forms + if (count($this->form->forms) > 0) { + $this->form->_putFormItems($n, $hPt); + } + } + } + + // Active Forms - Radio Button Group entries + // Output Radio Button Group form entries (radio_on_obj_id already determined) + if (count($this->form->form_radio_groups)) { + $this->form->_putRadioItems($n); + } + } + + public function writeEncryption() // _putencryption + { + $this->writer->write('/Filter /Standard'); + if ($this->protection->getUseRC128Encryption()) { + $this->writer->write('/V 2'); + $this->writer->write('/R 3'); + $this->writer->write('/Length 128'); + } else { + $this->writer->write('/V 1'); + $this->writer->write('/R 2'); + } + $this->writer->write('/O (' . $this->writer->escape($this->protection->getOValue()) . ')'); + $this->writer->write('/U (' . $this->writer->escape($this->protection->getUValue()) . ')'); + $this->writer->write('/P ' . $this->protection->getPValue()); + } + + public function writeTrailer() // _puttrailer + { + $this->writer->write('/Size ' . ($this->mpdf->n + 1)); + $this->writer->write('/Root ' . $this->mpdf->n . ' 0 R'); + $this->writer->write('/Info ' . $this->mpdf->InfoRoot . ' 0 R'); + + if ($this->mpdf->encrypted) { + $this->writer->write('/Encrypt ' . $this->mpdf->enc_obj_id . ' 0 R'); + $this->writer->write('/ID [<' . $this->protection->getUniqid() . '> <' . $this->protection->getUniqid() . '>]'); + } else { + $uniqid = md5(time() . $this->mpdf->buffer); + $this->writer->write('/ID [<' . $uniqid . '> <' . $uniqid . '>]'); + } + } + + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + private function getVersionString() + { + $return = Mpdf::VERSION; + $headFile = __DIR__ . '/../../.git/HEAD'; + if (file_exists($headFile)) { + $ref = file($headFile); + $path = explode('/', $ref[0], 3); + $branch = isset($path[2]) ? trim($path[2]) : ''; + $revFile = __DIR__ . '/../../.git/refs/heads/' . $branch; + if ($branch && file_exists($revFile)) { + $rev = file($revFile); + $rev = substr($rev[0], 0, 7); + $return .= ' (' . $rev . ')'; + } + } + + return $return; + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ObjectWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ObjectWriter.php new file mode 100644 index 0000000..2e0ad7d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ObjectWriter.php @@ -0,0 +1,64 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeImportedObjects() + { + if (is_array($this->mpdf->parsers) && count($this->mpdf->parsers) > 0) { + + foreach ($this->mpdf->parsers as $filename => $p) { + + $this->mpdf->current_parser = $this->mpdf->parsers[$filename]; + + if (is_array($this->mpdf->_obj_stack[$filename])) { + + while ($n = key($this->mpdf->_obj_stack[$filename])) { + + $nObj = $this->mpdf->current_parser->resolveObject($this->mpdf->_obj_stack[$filename][$n][1]); + $this->writer->object($this->mpdf->_obj_stack[$filename][$n][0]); + + if ($nObj[0] == pdf_parser::TYPE_STREAM) { + $this->mpdf->pdf_write_value($nObj); + } else { + $this->mpdf->pdf_write_value($nObj[1]); + } + + $this->writer->write('endobj'); + + $this->mpdf->_obj_stack[$filename][$n] = null; // free memory + + unset($this->mpdf->_obj_stack[$filename][$n]); + + reset($this->mpdf->_obj_stack[$filename]); + } + } + } + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/OptionalContentWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/OptionalContentWriter.php new file mode 100644 index 0000000..499a77f --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/OptionalContentWriter.php @@ -0,0 +1,71 @@ +mpdf = $mpdf; + $this->writer = $writer; + } + + public function writeOptionalContentGroups() // _putocg Optional Content Groups + { + if ($this->mpdf->hasOC) { + + $this->writer->object(); + $this->mpdf->n_ocg_print = $this->mpdf->n; + $this->writer->write('<writer->string('Print only')); + $this->writer->write('/Usage <> /View <>>>>>'); + $this->writer->write('endobj'); + + $this->writer->object(); + $this->mpdf->n_ocg_view = $this->mpdf->n; + $this->writer->write('<writer->string('Screen only')); + $this->writer->write('/Usage <> /View <>>>>>'); + $this->writer->write('endobj'); + + $this->writer->object(); + $this->mpdf->n_ocg_hidden = $this->mpdf->n; + $this->writer->write('<writer->string('Hidden')); + $this->writer->write('/Usage <> /View <>>>>>'); + $this->writer->write('endobj'); + } + + if (count($this->mpdf->layers)) { + + ksort($this->mpdf->layers); + foreach ($this->mpdf->layers as $id => $layer) { + $this->writer->object(); + $this->mpdf->layers[$id]['n'] = $this->mpdf->n; + + if (isset($this->mpdf->layerDetails[$id]['name']) && $this->mpdf->layerDetails[$id]['name']) { + $name = $this->mpdf->layerDetails[$id]['name']; + } else { + $name = $layer['name']; + } + + $this->writer->write('<writer->utf16BigEndianTextString($name) . '>>'); + $this->writer->write('endobj'); + } + } + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/PageWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/PageWriter.php new file mode 100644 index 0000000..7e4e21d --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/PageWriter.php @@ -0,0 +1,285 @@ +mpdf = $mpdf; + $this->form = $form; + $this->writer = $writer; + $this->metadataWriter = $metadataWriter; + } + + public function writePages() // _putpages + { + $nb = $this->mpdf->page; + $filter = $this->mpdf->compress ? '/Filter /FlateDecode ' : ''; + + if ($this->mpdf->DefOrientation === 'P') { + $defwPt = $this->mpdf->fwPt; + $defhPt = $this->mpdf->fhPt; + } else { + $defwPt = $this->mpdf->fhPt; + $defhPt = $this->mpdf->fwPt; + } + + $annotid = (3 + 2 * $nb); + + // Active Forms + $totaladdnum = 0; + for ($n = 1; $n <= $nb; $n++) { + if (isset($this->mpdf->PageLinks[$n])) { + $totaladdnum += count($this->mpdf->PageLinks[$n]); + } + + /* -- ANNOTATIONS -- */ + if (isset($this->mpdf->PageAnnots[$n])) { + foreach ($this->mpdf->PageAnnots[$n] as $k => $pl) { + if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { + $totaladdnum += 2; + } else { + $totaladdnum++; + } + } + } + /* -- END ANNOTATIONS -- */ + + /* -- FORMS -- */ + if (count($this->form->forms) > 0) { + $this->form->countPageForms($n, $totaladdnum); + } + /* -- END FORMS -- */ + } + + /* -- FORMS -- */ + // Make a note in the radio button group of the obj_id it will have + $ctr = 0; + if (count($this->form->form_radio_groups)) { + foreach ($this->form->form_radio_groups as $name => $frg) { + $this->form->form_radio_groups[$name]['obj_id'] = $annotid + $totaladdnum + $ctr; + $ctr++; + } + } + /* -- END FORMS -- */ + + // Select unused fonts (usually default font) + $unused = []; + foreach ($this->mpdf->fonts as $fk => $font) { + if (isset($font['type']) && $font['type'] === 'TTF' && !$font['used']) { + $unused[] = $fk; + } + } + + for ($n = 1; $n <= $nb; $n++) { + + $thispage = $this->mpdf->pages[$n]; + + if (isset($this->mpdf->OrientationChanges[$n])) { + $hPt = $this->mpdf->pageDim[$n]['w'] * Mpdf::SCALE; + $wPt = $this->mpdf->pageDim[$n]['h'] * Mpdf::SCALE; + $owidthPt_LR = $this->mpdf->pageDim[$n]['outer_width_TB'] * Mpdf::SCALE; + $owidthPt_TB = $this->mpdf->pageDim[$n]['outer_width_LR'] * Mpdf::SCALE; + } else { + $wPt = $this->mpdf->pageDim[$n]['w'] * Mpdf::SCALE; + $hPt = $this->mpdf->pageDim[$n]['h'] * Mpdf::SCALE; + $owidthPt_LR = $this->mpdf->pageDim[$n]['outer_width_LR'] * Mpdf::SCALE; + $owidthPt_TB = $this->mpdf->pageDim[$n]['outer_width_TB'] * Mpdf::SCALE; + } + + // Remove references to unused fonts (usually default font) + foreach ($unused as $fk) { + if ($this->mpdf->fonts[$fk]['sip'] || $this->mpdf->fonts[$fk]['smp']) { + foreach ($this->mpdf->fonts[$fk]['subsetfontids'] as $k => $fid) { + $thispage = preg_replace('/\s\/F' . $fid . ' \d[\d.]* Tf\s/is', ' ', $thispage); + } + } else { + $thispage = preg_replace('/\s\/F' . $this->mpdf->fonts[$fk]['i'] . ' \d[\d.]* Tf\s/is', ' ', $thispage); + } + } + + // Clean up repeated /GS1 gs statements + // For some reason using + for repetition instead of {2,20} crashes PHP Script Interpreter ??? + $thispage = preg_replace('/(\/GS1 gs\n){2,20}/', "/GS1 gs\n", $thispage); + + $thispage = preg_replace('/(\s*___BACKGROUND___PATTERNS' . $this->mpdf->uniqstr . '\s*)/', ' ', $thispage); + $thispage = preg_replace('/(\s*___HEADER___MARKER' . $this->mpdf->uniqstr . '\s*)/', ' ', $thispage); + $thispage = preg_replace('/(\s*___PAGE___START' . $this->mpdf->uniqstr . '\s*)/', ' ', $thispage); + $thispage = preg_replace('/(\s*___TABLE___BACKGROUNDS' . $this->mpdf->uniqstr . '\s*)/', ' ', $thispage); + + // mPDF 5.7.3 TRANSFORMS + while (preg_match('/(\% BTR(.*?)\% ETR)/is', $thispage, $m)) { + $thispage = preg_replace('/(\% BTR.*?\% ETR)/is', '', $thispage, 1) . "\n" . $m[2]; + } + + // Page + $this->writer->object(); + $this->writer->write('<writer->write('/Parent 1 0 R'); + + if (isset($this->mpdf->OrientationChanges[$n])) { + + $this->writer->write(sprintf('/MediaBox [0 0 %.3F %.3F]', $hPt, $wPt)); + + // If BleedBox is defined, it must be larger than the TrimBox, but smaller than the MediaBox + $bleedMargin = $this->mpdf->pageDim[$n]['bleedMargin'] * Mpdf::SCALE; + + if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) { + $x0 = $owidthPt_TB - $bleedMargin; + $y0 = $owidthPt_LR - $bleedMargin; + $x1 = $hPt - $owidthPt_TB + $bleedMargin; + $y1 = $wPt - $owidthPt_LR + $bleedMargin; + $this->writer->write(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1)); + } + + $this->writer->write(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_TB, $owidthPt_LR, $hPt - $owidthPt_TB, $wPt - $owidthPt_LR)); + + if ($this->mpdf->displayDefaultOrientation) { + if ($this->mpdf->DefOrientation === 'P') { + $this->writer->write('/Rotate 270'); + } else { + $this->writer->write('/Rotate 90'); + } + } + + } else { // elseif($wPt != $defwPt || $hPt != $defhPt) { + + $this->writer->write(sprintf('/MediaBox [0 0 %.3F %.3F]', $wPt, $hPt)); + $bleedMargin = $this->mpdf->pageDim[$n]['bleedMargin'] * Mpdf::SCALE; + + if ($bleedMargin && ($owidthPt_TB || $owidthPt_LR)) { + $x0 = $owidthPt_LR - $bleedMargin; + $y0 = $owidthPt_TB - $bleedMargin; + $x1 = $wPt - $owidthPt_LR + $bleedMargin; + $y1 = $hPt - $owidthPt_TB + $bleedMargin; + $this->writer->write(sprintf('/BleedBox [%.3F %.3F %.3F %.3F]', $x0, $y0, $x1, $y1)); + } + + $this->writer->write(sprintf('/TrimBox [%.3F %.3F %.3F %.3F]', $owidthPt_LR, $owidthPt_TB, $wPt - $owidthPt_LR, $hPt - $owidthPt_TB)); + } + $this->writer->write('/Resources 2 0 R'); + + // Important to keep in RGB colorSpace when using transparency + if (!$this->mpdf->PDFA && !$this->mpdf->PDFX) { + if ($this->mpdf->restrictColorSpace === 3) { + $this->writer->write('/Group << /Type /Group /S /Transparency /CS /DeviceCMYK >> '); + } elseif ($this->mpdf->restrictColorSpace === 1) { + $this->writer->write('/Group << /Type /Group /S /Transparency /CS /DeviceGray >> '); + } else { + $this->writer->write('/Group << /Type /Group /S /Transparency /CS /DeviceRGB >> '); + } + } + + $annotsnum = 0; + $embeddedfiles = []; // mPDF 5.7.2 /EmbeddedFiles + + if (isset($this->mpdf->PageLinks[$n])) { + $annotsnum += count($this->mpdf->PageLinks[$n]); + } + + if (isset($this->mpdf->PageAnnots[$n])) { + foreach ($this->mpdf->PageAnnots[$n] as $k => $pl) { + if (!empty($pl['opt']['file'])) { + $embeddedfiles[$annotsnum + 1] = true; + } // mPDF 5.7.2 /EmbeddedFiles + if (!empty($pl['opt']['popup']) || !empty($pl['opt']['file'])) { + $annotsnum += 2; + } else { + $annotsnum++; + } + $this->mpdf->PageAnnots[$n][$k]['pageobj'] = $this->mpdf->n; + } + } + + // Active Forms + $formsnum = 0; + if (count($this->form->forms) > 0) { + foreach ($this->form->forms as $val) { + if ($val['page'] == $n) { + $formsnum++; + } + } + } + + if ($annotsnum || $formsnum) { + + $s = '/Annots [ '; + + for ($i = 0; $i < $annotsnum; $i++) { + if (!isset($embeddedfiles[$i])) { + $s .= ($annotid + $i) . ' 0 R '; + } // mPDF 5.7.2 /EmbeddedFiles + } + + $annotid += $annotsnum; + + /* -- FORMS -- */ + if (count($this->form->forms) > 0) { + $this->form->addFormIds($n, $s, $annotid); + } + /* -- END FORMS -- */ + + $s .= '] '; + $this->writer->write($s); + } + + $this->writer->write('/Contents ' . ($this->mpdf->n + 1) . ' 0 R>>'); + $this->writer->write('endobj'); + + // Page content + $this->writer->object(); + $p = $this->mpdf->compress ? gzcompress($thispage) : $thispage; + $this->writer->write('<<' . $filter . '/Length ' . strlen($p) . '>>'); + $this->writer->stream($p); + $this->writer->write('endobj'); + } + + $this->metadataWriter->writeAnnotations(); // mPDF 5.7.2 + + // Pages root + $this->mpdf->offsets[1] = strlen($this->mpdf->buffer); + $this->writer->write('1 0 obj'); + $this->writer->write('<writer->write($kids . ']'); + $this->writer->write('/Count ' . $nb); + $this->writer->write(sprintf('/MediaBox [0 0 %.3F %.3F]', $defwPt, $defhPt)); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ResourceWriter.php b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ResourceWriter.php new file mode 100644 index 0000000..996b882 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/Writer/ResourceWriter.php @@ -0,0 +1,256 @@ +mpdf = $mpdf; + $this->writer = $writer; + $this->colorWriter = $colorWriter; + $this->fontWriter = $fontWriter; + $this->imageWriter = $imageWriter; + $this->formWriter = $formWriter; + $this->optionalContentWriter = $optionalContentWriter; + $this->backgroundWriter = $backgroundWriter; + $this->bookmarkWriter = $bookmarkWriter; + $this->metadataWriter = $metadataWriter; + $this->javaScriptWriter = $javaScriptWriter; + $this->logger = $logger; + } + + public function writeResources() // _putresources + { + if ($this->mpdf->hasOC || count($this->mpdf->layers)) { + $this->optionalContentWriter->writeOptionalContentGroups(); + } + + $this->mpdf->_putextgstates(); + $this->colorWriter->writeSpotColors(); + + // @log Compiling Fonts + + $this->fontWriter->writeFonts(); + + // @log Compiling Images + + $this->imageWriter->writeImages(); + + $this->formWriter->writeFormObjects(); + + $this->mpdf->writeImportedPagesAndResolvedObjects(); + + $this->backgroundWriter->writeShaders(); + $this->backgroundWriter->writePatterns(); + + // Resource dictionary + $this->mpdf->offsets[2] = strlen($this->mpdf->buffer); + $this->writer->write('2 0 obj'); + $this->writer->write('<writer->write('/Font <<'); + foreach ($this->mpdf->fonts as $font) { + if (isset($font['type']) && $font['type'] === 'TTF' && !$font['used']) { + continue; + } + if (isset($font['type']) && $font['type'] === 'TTF' && ($font['sip'] || $font['smp'])) { + foreach ($font['n'] as $k => $fid) { + $this->writer->write('/F' . $font['subsetfontids'][$k] . ' ' . $font['n'][$k] . ' 0 R'); + } + } else { + $this->writer->write('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); + } + } + $this->writer->write('>>'); + + if (count($this->mpdf->spotColors)) { + $this->writer->write('/ColorSpace <<'); + foreach ($this->mpdf->spotColors as $color) { + $this->writer->write('/CS' . $color['i'] . ' ' . $color['n'] . ' 0 R'); + } + $this->writer->write('>>'); + } + + if (count($this->mpdf->extgstates)) { + $this->writer->write('/ExtGState <<'); + foreach ($this->mpdf->extgstates as $k => $extgstate) { + if (isset($extgstate['trans'])) { + $this->writer->write('/' . $extgstate['trans'] . ' ' . $extgstate['n'] . ' 0 R'); + } else { + $this->writer->write('/GS' . $k . ' ' . $extgstate['n'] . ' 0 R'); + } + } + $this->writer->write('>>'); + } + + /* -- BACKGROUNDS -- */ + if (($this->mpdf->gradients !== null && (count($this->mpdf->gradients) > 0))) { // mPDF 5.7.3 + + $this->writer->write('/Shading <<'); + + foreach ($this->mpdf->gradients as $id => $grad) { + $this->writer->write('/Sh' . $id . ' ' . $grad['id'] . ' 0 R'); + } + + $this->writer->write('>>'); + + /* + // ??? Not needed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + $this->writer->write('/Pattern <<'); + foreach ($this->mpdf->gradients as $id => $grad) { + $this->writer->write('/P'.$id.' '.$grad['pattern'].' 0 R'); + } + $this->writer->write('>>'); + */ + } + /* -- END BACKGROUNDS -- */ + + if (count($this->mpdf->images) || count($this->mpdf->formobjects) || count($this->mpdf->getImportedPages())) { + $this->writer->write('/XObject <<'); + foreach ($this->mpdf->images as $image) { + $this->writer->write('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); + } + foreach ($this->mpdf->formobjects as $formobject) { + $this->writer->write('/FO' . $formobject['i'] . ' ' . $formobject['n'] . ' 0 R'); + } + /* -- IMPORTS -- */ + foreach ($this->mpdf->getImportedPages() as $pageData) { + $this->writer->write('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R'); + } + /* -- END IMPORTS -- */ + $this->writer->write('>>'); + } + + /* -- BACKGROUNDS -- */ + + if (count($this->mpdf->patterns)) { + $this->writer->write('/Pattern <<'); + foreach ($this->mpdf->patterns as $k => $patterns) { + $this->writer->write('/P' . $k . ' ' . $patterns['n'] . ' 0 R'); + } + $this->writer->write('>>'); + } + /* -- END BACKGROUNDS -- */ + + if ($this->mpdf->hasOC || count($this->mpdf->layers)) { + $this->writer->write('/Properties <<'); + if ($this->mpdf->hasOC) { + $this->writer->write('/OC1 ' . $this->mpdf->n_ocg_print . ' 0 R /OC2 ' . $this->mpdf->n_ocg_view . ' 0 R /OC3 ' . $this->mpdf->n_ocg_hidden . ' 0 R '); + } + if (count($this->mpdf->layers)) { + foreach ($this->mpdf->layers as $id => $layer) { + $this->writer->write('/ZI' . $id . ' ' . $layer['n'] . ' 0 R'); + } + } + $this->writer->write('>>'); + } + + $this->writer->write('>>'); + $this->writer->write('endobj'); // end resource dictionary + + $this->bookmarkWriter->writeBookmarks(); + + if (!empty($this->mpdf->js)) { + $this->javaScriptWriter->writeJavascript(); + } + + if ($this->mpdf->encrypted) { + $this->writer->object(); + $this->mpdf->enc_obj_id = $this->mpdf->n; + $this->writer->write('<<'); + $this->metadataWriter->writeEncryption(); + $this->writer->write('>>'); + $this->writer->write('endobj'); + } + } + + /** + * @param \Psr\Log\LoggerInterface $logger + * + * @return void + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } +} diff --git a/lib/MPDF/vendor/mpdf/mpdf/src/functions-dev.php b/lib/MPDF/vendor/mpdf/mpdf/src/functions-dev.php new file mode 100644 index 0000000..355f3e3 --- /dev/null +++ b/lib/MPDF/vendor/mpdf/mpdf/src/functions-dev.php @@ -0,0 +1,13 @@ +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

Klby!eOZ67Ux~l_z%HfLRF-ap! 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 z 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

fb* z0~WGCL2xLm3`dYshQGt7R>$sY95`~;f}ypGc)P?Ol_JwLhl?U(t4TK1B+uJcT$7n; zNUcdVWMR@pdX`y&B?Lr4B79-CEb&4a4JKO2S>~7 zK+OB0uJ~IvvFk-0Cj5mL`QddQVb!Y*!6rcKh!Yk%xh+0)xcfs?!B=_R{jwAKBLV25>t+<~^?#{^dUVHO8|IMJ; zg9goZ{8gm9n2F+(p4aM3&PU@O2BC-A1yb_Qg2<{-EchF^{tEF>UF$|}fZ7DRHR_3L zN6sWdMS5hHy?1H-C`X`eUFW=YfyTy`@*o@Jz$#%5!x4=X*!h1uT*8~g00DZ}UlS~v zaj?&$7pmlKvJc9xLlPb5rc7{u|7zlWw3br6xthtRBVJS`s$S z=bM*pOt4&A++$XR!c=OZZ%A5gMzzQ`pBjlP3ov=Wn+M1@_cqN z?-I|`<46TvnK7s%aTmdCw9Bkh`FT?-h9oVpMQUr(&HQ*ZUtAtLWjFOZ1^-6LN#y$DzsU2g*K%{9RvL!n=*z0``oUEGci)YqN*m@ ztWeZgYlNS1gLgg5PkwmU;Bl@K)*6Mvlv3lnt$?A4X4TXnRZY!CE0b@HbNpUYlMrXk zXQa@@zU}Id@}d!6gCwZSEb#cj28;B^GN%NOTp;6!2_@EhzclTShN z03s{OtgJ14$ApCoCoEiqKNs9%0Hn}y?xqt}cTFePJYe&)z*w@4JBwqhdb47GLviR_dO(Fb> zGbVnyIWlMsdQ*``iPV-T1Um{15X)h7hJD`Z4$VdT-iQ3D7Wv#(!X!IBV@5cZouBOxHjDnwQ~J;$oKf|aI5%xTvHYZ+AH0gxyZIBSd^coJ z{}s{Cojv;;-*PWVTq*2@F~gq9AdtK|YCCl=^$2x<`aAVJP^kbizF@P8o#ZVLUys$N zS@4Dy$l636`yqv7S7}eAza5myKsHJ$l;T!NyibyBmNdbB^HkUuXTo2x}E%83Z#4{@lU!r!*ao47W%O>(o?IYBWqwNo_-jmLzI zlgAp9RM%=JM+Z-1nf#di>in1uc)9dd_gB6&Ej_*udD`!;H#`KP(wzg5$3|7`CM~zOaO2s)CTku9orm9F^l{$2yvSwK3*gk#6K-%$%Ez&ohQHCl* zZspi@Q!IT$CQS;4uphQTCITP*27FXW^@sN^?1gs^pP=5PPEqi-MI>VeJp}1pyJ_*R zCtQ3Hc5su8wP5byglQKK0ppQPQf!+{$l>i((2 z6_l8lWmV;Ds&l-8d35r07mq5Ei}>@HN6S;`UH3ORR+#J+*0Dj;*{O=4s4zVnYmR`8 zy4TM7boO}XwsMtO3mbK#73@rQwt^jNEiX#TvPMP3W;Gsr-+AoJvBr#eRT}+;Hm|xM zdLw4I*W6zPhRaGz2Zpl(!}X1>sIoFE(zE<D z4Jybk>pf*pSbR=~uz|f5Wj8Y=xKHiiJ|Xmw%c}J5>pNj|S)bTYgKj{kK0I8JYlzHF z(iy_ydRJ$dC)~h9$Haw&GLXjs`6}{y1OutHu)q9K&~|uoB)^2KFhjX&5#U`;m$s|` za+P0krQ!qgK#0}^EQZtd@#>Q+$IV*QRsjO~(B-TsKz|-mnw?XD6aDk)s$87>zc;%S z?*!iI zA70y*p13&Gc7S)1ZEN!(k%RAfHI}E~S8Yqr>|bO%fc;)ke?-7axCQbZW`W&wfI12~ z#5E=0=op>=x>U8qWnO`eh2v>pVpT#QmsBpHJZhCFVo0SD^5HhZMH?Ipak+J+k*878 zqKU@L?T*SNv@%#;yMz|4b4IFO;{1nay%NNPixo>)$?|4gHB06~T_RbnlRwFmI78Qs ztGIqDI10?(K+Bk{UF^?NicDM6ODtr<38p#cDrLfGJZqOI6P24ri{(p#L~AF=Rlp>2 z;_3_!lfAjL=aB2Sj>*X$v-SERJ<%CrZ-L$k_2Hjs)Nbk_>T%FIhpA)T%thT-`vyV& zyV9JhG{HtzQeVgIXJR#Jf;6!1;iF4b0f*@a$@UW=Bah#4fL0usxb3x9b|9U|M(7uk zn6{jxRRzvdmt{8NHB+WcC@=r{01SE?x=8ql?g^^$6eMZkIFqQ4^iV&{N==0tVvxlE z`hYBmz;+*@q>^0+8U(6$`EGDz2u1ZuWL7~F`0r5=DFr1XSUXgL{|6s5WVeXbkhmyA zL7Kaq5?D!itpI8-5oZyKj7g=J6xBBk*5f@n^Iuq6F>c+sLS>|W@J%=e%e_(ZSAi=0 z{2k8IYP~kvr@~QmW~fx(h@a|wj-T$XZdCRj`uJxwMph^Z^@@s5R%JqQCGhibaV3>r zBdI5LFQfvD49!V`bcfR`$O20$M6eF1y^qI@9%ll0l z)VO5O*I)1X6MqQZNHWbP;1ms@A9BuP&-3pqrbDd&b(Ml*Sj4cZQz!E&_{c*B#^^kP z5*|LGfLByudee>@c{~oBH~A$!1tZVqXs<@HliM0R^4)pLJ+cLsj6bN zy?9JjcqA2xQm7P^OF<-MJiKqg$QPmn{__*uFZ^$$U&kKyd`koO8^o)RSA|AvbgCdk zF~RYwzoSIZG&+=6r7;AjMI#LrA085v5Pws0&`lv}s#E7qojazEDv2tAA7S{X&J{%I zO5j|HdqinuL}?I+b&aSYm3Aj~GC`G~PKZj-Bt$2~Bxnzz%udv&Z>HyrHVw3t#aL7(3qCOS zb zbJ<`Zw8m&r8lBUT^^>Pwe)%cqa zMW?VS96XKAWplZ(@rWtZ*$Wxxbn?7U*z+jp!3TlGkmCt}?HYhBoElyg#zHPugmQHd zT1`a|79tE>aMH~%5d^*nsKMcaFNwgXj0_?WDpP_8jLO`g+~C~si1Db95Z7La1C(aR z6We1Z*49pp*{<4u`|bO=UwW38_guYU1D2obIf}o9&@SUy>OUYrYbcN)B6;WBkN1`! zSl2Q*uSZe*d5}bmKiY9W!1EjFM@i|cA}N+p2BD!$B||fu5~TU$sqsV;l%E7~#uCS1 zsr!gX-IH$F!;8*Be?idSL|1?CW)vf)9da5mhtRi4d?NA+z6mlHcY!W}iVZQwUGM{E zXnY#soJQ>1Qg*mvf!~X}cENvF8@L0vfmT9J9HoI4xV$KCxpLPo_z#WIj$KoQKB0Y! z!rf;mMd7yi9*_1@@g3qAS`@Ca!5Ctor5b+m(@7)zc-E`WNTFBUPU&h-224K4UBa!1 zTGR4#&=&e$*wH~jQY6bMENP6{ZooE&mXxL_vKV0L0~h2|8}*7^nfLM^@wa?;BUJH4 zRcLzQk^UpzxaYt5RjFvYs;FSjpf&uD4_bQ+rcu&hq~FwV?bvbEak&FVEu1kZd*|Rj zEilfOmUDpEk#xOEp?Ow3X6nf?)UpJeuW5NP_-^JbSYh~$K;+3d8VK_$D;u3bkFzC& z1PU=54_B@vJ5I^?gRWV5U+$de@2e{9H`Qt9=d6|n4eLpu$3wTo<}aRk+e=$VThsXR zK?QL+c?t2o<56T}3l+%)Clv!2gHSjIqi=OwNLcv&kIm?{zN)mk$C6=puQg9tG_X85 zqsNeGm2r677%uiM7Cm$8hfNMjymj6mznwj-r(t34wrTXxL~~h^3MIworzb@@Uq)1L zbRPxkH)5SN>w)47gi5pbjCu4A_g5FDxyHo(6UL;+HJmA&I*%Xd#wj@3nMe(U7KVh4 zB@6f_FlIUdZNYeX_~8>6hbN{_KXKplb8=5S{BW9eG#Y+OPTab<9Of)R#f@vC0b!bg z0!<{MqSxGb_pl{Bc-lI1h&?&kK4d1Q=^Q>xIgq{`G!UjK5Kak?7Wm4F-F+o%f~7UU zkBjy2QV1rx2dbbpHm6tQCRs9)l8tGpH=uEveiI(&zvZ9d*Q_3)46>lmdkzdwKa+KMSGb7Xl_Q+9S$Y2qD|tLkWO zn1o0BT_wX>T>OgZs#0jziu{Uk3difjV|pa>fy$y?hDI~JJ^9+>yujZ;2=okkmefF? zOc>#S32g!7072jzfCl5SK!*zB;|3NK42+9kTUm9mvZ|``VAa3U;^PWT=7RXR)d#EK z=U`Q3WlIaShJP?<3sVQrzkyNGhhcGK6-B9(+D-IN{DWBD_*3*s<{P-aiF%noh1*eQ zpuIwSlQ8}k1ye6xZ&Apuug2E}9l>sd^D7u7^CR2`{k!CNHkXXgQ)l41yFZFz>OIa2 z{oKokaqn{{RTgdqb-1NirHBUoD)hrCxtZkrc^ID}8tX`+C!oFjJWIwS^z#)wcO^ZS zyT+@ZHRSwm_MBHg^7G#PEJr`Fqx|%4J;sCk5zou|VIP3=%jkt{sLG7t0{pL_ zmr~^f|6!bx?I~Pm9)`aw&`*G8cfS}fey>CSV0uzqIcrw-!*f$GvLV*oe1|?C1(wai=3pt~r z8R~g;bZ8`#&#F*9EbRa5TmcxKCt=Rb{i2|xG1#y@2uE+BvGhbVZvNai_^%(DUh906e~3HnC}&Pwto&rz((fBKFi$wj z0j~Wp-Y40KAO{p=3*dRm0Lev#XbqbF>Z|-+|NJLAk&k_WABdiL0q{Wcd-xjq5VY6g zx1DM59SW!~0}3oU25%rp(?ppHm8lj`U!-X4el&e=@#4s_bKh7P9~aJl!Lq3E9d2{g zOd4IAIo%w~PITnGi*`?0in9yiQ3AXX~1IK&GgL)M2^;sJVbW zjOsD}xvq@?I>I@6ib{#w0GXs~SQeM!_QEw9_9qMXu|+{k;M#TUH}ooxKCR?=_}U_N zjn}o+im5Ob;l8=}8hKurt55OTA}-A9+9X9UHXg&EUC16q!#&1Qt*B>hK}+FUBf#J} z7U4b&pX)vWPV&5J#bmf|9$W+X=<5LnxF0o=Yr=iPIGaeHSj2>-+PR>Eg3kMLm%C2a1 zQ}M)}1L-iRNmhZy3U(Zx{jnXF%KW4?ulnRG9*V=r7>>_+W((@J2Zv??J=o$K?A{z9J?SO&~r&M7o$GH=Oo`@Je=n3_(vGsqW z6fMV!$K=Ce`JWW;D|63%kyjObP58v{>%wmeXVG|2HPL{#7;uGbpj2w72Q7c&eMNNh zp$!e+|NB!y59(&H{m#?p;h9kJ6JT7~@;T?=eo!gU7v#9U<#YDmTqYcUNsjmP3+NZv zi7GSoUw}bD-+K)D0Xr!fKJEq`NBj+N|1|Kv4Fjrwnf&? zH}fy5N=81(oNB)C9M`Y;>9gk-Hynp?)BJT<#{wTe(Q++p)>q*1!TEjsU^>b@UL}2s znLx&S81+MMvRj4mYQV2k!|!42+TmYz>o5F6;NcUB)i zYp*%ZzrsF+y*bB1@aT-pb_yX_N#=s73wX{mK?Woj?AUYR!UcFFjOA(eb!Je|k18_< z`a`AU76Z=e#q+__+~+|nxy~Pg_TRvHXbJ7%E|`DCe)R74OWp0Ee_21*yU*i(aC>O! z>L&~O`4{^plcof_3+x(v9>E=ujGiXBO z313%Il!&M3W6%VGP_9Non<$|Vp$%?<8(hS8K22eMYh?ZgeZ;^qu5bZ~=^BXBK)%18 z0v7<%Zr>=aD=n>id&rpMz*{kBJ&LjHqzK z^GmTq{`=!&hPVgp?vWqCf1d<+giJ+>od-Ayp(ukI84@6D08EFLL3!sf2M(Yy{2sK8 zUdIgMgVC>!$N3cmOacGoKA2&#N#edU8f}%|iYVlLGocGxCOlJiujiez`?KGx$NlC|YR#H~x?KdAPk}Dt;KoALvc)ZfGAY@F|EkNG$LwngYy- zN8|2X7!z&_@-6VA(3)^1ZZ3>Oyg|UzheF>{d$G0H*fAB4yOnX!uR85)E_96UK@`D^ zh#S|KG5%enU~XxpEsMtha)w-O*$4&}AbzYs?do@elS9vP+gBR!tj9E+a!e5UM)j`S8lC-Qx& z@XQf@VT5P4@kHmhZ9K0z-S=ru0;51vZWQQ1;4Z+UrjUV812d7||M}^ubXl{S{ek`f zcF;`Z?}yE*B3`(=+qmcAFz#_b_pl$fdJkIe=Q;Ro^U7-g7crpFKy%=KF!jUKT4c~i zCBZO3cM2Pu@s49I3lbOq_NV`x3d)cL5~Y39$a=a ze|Fby%%;pe^KV>veZ{aTB2462xTXrxHtjqunyYH#ahPS>dLW^*VuuKuC?THE$zb#Q zG)Hd%HlK$%rpjR>a?7p+T?je>&vW9x{fwF)i5}rc(sQ`eEfoJU{9?rhKZ0Js_k_#! z2);A=m~r^X0F8%Oj75vR?x^w;=cUiJk3JyJO ze`L~nrtkycfp__r8`t)ZOOWvo=jsc%+qwyrbGsUWErFHCazD)jHZ$9;!%16YL&=B1!&wi@7xgQY`|NhmrG$&nSXj>pE}aS5B> z)CL@rgtCpW+-KO27!>}8>Dh%(Km04w9dn-Pv1-gPROjq(>|K4cHWJmL^Z)#HarT_U z7n*o8xDTm|UO2pz|LljGQp#W>+>J0s2HUgbxlyot#7sC3m%DH8$-s*3J(>#W*~&E% z%)s@Y&-Mqi*OU3Xd|;Ly>@@oUS)e;>0J?x417?=}LnHXtA&3WSi2O-3gQ)>|zm;Fm zLOBlu3k&)W-v==POi%g0Xf#uPD;Px@Rh!|9PJ0 z^ZEauna}T9Yp<7UUDsM`uYIkTy>DOs>aH~(`a1Y}1o~FPGH%BhPknFb5N%X52ON~E z4%36$`E1p6@mPDj^*LekDxX9DYirtLynk`<2Of^Ks>c~uv2tf@<72JbjzP~RvFQRM zY!m0^n)x+zJ!7+)r<`YQ#^o>@IjB!LwO~{h9R=gLg46b2wZ=VD2X%eMQ51Ro@l$Qj zgt89is{Yu^Q;iX-7CF@!Z==xV=p4||#5w6$EG9|}-c>VX%j-4$-2F9A@Y{~>S8cAz z@F$b;F+ZM%QH4B+cQ9A=Kxbji6NwphVD=t(@w~?;lo!uy<<;iABwnEA^T(LTF!BWX zmO?8^WTwx11z1aLGilZ6!=VvN6Iw%iKMy>5*O&)xyQC^3&@aGU*SY4ErOVhix7rF6 z4jORDpqe+-stEL6w7;f$u9*oop46716TP}+_>Z7NN;y!l<|m8Ms!lA3I=8aIdylA3 zow5$Liq-eIY)-i9eSaE8=&pGN$K!yMr0vtvhtO)wkyRVAGoKoyUB8#KsDH zo_k|OV$P<)aBWt~tDiYO&d^Qbc2;7k2{{up+Oh&Y58F6YMn3&|l`v1`P)O5e$2LCc zGRcIa(K?wF9t(LVorV6WAE|*O?|l!;qS?P2=`jS>+r6AL+{J@I)jec%w*!~ zE7j2__>PY8?)#3!q)JzJ4vz0OPd=F1M!|S;9@+;pD1Tc=)iE9Z2gme-IlS}-PCImr zXyE920;>skZQfFIt*s@De1HN@ui6|FZ;+@zMl^6R;|}IZdB7RTdcwhM2}6WeuLs8n zKd+VN<@}>xo;OBVA9B@pv@h&?vrApMRI`s?9phg=V8?rnCpE4!+x}gfPE4lnIq}q* zw*vFppFHmT3olH)zr#t+vg(s+=iJWNq+@kT-Q(z^$2n5-NW(@wuglz;dG&csqhpzS zHLsn0$7MG;?DvhSS-up-Wd0XO($rb@OGJ@>QI<5nPJU9BI(2eHNoqD8tdgIQgKz35 zR7t{EWPRBmQEVIvmacK%ulYWZ>Eq22+6f4AIxxY%<=khJiVXVPizB? zHzvAE^r`BPP6;Do;9{m{@d42u#hxsrw|Qe?4u3o&3pa0KCjZ`YGvei_JaL(@O1$wi zaPh%RJcbX>$C9)p8~(|K=}gYjz{S<8QM>x%9l=6>=4jdD&u_htZM@cZskxKu=5D&? zV0L{%9KyivQ&-1qEBj!6E!)psGk1rddH-n%W$UP@2OglaPK+eYHz)aK6dLR+;0u|@^~E?oWy(Yr=+N^K6vN- zlpqN`{xFhw&l^|ow?pdVCuCv8ytY1$BuU*0IkFrz)2V{^^Yq{tRDUcyiI3F%lF?8f z9KUEhjLEno4~Qy{_ED4PB);&gPn&vU;!jCbXDs?DkrHZ!G5VLuq-}MCak`F7M;;yP zN_6D$v93II21xdKKMQV;wF)!sQADpp zj1%k;EhP-$!!8b{>y-u3Ce2B9&b@?1V&EfbERx6K|bvQot)BF@4;*Kbf&&N;W z@ewC*S@_y;Hs@Cu%biHO4(&XIvnQmczL#p45V>T}1pe6JbEK?haAZ8~%_t3scBggbEOJXriwF=2L^C9aj@Q3JU?m%hc9r4)#q`X(~cjv zET~ylGo2~yHT?eUZ8d3o0#{W(=MJkb4Ww61HV%#~E7F)xasv7e%6koJG$!XrB``lvdCzEStxPRbmR{N&R*Vxj^Z%*@L`1Ruc5@7WVkK;aLxuaY;ZH_+c#x3kl6b|+sGAZc3*gmcb08Yq&sKT+BaoARO5rW)E4n> zOFur^%i>v=JTyMepMCl`f6i!yzSDZ*j9kM=cMDg(ga_yQ;n7|euKa4l<9v|cmvdt1 z29vW6KZ}pcIgyidsz)8Z79W?hUcB;8t_gezf96BvyFc`uuV18@g)_U>@WA`E;on<$ z>%{OlA1f!$XQF!`*jDvrkE5A|$N5YQ990|sy@kj5c;S54RiaOZn<5YU6qGxWWBP;Q ze8MpcZx;^_{OE^A{%qkXiQzJiGa8SCE{4yk@o?wq;7f5n?$hBk!kNY>f9Gj;xffnw z={tMj_iB3dTBK)$IqR5h;r9i1dG)Zx&T6*TvzqX^FEF}hi}I=2VrMq#F&e^onOwWy zj86!?j1RHlG42DJFOi?cD?iPBcRW6kuf@af(0IwNE~z8uq~M)#IjcXeBPS;U<8oGi z?8#{%wQ}C6=Vx8c5;V(;>*YQWywj_nxuKAioZ;R@dgP3Uhd%JaXIpq&-#DKGwS2T4 zYx#sPgU>|g6L)o8KJoCt@fHpr#@FoF^U3FNrluR`IlB3Wb~%#Gt08)Z_>`2!oMP?C zG?Iy2v*w{@$DZhL^5~?KJA~a%PTLMC+2`ru@vD{uGMrP-9@j9?WYB>}YBnZ!7#4UV zFuH2&-6uqkzug`1-6>7Z9oVAg%Whq!)>PE|wYsEc(-SP2_j%;H>xbUl=lFJmG8mJ=(pBJA$M}9=s6V0OG5VmeI)R)k0 z%v&r?Lm!Q4+$7MV$Kix=+P?EQM>-sTO7i&RL(4p?W_HOF_UzGnE4q~OQvC9MxR~|oQp!+yzrMTJkG}pml@S1 zb@)v3$1D1OqCAtFi~RoYCd%W5$MuR_f?kD(>Sf{c6XiEM_GJrSkQlDxM)aZtJ_pCo zE$&kZeD3$@j%rZkxPP&sh<+$ zWZVq)u6o19sck z!(Y$5YyS9|_e1#GnRhRqv)JvM)#J~2dx@UqHu-rT1xm2fgdbxOW7*%9r3F<>A9EmPZl% z;qY0K96nykLVuQ9!^ODw#u0vu>lZjfyLhLOAMchZ zFBVvKJFdD~2Y%gCKhJ{6q2_WK?(v!ixsC>}N5yI7=1`xf$pX!zb#GzB5&wdPJw%&4 zBtu1gCE4h-LbgsV#R@du}`!ewNKY~BirS6!b&Yp?>Fk$?z;pxX|UWHT}wFk zpxy_b`N_odz&M|8Po?Y^n!YM;?|`=zel?{?4W{jTlo-S>9yasMZ}-u>MqJUKSj z#vb|v?p3r;H|zUe+iM&1^c)*LT4q>VPl>m4_$?XEy*e#)Z|u?F#MmP?R%J*inkl70 z-cbskzSjsT$0_g*w;F4gkOj~>epqsT1HTxH$r z>sgF5l%xG8bP@cAN;3ZS4S5%(L4PSrzDY8p$1=`-NId;2sZ`36MoU?AG_ra34C%x4 zE4Q{U{KB@<`^4wryE@+JJ%7l3Vf7dLuC@%n|DhW?4bi@yD6^kG`AX^oJ!<>1Cv$B% zj7vH;_~rX<{ri{uX&Ghwh^}YqeRqf)@&10V-_Ps!)7t*-_v?I_=5CW);&R1y>3tRc z8{@%!jQtnUul%<2y6VjXq;T=-ytshK>XA zaoWZk_t)G@`La}9cLHThr_a73&xT)?QtqWi9(Wcr=4BB76kuG6XkFeT!^1c5>>EH{ z5b6pq#wM`TEhh|w+A$^ptqWEj%D9jJ>V8O^cfaYq7NKnJn?<2ap85VW-NqKl4LyqN z6F^%T0>-)ASBbE8YeYHd8@eBv9#;8libJ1J#z6R@zn?zoJjqO23C@+w$lKB?+@7-U zl2*|k(joj8(wU|1&~ZaDj9nIdQbsA9wXrRMeCpIg@KR}QX$MQAz#Xy> z+ioHDz-FL!K~3Nr;e8WONWTWy2@T?q7u2Qz4=b?$KEcJ#a7N-@fACta*D&5w`nAF1 zM_5bHHkdAV1s2L(V zR_Jx;0>&!iCB-6DnIhG<;IgVw#muhiHGoA|wVLqDaj|TxSvRiw47?6VS6zhrIcN(= zXKA+(z9Wv9=JWY}PZ;IYbO&?sUq{^6U?+Z7SkPnGjd+(o#^uR2!0 zgj<2z23ON^{;*2x%11h3DP-oadNkq4Qr$T2k7-@q4W@a}cu?Ic?p6&C&7%JExc5$H zY+a6BLElo?cs7szDb4~L1F)&wTd<+A_k&ZN>s;C{e4})y@4Xu?kG&IZ68pr>j=djg z8~Zr&VeHLFhuCYu6Xi@Dd+b?^jZ!-fF(xX1y_fWPrO#B2^XCAeqvcJFGZ~l**qF(9 zt7DXfWB-RY$UXRblK)~GyB?IAbv)ANFy$@?-6lnh8#n71#<W(j=DN_k>`xiKjkjfL(8ePOBtVo|HO`1Ad^Cu$WxJ_GA888 z>CsoHhd;=Ka7o>;gl#;)01_YKVkgqf?)3lND=@3ftTWAkZyf%Ek_l9VdfCnd+z zgnvUDYMY)W=a}oYyWjSawlY!qCA}plQs)m_8cnbHo|NnTwy)FfDhutdJR|=}J<#r| zfB0T`GU;<{nt7C+%lzju!s0UKBxT|6Bsn?IQiI+k0TsOvxb7E4s^&d46Q+va`W5ch!OMjzy!*$UsFbd01Db`0gbBGV#o z;BP1A`OnGFOVUxxw|j_Z63;q)-nG*L8UgWW6WuKhsk0JjV7(R_*K z>~JALQ>n_l~gt8JAyPoOSst$_J@^e?O(u%@DY zN87KC%Xq*u`Izwir14zs=f12aV=`sVlOEx_nA}YU>4iID`#iWzjEcU9Y_p+SMONaHy`p{S5Z9AY?`3Tly=Sc7 z`t74@D%6u-U$o~8ce@Ntx>#mJPLZL}z4B%xQ+^*_C~t-yk>4l%r}T)PET^em9&Lqu zE4f!&aeqC;{W^knU>>F8t=`*uemSOwLI;P=lXehI(&sZ5PDJO zgt|*o=tI)3l9bRQIRpFa>5#6Y@I($R#r=ruJLRhI9^#kFIE(*?eyQoFGtR=3=jAxJ z5S~jZdlvUoOKktGGBmJQJ_wY_*uZ#pxT{%%%Z_~;e4cfwSLLcmwmcp>S>{pZRiUSG zPv*KkHhP}<=Y<=3aVat{aKFrp?BKd3X;Vl?n5(+tlJ5Zx3rvW;7D|cb26wV9rFp*L z*-07LokNjvo~BVm?u+LS(SE`A;j7nY#vXOQm!Zrr&tq=zc;GYHh`d=yd;<%OXMmOf zyTz`tx17(xE#LumlCbg=>JQwmX>{#Mueo1H8^%U*j#qzhzbw>n+Nsq2jOXMN*bgfh zS00qrfmda9uv^?8x=a2TxK5_JMZ`}99}@n!tPZW03`@6=>(TPZP&)3dgkK0Qljfn` za$#tvtajh!9%{_^d9O4L4di+nygJC#;G>K^&w|0RDn+D;N?%BESk1@S>3nSM^w%)_hWXX2_C^xCA2$joxA8sp|Y?v2&#sv+CS0uj{ zNAyaWp+K%bC<0}%-AR{AcBF&c3I7@4e-O7_riZu416qcbt>r3^Z`%>Df^b$lMc-M* zu5`}Tbl75Vxt}|)f)m}(S(l8X05=<44m4bGKFHJlNj*H|X3Djym&ydM)q%k>+}HI; zuCM>$+~5qE{BzK{N<`?My4Q(yS-(ED9<>e+2dh`~h@M6Lcc#5?wVr+G_2HoHPzSV! zwn-u)Q)nyNKCz9g%?_<|t@~er=Rj?pGZyN4`lDd+VNgk!VutoP&X{DlLu`GyjoBkS zXWTW6q58Z@CGK{v0k&ajXbQIOqdeOf&)uUKy9>!jI>y2_tUblkl#quw4RZ^)hcurD zy;jhNn2*R5`oKh7<}-3({90Y-Ui`0Xe*v3)nV4JeM&<{@SHZIi)WGXe?9x5h&HrQ! zZN~Vu1RHe`*dN;*epEVzw#wz9cjXF2WEi&ae4fL9mwATgdES#J+)-{~o}3<9Ar}&V zdo+zP?JXG*zDRD0OrV@>xsgICXW9ct_L%ZZGca&tg*urFAH%sZVdKw0q%4| zb{Kow&ljE@4-3u3eOXe&@8aH%&8BHI?+9$$>5MV^@oWB(lIuQf{%m)UoNat2Sa_Cu zm*@V0{G0KA06f`wBX2P&YS$`YyUe?~>Wk zME4HT>$T?wx64Gv{xU-s(w@w`>09o{Z?S_8La%*Tc=R0FX@jKe`ZBJqGpp-|`)>Vs zy>4C@;@=qbJ=l(0@di?$Jd^g=M_i*ukxuKx+0%Zx%YabRKIg0tm2huCN3%440 zu7y`iFW>dU6W!os^t+kP} z`r*FohbOqff1uB^05@_oJUk>dL+?bCBJX^{>bVW*;|($;{YWnBE)&Duxlg;(W(T3y zJ}f*MrmsdAS6U+f5BPo85BFU^Ji!fqhy08kZd2}^3(0#SZTt@H`VPE2*t~c<^%zGw zu0hLodu7XrH(Ku6@mG zk7Qhh-!^tl-L%oMC(JnlaA)ub>RZA3vdXFDG&(7cqZqS~8gcO29fF?ds8!MsVk$$R&~becANC29XmIQc`w zGylCi)Djn4EBs7+|I7W9XQZA%P@C;`{1d2O=EZ931@~gx45BRuvRA9?PrClYnxLic zN1ixZ={~HjOFbyp@w^_+`qF6%TkklQJYUMQky+T6zhw^Z?Ps`pHsMqmt9ud}rgod= z4WGv~^YP$cB#b>R!4G9T=Rn2>?~cQ5Cuwd^8Sm^+#8w5rBD{x;XFMFQ;f8*sIaaP@ zemg$+85k{Lw>fEkEA4|%b8bQLzKmp@)m-)0qB(vAVeAu(M2?Z6D{-F$Ujg;2tI&Kc zfyVtIo{lklWN@C02#%7b!ST|IapUS>nw+G(bgx9y)=8sjy)?F_r#i6z6WY&uQES>j z%g{3Ya#c1LUX{2S2fsiCNb_9$!F%w}1B=1;$TiTD?Lo?ZfcV(}`Q5>|!@y|(J=~?Z zd%@YrM1GU=THG##tpmm2HW`TxdSP80_!9f{OSLm}UDMV&S)Z)$`fFi&pP*~z&$+b! zFFNC(>4Kb{@%LhFEs8a>dhVHAa~_60SjG@tV`m*e&pHHf2jQM%>uB`%`mU}?5x*4o z0^Ahux>MYZeHmemTKC!OyM8%GbdRuB=C7UESWG?oF6+jLXC0P$*S_1gcJKH9^6Z1I zQR@Dq+HTa(&!2(N_SUh)bNw~4pL1*1@Vqs>+BH#cFWTReu61cE+ZWB^Y?H1()5o;E zgA-$)s2e#AdD%ay?SFnh{4aL@mHue!>-G9C{p?}-&z-o|pZs?ImtF4+hkusih;IFM z^v`enj9c3t_13EW@JJE$-Cmkd=QsZpv^^Bjba7eBk3=T&8zL(>zwsRF+<%scK4%Vx z@HG+%UnkM%2J*cw5x({wjNU1nVdGx-2}EX42Hz#)`%5mHr4i1L1e2D)V-&om@QHi& z)8dF#22YGl!=Hw`7gT}ogP)S-Yh>$*jQu1+SwZHhE_1;sh?1nuF!2gx-O`d-;>EN>!;dK<9@Ck{c?`v{#?8GavaJ1rFtJu4`233Fjk}c z!FnA(AHcqG{G32B>yyQYlRa`5d35i%I98+k$2yLa_9F0*=All*pcD1`67HEGihnQn zcV}?EyDwIwd(Nc23jA909MT_jd{_AWMDIBe?G&rged_Rw^gYqD4|X=;`oq;xG>^3G zYe$#ivaii}(i7b{KVjz}?4U0B&BZ2=0Dgy)0-?ujomHIQ5wHOq=1Bt&=N7kG=Ci;0cz7y;(3&7gQ8|+EBteNY&Ib6aEV`~(FMX_0o zA)N?&-5FdnT+ig{dEDr)xewCEso-~Da{Qd3WHd}+{?1F2iv}mtHy)GL;9{UW zlEXWgKRiZ%c}!Y>+rk}0&$_UDSjGNjmc7-akX3W9*rK zBIA9MP2ahgF>`2gC4KWM>gmhabD>oDvF;LH#olRG>E@2(`FlLii{m(OUCg@nYSN9A z3$ZUw;r*=h-YBE}^Vbcw*Pg>3>4m8~6!h}0Z}eOZQ@^egXQ{2C=QWY1EV@3f zQ}iuKZqQ7UkGhd(`wxU+$3?%F4h_y{euu5B?V`55+QZ0G>TbiP-p`!=&x~_A|9e5& zByEy54Zgv@hA{SZaoZ$)Ds3#icP3u@6#KV#Dlc{Y`GdO1m&(1y{pL)^9p|}v%{hC1 z!?h0Vz9fyb1j$~$953Ia@oVNIhwwArdQWTKL|6S)lra=cOK`V)>6+o50si4#Kacyk z=O=IA3-Wk!EAQHCy~CEoNu8vl!NIO^AYnjU#AEoJ+< z`EvNzmaZr9JxJRx?yCQA(0I8&4ok0PsQjL6wXR>jy72bO;Qru#zlpQJ=a_BHJ;8lB zEX0dx3hudC3hu{`68+pqm7KMmtq8pme@6tKI>uz_yB49xoIzZF8wxmGbsXk-)8E6T zi~(igrGWJCoUg$Dcb;b@jQcl%zo;92(CMBC_H#~*jFJ;sH#*UsA}2&P$$;c3oMW64 zzt%9yzh4m;D)*_YWgG$d8XgpR?g;Tm%BSI550mFZ!rsTmtpu+hCjO`R9WL%;czhgQ z9Y=JS%v4Y>%LzYR`Sp2hB3&Zt$Jf7pi}XK_#5Sp4x7SnGiWTzmFMzgrE!YElE)njv z?2m%Pu*3P`q2>M6b8B_NPPkt|xMB#rrZA^|uNJ=SuVACZaWn4Cti6P-zXmw7Pa1d} z0xRnQ?q|gcdBv_*SbFj}le}w_rNNCdQ;`_g);MS_o;u+){CF% z-OnGfMw|x5@a)P(c5h6IyTM(~3BH}?yWt6eO=0%yYF+Bcy;8zFW0$F3!8O=*Yb4)y z-OrrQxNlES>LrDW1_M2Jx=g_DgsWsWHoKlDFIBtR<~m?w;yj!5PY5f)1?f{#ythduaa9 z-SM!)#c6p5!&UxYg3t)g!2mz4dmCq8fa;wH*JW)M_+j<0j}(5Sbe8@AHaPcE7#EE3 zT=gFjtQ(I8t2xiOI`Y~<1dr#QOn@&>eOKo;zOIRGVmi*KjZTbH{~L z^5UL)hI?)}ZWdSyazLJf^Hoc+g*9wxg!4a&&<)t;EoE}j4>Fx~k;jNz1y(Bf&gfiR zDkJrv9C*Zr$JM_m}WUKHuim(%LM*@}M zBJecOxaGv1kE^!*=lHJyFM+E-m&1hjkB2)K68A^^8Mr%fFTmA&-nDEER$$X|=8&)n z#FcUVVgMUB_-9!bs$#5ZE4hRd&snaYhNelVFXt@Aso94^-E@h0>ibnrll2brRNz0# zO{cGPmiqv%(+PJSE`7}j#X%b{piPqGx#&v9`&)T7_Ey`)If^mu9o#9nNpV;GPBplV zuyl|dUc<9*h4Xy8?VKUF%N3lFpAg#S{0Hbuy1|Liv|Otlt>Nlk>iPA00?=p1A8=0t zFM;l!n}Pcq;=1Dg9XE)pywn!QW@ikj1GN>MhTvCTxY`dYx0Z9Y=f4(L(FJI@y7h53 zVaOx}K+8x2%E#xYeuc(8Qo4_fnML}!T8Wdw}SiY0UIC~Vm`4P zgxME*7EEwokY@pPraC$czyNqrrlWQB09c6su{Z)JkQX?A1fPI*pf|V%+)G?J7=iy* z@cUo%%+lwY^$+bM|7FlQhPG#-tNz1bC*eN4cxQLLwAzn=b6gyp9b2JrQgO8no&=iL zZ#&E3W%;TJs*zn z4FrYGA8+t*n0chx$E2}zB7Lwa4M$yea6LoUG=3Vf@_O;QHgY2JSozBPzX9>Ji6is= zx%huaCVk$l0lwQ4Kk(PaYQq!aYuCl}d2xl}kU2o2&964T&I|TRib3a!ah$C42g0sU zu+EyS@A&g>^>+3^8tPd9_Qfx-eexyv*(cRCXg$B<@1t|Z_$FPGwLLL?zq$`=uI21& z+++Ld1N?U_!@NW24j`YN^_d_G^<7_{VPQRApu9p?fZ@`X_Z+ScML9ox8SitQ&v~&| zc@OM-xh8Zb^V-3Zj(=e2CgSgufxOR?9=e;eT+JV#V!KK zdAo;u;9I+gNxAmkVE7Kst^Jj{ZN{En6?KB^=M8WkFtl4b>%Ktb%GkQlFs{D@ceCC| ze%35zBU4VeH*$T;58@Uo>(KH$!=KWQ_3|+&H1hE1ovWhcq% zS?gN+u-6ale$YDCeGB@x-bbL5wFT?b+IF_za;~h_b1l|h?9Wo>3_p#>Yqs?P+Dp&R zD0GhodF~9%l-c0yP!|0M;6Dq@a}_7h zyN`N~wUl@DCPr@IT=eU_m)f6q(2gUV{T1sg+_TaC$nX!|nM`A!shb=--7+o@rpoy=C>Y#kIJ-Q8}=y&ah?;{{Xsd=G|Jz``(WOC zcXrN@_f3=8OXBQjM)JkDIg-J-^<>U~XG9mVcgDLWwQj%oHG6w~^*!&Z--2MRu`GNF=^l%H&D!19;jXxYa9_X$;ZCuy`Ci4>q1R$x zyCBjmHdf!orH|-2u5{ZIW2{J?D{0PZdD+<`Hw8|X9)X^`b9;fb)aygSiT_36EZdh`xoA20KAiy73qn8zuW?{LYGQvq$AfWEi5bP3c>=w<=vzd_WLzYkUY1N98Ve7&Dg80KgpJieFzScLKP5p-b%H05$cI^=DD0ehy zDFqFh$ifC;fO`~k;sEdcaZ+NOzONU$N(Mx7_zuVb?x#$i&zHh)o1NEL9e$j!Hn#8e zk-qDf2z|fM2W!!F-ZKn7AVWBxIz->%Hn5BB9O$$#;+z2EjQ?;D=WS(SD1_Xd*^u9@F@?;#RjuK3rk zIg2rwx`@BOcsN(z(cAC6mxt@WH|IVT+pYLluk~HJNZ0r~b?W-{#(N$!BFVg4Hys`N zG3FOA=D#8{g6~kyoq%^DIj3D(o1S+gqb&~ByZqaK`kfE`)9+z$Zl_H8=zE&xmdow& z>x3{rF77t*(q5*n>%B*ctoANx(22iKs`4}L6>@Fwl}6CP*GI=g!tFiN#QtRO7Je*w zKi9AR?RKx%&icM(gDV-EKBbLQI0Ikr+TLybn)sJFC;vHT=k;CJgll`}mG>AU(}>qI zR{9QX!Zl;Gz6(2!?`!RLb7}K>*Y*2-MBkO|!MOzQKA`Sq@D9ujzaR1pp20Xe!>>=q z|LNh2WxBf;-oK_ldHv3h_v_W~Z+`#MHqn0NyMB7U1)Uu}HkKXwPWpzA<(<0kSW`L{ z+u3uq&(!~m?&2M`RgAysykE>aZrIb6oclHenP+gWsgifp)t0FYO(gtNsZ7phzkL_s zS@AgdSMnUJKjL+B9md6%%TS~5e z+r{R#r1R}}lb<<&x;7V9U9fe{7Kdk|?QZtJet(61Ur(R^w(oD&>VvH6H+`6Ys4gn2 z%^Cc&Vmde1xk$b53z=?O4?3^Wxrge=yb;^izAZ zI%GZK4D5P+hr9^<)Hhj2dFg)k+pWoeW!(Ay0DOC{^8W{5r&s=uA&qs*|H<;|mz5#E zOPU~;GcKN+ly-10I%x>s%}m&v_WZv+Ojzyy_5XC-VPtIQ%h2%sgSvQOeMmnHe;;t} z;ehR_?|Z%OxyAVT&QjIG9yq^U&0Bg^3qe$7Gh5=T1wQ=iMB6cOo{(re`8JKi*W?n@ zC;H>|B+sJSImJ)=-S%qzR4r#reMjG^v+p2Ia2^WPMYn|O8}VNN65R{A_Mzb;zyQy+ z_uy1tTVLW^A^N?LM4K;hKA>|JJKu`!9QMAysn@{H?BWK%QhWEG=N#+G%TPeSsd6~j zH(28NnG?K%&8pw#7^W`Z8y)&?sl8vS?^pJut`z$Hjfd5(>*t#cBiuEl2Z?ETK4(Ny zv6q2s-}X?~_g8ClOOe!ADs)I}B{b9MJWEq(biUCAMvE-vtCnW1QYS@uI_-^~s%f0gM$a(X#pu~a zduUlsFXiC$w!D4Jzs>UQHUD=So^+q4OqytPveCb3Z1NAWzR-O#2718!RrpUqmu1jC zu^G@*qeV)c9!7f^wOD7b`r)s1qS47l{|0SOjh+eZ0opsQjcUEMciI{~+33eglYfxQ zp$DKH$kiU2O6zoxBBki4w2#rfN|XMkGRH89K>{ zMpI(P;qM!p3hjq>on(;FYhsh}XT;`0Gc9GdrOYv!Yc$VjzR^X-VX@I-qfZ)LV)QAa zB}SJT|7VPr8eL{|h0zy{zGQTz(N#uQ8-3a2DKq*fqpui!)g)YNbe+lbnw3><{@2Z4 zVg5JF|Gshi(C9}-KQX#psdJ3c#zv1ddYsYbS|`r&Mq3#@O-px9H+rVgvy65%+TCbx zmCCW&a7%^%(YdiVNjcAQ6&jsybb-;O zMxQZSYIK>=6-Hk)`jXL=MpqeKZS-ZMWk&yG^cAD8nrv&0R+ilSMF%_r!Yo!S_J;1O zxeEh!LzOTE7X^ajd6}V?C*X8}av~jeAPpntjlVYxY3<869Nwnphh`2Ae;_ z{6mdq#*QL9+c@MH%{7{5G~ei=SSD!}8|Py4KWTJ{(Wi`-@a*90l*WH)tTX;+%wKB$ zWky%T(g=Ui!e27~N~5ccuC}sXj-5-IGL!93=6}WLt0w1Kqi-6AcZ_aV$~{62IL$Se z)5_>c7T(V2SsFr1Q8TpBKIuh`t%YVA%`uv5G|y;0v^RCW588-lN^k01{U^{Cy{U7h zDcl9Ux%;+3`_dM@8F`fUw~#^R&!ETlrW8$?V>H)jp3!`xGcElrqqB|9FYG#UbJPxv`D(w>9-Z{nY3Av&U-BRZm~&#|%n92?tH>4D26)$aOKdZ7AG;Hj5Nttw67j!QM!Qcbp0 z`e9!}`WYQ$G=tuoN)2nu9HY5L^Ni*jRb5i;>5yu=q?#_Nrc0{nl8P?dNVCXzE;d?h z^hu*jj6P+w#OP9^&loK=y3FVbqc0kL$>>U>tBkHT`m)JfX7o=+UoomRmMU6fsj^*D zQe(x?*Vwpm8D%`&oW zmXXaMSFhnt|FZBim*f*^bUKvTc@; z?dU8c+tFD@wxhF*Y;68wsLnF7ZI+SElS}KTT%`tuX z4Ju^LF@1AP-yG97$MnrHeRE9T9Md<)^vyASb4=eH(>KTT%`ts*Oy3;SH^=nNF@1AP z-yG97$MnrHeRE9T9Md<)^vyASb4}k|(>K@j%{6^K@j%{6^K@j%{6^Krb6>Tz=9#{Erf;66>Tz=9#{Erf6>r*=9|9xrf6>r*=9|9xrfY>q$8(K-G!N9Xv{7!NOp>Ky-Zvz#BN2JXbKbNt7VP^r%GA4e)Er9*9w z|G3TZXEIuDmYJ4!CS#`hb(S%cT2-pEjG6FMsv?HlDMM=WOFS+j!14 zp0kbTY~wlGc=GiLq?&C!XB*Gi#&fpuoNYYk7|%JzbB^(xV?5^=&pF0(j`5shJm(nC zImUC2@tk8k=NQj9#nLQ6B>(#*Fs^DPbEYbNh}OEcfnEU+{SEX@K-v%u0Uurv!S zO_5n^MP{uPnYC7A)>@HSYejHKl_Im&ip*LoGHb2KthFNSjlRUHwN^wano_N`B1%!J z)>;vzC{=5%$gH&@v(}2tS}QVZt;npkBD2ujuEXJhp`8>`pZ zSiR21>UH$kak9?F>UH$kRQ$T4yN*(n>a%H`jn(UHtX^kh^*ZhaO{uolI%I&_SiR21 z>UB0&ud}gwosHG&Y^+{qWA!>4tJm3Bz0St!b@YF@*;u{K#_Dx8RujuE zXJhp`8>`pZSiR21>UB0&mz%!jrf<3FTW0564mYcrirf<3FTW0564mYcrirf<3FTWz7?i#h3Q*i`c{~}6{c^6>04p? zR+zpOrf-GmTVeWEn7$RJZ-wbwVft2>z7?i#h3Q*i`c{~}6{c^6>04p?R+zpOrf-Gm zTVeWEn7$RJZ-wbwVft2>rWK}Xg=t!0npT*mm5j9PM%(kZ(w@JS_WZ51=WnGwe=F_z zTWQbVN_+mUw_NKj*Lusf-g2$CT*q8!Xob%eBFBZLnM$EY}9hwZU?2 zuv{A~*G9{=(Q<9HTpKOdM$5I)a&5F+8!gvH%e9GI?PU|~awk+RgiU54Y@){0uNJ~4 zvk*3!g|Nvig!e4hdzR}x%k`e+de3sbXSv?9T<=+~_bk^Adc`)`L9WeEU4Py|YZ5}P z&2qrT@B_B)dVrp@k`P^YJwVU75vuF12k0~7pt?$Mz{ctWHdY_7vHF0G)dy^q-~jzf z(-a!jb=L#*E2X;bdVqeVe01IQfUOc7uyxl1^dizYy6$?w)?E+Sx@*j2iF_SH3vc*icn8_A1*<$qhl@c@AVkTS6WQ&<>F_SH3vc*ic zn8_A1*~;7|Oaalyze$>&8&ljiIa?Ls>V5vTh7z-5AQcF_d*h){UX88$($) zhO%x9U1U62H^yIV^hu*jj6P+Qbz@>#H-;`X%DOTBQlra^t}x2FG2t&6U1@ZcQPzzK zf7zsB-5CF$jJ{%&bz?$UH-@rq3}xLI%DS=B9&3cW4(rBH){UX88$($)hO)l`W%bx; zudByUR*#)7Y7IiMJfT>gP%K6$mM0X;(_uxF9>t0%HP4Eu`B}Te&)OXnYY@u1B2@2% zK57j@S-XQ`4MMR7p;&`ZtU)N&AQWp5iZuwu8ieXS(#P%*&fJ<`?~y)skMvP%5I<{o zP^>{H)*uvX5Q;Sj#TtZS4MMR7p;&`ZtU)N&AQWp5iZuwu8iZmELa_#+Sc6ckK`7QB z6l)NQH3-ETgtB%AW$n)Cqt+mlwL2)*pwmaKK`3i?&UwNtGBBB1Iu3d|zwL)qDfva=6mXFvHH z#ssD8>?eP(#_lF1 z&V?2!r9@&Wac=T{Ng?lkD{((%wa1@rAvs2KjpiB6H#!wL_fr-rDT{t-WmQ>ORaRD& zl~rYBRase8T2_-uIwnBrnNY?AC}RSYF#*b$0A);oGA2M76QGOh0m_&F zWlVrFCO{bzpo|Gn#sny10+cZU%3czbF#*b65|q6pD0@jz_L88C2~fraD0@jz#snyP zNl^BZpzI|<855xFB|+Isg0hzcWlVswmjq=@fU=haWiJWJm;hx=fHEdP855w42~8&H zm;hx=fHEdP855w42~b9ZCX;kDfHE31VdWt<0LoJU%1$(tooFaK(NK1xq3lFM*@=d- z6Afi28p=*Ibhc4;qVcm64P_@9%1$(tooFaK(NK1xq3lFM*@=d-6Afi28p=*Il$~fO zJJC>fqM__WLsuJRCmKIH(NK1xq3lFM*@=d-6Afi28p=*Il%41%Gr3#mLfMIib}`CM zbd#C%<@V4j=qz11hq7`GW#t^o$~lykb0{n4P*%>NteitxIft@x4rS#W%E~#EmGdUE zDC^B86-_>kt#9%Mw4g~PG^fd%&5$Et4bOT#N8cqd!MUL7ea&#^r&oL=rG$7qERU(aW zn=}+Twx38-cr;xoa$H9+9qbfoRv^-x_~z-LQltfZT9k<#kG~}{wIZ(7RFT%ipO7YU z;&4zd(k2z`7C8xiCvOpHhs-Hmz*tZMh&zSrQ!)U&+HVu-0Kbm#>qvYj_;uPPa_S0^ z)8KX543W-JutE4qS3uku=y67s$eGC4r59K(ayD^im+?8@{vzE#5BT*&p5E~2y_Zi2 ztO7el&M6T|?d)NS$hjGS`16{Iq;&-FJ|DgpwBV<_(5r7I*utlk;dc?dE}jl{i(E1S zY!m6n^`-E*v{dA>bbu_E?GU+~u*=J6YQp+&0((TRXau?d@(*x9YXHvy!$GmgK+3%e zeplhYio91*?p356M7}}Y06YgF^Pm+XSFZw_z%CJrkn|RyFUSS^L? zlIB|U%W(PWEBr%9KLlBZ^aCRR`GzbPxej@*gW+|AT}Rk;gkCBqIYb%OAB+Z5!E&$#>=wCkIw%G^;-9pO1fJ~ck33B+lKK8GXca8?+3;LbQ)d;c7S~%w>JXa0Q%idzS~y; z;_irowxAcN61lS@fZ3hXK{0^GoqI$^kZuI&MsPh69wVoMg#bPyH-TMz%344RK)$>B z0n*$>`n$+Kx;3Eu(fvj4ZX`0MGw2I40rHNayfNe(L;5jWz;5A{XF$Gt$afFwyWP7(ci^Lr`h-ZYQ_ zMgwHO7ya&C1vZIH=nQu8Q;hiU+rj53iN7CrVmiQ`1i#7TojhFRffit<$b-l-B?<_8 zCUXPqvfy;R#@k$khHK)5tfi8`vZAnnC#5u^didVCmIA@W3LKv_?$5}ApA=0cHK zq@7hNGMjQ|&lH&>U^FNPJHS4Xf;2D?370`#3vy7{DAK)MB_TR^%6q+3uXQiME39YGq%0HeWFun?>Qo4_s+ zE@fd0&;|4Z!@vYE1C)R@U@O=o^7|-g3wnWpU^tip3czwu33h;eeD<>u=m^q41{f`} z*ag!;F+j%R&S00wlcgd{;J2g@aQ&2k7N8602Zn(OU{;wAQ%QVh`caDae}eZb{Xr(6+*jeZ zrWcqbvUW7sE3z(&pRnu)3Pj2~gN1x{p$j1G>+r7V2;f(-MdXbrm?~1)2$23w(!WXg z`o3TVKczYxY!lfq5DWvQ06E^K{I^R)HueML-&iT~PAXU~vMC*G5P6p}-<<$=xNf8C&`T(!Hj;S3wn=1r8dxs!Df0ihDcB*hV}{6QEdX+Sj{l2BU?4!hFZPJ+%mVQFvL9Fl_VQU~ z`1}R_e!soA){dE+;|Lby~*Od3S zMxYDm4~Bs$pb(JeZ>0Gf=LPI1bTrCu$A9@#*L9KRsuE|_$_tb z6i5LXUk!u=u0vdhmjlAWghdttt|MGW zDKFX=qyx%K63_^=1(cagnaRcCG?)Np0Lp4Wz6M*t9&s8H-;lINxnQq2$B_S+9pW@9 z6Q?mUHr^>tlR{7>&av=mIvPw7=eX7Y{>{kWjQHlM0G=&~Z$bX!DX(Q;elmfyt=j^^ zT9f{SMxY}|0~vt4C#C@8YC~Kb>bMR0+H4S~Z7;A*oRj*2RpOjXzLRGHw*lia4jh^OQ<)+QXy$RB<{)!A@~HW`a%PbV9aM2|Kk!oYN@dH1eEQCQj#mU`MQv=3;DW`?<^OP z?<~U3?gA+9>|tO6Kz`;-PFMJK?GND9jr84`iql;{r8qsPhaLj~{CbkEC+T`-0?O{W z9IOGG0CM%p5~p`-&>6t1H(`Cq)29UN<7c-Uff-~z%SnIvHn3Nm{tW?n`)7cC;#>jW zD~5w|aR&4Q@VT-nApT1D4#Yo@atH1d=c-{~t2l#Jh;wzJIOzhiz*vwAD#f`5{@0`c zWE)KU;8Jm}B|ak)z$b%z8RXB{AkL7EU^;;3(9xh65I%ITIM;O(CllVkCe5$Y0P_60 zOq}c60?N9f5f}(&0LmRkS;OEl4F8Q?Kmk||xW1_oApcDz0Nyvl@8%hRaF*-_=v0skDC2JO+&vs1#~8{RgDzvZ z9z$B@NzRyk;@m^{J#9f3&<~6NlfZOP3`lp+769+DE@%xpgH(_XNI#bH#ukEYe4a-D zJjcOvTrV&XQ0BNPpa3ifm0$;;{PCn6-w~vN(EvWl5CUGWnJ(+SQuMy_~csxM92axSSpT_Ucb!*yLpMX8-PD^ zG3PP#dYn9u!}D>_V_poH;HaZq7_`3Miw1 zvI@xayHrph&RpW>Qr=u-nTI=XA*d3E`I1w(LY(=%zzl#~3yQ@lB7ISbI1Aym5FQID z=l96QT*X;L+@cBMEGExl_$=NhPH_gO8Iit}^}&=-*RY4Scj6RZH60P-zu1UiF$fHX_Vzm&M8n>Ob;Pv`WaVo}w8REP_nl~~4ac`^u#8+}% zIRzAg4dT4n85E1N9(O%?)+6^@_}`i&&ISRd=?LJz1^!#$|9(S| z0#ZRb7y)uYAy@$@<9*6_pE5q6j1Rhj0=x%Q$o`i!0FSRI^DDx45w>dz*e1?j zM}SS@d`;Nb1z?{ze`8*njetqhYet-IQ#m8QgMEC z0epX4CC+{U0plpLM;H{A^hPiP$q#0d?GWz4hcll0RHGs2_y{%yCjfI{^Sv0xda-t z1>|e6K>`hXfteCGDhkp;A%O4Eok1~x$1&XiX&WI=qbU+->;m#MhHsM$utfsL_5+l8 z>~0A(g~xHEIc^xJlt8nNfPBpfYd#PV)}jm8DuLtSef$auv}_8<-*S%xT4jP#3A83n z>*W$SLBI%rEdPhR`+=);Odt4vJ@=pIB-ssFvEdk@Au}O_P&3U;Lo<_^h7f9|W{PG? zH8Tw%WQ8yYAq+xn2qA<)$O?n(h7j7_*z6A5?zX$_?(cJ-Gim%;zy16Det)mu+PBWR zpXj*&_?p zpw1qxAkQAui;qAMDab}KYS9Gh$1~n|^2U#e+A|snNJB2lQI8gE#3oUD5wjPy_M&~S zZc%$jfZTiMqXy*Ndjp0rE-Hb!CnO>RtZr>zSV;yMUm-a;RC+31NBr=A?0gQ^;FADKU zMGi_)hh}u37eg2qH7y2-$Uq+2(St!Sm+8@<|8)9Kr)@fIN#snTEs3@y+LCD7pSb;* z^Ztx!f5x;wW7?lF?Y|zK*oa|K2MA)3giPdvF&!9%crfMz$$udE4{SrXsAPjUFuvp} zG@utl7#DR=3=)w6Vh$qaAYu+`K^OWkBI;oB92|#aWT6f$KX?G6q7I1xc@D`&F=|1M zLx?$q9EXr2g&Zm5NFhfGIrwa5m8trK#qS6i0kc)CK-*m>3&V19E z?+ohCp#BW%&&WY3>d=f1^kN9(qGrY*5&7sBl|kPO#*#t(j6qSe$Um!I)NIBvI|-Q} zc6K$^p%oiIUp|AYIS~jV1=%P@t*A_cWMrWRjp)VzMn%n~&s_ShFp}R9_zupjwatRvB(2$$I$N>`emhn+*#DkYQrW`^BB)O#xsw$d9=-A zJo6dn{0z`{ey6AfF-SxmnlUOWI|}hg#X3>P3K+++)LKZ5g^Yh;t*Aw`FJdffM|>V_dClm+n5dJZkqzc_a*L=_ znA0i5oWk-`hD4p3hH9)sD>i^Jow`X>eguL@K@Mur4we1fR$Wt&ZYDogh(T#CY zOS91>sxSl8DT+lQSiUS3J))M=wwyl8TSXN!juL8>FxQe=khg^So<^P1Mn#>Ti(=5f zG#-qnbXe4i7*K0PKAO=6>aOU;fT)$kuB;JN7L7hp<@_wCMtP&CGa|sUGa5jA1@$Y| z@mI0YUdh-h6F~jSCUl|)n?zL!s8>~vR?xPp6f9pgCW>bSYBhaU^M3V^s5P<32Jvf% zU(+wDIs$p3*0O9Zxz{Bw{vR=xA9bT2)VN3x1NvRWm@Zn6 z4)lnsr$#;T^-ZEKPDCj-in=5PEWeaxmy)9)3Cy`+RMchkxr~~Zbz)f5<!@{Q6sUV;tEj8Udlh}ICg0WTL^Vc(xim7~Yly!l2fV+gPt>*axwb{r zb;Mkk43=G2jV4g*x=~S0_9JuFfOV&28qZ(9;(oQ z7IdKxBcg6Hh(j{6P>MP@;Xh9eHFe2&}gE%B33x%jbBihi7 z0gQ@TABA|NA_t|YLo+(iiy@4Qx-|xg$Uq*d&AhovQUT`G@=dN7!Y+=BFNFo&(>7rpcHjzMhAK^gmF=K$AH+oGmr=R z-rax}bfFI;qV6$>Lo%{Zh#EAa4c!>PsHh)DArTqKLlqj(f-dx7L{ytW9FmcRLe!uU zZRo}TMn&Blg?OYQ2c@V(Gdj?VA&iT*nh#R* zL25ok&4;M@5H%kn=R;L!KnuFihY?X7260G6779^=Mzo_BLl_tJa10Vb?T3kbn7D_D zd$277y>z; zAm8RuRcJs9i0vY_YedwO260G6779^= zMzoggCHA_IA-LIYaRg+7dk+F%feWMrWbHE2W| zx-o!JQO`sn9;wIyvCk0uOaq!h>@$5B5%sJ=9Fma*VxJ}USz@1UK?i!lws?+h@f_RY zxg=yFA8fbh*ly3U-JWB+J;!!?&c%+2>W)DoGLVNVkhhyLbd$H6yxl_>7xg@`&lCGR zvCrp#yw8*O`6jet1NyN^)C&;^A_bXX94`?60`V^p{{pf9HtM`6NCNp^TnF;L$QWK^ zSr6?!^GJRhj5!IW8y#IHvuzp^p&#QwN6ZKjw zQjiVmzSf8VQ5&hTF&9-}92a92=fqZYV{4HwyG#Tr_@}EVZ8ttI(KdV1SR6qUu>Hl^RjN|P-QSa1> zdRIWLce6pvyB*jhY9JGNCM>qO0 zBIa(%Nz{kb{%}mxNA&%eJVV3{4T82`L?8$B8BRox zs87iC3FG>-Sk$jr{;NjNK9UK>GSUa?d=`fckngh&kpI{G{LMO1o9MSGDC+ZM^o#m} zF?`X8R%{S8Dx!WDi()XQ-&6bd8%6zr_hVV;74^qFtQYmCBn*rCbF--NXtas?OQ)#6 z;%~*GrA4%tjE$mI5;lp}8K@U+1knhJw)|DxmUf$iLeYMW=s+gu$8%J@RgCD!D5Qwq zx)yz+qlk$b6TJ;Tw;2%qy?Cq>{rxy>5FMR_e6)bLZF#*deYfTPw)EewT=e$DZr?3B z#(?qez&LiG#tylt#(HePpzxRIAc!>NqZaG20fVA<6a+#49U1$M`KUz`TCo9xqGMyh z*kaR=i)z$^xLD$1JJADTcM`-R0mSc=4`O#(k9H8Z(=f(F?;HVQcTT`Y(Q(!)42eAkCi%w2OhvNYGKe!4TMIS;xo)PLp)`9maF~|XVQW*20jNwpTA37}huq4p$F!CQZCi?JX@c!@) zjEYX>eJXiU8RrqyKB8Ilkpg0lWQ<2eAsa2C(`vwY(&(3-0^XI5a z5T&R^yXg5j;QjnM(F>x{g#ppo)X82i`q)?`gE<^a?uF|>%tCT6Vjhd?!Rs92bAqB5 zCx||d*xW|ZClrf5k)J1ZgP6Q1usn~NdDP5n1?wPhOf=s^(I$(=w(@=mq&p2%Nx;wKCrAf7Ac^;gmIMQpb7n= zPh(7{F&>`x=+lQpmlk7_=oRs(MYrgcyk5!cmAo!9Aij+H<*~>E@n__tLv#gWs3=FD z=*n#LimqZzs}e!`Dq>crU<1ZQui^EY1`LX>X8Bry`^oz=8QYn>K660yS(#|YCebyt z)$sFd#(Xw;&Pf8x&ms3Y#GcC-&n54<#GTuOF4491qR&eeeSQ>(xu8*W9c>quiso62 zz9<^wqIt%mFDBQ;b!ZiR3Arv|?3dJ{1wXZhuw z7!u917JWr7#ze29?mCuVnTBGlN5AN+sDBmjuWCXMh`l-=yuO;{R}YJBj6(w$!!@zU z1Mjct5`Aqvcz-SVuj6ME@0$iiU*8OJ-9Xz7P1q><#uV`S#u3rYsbI{_tr!=5Q#Kg$ z&BY-07GiIy1FzR-qD%Cx8R!*#8#QjL0b{$Jb#i+($a_06w^N(X{ko+?^c~SiK(pvO z1yvXjeHXRvY8Txag<4Se?pToH?rw~WzK4GIkmsIqG-6crk7JO6T-2ZijOWKJ1jPbq*kncX)@7pMv&%OHo9BdHH=UUw{Ao}4Q z7~>=4dQ=bx`aar#HVldGB!4G)_-v;;OTn_vb_|PtEDhCYM6c+_iF-T`v^`GF$2W<7 zq6w{{yMiE&&sX}XMA1(Vh<=uQ&y9b;Q%^1nf@HyFnoyg<>>DJ(E;R?bF(~@IDA4b{9F&8c?{#65==WLneln=X zJ*9r1obOZb{Q=P*L?9k4`=As}=m0rC7#BTA&cO_jbFcx_AM6+XAvr&!&xgc)RF6%f zKOPo6MBSg~f*L;`5&aAL{$f4I^~*w#`sqb#3J5 z-c|o9h!$)FIY;7=g?bS88GSz^-)D{B{jXz?1K$6J*T3QCCVp;mKf5p_`g7*;c?xn+ zi)M6-{-Q(lZ>jfN<~!al`frT!ZyjPJ7RBflG{i5L^3^Tcp}YW!3&5u;+ZqJ66t zF_FYamW$bXqnK?mnLR=gB~$E@_I*NxTiBalXDkp z?lL51S90u1+in>kE|@E3_w{0?bc@*|AJmR-19>irF^-onjIhZz47J%LZeZM(i}&rZYC~vrJMf$g_VCwPFrP0d)`DASO8(ePRwG z*FlWw;6^cr#E3~@4u=(sIh-8)`K396K1XJWIciW$TECd|Tro3fpD`k4W-Ug=WHf>0 zvv@x{6U|_}b2f>|q|e+~RDst=r+_gX-6!T4>SQH|nHMc)L7bRu5pyhKSePbeQIeRP z3^9v|IWAMo@lj%O$#X)sm=jyYoJ5U0a^>;*l5EiCIhDGdGGks{xzD)KKpnBj(&XF}2hq3@YI4b6%2r>25VlIvrb4i~V{+z>Ho+#$Z5iwUcin%5gJz}mU=K7$R z8yNeI)NIDhabj*E-z^Q`{rVgrIoR~Lh>l+mF z(?l^pV|@MO?Jq~an77ICHo4y3fB}q&d51B*!}51n{w}!&h#6pf?-BEUD!RmcK!pSP=VBDH_4@kA}s390S@vrv2lMVupAW?*v`QxCNKgWw1&jI84ORJc_Qul8O z7!fNQ#d_IdRjOE>AeQr)HA%=rJvuNX*7Dl6qhG9_h+4FQ_kjo`pa$d%jEjvRCZY;m zVz-J$KH9*t$Qma(tM#Z5J#BRgSZHW0^i&)N;Hkz1iv&3%4Yd(kD?Ww!{px78* z$7F-{7;?q*VMOc>26 zXBT32$wevZ(SjZfU`*_;#O|7c98{wjEZ>#oyRv*YmhZ;$-B`XG%Xee>ZY@4i}<~&LH)ftLH)g1zBl#v&II-Mrr+Mw z-+NeW0`(JUPat1HJ*bn=59&`%0QsiUK9%;VwC_XxeNsUDKIGYl`uj$J{QG8t{QJ_r zFZuT!7Mn=^MA{Q+PozDu8)IVkBYwYJG@u6~VyDF-1J!6jzu4(fp#StLw1W9?U9(A9 zs0aD>k3bw!zmM!i%p9H{nMzQ)(YyU6PKQadXR5M z1QL;pI&@-4>`dZj5;v2$nH?Awn-K@%G8)h$c9uaV$UmzUoF|$XvT7kpigX8K1RgOOFJGimSu}APZoOyV>)9{Yz46u#8#$&F;!BpDjK;UZ&e@0#jc76eOEEgRrFa!`)cy8 zrta!$v}0K88pgIJ6IECb@~s&YTb%%MR@aMNOZ~OHUfYO%v1bYrQH%!A=d2hIb5@7g z8eX4G{j;fY4r4nf2;$D!DE3^IotuR^42i8xK^6MMo=48}n!xzaC-?d5&?)wU1k__p zY#p!bQc)=O!YJgSSL}~6&?WYwT(pR-XIXuN*o*mjaTXZMB}pLPrLm~N2C)svVBQVG zVlSibW!+*gF9u`1g0Wsf{wq4fu8Tk^dc|HzpDSCjN$gd`UPas038=?_*v3Rq=Nj6s z;peqkScg8b*TsQ4*U|5~YS8DpCb3PmAkXzt$OP>-@cIVkaszd4WF6j^1Kx9gX`ADb zk8;p{2(R|aUmi+*>lLn}6*ADhIsMj(h3WP@0qy;$yR zZEHJvFo-d+cSj=uX~;!6>aiZ3*oa}V_XuK29- zcJyEnV`AH)k$^Phq8#;Dk4|jFu-JPAu}DHD@=*<9?`^^$Hi^BDIPTf)eJLRBzFMrq zdbDE$HewLO-!F(p5J_PB+|PEszXRRq6Wh-6c9yrZygd!=*no`~6#GC7*e(wwgKhHw zV|suwJuoWvK?9aQ$UgHR%O1=@A=aT2J?O_U#>75EzYg+rWP!L2mOV_rhiQK#9yOru zqtVDlBl<8Rw$q?N>|=r;(!@Sa{wGpF|0l@RMZYfc^7+Gdv5$3igT7D3AO-ng{7<%n z_$SB3J{1RYJw?B#SoTyasQI)Y5xFQu2S&wih(`|Ai+v^n>%=}w+_Q}1*#WW7(e_*{ zYQ%Ok2mTD)K3@&$y-$97!vy?ecx;V zefp^PRx0T87R!E`1@ixlK0oUe+fUB^F|lvc{x)rI)9-Eayc3N?(EpugY`~z{cLhOY zAQz>mMI*@fZZBNisMvuBkb}>2c7Qqq#i+r0bf5{*w2@{{?Md zbcy|K5?Vl>QQAgXC%>cZcl`W)7P`g$fuDci=U6s|#s0AnibmkLQ8cf9Vzb z*Cw%l3yLo>;(HP36JMK%YPl zhQ*H%#3BjwiO2_W5yVBbfw+i4jElcj3=)w6>TgB zZ4Ou$+p;dUWnFCBhHeaCRQ&Ct5RX(4yIm>jKU>w`0fpKhKj#}|!s2M|hObW75 z4AW>{2Xv8RNcqkjAaDI3s_P2%rC+a9qXZ#+5U=@U<%_zv`92&3ZfS&tF% z_sT~#)`47mk!vq%sE<^ZyR|9}q+% zHi&;<9P&VIo|F4L2k?`5&F6nVnRRjy<2fiBbr=x;V8(PX%MNDQA(?2xM$j*X@uZYu zMEpZ}eJINgCGM~!Fvi2yqaB0TB>v&?p!VU_U_6Jj?C@R;i=P^e6cnNX9iZP45l900 zj;KW|`apd?{%paY-3@BYp~f6)%%R4db?5{&GNX_TYGhI)lNy=S zn41889-R&1kM0%!m|XDsm|^j=sGr6AtPb(#Wr{zaJoCvve}ni71jS$;*^D*2P5fh% z&?5dq@-F1(q6m;PhdJbsGiO-*#l$SG7XLW<9=A#S<9U7jxcIqs=o9~h_2QpMz7vT* zk-jI9>!cd=i=P(@-shzt6S*KyUN!2`gjRH-2mKhvnD{40AQlNoK_+rhjB3=Q39aZv z5Bf2TG4W4{Kr9lFf=uM17}cmp6I#)U9`s`vW8$A0fmkFU1)0c2F{)9ICbXgxJ?O_U z#>CH$Kr9lFf=uM17}cmp6I#)U9`s`vW8xP?AQlNoK_+rhjB3=Q39aZv5Bf2TG4Yo~ zAQlNoK_+rhjB3=Q39aZv5Bf2TG4YqOJ(q42zmR>Qa76r~6cD#88x7(wXZsh&ArYy_ zLLN%N_Ae%;xEXEe0(nb?VNB=LieFnJ{`tgQK>j*%|EO5}`grj#p+-ZV_?Hv6j{Wk=YVog55&s%; zURN&u^&{dpuNVJj^4-!W{;g<<7XQu$@$b$Qzm0L+J1%}ZeILvczk}tEHi`c@eV!yI zpPl@t$n{ja_Za1;dXN&(rl=v^AhkP$}i~n-1_^(un&u13@wM6kZ z(&zOd@!urpTg~GCjJ*B5;=dCi{=4yc7wjaS2!>fk2i7w%RCxs748VzfJ<% zbx45wqrmpP5{PM)zz!`E_(7orcFdMQY_SA(ijlz1nG*P6o&@6PyNjS-0=srfV7Dp> z1QR8&J9&2}{}kHxST6ytyMaB4->X3adpAoUp z1f~mEmQ*Z({mUhAK&}M1egzI>JjslOXVrm&)=A)Ca&UbL95Nt*lu-#B+AD#>`XrFb z@>E_QNuQ&#B#=h`^aKga;63N>z|0W|WYB+hlLY40O5m7Q3C!z}zCFA9Sa;Jgz!h2^JE|I|haa2y8;c+W8xSh7h1 zOS>gd*e`*ib_pzF+46h|6enR^0wp*-Q39n{LHo*b36y0>pgchWXGBP#0#($jBF}1m zt|m`)JccE(wpRjYqNYg#XVZRet^{hUC2(FAMkR1Qt+ zItg4gD1k=Wucao>(E`^JdmUqFB1coZ1g@vw^$ilZAqIJ9!vM&8BYAGj1hsB#27Q}( z-%Q`;VhP+7M27@!PQ{o6ZixVWZb<@hw=|&>{TP$L`e-B|4Y?>sJs975;?{4(umo-u z#3BX6-CB(%^hn^gY}8^z0=Gwib#y!VZfESb6L)(f+R+PgwXiN*f?$j-};125D5r<@u|BeQ>i$U$X+az!g%kIfTJBa;pJaSQw4cH`swm49? zts0ECjl6AR61bN<_YO$lK9=2Aiw=;3Kl2Xo3@p%2z4k&hqgMhCQ0sv-RDs+NMuA!n zlJi08Jd})lG=k+FDd>>E!-*iz!^AyIy+_FVNCO5X@MsLOPzz!oB~NEO7=P!e1Rf** zW9!f>fyWK<&?SKHb$HjGH%`9jp75gj1*dGb9! zE`b+_e<2xJAnpb7z0iVg3}93OTn_>-CW4q3OF_(w%^=r{y%++yddS7|u|Q7-@=%2a zw4e)p7?r?F#J!Y^EEJ*!jc7wR20+|TqR=UUmlHsam&x&RA4Vk5YY+$W^pdBSJiX-U zB~LGTddbsEo?i02LY`ORk%}CYq7KdIKreNE9UrHvT6WRC_wHouOR ztqC!YYYBRP-Tc}}Q0>3@wUt;^ zxcRj&yQ)h!zmAY8>WR&-x0b`y=bK+|v*%&@n9Z-hC&h>Fx%qXp{NQlDQ5G7{wi0pp zu*{S)DVMcUAtkb0ils_|k|0ZEDnAd9B>p*&S4)Tp$_!$vq!JZUBn7fU5^0^wf53aG zOygC$l=4qd7JiwlGW4#9K1K9d&A$tYjQj_x9!$@0)f_6Vrq*eUbR}bS<0xRH|6Iik zYM(~G<75>XmeRihtvb?w| zn6Pwe@PMSG1A|M}24|F1RaR9L6|6`M&Rw~5S}?t|G`P@3RR$LpRTfpOE-IWB`Hijz zyRJC}t5=*>wsLuJMnUo4>6lS;TETIvf=i1FRxU593>H)r1xr>2%U3NaEm;~YEL%}f zvXYT~b&88Z6Re~;+<8&KO5V(1GNnvOW|Wok?{Dwo*6`-AEjkDPHe!s5|#Z62H8QwyXVB*mzAw# zLsYSOB(#fHv561kuXvlznh5U}tJ&n!=v&6m3O0L@xO^4tZbh`Od#G&-fL&qIv?yzvX-4gy?O7Arsc5b)c za!vf}JFCkyhrDZPpVe_Zu%=KSxU;M@W9^;2b#Q;$0dx;dAy zH6lZ=+^Mu6v=_QlOog1z(lWNnw`JJ!Wb0;@9m=;Nlx_0ha=C+SZ&#~m^C@(BsEXUB zZmYXIZo7x~y>PYg2{F9CyX94k!krdZhEDwDp=|ExaEEUhS*uv)PL___3*4-hvcz3V zBKhfNP!$@5tF`6+v@{gw_QP=Yi3~0}JofO3w}{N{_;6cm$`*Ucl+dNg^>zDi0Woe| zOX*v%d47>BaV@LZuU!^5)+&~VN570$rL?=Xl%_H` z(_TiERa9{!oES}EXa;VZmavXik;5$wuZPGl=kU!6F1uR~OBvZJ@=mOiHN0}Y-C4<9 znBAIj+xx3Cnpn@1m+^o;Pi!6c+O3y~Z5_#MCN6iC)N;$eZ62;YJkRNj zr-FBG>x3`(;oK#>ca^`o^(T(+Z=dzVnhWo5;r%Q;LpLrr%J5z{Iioe9_2JG~6Z8K2 z6~afF+XLNM-R-SzhT$_`xT4!r+)TvSh-niHi@f z*@&0xzd?2dx) z-GLjKTie0VzgP0komVE-bC9TTi<@hBj|?9H;WM&ZFOIu<6oqCNzGh91XH94yD-5mm zDc^EMokGv>nx9y^6Fnk1XHQ&hr*KC#v6qFfFIiM`N7Tgi#qCq>ICi5CkJar3ZXHh? zZ>w2avc=3M>J{;k)NN@uBNtuHKjEvFJL=t4CcMvm^)4qo=7~Ka@*CHi@EUN}EO#Au zSGe$g@9Ma{=BxYu|Gz^405axX)7VjSARXT=np^HN00vhPIu% z@0iH=-#AnK{aJ-Sq`IRsd_7$D<^Gl_vl!ECSs?Sd8n`vJfOk3k{bcEUM0U&O(iY@C zZXrvK<6Q==8MI6x!Yy&jr-Y8i<9VGUnZzv)rpq|S;kJc=Hx|%M|^_WS^V&1#gb7-5fx!!zwxjDG_dC1v3(j3|+ ztA2Gl9+sb7Mx41Rp_A9sN z&twLZdt7+Gck6p1HoO+x_L(2rvd1#>@D>T@bDxm6oQ2y?$A`AWuhrCyP9sy6XS7vv)juiw!`FFamSzA$K0shUf|xj3ho$j`1w!rCwvZA z9O^rf)%E-8`VA84j-!dViGJU8?g+1=iP~S?f^Khh>oPpT@R`J|hj8BTz7#$ZzJ5*$ zpXFz9U2|8+^3B(^O8SQHbSFOdg|G9I_cq~c&zAR{Zf#6lXSTc(2!A@5!__E!#oaP) zvNil^DSXYE{PgBxC$7og_6d6~S>2;Z7dLs=J9+mJzIzORCURG#@c7*wk-I++-vhdP zz3^R$yH2~$vf)`&gzoyopGYS@t%RSQxQL=HW?RV^-L>D1B3x_YK4mgj_`cG`g{!$W z93G9U7G9fw{~8+^8jFjZ_+;olk-EG83i7N8y{-z4Y9;Rr7)3bN#hl6eiO(uqKK}{N z(w%cAwoLdc|MhJ!F_&+y|488^%I>{e z1It3o+&$~WDBXIT-22?U^mMF6Yi{Uwu9{c~1ZT*K?)GCk*a*`2XH>rO2;bVgL7@E4lUPp2YlL zd#>c3Uw-qs(&RDyKl5BE@;jav{LegB3g5|v&-dc;%{uLVSafBkOefBq?xyO#f7eaaNcC(bROGEIKg{hxfw6d8I}@?B4v z+>zm)y8QQ_GP&n$?upz#@|4MaGXL*9Wpd9T(s}+gPmX3h6VLS0c`ork_w2}hF8t<` z#s95mN0Hxnb`<{sPChsL?q^5t_;LHuw>{7P z?>;-4c)I`huPEPq;xqB*o&U@eA6IAMiG=%e-v87SANT3UeJkl-d*b7s>bSH2zx%`| zlIJTE-}w1^Yw|z!gr@2ncUEbfbtb-f5*d0bMPU#1HtR2CHl zmlTzjt(iJ4_z!#wZd!0o>Duz*%3#Tg^0JDmqQc;^in0~K^opX@!SI*BCTfJfb+;<~ zt-CGDL`F_l=j&+&!SK+&{OVrhe&6}O$Zvkh?;rkt;1=@^RW7NFEC^Or6ciS%D5y9+ zShj33Ap9-E$jI!XiWMc5q3_U@R0fNSDvJ0*;qr=tl}tU6xwH1@#`gyKl3HT0sw`Nr za&54jZ{6{wyRs!!d~dLXRZtLI%9k1=iL5FvnpjUumzJ$4C)@>86_cIs8WydrWD89R zt&%BINmdvvsH`koT2es0$ilLvt5y`PtSYE--|1UcQp#5q6I{knhv1^JWmRif{Zpof zMp98!UQt%KYH3j@O<@UNpDbCjs;bD1A<|X&vO^+Yc3fJzs?d#OO-WU8*{UiAv!Y~k zAy*;vg-pKTR~B4V$wb|B5`!y>+^i!*Uz4mXP7F@gNOU!)msJESi};=<(IpIZ^Yp(~ z+Rc%)tTPHmhF4vv(3)a)ELZz09fGW=WvePymQ)tA^U<-eELd5V7_3~i`?QC2oaP9u^syL%M<`Wvh!qGYEgnG&F!OcY>8=Rcr>n0_uk4wn}JV z;XNR{ELd4wP+A(fq-gV6V;Fo_l%_4_S+q9VAWj05i5rX8$WTVAxRfI`#4gZkeAp_zx)ap-HR1r>~WRcS#*q+4BuMU^GXSB6&i z^6;@rC%1<5mVfZ-K^Y#$SLlyof2AQ zY?-Xh$IFr;jwF|L72CjVx7B4Op|A+uZUkrT%a zbqcD2#RZkD`=XU!uKiF-%1!Rwg~3%T3pWpVa;TA^!39Gz{I0E9$rpn;s)OZhHn(#W z1le-SNmse~_+`n`(+ie!UgkJlSr+LIHW&Dh?^F|;HB^cd7T=vNDqZFVl{qUod%^si z;GzYybB<46I4d}JQ80Vqg5&09%*qH(NngbKDT%@3=jLQCSez3iVqyCHoD+fzW(U*f zpAbA|?);3z;H=#2g|ikdid?WTICoxl*4$aN&7D6pYjMWh`E!CZ=r?~sPB3fkytz3f z%~=rYx;fR{S&Lk7A>!ebJH zBwN6g7Y0Ki(-)_ z{rODS<;hvFkQK6dD96uTG%GQfzHsg$w?$?zT)=SM_FOPKv7j3X*7K9m51D@xAXd>MB4KWe zH(t)le9?Wy=BbCyjZ3Qzo48e|3NCkRifdg}BwvT07L1Gx-Eq0mRt9HI{KCXPf9v#* z{(i)N=01qKt%-A)TVcyWqc8Z!?t>yH?}Jzk|I&R>q`Njup2b5OEqsYx8d~q6yAC(7 zFSlASbes5)`|4Iq>N|BS}2<_?rOZQ5l8;1Yly;5ZOfc>}bl_LLx_ezoO zq8q+f3T^&>;a(|n;;t-oU+^#7D~0a8E5GGlDfDYc|Jc1!XuEB`SK9K|o4#_p#Pyty zW&f$$B~CnFJv*`j|M}ac$SGS6H}tu2%76HlDRO1mm#3M3`Iag2KYGg)x%rkUbk+UW zZkZy#e#;d6S8kaizx9?W_|M!jMdqX*H}B{L?oKZ~^Iy6 zz^>+rm-~&pa@xN7UG(q%4a4bcN=`4CUczU)>S^W0<*ksj?5h$DPQp^i5;( zNwPn`3+jFo^dLD{4v`c&l&^LjE~#>a94SZfd*1GAk~4W=Ka0oC?kl=;`D2V@SZVWk z1ns`Odn}L7-4|#V^G6)V^9N8TFqe}gPfnIoAOv{9bO8d*vm0QSRd_=SyWBk8oe+ zA#RWSL|&6#c|~58Pk5mDrfihg<$k_swn?s(pGu#+#peB$d?pw3JI5t_aeW1keOJnQ z9xb22W_Q2TizUO`4^So$pTW>pWdoRY@!TW)?qZjM#Kz5Tpt-gGa?+uu9DJJ3t^4)PB6 z4)IdFL%qY~Bl*}n+)MS2@Q(D3^3uF?Z-zJ1%kXA-v%NW9rZ-pGy||Nqr>NR+md6#=vclw|TdFE#4j8o!(tut9Q3|kN0D*&AZpT&%57i_a5*b^d9m$ zyobFxy=J?C|M&wDR;FM2)ROWsesm%U!^74KE= zHE*N$y7z|nrq}1a<^9zAnb+^V?Y-l@>kWACdGC84c!S=D-bdcY-jMfm?-$-LyO-k-cbd*j|;yuW&XQ=&YjlvYMr z<*R^-P+O@;wY7>;+oIZ5^6{~hqJF6e6IJJw~RqdvNYIik7 z?V;k;o@y_(w@Oe`)jn!pm8kYp)6{g8r1n<_r~_59I!GO?4pAxUP<5C(T&1cb)RF2a zm8R0w3^h|_s99>Znxit+Ty?ZMMrEmaYQ9>avemI_p<1MJ)M9m_RlX`vOVmLzuwx<##5x2oIJ?W#rHq3%?7saAEjx<~z3wW)j6ed>PIt{zYis)wXs zK2#m*VfBc5RCTJy)Z^+2)uoIL

    0JvJ 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ðc|5Nw$u5b1^&lR<)YEVA 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

    u(RxJiCB&6K5Tvo2EFtW7W|9)#x0TIln>-< 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

    |bX@bT<K5aclEv7#^` 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 b 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¥Eaoenoyw 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 +``` + + +## Why? + +- How do you create copies of your objects? + +```php +$myCopy = clone $myObject; +``` + +- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)? + +You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior +yourself. + +- But how do you handle **cycles** in the association graph? + +Now you're in for a big mess :( + +![association graph](doc/graph.png) + + +### Using simply `clone` + +![Using clone](doc/clone.png) + + +### Overridding `__clone()` + +![Overridding __clone](doc/deep-clone.png) + + +### With `DeepCopy` + +![With DeepCopy](doc/deep-copy.png) + + +## How it works + +DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it +keeps a hash map of all instances and thus preserves the object graph. + +To use it: + +```php +use function DeepCopy\deep_copy; + +$copy = deep_copy($var); +``` + +Alternatively, you can create your own `DeepCopy` instance to configure it differently for example: + +```php +use DeepCopy\DeepCopy; + +$copier = new DeepCopy(true); + +$copy = $copier->copy($var); +``` + +You may want to roll your own deep copy function: + +```php +namespace Acme; + +use DeepCopy\DeepCopy; + +function deep_copy($var) +{ + static $copier = null; + + if (null === $copier) { + $copier = new DeepCopy(true); + } + + return $copier->copy($var); +} +``` + + +## Going further + +You can add filters to customize the copy process. + +The method to add a filter is `DeepCopy\DeepCopy::addFilter($filter, $matcher)`, +with `$filter` implementing `DeepCopy\Filter\Filter` +and `$matcher` implementing `DeepCopy\Matcher\Matcher`. + +We provide some generic filters and matchers. + + +### Matchers + + - `DeepCopy\Matcher` applies on a object attribute. + - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements. + + +#### Property name + +The `PropertyNameMatcher` will match a property by its name: + +```php +use DeepCopy\Matcher\PropertyNameMatcher; + +// Will apply a filter to any property of any objects named "id" +$matcher = new PropertyNameMatcher('id'); +``` + + +#### Specific property + +The `PropertyMatcher` will match a specific property of a specific class: + +```php +use DeepCopy\Matcher\PropertyMatcher; + +// Will apply a filter to the property "id" of any objects of the class "MyClass" +$matcher = new PropertyMatcher('MyClass', 'id'); +``` + + +#### Type + +The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of +[gettype()](http://php.net/manual/en/function.gettype.php) function): + +```php +use DeepCopy\TypeMatcher\TypeMatcher; + +// Will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection +$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection'); +``` + + +### Filters + +- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher` +- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher` + + +#### `SetNullFilter` (filter) + +Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have +any ID: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\SetNullFilter; +use DeepCopy\Matcher\PropertyNameMatcher; + +$object = MyClass::load(123); +echo $object->id; // 123 + +$copier = new DeepCopy(); +$copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id')); + +$copy = $copier->copy($object); + +echo $copy->id; // null +``` + + +#### `KeepFilter` (filter) + +If you want a property to remain untouched (for example, an association to an object): + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\KeepFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category')); + +$copy = $copier->copy($object); +// $copy->category has not been touched +``` + + +#### `DoctrineCollectionFilter` (filter) + +If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter; +use DeepCopy\Matcher\PropertyTypeMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection')); + +$copy = $copier->copy($object); +``` + + +#### `DoctrineEmptyCollectionFilter` (filter) + +If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the +`DoctrineEmptyCollectionFilter` + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty')); + +$copy = $copier->copy($object); + +// $copy->myProperty will return an empty collection +``` + + +#### `DoctrineProxyFilter` (filter) + +If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a +Doctrine proxy class (...\\\_\_CG\_\_\Proxy). +You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class. +**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded +before other filters are applied!** + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineProxyFilter; +use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher()); + +$copy = $copier->copy($object); + +// $copy should now contain a clone of all entities, including those that were not yet fully loaded. +``` + + +#### `ReplaceFilter` (type filter) + +1. If you want to replace the value of a property: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\ReplaceFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$callback = function ($currentValue) { + return $currentValue . ' (copy)' +}; +$copier->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title')); + +$copy = $copier->copy($object); + +// $copy->title will contain the data returned by the callback, e.g. 'The title (copy)' +``` + +2. If you want to replace whole element: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\TypeFilter\ReplaceFilter; +use DeepCopy\TypeMatcher\TypeMatcher; + +$copier = new DeepCopy(); +$callback = function (MyClass $myClass) { + return get_class($myClass); +}; +$copier->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass')); + +$copy = $copier->copy([new MyClass, 'some string', new MyClass]); + +// $copy will contain ['MyClass', 'some string', 'MyClass'] +``` + + +The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable. + + +#### `ShallowCopyFilter` (type filter) + +Stop *DeepCopy* from recursively copying element, using standard `clone` instead: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\TypeFilter\ShallowCopyFilter; +use DeepCopy\TypeMatcher\TypeMatcher; +use Mockery as m; + +$this->deepCopy = new DeepCopy(); +$this->deepCopy->addTypeFilter( + new ShallowCopyFilter, + new TypeMatcher(m\MockInterface::class) +); + +$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class)); +// All mocks will be just cloned, not deep copied +``` + + +## Edge cases + +The following structures cannot be deep-copied with PHP Reflection. As a result they are shallow cloned and filters are +not applied. There is two ways for you to handle them: + +- Implement your own `__clone()` method +- Use a filter with a type matcher + + +## Contributing + +DeepCopy is distributed under the MIT license. + + +### Tests + +Running the tests is simple: + +```php +vendor/bin/phpunit +``` diff --git a/lib/MPDF/vendor/myclabs/deep-copy/composer.json b/lib/MPDF/vendor/myclabs/deep-copy/composer.json new file mode 100644 index 0000000..4108a23 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/composer.json @@ -0,0 +1,38 @@ +{ + "name": "myclabs/deep-copy", + "type": "library", + "description": "Create deep copies (clones) of your objects", + "keywords": ["clone", "copy", "duplicate", "object", "object graph"], + "license": "MIT", + + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "autoload-dev": { + "psr-4": { + "DeepCopy\\": "fixtures/", + "DeepCopyTest\\": "tests/DeepCopyTest/" + } + }, + + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + + "config": { + "sort-packages": true + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/doc/clone.png b/lib/MPDF/vendor/myclabs/deep-copy/doc/clone.png new file mode 100644 index 0000000000000000000000000000000000000000..376afd491257d44a8c3772b0b7b0bd7b6c747086 GIT binary patch literal 12380 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�+9eLb17NhZax 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 literal 0 HcmV?d00001 diff --git a/lib/MPDF/vendor/myclabs/deep-copy/doc/graph.png b/lib/MPDF/vendor/myclabs/deep-copy/doc/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..4d5c9428f719bf6ad68f25a46d6e935c2362c4a5 GIT binary patch literal 6436 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 literal 0 HcmV?d00001 diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php new file mode 100644 index 0000000..2e53cf3 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php @@ -0,0 +1,289 @@ + Filter, 'matcher' => Matcher] pairs. + */ + private $filters = []; + + /** + * Type Filters to apply. + * + * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs. + */ + private $typeFilters = []; + + /** + * @var bool + */ + private $skipUncloneable = false; + + /** + * @var bool + */ + private $useCloneMethod; + + /** + * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used + * instead of the regular deep cloning. + */ + public function __construct($useCloneMethod = false) + { + $this->useCloneMethod = $useCloneMethod; + + $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class)); + $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class)); + } + + /** + * If enabled, will not throw an exception when coming across an uncloneable property. + * + * @param $skipUncloneable + * + * @return $this + */ + public function skipUncloneable($skipUncloneable = true) + { + $this->skipUncloneable = $skipUncloneable; + + return $this; + } + + /** + * Deep copies the given object. + * + * @param mixed $object + * + * @return mixed + */ + public function copy($object) + { + $this->hashMap = []; + + return $this->recursiveCopy($object); + } + + public function addFilter(Filter $filter, Matcher $matcher) + { + $this->filters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + public function prependFilter(Filter $filter, Matcher $matcher) + { + array_unshift($this->filters, [ + 'matcher' => $matcher, + 'filter' => $filter, + ]); + } + + public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher) + { + $this->typeFilters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + private function recursiveCopy($var) + { + // Matches Type Filter + if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) { + return $filter->apply($var); + } + + // Resource + if (is_resource($var)) { + return $var; + } + + // Array + if (is_array($var)) { + return $this->copyArray($var); + } + + // Scalar + if (! is_object($var)) { + return $var; + } + + // Object + return $this->copyObject($var); + } + + /** + * Copy an array + * @param array $array + * @return array + */ + private function copyArray(array $array) + { + foreach ($array as $key => $value) { + $array[$key] = $this->recursiveCopy($value); + } + + return $array; + } + + /** + * Copies an object. + * + * @param object $object + * + * @throws CloneException + * + * @return object + */ + private function copyObject($object) + { + $objectHash = spl_object_hash($object); + + if (isset($this->hashMap[$objectHash])) { + return $this->hashMap[$objectHash]; + } + + $reflectedObject = new ReflectionObject($object); + $isCloneable = $reflectedObject->isCloneable(); + + if (false === $isCloneable) { + if ($this->skipUncloneable) { + $this->hashMap[$objectHash] = $object; + + return $object; + } + + throw new CloneException( + sprintf( + 'The class "%s" is not cloneable.', + $reflectedObject->getName() + ) + ); + } + + $newObject = clone $object; + $this->hashMap[$objectHash] = $newObject; + + if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) { + return $newObject; + } + + if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) { + return $newObject; + } + + foreach (ReflectionHelper::getProperties($reflectedObject) as $property) { + $this->copyObjectProperty($newObject, $property); + } + + return $newObject; + } + + private function copyObjectProperty($object, ReflectionProperty $property) + { + // Ignore static properties + if ($property->isStatic()) { + return; + } + + // Apply the filters + foreach ($this->filters as $item) { + /** @var Matcher $matcher */ + $matcher = $item['matcher']; + /** @var Filter $filter */ + $filter = $item['filter']; + + if ($matcher->matches($object, $property->getName())) { + $filter->apply( + $object, + $property->getName(), + function ($object) { + return $this->recursiveCopy($object); + } + ); + + // If a filter matches, we stop processing this property + return; + } + } + + $property->setAccessible(true); + $propertyValue = $property->getValue($object); + + // Copy the property + $property->setValue($object, $this->recursiveCopy($propertyValue)); + } + + /** + * Returns first filter that matches variable, `null` if no such filter found. + * + * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and + * 'matcher' with value of type {@see TypeMatcher} + * @param mixed $var + * + * @return TypeFilter|null + */ + private function getFirstMatchedTypeFilter(array $filterRecords, $var) + { + $matched = $this->first( + $filterRecords, + function (array $record) use ($var) { + /* @var TypeMatcher $matcher */ + $matcher = $record['matcher']; + + return $matcher->matches($var); + } + ); + + return isset($matched) ? $matched['filter'] : null; + } + + /** + * Returns first element that matches predicate, `null` if no such element found. + * + * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs. + * @param callable $predicate Predicate arguments are: element. + * + * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher' + * with value of type {@see TypeMatcher} or `null`. + */ + private function first(array $elements, callable $predicate) + { + foreach ($elements as $element) { + if (call_user_func($predicate, $element)) { + return $element; + } + } + + return null; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php new file mode 100644 index 0000000..c046706 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php @@ -0,0 +1,9 @@ +setAccessible(true); + $oldCollection = $reflectionProperty->getValue($object); + + $newCollection = $oldCollection->map( + function ($item) use ($objectCopier) { + return $objectCopier($item); + } + ); + + $reflectionProperty->setValue($object, $newCollection); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php new file mode 100644 index 0000000..7b33fd5 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php @@ -0,0 +1,28 @@ +setAccessible(true); + + $reflectionProperty->setValue($object, new ArrayCollection()); + } +} \ No newline at end of file diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php new file mode 100644 index 0000000..8bee8f7 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php @@ -0,0 +1,22 @@ +__load(); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php new file mode 100644 index 0000000..85ba18c --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php @@ -0,0 +1,18 @@ +callback = $callable; + } + + /** + * Replaces the object property by the result of the callback called with the object property. + * + * {@inheritdoc} + */ + public function apply($object, $property, $objectCopier) + { + $reflectionProperty = ReflectionHelper::getProperty($object, $property); + $reflectionProperty->setAccessible(true); + + $value = call_user_func($this->callback, $reflectionProperty->getValue($object)); + + $reflectionProperty->setValue($object, $value); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php new file mode 100644 index 0000000..bea86b8 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php @@ -0,0 +1,24 @@ +setAccessible(true); + $reflectionProperty->setValue($object, null); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php new file mode 100644 index 0000000..ec8856f --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php @@ -0,0 +1,22 @@ +class = $class; + $this->property = $property; + } + + /** + * Matches a specific property of a specific class. + * + * {@inheritdoc} + */ + public function matches($object, $property) + { + return ($object instanceof $this->class) && $property == $this->property; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php new file mode 100644 index 0000000..c8ec0d2 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php @@ -0,0 +1,32 @@ +property = $property; + } + + /** + * Matches a property by its name. + * + * {@inheritdoc} + */ + public function matches($object, $property) + { + return $property == $this->property; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php new file mode 100644 index 0000000..a6b0c0b --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php @@ -0,0 +1,46 @@ +propertyType = $propertyType; + } + + /** + * {@inheritdoc} + */ + public function matches($object, $property) + { + try { + $reflectionProperty = ReflectionHelper::getProperty($object, $property); + } catch (ReflectionException $exception) { + return false; + } + + $reflectionProperty->setAccessible(true); + + return $reflectionProperty->getValue($object) instanceof $this->propertyType; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php new file mode 100644 index 0000000..742410c --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php @@ -0,0 +1,78 @@ +getProperties() does not return private properties from ancestor classes. + * + * @author muratyaman@gmail.com + * @see http://php.net/manual/en/reflectionclass.getproperties.php + * + * @param ReflectionClass $ref + * + * @return ReflectionProperty[] + */ + public static function getProperties(ReflectionClass $ref) + { + $props = $ref->getProperties(); + $propsArr = array(); + + foreach ($props as $prop) { + $propertyName = $prop->getName(); + $propsArr[$propertyName] = $prop; + } + + if ($parentClass = $ref->getParentClass()) { + $parentPropsArr = self::getProperties($parentClass); + foreach ($propsArr as $key => $property) { + $parentPropsArr[$key] = $property; + } + + return $parentPropsArr; + } + + return $propsArr; + } + + /** + * Retrieves property by name from object and all its ancestors. + * + * @param object|string $object + * @param string $name + * + * @throws PropertyException + * @throws ReflectionException + * + * @return ReflectionProperty + */ + public static function getProperty($object, $name) + { + $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object); + + if ($reflection->hasProperty($name)) { + return $reflection->getProperty($name); + } + + if ($parentClass = $reflection->getParentClass()) { + return self::getProperty($parentClass->getName(), $name); + } + + throw new PropertyException( + sprintf( + 'The class "%s" doesn\'t have a property with the given name: "%s".', + is_object($object) ? get_class($object) : $object, + $name + ) + ); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php new file mode 100644 index 0000000..becd1cf --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php @@ -0,0 +1,33 @@ + $propertyValue) { + $copy->{$propertyName} = $propertyValue; + } + + return $copy; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php new file mode 100644 index 0000000..164f8b8 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php @@ -0,0 +1,30 @@ +callback = $callable; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + return call_user_func($this->callback, $element); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php new file mode 100644 index 0000000..a5fbd7a --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php @@ -0,0 +1,17 @@ +copier = $copier; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + $newElement = clone $element; + + $copy = $this->createCopyClosure(); + + return $copy($newElement); + } + + private function createCopyClosure() + { + $copier = $this->copier; + + $copy = function (SplDoublyLinkedList $list) use ($copier) { + // Replace each element in the list with a deep copy of itself + for ($i = 1; $i <= $list->count(); $i++) { + $copy = $copier->recursiveCopy($list->shift()); + + $list->push($copy); + } + + return $list; + }; + + return Closure::bind($copy, null, DeepCopy::class); + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php new file mode 100644 index 0000000..5785a7d --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php @@ -0,0 +1,13 @@ +type = $type; + } + + /** + * @param mixed $element + * + * @return boolean + */ + public function matches($element) + { + return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type; + } +} diff --git a/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php new file mode 100644 index 0000000..55dcc92 --- /dev/null +++ b/lib/MPDF/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php @@ -0,0 +1,20 @@ +copy($value); + } +} diff --git a/lib/MPDF/vendor/paragonie/random_compat/LICENSE b/lib/MPDF/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 0000000..45c7017 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/lib/MPDF/vendor/paragonie/random_compat/build-phar.sh b/lib/MPDF/vendor/paragonie/random_compat/build-phar.sh new file mode 100755 index 0000000..b4a5ba3 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/build-phar.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) + +php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/lib/MPDF/vendor/paragonie/random_compat/composer.json b/lib/MPDF/vendor/paragonie/random_compat/composer.json new file mode 100644 index 0000000..1fa8de9 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,34 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "polyfill", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "vimeo/psalm": "^1", + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + } +} diff --git a/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 0000000..eb50ebf --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 0000000..6a1d7f3 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/lib/MPDF/vendor/paragonie/random_compat/lib/random.php b/lib/MPDF/vendor/paragonie/random_compat/lib/random.php new file mode 100644 index 0000000..c7731a5 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/lib/random.php @@ -0,0 +1,32 @@ +buildFromDirectory(dirname(__DIR__).'/lib'); +rename( + dirname(__DIR__).'/lib/index.php', + dirname(__DIR__).'/lib/random.php' +); + +/** + * If we pass an (optional) path to a private key as a second argument, we will + * sign the Phar with OpenSSL. + * + * If you leave this out, it will produce an unsigned .phar! + */ +if ($argc > 1) { + if (!@is_readable($argv[1])) { + echo 'Could not read the private key file:', $argv[1], "\n"; + exit(255); + } + $pkeyFile = file_get_contents($argv[1]); + + $private = openssl_get_privatekey($pkeyFile); + if ($private !== false) { + $pkey = ''; + openssl_pkey_export($private, $pkey); + $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + + /** + * Save the corresponding public key to the file + */ + if (!@is_readable($dist.'/random_compat.phar.pubkey')) { + $details = openssl_pkey_get_details($private); + file_put_contents( + $dist.'/random_compat.phar.pubkey', + $details['key'] + ); + } + } else { + echo 'An error occurred reading the private key from OpenSSL.', "\n"; + exit(255); + } +} diff --git a/lib/MPDF/vendor/paragonie/random_compat/psalm-autoload.php b/lib/MPDF/vendor/paragonie/random_compat/psalm-autoload.php new file mode 100644 index 0000000..d71d1b8 --- /dev/null +++ b/lib/MPDF/vendor/paragonie/random_compat/psalm-autoload.php @@ -0,0 +1,9 @@ + + + + + + + + + + + + + + + diff --git a/lib/MPDF/vendor/psr/log/.gitignore b/lib/MPDF/vendor/psr/log/.gitignore new file mode 100644 index 0000000..22d0d82 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/lib/MPDF/vendor/psr/log/LICENSE b/lib/MPDF/vendor/psr/log/LICENSE new file mode 100644 index 0000000..474c952 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/AbstractLogger.php b/lib/MPDF/vendor/psr/log/Psr/Log/AbstractLogger.php new file mode 100644 index 0000000..90e721a --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/AbstractLogger.php @@ -0,0 +1,128 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/lib/MPDF/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 0000000..67f852d --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/LoggerInterface.php b/lib/MPDF/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 0000000..e695046 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,125 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/NullLogger.php b/lib/MPDF/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 0000000..c8f7293 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,30 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/lib/MPDF/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php new file mode 100644 index 0000000..9ecb6c4 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php @@ -0,0 +1,146 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} + +class DummyTest +{ + public function __toString() + { + return 'DummyTest'; + } +} diff --git a/lib/MPDF/vendor/psr/log/Psr/Log/Test/TestLogger.php b/lib/MPDF/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 0000000..1be3230 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,147 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} diff --git a/lib/MPDF/vendor/psr/log/README.md b/lib/MPDF/vendor/psr/log/README.md new file mode 100644 index 0000000..a9f20c4 --- /dev/null +++ b/lib/MPDF/vendor/psr/log/README.md @@ -0,0 +1,58 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/lib/MPDF/vendor/psr/log/composer.json b/lib/MPDF/vendor/psr/log/composer.json new file mode 100644 index 0000000..3f6d4ee --- /dev/null +++ b/lib/MPDF/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/LICENSE.txt b/lib/MPDF/vendor/setasign/fpdi/LICENSE.txt new file mode 100644 index 0000000..7e75850 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Setasign - Jan Slabon, https://www.setasign.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/README.md b/lib/MPDF/vendor/setasign/fpdi/README.md new file mode 100644 index 0000000..42856df --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/README.md @@ -0,0 +1,168 @@ +FPDI - Free PDF Document Importer +================================= + +[![Latest Stable Version](https://poser.pugx.org/setasign/fpdi/v/stable.svg)](https://packagist.org/packages/setasign/fpdi) +[![Total Downloads](https://poser.pugx.org/setasign/fpdi/downloads.svg)](https://packagist.org/packages/setasign/fpdi) +[![Latest Unstable Version](https://poser.pugx.org/setasign/fpdi/v/unstable.svg)](https://packagist.org/packages/setasign/fpdi) +[![License](https://poser.pugx.org/setasign/fpdi/license.svg)](https://packagist.org/packages/setasign/fpdi) +[![Build Status](https://travis-ci.org/Setasign/FPDI.svg?branch=development)](https://travis-ci.org/Setasign/FPDI) + +:heavy_exclamation_mark: This document refers to FPDI 2. Version 1 is deprecated and development is discontinued. :heavy_exclamation_mark: + +FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF +documents and use them as templates in [FPDF](http://www.fpdf.org), which was developed by Olivier Plathey. Apart +from a copy of [FPDF](http://www.fpdf.org), FPDI does not require any special PHP extensions. + +FPDI can also be used as an extension for [TCPDF](https://github.com/tecnickcom/TCPDF) or +[tFPDF](http://fpdf.org/en/script/script92.php), too. + +## Installation with [Composer](https://packagist.org/packages/setasign/fpdi) + +Because FPDI can be used with FPDF, TCPDF or tFPDF we didn't added a fixed dependency in the main +composer.json file but we added metadata packages for +[FPDF](https://github.com/Setasign/FPDI-FPDF), +[TCPDF](https://github.com/Setasign/FPDI-TCPDF) and +[tFPDF](https://github.com/Setasign/FPDI-tFPDF). + +### Evaluate Dependencies Automatically + +For FPDF add following [package](https://github.com/Setasign/FPDI-FPDF) to your composer.json: +```json +{ + "require": { + "setasign/fpdi-fpdf": "^2.0" + } +} +``` + +For TCPDF add following [package](https://github.com/Setasign/FPDI-TCPDF) to your composer.json: +```json +{ + "require": { + "setasign/fpdi-tcpdf": "^2.0" + } +} +``` + +For tFPDF add following [package](https://github.com/Setasign/FPDI-tFPDF) to your composer.json: +```json +{ + "require": { + "setasign/fpdi-tfpdf": "^2.1" + } +} +``` + +### Manual Dependencies + +If you don't want to use the metadata packages, it is up to you to add the dependencies to your +composer.json file. + +To use FPDI with FPDF include following in your composer.json file: + +```json +{ + "require": { + "setasign/fpdf": "^1.8", + "setasign/fpdi": "^2.0" + } +} +``` + +If you want to use TCPDF, your have to update your composer.json respectively to: + +```json +{ + "require": { + "tecnickcom/tcpdf": "^6.2", + "setasign/fpdi": "^2.0" + } +} +``` + +If you want to use tFPDF, your have to update your composer.json respectively to: + +```json +{ + "require": { + "tecnickcom/tfpdf": "1.25", + "setasign/fpdi": "^2.1" + } +} +``` + +## Manual Installation + +If you do not use composer, just require the autoload.php in the /src folder: + +```php +require_once('src/autoload.php'); +``` + +If you have a PSR-4 autoloader implemented, just register the src path as follows: +```php +$loader = new \Example\Psr4AutoloaderClass; +$loader->register(); +$loader->addNamespace('setasign\Fpdi', 'path/to/src/'); +``` + +## Changes to Version 1 + +Version 2 is a complete rewrite from scratch of FPDI which comes with: +- Namespaced code +- Clean and up-to-date code base and style +- PSR-4 compatible autoloading +- Performance improvements by up to 100% +- Less memory consumption +- Native support for reading PDFs from strings or stream-resources +- Support for documents with "invalid" data before their file-header +- Optimized page tree resolving +- Usage of individual exceptions +- Several test types (unit, functional and visual tests) + +We tried to keep the main methods and logical workflow the same as in version 1 but please +notice that there were incompatible changes which you should consider when updating to +version 2: +- You need to load the code using the `src/autoload.php` file instead of `classes/FPDI.php`. +- The classes and traits are namespaced now: `setasign\Fpdi` +- Page boundaries beginning with a slash, such as `/MediaBox`, are not supported anymore. Remove + the slash or use a constant of `PdfReader\PageBoundaries`. +- The parameters $x, $y, $width and $height of the `useTemplate()` or `getTemplateSize()` + method have more logical correct default values now. Passing `0` as width or height will + result in an `InvalidArgumentException` now. +- The return value of `getTemplateSize()` had changed to an array with more speaking keys + and reusability: Use `width` instead of `w` and `height` instead of `h`. +- If you want to use **FPDI with TCPDF** you need to refactor your code to use the class `Tcpdf\Fpdi` +(since 2.1; before it was `TcpdfFpdi`) instead of `FPDI`. + +## Example and Documentation + +A simple example, that imports a single page and places this onto a new created page: + +```php +AddPage(); +// set the source file +$pdf->setSourceFile("Fantastic-Speaker.pdf"); +// import page 1 +$tplId = $pdf->importPage(1); +// use the imported page and place it at point 10,10 with a width of 100 mm +$pdf->useTemplate($tplId, 10, 10, 100); + +$pdf->Output(); +``` + +A full end-user documentation and API reference is available [here](https://manuals.setasign.com/fpdi-manual/). \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/composer.json b/lib/MPDF/vendor/setasign/fpdi/composer.json new file mode 100644 index 0000000..58f7931 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/composer.json @@ -0,0 +1,50 @@ +{ + "name": "setasign/fpdi", + "homepage": "https://www.setasign.com/fpdi", + "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.", + "type": "library", + "keywords": [ + "pdf", + "fpdi", + "fpdf" + ], + "license": "MIT", + "autoload": { + "psr-4": { + "setasign\\Fpdi\\": "src/" + } + }, + "require": { + "php": "^5.6 || ^7.0", + "ext-zlib": "*" + }, + "authors": [ + { + "name": "Jan Slabon", + "email": "jan.slabon@setasign.com", + "homepage": "https://www.setasign.com" + }, + { + "name": "Maximilian Kresse", + "email": "maximilian.kresse@setasign.com", + "homepage": "https://www.setasign.com" + } + ], + "suggest": { + "setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured.", + "setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.", + "setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF.", + "setasign/fpdi-tfpdf": "Use this package to automatically evaluate dependencies to tFPDF." + }, + "require-dev": { + "phpunit/phpunit": "~5.7", + "setasign/fpdf": "~1.8", + "tecnickcom/tcpdf": "~6.2", + "setasign/tfpdf": "1.25" + }, + "autoload-dev": { + "psr-4": { + "setasign\\Fpdi\\": "tests/" + } + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/FpdfTpl.php b/lib/MPDF/vendor/setasign/fpdi/src/FpdfTpl.php new file mode 100644 index 0000000..fba7c6a --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/FpdfTpl.php @@ -0,0 +1,22 @@ +currentTemplateId !== null) { + throw new \BadMethodCallException('The page format cannot be changed when writing to a template.'); + } + + if (!\in_array($orientation, ['P', 'L'], true)) { + throw new \InvalidArgumentException(\sprintf( + 'Invalid page orientation "%s"! Only "P" and "L" are allowed!', + $orientation + )); + } + + $size = $this->_getpagesize($size); + + if ($orientation != $this->CurOrientation + || $size[0] != $this->CurPageSize[0] + || $size[1] != $this->CurPageSize[1] + ) { + // New size or orientation + if ($orientation === 'P') { + $this->w = $size[0]; + $this->h = $size[1]; + } else { + $this->w = $size[1]; + $this->h = $size[0]; + } + $this->wPt = $this->w * $this->k; + $this->hPt = $this->h * $this->k; + $this->PageBreakTrigger = $this->h - $this->bMargin; + $this->CurOrientation = $orientation; + $this->CurPageSize = $size; + + $this->PageInfo[$this->page]['size'] = array($this->wPt, $this->hPt); + } + } + + /** + * Draws a template onto the page or another template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param array|float|int $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size + * @see FpdfTplTrait::getTemplateSize() + */ + public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + if (!isset($this->templates[$tpl])) { + throw new \InvalidArgumentException('Template does not exist!'); + } + + if (\is_array($x)) { + unset($x['tpl']); + \extract($x, EXTR_IF_EXISTS); + /** @noinspection NotOptimalIfConditionsInspection */ + /** @noinspection CallableParameterUseCaseInTypeContextInspection */ + if (\is_array($x)) { + $x = 0; + } + } + + $template = $this->templates[$tpl]; + + $originalSize = $this->getTemplateSize($tpl); + $newSize = $this->getTemplateSize($tpl, $width, $height); + if ($adjustPageSize) { + $this->setPageFormat($newSize, $newSize['orientation']); + } + + $this->_out( + // reset standard values, translate and scale + \sprintf( + 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q', + ($newSize['width'] / $originalSize['width']), + ($newSize['height'] / $originalSize['height']), + $x * $this->k, + ($this->h - $y - $newSize['height']) * $this->k, + $template['id'] + ) + ); + + return $newSize; + } + + /** + * Get the size of a template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P) + */ + public function getTemplateSize($tpl, $width = null, $height = null) + { + if (!isset($this->templates[$tpl])) { + return false; + } + + if ($width === null && $height === null) { + $width = $this->templates[$tpl]['width']; + $height = $this->templates[$tpl]['height']; + } elseif ($width === null) { + $width = $height * $this->templates[$tpl]['width'] / $this->templates[$tpl]['height']; + } + + if ($height === null) { + $height = $width * $this->templates[$tpl]['height'] / $this->templates[$tpl]['width']; + } + + if ($height <= 0. || $width <= 0.) { + throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.'); + } + + return [ + 'width' => $width, + 'height' => $height, + 0 => $width, + 1 => $height, + 'orientation' => $width > $height ? 'L' : 'P' + ]; + } + + /** + * Begins a new template. + * + * @param float|int|null $width The width of the template. If null, the current page width is used. + * @param float|int|null $height The height of the template. If null, the current page height is used. + * @param bool $groupXObject Define the form XObject as a group XObject to support transparency (if used). + * @return int A template identifier. + */ + public function beginTemplate($width = null, $height = null, $groupXObject = false) + { + if ($width === null) { + $width = $this->w; + } + + if ($height === null) { + $height = $this->h; + } + + $templateId = $this->getNextTemplateId(); + + // initiate buffer with current state of FPDF + $buffer = "2 J\n" + . \sprintf('%.2F w', $this->LineWidth * $this->k) . "\n"; + + if ($this->FontFamily) { + $buffer .= \sprintf("BT /F%d %.2F Tf ET\n", $this->CurrentFont['i'], $this->FontSizePt); + } + + if ($this->DrawColor !== '0 G') { + $buffer .= $this->DrawColor . "\n"; + } + if ($this->FillColor !== '0 g') { + $buffer .= $this->FillColor . "\n"; + } + + if ($groupXObject && \version_compare('1.4', $this->PDFVersion, '>')) { + $this->PDFVersion = '1.4'; + } + + $this->templates[$templateId] = [ + 'objectNumber' => null, + 'id' => 'TPL' . $templateId, + 'buffer' => $buffer, + 'width' => $width, + 'height' => $height, + 'groupXObject' => $groupXObject, + 'state' => [ + 'x' => $this->x, + 'y' => $this->y, + 'AutoPageBreak' => $this->AutoPageBreak, + 'bMargin' => $this->bMargin, + 'tMargin' => $this->tMargin, + 'lMargin' => $this->lMargin, + 'rMargin' => $this->rMargin, + 'h' => $this->h, + 'w' => $this->w, + 'FontFamily' => $this->FontFamily, + 'FontStyle' => $this->FontStyle, + 'FontSizePt' => $this->FontSizePt, + 'FontSize' => $this->FontSize, + 'underline' => $this->underline, + 'TextColor' => $this->TextColor, + 'DrawColor' => $this->DrawColor, + 'FillColor' => $this->FillColor, + 'ColorFlag' => $this->ColorFlag + ] + ]; + + $this->SetAutoPageBreak(false); + $this->currentTemplateId = $templateId; + + $this->h = $height; + $this->w = $width; + + $this->SetXY($this->lMargin, $this->tMargin); + $this->SetRightMargin($this->w - $width + $this->rMargin); + + return $templateId; + } + + /** + * Ends a template. + * + * @return bool|int|null A template identifier. + */ + public function endTemplate() + { + if (null === $this->currentTemplateId) { + return false; + } + + $templateId = $this->currentTemplateId; + $template = $this->templates[$templateId]; + + $state = $template['state']; + $this->SetXY($state['x'], $state['y']); + $this->tMargin = $state['tMargin']; + $this->lMargin = $state['lMargin']; + $this->rMargin = $state['rMargin']; + $this->h = $state['h']; + $this->w = $state['w']; + $this->SetAutoPageBreak($state['AutoPageBreak'], $state['bMargin']); + + $this->FontFamily = $state['FontFamily']; + $this->FontStyle = $state['FontStyle']; + $this->FontSizePt = $state['FontSizePt']; + $this->FontSize = $state['FontSize']; + + $this->TextColor = $state['TextColor']; + $this->DrawColor = $state['DrawColor']; + $this->FillColor = $state['FillColor']; + $this->ColorFlag = $state['ColorFlag']; + + $this->underline = $state['underline']; + + $fontKey = $this->FontFamily . $this->FontStyle; + if ($fontKey) { + $this->CurrentFont =& $this->fonts[$fontKey]; + } else { + unset($this->CurrentFont); + } + + $this->currentTemplateId = null; + + return $templateId; + } + + /** + * Get the next template id. + * + * @return int + */ + protected function getNextTemplateId() + { + return $this->templateId++; + } + + /* overwritten FPDF methods: */ + + /** + * @inheritdoc + */ + public function AddPage($orientation = '', $size = '', $rotation = 0) + { + if ($this->currentTemplateId !== null) { + throw new \BadMethodCallException('Pages cannot be added when writing to a template.'); + } + parent::AddPage($orientation, $size, $rotation); + } + + /** + * @inheritdoc + */ + public function Link($x, $y, $w, $h, $link) + { + if ($this->currentTemplateId !== null) { + throw new \BadMethodCallException('Links cannot be set when writing to a template.'); + } + parent::Link($x, $y, $w, $h, $link); + } + + /** + * @inheritdoc + */ + public function SetLink($link, $y = 0, $page = -1) + { + if ($this->currentTemplateId !== null) { + throw new \BadMethodCallException('Links cannot be set when writing to a template.'); + } + return parent::SetLink($link, $y, $page); + } + + /** + * @inheritdoc + */ + public function SetDrawColor($r, $g = null, $b = null) + { + parent::SetDrawColor($r, $g, $b); + if ($this->page === 0 && $this->currentTemplateId !== null) { + $this->_out($this->DrawColor); + } + } + + /** + * @inheritdoc + */ + public function SetFillColor($r, $g = null, $b = null) + { + parent::SetFillColor($r, $g, $b); + if ($this->page === 0 && $this->currentTemplateId !== null) { + $this->_out($this->FillColor); + } + } + + /** + * @inheritdoc + */ + public function SetLineWidth($width) + { + parent::SetLineWidth($width); + if ($this->page === 0 && $this->currentTemplateId !== null) { + $this->_out(\sprintf('%.2F w', $width * $this->k)); + } + } + + /** + * @inheritdoc + */ + public function SetFont($family, $style = '', $size = 0) + { + parent::SetFont($family, $style, $size); + if ($this->page === 0 && $this->currentTemplateId !== null) { + $this->_out(\sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); + } + } + + /** + * @inheritdoc + */ + public function SetFontSize($size) + { + parent::SetFontSize($size); + if ($this->page === 0 && $this->currentTemplateId !== null) { + $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); + } + } + + /** + * @inheritdoc + */ + protected function _putimages() + { + parent::_putimages(); + + foreach ($this->templates as $key => $template) { + $this->_newobj(); + $this->templates[$key]['objectNumber'] = $this->n; + + $this->_put('<_put(\sprintf('/BBox[0 0 %.2F %.2F]', $template['width'] * $this->k, $template['height'] * $this->k)); + $this->_put('/Resources 2 0 R'); // default resources dictionary of FPDF + + if ($this->compress) { + $buffer = \gzcompress($template['buffer']); + $this->_put('/Filter/FlateDecode'); + } else { + $buffer = $template['buffer']; + } + + $this->_put('/Length ' . \strlen($buffer)); + + if ($template['groupXObject']) { + $this->_put('/Group <>'); + } + + $this->_put('>>'); + $this->_putstream($buffer); + $this->_put('endobj'); + } + } + + /** + * @inheritdoc + */ + protected function _putxobjectdict() + { + foreach ($this->templates as $key => $template) { + $this->_put('/' . $template['id'] . ' ' . $template['objectNumber'] . ' 0 R'); + } + + parent::_putxobjectdict(); + } + + /** + * @inheritdoc + */ + public function _out($s) + { + if ($this->currentTemplateId !== null) { + $this->templates[$this->currentTemplateId]['buffer'] .= $s . "\n"; + } else { + parent::_out($s); + } + } +} \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/src/Fpdi.php b/lib/MPDF/vendor/setasign/fpdi/src/Fpdi.php new file mode 100644 index 0000000..b49c103 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/Fpdi.php @@ -0,0 +1,155 @@ +cleanUp(); + } + + /** + * Draws an imported page or a template onto the page or another template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size + * @see Fpdi::getTemplateSize() + */ + public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + if (isset($this->importedPages[$tpl])) { + $size = $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize); + if ($this->currentTemplateId !== null) { + $this->templates[$this->currentTemplateId]['resources']['templates']['importedPages'][$tpl] = $tpl; + } + return $size; + } + + return parent::useTemplate($tpl, $x, $y, $width, $height, $adjustPageSize); + } + + /** + * Get the size of an imported page or template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P) + */ + public function getTemplateSize($tpl, $width = null, $height = null) + { + $size = parent::getTemplateSize($tpl, $width, $height); + if ($size === false) { + return $this->getImportedPageSize($tpl, $width, $height); + } + + return $size; + } + + /** + * @inheritdoc + * @throws CrossReferenceException + * @throws PdfParserException + */ + protected function _putimages() + { + $this->currentReaderId = null; + parent::_putimages(); + + foreach ($this->importedPages as $key => $pageData) { + $this->_newobj(); + $this->importedPages[$key]['objectNumber'] = $this->n; + $this->currentReaderId = $pageData['readerId']; + $this->writePdfType($pageData['stream']); + $this->_put('endobj'); + } + + foreach (\array_keys($this->readers) as $readerId) { + $parser = $this->getPdfReader($readerId)->getParser(); + $this->currentReaderId = $readerId; + + while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) { + try { + $object = $parser->getIndirectObject($objectNumber); + + } catch (CrossReferenceException $e) { + if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) { + $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull()); + } else { + throw $e; + } + } + + $this->writePdfType($object); + } + } + + $this->currentReaderId = null; + } + + /** + * @inheritdoc + */ + protected function _putxobjectdict() + { + foreach ($this->importedPages as $key => $pageData) { + $this->_put('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R'); + } + + parent::_putxobjectdict(); + } + + /** + * @inheritdoc + */ + protected function _put($s, $newLine = true) + { + if ($newLine) { + $this->buffer .= $s . "\n"; + } else { + $this->buffer .= $s; + } + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/FpdiException.php b/lib/MPDF/vendor/setasign/fpdi/src/FpdiException.php new file mode 100644 index 0000000..d126c14 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/FpdiException.php @@ -0,0 +1,19 @@ +readers) : $this->createdReaders; + foreach ($readers as $id) { + $this->readers[$id]->getParser()->getStreamReader()->cleanUp(); + unset($this->readers[$id]); + } + + $this->createdReaders= []; + } + + /** + * Set the minimal PDF version. + * + * @param string $pdfVersion + */ + protected function setMinPdfVersion($pdfVersion) + { + if (\version_compare($pdfVersion, $this->PDFVersion, '>')) { + $this->PDFVersion = $pdfVersion; + } + } + + /** @noinspection PhpUndefinedClassInspection */ + /** + * Get a new pdf parser instance. + * + * @param StreamReader $streamReader + * @return PdfParser|FpdiPdfParser + */ + protected function getPdfParserInstance(StreamReader $streamReader) + { + /** @noinspection PhpUndefinedClassInspection */ + if (\class_exists(FpdiPdfParser::class)) { + /** @noinspection PhpUndefinedClassInspection */ + return new FpdiPdfParser($streamReader); + } + + return new PdfParser($streamReader); + } + + /** + * Get an unique reader id by the $file parameter. + * + * @param string|resource|PdfReader|StreamReader $file An open file descriptor, a path to a file, a PdfReader + * instance or a StreamReader instance. + * @return string + */ + protected function getPdfReaderId($file) + { + if (\is_resource($file)) { + $id = (string) $file; + } elseif (\is_string($file)) { + $id = \realpath($file); + if ($id === false) { + $id = $file; + } + } elseif (\is_object($file)) { + $id = \spl_object_hash($file); + } else { + throw new \InvalidArgumentException( + \sprintf('Invalid type in $file parameter (%s)', \gettype($file)) + ); + } + + /** @noinspection OffsetOperationsInspection */ + if (isset($this->readers[$id])) { + return $id; + } + + if (\is_resource($file)) { + $streamReader = new StreamReader($file); + } elseif (\is_string($file)) { + $streamReader = StreamReader::createByFile($file); + $this->createdReaders[] = $id; + } else { + $streamReader = $file; + } + + $reader = new PdfReader($this->getPdfParserInstance($streamReader)); + /** @noinspection OffsetOperationsInspection */ + $this->readers[$id] = $reader; + + return $id; + } + + /** + * Get a pdf reader instance by its id. + * + * @param string $id + * @return PdfReader + */ + protected function getPdfReader($id) + { + if (isset($this->readers[$id])) { + return $this->readers[$id]; + } + + throw new \InvalidArgumentException( + \sprintf('No pdf reader with the given id (%s) exists.', $id) + ); + } + + /** + * Set the source PDF file. + * + * @param string|resource|StreamReader $file Path to the file or a stream resource or a StreamReader instance. + * @return int The page count of the PDF document. + * @throws PdfParserException + */ + public function setSourceFile($file) + { + $this->currentReaderId = $this->getPdfReaderId($file); + $this->objectsToCopy[$this->currentReaderId] = []; + + $reader = $this->getPdfReader($this->currentReaderId); + $this->setMinPdfVersion($reader->getPdfVersion()); + + return $reader->getPageCount(); + } + + /** + * Imports a page. + * + * @param int $pageNumber The page number. + * @param string $box The page boundary to import. Default set to PageBoundaries::CROP_BOX. + * @param bool $groupXObject Define the form XObject as a group XObject to support transparency (if used). + * @return string A unique string identifying the imported page. + * @throws CrossReferenceException + * @throws FilterException + * @throws PdfParserException + * @throws PdfTypeException + * @throws PdfReaderException + * @see PageBoundaries + */ + public function importPage($pageNumber, $box = PageBoundaries::CROP_BOX, $groupXObject = true) + { + if (null === $this->currentReaderId) { + throw new \BadMethodCallException('No reader initiated. Call setSourceFile() first.'); + } + + $pageId = $this->currentReaderId; + + $pageNumber = (int)$pageNumber; + $pageId .= '|' . $pageNumber . '|' . ($groupXObject ? '1' : '0'); + + // for backwards compatibility with FPDI 1 + $box = \ltrim($box, '/'); + if (!PageBoundaries::isValidName($box)) { + throw new \InvalidArgumentException( + \sprintf('Box name is invalid: "%s"', $box) + ); + } + + $pageId .= '|' . $box; + + if (isset($this->importedPages[$pageId])) { + return $pageId; + } + + $reader = $this->getPdfReader($this->currentReaderId); + $page = $reader->getPage($pageNumber); + + $bbox = $page->getBoundary($box); + if ($bbox === false) { + throw new PdfReaderException( + \sprintf("Page doesn't have a boundary box (%s).", $box), + PdfReaderException::MISSING_DATA + ); + } + + $dict = new PdfDictionary(); + $dict->value['Type'] = PdfName::create('XObject'); + $dict->value['Subtype'] = PdfName::create('Form'); + $dict->value['FormType'] = PdfNumeric::create(1); + $dict->value['BBox'] = $bbox->toPdfArray(); + + if ($groupXObject) { + $this->setMinPdfVersion('1.4'); + $dict->value['Group'] = PdfDictionary::create([ + 'Type' => PdfName::create('Group'), + 'S' => PdfName::create('Transparency') + ]); + } + + $resources = $page->getAttribute('Resources'); + if ($resources !== null) { + $dict->value['Resources'] = $resources; + } + + list($width, $height) = $page->getWidthAndHeight($box); + + $a = 1; + $b = 0; + $c = 0; + $d = 1; + $e = -$bbox->getLlx(); + $f = -$bbox->getLly(); + + $rotation = $page->getRotation(); + + if ($rotation !== 0) { + $rotation *= -1; + $angle = $rotation * M_PI/180; + $a = \cos($angle); + $b = \sin($angle); + $c = -$b; + $d = $a; + + switch ($rotation) { + case -90: + $e = -$bbox->getLly(); + $f = $bbox->getUrx(); + break; + case -180: + $e = $bbox->getUrx(); + $f = $bbox->getUry(); + break; + case -270: + $e = $bbox->getUry(); + $f = -$bbox->getLlx(); + break; + } + } + + // we need to rotate/translate + if ($a != 1 || $b != 0 || $c != 0 || $d != 1 || $e != 0 || $f != 0) { + $dict->value['Matrix'] = PdfArray::create([ + PdfNumeric::create($a), PdfNumeric::create($b), PdfNumeric::create($c), + PdfNumeric::create($d), PdfNumeric::create($e), PdfNumeric::create($f) + ]); + } + + // try to use the existing content stream + $pageDict = $page->getPageDictionary(); + + $contentsObject = PdfType::resolve(PdfDictionary::get($pageDict, 'Contents'), $reader->getParser(), true); + $contents = PdfType::resolve($contentsObject, $reader->getParser()); + + // just copy the stream reference if it is only a single stream + if (($contentsIsStream = ($contents instanceof PdfStream)) + || ($contents instanceof PdfArray && \count($contents->value) === 1) + ) { + if ($contentsIsStream) { + /** + * @var PdfIndirectObject $contentsObject + */ + $stream = $contents; + } else { + $stream = PdfType::resolve($contents->value[0], $reader->getParser()); + } + + $filter = PdfDictionary::get($stream->value, 'Filter'); + if (!$filter instanceof PdfNull) { + $dict->value['Filter'] = $filter; + } + $length = PdfType::resolve(PdfDictionary::get($stream->value, 'Length'), $reader->getParser()); + $dict->value['Length'] = $length; + $stream->value = $dict; + + // otherwise extract it from the array and re-compress the whole stream + } else { + $streamContent = $this->compress + ? \gzcompress($page->getContentStream()) + : $page->getContentStream(); + + $dict->value['Length'] = PdfNumeric::create(\strlen($streamContent)); + if ($this->compress) { + $dict->value['Filter'] = PdfName::create('FlateDecode'); + } + + $stream = PdfStream::create($dict, $streamContent); + } + + $this->importedPages[$pageId] = [ + 'objectNumber' => null, + 'readerId' => $this->currentReaderId, + 'id' => 'TPL' . $this->getNextTemplateId(), + 'width' => $width / $this->k, + 'height' => $height / $this->k, + 'stream' => $stream + ]; + + return $pageId; + } + + /** + * Draws an imported page onto the page. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $pageId The page id + * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size. + * @see Fpdi::getTemplateSize() + */ + public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + if (\is_array($x)) { + /** @noinspection OffsetOperationsInspection */ + unset($x['pageId']); + \extract($x, EXTR_IF_EXISTS); + /** @noinspection NotOptimalIfConditionsInspection */ + if (\is_array($x)) { + $x = 0; + } + } + + if (!isset($this->importedPages[$pageId])) { + throw new \InvalidArgumentException('Imported page does not exist!'); + } + + $importedPage = $this->importedPages[$pageId]; + + $originalSize = $this->getTemplateSize($pageId); + $newSize = $this->getTemplateSize($pageId, $width, $height); + if ($adjustPageSize) { + $this->setPageFormat($newSize, $newSize['orientation']); + } + + $this->_out( + // reset standard values, translate and scale + \sprintf( + 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q', + ($newSize['width'] / $originalSize['width']), + ($newSize['height'] / $originalSize['height']), + $x * $this->k, + ($this->h - $y - $newSize['height']) * $this->k, + $importedPage['id'] + ) + ); + + return $newSize; + } + + /** + * Get the size of an imported page. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P) + */ + public function getImportedPageSize($tpl, $width = null, $height = null) + { + if (isset($this->importedPages[$tpl])) { + $importedPage = $this->importedPages[$tpl]; + + if ($width === null && $height === null) { + $width = $importedPage['width']; + $height = $importedPage['height']; + } elseif ($width === null) { + $width = $height * $importedPage['width'] / $importedPage['height']; + } + + if ($height === null) { + $height = $width * $importedPage['height'] / $importedPage['width']; + } + + if ($height <= 0. || $width <= 0.) { + throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.'); + } + + return [ + 'width' => $width, + 'height' => $height, + 0 => $width, + 1 => $height, + 'orientation' => $width > $height ? 'L' : 'P' + ]; + } + + return false; + } + + /** + * Writes a PdfType object to the resulting buffer. + * + * @param PdfType $value + * @throws PdfTypeException + */ + protected function writePdfType(PdfType $value) + { + if ($value instanceof PdfNumeric) { + if (\is_int($value->value)) { + $this->_put($value->value . ' ', false); + } else { + $this->_put(\rtrim(\rtrim(\sprintf('%.5F', $value->value), '0'), '.') . ' ', false); + } + + } elseif ($value instanceof PdfName) { + $this->_put('/' . $value->value . ' ', false); + + } elseif ($value instanceof PdfString) { + $this->_put('(' . $value->value . ')', false); + + } elseif ($value instanceof PdfHexString) { + $this->_put('<' . $value->value . '>'); + + } elseif ($value instanceof PdfBoolean) { + $this->_put($value->value ? 'true ' : 'false ', false); + + } elseif ($value instanceof PdfArray) { + $this->_put('[', false); + foreach ($value->value as $entry) { + $this->writePdfType($entry); + } + $this->_put(']'); + + } elseif ($value instanceof PdfDictionary) { + $this->_put('<<', false); + foreach ($value->value as $name => $entry) { + $this->_put('/' . $name . ' ', false); + $this->writePdfType($entry); + } + $this->_put('>>'); + + } elseif ($value instanceof PdfToken) { + $this->_put($value->value); + + } elseif ($value instanceof PdfNull) { + $this->_put('null '); + + } elseif ($value instanceof PdfStream) { + /** + * @var $value PdfStream + */ + $this->writePdfType($value->value); + $this->_put('stream'); + $this->_put($value->getStream()); + $this->_put('endstream'); + + } elseif ($value instanceof PdfIndirectObjectReference) { + if (!isset($this->objectMap[$this->currentReaderId])) { + $this->objectMap[$this->currentReaderId] = []; + } + + if (!isset($this->objectMap[$this->currentReaderId][$value->value])) { + $this->objectMap[$this->currentReaderId][$value->value] = ++$this->n; + $this->objectsToCopy[$this->currentReaderId][] = $value->value; + } + + $this->_put($this->objectMap[$this->currentReaderId][$value->value] . ' 0 R ', false); + + } elseif ($value instanceof PdfIndirectObject) { + /** + * @var $value PdfIndirectObject + */ + $n = $this->objectMap[$this->currentReaderId][$value->objectNumber]; + $this->_newobj($n); + $this->writePdfType($value->value); + $this->_put('endobj'); + } + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/AbstractReader.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/AbstractReader.php new file mode 100644 index 0000000..1d5c579 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/AbstractReader.php @@ -0,0 +1,96 @@ +parser = $parser; + $this->readTrailer(); + } + + /** + * Get the trailer dictionary. + * + * @return PdfDictionary + */ + public function getTrailer() + { + return $this->trailer; + } + + /** + * Read the trailer dictionary. + * + * @throws CrossReferenceException + * @throws PdfTypeException + */ + protected function readTrailer() + { + try { + $trailerKeyword = $this->parser->readValue(null, PdfToken::class); + if ($trailerKeyword->value !== 'trailer') { + throw new CrossReferenceException( + \sprintf( + 'Unexpected end of cross reference. "trailer"-keyword expected, got: %s.', + $trailerKeyword->value + ), + CrossReferenceException::UNEXPECTED_END + ); + } + } catch (PdfTypeException $e) { + throw new CrossReferenceException( + 'Unexpected end of cross reference. "trailer"-keyword expected, got an invalid object type.', + CrossReferenceException::UNEXPECTED_END, + $e + ); + } + + try { + $trailer = $this->parser->readValue(null, PdfDictionary::class); + } catch (PdfTypeException $e) { + throw new CrossReferenceException( + 'Unexpected end of cross reference. Trailer not found.', + CrossReferenceException::UNEXPECTED_END, + $e + ); + } + + $this->trailer = $trailer; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php new file mode 100644 index 0000000..95674ce --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReference.php @@ -0,0 +1,320 @@ +parser = $parser; + $this->fileHeaderOffset = $fileHeaderOffset; + + $offset = $this->findStartXref(); + $reader = null; + /** @noinspection TypeUnsafeComparisonInspection */ + while ($offset != false) { // By doing an unsafe comparsion we ignore faulty references to byte offset 0 + try { + $reader = $this->readXref($offset + $this->fileHeaderOffset); + } catch (CrossReferenceException $e) { + // sometimes the file header offset is part of the byte offsets, so let's retry by resetting it to zero. + if ($e->getCode() === CrossReferenceException::INVALID_DATA && $this->fileHeaderOffset !== 0) { + $this->fileHeaderOffset = 0; + $reader = $this->readXref($offset + $this->fileHeaderOffset); + } else { + throw $e; + } + } + + $trailer = $reader->getTrailer(); + $this->checkForEncryption($trailer); + $this->readers[] = $reader; + + if (isset($trailer->value['Prev'])) { + $offset = $trailer->value['Prev']->value; + } else { + $offset = false; + } + } + + // fix faulty sub-section header + if ($reader instanceof FixedReader) { + /** + * @var FixedReader $reader + */ + $reader->fixFaultySubSectionShift(); + } + + if ($reader === null) { + throw new CrossReferenceException('No cross-reference found.', CrossReferenceException::NO_XREF_FOUND); + } + } + + /** + * Get the size of the cross reference. + * + * @return integer + */ + public function getSize() + { + return $this->getTrailer()->value['Size']->value; + } + + /** + * Get the trailer dictionary. + * + * @return PdfDictionary + */ + public function getTrailer() + { + return $this->readers[0]->getTrailer(); + } + + /** + * Get the cross reference readser instances. + * + * @return ReaderInterface[] + */ + public function getReaders() + { + return $this->readers; + } + + /** + * Get the offset by an object number. + * + * @param int $objectNumber + * @return integer|bool + */ + public function getOffsetFor($objectNumber) + { + foreach ($this->getReaders() as $reader) { + $offset = $reader->getOffsetFor($objectNumber); + if ($offset !== false) { + return $offset; + } + } + + return false; + } + + /** + * Get an indirect object by its object number. + * + * @param int $objectNumber + * @return PdfIndirectObject + * @throws CrossReferenceException + */ + public function getIndirectObject($objectNumber) + { + $offset = $this->getOffsetFor($objectNumber); + if ($offset === false) { + throw new CrossReferenceException( + \sprintf('Object (id:%s) not found.', $objectNumber), + CrossReferenceException::OBJECT_NOT_FOUND + ); + } + + $parser = $this->parser; + + $parser->getTokenizer()->clearStack(); + $parser->getStreamReader()->reset($offset + $this->fileHeaderOffset); + + try { + /** @var PdfIndirectObject $object */ + $object = $parser->readValue(null, PdfIndirectObject::class); + } catch (PdfTypeException $e) { + throw new CrossReferenceException( + \sprintf('Object (id:%s) not found at location (%s).', $objectNumber, $offset), + CrossReferenceException::OBJECT_NOT_FOUND, + $e + ); + } + + if ($object->objectNumber !== $objectNumber) { + throw new CrossReferenceException( + \sprintf('Wrong object found, got %s while %s was expected.', $object->objectNumber, $objectNumber), + CrossReferenceException::OBJECT_NOT_FOUND + ); + } + + return $object; + } + + /** + * Read the cross-reference table at a given offset. + * + * Internally the method will try to evaluate the best reader for this cross-reference. + * + * @param int $offset + * @return ReaderInterface + * @throws CrossReferenceException + * @throws PdfTypeException + */ + protected function readXref($offset) + { + $this->parser->getStreamReader()->reset($offset); + $this->parser->getTokenizer()->clearStack(); + $initValue = $this->parser->readValue(); + + return $this->initReaderInstance($initValue); + } + + /** + * Get a cross-reference reader instance. + * + * @param PdfToken|PdfIndirectObject $initValue + * @return ReaderInterface|bool + * @throws CrossReferenceException + * @throws PdfTypeException + */ + protected function initReaderInstance($initValue) + { + $position = $this->parser->getStreamReader()->getPosition() + + $this->parser->getStreamReader()->getOffset() + $this->fileHeaderOffset; + + if ($initValue instanceof PdfToken && $initValue->value === 'xref') { + try { + return new FixedReader($this->parser); + } catch (CrossReferenceException $e) { + $this->parser->getStreamReader()->reset($position); + $this->parser->getTokenizer()->clearStack(); + + return new LineReader($this->parser); + } + } + + if ($initValue instanceof PdfIndirectObject) { + // check for encryption + $stream = PdfStream::ensure($initValue->value); + + $type = PdfDictionary::get($stream->value, 'Type'); + if ($type->value !== 'XRef') { + throw new CrossReferenceException( + 'The xref position points to an incorrect object type.', + CrossReferenceException::INVALID_DATA + ); + } + + $this->checkForEncryption($stream->value); + + throw new CrossReferenceException( + 'This PDF document probably uses a compression technique which is not supported by the ' . + 'free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)', + CrossReferenceException::COMPRESSED_XREF + ); + } + + throw new CrossReferenceException( + 'The xref position points to an incorrect object type.', + CrossReferenceException::INVALID_DATA + ); + } + + /** + * Check for encryption. + * + * @param PdfDictionary $dictionary + * @throws CrossReferenceException + */ + protected function checkForEncryption(PdfDictionary $dictionary) + { + if (isset($dictionary->value['Encrypt'])) { + throw new CrossReferenceException( + 'This PDF document is encrypted and cannot be processed with FPDI.', + CrossReferenceException::ENCRYPTED + ); + } + } + + /** + * Find the start position for the first cross-reference. + * + * @return int The byte-offset position of the first cross-reference. + * @throws CrossReferenceException + */ + protected function findStartXref() + { + $reader = $this->parser->getStreamReader(); + $reader->reset(-self::$trailerSearchLength, self::$trailerSearchLength); + + $buffer = $reader->getBuffer(false); + $pos = \strrpos($buffer, 'startxref'); + $addOffset = 9; + if ($pos === false) { + // Some corrupted documents uses startref, instead of startxref + $pos = \strrpos($buffer, 'startref'); + if ($pos === false) { + throw new CrossReferenceException( + 'Unable to find pointer to xref table', + CrossReferenceException::NO_STARTXREF_FOUND + ); + } + $addOffset = 8; + } + + $reader->setOffset($pos + $addOffset); + + try { + $value = $this->parser->readValue(null, PdfNumeric::class); + } catch (PdfTypeException $e) { + throw new CrossReferenceException( + 'Invalid data after startxref keyword.', + CrossReferenceException::INVALID_DATA, + $e + ); + } + + return $value->value; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReferenceException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReferenceException.php new file mode 100644 index 0000000..3fa9b33 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/CrossReferenceException.php @@ -0,0 +1,80 @@ +reader = $parser->getStreamReader(); + $this->read(); + parent::__construct($parser); + } + + /** + * Get all subsection data. + * + * @return array + */ + public function getSubSections() + { + return $this->subSections; + } + + /** + * @inheritdoc + */ + public function getOffsetFor($objectNumber) + { + foreach ($this->subSections as $offset => list($startObject, $objectCount)) { + if ($objectNumber >= $startObject && $objectNumber < ($startObject + $objectCount)) { + $position = $offset + 20 * ($objectNumber - $startObject); + $this->reader->ensure($position, 20); + $line = $this->reader->readBytes(20); + if ($line[17] === 'f') { + return false; + } + + return (int) \substr($line, 0, 10); + } + } + + return false; + } + + /** + * Read the cross-reference. + * + * This reader will only read the subsections in this method. The offsets were resolved individually by this + * information. + * + * @throws CrossReferenceException + */ + protected function read() + { + $subSections = []; + + $startObject = $entryCount = $lastLineStart = null; + $validityChecked = false; + while (($line = $this->reader->readLine(20)) !== false) { + if (\strpos($line, 'trailer') !== false) { + $this->reader->reset($lastLineStart); + break; + } + + // jump over if line content doesn't match the expected string + if (\sscanf($line, '%d %d', $startObject, $entryCount) !== 2) { + continue; + } + + $oldPosition = $this->reader->getPosition(); + $position = $oldPosition + $this->reader->getOffset(); + + if (!$validityChecked && $entryCount > 0) { + $nextLine = $this->reader->readBytes(21); + /* Check the next line for maximum of 20 bytes and not longer + * By catching 21 bytes and trimming the length should be still 21. + */ + if (\strlen(\trim($nextLine)) !== 21) { + throw new CrossReferenceException( + 'Cross-reference entries are larger than 20 bytes.', + CrossReferenceException::ENTRIES_TOO_LARGE + ); + } + + /* Check for less than 20 bytes: cut the line to 20 bytes and trim; have to result in exactly 18 bytes. + * If it would have less bytes the substring would get the first bytes of the next line which would + * evaluate to a 20 bytes long string after trimming. + */ + if (\strlen(\trim(\substr($nextLine, 0, 20))) !== 18) { + throw new CrossReferenceException( + 'Cross-reference entries are less than 20 bytes.', + CrossReferenceException::ENTRIES_TOO_SHORT + ); + } + + $validityChecked = true; + } + + $subSections[$position] = [$startObject, $entryCount]; + + $lastLineStart = $position + $entryCount * 20; + $this->reader->reset($lastLineStart); + } + + // reset after the last correct parsed line + $this->reader->reset($lastLineStart); + + if (\count($subSections) === 0) { + throw new CrossReferenceException( + 'No entries found in cross-reference.', + CrossReferenceException::NO_ENTRIES + ); + } + + $this->subSections = $subSections; + } + + /** + * Fixes an invalid object number shift. + * + * This method can be used to repair documents with an invalid subsection header: + * + * + * xref + * 1 7 + * 0000000000 65535 f + * 0000000009 00000 n + * 0000412075 00000 n + * 0000412172 00000 n + * 0000412359 00000 n + * 0000412417 00000 n + * 0000412468 00000 n + * + * + * It shall only be called on the first table. + * + * @return bool + */ + public function fixFaultySubSectionShift() + { + $subSections = $this->getSubSections(); + if (\count($subSections) > 1) { + return false; + } + + $subSection = \current($subSections); + if ($subSection[0] != 1) { + return false; + } + + if ($this->getOffsetFor(1) === false) { + foreach ($subSections as $offset => list($startObject, $objectCount)) { + $this->subSections[$offset] = [$startObject - 1, $objectCount]; + } + return true; + } + + return false; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/LineReader.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/LineReader.php new file mode 100644 index 0000000..31a96be --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/LineReader.php @@ -0,0 +1,173 @@ + 20 bytes). + * + * @package setasign\Fpdi\PdfParser\CrossReference + */ +class LineReader extends AbstractReader implements ReaderInterface +{ + /** + * The object offsets. + * + * @var array + */ + protected $offsets; + + /** + * LineReader constructor. + * + * @param PdfParser $parser + * @throws CrossReferenceException + */ + public function __construct(PdfParser $parser) + { + $this->read($this->extract($parser->getStreamReader())); + parent::__construct($parser); + } + + /** + * @inheritdoc + */ + public function getOffsetFor($objectNumber) + { + if (isset($this->offsets[$objectNumber])) { + return $this->offsets[$objectNumber][0]; + } + + return false; + } + + /** + * Get all found offsets. + * + * @return array + */ + public function getOffsets() + { + return $this->offsets; + } + + /** + * Extracts the cross reference data from the stream reader. + * + * @param StreamReader $reader + * @return string + * @throws CrossReferenceException + */ + protected function extract(StreamReader $reader) + { + $cycles = -1; + $bytesPerCycle = 100; + + $reader->reset(null, $bytesPerCycle); + + while ( + ($trailerPos = \strpos($reader->getBuffer(false), 'trailer', \max($bytesPerCycle * $cycles++, 0))) === false + ) { + if ($reader->increaseLength($bytesPerCycle) === false) { + break; + } + } + + if ($trailerPos === false) { + throw new CrossReferenceException( + 'Unexpected end of cross reference. "trailer"-keyword not found.', + CrossReferenceException::NO_TRAILER_FOUND + ); + } + + $xrefContent = \substr($reader->getBuffer(false), 0, $trailerPos); + $reader->reset($reader->getPosition() + $trailerPos); + + return $xrefContent; + } + + /** + * Read the cross-reference entries. + * + * @param string $xrefContent + * @throws CrossReferenceException + */ + protected function read($xrefContent) + { + // get eol markers in the first 100 bytes + \preg_match_all("/(\r\n|\n|\r)/", \substr($xrefContent, 0, 100), $m); + + if (\count($m[0]) === 0) { + throw new CrossReferenceException( + 'No data found in cross-reference.', + CrossReferenceException::INVALID_DATA + ); + } + + // count(array_count_values()) is faster then count(array_unique()) + // @see https://github.com/symfony/symfony/pull/23731 + // can be reverted for php7.2 + $differentLineEndings = \count(\array_count_values($m[0])); + if ($differentLineEndings > 1) { + $lines = \preg_split("/(\r\n|\n|\r)/", $xrefContent, -1, PREG_SPLIT_NO_EMPTY); + } else { + $lines = \explode($m[0][0], $xrefContent); + } + + unset($differentLineEndings, $m); + $linesCount = \count($lines); + $start = null; + $entryCount = 0; + + $offsets = []; + + /** @noinspection ForeachInvariantsInspection */ + for ($i = 0; $i < $linesCount; $i++) { + $line = \trim($lines[$i]); + if ($line) { + $pieces = \explode(' ', $line); + + $c = \count($pieces); + switch ($c) { + case 2: + $start = (int) $pieces[0]; + $entryCount += (int) $pieces[1]; + break; + + /** @noinspection PhpMissingBreakStatementInspection */ + case 3: + switch ($pieces[2]) { + case 'n': + $offsets[$start] = [(int) $pieces[0], (int) $pieces[1]]; + $start++; + break 2; + case 'f': + $start++; + break 2; + } + // fall through if pieces doesn't match + + default: + throw new CrossReferenceException( + \sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)), + CrossReferenceException::INVALID_DATA + ); + } + } + } + + $this->offsets = $offsets; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/ReaderInterface.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/ReaderInterface.php new file mode 100644 index 0000000..84b2267 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/CrossReference/ReaderInterface.php @@ -0,0 +1,35 @@ + + if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) { + break; + } + if (\preg_match('/^\s$/', \chr($ch))) { + continue; + } + if ($ch === 122 /* z */ && $state === 0) { + $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0); + continue; + } + if ($ch < 33 /* ! */ || $ch > 117 /* u */) { + throw new Ascii85Exception( + 'Illegal character found while ASCII85 decode.', + Ascii85Exception::ILLEGAL_CHAR_FOUND + ); + } + + $chn[$state] = $ch - 33;/* ! */ + $state++; + + if ($state === 5) { + $state = 0; + $r = 0; + for ($j = 0; $j < 5; ++$j) { + /** @noinspection UnnecessaryCastingInspection */ + $r = (int)($r * 85 + $chn[$j]); + } + + $out .= \chr($r >> 24) + . \chr($r >> 16) + . \chr($r >> 8) + . \chr($r); + } + } + + if ($state === 1) { + throw new Ascii85Exception( + 'Illegal length while ASCII85 decode.', + Ascii85Exception::ILLEGAL_LENGTH + ); + } + + if ($state === 2) { + $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85; + $out .= \chr($r >> 24); + + } elseif ($state === 3) { + $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85; + $out .= \chr($r >> 24); + $out .= \chr($r >> 16); + + } elseif ($state === 4) { + $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85; + $out .= \chr($r >> 24); + $out .= \chr($r >> 16); + $out .= \chr($r >> 8); + } + + return $out; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Ascii85Exception.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Ascii85Exception.php new file mode 100644 index 0000000..898276c --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/Ascii85Exception.php @@ -0,0 +1,28 @@ +')); + if ((\strlen($data) % 2) === 1) { + $data .= '0'; + } + + return \pack('H*', $data); + } + + /** + * Converts a string into ASCII hexadecimal representation. + * + * @param string $data The input string + * @param boolean $leaveEOD + * @return string + */ + public function encode($data, $leaveEOD = false) + { + $t = \unpack('H*', $data); + return \current($t) + . ($leaveEOD ? '' : '>'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FilterException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FilterException.php new file mode 100644 index 0000000..a41ce69 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FilterException.php @@ -0,0 +1,24 @@ +extensionLoaded()) { + $oData = $data; + $data = @((\strlen($data) > 0) ? \gzuncompress($data) : ''); + if ($data === false) { + // Try this fallback + $tries = 1; + while ($tries < 10 && ($data === false || \strlen($data) < (\strlen($oData) - $tries - 1))) { + $data = @(\gzinflate(\substr($oData, $tries))); + $tries++; + } + + if ($data === false) { + // let's try if the checksum is CRC32 + $fh = fopen('php://temp', 'w+b'); + \fwrite($fh, "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $oData); + \stream_filter_append($fh, 'zlib.inflate', \STREAM_FILTER_READ, ['window' => 30]); + \fseek($fh, 0); + $data = \stream_get_contents($fh); + \fclose($fh); + } + + if (!$data) { + throw new FlateException( + 'Error while decompressing stream.', + FlateException::DECOMPRESS_ERROR + ); + } + } + } else { + throw new FlateException( + 'To handle FlateDecode filter, enable zlib support in PHP.', + FlateException::NO_ZLIB + ); + } + + return $data; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FlateException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FlateException.php new file mode 100644 index 0000000..d44281d --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/FlateException.php @@ -0,0 +1,28 @@ +initsTable(); + + $this->data = $data; + $this->dataLength = \strlen($data); + + // Initialize pointers + $this->bytePointer = 0; + + $this->nextData = 0; + $this->nextBits = 0; + + $oldCode = 0; + + $uncompData = ''; + + while (($code = $this->getNextCode()) !== 257) { + if ($code === 256) { + $this->initsTable(); + $code = $this->getNextCode(); + + if ($code === 257) { + break; + } + + $uncompData .= $this->sTable[$code]; + $oldCode = $code; + + } else { + if ($code < $this->tIdx) { + $string = $this->sTable[$code]; + $uncompData .= $string; + + $this->addStringToTable($this->sTable[$oldCode], $string[0]); + $oldCode = $code; + } else { + $string = $this->sTable[$oldCode]; + $string .= $string[0]; + $uncompData .= $string; + + $this->addStringToTable($string); + $oldCode = $code; + } + } + } + + return $uncompData; + } + + /** + * Initialize the string table. + */ + protected function initsTable() + { + $this->sTable = []; + + for ($i = 0; $i < 256; $i++) { + $this->sTable[$i] = \chr($i); + } + + $this->tIdx = 258; + $this->bitsToGet = 9; + } + + /** + * Add a new string to the string table. + * + * @param string $oldString + * @param string $newString + */ + protected function addStringToTable($oldString, $newString = '') + { + $string = $oldString . $newString; + + // Add this new String to the table + $this->sTable[$this->tIdx++] = $string; + + if ($this->tIdx === 511) { + $this->bitsToGet = 10; + } elseif ($this->tIdx === 1023) { + $this->bitsToGet = 11; + } elseif ($this->tIdx === 2047) { + $this->bitsToGet = 12; + } + } + + /** + * Returns the next 9, 10, 11 or 12 bits. + * + * @return integer + */ + protected function getNextCode() + { + if ($this->bytePointer === $this->dataLength) { + return 257; + } + + $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff); + $this->nextBits += 8; + + if ($this->nextBits < $this->bitsToGet) { + $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff); + $this->nextBits += 8; + } + + $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet - 9]; + $this->nextBits -= $this->bitsToGet; + + return $code; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/LzwException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/LzwException.php new file mode 100644 index 0000000..e822bc9 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Filter/LzwException.php @@ -0,0 +1,23 @@ +streamReader = $streamReader; + $this->tokenizer = new Tokenizer($streamReader); + } + + /** + * Removes cycled references. + * + * @internal + */ + public function cleanUp() + { + $this->xref = null; + } + + /** + * Get the stream reader instance. + * + * @return StreamReader + */ + public function getStreamReader() + { + return $this->streamReader; + } + + /** + * Get the tokenizer instance. + * + * @return Tokenizer + */ + public function getTokenizer() + { + return $this->tokenizer; + } + + /** + * Resolves the file header. + * + * @throws PdfParserException + * @return int + */ + protected function resolveFileHeader() + { + if ($this->fileHeader) { + return $this->fileHeaderOffset; + } + + $this->streamReader->reset(0); + $offset = false; + $maxIterations = 1000; + while (true) { + $buffer = $this->streamReader->getBuffer(false); + $offset = \strpos($buffer, '%PDF-'); + if ($offset === false) { + if (!$this->streamReader->increaseLength(100) || (--$maxIterations === 0)) { + throw new PdfParserException( + 'Unable to find PDF file header.', + PdfParserException::FILE_HEADER_NOT_FOUND + ); + } + continue; + } + break; + } + + $this->fileHeaderOffset = $offset; + $this->streamReader->setOffset($offset); + + $this->fileHeader = \trim($this->streamReader->readLine()); + return $this->fileHeaderOffset; + } + + /** + * Get the cross reference instance. + * + * @return CrossReference + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function getCrossReference() + { + if ($this->xref === null) { + $this->xref = new CrossReference($this, $this->resolveFileHeader()); + } + + return $this->xref; + } + + /** + * Get the PDF version. + * + * @return int[] An array of major and minor version. + * @throws PdfParserException + */ + public function getPdfVersion() + { + $this->resolveFileHeader(); + + if (\preg_match('/%PDF-(\d)\.(\d)/', $this->fileHeader, $result) === 0) { + throw new PdfParserException( + 'Unable to extract PDF version from file header.', + PdfParserException::PDF_VERSION_NOT_FOUND + ); + } + list(, $major, $minor) = $result; + + $catalog = $this->getCatalog(); + if (isset($catalog->value['Version'])) { + $versionParts = \explode('.', PdfName::unescape(PdfType::resolve($catalog->value['Version'], $this)->value)); + if (count($versionParts) === 2) { + list($major, $minor) = $versionParts; + } + } + + return [(int) $major, (int) $minor]; + } + + /** + * Get the catalog dictionary. + * + * @return PdfDictionary + * @throws Type\PdfTypeException + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function getCatalog() + { + $xref = $this->getCrossReference(); + $trailer = $xref->getTrailer(); + + $catalog = PdfType::resolve(PdfDictionary::get($trailer, 'Root'), $this); + + return PdfDictionary::ensure($catalog); + } + + /** + * Get an indirect object by its object number. + * + * @param int $objectNumber + * @param bool $cache + * @return PdfIndirectObject + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function getIndirectObject($objectNumber, $cache = false) + { + $objectNumber = (int) $objectNumber; + if (isset($this->objects[$objectNumber])) { + return $this->objects[$objectNumber]; + } + + $xref = $this->getCrossReference(); + $object = $xref->getIndirectObject($objectNumber); + + if ($cache) { + $this->objects[$objectNumber] = $object; + } + + return $object; + } + + /** + * Read a PDF value. + * + * @param null|bool|string $token + * @param null|string $expectedType + * @return bool|PdfArray|PdfBoolean|PdfHexString|PdfName|PdfNull|PdfNumeric|PdfString|PdfToken|PdfIndirectObjectReference + * @throws Type\PdfTypeException + */ + public function readValue($token = null, $expectedType = null) + { + if ($token === null) { + $token = $this->tokenizer->getNextToken(); + } + + if ($token === false) { + if ($expectedType !== null) { + throw new Type\PdfTypeException('Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE); + } + return false; + } + + switch ($token) { + case '(': + $this->ensureExpectedType($token, $expectedType); + return PdfString::parse($this->streamReader); + + case '<': + if ($this->streamReader->getByte() === '<') { + $this->ensureExpectedType('<<', $expectedType); + $this->streamReader->addOffset(1); + return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this); + } + + $this->ensureExpectedType($token, $expectedType); + return PdfHexString::parse($this->streamReader); + + case '/': + $this->ensureExpectedType($token, $expectedType); + return PdfName::parse($this->tokenizer, $this->streamReader); + + case '[': + $this->ensureExpectedType($token, $expectedType); + return PdfArray::parse($this->tokenizer, $this); + + default: + if (\is_numeric($token)) { + if (($token2 = $this->tokenizer->getNextToken()) !== false) { + if (\is_numeric($token2)) { + if (($token3 = $this->tokenizer->getNextToken()) !== false) { + switch ($token3) { + case 'obj': + if ($expectedType !== null && $expectedType !== PdfIndirectObject::class) { + throw new Type\PdfTypeException( + 'Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE + ); + } + + return PdfIndirectObject::parse( + $token, + $token2, + $this, + $this->tokenizer, + $this->streamReader + ); + case 'R': + if ($expectedType !== null && + $expectedType !== PdfIndirectObjectReference::class + ) { + throw new Type\PdfTypeException( + 'Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE + ); + } + + return PdfIndirectObjectReference::create($token, $token2); + } + + $this->tokenizer->pushStack($token3); + } + } + + $this->tokenizer->pushStack($token2); + } + + if ($expectedType !== null && $expectedType !== PdfNumeric::class) { + throw new Type\PdfTypeException( + 'Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE + ); + } + return PdfNumeric::create($token); + } + + if ($token === 'true' || $token === 'false') { + $this->ensureExpectedType($token, $expectedType); + return PdfBoolean::create($token === 'true'); + } + + if ($token === 'null') { + $this->ensureExpectedType($token, $expectedType); + return new PdfNull(); + } + + if ($expectedType !== null && $expectedType !== PdfToken::class) { + throw new Type\PdfTypeException( + 'Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE + ); + } + + $v = new PdfToken(); + $v->value = $token; + + return $v; + } + } + + /** + * Ensures that the token will evaluate to an expected object type (or not). + * + * @param string $token + * @param string|null $expectedType + * @return bool + * @throws Type\PdfTypeException + */ + private function ensureExpectedType($token, $expectedType) + { + static $mapping = [ + '(' => PdfString::class, + '<' => PdfHexString::class, + '<<' => PdfDictionary::class, + '/' => PdfName::class, + '[' => PdfArray::class, + 'true' => PdfBoolean::class, + 'false' => PdfBoolean::class, + 'null' => PdfNull::class + ]; + + if ($expectedType === null || $mapping[$token] === $expectedType) { + return true; + } + + throw new Type\PdfTypeException('Got unexpected token type.', Type\PdfTypeException::INVALID_DATA_TYPE); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/PdfParserException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/PdfParserException.php new file mode 100644 index 0000000..476bccd --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/PdfParserException.php @@ -0,0 +1,50 @@ +stream = $stream; + $this->closeStream = $closeStream; + $this->reset(); + } + + /** + * The destructor. + */ + public function __destruct() + { + $this->cleanUp(); + } + + /** + * Closes the file handle. + */ + public function cleanUp() + { + if ($this->closeStream && is_resource($this->stream)) { + \fclose($this->stream); + } + } + + /** + * Returns the byte length of the buffer. + * + * @param bool $atOffset + * @return int + */ + public function getBufferLength($atOffset = false) + { + if ($atOffset === false) { + return $this->bufferLength; + } + + return $this->bufferLength - $this->offset; + } + + /** + * Get the current position in the stream. + * + * @return int + */ + public function getPosition() + { + return $this->position; + } + + /** + * Returns the current buffer. + * + * @param bool $atOffset + * @return string + */ + public function getBuffer($atOffset = true) + { + if ($atOffset === false) { + return $this->buffer; + } + + $string = \substr($this->buffer, $this->offset); + + return (string) $string; + } + + /** + * Gets a byte at a specific position in the buffer. + * + * If the position is invalid the method will return false. + * + * If the $position parameter is set to null the value of $this->offset will be used. + * + * @param int|null $position + * @return string|bool + */ + public function getByte($position = null) + { + $position = (int) ($position !== null ? $position : $this->offset); + if ($position >= $this->bufferLength && + (!$this->increaseLength() || $position >= $this->bufferLength) + ) { + return false; + } + + return $this->buffer[$position]; + } + + /** + * Returns a byte at a specific position, and set the offset to the next byte position. + * + * If the position is invalid the method will return false. + * + * If the $position parameter is set to null the value of $this->offset will be used. + * + * @param int|null $position + * @return string|bool + */ + public function readByte($position = null) + { + if ($position !== null) { + $position = (int) $position; + // check if needed bytes are available in the current buffer + if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) { + $this->reset($position); + $offset = $this->offset; + } else { + $offset = $position - $this->position; + } + } else { + $offset = $this->offset; + } + + if ($offset >= $this->bufferLength && + ((!$this->increaseLength()) || $offset >= $this->bufferLength) + ) { + return false; + } + + $this->offset = $offset + 1; + return $this->buffer[$offset]; + } + + /** + * Read bytes from the current or a specific offset position and set the internal pointer to the next byte. + * + * If the position is invalid the method will return false. + * + * If the $position parameter is set to null the value of $this->offset will be used. + * + * @param int $length + * @param int|null $position + * @return string + */ + public function readBytes($length, $position = null) + { + $length = (int) $length; + if ($position !== null) { + // check if needed bytes are available in the current buffer + if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) { + $this->reset($position, $length); + $offset = $this->offset; + } else { + $offset = $position - $this->position; + } + } else { + $offset = $this->offset; + } + + if (($offset + $length) > $this->bufferLength && + ((!$this->increaseLength($length)) || ($offset + $length) > $this->bufferLength) + ) { + return false; + } + + $bytes = \substr($this->buffer, $offset, $length); + $this->offset = $offset + $length; + + return $bytes; + } + + /** + * Read a line from the current position. + * + * @param int $length + * @return string|bool + */ + public function readLine($length = 1024) + { + if ($this->ensureContent() === false) { + return false; + } + + $line = ''; + while ($this->ensureContent()) { + $char = $this->readByte(); + + if ($char === "\n") { + break; + } + + if ($char === "\r") { + if ($this->getByte() === "\n") { + $this->addOffset(1); + } + break; + } + + $line .= $char; + + if (\strlen($line) >= $length) { + break; + } + } + + return $line; + } + + /** + * Set the offset position in the current buffer. + * + * @param int $offset + */ + public function setOffset($offset) + { + if ($offset > $this->bufferLength || $offset < 0) { + throw new \OutOfRangeException( + \sprintf('Offset (%s) out of range (length: %s)', $offset, $this->bufferLength) + ); + } + + $this->offset = (int) $offset; + } + + /** + * Returns the current offset in the current buffer. + * + * @return int + */ + public function getOffset() + { + return $this->offset; + } + + /** + * Add an offset to the current offset. + * + * @param int $offset + */ + public function addOffset($offset) + { + $this->setOffset($this->offset + $offset); + } + + /** + * Make sure that there is at least one character beyond the current offset in the buffer. + * + * @return bool + */ + public function ensureContent() + { + while ($this->offset >= $this->bufferLength) { + if (!$this->increaseLength()) { + return false; + } + } + return true; + } + + /** + * Returns the stream. + * + * @return resource + */ + public function getStream() + { + return $this->stream; + } + + /** + * Gets the total available length. + * + * @return int + */ + public function getTotalLength() + { + if ($this->totalLength === null) { + $stat = \fstat($this->stream); + $this->totalLength = $stat['size']; + } + + return $this->totalLength; + } + + /** + * Resets the buffer to a position and re-read the buffer with the given length. + * + * If the $pos parameter is negative the start buffer position will be the $pos'th position from + * the end of the file. + * + * If the $pos parameter is negative and the absolute value is bigger then the totalLength of + * the file $pos will set to zero. + * + * @param int|null $pos Start position of the new buffer + * @param int $length Length of the new buffer. Mustn't be negative + */ + public function reset($pos = 0, $length = 200) + { + if ($pos === null) { + $pos = $this->position + $this->offset; + } elseif ($pos < 0) { + $pos = \max(0, $this->getTotalLength() + $pos); + } + + \fseek($this->stream, $pos); + + $this->position = $pos; + $this->buffer = $length > 0 ? \fread($this->stream, $length) : ''; + $this->bufferLength = \strlen($this->buffer); + $this->offset = 0; + + // If a stream wrapper is in use it is possible that + // length values > 8096 will be ignored, so use the + // increaseLength()-method to correct that behavior + if ($this->bufferLength < $length && $this->increaseLength($length - $this->bufferLength)) { + // increaseLength parameter is $minLength, so cut to have only the required bytes in the buffer + $this->buffer = \substr($this->buffer, 0, $length); + $this->bufferLength = \strlen($this->buffer); + } + } + + /** + * Ensures bytes in the buffer with a specific length and location in the file. + * + * @param int $pos + * @param int $length + * @see reset() + */ + public function ensure($pos, $length) + { + if ($pos >= $this->position + && $pos < ($this->position + $this->bufferLength) + && ($this->position + $this->bufferLength) >= ($pos + $length) + ) { + $this->offset = $pos - $this->position; + } else { + $this->reset($pos, $length); + } + } + + /** + * Forcefully read more data into the buffer. + * + * @param int $minLength + * @return bool Returns false if the stream reaches the end + */ + public function increaseLength($minLength = 100) + { + $length = \max($minLength, 100); + + if (\feof($this->stream) || $this->getTotalLength() === $this->position + $this->bufferLength) { + return false; + } + + $newLength = $this->bufferLength + $length; + do { + $this->buffer .= \fread($this->stream, $newLength - $this->bufferLength); + $this->bufferLength = \strlen($this->buffer); + } while (($this->bufferLength !== $newLength) && !\feof($this->stream)); + + return true; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Tokenizer.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Tokenizer.php new file mode 100644 index 0000000..ebf0d0b --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Tokenizer.php @@ -0,0 +1,161 @@ +streamReader = $streamReader; + } + + /** + * Get the stream reader instance. + * + * @return StreamReader + */ + public function getStreamReader() + { + return $this->streamReader; + } + + /** + * Clear the token stack. + */ + public function clearStack() + { + $this->stack = []; + } + + /** + * Push a token onto the stack. + * + * @param string $token + */ + public function pushStack($token) + { + $this->stack[] = $token; + } + + /** + * Get next token. + * + * @return bool|string + */ + public function getNextToken() + { + $token = \array_pop($this->stack); + if ($token !== null) { + return $token; + } + + if (($byte = $this->streamReader->readByte()) === false) { + return false; + } + + if ($byte === "\x20" || + $byte === "\x0A" || + $byte === "\x0D" || + $byte === "\x0C" || + $byte === "\x09" || + $byte === "\x00" + ) { + if ($this->leapWhiteSpaces() === false) { + return false; + } + $byte = $this->streamReader->readByte(); + } + + switch ($byte) { + case '/': + case '[': + case ']': + case '(': + case ')': + case '{': + case '}': + case '<': + case '>': + return $byte; + case '%': + $this->streamReader->readLine(); + return $this->getNextToken(); + } + + /* This way is faster than checking single bytes. + */ + $bufferOffset = $this->streamReader->getOffset(); + do { + $lastBuffer = $this->streamReader->getBuffer(false); + $pos = \strcspn( + $lastBuffer, + "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%", + $bufferOffset + ); + } while ( + // Break the loop if a delimiter or white space char is matched + // in the current buffer or increase the buffers length + $lastBuffer !== false && + ( + $bufferOffset + $pos === \strlen($lastBuffer) && + $this->streamReader->increaseLength() + ) + ); + + $result = \substr($lastBuffer, $bufferOffset - 1, $pos + 1); + $this->streamReader->setOffset($bufferOffset + $pos); + + return $result; + } + + /** + * Leap white spaces. + * + * @return boolean + */ + public function leapWhiteSpaces() + { + do { + if (!$this->streamReader->ensureContent()) { + return false; + } + + $buffer = $this->streamReader->getBuffer(false); + $matches = \strspn($buffer, "\x20\x0A\x0C\x0D\x09\x00", $this->streamReader->getOffset()); + if ($matches > 0) { + $this->streamReader->addOffset($matches); + } + } while ($this->streamReader->getOffset() >= $this->streamReader->getBufferLength()); + + return true; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php new file mode 100644 index 0000000..9cf449a --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfArray.php @@ -0,0 +1,85 @@ +getNextToken()) !== ']') { + if ($token === false || ($value = $parser->readValue($token)) === false) { + return false; + } + + $result[] = $value; + } + + $v = new self; + $v->value = $result; + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param PdfType[] $values + * @return self + */ + public static function create(array $values = []) + { + $v = new self; + $v->value = $values; + + return $v; + } + + /** + * Ensures that the passed array is a PdfArray instance with a (optional) specific size. + * + * @param mixed $array + * @param null|int $size + * @return self + * @throws PdfTypeException + */ + public static function ensure($array, $size = null) + { + $result = PdfType::ensureType(self::class, $array, 'Array value expected.'); + + if ($size !== null && \count($array->value) !== $size) { + throw new PdfTypeException( + \sprintf('Array with %s entries expected.', $size), + PdfTypeException::INVALID_DATA_SIZE + ); + } + + return $result; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php new file mode 100644 index 0000000..5f746b7 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfBoolean.php @@ -0,0 +1,43 @@ +value = (boolean) $value; + return $v; + } + + /** + * Ensures that the passed value is a PdfBoolean instance. + * + * @param mixed $value + * @return self + * @throws PdfTypeException + */ + public static function ensure($value) + { + return PdfType::ensureType(self::class, $value, 'Boolean value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php new file mode 100644 index 0000000..46b669d --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfDictionary.php @@ -0,0 +1,135 @@ +getNextToken(); + if ($token === '>' && $streamReader->getByte() === '>') { + $streamReader->addOffset(1); + break; + } + + $key = $parser->readValue($token); + if ($key === false) { + return false; + } + + // ensure the first value to be a Name object + if (!($key instanceof PdfName)) { + $lastToken = null; + // ignore all other entries and search for the closing brackets + while (($token = $tokenizer->getNextToken()) !== '>' && $token !== false && $lastToken !== '>') { + $lastToken = $token; + } + + if ($token === false) { + return false; + } + + break; + } + + + $value = $parser->readValue(); + if ($value === false) { + return false; + } + + if ($value instanceof PdfNull) { + continue; + } + + // catch missing value + if ($value instanceof PdfToken && $value->value === '>' && $streamReader->getByte() === '>') { + $streamReader->addOffset(1); + break; + } + + $entries[$key->value] = $value; + } + + $v = new self; + $v->value = $entries; + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param PdfType[] $entries The keys are the name entries of the dictionary. + * @return self + */ + public static function create(array $entries = []) + { + $v = new self; + $v->value = $entries; + + return $v; + } + + /** + * Get a value by its key from a dictionary or a default value. + * + * @param mixed $dictionary + * @param string $key + * @param PdfType|mixed|null $default + * @return PdfNull|PdfType + * @throws PdfTypeException + */ + public static function get($dictionary, $key, PdfType $default = null) + { + $dictionary = self::ensure($dictionary); + + if (isset($dictionary->value[$key])) { + return $dictionary->value[$key]; + } + + return $default === null + ? new PdfNull() + : $default; + } + + /** + * Ensures that the passed value is a PdfDictionary instance. + * + * @param mixed $dictionary + * @return self + * @throws PdfTypeException + */ + public static function ensure($dictionary) + { + return PdfType::ensureType(self::class, $dictionary, 'Dictionary value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php new file mode 100644 index 0000000..793fa43 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfHexString.php @@ -0,0 +1,82 @@ +getOffset(); + + /** + * @var string $buffer + * @var int $pos + */ + while (true) { + $buffer = $streamReader->getBuffer(false); + $pos = \strpos($buffer, '>', $bufferOffset); + if ($pos === false) { + if (!$streamReader->increaseLength()) { + return false; + } + continue; + } + + break; + } + + $result = \substr($buffer, $bufferOffset, $pos - $bufferOffset); + $streamReader->setOffset($pos + 1); + + $v = new self; + $v->value = $result; + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param string $string The hex encoded string. + * @return self + */ + public static function create($string) + { + $v = new self; + $v->value = $string; + + return $v; + } + + /** + * Ensures that the passed value is a PdfHexString instance. + * + * @param mixed $hexString + * @return self + * @throws PdfTypeException + */ + public static function ensure($hexString) + { + return PdfType::ensureType(self::class, $hexString, 'Hex string value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php new file mode 100644 index 0000000..a5bd2ac --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObject.php @@ -0,0 +1,104 @@ +readValue(); + if ($value === false) { + return false; + } + + $nextToken = $tokenizer->getNextToken(); + if ($nextToken === 'stream') { + $value = PdfStream::parse($value, $reader, $parser); + } elseif ($nextToken !== false) { + $tokenizer->pushStack($nextToken); + } + + $v = new self; + $v->objectNumber = (int) $objectNumberToken; + $v->generationNumber = (int) $objectGenerationNumberToken; + $v->value = $value; + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param int $objectNumber + * @param int $generationNumber + * @param PdfType $value + * @return self + */ + public static function create($objectNumber, $generationNumber, PdfType $value) + { + $v = new self; + $v->objectNumber = (int) $objectNumber; + $v->generationNumber = (int) $generationNumber; + $v->value = $value; + + return $v; + } + + /** + * Ensures that the passed value is a PdfIndirectObject instance. + * + * @param mixed $indirectObject + * @return self + * @throws PdfTypeException + */ + public static function ensure($indirectObject) + { + return PdfType::ensureType(self::class, $indirectObject, 'Indirect object expected.'); + } + + /** + * The object number. + * + * @var int + */ + public $objectNumber; + + /** + * The generation number. + * + * @var int + */ + public $generationNumber; +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php new file mode 100644 index 0000000..c6a67a0 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfIndirectObjectReference.php @@ -0,0 +1,53 @@ +value = (int) $objectNumber; + $v->generationNumber = (int) $generationNumber; + + return $v; + } + + /** + * Ensures that the passed value is a PdfIndirectObject instance. + * + * @param mixed $value + * @return self + * @throws PdfTypeException + */ + public static function ensure($value) + { + return PdfType::ensureType(self::class, $value, 'Indirect reference value expected.'); + } + + /** + * The generation number. + * + * @var int + */ + public $generationNumber; +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php new file mode 100644 index 0000000..6be7d0e --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfName.php @@ -0,0 +1,82 @@ +getByte(), "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%") === 0) { + $v->value = (string) $tokenizer->getNextToken(); + return $v; + } + + $v->value = ''; + return $v; + } + + /** + * Unescapes a name string. + * + * @param string $value + * @return string + */ + static public function unescape($value) + { + if (strpos($value, '#') === false) + return $value; + + return preg_replace_callback('/#[a-fA-F\d]{2}/', function($matches) { + return chr(hexdec($matches[0])); + }, $value); + } + + /** + * Helper method to create an instance. + * + * @param string $string + * @return self + */ + public static function create($string) + { + $v = new self; + $v->value = $string; + + return $v; + } + + /** + * Ensures that the passed value is a PdfName instance. + * + * @param mixed $name + * @return self + * @throws PdfTypeException + */ + public static function ensure($name) + { + return PdfType::ensureType(self::class, $name, 'Name value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php new file mode 100644 index 0000000..3dbe37c --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfNull.php @@ -0,0 +1,20 @@ +value = $value + 0; + + return $v; + } + + /** + * Ensures that the passed value is a PdfNumeric instance. + * + * @param mixed $value + * @return self + * @throws PdfTypeException + */ + public static function ensure($value) + { + return PdfType::ensureType(self::class, $value, 'Numeric value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php new file mode 100644 index 0000000..4b9300b --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfStream.php @@ -0,0 +1,320 @@ +value = $dictionary; + $v->reader = $reader; + $v->parser = $parser; + + $offset = $reader->getOffset(); + + // Find the first "newline" + while (($firstByte = $reader->getByte($offset)) !== false) { + if ($firstByte !== "\n" && $firstByte !== "\r") { + $offset++; + } else { + break; + } + } + + if (false === $firstByte) { + throw new PdfTypeException( + 'Unable to parse stream data. No newline after the stream keyword found.', + PdfTypeException::NO_NEWLINE_AFTER_STREAM_KEYWORD + ); + } + + $sndByte = $reader->getByte($offset + 1); + if ($firstByte === "\n" || $firstByte === "\r") { + $offset++; + } + + if ($sndByte === "\n" && $firstByte !== "\n") { + $offset++; + } + + $reader->setOffset($offset); + // let's only save the byte-offset and read the stream only when needed + $v->stream = $reader->getPosition() + $reader->getOffset(); + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param PdfDictionary $dictionary + * @param string $stream + * @return self + */ + public static function create(PdfDictionary $dictionary, $stream) + { + $v = new self; + $v->value = $dictionary; + $v->stream = (string) $stream; + + return $v; + } + + /** + * Ensures that the passed value is a PdfStream instance. + * + * @param mixed $stream + * @return self + * @throws PdfTypeException + */ + public static function ensure($stream) + { + return PdfType::ensureType(self::class, $stream, 'Stream value expected.'); + } + + /** + * The stream or its byte-offset position. + * + * @var int|string + */ + protected $stream; + + /** + * The stream reader instance. + * + * @var StreamReader + */ + protected $reader; + + /** + * The PDF parser instance. + * + * @var PdfParser + */ + protected $parser; + + /** + * Get the stream data. + * + * @param bool $cache Whether cache the stream data or not. + * @return bool|string + * @throws PdfTypeException + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function getStream($cache = false) + { + if (\is_int($this->stream)) { + $length = PdfDictionary::get($this->value, 'Length'); + if ($this->parser !== null) { + $length = PdfType::resolve($length, $this->parser); + } + + if (!($length instanceof PdfNumeric) || $length->value === 0) { + $this->reader->reset($this->stream, 100000); + $buffer = $this->extractStream(); + } else { + $this->reader->reset($this->stream, $length->value); + $buffer = $this->reader->getBuffer(false); + if ($this->parser !== null) { + $this->reader->reset($this->stream + strlen($buffer)); + $this->parser->getTokenizer()->clearStack(); + $token = $this->parser->readValue(); + if ($token === false || !($token instanceof PdfToken) || $token->value !== 'endstream') { + $this->reader->reset($this->stream, 100000); + $buffer = $this->extractStream(); + $this->reader->reset($this->stream + strlen($buffer)); + } + } + } + + if ($cache === false) { + return $buffer; + } + + $this->stream = $buffer; + $this->reader = null; + } + + return $this->stream; + } + + /** + * Extract the stream "manually". + * + * @return string + * @throws PdfTypeException + */ + protected function extractStream() + { + while (true) { + $buffer = $this->reader->getBuffer(false); + $length = \strpos($buffer, 'endstream'); + if ($length === false) { + if (!$this->reader->increaseLength(100000)) { + throw new PdfTypeException('Cannot extract stream.'); + } + continue; + } + break; + } + + $buffer = \substr($buffer, 0, $length); + $lastByte = \substr($buffer, -1); + + /* Check for EOL marker = + * CARRIAGE RETURN (\r) and a LINE FEED (\n) or just a LINE FEED (\n}, + * and not by a CARRIAGE RETURN (\r) alone + */ + if ($lastByte === "\n") { + $buffer = \substr($buffer, 0, -1); + + $lastByte = \substr($buffer, -1); + if ($lastByte === "\r") { + $buffer = \substr($buffer, 0, -1); + } + } + + return $buffer; + } + + /** + * Get the unfiltered stream data. + * + * @return string + * @throws FilterException + * @throws PdfParserException + */ + public function getUnfilteredStream() + { + $stream = $this->getStream(); + $filters = PdfDictionary::get($this->value, 'Filter'); + if ($filters instanceof PdfNull) { + return $stream; + } + + if ($filters instanceof PdfArray) { + $filters = $filters->value; + } else { + $filters = [$filters]; + } + + $decodeParams = PdfDictionary::get($this->value, 'DecodeParms'); + if ($decodeParams instanceof PdfArray) { + $decodeParams = $decodeParams->value; + } else { + $decodeParams = [$decodeParams]; + } + + foreach ($filters as $key => $filter) { + if (!($filter instanceof PdfName)) { + continue; + } + + $decodeParam = null; + if (isset($decodeParams[$key])) { + $decodeParam = ($decodeParams[$key] instanceof PdfDictionary ? $decodeParams[$key] : null); + } + + switch ($filter->value) { + case 'FlateDecode': + case 'Fl': + case 'LZWDecode': + case 'LZW': + if (\strpos($filter->value, 'LZW') === 0) { + $filterObject = new Lzw(); + } else { + $filterObject = new Flate(); + } + + $stream = $filterObject->decode($stream); + + if ($decodeParam instanceof PdfDictionary) { + $predictor = PdfDictionary::get($decodeParam, 'Predictor', PdfNumeric::create(1)); + if ($predictor->value !== 1) { + if (!\class_exists(Predictor::class)) { + throw new PdfParserException( + 'This PDF document makes use of features which are only implemented in the ' . + 'commercial "FPDI PDF-Parser" add-on (see https://www.setasign.com/fpdi-pdf-' . + 'parser).', + PdfParserException::IMPLEMENTED_IN_FPDI_PDF_PARSER + ); + } + + $colors = PdfDictionary::get($decodeParam, 'Colors', PdfNumeric::create(1)); + $bitsPerComponent = PdfDictionary::get( + $decodeParam, + 'BitsPerComponent', + PdfNumeric::create(8) + ); + + $columns = PdfDictionary::get($decodeParam, 'Columns', PdfNumeric::create(1)); + + $filterObject = new Predictor( + $predictor->value, + $colors->value, + $bitsPerComponent->value, + $columns->value + ); + + $stream = $filterObject->decode($stream); + } + } + + break; + case 'ASCII85Decode': + case 'A85': + $filterObject = new Ascii85(); + $stream = $filterObject->decode($stream); + break; + + case 'ASCIIHexDecode': + case 'AHx': + $filterObject = new AsciiHex(); + $stream = $filterObject->decode($stream); + break; + + default: + throw new FilterException( + \sprintf('Unsupported filter "%s".', $filter->value), + FilterException::UNSUPPORTED_FILTER + ); + } + } + + return $stream; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php new file mode 100644 index 0000000..f933b1a --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfString.php @@ -0,0 +1,172 @@ +getOffset(); + $openBrackets = 1; + do { + $buffer = $streamReader->getBuffer(false); + for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) { + switch ($buffer[$pos]) { + case '(': + $openBrackets++; + break; + case ')': + $openBrackets--; + break; + case '\\': + $pos++; + } + } + } while ($openBrackets !== 0 && $streamReader->increaseLength()); + + $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1); + $streamReader->setOffset($pos); + + $v = new self; + $v->value = $result; + + return $v; + } + + /** + * Helper method to create an instance. + * + * @param string $value The string needs to be escaped accordingly. + * @return self + */ + public static function create($value) + { + $v = new self; + $v->value = $value; + + return $v; + } + + /** + * Ensures that the passed value is a PdfString instance. + * + * @param mixed $string + * @return self + * @throws PdfTypeException + */ + public static function ensure($string) + { + return PdfType::ensureType(self::class, $string, 'String value expected.'); + } + + /** + * Unescapes escaped sequences in a PDF string according to the PDF specification. + * + * @param string $s + * @return string + */ + public static function unescape($s) + { + $out = ''; + /** @noinspection ForeachInvariantsInspection */ + for ($count = 0, $n = \strlen($s); $count < $n; $count++) { + if ($s[$count] !== '\\') { + $out .= $s[$count]; + } else { + // A backslash at the end of the string - ignore it + if ($count === ($n - 1)) { + break; + } + + switch ($s[++$count]) { + case ')': + case '(': + case '\\': + $out .= $s[$count]; + break; + + case 'f': + $out .= "\x0C"; + break; + + case 'b': + $out .= "\x08"; + break; + + case 't': + $out .= "\x09"; + break; + + case 'r': + $out .= "\x0D"; + break; + + case 'n': + $out .= "\x0A"; + break; + + case "\r": + if ($count !== $n - 1 && $s[$count + 1] === "\n") { + $count++; + } + break; + + case "\n": + break; + + default: + $actualChar = \ord($s[$count]); + // ascii 48 = number 0 + // ascii 57 = number 9 + if ($actualChar >= 48 && + $actualChar <= 57) { + $oct = '' . $s[$count]; + + /** @noinspection NotOptimalIfConditionsInspection */ + if ($count + 1 < $n && + \ord($s[$count + 1]) >= 48 && + \ord($s[$count + 1]) <= 57 + ) { + $count++; + $oct .= $s[$count]; + + /** @noinspection NotOptimalIfConditionsInspection */ + if ($count + 1 < $n && + \ord($s[$count + 1]) >= 48 && + \ord($s[$count + 1]) <= 57 + ) { + $oct .= $s[++$count]; + } + } + + $out .= \chr(\octdec($oct)); + } else { + // If the character is not one of those defined, the backslash is ignored + $out .= $s[$count]; + } + } + } + } + return $out; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php new file mode 100644 index 0000000..4abda09 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfToken.php @@ -0,0 +1,44 @@ +value = $token; + + return $v; + } + + /** + * Ensures that the passed value is a PdfToken instance. + * + * @param mixed $token + * @return self + * @throws PdfTypeException + */ + public static function ensure($token) + { + return PdfType::ensureType(self::class, $token, 'Token value expected.'); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php new file mode 100644 index 0000000..6ce3c8c --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfType.php @@ -0,0 +1,79 @@ +value, $parser, $stopAtIndirectObject); + } + + if ($value instanceof PdfIndirectObjectReference) { + return self::resolve($parser->getIndirectObject($value->value), $parser, $stopAtIndirectObject); + } + + return $value; + } + + /** + * Ensure that a value is an instance of a specific PDF type. + * + * @param string $type + * @param PdfType $value + * @param string $errorMessage + * @return mixed + * @throws PdfTypeException + */ + protected static function ensureType($type, $value, $errorMessage) + { + if (!($value instanceof $type)) { + throw new PdfTypeException( + $errorMessage, + PdfTypeException::INVALID_DATA_TYPE + ); + } + + return $value; + } + + /** + * The value of the PDF type. + * + * @var mixed + */ + public $value; +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php new file mode 100644 index 0000000..8327220 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfParser/Type/PdfTypeException.php @@ -0,0 +1,25 @@ +value; + $ax = PdfNumeric::ensure(PdfType::resolve($array[0], $parser))->value; + $ay = PdfNumeric::ensure(PdfType::resolve($array[1], $parser))->value; + $bx = PdfNumeric::ensure(PdfType::resolve($array[2], $parser))->value; + $by = PdfNumeric::ensure(PdfType::resolve($array[3], $parser))->value; + + return new self($ax, $ay, $bx, $by); + } + + /** + * Rectangle constructor. + * + * @param float|int $ax + * @param float|int $ay + * @param float|int $bx + * @param float|int $by + */ + public function __construct($ax, $ay, $bx, $by) + { + $this->llx = \min($ax, $bx); + $this->lly = \min($ay, $by); + $this->urx = \max($ax, $bx); + $this->ury = \max($ay, $by); + } + + /** + * Get the width of the rectangle. + * + * @return float|int + */ + public function getWidth() + { + return $this->urx - $this->llx; + } + + /** + * Get the height of the rectangle. + * + * @return float|int + */ + public function getHeight() + { + return $this->ury - $this->lly; + } + + /** + * Get the lower left abscissa. + * + * @return float|int + */ + public function getLlx() + { + return $this->llx; + } + + /** + * Get the lower left ordinate. + * + * @return float|int + */ + public function getLly() + { + return $this->lly; + } + + /** + * Get the upper right abscissa. + * + * @return float|int + */ + public function getUrx() + { + return $this->urx; + } + + /** + * Get the upper right ordinate. + * + * @return float|int + */ + public function getUry() + { + return $this->ury; + } + + /** + * Get the rectangle as an array. + * + * @return array + */ + public function toArray() + { + return [ + $this->llx, + $this->lly, + $this->urx, + $this->ury + ]; + } + + /** + * Get the rectangle as a PdfArray. + * + * @return PdfArray + */ + public function toPdfArray() + { + $array = new PdfArray(); + $array->value[] = PdfNumeric::create($this->llx); + $array->value[] = PdfNumeric::create($this->lly); + $array->value[] = PdfNumeric::create($this->urx); + $array->value[] = PdfNumeric::create($this->ury); + + return $array; + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/Page.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/Page.php new file mode 100644 index 0000000..0c2fb56 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/Page.php @@ -0,0 +1,272 @@ +pageObject = $page; + $this->parser = $parser; + } + + /** + * Get the indirect object of this page. + * + * @return PdfIndirectObject + */ + public function getPageObject() + { + return $this->pageObject; + } + + /** + * Get the dictionary of this page. + * + * @return PdfDictionary + * @throws PdfParserException + * @throws PdfTypeException + * @throws CrossReferenceException + */ + public function getPageDictionary() + { + if (null === $this->pageDictionary) { + $this->pageDictionary = PdfDictionary::ensure(PdfType::resolve($this->getPageObject(), $this->parser)); + } + + return $this->pageDictionary; + } + + /** + * Get a page attribute. + * + * @param string $name + * @param bool $inherited + * @return PdfType|null + * @throws PdfParserException + * @throws PdfTypeException + * @throws CrossReferenceException + */ + public function getAttribute($name, $inherited = true) + { + $dict = $this->getPageDictionary(); + + if (isset($dict->value[$name])) { + return $dict->value[$name]; + } + + $inheritedKeys = ['Resources', 'MediaBox', 'CropBox', 'Rotate']; + if ($inherited && \in_array($name, $inheritedKeys, true)) { + if ($this->inheritedAttributes === null) { + $this->inheritedAttributes = []; + $inheritedKeys = \array_filter($inheritedKeys, function ($key) use ($dict) { + return !isset($dict->value[$key]); + }); + + if (\count($inheritedKeys) > 0) { + $parentDict = PdfType::resolve(PdfDictionary::get($dict, 'Parent'), $this->parser); + while ($parentDict instanceof PdfDictionary) { + foreach ($inheritedKeys as $index => $key) { + if (isset($parentDict->value[$key])) { + $this->inheritedAttributes[$key] = $parentDict->value[$key]; + unset($inheritedKeys[$index]); + } + } + + /** @noinspection NotOptimalIfConditionsInspection */ + if (isset($parentDict->value['Parent']) && \count($inheritedKeys) > 0) { + $parentDict = PdfType::resolve(PdfDictionary::get($parentDict, 'Parent'), $this->parser); + } else { + break; + } + } + } + } + + if (isset($this->inheritedAttributes[$name])) { + return $this->inheritedAttributes[$name]; + } + } + + return null; + } + + /** + * Get the rotation value. + * + * @return int + * @throws PdfParserException + * @throws PdfTypeException + * @throws CrossReferenceException + */ + public function getRotation() + { + $rotation = $this->getAttribute('Rotate'); + if (null === $rotation) { + return 0; + } + + $rotation = PdfNumeric::ensure(PdfType::resolve($rotation, $this->parser))->value % 360; + + if ($rotation < 0) { + $rotation += 360; + } + + return $rotation; + } + + /** + * Get a boundary of this page. + * + * @param string $box + * @param bool $fallback + * @return bool|Rectangle + * @throws PdfParserException + * @throws PdfTypeException + * @throws CrossReferenceException + * @see PageBoundaries + */ + public function getBoundary($box = PageBoundaries::CROP_BOX, $fallback = true) + { + $value = $this->getAttribute($box); + + if ($value !== null) { + return Rectangle::byPdfArray($value, $this->parser); + } + + if ($fallback === false) { + return false; + } + + switch ($box) { + case PageBoundaries::BLEED_BOX: + case PageBoundaries::TRIM_BOX: + case PageBoundaries::ART_BOX: + return $this->getBoundary(PageBoundaries::CROP_BOX, true); + case PageBoundaries::CROP_BOX: + return $this->getBoundary(PageBoundaries::MEDIA_BOX, true); + } + + return false; + } + + /** + * Get the width and height of this page. + * + * @param string $box + * @param bool $fallback + * @return array|bool + * @throws PdfParserException + * @throws PdfTypeException + * @throws CrossReferenceException + */ + public function getWidthAndHeight($box = PageBoundaries::CROP_BOX, $fallback = true) + { + $boundary = $this->getBoundary($box, $fallback); + if ($boundary === false) { + return false; + } + + $rotation = $this->getRotation(); + $interchange = ($rotation / 90) % 2; + + return [ + $interchange ? $boundary->getHeight() : $boundary->getWidth(), + $interchange ? $boundary->getWidth() : $boundary->getHeight() + ]; + } + + /** + * Get the raw content stream. + * + * @return string + * @throws PdfReaderException + * @throws PdfTypeException + * @throws FilterException + * @throws PdfParserException + */ + public function getContentStream() + { + $dict = $this->getPageDictionary(); + $contents = PdfType::resolve(PdfDictionary::get($dict, 'Contents'), $this->parser); + if ($contents instanceof PdfNull) { + return ''; + } + + if ($contents instanceof PdfArray) { + $result = []; + foreach ($contents->value as $content) { + $content = PdfType::resolve($content, $this->parser); + if (!($content instanceof PdfStream)) { + continue; + } + $result[] = $content->getUnfilteredStream(); + } + + return \implode("\n", $result); + } + + if ($contents instanceof PdfStream) { + return $contents->getUnfilteredStream(); + } + + throw new PdfReaderException( + 'Array or stream expected.', + PdfReaderException::UNEXPECTED_DATA_TYPE + ); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PageBoundaries.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PageBoundaries.php new file mode 100644 index 0000000..aaeaf91 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PageBoundaries.php @@ -0,0 +1,95 @@ +parser = $parser; + } + + /** + * PdfReader destructor. + */ + public function __destruct() + { + if ($this->parser !== null) { + /** @noinspection PhpInternalEntityUsedInspection */ + $this->parser->cleanUp(); + } + } + + /** + * Get the pdf parser instance. + * + * @return PdfParser + */ + public function getParser() + { + return $this->parser; + } + + /** + * Get the PDF version. + * + * @return string + * @throws PdfParserException + */ + public function getPdfVersion() + { + return \implode('.', $this->parser->getPdfVersion()); + } + + /** + * Get the page count. + * + * @return int + * @throws PdfTypeException + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function getPageCount() + { + if ($this->pageCount === null) { + $catalog = $this->parser->getCatalog(); + + $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser); + $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser); + + $this->pageCount = PdfNumeric::ensure($count)->value; + } + + return $this->pageCount; + } + + /** + * Get a page instance. + * + * @param int $pageNumber + * @return Page + * @throws PdfTypeException + * @throws CrossReferenceException + * @throws PdfParserException + * @throws \InvalidArgumentException + */ + public function getPage($pageNumber) + { + if (!\is_numeric($pageNumber)) { + throw new \InvalidArgumentException( + 'Page number needs to be a number.' + ); + } + + if ($pageNumber < 1 || $pageNumber > $this->getPageCount()) { + throw new \InvalidArgumentException( + \sprintf( + 'Page number "%s" out of available page range (1 - %s)', + $pageNumber, + $this->getPageCount() + ) + ); + } + + $this->readPages(); + + $page = $this->pages[$pageNumber - 1]; + + if ($page instanceof PdfIndirectObjectReference) { + $readPages = function ($kids) use (&$readPages) { + $kids = PdfArray::ensure($kids); + + /** @noinspection LoopWhichDoesNotLoopInspection */ + foreach ($kids->value as $reference) { + $reference = PdfIndirectObjectReference::ensure($reference); + $object = $this->parser->getIndirectObject($reference->value); + $type = PdfDictionary::get($object->value, 'Type'); + + if ($type->value === 'Pages') { + return $readPages(PdfDictionary::get($object->value, 'Kids')); + } + + return $object; + } + + throw new PdfReaderException( + 'Kids array cannot be empty.', + PdfReaderException::KIDS_EMPTY + ); + }; + + $page = $this->parser->getIndirectObject($page->value); + $dict = PdfType::resolve($page, $this->parser); + $type = PdfDictionary::get($dict, 'Type'); + if ($type->value === 'Pages') { + $kids = PdfType::resolve(PdfDictionary::get($dict, 'Kids'), $this->parser); + $page = $this->pages[$pageNumber - 1] = $readPages($kids); + } else { + $this->pages[$pageNumber - 1] = $page; + } + } + + return new Page($page, $this->parser); + } + + /** + * Walk the page tree and resolve all indirect objects of all pages. + * + * @throws PdfTypeException + * @throws CrossReferenceException + * @throws PdfParserException + */ + protected function readPages() + { + if (\count($this->pages) > 0) { + return; + } + + $readPages = function ($kids, $count) use (&$readPages) { + $kids = PdfArray::ensure($kids); + $isLeaf = $count->value === \count($kids->value); + + foreach ($kids->value as $reference) { + $reference = PdfIndirectObjectReference::ensure($reference); + + if ($isLeaf) { + $this->pages[] = $reference; + continue; + } + + $object = $this->parser->getIndirectObject($reference->value); + $type = PdfDictionary::get($object->value, 'Type'); + + if ($type->value === 'Pages') { + $readPages(PdfDictionary::get($object->value, 'Kids'), PdfDictionary::get($object->value, 'Count')); + } else { + $this->pages[] = $object; + } + } + }; + + $catalog = $this->parser->getCatalog(); + $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser); + $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser); + $kids = PdfType::resolve(PdfDictionary::get($pages, 'Kids'), $this->parser); + $readPages($kids, $count); + } +} diff --git a/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PdfReaderException.php b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PdfReaderException.php new file mode 100644 index 0000000..c1159ba --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/PdfReader/PdfReaderException.php @@ -0,0 +1,35 @@ +cleanUp(); + } + + /** + * Get the next template id. + * + * @return int + */ + protected function getNextTemplateId() + { + return $this->templateId++; + } + + /** + * Draws an imported page onto the page or another template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size + * @see FpdiTrait::getTemplateSize() + */ + public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + return $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize); + } + + /** + * Draws an imported page onto the page. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $pageId The page id + * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size. + * @see Fpdi::getTemplateSize() + */ + public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + $size = $this->fpdiUseImportedPage($pageId, $x, $y, $width, $height, $adjustPageSize); + if ($this->inxobj) { + $importedPage = $this->importedPages[$pageId]; + $this->xobjects[$this->xobjid]['importedPages'][$importedPage['id']] = $pageId; + } + + return $size; + } + + /** + * Get the size of an imported page. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P) + */ + public function getTemplateSize($tpl, $width = null, $height = null) + { + return $this->getImportedPageSize($tpl, $width, $height); + } + + /** + * @inheritdoc + */ + protected function _getxobjectdict() + { + $out = parent::_getxobjectdict(); + + foreach ($this->importedPages as $key => $pageData) { + $out .= '/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R '; + } + + return $out; + } + + /** + * @inheritdoc + * @throws CrossReferenceException + * @throws PdfParserException + */ + protected function _putxobjects() + { + foreach ($this->importedPages as $key => $pageData) { + $this->currentObjectNumber = $this->_newobj(); + $this->importedPages[$key]['objectNumber'] = $this->currentObjectNumber; + $this->currentReaderId = $pageData['readerId']; + $this->writePdfType($pageData['stream']); + $this->_put('endobj'); + } + + foreach (\array_keys($this->readers) as $readerId) { + $parser = $this->getPdfReader($readerId)->getParser(); + $this->currentReaderId = $readerId; + + while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) { + try { + $object = $parser->getIndirectObject($objectNumber); + + } catch (CrossReferenceException $e) { + if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) { + $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull()); + } else { + throw $e; + } + } + + $this->writePdfType($object); + } + } + + // let's prepare resources for imported pages in templates + foreach ($this->xobjects as $xObjectId => $data) { + if (!isset($data['importedPages'])) { + continue; + } + + foreach ($data['importedPages'] as $id => $pageKey) { + $page = $this->importedPages[$pageKey]; + $this->xobjects[$xObjectId]['xobjects'][$id] = ['n' => $page['objectNumber']]; + } + } + + + parent::_putxobjects(); + $this->currentObjectNumber = null; + } + + /** + * Append content to the buffer of TCPDF. + * + * @param string $s + * @param bool $newLine + */ + protected function _put($s, $newLine = true) + { + if ($newLine) { + $this->setBuffer($s . "\n"); + } else { + $this->setBuffer($s); + } + } + + /** + * Begin a new object and return the object number. + * + * @param int|string $objid Object ID (leave empty to get a new ID). + * @return int object number + */ + protected function _newobj($objid = '') + { + $this->_out($this->_getobj($objid)); + return $this->n; + } + + /** + * Writes a PdfType object to the resulting buffer. + * + * @param PdfType $value + * @throws PdfTypeException + */ + protected function writePdfType(PdfType $value) + { + if (!$this->encrypted) { + $this->fpdiWritePdfType($value); + return; + } + + if ($value instanceof PdfString) { + $string = PdfString::unescape($value->value); + $string = $this->_encrypt_data($this->currentObjectNumber, $string); + $value->value = \TCPDF_STATIC::_escape($string); + + } elseif ($value instanceof PdfHexString) { + $filter = new AsciiHex(); + $string = $filter->decode($value->value); + $string = $this->_encrypt_data($this->currentObjectNumber, $string); + $value->value = $filter->encode($string, true); + + } elseif ($value instanceof PdfStream) { + $stream = $value->getStream(); + $stream = $this->_encrypt_data($this->currentObjectNumber, $stream); + $dictionary = $value->value; + $dictionary->value['Length'] = PdfNumeric::create(\strlen($stream)); + $value = PdfStream::create($dictionary, $stream); + + } elseif ($value instanceof PdfIndirectObject) { + /** + * @var $value PdfIndirectObject + */ + $this->currentObjectNumber = $this->objectMap[$this->currentReaderId][$value->objectNumber]; + } + + $this->fpdiWritePdfType($value); + } +} \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/src/TcpdfFpdi.php b/lib/MPDF/vendor/setasign/fpdi/src/TcpdfFpdi.php new file mode 100644 index 0000000..6b617a1 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/TcpdfFpdi.php @@ -0,0 +1,23 @@ +_protectedPutimages(); + } + + /** + * Make the method public as in tFPDF. + */ + public function _putxobjectdict() + { + $this->_protectedPutxobjectdict(); + } + + /** + * Set the page format of the current page. + * + * @param array $size An array with two values defining the size. + * @param string $orientation "L" for landscape, "P" for portrait. + * @throws \BadMethodCallException + */ + public function setPageFormat($size, $orientation) + { + if ($this->currentTemplateId !== null) { + throw new \BadMethodCallException('The page format cannot be changed when writing to a template.'); + } + + if (!\in_array($orientation, ['P', 'L'], true)) { + throw new \InvalidArgumentException(\sprintf( + 'Invalid page orientation "%s"! Only "P" and "L" are allowed!', + $orientation + )); + } + + $size = $this->_getpagesize($size); + + if ($orientation != $this->CurOrientation + || $size[0] != $this->CurPageSize[0] + || $size[1] != $this->CurPageSize[1] + ) { + // New size or orientation + if ($orientation === 'P') { + $this->w = $size[0]; + $this->h = $size[1]; + } else { + $this->w = $size[1]; + $this->h = $size[0]; + } + $this->wPt = $this->w * $this->k; + $this->hPt = $this->h * $this->k; + $this->PageBreakTrigger = $this->h - $this->bMargin; + $this->CurOrientation = $orientation; + $this->CurPageSize = $size; + + $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); + } + } + + /** + * @inheritdoc + */ + protected function _put($s, $newLine = true) + { + if ($newLine) { + $this->buffer .= $s . "\n"; + } else { + $this->buffer .= $s; + } + } +} \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php b/lib/MPDF/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php new file mode 100644 index 0000000..f22625f --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/Tfpdf/Fpdi.php @@ -0,0 +1,164 @@ +cleanUp(); + } + + /** + * Draws an imported page or a template onto the page or another template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array + * with the keys "x", "y", "width", "height", "adjustPageSize". + * @param float|int $y The ordinate of upper-left corner. + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @param bool $adjustPageSize + * @return array The size + * @see Fpdi::getTemplateSize() + */ + public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false) + { + if (isset($this->importedPages[$tpl])) { + $size = $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize); + if ($this->currentTemplateId !== null) { + $this->templates[$this->currentTemplateId]['resources']['templates']['importedPages'][$tpl] = $tpl; + } + return $size; + } + + return parent::useTemplate($tpl, $x, $y, $width, $height, $adjustPageSize); + } + + /** + * Get the size of an imported page or template. + * + * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the + * aspect ratio. + * + * @param mixed $tpl The template id + * @param float|int|null $width The width. + * @param float|int|null $height The height. + * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P) + */ + public function getTemplateSize($tpl, $width = null, $height = null) + { + $size = parent::getTemplateSize($tpl, $width, $height); + if ($size === false) { + return $this->getImportedPageSize($tpl, $width, $height); + } + + return $size; + } + + /** + * @inheritdoc + * @throws CrossReferenceException + * @throws PdfParserException + */ + public function _putimages() + { + $this->currentReaderId = null; + parent::_putimages(); + + foreach ($this->importedPages as $key => $pageData) { + $this->_newobj(); + $this->importedPages[$key]['objectNumber'] = $this->n; + $this->currentReaderId = $pageData['readerId']; + $this->writePdfType($pageData['stream']); + $this->_put('endobj'); + } + + foreach (\array_keys($this->readers) as $readerId) { + $parser = $this->getPdfReader($readerId)->getParser(); + $this->currentReaderId = $readerId; + + while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) { + try { + $object = $parser->getIndirectObject($objectNumber); + + } catch (CrossReferenceException $e) { + if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) { + $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull()); + } else { + throw $e; + } + } + + $this->writePdfType($object); + } + } + + $this->currentReaderId = null; + } + + /** + * @inheritdoc + */ + public function _putxobjectdict() + { + foreach ($this->importedPages as $key => $pageData) { + $this->_put('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R'); + } + + parent::_putxobjectdict(); + } + + /** + * @inheritdoc + */ + public function _newobj($n = null) + { + // Begin a new object + if($n === null) + $n = ++$this->n; + $this->offsets[$n] = $this->_getoffset(); + $this->_put($n.' 0 obj'); + } + + /** + * @inheritdoc + */ + protected function _getoffset() + { + return strlen($this->buffer); + } +} \ No newline at end of file diff --git a/lib/MPDF/vendor/setasign/fpdi/src/autoload.php b/lib/MPDF/vendor/setasign/fpdi/src/autoload.php new file mode 100644 index 0000000..fd7d472 --- /dev/null +++ b/lib/MPDF/vendor/setasign/fpdi/src/autoload.php @@ -0,0 +1,20 @@ +

    0<$h3@tMR@l02pCq=OY=$aLugX4{M6 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�mu*A6mvJpTYFyhxQjrsGphrzurm{Dt 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%0A6L-9E!U(>}{S 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 J``3T=e*r(mX378n literal 0 HcmV?d00001 diff --git a/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf b/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9d40c325694b3bfb8cdd4c0146ad44379d5c4ade GIT binary patch literal 741536 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

QOJL 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 SeP{e@d}lP{|82#kjsF8c)GOuy literal 0 HcmV?d00001 diff --git a/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-BoldOblique.ttf b/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7e3bcc10571bd0d7444238543726835f31e8da87 GIT binary patch literal 632168 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 b4-)VB!AI+E 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%0DANk_MKO`KFRN)KFs&63&P+?shm^ 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ℑ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ℑr*na;%s#`-4=#3jMxjg4Sw0- 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 literal 0 HcmV?d00001 diff --git a/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Oblique.ttf b/lib/MPDF/vendor/mpdf/mpdf/ttfonts/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e33ab144d7a2380b8f8db2d964ad16c243edc30f GIT binary patch literal 632416 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