From 4e393913a4b1f06509da4341f0f58a41adac9117 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 13:31:45 +0200 Subject: Adding upstream version 0.12.1+ds. Signed-off-by: Daniel Baumann --- vendor/phenx/php-font-lib/.htaccess | 1 + vendor/phenx/php-font-lib/LICENSE | 456 ++ vendor/phenx/php-font-lib/README.md | 28 + vendor/phenx/php-font-lib/bower.json | 23 + vendor/phenx/php-font-lib/composer.json | 32 + vendor/phenx/php-font-lib/index.php | 1 + .../php-font-lib/maps/adobe-standard-encoding.map | 231 + vendor/phenx/php-font-lib/maps/cp1250.map | 251 + vendor/phenx/php-font-lib/maps/cp1251.map | 255 + vendor/phenx/php-font-lib/maps/cp1252.map | 251 + vendor/phenx/php-font-lib/maps/cp1253.map | 239 + vendor/phenx/php-font-lib/maps/cp1254.map | 249 + vendor/phenx/php-font-lib/maps/cp1255.map | 233 + vendor/phenx/php-font-lib/maps/cp1257.map | 244 + vendor/phenx/php-font-lib/maps/cp1258.map | 247 + vendor/phenx/php-font-lib/maps/cp874.map | 225 + vendor/phenx/php-font-lib/maps/iso-8859-1.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-11.map | 248 + vendor/phenx/php-font-lib/maps/iso-8859-15.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-16.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-2.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-4.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-5.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-7.map | 250 + vendor/phenx/php-font-lib/maps/iso-8859-9.map | 256 + vendor/phenx/php-font-lib/maps/koi8-r.map | 256 + vendor/phenx/php-font-lib/maps/koi8-u.map | 256 + .../php-font-lib/src/FontLib/AdobeFontMetrics.php | 217 + .../phenx/php-font-lib/src/FontLib/Autoloader.php | 43 + .../php-font-lib/src/FontLib/BinaryStream.php | 449 ++ vendor/phenx/php-font-lib/src/FontLib/EOT/File.php | 159 + .../phenx/php-font-lib/src/FontLib/EOT/Header.php | 113 + .../phenx/php-font-lib/src/FontLib/EncodingMap.php | 37 + .../FontLib/Exception/FontNotFoundException.php | 11 + vendor/phenx/php-font-lib/src/FontLib/Font.php | 89 + .../php-font-lib/src/FontLib/Glyph/Outline.php | 109 + .../src/FontLib/Glyph/OutlineComponent.php | 31 + .../src/FontLib/Glyph/OutlineComposite.php | 242 + .../src/FontLib/Glyph/OutlineSimple.php | 335 + vendor/phenx/php-font-lib/src/FontLib/Header.php | 37 + .../php-font-lib/src/FontLib/OpenType/File.php | 18 + .../src/FontLib/OpenType/TableDirectoryEntry.php | 18 + .../src/FontLib/Table/DirectoryEntry.php | 134 + .../phenx/php-font-lib/src/FontLib/Table/Table.php | 93 + .../php-font-lib/src/FontLib/Table/Type/cmap.php | 298 + .../php-font-lib/src/FontLib/Table/Type/glyf.php | 154 + .../php-font-lib/src/FontLib/Table/Type/head.php | 46 + .../php-font-lib/src/FontLib/Table/Type/hhea.php | 44 + .../php-font-lib/src/FontLib/Table/Type/hmtx.php | 59 + .../php-font-lib/src/FontLib/Table/Type/kern.php | 80 + .../php-font-lib/src/FontLib/Table/Type/loca.php | 80 + .../php-font-lib/src/FontLib/Table/Type/maxp.php | 42 + .../php-font-lib/src/FontLib/Table/Type/name.php | 193 + .../src/FontLib/Table/Type/nameRecord.php | 53 + .../php-font-lib/src/FontLib/Table/Type/os2.php | 47 + .../php-font-lib/src/FontLib/Table/Type/post.php | 143 + .../src/FontLib/TrueType/Collection.php | 100 + .../php-font-lib/src/FontLib/TrueType/File.php | 471 ++ .../php-font-lib/src/FontLib/TrueType/Header.php | 31 + .../src/FontLib/TrueType/TableDirectoryEntry.php | 33 + .../phenx/php-font-lib/src/FontLib/WOFF/File.php | 81 + .../phenx/php-font-lib/src/FontLib/WOFF/Header.php | 32 + .../src/FontLib/WOFF/TableDirectoryEntry.php | 34 + vendor/phenx/php-svg-lib/LICENSE | 165 + vendor/phenx/php-svg-lib/README.md | 13 + vendor/phenx/php-svg-lib/composer.json | 31 + vendor/phenx/php-svg-lib/src/Svg/CssLength.php | 135 + vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php | 29 + vendor/phenx/php-svg-lib/src/Svg/Document.php | 406 ++ vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php | 16 + vendor/phenx/php-svg-lib/src/Svg/Style.php | 541 ++ vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php | 6418 ++++++++++++++++++++ .../php-svg-lib/src/Svg/Surface/SurfaceCpdf.php | 495 ++ .../src/Svg/Surface/SurfaceInterface.php | 90 + .../php-svg-lib/src/Svg/Surface/SurfacePDFLib.php | 430 ++ .../phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php | 236 + vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php | 14 + vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php | 36 + vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php | 33 + vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php | 42 + vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php | 33 + vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php | 68 + vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php | 43 + .../php-svg-lib/src/Svg/Tag/LinearGradient.php | 83 + vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php | 576 ++ vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php | 42 + vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php | 40 + .../php-svg-lib/src/Svg/Tag/RadialGradient.php | 17 + vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php | 50 + vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php | 63 + vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php | 17 + vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php | 27 + vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php | 72 + vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php | 102 + 94 files changed, 20287 insertions(+) create mode 100644 vendor/phenx/php-font-lib/.htaccess create mode 100644 vendor/phenx/php-font-lib/LICENSE create mode 100644 vendor/phenx/php-font-lib/README.md create mode 100644 vendor/phenx/php-font-lib/bower.json create mode 100644 vendor/phenx/php-font-lib/composer.json create mode 100644 vendor/phenx/php-font-lib/index.php create mode 100644 vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1250.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1251.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1252.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1253.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1254.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1255.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1257.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1258.map create mode 100644 vendor/phenx/php-font-lib/maps/cp874.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-1.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-11.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-15.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-16.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-2.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-4.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-5.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-7.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-9.map create mode 100644 vendor/phenx/php-font-lib/maps/koi8-r.map create mode 100644 vendor/phenx/php-font-lib/maps/koi8-u.map create mode 100644 vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Autoloader.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EOT/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Font.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Table.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-svg-lib/LICENSE create mode 100644 vendor/phenx/php-svg-lib/README.md create mode 100644 vendor/phenx/php-svg-lib/composer.json create mode 100644 vendor/phenx/php-svg-lib/src/Svg/CssLength.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Document.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Style.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php (limited to 'vendor/phenx') diff --git a/vendor/phenx/php-font-lib/.htaccess b/vendor/phenx/php-font-lib/.htaccess new file mode 100644 index 0000000..d02bd68 --- /dev/null +++ b/vendor/phenx/php-font-lib/.htaccess @@ -0,0 +1 @@ +#deny from all \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/LICENSE b/vendor/phenx/php-font-lib/LICENSE new file mode 100644 index 0000000..bca992d --- /dev/null +++ b/vendor/phenx/php-font-lib/LICENSE @@ -0,0 +1,456 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/README.md b/vendor/phenx/php-font-lib/README.md new file mode 100644 index 0000000..0fa24ee --- /dev/null +++ b/vendor/phenx/php-font-lib/README.md @@ -0,0 +1,28 @@ +[![PHPUnit tests](https://github.com/dompdf/php-font-lib/actions/workflows/phpunit.yml/badge.svg)](https://github.com/dompdf/php-font-lib/actions/workflows/phpunit.yml) + +# PHP Font Lib + +This library can be used to: + * Read TrueType, OpenType (with TrueType glyphs), WOFF font files + * Extract basic info (name, style, etc) + * Extract advanced info (horizontal metrics, glyph names, glyph shapes, etc) + * Make an Adobe Font Metrics (AFM) file from a font + +You can find a demo GUI [here](http://pxd.me/php-font-lib/www/font_explorer.html). + +This project was initiated by the need to read font files in the [DOMPDF project](https://github.com/dompdf/dompdf). + +Usage Example +------------- + +``` +$font = \FontLib\Font::load('../../fontfile.ttf'); +$font->parse(); // for getFontWeight() to work this call must be done first! +echo $font->getFontName() .'
'; +echo $font->getFontSubfamily() .'
'; +echo $font->getFontSubfamilyID() .'
'; +echo $font->getFontFullName() .'
'; +echo $font->getFontVersion() .'
'; +echo $font->getFontWeight() .'
'; +echo $font->getFontPostscriptName() .'
'; +``` diff --git a/vendor/phenx/php-font-lib/bower.json b/vendor/phenx/php-font-lib/bower.json new file mode 100644 index 0000000..0a4a45b --- /dev/null +++ b/vendor/phenx/php-font-lib/bower.json @@ -0,0 +1,23 @@ +{ + "name": "php-font-lib", + "version": "0.3.1", + "license": "LGPL-3.0", + "keywords": [ + "font", + "parse", + "export", + "truetype", + "opentype", + "woff" + ], + "homepage": "https://github.com/PhenX/php-font-lib", + "_release": "0.3.1", + "_resolution": { + "type": "version", + "tag": "v0.3.1", + "commit": "d13682b7e27d14a6323c441426f3dde1cd86c751" + }, + "_source": "https://github.com/PhenX/php-font-lib.git", + "_target": "*", + "_originalSource": "https://github.com/PhenX/php-font-lib.git" +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/composer.json b/vendor/phenx/php-font-lib/composer.json new file mode 100644 index 0000000..29b0653 --- /dev/null +++ b/vendor/phenx/php-font-lib/composer.json @@ -0,0 +1,32 @@ +{ + "name": "phenx/php-font-lib", + "type": "library", + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "license": "LGPL-3.0", + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "autoload-dev": { + "psr-4": { + "FontLib\\Tests\\": "tests/FontLib" + } + }, + "config": { + "bin-dir": "bin" + }, + "require": { + "ext-mbstring": "*" + }, + "require-dev": { + "symfony/phpunit-bridge" : "^3 || ^4 || ^5" + } +} diff --git a/vendor/phenx/php-font-lib/index.php b/vendor/phenx/php-font-lib/index.php new file mode 100644 index 0000000..7ed173a --- /dev/null +++ b/vendor/phenx/php-font-lib/index.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map b/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map new file mode 100644 index 0000000..230d4a1 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map @@ -0,0 +1,231 @@ +// Adobe Standard Encoding table for ttf2pt1 +// Thomas Henlich + +=20 U+0020 SPACE +=21 U+0021 EXCLAMATION MARK +=22 U+0022 QUOTATION MARK +=23 U+0023 NUMBER SIGN +=24 U+0024 DOLLAR SIGN +=25 U+0025 PERCENT SIGN +=26 U+0026 AMPERSAND +=27 U+2019 RIGHT SINGLE QUOTATION MARK +=28 U+0028 LEFT PARENTHESIS +=29 U+0029 RIGHT PARENTHESIS +=2A U+002A ASTERISK +=2B U+002B PLUS SIGN +=2C U+002C COMMA +=2D U+002D HYPHEN-MINUS +=2E U+002E FULL STOP +=2F U+002F SOLIDUS +=30 U+0030 DIGIT ZERO +=31 U+0031 DIGIT ONE +=32 U+0032 DIGIT TWO +=33 U+0033 DIGIT THREE +=34 U+0034 DIGIT FOUR +=35 U+0035 DIGIT FIVE +=36 U+0036 DIGIT SIX +=37 U+0037 DIGIT SEVEN +=38 U+0038 DIGIT EIGHT +=39 U+0039 DIGIT NINE +=3A U+003A COLON +=3B U+003B SEMICOLON +=3C U+003C LESS-THAN SIGN +=3D U+003D EQUALS SIGN +=3E U+003E GREATER-THAN SIGN +=3F U+003F QUESTION MARK +=40 U+0040 COMMERCIAL AT +=41 U+0041 LATIN CAPITAL LETTER A +=42 U+0042 LATIN CAPITAL LETTER B +=43 U+0043 LATIN CAPITAL LETTER C +=44 U+0044 LATIN CAPITAL LETTER D +=45 U+0045 LATIN CAPITAL LETTER E +=46 U+0046 LATIN CAPITAL LETTER F +=47 U+0047 LATIN CAPITAL LETTER G +=48 U+0048 LATIN CAPITAL LETTER H +=49 U+0049 LATIN CAPITAL LETTER I +=4A U+004A LATIN CAPITAL LETTER J +=4B U+004B LATIN CAPITAL LETTER K +=4C U+004C LATIN CAPITAL LETTER L +=4D U+004D LATIN CAPITAL LETTER M +=4E U+004E LATIN CAPITAL LETTER N +=4F U+004F LATIN CAPITAL LETTER O +=50 U+0050 LATIN CAPITAL LETTER P +=51 U+0051 LATIN CAPITAL LETTER Q +=52 U+0052 LATIN CAPITAL LETTER R +=53 U+0053 LATIN CAPITAL LETTER S +=54 U+0054 LATIN CAPITAL LETTER T +=55 U+0055 LATIN CAPITAL LETTER U +=56 U+0056 LATIN CAPITAL LETTER V +=57 U+0057 LATIN CAPITAL LETTER W +=58 U+0058 LATIN CAPITAL LETTER X +=59 U+0059 LATIN CAPITAL LETTER Y +=5A U+005A LATIN CAPITAL LETTER Z +=5B U+005B LEFT SQUARE BRACKET +=5C U+005C REVERSE SOLIDUS +=5D U+005D RIGHT SQUARE BRACKET +=5E U+005E CIRCUMFLEX ACCENT +=5F U+005F LOW LINE +=60 U+2018 LEFT SINGLE QUOTATION MARK +=61 U+0061 LATIN SMALL LETTER A +=62 U+0062 LATIN SMALL LETTER B +=63 U+0063 LATIN SMALL LETTER C +=64 U+0064 LATIN SMALL LETTER D +=65 U+0065 LATIN SMALL LETTER E +=66 U+0066 LATIN SMALL LETTER F +=67 U+0067 LATIN SMALL LETTER G +=68 U+0068 LATIN SMALL LETTER H +=69 U+0069 LATIN SMALL LETTER I +=6A U+006A LATIN SMALL LETTER J +=6B U+006B LATIN SMALL LETTER K +=6C U+006C LATIN SMALL LETTER L +=6D U+006D LATIN SMALL LETTER M +=6E U+006E LATIN SMALL LETTER N +=6F U+006F LATIN SMALL LETTER O +=70 U+0070 LATIN SMALL LETTER P +=71 U+0071 LATIN SMALL LETTER Q +=72 U+0072 LATIN SMALL LETTER R +=73 U+0073 LATIN SMALL LETTER S +=74 U+0074 LATIN SMALL LETTER T +=75 U+0075 LATIN SMALL LETTER U +=76 U+0076 LATIN SMALL LETTER V +=77 U+0077 LATIN SMALL LETTER W +=78 U+0078 LATIN SMALL LETTER X +=79 U+0079 LATIN SMALL LETTER Y +=7A U+007A LATIN SMALL LETTER Z +=7B U+007B LEFT CURLY BRACKET +=7C U+007C VERTICAL LINE +=7D U+007D RIGHT CURLY BRACKET +=7E U+007E TILDE +=A1 U+00A1 INVERTED EXCLAMATION MARK +=A2 U+00A2 CENT SIGN +=A3 U+00A3 POUND SIGN +=A4 U+2044 FRACTION SLASH +=A5 U+00A5 YEN SIGN +=A6 U+0192 LATIN SMALL LETTER F WITH HOOK +=A7 U+00A7 SECTION SIGN +=A8 U+00A4 CURRENCY SIGN +=A9 U+0027 APOSTROPHE +=AA U+201C LEFT DOUBLE QUOTATION MARK +=AB U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +=AC U+2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +=AD U+203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +=AE U+FB01 LATIN SMALL LIGATURE FI +=AF U+FB02 LATIN SMALL LIGATURE FL +=B1 U+2013 EN DASH +=B2 U+2020 DAGGER +=B3 U+2021 DOUBLE DAGGER +=B4 U+00B7 MIDDLE DOT +=B6 U+00B6 PILCROW SIGN +=B7 U+2022 BULLET +=B8 U+201A SINGLE LOW-9 QUOTATION MARK +=B9 U+201E DOUBLE LOW-9 QUOTATION MARK +=BA U+201D RIGHT DOUBLE QUOTATION MARK +=BB U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +=BC U+2026 HORIZONTAL ELLIPSIS +=BD U+2030 PER MILLE SIGN +=BF U+00BF INVERTED QUESTION MARK +=C1 U+0060 GRAVE ACCENT +=C2 U+00B4 ACUTE ACCENT +=C3 U+02C6 MODIFIER LETTER CIRCUMFLEX ACCENT +=C4 U+02DC SMALL TILDE +=C5 U+00AF MACRON +=C6 U+02D8 BREVE +=C7 U+02D9 DOT ABOVE +=C8 U+00A8 DIAERESIS +=CA U+02DA RING ABOVE +=CB U+00B8 CEDILLA +=CD U+02DD DOUBLE ACUTE ACCENT +=CE U+02DB OGONEK +=CF U+02C7 CARON +=D0 U+2014 EM DASH +=E1 U+00C6 LATIN CAPITAL LETTER AE +=E3 U+00AA FEMININE ORDINAL INDICATOR +=E8 U+0141 LATIN CAPITAL LETTER L WITH STROKE +=E9 U+00D8 LATIN CAPITAL LETTER O WITH STROKE +=EA U+0152 LATIN CAPITAL LIGATURE OE +=EB U+00BA MASCULINE ORDINAL INDICATOR +=F1 U+00E6 LATIN SMALL LETTER AE +=F5 U+0131 LATIN SMALL LETTER DOTLESS I +=F8 U+0142 LATIN SMALL LETTER L WITH STROKE +=F9 U+00F8 LATIN SMALL LETTER O WITH STROKE +=FA U+0153 LATIN SMALL LIGATURE OE +=FB U+00DF LATIN SMALL LETTER SHARP S + +// unencoded characters: +=100 U+00E7 LATIN SMALL LETTER C WITH CEDILLA +=101 U+00FF LATIN SMALL LETTER Y WITH DIAERESIS +=102 U+00E3 LATIN SMALL LETTER A WITH TILDE +=103 U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +=104 U+00B3 SUPERSCRIPT THREE +=105 U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +=106 U+00FE LATIN SMALL LETTER THORN +=107 U+00E8 LATIN SMALL LETTER E WITH GRAVE +=108 U+00B2 SUPERSCRIPT TWO +=109 U+00E9 LATIN SMALL LETTER E WITH ACUTE +=10A U+00F5 LATIN SMALL LETTER O WITH TILDE +=10B U+00C1 LATIN CAPITAL LETTER A WITH ACUTE +=10C U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +=10D U+00FD LATIN SMALL LETTER Y WITH ACUTE +=10E U+00FC LATIN SMALL LETTER U WITH DIAERESIS +=10F U+00BE VULGAR FRACTION THREE QUARTERS +=110 U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +=111 U+00D0 LATIN CAPITAL LETTER ETH +=112 U+00EB LATIN SMALL LETTER E WITH DIAERESIS +=113 U+00F9 LATIN SMALL LETTER U WITH GRAVE +=114 U+2122 TRADE MARK SIGN +=115 U+00F2 LATIN SMALL LETTER O WITH GRAVE +=116 U+0161 LATIN SMALL LETTER S WITH CARON +=117 U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS +=118 U+00FA LATIN SMALL LETTER U WITH ACUTE +=119 U+00E0 LATIN SMALL LETTER A WITH GRAVE +=11A U+00F1 LATIN SMALL LETTER N WITH TILDE +=11B U+00E5 LATIN SMALL LETTER A WITH RING ABOVE +=11C U+017E LATIN SMALL LETTER Z WITH CARON +=11D U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +=11E U+00D1 LATIN CAPITAL LETTER N WITH TILDE +=11F U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +=120 U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +=121 U+00CD LATIN CAPITAL LETTER I WITH ACUTE +=122 U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA +=123 U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +=124 U+0160 LATIN CAPITAL LETTER S WITH CARON +=125 U+00CC LATIN CAPITAL LETTER I WITH GRAVE +=126 U+00E4 LATIN SMALL LETTER A WITH DIAERESIS +=127 U+00D2 LATIN CAPITAL LETTER O WITH GRAVE +=128 U+00C8 LATIN CAPITAL LETTER E WITH GRAVE +=129 U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +=12A U+00AE REGISTERED SIGN +=12B U+00D5 LATIN CAPITAL LETTER O WITH TILDE +=12C U+00BC VULGAR FRACTION ONE QUARTER +=12D U+00D9 LATIN CAPITAL LETTER U WITH GRAVE +=12E U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +=12F U+00DE LATIN CAPITAL LETTER THORN +=130 U+00F7 DIVISION SIGN +=131 U+00C3 LATIN CAPITAL LETTER A WITH TILDE +=132 U+00DA LATIN CAPITAL LETTER U WITH ACUTE +=133 U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +=134 U+00AC NOT SIGN +=135 U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +=136 U+00EF LATIN SMALL LETTER I WITH DIAERESIS +=137 U+00ED LATIN SMALL LETTER I WITH ACUTE +=138 U+00E1 LATIN SMALL LETTER A WITH ACUTE +=139 U+00B1 PLUS-MINUS SIGN +=13A U+00D7 MULTIPLICATION SIGN +=13B U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS +=13C U+2212 MINUS SIGN +=13D U+00B9 SUPERSCRIPT ONE +=13E U+00C9 LATIN CAPITAL LETTER E WITH ACUTE +=13F U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +=140 U+00A9 COPYRIGHT SIGN +=141 U+00C0 LATIN CAPITAL LETTER A WITH GRAVE +=142 U+00F6 LATIN SMALL LETTER O WITH DIAERESIS +=143 U+00F3 LATIN SMALL LETTER O WITH ACUTE +=144 U+00B0 DEGREE SIGN +=145 U+00EC LATIN SMALL LETTER I WITH GRAVE +=146 U+00B5 MICRO SIGN +=147 U+00D3 LATIN CAPITAL LETTER O WITH ACUTE +=148 U+00F0 LATIN SMALL LETTER ETH +=149 U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +=14A U+00DD LATIN CAPITAL LETTER Y WITH ACUTE +=14B U+00A6 BROKEN BAR +=14C U+00BD VULGAR FRACTION ONE HALF diff --git a/vendor/phenx/php-font-lib/maps/cp1250.map b/vendor/phenx/php-font-lib/maps/cp1250.map new file mode 100644 index 0000000..33a555e --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1250.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+015A Sacute +!8D U+0164 Tcaron +!8E U+017D Zcaron +!8F U+0179 Zacute +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+015B sacute +!9D U+0165 tcaron +!9E U+017E zcaron +!9F U+017A zacute +!A0 U+00A0 space +!A1 U+02C7 caron +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+0104 Aogonek +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+015E Scedilla +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+0105 aogonek +!BA U+015F scedilla +!BB U+00BB guillemotright +!BC U+013D Lcaron +!BD U+02DD hungarumlaut +!BE U+013E lcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/cp1251.map b/vendor/phenx/php-font-lib/maps/cp1251.map new file mode 100644 index 0000000..b5960fe --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1251.map @@ -0,0 +1,255 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0402 afii10051 +!81 U+0403 afii10052 +!82 U+201A quotesinglbase +!83 U+0453 afii10100 +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+20AC Euro +!89 U+2030 perthousand +!8A U+0409 afii10058 +!8B U+2039 guilsinglleft +!8C U+040A afii10059 +!8D U+040C afii10061 +!8E U+040B afii10060 +!8F U+040F afii10145 +!90 U+0452 afii10099 +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0459 afii10106 +!9B U+203A guilsinglright +!9C U+045A afii10107 +!9D U+045C afii10109 +!9E U+045B afii10108 +!9F U+045F afii10193 +!A0 U+00A0 space +!A1 U+040E afii10062 +!A2 U+045E afii10110 +!A3 U+0408 afii10057 +!A4 U+00A4 currency +!A5 U+0490 afii10050 +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+0401 afii10023 +!A9 U+00A9 copyright +!AA U+0404 afii10053 +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+0407 afii10056 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+0406 afii10055 +!B3 U+0456 afii10103 +!B4 U+0491 afii10098 +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0451 afii10071 +!B9 U+2116 afii61352 +!BA U+0454 afii10101 +!BB U+00BB guillemotright +!BC U+0458 afii10105 +!BD U+0405 afii10054 +!BE U+0455 afii10102 +!BF U+0457 afii10104 +!C0 U+0410 afii10017 +!C1 U+0411 afii10018 +!C2 U+0412 afii10019 +!C3 U+0413 afii10020 +!C4 U+0414 afii10021 +!C5 U+0415 afii10022 +!C6 U+0416 afii10024 +!C7 U+0417 afii10025 +!C8 U+0418 afii10026 +!C9 U+0419 afii10027 +!CA U+041A afii10028 +!CB U+041B afii10029 +!CC U+041C afii10030 +!CD U+041D afii10031 +!CE U+041E afii10032 +!CF U+041F afii10033 +!D0 U+0420 afii10034 +!D1 U+0421 afii10035 +!D2 U+0422 afii10036 +!D3 U+0423 afii10037 +!D4 U+0424 afii10038 +!D5 U+0425 afii10039 +!D6 U+0426 afii10040 +!D7 U+0427 afii10041 +!D8 U+0428 afii10042 +!D9 U+0429 afii10043 +!DA U+042A afii10044 +!DB U+042B afii10045 +!DC U+042C afii10046 +!DD U+042D afii10047 +!DE U+042E afii10048 +!DF U+042F afii10049 +!E0 U+0430 afii10065 +!E1 U+0431 afii10066 +!E2 U+0432 afii10067 +!E3 U+0433 afii10068 +!E4 U+0434 afii10069 +!E5 U+0435 afii10070 +!E6 U+0436 afii10072 +!E7 U+0437 afii10073 +!E8 U+0438 afii10074 +!E9 U+0439 afii10075 +!EA U+043A afii10076 +!EB U+043B afii10077 +!EC U+043C afii10078 +!ED U+043D afii10079 +!EE U+043E afii10080 +!EF U+043F afii10081 +!F0 U+0440 afii10082 +!F1 U+0441 afii10083 +!F2 U+0442 afii10084 +!F3 U+0443 afii10085 +!F4 U+0444 afii10086 +!F5 U+0445 afii10087 +!F6 U+0446 afii10088 +!F7 U+0447 afii10089 +!F8 U+0448 afii10090 +!F9 U+0449 afii10091 +!FA U+044A afii10092 +!FB U+044B afii10093 +!FC U+044C afii10094 +!FD U+044D afii10095 +!FE U+044E afii10096 +!FF U+044F afii10097 diff --git a/vendor/phenx/php-font-lib/maps/cp1252.map b/vendor/phenx/php-font-lib/maps/cp1252.map new file mode 100644 index 0000000..b79015c --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1252.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!8E U+017D Zcaron +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9E U+017E zcaron +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp1253.map b/vendor/phenx/php-font-lib/maps/cp1253.map new file mode 100644 index 0000000..b5d843c --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1253.map @@ -0,0 +1,239 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+0385 dieresistonos +!A2 U+0386 Alphatonos +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/vendor/phenx/php-font-lib/maps/cp1254.map b/vendor/phenx/php-font-lib/maps/cp1254.map new file mode 100644 index 0000000..3cc8c78 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1254.map @@ -0,0 +1,249 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp1255.map b/vendor/phenx/php-font-lib/maps/cp1255.map new file mode 100644 index 0000000..fa13530 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1255.map @@ -0,0 +1,233 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AA afii57636 +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00D7 multiply +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD sfthyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 middot +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00F7 divide +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+05B0 afii57799 +!C1 U+05B1 afii57801 +!C2 U+05B2 afii57800 +!C3 U+05B3 afii57802 +!C4 U+05B4 afii57793 +!C5 U+05B5 afii57794 +!C6 U+05B6 afii57795 +!C7 U+05B7 afii57798 +!C8 U+05B8 afii57797 +!C9 U+05B9 afii57806 +!CB U+05BB afii57796 +!CC U+05BC afii57807 +!CD U+05BD afii57839 +!CE U+05BE afii57645 +!CF U+05BF afii57841 +!D0 U+05C0 afii57842 +!D1 U+05C1 afii57804 +!D2 U+05C2 afii57803 +!D3 U+05C3 afii57658 +!D4 U+05F0 afii57716 +!D5 U+05F1 afii57717 +!D6 U+05F2 afii57718 +!D7 U+05F3 gereshhebrew +!D8 U+05F4 gershayimhebrew +!E0 U+05D0 afii57664 +!E1 U+05D1 afii57665 +!E2 U+05D2 afii57666 +!E3 U+05D3 afii57667 +!E4 U+05D4 afii57668 +!E5 U+05D5 afii57669 +!E6 U+05D6 afii57670 +!E7 U+05D7 afii57671 +!E8 U+05D8 afii57672 +!E9 U+05D9 afii57673 +!EA U+05DA afii57674 +!EB U+05DB afii57675 +!EC U+05DC afii57676 +!ED U+05DD afii57677 +!EE U+05DE afii57678 +!EF U+05DF afii57679 +!F0 U+05E0 afii57680 +!F1 U+05E1 afii57681 +!F2 U+05E2 afii57682 +!F3 U+05E3 afii57683 +!F4 U+05E4 afii57684 +!F5 U+05E5 afii57685 +!F6 U+05E6 afii57686 +!F7 U+05E7 afii57687 +!F8 U+05E8 afii57688 +!F9 U+05E9 afii57689 +!FA U+05EA afii57690 +!FD U+200E afii299 +!FE U+200F afii300 diff --git a/vendor/phenx/php-font-lib/maps/cp1257.map b/vendor/phenx/php-font-lib/maps/cp1257.map new file mode 100644 index 0000000..077fdc3 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1257.map @@ -0,0 +1,244 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8D U+00A8 dieresis +!8E U+02C7 caron +!8F U+00B8 cedilla +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!9D U+00AF macron +!9E U+02DB ogonek +!A0 U+00A0 space +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00D8 Oslash +!A9 U+00A9 copyright +!AA U+0156 Rcommaaccent +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00C6 AE +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00F8 oslash +!B9 U+00B9 onesuperior +!BA U+0157 rcommaaccent +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00E6 ae +!C0 U+0104 Aogonek +!C1 U+012E Iogonek +!C2 U+0100 Amacron +!C3 U+0106 Cacute +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+0118 Eogonek +!C7 U+0112 Emacron +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0179 Zacute +!CB U+0116 Edotaccent +!CC U+0122 Gcommaaccent +!CD U+0136 Kcommaaccent +!CE U+012A Imacron +!CF U+013B Lcommaaccent +!D0 U+0160 Scaron +!D1 U+0143 Nacute +!D2 U+0145 Ncommaaccent +!D3 U+00D3 Oacute +!D4 U+014C Omacron +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0172 Uogonek +!D9 U+0141 Lslash +!DA U+015A Sacute +!DB U+016A Umacron +!DC U+00DC Udieresis +!DD U+017B Zdotaccent +!DE U+017D Zcaron +!DF U+00DF germandbls +!E0 U+0105 aogonek +!E1 U+012F iogonek +!E2 U+0101 amacron +!E3 U+0107 cacute +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+0119 eogonek +!E7 U+0113 emacron +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+017A zacute +!EB U+0117 edotaccent +!EC U+0123 gcommaaccent +!ED U+0137 kcommaaccent +!EE U+012B imacron +!EF U+013C lcommaaccent +!F0 U+0161 scaron +!F1 U+0144 nacute +!F2 U+0146 ncommaaccent +!F3 U+00F3 oacute +!F4 U+014D omacron +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0173 uogonek +!F9 U+0142 lslash +!FA U+015B sacute +!FB U+016B umacron +!FC U+00FC udieresis +!FD U+017C zdotaccent +!FE U+017E zcaron +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/cp1258.map b/vendor/phenx/php-font-lib/maps/cp1258.map new file mode 100644 index 0000000..7032c35 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1258.map @@ -0,0 +1,247 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+0300 gravecomb +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+00D1 Ntilde +!D2 U+0309 hookabovecomb +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+01A0 Ohorn +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+01AF Uhorn +!DE U+0303 tildecomb +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+0301 acutecomb +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+00F1 ntilde +!F2 U+0323 dotbelowcomb +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+01A1 ohorn +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+01B0 uhorn +!FE U+20AB dong +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp874.map b/vendor/phenx/php-font-lib/maps/cp874.map new file mode 100644 index 0000000..16330d0 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp874.map @@ -0,0 +1,225 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!85 U+2026 ellipsis +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-1.map b/vendor/phenx/php-font-lib/maps/iso-8859-1.map new file mode 100644 index 0000000..74fb2fe --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-1.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-11.map b/vendor/phenx/php-font-lib/maps/iso-8859-11.map new file mode 100644 index 0000000..8cf6673 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-11.map @@ -0,0 +1,248 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-15.map b/vendor/phenx/php-font-lib/maps/iso-8859-15.map new file mode 100644 index 0000000..2689703 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-15.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AC Euro +!A5 U+00A5 yen +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+017D Zcaron +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-16.map b/vendor/phenx/php-font-lib/maps/iso-8859-16.map new file mode 100644 index 0000000..89b802a --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-16.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0105 aogonek +!A3 U+0141 Lslash +!A4 U+20AC Euro +!A5 U+201E quotedblbase +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+0218 Scommaaccent +!AB U+00AB guillemotleft +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017A zacute +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+010C Ccaron +!B3 U+0142 lslash +!B4 U+017D Zcaron +!B5 U+201D quotedblright +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+010D ccaron +!BA U+0219 scommaaccent +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+017C zdotaccent +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0106 Cacute +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+015A Sacute +!D8 U+0170 Uhungarumlaut +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0118 Eogonek +!DE U+021A Tcommaaccent +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+0107 cacute +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+015B sacute +!F8 U+0171 uhungarumlaut +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0119 eogonek +!FE U+021B tcommaaccent +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-2.map b/vendor/phenx/php-font-lib/maps/iso-8859-2.map new file mode 100644 index 0000000..af9588d --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-2.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+013D Lcaron +!A6 U+015A Sacute +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+015E Scedilla +!AB U+0164 Tcaron +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+013E lcaron +!B6 U+015B sacute +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+015F scedilla +!BB U+0165 tcaron +!BC U+017A zacute +!BD U+02DD hungarumlaut +!BE U+017E zcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-4.map b/vendor/phenx/php-font-lib/maps/iso-8859-4.map new file mode 100644 index 0000000..e81dd7f --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-4.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0138 kgreenlandic +!A3 U+0156 Rcommaaccent +!A4 U+00A4 currency +!A5 U+0128 Itilde +!A6 U+013B Lcommaaccent +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+0112 Emacron +!AB U+0122 Gcommaaccent +!AC U+0166 Tbar +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0157 rcommaaccent +!B4 U+00B4 acute +!B5 U+0129 itilde +!B6 U+013C lcommaaccent +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+0113 emacron +!BB U+0123 gcommaaccent +!BC U+0167 tbar +!BD U+014A Eng +!BE U+017E zcaron +!BF U+014B eng +!C0 U+0100 Amacron +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+012E Iogonek +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+0116 Edotaccent +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+012A Imacron +!D0 U+0110 Dcroat +!D1 U+0145 Ncommaaccent +!D2 U+014C Omacron +!D3 U+0136 Kcommaaccent +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+0172 Uogonek +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0168 Utilde +!DE U+016A Umacron +!DF U+00DF germandbls +!E0 U+0101 amacron +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+012F iogonek +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+0117 edotaccent +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+012B imacron +!F0 U+0111 dcroat +!F1 U+0146 ncommaaccent +!F2 U+014D omacron +!F3 U+0137 kcommaaccent +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+0173 uogonek +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0169 utilde +!FE U+016B umacron +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-5.map b/vendor/phenx/php-font-lib/maps/iso-8859-5.map new file mode 100644 index 0000000..8030fd5 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-5.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0401 afii10023 +!A2 U+0402 afii10051 +!A3 U+0403 afii10052 +!A4 U+0404 afii10053 +!A5 U+0405 afii10054 +!A6 U+0406 afii10055 +!A7 U+0407 afii10056 +!A8 U+0408 afii10057 +!A9 U+0409 afii10058 +!AA U+040A afii10059 +!AB U+040B afii10060 +!AC U+040C afii10061 +!AD U+00AD hyphen +!AE U+040E afii10062 +!AF U+040F afii10145 +!B0 U+0410 afii10017 +!B1 U+0411 afii10018 +!B2 U+0412 afii10019 +!B3 U+0413 afii10020 +!B4 U+0414 afii10021 +!B5 U+0415 afii10022 +!B6 U+0416 afii10024 +!B7 U+0417 afii10025 +!B8 U+0418 afii10026 +!B9 U+0419 afii10027 +!BA U+041A afii10028 +!BB U+041B afii10029 +!BC U+041C afii10030 +!BD U+041D afii10031 +!BE U+041E afii10032 +!BF U+041F afii10033 +!C0 U+0420 afii10034 +!C1 U+0421 afii10035 +!C2 U+0422 afii10036 +!C3 U+0423 afii10037 +!C4 U+0424 afii10038 +!C5 U+0425 afii10039 +!C6 U+0426 afii10040 +!C7 U+0427 afii10041 +!C8 U+0428 afii10042 +!C9 U+0429 afii10043 +!CA U+042A afii10044 +!CB U+042B afii10045 +!CC U+042C afii10046 +!CD U+042D afii10047 +!CE U+042E afii10048 +!CF U+042F afii10049 +!D0 U+0430 afii10065 +!D1 U+0431 afii10066 +!D2 U+0432 afii10067 +!D3 U+0433 afii10068 +!D4 U+0434 afii10069 +!D5 U+0435 afii10070 +!D6 U+0436 afii10072 +!D7 U+0437 afii10073 +!D8 U+0438 afii10074 +!D9 U+0439 afii10075 +!DA U+043A afii10076 +!DB U+043B afii10077 +!DC U+043C afii10078 +!DD U+043D afii10079 +!DE U+043E afii10080 +!DF U+043F afii10081 +!E0 U+0440 afii10082 +!E1 U+0441 afii10083 +!E2 U+0442 afii10084 +!E3 U+0443 afii10085 +!E4 U+0444 afii10086 +!E5 U+0445 afii10087 +!E6 U+0446 afii10088 +!E7 U+0447 afii10089 +!E8 U+0448 afii10090 +!E9 U+0449 afii10091 +!EA U+044A afii10092 +!EB U+044B afii10093 +!EC U+044C afii10094 +!ED U+044D afii10095 +!EE U+044E afii10096 +!EF U+044F afii10097 +!F0 U+2116 afii61352 +!F1 U+0451 afii10071 +!F2 U+0452 afii10099 +!F3 U+0453 afii10100 +!F4 U+0454 afii10101 +!F5 U+0455 afii10102 +!F6 U+0456 afii10103 +!F7 U+0457 afii10104 +!F8 U+0458 afii10105 +!F9 U+0459 afii10106 +!FA U+045A afii10107 +!FB U+045B afii10108 +!FC U+045C afii10109 +!FD U+00A7 section +!FE U+045E afii10110 +!FF U+045F afii10193 diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-7.map b/vendor/phenx/php-font-lib/maps/iso-8859-7.map new file mode 100644 index 0000000..be8698a --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-7.map @@ -0,0 +1,250 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+2018 quoteleft +!A2 U+2019 quoteright +!A3 U+00A3 sterling +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+0385 dieresistonos +!B6 U+0386 Alphatonos +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-9.map b/vendor/phenx/php-font-lib/maps/iso-8859-9.map new file mode 100644 index 0000000..a60bb19 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-9.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/koi8-r.map b/vendor/phenx/php-font-lib/maps/koi8-r.map new file mode 100644 index 0000000..026880d --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/koi8-r.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2219 periodcentered +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+2553 SF520000 +!A5 U+2554 SF390000 +!A6 U+2555 SF220000 +!A7 U+2556 SF210000 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+255C SF270000 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+2562 SF200000 +!B5 U+2563 SF230000 +!B6 U+2564 SF470000 +!B7 U+2565 SF480000 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+256B SF530000 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/vendor/phenx/php-font-lib/maps/koi8-u.map b/vendor/phenx/php-font-lib/maps/koi8-u.map new file mode 100644 index 0000000..97d9d03 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/koi8-u.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2022 bullet +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+0454 afii10101 +!A5 U+2554 SF390000 +!A6 U+0456 afii10103 +!A7 U+0457 afii10104 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+0491 afii10098 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+0404 afii10053 +!B5 U+2563 SF230000 +!B6 U+0406 afii10055 +!B7 U+0407 afii10056 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+0490 afii10050 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php b/vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php new file mode 100644 index 0000000..e75385f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php @@ -0,0 +1,217 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +use FontLib\Table\Type\name; +use FontLib\TrueType\File; + +/** + * Adobe Font Metrics file creation utility class. + * + * @package php-font-lib + */ +class AdobeFontMetrics { + private $f; + + /** + * @var File + */ + private $font; + + function __construct(File $font) { + $this->font = $font; + } + + function write($file, $encoding = null) { + $map_data = array(); + + if ($encoding) { + $encoding = preg_replace("/[^a-z0-9-_]/", "", $encoding); + $map_file = dirname(__FILE__) . "/../maps/$encoding.map"; + if (!file_exists($map_file)) { + throw new \Exception("Unknown encoding ($encoding)"); + } + + $map = new EncodingMap($map_file); + $map_data = $map->parse(); + } + + $this->f = fopen($file, "w+"); + + $font = $this->font; + + $this->startSection("FontMetrics", 4.1); + $this->addPair("Notice", "Converted by PHP-font-lib"); + $this->addPair("Comment", "https://github.com/PhenX/php-font-lib"); + + $encoding_scheme = ($encoding ? $encoding : "FontSpecific"); + $this->addPair("EncodingScheme", $encoding_scheme); + + $records = $font->getData("name", "records"); + foreach ($records as $id => $record) { + if (!isset(name::$nameIdCodes[$id]) || preg_match("/[\r\n]/", $record->string)) { + continue; + } + + $this->addPair(name::$nameIdCodes[$id], $record->string); + } + + $os2 = $font->getData("OS/2"); + $this->addPair("Weight", ($os2["usWeightClass"] > 400 ? "Bold" : "Medium")); + + $post = $font->getData("post"); + $this->addPair("ItalicAngle", $post["italicAngle"]); + $this->addPair("IsFixedPitch", ($post["isFixedPitch"] ? "true" : "false")); + $this->addPair("UnderlineThickness", $font->normalizeFUnit($post["underlineThickness"])); + $this->addPair("UnderlinePosition", $font->normalizeFUnit($post["underlinePosition"])); + + $hhea = $font->getData("hhea"); + + if (isset($hhea["ascent"])) { + $this->addPair("FontHeightOffset", $font->normalizeFUnit($hhea["lineGap"])); + $this->addPair("Ascender", $font->normalizeFUnit($hhea["ascent"])); + $this->addPair("Descender", $font->normalizeFUnit($hhea["descent"])); + } + else { + $this->addPair("FontHeightOffset", $font->normalizeFUnit($os2["typoLineGap"])); + $this->addPair("Ascender", $font->normalizeFUnit($os2["typoAscender"])); + $this->addPair("Descender", -abs($font->normalizeFUnit($os2["typoDescender"]))); + } + + $head = $font->getData("head"); + $this->addArray("FontBBox", array( + $font->normalizeFUnit($head["xMin"]), + $font->normalizeFUnit($head["yMin"]), + $font->normalizeFUnit($head["xMax"]), + $font->normalizeFUnit($head["yMax"]), + )); + + $glyphIndexArray = $font->getUnicodeCharMap(); + + if ($glyphIndexArray) { + $hmtx = $font->getData("hmtx"); + $names = $font->getData("post", "names"); + + $this->startSection("CharMetrics", count($hmtx)); + + if ($encoding) { + foreach ($map_data as $code => $value) { + list($c, $name) = $value; + + if (!isset($glyphIndexArray[$c])) { + continue; + } + + $g = $glyphIndexArray[$c]; + + if (!isset($hmtx[$g])) { + $hmtx[$g] = $hmtx[0]; + } + + $this->addMetric(array( + "C" => ($code > 255 ? -1 : $code), + "WX" => $font->normalizeFUnit($hmtx[$g][0]), + "N" => $name, + )); + } + } + else { + foreach ($glyphIndexArray as $c => $g) { + if (!isset($hmtx[$g])) { + $hmtx[$g] = $hmtx[0]; + } + + $this->addMetric(array( + "U" => $c, + "WX" => $font->normalizeFUnit($hmtx[$g][0]), + "N" => (isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $c)), + "G" => $g, + )); + } + } + + $this->endSection("CharMetrics"); + + $kern = $font->getData("kern", "subtable"); + $tree = is_array($kern) ? $kern["tree"] : null; + + if (!$encoding && is_array($tree)) { + $this->startSection("KernData"); + $this->startSection("KernPairs", count($tree, COUNT_RECURSIVE) - count($tree)); + + foreach ($tree as $left => $values) { + if (!is_array($values)) { + continue; + } + if (!isset($glyphIndexArray[$left])) { + continue; + } + + $left_gid = $glyphIndexArray[$left]; + + if (!isset($names[$left_gid])) { + continue; + } + + $left_name = $names[$left_gid]; + + $this->addLine(""); + + foreach ($values as $right => $value) { + if (!isset($glyphIndexArray[$right])) { + continue; + } + + $right_gid = $glyphIndexArray[$right]; + + if (!isset($names[$right_gid])) { + continue; + } + + $right_name = $names[$right_gid]; + $this->addPair("KPX", "$left_name $right_name $value"); + } + } + + $this->endSection("KernPairs"); + $this->endSection("KernData"); + } + } + + $this->endSection("FontMetrics"); + } + + function addLine($line) { + fwrite($this->f, "$line\n"); + } + + function addPair($key, $value) { + $this->addLine("$key $value"); + } + + function addArray($key, $array) { + $this->addLine("$key " . implode(" ", $array)); + } + + function addMetric($data) { + $array = array(); + foreach ($data as $key => $value) { + $array[] = "$key $value"; + } + $this->addLine(implode(" ; ", $array)); + } + + function startSection($name, $value = "") { + $this->addLine("Start$name $value"); + } + + function endSection($name) { + $this->addLine("End$name"); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php b/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php new file mode 100644 index 0000000..cd30545 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php @@ -0,0 +1,43 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Autoloads FontLib classes + * + * @package php-font-lib + */ +class Autoloader { + const PREFIX = 'FontLib'; + + /** + * Register the autoloader + */ + public static function register() { + spl_autoload_register(array(new self, 'autoload')); + } + + /** + * Autoloader + * + * @param string + */ + public static function autoload($class) { + $prefixLength = strlen(self::PREFIX); + if (0 === strncmp(self::PREFIX, $class, $prefixLength)) { + $file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $prefixLength)); + $file = realpath(__DIR__ . (empty($file) ? '' : DIRECTORY_SEPARATOR) . $file . '.php'); + if (file_exists($file)) { + require_once $file; + } + } + } +} + +Autoloader::register(); \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php b/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php new file mode 100644 index 0000000..c7eb52f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php @@ -0,0 +1,449 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Generic font file binary stream. + * + * @package php-font-lib + */ +class BinaryStream { + /** + * @var resource The file pointer + */ + protected $f; + + const uint8 = 1; + const int8 = 2; + const uint16 = 3; + const int16 = 4; + const uint32 = 5; + const int32 = 6; + const shortFrac = 7; + const Fixed = 8; + const FWord = 9; + const uFWord = 10; + const F2Dot14 = 11; + const longDateTime = 12; + const char = 13; + + const modeRead = "rb"; + const modeWrite = "wb"; + const modeReadWrite = "rb+"; + + static function backtrace() { + var_dump(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); + } + + /** + * Open a font file in read mode + * + * @param string $filename The file name of the font to open + * + * @return bool + */ + public function load($filename) { + return $this->open($filename, self::modeRead); + } + + /** + * Open a font file in a chosen mode + * + * @param string $filename The file name of the font to open + * @param string $mode The opening mode + * + * @throws \Exception + * @return bool + */ + public function open($filename, $mode = self::modeRead) { + if (!in_array($mode, array(self::modeRead, self::modeWrite, self::modeReadWrite))) { + throw new \Exception("Unknown file open mode"); + } + + $this->f = fopen($filename, $mode); + + return $this->f != false; + } + + /** + * Close the internal file pointer + */ + public function close() { + return fclose($this->f) != false; + } + + /** + * Change the internal file pointer + * + * @param resource $fp + * + * @throws \Exception + */ + public function setFile($fp) { + if (!is_resource($fp)) { + throw new \Exception('$fp is not a valid resource'); + } + + $this->f = $fp; + } + + /** + * Create a temporary file in write mode + * + * @param bool $allow_memory Allow in-memory files + * + * @return resource the temporary file pointer resource + */ + public static function getTempFile($allow_memory = true) { + $f = null; + + if ($allow_memory) { + $f = fopen("php://temp", "rb+"); + } + else { + $f = fopen(tempnam(sys_get_temp_dir(), "fnt"), "rb+"); + } + + return $f; + } + + /** + * Move the internal file pinter to $offset bytes + * + * @param int $offset + * + * @return bool True if the $offset position exists in the file + */ + public function seek($offset) { + return fseek($this->f, $offset, SEEK_SET) == 0; + } + + /** + * Gives the current position in the file + * + * @return int The current position + */ + public function pos() { + return ftell($this->f); + } + + public function skip($n) { + fseek($this->f, $n, SEEK_CUR); + } + + /** + * @param int $n The number of bytes to read + * + * @return string + */ + public function read($n) { + if ($n < 1) { + return ""; + } + + return (string) fread($this->f, $n); + } + + public function write($data, $length = null) { + if ($data === null || $data === "" || $data === false) { + return 0; + } + + return fwrite($this->f, $data, $length); + } + + public function readUInt8() { + return ord($this->read(1)); + } + + public function readUInt8Many($count) { + return array_values(unpack("C*", $this->read($count))); + } + + public function writeUInt8($data) { + return $this->write(chr($data), 1); + } + + public function readInt8() { + $v = $this->readUInt8(); + + if ($v >= 0x80) { + $v -= 0x100; + } + + return $v; + } + + public function readInt8Many($count) { + return array_values(unpack("c*", $this->read($count))); + } + + public function writeInt8($data) { + if ($data < 0) { + $data += 0x100; + } + + return $this->writeUInt8($data); + } + + public function readUInt16() { + $a = unpack("nn", $this->read(2)); + + return $a["n"]; + } + + public function readUInt16Many($count) { + return array_values(unpack("n*", $this->read($count * 2))); + } + + public function readUFWord() { + return $this->readUInt16(); + } + + public function writeUInt16($data) { + return $this->write(pack("n", $data), 2); + } + + public function writeUFWord($data) { + return $this->writeUInt16($data); + } + + public function readInt16() { + $a = unpack("nn", $this->read(2)); + $v = $a["n"]; + + if ($v >= 0x8000) { + $v -= 0x10000; + } + + return $v; + } + + public function readInt16Many($count) { + $vals = array_values(unpack("n*", $this->read($count * 2))); + foreach ($vals as &$v) { + if ($v >= 0x8000) { + $v -= 0x10000; + } + } + + return $vals; + } + + public function readFWord() { + return $this->readInt16(); + } + + public function writeInt16($data) { + if ($data < 0) { + $data += 0x10000; + } + + return $this->writeUInt16($data); + } + + public function writeFWord($data) { + return $this->writeInt16($data); + } + + public function readUInt32() { + $a = unpack("NN", $this->read(4)); + + return $a["N"]; + } + + public function writeUInt32($data) { + return $this->write(pack("N", $data), 4); + } + + public function readFixed() { + $d = $this->readInt16(); + $d2 = $this->readUInt16(); + + return round($d + $d2 / 0x10000, 4); + } + + public function writeFixed($data) { + $left = floor($data); + $right = ($data - $left) * 0x10000; + + return $this->writeInt16($left) + $this->writeUInt16($right); + } + + public function readLongDateTime() { + $this->readUInt32(); // ignored + $date = $this->readUInt32() - 2082844800; + + # PHP_INT_MIN isn't defined in PHP < 7.0 + $php_int_min = defined("PHP_INT_MIN") ? PHP_INT_MIN : ~PHP_INT_MAX; + + if (is_string($date) || $date > PHP_INT_MAX || $date < $php_int_min) { + $date = 0; + } + + return date("Y-m-d H:i:s", $date); + } + + public function writeLongDateTime($data) { + $date = strtotime($data); + $date += 2082844800; + + return $this->writeUInt32(0) + $this->writeUInt32($date); + } + + public function unpack($def) { + $d = array(); + foreach ($def as $name => $type) { + $d[$name] = $this->r($type); + } + + return $d; + } + + public function pack($def, $data) { + $bytes = 0; + foreach ($def as $name => $type) { + $bytes += $this->w($type, $data[$name]); + } + + return $bytes; + } + + /** + * Read a data of type $type in the file from the current position + * + * @param mixed $type The data type to read + * + * @return mixed The data that was read + */ + public function r($type) { + switch ($type) { + case self::uint8: + return $this->readUInt8(); + case self::int8: + return $this->readInt8(); + case self::uint16: + return $this->readUInt16(); + case self::int16: + return $this->readInt16(); + case self::uint32: + return $this->readUInt32(); + case self::int32: + return $this->readUInt32(); + case self::shortFrac: + return $this->readFixed(); + case self::Fixed: + return $this->readFixed(); + case self::FWord: + return $this->readInt16(); + case self::uFWord: + return $this->readUInt16(); + case self::F2Dot14: + return $this->readInt16(); + case self::longDateTime: + return $this->readLongDateTime(); + case self::char: + return $this->read(1); + default: + if (is_array($type)) { + if ($type[0] == self::char) { + return $this->read($type[1]); + } + if ($type[0] == self::uint16) { + return $this->readUInt16Many($type[1]); + } + if ($type[0] == self::int16) { + return $this->readInt16Many($type[1]); + } + if ($type[0] == self::uint8) { + return $this->readUInt8Many($type[1]); + } + if ($type[0] == self::int8) { + return $this->readInt8Many($type[1]); + } + + $ret = array(); + for ($i = 0; $i < $type[1]; $i++) { + $ret[] = $this->r($type[0]); + } + + return $ret; + } + + return null; + } + } + + /** + * Write $data of type $type in the file from the current position + * + * @param mixed $type The data type to write + * @param mixed $data The data to write + * + * @return int The number of bytes read + */ + public function w($type, $data) { + switch ($type) { + case self::uint8: + return $this->writeUInt8($data); + case self::int8: + return $this->writeInt8($data); + case self::uint16: + return $this->writeUInt16($data); + case self::int16: + return $this->writeInt16($data); + case self::uint32: + return $this->writeUInt32($data); + case self::int32: + return $this->writeUInt32($data); + case self::shortFrac: + return $this->writeFixed($data); + case self::Fixed: + return $this->writeFixed($data); + case self::FWord: + return $this->writeInt16($data); + case self::uFWord: + return $this->writeUInt16($data); + case self::F2Dot14: + return $this->writeInt16($data); + case self::longDateTime: + return $this->writeLongDateTime($data); + case self::char: + return $this->write($data, 1); + default: + if (is_array($type)) { + if ($type[0] == self::char) { + return $this->write($data, $type[1]); + } + + $ret = 0; + for ($i = 0; $i < $type[1]; $i++) { + if (isset($data[$i])) { + $ret += $this->w($type[0], $data[$i]); + } + } + + return $ret; + } + + return null; + } + } + + /** + * Converts a Uint32 value to string + * + * @param int $uint32 + * + * @return string The string + */ + public function convertUInt32ToStr($uint32) { + return chr(($uint32 >> 24) & 0xFF) . chr(($uint32 >> 16) & 0xFF) . chr(($uint32 >> 8) & 0xFF) . chr($uint32 & 0xFF); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php b/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php new file mode 100644 index 0000000..f51d876 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php @@ -0,0 +1,159 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\EOT; + +/** + * EOT font file. + * + * @package php-font-lib + */ +class File extends \FontLib\TrueType\File { + const TTEMBED_SUBSET = 0x00000001; + const TTEMBED_TTCOMPRESSED = 0x00000004; + const TTEMBED_FAILIFVARIATIONSIMULATED = 0x00000010; + const TTMBED_EMBEDEUDC = 0x00000020; + const TTEMBED_VALIDATIONTESTS = 0x00000040; // Deprecated + const TTEMBED_WEBOBJECT = 0x00000080; + const TTEMBED_XORENCRYPTDATA = 0x10000000; + + /** + * @var Header + */ + public $header; + + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->header = new Header($this); + $this->header->parse(); + } + + function parse() { + $this->parseHeader(); + + $flags = $this->header->data["Flags"]; + + if ($flags & self::TTEMBED_TTCOMPRESSED) { + $mtx_version = $this->readUInt8(); + $mtx_copy_limit = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + $mtx_offset_1 = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + $mtx_offset_2 = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + /* + var_dump("$mtx_version $mtx_copy_limit $mtx_offset_1 $mtx_offset_2"); + + $pos = $this->pos(); + $size = $mtx_offset_1 - $pos; + var_dump("pos: $pos"); + var_dump("size: $size");*/ + } + + if ($flags & self::TTEMBED_XORENCRYPTDATA) { + // Process XOR + } + // TODO Read font data ... + } + + /** + * Little endian version of the read method + * + * @param int $n The number of bytes to read + * + * @return string + */ + public function read($n) { + if ($n < 1) { + return ""; + } + + $string = (string) fread($this->f, $n); + $chunks = mb_str_split($string, 2, '8bit'); + $chunks = array_map("strrev", $chunks); + return implode("", $chunks); + } + + public function readUInt32() { + $uint32 = parent::readUInt32(); + + return $uint32 >> 16 & 0x0000FFFF | $uint32 << 16 & 0xFFFF0000; + } + + /** + * Get font copyright + * + * @return string|null + */ + function getFontCopyright() { + return null; + } + + /** + * Get font name + * + * @return string|null + */ + function getFontName() { + return $this->header->data["FamilyName"]; + } + + /** + * Get font subfamily + * + * @return string|null + */ + function getFontSubfamily() { + return $this->header->data["StyleName"]; + } + + /** + * Get font subfamily ID + * + * @return string|null + */ + function getFontSubfamilyID() { + return $this->header->data["StyleName"]; + } + + /** + * Get font full name + * + * @return string|null + */ + function getFontFullName() { + return $this->header->data["FullName"]; + } + + /** + * Get font version + * + * @return string|null + */ + function getFontVersion() { + return $this->header->data["VersionName"]; + } + + /** + * Get font weight + * + * @return string|null + */ + function getFontWeight() { + return $this->header->data["Weight"]; + } + + /** + * Get font Postscript name + * + * @return string|null + */ + function getFontPostscriptName() { + return null; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php b/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php new file mode 100644 index 0000000..960e36a --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php @@ -0,0 +1,113 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\EOT; + +use Exception; +use FontLib\Font; + +/** + * TrueType font file header. + * + * @package php-font-lib + * + * @property File $font + */ +class Header extends \FontLib\Header { + protected $def = array( + "format" => self::uint32, + "numTables" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + public function parse() { + $font = $this->font; + + $this->data = $font->unpack(array( + "EOTSize" => self::uint32, + "FontDataSize" => self::uint32, + "Version" => self::uint32, + "Flags" => self::uint32, + "FontPANOSE" => array(self::uint8, 10), + "Charset" => self::uint8, + "Italic" => self::uint8, + "Weight" => self::uint32, + "fsType" => self::uint16, + "MagicNumber" => self::uint16, + "UnicodeRange1" => self::uint32, + "UnicodeRange2" => self::uint32, + "UnicodeRange3" => self::uint32, + "UnicodeRange4" => self::uint32, + "CodePageRange1" => self::uint32, + "CodePageRange2" => self::uint32, + "CheckSumAdjustment" => self::uint32, + "Reserved1" => self::uint32, + "Reserved2" => self::uint32, + "Reserved3" => self::uint32, + "Reserved4" => self::uint32, + )); + + $this->data["Padding1"] = $font->readUInt16(); + $this->readString("FamilyName"); + + $this->data["Padding2"] = $font->readUInt16(); + $this->readString("StyleName"); + + $this->data["Padding3"] = $font->readUInt16(); + $this->readString("VersionName"); + + $this->data["Padding4"] = $font->readUInt16(); + $this->readString("FullName"); + + switch ($this->data["Version"]) { + default: + throw new Exception("Unknown EOT version " . $this->data["Version"]); + + case 0x00010000: + // Nothing to do more + break; + + case 0x00020001: + $this->data["Padding5"] = $font->readUInt16(); + $this->readString("RootString"); + break; + + case 0x00020002: + $this->data["Padding5"] = $font->readUInt16(); + $this->readString("RootString"); + + $this->data["RootStringCheckSum"] = $font->readUInt32(); + $this->data["EUDCCodePage"] = $font->readUInt32(); + + $this->data["Padding6"] = $font->readUInt16(); + $this->readString("Signature"); + + $this->data["EUDCFlags"] = $font->readUInt32(); + $this->data["EUDCFontSize"] = $font->readUInt32(); + break; + } + + if (!empty($this->data["RootString"])) { + $this->data["RootString"] = explode("\0", $this->data["RootString"]); + } + } + + private function readString($name) { + $font = $this->font; + $size = $font->readUInt16(); + + $this->data["{$name}Size"] = $size; + $this->data[$name] = Font::UTF16ToUTF8($font->read($size)); + } + + public function encode() { + //return $this->font->pack($this->def, $this->data); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php b/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php new file mode 100644 index 0000000..2acdebc --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php @@ -0,0 +1,37 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Encoding map used to map a code point to a Unicode char. + * + * @package php-font-lib + */ +class EncodingMap { + private $f; + + function __construct($file) { + $this->f = fopen($file, "r"); + } + + function parse() { + $map = array(); + + while ($line = fgets($this->f)) { + if (preg_match('/^[\!\=]([0-9A-F]{2,})\s+U\+([0-9A-F]{2})([0-9A-F]{2})\s+([^\s]+)/', $line, $matches)) { + $unicode = (hexdec($matches[2]) << 8) + hexdec($matches[3]); + $map[hexdec($matches[1])] = array($unicode, $matches[4]); + } + } + + ksort($map); + + return $map; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php b/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php new file mode 100644 index 0000000..d97f252 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php @@ -0,0 +1,11 @@ +message = 'Font not found in: ' . $fontPath; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Font.php b/vendor/phenx/php-font-lib/src/FontLib/Font.php new file mode 100644 index 0000000..e13a653 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Font.php @@ -0,0 +1,89 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +use FontLib\Exception\FontNotFoundException; + +/** + * Generic font file. + * + * @package php-font-lib + */ +class Font { + static $debug = false; + + /** + * @param string $file The font file + * + * @return TrueType\File|null $file + */ + public static function load($file) { + if(!file_exists($file)){ + throw new FontNotFoundException($file); + } + + $header = file_get_contents($file, false, null, 0, 4); + $class = null; + + switch ($header) { + case "\x00\x01\x00\x00": + case "true": + case "typ1": + $class = "TrueType\\File"; + break; + + case "OTTO": + $class = "OpenType\\File"; + break; + + case "wOFF": + $class = "WOFF\\File"; + break; + + case "ttcf": + $class = "TrueType\\Collection"; + break; + + // Unknown type or EOT + default: + $magicNumber = file_get_contents($file, false, null, 34, 2); + + if ($magicNumber === "LP") { + $class = "EOT\\File"; + } + } + + if ($class) { + $class = "FontLib\\$class"; + + /** @var TrueType\File $obj */ + $obj = new $class; + $obj->load($file); + + return $obj; + } + + return null; + } + + static function d($str) { + if (!self::$debug) { + return; + } + echo "$str\n"; + } + + static function UTF16ToUTF8($str) { + return mb_convert_encoding($str, "utf-8", "utf-16"); + } + + static function UTF8ToUTF16($str) { + return mb_convert_encoding($str, "utf-16", "utf-8"); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php new file mode 100644 index 0000000..639ff60 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php @@ -0,0 +1,109 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ +namespace FontLib\Glyph; + +use FontLib\Table\Type\glyf; +use FontLib\TrueType\File; +use FontLib\BinaryStream; + +/** + * `glyf` font table. + * + * @package php-font-lib + */ +class Outline extends BinaryStream { + /** + * @var \FontLib\Table\Type\glyf + */ + protected $table; + + protected $offset; + protected $size; + + // Data + public $numberOfContours; + public $xMin; + public $yMin; + public $xMax; + public $yMax; + + /** + * @var string|null + */ + public $raw; + + /** + * @param glyf $table + * @param $offset + * @param $size + * + * @return Outline + */ + static function init(glyf $table, $offset, $size, BinaryStream $font) { + $font->seek($offset); + + if ($font->readInt16() > -1) { + /** @var OutlineSimple $glyph */ + $glyph = new OutlineSimple($table, $offset, $size); + } + else { + /** @var OutlineComposite $glyph */ + $glyph = new OutlineComposite($table, $offset, $size); + } + + $glyph->parse($font); + + return $glyph; + } + + /** + * @return File + */ + function getFont() { + return $this->table->getFont(); + } + + function __construct(glyf $table, $offset = null, $size = null) { + $this->table = $table; + $this->offset = $offset; + $this->size = $size; + } + + function parse(BinaryStream $font) { + $font->seek($this->offset); + + $this->raw = $font->read($this->size); + } + + function parseData() { + $font = $this->getFont(); + $font->seek($this->offset); + + $this->numberOfContours = $font->readInt16(); + $this->xMin = $font->readFWord(); + $this->yMin = $font->readFWord(); + $this->xMax = $font->readFWord(); + $this->yMax = $font->readFWord(); + } + + function encode() { + $font = $this->getFont(); + + return $font->write($this->raw, mb_strlen((string) $this->raw, '8bit')); + } + + function getSVGContours() { + // Inherit + } + + function getGlyphIDs() { + return array(); + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php new file mode 100644 index 0000000..9cafaf4 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; +/** + * Glyph outline component + * + * @package php-font-lib + */ +class OutlineComponent { + public $flags; + public $glyphIndex; + public $a, $b, $c, $d, $e, $f; + public $point_compound; + public $point_component; + public $instructions; + + function getMatrix() { + return array( + $this->a, $this->b, + $this->c, $this->d, + $this->e, $this->f, + ); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php new file mode 100644 index 0000000..8ab0d2c --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php @@ -0,0 +1,242 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; + +/** + * Composite glyph outline + * + * @package php-font-lib + */ +class OutlineComposite extends Outline { + const ARG_1_AND_2_ARE_WORDS = 0x0001; + const ARGS_ARE_XY_VALUES = 0x0002; + const ROUND_XY_TO_GRID = 0x0004; + const WE_HAVE_A_SCALE = 0x0008; + const MORE_COMPONENTS = 0x0020; + const WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; + const WE_HAVE_A_TWO_BY_TWO = 0x0080; + const WE_HAVE_INSTRUCTIONS = 0x0100; + const USE_MY_METRICS = 0x0200; + const OVERLAP_COMPOUND = 0x0400; + + /** + * @var OutlineComponent[] + */ + public $components = array(); + + function getGlyphIDs() { + if (empty($this->components)) { + $this->parseData(); + } + + $glyphIDs = array(); + foreach ($this->components as $_component) { + $glyphIDs[] = $_component->glyphIndex; + + $_glyph = $this->table->data[$_component->glyphIndex]; + + if ($_glyph !== $this) { + $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs()); + } + } + + return $glyphIDs; + } + + /*function parse() { + //$this->parseData(); + }*/ + + function parseData() { + parent::parseData(); + + $font = $this->getFont(); + + do { + $flags = $font->readUInt16(); + $glyphIndex = $font->readUInt16(); + + $a = 1.0; + $b = 0.0; + $c = 0.0; + $d = 1.0; + $e = 0.0; + $f = 0.0; + + $point_compound = null; + $point_component = null; + + $instructions = null; + + if ($flags & self::ARG_1_AND_2_ARE_WORDS) { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $e = $font->readInt16(); + $f = $font->readInt16(); + } + else { + $point_compound = $font->readUInt16(); + $point_component = $font->readUInt16(); + } + } + else { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $e = $font->readInt8(); + $f = $font->readInt8(); + } + else { + $point_compound = $font->readUInt8(); + $point_component = $font->readUInt8(); + } + } + + if ($flags & self::WE_HAVE_A_SCALE) { + $a = $d = $font->readInt16(); + } + elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { + $a = $font->readInt16(); + $d = $font->readInt16(); + } + elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { + $a = $font->readInt16(); + $b = $font->readInt16(); + $c = $font->readInt16(); + $d = $font->readInt16(); + } + + //if ($flags & self::WE_HAVE_INSTRUCTIONS) { + // + //} + + $component = new OutlineComponent(); + $component->flags = $flags; + $component->glyphIndex = $glyphIndex; + $component->a = $a; + $component->b = $b; + $component->c = $c; + $component->d = $d; + $component->e = $e; + $component->f = $f; + $component->point_compound = $point_compound; + $component->point_component = $point_component; + $component->instructions = $instructions; + + $this->components[] = $component; + } while ($flags & self::MORE_COMPONENTS); + } + + function encode() { + $font = $this->getFont(); + + $gids = $font->getSubset(); + + $size = $font->writeInt16(-1); + $size += $font->writeFWord($this->xMin); + $size += $font->writeFWord($this->yMin); + $size += $font->writeFWord($this->xMax); + $size += $font->writeFWord($this->yMax); + + foreach ($this->components as $_i => $_component) { + $flags = 0; + if ($_component->point_component === null && $_component->point_compound === null) { + $flags |= self::ARGS_ARE_XY_VALUES; + + if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) { + $flags |= self::ARG_1_AND_2_ARE_WORDS; + } + } + elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) { + $flags |= self::ARG_1_AND_2_ARE_WORDS; + } + + if ($_component->b == 0 && $_component->c == 0) { + if ($_component->a == $_component->d) { + if ($_component->a != 1.0) { + $flags |= self::WE_HAVE_A_SCALE; + } + } + else { + $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE; + } + } + else { + $flags |= self::WE_HAVE_A_TWO_BY_TWO; + } + + if ($_i < count($this->components) - 1) { + $flags |= self::MORE_COMPONENTS; + } + + $size += $font->writeUInt16($flags); + + $new_gid = array_search($_component->glyphIndex, $gids); + $size += $font->writeUInt16($new_gid); + + if ($flags & self::ARG_1_AND_2_ARE_WORDS) { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $size += $font->writeInt16($_component->e); + $size += $font->writeInt16($_component->f); + } + else { + $size += $font->writeUInt16($_component->point_compound); + $size += $font->writeUInt16($_component->point_component); + } + } + else { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $size += $font->writeInt8($_component->e); + $size += $font->writeInt8($_component->f); + } + else { + $size += $font->writeUInt8($_component->point_compound); + $size += $font->writeUInt8($_component->point_component); + } + } + + if ($flags & self::WE_HAVE_A_SCALE) { + $size += $font->writeInt16($_component->a); + } + elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { + $size += $font->writeInt16($_component->a); + $size += $font->writeInt16($_component->d); + } + elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { + $size += $font->writeInt16($_component->a); + $size += $font->writeInt16($_component->b); + $size += $font->writeInt16($_component->c); + $size += $font->writeInt16($_component->d); + } + } + + return $size; + } + + public function getSVGContours() { + $contours = array(); + + /** @var \FontLib\Table\Type\glyf $glyph_data */ + $glyph_data = $this->getFont()->getTableObject("glyf"); + + /** @var Outline[] $glyphs */ + $glyphs = $glyph_data->data; + + foreach ($this->components as $component) { + $_glyph = $glyphs[$component->glyphIndex]; + + if ($_glyph !== $this) { + $contours[] = array( + "contours" => $_glyph->getSVGContours(), + "transform" => $component->getMatrix(), + ); + } + } + + return $contours; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php new file mode 100644 index 0000000..56b2fb4 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php @@ -0,0 +1,335 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; + +/** + * `glyf` font table. + * + * @package php-font-lib + */ +class OutlineSimple extends Outline { + const ON_CURVE = 0x01; + const X_SHORT_VECTOR = 0x02; + const Y_SHORT_VECTOR = 0x04; + const REPEAT = 0x08; + const THIS_X_IS_SAME = 0x10; + const THIS_Y_IS_SAME = 0x20; + + public $instructions; + public $points; + + function parseData() { + parent::parseData(); + + if (!$this->size) { + return; + } + + $font = $this->getFont(); + + $noc = $this->numberOfContours; + + if ($noc == 0) { + return; + } + + $endPtsOfContours = $font->r(array(self::uint16, $noc)); + + $instructionLength = $font->readUInt16(); + $this->instructions = $font->r(array(self::uint8, $instructionLength)); + + $count = $endPtsOfContours[$noc - 1] + 1; + + // Flags + $flags = array(); + for ($index = 0; $index < $count; $index++) { + $flags[$index] = $font->readUInt8(); + + if ($flags[$index] & self::REPEAT) { + $repeats = $font->readUInt8(); + + for ($i = 1; $i <= $repeats; $i++) { + $flags[$index + $i] = $flags[$index]; + } + + $index += $repeats; + } + } + + $points = array(); + foreach ($flags as $i => $flag) { + $points[$i]["onCurve"] = $flag & self::ON_CURVE; + $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours); + } + + // X Coords + $x = 0; + for ($i = 0; $i < $count; $i++) { + $flag = $flags[$i]; + + if ($flag & self::THIS_X_IS_SAME) { + if ($flag & self::X_SHORT_VECTOR) { + $x += $font->readUInt8(); + } + } + else { + if ($flag & self::X_SHORT_VECTOR) { + $x -= $font->readUInt8(); + } + else { + $x += $font->readInt16(); + } + } + + $points[$i]["x"] = $x; + } + + // Y Coords + $y = 0; + for ($i = 0; $i < $count; $i++) { + $flag = $flags[$i]; + + if ($flag & self::THIS_Y_IS_SAME) { + if ($flag & self::Y_SHORT_VECTOR) { + $y += $font->readUInt8(); + } + } + else { + if ($flag & self::Y_SHORT_VECTOR) { + $y -= $font->readUInt8(); + } + else { + $y += $font->readInt16(); + } + } + + $points[$i]["y"] = $y; + } + + $this->points = $points; + } + + public function splitSVGPath($path) { + preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER); + + return $matches[0]; + } + + public function makePoints($path) { + $path = $this->splitSVGPath($path); + $l = count($path); + $i = 0; + + $points = array(); + + while ($i < $l) { + switch ($path[$i]) { + // moveTo + case "M": + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // lineTo + case "L": + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // quadraticCurveTo + case "Q": + $points[] = array( + "onCurve" => false, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // closePath + /** @noinspection PhpMissingBreakStatementInspection */ + case "z": + $points[count($points) - 1]["endOfContour"] = true; + + default: + $i++; + break; + } + } + + return $points; + } + + function encode() { + if (empty($this->points)) { + return parent::encode(); + } + + return $this->size = $this->encodePoints($this->points); + } + + public function encodePoints($points) { + $endPtsOfContours = array(); + $flags = array(); + $coords_x = array(); + $coords_y = array(); + + $last_x = 0; + $last_y = 0; + $xMin = $yMin = 0xFFFF; + $xMax = $yMax = -0xFFFF; + foreach ($points as $i => $point) { + $flag = 0; + if ($point["onCurve"]) { + $flag |= self::ON_CURVE; + } + + if ($point["endOfContour"]) { + $endPtsOfContours[] = $i; + } + + // Simplified, we could do some optimizations + if ($point["x"] == $last_x) { + $flag |= self::THIS_X_IS_SAME; + } + else { + $x = intval($point["x"]); + $xMin = min($x, $xMin); + $xMax = max($x, $xMax); + $coords_x[] = $x - $last_x; // int16 + } + + // Simplified, we could do some optimizations + if ($point["y"] == $last_y) { + $flag |= self::THIS_Y_IS_SAME; + } + else { + $y = intval($point["y"]); + $yMin = min($y, $yMin); + $yMax = max($y, $yMax); + $coords_y[] = $y - $last_y; // int16 + } + + $flags[] = $flag; + $last_x = $point["x"]; + $last_y = $point["y"]; + } + + $font = $this->getFont(); + + $l = 0; + $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours + $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin + $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin + $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax + $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax + + // Simple glyf + $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours + $l += $font->writeUInt16(0); // instructionLength + $l += $font->w(array(self::uint8, count($flags)), $flags); // flags + $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates + $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates + return $l; + } + + public function getSVGContours($points = null) { + $path = ""; + + if (!$points) { + if (empty($this->points)) { + $this->parseData(); + } + + $points = $this->points; + } + + $length = (empty($points) ? 0 : count($points)); + $firstIndex = 0; + $count = 0; + + for ($i = 0; $i < $length; $i++) { + $count++; + + if ($points[$i]["endOfContour"]) { + $path .= $this->getSVGPath($points, $firstIndex, $count); + $firstIndex = $i + 1; + $count = 0; + } + } + + return $path; + } + + protected function getSVGPath($points, $startIndex, $count) { + $offset = 0; + $path = ""; + + while ($offset < $count) { + $point = $points[$startIndex + $offset % $count]; + $point_p1 = $points[$startIndex + ($offset + 1) % $count]; + + if ($offset == 0) { + $path .= "M{$point['x']},{$point['y']} "; + } + + if ($point["onCurve"]) { + if ($point_p1["onCurve"]) { + $path .= "L{$point_p1['x']},{$point_p1['y']} "; + $offset++; + } + else { + $point_p2 = $points[$startIndex + ($offset + 2) % $count]; + + if ($point_p2["onCurve"]) { + $path .= "Q{$point_p1['x']},{$point_p1['y']},{$point_p2['x']},{$point_p2['y']} "; + } + else { + $path .= "Q{$point_p1['x']},{$point_p1['y']}," . $this->midValue($point_p1['x'], $point_p2['x']) . "," . $this->midValue($point_p1['y'], $point_p2['y']) . " "; + } + + $offset += 2; + } + } + else { + if ($point_p1["onCurve"]) { + $path .= "Q{$point['x']},{$point['y']},{$point_p1['x']},{$point_p1['y']} "; + } + else { + $path .= "Q{$point['x']},{$point['y']}," . $this->midValue($point['x'], $point_p1['x']) . "," . $this->midValue($point['y'], $point_p1['y']) . " "; + } + + $offset++; + } + } + + $path .= "z "; + + return $path; + } + + function midValue($a, $b) { + return $a + ($b - $a) / 2; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Header.php b/vendor/phenx/php-font-lib/src/FontLib/Header.php new file mode 100644 index 0000000..cbf137e --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Header.php @@ -0,0 +1,37 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib; + +use FontLib\TrueType\File; + +/** + * Font header container. + * + * @package php-font-lib + */ +abstract class Header extends BinaryStream { + /** + * @var File + */ + protected $font; + protected $def = array(); + + public $data; + + public function __construct(File $font) { + $this->font = $font; + } + + public function encode() { + return $this->font->pack($this->def, $this->data); + } + + public function parse() { + $this->data = $this->font->unpack($this->def); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php b/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php new file mode 100644 index 0000000..9c6df96 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php @@ -0,0 +1,18 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\OpenType; + +/** + * Open Type font, the same as a TrueType one. + * + * @package php-font-lib + */ +class File extends \FontLib\TrueType\File { + // +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php new file mode 100644 index 0000000..dd75a3e --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php @@ -0,0 +1,18 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\OpenType; + +/** + * Open Type Table directory entry, the same as a TrueType one. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends \FontLib\TrueType\TableDirectoryEntry { + +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php new file mode 100644 index 0000000..54a67af --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php @@ -0,0 +1,134 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table; + +use FontLib\TrueType\File; +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Generic Font table directory entry. + * + * @package php-font-lib + */ +class DirectoryEntry extends BinaryStream { + /** + * @var File + */ + protected $font; + + /** + * @var Table + */ + protected $font_table; + + public $entryLength = 4; + + public $tag; + public $checksum; + public $offset; + public $length; + + protected $origF; + + /** + * @param string $data + * + * @return int + */ + static function computeChecksum($data) { + $len = mb_strlen($data, '8bit'); + $mod = $len % 4; + + if ($mod) { + $data = str_pad($data, $len + (4 - $mod), "\0"); + } + + $len = mb_strlen($data, '8bit'); + + $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; + $lo = $lo & 0xFFFF; + $hi = $hi & 0xFFFF; + } + + return ($hi << 8) + $lo; + } + + function __construct(File $font) { + $this->font = $font; + $this->f = $font->f; + } + + function parse() { + $this->tag = $this->font->read(4); + } + + function open($filename, $mode = self::modeRead) { + // void + } + + function setTable(Table $font_table) { + $this->font_table = $font_table; + } + + function encode($entry_offset) { + Font::d("\n==== $this->tag ===="); + //Font::d("Entry offset = $entry_offset"); + + $data = $this->font_table; + $font = $this->font; + + $table_offset = $font->pos(); + $this->offset = $table_offset; + $table_length = $data->encode(); + + $font->seek($table_offset); + $table_data = $font->read($table_length); + + $font->seek($entry_offset); + + $font->write($this->tag, 4); + $font->writeUInt32(self::computeChecksum($table_data)); + $font->writeUInt32($table_offset); + $font->writeUInt32($table_length); + + Font::d("Bytes written = $table_length"); + + $font->seek($table_offset + $table_length); + } + + /** + * @return File + */ + function getFont() { + return $this->font; + } + + function startRead() { + $this->font->seek($this->offset); + } + + function endRead() { + // + } + + function startWrite() { + $this->font->seek($this->offset); + } + + function endWrite() { + // + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php new file mode 100644 index 0000000..b127112 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php @@ -0,0 +1,93 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table; + +use FontLib\TrueType\File; +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Generic font table. + * + * @package php-font-lib + */ +class Table extends BinaryStream { + /** + * @var DirectoryEntry + */ + protected $entry; + protected $def = array(); + + public $data; + + final public function __construct(DirectoryEntry $entry) { + $this->entry = $entry; + $entry->setTable($this); + } + + /** + * @return File + */ + public function getFont() { + return $this->entry->getFont(); + } + + protected function _encode() { + if (empty($this->data)) { + Font::d(" >> Table is empty"); + + return 0; + } + + return $this->getFont()->pack($this->def, $this->data); + } + + protected function _parse() { + $this->data = $this->getFont()->unpack($this->def); + } + + protected function _parseRaw() { + $this->data = $this->getFont()->read($this->entry->length); + } + + protected function _encodeRaw() { + return $this->getFont()->write($this->data, $this->entry->length); + } + + public function toHTML() { + return "
" . var_export($this->data, true) . "
"; + } + + final public function encode() { + $this->entry->startWrite(); + + if (false && empty($this->def)) { + $length = $this->_encodeRaw(); + } + else { + $length = $this->_encode(); + } + + $this->entry->endWrite(); + + return $length; + } + + final public function parse() { + $this->entry->startRead(); + + if (false && empty($this->def)) { + $this->_parseRaw(); + } + else { + $this->_parse(); + } + + $this->entry->endRead(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php new file mode 100644 index 0000000..7db77e1 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php @@ -0,0 +1,298 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `cmap` font table. + * + * @package php-font-lib + */ +class cmap extends Table { + private static $header_format = array( + "version" => self::uint16, + "numberSubtables" => self::uint16, + ); + + private static $subtable_header_format = array( + "platformID" => self::uint16, + "platformSpecificID" => self::uint16, + "offset" => self::uint32, + ); + + private static $subtable_v4_format = array( + "length" => self::uint16, + "language" => self::uint16, + "segCountX2" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + private static $subtable_v12_format = array( + "length" => self::uint32, + "language" => self::uint32, + "ngroups" => self::uint32 + ); + + protected function _parse() { + $font = $this->getFont(); + + $cmap_offset = $font->pos(); + + $data = $font->unpack(self::$header_format); + + $subtables = array(); + for ($i = 0; $i < $data["numberSubtables"]; $i++) { + $subtables[] = $font->unpack(self::$subtable_header_format); + } + + $data["subtables"] = $subtables; + + foreach ($data["subtables"] as $i => &$subtable) { + $font->seek($cmap_offset + $subtable["offset"]); + + $subtable["format"] = $font->readUInt16(); + + // @todo Only CMAP version 4 and 12 + if (($subtable["format"] != 4) && ($subtable["format"] != 12)) { + unset($data["subtables"][$i]); + $data["numberSubtables"]--; + continue; + } + + if ($subtable["format"] == 12) { + + $font->readUInt16(); + + $subtable += $font->unpack(self::$subtable_v12_format); + + $glyphIndexArray = array(); + $endCodes = array(); + $startCodes = array(); + + for ($p = 0; $p < $subtable['ngroups']; $p++) { + + $startCode = $startCodes[] = $font->readUInt32(); + $endCode = $endCodes[] = $font->readUInt32(); + $startGlyphCode = $font->readUInt32(); + + for ($c = $startCode; $c <= $endCode; $c++) { + $glyphIndexArray[$c] = $startGlyphCode; + $startGlyphCode++; + } + } + + $subtable += array( + "startCode" => $startCodes, + "endCode" => $endCodes, + "glyphIndexArray" => $glyphIndexArray, + ); + + } + else if ($subtable["format"] == 4) { + + $subtable += $font->unpack(self::$subtable_v4_format); + + $segCount = $subtable["segCountX2"] / 2; + $subtable["segCount"] = $segCount; + + $endCode = $font->readUInt16Many($segCount); + + $font->readUInt16(); // reservedPad + + $startCode = $font->readUInt16Many($segCount); + $idDelta = $font->readInt16Many($segCount); + + $ro_start = $font->pos(); + $idRangeOffset = $font->readUInt16Many($segCount); + + $glyphIndexArray = array(); + for ($i = 0; $i < $segCount; $i++) { + $c1 = $startCode[$i]; + $c2 = $endCode[$i]; + $d = $idDelta[$i]; + $ro = $idRangeOffset[$i]; + + if ($ro > 0) { + $font->seek($subtable["offset"] + 2 * $i + $ro); + } + + for ($c = $c1; $c <= $c2; $c++) { + if ($ro == 0) { + $gid = ($c + $d) & 0xFFFF; + } + else { + $offset = ($c - $c1) * 2 + $ro; + $offset = $ro_start + 2 * $i + $offset; + + $font->seek($offset); + $gid = $font->readUInt16(); + + if ($gid != 0) { + $gid = ($gid + $d) & 0xFFFF; + } + } + + if ($gid > 0) { + $glyphIndexArray[$c] = $gid; + } + } + } + + $subtable += array( + "endCode" => $endCode, + "startCode" => $startCode, + "idDelta" => $idDelta, + "idRangeOffset" => $idRangeOffset, + "glyphIndexArray" => $glyphIndexArray, + ); + } + } + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + + $subset = $font->getSubset(); + $glyphIndexArray = $font->getUnicodeCharMap(); + + $newGlyphIndexArray = array(); + foreach ($glyphIndexArray as $code => $gid) { + $new_gid = array_search($gid, $subset); + if ($new_gid !== false) { + $newGlyphIndexArray[$code] = $new_gid; + } + } + + ksort($newGlyphIndexArray); // Sort by char code + + $segments = array(); + + $i = -1; + $prevCode = 0xFFFF; + $prevGid = 0xFFFF; + + foreach ($newGlyphIndexArray as $code => $gid) { + if ( + $prevCode + 1 != $code || + $prevGid + 1 != $gid + ) { + $i++; + $segments[$i] = array(); + } + + $segments[$i][] = array($code, $gid); + + $prevCode = $code; + $prevGid = $gid; + } + + $segments[][] = array(0xFFFF, 0xFFFF); + + $startCode = array(); + $endCode = array(); + $idDelta = array(); + + foreach ($segments as $codes) { + $start = reset($codes); + $end = end($codes); + + $startCode[] = $start[0]; + $endCode[] = $end[0]; + $idDelta[] = $start[1] - $start[0]; + } + + $segCount = count($startCode); + $idRangeOffset = array_fill(0, $segCount, 0); + + $searchRange = 1; + $entrySelector = 0; + while ($searchRange * 2 <= $segCount) { + $searchRange *= 2; + $entrySelector++; + } + $searchRange *= 2; + $rangeShift = $segCount * 2 - $searchRange; + + $subtables = array( + array( + // header + "platformID" => 3, // Unicode + "platformSpecificID" => 1, + "offset" => null, + + // subtable + "format" => 4, + "length" => null, + "language" => 0, + "segCount" => $segCount, + "segCountX2" => $segCount * 2, + "searchRange" => $searchRange, + "entrySelector" => $entrySelector, + "rangeShift" => $rangeShift, + "startCode" => $startCode, + "endCode" => $endCode, + "idDelta" => $idDelta, + "idRangeOffset" => $idRangeOffset, + "glyphIndexArray" => $newGlyphIndexArray, + ) + ); + + $data = array( + "version" => 0, + "numberSubtables" => count($subtables), + "subtables" => $subtables, + ); + + $length = $font->pack(self::$header_format, $data); + + $subtable_headers_size = $data["numberSubtables"] * 8; // size of self::$subtable_header_format + $subtable_headers_offset = $font->pos(); + + $length += $font->write(str_repeat("\0", $subtable_headers_size), $subtable_headers_size); + + // write subtables data + foreach ($data["subtables"] as $i => $subtable) { + $length_before = $length; + $data["subtables"][$i]["offset"] = $length; + + $length += $font->writeUInt16($subtable["format"]); + + $before_subheader = $font->pos(); + $length += $font->pack(self::$subtable_v4_format, $subtable); + + $segCount = $subtable["segCount"]; + $length += $font->w(array(self::uint16, $segCount), $subtable["endCode"]); + $length += $font->writeUInt16(0); // reservedPad + $length += $font->w(array(self::uint16, $segCount), $subtable["startCode"]); + $length += $font->w(array(self::int16, $segCount), $subtable["idDelta"]); + $length += $font->w(array(self::uint16, $segCount), $subtable["idRangeOffset"]); + $length += $font->w(array(self::uint16, $segCount), array_values($subtable["glyphIndexArray"])); + + $after_subtable = $font->pos(); + + $subtable["length"] = $length - $length_before; + $font->seek($before_subheader); + $length += $font->pack(self::$subtable_v4_format, $subtable); + + $font->seek($after_subtable); + } + + // write subtables headers + $font->seek($subtable_headers_offset); + foreach ($data["subtables"] as $subtable) { + $font->pack(self::$subtable_header_format, $subtable); + } + + return $length; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php new file mode 100644 index 0000000..1fbec3f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php @@ -0,0 +1,154 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; + +use FontLib\Table\Table; +use FontLib\Glyph\Outline; +use FontLib\Glyph\OutlineSimple; + +/** + * `glyf` font table. + * + * @package php-font-lib + * @property Outline[] $data + */ +class glyf extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $loca = $font->getData("loca"); + $real_loca = array_slice($loca, 0, -1); // Not the last dummy loca entry + + $data = array(); + + foreach ($real_loca as $gid => $location) { + $_offset = $offset + $loca[$gid]; + $_size = $loca[$gid + 1] - $loca[$gid]; + $data[$gid] = Outline::init($this, $_offset, $_size, $font); + } + + $this->data = $data; + } + + public function getGlyphIDs($gids = array()) { + $glyphIDs = array(); + + foreach ($gids as $_gid) { + $_glyph = $this->data[$_gid]; + $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs()); + } + + return array_unique(array_merge($gids, $glyphIDs)); + } + + public function toHTML() { + $max = 160; + $font = $this->getFont(); + + $head = $font->getData("head"); + $head_json = json_encode($head); + + $os2 = $font->getData("OS/2"); + $os2_json = json_encode($os2); + + $hmtx = $font->getData("hmtx"); + $hmtx_json = json_encode($hmtx); + + $names = $font->getData("post", "names"); + $glyphIndexArray = array_flip($font->getUnicodeCharMap()); + + $width = (abs($head["xMin"]) + $head["xMax"]); + $height = (abs($head["yMin"]) + $head["yMax"]); + + $ratio = 1; + if ($width > $max || $height > $max) { + $ratio = max($width, $height) / $max; + $width = round($width / $ratio); + $height = round($height / $ratio); + } + + $n = 500; + + $s = "

" . "Only the first $n simple glyphs are shown (" . count($this->data) . " total) +
Simple glyph
+
Composite glyph
+ Zoom: +

+ "; + + foreach ($this->data as $g => $glyph) { + if ($n-- <= 0) { + break; + } + + $glyph->parseData(); + + $shape = array( + "SVGContours" => $glyph->getSVGContours(), + "xMin" => $glyph->xMin, + "yMin" => $glyph->yMin, + "xMax" => $glyph->xMax, + "yMax" => $glyph->yMax, + ); + $shape_json = json_encode($shape); + + $type = ($glyph instanceof OutlineSimple ? "simple" : "composite"); + $char = isset($glyphIndexArray[$g]) ? $glyphIndexArray[$g] : 0; + $name = isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $char); + $char = $char ? "&#{$glyphIndexArray[$g]};" : ""; + + $s .= "
+ $g + $char + $name + "; + + if ($type == "composite") { + foreach ($glyph->getGlyphIDs() as $_id) { + $s .= "$_id "; + } + } + + $s .= "
+ +
+ "; + } + + return $s; + } + + + protected function _encode() { + $font = $this->getFont(); + $subset = $font->getSubset(); + $data = $this->data; + + $loca = array(); + + $length = 0; + foreach ($subset as $gid) { + $loca[] = $length; + $length += $data[$gid]->encode(); + } + + $loca[] = $length; // dummy loca + $font->getTableObject("loca")->data = $loca; + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php new file mode 100644 index 0000000..6349f14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php @@ -0,0 +1,46 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; +use Exception; + +/** + * `head` font table. + * + * @package php-font-lib + */ +class head extends Table { + protected $def = array( + "tableVersion" => self::Fixed, + "fontRevision" => self::Fixed, + "checkSumAdjustment" => self::uint32, + "magicNumber" => self::uint32, + "flags" => self::uint16, + "unitsPerEm" => self::uint16, + "created" => self::longDateTime, + "modified" => self::longDateTime, + "xMin" => self::FWord, + "yMin" => self::FWord, + "xMax" => self::FWord, + "yMax" => self::FWord, + "macStyle" => self::uint16, + "lowestRecPPEM" => self::uint16, + "fontDirectionHint" => self::int16, + "indexToLocFormat" => self::int16, + "glyphDataFormat" => self::int16, + ); + + protected function _parse() { + parent::_parse(); + + if ($this->data["magicNumber"] != 0x5F0F3CF5) { + throw new Exception("Incorrect magic number (" . dechex($this->data["magicNumber"]) . ")"); + } + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php new file mode 100644 index 0000000..dc60a14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php @@ -0,0 +1,44 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `hhea` font table. + * + * @package php-font-lib + */ +class hhea extends Table { + protected $def = array( + "version" => self::Fixed, + "ascent" => self::FWord, + "descent" => self::FWord, + "lineGap" => self::FWord, + "advanceWidthMax" => self::uFWord, + "minLeftSideBearing" => self::FWord, + "minRightSideBearing" => self::FWord, + "xMaxExtent" => self::FWord, + "caretSlopeRise" => self::int16, + "caretSlopeRun" => self::int16, + "caretOffset" => self::FWord, + self::int16, + self::int16, + self::int16, + self::int16, + "metricDataFormat" => self::int16, + "numOfLongHorMetrics" => self::uint16, + ); + + function _encode() { + $font = $this->getFont(); + $this->data["numOfLongHorMetrics"] = count($font->getSubset()); + + return parent::_encode(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php new file mode 100644 index 0000000..76e3307 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php @@ -0,0 +1,59 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `hmtx` font table. + * + * @package php-font-lib + */ +class hmtx extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $numOfLongHorMetrics = $font->getData("hhea", "numOfLongHorMetrics"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + + $font->seek($offset); + + $data = array(); + $metrics = $font->readUInt16Many($numOfLongHorMetrics * 2); + for ($gid = 0, $mid = 0; $gid < $numOfLongHorMetrics; $gid++) { + $advanceWidth = isset($metrics[$mid]) ? $metrics[$mid] : 0; + $mid += 1; + $leftSideBearing = isset($metrics[$mid]) ? $metrics[$mid] : 0; + $mid += 1; + $data[$gid] = array($advanceWidth, $leftSideBearing); + } + + if ($numOfLongHorMetrics < $numGlyphs) { + $lastWidth = end($data); + $data = array_pad($data, $numGlyphs, $lastWidth); + } + + $this->data = $data; + } + + protected function _encode() { + $font = $this->getFont(); + $subset = $font->getSubset(); + $data = $this->data; + + $length = 0; + + foreach ($subset as $gid) { + $length += $font->writeUInt16($data[$gid][0]); + $length += $font->writeUInt16($data[$gid][1]); + } + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php new file mode 100644 index 0000000..9875946 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php @@ -0,0 +1,80 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `kern` font table. + * + * @package php-font-lib + */ +class kern extends Table { + protected function _parse() { + $font = $this->getFont(); + + $data = $font->unpack(array( + "version" => self::uint16, + "nTables" => self::uint16, + + // only the first subtable will be parsed + "subtableVersion" => self::uint16, + "length" => self::uint16, + "coverage" => self::uint16, + )); + + $data["format"] = ($data["coverage"] >> 8); + + $subtable = array(); + + switch ($data["format"]) { + case 0: + $subtable = $font->unpack(array( + "nPairs" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + )); + + $pairs = array(); + $tree = array(); + + $values = $font->readUInt16Many($subtable["nPairs"] * 3); + for ($i = 0, $idx = 0; $i < $subtable["nPairs"]; $i++) { + $left = $values[$idx++]; + $right = $values[$idx++]; + $value = $values[$idx++]; + + if ($value >= 0x8000) { + $value -= 0x10000; + } + + $pairs[] = array( + "left" => $left, + "right" => $right, + "value" => $value, + ); + + $tree[$left][$right] = $value; + } + + //$subtable["pairs"] = $pairs; + $subtable["tree"] = $tree; + break; + + case 1: + case 2: + case 3: + break; + } + + $data["subtable"] = $subtable; + + $this->data = $data; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php new file mode 100644 index 0000000..cbc2a20 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php @@ -0,0 +1,80 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `loca` font table. + * + * @package php-font-lib + */ +class loca extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $indexToLocFormat = $font->getData("head", "indexToLocFormat"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + + $font->seek($offset); + + $data = array(); + + // 2 bytes + if ($indexToLocFormat == 0) { + $d = $font->read(($numGlyphs + 1) * 2); + $loc = unpack("n*", $d); + + for ($i = 0; $i <= $numGlyphs; $i++) { + $data[] = isset($loc[$i + 1]) ? $loc[$i + 1] * 2 : 0; + } + } + + // 4 bytes + else { + if ($indexToLocFormat == 1) { + $d = $font->read(($numGlyphs + 1) * 4); + $loc = unpack("N*", $d); + + for ($i = 0; $i <= $numGlyphs; $i++) { + $data[] = isset($loc[$i + 1]) ? $loc[$i + 1] : 0; + } + } + } + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + $data = $this->data; + + $indexToLocFormat = $font->getData("head", "indexToLocFormat"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + $length = 0; + + // 2 bytes + if ($indexToLocFormat == 0) { + for ($i = 0; $i <= $numGlyphs; $i++) { + $length += $font->writeUInt16($data[$i] / 2); + } + } + + // 4 bytes + else { + if ($indexToLocFormat == 1) { + for ($i = 0; $i <= $numGlyphs; $i++) { + $length += $font->writeUInt32($data[$i]); + } + } + } + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php new file mode 100644 index 0000000..b4ebae0 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php @@ -0,0 +1,42 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `maxp` font table. + * + * @package php-font-lib + */ +class maxp extends Table { + protected $def = array( + "version" => self::Fixed, + "numGlyphs" => self::uint16, + "maxPoints" => self::uint16, + "maxContours" => self::uint16, + "maxComponentPoints" => self::uint16, + "maxComponentContours" => self::uint16, + "maxZones" => self::uint16, + "maxTwilightPoints" => self::uint16, + "maxStorage" => self::uint16, + "maxFunctionDefs" => self::uint16, + "maxInstructionDefs" => self::uint16, + "maxStackElements" => self::uint16, + "maxSizeOfInstructions" => self::uint16, + "maxComponentElements" => self::uint16, + "maxComponentDepth" => self::uint16, + ); + + function _encode() { + $font = $this->getFont(); + $this->data["numGlyphs"] = count($font->getSubset()); + + return parent::_encode(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php new file mode 100644 index 0000000..794824d --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php @@ -0,0 +1,193 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; + +use FontLib\Table\Table; +use FontLib\Font; + +/** + * `name` font table. + * + * @package php-font-lib + */ +class name extends Table { + private static $header_format = array( + "format" => self::uint16, + "count" => self::uint16, + "stringOffset" => self::uint16, + ); + + const NAME_COPYRIGHT = 0; + const NAME_NAME = 1; + const NAME_SUBFAMILY = 2; + const NAME_SUBFAMILY_ID = 3; + const NAME_FULL_NAME = 4; + const NAME_VERSION = 5; + const NAME_POSTSCRIPT_NAME = 6; + const NAME_TRADEMARK = 7; + const NAME_MANUFACTURER = 8; + const NAME_DESIGNER = 9; + const NAME_DESCRIPTION = 10; + const NAME_VENDOR_URL = 11; + const NAME_DESIGNER_URL = 12; + const NAME_LICENSE = 13; + const NAME_LICENSE_URL = 14; + const NAME_PREFERRE_FAMILY = 16; + const NAME_PREFERRE_SUBFAMILY = 17; + const NAME_COMPAT_FULL_NAME = 18; + const NAME_SAMPLE_TEXT = 19; + + static $nameIdCodes = array( + 0 => "Copyright", + 1 => "FontName", + 2 => "FontSubfamily", + 3 => "UniqueID", + 4 => "FullName", + 5 => "Version", + 6 => "PostScriptName", + 7 => "Trademark", + 8 => "Manufacturer", + 9 => "Designer", + 10 => "Description", + 11 => "FontVendorURL", + 12 => "FontDesignerURL", + 13 => "LicenseDescription", + 14 => "LicenseURL", + // 15 + 16 => "PreferredFamily", + 17 => "PreferredSubfamily", + 18 => "CompatibleFullName", + 19 => "SampleText", + ); + + static $platforms = array( + 0 => "Unicode", + 1 => "Macintosh", + // 2 => Reserved + 3 => "Microsoft", + ); + + static $platformSpecific = array( + // Unicode + 0 => array( + 0 => "Default semantics", + 1 => "Version 1.1 semantics", + 2 => "ISO 10646 1993 semantics (deprecated)", + 3 => "Unicode 2.0 or later semantics", + ), + + // Macintosh + 1 => array( + 0 => "Roman", + 1 => "Japanese", + 2 => "Traditional Chinese", + 3 => "Korean", + 4 => "Arabic", + 5 => "Hebrew", + 6 => "Greek", + 7 => "Russian", + 8 => "RSymbol", + 9 => "Devanagari", + 10 => "Gurmukhi", + 11 => "Gujarati", + 12 => "Oriya", + 13 => "Bengali", + 14 => "Tamil", + 15 => "Telugu", + 16 => "Kannada", + 17 => "Malayalam", + 18 => "Sinhalese", + 19 => "Burmese", + 20 => "Khmer", + 21 => "Thai", + 22 => "Laotian", + 23 => "Georgian", + 24 => "Armenian", + 25 => "Simplified Chinese", + 26 => "Tibetan", + 27 => "Mongolian", + 28 => "Geez", + 29 => "Slavic", + 30 => "Vietnamese", + 31 => "Sindhi", + ), + + // Microsoft + 3 => array( + 0 => "Symbol", + 1 => "Unicode BMP (UCS-2)", + 2 => "ShiftJIS", + 3 => "PRC", + 4 => "Big5", + 5 => "Wansung", + 6 => "Johab", + // 7 => Reserved + // 8 => Reserved + // 9 => Reserved + 10 => "Unicode UCS-4", + ), + ); + + protected function _parse() { + $font = $this->getFont(); + + $tableOffset = $font->pos(); + + $data = $font->unpack(self::$header_format); + + $records = array(); + for ($i = 0; $i < $data["count"]; $i++) { + $record = new nameRecord(); + $record_data = $font->unpack(nameRecord::$format); + $record->map($record_data); + + $records[] = $record; + } + + $names = array(); + foreach ($records as $record) { + $font->seek($tableOffset + $data["stringOffset"] + $record->offset); + $s = $font->read($record->length); + $record->string = Font::UTF16ToUTF8($s); + $names[$record->nameID] = $record; + } + + $data["records"] = $names; + + $this->data = $data; + } + + protected function _encode() { + $font = $this->getFont(); + + /** @var nameRecord[] $records */ + $records = $this->data["records"]; + $count_records = count($records); + + $this->data["count"] = $count_records; + $this->data["stringOffset"] = 6 + $count_records * 12; // 6 => uint16 * 3, 12 => sizeof self::$record_format + + $length = $font->pack(self::$header_format, $this->data); + + $offset = 0; + foreach ($records as $record) { + $record->length = mb_strlen($record->getUTF16(), "8bit"); + $record->offset = $offset; + $offset += $record->length; + $length += $font->pack(nameRecord::$format, (array)$record); + } + + foreach ($records as $record) { + $str = $record->getUTF16(); + $length += $font->write($str, mb_strlen($str, "8bit")); + } + + return $length; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php new file mode 100644 index 0000000..2073c20 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php @@ -0,0 +1,53 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table\Type; + +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Font table name record. + * + * @package php-font-lib + */ +class nameRecord extends BinaryStream { + public $platformID; + public $platformSpecificID; + public $languageID; + public $nameID; + public $length; + public $offset; + public $string; + + public static $format = array( + "platformID" => self::uint16, + "platformSpecificID" => self::uint16, + "languageID" => self::uint16, + "nameID" => self::uint16, + "length" => self::uint16, + "offset" => self::uint16, + ); + + public function map($data) { + foreach ($data as $key => $value) { + $this->$key = $value; + } + } + + public function getUTF8() { + return $this->string; + } + + public function getUTF16() { + return Font::UTF8ToUTF16($this->string); + } + + function __toString() { + return $this->string; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php new file mode 100644 index 0000000..19a3e21 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php @@ -0,0 +1,47 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `OS/2` font table. + * + * @package php-font-lib + */ +class os2 extends Table { + protected $def = array( + "version" => self::uint16, + "xAvgCharWidth" => self::int16, + "usWeightClass" => self::uint16, + "usWidthClass" => self::uint16, + "fsType" => self::int16, + "ySubscriptXSize" => self::int16, + "ySubscriptYSize" => self::int16, + "ySubscriptXOffset" => self::int16, + "ySubscriptYOffset" => self::int16, + "ySuperscriptXSize" => self::int16, + "ySuperscriptYSize" => self::int16, + "ySuperscriptXOffset" => self::int16, + "ySuperscriptYOffset" => self::int16, + "yStrikeoutSize" => self::int16, + "yStrikeoutPosition" => self::int16, + "sFamilyClass" => self::int16, + "panose" => array(self::uint8, 10), + "ulCharRange" => array(self::uint32, 4), + "achVendID" => array(self::char, 4), + "fsSelection" => self::uint16, + "fsFirstCharIndex" => self::uint16, + "fsLastCharIndex" => self::uint16, + "typoAscender" => self::int16, + "typoDescender" => self::int16, + "typoLineGap" => self::int16, + "winAscent" => self::int16, + "winDescent" => self::int16, + ); +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php new file mode 100644 index 0000000..030a942 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php @@ -0,0 +1,143 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; +use FontLib\TrueType\File; + +/** + * `post` font table. + * + * @package php-font-lib + */ +class post extends Table { + protected $def = array( + "format" => self::Fixed, + "italicAngle" => self::Fixed, + "underlinePosition" => self::FWord, + "underlineThickness" => self::FWord, + "isFixedPitch" => self::uint32, + "minMemType42" => self::uint32, + "maxMemType42" => self::uint32, + "minMemType1" => self::uint32, + "maxMemType1" => self::uint32, + ); + + protected function _parse() { + $font = $this->getFont(); + $data = $font->unpack($this->def); + + $names = array(); + + switch ($data["format"]) { + case 1: + $names = File::$macCharNames; + break; + + case 2: + $data["numberOfGlyphs"] = $font->readUInt16(); + + $glyphNameIndex = $font->readUInt16Many($data["numberOfGlyphs"]); + + $data["glyphNameIndex"] = $glyphNameIndex; + + $namesPascal = array(); + for ($i = 0; $i < $data["numberOfGlyphs"]; $i++) { + $len = $font->readUInt8(); + $namesPascal[] = $font->read($len); + } + + foreach ($glyphNameIndex as $g => $index) { + if ($index < 258) { + $names[$g] = File::$macCharNames[$index]; + } + else { + if (array_key_exists($index - 258, $namesPascal)) { + $names[$g] = $namesPascal[$index - 258]; + } + } + } + + break; + + case 2.5: + // TODO + break; + + case 3: + // nothing + break; + + case 4: + // TODO + break; + } + + $data["names"] = $names; + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + $data = $this->data; + $data["format"] = 3; + + $length = $font->pack($this->def, $data); + + return $length; + /* + $subset = $font->getSubset(); + + switch($data["format"]) { + case 1: + // nothing to do + break; + + case 2: + $old_names = $data["names"]; + + $glyphNameIndex = range(0, count($subset)); + + $names = array(); + foreach($subset as $gid) { + $names[] = $data["names"][$data["glyphNameIndex"][$gid]]; + } + + $numberOfGlyphs = count($names); + $length += $font->writeUInt16($numberOfGlyphs); + + foreach($glyphNameIndex as $gni) { + $length += $font->writeUInt16($gni); + } + + //$names = array_slice($names, 257); + foreach($names as $name) { + $len = strlen($name); + $length += $font->writeUInt8($len); + $length += $font->write($name, $len); + } + + break; + + case 2.5: + // TODO + break; + + case 3: + // nothing + break; + + case 4: + // TODO + break; + } + + return $length;*/ + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php new file mode 100644 index 0000000..460ef4d --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php @@ -0,0 +1,100 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use Countable; +use FontLib\BinaryStream; +use Iterator; +use OutOfBoundsException; + +/** + * TrueType collection font file. + * + * @package php-font-lib + */ +class Collection extends BinaryStream implements Iterator, Countable { + /** + * Current iterator position. + * + * @var integer + */ + private $position = 0; + + protected $collectionOffsets = array(); + protected $collection = array(); + protected $version; + protected $numFonts; + + function parse() { + if (isset($this->numFonts)) { + return; + } + + $this->read(4); // tag name + + $this->version = $this->readFixed(); + $this->numFonts = $this->readUInt32(); + + for ($i = 0; $i < $this->numFonts; $i++) { + $this->collectionOffsets[] = $this->readUInt32(); + } + } + + /** + * @param int $fontId + * + * @throws OutOfBoundsException + * @return File + */ + function getFont($fontId) { + $this->parse(); + + if (!isset($this->collectionOffsets[$fontId])) { + throw new OutOfBoundsException(); + } + + if (isset($this->collection[$fontId])) { + return $this->collection[$fontId]; + } + + $font = new File(); + $font->f = $this->f; + $font->setTableOffset($this->collectionOffsets[$fontId]); + + return $this->collection[$fontId] = $font; + } + + function current() { + return $this->getFont($this->position); + } + + function key() { + return $this->position; + } + + function next() { + return ++$this->position; + } + + function rewind() { + $this->position = 0; + } + + function valid() { + $this->parse(); + + return isset($this->collectionOffsets[$this->position]); + } + + function count() { + $this->parse(); + + return $this->numFonts; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php new file mode 100644 index 0000000..3594479 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php @@ -0,0 +1,471 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use FontLib\AdobeFontMetrics; +use FontLib\Font; +use FontLib\BinaryStream; +use FontLib\Table\Table; +use FontLib\Table\DirectoryEntry; +use FontLib\Table\Type\glyf; +use FontLib\Table\Type\name; +use FontLib\Table\Type\nameRecord; + +/** + * TrueType font file. + * + * @package php-font-lib + */ +class File extends BinaryStream { + /** + * @var Header + */ + public $header = array(); + + private $tableOffset = 0; // Used for TTC + + private static $raw = false; + + protected $directory = array(); + protected $data = array(); + + protected $glyph_subset = array(); + + public $glyph_all = array(); + + static $macCharNames = array( + ".notdef", ".null", "CR", + "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quotesingle", + "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", + "zero", "one", "two", "three", + "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", + "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "asciicircum", "underscore", + "grave", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", + "Aring", "Ccedilla", "Eacute", "Ntilde", + "Odieresis", "Udieresis", "aacute", "agrave", + "acircumflex", "adieresis", "atilde", "aring", + "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", + "idieresis", "ntilde", "oacute", "ograve", + "ocircumflex", "odieresis", "otilde", "uacute", + "ugrave", "ucircumflex", "udieresis", "dagger", + "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", + "copyright", "trademark", "acute", "dieresis", + "notequal", "AE", "Oslash", "infinity", + "plusminus", "lessequal", "greaterequal", "yen", + "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", + "Omega", "ae", "oslash", "questiondown", + "exclamdown", "logicalnot", "radical", "florin", + "approxequal", "increment", "guillemotleft", "guillemotright", + "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", + "emdash", "quotedblleft", "quotedblright", "quoteleft", + "quoteright", "divide", "lozenge", "ydieresis", + "Ydieresis", "fraction", "currency", "guilsinglleft", + "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", + "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", + "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Oacute", "Ocircumflex", "applelogo", + "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", + "breve", "dotaccent", "ring", "cedilla", + "hungarumlaut", "ogonek", "caron", "Lslash", + "lslash", "Scaron", "scaron", "Zcaron", + "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", + "minus", "multiply", "onesuperior", "twosuperior", + "threesuperior", "onehalf", "onequarter", "threequarters", + "franc", "Gbreve", "gbreve", "Idot", + "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron" + ); + + function getTable() { + $this->parseTableEntries(); + + return $this->directory; + } + + function setTableOffset($offset) { + $this->tableOffset = $offset; + } + + function parse() { + $this->parseTableEntries(); + + $this->data = array(); + + foreach ($this->directory as $tag => $table) { + if (empty($this->data[$tag])) { + $this->readTable($tag); + } + } + } + + function utf8toUnicode($str) { + $len = mb_strlen($str, '8bit'); + $out = array(); + + for ($i = 0; $i < $len; $i++) { + $uni = -1; + $h = ord($str[$i]); + + if ($h <= 0x7F) { + $uni = $h; + } + elseif ($h >= 0xC2) { + if (($h <= 0xDF) && ($i < $len - 1)) { + $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xEF) && ($i < $len - 2)) { + $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xF4) && ($i < $len - 3)) { + $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + } + + if ($uni >= 0) { + $out[] = $uni; + } + } + + return $out; + } + + function getUnicodeCharMap() { + $subtable = null; + foreach ($this->getData("cmap", "subtables") as $_subtable) { + if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { + $subtable = $_subtable; + break; + } + } + + if ($subtable) { + return $subtable["glyphIndexArray"]; + } + + return null; + } + + function setSubset($subset) { + if (!is_array($subset)) { + $subset = $this->utf8toUnicode($subset); + } + + $subset = array_unique($subset); + + $glyphIndexArray = $this->getUnicodeCharMap(); + + if (!$glyphIndexArray) { + return; + } + + $gids = array( + 0, // .notdef + 1, // .null + ); + + foreach ($subset as $code) { + if (!isset($glyphIndexArray[$code])) { + continue; + } + + $gid = $glyphIndexArray[$code]; + $gids[$gid] = $gid; + } + + /** @var glyf $glyf */ + $glyf = $this->getTableObject("glyf"); + $gids = $glyf->getGlyphIDs($gids); + + sort($gids); + + $this->glyph_subset = $gids; + $this->glyph_all = array_values($glyphIndexArray); // FIXME + } + + function getSubset() { + if (empty($this->glyph_subset)) { + return $this->glyph_all; + } + + return $this->glyph_subset; + } + + function encode($tags = array()) { + if (!self::$raw) { + $tags = array_merge(array("head", "hhea", "cmap", "hmtx", "maxp", "glyf", "loca", "name", "post"), $tags); + } + else { + $tags = array_keys($this->directory); + } + + $num_tables = count($tags); + $n = 16; // @todo + + Font::d("Tables : " . implode(", ", $tags)); + + /** @var DirectoryEntry[] $entries */ + $entries = array(); + foreach ($tags as $tag) { + if (!isset($this->directory[$tag])) { + Font::d(" >> '$tag' table doesn't exist"); + continue; + } + + $entries[$tag] = $this->directory[$tag]; + } + + $this->header->data["numTables"] = $num_tables; + $this->header->encode(); + + $directory_offset = $this->pos(); + $offset = $directory_offset + $num_tables * $n; + $this->seek($offset); + + $i = 0; + foreach ($entries as $entry) { + $entry->encode($directory_offset + $i * $n); + $i++; + } + } + + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->seek($this->tableOffset); + + $this->header = new Header($this); + $this->header->parse(); + } + + function getFontType(){ + $class_parts = explode("\\", get_class($this)); + return $class_parts[1]; + } + + function parseTableEntries() { + $this->parseHeader(); + + if (!empty($this->directory)) { + return; + } + + if (empty($this->header->data["numTables"])) { + return; + } + + + $type = $this->getFontType(); + $class = "FontLib\\$type\\TableDirectoryEntry"; + + for ($i = 0; $i < $this->header->data["numTables"]; $i++) { + /** @var TableDirectoryEntry $entry */ + $entry = new $class($this); + $entry->parse(); + + $this->directory[$entry->tag] = $entry; + } + } + + function normalizeFUnit($value, $base = 1000) { + return round($value * ($base / $this->getData("head", "unitsPerEm"))); + } + + protected function readTable($tag) { + $this->parseTableEntries(); + + if (!self::$raw) { + $name_canon = preg_replace("/[^a-z0-9]/", "", strtolower($tag)); + + $class = "FontLib\\Table\\Type\\$name_canon"; + + if (!isset($this->directory[$tag]) || !@class_exists($class)) { + return; + } + } + else { + $class = "FontLib\\Table\\Table"; + } + + /** @var Table $table */ + $table = new $class($this->directory[$tag]); + $table->parse(); + + $this->data[$tag] = $table; + } + + /** + * @param $name + * + * @return Table + */ + public function getTableObject($name) { + return $this->data[$name]; + } + + public function setTableObject($name, Table $data) { + $this->data[$name] = $data; + } + + public function getData($name, $key = null) { + $this->parseTableEntries(); + + if (empty($this->data[$name])) { + $this->readTable($name); + } + + if (!isset($this->data[$name])) { + return null; + } + + if (!$key) { + return $this->data[$name]->data; + } + else { + return $this->data[$name]->data[$key]; + } + } + + function addDirectoryEntry(DirectoryEntry $entry) { + $this->directory[$entry->tag] = $entry; + } + + function saveAdobeFontMetrics($file, $encoding = null) { + $afm = new AdobeFontMetrics($this); + $afm->write($file, $encoding); + } + + /** + * Get a specific name table string value from its ID + * + * @param int $nameID The name ID + * + * @return string|null + */ + function getNameTableString($nameID) { + /** @var nameRecord[] $records */ + $records = $this->getData("name", "records"); + + if (!isset($records[$nameID])) { + return null; + } + + return $records[$nameID]->string; + } + + /** + * Get font copyright + * + * @return string|null + */ + function getFontCopyright() { + return $this->getNameTableString(name::NAME_COPYRIGHT); + } + + /** + * Get font name + * + * @return string|null + */ + function getFontName() { + return $this->getNameTableString(name::NAME_NAME); + } + + /** + * Get font subfamily + * + * @return string|null + */ + function getFontSubfamily() { + return $this->getNameTableString(name::NAME_SUBFAMILY); + } + + /** + * Get font subfamily ID + * + * @return string|null + */ + function getFontSubfamilyID() { + return $this->getNameTableString(name::NAME_SUBFAMILY_ID); + } + + /** + * Get font full name + * + * @return string|null + */ + function getFontFullName() { + return $this->getNameTableString(name::NAME_FULL_NAME); + } + + /** + * Get font version + * + * @return string|null + */ + function getFontVersion() { + return $this->getNameTableString(name::NAME_VERSION); + } + + /** + * Get font weight + * + * @return string|null + */ + function getFontWeight() { + return $this->getTableObject("OS/2")->data["usWeightClass"]; + } + + /** + * Get font Postscript name + * + * @return string|null + */ + function getFontPostscriptName() { + return $this->getNameTableString(name::NAME_POSTSCRIPT_NAME); + } + + function reduce() { + $names_to_keep = array( + name::NAME_COPYRIGHT, + name::NAME_NAME, + name::NAME_SUBFAMILY, + name::NAME_SUBFAMILY_ID, + name::NAME_FULL_NAME, + name::NAME_VERSION, + name::NAME_POSTSCRIPT_NAME, + ); + + foreach ($this->data["name"]->data["records"] as $id => $rec) { + if (!in_array($id, $names_to_keep)) { + unset($this->data["name"]->data["records"][$id]); + } + } + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php new file mode 100644 index 0000000..7ff79cc --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +/** + * TrueType font file header. + * + * @package php-font-lib + */ +class Header extends \FontLib\Header { + protected $def = array( + "format" => self::uint32, + "numTables" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + public function parse() { + parent::parse(); + + $format = $this->data["format"]; + $this->data["formatText"] = $this->convertUInt32ToStr($format); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php new file mode 100644 index 0000000..fc4fe55 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php @@ -0,0 +1,33 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use FontLib\Table\DirectoryEntry; + +/** + * TrueType table directory entry. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends DirectoryEntry { + function __construct(File $font) { + parent::__construct($font); + } + + function parse() { + parent::parse(); + + $font = $this->font; + $this->checksum = $font->readUInt32(); + $this->offset = $font->readUInt32(); + $this->length = $font->readUInt32(); + $this->entryLength += 12; + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php new file mode 100644 index 0000000..4668c23 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php @@ -0,0 +1,81 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +use FontLib\Table\DirectoryEntry; + +/** + * WOFF font file. + * + * @package php-font-lib + * + * @property TableDirectoryEntry[] $directory + */ +class File extends \FontLib\TrueType\File { + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->header = new Header($this); + $this->header->parse(); + } + + public function load($file) { + parent::load($file); + + $this->parseTableEntries(); + $dataOffset = $this->pos() + count($this->directory) * 20; + + $fw = $this->getTempFile(false); + $fr = $this->f; + + $this->f = $fw; + $offset = $this->header->encode(); + + foreach ($this->directory as $entry) { + // Read ... + $this->f = $fr; + $this->seek($entry->offset); + $data = $this->read($entry->length); + + if ($entry->length < $entry->origLength) { + $data = (string) gzuncompress($data); + } + + // Prepare data ... + $length = mb_strlen($data, '8bit'); + $entry->length = $entry->origLength = $length; + $entry->offset = $dataOffset; + + // Write ... + $this->f = $fw; + + // Woff Entry + $this->seek($offset); + $offset += $this->write($entry->tag, 4); // tag + $offset += $this->writeUInt32($dataOffset); // offset + $offset += $this->writeUInt32($length); // length + $offset += $this->writeUInt32($length); // origLength + $offset += $this->writeUInt32(DirectoryEntry::computeChecksum($data)); // checksum + + // Data + $this->seek($dataOffset); + $dataOffset += $this->write($data, $length); + } + + $this->f = $fw; + $this->seek(0); + + // Need to re-parse this, don't know why + $this->header = null; + $this->directory = array(); + $this->parseTableEntries(); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php new file mode 100644 index 0000000..65a6f14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php @@ -0,0 +1,32 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +/** + * WOFF font file header. + * + * @package php-font-lib + */ +class Header extends \FontLib\TrueType\Header { + protected $def = array( + "format" => self::uint32, + "flavor" => self::uint32, + "length" => self::uint32, + "numTables" => self::uint16, + self::uint16, + "totalSfntSize" => self::uint32, + "majorVersion" => self::uint16, + "minorVersion" => self::uint16, + "metaOffset" => self::uint32, + "metaLength" => self::uint32, + "metaOrigLength" => self::uint32, + "privOffset" => self::uint32, + "privLength" => self::uint32, + ); +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php new file mode 100644 index 0000000..eb67c9c --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php @@ -0,0 +1,34 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +use FontLib\Table\DirectoryEntry; + +/** + * WOFF font file table directory entry. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends DirectoryEntry { + public $origLength; + + function __construct(File $font) { + parent::__construct($font); + } + + function parse() { + parent::parse(); + + $font = $this->font; + $this->offset = $font->readUInt32(); + $this->length = $font->readUInt32(); + $this->origLength = $font->readUInt32(); + $this->checksum = $font->readUInt32(); + } +} diff --git a/vendor/phenx/php-svg-lib/LICENSE b/vendor/phenx/php-svg-lib/LICENSE new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/vendor/phenx/php-svg-lib/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/phenx/php-svg-lib/README.md b/vendor/phenx/php-svg-lib/README.md new file mode 100644 index 0000000..2b8e6f6 --- /dev/null +++ b/vendor/phenx/php-svg-lib/README.md @@ -0,0 +1,13 @@ +# SVG file parsing / rendering library + +[![Build Status](https://github.com/phenx/php-svg-lib/workflows/test/badge.svg)](https://github.com/phenx/php-svg-lib/actions) + + +[![Latest Stable Version](https://poser.pugx.org/phenx/php-svg-lib/v/stable)](https://packagist.org/packages/phenx/php-svg-lib) +[![Total Downloads](https://poser.pugx.org/phenx/php-svg-lib/downloads)](https://packagist.org/packages/phenx/php-svg-lib) +[![Latest Unstable Version](https://poser.pugx.org/phenx/php-svg-lib/v/unstable)](https://packagist.org/packages/phenx/php-svg-lib) +[![License](https://poser.pugx.org/phenx/php-svg-lib/license)](https://packagist.org/packages/phenx/php-svg-lib) + +The main purpose of this lib is to rasterize SVG to a surface which can be an image or a PDF for example, through a `\Svg\Surface` PHP interface. + +This project was initialized by the need to render SVG documents inside PDF files for the [DomPdf](http://dompdf.github.io) project. diff --git a/vendor/phenx/php-svg-lib/composer.json b/vendor/phenx/php-svg-lib/composer.json new file mode 100644 index 0000000..a6ed9c5 --- /dev/null +++ b/vendor/phenx/php-svg-lib/composer.json @@ -0,0 +1,31 @@ +{ + "name": "phenx/php-svg-lib", + "type": "library", + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "license": "LGPL-3.0", + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "autoload-dev": { + "psr-4": { + "Svg\\Tests\\": "tests/Svg" + } + }, + "require": { + "php": "^7.1 || ^8.0", + "ext-mbstring": "*", + "sabberworm/php-css-parser": "^8.4" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5" + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/CssLength.php b/vendor/phenx/php-svg-lib/src/Svg/CssLength.php new file mode 100644 index 0000000..88eda8c --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/CssLength.php @@ -0,0 +1,135 @@ + + */ + protected static $inchDivisions = [ + 'in' => 1, + 'cm' => 2.54, + 'mm' => 25.4, + 'q' => 101.6, + 'pc' => 6, + 'pt' => 72, + ]; + + /** + * The CSS length unit indicator. + * Will be lower-case and one of the units listed in the '$units' array or empty. + * + * @var string + */ + protected $unit = ''; + + /** + * The numeric value of the given length. + * + * @var float + */ + protected $value = 0; + + /** + * The original unparsed length provided. + * + * @var string + */ + protected $unparsed; + + public function __construct(string $length) + { + $this->unparsed = $length; + $this->parseLengthComponents($length); + } + + /** + * Parse out the unit and value components from the given string length. + */ + protected function parseLengthComponents(string $length): void + { + $length = strtolower($length); + + foreach (self::$units as $unit) { + $pos = strpos($length, $unit); + if ($pos) { + $this->value = floatval(substr($length, 0, $pos)); + $this->unit = $unit; + return; + } + } + + $this->unit = ''; + $this->value = floatval($length); + } + + /** + * Get the unit type of this css length. + * Units are standardised to be lower-cased. + * + * @return string + */ + public function getUnit(): string + { + return $this->unit; + } + + /** + * Get this CSS length in the equivalent pixel count size. + * + * @param float $referenceSize + * @param float $dpi + * + * @return float + */ + public function toPixels(float $referenceSize = 11.0, float $dpi = 96.0): float + { + // Standard relative units + if (in_array($this->unit, ['em', 'rem', 'ex', 'ch'])) { + return $this->value * $referenceSize; + } + + // Percentage relative units + if (in_array($this->unit, ['%', 'vw', 'vh', 'vmin', 'vmax'])) { + return $this->value * ($referenceSize / 100); + } + + // Inch relative units + if (in_array($this->unit, array_keys(static::$inchDivisions))) { + $inchValue = $this->value * $dpi; + $division = static::$inchDivisions[$this->unit]; + return $inchValue / $division; + } + + return $this->value; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php b/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php new file mode 100644 index 0000000..4e73d29 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php @@ -0,0 +1,29 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +class DefaultStyle extends Style +{ + public $color = [0, 0, 0, 1]; + public $opacity = 1.0; + public $display = 'inline'; + + public $fill = [0, 0, 0, 1]; + public $fillOpacity = 1.0; + public $fillRule = 'nonzero'; + + public $stroke = 'none'; + public $strokeOpacity = 1.0; + public $strokeLinecap = 'butt'; + public $strokeLinejoin = 'miter'; + public $strokeMiterlimit = 4; + public $strokeWidth = 1.0; + public $strokeDasharray = 0; + public $strokeDashoffset = 0; +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Document.php b/vendor/phenx/php-svg-lib/src/Svg/Document.php new file mode 100644 index 0000000..4de226e --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Document.php @@ -0,0 +1,406 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +use Svg\Surface\SurfaceInterface; +use Svg\Tag\AbstractTag; +use Svg\Tag\Anchor; +use Svg\Tag\Circle; +use Svg\Tag\Ellipse; +use Svg\Tag\Group; +use Svg\Tag\ClipPath; +use Svg\Tag\Image; +use Svg\Tag\Line; +use Svg\Tag\LinearGradient; +use Svg\Tag\Path; +use Svg\Tag\Polygon; +use Svg\Tag\Polyline; +use Svg\Tag\Rect; +use Svg\Tag\Stop; +use Svg\Tag\Text; +use Svg\Tag\StyleTag; +use Svg\Tag\UseTag; + +class Document extends AbstractTag +{ + protected $filename; + public $inDefs = false; + + protected $x; + protected $y; + protected $width; + protected $height; + + protected $subPathInit; + protected $pathBBox; + protected $viewBox; + + /** @var SurfaceInterface */ + protected $surface; + + /** @var AbstractTag[] */ + protected $stack = array(); + + /** @var AbstractTag[] */ + protected $defs = array(); + + /** @var \Sabberworm\CSS\CSSList\Document[] */ + protected $styleSheets = array(); + + public function loadFile($filename) + { + $this->filename = $filename; + } + + protected function initParser() { + $parser = xml_parser_create("utf-8"); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); + xml_set_element_handler( + $parser, + array($this, "_tagStart"), + array($this, "_tagEnd") + ); + xml_set_character_data_handler( + $parser, + array($this, "_charData") + ); + + return $parser; + } + + public function __construct() { + + } + + /** + * @return SurfaceInterface + */ + public function getSurface() + { + return $this->surface; + } + + public function getStack() + { + return $this->stack; + } + + public function getWidth() + { + return $this->width; + } + + public function getHeight() + { + return $this->height; + } + + public function getDiagonal() + { + return sqrt(($this->width)**2 + ($this->height)**2) / sqrt(2); + } + + public function getDimensions() { + $rootAttributes = null; + + $parser = xml_parser_create("utf-8"); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); + xml_set_element_handler( + $parser, + function ($parser, $name, $attributes) use (&$rootAttributes) { + if ($name === "svg" && $rootAttributes === null) { + $attributes = array_change_key_case($attributes, CASE_LOWER); + + $rootAttributes = $attributes; + } + }, + function ($parser, $name) {} + ); + + $fp = fopen($this->filename, "r"); + while ($line = fread($fp, 8192)) { + xml_parse($parser, $line, false); + + if ($rootAttributes !== null) { + break; + } + } + + xml_parser_free($parser); + + return $this->handleSizeAttributes($rootAttributes); + } + + public function handleSizeAttributes($attributes){ + if ($this->width === null) { + if (isset($attributes["width"])) { + $width = $this->convertSize($attributes["width"], 400); + $this->width = $width; + } + + if (isset($attributes["height"])) { + $height = $this->convertSize($attributes["height"], 300); + $this->height = $height; + } + + if (isset($attributes['viewbox'])) { + $viewBox = preg_split('/[\s,]+/is', trim($attributes['viewbox'])); + if (count($viewBox) == 4) { + $this->x = $viewBox[0]; + $this->y = $viewBox[1]; + + if (!$this->width) { + $this->width = $viewBox[2]; + } + if (!$this->height) { + $this->height = $viewBox[3]; + } + } + } + } + + return array( + 0 => $this->width, + 1 => $this->height, + + "width" => $this->width, + "height" => $this->height, + ); + } + + public function getDocument(){ + return $this; + } + + /** + * Append a style sheet + * + * @param \Sabberworm\CSS\CSSList\Document $stylesheet + */ + public function appendStyleSheet($stylesheet) { + $this->styleSheets[] = $stylesheet; + } + + /** + * Get the document style sheets + * + * @return \Sabberworm\CSS\CSSList\Document[] + */ + public function getStyleSheets() { + return $this->styleSheets; + } + + protected function before($attributes) + { + $surface = $this->getSurface(); + + $style = new DefaultStyle(); + $style->inherit($this); + $style->fromAttributes($attributes); + + $this->setStyle($style); + + $surface->setStyle($style); + } + + public function render(SurfaceInterface $surface) + { + $this->inDefs = false; + $this->surface = $surface; + + $parser = $this->initParser(); + + if ($this->x || $this->y) { + $surface->translate(-$this->x, -$this->y); + } + + $fp = fopen($this->filename, "r"); + while ($line = fread($fp, 8192)) { + xml_parse($parser, $line, false); + } + + xml_parse($parser, "", true); + + xml_parser_free($parser); + } + + protected function svgOffset($attributes) + { + $this->attributes = $attributes; + + $this->handleSizeAttributes($attributes); + } + + public function getDef($id) { + $id = ltrim($id, "#"); + + return isset($this->defs[$id]) ? $this->defs[$id] : null; + } + + private function _tagStart($parser, $name, $attributes) + { + $this->x = 0; + $this->y = 0; + + $tag = null; + + $attributes = array_change_key_case($attributes, CASE_LOWER); + + switch (strtolower($name)) { + case 'defs': + $this->inDefs = true; + return; + + case 'svg': + if (count($this->attributes)) { + $tag = new Group($this, $name); + } + else { + $tag = $this; + $this->svgOffset($attributes); + } + break; + + case 'path': + $tag = new Path($this, $name); + break; + + case 'rect': + $tag = new Rect($this, $name); + break; + + case 'circle': + $tag = new Circle($this, $name); + break; + + case 'ellipse': + $tag = new Ellipse($this, $name); + break; + + case 'image': + $tag = new Image($this, $name); + break; + + case 'line': + $tag = new Line($this, $name); + break; + + case 'polyline': + $tag = new Polyline($this, $name); + break; + + case 'polygon': + $tag = new Polygon($this, $name); + break; + + case 'lineargradient': + $tag = new LinearGradient($this, $name); + break; + + case 'radialgradient': + $tag = new LinearGradient($this, $name); + break; + + case 'stop': + $tag = new Stop($this, $name); + break; + + case 'style': + $tag = new StyleTag($this, $name); + break; + + case 'a': + $tag = new Anchor($this, $name); + break; + + case 'g': + case 'symbol': + $tag = new Group($this, $name); + break; + + case 'clippath': + $tag = new ClipPath($this, $name); + break; + + case 'use': + $tag = new UseTag($this, $name); + break; + + case 'text': + $tag = new Text($this, $name); + break; + + case 'desc': + return; + } + + if ($tag) { + if (isset($attributes["id"])) { + $this->defs[$attributes["id"]] = $tag; + } + else { + /** @var AbstractTag $top */ + $top = end($this->stack); + if ($top && $top != $tag) { + $top->children[] = $tag; + } + } + + $this->stack[] = $tag; + + $tag->handle($attributes); + } + } + + function _charData($parser, $data) + { + $stack_top = end($this->stack); + + if ($stack_top instanceof Text || $stack_top instanceof StyleTag) { + $stack_top->appendText($data); + } + } + + function _tagEnd($parser, $name) + { + /** @var AbstractTag $tag */ + $tag = null; + switch (strtolower($name)) { + case 'defs': + $this->inDefs = false; + return; + + case 'svg': + case 'path': + case 'rect': + case 'circle': + case 'ellipse': + case 'image': + case 'line': + case 'polyline': + case 'polygon': + case 'radialgradient': + case 'lineargradient': + case 'stop': + case 'style': + case 'text': + case 'g': + case 'symbol': + case 'clippath': + case 'use': + case 'a': + $tag = array_pop($this->stack); + break; + } + + if (!$this->inDefs && $tag) { + $tag->handleEnd(); + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php b/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php new file mode 100644 index 0000000..a37fb97 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php @@ -0,0 +1,16 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Gradient; + +class Stop +{ + public $offset; + public $color; + public $opacity = 1.0; +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Style.php b/vendor/phenx/php-svg-lib/src/Svg/Style.php new file mode 100644 index 0000000..14b11e9 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Style.php @@ -0,0 +1,541 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +use Svg\Tag\AbstractTag; + +class Style +{ + const TYPE_COLOR = 1; + const TYPE_LENGTH = 2; + const TYPE_NAME = 3; + const TYPE_ANGLE = 4; + const TYPE_NUMBER = 5; + + private $_parentStyle; + + public $color; + public $opacity; + public $display; + + public $fill; + public $fillOpacity; + public $fillRule; + + public $stroke; + public $strokeOpacity; + public $strokeLinecap; + public $strokeLinejoin; + public $strokeMiterlimit; + public $strokeWidth; + public $strokeDasharray; + public $strokeDashoffset; + + public $fontFamily = 'serif'; + public $fontSize = 12; + public $fontWeight = 'normal'; + public $fontStyle = 'normal'; + public $textAnchor = 'start'; + + protected function getStyleMap() + { + return array( + 'color' => array('color', self::TYPE_COLOR), + 'opacity' => array('opacity', self::TYPE_NUMBER), + 'display' => array('display', self::TYPE_NAME), + + 'fill' => array('fill', self::TYPE_COLOR), + 'fill-opacity' => array('fillOpacity', self::TYPE_NUMBER), + 'fill-rule' => array('fillRule', self::TYPE_NAME), + + 'stroke' => array('stroke', self::TYPE_COLOR), + 'stroke-dasharray' => array('strokeDasharray', self::TYPE_NAME), + 'stroke-dashoffset' => array('strokeDashoffset', self::TYPE_NUMBER), + 'stroke-linecap' => array('strokeLinecap', self::TYPE_NAME), + 'stroke-linejoin' => array('strokeLinejoin', self::TYPE_NAME), + 'stroke-miterlimit' => array('strokeMiterlimit', self::TYPE_NUMBER), + 'stroke-opacity' => array('strokeOpacity', self::TYPE_NUMBER), + 'stroke-width' => array('strokeWidth', self::TYPE_NUMBER), + + 'font-family' => array('fontFamily', self::TYPE_NAME), + 'font-size' => array('fontSize', self::TYPE_NUMBER), + 'font-weight' => array('fontWeight', self::TYPE_NAME), + 'font-style' => array('fontStyle', self::TYPE_NAME), + 'text-anchor' => array('textAnchor', self::TYPE_NAME), + ); + } + + /** + * @param $attributes + * + * @return Style + */ + public function fromAttributes($attributes) + { + $this->fillStyles($attributes); + + if (isset($attributes["style"])) { + $styles = self::parseCssStyle($attributes["style"]); + $this->fillStyles($styles); + } + } + + public function inherit(AbstractTag $tag) { + $group = $tag->getParentGroup(); + if ($group) { + $parent_style = $group->getStyle(); + $this->_parentStyle = $parent_style; + foreach ($parent_style as $_key => $_value) { + if ($_value !== null) { + $this->$_key = $_value; + } + } + } + } + + public function fromStyleSheets(AbstractTag $tag, $attributes) { + $class = isset($attributes["class"]) ? preg_split('/\s+/', trim($attributes["class"])) : null; + + $stylesheets = $tag->getDocument()->getStyleSheets(); + + $styles = array(); + + foreach ($stylesheets as $_sc) { + + /** @var \Sabberworm\CSS\RuleSet\DeclarationBlock $_decl */ + foreach ($_sc->getAllDeclarationBlocks() as $_decl) { + + /** @var \Sabberworm\CSS\Property\Selector $_selector */ + foreach ($_decl->getSelectors() as $_selector) { + $_selector = $_selector->getSelector(); + + // Match class name + if ($class !== null) { + foreach ($class as $_class) { + if ($_selector === ".$_class") { + /** @var \Sabberworm\CSS\Rule\Rule $_rule */ + foreach ($_decl->getRules() as $_rule) { + $styles[$_rule->getRule()] = $_rule->getValue() . ""; + } + + break 2; + } + } + } + + // Match tag name + if ($_selector === $tag->tagName) { + /** @var \Sabberworm\CSS\Rule\Rule $_rule */ + foreach ($_decl->getRules() as $_rule) { + $styles[$_rule->getRule()] = $_rule->getValue() . ""; + } + + break; + } + } + } + } + + $this->fillStyles($styles); + } + + protected function fillStyles($styles) + { + $style_map = $this->getStyleMap(); + foreach ($style_map as $from => $spec) { + if (isset($styles[$from])) { + list($to, $type) = $spec; + $value = null; + switch ($type) { + case self::TYPE_COLOR: + $value = self::parseColor($styles[$from]); + if ($value === "currentcolor") { + if ($type === "color") { + $value = $this->_parentStyle->color; + } else { + $value = $this->color; + } + } + if ($value !== null && $value[3] !== 1 && array_key_exists("{$from}-opacity", $style_map) === true) { + $styles["{$from}-opacity"] = $value[3]; + } + break; + + case self::TYPE_NUMBER: + $value = ($styles[$from] === null) ? null : (float)$styles[$from]; + break; + + default: + $value = $styles[$from]; + } + + if ($value !== null) { + $this->$to = $value; + } + } + } + } + + static function parseColor($color) + { + $color = strtolower(trim($color)); + + $parts = preg_split('/[^,]\s+/', $color, 2); + + if (count($parts) == 2) { + $color = $parts[1]; + } else { + $color = $parts[0]; + } + + if ($color === "none") { + return "none"; + } + + if ($color === "currentcolor") { + return "currentcolor"; + } + + // SVG color name + if (isset(self::$colorNames[$color])) { + return self::parseHexColor(self::$colorNames[$color]); + } + + // Hex color + if ($color[0] === "#") { + return self::parseHexColor($color); + } + + // RGB color + if (strpos($color, "rgb") !== false) { + return self::getQuad($color); + } + + // RGB color + if (strpos($color, "hsl") !== false) { + $quad = self::getQuad($color, true); + + if ($quad == null) { + return null; + } + + list($h, $s, $l, $a) = $quad; + + $r = $l; + $g = $l; + $b = $l; + $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s); + if ($v > 0) { + $m = $l + $l - $v; + $sv = ($v - $m) / $v; + $h *= 6.0; + $sextant = floor($h); + $fract = $h - $sextant; + $vsf = $v * $sv * $fract; + $mid1 = $m + $vsf; + $mid2 = $v - $vsf; + + switch ($sextant) { + case 0: + $r = $v; + $g = $mid1; + $b = $m; + break; + case 1: + $r = $mid2; + $g = $v; + $b = $m; + break; + case 2: + $r = $m; + $g = $v; + $b = $mid1; + break; + case 3: + $r = $m; + $g = $mid2; + $b = $v; + break; + case 4: + $r = $mid1; + $g = $m; + $b = $v; + break; + case 5: + $r = $v; + $g = $m; + $b = $mid2; + break; + } + } + $a = $a * 255; + + return array( + $r * 255.0, + $g * 255.0, + $b * 255.0, + $a + ); + } + + // Gradient + if (strpos($color, "url(#") !== false) { + $i = strpos($color, "("); + $j = strpos($color, ")"); + + // Bad url format + if ($i === false || $j === false) { + return null; + } + + return trim(substr($color, $i + 1, $j - $i - 1)); + } + + return null; + } + + static function getQuad($color, $percent = false) { + $i = strpos($color, "("); + $j = strpos($color, ")"); + + // Bad color value + if ($i === false || $j === false) { + return null; + } + + $quad = preg_split("/\\s*[,\\/]\\s*/", trim(substr($color, $i + 1, $j - $i - 1))); + if (!isset($quad[3])) { + $quad[3] = 1; + } + + if (count($quad) != 3 && count($quad) != 4) { + return null; + } + + foreach (array_keys($quad) as $c) { + $quad[$c] = trim($quad[$c]); + + if ($percent) { + if ($quad[$c][strlen($quad[$c]) - 1] === "%") { + $quad[$c] = floatval($quad[$c]) / 100; + } else { + $quad[$c] = $quad[$c] / 255; + } + } else { + if ($quad[$c][strlen($quad[$c]) - 1] === "%") { + $quad[$c] = round(floatval($quad[$c]) * 2.55); + } + } + } + + return $quad; + } + + static function parseHexColor($hex) + { + $c = array(0, 0, 0, 1); + + // #FFFFFF + if (isset($hex[6])) { + $c[0] = hexdec(substr($hex, 1, 2)); + $c[1] = hexdec(substr($hex, 3, 2)); + $c[2] = hexdec(substr($hex, 5, 2)); + + if (isset($hex[7])) { + $alpha = substr($hex, 7, 2); + if (ctype_xdigit($alpha)) { + $c[3] = round(hexdec($alpha)/255, 2); + } + } + } else { + $c[0] = hexdec($hex[1] . $hex[1]); + $c[1] = hexdec($hex[2] . $hex[2]); + $c[2] = hexdec($hex[3] . $hex[3]); + + if (isset($hex[4])) { + if (ctype_xdigit($hex[4])) { + $c[3] = round(hexdec($hex[4] . $hex[4])/255, 2); + } + } + } + + return $c; + } + + /** + * Simple CSS parser + * + * @param $style + * + * @return array + */ + static function parseCssStyle($style) + { + $matches = array(); + preg_match_all("/([a-z-]+)\\s*:\\s*([^;$]+)/si", $style, $matches, PREG_SET_ORDER); + + $styles = array(); + foreach ($matches as $match) { + $styles[$match[1]] = $match[2]; + } + + return $styles; + } + + static $colorNames = array( + 'antiquewhite' => '#FAEBD7', + 'aqua' => '#00FFFF', + 'aquamarine' => '#7FFFD4', + 'beige' => '#F5F5DC', + 'black' => '#000000', + 'blue' => '#0000FF', + 'brown' => '#A52A2A', + 'cadetblue' => '#5F9EA0', + 'chocolate' => '#D2691E', + 'cornflowerblue' => '#6495ED', + 'crimson' => '#DC143C', + 'darkblue' => '#00008B', + 'darkgoldenrod' => '#B8860B', + 'darkgreen' => '#006400', + 'darkmagenta' => '#8B008B', + 'darkorange' => '#FF8C00', + 'darkred' => '#8B0000', + 'darkseagreen' => '#8FBC8F', + 'darkslategray' => '#2F4F4F', + 'darkviolet' => '#9400D3', + 'deepskyblue' => '#00BFFF', + 'dodgerblue' => '#1E90FF', + 'firebrick' => '#B22222', + 'forestgreen' => '#228B22', + 'fuchsia' => '#FF00FF', + 'gainsboro' => '#DCDCDC', + 'gold' => '#FFD700', + 'gray' => '#808080', + 'green' => '#008000', + 'greenyellow' => '#ADFF2F', + 'hotpink' => '#FF69B4', + 'indigo' => '#4B0082', + 'khaki' => '#F0E68C', + 'lavenderblush' => '#FFF0F5', + 'lemonchiffon' => '#FFFACD', + 'lightcoral' => '#F08080', + 'lightgoldenrodyellow' => '#FAFAD2', + 'lightgreen' => '#90EE90', + 'lightsalmon' => '#FFA07A', + 'lightskyblue' => '#87CEFA', + 'lightslategray' => '#778899', + 'lightyellow' => '#FFFFE0', + 'lime' => '#00FF00', + 'limegreen' => '#32CD32', + 'magenta' => '#FF00FF', + 'maroon' => '#800000', + 'mediumaquamarine' => '#66CDAA', + 'mediumorchid' => '#BA55D3', + 'mediumseagreen' => '#3CB371', + 'mediumspringgreen' => '#00FA9A', + 'mediumvioletred' => '#C71585', + 'midnightblue' => '#191970', + 'mintcream' => '#F5FFFA', + 'moccasin' => '#FFE4B5', + 'navy' => '#000080', + 'olive' => '#808000', + 'orange' => '#FFA500', + 'orchid' => '#DA70D6', + 'palegreen' => '#98FB98', + 'palevioletred' => '#D87093', + 'peachpuff' => '#FFDAB9', + 'pink' => '#FFC0CB', + 'powderblue' => '#B0E0E6', + 'purple' => '#800080', + 'red' => '#FF0000', + 'royalblue' => '#4169E1', + 'salmon' => '#FA8072', + 'seagreen' => '#2E8B57', + 'sienna' => '#A0522D', + 'silver' => '#C0C0C0', + 'skyblue' => '#87CEEB', + 'slategray' => '#708090', + 'springgreen' => '#00FF7F', + 'steelblue' => '#4682B4', + 'tan' => '#D2B48C', + 'teal' => '#008080', + 'thistle' => '#D8BFD8', + 'turquoise' => '#40E0D0', + 'violetred' => '#D02090', + 'white' => '#FFFFFF', + 'yellow' => '#FFFF00', + 'aliceblue' => '#f0f8ff', + 'azure' => '#f0ffff', + 'bisque' => '#ffe4c4', + 'blanchedalmond' => '#ffebcd', + 'blueviolet' => '#8a2be2', + 'burlywood' => '#deb887', + 'chartreuse' => '#7fff00', + 'coral' => '#ff7f50', + 'cornsilk' => '#fff8dc', + 'cyan' => '#00ffff', + 'darkcyan' => '#008b8b', + 'darkgray' => '#a9a9a9', + 'darkgrey' => '#a9a9a9', + 'darkkhaki' => '#bdb76b', + 'darkolivegreen' => '#556b2f', + 'darkorchid' => '#9932cc', + 'darksalmon' => '#e9967a', + 'darkslateblue' => '#483d8b', + 'darkslategrey' => '#2f4f4f', + 'darkturquoise' => '#00ced1', + 'deeppink' => '#ff1493', + 'dimgray' => '#696969', + 'dimgrey' => '#696969', + 'floralwhite' => '#fffaf0', + 'ghostwhite' => '#f8f8ff', + 'goldenrod' => '#daa520', + 'grey' => '#808080', + 'honeydew' => '#f0fff0', + 'indianred' => '#cd5c5c', + 'ivory' => '#fffff0', + 'lavender' => '#e6e6fa', + 'lawngreen' => '#7cfc00', + 'lightblue' => '#add8e6', + 'lightcyan' => '#e0ffff', + 'lightgray' => '#d3d3d3', + 'lightgrey' => '#d3d3d3', + 'lightpink' => '#ffb6c1', + 'lightseagreen' => '#20b2aa', + 'lightslategrey' => '#778899', + 'lightsteelblue' => '#b0c4de', + 'linen' => '#faf0e6', + 'mediumblue' => '#0000cd', + 'mediumpurple' => '#9370db', + 'mediumslateblue' => '#7b68ee', + 'mediumturquoise' => '#48d1cc', + 'mistyrose' => '#ffe4e1', + 'navajowhite' => '#ffdead', + 'oldlace' => '#fdf5e6', + 'olivedrab' => '#6b8e23', + 'orangered' => '#ff4500', + 'palegoldenrod' => '#eee8aa', + 'paleturquoise' => '#afeeee', + 'papayawhip' => '#ffefd5', + 'peru' => '#cd853f', + 'plum' => '#dda0dd', + 'rosybrown' => '#bc8f8f', + 'saddlebrown' => '#8b4513', + 'sandybrown' => '#f4a460', + 'seashell' => '#fff5ee', + 'slateblue' => '#6a5acd', + 'slategrey' => '#708090', + 'snow' => '#fffafa', + 'tomato' => '#ff6347', + 'violet' => '#ee82ee', + 'wheat' => '#f5deb3', + 'whitesmoke' => '#f5f5f5', + 'yellowgreen' => '#9acd32', + ); +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php new file mode 100644 index 0000000..caa28a8 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php @@ -0,0 +1,6418 @@ + + * @author Orion Richardson + * @author Helmut Tischer + * @author Ryan H. Masten + * @author Brian Sweeney + * @author Fabien Ménager + * @license Public Domain http://creativecommons.org/licenses/publicdomain/ + * @package Cpdf + */ + +namespace Svg\Surface; + +class CPdf +{ + const PDF_VERSION = '1.7'; + + const ACROFORM_SIG_SIGNATURESEXISTS = 0x0001; + const ACROFORM_SIG_APPENDONLY = 0x0002; + + const ACROFORM_FIELD_BUTTON = 'Btn'; + const ACROFORM_FIELD_TEXT = 'Tx'; + const ACROFORM_FIELD_CHOICE = 'Ch'; + const ACROFORM_FIELD_SIG = 'Sig'; + + const ACROFORM_FIELD_READONLY = 0x0001; + const ACROFORM_FIELD_REQUIRED = 0x0002; + + const ACROFORM_FIELD_TEXT_MULTILINE = 0x1000; + const ACROFORM_FIELD_TEXT_PASSWORD = 0x2000; + const ACROFORM_FIELD_TEXT_RICHTEXT = 0x10000; + + const ACROFORM_FIELD_CHOICE_COMBO = 0x20000; + const ACROFORM_FIELD_CHOICE_EDIT = 0x40000; + const ACROFORM_FIELD_CHOICE_SORT = 0x80000; + const ACROFORM_FIELD_CHOICE_MULTISELECT = 0x200000; + + const XOBJECT_SUBTYPE_FORM = 'Form'; + + /** + * @var integer The current number of pdf objects in the document + */ + public $numObj = 0; + + /** + * @var array This array contains all of the pdf objects, ready for final assembly + */ + public $objects = []; + + /** + * @var integer The objectId (number within the objects array) of the document catalog + */ + public $catalogId; + + /** + * @var integer The objectId (number within the objects array) of indirect references (Javascript EmbeddedFiles) + */ + protected $indirectReferenceId = 0; + + /** + * @var integer The objectId (number within the objects array) + */ + protected $embeddedFilesId = 0; + + /** + * AcroForm objectId + * + * @var integer + */ + public $acroFormId; + + /** + * @var int + */ + public $signatureMaxLen = 5000; + + /** + * @var array Array carrying information about the fonts that the system currently knows about + * Used to ensure that a font is not loaded twice, among other things + */ + public $fonts = []; + + /** + * @var string The default font metrics file to use if no other font has been loaded. + * The path to the directory containing the font metrics should be included + */ + public $defaultFont = './fonts/Helvetica.afm'; + + /** + * @string A record of the current font + */ + public $currentFont = ''; + + /** + * @var string The current base font + */ + public $currentBaseFont = ''; + + /** + * @var integer The number of the current font within the font array + */ + public $currentFontNum = 0; + + /** + * @var integer + */ + public $currentNode; + + /** + * @var integer Object number of the current page + */ + public $currentPage; + + /** + * @var integer Object number of the currently active contents block + */ + public $currentContents; + + /** + * @var integer Number of fonts within the system + */ + public $numFonts = 0; + + /** + * @var integer Number of graphic state resources used + */ + private $numStates = 0; + + /** + * @var array Number of graphic state resources used + */ + private $gstates = []; + + /** + * @var array Current color for fill operations, defaults to inactive value, + * all three components should be between 0 and 1 inclusive when active + */ + public $currentColor = null; + + /** + * @var array Current color for stroke operations (lines etc.) + */ + public $currentStrokeColor = null; + + /** + * @var string Fill rule (nonzero or evenodd) + */ + public $fillRule = "nonzero"; + + /** + * @var string Current style that lines are drawn in + */ + public $currentLineStyle = ''; + + /** + * @var array Current line transparency (partial graphics state) + */ + public $currentLineTransparency = ["mode" => "Normal", "opacity" => 1.0]; + + /** + * array Current fill transparency (partial graphics state) + */ + public $currentFillTransparency = ["mode" => "Normal", "opacity" => 1.0]; + + /** + * @var array An array which is used to save the state of the document, mainly the colors and styles + * it is used to temporarily change to another state, then change back to what it was before + */ + public $stateStack = []; + + /** + * @var integer Number of elements within the state stack + */ + public $nStateStack = 0; + + /** + * @var integer Number of page objects within the document + */ + public $numPages = 0; + + /** + * @var array Object Id storage stack + */ + public $stack = []; + + /** + * @var integer Number of elements within the object Id storage stack + */ + public $nStack = 0; + + /** + * an array which contains information about the objects which are not firmly attached to pages + * these have been added with the addObject function + */ + public $looseObjects = []; + + /** + * array contains information about how the loose objects are to be added to the document + */ + public $addLooseObjects = []; + + /** + * @var integer The objectId of the information object for the document + * this contains authorship, title etc. + */ + public $infoObject = 0; + + /** + * @var integer Number of images being tracked within the document + */ + public $numImages = 0; + + /** + * @var array An array containing options about the document + * it defaults to turning on the compression of the objects + */ + public $options = ['compression' => true]; + + /** + * @var integer The objectId of the first page of the document + */ + public $firstPageId; + + /** + * @var integer The object Id of the procset object + */ + public $procsetObjectId; + + /** + * @var array Store the information about the relationship between font families + * this used so that the code knows which font is the bold version of another font, etc. + * the value of this array is initialised in the constructor function. + */ + public $fontFamilies = []; + + /** + * @var string Folder for php serialized formats of font metrics files. + * If empty string, use same folder as original metrics files. + * This can be passed in from class creator. + * If this folder does not exist or is not writable, Cpdf will be **much** slower. + * Because of potential trouble with php safe mode, folder cannot be created at runtime. + */ + public $fontcache = ''; + + /** + * @var integer The version of the font metrics cache file. + * This value must be manually incremented whenever the internal font data structure is modified. + */ + public $fontcacheVersion = 6; + + /** + * @var string Temporary folder. + * If empty string, will attempt system tmp folder. + * This can be passed in from class creator. + */ + public $tmp = ''; + + /** + * @var string Track if the current font is bolded or italicised + */ + public $currentTextState = ''; + + /** + * @var string Messages are stored here during processing, these can be selected afterwards to give some useful debug information + */ + public $messages = ''; + + /** + * @var string The encryption array for the document encryption is stored here + */ + public $arc4 = ''; + + /** + * @var integer The object Id of the encryption information + */ + public $arc4_objnum = 0; + + /** + * @var string The file identifier, used to uniquely identify a pdf document + */ + public $fileIdentifier = ''; + + /** + * @var boolean A flag to say if a document is to be encrypted or not + */ + public $encrypted = false; + + /** + * @var string The encryption key for the encryption of all the document content (structure is not encrypted) + */ + public $encryptionKey = ''; + + /** + * @var array Array which forms a stack to keep track of nested callback functions + */ + public $callback = []; + + /** + * @var integer The number of callback functions in the callback array + */ + public $nCallback = 0; + + /** + * @var array Store label->id pairs for named destinations, these will be used to replace internal links + * done this way so that destinations can be defined after the location that links to them + */ + public $destinations = []; + + /** + * @var array Store the stack for the transaction commands, each item in here is a record of the values of all the + * publiciables within the class, so that the user can rollback at will (from each 'start' command) + * note that this includes the objects array, so these can be large. + */ + public $checkpoint = ''; + + /** + * @var array Table of Image origin filenames and image labels which were already added with o_image(). + * Allows to merge identical images + */ + public $imagelist = []; + + /** + * @var array Table of already added alpha and plain image files for transparent PNG images. + */ + protected $imageAlphaList = []; + + /** + * @var array List of temporary image files to be deleted after processing. + */ + protected $imageCache = []; + + /** + * @var boolean Whether the text passed in should be treated as Unicode or just local character set. + */ + public $isUnicode = false; + + /** + * @var string the JavaScript code of the document + */ + public $javascript = ''; + + /** + * @var boolean whether the compression is possible + */ + protected $compressionReady = false; + + /** + * @var array Current page size + */ + protected $currentPageSize = ["width" => 0, "height" => 0]; + + /** + * @var array All the chars that will be required in the font subsets + */ + protected $stringSubsets = []; + + /** + * @var string The target internal encoding + */ + protected static $targetEncoding = 'Windows-1252'; + + /** + * @var array + */ + protected $byteRange = array(); + + /** + * @var array The list of the core fonts + */ + protected static $coreFonts = [ + 'courier', + 'courier-bold', + 'courier-oblique', + 'courier-boldoblique', + 'helvetica', + 'helvetica-bold', + 'helvetica-oblique', + 'helvetica-boldoblique', + 'times-roman', + 'times-bold', + 'times-italic', + 'times-bolditalic', + 'symbol', + 'zapfdingbats' + ]; + + /** + * Class constructor + * This will start a new document + * + * @param array $pageSize Array of 4 numbers, defining the bottom left and upper right corner of the page. first two are normally zero. + * @param boolean $isUnicode Whether text will be treated as Unicode or not. + * @param string $fontcache The font cache folder + * @param string $tmp The temporary folder + */ + function __construct($pageSize = [0, 0, 612, 792], $isUnicode = false, $fontcache = '', $tmp = '') + { + $this->isUnicode = $isUnicode; + $this->fontcache = rtrim($fontcache, DIRECTORY_SEPARATOR."/\\"); + $this->tmp = ($tmp !== '' ? $tmp : sys_get_temp_dir()); + $this->newDocument($pageSize); + + $this->compressionReady = function_exists('gzcompress'); + + if (in_array('Windows-1252', mb_list_encodings())) { + self::$targetEncoding = 'Windows-1252'; + } + + // also initialize the font families that are known about already + $this->setFontFamily('init'); + } + + public function __destruct() + { + foreach ($this->imageCache as $file) { + if (file_exists($file)) { + unlink($file); + } + } + } + + /** + * Document object methods (internal use only) + * + * There is about one object method for each type of object in the pdf document + * Each function has the same call list ($id,$action,$options). + * $id = the object ID of the object, or what it is to be if it is being created + * $action = a string specifying the action to be performed, though ALL must support: + * 'new' - create the object with the id $id + * 'out' - produce the output for the pdf object + * $options = optional, a string or array containing the various parameters for the object + * + * These, in conjunction with the output function are the ONLY way for output to be produced + * within the pdf 'file'. + */ + + /** + * Destination object, used to specify the location for the user to jump to, presently on opening + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_destination($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'destination', 'info' => []]; + $tmp = ''; + switch ($options['type']) { + case 'XYZ': + /** @noinspection PhpMissingBreakStatementInspection */ + case 'FitR': + $tmp = ' ' . $options['p3'] . $tmp; + case 'FitH': + case 'FitV': + case 'FitBH': + /** @noinspection PhpMissingBreakStatementInspection */ + case 'FitBV': + $tmp = ' ' . $options['p1'] . ' ' . $options['p2'] . $tmp; + case 'Fit': + case 'FitB': + $tmp = $options['type'] . $tmp; + $this->objects[$id]['info']['string'] = $tmp; + $this->objects[$id]['info']['page'] = $options['page']; + } + break; + + case 'out': + $o = &$this->objects[$id]; + + $tmp = $o['info']; + $res = "\n$id 0 obj\n" . '[' . $tmp['page'] . ' 0 R /' . $tmp['string'] . "]\nendobj"; + + return $res; + } + + return null; + } + + /** + * set the viewer preferences + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + */ + protected function o_viewerPreferences($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'viewerPreferences', 'info' => []]; + break; + + case 'add': + $o = &$this->objects[$id]; + + foreach ($options as $k => $v) { + switch ($k) { + // Boolean keys + case 'HideToolbar': + case 'HideMenubar': + case 'HideWindowUI': + case 'FitWindow': + case 'CenterWindow': + case 'DisplayDocTitle': + case 'PickTrayByPDFSize': + $o['info'][$k] = (bool)$v; + break; + + // Integer keys + case 'NumCopies': + $o['info'][$k] = (int)$v; + break; + + // Name keys + case 'ViewArea': + case 'ViewClip': + case 'PrintClip': + case 'PrintArea': + $o['info'][$k] = (string)$v; + break; + + // Named with limited valid values + case 'NonFullScreenPageMode': + if (!in_array($v, ['UseNone', 'UseOutlines', 'UseThumbs', 'UseOC'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'Direction': + if (!in_array($v, ['L2R', 'R2L'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'PrintScaling': + if (!in_array($v, ['None', 'AppDefault'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'Duplex': + if (!in_array($v, ['None', 'Simplex', 'DuplexFlipShortEdge', 'DuplexFlipLongEdge'])) { + break; + } + $o['info'][$k] = $v; + break; + + // Integer array + case 'PrintPageRange': + // Cast to integer array + foreach ($v as $vK => $vV) { + $v[$vK] = (int)$vV; + } + $o['info'][$k] = array_values($v); + break; + } + } + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + + foreach ($o['info'] as $k => $v) { + if (is_string($v)) { + $v = '/' . $v; + } elseif (is_int($v)) { + $v = (string) $v; + } elseif (is_bool($v)) { + $v = ($v ? 'true' : 'false'); + } elseif (is_array($v)) { + $v = '[' . implode(' ', $v) . ']'; + } + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * define the document catalog, the overall controller for the document + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + */ + protected function o_catalog($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'catalog', 'info' => []]; + $this->catalogId = $id; + break; + + case 'acroform': + case 'outlines': + case 'pages': + case 'openHere': + case 'names': + $o['info'][$action] = $options; + break; + + case 'viewerPreferences': + if (!isset($o['info']['viewerPreferences'])) { + $this->numObj++; + $this->o_viewerPreferences($this->numObj, 'new'); + $o['info']['viewerPreferences'] = $this->numObj; + } + + $vp = $o['info']['viewerPreferences']; + $this->o_viewerPreferences($vp, 'add', $options); + + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Catalog"; + + foreach ($o['info'] as $k => $v) { + switch ($k) { + case 'outlines': + $res .= "\n/Outlines $v 0 R"; + break; + + case 'pages': + $res .= "\n/Pages $v 0 R"; + break; + + case 'viewerPreferences': + $res .= "\n/ViewerPreferences $v 0 R"; + break; + + case 'openHere': + $res .= "\n/OpenAction $v 0 R"; + break; + + case 'names': + $res .= "\n/Names $v 0 R"; + break; + + case 'acroform': + $res .= "\n/AcroForm $v 0 R"; + break; + } + } + + $res .= " >>\nendobj"; + + return $res; + } + + return null; + } + + /** + * object which is a parent to the pages in the document + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_pages($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'pages', 'info' => []]; + $this->o_catalog($this->catalogId, 'pages', $id); + break; + + case 'page': + if (!is_array($options)) { + // then it will just be the id of the new page + $o['info']['pages'][] = $options; + } else { + // then it should be an array having 'id','rid','pos', where rid=the page to which this one will be placed relative + // and pos is either 'before' or 'after', saying where this page will fit. + if (isset($options['id']) && isset($options['rid']) && isset($options['pos'])) { + $i = array_search($options['rid'], $o['info']['pages']); + if (isset($o['info']['pages'][$i]) && $o['info']['pages'][$i] == $options['rid']) { + + // then there is a match + // make a space + switch ($options['pos']) { + case 'before': + $k = $i; + break; + + case 'after': + $k = $i + 1; + break; + + default: + $k = -1; + break; + } + + if ($k >= 0) { + for ($j = count($o['info']['pages']) - 1; $j >= $k; $j--) { + $o['info']['pages'][$j + 1] = $o['info']['pages'][$j]; + } + + $o['info']['pages'][$k] = $options['id']; + } + } + } + } + break; + + case 'procset': + $o['info']['procset'] = $options; + break; + + case 'mediaBox': + $o['info']['mediaBox'] = $options; + // which should be an array of 4 numbers + $this->currentPageSize = ['width' => $options[2], 'height' => $options[3]]; + break; + + case 'font': + $o['info']['fonts'][] = ['objNum' => $options['objNum'], 'fontNum' => $options['fontNum']]; + break; + + case 'extGState': + $o['info']['extGStates'][] = ['objNum' => $options['objNum'], 'stateNum' => $options['stateNum']]; + break; + + case 'xObject': + $o['info']['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; + break; + + case 'out': + if (count($o['info']['pages'])) { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Kids ["; + foreach ($o['info']['pages'] as $v) { + $res .= "$v 0 R\n"; + } + + $res .= "]\n/Count " . count($this->objects[$id]['info']['pages']); + + if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) || + isset($o['info']['procset']) || + (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) + ) { + $res .= "\n/Resources <<"; + + if (isset($o['info']['procset'])) { + $res .= "\n/ProcSet " . $o['info']['procset'] . " 0 R"; + } + + if (isset($o['info']['fonts']) && count($o['info']['fonts'])) { + $res .= "\n/Font << "; + foreach ($o['info']['fonts'] as $finfo) { + $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])) { + $res .= "\n/XObject << "; + foreach ($o['info']['xObjects'] as $finfo) { + $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) { + $res .= "\n/ExtGState << "; + foreach ($o['info']['extGStates'] as $gstate) { + $res .= "\n/GS" . $gstate['stateNum'] . " " . $gstate['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + $res .= "\n>>"; + if (isset($o['info']['mediaBox'])) { + $tmp = $o['info']['mediaBox']; + $res .= "\n/MediaBox [" . sprintf( + '%.3F %.3F %.3F %.3F', + $tmp[0], + $tmp[1], + $tmp[2], + $tmp[3] + ) . ']'; + } + } + + $res .= "\n >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj"; + } + + return $res; + } + + return null; + } + + /** + * define the outlines in the doc, empty for now + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_outlines($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'outlines', 'info' => ['outlines' => []]]; + $this->o_catalog($this->catalogId, 'outlines', $id); + break; + + case 'outline': + $o['info']['outlines'][] = $options; + break; + + case 'out': + if (count($o['info']['outlines'])) { + $res = "\n$id 0 obj\n<< /Type /Outlines /Kids ["; + foreach ($o['info']['outlines'] as $v) { + $res .= "$v 0 R "; + } + + $res .= "] /Count " . count($o['info']['outlines']) . " >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj"; + } + + return $res; + } + + return null; + } + + /** + * an object to hold the font description + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + * @throws FontNotFoundException + */ + protected function o_font($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'font', + 'info' => [ + 'name' => $options['name'], + 'fontFileName' => $options['fontFileName'], + 'SubType' => 'Type1', + 'isSubsetting' => $options['isSubsetting'] + ] + ]; + $fontNum = $this->numFonts; + $this->objects[$id]['info']['fontNum'] = $fontNum; + + // deal with the encoding and the differences + if (isset($options['differences'])) { + // then we'll need an encoding dictionary + $this->numObj++; + $this->o_fontEncoding($this->numObj, 'new', $options); + $this->objects[$id]['info']['encodingDictionary'] = $this->numObj; + } else { + if (isset($options['encoding'])) { + // we can specify encoding here + switch ($options['encoding']) { + case 'WinAnsiEncoding': + case 'MacRomanEncoding': + case 'MacExpertEncoding': + $this->objects[$id]['info']['encoding'] = $options['encoding']; + break; + + case 'none': + break; + + default: + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + break; + } + } else { + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + } + } + + if ($this->fonts[$options['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more information. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $toUnicodeId = ++$this->numObj; + $this->o_toUnicode($toUnicodeId, 'new'); + $this->objects[$id]['info']['toUnicode'] = $toUnicodeId; + + $cidFontId = ++$this->numObj; + $this->o_fontDescendentCID($cidFontId, 'new', $options); + $this->objects[$id]['info']['cidFont'] = $cidFontId; + } + + // also tell the pages node about the new font + $this->o_pages($this->currentNode, 'font', ['fontNum' => $fontNum, 'objNum' => $id]); + break; + + case 'add': + $font_options = $this->processFont($id, $o['info']); + + if ($font_options !== false) { + foreach ($font_options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + case 'FirstChar': + case 'LastChar': + case 'Widths': + case 'FontDescriptor': + case 'SubType': + $this->addMessage('o_font ' . $k . " : " . $v); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to descendent font + if (isset($o['info']['cidFont'])) { + $this->o_fontDescendentCID($o['info']['cidFont'], 'add', $font_options); + } + } + break; + + case 'out': + if ($this->fonts[$this->objects[$id]['info']['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more information. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $res = "\n$id 0 obj\n<fonts[$fontFileName])) { + return false; + } + + $font = &$this->fonts[$fontFileName]; + + $fileSuffix = $font['fileSuffix']; + $fileSuffixLower = strtolower($font['fileSuffix']); + $fbfile = "$fontFileName.$fileSuffix"; + $isTtfFont = $fileSuffixLower === 'ttf'; + $isPfbFont = $fileSuffixLower === 'pfb'; + + $this->addMessage('selectFont: checking for - ' . $fbfile); + + if (!$fileSuffix) { + $this->addMessage( + 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts' + ); + + return false; + } else { + $adobeFontName = isset($font['PostScriptName']) ? $font['PostScriptName'] : $font['FontName']; + // $fontObj = $this->numObj; + $this->addMessage("selectFont: adding font file - $fbfile - $adobeFontName"); + + // find the array of font widths, and put that into an object. + $firstChar = -1; + $lastChar = 0; + $widths = []; + $cid_widths = []; + + foreach ($font['C'] as $num => $d) { + if (intval($num) > 0 || $num == '0') { + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + if ($lastChar > 0 && $num > $lastChar + 1) { + for ($i = $lastChar + 1; $i < $num; $i++) { + $widths[] = 0; + } + } + } + + $widths[] = $d; + + if ($font['isUnicode']) { + $cid_widths[$num] = $d; + } + + if ($firstChar == -1) { + $firstChar = $num; + } + + $lastChar = $num; + } + } + + // also need to adjust the widths for the differences array + if (isset($object['differences'])) { + foreach ($object['differences'] as $charNum => $charName) { + if ($charNum > $lastChar) { + if (!$object['isUnicode']) { + // With Unicode, widths array isn't used + for ($i = $lastChar + 1; $i <= $charNum; $i++) { + $widths[] = 0; + } + } + + $lastChar = $charNum; + } + + if (isset($font['C'][$charName])) { + $widths[$charNum - $firstChar] = $font['C'][$charName]; + if ($font['isUnicode']) { + $cid_widths[$charName] = $font['C'][$charName]; + } + } + } + } + + if ($font['isUnicode']) { + $font['CIDWidths'] = $cid_widths; + } + + $this->addMessage('selectFont: FirstChar = ' . $firstChar); + $this->addMessage('selectFont: LastChar = ' . $lastChar); + + $widthid = -1; + + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + + $this->numObj++; + $this->o_contents($this->numObj, 'new', 'raw'); + $this->objects[$this->numObj]['c'] .= '[' . implode(' ', $widths) . ']'; + $widthid = $this->numObj; + } + + $missing_width = 500; + $stemV = 70; + + if (isset($font['MissingWidth'])) { + $missing_width = $font['MissingWidth']; + } + if (isset($font['StdVW'])) { + $stemV = $font['StdVW']; + } else { + if (isset($font['Weight']) && preg_match('!(bold|black)!i', $font['Weight'])) { + $stemV = 120; + } + } + + // load the pfb file, and put that into an object too. + // note that pdf supports only binary format type 1 font files, though there is a + // simple utility to convert them from pfa to pfb. + $data = file_get_contents($fbfile); + + // create the font descriptor + $this->numObj++; + $fontDescriptorId = $this->numObj; + + $this->numObj++; + $pfbid = $this->numObj; + + // determine flags (more than a little flakey, hopefully will not matter much) + $flags = 0; + + if ($font['ItalicAngle'] != 0) { + $flags += pow(2, 6); + } + + if ($font['IsFixedPitch'] === 'true') { + $flags += 1; + } + + $flags += pow(2, 5); // assume non-sybolic + $list = [ + 'Ascent' => 'Ascender', + 'CapHeight' => 'Ascender', //FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight' + 'MissingWidth' => 'MissingWidth', + 'Descent' => 'Descender', + 'FontBBox' => 'FontBBox', + 'ItalicAngle' => 'ItalicAngle' + ]; + $fdopt = [ + 'Flags' => $flags, + 'FontName' => $adobeFontName, + 'StemV' => $stemV + ]; + + foreach ($list as $k => $v) { + if (isset($font[$v])) { + $fdopt[$k] = $font[$v]; + } + } + + if ($isPfbFont) { + $fdopt['FontFile'] = $pfbid; + } elseif ($isTtfFont) { + $fdopt['FontFile2'] = $pfbid; + } + + $this->o_fontDescriptor($fontDescriptorId, 'new', $fdopt); + + // embed the font program + $this->o_contents($this->numObj, 'new'); + $this->objects[$pfbid]['c'] .= $data; + + // determine the cruicial lengths within this file + if ($isPfbFont) { + $l1 = strpos($data, 'eexec') + 6; + $l2 = strpos($data, '00000000') - $l1; + $l3 = mb_strlen($data, '8bit') - $l2 - $l1; + $this->o_contents( + $this->numObj, + 'add', + ['Length1' => $l1, 'Length2' => $l2, 'Length3' => $l3] + ); + } elseif ($isTtfFont) { + $l1 = mb_strlen($data, '8bit'); + $this->o_contents($this->numObj, 'add', ['Length1' => $l1]); + } + + // tell the font object about all this new stuff + $options = [ + 'BaseFont' => $adobeFontName, + 'MissingWidth' => $missing_width, + 'Widths' => $widthid, + 'FirstChar' => $firstChar, + 'LastChar' => $lastChar, + 'FontDescriptor' => $fontDescriptorId + ]; + + if ($isTtfFont) { + $options['SubType'] = 'TrueType'; + } + + $this->addMessage("adding extra info to font.($fontObjId)"); + + foreach ($options as $fk => $fv) { + $this->addMessage("$fk : $fv"); + } + } + + return $options; + } + + /** + * A toUnicode section, needed for unicode fonts + * + * @param $id + * @param $action + * @return null|string + */ + protected function o_toUnicode($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'toUnicode' + ]; + break; + case 'add': + break; + case 'out': + $ordering = 'UCS'; + $registry = 'Adobe'; + + if ($this->encrypted) { + $this->encryptInit($id); + $ordering = $this->ARC4($ordering); + $registry = $this->filterText($this->ARC4($registry), false, false); + } + + $stream = <<> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> +endcodespacerange +1 beginbfrange +<0000> <0000> +endbfrange +endcmap +CMapName currentdict /CMap defineresource pop +end +end +EOT; + + $res = "\n$id 0 obj\n"; + $res .= "<>\n"; + $res .= "stream\n" . $stream . "\nendstream" . "\nendobj";; + + return $res; + } + + return null; + } + + /** + * a font descriptor, needed for including additional fonts + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_fontDescriptor($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontDescriptor', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /FontDescriptor\n"; + foreach ($o['info'] as $label => $value) { + switch ($label) { + case 'Ascent': + case 'CapHeight': + case 'Descent': + case 'Flags': + case 'ItalicAngle': + case 'StemV': + case 'AvgWidth': + case 'Leading': + case 'MaxWidth': + case 'MissingWidth': + case 'StemH': + case 'XHeight': + case 'CharSet': + if (mb_strlen($value, '8bit')) { + $res .= "/$label $value\n"; + } + + break; + case 'FontFile': + case 'FontFile2': + case 'FontFile3': + $res .= "/$label $value 0 R\n"; + break; + + case 'FontBBox': + $res .= "/$label [$value[0] $value[1] $value[2] $value[3]]\n"; + break; + + case 'FontName': + $res .= "/$label /$value\n"; + break; + } + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * the font encoding + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_fontEncoding($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // the options array should contain 'differences' and maybe 'encoding' + $this->objects[$id] = ['t' => 'fontEncoding', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Encoding\n"; + if (!isset($o['info']['encoding'])) { + $o['info']['encoding'] = 'WinAnsiEncoding'; + } + + if ($o['info']['encoding'] !== 'none') { + $res .= "/BaseEncoding /" . $o['info']['encoding'] . "\n"; + } + + $res .= "/Differences \n["; + + $onum = -100; + + foreach ($o['info']['differences'] as $num => $label) { + if ($num != $onum + 1) { + // we cannot make use of consecutive numbering + $res .= "\n$num /$label"; + } else { + $res .= " /$label"; + } + + $onum = $num; + } + + $res .= "\n]\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * a descendent cid font, needed for unicode fonts + * + * @param $id + * @param $action + * @param string|array $options + * @return null|string + */ + protected function o_fontDescendentCID($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontDescendentCID', 'info' => $options]; + + // we need a CID system info section + $cidSystemInfoId = ++$this->numObj; + $this->o_cidSystemInfo($cidSystemInfoId, 'new'); + $this->objects[$id]['info']['cidSystemInfo'] = $cidSystemInfoId; + + // and a CID to GID map + $cidToGidMapId = ++$this->numObj; + $this->o_fontGIDtoCIDMap($cidToGidMapId, 'new', $options); + $this->objects[$id]['info']['cidToGidMap'] = $cidToGidMapId; + break; + + case 'add': + foreach ($options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + + case 'FirstChar': + case 'LastChar': + case 'MissingWidth': + case 'FontDescriptor': + case 'SubType': + $this->addMessage("o_fontDescendentCID $k : $v"); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to cid to gid map + $this->o_fontGIDtoCIDMap($o['info']['cidToGidMap'], 'add', $options); + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $res .= "<fonts[$o['info']['fontFileName']]['CIDWidths'])) { + $cid_widths = &$this->fonts[$o['info']['fontFileName']]['CIDWidths']; + $w = ''; + foreach ($cid_widths as $cid => $width) { + $w .= "$cid [$width] "; + } + $res .= "/W [$w]\n"; + } + + $res .= "/CIDToGIDMap " . $o['info']['cidToGidMap'] . " 0 R\n"; + $res .= ">>\n"; + $res .= "endobj"; + + return $res; + } + + return null; + } + + /** + * CID system info section, needed for unicode fonts + * + * @param $id + * @param $action + * @return null|string + */ + protected function o_cidSystemInfo($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'cidSystemInfo' + ]; + break; + case 'add': + break; + case 'out': + $ordering = 'UCS'; + $registry = 'Adobe'; + + if ($this->encrypted) { + $this->encryptInit($id); + $ordering = $this->ARC4($ordering); + $registry = $this->ARC4($registry); + } + + + $res = "\n$id 0 obj\n"; + + $res .= '<objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontGIDtoCIDMap', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $fontFileName = $o['info']['fontFileName']; + $tmp = $this->fonts[$fontFileName]['CIDtoGID'] = base64_decode($this->fonts[$fontFileName]['CIDtoGID']); + + $compressed = isset($this->fonts[$fontFileName]['CIDtoGID_Compressed']) && + $this->fonts[$fontFileName]['CIDtoGID_Compressed']; + + if (!$compressed && isset($o['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + + if (!$compressed && $this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $compressed = true; + $tmp = gzcompress($tmp, 6); + } + if ($compressed) { + $res .= "\n/Filter /FlateDecode"; + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + + return null; + } + + /** + * the document procset, solves some problems with printing to old PS printers + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_procset($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'procset', 'info' => ['PDF' => 1, 'Text' => 1]]; + $this->o_pages($this->currentNode, 'procset', $id); + $this->procsetObjectId = $id; + break; + + case 'add': + // this is to add new items to the procset list, despite the fact that this is considered + // obsolete, the items are required for printing to some postscript printers + switch ($options) { + case 'ImageB': + case 'ImageC': + case 'ImageI': + $o['info'][$options] = 1; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n["; + foreach ($o['info'] as $label => $val) { + $res .= "/$label "; + } + $res .= "]\nendobj"; + + return $res; + } + + return null; + } + + /** + * define the document information + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_info($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->infoObject = $id; + $date = 'D:' . @date('Ymd'); + $this->objects[$id] = [ + 't' => 'info', + 'info' => [ + 'Producer' => 'CPDF (dompdf)', + 'CreationDate' => $date + ] + ]; + break; + case 'Title': + case 'Author': + case 'Subject': + case 'Keywords': + case 'Creator': + case 'Producer': + case 'CreationDate': + case 'ModDate': + case 'Trapped': + $this->objects[$id]['info'][$action] = $options; + break; + + case 'out': + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<<\n"; + $o = &$this->objects[$id]; + foreach ($o['info'] as $k => $v) { + $res .= "/$k ("; + + // dates must be outputted as-is, without Unicode transformations + if ($k !== 'CreationDate' && $k !== 'ModDate') { + $v = $this->filterText($v, true, false); + } + + if ($encrypted) { + $v = $this->ARC4($v); + } + + $res .= $v; + $res .= ")\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an action object, used to link to URLS initially + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_action($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + if (is_array($options)) { + $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => $options['type']]; + } else { + // then assume a URI action + $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => 'URI']; + } + break; + + case 'out': + if ($this->encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<< /Type /Action"; + switch ($o['type']) { + case 'ilink': + if (!isset($this->destinations[(string)$o['info']['label']])) { + break; + } + + // there will be an 'label' setting, this is the name of the destination + $res .= "\n/S /GoTo\n/D " . $this->destinations[(string)$o['info']['label']] . " 0 R"; + break; + + case 'URI': + $res .= "\n/S /URI\n/URI ("; + if ($this->encrypted) { + $res .= $this->filterText($this->ARC4($o['info']), false, false); + } else { + $res .= $this->filterText($o['info'], false, false); + } + + $res .= ")"; + break; + } + + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an annotation object, this will add an annotation to the current page. + * initially will support just link annotations + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_annotation($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // add the annotation to the current page + $pageId = $this->currentPage; + $this->o_page($pageId, 'annot', $id); + + // and add the action object which is going to be required + switch ($options['type']) { + case 'link': + $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; + $this->numObj++; + $this->o_action($this->numObj, 'new', $options['url']); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + + case 'ilink': + // this is to a named internal link + $label = $options['label']; + $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; + $this->numObj++; + $this->o_action($this->numObj, 'new', ['type' => 'ilink', 'label' => $label]); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Annot"; + switch ($o['info']['type']) { + case 'link': + case 'ilink': + $res .= "\n/Subtype /Link"; + break; + } + $res .= "\n/A " . $o['info']['actionId'] . " 0 R"; + $res .= "\n/Border [0 0 0]"; + $res .= "\n/H /I"; + $res .= "\n/Rect [ "; + + foreach ($o['info']['rect'] as $v) { + $res .= sprintf("%.4F ", $v); + } + + $res .= "]"; + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * a page object, it also creates a contents object to hold its contents + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_page($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->numPages++; + $this->objects[$id] = [ + 't' => 'page', + 'info' => [ + 'parent' => $this->currentNode, + 'pageNum' => $this->numPages, + 'mediaBox' => $this->objects[$this->currentNode]['info']['mediaBox'] + ] + ]; + + if (is_array($options)) { + // then this must be a page insertion, array should contain 'rid','pos'=[before|after] + $options['id'] = $id; + $this->o_pages($this->currentNode, 'page', $options); + } else { + $this->o_pages($this->currentNode, 'page', $id); + } + + $this->currentPage = $id; + //make a contents object to go with this page + $this->numObj++; + $this->o_contents($this->numObj, 'new', $id); + $this->currentContents = $this->numObj; + $this->objects[$id]['info']['contents'] = []; + $this->objects[$id]['info']['contents'][] = $this->numObj; + + $match = ($this->numPages % 2 ? 'odd' : 'even'); + foreach ($this->addLooseObjects as $oId => $target) { + if ($target === 'all' || $match === $target) { + $this->objects[$id]['info']['contents'][] = $oId; + } + } + break; + + case 'content': + $o['info']['contents'][] = $options; + break; + + case 'annot': + // add an annotation to this page + if (!isset($o['info']['annot'])) { + $o['info']['annot'] = []; + } + + // $options should contain the id of the annotation dictionary + $o['info']['annot'][] = $options; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Page"; + if (isset($o['info']['mediaBox'])) { + $tmp = $o['info']['mediaBox']; + $res .= "\n/MediaBox [" . sprintf( + '%.3F %.3F %.3F %.3F', + $tmp[0], + $tmp[1], + $tmp[2], + $tmp[3] + ) . ']'; + } + $res .= "\n/Parent " . $o['info']['parent'] . " 0 R"; + + if (isset($o['info']['annot'])) { + $res .= "\n/Annots ["; + foreach ($o['info']['annot'] as $aId) { + $res .= " $aId 0 R"; + } + $res .= " ]"; + } + + $count = count($o['info']['contents']); + if ($count == 1) { + $res .= "\n/Contents " . $o['info']['contents'][0] . " 0 R"; + } else { + if ($count > 1) { + $res .= "\n/Contents [\n"; + + // reverse the page contents so added objects are below normal content + //foreach (array_reverse($o['info']['contents']) as $cId) { + // Back to normal now that I've got transparency working --Benj + foreach ($o['info']['contents'] as $cId) { + $res .= "$cId 0 R\n"; + } + $res .= "]"; + } + } + + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * the contents objects hold all of the content which appears on pages + * + * @param $id + * @param $action + * @param string|array $options + * @return null|string + */ + protected function o_contents($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'contents', 'c' => '', 'info' => []]; + if (mb_strlen($options, '8bit') && intval($options)) { + // then this contents is the primary for a page + $this->objects[$id]['onPage'] = $options; + } else { + if ($options === 'raw') { + // then this page contains some other type of system object + $this->objects[$id]['raw'] = 1; + } + } + break; + + case 'add': + // add more options to the declaration + foreach ($options as $k => $v) { + $o['info'][$k] = $v; + } + + case 'out': + $tmp = $o['c']; + $res = "\n$id 0 obj\n"; + + if (isset($this->objects[$id]['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $res .= " /Filter /FlateDecode"; + $tmp = gzcompress($tmp, 6); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . " >>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @return string|null + */ + protected function o_embedjs($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'embedjs', + 'info' => [ + 'Names' => '[(EmbeddedJS) ' . ($id + 1) . ' 0 R]' + ] + ]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param string $code + * @return null|string + */ + protected function o_javascript($id, $action, $code = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'javascript', + 'info' => [ + 'S' => '/JavaScript', + 'JS' => '(' . $this->filterText($code, true, false) . ')', + ] + ]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an image object, will be an XObject in the document, includes description and data + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_image($id, $action, $options = '') + { + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = ['t' => 'image', 'data' => &$options['data'], 'info' => []]; + + $info =& $this->objects[$id]['info']; + + $info['Type'] = '/XObject'; + $info['Subtype'] = '/Image'; + $info['Width'] = $options['iw']; + $info['Height'] = $options['ih']; + + if (isset($options['masked']) && $options['masked']) { + $info['SMask'] = ($this->numObj - 1) . ' 0 R'; + } + + if (!isset($options['type']) || $options['type'] === 'jpg') { + if (!isset($options['channels'])) { + $options['channels'] = 3; + } + + switch ($options['channels']) { + case 1: + $info['ColorSpace'] = '/DeviceGray'; + break; + case 4: + $info['ColorSpace'] = '/DeviceCMYK'; + break; + default: + $info['ColorSpace'] = '/DeviceRGB'; + break; + } + + if ($info['ColorSpace'] === '/DeviceCMYK') { + $info['Decode'] = '[1 0 1 0 1 0 1 0]'; + } + + $info['Filter'] = '/DCTDecode'; + $info['BitsPerComponent'] = 8; + } else { + if ($options['type'] === 'png') { + $info['Filter'] = '/FlateDecode'; + $info['DecodeParms'] = '<< /Predictor 15 /Colors ' . $options['ncolor'] . ' /Columns ' . $options['iw'] . ' /BitsPerComponent ' . $options['bitsPerComponent'] . '>>'; + + if ($options['isMask']) { + $info['ColorSpace'] = '/DeviceGray'; + } else { + if (mb_strlen($options['pdata'], '8bit')) { + $tmp = ' [ /Indexed /DeviceRGB ' . (mb_strlen($options['pdata'], '8bit') / 3 - 1) . ' '; + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->objects[$this->numObj]['c'] = $options['pdata']; + $tmp .= $this->numObj . ' 0 R'; + $tmp .= ' ]'; + $info['ColorSpace'] = $tmp; + + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . + $transparency['g'] . ' ' . $transparency['g'] . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + } else { + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . ' ' . + $transparency['g'] . ' ' . $transparency['g'] . ' ' . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + $info['ColorSpace'] = '/' . $options['color']; + } + } + + $info['BitsPerComponent'] = $options['bitsPerComponent']; + } + } + + // assign it a place in the named resource dictionary as an external object, according to + // the label passed in with it. + $this->o_pages($this->currentNode, 'xObject', ['label' => $options['label'], 'objNum' => $id]); + + // also make sure that we have the right procset object for it. + $this->o_procset($this->procsetObjectId, 'add', 'ImageC'); + break; + + case 'out': + $o = &$this->objects[$id]; + $tmp = &$o['data']; + $res = "\n$id 0 obj\n<<"; + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream\nendobj"; + + return $res; + } + + return null; + } + + /** + * graphics state object + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_extGState($id, $action, $options = "") + { + static $valid_params = [ + "LW", + "LC", + "LC", + "LJ", + "ML", + "D", + "RI", + "OP", + "op", + "OPM", + "Font", + "BG", + "BG2", + "UCR", + "TR", + "TR2", + "HT", + "FL", + "SM", + "SA", + "BM", + "SMask", + "CA", + "ca", + "AIS", + "TK" + ]; + + switch ($action) { + case "new": + $this->objects[$id] = ['t' => 'extGState', 'info' => $options]; + + // Tell the pages about the new resource + $this->numStates++; + $this->o_pages($this->currentNode, 'extGState', ["objNum" => $id, "stateNum" => $this->numStates]); + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /ExtGState\n"; + + foreach ($o["info"] as $k => $v) { + if (!in_array($k, $valid_params)) { + continue; + } + $res .= "/$k $v\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param integer $id + * @param string $action + * @param mixed $options + * @return string + */ + protected function o_xobject($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'xobject', 'info' => $options, 'c' => '']; + break; + + case 'procset': + $this->objects[$id]['procset'] = $options; + break; + + case 'font': + $this->objects[$id]['fonts'][$options['fontNum']] = [ + 'objNum' => $options['objNum'], + 'fontNum' => $options['fontNum'] + ]; + break; + + case 'xObject': + $this->objects[$id]['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /XObject\n"; + + foreach ($o["info"] as $k => $v) { + switch($k) + { + case 'Subtype': + $res .= "/Subtype /$v\n"; + break; + case 'bbox': + $res .= "/BBox ["; + foreach ($v as $value) { + $res .= sprintf("%.4F ", $value); + } + $res .= "]\n"; + break; + default: + $res .= "/$k $v\n"; + break; + } + } + $res .= "/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]\n"; + + $res .= "/Resources <<"; + if (isset($o['procset'])) { + $res .= "\n/ProcSet " . $o['procset'] . " 0 R"; + } else { + $res .= "\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"; + } + if (isset($o['fonts']) && count($o['fonts'])) { + $res .= "\n/Font << "; + foreach ($o['fonts'] as $finfo) { + $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + if (isset($o['xObjects']) && count($o['xObjects'])) { + $res .= "\n/XObject << "; + foreach ($o['xObjects'] as $finfo) { + $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + $res .= "\n>>\n"; + + $tmp = $o["c"]; + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $res .= " /Filter /FlateDecode\n"; + $tmp = gzcompress($tmp, 6); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "/Length " . mb_strlen($tmp, '8bit') . " >>\n"; + $res .= "stream\n" . $tmp . "\nendstream" . "\nendobj";; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_acroform($id, $action, $options = '') + { + switch ($action) { + case "new": + $this->o_catalog($this->catalogId, 'acroform', $id); + $this->objects[$id] = array('t' => 'acroform', 'info' => $options); + break; + + case 'addfield': + $this->objects[$id]['info']['Fields'][] = $options; + break; + + case 'font': + $this->objects[$id]['fonts'][$options['fontNum']] = [ + 'objNum' => $options['objNum'], + 'fontNum' => $options['fontNum'] + ]; + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<<"; + + foreach ($o["info"] as $k => $v) { + switch($k) { + case 'Fields': + $res .= " /Fields ["; + foreach ($v as $i) { + $res .= "$i 0 R "; + } + $res .= "]\n"; + break; + default: + $res .= "/$k $v\n"; + } + } + + $res .= "/DR <<\n"; + if (isset($o['fonts']) && count($o['fonts'])) { + $res .= "/Font << \n"; + foreach ($o['fonts'] as $finfo) { + $res .= "/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R\n"; + } + $res .= ">>\n"; + } + $res .= ">>\n"; + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param mixed $options + * @return null|string + */ + protected function o_field($id, $action, $options = '') + { + switch ($action) { + case "new": + $this->o_page($options['pageid'], 'annot', $id); + $this->o_acroform($this->acroFormId, 'addfield', $id); + $this->objects[$id] = ['t' => 'field', 'info' => $options]; + break; + + case 'set': + $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /Annot /Subtype /Widget \n"; + + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + foreach ($o["info"] as $k => $v) { + switch ($k) { + case 'pageid': + $res .= "/P $v 0 R\n"; + break; + case 'value': + if ($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/V ($v)\n"; + break; + case 'refvalue': + $res .= "/V $v 0 R\n"; + break; + case 'da': + if ($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/DA ($v)\n"; + break; + case 'options': + $res .= "/Opt [\n"; + foreach ($v as $opt) { + if ($encrypted) { + $opt = $this->filterText($this->ARC4($opt), false, false); + } + $res .= "($opt)\n"; + } + $res .= "]\n"; + break; + case 'rect': + $res .= "/Rect ["; + foreach ($v as $value) { + $res .= sprintf("%.4F ", $value); + } + $res .= "]\n"; + break; + case 'appearance': + $res .= "/AP << "; + foreach ($v as $a => $ref) { + $res .= "/$a $ref 0 R "; + } + $res .= ">>\n"; + break; + case 'T': + if($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/T ($v)\n"; + break; + default: + $res .= "/$k $v\n"; + } + + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_sig($id, $action, $options = '') + { + $sign_maxlen = $this->signatureMaxLen; + + switch ($action) { + case "new": + $this->objects[$id] = array('t' => 'sig', 'info' => $options); + $this->byteRange[$id] = ['t' => 'sig']; + break; + + case 'byterange': + $o = &$this->objects[$id]; + $content =& $options['content']; + $content_len = strlen($content); + $pos = strpos($content, sprintf("/ByteRange [ %'.010d", $id)); + $len = strlen('/ByteRange [ ********** ********** ********** ********** ]'); + $rangeStartPos = $pos + $len + 1 + 10; // before '<' + $content = substr_replace($content, str_pad(sprintf('/ByteRange [ 0 %u %u %u ]', $rangeStartPos, $rangeStartPos + $sign_maxlen + 2, $content_len - 2 - $sign_maxlen - $rangeStartPos ), $len, ' ', STR_PAD_RIGHT), $pos, $len); + + $fuid = uniqid(); + $tmpInput = $this->tmp . "/pkcs7.tmp." . $fuid . '.in'; + $tmpOutput = $this->tmp . "/pkcs7.tmp." . $fuid . '.out'; + + if (file_put_contents($tmpInput, substr($content, 0, $rangeStartPos)) === false) { + throw new \Exception("Unable to write temporary file for signing."); + } + if (file_put_contents($tmpInput, substr($content, $rangeStartPos + 2 + $sign_maxlen), + FILE_APPEND) === false) { + throw new \Exception("Unable to write temporary file for signing."); + } + + if (openssl_pkcs7_sign($tmpInput, $tmpOutput, + $o['info']['SignCert'], + array($o['info']['PrivKey'], $o['info']['Password']), + array(), PKCS7_BINARY | PKCS7_DETACHED) === false) { + throw new \Exception("Failed to prepare signature."); + } + + $signature = file_get_contents($tmpOutput); + + unlink($tmpInput); + unlink($tmpOutput); + + $sign = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); + list($head, $signature) = explode("\n\n", $sign); + + $signature = base64_decode(trim($signature)); + + $signature = current(unpack('H*', $signature)); + $signature = str_pad($signature, $sign_maxlen, '0'); + $siglen = strlen($signature); + if (strlen($signature) > $sign_maxlen) { + throw new \Exception("Signature length ($siglen) exceeds the $sign_maxlen limit."); + } + + $content = substr_replace($content, $signature, $rangeStartPos + 1, $sign_maxlen); + break; + + case "out": + $res = "\n$id 0 obj\n<<\n"; + + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + $res .= "/ByteRange " .sprintf("[ %'.010d ********** ********** ********** ]\n", $id); + $res .= "/Contents <" . str_pad('', $sign_maxlen, '0') . ">\n"; + $res .= "/Filter/Adobe.PPKLite\n"; //PPKMS \n"; + $res .= "/Type/Sig/SubFilter/adbe.pkcs7.detached \n"; + + $date = "D:" . substr_replace(date('YmdHisO'), '\'', -2, 0) . '\''; + if ($encrypted) { + $date = $this->ARC4($date); + } + + $res .= "/M ($date)\n"; + $res .= "/Prop_Build << /App << /Name /DomPDF >> /Filter << /Name /Adobe.PPKLite >> >>\n"; + + $o = &$this->objects[$id]; + foreach ($o['info'] as $k => $v) { + switch($k) { + case 'Name': + case 'Location': + case 'Reason': + case 'ContactInfo': + if ($v !== null && $v !== '') { + $res .= "/$k (" . + ($encrypted ? $this->filterText($this->ARC4($v), false, false) : $v) . ") \n"; + } + break; + } + } + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * encryption object. + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_encryption($id, $action, $options = '') + { + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = ['t' => 'encryption', 'info' => $options]; + $this->arc4_objnum = $id; + break; + + case 'keys': + // figure out the additional parameters required + $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41) + . chr(0x64) . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) + . chr(0x2E) . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) + . chr(0x2F) . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A); + + $info = $this->objects[$id]['info']; + + $len = mb_strlen($info['owner'], '8bit'); + + if ($len > 32) { + $owner = substr($info['owner'], 0, 32); + } else { + if ($len < 32) { + $owner = $info['owner'] . substr($pad, 0, 32 - $len); + } else { + $owner = $info['owner']; + } + } + + $len = mb_strlen($info['user'], '8bit'); + if ($len > 32) { + $user = substr($info['user'], 0, 32); + } else { + if ($len < 32) { + $user = $info['user'] . substr($pad, 0, 32 - $len); + } else { + $user = $info['user']; + } + } + + $tmp = $this->md5_16($owner); + $okey = substr($tmp, 0, 5); + $this->ARC4_init($okey); + $ovalue = $this->ARC4($user); + $this->objects[$id]['info']['O'] = $ovalue; + + // now make the u value, phew. + $tmp = $this->md5_16( + $user . $ovalue . chr($info['p']) . chr(255) . chr(255) . chr(255) . hex2bin($this->fileIdentifier) + ); + + $ukey = substr($tmp, 0, 5); + $this->ARC4_init($ukey); + $this->encryptionKey = $ukey; + $this->encrypted = true; + $uvalue = $this->ARC4($pad); + $this->objects[$id]['info']['U'] = $uvalue; + // initialize the arc4 array + break; + + case 'out': + $o = &$this->objects[$id]; + + $res = "\n$id 0 obj\n<<"; + $res .= "\n/Filter /Standard"; + $res .= "\n/V 1"; + $res .= "\n/R 2"; + $res .= "\n/O (" . $this->filterText($o['info']['O'], false, false) . ')'; + $res .= "\n/U (" . $this->filterText($o['info']['U'], false, false) . ')'; + // and the p-value needs to be converted to account for the twos-complement approach + $o['info']['p'] = (($o['info']['p'] ^ 255) + 1) * -1; + $res .= "\n/P " . ($o['info']['p']); + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + protected function o_indirect_references($id, $action, $options = null) + { + switch ($action) { + case 'new': + case 'add': + if ($id === 0) { + $id = ++$this->numObj; + $this->o_catalog($this->catalogId, 'names', $id); + $this->objects[$id] = ['t' => 'indirect_references', 'info' => $options]; + $this->indirectReferenceId = $id; + } else { + $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); + } + break; + case 'out': + $res = "\n$id 0 obj << "; + + foreach($this->objects[$id]['info'] as $referenceObjName => $referenceObjId) { + $res .= "/$referenceObjName $referenceObjId 0 R "; + } + + $res .= ">> endobj"; + return $res; + } + + return null; + } + + protected function o_names($id, $action, $options = null) + { + switch ($action) { + case 'new': + case 'add': + if ($id === 0) { + $id = ++$this->numObj; + $this->objects[$id] = ['t' => 'names', 'info' => [$options]]; + $this->o_indirect_references($this->indirectReferenceId, 'add', ['EmbeddedFiles' => $id]); + $this->embeddedFilesId = $id; + } else { + $this->objects[$id]['info'][] = $options; + } + break; + case 'out': + $info = &$this->objects[$id]['info']; + $res = ''; + if (count($info) > 0) { + $res = "\n$id 0 obj << /Names [ "; + + if ($this->encrypted) { + $this->encryptInit($id); + } + + foreach ($info as $entry) { + if ($this->encrypted) { + $filename = $this->ARC4($entry['filename']); + } else { + $filename = $entry['filename']; + } + + $res .= "($filename) " . $entry['dict_reference'] . " 0 R "; + } + + $res .= "] >> endobj"; + } + return $res; + } + + return null; + } + + protected function o_embedded_file_dictionary($id, $action, $options = null) + { + switch ($action) { + case 'new': + $embeddedFileId = ++$this->numObj; + $options['embedded_reference'] = $embeddedFileId; + $this->objects[$id] = ['t' => 'embedded_file_dictionary', 'info' => $options]; + $this->o_embedded_file($embeddedFileId, 'new', $options); + $options['dict_reference'] = $id; + $this->o_names($this->embeddedFilesId, 'add', $options); + break; + case 'out': + $info = &$this->objects[$id]['info']; + + if ($this->encrypted) { + $this->encryptInit($id); + $filename = $this->ARC4($info['filename']); + $description = $this->ARC4($info['description']); + } else { + $filename = $info['filename']; + $description = $info['description']; + } + + $res = "\n$id 0 obj <>"; + $res .= " /F ($filename) /UF ($filename) /Desc ($description)"; + $res .= " >> endobj"; + return $res; + } + + return null; + } + + protected function o_embedded_file($id, $action, $options = null): ?string + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'embedded_file', 'info' => $options]; + break; + case 'out': + $info = &$this->objects[$id]['info']; + + if ($this->compressionReady) { + $filepath = $info['filepath']; + $checksum = md5_file($filepath); + $f = fopen($filepath, "rb"); + + $file_content_compressed = ''; + $deflateContext = deflate_init(ZLIB_ENCODING_DEFLATE, ['level' => 6]); + while (($block = fread($f, 8192))) { + $file_content_compressed .= deflate_add($deflateContext, $block, ZLIB_NO_FLUSH); + } + $file_content_compressed .= deflate_add($deflateContext, '', ZLIB_FINISH); + $file_size_uncompressed = ftell($f); + fclose($f); + } else { + $file_content = file_get_contents($info['filepath']); + $file_size_uncompressed = mb_strlen($file_content, '8bit'); + $checksum = md5($file_content); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $checksum = $this->ARC4($checksum); + $file_content_compressed = $this->ARC4($file_content_compressed); + } + $file_size_compressed = mb_strlen($file_content_compressed, '8bit'); + + $res = "\n$id 0 obj <>" . + " /Type/EmbeddedFile /Filter/FlateDecode" . + " /Length $file_size_compressed >> stream\n$file_content_compressed\nendstream\nendobj"; + + return $res; + } + + return null; + } + + /** + * ARC4 functions + * A series of function to implement ARC4 encoding in PHP + */ + + /** + * calculate the 16 byte version of the 128 bit md5 digest of the string + * + * @param $string + * @return string + */ + function md5_16($string) + { + $tmp = md5($string); + $out = ''; + for ($i = 0; $i <= 30; $i = $i + 2) { + $out .= chr(hexdec(substr($tmp, $i, 2))); + } + + return $out; + } + + /** + * initialize the encryption for processing a particular object + * + * @param $id + */ + function encryptInit($id) + { + $tmp = $this->encryptionKey; + $hex = dechex($id); + if (mb_strlen($hex, '8bit') < 6) { + $hex = substr('000000', 0, 6 - mb_strlen($hex, '8bit')) . $hex; + } + $tmp .= chr(hexdec(substr($hex, 4, 2))) + . chr(hexdec(substr($hex, 2, 2))) + . chr(hexdec(substr($hex, 0, 2))) + . chr(0) + . chr(0) + ; + $key = $this->md5_16($tmp); + $this->ARC4_init(substr($key, 0, 10)); + } + + /** + * initialize the ARC4 encryption + * + * @param string $key + */ + function ARC4_init($key = '') + { + $this->arc4 = ''; + + // setup the control array + if (mb_strlen($key, '8bit') == 0) { + return; + } + + $k = ''; + while (mb_strlen($k, '8bit') < 256) { + $k .= $key; + } + + $k = substr($k, 0, 256); + for ($i = 0; $i < 256; $i++) { + $this->arc4 .= chr($i); + } + + $j = 0; + + for ($i = 0; $i < 256; $i++) { + $t = $this->arc4[$i]; + $j = ($j + ord($t) + ord($k[$i])) % 256; + $this->arc4[$i] = $this->arc4[$j]; + $this->arc4[$j] = $t; + } + } + + /** + * ARC4 encrypt a text string + * + * @param $text + * @return string + */ + function ARC4($text) + { + $len = mb_strlen($text, '8bit'); + $a = 0; + $b = 0; + $c = $this->arc4; + $out = ''; + for ($i = 0; $i < $len; $i++) { + $a = ($a + 1) % 256; + $t = $c[$a]; + $b = ($b + ord($t)) % 256; + $c[$a] = $c[$b]; + $c[$b] = $t; + $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]); + $out .= chr(ord($text[$i]) ^ $k); + } + + return $out; + } + + /** + * functions which can be called to adjust or add to the document + */ + + /** + * add a link in the document to an external URL + * + * @param $url + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + */ + function addLink($url, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = ['type' => 'link', 'url' => $url, 'rect' => [$x0, $y0, $x1, $y1]]; + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * add a link in the document to an internal destination (ie. within the document) + * + * @param $label + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + */ + function addInternalLink($label, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = ['type' => 'ilink', 'label' => $label, 'rect' => [$x0, $y0, $x1, $y1]]; + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * set the encryption of the document + * can be used to turn it on and/or set the passwords which it will have. + * also the functions that the user will have are set here, such as print, modify, add + * + * @param string $userPass + * @param string $ownerPass + * @param array $pc + */ + function setEncryption($userPass = '', $ownerPass = '', $pc = []) + { + $p = bindec("11000000"); + + $options = ['print' => 4, 'modify' => 8, 'copy' => 16, 'add' => 32]; + + foreach ($pc as $k => $v) { + if ($v && isset($options[$k])) { + $p += $options[$k]; + } else { + if (isset($options[$v])) { + $p += $options[$v]; + } + } + } + + // implement encryption on the document + if ($this->arc4_objnum == 0) { + // then the block does not exist already, add it. + $this->numObj++; + if (mb_strlen($ownerPass) == 0) { + $ownerPass = $userPass; + } + + $this->o_encryption($this->numObj, 'new', ['user' => $userPass, 'owner' => $ownerPass, 'p' => $p]); + } + } + + /** + * should be used for internal checks, not implemented as yet + */ + function checkAllHere() + { + } + + /** + * return the pdf stream as a string returned from the function + * + * @param bool $debug + * @return string + */ + function output($debug = false) + { + if ($debug) { + // turn compression off + $this->options['compression'] = false; + } + + if ($this->javascript) { + $this->numObj++; + + $js_id = $this->numObj; + $this->o_embedjs($js_id, 'new'); + $this->o_javascript(++$this->numObj, 'new', $this->javascript); + + $id = $this->catalogId; + + $this->o_indirect_references($this->indirectReferenceId, 'add', ['JavaScript' => $js_id]); + } + + if ($this->fileIdentifier === '') { + $tmp = implode('', $this->objects[$this->infoObject]['info']); + $this->fileIdentifier = md5('DOMPDF' . __FILE__ . $tmp . microtime() . mt_rand()); + } + + if ($this->arc4_objnum) { + $this->o_encryption($this->arc4_objnum, 'keys'); + $this->ARC4_init($this->encryptionKey); + } + + $this->checkAllHere(); + + $xref = []; + $content = '%PDF-' . self::PDF_VERSION; + $pos = mb_strlen($content, '8bit'); + + // pre-process o_font objects before output of all objects + foreach ($this->objects as $k => $v) { + if ($v['t'] === 'font') { + $this->o_font($k, 'add'); + } + } + + foreach ($this->objects as $k => $v) { + $tmp = 'o_' . $v['t']; + $cont = $this->$tmp($k, 'out'); + $content .= $cont; + $xref[] = $pos + 1; //+1 to account for \n at the start of each object + $pos += mb_strlen($cont, '8bit'); + } + + $content .= "\nxref\n0 " . (count($xref) + 1) . "\n0000000000 65535 f \n"; + + foreach ($xref as $p) { + $content .= str_pad($p, 10, "0", STR_PAD_LEFT) . " 00000 n \n"; + } + + $content .= "trailer\n<<\n" . + '/Size ' . (count($xref) + 1) . "\n" . + '/Root 1 0 R' . "\n" . + '/Info ' . $this->infoObject . " 0 R\n" + ; + + // if encryption has been applied to this document then add the marker for this dictionary + if ($this->arc4_objnum > 0) { + $content .= '/Encrypt ' . $this->arc4_objnum . " 0 R\n"; + } + + $content .= '/ID[<' . $this->fileIdentifier . '><' . $this->fileIdentifier . ">]\n"; + + // account for \n added at start of xref table + $pos++; + + $content .= ">>\nstartxref\n$pos\n%%EOF\n"; + + if (count($this->byteRange) > 0) { + foreach ($this->byteRange as $k => $v) { + $tmp = 'o_' . $v['t']; + $this->$tmp($k, 'byterange', ['content' => &$content]); + } + } + + return $content; + } + + /** + * initialize a new document + * if this is called on an existing document results may be unpredictable, but the existing document would be lost at minimum + * this function is called automatically by the constructor function + * + * @param array $pageSize + */ + private function newDocument($pageSize = [0, 0, 612, 792]) + { + $this->numObj = 0; + $this->objects = []; + + $this->numObj++; + $this->o_catalog($this->numObj, 'new'); + + $this->numObj++; + $this->o_outlines($this->numObj, 'new'); + + $this->numObj++; + $this->o_pages($this->numObj, 'new'); + + $this->o_pages($this->numObj, 'mediaBox', $pageSize); + $this->currentNode = 3; + + $this->numObj++; + $this->o_procset($this->numObj, 'new'); + + $this->numObj++; + $this->o_info($this->numObj, 'new'); + + $this->numObj++; + $this->o_page($this->numObj, 'new'); + + // need to store the first page id as there is no way to get it to the user during + // startup + $this->firstPageId = $this->currentContents; + } + + /** + * open the font file and return a php structure containing it. + * first check if this one has been done before and saved in a form more suited to php + * note that if a php serialized version does not exist it will try and make one, but will + * require write access to the directory to do it... it is MUCH faster to have these serialized + * files. + * + * @param $font + */ + private function openFont($font) + { + // assume that $font contains the path and file but not the extension + $name = basename($font); + $dir = dirname($font) . '/'; + + $fontcache = $this->fontcache; + if ($fontcache == '') { + $fontcache = rtrim($dir, DIRECTORY_SEPARATOR."/\\"); + } + + //$name filename without folder and extension of font metrics + //$dir folder of font metrics + //$fontcache folder of runtime created php serialized version of font metrics. + // If this is not given, the same folder as the font metrics will be used. + // Storing and reusing serialized versions improves speed much + + $this->addMessage("openFont: $font - $name"); + + if (!$this->isUnicode || in_array(mb_strtolower(basename($name)), self::$coreFonts)) { + $metrics_name = "$name.afm"; + } else { + $metrics_name = "$name.ufm"; + } + + $cache_name = "$metrics_name.php"; + $this->addMessage("metrics: $metrics_name, cache: $cache_name"); + + if (file_exists($fontcache . '/' . $cache_name)) { + $this->addMessage("openFont: php file exists $fontcache/$cache_name"); + $this->fonts[$font] = require($fontcache . '/' . $cache_name); + + if (!isset($this->fonts[$font]['_version_']) || $this->fonts[$font]['_version_'] != $this->fontcacheVersion) { + // if the font file is old, then clear it out and prepare for re-creation + $this->addMessage('openFont: clear out, make way for new version.'); + $this->fonts[$font] = null; + unset($this->fonts[$font]); + } + } else { + $old_cache_name = "php_$metrics_name"; + if (file_exists($fontcache . '/' . $old_cache_name)) { + $this->addMessage( + "openFont: php file doesn't exist $fontcache/$cache_name, creating it from the old format" + ); + $old_cache = file_get_contents($fontcache . '/' . $old_cache_name); + file_put_contents($fontcache . '/' . $cache_name, 'openFont($font); + return; + } + } + + if (!isset($this->fonts[$font]) && file_exists($dir . $metrics_name)) { + // then rebuild the php_.afm file from the .afm file + $this->addMessage("openFont: build php file from $dir$metrics_name"); + $data = []; + + // 20 => 'space' + $data['codeToName'] = []; + + // Since we're not going to enable Unicode for the core fonts we need to use a font-based + // setting for Unicode support rather than a global setting. + $data['isUnicode'] = (strtolower(substr($metrics_name, -3)) !== 'afm'); + + $cidtogid = ''; + if ($data['isUnicode']) { + $cidtogid = str_pad('', 256 * 256 * 2, "\x00"); + } + + $file = file($dir . $metrics_name); + + foreach ($file as $rowA) { + $row = trim($rowA); + $pos = strpos($row, ' '); + + if ($pos) { + // then there must be some keyword + $key = substr($row, 0, $pos); + switch ($key) { + case 'FontName': + case 'FullName': + case 'FamilyName': + case 'PostScriptName': + case 'Weight': + case 'ItalicAngle': + case 'IsFixedPitch': + case 'CharacterSet': + case 'UnderlinePosition': + case 'UnderlineThickness': + case 'Version': + case 'EncodingScheme': + case 'CapHeight': + case 'XHeight': + case 'Ascender': + case 'Descender': + case 'StdHW': + case 'StdVW': + case 'StartCharMetrics': + case 'FontHeightOffset': // OAR - Added so we can offset the height calculation of a Windows font. Otherwise it's too big. + $data[$key] = trim(substr($row, $pos)); + break; + + case 'FontBBox': + $data[$key] = explode(' ', trim(substr($row, $pos))); + break; + + //C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; + case 'C': // Found in AFM files + $bits = explode(';', trim($row)); + $dtmp = ['C' => null, 'N' => null, 'WX' => null, 'B' => []]; + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') == 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = []; + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['C']; + $n = $dtmp['N']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + if (!ctype_xdigit($n) || $c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } elseif (isset($n)) { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + // U 827 ; WX 0 ; N squaresubnosp ; G 675 ; + case 'U': // Found in UFM files + if (!$data['isUnicode']) { + break; + } + + $bits = explode(';', trim($row)); + $dtmp = ['G' => null, 'N' => null, 'U' => null, 'WX' => null]; + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') === 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = []; + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['U']; + $n = $dtmp['N']; + $glyph = $dtmp['G']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + // Set values in CID to GID map + if ($c >= 0 && $c < 0xFFFF && $glyph) { + $cidtogid[$c * 2] = chr($glyph >> 8); + $cidtogid[$c * 2 + 1] = chr($glyph & 0xFF); + } + + if (!ctype_xdigit($n) || $c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } elseif (isset($n)) { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + case 'KPX': + break; // don't include them as they are not used yet + //KPX Adieresis yacute -40 + /*$bits = explode(' ', trim($row)); + $data['KPX'][$bits[1]][$bits[2]] = $bits[3]; + break;*/ + } + } + } + + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on CIDtoGID string + $data['CIDtoGID_Compressed'] = true; + $cidtogid = gzcompress($cidtogid, 6); + } + $data['CIDtoGID'] = base64_encode($cidtogid); + $data['_version_'] = $this->fontcacheVersion; + $this->fonts[$font] = $data; + + //Because of potential trouble with php safe mode, expect that the folder already exists. + //If not existing, this will hit performance because of missing cached results. + if (is_dir($fontcache) && is_writable($fontcache)) { + file_put_contents($fontcache . '/' . $cache_name, 'fonts[$font])) { + $this->addMessage("openFont: no font file found for $font. Do you need to run load_font.php?"); + } + + //pre_r($this->messages); + } + + /** + * if the font is not loaded then load it and make the required object + * else just make it the current font + * the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding' + * note that encoding='none' will need to be used for symbolic fonts + * and 'differences' => an array of mappings between numbers 0->255 and character names. + * + * @param $fontName + * @param string $encoding + * @param bool $set + * @param bool $isSubsetting + * @return int + * @throws FontNotFoundException + */ + function selectFont($fontName, $encoding = '', $set = true, $isSubsetting = true) + { + if ($fontName === null || $fontName === '') { + return $this->currentFontNum; + } + + $ext = substr($fontName, -4); + if ($ext === '.afm' || $ext === '.ufm') { + $fontName = substr($fontName, 0, mb_strlen($fontName) - 4); + } + + if (!isset($this->fonts[$fontName])) { + $this->addMessage("selectFont: selecting - $fontName - $encoding, $set"); + + // load the file + $this->openFont($fontName); + + if (isset($this->fonts[$fontName])) { + $this->numObj++; + $this->numFonts++; + + $font = &$this->fonts[$fontName]; + + $name = basename($fontName); + $options = ['name' => $name, 'fontFileName' => $fontName, 'isSubsetting' => $isSubsetting]; + + if (is_array($encoding)) { + // then encoding and differences might be set + if (isset($encoding['encoding'])) { + $options['encoding'] = $encoding['encoding']; + } + + if (isset($encoding['differences'])) { + $options['differences'] = $encoding['differences']; + } + } else { + if (mb_strlen($encoding, '8bit')) { + // then perhaps only the encoding has been set + $options['encoding'] = $encoding; + } + } + + $this->o_font($this->numObj, 'new', $options); + + if (file_exists("$fontName.ttf")) { + $fileSuffix = 'ttf'; + } elseif (file_exists("$fontName.TTF")) { + $fileSuffix = 'TTF'; + } elseif (file_exists("$fontName.pfb")) { + $fileSuffix = 'pfb'; + } elseif (file_exists("$fontName.PFB")) { + $fileSuffix = 'PFB'; + } else { + $fileSuffix = ''; + } + + $font['fileSuffix'] = $fileSuffix; + + $font['fontNum'] = $this->numFonts; + $font['isSubsetting'] = $isSubsetting && $font['isUnicode'] && strtolower($fileSuffix) === 'ttf'; + + // also set the differences here, note that this means that these will take effect only the + //first time that a font is selected, else they are ignored + if (isset($options['differences'])) { + $font['differences'] = $options['differences']; + } + } + } + + if ($set && isset($this->fonts[$fontName])) { + // so if for some reason the font was not set in the last one then it will not be selected + $this->currentBaseFont = $fontName; + + // the next lines mean that if a new font is selected, then the current text state will be + // applied to it as well. + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + } + + return $this->currentFontNum; + } + + /** + * sets up the current font, based on the font families, and the current text state + * note that this system is quite flexible, a bold-italic font can be completely different to a + * italic-bold font, and even bold-bold will have to be defined within the family to have meaning + * This function is to be called whenever the currentTextState is changed, it will update + * the currentFont setting to whatever the appropriate family one is. + * If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont + * This function will change the currentFont to whatever it should be, but will not change the + * currentBaseFont. + */ + private function setCurrentFont() + { + // if (strlen($this->currentBaseFont) == 0){ + // // then assume an initial font + // $this->selectFont($this->defaultFont); + // } + // $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1); + // if (strlen($this->currentTextState) + // && isset($this->fontFamilies[$cf]) + // && isset($this->fontFamilies[$cf][$this->currentTextState])){ + // // then we are in some state or another + // // and this font has a family, and the current setting exists within it + // // select the font, then return it + // $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState]; + // $this->selectFont($nf,'',0); + // $this->currentFont = $nf; + // $this->currentFontNum = $this->fonts[$nf]['fontNum']; + // } else { + // // the this font must not have the right family member for the current state + // // simply assume the base font + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + // } + } + + /** + * function for the user to find out what the ID is of the first page that was created during + * startup - useful if they wish to add something to it later. + * + * @return int + */ + function getFirstPageId() + { + return $this->firstPageId; + } + + /** + * add content to the currently active object + * + * @param $content + */ + private function addContent($content) + { + $this->objects[$this->currentContents]['c'] .= $content; + } + + /** + * sets the color for fill operations + * + * @param $color + * @param bool $force + */ + function setColor($color, $force = false) + { + $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; + + if (!$force && $this->currentColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + $this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F k", $this->currentColor)); + } else { + if (isset($new_color[2])) { + $this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F rg", $this->currentColor)); + } + } + } + + /** + * sets the color for fill operations + * + * @param $fillRule + */ + function setFillRule($fillRule) + { + if (!in_array($fillRule, ["nonzero", "evenodd"])) { + return; + } + + $this->fillRule = $fillRule; + } + + /** + * sets the color for stroke operations + * + * @param $color + * @param bool $force + */ + function setStrokeColor($color, $force = false) + { + $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; + + if (!$force && $this->currentStrokeColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + $this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F K", $this->currentStrokeColor)); + } else { + if (isset($new_color[2])) { + $this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F RG", $this->currentStrokeColor)); + } + } + } + + /** + * Set the graphics state for compositions + * + * @param $parameters + */ + function setGraphicsState($parameters) + { + // Create a new graphics state object if necessary + if (($gstate = array_search($parameters, $this->gstates)) === false) { + $this->numObj++; + $this->o_extGState($this->numObj, 'new', $parameters); + $gstate = $this->numStates; + $this->gstates[$gstate] = $parameters; + } + $this->addContent("\n/GS$gstate gs"); + } + + /** + * Set current blend mode & opacity for lines. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setLineTransparency($mode, $opacity) + { + static $blend_modes = [ + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ]; + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + if (is_null($this->currentLineTransparency)) { + $this->currentLineTransparency = []; + } + + if ($mode === (key_exists('mode', $this->currentLineTransparency) ? + $this->currentLineTransparency['mode'] : '') && + $opacity === (key_exists('opacity', $this->currentLineTransparency) ? + $this->currentLineTransparency["opacity"] : '')) { + return; + } + + $this->currentLineTransparency["mode"] = $mode; + $this->currentLineTransparency["opacity"] = $opacity; + + $options = [ + "BM" => "/$mode", + "CA" => (float)$opacity + ]; + + $this->setGraphicsState($options); + } + + /** + * Set current blend mode & opacity for filled objects. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setFillTransparency($mode, $opacity) + { + static $blend_modes = [ + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ]; + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + if (is_null($this->currentFillTransparency)) { + $this->currentFillTransparency = []; + } + + if ($mode === (key_exists('mode', $this->currentFillTransparency) ? + $this->currentFillTransparency['mode'] : '') && + $opacity === (key_exists('opacity', $this->currentFillTransparency) ? + $this->currentFillTransparency["opacity"] : '')) { + return; + } + + $this->currentFillTransparency["mode"] = $mode; + $this->currentFillTransparency["opacity"] = $opacity; + + $options = [ + "BM" => "/$mode", + "ca" => (float)$opacity, + ]; + + $this->setGraphicsState($options); + } + + /** + * draw a line from one set of coordinates to another + * + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param bool $stroke + */ + function line($x1, $y1, $x2, $y2, $stroke = true) + { + $this->addContent(sprintf("\n%.3F %.3F m %.3F %.3F l", $x1, $y1, $x2, $y2)); + + if ($stroke) { + $this->addContent(' S'); + } + } + + /** + * draw a bezier curve based on 4 control points + * + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param $x3 + * @param $y3 + */ + function curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) + { + // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points + // as the control points for the curve. + $this->addContent( + sprintf("\n%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c S", $x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) + ); + } + + /** + * draw a part of an ellipse + * + * @param $x0 + * @param $y0 + * @param $astart + * @param $afinish + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + */ + function partEllipse($x0, $y0, $astart, $afinish, $r1, $r2 = 0, $angle = 0, $nSeg = 8) + { + $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, false); + } + + /** + * draw a filled ellipse + * + * @param $x0 + * @param $y0 + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + * @param int $astart + * @param int $afinish + */ + function filledEllipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360) + { + $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, true, true); + } + + /** + * @param $x + * @param $y + */ + function lineTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F l", $x, $y)); + } + + /** + * @param $x + * @param $y + */ + function moveTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F m", $x, $y)); + } + + /** + * draw a bezier curve based on 4 control points + * + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param $x3 + * @param $y3 + */ + function curveTo($x1, $y1, $x2, $y2, $x3, $y3) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F %.3F %.3F c", $x1, $y1, $x2, $y2, $x3, $y3)); + } + + /** + * draw a bezier curve based on 4 control points + */ + function quadTo($cpx, $cpy, $x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F v", $cpx, $cpy, $x, $y)); + } + + function closePath() + { + $this->addContent(' h'); + } + + function endPath() + { + $this->addContent(' n'); + } + + /** + * draw an ellipse + * note that the part and filled ellipse are just special cases of this function + * + * draws an ellipse in the current line style + * centered at $x0,$y0, radii $r1,$r2 + * if $r2 is not set, then a circle is drawn + * from $astart to $afinish, measured in degrees, running anti-clockwise from the right hand side of the ellipse. + * nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a + * pretty crappy shape at 2, as we are approximating with bezier curves. + * + * @param $x0 + * @param $y0 + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + * @param int $astart + * @param int $afinish + * @param bool $close + * @param bool $fill + * @param bool $stroke + * @param bool $incomplete + */ + function ellipse( + $x0, + $y0, + $r1, + $r2 = 0, + $angle = 0, + $nSeg = 8, + $astart = 0, + $afinish = 360, + $close = true, + $fill = false, + $stroke = true, + $incomplete = false + ) { + if ($r1 == 0) { + return; + } + + if ($r2 == 0) { + $r2 = $r1; + } + + if ($nSeg < 2) { + $nSeg = 2; + } + + $astart = deg2rad((float)$astart); + $afinish = deg2rad((float)$afinish); + $totalAngle = $afinish - $astart; + + $dt = $totalAngle / $nSeg; + $dtm = $dt / 3; + + if ($angle != 0) { + $a = -1 * deg2rad((float)$angle); + + $this->addContent( + sprintf("\n q %.3F %.3F %.3F %.3F %.3F %.3F cm", cos($a), -sin($a), sin($a), cos($a), $x0, $y0) + ); + + $x0 = 0; + $y0 = 0; + } + + $t1 = $astart; + $a0 = $x0 + $r1 * cos($t1); + $b0 = $y0 + $r2 * sin($t1); + $c0 = -$r1 * sin($t1); + $d0 = $r2 * cos($t1); + + if (!$incomplete) { + $this->addContent(sprintf("\n%.3F %.3F m ", $a0, $b0)); + } + + for ($i = 1; $i <= $nSeg; $i++) { + // draw this bit of the total curve + $t1 = $i * $dt + $astart; + $a1 = $x0 + $r1 * cos($t1); + $b1 = $y0 + $r2 * sin($t1); + $c1 = -$r1 * sin($t1); + $d1 = $r2 * cos($t1); + + $this->addContent( + sprintf( + "\n%.3F %.3F %.3F %.3F %.3F %.3F c", + ($a0 + $c0 * $dtm), + ($b0 + $d0 * $dtm), + ($a1 - $c1 * $dtm), + ($b1 - $d1 * $dtm), + $a1, + $b1 + ) + ); + + $a0 = $a1; + $b0 = $b1; + $c0 = $c1; + $d0 = $d1; + } + + if (!$incomplete) { + if ($fill) { + $this->addContent(' f'); + } + + if ($stroke) { + if ($close) { + $this->addContent(' s'); // small 's' signifies closing the path as well + } else { + $this->addContent(' S'); + } + } + } + + if ($angle != 0) { + $this->addContent(' Q'); + } + } + + /** + * this sets the line drawing style. + * width, is the thickness of the line in user units + * cap is the type of cap to put on the line, values can be 'butt','round','square' + * where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the + * end of the line. + * join can be 'miter', 'round', 'bevel' + * dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the + * on and off dashes. + * (2) represents 2 on, 2 off, 2 on , 2 off ... + * (2,1) is 2 on, 1 off, 2 on, 1 off.. etc + * phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. + * + * @param int $width + * @param string $cap + * @param string $join + * @param string $dash + * @param int $phase + */ + function setLineStyle($width = 1, $cap = '', $join = '', $dash = '', $phase = 0) + { + // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day + $string = ''; + + if ($width > 0) { + $string .= "$width w"; + } + + $ca = ['butt' => 0, 'round' => 1, 'square' => 2]; + + if (isset($ca[$cap])) { + $string .= " $ca[$cap] J"; + } + + $ja = ['miter' => 0, 'round' => 1, 'bevel' => 2]; + + if (isset($ja[$join])) { + $string .= " $ja[$join] j"; + } + + if (is_array($dash)) { + $string .= ' [ ' . implode(' ', $dash) . " ] $phase d"; + } + + $this->currentLineStyle = $string; + $this->addContent("\n$string"); + } + + /** + * draw a polygon, the syntax for this is similar to the GD polygon command + * + * @param $p + * @param $np + * @param bool $f + */ + function polygon($p, $np, $f = false) + { + $this->addContent(sprintf("\n%.3F %.3F m ", $p[0], $p[1])); + + for ($i = 2; $i < $np * 2; $i = $i + 2) { + $this->addContent(sprintf("%.3F %.3F l ", $p[$i], $p[$i + 1])); + } + + if ($f) { + $this->addContent(' f'); + } else { + $this->addContent(' S'); + } + } + + /** + * a filled rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function filledRectangle($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re f", $x1, $y1, $width, $height)); + } + + /** + * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function rectangle($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re S", $x1, $y1, $width, $height)); + } + + /** + * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function rect($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re", $x1, $y1, $width, $height)); + } + + function stroke(bool $close = false) + { + $this->addContent("\n" . ($close ? "s" : "S")); + } + + function fill() + { + $this->addContent("\nf" . ($this->fillRule === "evenodd" ? "*" : "")); + } + + function fillStroke(bool $close = false) + { + $this->addContent("\n" . ($close ? "b" : "B") . ($this->fillRule === "evenodd" ? "*" : "")); + } + + /** + * @param string $subtype + * @param integer $x + * @param integer $y + * @param integer $w + * @param integer $h + * @return int + */ + function addXObject($subtype, $x, $y, $w, $h) + { + $id = ++$this->numObj; + $this->o_xobject($id, 'new', ['Subtype' => $subtype, 'bbox' => [$x, $y, $w, $h]]); + return $id; + } + + /** + * @param integer $numXObject + * @param string $type + * @param array $options + */ + function setXObjectResource($numXObject, $type, $options) + { + if (in_array($type, ['procset', 'font', 'xObject'])) { + $this->o_xobject($numXObject, $type, $options); + } + } + + /** + * add signature + * + * $fieldSigId = $cpdf->addFormField(Cpdf::ACROFORM_FIELD_SIG, 'Signature1', 0, 0, 0, 0, 0); + * + * $signatureId = $cpdf->addSignature([ + * 'signcert' => file_get_contents('dompdf.crt'), + * 'privkey' => file_get_contents('dompdf.key'), + * 'password' => 'password', + * 'name' => 'DomPDF DEMO', + * 'location' => 'Home', + * 'reason' => 'First Form', + * 'contactinfo' => 'info' + * ]); + * $cpdf->setFormFieldValue($fieldSigId, "$signatureId 0 R"); + * + * @param string $signcert + * @param string $privkey + * @param string $password + * @param string|null $name + * @param string|null $location + * @param string|null $reason + * @param string|null $contactinfo + * @return int + */ + function addSignature($signcert, $privkey, $password = '', $name = null, $location = null, $reason = null, $contactinfo = null) { + $sigId = ++$this->numObj; + $this->o_sig($sigId, 'new', [ + 'SignCert' => $signcert, + 'PrivKey' => $privkey, + 'Password' => $password, + 'Name' => $name, + 'Location' => $location, + 'Reason' => $reason, + 'ContactInfo' => $contactinfo + ]); + + return $sigId; + } + + /** + * add field to form + * + * @param string $type ACROFORM_FIELD_* + * @param string $name + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + * @param integer $ff Field Flag ACROFORM_FIELD_*_* + * @param float $size + * @param array $color + * @return int + */ + public function addFormField($type, $name, $x0, $y0, $x1, $y1, $ff = 0, $size = 10.0, $color = [0, 0, 0]) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $color = implode(' ', $color) . ' rg'; + + $currentFontNum = $this->currentFontNum; + $font = array_filter($this->objects[$this->currentNode]['info']['fonts'], + function($item) use ($currentFontNum) { return $item['fontNum'] == $currentFontNum; }); + + $this->o_acroform($this->acroFormId, 'font', + ['objNum' => $font[0]['objNum'], 'fontNum' => $font[0]['fontNum']]); + + $fieldId = ++$this->numObj; + $this->o_field($fieldId, 'new', [ + 'rect' => [$x0, $y0, $x1, $y1], + 'F' => 4, + 'FT' => "/$type", + 'T' => $name, + 'Ff' => $ff, + 'pageid' => $this->currentPage, + 'da' => "$color /F$this->currentFontNum " . sprintf('%.1F Tf ', $size) + ]); + + return $fieldId; + } + + /** + * set Field value + * + * @param integer $numFieldObj + * @param string $value + */ + public function setFormFieldValue($numFieldObj, $value) + { + $this->o_field($numFieldObj, 'set', ['value' => $value]); + } + + /** + * set Field value (reference) + * + * @param integer $numFieldObj + * @param integer $numObj Object number + */ + public function setFormFieldRefValue($numFieldObj, $numObj) + { + $this->o_field($numFieldObj, 'set', ['refvalue' => $numObj]); + } + + /** + * set Field Appearanc (reference) + * + * @param integer $numFieldObj + * @param integer $normalNumObj + * @param integer|null $rolloverNumObj + * @param integer|null $downNumObj + */ + public function setFormFieldAppearance($numFieldObj, $normalNumObj, $rolloverNumObj = null, $downNumObj = null) + { + $appearance['N'] = $normalNumObj; + + if ($rolloverNumObj !== null) { + $appearance['R'] = $rolloverNumObj; + } + + if ($downNumObj !== null) { + $appearance['D'] = $downNumObj; + } + + $this->o_field($numFieldObj, 'set', ['appearance' => $appearance]); + } + + /** + * set Choice Field option values + * + * @param integer $numFieldObj + * @param array $value + */ + public function setFormFieldOpt($numFieldObj, $value) + { + $this->o_field($numFieldObj, 'set', ['options' => $value]); + } + + /** + * add form to document + * + * @param integer $sigFlags + * @param boolean $needAppearances + */ + public function addForm($sigFlags = 0, $needAppearances = false) + { + $this->acroFormId = ++$this->numObj; + $this->o_acroform($this->acroFormId, 'new', [ + 'NeedAppearances' => $needAppearances ? 'true' : 'false', + 'SigFlags' => $sigFlags + ]); + } + + /** + * save the current graphic state + */ + function save() + { + // we must reset the color cache or it will keep bad colors after clipping + $this->currentColor = null; + $this->currentStrokeColor = null; + $this->addContent("\nq"); + } + + /** + * restore the last graphic state + */ + function restore() + { + // we must reset the color cache or it will keep bad colors after clipping + $this->currentColor = null; + $this->currentStrokeColor = null; + $this->addContent("\nQ"); + } + + /** + * draw a clipping rectangle, all the elements added after this will be clipped + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function clippingRectangle($x1, $y1, $width, $height) + { + $this->save(); + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re W n", $x1, $y1, $width, $height)); + } + + /** + * draw a clipping rounded rectangle, all the elements added after this will be clipped + * + * @param $x1 + * @param $y1 + * @param $w + * @param $h + * @param $rTL + * @param $rTR + * @param $rBR + * @param $rBL + */ + function clippingRectangleRounded($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) + { + $this->save(); + + // start: top edge, left end + $this->addContent(sprintf("\n%.3F %.3F m ", $x1, $y1 - $rTL + $h)); + + // line: bottom edge, left end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1, $y1 + $rBL)); + + // curve: bottom-left corner + $this->ellipse($x1 + $rBL, $y1 + $rBL, $rBL, 0, 0, 8, 180, 270, false, false, false, true); + + // line: right edge, bottom end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w - $rBR, $y1)); + + // curve: bottom-right corner + $this->ellipse($x1 + $w - $rBR, $y1 + $rBR, $rBR, 0, 0, 8, 270, 360, false, false, false, true); + + // line: right edge, top end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w, $y1 + $h - $rTR)); + + // curve: bottom-right corner + $this->ellipse($x1 + $w - $rTR, $y1 + $h - $rTR, $rTR, 0, 0, 8, 0, 90, false, false, false, true); + + // line: bottom edge, right end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rTL, $y1 + $h)); + + // curve: top-right corner + $this->ellipse($x1 + $rTL, $y1 + $h - $rTL, $rTL, 0, 0, 8, 90, 180, false, false, false, true); + + // line: top edge, left end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rBL, $y1)); + + // Close & clip + $this->addContent(" W n"); + } + + /** + * ends the last clipping shape + */ + function clippingEnd() + { + $this->restore(); + } + + /** + * scale + * + * @param float $s_x scaling factor for width as percent + * @param float $s_y scaling factor for height as percent + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function scale($s_x, $s_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tm = [ + $s_x, + 0, + 0, + $s_y, + $x * (1 - $s_x), + $y * (1 - $s_y) + ]; + + $this->transform($tm); + } + + /** + * translate + * + * @param float $t_x movement to the right + * @param float $t_y movement to the bottom + */ + function translate($t_x, $t_y) + { + $tm = [ + 1, + 0, + 0, + 1, + $t_x, + -$t_y + ]; + + $this->transform($tm); + } + + /** + * rotate + * + * @param float $angle angle in degrees for counter-clockwise rotation + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function rotate($angle, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $a = deg2rad($angle); + $cos_a = cos($a); + $sin_a = sin($a); + + $tm = [ + $cos_a, + -$sin_a, + $sin_a, + $cos_a, + $x - $sin_a * $y - $cos_a * $x, + $y - $cos_a * $y + $sin_a * $x, + ]; + + $this->transform($tm); + } + + /** + * skew + * + * @param float $angle_x + * @param float $angle_y + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function skew($angle_x, $angle_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tan_x = tan(deg2rad($angle_x)); + $tan_y = tan(deg2rad($angle_y)); + + $tm = [ + 1, + -$tan_y, + -$tan_x, + 1, + $tan_x * $y, + $tan_y * $x, + ]; + + $this->transform($tm); + } + + /** + * apply graphic transformations + * + * @param array $tm transformation matrix + */ + function transform($tm) + { + $this->addContent(vsprintf("\n %.3F %.3F %.3F %.3F %.3F %.3F cm", $tm)); + } + + /** + * add a new page to the document + * this also makes the new page the current active object + * + * @param int $insert + * @param int $id + * @param string $pos + * @return int + */ + function newPage($insert = 0, $id = 0, $pos = 'after') + { + // if there is a state saved, then go up the stack closing them + // then on the new page, re-open them with the right setings + + if ($this->nStateStack) { + for ($i = $this->nStateStack; $i >= 1; $i--) { + $this->restoreState($i); + } + } + + $this->numObj++; + + if ($insert) { + // the id from the ezPdf class is the id of the contents of the page, not the page object itself + // query that object to find the parent + $rid = $this->objects[$id]['onPage']; + $opt = ['rid' => $rid, 'pos' => $pos]; + $this->o_page($this->numObj, 'new', $opt); + } else { + $this->o_page($this->numObj, 'new'); + } + + // if there is a stack saved, then put that onto the page + if ($this->nStateStack) { + for ($i = 1; $i <= $this->nStateStack; $i++) { + $this->saveState($i); + } + } + + // and if there has been a stroke or fill color set, then transfer them + if (isset($this->currentColor)) { + $this->setColor($this->currentColor, true); + } + + if (isset($this->currentStrokeColor)) { + $this->setStrokeColor($this->currentStrokeColor, true); + } + + // if there is a line style set, then put this in too + if (mb_strlen($this->currentLineStyle, '8bit')) { + $this->addContent("\n$this->currentLineStyle"); + } + + // the call to the o_page object set currentContents to the present page, so this can be returned as the page id + return $this->currentContents; + } + + /** + * Streams the PDF to the client. + * + * @param string $filename The filename to present to the client. + * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1). + */ + function stream($filename = "document.pdf", $options = []) + { + if (headers_sent()) { + die("Unable to stream pdf: headers already sent"); + } + + if (!isset($options["compress"])) $options["compress"] = true; + if (!isset($options["Attachment"])) $options["Attachment"] = true; + + $debug = !$options['compress']; + $tmp = ltrim($this->output($debug)); + + header("Cache-Control: private"); + header("Content-Type: application/pdf"); + header("Content-Length: " . mb_strlen($tmp, "8bit")); + + $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf"; + $attachment = $options["Attachment"] ? "attachment" : "inline"; + + $encoding = mb_detect_encoding($filename); + $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); + $fallbackfilename = str_replace("\"", "", $fallbackfilename); + $encodedfilename = rawurlencode($filename); + + $contentDisposition = "Content-Disposition: $attachment; filename=\"$fallbackfilename\""; + if ($fallbackfilename !== $filename) { + $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; + } + header($contentDisposition); + + echo $tmp; + flush(); + } + + /** + * return the height in units of the current font in the given size + * + * @param $size + * @return float|int + */ + function getFontHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['Ascender']) && isset($font['Descender'])) { + $h = $font['Ascender'] - $font['Descender']; + } else { + $h = $font['FontBBox'][3] - $font['FontBBox'][1]; + } + + // have to adjust by a font offset for Windows fonts. unfortunately it looks like + // the bounding box calculations are wrong and I don't know why. + if (isset($font['FontHeightOffset'])) { + // For CourierNew from Windows this needs to be -646 to match the + // Adobe native Courier font. + // + // For FreeMono from GNU this needs to be -337 to match the + // Courier font. + // + // Both have been added manually to the .afm and .ufm files. + $h += (int)$font['FontHeightOffset']; + } + + return $size * $h / 1000; + } + + /** + * @param $size + * @return float|int + */ + function getFontXHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['XHeight'])) { + $xh = $font['Ascender'] - $font['Descender']; + } else { + $xh = $this->getFontHeight($size) / 2; + } + + return $size * $xh / 1000; + } + + /** + * return the font descender, this will normally return a negative number + * if you add this number to the baseline, you get the level of the bottom of the font + * it is in the pdf user units + * + * @param $size + * @return float|int + */ + function getFontDescender($size) + { + // note that this will most likely return a negative value + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + //$h = $this->fonts[$this->currentFont]['FontBBox'][1]; + $h = $this->fonts[$this->currentFont]['Descender']; + + return $size * $h / 1000; + } + + /** + * filter the text, this is applied to all text just before being inserted into the pdf document + * it escapes the various things that need to be escaped, and so on + * + * @access private + * + * @param $text + * @param bool $bom + * @param bool $convert_encoding + * @return string + */ + function filterText($text, $bom = true, $convert_encoding = true) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + if ($convert_encoding) { + $cf = $this->currentFont; + if (isset($this->fonts[$cf]) && $this->fonts[$cf]['isUnicode']) { + $text = $this->utf8toUtf16BE($text, $bom); + } else { + //$text = html_entity_decode($text, ENT_QUOTES); + $text = mb_convert_encoding($text, self::$targetEncoding, 'UTF-8'); + } + } else if ($bom) { + $text = $this->utf8toUtf16BE($text, $bom); + } + + // the chr(13) substitution fixes a bug seen in TCPDF (bug #1421290) + return strtr($text, [')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r']); + } + + /** + * return array containing codepoints (UTF-8 character values) for the + * string passed in. + * + * based on the excellent TCPDF code by Nicola Asuni and the + * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html + * + * @access private + * @author Orion Richardson + * @since January 5, 2008 + * + * @param string $text UTF-8 string to process + * + * @return array UTF-8 codepoints array for the string + */ + function utf8toCodePointsArray(&$text) + { + $length = mb_strlen($text, '8bit'); // http://www.php.net/manual/en/function.mb-strlen.php#77040 + $unicode = []; // array containing unicode values + $bytes = []; // array containing single character byte sequences + $numbytes = 1; // number of octets needed to represent the UTF-8 character + + for ($i = 0; $i < $length; $i++) { + $c = ord($text[$i]); // get one string character at time + if (count($bytes) === 0) { // get starting octect + if ($c <= 0x7F) { + $unicode[] = $c; // use the character "as is" because is ASCII + $numbytes = 1; + } elseif (($c >> 0x05) === 0x06) { // 2 bytes character (0x06 = 110 BIN) + $bytes[] = ($c - 0xC0) << 0x06; + $numbytes = 2; + } elseif (($c >> 0x04) === 0x0E) { // 3 bytes character (0x0E = 1110 BIN) + $bytes[] = ($c - 0xE0) << 0x0C; + $numbytes = 3; + } elseif (($c >> 0x03) === 0x1E) { // 4 bytes character (0x1E = 11110 BIN) + $bytes[] = ($c - 0xF0) << 0x12; + $numbytes = 4; + } else { + // use replacement character for other invalid sequences + $unicode[] = 0xFFFD; + $bytes = []; + $numbytes = 1; + } + } elseif (($c >> 0x06) === 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN + $bytes[] = $c - 0x80; + if (count($bytes) === $numbytes) { + // compose UTF-8 bytes to a single unicode value + $c = $bytes[0]; + for ($j = 1; $j < $numbytes; $j++) { + $c += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); + } + if ((($c >= 0xD800) and ($c <= 0xDFFF)) or ($c >= 0x10FFFF)) { + // The definition of UTF-8 prohibits encoding character numbers between + // U+D800 and U+DFFF, which are reserved for use with the UTF-16 + // encoding form (as surrogate pairs) and do not directly represent + // characters. + $unicode[] = 0xFFFD; // use replacement character + } else { + $unicode[] = $c; // add char to array + } + // reset data for next char + $bytes = []; + $numbytes = 1; + } + } else { + // use replacement character for other invalid sequences + $unicode[] = 0xFFFD; + $bytes = []; + $numbytes = 1; + } + } + + return $unicode; + } + + /** + * convert UTF-8 to UTF-16 with an additional byte order marker + * at the front if required. + * + * based on the excellent TCPDF code by Nicola Asuni and the + * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html + * + * @access private + * @author Orion Richardson + * @since January 5, 2008 + * + * @param string $text UTF-8 string to process + * @param boolean $bom whether to add the byte order marker + * + * @return string UTF-16 result string + */ + function utf8toUtf16BE(&$text, $bom = true) + { + $out = $bom ? "\xFE\xFF" : ''; + + $unicode = $this->utf8toCodePointsArray($text); + foreach ($unicode as $c) { + if ($c === 0xFFFD) { + $out .= "\xFF\xFD"; // replacement character + } elseif ($c < 0x10000) { + $out .= chr($c >> 0x08) . chr($c & 0xFF); + } else { + $c -= 0x10000; + $w1 = 0xD800 | ($c >> 0x10); + $w2 = 0xDC00 | ($c & 0x3FF); + $out .= chr($w1 >> 0x08) . chr($w1 & 0xFF) . chr($w2 >> 0x08) . chr($w2 & 0xFF); + } + } + + return $out; + } + + /** + * given a start position and information about how text is to be laid out, calculate where + * on the page the text will end + * + * @param $x + * @param $y + * @param $angle + * @param $size + * @param $wa + * @param $text + * @return array + */ + private function getTextPosition($x, $y, $angle, $size, $wa, $text) + { + // given this information return an array containing x and y for the end position as elements 0 and 1 + $w = $this->getTextWidth($size, $text); + + // need to adjust for the number of spaces in this text + $words = explode(' ', $text); + $nspaces = count($words) - 1; + $w += $wa * $nspaces; + $a = deg2rad((float)$angle); + + return [cos($a) * $w + $x, -sin($a) * $w + $y]; + } + + /** + * Callback method used by smallCaps + * + * @param array $matches + * + * @return string + */ + function toUpper($matches) + { + return mb_strtoupper($matches[0]); + } + + function concatMatches($matches) + { + $str = ""; + foreach ($matches as $match) { + $str .= $match[0]; + } + + return $str; + } + + /** + * register text for font subsetting + * + * @param $font + * @param $text + */ + function registerText($font, $text) + { + if (!$this->isUnicode || in_array(mb_strtolower(basename($font)), self::$coreFonts)) { + return; + } + + if (!isset($this->stringSubsets[$font])) { + $this->stringSubsets[$font] = []; + } + + $this->stringSubsets[$font] = array_unique( + array_merge($this->stringSubsets[$font], $this->utf8toCodePointsArray($text)) + ); + } + + /** + * add text to the document, at a specified location, size and angle on the page + * + * @param $x + * @param $y + * @param $size + * @param $text + * @param int $angle + * @param int $wordSpaceAdjust + * @param int $charSpaceAdjust + * @param bool $smallCaps + */ + function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSpaceAdjust = 0, $smallCaps = false) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(["\r", "\n"], "", $text); + + // if ($smallCaps) { + // preg_match_all("/(\P{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + // $lower = $this->concatMatches($matches); + // d($lower); + + // preg_match_all("/(\p{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + // $other = $this->concatMatches($matches); + // d($other); + + // $text = preg_replace_callback("/\p{Ll}/u", array($this, "toUpper"), $text); + // } + + // if there are any open callbacks, then they should be called, to show the start of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $info = [ + 'x' => $x, + 'y' => $y, + 'angle' => $angle, + 'status' => 'sol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ]; + + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + + if ($angle == 0) { + $this->addContent(sprintf("\nBT %.3F %.3F Td", $x, $y)); + } else { + $a = deg2rad((float)$angle); + $this->addContent( + sprintf("\nBT %.3F %.3F %.3F %.3F %.3F %.3F Tm", cos($a), -sin($a), sin($a), cos($a), $x, $y) + ); + } + + if ($wordSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tw", $wordSpaceAdjust)); + } + + if ($charSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tc", $charSpaceAdjust)); + } + + $len = mb_strlen($text); + $start = 0; + + if ($start < $len) { + $part = $text; // OAR - Don't need this anymore, given that $start always equals zero. substr($text, $start); + $place_text = $this->filterText($part, false); + // modify unicode text so that extra word spacing is manually implemented (bug #) + if ($this->fonts[$this->currentFont]['isUnicode'] && $wordSpaceAdjust != 0) { + $space_scale = 1000 / $size; + $place_text = str_replace("\x00\x20", "\x00\x20)\x00\x20" . (-round($space_scale * $wordSpaceAdjust)) . "\x00\x20(", $place_text); + } + $this->addContent(" /F$this->currentFontNum " . sprintf('%.1F Tf ', $size)); + $this->addContent(" [($place_text)] TJ"); + } + + if ($wordSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tw", 0)); + } + + if ($charSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tc", 0)); + } + + $this->addContent(' ET'); + + // if there are any open callbacks, then they should be called, to show the end of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $tmp = $this->getTextPosition($x, $y, $angle, $size, $wordSpaceAdjust, $text); + $info = [ + 'x' => $tmp[0], + 'y' => $tmp[1], + 'angle' => $angle, + 'status' => 'eol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ]; + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + + if ($this->fonts[$this->currentFont]['isSubsetting']) { + $this->registerText($this->currentFont, $text); + } + } + + /** + * calculate how wide a given text string will be on a page, at a given size. + * this can be called externally, but is also used by the other class functions + * + * @param float $size + * @param string $text + * @param float $word_spacing + * @param float $char_spacing + * @return float + */ + function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) + { + static $ord_cache = []; + + // this function should not change any of the settings, though it will need to + // track any directives which change during calculation, so copy them at the start + // and put them back at the end. + $store_currentTextState = $this->currentTextState; + + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(["\r", "\n"], "", $text); + + // converts a number or a float to a string so it can get the width + $text = "$text"; + + // hmm, this is where it all starts to get tricky - use the font information to + // calculate the width of each character, add them up and convert to user units + $w = 0; + $cf = $this->currentFont; + $current_font = $this->fonts[$cf]; + $space_scale = 1000 / ($size > 0 ? $size : 1); + + if ($current_font['isUnicode']) { + // for Unicode, use the code points array to calculate width rather + // than just the string itself + $unicode = $this->utf8toCodePointsArray($text); + + foreach ($unicode as $char) { + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + } + } + } + + // add additional char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * count($unicode); + } + + } else { + // If CPDF is in Unicode mode but the current font does not support Unicode we need to convert the character set to Windows-1252 + if ($this->isUnicode) { + $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); + } + + $len = mb_strlen($text, 'Windows-1252'); + + for ($i = 0; $i < $len; $i++) { + $c = $text[$i]; + $char = isset($ord_cache[$c]) ? $ord_cache[$c] : ($ord_cache[$c] = ord($c)); + + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + } + } + } + + // add additional char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * $len; + } + } + + $this->currentTextState = $store_currentTextState; + $this->setCurrentFont(); + + return $w * $size / 1000; + } + + /** + * this will be called at a new page to return the state to what it was on the + * end of the previous page, before the stack was closed down + * This is to get around not being able to have open 'q' across pages + * + * @param int $pageEnd + */ + function saveState($pageEnd = 0) + { + if ($pageEnd) { + // this will be called at a new page to return the state to what it was on the + // end of the previous page, before the stack was closed down + // This is to get around not being able to have open 'q' across pages + $opt = $this->stateStack[$pageEnd]; + // ok to use this as stack starts numbering at 1 + $this->setColor($opt['col'], true); + $this->setStrokeColor($opt['str'], true); + $this->addContent("\n" . $opt['lin']); + // $this->currentLineStyle = $opt['lin']; + } else { + $this->nStateStack++; + $this->stateStack[$this->nStateStack] = [ + 'col' => $this->currentColor, + 'str' => $this->currentStrokeColor, + 'lin' => $this->currentLineStyle + ]; + } + + $this->save(); + } + + /** + * restore a previously saved state + * + * @param int $pageEnd + */ + function restoreState($pageEnd = 0) + { + if (!$pageEnd) { + $n = $this->nStateStack; + $this->currentColor = $this->stateStack[$n]['col']; + $this->currentStrokeColor = $this->stateStack[$n]['str']; + $this->addContent("\n" . $this->stateStack[$n]['lin']); + $this->currentLineStyle = $this->stateStack[$n]['lin']; + $this->stateStack[$n] = null; + unset($this->stateStack[$n]); + $this->nStateStack--; + } + + $this->restore(); + } + + /** + * make a loose object, the output will go into this object, until it is closed, then will revert to + * the current one. + * this object will not appear until it is included within a page. + * the function will return the object number + * + * @return int + */ + function openObject() + { + $this->nStack++; + $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; + // add a new object of the content type, to hold the data flow + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->currentContents = $this->numObj; + $this->looseObjects[$this->numObj] = 1; + + return $this->numObj; + } + + /** + * open an existing object for editing + * + * @param $id + */ + function reopenObject($id) + { + $this->nStack++; + $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; + $this->currentContents = $id; + + // also if this object is the primary contents for a page, then set the current page to its parent + if (isset($this->objects[$id]['onPage'])) { + $this->currentPage = $this->objects[$id]['onPage']; + } + } + + /** + * close an object + */ + function closeObject() + { + // close the object, as long as there was one open in the first place, which will be indicated by + // an objectId on the stack. + if ($this->nStack > 0) { + $this->currentContents = $this->stack[$this->nStack]['c']; + $this->currentPage = $this->stack[$this->nStack]['p']; + $this->nStack--; + // easier to probably not worry about removing the old entries, they will be overwritten + // if there are new ones. + } + } + + /** + * stop an object from appearing on pages from this point on + * + * @param $id + */ + function stopObject($id) + { + // if an object has been appearing on pages up to now, then stop it, this page will + // be the last one that could contain it. + if (isset($this->addLooseObjects[$id])) { + $this->addLooseObjects[$id] = ''; + } + } + + /** + * after an object has been created, it wil only show if it has been added, using this function. + * + * @param $id + * @param string $options + */ + function addObject($id, $options = 'add') + { + // add the specified object to the page + if (isset($this->looseObjects[$id]) && $this->currentContents != $id) { + // then it is a valid object, and it is not being added to itself + switch ($options) { + case 'all': + // then this object is to be added to this page (done in the next block) and + // all future new pages. + $this->addLooseObjects[$id] = 'all'; + + case 'add': + if (isset($this->objects[$this->currentContents]['onPage'])) { + // then the destination contents is the primary for the page + // (though this object is actually added to that page) + $this->o_page($this->objects[$this->currentContents]['onPage'], 'content', $id); + } + break; + + case 'even': + $this->addLooseObjects[$id] = 'even'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 0) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'odd': + $this->addLooseObjects[$id] = 'odd'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 1) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'next': + $this->addLooseObjects[$id] = 'all'; + break; + + case 'nexteven': + $this->addLooseObjects[$id] = 'even'; + break; + + case 'nextodd': + $this->addLooseObjects[$id] = 'odd'; + break; + } + } + } + + /** + * return a storable representation of a specific object + * + * @param $id + * @return string|null + */ + function serializeObject($id) + { + if (array_key_exists($id, $this->objects)) { + return serialize($this->objects[$id]); + } + + return null; + } + + /** + * restore an object from its stored representation. Returns its new object id. + * + * @param $obj + * @return int + */ + function restoreSerializedObject($obj) + { + $obj_id = $this->openObject(); + $this->objects[$obj_id] = unserialize($obj); + $this->closeObject(); + + return $obj_id; + } + + /** + * Embeds a file inside the PDF + * + * @param string $filepath path to the file to store inside the PDF + * @param string $embeddedFilename the filename displayed in the list of embedded files + * @param string $description a description in the list of embedded files + */ + public function addEmbeddedFile(string $filepath, string $embeddedFilename, string $description): void + { + $this->numObj++; + $this->o_embedded_file_dictionary( + $this->numObj, + 'new', + [ + 'filepath' => $filepath, + 'filename' => $embeddedFilename, + 'description' => $description + ] + ); + } + + /** + * add content to the documents info object + * + * @param $label + * @param int $value + */ + function addInfo($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + // modify this so that arrays can be passed as well. + // if $label is an array then assume that it is key => value pairs + // else assume that they are both scalar, anything else will probably error + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_info($this->infoObject, $l, $v); + } + } else { + $this->o_info($this->infoObject, $label, $value); + } + } + + /** + * set the viewer preferences of the document, it is up to the browser to obey these. + * + * @param $label + * @param int $value + */ + function setPreferences($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_catalog($this->catalogId, 'viewerPreferences', [$l => $v]); + } + } else { + $this->o_catalog($this->catalogId, 'viewerPreferences', [$label => $value]); + } + } + + /** + * extract an integer from a position in a byte stream + * + * @param $data + * @param $pos + * @param $num + * @return int + */ + private function getBytes(&$data, $pos, $num) + { + // return the integer represented by $num bytes from $pos within $data + $ret = 0; + for ($i = 0; $i < $num; $i++) { + $ret *= 256; + $ret += ord($data[$pos + $i]); + } + + return $ret; + } + + /** + * Check if image already added to pdf image directory. + * If yes, need not to create again (pass empty data) + * + * @param string $imgname + * @return bool + */ + function image_iscached($imgname) + { + return isset($this->imagelist[$imgname]); + } + + /** + * add a PNG image into the document, from a GD object + * this should work with remote files + * + * @param \GdImage|resource $img A GD resource + * @param string $file The PNG file + * @param float $x X position + * @param float $y Y position + * @param float $w Width + * @param float $h Height + * @param bool $is_mask true if the image is a mask + * @param bool $mask true if the image is masked + * @throws Exception + */ + function addImagePng(&$img, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) + { + if (!function_exists("imagepng")) { + throw new \Exception("The PHP GD extension is required, but is not installed."); + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $data = null; + } else { + // Example for transparency handling on new image. Retain for current image + // $tIndex = imagecolortransparent($img); + // if ($tIndex > 0) { + // $tColor = imagecolorsforindex($img, $tIndex); + // $new_tIndex = imagecolorallocate($new_img, $tColor['red'], $tColor['green'], $tColor['blue']); + // imagefill($new_img, 0, 0, $new_tIndex); + // imagecolortransparent($new_img, $new_tIndex); + // } + // blending mode (literal/blending) on drawing into current image. not relevant when not saved or not drawn + //imagealphablending($img, true); + + //default, but explicitely set to ensure pdf compatibility + imagesavealpha($img, false/*!$is_mask && !$mask*/); + + $error = 0; + //DEBUG_IMG_TEMP + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addImagePng ' . $file . ']'; + } + + ob_start(); + @imagepng($img); + $data = ob_get_clean(); + + if ($data == '') { + $error = 1; + $errormsg = 'trouble writing file from GD'; + //DEBUG_IMG_TEMP + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print 'trouble writing file from GD'; + } + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + } //End isset($this->imagelist[$file]) (png Duplicate removal) + + $this->addPngFromBuf($data, $file, $x, $y, $w, $h, $is_mask, $mask); + } + + /** + * @param $file + * @param $x + * @param $y + * @param $w + * @param $h + * @param $byte + */ + protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte) + { + // generate images + $img = imagecreatefrompng($file); + + if ($img === false) { + return; + } + + // FIXME The pixel transformation doesn't work well with 8bit PNGs + $eight_bit = ($byte & 4) !== 4; + + $wpx = imagesx($img); + $hpx = imagesy($img); + + imagesavealpha($img, false); + + // create temp alpha file + $tempfile_alpha = @tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_alpha); + $tempfile_alpha = "$tempfile_alpha.png"; + + // create temp plain file + $tempfile_plain = @tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_plain); + $tempfile_plain = "$tempfile_plain.png"; + + $imgalpha = imagecreate($wpx, $hpx); + imagesavealpha($imgalpha, false); + + // generate gray scale palette (0 -> 255) + for ($c = 0; $c < 256; ++$c) { + imagecolorallocate($imgalpha, $c, $c, $c); + } + + // Use PECL gmagick + Graphics Magic to process transparent PNG images + if (extension_loaded("gmagick")) { + $gmagick = new \Gmagick($file); + $gmagick->setimageformat('png'); + + // Get opacity channel (negative of alpha channel) + $alpha_channel_neg = clone $gmagick; + $alpha_channel_neg->separateimagechannel(\Gmagick::CHANNEL_OPACITY); + + // Negate opacity channel + $alpha_channel = new \Gmagick(); + $alpha_channel->newimage($wpx, $hpx, "#FFFFFF", "png"); + $alpha_channel->compositeimage($alpha_channel_neg, \Gmagick::COMPOSITE_DIFFERENCE, 0, 0); + $alpha_channel->separateimagechannel(\Gmagick::CHANNEL_RED); + $alpha_channel->writeimage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + + // Make opaque image + $color_channels = new \Gmagick(); + $color_channels->newimage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeimage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } + // Use PECL imagick + ImageMagic to process transparent PNG images + elseif (extension_loaded("imagick")) { + // Native cloning was added to pecl-imagick in svn commit 263814 + // the first version containing it was 3.0.1RC1 + static $imagickClonable = null; + if ($imagickClonable === null) { + $imagickClonable = true; + if (defined('Imagick::IMAGICK_EXTVER')) { + $imagickVersion = \Imagick::IMAGICK_EXTVER; + } else { + $imagickVersion = '0'; + } + if (version_compare($imagickVersion, '0.0.1', '>=')) { + $imagickClonable = version_compare($imagickVersion, '3.0.1rc1', '>='); + } + } + + $imagick = new \Imagick($file); + $imagick->setFormat('png'); + + // Get opacity channel (negative of alpha channel) + if ($imagick->getImageAlphaChannel() !== 0) { + $alpha_channel = $imagickClonable ? clone $imagick : $imagick->clone(); + $alpha_channel->separateImageChannel(\Imagick::CHANNEL_ALPHA); + // Since ImageMagick7 negate invert transparency as default + if (\Imagick::getVersion()['versionNumber'] < 1800) { + $alpha_channel->negateImage(true); + } + $alpha_channel->writeImage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + } else { + $tempfile_alpha = null; + } + + // Make opaque image + $color_channels = new \Imagick(); + $color_channels->newImage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeImage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } else { + // allocated colors cache + $allocated_colors = []; + + // extract alpha channel + for ($xpx = 0; $xpx < $wpx; ++$xpx) { + for ($ypx = 0; $ypx < $hpx; ++$ypx) { + $color = imagecolorat($img, $xpx, $ypx); + $col = imagecolorsforindex($img, $color); + $alpha = $col['alpha']; + + if ($eight_bit) { + // with gamma correction + $gammacorr = 2.2; + $pixel = round(pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255); + } else { + // without gamma correction + $pixel = (127 - $alpha) * 2; + + $key = $col['red'] . $col['green'] . $col['blue']; + + if (!isset($allocated_colors[$key])) { + $pixel_img = imagecolorallocate($img, $col['red'], $col['green'], $col['blue']); + $allocated_colors[$key] = $pixel_img; + } else { + $pixel_img = $allocated_colors[$key]; + } + + imagesetpixel($img, $xpx, $ypx, $pixel_img); + } + + imagesetpixel($imgalpha, $xpx, $ypx, $pixel); + } + } + + // extract image without alpha channel + $imgplain = imagecreatetruecolor($wpx, $hpx); + imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($img); + + imagepng($imgalpha, $tempfile_alpha); + imagepng($imgplain, $tempfile_plain); + } + + $this->imageAlphaList[$file] = [$tempfile_alpha, $tempfile_plain]; + + // embed mask image + if ($tempfile_alpha) { + $this->addImagePng($imgalpha, $tempfile_alpha, $x, $y, $w, $h, true); + imagedestroy($imgalpha); + $this->imageCache[] = $tempfile_alpha; + } + + // embed image, masked with previously embedded mask + $this->addImagePng($imgplain, $tempfile_plain, $x, $y, $w, $h, false, ($tempfile_alpha !== null)); + imagedestroy($imgplain); + $this->imageCache[] = $tempfile_plain; + } + + /** + * add a PNG image into the document, from a file + * this should work with remote files + * + * @param $file + * @param $x + * @param $y + * @param int $w + * @param int $h + * @throws Exception + */ + function addPngFromFile($file, $x, $y, $w = 0, $h = 0) + { + if (!function_exists("imagecreatefrompng")) { + throw new \Exception("The PHP GD extension is required, but is not installed."); + } + + if (isset($this->imageAlphaList[$file])) { + [$alphaFile, $plainFile] = $this->imageAlphaList[$file]; + + if ($alphaFile) { + $img = null; + $this->addImagePng($img, $alphaFile, $x, $y, $w, $h, true); + } + + $img = null; + $this->addImagePng($img, $plainFile, $x, $y, $w, $h, false, ($plainFile !== null)); + return; + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $img = null; + } else { + $info = file_get_contents($file, false, null, 24, 5); + $meta = unpack("CbitDepth/CcolorType/CcompressionMethod/CfilterMethod/CinterlaceMethod", $info); + $bit_depth = $meta["bitDepth"]; + $color_type = $meta["colorType"]; + + // http://www.w3.org/TR/PNG/#11IHDR + // 3 => indexed + // 4 => greyscale with alpha + // 6 => fullcolor with alpha + $is_alpha = in_array($color_type, [4, 6]) || ($color_type == 3 && $bit_depth != 4); + + if ($is_alpha) { // exclude grayscale alpha + $this->addImagePngAlpha($file, $x, $y, $w, $h, $color_type); + return; + } + + //png files typically contain an alpha channel. + //pdf file format or class.pdf does not support alpha blending. + //on alpha blended images, more transparent areas have a color near black. + //This appears in the result on not storing the alpha channel. + //Correct would be the box background image or its parent when transparent. + //But this would make the image dependent on the background. + //Therefore create an image with white background and copy in + //A more natural background than black is white. + //Therefore create an empty image with white background and merge the + //image in with alpha blending. + $imgtmp = @imagecreatefrompng($file); + if (!$imgtmp) { + return; + } + $sx = imagesx($imgtmp); + $sy = imagesy($imgtmp); + $img = imagecreatetruecolor($sx, $sy); + imagealphablending($img, true); + + // @todo is it still needed ?? + $ti = imagecolortransparent($imgtmp); + if ($ti >= 0) { + $tc = imagecolorsforindex($imgtmp, $ti); + $ti = imagecolorallocate($img, $tc['red'], $tc['green'], $tc['blue']); + imagefill($img, 0, 0, $ti); + imagecolortransparent($img, $ti); + } else { + imagefill($img, 1, 1, imagecolorallocate($img, 255, 255, 255)); + } + + imagecopy($img, $imgtmp, 0, 0, 0, 0, $sx, $sy); + imagedestroy($imgtmp); + } + $this->addImagePng($img, $file, $x, $y, $w, $h); + + if ($img) { + imagedestroy($img); + } + } + + /** + * add a PNG image into the document, from a memory buffer of the file + * + * @param $data + * @param $file + * @param $x + * @param $y + * @param float $w + * @param float $h + * @param bool $is_mask + * @param null $mask + */ + function addPngFromBuf(&$data, $file, $x, $y, $w = 0.0, $h = 0.0, $is_mask = false, $mask = null) + { + if (isset($this->imagelist[$file])) { + $data = null; + $info['width'] = $this->imagelist[$file]['w']; + $info['height'] = $this->imagelist[$file]['h']; + $label = $this->imagelist[$file]['label']; + } else { + if ($data == null) { + $this->addMessage('addPngFromBuf error - data not present!'); + + return; + } + + $error = 0; + + if (!$error) { + $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10); + + if (mb_substr($data, 0, 8, '8bit') != $header) { + $error = 1; + + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile this file does not have a valid header ' . $file . ']'; + } + + $errormsg = 'this file does not have a valid header'; + } + } + + if (!$error) { + // set pointer + $p = 8; + $len = mb_strlen($data, '8bit'); + + // cycle through the file, identifying chunks + $haveHeader = 0; + $info = []; + $idata = ''; + $pdata = ''; + + while ($p < $len) { + $chunkLen = $this->getBytes($data, $p, 4); + $chunkType = mb_substr($data, $p + 4, 4, '8bit'); + + switch ($chunkType) { + case 'IHDR': + // this is where all the file information comes from + $info['width'] = $this->getBytes($data, $p + 8, 4); + $info['height'] = $this->getBytes($data, $p + 12, 4); + $info['bitDepth'] = ord($data[$p + 16]); + $info['colorType'] = ord($data[$p + 17]); + $info['compressionMethod'] = ord($data[$p + 18]); + $info['filterMethod'] = ord($data[$p + 19]); + $info['interlaceMethod'] = ord($data[$p + 20]); + + //print_r($info); + $haveHeader = 1; + if ($info['compressionMethod'] != 0) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported compression method ' . $file . ']'; + } + + $errormsg = 'unsupported compression method'; + } + + if ($info['filterMethod'] != 0) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported filter method ' . $file . ']'; + } + + $errormsg = 'unsupported filter method'; + } + break; + + case 'PLTE': + $pdata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'IDAT': + $idata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'tRNS': + //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk + //print "tRNS found, color type = ".$info['colorType']."\n"; + $transparency = []; + + switch ($info['colorType']) { + // indexed color, rbg + case 3: + /* corresponding to entries in the plte chunk + Alpha for palette index 0: 1 byte + Alpha for palette index 1: 1 byte + ...etc... + */ + // there will be one entry for each palette entry. up until the last non-opaque entry. + // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent) + $transparency['type'] = 'indexed'; + $trans = 0; + + for ($i = $chunkLen; $i >= 0; $i--) { + if (ord($data[$p + 8 + $i]) == 0) { + $trans = $i; + } + } + + $transparency['data'] = $trans; + break; + + // grayscale + case 0: + /* corresponding to entries in the plte chunk + Gray: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + // $transparency['grayscale'] = $this->PRVT_getBytes($data,$p+8,2); // g = grayscale + $transparency['type'] = 'indexed'; + $transparency['data'] = ord($data[$p + 8 + 1]); + break; + + // truecolor + case 2: + /* corresponding to entries in the plte chunk + Red: 2 bytes, range 0 .. (2^bitdepth)-1 + Green: 2 bytes, range 0 .. (2^bitdepth)-1 + Blue: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + $transparency['r'] = $this->getBytes($data, $p + 8, 2); + // r from truecolor + $transparency['g'] = $this->getBytes($data, $p + 10, 2); + // g from truecolor + $transparency['b'] = $this->getBytes($data, $p + 12, 2); + // b from truecolor + + $transparency['type'] = 'color-key'; + break; + + //unsupported transparency type + default: + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported transparency type ' . $file . ']'; + } + break; + } + + // KS End new code + break; + + default: + break; + } + + $p += $chunkLen + 12; + } + + if (!$haveHeader) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile information header is missing ' . $file . ']'; + } + + $errormsg = 'information header is missing'; + } + + if (isset($info['interlaceMethod']) && $info['interlaceMethod']) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile no support for interlaced images in pdf ' . $file . ']'; + } + + $errormsg = 'There appears to be no support for interlaced images in pdf.'; + } + } + + if (!$error && $info['bitDepth'] > 8) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile bit depth of 8 or less is supported ' . $file . ']'; + } + + $errormsg = 'only bit depth of 8 or less is supported'; + } + + if (!$error) { + switch ($info['colorType']) { + case 3: + $color = 'DeviceRGB'; + $ncolor = 1; + break; + + case 2: + $color = 'DeviceRGB'; + $ncolor = 3; + break; + + case 0: + $color = 'DeviceGray'; + $ncolor = 1; + break; + + default: + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile alpha channel not supported: ' . $info['colorType'] . ' ' . $file . ']'; + } + + $errormsg = 'transparency alpha channel not supported, transparency only supported for palette images.'; + } + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + + //print_r($info); + // so this image is ok... add it in. + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + // $this->o_image($this->numObj,'new',array('label' => $label,'data' => $idata,'iw' => $w,'ih' => $h,'type' => 'png','ic' => $info['width'])); + $options = [ + 'label' => $label, + 'data' => $idata, + 'bitsPerComponent' => $info['bitDepth'], + 'pdata' => $pdata, + 'iw' => $info['width'], + 'ih' => $info['height'], + 'type' => 'png', + 'color' => $color, + 'ncolor' => $ncolor, + 'masked' => $mask, + 'isMask' => $is_mask + ]; + + if (isset($transparency)) { + $options['transparency'] = $transparency; + } + + $this->o_image($this->numObj, 'new', $options); + $this->imagelist[$file] = ['label' => $label, 'w' => $info['width'], 'h' => $info['height']]; + } + + if ($is_mask) { + return; + } + + if ($w <= 0 && $h <= 0) { + $w = $info['width']; + $h = $info['height']; + } + + if ($w <= 0) { + $w = $h / $info['height'] * $info['width']; + } + + if ($h <= 0) { + $h = $w * $info['height'] / $info['width']; + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ", $w, $h, $x, $y, $label)); + } + + /** + * add a JPEG image into the document, from a file + * + * @param $img + * @param $x + * @param $y + * @param int $w + * @param int $h + */ + function addJpegFromFile($img, $x, $y, $w = 0, $h = 0) + { + // attempt to add a jpeg image straight from a file, using no GD commands + // note that this function is unable to operate on a remote file. + + if (!file_exists($img)) { + return; + } + + if ($this->image_iscached($img)) { + $data = null; + $imageWidth = $this->imagelist[$img]['w']; + $imageHeight = $this->imagelist[$img]['h']; + $channels = $this->imagelist[$img]['c']; + } else { + $tmp = getimagesize($img); + $imageWidth = $tmp[0]; + $imageHeight = $tmp[1]; + + if (isset($tmp['channels'])) { + $channels = $tmp['channels']; + } else { + $channels = 3; + } + + $data = file_get_contents($img); + } + + if ($w <= 0 && $h <= 0) { + $w = $imageWidth; + } + + if ($w == 0) { + $w = $h / $imageHeight * $imageWidth; + } + + if ($h == 0) { + $h = $w * $imageHeight / $imageWidth; + } + + $this->addJpegImage_common($data, $img, $imageWidth, $imageHeight, $x, $y, $w, $h, $channels); + } + + /** + * common code used by the two JPEG adding functions + * @param $data + * @param $imgname + * @param $imageWidth + * @param $imageHeight + * @param $x + * @param $y + * @param int $w + * @param int $h + * @param int $channels + */ + private function addJpegImage_common( + &$data, + $imgname, + $imageWidth, + $imageHeight, + $x, + $y, + $w = 0, + $h = 0, + $channels = 3 + ) { + if ($this->image_iscached($imgname)) { + $label = $this->imagelist[$imgname]['label']; + //debugpng + //if (DEBUGPNG) print '[addJpegImage_common Duplicate '.$imgname.']'; + + } else { + if ($data == null) { + $this->addMessage('addJpegImage_common error - (' . $imgname . ') data not present!'); + + return; + } + + // note that this function is not to be called externally + // it is just the common code between the GD and the file options + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + $this->o_image( + $this->numObj, + 'new', + [ + 'label' => $label, + 'data' => &$data, + 'iw' => $imageWidth, + 'ih' => $imageHeight, + 'channels' => $channels + ] + ); + + $this->imagelist[$imgname] = [ + 'label' => $label, + 'w' => $imageWidth, + 'h' => $imageHeight, + 'c' => $channels + ]; + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ ", $w, $h, $x, $y, $label)); + } + + /** + * specify where the document should open when it first starts + * + * @param $style + * @param int $a + * @param int $b + * @param int $c + */ + function openHere($style, $a = 0, $b = 0, $c = 0) + { + // this function will open the document at a specified page, in a specified style + // the values for style, and the required parameters are: + // 'XYZ' left, top, zoom + // 'Fit' + // 'FitH' top + // 'FitV' left + // 'FitR' left,bottom,right + // 'FitB' + // 'FitBH' top + // 'FitBV' left + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] + ); + $id = $this->catalogId; + $this->o_catalog($id, 'openHere', $this->numObj); + } + + /** + * Add JavaScript code to the PDF document + * + * @param string $code + */ + function addJavascript($code) + { + $this->javascript .= $code; + } + + /** + * create a labelled destination within the document + * + * @param $label + * @param $style + * @param int $a + * @param int $b + * @param int $c + */ + function addDestination($label, $style, $a = 0, $b = 0, $c = 0) + { + // associates the given label with the destination, it is done this way so that a destination can be specified after + // it has been linked to + // styles are the same as the 'openHere' function + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] + ); + $id = $this->numObj; + + // store the label->idf relationship, note that this means that labels can be used only once + $this->destinations["$label"] = $id; + } + + /** + * define font families, this is used to initialize the font families for the default fonts + * and for the user to add new ones for their fonts. The default bahavious can be overridden should + * that be desired. + * + * @param $family + * @param string $options + */ + function setFontFamily($family, $options = '') + { + if (!is_array($options)) { + if ($family === 'init') { + // set the known family groups + // these font families will be used to enable bold and italic markers to be included + // within text streams. html forms will be used... + $this->fontFamilies['Helvetica.afm'] = + [ + 'b' => 'Helvetica-Bold.afm', + 'i' => 'Helvetica-Oblique.afm', + 'bi' => 'Helvetica-BoldOblique.afm', + 'ib' => 'Helvetica-BoldOblique.afm' + ]; + + $this->fontFamilies['Courier.afm'] = + [ + 'b' => 'Courier-Bold.afm', + 'i' => 'Courier-Oblique.afm', + 'bi' => 'Courier-BoldOblique.afm', + 'ib' => 'Courier-BoldOblique.afm' + ]; + + $this->fontFamilies['Times-Roman.afm'] = + [ + 'b' => 'Times-Bold.afm', + 'i' => 'Times-Italic.afm', + 'bi' => 'Times-BoldItalic.afm', + 'ib' => 'Times-BoldItalic.afm' + ]; + } + } else { + + // the user is trying to set a font family + // note that this can also be used to set the base ones to something else + if (mb_strlen($family)) { + $this->fontFamilies[$family] = $options; + } + } + } + + /** + * used to add messages for use in debugging + * + * @param $message + */ + function addMessage($message) + { + $this->messages .= $message . "\n"; + } + + /** + * a few functions which should allow the document to be treated transactionally. + * + * @param $action + */ + function transaction($action) + { + switch ($action) { + case 'start': + // store all the data away into the checkpoint variable + $data = get_object_vars($this); + $this->checkpoint = $data; + unset($data); + break; + + case 'commit': + if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])) { + $tmp = $this->checkpoint['checkpoint']; + $this->checkpoint = $tmp; + unset($tmp); + } else { + $this->checkpoint = ''; + } + break; + + case 'rewind': + // do not destroy the current checkpoint, but move us back to the state then, so that we can try again + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + + foreach ($tmp as $k => $v) { + if ($k !== 'checkpoint') { + $this->$k = $v; + } + } + unset($tmp); + } + break; + + case 'abort': + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + foreach ($tmp as $k => $v) { + $this->$k = $v; + } + unset($tmp); + } + break; + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php new file mode 100644 index 0000000..62cc74a --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php @@ -0,0 +1,495 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Document; +use Svg\Style; + +class SurfaceCpdf implements SurfaceInterface +{ + const DEBUG = false; + + /** @var \Svg\Surface\CPdf */ + private $canvas; + + private $width; + private $height; + + /** @var Style */ + private $style; + + public function __construct(Document $doc, $canvas = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $dimensions = $doc->getDimensions(); + $w = $dimensions["width"]; + $h = $dimensions["height"]; + + if (!$canvas) { + $canvas = new \Svg\Surface\CPdf(array(0, 0, $w, $h)); + $refl = new \ReflectionClass($canvas); + $canvas->fontcache = realpath(dirname($refl->getFileName()) . "/../../fonts/")."/"; + } + + // Flip PDF coordinate system so that the origin is in + // the top left rather than the bottom left + $canvas->transform(array( + 1, 0, + 0, -1, + 0, $h + )); + + $this->width = $w; + $this->height = $h; + + $this->canvas = $canvas; + } + + function out() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->canvas->output(); + } + + public function save() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->save(); + } + + public function restore() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->restore(); + } + + public function scale($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->transform($x, 0, 0, $y, 0, 0); + } + + public function rotate($angle) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $a = deg2rad($angle); + $cos_a = cos($a); + $sin_a = sin($a); + + $this->transform( + $cos_a, $sin_a, + -$sin_a, $cos_a, + 0, 0 + ); + } + + public function translate($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->transform( + 1, 0, + 0, 1, + $x, $y + ); + } + + public function transform($a, $b, $c, $d, $e, $f) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->canvas->transform(array($a, $b, $c, $d, $e, $f)); + } + + public function beginPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement beginPath() method. + } + + public function closePath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->closePath(); + } + + public function fillStroke(bool $close = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fillStroke($close); + } + + public function clip() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->clip(); + } + + public function fillText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->addText($x, $y, $this->style->fontSize, $text); + } + + public function strokeText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->addText($x, $y, $this->style->fontSize, $text); + } + + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + if (strpos($image, "data:") === 0) { + $parts = explode(',', $image, 2); + + $data = $parts[1]; + $base64 = false; + + $token = strtok($parts[0], ';'); + while ($token !== false) { + if ($token == 'base64') { + $base64 = true; + } + + $token = strtok(';'); + } + + if ($base64) { + $data = base64_decode($data); + } + } + else { + $data = file_get_contents($image); + } + + $image = tempnam(sys_get_temp_dir(), "svg"); + file_put_contents($image, $data); + + $img = $this->image($image, $sx, $sy, $sw, $sh, "normal"); + + + unlink($image); + } + + public static function getimagesize($filename) + { + static $cache = array(); + + if (isset($cache[$filename])) { + return $cache[$filename]; + } + + list($width, $height, $type) = getimagesize($filename); + + if ($width == null || $height == null) { + $data = file_get_contents($filename, null, null, 0, 26); + + if (substr($data, 0, 2) === "BM") { + $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data); + $width = (int)$meta['width']; + $height = (int)$meta['height']; + $type = IMAGETYPE_BMP; + } + } + + return $cache[$filename] = array($width, $height, $type); + } + + function image($img, $x, $y, $w, $h, $resolution = "normal") + { + list($width, $height, $type) = $this->getimagesize($img); + + switch ($type) { + case IMAGETYPE_JPEG: + $this->canvas->addJpegFromFile($img, $x, $y - $h, $w, $h); + break; + + case IMAGETYPE_GIF: + case IMAGETYPE_BMP: + // @todo use cache for BMP and GIF + $img = $this->_convert_gif_bmp_to_png($img, $type); + + case IMAGETYPE_PNG: + $this->canvas->addPngFromFile($img, $x, $y - $h, $w, $h); + break; + + default: + } + } + + public function lineTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->lineTo($x, $y); + } + + public function moveTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->moveTo($x, $y); + } + + public function quadraticCurveTo($cpx, $cpy, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + // FIXME not accurate + $this->canvas->quadTo($cpx, $cpy, $x, $y); + } + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + } + + public function arcTo($x1, $y1, $x2, $y2, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + } + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true); + } + + public function circle($x, $y, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false); + } + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false); + } + + public function fillRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->fill(); + } + + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $canvas = $this->canvas; + + if ($rx <= 0.000001/* && $ry <= 0.000001*/) { + $canvas->rect($x, $y, $w, $h); + + return; + } + + $rx = min($rx, $w / 2); + $rx = min($rx, $h / 2); + + /* Define a path for a rectangle with corners rounded by a given radius. + * Start from the lower left corner and proceed counterclockwise. + */ + $this->moveTo($x + $rx, $y); + + /* Start of the arc segment in the lower right corner */ + $this->lineTo($x + $w - $rx, $y); + + /* Arc segment in the lower right corner */ + $this->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); + + /* Start of the arc segment in the upper right corner */ + $this->lineTo($x + $w, $y + $h - $rx ); + + /* Arc segment in the upper right corner */ + $this->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); + + /* Start of the arc segment in the upper left corner */ + $this->lineTo($x + $rx, $y + $h); + + /* Arc segment in the upper left corner */ + $this->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); + + /* Start of the arc segment in the lower left corner */ + $this->lineTo($x , $y + $rx); + + /* Arc segment in the lower left corner */ + $this->arc($x + $rx, $y + $rx, $rx, 180, 270); + } + + public function fill() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill(); + } + + public function strokeRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->stroke(); + } + + public function stroke(bool $close = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->stroke($close); + } + + public function endPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->endPath(); + } + + public function measureText($text) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $style = $this->getStyle(); + $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + + return $this->canvas->getTextWidth($this->getStyle()->fontSize, $text); + } + + public function getStyle() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->style; + } + + public function setStyle(Style $style) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->style = $style; + $canvas = $this->canvas; + + if (is_array($style->stroke) && $stroke = $style->stroke) { + $canvas->setStrokeColor(array((float)$stroke[0]/255, (float)$stroke[1]/255, (float)$stroke[2]/255), true); + } + + if (is_array($style->fill) && $fill = $style->fill) { + $canvas->setColor(array((float)$fill[0]/255, (float)$fill[1]/255, (float)$fill[2]/255), true); + } + + if ($fillRule = strtolower($style->fillRule)) { + $canvas->setFillRule($fillRule); + } + + $opacity = $style->opacity; + if ($opacity !== null && $opacity < 1.0) { + $canvas->setLineTransparency("Normal", $opacity); + $canvas->currentLineTransparency = null; + + $canvas->setFillTransparency("Normal", $opacity); + $canvas->currentFillTransparency = null; + } + else { + $fillOpacity = $style->fillOpacity; + if ($fillOpacity !== null && $fillOpacity < 1.0) { + $canvas->setFillTransparency("Normal", $fillOpacity); + $canvas->currentFillTransparency = null; + } + + $strokeOpacity = $style->strokeOpacity; + if ($strokeOpacity !== null && $strokeOpacity < 1.0) { + $canvas->setLineTransparency("Normal", $strokeOpacity); + $canvas->currentLineTransparency = null; + } + } + + $dashArray = null; + if ($style->strokeDasharray) { + $dashArray = preg_split('/\s*,\s*/', $style->strokeDasharray); + } + + + $phase=0; + if ($style->strokeDashoffset) { + $phase = $style->strokeDashoffset; + } + + + $canvas->setLineStyle( + $style->strokeWidth, + $style->strokeLinecap, + $style->strokeLinejoin, + $dashArray, + $phase + ); + + $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + } + + public function setFont($family, $style, $weight) + { + $map = [ + "serif" => "times", + "sans-serif" => "helvetica", + "fantasy" => "symbol", + "cursive" => "times", + "monospace" => "courier" + ]; + + $styleMap = [ + "courier" => [ + "" => "Courier", + "b" => "Courier-Bold", + "i" => "Courier-Oblique", + "bi" => "Courier-BoldOblique", + ], + "helvetica" => [ + "" => "Helvetica", + "b" => "Helvetica-Bold", + "i" => "Helvetica-Oblique", + "bi" => "Helvetica-BoldOblique", + ], + "symbol" => [ + "" => "Symbol" + ], + "times" => [ + "" => "Times-Roman", + "b" => "Times-Bold", + "i" => "Times-Italic", + "bi" => "Times-BoldItalic", + ], + ]; + + $family_lc = strtolower($family); + if (isset($map[$family_lc])) { + $family = $map[$family_lc]; + } + + if (isset($styleMap[$family])) { + $key = ""; + + $weight = strtolower($weight); + if ($weight === "bold" || $weight === "bolder" || (is_numeric($weight) && $weight >= 600)) { + $key .= "b"; + } + + $style = strtolower($style); + if ($style === "italic" || $style === "oblique") { + $key .= "i"; + } + + if (isset($styleMap[$family][$key])) { + $family = $styleMap[$family][$key]; + } + } + + $this->canvas->selectFont("$family.afm"); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php new file mode 100644 index 0000000..25b3001 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php @@ -0,0 +1,90 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Style; + +/** + * Interface Surface, like CanvasRenderingContext2D + * + * @package Svg + */ +interface SurfaceInterface +{ + public function save(); + + public function restore(); + + // transformations (default transform is the identity matrix) + public function scale($x, $y); + + public function rotate($angle); + + public function translate($x, $y); + + public function transform($a, $b, $c, $d, $e, $f); + + // path ends + public function beginPath(); + + public function closePath(); + + public function fill(); + + public function stroke(bool $close = false); + + public function endPath(); + + public function fillStroke(bool $close = false); + + public function clip(); + + // text (see also the CanvasDrawingStyles interface) + public function fillText($text, $x, $y, $maxWidth = null); + + public function strokeText($text, $x, $y, $maxWidth = null); + + public function measureText($text); + + // drawing images + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null); + + // paths + public function lineTo($x, $y); + + public function moveTo($x, $y); + + public function quadraticCurveTo($cpx, $cpy, $x, $y); + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + + public function arcTo($x1, $y1, $x2, $y2, $radius); + + public function circle($x, $y, $radius); + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false); + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise); + + // Rectangle + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0); + + public function fillRect($x, $y, $w, $h); + + public function strokeRect($x, $y, $w, $h); + + public function setStyle(Style $style); + + /** + * @return Style + */ + public function getStyle(); + + public function setFont($family, $style, $weight); +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php new file mode 100644 index 0000000..3d25aef --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php @@ -0,0 +1,430 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Style; +use Svg\Document; + +class SurfacePDFLib implements SurfaceInterface +{ + const DEBUG = false; + + private $canvas; + + private $width; + private $height; + + /** @var Style */ + private $style; + + public function __construct(Document $doc, $canvas = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $dimensions = $doc->getDimensions(); + $w = $dimensions["width"]; + $h = $dimensions["height"]; + + if (!$canvas) { + $canvas = new \PDFlib(); + + /* all strings are expected as utf8 */ + $canvas->set_option("stringformat=utf8"); + $canvas->set_option("errorpolicy=return"); + + /* open new PDF file; insert a file name to create the PDF on disk */ + if ($canvas->begin_document("", "") == 0) { + die("Error: " . $canvas->get_errmsg()); + } + $canvas->set_info("Creator", "PDFlib starter sample"); + $canvas->set_info("Title", "starter_graphics"); + + $canvas->begin_page_ext($w, $h, ""); + } + + // Flip PDF coordinate system so that the origin is in + // the top left rather than the bottom left + $canvas->setmatrix( + 1, 0, + 0, -1, + 0, $h + ); + + $this->width = $w; + $this->height = $h; + + $this->canvas = $canvas; + } + + function out() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->canvas->end_page_ext(""); + $this->canvas->end_document(""); + + return $this->canvas->get_buffer(); + } + + public function save() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->save(); + } + + public function restore() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->restore(); + } + + public function scale($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->scale($x, $y); + } + + public function rotate($angle) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->rotate($angle); + } + + public function translate($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->translate($x, $y); + } + + public function transform($a, $b, $c, $d, $e, $f) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->concat($a, $b, $c, $d, $e, $f); + } + + public function beginPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement beginPath() method. + } + + public function closePath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->closepath(); + } + + public function fillStroke(bool $close = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + if ($close) { + $this->canvas->closepath_fill_stroke(); + } else { + $this->canvas->fill_stroke(); + } + } + + public function clip() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->clip(); + } + + public function fillText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->set_text_pos($x, $y); + $this->canvas->show($text); + } + + public function strokeText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement drawImage() method. + } + + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + if (strpos($image, "data:") === 0) { + $data = substr($image, strpos($image, ";") + 1); + if (strpos($data, "base64") === 0) { + $data = base64_decode(substr($data, 7)); + } + } + else { + $data = file_get_contents($image); + } + + $image = tempnam(sys_get_temp_dir(), "svg"); + file_put_contents($image, $data); + + $img = $this->canvas->load_image("auto", $image, ""); + + $sy = $sy - $sh; + $this->canvas->fit_image($img, $sx, $sy, 'boxsize={' . "$sw $sh" . '} fitmethod=entire'); + + unlink($image); + } + + public function lineTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->lineto($x, $y); + } + + public function moveTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->moveto($x, $y); + } + + public function quadraticCurveTo($cpx, $cpy, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + // FIXME not accurate + $this->canvas->curveTo($cpx, $cpy, $cpx, $cpy, $x, $y); + } + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->curveto($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + } + + public function arcTo($x1, $y1, $x2, $y2, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + } + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->arc($x, $y, $radius, $startAngle, $endAngle); + } + + public function circle($x, $y, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->circle($x, $y, $radius); + } + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radiusX, $radiusY); + } + + public function fillRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->fill(); + } + + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $canvas = $this->canvas; + + if ($rx <= 0.000001/* && $ry <= 0.000001*/) { + $canvas->rect($x, $y, $w, $h); + + return; + } + + /* Define a path for a rectangle with corners rounded by a given radius. + * Start from the lower left corner and proceed counterclockwise. + */ + $canvas->moveto($x + $rx, $y); + + /* Start of the arc segment in the lower right corner */ + $canvas->lineto($x + $w - $rx, $y); + + /* Arc segment in the lower right corner */ + $canvas->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); + + /* Start of the arc segment in the upper right corner */ + $canvas->lineto($x + $w, $y + $h - $rx ); + + /* Arc segment in the upper right corner */ + $canvas->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); + + /* Start of the arc segment in the upper left corner */ + $canvas->lineto($x + $rx, $y + $h); + + /* Arc segment in the upper left corner */ + $canvas->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); + + /* Start of the arc segment in the lower left corner */ + $canvas->lineto($x , $y + $rx); + + /* Arc segment in the lower left corner */ + $canvas->arc($x + $rx, $y + $rx, $rx, 180, 270); + } + + public function fill() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill(); + } + + public function strokeRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->stroke(); + } + + public function stroke(bool $close = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + if ($close) { + $this->canvas->closepath_stroke(); + } else { + $this->canvas->stroke(); + } + } + + public function endPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->endPath(); + } + + public function measureText($text) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $style = $this->getStyle(); + $font = $this->getFont($style->fontFamily, $style->fontStyle); + + return $this->canvas->stringwidth($text, $font, $this->getStyle()->fontSize); + } + + public function getStyle() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->style; + } + + public function setStyle(Style $style) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->style = $style; + $canvas = $this->canvas; + + if (is_array($style->stroke) && $stroke = $style->stroke) { + $canvas->setcolor( + "stroke", + "rgb", + $stroke[0] / 255, + $stroke[1] / 255, + $stroke[2] / 255, + null + ); + } + + if (is_array($style->fill) && $fill = $style->fill) { + $canvas->setcolor( + "fill", + "rgb", + $fill[0] / 255, + $fill[1] / 255, + $fill[2] / 255, + null + ); + } + + if ($fillRule = strtolower($style->fillRule)) { + $map = array( + "nonzero" => "winding", + "evenodd" => "evenodd", + ); + + if (isset($map[$fillRule])) { + $fillRule = $map[$fillRule]; + + $canvas->set_parameter("fillrule", $fillRule); + } + } + + $opts = array(); + if ($style->strokeWidth > 0.000001) { + $opts[] = "linewidth=$style->strokeWidth"; + } + + if (in_array($style->strokeLinecap, array("butt", "round", "projecting"))) { + $opts[] = "linecap=$style->strokeLinecap"; + } + + if (in_array($style->strokeLinejoin, array("miter", "round", "bevel"))) { + $opts[] = "linejoin=$style->strokeLinejoin"; + } + + $canvas->set_graphics_option(implode(" ", $opts)); + + $opts = array(); + $opacity = $style->opacity; + if ($opacity !== null && $opacity < 1.0) { + $opts[] = "opacityfill=$opacity"; + $opts[] = "opacitystroke=$opacity"; + } + else { + $fillOpacity = $style->fillOpacity; + if ($fillOpacity !== null && $fillOpacity < 1.0) { + $opts[] = "opacityfill=$fillOpacity"; + } + + $strokeOpacity = $style->strokeOpacity; + if ($strokeOpacity !== null && $strokeOpacity < 1.0) { + $opts[] = "opacitystroke=$strokeOpacity"; + } + } + + if (count($opts)) { + $gs = $canvas->create_gstate(implode(" ", $opts)); + $canvas->set_gstate($gs); + } + + $font = $this->getFont($style->fontFamily, $style->fontStyle); + if ($font) { + $canvas->setfont($font, $style->fontSize); + } + } + + private function getFont($family, $style) + { + $map = array( + "serif" => "Times", + "sans-serif" => "Helvetica", + "fantasy" => "Symbol", + "cursive" => "Times", + "monospace" => "Courier", + + "arial" => "Helvetica", + "verdana" => "Helvetica", + ); + + $family = strtolower($family); + if (isset($map[$family])) { + $family = $map[$family]; + } + + return $this->canvas->load_font($family, "unicode", "fontstyle=$style"); + } + + public function setFont($family, $style, $weight) + { + // TODO: Implement setFont() method. + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php new file mode 100644 index 0000000..9fa6793 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php @@ -0,0 +1,236 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\CssLength; +use Svg\Document; +use Svg\Style; + +abstract class AbstractTag +{ + /** @var Document */ + protected $document; + + public $tagName; + + /** @var Style */ + protected $style; + + protected $attributes = array(); + + protected $hasShape = true; + + /** @var self[] */ + protected $children = array(); + + public function __construct(Document $document, $tagName) + { + $this->document = $document; + $this->tagName = $tagName; + } + + public function getDocument(){ + return $this->document; + } + + /** + * @return Group|null + */ + public function getParentGroup() { + $stack = $this->getDocument()->getStack(); + for ($i = count($stack)-2; $i >= 0; $i--) { + $tag = $stack[$i]; + + if ($tag instanceof Group || $tag instanceof Document) { + return $tag; + } + } + + return null; + } + + public function handle($attributes) + { + $this->attributes = $attributes; + + if (!$this->getDocument()->inDefs) { + $this->before($attributes); + $this->start($attributes); + } + } + + public function handleEnd() + { + if (!$this->getDocument()->inDefs) { + $this->end(); + $this->after(); + } + } + + protected function before($attributes) + { + } + + protected function start($attributes) + { + } + + protected function end() + { + } + + protected function after() + { + } + + public function getAttributes() + { + return $this->attributes; + } + + protected function setStyle(Style $style) + { + $this->style = $style; + + if ($style->display === "none") { + $this->hasShape = false; + } + } + + /** + * @return Style + */ + public function getStyle() + { + return $this->style; + } + + /** + * Make a style object from the tag and its attributes + * + * @param array $attributes + * + * @return Style + */ + protected function makeStyle($attributes) { + $style = new Style(); + $style->inherit($this); + $style->fromStyleSheets($this, $attributes); + $style->fromAttributes($attributes); + + return $style; + } + + protected function applyTransform($attributes) + { + + if (isset($attributes["transform"])) { + $surface = $this->document->getSurface(); + + $transform = $attributes["transform"]; + + $matches = array(); + preg_match_all( + '/(matrix|translate|scale|rotate|skew|skewX|skewY)\((.*?)\)/is', + $transform, + $matches, + PREG_SET_ORDER + ); + + $transformations = array(); + foreach ($matches as $match) { + $arguments = preg_split('/[ ,]+/', $match[2]); + array_unshift($arguments, $match[1]); + $transformations[] = $arguments; + } + + foreach ($transformations as $t) { + switch ($t[0]) { + case "matrix": + $surface->transform($t[1], $t[2], $t[3], $t[4], $t[5], $t[6]); + break; + + case "translate": + $surface->translate($t[1], isset($t[2]) ? $t[2] : 0); + break; + + case "scale": + $surface->scale($t[1], isset($t[2]) ? $t[2] : $t[1]); + break; + + case "rotate": + if (isset($t[2])) { + $t[3] = isset($t[3]) ? $t[3] : 0; + $surface->translate($t[2], $t[3]); + $surface->rotate($t[1]); + $surface->translate(-$t[2], -$t[3]); + } else { + $surface->rotate($t[1]); + } + break; + + case "skewX": + $tan_x = tan(deg2rad($t[1])); + $surface->transform(1, 0, $tan_x, 1, 0, 0); + break; + + case "skewY": + $tan_y = tan(deg2rad($t[1])); + $surface->transform(1, $tan_y, 0, 1, 0, 0); + break; + } + } + } + } + + /** + * Convert the given size for the context of this current tag. + * Takes a pixel-based reference, which is usually specific to the context of the size, + * but the actual reference size will be decided based upon the unit used. + * + * @param string $size + * @param float $pxReference + * + * @return float + */ + protected function convertSize(string $size, float $pxReference): float + { + $length = new CssLength($size); + $reference = $pxReference; + $defaultFontSize = 12; + + switch ($length->getUnit()) { + case "em": + $reference = $this->style->fontSize ?? $defaultFontSize; + break; + case "rem": + $reference = $this->document->style->fontSize ?? $defaultFontSize; + break; + case "ex": + case "ch": + $emRef = $this->style->fontSize ?? $defaultFontSize; + $reference = $emRef * 0.5; + break; + case "vw": + $reference = $this->getDocument()->getWidth(); + break; + case "vh": + $reference = $this->getDocument()->getHeight(); + break; + case "vmin": + $reference = min($this->getDocument()->getHeight(), $this->getDocument()->getWidth()); + break; + case "vmax": + $reference = max($this->getDocument()->getHeight(), $this->getDocument()->getWidth()); + break; + } + + return (new CssLength($size))->toPixels($reference); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php new file mode 100644 index 0000000..6979495 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php @@ -0,0 +1,14 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Anchor extends Group +{ + +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php new file mode 100644 index 0000000..e504ffe --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php @@ -0,0 +1,36 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Circle extends Shape +{ + protected $cx = 0; + protected $cy = 0; + protected $r; + + public function start($attributes) + { + if (isset($attributes['cx'])) { + $width = $this->document->getWidth(); + $this->cx = $this->convertSize($attributes['cx'], $width); + } + if (isset($attributes['cy'])) { + $height = $this->document->getHeight(); + $this->cy = $this->convertSize($attributes['cy'], $height); + } + if (isset($attributes['r'])) { + $diagonal = $this->document->getDiagonal(); + $this->r = $this->convertSize($attributes['r'], $diagonal); + } + + $this->document->getSurface()->circle($this->cx, $this->cy, $this->r); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php new file mode 100644 index 0000000..46722f9 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php @@ -0,0 +1,33 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class ClipPath extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php new file mode 100644 index 0000000..42891e0 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php @@ -0,0 +1,42 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Ellipse extends Shape +{ + protected $cx = 0; + protected $cy = 0; + protected $rx = 0; + protected $ry = 0; + + public function start($attributes) + { + parent::start($attributes); + + $width = $this->document->getWidth(); + $height = $this->document->getHeight(); + + if (isset($attributes['cx'])) { + $this->cx = $this->convertSize($attributes['cx'], $width); + } + if (isset($attributes['cy'])) { + $this->cy = $this->convertSize($attributes['cy'], $height); + } + if (isset($attributes['rx'])) { + $this->rx = $this->convertSize($attributes['rx'], $width); + } + if (isset($attributes['ry'])) { + $this->ry = $this->convertSize($attributes['ry'], $height); + } + + $this->document->getSurface()->ellipse($this->cx, $this->cy, $this->rx, $this->ry, 0, 0, 360, false); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php new file mode 100644 index 0000000..bacb385 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php @@ -0,0 +1,33 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Group extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php new file mode 100644 index 0000000..bda17ea --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php @@ -0,0 +1,68 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Image extends AbstractTag +{ + protected $x = 0; + protected $y = 0; + protected $width = 0; + protected $height = 0; + protected $href = null; + + protected function before($attributes) + { + parent::before($attributes); + + $surface = $this->document->getSurface(); + $surface->save(); + + $this->applyTransform($attributes); + } + + public function start($attributes) + { + $height = $this->document->getHeight(); + $width = $this->document->getWidth(); + $this->y = $height; + + if (isset($attributes['x'])) { + $this->x = $this->convertSize($attributes['x'], $width); + } + if (isset($attributes['y'])) { + $this->y = $height - $this->convertSize($attributes['y'], $height); + } + + if (isset($attributes['width'])) { + $this->width = $this->convertSize($attributes['width'], $width); + } + if (isset($attributes['height'])) { + $this->height = $this->convertSize($attributes['height'], $height); + } + + if (isset($attributes['xlink:href'])) { + $this->href = $attributes['xlink:href']; + } + + if (isset($attributes['href'])) { + $this->href = $attributes['href']; + } + + $this->document->getSurface()->transform(1, 0, 0, -1, 0, $height); + + $this->document->getSurface()->drawImage($this->href, $this->x, $this->y, $this->width, $this->height); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php new file mode 100644 index 0000000..fb3b64c --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php @@ -0,0 +1,43 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Line extends Shape +{ + protected $x1 = 0; + protected $y1 = 0; + + protected $x2 = 0; + protected $y2 = 0; + + public function start($attributes) + { + $height = $this->document->getHeight(); + $width = $this->document->getWidth(); + + if (isset($attributes['x1'])) { + $this->x1 = $this->convertSize($attributes['x1'], $width); + } + if (isset($attributes['y1'])) { + $this->y1 = $this->convertSize($attributes['y1'], $height); + } + if (isset($attributes['x2'])) { + $this->x2 = $this->convertSize($attributes['x2'], $width); + } + if (isset($attributes['y2'])) { + $this->y2 = $this->convertSize($attributes['y2'], $height); + } + + $surface = $this->document->getSurface(); + $surface->moveTo($this->x1, $this->y1); + $surface->lineTo($this->x2, $this->y2); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php new file mode 100644 index 0000000..c5e6397 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php @@ -0,0 +1,83 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + + +use Svg\Gradient; +use Svg\Style; + +class LinearGradient extends AbstractTag +{ + protected $x1; + protected $y1; + protected $x2; + protected $y2; + + /** @var Gradient\Stop[] */ + protected $stops = array(); + + public function start($attributes) + { + parent::start($attributes); + + if (isset($attributes['x1'])) { + $this->x1 = $attributes['x1']; + } + if (isset($attributes['y1'])) { + $this->y1 = $attributes['y1']; + } + if (isset($attributes['x2'])) { + $this->x2 = $attributes['x2']; + } + if (isset($attributes['y2'])) { + $this->y2 = $attributes['y2']; + } + } + + public function getStops() { + if (empty($this->stops)) { + foreach ($this->children as $_child) { + if ($_child->tagName != "stop") { + continue; + } + + $_stop = new Gradient\Stop(); + $_attributes = $_child->attributes; + + // Style + if (isset($_attributes["style"])) { + $_style = Style::parseCssStyle($_attributes["style"]); + + if (isset($_style["stop-color"])) { + $_stop->color = Style::parseColor($_style["stop-color"]); + } + + if (isset($_style["stop-opacity"])) { + $_stop->opacity = max(0, min(1.0, $_style["stop-opacity"])); + } + } + + // Attributes + if (isset($_attributes["offset"])) { + $_stop->offset = $_attributes["offset"]; + } + if (isset($_attributes["stop-color"])) { + $_stop->color = Style::parseColor($_attributes["stop-color"]); + } + if (isset($_attributes["stop-opacity"])) { + $_stop->opacity = max(0, min(1.0, $_attributes["stop-opacity"])); + } + + $this->stops[] = $_stop; + } + } + + return $this->stops; + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php new file mode 100644 index 0000000..3dce7a6 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php @@ -0,0 +1,576 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Surface\SurfaceInterface; + +class Path extends Shape +{ + // kindly borrowed from fabric.util.parsePath. + /* @see https://github.com/fabricjs/fabric.js/blob/master/src/util/path.js#L664 */ + const NUMBER_PATTERN = '([-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?)\s*'; + const COMMA_PATTERN = '(?:\s+,?\s*|,\s*)?'; + const FLAG_PATTERN = '([01])'; + const ARC_REGEXP = '/' + . self::NUMBER_PATTERN + . self::COMMA_PATTERN + . self::NUMBER_PATTERN + . self::COMMA_PATTERN + . self::NUMBER_PATTERN + . self::COMMA_PATTERN + . self::FLAG_PATTERN + . self::COMMA_PATTERN + . self::FLAG_PATTERN + . self::COMMA_PATTERN + . self::NUMBER_PATTERN + . self::COMMA_PATTERN + . self::NUMBER_PATTERN + . '/'; + + static $commandLengths = array( + 'm' => 2, + 'l' => 2, + 'h' => 1, + 'v' => 1, + 'c' => 6, + 's' => 4, + 'q' => 4, + 't' => 2, + 'a' => 7, + ); + + static $repeatedCommands = array( + 'm' => 'l', + 'M' => 'L', + ); + + public static function parse(string $commandSequence): array + { + $commands = array(); + preg_match_all('/([MZLHVCSQTAmzlhvcsqta])([eE ,\-.\d]+)*/', $commandSequence, $commands, PREG_SET_ORDER); + + $path = array(); + foreach ($commands as $c) { + if (count($c) == 3) { + $commandLower = strtolower($c[1]); + + // arcs have special flags that apparently don't require spaces. + if ($commandLower === 'a' && preg_match_all(static::ARC_REGEXP, $c[2], $matches, PREG_PATTERN_ORDER)) { + $numberOfMatches = count($matches[0]); + for ($k = 0; $k < $numberOfMatches; ++$k) { + $path[] = [ + $c[1], + $matches[1][$k], + $matches[2][$k], + $matches[3][$k], + $matches[4][$k], + $matches[5][$k], + $matches[6][$k], + $matches[7][$k], + ]; + } + continue; + } + + $arguments = array(); + preg_match_all('/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/i', $c[2], $arguments, PREG_PATTERN_ORDER); + $item = $arguments[0]; + + if ( + isset(self::$commandLengths[$commandLower]) && + ($commandLength = self::$commandLengths[$commandLower]) && + count($item) > $commandLength + ) { + $repeatedCommand = isset(self::$repeatedCommands[$c[1]]) ? self::$repeatedCommands[$c[1]] : $c[1]; + $command = $c[1]; + + for ($k = 0, $klen = count($item); $k < $klen; $k += $commandLength) { + $_item = array_slice($item, $k, $k + $commandLength); + array_unshift($_item, $command); + $path[] = $_item; + + $command = $repeatedCommand; + } + } else { + array_unshift($item, $c[1]); + $path[] = $item; + } + + } else { + $item = array($c[1]); + + $path[] = $item; + } + } + + return $path; + } + + public function start($attributes) + { + if (!isset($attributes['d'])) { + $this->hasShape = false; + + return; + } + + $path = static::parse($attributes['d']); + $surface = $this->document->getSurface(); + + // From https://github.com/kangax/fabric.js/blob/master/src/shapes/path.class.js + $current = null; // current instruction + $previous = null; + $subpathStartX = 0; + $subpathStartY = 0; + $x = 0; // current x + $y = 0; // current y + $controlX = 0; // current control point x + $controlY = 0; // current control point y + $tempX = null; + $tempY = null; + $tempControlX = null; + $tempControlY = null; + $l = 0; //-((this.width / 2) + $this.pathOffset.x), + $t = 0; //-((this.height / 2) + $this.pathOffset.y), + + foreach ($path as $current) { + switch ($current[0]) { // first letter + case 'l': // lineto, relative + $x += $current[1]; + $y += $current[2]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'L': // lineto, absolute + $x = $current[1]; + $y = $current[2]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'h': // horizontal lineto, relative + $x += $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'H': // horizontal lineto, absolute + $x = $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'v': // vertical lineto, relative + $y += $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'V': // verical lineto, absolute + $y = $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'm': // moveTo, relative + $x += $current[1]; + $y += $current[2]; + $subpathStartX = $x; + $subpathStartY = $y; + $surface->moveTo($x + $l, $y + $t); + break; + + case 'M': // moveTo, absolute + $x = $current[1]; + $y = $current[2]; + $subpathStartX = $x; + $subpathStartY = $y; + $surface->moveTo($x + $l, $y + $t); + break; + + case 'c': // bezierCurveTo, relative + $tempX = $x + $current[5]; + $tempY = $y + $current[6]; + $controlX = $x + $current[3]; + $controlY = $y + $current[4]; + $surface->bezierCurveTo( + $x + $current[1] + $l, // x1 + $y + $current[2] + $t, // y1 + $controlX + $l, // x2 + $controlY + $t, // y2 + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'C': // bezierCurveTo, absolute + $x = $current[5]; + $y = $current[6]; + $controlX = $current[3]; + $controlY = $current[4]; + $surface->bezierCurveTo( + $current[1] + $l, + $current[2] + $t, + $controlX + $l, + $controlY + $t, + $x + $l, + $y + $t + ); + break; + + case 's': // shorthand cubic bezierCurveTo, relative + + // transform to absolute x,y + $tempX = $x + $current[3]; + $tempY = $y + $current[4]; + + if (!preg_match('/[CcSs]/', $previous[0])) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + $controlX = $x; + $controlY = $y; + } else { + // calculate reflection of previous control points + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } + + $surface->bezierCurveTo( + $controlX + $l, + $controlY + $t, + $x + $current[1] + $l, + $y + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + $controlX = $x + $current[1]; + $controlY = $y + $current[2]; + + $x = $tempX; + $y = $tempY; + break; + + case 'S': // shorthand cubic bezierCurveTo, absolute + $tempX = $current[3]; + $tempY = $current[4]; + + if (!preg_match('/[CcSs]/', $previous[0])) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + $controlX = $x; + $controlY = $y; + } else { + // calculate reflection of previous control points + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } + + $surface->bezierCurveTo( + $controlX + $l, + $controlY + $t, + $current[1] + $l, + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + $controlX = $current[1]; + $controlY = $current[2]; + + break; + + case 'q': // quadraticCurveTo, relative + // transform to absolute x,y + $tempX = $x + $current[3]; + $tempY = $y + $current[4]; + + $controlX = $x + $current[1]; + $controlY = $y + $current[2]; + + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'Q': // quadraticCurveTo, absolute + $tempX = $current[3]; + $tempY = $current[4]; + + $surface->quadraticCurveTo( + $current[1] + $l, + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + $controlX = $current[1]; + $controlY = $current[2]; + break; + + case 't': // shorthand quadraticCurveTo, relative + + // transform to absolute x,y + $tempX = $x + $current[1]; + $tempY = $y + $current[2]; + + // calculate reflection of previous control points + if (preg_match('/[QqT]/', $previous[0])) { + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } elseif ($previous[0] === 't') { + $controlX = 2 * $x - $tempControlX; + $controlY = 2 * $y - $tempControlY; + } else { + $controlX = $x; + $controlY = $y; + } + + $tempControlX = $controlX; + $tempControlY = $controlY; + + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'T': + $tempX = $current[1]; + $tempY = $current[2]; + + // calculate reflection of previous control points + if (preg_match('/[QqTt]/', $previous[0])) { + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } else { + $controlX = $x; + $controlY = $y; + } + + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'a': + $this->drawArc( + $surface, + $x + $l, + $y + $t, + array( + $current[1], + $current[2], + $current[3], + $current[4], + $current[5], + $current[6] + $x + $l, + $current[7] + $y + $t + ) + ); + $x += $current[6]; + $y += $current[7]; + break; + + case 'A': + // TODO: optimize this + $this->drawArc( + $surface, + $x + $l, + $y + $t, + array( + $current[1], + $current[2], + $current[3], + $current[4], + $current[5], + $current[6] + $l, + $current[7] + $t + ) + ); + $x = $current[6]; + $y = $current[7]; + break; + + case 'z': + case 'Z': + $x = $subpathStartX; + $y = $subpathStartY; + $surface->closePath(); + break; + } + $previous = $current; + } + } + + function drawArc(SurfaceInterface $surface, $fx, $fy, $coords) + { + $rx = $coords[0]; + $ry = $coords[1]; + $rot = $coords[2]; + $large = $coords[3]; + $sweep = $coords[4]; + $tx = $coords[5]; + $ty = $coords[6]; + $segs = array( + array(), + array(), + array(), + array(), + ); + + $toX = $tx - $fx; + $toY = $ty - $fy; + + if ($toX + $toY === 0) { + return; + } + + $segsNorm = $this->arcToSegments($toX, $toY, $rx, $ry, $large, $sweep, $rot); + + for ($i = 0, $len = count($segsNorm); $i < $len; $i++) { + $segs[$i][0] = $segsNorm[$i][0] + $fx; + $segs[$i][1] = $segsNorm[$i][1] + $fy; + $segs[$i][2] = $segsNorm[$i][2] + $fx; + $segs[$i][3] = $segsNorm[$i][3] + $fy; + $segs[$i][4] = $segsNorm[$i][4] + $fx; + $segs[$i][5] = $segsNorm[$i][5] + $fy; + + call_user_func_array(array($surface, "bezierCurveTo"), $segs[$i]); + } + } + + function arcToSegments($toX, $toY, $rx, $ry, $large, $sweep, $rotateX) + { + $th = $rotateX * M_PI / 180; + $sinTh = sin($th); + $cosTh = cos($th); + $fromX = 0; + $fromY = 0; + + $rx = abs($rx); + $ry = abs($ry); + + $px = -$cosTh * $toX * 0.5 - $sinTh * $toY * 0.5; + $py = -$cosTh * $toY * 0.5 + $sinTh * $toX * 0.5; + $rx2 = $rx * $rx; + $ry2 = $ry * $ry; + $py2 = $py * $py; + $px2 = $px * $px; + $pl = $rx2 * $ry2 - $rx2 * $py2 - $ry2 * $px2; + $root = 0; + + if ($pl < 0) { + $s = sqrt(1 - $pl / ($rx2 * $ry2)); + $rx *= $s; + $ry *= $s; + } else { + $root = ($large == $sweep ? -1.0 : 1.0) * sqrt($pl / ($rx2 * $py2 + $ry2 * $px2)); + } + + $cx = $root * $rx * $py / $ry; + $cy = -$root * $ry * $px / $rx; + $cx1 = $cosTh * $cx - $sinTh * $cy + $toX * 0.5; + $cy1 = $sinTh * $cx + $cosTh * $cy + $toY * 0.5; + $mTheta = $this->calcVectorAngle(1, 0, ($px - $cx) / $rx, ($py - $cy) / $ry); + $dtheta = $this->calcVectorAngle(($px - $cx) / $rx, ($py - $cy) / $ry, (-$px - $cx) / $rx, (-$py - $cy) / $ry); + + if ($sweep == 0 && $dtheta > 0) { + $dtheta -= 2 * M_PI; + } else { + if ($sweep == 1 && $dtheta < 0) { + $dtheta += 2 * M_PI; + } + } + + // $Convert $into $cubic $bezier $segments <= 90deg + $segments = ceil(abs($dtheta / M_PI * 2)); + $result = array(); + $mDelta = $dtheta / $segments; + $mT = 8 / 3 * sin($mDelta / 4) * sin($mDelta / 4) / sin($mDelta / 2); + $th3 = $mTheta + $mDelta; + + for ($i = 0; $i < $segments; $i++) { + $result[$i] = $this->segmentToBezier( + $mTheta, + $th3, + $cosTh, + $sinTh, + $rx, + $ry, + $cx1, + $cy1, + $mT, + $fromX, + $fromY + ); + $fromX = $result[$i][4]; + $fromY = $result[$i][5]; + $mTheta = $th3; + $th3 += $mDelta; + } + + return $result; + } + + function segmentToBezier($th2, $th3, $cosTh, $sinTh, $rx, $ry, $cx1, $cy1, $mT, $fromX, $fromY) + { + $costh2 = cos($th2); + $sinth2 = sin($th2); + $costh3 = cos($th3); + $sinth3 = sin($th3); + $toX = $cosTh * $rx * $costh3 - $sinTh * $ry * $sinth3 + $cx1; + $toY = $sinTh * $rx * $costh3 + $cosTh * $ry * $sinth3 + $cy1; + $cp1X = $fromX + $mT * (-$cosTh * $rx * $sinth2 - $sinTh * $ry * $costh2); + $cp1Y = $fromY + $mT * (-$sinTh * $rx * $sinth2 + $cosTh * $ry * $costh2); + $cp2X = $toX + $mT * ($cosTh * $rx * $sinth3 + $sinTh * $ry * $costh3); + $cp2Y = $toY + $mT * ($sinTh * $rx * $sinth3 - $cosTh * $ry * $costh3); + + return array( + $cp1X, + $cp1Y, + $cp2X, + $cp2Y, + $toX, + $toY + ); + } + + function calcVectorAngle($ux, $uy, $vx, $vy) + { + $ta = atan2($uy, $ux); + $tb = atan2($vy, $vx); + if ($tb >= $ta) { + return $tb - $ta; + } else { + return 2 * M_PI - ($ta - $tb); + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php new file mode 100644 index 0000000..e7ca92a --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php @@ -0,0 +1,42 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Polygon extends Shape +{ + public function start($attributes) + { + $tmp = array(); + preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp, PREG_PATTERN_ORDER); + + $points = $tmp[0]; + $count = count($points); + + if ($count < 4) { + // nothing to draw + return; + } + + $surface = $this->document->getSurface(); + list($x, $y) = $points; + $surface->moveTo($x, $y); + + for ($i = 2; $i < $count; $i += 2) { + if ($i + 1 === $count) { + // invalid trailing point + continue; + } + $x = $points[$i]; + $y = $points[$i + 1]; + $surface->lineTo($x, $y); + } + + $surface->closePath(); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php new file mode 100644 index 0000000..45e2131 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php @@ -0,0 +1,40 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Polyline extends Shape +{ + public function start($attributes) + { + $tmp = array(); + preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp, PREG_PATTERN_ORDER); + + $points = $tmp[0]; + $count = count($points); + + if ($count < 4) { + // nothing to draw + return; + } + + $surface = $this->document->getSurface(); + list($x, $y) = $points; + $surface->moveTo($x, $y); + + for ($i = 2; $i < $count; $i += 2) { + if ($i + 1 === $count) { + // invalid trailing point + continue; + } + $x = $points[$i]; + $y = $points[$i + 1]; + $surface->lineTo($x, $y); + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php new file mode 100644 index 0000000..a9de62f --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php @@ -0,0 +1,17 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class RadialGradient extends AbstractTag +{ + public function start($attributes) + { + + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php new file mode 100644 index 0000000..b5f3f77 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php @@ -0,0 +1,50 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Rect extends Shape +{ + protected $x = 0; + protected $y = 0; + protected $width = 0; + protected $height = 0; + protected $rx = 0; + protected $ry = 0; + + public function start($attributes) + { + $width = $this->document->getWidth(); + $height = $this->document->getHeight(); + + if (isset($attributes['x'])) { + $this->x = $this->convertSize($attributes['x'], $width); + } + if (isset($attributes['y'])) { + $this->y = $this->convertSize($attributes['y'], $height); + } + + if (isset($attributes['width'])) { + $this->width = $this->convertSize($attributes['width'], $width); + } + if (isset($attributes['height'])) { + $this->height = $this->convertSize($attributes['height'], $height); + } + + if (isset($attributes['rx'])) { + $this->rx = $attributes['rx']; + } + if (isset($attributes['ry'])) { + $this->ry = $attributes['ry']; + } + + $this->document->getSurface()->rect($this->x, $this->y, $this->width, $this->height, $this->rx, $this->ry); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php new file mode 100644 index 0000000..767e81d --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php @@ -0,0 +1,63 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Shape extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $surface = $this->document->getSurface(); + + if ($this->hasShape) { + $style = $surface->getStyle(); + + $fill = $style->fill && is_array($style->fill); + $stroke = $style->stroke && is_array($style->stroke); + + if ($fill) { + if ($stroke) { + $surface->fillStroke(false); + } else { +// if (is_string($style->fill)) { +// /** @var LinearGradient|RadialGradient $gradient */ +// $gradient = $this->getDocument()->getDef($style->fill); +// +// var_dump($gradient->getStops()); +// } + + $surface->fill(); + } + } + elseif ($stroke) { + $surface->stroke(false); + } + else { + $surface->endPath(); + } + } + + $surface->restore(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php new file mode 100644 index 0000000..22c9a98 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php @@ -0,0 +1,17 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Stop extends AbstractTag +{ + public function start($attributes) + { + + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php new file mode 100644 index 0000000..309de01 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php @@ -0,0 +1,27 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Sabberworm\CSS; + +class StyleTag extends AbstractTag +{ + protected $text = ""; + + public function end() + { + $parser = new CSS\Parser($this->text); + $this->document->appendStyleSheet($parser->parse()); + } + + public function appendText($text) + { + $this->text .= $text; + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php new file mode 100644 index 0000000..80e08a6 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php @@ -0,0 +1,72 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Text extends Shape +{ + protected $x = 0; + protected $y = 0; + protected $text = ""; + + public function start($attributes) + { + $height = $this->document->getHeight(); + $this->y = $height; + + if (isset($attributes['x'])) { + $width = $this->document->getWidth(); + $this->x = $this->convertSize($attributes['x'], $width); + } + if (isset($attributes['y'])) { + $this->y = $height - $this->convertSize($attributes['y'], $height); + } + + $this->document->getSurface()->transform(1, 0, 0, -1, 0, $height); + } + + public function end() + { + $surface = $this->document->getSurface(); + $x = $this->x; + $y = $this->y; + $style = $surface->getStyle(); + $surface->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + + switch ($style->textAnchor) { + case "middle": + $width = $surface->measureText($this->text); + $x -= $width / 2; + break; + + case "end": + $width = $surface->measureText($this->text); + $x -= $width; + break; + } + + $surface->fillText($this->getText(), $x, $y); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } + + public function appendText($text) + { + $this->text .= $text; + } + + public function getText() + { + return trim($this->text); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php new file mode 100644 index 0000000..c5f00ea --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php @@ -0,0 +1,102 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class UseTag extends AbstractTag +{ + protected $x = 0; + protected $y = 0; + protected $width; + protected $height; + + /** @var AbstractTag */ + protected $reference; + + protected function before($attributes) + { + if (isset($attributes['x'])) { + $this->x = $attributes['x']; + } + if (isset($attributes['y'])) { + $this->y = $attributes['y']; + } + + if (isset($attributes['width'])) { + $this->width = $attributes['width']; + } + if (isset($attributes['height'])) { + $this->height = $attributes['height']; + } + + parent::before($attributes); + + $document = $this->getDocument(); + + $link = $attributes["href"] ?? $attributes["xlink:href"]; + $this->reference = $document->getDef($link); + + if ($this->reference) { + $this->reference->before($attributes); + } + + $surface = $document->getSurface(); + $surface->save(); + + $surface->translate($this->x, $this->y); + } + + protected function after() { + parent::after(); + + if ($this->reference) { + $this->reference->after(); + } + + $this->getDocument()->getSurface()->restore(); + } + + public function handle($attributes) + { + parent::handle($attributes); + + if (!$this->reference) { + return; + } + + $mergedAttributes = $this->reference->attributes; + $attributesToNotMerge = ['x', 'y', 'width', 'height']; + foreach ($attributes as $attrKey => $attrVal) { + if (!in_array($attrKey, $attributesToNotMerge) && !isset($mergedAttributes[$attrKey])) { + $mergedAttributes[$attrKey] = $attrVal; + } + } + + $this->reference->handle($mergedAttributes); + + foreach ($this->reference->children as $_child) { + $_attributes = array_merge($_child->attributes, $mergedAttributes); + $_child->handle($_attributes); + } + } + + public function handleEnd() + { + parent::handleEnd(); + + if (!$this->reference) { + return; + } + + $this->reference->handleEnd(); + + foreach ($this->reference->children as $_child) { + $_child->handleEnd(); + } + } +} -- cgit v1.2.3